C#ATIA

↑タイトル詐欺 主にCATIA V5 の VBA(最近はPMillマクロとFusion360APIが多い)

Dual Geodesic Icosahedra3

こちらの続きです。
Dual Geodesic Icosahedra2 - C#ATIA

完成したので、テストデータと共にGrabCADにUpしました。
恐らく誰にも役には立たないでしょう。
3D CAD Model Collection | GrabCAD Community Library
結局一番苦労したのは、正規表記のパターンでした。
未だに宝探しをしている気分です。


面の作成に失敗していた理由がわかりました。
Visual PolyhedraのサイトにUpされている座標データの中に
こんな感じの☆型の面を、5個の頂点だけで表現している
データがあります。
f:id:kandennti:20180626165307p:plain
フィルサーフェスを利用して面を作成している為、こんな感じの自己交差
した状態ではエラーになる為、面が抜けてしまったようです。
対応策を考えるのも面倒な為、そのままにしました。

実は、こんなスケッチでもFusion360は面が作れるんですよね。
こちらでそれを利用したものを作りました。
Solved: How to remove inner sketch lines from an intersection sketch? - Autodesk Community
スケッチの考え方の違いを利用しています。


Upしたマクロファイルの "SurfaceFactory.cls" ですが(生意気なネーミングで申し訳ないのです)
このマクロだけではなく、他にも利用できるように考えて作っています。
英語じゃ書けそうになかったので、こちらで説明を。

3D点:array(double,double,double) でXYZの順です。都合上ArrayVariantです。
一枚の面:array(3D点,3D点,3D点…)です。各頂点を表す為、当然3点以上が必要です。
複数の面:array(一枚の面,一枚の面,一枚の面・・・)です。

一枚だけ面を作成したい場合は、ary(ary,・・・) な感じです。

Sub Example_Single()
    'パートドキュメント
    Dim doc As PartDocument: Set doc = CATIA.Documents.Add("Part")
    
    '座標値
    Dim pos As Variant
    pos = Array(Array(0, 0, 0), Array(1, 0, 0), Array(0, 1, 0))
    
    'SurfaceFactoryインスタンス
    Dim surfFact As SurfaceFactory: Set surfFact = New SurfaceFactory
    
    '面を作成するパートドキュメントをセット
    Call surfFact.SetPartDoc(doc)
    
    '座標値から面を作成 - 形状セットには入りません!
    '戻りは HybridShapeSurfaceExplicit
    Dim surf As HybridShapeSurfaceExplicit
    Set surf = surfFact.CreateSurf(pos)
    
    '形状セットに挿入
    Dim hBody As HybridBody: Set hBody = doc.Part.hybridBodies.Add()
    Call hBody.AppendHybridShape(surf)
    
    'インスタンス破棄 - 破棄することで内部の一時的なものを削除します。
    Set surfFact = Nothing
End Sub

複数面であれば、ary(ary(ary,・・・),・・・) な感じです。

Sub Example_Multi()
    'パートドキュメント
    Dim doc As PartDocument: Set doc = CATIA.Documents.Add("Part")
    
    '座標値郡
    Dim posary As Variant
    posary = Array( _
                Array(Array(0, 0, 0), Array(1, 0, 0), Array(0, 1, 0)), _
                Array(Array(0, 0, 0), Array(0, 1, 0), Array(-1, 1, 0)), _
                Array(Array(0, 0, 0), Array(-1, 0, 0), Array(0, -1, 0)), _
                Array(Array(0, 0, 0), Array(0, -1, 0), Array(1, -1, 0)))
    
    'SurfaceFactoryインスタンス
    Dim surfFact As SurfaceFactory: Set surfFact = New SurfaceFactory
    
    '面を作成するパートドキュメントをセット
    Call surfFact.SetPartDoc(doc)
    
    '座標値郡から面郡を作成 - 形状セットには入りません!
    '戻りは Collectiont
    Dim surfs As Collection
    Set surfs = surfFact.CreateSurfs(posary)
    
    '形状セットに挿入
    Dim hBody As HybridBody: Set hBody = doc.Part.hybridBodies.Add()
    Dim surf As HybridShapeSurfaceExplicit
    For Each surf In surfs
        Call hBody.AppendHybridShape(surf)
    Next
    
    'インスタンス破棄 - 破棄することで内部の一時的なものを削除します。
    Set surfFact = Nothing
    
End Sub

で、折れ線とフィルで作成可能な面が作れます。
その為、STLや3DDXF等のポリゴンっぽいものも、座標値配列にさえすれば
流用可能です。 恐らく使わないですが。