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.

Risks of using Number instead of Length for Variables?

EvanReeseEvanReese Member, Mentor Posts: 2,141 ✭✭✭✭✭
It's easy to define all variables as just a number, and let Onshape autocomplete the units later by adding the millimeters or degrees. What are the risks associated with working this way? if there are none, why does the variable feature even have options for them?
Evan Reese

Comments

  • korikori Onshape Employees Posts: 25
    The risk is that if you change your workspace units, and then use that variable again, you will end up with a different length value than you had originally.  Providing units gives you more control over the design intent that your variable represents.
  • EvanReeseEvanReese Member, Mentor Posts: 2,141 ✭✭✭✭✭
    makes sense. Anything else anyone can think of? I'm considering taking the csv Variables feature @john_mcclary made and adding the ability to have a column for units as well, but it's more complex to do than I originally guessed. If that's the only downside to not assigning units with variables then it's probably not worth the effort.
    Evan Reese
  • john_mcclaryjohn_mcclary Member, Developers Posts: 3,936 PRO
    if you create a function that converts text into units, then you can simply add a multiplier to that function in the for-loop

    CSV: some variables will have units, others will not


    Create an if statement for each unit you want to parse
    </code>function units(unitName)
        {
            if (unitName  == "mm")
            {
                return millimeter;
            }
            else if (unitName == "in")
            {
                return inch;
            }
            else if (unitName == "deg")
            {
                return degree;
            }
            
            return 1;
        }
    </pre><div>return 1 will default to unitless<br><br>now add&nbsp;<br><pre class="CodeBlock"><code> * units(file[i][2]
    inside the for loop
    export const CSV_Vars = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            annotation { "Name" : "CSV file" }
            definition.myCsvFile is TableData;        
        }
        {
            var file = definition.myCsvFile.csvData;
            var v = {};
                
            for (var i = 0; i < size(file); i += 1)
            {
                v[file[i][0]] = file[i][1];
                setVariable(context, file[i][0], file[i][1] * units(file[i][2]));
            }
            
        });

    https://cad.onshape.com/documents/75dfbb9091b5bea038398789/w/20b6cc9fc5923631d05184a8/e/97a921379d1437bdaef7fcdf
  • EvanReeseEvanReese Member, Mentor Posts: 2,141 ✭✭✭✭✭
    edited June 2020
    if you create a function that converts text into units, then you can simply add a multiplier to that function in the for-loop

    CSV: some variables will have units, others will not


    Create an if statement for each unit you want to parse
    </code>function units(unitName)
        {
            if (unitName  == "mm")
            {
                return millimeter;
            }
            else if (unitName == "in")
            {
                return inch;
            }
            else if (unitName == "deg")
            {
                return degree;
            }
            
            return 1;
        }
    </pre><div>return 1 will default to unitless<br><br>now add&nbsp;<br><pre class="CodeBlock"><code> * units(file[i][2]
    inside the for loop
    export const CSV_Vars = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            annotation { "Name" : "CSV file" }
            definition.myCsvFile is TableData;        
        }
        {
            var file = definition.myCsvFile.csvData;
            var v = {};
                
            for (var i = 0; i < size(file); i += 1)
            {
                v[file[i][0]] = file[i][1];
                setVariable(context, file[i][0], file[i][1] * units(file[i][2]));
            }
            
        });

    https://cad.onshape.com/documents/75dfbb9091b5bea038398789/w/20b6cc9fc5923631d05184a8/e/97a921379d1437bdaef7fcdf
    dang! I was close. I tried doing pretty much the same thing, but with a map instead of the function. for my own education, any idea why I couldn't get a map to work but this does?

    for example, I tried just this before even trying the for loop:
    var unitMap = {"inch":inch};
    var unit = unitMap.file[1][2];
    
    I also tried "*inch*" in case it needed a substring (not sure if that's how it works at all, haha)
    Evan Reese
  • john_mcclaryjohn_mcclary Member, Developers Posts: 3,936 PRO
    edited June 2020
    It looks like it was not liking the dot notation, use [ * ]  instead and it works

    Also i noticed you had the number 1 in  file[1][2]   that was the letter i to iterate between each row
    FeatureScript 1271;
    import(path : "onshape/std/geometry.fs", version : "1271.0");
    
    export const units = {
     "in" : inch,
     "mm" : millimeter,
     "deg" : degree,
     "" : 1
    };
    
    annotation { "Feature Type Name" : "CSV Variables" }
    export const CSV_Vars = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            annotation { "Name" : "CSV file" }
            definition.myCsvFile is TableData;        
        }
        {
            var file = definition.myCsvFile.csvData;
            var v = {};
                
            for (var i = 0; i < size(file); i += 1)
            {
                v[file[i][0]] = file[i][1];
                setVariable(context, file[i][0], file[i][1] * units[file[i][2]]);
            }
            
        });


  • john_mcclaryjohn_mcclary Member, Developers Posts: 3,936 PRO
    I've added some error checking and spelling along with every unit Onshape recognizes.

    can't use ' for feet and ° for degrees though. 

    if anyone knows how to make a function
    string toLower(string) {  ?? }
    then it would account for poor capitalization too.

    FeatureScript 1271;
    import(path : "onshape/std/geometry.fs", version : "1271.0");
    
    export const units = {
     "in" : inch,
     "inch" : inch,
     "inches" : inch,
     "\"" : inch,
     "ft" : foot,
     "foot" : foot,
     "feet" : foot,
     "\'" : foot,
     "yd" : yard,
     "yard" : yard,
     "yards" : yard,
     "mm" : millimeter,
     "millimeter" : millimeter,
     "millimeters" : millimeter,
     "cm" : centimeter,
     "centimeter" : centimeter,
     "centimeters" : centimeter,
     "m" : meter,
     "meter" : meter,
     "meters" : meter,
     "rad" : radian,
     "radian" : radian,
     "radians" : radian,
     "deg" : degree,
     "degree" : degree,
     "degrees" : degree,
     "kg" : kilogram,
     "kilogram" : kilogram,
     "kilograms" : kilogram,
     "g" : gram,
     "gram" : gram,
     "grams" : gram,
     "oz" : ounce,
     "ounce" : ounce,
     "ounces" : ounce,
     "lb" : pound,
     "lbs" : pound,
     "pound" : pound,
     "pounds" : pound,
     "s" : second,
     "sec" : second,
     "second" : second,
     "seconds" : second
    };
    
    annotation { "Feature Type Name" : "CSV Variables" }
    export const CSV_Vars = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            annotation { "Name" : "CSV file" }
            definition.myCsvFile is TableData;        
        }
        {
            var file = definition.myCsvFile.csvData;
            var v = {};
            var unit = 1;
                
            for (var i = 0; i < size(file); i += 1)
            {
                v[file[i][0]] = file[i][1];
                
                if (units[file[i][2]] != undefined)
                {
                    unit = units[file[i][2]];
                }else
                {
                    unit = 1;
                }
                
                setVariable(context, file[i][0], file[i][1] * unit);
            }
            
        });
    


  • EvanReeseEvanReese Member, Mentor Posts: 2,141 ✭✭✭✭✭
    @john_mcclary

    well you've just done what I was setting out to do which works for me :blush:. I guess I can still help by making an icon?

    In answer to your other question, I was using [1][2] to prototype the basic function before switching to [i][2] in the for loop. Thanks for pointing out the dot notation issue too. I'm really not sure how to find some things out if I don't already know the answer. Featurescript is my first and only coding language.
    Evan Reese
  • EvanReeseEvanReese Member, Mentor Posts: 2,141 ✭✭✭✭✭
    edited June 2020
    Evan Reese
  • john_mcclaryjohn_mcclary Member, Developers Posts: 3,936 PRO
    Hah, yea you are probably better at icons than me 😉

    I just play around until things work. I haven't found a good comprehensive tutorial on fs yet. 

    Most of what i can do is limited to what i can carry over from c++ and c#

    Still can't do any cad related stuff in fs
  • john_mcclaryjohn_mcclary Member, Developers Posts: 3,936 PRO
    Ok, I updated it with your icon, thank you :)
  • EvanReeseEvanReese Member, Mentor Posts: 2,141 ✭✭✭✭✭
    Ok, I updated it with your icon, thank you :)
    Thanks! Having an icon always makes it feel so official (at least to me)
    Evan Reese
  • romeograhamromeograham Member, csevp Posts: 677 PRO
    edited June 2020
    Hey guys - can you use the new Custom Tables to show a table of all the variables in the CSV Variables FS you're messing with?
    It works really nicely (and FAST)...but once in the Onshape document there's no way to view the variable values (unless you use Link Tab I guess). You can't view the .csv directly, and when you use the CSV Variables FS, you can't see the content of the csv anywhere. All the variables are loaded to the document.

    Now that I've tried it, Link Tab (at least in Chrome) works nicely to show the Variables in the document:

    @TimRice did you have to do anything special to your Sensor feature to enable the Table?

    Thanks!

  • john_mcclaryjohn_mcclary Member, Developers Posts: 3,936 PRO
    Nice
  • TimRiceTimRice Member, Moderator, Onshape Employees Posts: 315
    @romeograham
    Yes I believe that is possible to list out the variables. To learn more about writing custom tables please see the FS documentation:
    https://cad.onshape.com/FsDoc/tables.html
    Tim Rice | User Experience | Support 
    Onshape, Inc.
  • EvanReeseEvanReese Member, Mentor Posts: 2,141 ✭✭✭✭✭
    @romeograham
    I like the idea of using the custom table to show the variables. I've not had time to dig into the tables yet and it's still all Latin to me. I like the Link Tab solution. This whole undertaking is really turning into a Bargain Basement version of the Global Variables that Onshape is supposedly already working on 😆. Either way, I'm having fun.
    Evan Reese
  • romeograhamromeograham Member, csevp Posts: 677 PRO
    @romeograham
    I like the idea of using the custom table to show the variables. I've not had time to dig into the tables yet and it's still all Latin to me. I like the Link Tab solution. This whole undertaking is really turning into a Bargain Basement version of the Global Variables that Onshape is supposedly already working on 😆. Either way, I'm having fun.
    @john_mcclary 's Variables FeatureScript suggestion (from the San Diego User Group meeting) is slick too, because you can directly edit the variables onscreen, commit, and they update in the document (after you update the FS in each Part Studio, of course!). With the link tab setup above, you still need to export the csv (from the Google Doc) & update the CSV tab to propagate changes (though I like the instantaneous updating in the Part Studio as soon as the CSV is updated).



  • john_mcclaryjohn_mcclary Member, Developers Posts: 3,936 PRO
    Yea, global variables are nice. These work arounds work for most of what I need. but they will never be able to do everything until I can call these variables in an assembly, like in a pattern.
  • EvanReeseEvanReese Member, Mentor Posts: 2,141 ✭✭✭✭✭
    they will never be able to do everything until I can call these variables in an assembly
    exactly

    @romeograham
     
    That's the way I've typically been doing it, but I like something about the CSV. I'll probably use it for things that won't change as much. For example, I made a library of press-fit threaded inserts that will never change, but I still want a feature to call out the lengths and hole sizes as variables. it's easier to do it with a CSV than typing each one. In fact, when I've had a lot to write, I've set up some concatenate functions in a spreadsheet so I can type them faster, then copy/paste them into my custom feature.
    Evan Reese
  • romeograhamromeograham Member, csevp Posts: 677 PRO
    @Evan_Reese
    Also - right back to your original question: for me, having variables unitless would cause real problems. When I deal with different suppliers / partners / customers that "think" in Standard (inches, etc) and my design work is done in metric - the only way to quickly show a distance or edge on the model in inches (without making or switching to a drawing) is to change the units of the document.

    We need dual dimensions to show in the Measure dialogue...this would reduce the need to change document units just to query dimensions in Part Studios.
  • mahirmahir Member, Developers Posts: 1,307 ✭✭✭✭✭
    We need dual dimensions to show in the Measure dialogue...this would reduce the need to change document units just to query dimensions in Part Studios.
    On that note, vote for your favorite improvement requests!
    Multi-unit Measurement
    Manage Units Per Tab
  • john_mcclaryjohn_mcclary Member, Developers Posts: 3,936 PRO
    I never use units, it has never been an issue for me, even when changing the units of the document.

    because every dimension that drives geometry must have a unit.
    if you call it out during variable creation, then you don't need to call it out at the dimension
    if you don't call it out at variable creation, then you do need to call it out at the dimension (Onshape auto-completes this)

    So I haven't had anything break.





    and i'm doing some math on the values unitless in the background

  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 2,050 ✭✭✭✭✭
    Hey guys - can you use the new Custom Tables to show a table of all the variables in the CSV Variables FS you're messing with?
    It works really nicely (and FAST)...but once in the Onshape document there's no way to view the variable values (unless you use Link Tab I guess). You can't view the .csv directly, and when you use the CSV Variables FS, you can't see the content of the csv anywhere. All the variables are loaded to the document.

    Now that I've tried it, Link Tab (at least in Chrome) works nicely to show the Variables in the document:

    @TimRice did you have to do anything special to your Sensor feature to enable the Table?

    Thanks!

    Here's a custom table that will show all the variables in a Part Studio:
    FeatureScript 1301;
    import(path : "onshape/std/table.fs", version : "1301.0");
    
    annotation { "Table Type Name" : "All Variables" }
    export const allVariables = defineTable(function(context is Context, definition is map) returns Table
        precondition
        {
        }
        {
            const vars is map = getAllVariables(context);
            const t is Table = table("Variables",
                    [
                        tableColumnDefinition("key", "Variable name"),
                        tableColumnDefinition("value", "Value")
                    ],
                    mapArray(
                        keys(vars),
                        function(key) returns TableRow
                    {
                        return tableRow({
                                    "key" : key,
                                    "value" : vars[key]
                                });
                    }));
            return t;
        });
    

    mb - draftsman - also FS author: View FeatureScripts
    IR for AS/NZS 1100
Sign In or Register to comment.