C#ATIA

↑タイトル詐欺 主にCATIA V5 の VBA

ボディの外側をマクロで判断する

以前、3次元測定機の測定結果(CSV)をCATIAに取り込み、
実物とCADデータを差を調整しながらモデリングを行った事があったのですが、
大量の点をイチイチ測定する手間が非現実的なため、誤差を測定する為の
マクロを作成し作業をしたことが有ります。

単に 点 - ボディ 間の距離を測定するだけであれば、こちらの方法で
良いのですが、(リファレンスさえ取得できれば、何でも同じです)
ボディ - ボディ の最短距離の測定3 - C#ATIA

測定点がCADデータに比べ 小さいのか? 大きいのか?
を判断する方法が最初はわかりませんでした。

イロイロと試しているうちにわかったのですが、ボディとボディ内に
含まれている点の距離を測定した場合、
パートデザインフューチャー(パッド等)と点の距離を測定すると "0" となり
ボディの表面と点の距離を測定すれば、実際に離れている距離が
得られます。

f:id:kandennti:20170613150918p:plain

実際に、これをマクロ化することでOKでした。

'vba sample_IsInBox
'ボディ表面上は外側に判断

Option Explicit

Sub CATMain()

    '必要なもの
    Dim PDoc As PartDocument: Set PDoc = CATIA.ActiveDocument
    Dim Pt As Part: Set Pt = PDoc.Part
    Dim Fact As HybridShapeFactory: Set Fact = Pt.HybridShapeFactory
    
    '点
    Dim Pnt As HybridShapePointCoord
    Set Pnt = Pt.HybridBodies.Item(1).HybridShapes.Item(1)
    
    '点リファレンス
    Dim PntRef As Reference
    Set PntRef = Pt.CreateReferenceFromGeometry(Pnt)
    
    'パーツボディ
    Dim Bd As Body: Set Bd = Pt.MainBody
    
    'パーツボディの最後のパートデザインフューチャー
    Dim LastShape As Shape
    Set LastShape = Bd.Shapes.Item(Bd.Shapes.Count)
    
    'フューチャーのリファレンス
    Dim ShapeRef As Reference
    Set ShapeRef = Pt.CreateReferenceFromGeometry(LastShape)
    
    '抽出(サーフェス)したリファレンス
    Dim SurfRef As Reference
    Set SurfRef = CreateExtractRef(Pt, Fact, ShapeRef)
    
    '点とフューチャーの距離
    Dim ShapeLng As Double
    ShapeLng = GetMaximumLength(Pt, PntRef, ShapeRef)
    
    '点と抽出の距離
    Dim SurfLng As Double
    SurfLng = GetMaximumLength(Pt, PntRef, SurfRef)
    
    '判断
    Dim Msg As String
    Msg = Pnt.Name & "は、" & Bd.Name & "の" & _
          IIf(ShapeLng = SurfLng, "外", "内") & _
          "側にあります"
    MsgBox Msg
    
    Call Fact.DeleteObjectForDatum(SurfRef)
End Sub

'抽出
Private Function CreateExtractRef( _
                    ByVal Pt As Part, _
                    ByVal Fact As HybridShapeFactory, _
                    ByVal Ref As Reference) As Reference
    Dim HSExt As HybridShapeExtract
    Set HSExt = Fact.AddNewExtract(Ref)
    With HSExt
        .PropagationType = 3
        .ComplementaryExtract = False
        .IsFederated = False
        .Compute
    End With
    
    Set CreateExtractRef = Pt.CreateReferenceFromGeometry(HSExt)
End Function

'最短距離測定
Private Function GetMaximumLength(ByVal Pt As Part, _
                                  ByVal Ref1 As Reference, _
                                  ByVal Ref2 As Reference) As Double
    GetMaximumLength = Pt.Parent.GetWorkbench("SPAWorkbench") _
                         .GetMeasurable(Ref1) _
                         .GetMinimumDistance(Ref2)
End Function

表面のリファレンスを得る為に、"抽出" を利用しましたが、座標変換(同じ座標系)・
移動(移動量0)・回転・スケーリング・・・・何でも構わないと思います。

こんな感じで、原点を重心とした□100のボディと点が存在するデータを
想定しています。
f:id:kandennti:20170613150933p:plain

実行した感じはこちら。

これ自体は無意味ですが、判断は出来ています。


こちらのコメント部分に、チラッと書いたのですが、
UpdateとUpdateObject - C#ATIA
この方法を利用すれば、ボディに限りどちらが外側にオフセット
されるのかを判断する事が可能です。


余談ですが、3次元スキャナ等から得たデータとCADデータの差を見ることが
出来るフリーソフトはこちらで入手可能です。
GOM Inspect