Change property on an external component and save it

Change property on an external component and save it

francois_riot7TBHB
Explorer Explorer
270 Views
1 Reply
Message 1 of 2

Change property on an external component and save it

francois_riot7TBHB
Explorer
Explorer

Hello,

I am trying to write a script that allow me to change the custom property of a component and save the modification, base on my selection with

 

app = adsk.core.Application.get()
        ui = app.userInterface

        # Retrieve the current selection
        selection = ui.activeSelections

 

 

The selection and property edition is working on both internal or external component.

 

The issue is to save.

I'am using

 

  doc = selected_comp.parentDesign.parentDocument

 

 to save the external document but it is not working. When i try to save an external component, is saving only the root document and the internal component, but not the external component.

I need to open it, change the property and save it to savec the modification.

Is there a way to save an external component whithin another component/assembly?

 

Here is my complete script :

 

mport adsk.core, adsk.fusion, adsk.cam, traceback

statut_options = {
    'Custom': 'Custom',
    'Standard': 'Standard'
}

def create_command_inputs(inputs, selected_comp):
    app = adsk.core.Application.get()
    design = app.activeProduct

    # Retrieve the current property if it exists
    current_property_statut = None
    if selected_comp:
        attribs = selected_comp.attributes
        current_property_statut = attribs.itemByName('CustomProperties', 'Statut')

    # Add dropdown for status
    dropdown_label_statut = 'Choose a status' if not current_property_statut else f'Current status: {current_property_statut.value}'
    dropdown_statut = inputs.addDropDownCommandInput('propertyDropdownStatut', dropdown_label_statut, adsk.core.DropDownStyles.TextListDropDownStyle)
    for word in statut_options.keys():
        dropdown_statut.listItems.add(word, word == 'custom', '')

    if current_property_statut:
        for item in dropdown_statut.listItems:
            if item.name == current_property_statut.value:
                item.isSelected = True
                break

def update_component_properties(component, selected_statut_value):
    attribs = component.attributes
    if selected_statut_value is not None:
        attribs.add('CustomProperties', 'Statut', selected_statut_value)

def on_execute(event_args, selected_comp):
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        design = app.activeProduct

        if not isinstance(design, adsk.fusion.Design):
            ui.messageBox('This script only works with an active Fusion Design file.')
            return

        inputs = event_args.command.commandInputs
        dropdown_statut = inputs.itemById('propertyDropdownStatut')

        selected_statut_value = None

        if dropdown_statut.selectedItem:
            selected_statut = dropdown_statut.selectedItem.name
            selected_statut_value = statut_options[selected_statut]

        # Update the selected component properties
        if selected_comp:
            update_component_properties(selected_comp, selected_statut_value)
            ui.messageBox(f'Properties updated for the selected component.')

            # Save the selected component
            doc = selected_comp.parentDesign.parentDocument
            if doc:
                if not doc.isSaved:
                    doc.saveAs(doc.name, doc.parentFolder, "Properties updated", "Automatic")
                else:
                    doc.save("Properties updated")
        else:
            ui.messageBox('No selected component found.')

        # Terminate the command after execution
        adsk.terminate()

    except Exception as e:
        app = adsk.core.Application.get()
        ui = app.userInterface
        ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def on_create(event_args):
    app = adsk.core.Application.get()
    ui = app.userInterface

    # Retrieve the current selection
    selection = ui.activeSelections
    if selection.count == 0:
        # If no selection, use the active component
        selected_comp = app.activeProduct.rootComponent
    else:
        selected_entity = selection.item(0).entity
        if not isinstance(selected_entity, adsk.fusion.Occurrence):
            ui.messageBox('The selection is not a valid component or sub-component.')
            return
        selected_comp = selected_entity.component

    inputs = event_args.command.commandInputs
    create_command_inputs(inputs, selected_comp)

def on_cancel(event_args):
    adsk.terminate()

def run(context):
    app = adsk.core.Application.get()
    ui = app.userInterface

    try:
        # Create a user command
        cmd_def = ui.commandDefinitions.addButtonDefinition('AddPropertyCommand', 'Add a property', 'Adds a custom property to the activated component.', '')

        # Connect events
        on_create_handler = CommandCreatedHandler()
        cmd_def.commandCreated.add(on_create_handler)
        handlers.append(on_create_handler)

        # Execute the command
        cmd_def.execute()

        # Ensure Fusion 360 keeps the script in memory
        adsk.autoTerminate(False)

    except Exception as e:
        if ui:
            ui.messageBox(f'Error: {str(e)}')

handlers = []

class CommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args):
        on_create(args)
        command = args.command

        # Connect the command execution event
        on_execute_handler = CommandExecuteHandler()
        command.execute.add(on_execute_handler)
        handlers.append(on_execute_handler)

        # Connect the command cancellation event
        on_cancel_handler = CommandCancelledHandler()
        command.destroy.add(on_cancel_handler)
        handlers.append(on_cancel_handler)

class CommandExecuteHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args):
        app = adsk.core.Application.get()
        ui = app.userInterface

        # Retrieve the current selection
        selection = ui.activeSelections
        if selection.count == 0:
            # If no selection, use the active component
            selected_comp = app.activeProduct.rootComponent
        else:
            selected_entity = selection.item(0).entity
            if not isinstance(selected_entity, adsk.fusion.Occurrence):
                ui.messageBox('The selection is not a valid component or sub-component.')
                return
            selected_comp = selected_entity.component

        on_execute(args, selected_comp)

class CommandCancelledHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args):
        on_cancel(args)

def stop(context):
    app = adsk.core.Application.get()
    ui = app.userInterface

    try:
        # Delete the command if it exists
        cmd_def = ui.commandDefinitions.itemById('AddPropertyCommand')
        if cmd_def:
            cmd_def.deleteMe()

        adsk.autoTerminate(True)

    except Exception as e:
        if ui:
            ui.messageBox(f'Error during stop: {str(e)}')

 

 EDIT : i have managed to do the trick by open the "external" component and apply changement, save the component and close it. The changement of attributs are saved this way.

0 Likes
271 Views
1 Reply
Reply (1)
Message 2 of 2

BrianEkins
Mentor
Mentor

Unfortunately, I don't believe this is currently possible. You can do this in the UI by using "Edit in Place" to edit the referenced component. The API doesn't currently support the equivalent of "Edit in Place".

 

At first, I thought you could do this by opening the referenced file on its own, editing the property, saving, and closing the file. That still might work, but it gets a bit weird because by doing that, you're creating a new version of the file, and the file you started with will reference the old version.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
0 Likes