【フィーチャー履歴の深掘り】GetFirstSubFeatureとGetNextFeatureによる複雑なツリー構造の再帰的解析
SolidWorksのAPI開発において、フィーチャーマネージャ・デザイン・ツリー(以下、FMP)の構造解析は、避けて通れないが最も深遠な領域の一つだ。
表面上の `GetFirstFeature` だけを順次たどる平坦なループでは、フォルダ、パターン、対称コピー、そしてアセンブリの合致関係やマルチボディのコンテキストに隠された「真の履歴構造」を取りこぼす。真に堅牢な自動化ツールやシステム連携基盤を構築するためには、ツリー構造を正しく理解し、メモリリークの罠を回避しながら再帰的に走査する技術が不可欠である。
本稿では、`GetFirstSubFeature` と `GetNextFeature` を駆使したツリー解析の極限の知見を、実用的なVBAコードとともに解説する。
—
1. 表面的な走査の限界と「真のツリー構造」の正体
多くの開発者が陥る最初のアンチパターンは、以下のようなコードだ。
‘ 【アンチパターン】これではサブフィーチャーやコンテキストを見落とす
Dim swFeat As SldWorks.Feature
Set swFeat = swModel.FirstFeature
Do While Not swFeat Is Nothing
Debug.Print swFeat.Name
Set swFeat = swFeat.GetNextFeature
Loop
このコードでは、ルートレベルのフィーチャーしか取得できない。例えば、以下のような構造は完全に無視される。
- パターン(Linear Pattern / Circular Pattern)の内部アイテム
- スイープやロフトのガイドカーブ・プロファイル
- フォルダ内に格納されたフィーチャー群
- Coss-reference(外部参照)やコンテキストフィーチャー
SolidWorksのAPIモデルにおいて、フィーチャーは単なるリストではなく、「親子関係(Parent-Child / SubFeature)」を持つ多重ツリー構造を形成している。これを網羅するためには、兄弟(Next)を辿るだけでなく、常に子(SubFeature)の存在を確認し、再帰的に潜り込むアプローチが必要となる。
—
2. 再帰的ツリー解析のアーキテクチャと実装コード
以下のコードは、ModelDoc2から出発し、すべてのサブフィーチャー、次位フィーチャーを完全網羅する再帰関数の実装例である。
実務でそのまま利用できるよう、インデントによる階層可視化と、オブジェクトの解放処理を組み込んでいる。
Option Explicit
‘ メインエントリーポイント
Sub RunFeatureTreeAnalysis()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントがありません。”, vbCritical
Exit Sub
End If
Debug.Print “=== フィーチャーツリー解析開始: ” & swModel.GetTitle & ” ===”
Dim swFeat As SldWorks.Feature
Set swFeat = swModel.FirstFeature
‘ 再帰処理の呼び出し
Call TraverseFeatures(swFeat, 0)
Debug.Print “=== 解析終了 ===”
End Sub
‘ 再帰的にフィーチャーを走査するプロシージャ
Private Sub TraverseFeatures(ByVal swFeat As SldWorks.Feature, ByVal indentLevel As Long)
Dim swSubFeat As SldWorks.Feature
Dim indentStr As String
Dim i As Long
‘ 階層に応じたインデント文字列の生成
For i = 1 To indentLevel
indentStr = indentStr & ” ”
Next i
Do While Not swFeat Is Nothing
‘ フィーチャー情報の出力(名前、タイプなど)
Debug.Print indentStr & “[Feat] ” & swFeat.Name & ” (Type: ” & swFeat.GetTypeName2 & “)”
‘ 1. サブフィーチャー(子)の存在チェックと再帰呼び出し
Set swSubFeat = swFeat.GetFirstSubFeature()
If Not swSubFeat Is Nothing Then
‘ 子階層へ潜る
Call TraverseFeatures(swSubFeat, indentLevel + 1)
End If
‘ 2. 次の兄弟フィーチャーへ移行
Dim swNextFeat As SldWorks.Feature
Set swNextFeat = swFeat.GetNextFeature
‘ COMオブジェクトの明示的解放(VBAにおけるメモリ最適化の極意)
Set swFeat = Nothing
Set swSubFeat = Nothing
Set swFeat = swNextFeat
Loop
End Sub
—
3. シニアエンジニアが知るべき「メモリ管理とCOMオブジェクトの罠」
VBAにおけるSolidWorks API開発で最も恐ろしいのは、見えないメモリリークとCOM参照カウンタの枯渇である。
上記の再帰コードにおいて、以下の点に注目してほしい。
循環参照と参照解放のタイミング
VBAのガベージコレクションは参照カウンタ方式(Reference Counting)に依存している。特に再帰呼び出し(Recursion)を行う場合、ループ内で生成されたCOMオブジェクト変数がスコープを抜けるタイミングや、ポインタの置き換え時に適切に `Nothing` を代入しないと、SolidWorksのプロセス(`SLDWORKS.exe`)内にメモリリークが蓄積する。
大規模なアセンブリや数千のフィーチャーを持つ複雑なパーツモデルを解析する際、このメモリリークが原因で `Automation error` や突然のクラッシュ(Fatal Error)を引き起こす。
- 対策: ループのイテレーションごとに、一時変数(`swNextFeat`, `swSubFeat` 等)を確実に `Set … = Nothing` で解放し、参照カウンタをデクリメントさせること。
—
4. レガシー環境・システム連携への応用
この再帰的ツリー解析技術をマスターすることで、以下のような高度なシステム間連携やレガシー保守が可能になる。
1. 特定カスタムフィーチャーの強制検出(バリデーション)
- 社内規程で禁止されているフィーチャー(例:特定のフィレット形状や、未承認のカットなど)がツリーの深部に隠されていないかを自動検出し、図面チェックシステム(PDM連携)のゲートキーパーとして機能させる。
2. PLM/ERPシステムへの履歴メタデータの吐き出し
- 単なる部品点数だけでなく、「どのような製造履歴を経てその形状に至ったか」の構造ツリーをJSONやXML形式にシリアライズし、外部の製造管理データベースへ非同期送信する。
3. レガシーマクロのモダン化
- 過去の設計者が書いたスパゲッティコード(ハードコードされたフィーチャー名に依存した処理)を、この動的再帰走査ロジックに置き換えることで、モデルの形状変更に対して圧倒的に堅牢な(ロバストな)自動化基盤へと生まれ変わらせる。
—
総括
SolidWorks APIにおける `GetFirstSubFeature` と `GetNextFeature` の組み合わせは、単なるツリーの「覗き見」ではない。それは、3D CADの内部で構築された設計意図の歴史(フィロソフィー)をプログラムの文脈へと完全に翻訳するための唯一の鍵である。
オブジェクトのライフサイクルをコントロールし、メモリの深淵を意識したコードを書くこと。それこそが、プロフェッショナルなSolidWorks自動化エンジニアに求められる真のスキルである。
