SolidWorks VBAを掌握する極限の知見
アセンブリの運動シネマティクス検証:可動合致の連続駆動と干渉スナップショット自動化
機構設計の最終段階において、最も恐れられるフェーズは「干渉チェック」である。静的な状態での干渉回避はCADの基本機能で完結するが、実際のメカニズムが可動範囲の端から端まで動いたとき、予期せぬ部品同士の衝突が起きることは珍しくない。
手動でアセンブリの合致(Mate)の角度や距離を少しずつ動かし、その都度干渉を確認して画面キャプチャを撮る――この泥臭い作業にエンジニアの貴重な時間を奪われてはならない。
今回は、SolidWorks APIとVBAを駆使し、「可動合致のパラメータをプログラムで連続的に変化させ、全ストロークにわたる干渉チェックと高解像度スナップショットの保存を完全自動化するシステム」の構築手法を解説する。
—
1. 限界領域を突破するアーキテクチャの設計思想
SolidWorks VBAによるシネマティクス検証において、初心者が陥る最大の罠は「画面描画(Graphics Update)とオブジェクト解放のライフサイクル管理の欠落」である。
数千ステップに及ぶループ処理の中で、毎回画面を再描画させ、生成されたCOMオブジェクトを放置すれば、メモリリークによるSolidWorksの強制終了(クラッシュ)は免れない。
本システムでは、以下の極限最適化を施す。
1. 画面描画の完全抑制(UserControlの制御): 処理速度を最大化するため、VBAからSolidWorksのGUI描画をロックする。
2. 合致値の動的書き換えと強制解決(Rebuild): `IMate2::ChamferOrDist` や角度プロパティを直接書き換え、`IModelDocExt::Rebuild` で最小限の再計算を行わせる。
3. 干渉検出APIの高速ポーリング: `IModelDocExtension::InterferenceDetectionMgr` を用いて、アセンブリ全体の干渉を高精度かつ高速に検知する。
4. メモリの厳格な解放: ループ内で生成される一時的な配列やCOMラッパーは、即座に `Nothing` を代入して参照カウンタを適正にデクリメントする。
—
2. 実装コード:シネマティクス検証エンジン
以下のコードは、アセンブリ内の特定の「角度合致(Angle Mate)」を初期角度から終端角度まで指定ステップで動かし、各ステップで干渉チェックと画像保存を実行するプロダクションレベルのVBAモジュールである。
Option Explicit
‘ =========================================================================
‘ 慈悲なきシネマティクス検証・自動キャプチャシステム
‘ Architecture: SolidWorks API + VBA Extreme Optimization
‘ =========================================================================
Public Sub RunKinematicsValidation()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssembly As SldWorks.AssemblyDoc
Dim swMate As SldWorks.Mate2
Dim boolstatus As Boolean
‘ 1. アプリケーションコンテキストの取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical
Exit Sub
End If
If swModel.GetType <> swDocASSEMBLY Then
MsgBox “対象はアセンブリ文書である必要があります。”, vbCritical
Exit Sub
End If
Set swAssembly = swModel
‘ 2. 対象となる合致(Angle Mate)の取得
‘ ※あらかじめFeatureManagerで対象の合致名称を確認しておくこと
Dim targetMateName As String
targetMateName = “Angle1” ‘ 実際の合致名に変更してください
Dim swFeat As SldWorks.Feature
Set swFeat = swModel.Extension.GetFeatureByName(targetMateName)
If swFeat Is Nothing Then
MsgBox “指定された合致が見つかりません: ” & targetMateName, vbCritical
Exit Sub
End If
Set swMate = swFeat.GetSpecificFeature2
If swMate Is Nothing Then
Set swFeat = Nothing
Exit Sub
End If
‘ 3. 実行時パフォーマンスの極限最適化(画面描画の凍結)
swApp.UserControl = False
swModel.Visible = False ‘ バックグラウンド処理により描画負荷を排除する場合(任意)
swModel.Visible = True ‘ 画像キャプチャを行うため可視状態は維持しつつ描画を止める
swModel.Extension.EnableGraphicsUpdate = False
On Error GoTo ErrorHandler
‘ 4. シネマティクス・ループの定義
Dim startAngle As Double: startAngle = 0# ‘ 開始角度 (度)
Dim endAngle As Double: endAngle = 90# ‘ 終了角度 (度)
Dim stepCount As Long: stepCount = 18 ‘ 分割数 (5度刻み)
Dim currentAngle As Double
Dim angleRad As Double
Dim i As Long
Dim deltaAngle As Double
deltaAngle = (endAngle – startAngle) / stepCount
Dim savePath As String
savePath = “C:\SolidWorks_Output\” ‘ 出力先ディレクトリ(事前に作成必須)
Dim interferenceCount As Long
For i = 0 To stepCount
currentAngle = startAngle + (deltaAngle i)
angleRad = currentAngle (3.14159265358979 / 180#) ‘ ラジアン変換
‘ 5. 合致パラメータの書き換え
‘ ※Angle Mateの場合、Distance または Angleプロパティを操作
‘ ※SolidWorksのバージョンや合致タイプによりAPIメソッドが異なる点に注意
boolstatus = swMate.SetParameterValues(angleRad, 0)
‘ 6. アセンブリの強制再構築(ここでキネマティクスが連動して動く)
boolstatus = swModel.Extension.Rebuild(swRebuildAll)
‘ 7. 干渉チェックの実行
interferenceCount = CheckInterference(swModel)
‘ 8. 高解像度スナップショットの保存
Dim fileName As String
fileName = savePath & “Step_” & Format(i, “00”) & “_Angle_” & Format(currentAngle, “000.0”) & “deg.png”
‘ 画面描画を一時的に許可してキャプチャを取得
swModel.Extension.EnableGraphicsUpdate = True
swModel.GraphicsRedraw2
boolstatus = swModel.Extension.SaveAsOpenGLImage(fileName)
‘ 再び描画を凍結
swModel.Extension.EnableGraphicsUpdate = False
‘ ログ出力(イミディエイトウインドウ)
Debug.Print “Step: ” & i & ” | Angle: ” & currentAngle & “° | Interferences: ” & interferenceCount & ” | Saved: ” & fileName
Next i
ErrorHandler:
‘ 9. 確実に環境を復旧させるためのクリーンアップ
swModel.Extension.EnableGraphicsUpdate = True
swApp.UserControl = True
‘ オブジェクトの明示的解放(メモリリーク防止)
Set swMate = Nothing
Set swFeat = Nothing
Set swAssembly = Nothing
Set swModel = Nothing
Set swApp = Nothing
If Err.Number <> 0 Then
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
Else
MsgBox “シネマティクス検証が正常に完了しました。”, vbInformation
End If
End Sub
‘ =========================================================================
‘ 補助関数: 干渉チェックの実行と衝突ペア数の返却
‘ =========================================================================
Private Function CheckInterference(ByVal swModel As SldWorks.ModelDoc2) As Long
Dim swModelExt As SldWorks.ModelDocExtension
Set swModelExt = swModel.Extension
Dim swInterferenceMgr As SldWorks.InterferenceDetectionMgr
Set swInterferenceMgr = swModelExt.CreateInterferenceDetectionMgr()
‘ 設定の構成(全コンポーネント対象)
swInterferenceMgr.IgnoreHidden = True
swInterferenceMgr.TreatCoincidentAsInterference = False
swInterferenceMgr.MakeMultiBodyPartAsSubAssembly = False
‘ 干渉計算の実行
Dim vInterferences As Variant
vInterferences = swInterferenceMgr.Run()
Dim count As Long
If Not IsEmpty(vInterferences) Then
count = UBound(vInterferences) – LBound(vInterferences) + 1
Else
count = 0
End If
‘ マネージャの終了
swInterferenceMgr.Done
‘ 解放
Set swInterferenceMgr = Nothing
Set swModelExt = Nothing
CheckInterference = count
End Function
—
3. チーフアーキテクトが指摘する「現場の罠」と回避策
実務の現場において、上記のコードをそのままレガシーな巨大アセンブリ(構成部品が数万点あるような環境)に投入すると、いくつかの致命的な壁にぶ当たる。シニアエンジニアとして、それらの回避策を共有しておく。
① コンテキストの不整合と「合致の破綻(Error Mates)」
可動範囲の端点付近で、キネマティクスが特異点(Singularity)に達したり、部品が裏返ったりして合致がエラーを起こすことがある。
これを防ぐためには、`swMate.SetParameterValues` を実行した直後の `Rebuild` の戻り値(Boolean)を監視し、`False` が返った場合はそのステップでのシミュレーションを中断、あるいは警告ログを吐き出す例外ハンドリングを組み込むべきだ。
② 描画スレッドとCOMオブジェクトの競合
`SaveAsOpenGLImage` を実行する際、`EnableGraphicsUpdate = False` のままだと真っ黒な画像が出力される、あるいは直前のフレームがキャッシュされてしまう現象が起きる。
そのため、コード例にある通り、画像保存の瞬間だけ極めて短時間グラフィックを有効化し、即座に再凍結するというテクニックが、高速性と正確なビジュアルキャプチャを両立させる唯一の解となる。
③ 大規模アセンブリにおける干渉チェックの負荷削減
`InterferenceDetectionMgr` は非常に重い処理である。もしすべての部品同士を毎ステップチェックしていると、1ループに数十秒を要することになる。
実務では、干渉の可能性がある「可動部品群」の配列(Component Array)をあらかじめ抽出し、`swInterferenceMgr.Components` プロパティに明示的に渡すことで、計算対象を必要最小限に絞り込むカスタマイズが不可欠である。
—
終わりに
VBAは、レガシーで古臭い言語と揶揄されることがある。しかし、SolidWorksのCOM APIを直接叩き、CADの心臓部を意のままにコントロールするための最も身近で強力なインターフェースである事実は揺るぎない。
手作業による「動かして見る」という属人化した検証から脱却し、コードによって製品の信頼性を担保する――これこそが、現代の機械設計エンジニアに求められる真の自動化の姿である。
