【テクニカル・上級編】【上級プロ】アセンブリ内の干渉チェック結果(Collision Detection)の空間座標データをパースし、3D空間上の衝突位置にマーカーパーツを自動配置 – SolidWorks VBA解析バイブル

スポンサーリンク

【SolidWorks API】干渉箇所の「座標パース」と「可視化」:自動化の先にある設計最適化

SolidWorksの干渉検知(Collision Detection)は、多くの設計者にとって「レポートを出して終わり」の儀式になっている。しかし、アセンブリの規模が数千点を超えたとき、レポートのテキストを読み解く時間はエンジニアの最大の浪費となる。

真の自動化エンジニアは、干渉を単なる「エラー情報」としてではなく、「3D空間上のベクトルデータ」として扱う。今回は、`IAssemblyDoc::GetInterference`から衝突座標を抽出し、そこに警告マーカーを動的配置する、極限の自動化アーキテクチャを提示する。

—

1. 物理メモリを解放せよ:オブジェクトのライフサイクル管理

VBA環境において、`SldWorks`オブジェクトや`ModelDoc2`を無造作に扱うのは、システムを不安定にする最大の要因だ。特に衝突判定のような再帰的な処理を行う場合、メモリリークは即座にパフォーマンス低下に直結する。

  • 明示的なNothing代入: ループの各イテレーションで生成される`Component2`や`MathPoint`は、処理終了直後に`Set obj = Nothing`で確実に解放せよ。
  • イベントの遮断: 大規模なアセンブリで再構築(Rebuild)を伴う処理を行う際は、`swApp.UserControl = False`とし、画面描画を停止させ、イベントのフックを最小化する。

—

2. 衝突位置座標の抽出:MathUtilityの真価

`GetInterference`メソッドは `Interference` オブジェクトの配列を返す。ここに含まれる `ContactPoint` はローカル空間の座標であることが多い。これをグローバル座標系に変換する際、`IMathUtility` を通じた行列変換を避けてはならない。

‘ 衝突位置にダミーパーツを生成するコアロジック
Sub CreateCollisionMarker(swModel As ModelDoc2, contactPoint As MathPoint)
Dim swPart As PartDoc
Dim swAssy As AssemblyDoc
Set swAssy = swModel

‘ 外部参照ライブラリとして用意した赤色マーカーパーツを挿入
Dim swComp As Component2
Set swComp = swAssy.AddComponent(“C:\StandardParts\CollisionMarker.SLDPRT”, “”)

‘ マーカーを衝突位置に配置するための変換行列を生成
Dim swMathUtil As MathUtility
Set swMathUtil = Application.SldWorks.GetMathUtility

‘ 位置情報の適用
Dim swTransform As MathTransform
Set swTransform = swMathUtil.CreateTransform(contactPoint.ArrayData)

‘ コンポーネントの位置を更新
swComp.Transform2 = swTransform

‘ メモリ最適化
Set swComp = Nothing
Set swMathUtil = Nothing
End Sub

—

3. 高度な実装:干渉チェックの再帰的パース

干渉チェックを全モデルに対して総当たりで実行すると、計算コストが爆発する。`IAssemblyDoc::GetInterference`で取得した `Interference` オブジェクトから、`GetEntities` を使用して干渉している `Face` を特定し、その面の重心を計算することで、より正確な「衝突ポイント」を算出することが可能だ。

‘ 干渉検出の実行と座標パース
Public Sub DetectAndMarkCollisions(swAssy As AssemblyDoc)
Dim swIntMgr As InterferenceDetectionMgr
Set swIntMgr = swAssy.CreateInterferenceMgr()

‘ 干渉計算の実行
swIntMgr.Create

Dim vInterferences As Variant
vInterferences = swIntMgr.GetInterferences

If IsEmpty(vInterferences) Then Exit Sub

Dim i As Long
For i = 0 To UBound(vInterferences)
Dim swInterference As Interference
Set swInterference = vInterferences(i)

‘ 衝突座標を取得(IInterference::ContactPoints)
Dim vPoints As Variant
vPoints = swInterference.ContactPoints

‘ 最初の接触点に対してマーカーを配置
If Not IsEmpty(vPoints) Then
Dim swMathUtil As MathUtility
Set swMathUtil = Application.SldWorks.GetMathUtility
Dim pt As MathPoint
Set pt = swMathUtil.CreatePoint(vPoints)

CreateCollisionMarker swAssy, pt
End If
Set swInterference = Nothing
Next i

‘ 管理者の明示的終了
swIntMgr.Delete
Set swIntMgr = Nothing
End Sub

—

4. シニアエンジニアへの提言:レガシーとの共生

このコードを実務環境に導入する際、注意すべきは「アセンブリの再帰的な構造」だ。サブアセンブリが含まれる場合、座標系の変換には `Component2::GetTotalTransform` を駆使しなければならない。

また、Windows API (`User32.dll`) を用いて、処理中のダイアログを強制的に最前面に固定するなど、UX上の配慮も忘れてはならない。VBAは古臭い言語ではない。APIという「筋肉」を正しく鍛えれば、最新のCAD環境においても最強の自動化ツールへと化ける。

結論:
干渉チェックの結果を「見る」のではなく「配置する」。この発想の転換こそが、設計時間を短縮し、ヒューマンエラーを物理的に遮断する唯一の道である。コードは常にシンプルに、かつメモリ消費は極限まで意識せよ。それが伝説のアーキテクトが辿り着いた、自動化の極致だ。

タイトルとURLをコピーしました