Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:
  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

How to add an unlimited number of predecates

Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
I'm wanting to create a Multi-Variable feature that allows for several variable declarations at once. I'm trying to figure out the best way to structure the UI for that. Ideally, the user should be able to click a button to add another variable, or (less preferably) to be able to use a count parameter at the top to say how many there should be. Here's what I've got so far, but the code seems clumsy. I'm just nesting if statements for each additional variable input, so there's a limit on how many variables someone could declare. Who knows, maybe I could just limit it to 5 and that's a good thing so the dialog window doesn't go off-screen. Thoughts?

Evan Reese / Principal and Industrial Designer with Ovyl
Website: ovyl.io

Best Answer

Answers

  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 5,308
    Have you tried array parameters? That is the mechanism used in Loft and Fill to add multiple inputs.
    Senior Director, Technical Services, EMEAI
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    the execution above is also not great because if I uncheck boolean 1, then everything after it disappears. So anyway, it's got some issues, and I'm trying to figure out how clean this could be 
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    NeilCooke said:
    Have you tried array parameters? That is the mechanism used in Loft and Fill to add multiple inputs.
    I looked into it a bit but wasn't sure it would work for me since I'm still not sure how I'd add a parameter. With Fill, each edge query opens up a parameter in the array with selections for continuity. With mine, I don't know how to tell Featurescript to add another parameter, since I'm not selecting anything in the model. Could I control that some other way? if so, you're right, Array Parameter is what I need.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 5,308
    You should probably ignore me - array parameters have limited logic capability so it may be difficult to get the full variable functionality you need.
    Senior Director, Technical Services, EMEAI
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    @NeilCooke haha I appreciate the input.
    @kevin_o_toole_1 That seems like exactly what I'm looking for. I'm out of time to test it right now, but I'll report back once I do.

    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • kevin_o_toole_1kevin_o_toole_1 Onshape Employees, Developers, HDM Posts: 565
    Unfortunately Neil rightly points out that your feature with array parameters will unfortunately run into a limitation of array parameters that parameter visibility can depend on the primary map "definition" (like if (definition.type == Type.A)) but can't depend on individual array items (like if (profile.type == Type.A)).

    You can vote on the improvement request to support the latter here: https://forum.onshape.com/discussion/7628/conditional-visibility-of-array-parameters/p1
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    So that might prevent me from having different enums for variable type? I feel that's not ideal, but also not a killer. I can always just manually add the units to the variable itself and achieve the same thing, right? so instead of selecting "angle" and typing "50", can't I just type "50 deg" and get the same result? It would be good enough.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • kevin_o_toole_1kevin_o_toole_1 Onshape Employees, Developers, HDM Posts: 565
    Correct. You could also have a single "Length/Angle/Number/Any" control outside the array which controls all items... but now that I think about it I like your solution better.
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,173
    The reason we added Length/Angle/Number/Any to variables was primarily to get automatic units completion since like 90% of variables users want are lengths.  If you don't need it, it's good enough.
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    hey, thanks for the input everyone! I got it working pretty much as expected. Its a nice balance between making a ton of individual variable features, and actually writing them into a custom feature that I put at the top. I think it's approachable for most users too... now, why is my code so much shorter than the actual Variable feature? Is there some crucial safeguard there that I should add here?
    Here's the link.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    one more thing I think is important with this feature is the ability to reference previous variables in the same feature. I want to be able to use it as a container for similar variables, so I'd use a new Multi-Variable feature for "Size Variables", "Wall Thicknesses", and "Draft Angles" and many of them should be reference other variables in the array like #nominal = 2.5mm and #rib = #nominal*.6

    I expected this to work as long as #nominal is declared before #rib, since the for loop is iterating through, and by the time it's on the second iteration #nominal has already been declared. It doesn't seem to work that way, which limits the usefulness of the feature, at least for the way I work. Any pointers on how to get this working? Can it even be done?
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    The reason we added Length/Angle/Number/Any to variables was primarily to get automatic units completion since like 90% of variables users want are lengths.  If you don't need it, it's good enough.
    Makes sense. The default to length reduces user error.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 2,034 EDU
    one more thing I think is important with this feature is the ability to reference previous variables in the same feature. I want to be able to use it as a container for similar variables, so I'd use a new Multi-Variable feature for "Size Variables", "Wall Thicknesses", and "Draft Angles" and many of them should be reference other variables in the array like #nominal = 2.5mm and #rib = #nominal*.6

    I expected this to work as long as #nominal is declared before #rib, since the for loop is iterating through, and by the time it's on the second iteration #nominal has already been declared. It doesn't seem to work that way, which limits the usefulness of the feature, at least for the way I work. Any pointers on how to get this working? Can it even be done?
    @Evan_Reese
    It most likely will not be able to be done because Onshape actually works out the values before the feature even starts, so that is why you cannot reference a variable created in the feature. :(
    mb - draftsman - also FS author: View FeatureScripts
    IR for AS/NZS 1100
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    edited December 2019
    one more thing I think is important with this feature is the ability to reference previous variables in the same feature. I want to be able to use it as a container for similar variables, so I'd use a new Multi-Variable feature for "Size Variables", "Wall Thicknesses", and "Draft Angles" and many of them should be reference other variables in the array like #nominal = 2.5mm and #rib = #nominal*.6

    I expected this to work as long as #nominal is declared before #rib, since the for loop is iterating through, and by the time it's on the second iteration #nominal has already been declared. It doesn't seem to work that way, which limits the usefulness of the feature, at least for the way I work. Any pointers on how to get this working? Can it even be done?
    @Evan_Reese
    It most likely will not be able to be done because Onshape actually works out the values before the feature even starts, so that is why you cannot reference a variable created in the feature. :(
    aw man! Couldn't you lie to me or something?

    I think I see what you're saying. It loops through the whole predicate before it even starts executing the feature, so there's no way the values computed by the feature can feed back into the predicate. If they could, I could write recursive nonsense. Something like that?

    Before I give up on it completely, does anyone else have any tricks for something like this? I wonder if there might be a way to parse the values in the execution part of the code. I know getVariable() can reference an existing variable within one feature. I've started a new thread here since this seemed like a new topic.

    All I really want for Chirstmas is:
    1. make a feature to declare multiple variables at once
    2. let them reference each other
    3. not write a custom featurescript every time I want a bunch of variables. I want it to be accessible to users of all skill levels.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 2,034 EDU
    mb - draftsman - also FS author: View FeatureScripts
    IR for AS/NZS 1100
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    @MBartlett21
    not sure what I'm looking at here, but it seems like you're showing it working. If I enter the same values I'm getting an error. Care to expound a bit?
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 2,034 EDU
    edited December 2019
    @Evan_Reese
    How about this:

    mb - draftsman - also FS author: View FeatureScripts
    IR for AS/NZS 1100
  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 2,034 EDU
    edited December 2019
    @Evan_Reese

    Here is the link: :)
    http://onsha.pe/documents/da7abfbf7607534743ef3e77


    Here is what I am doing:

    In the UI, the value parameters are strings, rather than using isAnything.
    The FeatureScript then passes those values to a little library that I made, which evaluates the value of the string, checking if it needs to use another variable and calculating the other variable if so (Circular references are also checked).
    Those values are then set for each variable and populated into the Variable summary notification
    mb - draftsman - also FS author: View FeatureScripts
    IR for AS/NZS 1100
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    @MBartlett21

    I'm so far from being able to write something like that. I'll dig into how you did it after hours sometimes and I'm sure I'll learn a lot. Thank you for taking the time. I'll probably be back with questions once I've sat with it a while.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 2,034 EDU
    @Evan_Reese
    Here is the library that I am using:
    http://onsha.pe/documents/429fd7dda5f0fdb93833a34a

    It exports a function called evalExpression that takes a string and a map of variables.
    This function first splits the text into tokens. e.g: "5 + 5" => [5, "+", 5]
    It then checks for any variables that it needs that have not been calculated. If there is any needed variables, it returns an array of variable names that it needs.
    After this, it converts the tokens to Reverse Polish Notation (RPN). e.g: [5, "+", 5] => [5, 5, "+"]
    After it has been converted to RPN, it then evaluates the RPN and returns the end value.
    mb - draftsman - also FS author: View FeatureScripts
    IR for AS/NZS 1100
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,173
    @MBartlett21
    Nice!
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 2,034 EDU
    @ilya_baran
    Would there be any way to get autocomplete for the functions and variables to work with this, or would it have to be supported internally?
    mb - draftsman - also FS author: View FeatureScripts
    IR for AS/NZS 1100
  • john_mcclaryjohn_mcclary Member, Developers Posts: 3,890 PRO
    That's why I love Morgan. He doesn't believe in 'good enough' :)
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,173
    Sorry, we'd have to support autocomplete.  BTW, we are (also) planning to do multiple variables more easily at some point, probably via a table :)
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • john_mcclaryjohn_mcclary Member, Developers Posts: 3,890 PRO
    :D
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    Sorry, we'd have to support autocomplete.  BTW, we are (also) planning to do multiple variables more easily at some point, probably via a table :)
    I've been waiting my whole life for this.

    Hopefully, they could be set up as globals for the whole doc, and maybe even linked between documents the same way parts are.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • Evan_ReeseEvan_Reese Member Posts: 2,060 PRO
    @MBartlett21 thanks for the breakdown of the library and how you're doing it! I'll study it when I have time.

    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
Sign In or Register to comment.