SolidWorks VBAを掌握する極限の知見
【サーフェスモデリング】FilledSurface.SetPatchBoundaryを用いた多角形境界ループからの高品質な穴埋めサーフェス生成
—
開発現場でこんな絶望を味わったことはないだろうか。
複雑な切削加工痕、インダストリアルデザインの有機的な抜き勾配、あるいは他社CADからインポートした不連続なIGES/STEPデータ。そこにぽっかりと空いた多角形の穴に対し、安易に「平面サーフェス」や「境界サーフェス」を適用し、幾何学的整合性の崩壊(ゼロ厚みエラーや面切れ)に頭を抱える夜――。
実務において、サーフェスモデリングの自動化は、単なるマクロによる省力化の次元を超えている。数学的に破綻のないパッチを生成し、ソリッド化(Knit & Create Solid)への橋渡しを完全自動化することこそが、真の「ロバストな(堅牢な)設計自動化システム」の要件である。
今回は、SolidWorks APIの奥底に眠る `FilledSurface.SetPatchBoundary` を極め、任意の多角形境界ループからG1(接線)またはG2(曲率)連続性を担保した高品質な穴埋めサーフェスを生成する、プロダクションレベルのVBAコードを伝授する。
—
1. なぜ「境界サーフェス(Boundary Surface)」ではなく「FILLED SURFACE」なのか?
多くのエンジニアが陥る罠がこれだ。「4辺のループならBoundary Surfaceで十分だろう」という思い込み。
しかし、実務の現場で発生する開口部は、3辺、5辺、あるいはそれ以上の多角形(N-sided hole)であることが多い。境界サーフェスで無理やり多角形を埋めようとすると、一点への収束特異点(Singularity)で面がねじれ、パッチの品質が致命的に劣化する。
一方、SolidWorksの「面埋め(Filled Surface:API内部名 `ISurfaceDeformation` / `IFilledSurfaceFeatureData`)」は、境界の連続性(接触・接線・曲率)を維持しながら、N角形のトポロジーを美しく調和させる数理モデルを持っている。
特に、`SetPatchBoundary` メソッドを正しく使いこなすことで、「どのエッジに対して、どのような連続性(Contact=0, Tangent=1, Curve=2)を適用し、必要に応じてどの拘束カーブ(Constraint Curves)を通過させるか」を完全にプログラムから制御できる。
—
2. バグの起きない堅牢な設計:実務での3大鉄則
現場で使えるツールにするためには、API特有の「お作法」と「破壊的変更への耐性」を考慮しなければならない。
鉄則①:エッジの選択は「ポインタの生存期間」を意識せよ
APIで取得したエッジ(`IEdge`オブジェクト)は、フィーチャツリーが更新された瞬間にメモリ上で無効化(Dangling)される。境界を構成するエッジ配列は、一気に取得し、配列に格納した上で一括して渡す必要がある。
鉄則②:コンテキストの明確化(Partドキュメントの強制)
サーフェス操作は、アセンブリ文脈(`IAssemblyDoc`)ではなく、必ずパーツドキュメント(`IPartDoc`)のフィーチャマネージャー配下で実行されなければならない。ドキュメントの取り違えは、静的な型安全性を破壊する。
鉄則③:エラーハンドリングの徹底
`SetPatchBoundary` は、エッジの方向(Reverse)や接続整合性に敏感だ。戻り値の成否判定(Boolean)を無視したコードは、現場では「動いたり止まったりする不良品」の烙印を押される。必ずトランザクション的なエラー処理を組み込むこと。
—
3. プロダクションコード:多角形穴埋め自動化マクロ
以下のコードは、選択した複数の境界エッジ(ループを形成していること)を自動認識し、G1連続性を持つFilled Surfaceを生成する実務仕様のVBAプロシージャである。
Option Explicit
‘ =========================================================================
‘ 模範的プロダクションコード:FilledSurfaceによる高品質穴埋め生成
‘ 前提条件: 対象のパーツドキュメントを開き、穴を囲む連続したエッジを
‘ 事前に複数選択(Multi-Select)している状態であること。
‘ =========================================================================
Sub CreateHighQualityFilledSurface()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Dim swSelMgr As SldWorks.SelectionMgr
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ 1. ガード節:ドキュメントタイプの検証
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical, “API Error”
Exit Sub
End If
If swModel.GetType <> swDocPART Then
MsgBox “このマクロはパーツドキュメントでのみ実行可能です。”, vbCritical, “Type Error”
Exit Sub
End If
Set swPart = swModel
Set swSelMgr = swModel.SelectionManager
‘ 2. 選択エッジの検証と配列化
Dim selCount As Long
selCount = swSelMgr.GetSelectedObjectCount2(-1)
If selCount < 3 Then
MsgBox "穴を囲む少なくとも3つ以上の境界エッジを選択してください。", vbExclamation, "Selection Error"
Exit Sub
End If
Dim i As Long
Dim edgeArray() As Object
ReDim edgeArray(selCount - 1)
Dim continuityArray() As Long
ReDim continuityArray(selCount - 1)
Dim contactArray() As Boolean
ReDim contactArray(selCount - 1)
For i = 0 To selCount - 1
' 選択されているのがエッジ(Mark = 1など用途に合わせる)か確認
If swSelMgr.GetSelectedObjectType3(i + 1, -1) = swSelEDGES Then
Set edgeArray(i) = swSelMgr.GetSelectedObject6(i + 1, -1)
' 【重要】連続性の定義:
' 0 = 接触 (Contact)
' 1 = 接線 (Tangent) -> G1
‘ 2 = 曲率 (Curvature) -> G2
continuityArray(i) = 1 ‘ ここでは実務で最も堅牢なG1(Tangent)を指定
‘ 逆向きフラグ(必要に応じて制御)
contactArray(i) = False
Else
MsgBox “エッジ以外のエンティティが選択されています。”, vbCritical, “Type Error”
Exit Sub
End If
Next i
‘ 3. 画面更新の抑止(パフォーマンス最適化)
swModel.Extension.EnableUIChanges = False
swModel.LockUpdate
On Error GoTo ErrorHandler
‘ 4. フィーチャデータの作成
Dim swFeatData As SldWorks.FilledSurfaceFeatureData
Dim swFeatureManager As SldWorks.FeatureManager
Set swFeatureManager = swModel.FeatureManager
‘ FilledSurfaceのフィーチャデータ作成定義を取得
‘ ※SolidWorksのバージョンによるAPI差異を吸収する抽象化
Set swFeatData = swPart.CreateDefinition(swFeatureFilledSurface)
If swFeatData Is Nothing Then
Err.Raise 1000, “CreateDefinition”, “FilledSurfaceフィーチャデータの生成に失敗しました。”
End If
‘ 5. パッチ境界の設定 (SetPatchBoundary の核心)
‘ 引数: (EdgesArray, ContinuityArray, ReverseEdgeArray)
Dim bSuccess As Boolean
bSuccess = swFeatData.SetPatchBoundary(edgeArray, continuityArray, contactArray)
If Not bSuccess Then
Err.Raise 1001, “SetPatchBoundary”, “境界パッチの設定に失敗しました。エッジのトポロジー連続性を確認してください。”
End If
‘ オプション設定:最適化パッチ、接触面作成などのパラメータ調整
swFeatData.OptimizeSurface = True
swFeatData.Contact = False ‘ ソリッドを作成せずサーフェスとして生成
‘ 6. フィーチャのビルド(実体化)
Dim swFeat As SldWorks.Feature
Set swFeat = swFeatureManager.CreateFeature(swFeatData)
If swFeat Is Nothing Then
Err.Raise 1002, “CreateFeature”, “FilledSurfaceフィーチャのビルドに失敗しました。”
End If
‘ 正常終了処理
swModel.UnlockUpdate
swModel.Extension.EnableUIChanges = True
swModel.GraphicsRedraw2
MsgBox “高品質な穴埋めサーフェスの生成に成功しました。”, vbInformation, “Success”
Exit Sub
ErrorHandler:
‘ 異常終了時の安全な復旧処理
swModel.UnlockUpdate
swModel.Extension.EnableUIChanges = True
swModel.GraphicsRedraw2
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “Runtime Exception”
End Sub
—
4. チーフアーキテクトからの実践的アドバイス
このコードをそのまま社内の設計自動化パイプラインに組み込む際、次の拡張性を考慮しておくと後々の改修コストが劇的に下がる。
1. 連続性(Continuity)の動的切り替えUI
実務では、意匠面(Class-A)なら `2 (Curvature)` を、内部の構造体やMillingの逃げ形状なら `1 (Tangent)` を自動判別させたい。隣接面の曲率変化量を `IMathUtility` や面法線ベクトルから算出し、`continuityArray` の値を動的に切り替えるロジックを前段に挟むと、真にインテリジェントなツールに昇華する。
2. Knit(縫い合わせ)とのパイプライン化
`swFeatData.Contact = False` で生成したサーフェスは、そのままでは単体の独立したサーフェスボディである。これを既存のボディと `ISurfaceBody.Knit` または `IFeatureManager.InsertSewSurface3` を用いてシームレスに結合し、最終的に `CreateSolidFromClosedVolume` でソリッド化する一連のバッチ処理を記述することで、穴埋めからソリッド再構築までの完全自動化が達成される。
妥協のないコードと堅牢な例外処理。これこそが、現場を救うエンジニアの武器である。今日から君のVBA環境にこの知見を実装し、手作業によるモデリング地獄から設計者たちを解放してやってほしい。
