【入門編】【フィレット・面取り】Body2.GetFacesとEdge.GetCurveを用いた、特定の曲率を持つエッジのみを抽出して一括フィレットをかける応用マクロ – SolidWorks VBA解析バイブル

スポンサーリンク

こんにちは!SolidWorksの自動化の海へようこそ。
マクロの記録ボタンを押して出てくるコードを眺めるだけの日々は、今日で終わりです。

今回は、SolidWorks VBAの真骨頂である「幾何学情報のプログラムによる走査(スキャン)」をテーマに、実務で即戦力となるテクニックを伝授します。

私たちが取り組むのは「特定の曲率や条件を持つエッジだけをピンポイントで抽出し、一括でフィレットをかける」という高度なオブジェクト走査術です。

「モデル全体のすべての角にフィレットをかけたいわけじゃない、特定の穴の縁だけ、あるいは特定の半径を持つエッジだけに処理を施したいんだ!」
そんな現場の切実な要望に応えるための、チーフアーキテクト直伝の知見を授けましょう。ここをクリアすれば、あなたのVBAスキルは間違いなく一段上のステージに到達します。

1. なぜ「マクロの記録」ではこの処理が作れないのか?

SolidWorksのマクロの記録機能を使うと、ユーザーが手動でクリックしたエッジのID(固有名)がコードにハードコーディングされます。

‘ マクロの記録が吐き出す典型的なコード(実務では使い物になりません)
boolstatus = Part.Extension.SelectByID2(“Edge1@Boss-Extrude1@Part1.SLDPRT”, “EDGE”, 0, 0, 0, False, 0, Nothing, 0)

しかし、CADの形状(フィーチャ)を変更したり、別のモデルにマクロを流用したりすると、この`Edge1`という名前は簡単に変わり、「オブジェクトが見つかりません」というエラー(実行時エラー)でマクロがクラッシュします。

真にロバスト(堅牢)な自動化エンジニアは、名前でエッジを探しません。
「モデルの数学的構造(B-Rep:境界表現)をプログラムで舐め回し、条件に合致するエッジをその場で動的に発見する」のです。

2. 攻略のキーテクノロジー:Body2, Face, Edge, Curve

SolidWorksのAPIでは、3Dモデルは以下のような階層構造(ツリー構造)でメモリ上に存在しています。

1. PartDoc(パーツドキュメント)
2. Body2(ソリッドボディ):モデルの実体
3. Face(面):Bodyを構成する表面
4. Edge(エッジ):面と面の境界線
5. Curve(曲線):Edgeの数学的実体(円、直線、スプラインなど)

今回は、「モデル内のすべての面(Face)からエッジ(Edge)をかき集め、そのエッジが持つ曲線(Curve)の半径を数学的に判定して、条件に合うものだけを配列に収めて一括フィレットをかける」というアプローチを取ります。

3. 実装コード:特定曲率エッジ抽出&一括フィレットマクロ

以下のコードをSolidWorksのVBAエディタ([Alt] + [F11])に貼り付けてください。
今回は、「特定の半径(例:半径2mmの円弧のエッジ)を持つものだけを抽出し、R1のフィレットをかける」というシナリオを実装しています。

Option Explicit

Sub ApplySmartFillet()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Dim swBody As SldWorks.Body2
Dim swBodies As Variant
Dim swFaces As Variant
Dim swFace As SldWorks.Face2
Dim swEdges As Variant
Dim swEdge As SldWorks.Edge
Dim swCurve As SldWorks.Curve

‘ 選択用コレクション(動的配列)
Dim targetEdges() As SldWorks.Edge
Dim edgeCount 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
edgeCount = 0

‘ 1. パーツ内のすべてのソリッドボディを取得
swBodies = swPart.GetBodies2(swSolidBody, True)
If IsEmpty(swBodies) Then
MsgBox “ソリッドボディが見つかりません。”, vbCritical
Exit Sub
End If

‘ 2. ボディ、フェイス、エッジの階層を走査
Dim i As Long, j As Long, k As Long
For i = LBound(swBodies) To UBound(swBodies)
Set swBody = swBodies(i)
swFaces = swBody.GetFaces

For j = LBound(swFaces) To UBound(swFaces)
Set swFace = swFaces(j)
swEdges = swFace.GetEdges

For k = LBound(swEdges) To UBound(swEdges)
Set swEdge = swEdges(k)

‘ 3. エッジの数学的実体(Curve)を取得
Set swCurve = swEdge.GetCurve

‘ 4. 条件判定:円弧(Circle)であり、かつ半径が指定の値に近いか?
‘ ※SolidWorksの単位系は「メートル法(m)」なので注意! 2mm = 0.002m
If swCurve.IsCircle Then
Dim radius As Double
Dim center As Variant
Dim axis As Variant

‘ 円弧のパラメータを取得(GetCircleParamsの戻り値配列を解析)
Dim circleInfo As Variant
circleInfo = swCurve.GetCircleParams

‘ circleInfo(6) に半径が入る(API仕様に準拠)
radius = circleInfo(6)

‘ 例:半径 5mm (0.005m) のエッジをターゲットにする場合
‘ 浮動小数点の比較のため、微小な許容誤差(Tolerance)を設ける
If Abs(radius – 0.005) < 0.0001 Then ' 条件に合致したエッジを動的配列に蓄積 ReDim Preserve targetEdges(edgeCount) Set targetEdges(edgeCount) = swEdge edgeCount = edgeCount + 1 End If End If Next k Next j Next i ' 5. 対象エッジが見つかったか確認 If edgeCount = 0 Then MsgBox "条件に一致するエッジが見つかりませんでした。", vbInformation Exit Sub End If ' 6. 抽出したエッジを実際にSolidWorks上で選択状態にする swModel.ClearSelection2 True Dim swSelData As SldWorks.SelectionData Set swSelData = swModel.CreateSelectionData swSelData.Callout = Nothing For i = 0 To edgeCount - 1 Dim swEntity As SldWorks.Entity Set swEntity = targetEdges(i) ' マーク「1」を指定してエッジを追加選択 swEntity.Select4 True, swSelData Next i ' 7. 一括フィレットフィーチャの実行(例:半径1mm = 0.001m) ' 引数: 半径, 伝播(True/False), 保持面, 形状など Dim swFeatureManager As SldWorks.FeatureManager Set swFeatureManager = swModel.FeatureManager ' FeatureFillet2(Radius, Propagate, UseManagedEdges, 保持オプション...) Dim swFeat As SldWorks.Feature Set swFeat = swFeatureManager.FeatureFillet2(0.001, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) If Not swFeat Is Nothing Then MsgBox edgeCount & "個のエッジに対して、フィレットの作成に成功しました!", vbInformation Else MsgBox "フィレットの生成に失敗しました。形状干渉を確認してください。", vbExclamation End If ' 選択をクリア swModel.ClearSelection2 True End Sub ---

4. チーフアーキテクトが教える、陥りやすい罠と極意

このコードを実務で動かす際、初心者が必ずハマるポイントがいくつかあります。ここを押さえておけば完璧です。

罠1:単位系(MKS vs MMGS)の混乱

SolidWorksのAPIが内部で扱う数値の単位は、モデルの設定に関わらずすべて「メートル(m)」です。

  • 画面上で「5mm」と見えていても、APIには `0.005` と記述しなければなりません。ここを間違えると、エッジが一生ヒットしません。

罠2:重複エッジの存在

上記のコードは `Face -> GetEdges` のループを回しています。ひとつのエッジは通常「2つの面(隣り合う面)」に共有されているため、同じエッジが2回検出されて配列に重複登録される現象が起きます。
そのまま `Select4` を呼ぶとエラーになるか、挙動がおかしくなります。

  • 【プロの知見】: 厳密なプロダクションコードを書く場合は、エッジのポインタ(`Ptr` や一意のID)をDictionaryなどでハッシュ化し、重複を排除するガード処理を入れると完璧です。

罠3:浮動小数点の比較誤差

コンピュータは少数の計算が少し苦手です。`radius = 0.005` のように完全一致で条件テイスティングすると、内部の丸め誤差で弾かれてしまいます。
コード内でも用いたように、`Abs(radius – 0.005) < 0.0001` のように許容誤差(イプシロン)を持たせて比較するのが、エンジニアとしての作法です。

5. おわりに:ここをクリアすれば、基本はバッチリ!

お疲れ様でした!
「モデルのボディ構造を分解し、数学的特性(Curve)を読み解き、プログラム側から能動的にエンティティを選択してフィーチャを操作する」
ここまでできれば、もうあなたは「マクロの記録係」ではありません。立派なSolidWorks自動化エンジニアです。

現場の設計業務において、定型作業の自動化はコスト削減の最大の武器になります。ぜひこのコードをご自身の環境に合わせてカスタマイズし、日々の設計効率を爆発的に高めてください。

それでは、次回の高度なAPI解説でお会いしましょう。良き自動化ライフを!

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