【AutoCAD VBA】3Dオブジェクトの深淵:ソリッド・サーフェス・メッシュを支配するメモリ戦略
AutoCADの3Dオブジェクト操作をVBAで扱う際、多くのエンジニアは「単純なメソッド呼び出し」の壁に突き当たり、メモリリークとパフォーマンス低下という現実を突きつけられる。
AcadApplicationやAcadDocumentを単なる「ラッパー」として捉えていては、数万個の頂点を持つメッシュや複雑なB-Rep(境界表現)を扱う際にシステムは悲鳴を上げるだろう。本稿では、レガシー環境の制約を逆手に取り、極限のパフォーマンスを引き出すための「アーキテクトの作法」を伝授する。
—
1. 3Dオブジェクトの階層とメモリの「不可視な重み」
AutoCADの3Dモデルは、単なる幾何情報の集合体ではない。`Acad3DSolid`、`AcadSurface`、`AcadMesh`は、それぞれデータベース上の計算コストが異なる。
- Acad3DSolid (B-Rep): 最も堅牢だが、操作ごとに形状解析のオーバーヘッドが発生する。
- AcadSurface: 非多様体(Non-manifold)を扱うための数学的モデル。
- AcadMesh: 面の集合体。大量に生成すると`AcadDocument`のインデックス負荷が急増する。
これらを扱う際、最大の敵は「COMオブジェクトの解放遅延」である。VBAのガベージコレクションは非力だ。大規模な3D生成を行う際は、ループ内での明示的なオブジェクト解放が必須となる。
—
2. 実践:メモリを制御しながら3Dソリッドを生成する
以下のコードは、単に立方体を生成するものではない。`Set Nothing`による参照カウンタの強制デクリメントと、`ThisDrawing.Utility.Prompt`を用いた処理の同期制御を組み込んだ「量産用テンプレート」である。
‘ 【極限の最適化】大規模3D生成用ルーチン
Public Sub CreateMassiveSolids()
Dim acadApp As AcadApplication
Dim acadDoc As AcadDocument
Dim boxSolid As Acad3DSolid
Dim center(0 To 2) As Double
Dim i As Long
Set acadApp = ThisDrawing.Application
Set acadDoc = ThisDrawing.Document
‘ 図面上の計算を一時停止させパフォーマンスを向上させる(重要)
acadDoc.SetVariable “PICKFIRST”, 0
For i = 1 To 1000
‘ 3Dソリッド生成
Set boxSolid = acadDoc.ModelSpace.AddBox(center, 10, 10, 10)
‘ ここで計算処理や属性付与を行う
‘ …
‘ 【重要】明示的なメモリ解放
‘ COMオブジェクトを放置するとスタックとヒープを圧迫する
Set boxSolid = Nothing
‘ 数千個単位の処理ならDoEventsでUIスレッドを解放する
If i Mod 100 = 0 Then DoEvents
Next i
acadDoc.SetVariable “PICKFIRST”, 1
MsgBox “生成完了”
End Sub
—
3. Windows APIによる「VBAの限界」の突破
VBAの標準機能では、大規模な3Dデータの高速な頂点解析や、外部のバイナリ形式(点群データ等)との高速な直接読み書きは困難である。ここで、`Kernel32.dll`を用いたメモリの直接操作が必要になることがある。
例えば、大量のメッシュ頂点を配列として一気に渡す場合、`CopyMemory` APIを使用することで、VBAの配列コピーのオーバーヘッドをバイパスし、処理速度を数倍に引き上げることが可能だ。
‘ メモリ直接コピーによる高速データ転送のためのAPI定義
Private Declare PtrSafe Sub CopyMemory Lib “kernel32” Alias “RtlMoveMemory” _
(Destination As Any, Source As Any, ByVal Length As LongPtr)
‘ 大量の頂点配列を扱う際の設計指針:
‘ VBA配列をそのまま渡すのではなく、一度SafeArray構造体を解釈し、
‘ ポインタ経由でAutoCADのネイティブなデータ領域へ流し込むのが真の最適解。
—
4. レガシー保守における「アーキテクトの鉄則」
AutoCAD VBAは、現代的な.NET API(ObjectARXベース)と比較すれば確かに「旧世代」だ。しかし、この枯れた技術には、「CADのデータベース構造を直接叩ける」という圧倒的な特権がある。
- 図面情報の正規化: 3Dオブジェクト生成時に、必ず`XData`(拡張データ)でメタ情報を付与せよ。これにより、システム間連携時に外部DBとの整合性を担保できる。
- 例外処理の徹底: 3D生成は計算誤差によるエラー(`eInvalidInput`等)が頻発する。`On Error Resume Next`で逃げず、エラーコードを解析し、なぜその3D形状が生成できなかったのかをログに吐き出せ。
結び:エンジニアの誇り
AutoCADの3D空間は、単なるビジュアルの遊び場ではない。座標、ベクトル、そして物理的な制約が支配するシビアな世界だ。VBAという古き良きツールで、この空間を意のままに操れるようになることは、技術者として一つの到達点である。
今日書いたコードが、明日の業務を自動化する。その積み重ねこそが、アーキテクトの仕事である。もし、VBAの限界を感じるほどの巨大プロジェクトに直面したなら、その時は迷わずVB.NETへの移行を検討すべきだ。だが、その判断を下すためにも、まずはVBAで「オブジェクトのライフサイクル」を完全に支配することから始めてほしい。
コードは嘘をつかない。メモリ管理を制する者が、CAD自動化を制するのだ。
