【実務・中級編】【マルチボディ対応】SolidBodyオブジェクトの走査と、干渉ボディの自動ブーリアン演算(結合・削除) – SolidWorks VBA解析バイブル

スポンサーリンク

SolidWorks VBAを掌握する極限の知見
第4回:【マルチボディ対応】SolidBodyオブジェクトの走査と、干渉ボディの自動ブーリアン演算(結合・削除)

こんにちは。開発プロジェクトの現場で「動くだけの脆いマクロ」のせいで幾度となく徹夜を余儀なくされてきたエンジニアたちを見てきた。
SolidWorks VBAにおいて、単にAPIのメソッドを呼び出すだけのコードは、実務の現場ではゴミと同然だ。特にマルチボディ(Multi-Body)環境を扱う際、オブジェクトのライフサイクルやセッションのコンテキストを理解していないコードは、すぐに「ランタイムエラー」「不正なポインタ参照」「意図しないジオメトリの消滅」を引き起こす。

今回は、1つのパーツファイル内に生成された複数のソリッドボディを完全に制御し、干渉ボディのブーリアン演算(結合・カット・削除)を極限までロジカルかつ堅牢に自動化する手法を伝授する。

なぜ「愚直なボディ走査」は実務で破綻するのか?

マルチボディのパーツを扱う際、多くの初心者は `PartDoc::GetBodies2` メソッドを呼び出し、得られた配列を適当なループで回して処理しようとする。
だが、ちょっと待ってほしい。

1. ポインタの無効化(Stale Pointers)
ブーリアン演算(`CombineBodies2` など)を実行した瞬間、演算に関わった元のボディオブジェクトはメモリ上で破棄され、新しく生成されたボディのポインタへと置き換わる。これを理解せずに古い `SolidBody` オブジェクトの参照を保持し続けようとすれば、SolidWorksごと沈黙(クラッシュ)する。
2. フィーチャツリーの汚染
APIで場当たり的にボディを操作すると、意図しないフィーチャの順序(フィーチャの依存関係)が崩れ、再ビルドエラー(Rebuild Error)の温床となる。
3. セレクションマネージャの罠
VBAからUIを模倣して `Extension.SelectByID2` を連発するコードは、画面の描画状態やコンフィギュレーションの切り替えに依存するため、バックグラウンド処理(Headless実行)において確実に破綻する。

我々プロフェッショナルは、「APIの内部状態の変化」と「オブジェクトの寿命」を完全に同期させたコードを書かなければならない。

堅牢なマルチボディ制御のアーキテクチャ

実務で耐えうる自動化ツールを構築するため、以下の設計原則を徹底する。

  • 型安全な配列処理: `GetBodies2` で取得したバリアント型配列の境界チェックを必ず行う。
  • 明示的な選択解除: API操作の前後は必ず `ClearSelection2` を呼び出し、セレクションバッファをクリーンに保つ。
  • エラーハンドリングと復帰: ブーリアン演算が失敗した際の状態ロールバックを想定した構造にする。

【プロダクションコード】干渉ボディ自動結合・削除マクロ

以下のコードは、アクティブなパーツ内のすべてのソリッドボディを取得し、特定の条件(あるいは全ボディの統合、または干渉チェックに基づくブーリアン処理)を安全に実行するためのテンプレートだ。
そのまま現場の業務効率化ツールに組み込んでほしい。

Option Explicit

‘ =========================================================================
‘ ódulo名: MultiBodyProcessor
‘ 概要 : マルチボディパーツにおけるソリッドボディの走査とブーリアン演算
‘ 著者 : チーフアーキテクト
‘ =========================================================================

Sub Main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc

‘ 1. アプリケーションおよびドキュメントの取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc

If swModel Is Nothing Then
MsgBox “ドキュメントが開かれていません。”, vbCritical, “エラー”
Exit Sub
End If

‘ パーツドキュメントかどうかの型チェック
If swModel.GetType <> swDocPART Then
MsgBox “このマクロはパーツドキュメントでのみ実行可能です。”, vbCritical, “エラー”
Exit Sub
End If

Set swPart = swModel

‘ 2. 処理前の画面更新停止(パフォーマンス最適化)
swModel.Extension.EnableGraphicsUpdate = False

On Error GoTo ErrorHandler

‘ 3. ソリッドボディの取得と走査
Dim vBodies As Variant
vBodies = swPart.GetBodies2(swSolidBody, False)

If IsEmpty(vBodies) Then
MsgBox “ソリッドボディが存在しません。”, vbExclamation, “情報”
GoTo Finally
End If

Dim bodyCount As Long
bodyCount = UBound(vBodies) – LBound(vBodies) + 1
Debug.Print “検出されたソリッドボディ数: ” & bodyCount

Dim i As Long
Dim swBody As SldWorks.Body2

For i = LBound(vBodies) To UBound(vBodies)
Set swBody = vBodies(i)

‘ 非表示ボディやテンポラリボディを除外する場合のガード
If Not swBody.IsHidden Then
Debug.Print ” – ボディ名: ” & swBody.Name & ” / 容積: ” & swBody.GetVolume
End If
Next i

‘ 4. 【実務応用】複数ボディの結合(CombineBodies2)の実行例
‘ ※ここでは最初のボディをメインとし、残りのボディをすべて結合するロジックの骨子を示す
If bodyCount >= 2 Then
Call ExecuteBodyCombine(swModel, swPart)
End If

Finally:
‘ 5. クリーンアップと画面更新の復元
swModel.Extension.EnableGraphicsUpdate = True
swModel.GraphicsRedraw2
Exit Sub

ErrorHandler:
swModel.Extension.EnableGraphicsUpdate = True
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “致命的エラー”
End Sub

‘ =========================================================================
‘ 内部関数: ボディの結合処理 (CombineBodies2 の正しい実装ラッパー)
‘ =========================================================================
Private Sub ExecuteBodyCombine(swModel As SldWorks.ModelDoc2, swPart As SldWorks.PartDoc)
Dim vBodies As Variant
vBodies = swPart.GetBodies2(swSolidBody, False)

If UBound(vBodies) < 1 Then Exit Sub ' 選択バッファを完全クリア swModel.ClearSelection2 True ' 結合先のメインボディを選択 Dim swMainBody As SldWorks.Body2 Set swMainBody = vBodies(0) Dim bRet As Boolean bRet = swMainBody.Select2(False, 0) If Not bRet Then Err.Raise vbObjectError + 1, "ExecuteBodyCombine", "メインボディの選択に失敗しました。" End If ' 結合するサブボディたちを配列または個別に選択追加 Dim i As Long Dim swSubBody As SldWorks.Body2 For i = 1 To UBound(vBodies) Set swSubBody = vBodies(i) ' Append = True で選択に追加 bRet = swSubBody.Select2(True, 0) If Not bRet Then Debug.Print "警告: サブボディ '" & swSubBody.Name & "' の選択に失敗しました。" End If Next i ' FeatureManager を用いたボディ結合フィーチャの作成 ' OperationType: 1=結合(Add), 2=削除(Subtract), 3=共通(Common) Dim swFeatMgr As SldWorks.FeatureManager Set swFeatMgr = swModel.FeatureManager ' CombineBodies2の呼び出し ' 引数: OperationType Dim swFeat As SldWorks.Feature Set swFeat = swFeatMgr.CombineBodies2(1) ' 1 = 結合 (Add) If swFeat Is Nothing Then MsgBox "ボディの結合演算に失敗しました。干渉状態を確認してください。", vbExclamation, "警告" Else Debug.Print "ボディの結合フィーチャが正常に作成されました: " & swFeat.Name End If swModel.ClearSelection2 True End Sub --- 恵まれた環境でコードを書いているだけでは、こうした「ポインタの生存期間」や「セレクションのコンテキスト汚染」という深淵には気づけない。 実務でマクロを組み込む際は、必ず「画面更新の抑制(`EnableGraphicsUpdate = False`)」「厳密なエラーハンドリング」をセットで実装し、SolidWorksという巨大なC++アプリケーションとVBAの通話橋渡しを安全に行うこと。

この知見をあなたの開発環境にインストールし、明日からの設計・製造プロセスの自動化を一段上のステージへと引き上げてほしい。健闘を祈る。

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