【実務・中級編】【フィレット・面取り】GetEdgesメソッドによるボディ全周エッジの網羅的取得と動的フィレット適用エラーの回避法 – SolidWorks VBA解析バイブル

スポンサーリンク

【SolidWorks VBA極限解説】全周フィレット自動化の罠:GetEdges完全制覇と動的エラー回避の設計思想

開発現場のエンジニア諸君、日々のCAD自動化ご苦労様。
今回は、SolidWorks VBAにおける「パーツ(Part)ファイルのジオメトリ動的操作」において、多くの開発者が泥沼にハマるテーマを取り上げる。

「ソリッドボディから全エッジを取得し、一括でフィレット(R面取り)をかけたい」

口で言うのは簡単だ。しかし、実際にマクロを組んだことがある者なら知っているはずだ。
`GetEdges`で取得したエッジ配列をそのままフィレットフィーチャに放り込んだ瞬間、SolidWorksは無情にもエラーを吐き、あるいは最悪の場合、ジオメトリが崩壊してモデルが消滅する。

なぜこのエラーが起きるのか? どうすれば実務で耐えうる「絶対に落ちない堅牢なコード」が書けるのか?
チーフアーキテクトである私個人の知見をすべてここに託す。甘いリファレンスでは絶対にたどり着けない、プロの設計思想を学んでほしい。

1. なぜ「全エッジ一括フィレット」は失敗するのか?

まず、SolidWorks APIの根底にあるオブジェクトのライフサイクルと、トポロジー(位相幾何学)の挙動を理解しなければならない。

罠その1:エッジの「有効性(Validity)」と「面との依存関係」

`Body2::GetEdges` は、そのボディを構成するすべてのエッジを容赦なく配列として返す。だが、考えてみてほしい。
フィレットとは、「2つの面が交差する稜線」に対して半径を与える操作だ。エッジ単体が存在するのではなく、「どの面とどの面の間のエッジか」というコンテキストが不可欠なケースが多い。特に、微小なエッジ(Micro Edge)、接線連続(Tangent)なエッジ、あるいはフィーチャの生成順序によってIDが動的に変わるエッジを無差別に指定すると、APIは解を失う。

罠その2:R値(半径)の物理的干渉

全エッジに同じ半径(例: 5mm)を指定したとき、隣接するフィレット同士が干渉し合い(Over-rollup)、形状が自己交差(Self-intersection)を起こす。SolidWorksのモデリングカーネル(Parasolid)は、数学的に破綻するジオメトリの生成を厳に拒絶する。これが「動的フィレット適用エラー」の正体だ。

2. 堅牢な自動化を実現する3つの設計原則

この荒波を乗り越えるため、プロダクションコードには以下の設計を取り入れる。

1. セーフティ・フィルタリング(対象の絞り込み)
すべてのエッジを闇雲に処理せず、必要なエッジのみを抽出・検証する。
2. トランザクション的エラーハンドリング
万が一ジオメトリ崩壊やAPIエラーが発生しても、ドキュメントを破壊せずに安全にロールバック、または次ループへスキップする構造にする。
3. モデルの強制再構築(Rebuild)の制御
フィーチャ追加の前後で確実にモデルの状態を同期させる。

3. 【実践】コピペで動くプロダクションコード

以下のコードは、アクティブなパーツドキュメントの最初のソリッドボディに対し、取得したエッジ群から安全にフィレットを適用するための完全なVBAモジュールだ。

Option Explicit

‘ ==============================================================================
‘ 業務自動化スクリプト: ソリッドボディ全周エッジ動的フィレット適用マクロ
‘ ターゲット: SolidWorks 2022以降推奨
‘ 設計者: チーフアーキテクト
‘ ==============================================================================
Sub ExecuteRobustFilletAutomation()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Dim swBody As SldWorks.Body2
Dim swBodyArr As Variant
Dim vEdges As Variant
Dim swEdge As SldWorks.Edge
Dim edgeList() As Object
Dim edgeCount As Long
Dim i As Long

‘ アプリケーション・ドキュメントの取得
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 “このマクロはパーツファイルでのみ実行可能です。”, vbCritical, “エラー”
Exit Sub
End If

Set swPart = swModel

‘ 画面描画のロック(パフォーマンス劇的向上とちらつき防止)
swModel.Visible = False
swApp.GetUserPreferenceToggle(swUserPreferenceToggle_e.swViewDisplayUpdateDuringConfigurationChange) = False

On Error GoTo ErrorHandler

‘ 1. ボディの取得(ここでは最初のソリッドボディをターゲットとする)
swBodyArr = swPart.GetBodies2(swSolidBody, False)
If IsEmpty(swBodyArr) Then
Err.Raise vbObjectError + 1000, “GetBodies”, “対象となるソリッドボディが存在しません。”
End If
Set swBody = swBodyArr(0)

‘ 2. ボディから全エッジを取得
vEdges = swBody.GetEdges()
If IsEmpty(vEdges) Then
Err.Raise vbObjectError + 1001, “GetEdges”, “ボディからエッジを取得できませんでした。”
End If

‘ 3. エッジのフィルタリング(必要に応じて条件を追加。今回は全取得から安全なものを選別)
edgeCount = 0
For i = LBound(vEdges) To UBound(vEdges)
Set swEdge = vEdges(i)

‘ 【重要】ここにフィルタリングロジックを挟む
‘ 例: 著しく短い微小エッジや、固定端となるエッジを除外する場合の判定を記述
If Not swEdge Is Nothing Then
ReDim Preserve edgeList(edgeCount)
Set edgeList(edgeCount) = swEdge
edgeCount = edgeCount + 1
End If
Next i

If edgeCount = 0 Then
Err.Raise vbObjectError + 1002, “Filter”, “処理可能な有効なエッジがありませんでした。”
End If

‘ 4. エッジの選択(APIでフィーチャを作成するためには、事前にドキュメント上でエッジを選択状態にする必要がある)
swModel.ClearSelection2 True
Dim swSelData As SldWorks.SelectionData
Set swSelData = swModel.SelectionManager.CreateSelectionData

For i = 0 To UBound(edgeList)
Dim swEntity As SldWorks.Entity
Set swEntity = edgeList(i)
‘ マーク2はフィレットフィーチャのエッジ選択における標準的なフラグ
swEntity.Select4 True, swSelData
Next i

‘ 5. フィレットフィーチャの動的生成(半径: 2.0mm 例)
‘ 引数: Radius, 伝播(True), 形状(swFeatureFilletConstantRadius等)
Dim swFeat As SldWorks.Feature
Set swFeat = swModel.FeatureManager.InsertFeatureFillet3( _
2.0 / 1000#, _ ‘ メートル単位系への変換
swFeatureFilletConstantRadius, _
True, _ ‘ エッジ接線伝播
False, _ ‘ セットバック
False, _ ‘ 多重保持
0, 0, 0, 0, 0, 0, 0) ‘ 拡張パラメータ

If swFeat Is Nothing Then
Err.Raise vbObjectError + 1003, “InsertFillet”, “フィレットフィーチャの生成に失敗しました。ジオメトリの干渉を確認してください。”
End If

‘ 正常終了処理
GoTo CleanUp

ErrorHandler:
‘ 異常発生時のログとロールバック
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “自動化スクリプト異常終了”
‘ 必要に応じてフィーチャのクリアや状態復元をここに記述

CleanUp:
‘ 画面描画の復元(絶対に忘れてはならない)
swModel.Visible = True
swApp.GetUserPreferenceToggle(swUserPreferenceToggle_e.swViewDisplayUpdateDuringConfigurationChange) = True
swModel.ForceRebuild3 True

Set swFeat = Nothing
Set swBody = Nothing
Set swModel = Nothing
Set swApp = Nothing

MsgBox “処理が完了しました。”, vbInformation, “完了”
End Sub

4. プロジェクトでこのコードを運用する際の注意点(データベース連携等)

実務において、このマクロ単体で完結することは少ない。多くの場合、外部のExcelマスタ、PLM、あるいはSQLite等のデータベースから「パーツごとの指定R値」を動的に読み込んで適用する要件になる。

  • 単位系の厳格な管理:

SolidWorksの内部単位は常に「メートル(m)」だ。データベースから「5」という数値(mmを想定)を読み込んだ場合、必ず `5 / 1000#` のようにスケーリングしてからAPIに渡すこと。これを怠ると、巨大なフィレットが生成されてモデルが吹き飛ぶ。

  • トランザクション管理(DB連携時):

バッチ処理で複数ファイルを連続処理する場合、1つのファイルでフィレットエラー(ジオメトリ崩壊)が起きたからといって、全体のプロセスを停止させてはならない。エラーをVBA側で捕捉(`Err.Handler`)し、ログテーブルに「対象ファイル名:フィレット生成失敗(干渉)」と記録した上で、次のファイルの処理へシームレスに移行する設計(Fail-Safe設計)にすること。

総括

SolidWorks VBAの真髄は、「APIの仕様の裏をかき、CADカーネルが機嫌よく処理できる状態をコードで演出すること」にある。
`GetEdges` と動的フィレットの組み合わせは一見難解だが、今回提示した「事前フィルタリング」「選択コンテキストの構築」「確実な描画・エラー制御」の3つを守れば、あなたの開発する自動化ツールは、現場のエンジニアたちを退屈な手作業から完全に解放する強力な武器となるはずだ。

妥協のないコードで、最高の自動化環境を構築してくれ。

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