SolidWorks APIの深淵:`SketchManager.CreateSpline` による自由曲面デザインスケッチ完全自動化
意匠性の高い製品設計や流体力学に基づいた翼形状、あるいはエルゴノミクスデザインのパーツ――これらをプログラムから自動生成しようとした際、多くのエンジニアが最初に突き当たる壁が「スプライン曲線の自動制御」です。
単なる直線(`CreateLine`)や円弧(`CreateArc`)の組み合わせとは異なり、自由曲面を定義するスプラインは、数学的連続性(C1, C2連続)やSolidWorks内部のカーネル(Parasolid)への依存度が極めて高いジオメトリです。安易な座標配列の流し込みは、スケッチの自己交差、再計算エラー、ひいてはCADモデルの崩壊を招きます。
本記事では、SolidWorks VBAを知り尽くしたチーフアーキテクトの視点から、プロダクション環境で耐えうる`SketchManager.CreateSpline`を活用した高精度なスケッチ自動化手法を徹底解説します。
—
1. スプライン自動生成における「3つの罠」と内部メカニズム
コードを書く前に、なぜ素人が書いたVBAスクリプトが実務で破綻するのか、SolidWorks APIの内部挙動からその理由を解明します。
罠①:単位系の絶対規則(SI単位系:メートル主義)
SolidWorks APIは、アクティブなドキュメントの表示単位が「mm」であろうと「inch」であろうと、内部的には絶対的に「メートル(m)」で数値を処理します。
VBA側で `100`(100mmのつもり)という値を渡すと、SolidWorksはそれを `100m` と解釈し、グラフィックス領域の遥か彼方に巨大なジオメトリを生成します。単位変換ロジックをカプセル化しない設計はバグの温床です。
罠②:座標配列のメモリレイアウト
`SketchManager.CreateSpline` メソッドが要求する引数は、単なる2次元配列ではありません。`x, y, z` の要素が連続した1次元の `Double` 型配列(Variant化)です。
配列の要素数や型宣言にわずかでも矛盾があると、VBAは型不一致のエラー(Runtime Error 13)を吐くか、サイレントにSolidWorksをクラッシュさせます。
罠③:画面描画とパイプラインのオーバーヘッド
ループ処理で大量の制御点を打ちながらスプラインを生成する際、SolidWorksのUI(グラフィックスビューおよびFeatureManagerデザインツリー)の描画更新を有効にしたままだと、処理時間は指数関数的に増加します。100点の制御点を持つスプラインを生成する場合、UI制御を行うかどうかで処理速度に10倍以上の差が生じます。
—
2. 保守性と堅牢性を担保するアーキテクチャ設計
現場で長く使われる自動化ツールを作るには、データソース(CSV/DB/アルゴリズム)とCAD描画ロジックを明確に分離(関心事の分離)しなければなりません。
[データソース] [データ変換層] [SolidWorks API層]
CSV / Excel / DB –> Point3D構造体配列 –> SplineBuilderモジュール
(数値データ) (mm -> m 単位変換) (画面更新停止・安全生成)
この分離を行うことで、将来的に入力ソースがExcelから基幹システム(PLM/DB)へ変更された場合でも、SolidWorks描画エンジンのコードには一切手を加える必要がなくなります。
—
3. プロダクショングレードのVBA実装コード
以下に、実務でそのまま導入可能なリファクタリング済みのVBAコードを示します。
厳格なエラーハンドリング、描画最適化、リソース解放処理を網羅しています。
モジュール構成
1. `clsPoint3D`(または標準モジュールの構造体):座標データ保持用
2. `modSplineAutomation`:メイン処理およびCAD制御ロジック
構造体定義(標準モジュール上部に記述)
Public Type Point3D
X As Double ‘ [mm] 単位で保持
Y As Double ‘ [mm] 単位で保持
Z As Double ‘ [mm] 単位で保持
End Type
メインモジュールコード
Option Explicit
‘ ==============================================================================
‘ 定数定義
‘ ==============================================================================
Private Const MM_TO_M As Double = 0.001 ‘ mmからmへの変換係数
‘ ==============================================================================
‘ メインエントリポイント
‘ ==============================================================================
Public Sub Execute_CreateSplineDesign()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Dim swSketchMgr As SldWorks.SketchManager
Dim swModelExt As SldWorks.ModelDocExtension
‘ 1. SolidWorksインスタンスの取得
On Error Resume Next
Set swApp = Application.SldWorks
On Error GoTo ErrorHandler
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical, “エラー”
Exit Sub
End If
‘ 2. 新規パーツドキュメントの作成
Set swModel = swApp.NewDocument(swApp.GetUserPreferenceStringValue(swUserPreferenceStringValue_e.swDefaultTemplatePart), 0, 0, 0)
If swModel Is Nothing Then
Err.Raise vbObjectError + 513, , “新規パーツテンプレートの読み込みに失敗しました。”
End If
Set swPart = swModel
Set swSketchMgr = swModel.SketchManager
Set swModelExt = swModel.Extension
‘ 3. パフォーマンス最適化:描画・計算の凍結
ConfigurePerformanceMode swApp, swModel, True
‘ 4. 座標データの準備(実務ではCSVやDBから取得する層)
Dim ctrlPoints() As Point3D
ctrlPoints = SampleData_GetNACAProfile() ‘ 例として翼型風のデータ群を取得
‘ 5. スケッチ平面の選択(「前準面 / Front Plane」を選択)
Dim selectSuccess As Boolean
selectSuccess = swModelExt.SelectByID2(“Front Plane”, “PLANE”, 0, 0, 0, False, 0, Nothing, 0)
If Not selectSuccess Then
‘ 英語環境へのフォールバック処理
selectSuccess = swModelExt.SelectByID2(“前準面”, “PLANE”, 0, 0, 0, False, 0, Nothing, 0)
End If
If Not selectSuccess Then
Err.Raise vbObjectError + 514, , “スケッチ平面の選択に失敗しました。”
End If
‘ 6. スケッチの開始
swSketchMgr.InsertSketch True
‘ 7. スプライン曲線の生成
Dim swSketchSegment As SldWorks.SketchSegment
Set swSketchSegment = BuildSpline(swSketchMgr, ctrlPoints)
If swSketchSegment Is Nothing Then
Err.Raise vbObjectError + 515, , “スプラインの生成に失敗しました。”
End If
‘ 8. スケッチの終了とビューのフィット
swSketchMgr.InsertSketch True
swModel.ViewZoomtofit2
MsgBox “スプラインスケッチの生成が正常に完了しました。”, vbInformation, “成功”
CleanUp:
‘ パフォーマンス最適化の解除(必ず通過させる)
If Not swApp Is Nothing And Not swModel Is Nothing Then
ConfigurePerformanceMode swApp, swModel, False
End If
‘ メモリ開放
Set swSketchSegment = Nothing
Set swSketchMgr = Nothing
Set swPart = Nothing
Set swModel = Nothing
Set swApp = Nothing
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました:” & vbCrLf & Err.Description, vbCritical, “実行時エラー”
Resume CleanUp
End Sub
‘ ==============================================================================
‘ スプライン生成コアロジック
‘ ==============================================================================
Private Function BuildSpline(ByRef sketchMgr As SldWorks.SketchManager, ByRef points() As Point3D) As SldWorks.SketchSegment
Dim pointCount As Long
pointCount = UBound(points) – LBound(points) + 1
If pointCount < 2 Then
Exit Function ' 制御点が足らない場合はスプラインを定義できない
End If
' APIに渡す1次元配列の作成 (各点につき X, Y, Z の3要素)
Dim rawCoords() As Double
ReDim rawCoords(0 To (pointCount 3) - 1)
Dim i As Long
Dim idx As Long
idx = 0
' 単位変換 (mm -> m) を適用しながら平坦配列に詰め替える
For i = LBound(points) To UBound(points)
rawCoords(idx) = points(i).X MM_TO_M
rawCoords(idx + 1) = points(i).Y MM_TO_M
rawCoords(idx + 2) = points(i).Z MM_TO_M
idx = idx + 3
Next i
‘ SolidWorks API CreateSpline の呼び出し
‘ Variant型にキャストして配列を渡す
Dim vCoords As Variant
vCoords = rawCoords
Set BuildSpline = sketchMgr.CreateSpline(vCoords)
End Function
‘ ==============================================================================
‘ パフォーマンス制御用サブルーチン
‘ ==============================================================================
Private Sub ConfigurePerformanceMode(ByRef swApp As SldWorks.SldWorks, ByRef swModel As SldWorks.ModelDoc2, ByVal enableOptimization As Boolean)
On Error Resume Next
If enableOptimization Then
swApp.CommandInProgress = True
swModel.FeatureManager.EnableFeatureTree = False
swModel.ActiveView.EnableGraphicsUpdate = False
Else
swApp.CommandInProgress = False
swModel.FeatureManager.EnableFeatureTree = True
swModel.ActiveView.EnableGraphicsUpdate = True
swModel.ForceRebuild3 False
End If
On Error GoTo 0
End Sub
‘ ==============================================================================
‘ テスト用データ生成(NACA風の翼型カーブ座標群)
‘ ==============================================================================
Private Function SampleData_GetNACAProfile() As Point3D()
Dim pts(0 To 10) As Point3D
‘ 単位: [mm]
pts(0).X = 200#: pts(0).Y = 0#: pts(0).Z = 0#
pts(1).X = 160#: pts(1).Y = 15#: pts(1).Z = 0#
pts(2).X = 120#: pts(2).Y = 25#: pts(2).Z = 0#
pts(3).X = 70#: pts(3).Y = 28#: pts(3).Z = 0#
pts(4).X = 30#: pts(4).Y = 20#: pts(4).Z = 0#
pts(5).X = 0#: pts(5).Y = 0#: pts(5).Z = 0#
pts(6).X = 30#: pts(6).Y = -10#: pts(6).Z = 0#
pts(7).X = 70#: pts(7).Y = -12#: pts(7).Z = 0#
pts(8).X = 120#: pts(8).Y = -10#: pts(8).Z = 0#
pts(9).X = 160#: pts(9).Y = -5#: pts(9).Z = 0#
pts(10).X = 200#: pts(10).Y = 0#: pts(10).Z = 0#
SampleData_GetNACAProfile = pts
End Function
—
4. 現場で直面する高度なトラブルシューティング
閉曲線(Closed Spline)の公差(Tolerance)問題
意匠設計や押し出しボス成形を行う場合、スプラインが「完全に閉じているか」が運命を分けます。
始点座標 `pts(0)` と終点座標 `pts(N)` が数学的に微妙にズレている場合(浮動小数点演算誤差など)、SolidWorksはこれを「開いたスケッチ」と認識し、サーフェスにしかなりません。
対策:
VBA側で明示的に始点と終点の距離を計算し、許容値(例: $10^{-6}$ mm以下)であれば終点座標に始点座標を代入するスナップ処理を自動化モジュール内に実装してください。
‘ 始点と終点の強制スナップ処理例
Dim dist As Double
dist = Sqr((pts(0).X – pts(N).X)^2 + (pts(0).Y – pts(N).Y)^2 + (pts(0).Z – pts(N).Z)^2)
If dist < 0.000001 Then ' 1μm以下の場合は完全一致とみなす pts(N).X = pts(0).X pts(N).Y = pts(0).Y pts(N).Z = pts(0).Z End If
スプラインの品質と曲率不連続(C2連続性)
`CreateSpline` で生成されるスプラインは、通過点を補間するB-Splineです。急激に座標が変化する点列を流し込むと、曲率グラフ(Curvature Comb)が急跳びし、後の「ロフト」や「スイープ」フィーチャ作成時にParasolidカーネルが幾何エラーを報告します。
幾何精度の高いデザインを自動生成する場合は、点列のピッチを曲率半径に応じて可変にする(曲率が大きい箇所は密に、直線に近い箇所は疎にする)前処理ロジックを入れるのが設計アーキテクトの真骨頂です。
—
5. まとめ:プロフェッショナルなCAD自動化への道
SolidWorksにおけるスケッチ自動化は、単なる「操作の記録」ではありません。
- 単位系(m/mm)の厳密な管理
- 画面描画と再計算パイプラインの停止による高速化
- 幾何公差を考慮した座標データのクリーニング
- エラーハンドリングと安全なメモリ・UI復元
これらが組み合わさって初めて、実務のプロダクション環境で「止まらない、バグらない自動化ツール」が完成します。
今回提示したモジュール構成をベースに、自社のCSVデータ解析や計算アルゴリズムを組み込み、次世代の3D意匠自動設計エンジンの構築へ足を踏み入れてください。
