Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Strange behavior setting a solid body's attributes

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
perryK67ZX
156 Views, 4 Replies

Strange behavior setting a solid body's attributes

I'm new to the Fusion 360 API, and to Fusion 360 in general.

I'm writing an add-in that needs to persist some custom data associated with a selected body. From the docs, it seemed like my best bet was to set an attribute on the selected body. (Correct me if I'm off-base here!)

For testing purposes, I set the attribute as soon as the body is selected, unless it already exists. When I add this code, clicking a body with the command dialog open intermittently fails (the body clicked in the UI does not turn blue). When the selection fails to show in the UI, the code still runs to completion, but the previously-set attribute is not found.

Here is some code to reproduce the issue. This was modified from the template generated from "Scripts and Add-Ins" -> "Create".

# Function that is called when a user clicks the corresponding button in the UI.
# This defines the contents of the command dialog and connects to the command related events.
def command_created(args: adsk.core.CommandCreatedEventArgs):
    # General logging for debug.
    futil.log(f"{CMD_NAME} Command Created Event")

    # https://help.autodesk.com/view/fusion360/ENU/?contextId=CommandInputs
    inputs = args.command.commandInputs

    # TODO Define the dialog for your command by adding different inputs to the command.

    selector = inputs.addSelectionInput(
        "body_input", "Select Body", "Select a body to analyze"
    )
    selector.addSelectionFilter(
        "SolidBodies",
    )
    selector.setSelectionLimits(1, 1)  # Exactly one body should be selected.

    def on_change(args):
        if args.input.id != "body_input":
            futil.log("Wrong input")
            return

        if selector.selectionCount != 1:
            futil.log("wrong selection count")
            return

        selection = selector.selection(0).entity
        if selection.objectType != adsk.fusion.BRepBody.classType():
            futil.handle_error(
                f"Expected a BRepBody to be selected, got a {selection.objectType}."
                " This should never happen."
            )
            return

        body = adsk.fusion.BRepBody.cast(selector.selection(0).entity)

        if body is None:
            return

        futil.log(f"Selected Body: {body.name}")

        if body.attributes.itemByName("TestStuff", "my_test") is None:
            futil.log("no data :(")
            futil.log(f"Number of existing attributes: {body.attributes.count}")

            body.attributes.add("TestStuff", "my_test", "test")

            futil.log(f"Existing attributes now: {body.attributes.count}")
        else:
            a = body.attributes.itemByName("TestStuff", "my_test")
            futil.log("read from storage!")
            futil.log(f"Read value: {a.value}")

    futil.add_handler(
        args.command.inputChanged, on_change, local_handlers=local_handlers
    )

    # TODO Connect to the events that are needed by this command.
    # (...default handlers are unmodified from the template, omitted for conciseness)


Here is a recording of the behavior experienced when the above code is run. I try to click the body 3 times, but it only shows as highlighted in the UI the second time: https://www.loom.com/share/46148ea9530a4dc6a018ad1ffd45685f

This is the behavior if I comment out line 48: https://www.loom.com/share/e166adf415d344dfb63c06911b628437

One other wrinkle: From the log statements, it seems like elements are being selected twice, or at least the inputChanged event is firing twice, even when the attribute is not being modified. Is that expected? If so, why?



4 REPLIES 4
Message 2 of 5

Hi,

 

I believe your problem comes from the fact that changes to the model are commited only inside execute and executePreview events; but not inside inputChange event, which is the one you're using to set the attribute to the body.

I'd suggest to change the the on_change() event to be fired by the executePreview event instead of inputChanged event, and setting isValidResult property to True to indicate you want to commit the changes to the model.

 

You can learn more about the command events here: https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-3922697A-7BF1-4799-9A5B-C8539DF57051

 

Regards,

Jorge Jaramillo

Software Engineer

 

Message 3 of 5
perryK67ZX
in reply to: perryK67ZX

I see, thanks. I'd like to be able to save persistent data without having to close the dialog, but it seems like changes within executePreview are only committed when the command is executed. Is there a way to accomplish this? Are there any means of persisting data that don't involve setting attributes?

Message 4 of 5

Hi,

 

An option could be to use a custom event which can be triggered from the InputChangedEvent, and when executed could be used to persist the data inside some object's attributes (since it runs outside the events scope, the information is committed into the model).  It should be used to store or update the attributes, however you can read them from anywhere.

Since I don't know your final goal, it is hard to suggest you other options.

And I don't know options to store information inside the model other than attributes; outside the model, an external file, database, etc. could be an alternative.

 

Regards,

Jorge Jaramillo

Software Engineer

 

 

 

Message 5 of 5
perryK67ZX
in reply to: perryK67ZX

Noted, thank you!

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report