This isn't really a bug persay but maybe a suggestion for improvement.
Say you want to create a User Parameter (x) that is a function of other user parameters say (y/100). The user parameter.add() method must contain a valueInput object. I found that I can not directly add my expression in the valueInput.createByString method. I have to add it in 3 steps:
userValue = self.core.ValueInput.createByString('1' + units)
up = self.design.userParameters.add('x',userValue,units,' ')
up._set_expression('y/100')
This could be improved by comparing the type of valueInput and handling it appropriately if it is a string. Either that or I don't understand how to set this correctly in a single call. In my opinion, the userParameters.add() method should not accept a valueInput object but be accepting a string as it is done in the Fusion 360 GUI. It is cumbersom to create a valueInput object in the first place when a string could easily do what you want.
Just my opinion
Solved! Go to Solution.
Solved by ekinsb. Go to Solution.
Thank you for your suggestions, it will really help us make the API better. We will have more detailed discussion internally and let you updated when we get some conclusions.
I agree that you should be able to define an expression when initially creating a parameter, but I am able to do that. Below is a simple function that tests this and works correctly for me. It assumes that there's already a parameter named "Test" and creates a new parameter named "NewTest" that has the value "5 + Test".
def createParam(): app = adsk.core.Application.get() design = app.activeProduct userValue = adsk.core.ValueInput.createByString('5 + Test') newParam = design.userParameters.add('NewTest', userValue, design.unitsManager.defaultLengthUnits, ' ') print(newParam.expression)
It results in this:
maybe it is due to my inclusion of units in the value string. Let me see if that changes anything.
That was it. I was taggin the units onto the expression before.
I would still think just passing a string into the add method would be easier since I am already passing the units to the method as well. It is less confusing and I don't see the benefit of having to create a valueInput instance first. Either way it is ok, just an extra line of code every time you want to make a user parameter. In my mind it follows the GUI more to just pass a string in like you would from the entry box, but that is just me.
I'm able to have a string that also contains units. Here's a test case that works. I suspect that in your case you might have had an invalid expression. Whatever you can type in interactively for the parameter expression should also work in the API.
import adsk.core, adsk.fusion, traceback def main(): ui = None try: app = adsk.core.Application.get() des = app.activeProduct userValue = adsk.core.ValueInput.createByString('5 cm + Test') newParam = des.userParameters.add('NewTest', userValue, des.unitsManager.defaultLengthUnits, ' ') print(newParam.expression) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) main()
The reason for having the ValueInput object is to be able to specify either a string or a value when creating a parameter. This is used when creating user parameters and also when creating other things that result in the creation of a model parameter, i.e. features, sketch dimension constraints, etc. In fact values are used more commonly than string expressions. For example, if you're creating an extrusion and have a fomula to calculate the extent the result of that calculation is typically a real value. You can use that value directly rather than have to build up a string from the number. This is one area where the API has more functionality than the UI. In the UI you always set a parameter value using a string. In the API you have a choice.
that makes sense and is useful.