【実務・中級編】【フィレット・面取り】Body2.GetFacesを活用した「特定の法線方向を持つ平滑面」に対する一括フィレット適用 – SolidWorks VBA解析バイブル

スポンサーリンク

SolidWorks VBAを掌握する開発者諸君。
日々の業務で、こんな不毛な作業に時間を溶かしていないだろうか?

「設計変更でモデルのトポロジー(位相)変わり、ハードコードしたエッジ名(`@`など)が外れてマクロが爆発する」
「パラメータスタディや派生モデルの生成において、モデルの向きやサイズが変わるたびにフィレットのマクロを書き直している」

断言しよう。エッジ名に依存したフィレット自動化は、レガシーかつ最悪の設計だ。
真に堅牢な自動化エンジニアを目指すなら、モデルの「名前」ではなく「幾何学的特徴(ジオメトリ)」をコードで解釈させなければならない。

今回は、`Body2.GetFaces` を駆使し、「特定の法線方向を持つ平滑面」を動的に特定し、それらに隣接するエッジ群を一括してフィレット留めするプロダクションコードを授与する。
実務の最前線で耐えうる、泥臭くも洗練された設計論を共に行こう。

1. なぜ「エッジ名」のハードコードは悪なのか?

SolidWorksのAPI初学者が最初に陥る罠が、セレクションマネージャ(SelectionManager)を使って特定のエッジ名を取得し、それをコードにべた書きする手法だ。

‘ 【アンチパターン】絶対にしてはならない実装
boolstatus = swModel.Extension.SelectByID2(“Edge1@Part1”, “EDGE”, 0, 0, 0, False, 0, Nothing, 0)

このアプローチがなぜ現場で破綻するのか。理由は単純だ。
SolidWorksのB-Rep(境界表現)において、フィーチャの追加やカット、寸法変更が行われると、エッジの内部ID(Internal ID)やトポロジカルな名称は容赦なく再割り当てされる。
結果、昨日まで動いていたマクロが、今日、別コンフィギュレーションや微小な形状変更によって「エッジが見つかりません(Error -1)」を吐いて停止する。

堅牢な設計アプローチ:幾何学的特徴(Normal Vector)からの逆引き

エッジ名がダメならどうするか?
「面の法線ベクトル(Normal Vector)」と「形状(平滑面)」を数学的にスキャンし、ターゲットとなる面をプログラム側で動的に特定する。 その面が共有する境界エッジ(Boundary Edges)を抽出してフィレットをかける。これが、環境変化にビクともしないプロフェッショナルな設計思想だ。

2. 全体アーキテクチャとアルゴリズム

今回構築するマクロの処理フローは以下の通りだ。

1. アクティブドキュメントの取得: 対象がパーツファイル(`swModelDocExt`)であることを厳格に担保。
2. ボディの走査: `PartDoc.GetBodies2` を使用して、ソリッドボディ(`Body2`)を取得。
3. 面の列挙と法線評価: `Body2.GetFaces` でボディを構成する全フェースの配列を取得。各フェースが「平面(Planar)」であるか判定し、その法線ベクトルが「狙った方向(例: Z軸方向)」と一致するかを内積(Dot Product)で判定。
4. エッジの抽出: 条件に合致する面から、隣接するエッジ(`Face2.GetEdges`)を収集。
5. フィーチャ一括生成: 収集したエッジ群に対して `FeatureManager.FeatureFillet3` を実行。

3. プロダクションコード実装

以下のコードは、エラーハンドリング、型安全性、メモリ管理(COMオブジェクトの解放)を考慮した実務レベルのVBAコードだ。そのままモジュールに貼り付けて利用してほしい。

Option Explicit

‘ ==============================================================================
‘ 処理名: 指定法線方向を持つ平滑面のエッジに対する一括フィレット自動適用
‘ ターゲット: SolidWorks 2022以降推奨
‘ ==============================================================================
Sub ExecuteDynamicFillet()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Dim swBody As SldWorks.Body2
Dim vBodies As Variant
Dim vFaces As Variant
Dim swFace As SldWorks.Face2
Dim swSurface As SldWorks.Surface

‘ アプリケーション・ドキュメントの安全な取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc

If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical, “エラー”
Exit Sub
End If

If swModel.GetType <> swDocPART Then
MsgBox “このマクロはパーツ(Part)ファイルでのみ実行可能です。”, vbCritical, “エラー”
Exit Sub
End If

Set swPart = swModel

‘ 1. パーティション内のソリッドボディを取得(単一/マルチボディ対応)
vBodies = swPart.GetBodies2(swSolidBody, False)
If IsEmpty(vBodies) Then
MsgBox “対象となるソリッドボディが見つかりません。”, vbCritical, “エラー”
Exit Sub
End If

‘ 処理のパフォーマンス向上と画面描画のロック
swModel.Extension.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayUpdateWhileMacroRuns, False

Dim swSelectionMgr As SldWorks.SelectionMgr
Set swSelectionMgr = swModel.SelectionManager
swModel.ClearSelection2 True

Dim edgeCount As Long
edgeCount = 0

Dim i As Long, j As Long
For i = LBound(vBodies) To UBound(vBodies)
Set swBody = vBodies(i)

‘ ボディから全フェースの配列を取得(極めて強力なAPI)
vFaces = swBody.GetFaces
If Not IsEmpty(vFaces) Then
For j = LBound(vFaces) To UBound(vFaces)
Set swFace = vFaces(j)
Set swSurface = swFace.GetSurface

‘ 条件A: サーフェスが「平面 (Planar)」であること
If swSurface.IsPlane Then
‘ 平面の法線ベクトルを取得 (配列: 0=X, 1=Y, 2=Z)
Dim vParam As Variant
vParam = swSurface.PlaneParameters

‘ 平面パラメータの後半3要素が法線ベクトル (Nx, Ny, Nz)
Dim normalX As Double, normalY As Double, normalZ As Double
normalX = vParam(3)
normalY = vParam(4)
normalZ = vParam(5)

‘ 条件B: 法線が上向き(Z方向 = +1.0)の面であるかを判定
‘ 浮動小数点の比較のため、許容誤差(Tolerance)を考慮
If Abs(normalZ – 1.0) < 0.0001 Then ' 条件に合致した面から「隣接するエッジ」を抽出して選択セットに追加 Dim vEdges As Variant vEdges = swFace.GetEdges If Not IsEmpty(vEdges) Then Dim k As Long For k = LBound(vEdges) To UBound(vEdges) Dim swEdge As SldWorks.Edge Set swEdge = vEdges(k) ' エッジをマーク付きで選択 (Mark=1 はフィレット用などの指定に利用) Dim swEntity As SldWorks.Entity Set swEntity = swEdge swEntity.Select4 True, Nothing edgeCount = edgeCount + 1 Set swEntity = Nothing Set swEdge = Nothing Next k End If End If End If Set swSurface = Nothing Set swFace = Nothing Next j End If Set swBody = Nothing Next i ' 2. エッジが正常に収集できた場合のみフィレットフィーチャを生成 If edgeCount > 0 Then
Dim swFeature As SldWorks.Feature
Dim radius As Double
radius = 0.005 ‘ フィレット半径: 5mm (メートル単位で指定)

‘ FeatureFillet3 によるフィレット生成
‘ 引数: Radius, 処理タイプ, 断面形状, 保持タイプ等
Set swFeature = swModel.FeatureManager.FeatureFillet3( _
radius, _
swFeatureFilletType_ConstantSize, _
swFeatureFilletEdge_Round, _
swFeatureFilletPropagate_None, _
False, False, False)

If Not swFeature Is Nothing Then
MsgBox “動的エッジ解析によるフィレットの生成に成功しました。(対象エッジ数: ” & edgeCount & “本)”, vbInformation, “完了”
Else
MsgBox “エッジの選択には成功しましたが、フィレットの生成に失敗しました(幾何学的な干渉の可能性があります)。”, vbExclamation, “警告”
End If
Else
MsgBox “条件に合致する面およびエッジが見つかりませんでした。”, vbExclamation, “情報”
End If

‘ 画面描画の復元
swModel.Extension.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayUpdateWhileMacroRuns, True
swModel.WindowRedraw
End Sub

4. コードの深掘り:プロが解説するキモ

このコードが他の凡庸なマクロと一線を画すポイントを解説しよう。

① `Surface.IsPlane` と `PlaneParameters` の活用

SolidWorks APIにおいて、ジオメトリの数学的評価はパフォーマンスの鍵を握る。
`Face2.GetSurface` で取得できる `Surface` オブジェクトに対し `IsPlane` を叩くことで、面が平滑かどうかが一瞬で判定できる。さらに `PlaneParameters` は、`[Px, Py, Pz, Nx, Ny, Nz]`(通過点と法線ベクトル)の6要素配列を返す。これを利用することで、「ワールド座標系における特定の向きを向いた面」を数学的に一発で特定できる。

② 浮動小数点演算の罠(`Abs(normalZ – 1.0) < 0.0001`)

CAD内部の計算精度は極めて高いため、法線ベクトルが完全に `1.0000000000` にならないケースがある。`normalZ = 1` という厳密な比較(`=`)を行うと、微小な丸め誤差によって条件から漏れるバグが頻発する。許容誤差(イプシロン)を設けた範囲比較を行うことが、実務におけるバグを防ぐ鉄則だ。

③ メモリリークの防止(COMオブジェクトの確実な解放)

VBAはガベージコレクションを持たない。`Body2.GetFaces` や `Face2.GetEdges` が返すバリアント配列内のCOMオブジェクト(`Face2`, `Edge`, `Surface` 等)は、ループの都度 `Set Object = Nothing` で明示的に開放しなければ、大規模なモデルを処理した際に確実にメモリーリーク(Excel/SolidWorksのクラッシュ)を引き起こす。上記のコードではこのライフサイクル管理を完璧に網羅している。

5. ファイル連携・データベース連携への拡張性

現場の自動化を進めるにあたって、この「動的法線解析マクロ」をさらに拡張するためのヒントを提示しよう。

  • 外部CSV/JSONからのパラメータ駆動:

「どの方向の面に対して、何ミリのフィレットをかけるか」というルール(例: `Z+方向 = 5mm`, `Y-方向 = 3mm`)を外部のマスター設定ファイルから読み込ませることで、コードを1行も変えずにあらゆるバリエーションのパーツに対応可能になる。

  • PDM / ERP連携:

エンジニアリングデータベースから取得した製品仕様データ(JSON)に基づき、このマクロをHeadless(バックグラウンド)モードでSolidWorksタスクスケジューラからバッチ実行させる。これにより、「図面が発行されたら自動で指定エッジに丸め処理を施したステップファイルを吐き出す」といった完全無人のCIM(Computer Integrated Manufacturing)パイプラインが構築できる。

総括

名前に依存した自動化は、現場の成長とともに必ず死ぬ。
だが、「幾何学的特徴」をコードに語らせた自動化は、モデルがどう変化しようとも半永久的に動き続ける。

今回解説した `Body2.GetFaces` と法線ベクトルの動的解析手法は、フィレットだけでなく、面取り、特定の面を基準とした穴あけ、自動図面寸法配置など、あらゆる高度な自動化の基盤となる技術だ。

あなたの設計デスクにあるその非効率なルーチンワークを、この知見をもって今すぐコードの海に沈めてほしい。健闘を祈る。

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