C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

スピードテスト5

一応、こちらの続きです。
http://kantoku.hatenablog.com/entry/2015/04/15/195513

前回のコメントで、"HybridShapeクラスのComputeメソッドでもアップデート出来るよ" と
imihitoさんに教えていただき、少し速くなりそうな気がしたので、
こちらのコードを元に試してみました。
http://kantoku.hatenablog.com/entry/2015/04/11/172004

元のコードが32bitだった為、テストが手軽に行えるようにしつつ
64bit用に修正しました。

'VBA Speed_Test using-'ver0.0.10'
Option Explicit

Private Const Max = 500         '点の生成数
Private Const TestCount = 5&    'テスト回数

Sub CATMain()
    Debug.Print "*** start ***"
    
    Dim i&, PDoc As PartDocument
    For i = 1 To TestCount
        Set PDoc = CATIA.Documents.Add("Part")
        
        KCL.SW_Start
        Call SubCreateDatumPoint
        Debug.Print KCL.SW_GetTime & "秒"
        
        Call PDoc.Close
    Next
End Sub

Private Sub SubCreateDatumPoint()
    Dim oPart As MECMOD.Part
    Dim oHybShpFact As HybridShapeTypeLib.HybridShapeFactory
    Dim oHybBdy As MECMOD.HybridBody
    Dim oHybShpPt 'As HybridShapeTypeLib.HybridShapePointCoord
    Dim oHybShpPtExp As HybridShapeTypeLib.HybridShapePointExplicit
    Dim i As Integer
    Dim oPt As Variant
    Dim colMyObj1 As Collection
    Dim oMyobj As Object
    
    Set oPart = CATIA.ActiveDocument.Part
    Set oHybShpFact = oPart.HybridShapeFactory

    Set colMyObj1 = New Collection

'------------ Add Body ------------------------------
    Set oHybBdy = oPart.HybridBodies.Add()

'------------ Create RefPoint ------------------------------
    oPt = Array(0, 0, 0)
    Set oHybShpPt = oHybShpFact.AddNewPointCoord(oPt(0), oPt(1), oPt(2))
    Call oHybBdy.AppendHybridShape(oHybShpPt)
    Call oPart.UpdateObject(oHybShpPt)

'------------ Create DetumPoints ------------------------------
    For i = 1 To 500
        oPt(0) = oPt(0) + 10
        Call oHybShpPt.SetCoordinates(oPt)
        Call oPart.UpdateObject(oHybShpPt)
        Set oHybShpPtExp = oHybShpFact.AddNewPointDatum(oHybShpPt)
        Call colMyObj1.Add(oHybShpPtExp)
    Next
'------------ Append DetumPoints ------------------------------
    With oHybBdy
        For Each oMyobj In colMyObj1
            Call .AppendHybridShape(oMyobj)
        Next
    End With
    Call oHybShpFact.DeleteObjectForDatum(oHybShpPt)    'Delete RefPoint
    Call oPart.Update
    
    Set colMyObj1 = Nothing
End Sub

SubCreateDatumPoint関数は前回のままで、KCLは単に時間の測定に利用している
だけです。 結果はこちら。

*** start ***
1.191秒
1.195秒
1.195秒
1.195秒
1.193秒

32bit当時は、1.6~1.7秒程だったので64bitの恩恵を受けているようです。

見直したところ、SubCreateDatumPoint関数をこんな感じに修正すると
更に時間が短縮できそうだとわかりました。

Private Sub SubCreateDatumPoint()
    Dim Pt As Part: Set Pt = CATIA.ActiveDocument.Part
    Dim Fact As HybridShapeFactory: Set Fact = Pt.HybridShapeFactory

'------------ Add Body ------------------------------
    Dim HBdy As HybridBody: Set HBdy = Pt.HybridBodies.Add()

'------------ Create RefPoint ------------------------------
    Dim Pos As Variant: Pos = Array(0#, 0#, 0#)
    Dim Pnt As Variant: Set Pnt = Fact.AddNewPointCoord(Pos(0), Pos(1), Pos(2))

'------------ Create DetumPoints ------------------------------
    Dim Ary() As HybridShapePointExplicit: ReDim Ary(Max) As HybridShapePointExplicit
    Dim i As Long
    
    For i = 1 To Max
        Pos(0) = Pos(0) + 10#
        Call Pnt.SetCoordinates(Pos)
        Call Pt.UpdateObject(Pnt)
        Set Ary(i) = Fact.AddNewPointDatum(Pnt)
    Next
    
'------------ Append DetumPoints ------------------------------
    For i = 1 To Max
        Call HBdy.AppendHybridShape(Ary(i))
    Next
    Call Fact.DeleteObjectForDatum(Pnt)
    Call Pt.UpdateObject(HBdy)
End Sub

変数名等も修正してしまいましたが、主に
・最初のRefPoint作成時、更新しない
・コレクション → 配列化
・Partファイルのアップデート → 形状セットのアップデート
です。 結果はこち

*** start ***
1.02秒
1.021秒
1.015秒
1.01秒
1.014秒

"キー付きコレクション" も試しましたが、配列の方が少しだけ速い気がしました。
0.1秒強の短縮ですが、一番効果を感じたのは、
"Partファイルのアップデート → 形状セットのアップデート"
でした。


ここで本題の "Computeメソッド" です。利用出来そうなのが
RefPointの座標値書き換え後のアップデート時のみです。

 ・・・
'------------ Create DetumPoints ------------------------------
    Dim Ary() As HybridShapePointExplicit: ReDim Ary(Max) As HybridShapePointExplicit
    Dim i As Long
    
    For i = 1 To Max
        Pos(0) = Pos(0) + 10#
        Call Pnt.SetCoordinates(Pos)
        Call Pnt.Compute 'ここだけ書き換え
        Set Ary(i) = Fact.AddNewPointDatum(Pnt)
    Next
 ・・・

結果はこちら。

*** start ***
1.017秒
1.024秒
1.018秒
1.019秒
1.016秒

処理量が少ないので、誤差レベルの違いしか感じません・・・。


個人的には点・線・面等を作成する関数化させるのですが、
アップデートしたい為だけに、Partクラスを引数渡しする場合が
多々あります。 それが不要になるのは、かなりうれしい。