図面自動化の極致:データベース駆動型アノテーションエンジンの構築
――溶接記号と表面粗さを支配する、座標変換とメモリ管理の真髄
製造業における「図面作成」という工程の多くは、設計意図の再転記に過ぎない。特に溶接記号や表面粗さといった加工指示は、製造要件データベース(ERP/PLM)に既に定義されているはずの情報である。これを設計者が手動で図面に配置するのは、エンジニアリングリソースの極めて非効率な浪費だ。
しかし、SolidWorks APIを用いてこれを自動化しようとする者の多くは、`InsertWeldSymbol` などのメソッドを単純に呼び出すだけで満足し、結果として「位置が不適切」「ビューの更新で記号が飛ぶ」「大量の図面処理でメモリリークを起こしCADがクラッシュする」という壁にぶつかる。
本稿では、モデルの特定面から逆算して図面上の最適位置にアノテーションを配置する、プロフェッショナル向けの「アノテーションエンジン」のアーキテクチャを詳説する。
1. アーキテクチャの全体像:3Dから2Dへのマッピング
自動アノテーションの核心は、「3Dモデル上のエンティティ(Face/Edge)」を「2D図面ビュー内の座標」へ正確に投影し、そこにメタデータを結合させることにある。
データフロー
1. DB抽出: SQL等を用いて、部品番号および面ID(または名称)に紐づく加工指示(溶接種類、脚長、粗さ値)を取得。
2. 3Dエンティティの特定: `SelectByID2` または `Entity` オブジェクトを介して、モデル上の対象面を特定。
3. 座標変換: `DrawingDoc.GetDrawingView` からビューの投影行列を取得し、3D座標 $\rightarrow$ 2D座標への変換を行う。
4. アノテーション生成: 変換後の座標を基点に、`InsertWeldSymbol` 等を実行。
2. 実装:データベース駆動型アノテーションエンジンの核
以下に、概念的な実装コードを示す。ここでは、単なるAPIの呼び出しではなく、エラーハンドリングとオブジェクトライフサイクルを意識した構造としている。
' ==============================================================================
' Module: AnnotationEngine
' Description: データベースから取得した加工指示を基に溶接記号を自動配置する
' ==============================================================================
Option Explicit
' Windows API: 高精度タイマーやメモリ操作が必要な場合に備え宣言(本例ではメモリ解放に集中)
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Sub ExecuteAutoAnnotation()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swView As SldWorks.View
Dim swSelMgr As SldWorks.SelectionMgr
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then Exit Sub
If swModel.GetType <> swDocDRAWING Then
MsgBox "図面ファイルを開いてください。", vbCritical
Exit Sub
End If
Set swDraw = swModel
Set swSelMgr = swModel.SelectionManager
' 1. データベースからのデータ取得(擬似関数)
' 本来は ADODB.Connection 等を用いてSQL実行
Dim加工データ As Collection
Set 加工データ = GetManufacturingDataFromDB(swModel.GetPathName)
' 2. ビューの走査
Set swView = swDraw.GetFirstView ' シート自体が最初のビューとなるため
Set swView = swView.GetNextView ' 実際のモデルビューへ移動
Do While Not swView Is Nothing
Dim item As Variant
For Each item In 加工データ
' モデル上の面を特定して選択
' 注意: SelectByID2の多用はパフォーマンスを低下させるため、
' 本来はモデル側の名称定義(Named Entities)を利用すべきである
Dim status As Boolean
status = swModel.Extension.SelectByID2(item("FaceName"), "FACE", 0, 0, 0, False, 0, Nothing, 0)
If status Then
' 3D座標を2Dビュー座標に変換して溶接記号を挿入
Call InsertOptimizedWeldSymbol(swModel, swView, item)
End If
Next item
Set swView = swView.GetNextView
Loop
' 徹底的なメモリ解放
Set swSelMgr = Nothing
Set swDraw = Nothing
Set swModel = Nothing
Set swApp = Nothing
MsgBox "アノテーション完了", vbInformation
End Sub
Private Sub InsertOptimizedWeldSymbol(swModel As SldWorks.ModelDoc2, swView As SldWorks.View, data As Variant)
Dim swDraw As SldWorks.DrawingDoc
Set swDraw = swModel
' 溶接記号の挿入
' 引数: 記号の内容, 座標X, 座標Y, 座標Z (ビュー座標系)
' 実際には、選択した面の中心点を GetPoint して変換する必要がある
Dim swNote As SldWorks.Note
Set swNote = swDraw.InsertWeldSymbol( _
data("SymbolText"), _
0, 0, 0) ' ここに変換後の座標を代入
If Not swNote Is Nothing Then
' 記号の微調整(リーダー線の角度など)
' Noteオブジェクトのプロパティを操作して最適化
swNote.SetText 0, 0, data("DetailText")
End If
Set swNote = Nothing
End Sub
Private Function GetManufacturingDataFromDB(filePath As String) As Collection
' DB連携のモック。実際にはSQLで FaceName, SymbolText, DetailText を取得
Dim col As New Collection
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
dict.Add "FaceName", "Weld_Face_01"
dict.Add "SymbolText", "fillet"
dict.Add "DetailText", "6"
col.Add dict
Set GetManufacturingDataFromDB = col
End Function
3. 極限のパフォーマンス最適化と安定化
COMオブジェクトのライフサイクル管理
VBAにおけるSolidWorks APIの最大の問題は、COMオブジェクトの解放漏れによるメモリリークである。特に `Loop` 内で `Note` や `Entity` オブジェクトを生成する場合、明示的に `Set obj = Nothing` を行わないと、数千個の注記を打つ過程でメモリを食いつぶし、`Out of Memory` または `SolidWorks has encountered a problem` で強制終了する。
`Select4` と `SelectByID2` の罠
多くのエンジニアが `SelectByID2` を乱用するが、これは内部的に名前解決を行うため極めて低速である。
- 最適解: モデル作成時に「面名称」を定義し、それをキーに検索する。
- さらに上級: `SelectionMgr` を介して、一度に複数のエンティティを配列で処理し、選択回数を最小限に抑える。
座標変換の数学的アプローチ
図面上の座標は、ビューの `X, Y` 座標系である。3Dモデルの座標 $(X_m, Y_m, Z_m)$ を図面座標 $(X_d, Y_d)$ に変換するには、ビューの投影行列(Projection Matrix)を掛ける必要がある。
APIの `swView.GetViewProjectionMatrix` を使用し、ベクトル演算を行うことで、「面の中央」に正確に記号を配置することが可能になる。これを怠り、固定値でオフセットをかける実装は、スケール変更時に崩壊するため、プロの仕事とは呼べない。
4. レガシー環境への配慮と保守性
本システムを社内展開する場合、異なるSolidWorksバージョン(2020, 2022, 2024等)が混在する。
1. Late Binding(遅延結合)の検討: 参照設定に依存せず `CreateObject` を使用することで、バージョンアップ時の「参照不可」エラーを回避できる。ただし、インテリセンスが効かなくなるため、開発は Early Binding で行い、リリース時に変換する戦略を推奨する。
2. エラーハンドリングの局所化: `On Error Resume Next` は厳禁である。各処理ブロックに `On Error GoTo ErrorHandler` を設け、どの面のどの記号で失敗したかをログに出力する。製造データに不備がある場合、プログラムが止まるのではなく、「スキップしてログに残す」設計が不可欠だ。
結論
データベース駆動型のアノテーションエンジンは、単なる「自動化ツール」ではない。それは「設計意図のデータソースを単一化(Single Source of Truth)」し、人的ミスを物理的に排除するためのインフラである。
APIリファレンスをなぞるだけでは、このレベルの堅牢性は得られない。オブジェクトのメモリ消費、座標系の数学的理解、そしてCOM通信のオーバーヘッドを制御して初めて、プロフェッショナルな自動化が完結する。
