一応、こちらの続きです。
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クラスを引数渡しする場合が
多々あります。 それが不要になるのは、かなりうれしい。