SolidWorks APIの深淵:マルチボディ物理特性抽出エンジンの設計思想
SolidWorks APIを扱う際、多くの開発者が陥る罠がある。それは「オブジェクトをただ走査する」という浅い思考だ。特にマルチボディパーツを扱う際、`GetBodies2` メソッドを安易に呼び出し、ループ内でオブジェクトを生成・破棄し続けるようなコードは、複雑なアセンブリや大規模パーツにおいて致命的なメモリリークとパフォーマンス低下を招く。
本稿では、数千ボディを超える複雑なモデルでも瞬時に物理特性を掌握するための「メモリ効率を極限まで高めた抽出エンジン」のアーキテクチャを提示する。
—
1. 物理特性抽出における「隠れたコスト」の排除
`Body2.GetVolume` や `GetCenterOfMass` は、内部的に一時的な計算キャッシュを生成する。これをループ内で無計画に叩けば、GC(ガベージコレクション)が追いつかず、SolidWorksプロセスそのものが肥大化する。
シニアエンジニアが意識すべきは、「オブジェクトの参照を最小化し、明示的な解放を行う」ことだ。VBAにおいては `Set obj = Nothing` を行うのは当然として、COMポインタのライフサイクルを考慮したスコープ設計が求められる。
実装の要点
- Variant型の配列利用: `GetBodies2` から返される配列をキャッシュし、不要になった瞬間に解放する。
- 再計算の回避: 形状変更が発生しない限り、物理特性計算は一度に留める。
—
2. マルチボディ抽出エンジン:実装コード
以下は、パーツ内の全ソリッドボディを走査し、個別の物理特性を抽出する高効率なVBAモジュールである。
Option Explicit
‘ 伝説的な堅牢性を備えたボディ抽出エンジン
Public Sub ExtractBodyProperties()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Dim vBodies As Variant
Dim swBody As SldWorks.Body2
Dim i As Long
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Or swModel.GetType <> swDocPART Then Exit Sub
Set swPart = swModel
‘ ボディ配列の取得 (タイプ指定: swSolidBody)
vBodies = swPart.GetBodies2(swSolidBody, False)
If IsEmpty(vBodies) Then Exit Sub
Debug.Print “BodyID, Volume(mm^3), CenterOfMass(X,Y,Z)”
For i = LBound(vBodies) To UBound(vBodies)
Set swBody = vBodies(i)
‘ メモリへの配慮:各ボディのプロパティを局所的に計算
ProcessBody swBody
‘ オブジェクトの明示的解放
Set swBody = Nothing
Next i
‘ 配列の消去
Erase vBodies
MsgBox “物理特性の抽出が完了しました。”
End Sub
Private Sub ProcessBody(ByVal swBody As SldWorks.Body2)
Dim dVolume As Double
Dim vCom As Variant
Dim dSurfArea As Double
‘ GetVolumeは軽量だが、大規模モデルでは計算負荷に注意
dVolume = swBody.GetVolume
‘ 重心位置の取得
vCom = swBody.GetCenterOfMass
‘ 表面積の取得
dSurfArea = swBody.GetArea
‘ 出力(必要に応じてCSVファイル出力やDB連携へ拡張可能)
Debug.Print swBody.Name & “, ” & dVolume & “, ” & _
vCom(0) & “,” & vCom(1) & “,” & vCom(2)
End Sub
—
3. レガシー環境とシステム連携の極意
このツールを単なる「レポート出力器」で終わらせてはならない。真の業務自動化エンジニアは、このデータを「下流工程へのインプット」に変える。
システム間連携への最適化
- Windows APIによる高速化: 大量のボディを処理する場合、標準の `Debug.Print` では遅延が発生する。`kernel32` の `WriteFile` を利用したダイレクトなファイルストリーム書き込みに切り替えることで、I/O性能は劇的に改善する。
- トランザクション管理: ファイルへの書き込みは一度のループ内で行わず、メモリ上にバッファリングしてから一括でFlushせよ。
メモリリークを完全に封じ込めるには
VBAの `Set = Nothing` はあくまで参照カウンタを減らすだけである。もしSolidWorksのセッションを長時間維持しつつ数万回この処理を行うような「常駐監視システム」を構築する場合は、`.NET (C#)` への移行を強く推奨する。COM Wrapperの解放(`Marshal.ReleaseComObject`)を厳密に制御できるのは、.NET環境の特権だからだ。
—
結論:技術は「道具」ではなく「哲学」
単に「動くコード」を書くことは誰にでもできる。しかし、SolidWorksの内部構造(Parasolidカーネルの振る舞い)を理解し、メモリ管理を最適化したコードを書くことは、エンジニアとしての矜持である。
このエンジンをベースに、貴殿の環境で求められる「真の自動化」を構築してほしい。API仕様書をなぞるだけではたどり着けない領域へ、一歩踏み出すことを期待する。
