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.

global data

billy2billy2 Member, OS Professional, Mentor, Developers Posts: 1,313 PRO
edited February 2016 in FeatureScript
Is there anyway to pass around data?

createData creates a huge array, can getData access this array?



create some data:
FeatureScript 307;
import(path : "onshape/std/geometry.fs", version : "307.0");
annotation { "Feature Type Name" : "createData" }
export const createData = defineFeature(function(context is Context, id is Id, definition is map)
    precondition
    {
        
    }
    {
        const billysData=5;
    }, { /* default parameters */ });


get some global data:

FeatureScript 307;
import(path : "onshape/std/geometry.fs", version : "307.0");
DATA::import(path : "03b271aa9f983f47f1473e51", version : "b5ddb1c97dd36645bc48123e");//link to createData
annotation { "Feature Type Name" : "getData" }
export const getData = defineFeature(function(context is Context, id is Id, definition is map)
    precondition
    {
        // Define the parameters of the feature type
    }
    {
        println('DATA::billysData '~DATA::billysData);
    }, { /* default parameters */ });


Comments

  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 944
    Will write a more detailed message tomorrow, but for now I'll just point to two ways of doing it (both attach data to the context):

    1. Variables (see setVariable and getVariable in context.fs) -- they may have any value including a large array.
    2. Attributes (are attached to topology and are a little harder to use) -- see attribute.fs or the doc https://cad.onshape.com/FsDoc/library.html#module-attributes.fs
    Ilya Baran \ Director, Architecture and FeatureScript \ Onshape Inc
  • billy2billy2 Member, OS Professional, Mentor, Developers Posts: 1,313 PRO
    edited February 2016
    Thanks, will read up on those.





    I figured it had something todo with context.

    A module has context, and a module is located in a tab. I'm using 2 tabs, do they have different contexts?

    Is context a document, part studio, module or tab?

    Part studios have context, I have 2 modules in a part studio therefore they share 1 context?

    Why would this ever be false?


    If it's always true, why have it?

    Can I run a function when it's not in context?



  • billy2billy2 Member, OS Professional, Mentor, Developers Posts: 1,313 PRO
    edited February 2016
    Well, sorry for butchering up your language.

    I can't get the simple one to work. I tried passing billysData=5 thinking this would be easy and it wasn't. So, I figured I'd give you a tougher problem closer to what I need. I'm interested in sending an array of vectors, 58,000 vectors. Maybe I'll just send the parsed x,y,z values. What's the best way to handle large data sets?

    Questions:
    1. how do you get this to work?
    2. speed is everything. should I convert all x, y, z to vectors and then ship vectors? or should I send x, y, z around, pick the 1,000 I want and convert them?
    3. are certain data types faster? arrays seem like they'd be faster than maps?
    4. I am reading the manual (honest), you talk about a box value passing by reference as opposed to a deep copy, should I be using billysData[]=array? Wouldn't passing by reference be faster than any other methods outlined so far? I could be way out in right field. Not sure what a boxed value is used for other than accessing data.



    createData.fs:
    FeatureScript 307;
    import(path : "onshape/std/geometry.fs", version : "307.0");
    annotation { "Feature Type Name" : "createData", "UIHint":"NO_PREVIEW_PROVIDED"  }
    export const createData = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            
        }
        {
            const billysData=[vector(1,2,3), vector(1,1,1), vector(1,2,1)];
            const billysMap={'1':vector(1,2,3), '2':vector(1,1,1), '3':vector(1,2,1)};
            
            setVariable (context is Context, 'billysData', billysData);
            
            setAttribute (context is Context, billysMap);
            
        }, { /* default parameters */ });



    getData.fs:

    FeatureScript 307;
    import(path : "onshape/std/geometry.fs", version : "307.0");

    annotation { "Feature Type Name" : "getData", "UIHint":"NO_PREVIEW_PROVIDED" }
    export const getData = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            // Define the parameters of the feature type
        }
        {
            var billysData;
            getVariable(context is Context, 'billysData');
            getAttributes (context is Context, billysMap);
            println('billysData ' ~ billysData);
            println('billysMap ' ~ billysMap);
        }, { /* default parameters */ });



    and none of it works:


  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 944
    The reason you're having some of the issues is the "is Context" has different meaning in a function declaration and a function call.

    When you declare a function as:
    function foo(context is Context)
    {
        ...
    }
    you're specifying that the argument passed into foo must be a Context.  It is an error (or warning if it is caught) if you pass in something else.
    In your function, you're calling:
    getVariable(context is Context, 'billysData');
    and "context is Context" is indeed a boolean that always evaluates to true.  But the getVariable function expects a Context, not a boolean as its first argument, hence the error.  The correct call is (with the assignment to your variable):
    billysData = getVariable(context, 'billysData');
    Now there's another issue: billysMap is not declared in the second feature so trying to pass it to getAttributes won't work (and even if it could be done, it wouldn't do the right thing -- like I said, attributes are a bit more complicated and I don't think you need them yet here).

    Regarding speed, FeatureScript does very little actual copying, so passing around a 50k element array shouldn't be any more expensive than passing around a smaller one.  One thing that is currently inordinately expensive (we're working on it) is modifying a large array.  So maps are likely to be faster than arrays actually for now.  The general rule is that YMMV so try profiling different things -- every use case is slightly different.

    Hope this helps.
    Ilya Baran \ Director, Architecture and FeatureScript \ Onshape Inc
  • billy2billy2 Member, OS Professional, Mentor, Developers Posts: 1,313 PRO
    edited February 2016
    I was off by just a little bit, thanks for your help.

    I'm passing arrays & maps. It's cool that the vectors stay true through the transfer. I thought I'd have to serialize my object before sending and then parse the variable on the other side. Nope, everything stays valid. You can store a lot in one variable.

    Will run a little test and find out which is faster.





    Here's the source for those who want to pass variables around feature scripts.

    createData:
    FeatureScript 307;
    import(path : "onshape/std/geometry.fs", version : "307.0");
    annotation { "Feature Type Name" : "createData", "UIHint":"NO_PREVIEW_PROVIDED"  }
    export const createData = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            
        }
        {
            const billysData=5;
            //const billysData=[vector(1,2,3), vector(1,1,1), vector(1,2,1)];
            
            setVariable (context, 'billysData', billysData);
            
        }, { /* default parameters */ });


    getData:
    FeatureScript 307;
    import(path : "onshape/std/geometry.fs", version : "307.0");

    annotation { "Feature Type Name" : "getData", "UIHint":"NO_PREVIEW_PROVIDED" }
    export const getData = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            // Define the parameters of the feature type
        }
        {
            var billysData;
            billysData=getVariable(context, 'billysData');
            println('billysData ' ~ billysData);
        }, { /* default parameters */ });





Sign In or Register to comment.