【テクニカル・上級編】【上級プロ向け】図面内「溶接記号(Weld Symbols)」と「表面粗さ記号」のデータベース駆動型自動アノテーションエンジン – SolidWorks VBA解析バイブル

スポンサーリンク
スポンサーリンク

図面自動化の極致:データベース駆動型アノテーションエンジンの構築

――溶接記号と表面粗さを支配する、座標変換とメモリ管理の真髄

製造業における「図面作成」という工程の多くは、設計意図の再転記に過ぎない。特に溶接記号や表面粗さといった加工指示は、製造要件データベース(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通信のオーバーヘッドを制御して初めて、プロフェッショナルな自動化が完結する。

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