SolidWorks VBAを掌握する極限の知見
【サーフェスモデリング】FilledSurface.SetPatchBoundaryを用いた多角形境界ループからの高品質な穴埋めサーフェス生成
SolidWorks APIを用いた自動化の領域において、ソリッドモデルのブーリアン演算やフィレットの破綻に直面したとき、最後の砦となるのは常に「サーフェスモデリングの制御」である。
特に、複雑な切削加工痕やインポートデータ(IGES/STEP)の修復において、多角形の開口部に対してG1(接線)あるいはG2(曲率)連続性を保持した「面張力」の高いフィラー面を生成する作業は、手動操作であっても熟練の技を要する。これをVBAからノーミスで、かつミリ秒単位のオーバーヘッドで実行するには、APIの隠れたライフサイクルとメモリ管理の鉄則を完全に理解していなければならない。
今回は、`FilledSurface`フィーチャの核心である `SetPatchBoundary` メソッドに焦点を当て、境界ループの正確な定義から、COMオブジェクトのメモリ最適化、さらには実務で即座に使える堅牢なVBAコードまでを網羅的に解説する。
—
1. 現場のシニアが知るべき `FilledSurface` の深層とAPIの罠
SolidWorksの `IFilledSurfaceFeatureData` インターフェースは、指定された閉じた境界ループに対して、Nurbsベースのサーフェスをパッチとして生成する極めて強力な機能を持つ。しかし、このAPIをVBAから制御する際には、以下の「レガシー環境特有の罠」に注意が必要である。
1. 選択セットの不整合によるサイレントクラッシュ
`SetPatchBoundary` に渡すエッジ配列(Edge Array)のトポロジーが完璧にC0連続で閉じている必要がある。わずかでも隙間(ギャップ)が存在する場合、APIはエラーを返さずに実行時エラーやVBAの強制終了を引き起こすことがある。
2. COMポインタの解放漏れによるメモリリーク
SolidWorks APIをループ内で多用する際、`ModelDocExtension` や `SelectionMgr`、さらには個々の `Edge` オブジェクトを適切に `Nothing` 解放しないと、VBAランタイムとCOMコンテキスト間でメモリリークが発生し、大容量アセンブリやバッチ処理の途中でSolidWorks自体がフリーズする。
3. 連続性(Constraint)の厳密な定義
単なる穴埋め(C0: 接触)にとどまらず、G1(接線)やG2(曲率)を維持させるためには、境界エッジに隣接する面(Face)の参照を正しく紐付ける必要がある。
—
2. 実装アーキテクチャ:多角形境界からのFilledSurface自動生成
以下のVBAコードは、選択された境界エッジ群から配列を構築し、G1連続性を持つFilled Surfaceを動的に生成するプロダクションレベルの実装である。エラーハンドリングとオブジェクトの明示的解放を徹底している点に注目してほしい。
Option Explicit
‘ ==============================================================================
‘ 処理名: CreateHighQualityFilledSurface
‘ 概要: 選択された境界エッジ群からG1連続性を持つフィラードサーフェスを生成する
‘ 備考: SolidWorks 202X / VBA 7.1 環境対応
‘ ==============================================================================
Public Sub CreateHighQualityFilledSurface()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swModExt As SldWorks.ModelDocExtension
Dim swSelMgr As SldWorks.SelectionMgr
Dim swFeatMgr As SldWorks.FeatureManager
‘ アプリケーション・ドキュメントの取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then Exit Sub
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical
Exit Sub
End If
If swModel.GetType <> swDocPART Then
MsgBox “このマクロはパーツドキュメントでのみ実行可能です。”, vbExclamation
Exit Sub
End If
Set swModExt = swModel.Extension
Set swSelMgr = swModel.SelectionManager
Set swFeatMgr = swModel.FeatureManager
‘ 1. 選択されたエッジの数を検証し、動的配列に格納
Dim selCount As Long
selCount = swSelMgr.GetSelectedObjectCount2(-1)
If selCount < 3 Then MsgBox "最低3つ以上の境界エッジを選択してください。", vbExclamation GoTo CleanUp End If Dim i As Long Dim edgeList() As Object ReDim edgeList(0 To selCount - 1) Dim swEdge As SldWorks.Edge For i = 0 To selCount - 1 ' 選択オブジェクトがエッジであるか確認 If swSelMgr.GetSelectedObjectType3(i + 1, -1) == swSelectType_EDGE Then Set swEdge = swSelMgr.GetSelectedObject6(i + 1, -1) Set edgeList(i) = swEdge Else MsgBox "選択されたアイテムにエッジ以外のものが含まれています。", vbCritical GoTo CleanUp End If Next i ' 2. フィラードサーフェス定義データの作成 Dim swFeatData As SldWorks.FilledSurfaceFeatureData Set swFeatData = swFeatMgr.CreateDefinition(swFeatureFilledSurface) If swFeatData Is Nothing Then MsgBox "FilledSurfaceフィーチャデータの作成に失敗しました。", vbCritical GoTo CleanUp End If ' 3. パッチ境界の設定 (SetPatchBoundaryの適用) ' 構文: SetPatchBoundary(EdgeArray, PatchOptions) Dim vEdges As Variant vEdges = edgeList ' 境界エッジの割り当て swFeatData.SetPatchBoundary vEdges ' 4. 連続性の設定 (0: 接触[Contact/C0], 1: 接線[Tangent/G1], 2: 曲率[Curvature/G2]) ' ここでは実用性の高いG1(接線)を指定 swFeatData.ContactType = 1 ' swFilledSurface_Tangent (環境による定数差異に注意) ' 5. 最適化およびプレビューの強制 swFeatData.Optimize = True ' 6. フィーチャの生成実行 Dim swFeat As SldWorks.Feature Set swFeat = swFeatMgr.CreateFeature(swFeatData) If Not swFeat Is Nothing Then swModel.ClearSelection2 True MsgBox "高品質なFilledSurfaceの生成に成功しました。", vbInformation Else MsgBox "フィーチャの構築に失敗しました。境界の連続性を確認してください。", vbCritical End If CleanUp: ' -------------------------------------------------------------------------- ' 極限のメモリ最適化: COMポインタの明示的破棄 ' -------------------------------------------------------------------------- On Error Resume Next For i = LBound(edgeList) To UBound(edgeList) Set edgeList(i) = Nothing Next i Set swEdge = Nothing Set swFeat = Nothing Set swFeatData = Nothing Set swSelMgr = Nothing Set swModExt = Nothing Set swModel = Nothing Set swApp = Nothing On Error GoTo 0 End Sub ---
3. チーフアーキテクトが教えるパフォーマンスチューニングの極意
オブジェクトの明示的解放(Garbage Collectionの制御)
VBAのランタイムは参照カウント方式をとっているが、SolidWorksのCOMオブジェクト(特に `SelectionMgr` や `Feature` などの深い階層)は、スコープを抜けても即座にメモリから解放されないケースが多い。特に上記コードのように `ReDim` で配列にエッジを格納する処理や、ループ内でAPIを連続コールするバッチ処理では、明示的な `Set Object = Nothing` の記述がメモリリークを防ぐ唯一の防壁となる。
トポロジーエラーを未然に防ぐ境界検証
`SetPatchBoundary` を呼び出す前に、選択されたエッジ群が本当に閉じたループ(Closed Loop)を形成しているかをAPI側で厳密に検証することは難しい。実務システムでは、エッジの端点(Start Point / End Point)の座標を数学的に比較し、許容差(Tolerance: 例 `0.00001 mm`)以内でつながっているかを事前にコード側でバリデーションするサブルーチンを挟むべきである。これによって、SolidWorksの強制終了という最悪のシナリオを完全に排除できる。
総括
SolidWorks VBAにおけるサーフェスモデリング自動化は、単なるマクロの記録の延長線上には存在しない。APIの仕様(COMのライフサイクル、引数の型、トポロジーの制約)を深く理解し、堅牢なエラーハンドリングとメモリ管理を組み込むことで初めて、プロダクション環境に耐えうる真のエンジニアリングシステムが完成する。
本記事で示した `FilledSurface.SetPatchBoundary` の制御手法を基盤として、貴社の自動化パイプラインを次の次元へと引き上げてほしい。
