I've never tried scripts with Fusion 360 and I currently have a need for something which I think should be pretty simple. I have two versions of a part and I have named parameter values setup where I can change about a dozen of them to make the other version of the part. I'd like to be able to switch back and forth between the two versions by running a script that just sets these dozen parameters. Can someone give me an idea on how to do this? Thanks.
Solved! Go to Solution.
Solved by ekinsb. Go to Solution.
It is fairly simple to edit the user parameters. Model parameters are also possible but a little more difficult because they can be scattered around in various components whereas there is only one set of user parameters for the entire design.
The program below changes two user parameters called "Length" and "Height" and depending on how you answer the message box will change them to one of two sets of values. You can change the names to whatever your parameters are called. Setting the expression property is exactly the same as changing it in the dialog and it supports all of the same things. For example you can specify the units as part of the string, i.e. "3 in" or "2 mm". Just "3" will default to 3 of whatever the current design unit is. You can also use equations and reference other parameters. For example, "(3 + Length)/2". If you use the "Scripts and Add-Ins" command to create a new script you can copy the code below and replace the run function in the created code. Then you can run it from the "Scripts and Add-Ins" command.
def run(context): ui = None try: app = adsk.core.Application.get() ui = app.userInterface des = adsk.fusion.Design.cast(app.activeProduct) userParams = des.userParameters if ui.messageBox('Change to configuration one?', 'Parameter Edit', adsk.core.MessageBoxButtonTypes.YesNoButtonType, adsk.core.MessageBoxIconTypes.QuestionIconType) == adsk.core.DialogResults.DialogYes: userParams.itemByName('Length').expression = '50' userParams.itemByName('Height').expression = '30' else: userParams.itemByName('Length').expression = '30' userParams.itemByName('Height').expression = '20' except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
I forgot about the Design.allParameters property. This returns all of the parameters in design, both Model and User parameters so using that makes it easy to use both.
That worked great. I have a follow up question: How can I hide and unhide a body.
is "body" in body.isVislble = True the name of the body? So if my body was named bolt1, I'd use: bolt1.isVisible = true. If so, how do I handle a body where theres a space in the name. Let's say my body is called "Front Bolt"
Actually it is a reference to the actual body object. So you would do something like:
# Get application reference
app = adsk.core.Application.get()
design = app.activeProduct
#Get Root Component
rootComp = design.rootComponent
# Get All bodies in Design
bRepBodies_var = rootComp.bRepBodies
# Find the body with a given Name
body = bRepBodies_var.itemByName('My body Name')
# Set visibility of the Body
body.isVisible = True
@prainsberry wrote:Actually it is a reference to the actual body object. So you would do something like:
# Get application reference
app = adsk.core.Application.get()
design = app.activeProduct
#Get Root Component
rootComp = design.rootComponent
# Get All bodies in Design
bRepBodies_var = rootComp.bRepBodies
# Find the body with a given Name
body = bRepBodies_var.itemByName('My body Name')
# Set visibility of the Body
body.isVisible = True
That didn't work for me; I'm getting the error: AttributeError: NoneType object has no attribute isVisible. It seems the itemByName() didn't work. Is there a way to list all the bodies it finds? Also, how can I test for NoneType so I know if it found the body or not.
You changed 'My Body Name" to the name of the body in the design, correct? Note it is case sensitive. The error means that it is not finding the body of that name.
You can check if an object is "None" in python with:
if body is None:
# OR:
if body is not None:
So it would look something like this:
# Get application reference
app = adsk.core.Application.get()
design = app.activeProduct
#Get Root Component
rootComp = design.rootComponent
# Get All bodies in Design
bRepBodies_var = rootComp.bRepBodies
# Find the body with a given Name
body = bRepBodies_var.itemByName('My body Name')
# Set visibility of the Body
if body is not None:
body.isVisible = True
Oh also if the bodies you are looking for are not in the root COmponent and are in a sub component then you would need to call the brep bodies on the component you are interested in not the root component? Maybe this is the problem?
Ok here this should work. Kind of long for what you are trying to do but it looks like there is not an itemByName method on components:
#Author- #Description- import adsk.core, adsk.fusion, traceback def run(context): ui = None try: # Get application reference app = adsk.core.Application.get() design = app.activeProduct # Get all components in design allComponents_var = design.allComponents # Loop through all components for component_var in allComponents_var: # Find the correct compoenent if component_var.name == "My Component": # Get All bodies in Component bRepBodies_var = component_var.bRepBodies # Find the body with a given Name body = bRepBodies_var.itemByName('My Body') # Set visibility of the Body if body is not None: body.isVisible = True except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
Like @prainsberry I use a set of params (actual number is 13) to configure different versions of my product.
PERFORMANCE PROBLEMS
When I manually change every single param in the dialog box, model computing automatically starts. This operation takes minutes. Since I have many parameters, when I need to switch from a version to another, I waste a lot of time in waiting for computing operations that are not useful, because they compute a partial configuration.
CAN SCRIPTING HELP ME?
Is it possible to make model computing start one time only, that is when I have finished to set up ALL my 13 params?
Unfortunately, Fusion doesn't support delaying the compute while you change multiple parameters, either in the UI or the API. I've been asking for it for years.
There is a workaround to that : move the timeline history marker backwards (up to root if needed), change your parameters, then move back the history marker at the end.
Can't find what you're looking for? Ask the community or share your knowledge.