【SolidWorks API】図面寸法を制する:DisplayDimensionの自動整列とメモリ最適化の極意
図面自動作成の現場で、最後に立ちはだかる「寸法線の重なり」という壁。多くのエンジニアが `AutoArrangeDimensions` メソッドに頼り、その結果得られる「妥協の産物」に疲弊しているのではないか。
SolidWorks APIにおける寸法操作は、単なるプロパティの書き換えではない。それは、`DisplayDimension` オブジェクトが持つ幾何学的な制約と、背後のドキュメント・データベースの同期を支配する行為だ。本稿では、レガシーコードを一掃し、堅牢かつ極限まで最適化された図面レイアウト自動化の真髄を説く。
—
1. 勘違いされた「AutoArrange」を脱却する
多くの開発者が陥る罠は、`DrawingDoc.AutoArrangeDimensions` を盲信することだ。これは、あくまで「そこそこ見られる状態」を目指すヒューリスティックなアルゴリズムに過ぎない。
真の自動化エンジニアは、`IDisplayDimension` インターフェースを直接叩き、アンカーポイント(Anchor Point)を座標計算によって制御する。 寸法線の配置は、図面ビュー(View)のバウンディングボックスと、寸法が参照しているエンティティのベクトルに基づいて、数学的に決定すべきである。
—
2. メモリ管理の鉄則:COMオブジェクトの残骸を残すな
VBAにおいて、`SldWorks` や `ModelDoc2` を扱う際、参照の解放を怠ることは「死」を意味する。特にループ処理の中で `GetFirstDisplayDimension` を繰り返す場合、メモリリークは即座に深刻なパフォーマンス低下を招く。
以下のコードでは、オブジェクトのライフサイクルを厳密に管理する。
‘ 推奨されるオブジェクト管理のパターン
Public Sub OptimizeDimensionLayout()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swView As SldWorks.View
Dim swDispDim As SldWorks.DisplayDimension
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then Exit Sub
If swModel.GetType <> swDocDRAWING Then Exit Sub
Set swDraw = swModel
Set swView = swDraw.GetFirstView ‘ シート自体をスキップ
Do While Not swView Is Nothing
Set swDispDim = swView.GetFirstDisplayDimension
Do While Not swDispDim Is Nothing
‘ ここで寸法位置を物理座標(X, Y)で制御する
Call AlignDimension(swDispDim)
‘ 次の寸法へ移動し、現在の参照を明示的に解放
Dim swNextDim As SldWorks.DisplayDimension
Set swNextDim = swDispDim.GetNext
Set swDispDim = Nothing ‘ 参照カウントを意図的に減らす
Set swDispDim = swNextDim
Loop
Set swView = swView.GetNextView
Loop
‘ 最終的なメモリ解放
Set swDraw = Nothing
Set swModel = Nothing
End Sub
—
3. 寸法線の整列:ベクトルの直交性とオフセット計算
寸法を整列させる際、最も重要なのは `IDisplayDimension::SetTextPosition` だ。このメソッドの引数は、図面上の座標系(単位はメートル)に依存する。
システム管理者として意識すべきは、「ビューの拡大縮小率(Scale)」と「用紙サイズ」の相関である。以下のロジックは、基準となる寸法から一定のオフセットを持たせて並列配置するアルゴリズムの断片である。
Private Sub AlignDimension(ByRef swDispDim As SldWorks.DisplayDimension)
Dim swDim As SldWorks.Dimension
Set swDim = swDispDim.GetDimension
‘ ここで寸法値を取得し、配置ロジックを分岐させる
‘ 実際の実務では、この座標計算に三角関数を駆使し、
‘ ビューの境界線からの最短距離を算出する
‘ 例: 寸法線をY方向に10mmオフセットさせる処理
‘ swDispDim.SetTextPosition x, y + 0.01, 0
Set swDim = Nothing
End Sub
—
4. レガシー環境とWindows APIの静かなる連携
大規模な図面データでは、SolidWorks APIの応答待ちでVBAがフリーズしたように見えることがある。これを回避するため、`User32.dll` の `DoEvents` 以上の介入を検討せよ。
具体的には、`Sleep` 関数をループの要所に挿入し、Windowsメッセージキューを解放することで、OS側の描画更新を阻害しない設計にする。
If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
Else
Private Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
End If
‘ ループ処理の合間に挟み込む
Sleep 10 ‘ 10ミリ秒の猶予をOSに与える
—
5. 伝説のアーキテクトからの提言
寸法線の自動整列とは、単なる「見た目の調整」ではない。それは、「製造現場が読み取るべき設計意図を、アルゴリズムによって再構築すること」である。
- バリデーションの欠如を許すな: 寸法が「吊り下げ状態(Dangling)」になっていないか、常に `IDisplayDimension::IsDangling` でチェックを走らせること。
- レイヤー管理との統合: 整列後の寸法は、規定のレイヤーへ移動させる処理を自動化パイプラインに組み込むべきだ。
- エラーハンドリングの徹底: APIの戻り値を判定しないコードは、ゴミである。必ず `HRESULT` を確認せよ。
SolidWorks APIは広大だ。しかし、その根底にあるのは「ジオメトリとデータ構造」の極めて論理的な関係性である。この本質を掴んだ者だけが、手作業の地獄からエンジニアを救い出すことができる。
君のコードが、図面という名の無機質なデータに命を吹き込むことを期待している。
