C#ATIA

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

全ての面を取得する

細々とFusion360APIも挑戦しているのですが、
イマイチFusion360APIも理解できていない上に、Pythonも理解できていないです。

考えている処理で、全ての面を取得したいのですが出来るだけ
素早く取得したいです。 ドキュメントから辿って行く事になるのですが
結構深い位置にあります。大体こんな感じですね。

Application
 L Product
   L Component
     L bRepBody
          L bRepFace

リスト? コレクション? 類は省いているので、正しくは無いのですが…。
実際にはComponentやBodyが複数あるので、良くあるListのflattenに
近い感覚なのですが、ん~思うようには書けませんでした。


先日のPowerMill同様、5000枚程面のあるプロジェクトで幾つかの書き方で
速度を比較してみました。

import adsk.core, adsk.fusion, traceback

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        
        des = adsk.fusion.Design.cast(app.activeProduct)
        import time
        testtimes = []
        
        #test1
        faces = []
        s = time.time()
        for comp in des.allComponents:
            for bBody in comp.bRepBodies:
                for face in bBody.faces:
                    faces.append(face)
        t = time.time()
        testtimes.append('test1 : All Face Count {} : time {:.2f}s'.format(len(faces),t - s))
        
        #test2
        faces = []
        s = time.time()
        faces = [face
                    for comp in des.allComponents
                    for bBody in comp.bRepBodies
                    for face in bBody.faces]
        t = time.time()
        testtimes.append('test2 : All Face Count {} : time {:.2f}s'.format(len(faces),t - s))
        
        #test3
        faces = []
        from itertools import chain
        s = time.time()
        bBodies = [comp.bRepBodies for comp in des.allComponents]
        faceslst = [bBody.faces for bBody in list(chain.from_iterable(bBodies))]
        faces = list(chain.from_iterable(faceslst))
        t = time.time()
        testtimes.append('test3 : All Face Count {} : time {:.2f}s'.format(len(faces),t - s))
        
        #test4
        faces = []
        s = time.time()
        faces = list(chain.from_iterable(
                [bBody.faces for bBody in 
                list(chain.from_iterable(
                [comp.bRepBodies for comp in des.allComponents]))]))
        t = time.time()
        testtimes.append('test4 : All Face Count {} : time {:.2f}s'.format(len(faces),t - s))
        ui.messageBox('\n'.join(testtimes))
        
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

test1 : for を利用した無難な?書き方。
test2 : Pythonならではの内包表記。
test3 : イテレ-タと内包表記の組み合わせ。
test4 : test3をムリムリ一行に書いたもの。

結果はこんな感じなのですが、
f:id:kandennti:20180603005908p:plain
イマイチ結果が安定しないです。
test2~4のどれが一番速いのか? が良くわからないのですが
test1だけではなさそうです。