C#ATIA

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

押し出しのスピードテスト1

タイトルが異なりますが、こちらの続きです。
スケッチのスピードテスト - C#ATIA

前回のスケッチに関しては、ある程度知っていたので、
本当はこちらの "押し出し" についてテストしたかったんです。

前回同様、スケッチに100個の四角を作り押し出します。
テスト内容は、作成方法を変更し各5回です。
f:id:kandennti:20180928111935p:plain

ベースにするコードはこちら。

#FusionAPI_python 押し出しの速度テスト
#Author-kantoku

import adsk.core, adsk.fusion, traceback
import time, inspect, itertools
        
DEBUG = False
def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        
        unit_size = 2.0
        lst = [((v*3, 0.0, 0.0),(unit_size+v*3, unit_size, 0.0)) for v in range(100)]
        
        #test
        for i in range(5):
            doc = NewDoc(app)
            root = app.activeProduct.rootComponent
            
            t = time.time()
            
            funcname = test1(root,lst,unit_size)#ここ書き換え
            
            msg='{}-time:{:.2f}s'.format(funcname,time.time()- t)
            print(msg)
            
            if not DEBUG:
                doc.close(False)
                
        if DEBUG:
            ui.messageBox(msg)
        
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def NewDoc(app):
    return app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)

def initBox(skt,ary1,ary2):
    lines = skt.sketchCurves.sketchLines
    p1 = adsk.core.Point3D.create(ary1[0],ary1[1],ary1[2])
    p2 = adsk.core.Point3D.create(ary2[0],ary2[1],ary2[2])
    box = lines.addTwoPointRectangle(p1,p2)
    return box

def lst2objs(lst):
    objs = adsk.core.ObjectCollection.create()
    [objs.add(obj) for obj in lst]    
    return objs

def QuickOn(skt):
    skt.isComputeDeferred = True
    skt.areProfilesShown = False
    skt.areDimensionsShown = False

def QuickOff(skt):    
    skt.areDimensionsShown = True
    skt.areProfilesShown = True
    skt.isComputeDeferred = False

QuickOn・QuickOffについては前回のテストからの産物です。

"押し出し" は、プロファイルかボディやパッチの平坦な面を元に
高さを付けてボディ化します。
前回のテストでプロファイルを非表示化することで処理時間を
短縮する効果が有ることがわかったのですが、テストを行っている
うちに、押し出しを行う為のプロファイルを選択するタイミングでは
プロファイルが表示されている必要が有ることがわかりました。
(非表示のままではボディが作成されません)


○テスト1
オーソドックスに、四角1個に対しスケッチを作成→押し出しです。

#test1 1個毎に スケッチ-押し出し
def test1(comp,pnts,height):
    
    exts = comp.features.extrudeFeatures
    joinBody =  adsk.fusion.FeatureOperations.JoinFeatureOperation
    h = adsk.core.ValueInput.createByReal(height)
    
    for (a1,a2) in pnts:
        #sketch
        skt = comp.sketches.add(comp.xYConstructionPlane)
        QuickOn(skt)
        initBox(skt,a1,a2)
        QuickOff(skt)
        
        #extrude
        exts.addSimple(skt.profiles[0], h, joinBody)
        
    return inspect.getframeinfo(inspect.currentframe())[2]

比較すべきものが無いのでこれが基準です。

test1-time:7.68s
test1-time:7.60s
test1-time:7.61s
test1-time:7.71s
test1-time:7.73s


○テスト2
1個のスケッチに全ての四角を作成し、プロファイル毎に押し出しです。

#test2 まとめてスケッチしプロファイル毎に押し出し
def test2(comp,pnts,height):
    #sketch
    skt = comp.sketches.add(comp.xYConstructionPlane)
    QuickOn(skt)
    [initBox(skt,a1,a2) for (a1,a2) in pnts]
    QuickOff(skt)
    
    #enums
    joinBody =  adsk.fusion.FeatureOperations.JoinFeatureOperation
    
    #extrude
    h = adsk.core.ValueInput.createByReal(height)
    exts = comp.features.extrudeFeatures
    
    [exts.addSimple(prof, h, joinBody) for prof in skt.profiles]
    
    return inspect.getframeinfo(inspect.currentframe())[2]

半分程の処理時間となります。スケッチを作成数が少ない分効果が大きいです。

test2-time:3.30s
test2-time:3.28s
test2-time:3.28s
test2-time:3.27s
test2-time:3.28s


○テスト3
1個のスケッチに全ての四角を作成し、全てのプロファイルを一度に押し出しです。

#test3 まとめてスケッチし、まとめて押し出し
def test3(comp,pnts,height):
    #sketch
    skt = comp.sketches.add(comp.xYConstructionPlane)
    QuickOn(skt)
    [initBox(skt,a1,a2) for (a1,a2) in pnts]
    QuickOff(skt)
    
    #enums
    joinBody =  adsk.fusion.FeatureOperations.JoinFeatureOperation
    
    #extrude
    h = adsk.core.ValueInput.createByReal(height)
    profs = lst2objs(skt.profiles)
    exts = comp.features.extrudeFeatures
    
    exts.addSimple(profs, h, joinBody)
    
    return inspect.getframeinfo(inspect.currentframe())[2]

現状知っている方法の中では最速だと思っています。
但し問題も抱えています。

test3-time:1.11s
test3-time:1.14s
test3-time:1.10s
test3-time:1.09s
test3-time:1.10s


○テスト4
四角1個に対しスケッチを作成しプロファイルをストック。
押し出しは1度に行います。

#test4 1個毎にスケッチを作りプロファイルをストック、まとめて押し出し
def test4(comp,pnts,height):
    #sketch
    objs = adsk.core.ObjectCollection.create()
    
    for (a1,a2) in pnts:
        skt = comp.sketches.add(comp.xYConstructionPlane)
        QuickOn(skt)
        initBox(skt,a1,a2)
        skt.areProfilesShown = True
        [objs.add(prof) for prof in skt.profiles]
        QuickOn(skt)
    
    #extrude
    exts = comp.features.extrudeFeatures
    joinBody =  adsk.fusion.FeatureOperations.JoinFeatureOperation
    h = adsk.core.ValueInput.createByReal(height)    
    
    exts.addSimple(objs, h, joinBody)
        
    return inspect.getframeinfo(inspect.currentframe())[2]

自分の中では、テスト3の問題を解決する為には現状これしか
思いつかないなぁと言う方法です。スケッチを多く作成している為
処理時間が劣っています。

test4-time:2.76s
test4-time:2.74s
test4-time:2.74s
test4-time:2.72s
test4-time:2.75s


○テスト5
基本的にはテスト4と同様の考え方で、処理の手順を少し変えました。

#test5 1個毎にスケッチを作りプロファイルをストック、まとめて押し出し
def test5(comp,pnts,height):
    #sketch
    skts = comp.sketches
    xy = comp.xYConstructionPlane
    
    skts = [skts.add(xy) for _ in pnts]
    [QuickOn(skt) for skt in skts]
    [initBox(skt,a1,a2) for ((a1,a2),skt) in zip(pnts,skts)]
    [QuickOff(skt) for skt in skts]
    
    objs = adsk.core.ObjectCollection.create()
    profs = [skt.profiles for skt in skts]
    [objs.add(prof) for prof in list(itertools.chain.from_iterable(profs))]
    [QuickOn(skt) for skt in skts]
    
    #extrude
    exts = comp.features.extrudeFeatures
    joinBody = adsk.fusion.FeatureOperations.JoinFeatureOperation
    h = adsk.core.ValueInput.createByReal(height)    
    
    exts.addSimple(objs, h, joinBody)
        
    return inspect.getframeinfo(inspect.currentframe())[2]

若干遅くなってしまいました。

test5-time:3.01s
test5-time:2.95s
test5-time:2.95s
test5-time:2.95s
test5-time:2.97s