Fusion360 APIの部品カウントダイアログ

2021/10/10 categories:Fusion360| tags:Fusion360|Fusion360 API|Python|

Fusion360 APIでアセンブリ内に含まれる部品をカウントするプログラムを作成してみました。

カウントしたい部品名を入力

スクリプトを実行すると文字列入力のダイアログが表示されるので、カウントするコンポーネント名を入力します。ワイルドカードを使えるような処理にしているので、M3から始まるコンポーネントの数をカウントする場合はM3*と入力します。

コンポーネント名を再帰的に取得

全てのコンポーネント名を取得するために、ルートコンポーネントに含まれる子コンポーネントを再帰的に取得します。

children = self.get_children(design.rootComponent)

def get_children(self, component):
    components = []
    for occurrence in component.occurrences:
        child = occurrence.component
        components.append(child)
        child_components = self.get_children(child)
        components.extend(child_components)
    return components

コンポーネント名の比較

ダイアログに入力した*を正規表現の.*に置換して、その置換した文字列とコンポーネント名と正規表現で比較して、コンポーネントの数をカウントしています。

pattern = input_value.replace(r'*', r'.*')

count = 0
for child in children:
    if not re.fullmatch(pattern, child.name) is None:
        count += 1

実行結果

下記のようなアセンブリでM3と先頭一致するコンポーネント数は6個です。

ソースコード

import adsk.core, adsk.fusion, adsk.cam, traceback
import re

handlers = []
app = adsk.core.Application.get()
if app:
    ui = app.userInterface

class PartsCounterCommandExcuteHandler(adsk.core.CommandEventHandler):
    def notify(self, args):
        try:
            adsk.terminate()
            command = args.firingEvent.sender
            input_value = command.commandInputs[0].value
            pattern = input_value.replace(r'*', r'.*')

            product = app.activeProduct
            design = adsk.fusion.Design.cast(product)
            children = self.get_children(design.rootComponent)

            count = 0
            for child in children:
                if not re.fullmatch(pattern, child.name) is None:
                    count += 1
            
            ui.messageBox('{:s} found : {:d}'.format(input_value, count))
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
            
    def get_children(self, component):
        components = []
        for occurrence in component.occurrences:
            child = occurrence.component
            components.append(child)
            child_components = self.get_children(child)
            components.extend(child_components)
        return components

class PartsCounterCommandDestroyHandler(adsk.core.CommandEventHandler):
    def notify(self, args):
        try:
            adsk.terminate()
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

class PartsCounterCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def notify(self, args):
        try:
            cmd = args.command
            cmd.isRepeatable = False
            onExecute = PartsCounterCommandExcuteHandler()
            cmd.execute.add(onExecute)
            onDestroy = PartsCounterCommandDestroyHandler()
            cmd.destroy.add(onDestroy)
            
            handlers.append(onExecute)
            handlers.append(onDestroy)

            inputs = cmd.commandInputs
            inputs.addStringValueInput('Input string', 'Please input string', '')
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def run(context):
    try:
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        if not design:
            ui.messageBox('It is not supported in current workspace, please change to MODEL workspace and try again.')
            return
        commandDefinitions = ui.commandDefinitions
        
        cmdDef = commandDefinitions.itemById('Input string')
        if not cmdDef:
            cmdDef = commandDefinitions.addButtonDefinition('Input string', 'Input string', 'Parts count', './resources')

        onCommandCreated = PartsCounterCommandCreatedHandler()
        cmdDef.commandCreated.add(onCommandCreated)
        handlers.append(onCommandCreated)
        inputs = adsk.core.NamedValues.create()
        cmdDef.execute(inputs)

        adsk.autoTerminate(False)

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

Share post

Related Posts

コメント