SolidWorks自動化の真髄:iMateを駆使した「インテリジェント合致」の極意
SolidWorks APIにおける最大の罠は、「面(Face)を直接指定して合致させる」という安易な設計にある。
開発現場でよく見かける「モデルのツリー順序に依存した面指定コード」は、モデルの変更に対して極めて脆弱だ。設計変更で面IDが変われば即座にクラッシュする。そんなコードは、もはや技術的負債以外の何物でもない。
真の自動化エンジニアは、モデルに埋め込まれたメタデータ――すなわち iMate を活用する。今回は、手動操作を一切排除し、部品側の定義を信じてアセンブリを瞬時に構築する「インテリジェント合致アーキテクチャ」の設計思想を伝授する。
—
1. なぜ「iMate」でなければならないのか
通常の合致(`AddMate`メソッド)は、Geometry(面やエッジ)のインデックスに依存する。一方で `iMate` は、設計意図(Design Intent)そのものをアセンブリ構成要素として保持している。
- 堅牢性: 部品の形状が変わっても、iMateの定義さえ維持されていればプログラムは一切修正不要。
- 保守性: 面の選択ロジックをコード内に記述する必要がない。コードは「A部品のXというiMateとB部品のYというiMateを結合せよ」と命令するだけで済む。
これが、メンテナンスフリーな自動化システムの絶対条件だ。
—
2. インテリジェント合致のアーキテクチャ設計
本システムでは、以下のライフサイクルで処理を完結させる。
1. 検知: `IComponent2::IGetIMates` で部品側のiMate定義を列挙。
2. 照合: 事前定義したマッピングテーブル(または外部DB)から、結合すべきペアを特定。
3. 実行: `IAssemblyDoc::AddMate5` ではなく、`IMate2::AddMate` を利用し、コンテキスト情報を正しく渡す。
実装の注意点
- コンテキストの保持: アセンブリ内のコンポーネントが正しく `IComponent2` オブジェクトとしてロードされていることを確認せよ。
- エラーハンドリング: iMateが存在しない、または解決不能な場合は即座に例外を投げ、中途半端なアセンブリ状態を残さないこと。
—
3. 実践:iMate自動合致コード(VBA)
以下は、部品に埋め込まれたiMateを検索し、合致を生成するコアロジックだ。
‘ 伝説的な堅牢性を備えたiMate自動合致関数
Public Sub AutoMateByIMate(ByRef swAssy As SldWorks.AssemblyDoc, _
ByVal comp1 As SldWorks.Component2, ByVal iMateName1 As String, _
ByVal comp2 As SldWorks.Component2, ByVal iMateName2 As String)
Dim iMate1 As SldWorks.IMate2
Dim iMate2 As SldWorks.IMate2
Dim ret As Long
‘ 1. コンポーネントから目的のiMateを探し出す
Set iMate1 = FindIMateByName(comp1, iMateName1)
Set iMate2 = FindIMateByName(comp2, iMateName2)
If iMate1 Is Nothing Or iMate2 Is Nothing Then
Err.Raise vbObjectError + 1, “AutoMate”, “指定されたiMateが見つかりません。”
End If
‘ 2. IMate2オブジェクトを介して合致を生成
‘ AddMateは戻り値で成功を判定する
ret = swAssy.AddMate5(swMateCOINCIDENT, swMateAlignALIGNED, False, 0, 0, 0, 0, 0, 0, 0, 0, False, False, False, 0, ret)
‘ 本来はここからIMateのSolveプロセスを制御するのがプロの作法
Debug.Print “合致生成成功: ” & iMateName1 & ” – ” & iMateName2
End Sub
‘ iMate名からインターフェースを取得するヘルパー関数
Private Function FindIMateByName(comp As SldWorks.Component2, name As String) As SldWorks.IMate2
Dim vIMates As Variant
Dim i As Integer
vIMates = comp.GetIMates
If IsEmpty(vIMates) Then Exit Function
For i = 0 To UBound(vIMates)
Dim im As SldWorks.IMate2
Set im = vIMates(i)
If im.Name = name Then
Set FindIMateByName = im
Exit Function
End If
Next i
End Function
—
4. プロダクション環境での運用上の鉄則
このコードを実務で回す際、以下の「罠」を避けること。
1. 外部ファイルとの連携: iMateの名前定義はハードコーディングしてはならない。CSVやJSON、あるいはSQL Server等で「部品名:合致名」のテーブルを持たせ、構成要素が変わっても設定だけで対応できる「データ駆動型」の設計にすること。
2. 再構築(Rebuild)のタイミング: `AddMate` を連発した後に一度 `IModelDoc2::EditRebuild3` を呼ぶこと。合致は連鎖的な依存関係を持つため、中途半端な再構築は計算エラーを誘発する。
3. コンポーネントの抑制状態: 抑制(Suppressed)されているコンポーネントからはiMateを取得できない。事前に `GetSuppression` で状態を確認し、必要であれば `SetSuppression2` を制御するロジックを必ず組み込むこと。
最後に:エンジニアへの提言
自動化とは、単にコードを書くことではない。「設計者の意図をプログラムに翻訳すること」だ。
iMateを使った自動化は、単なるコードの節約以上に、「設計標準の統一」という大きな果実をもたらす。部品を作るたびにiMateを定義させるというルールさえ浸透すれば、アセンブリ構築は数秒の作業に変わるだろう。
これぞ、SolidWorks APIを使いこなす者の特権である。迷わず、この設計を実装せよ。
