Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape, CAD, maker project and design.

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.

Measurement Tool Feature

ethan_keller924ethan_keller924 Member Posts: 15
I want a way for data to go from OnShape to python in a clearly defined interface. Say I have a sketch with many complex constraints, and some of the lengths are driven by configurations. In the simplest case, say I have a right triangle with the two legs driven by config values. Now I want the length of the hypotenuse in order to do some more calculations. How do I get that through the REST API?

My current approach would be to use a feature called something like "take measurement" and then when I'm looking for a measurement of that part in the REST API, I can read the feature list and reliably pull the measurement requested. Essentially, I want to add the measurement functionality OnShape has in the lower right as a FeatureScript feature, where the input is a collection of entities (like it is within the measure tool) and the output is the measurement - this would be dynamic and smart - volume/mass for bodies, length for lines, etc... I'm not looking for an ideal solution - I realize my suggestion is a bit hacky and would clutter the feature list, but it would provide a reasonable way for a part designer to generate "output" for the REST API to consume. Maybe there is a solution to this problem already proposed?

I've been working on a simple OnShape python connector that I put up on pip so my students have a way to manipulate parts from functions defined in Python. 

I saw the featurescript measure distance... should I use that? What if I want to measure other things, such as mass? The builtin measurement tool supports this, so how do I access that?

Comments

  • kevin_o_toole_1kevin_o_toole_1 Onshape Employees, Developers Posts: 380
    edited August 7
    Awesome setup, and great use of configs!

    For the kinds of measurements you want to take, I'd recommend using our "Evaluate FeatureScript" API endpoint. This endpoint evaluates a given FeatureScript function on a given Part Studio.

    There's lots of great uses for this functionality. In your case, I can think of a few approaches to do what you want.
    1. You could use FeatureScript to directly measure the thing you want, e.g.
      function(context, queries) {
          return evLength(context, {
              "entities" : qLargest(qGeometry(qEverything(EntityType.EDGE), GeometryType.LINE))
          });
      }
      This involves knowing how to grab the right edge with a FeatureScript query (they're documented here). The example above measures the largest straight line in the Part Studio.

    2. If you have an entity's id (e.g. from another API endpoint. It's often called a partId, but they exist for lines, points, etc. too), you can pass that id into "queries" argument:
      { "queries" : { "key" : "myQueryName",  "value" : "myId" } }
      It will then be translated into a FeatureScript query you can use in your function:
      function(context, queries) {
      return evLength(context, { "entities" : queries.myQueryName }); }

    3. If you use the "Measure distance" custom feature to store a distance in the Part Studio variable "#myDistance", you can simply retrieve that variable:
      function(context, queries) {
          return getVariable(context, "myDistance");
      }

    In all cases, you'll quickly run into the fact that FeatureScript values have units (documented here). If your library just wants plain numbers (which internally assume some unit), you can simply divide the units out when your function returns:
    return myLength / inch;

    Evaluate FeatureScript is a really powerful interface into everything happening in Part Studios. Let us know if you get stuck, or if you have further questions!

  • ethan_keller924ethan_keller924 Member Posts: 15
    @kevin_o_toole_1 Thanks for such a detailed response! That is a cool endpoint - super flexible. I'm wondering if there is any way to access the featureScript that is in the measurement tool easily? It's just that the measurement tool already deals with myriad different entity selection pairings... where would I find the measurement tool Fs?
  • kevin_o_toole_1kevin_o_toole_1 Onshape Employees, Developers Posts: 380
    Unfortunately, the measurement tool was not written in FS. It does a combination of several measurements, all of which should be accessible from FS. The main one is evDistance, but there's also info available from evLength, evArea, and evVolume. For curves, you can use evCurveDefinition and check the type of the result (and the data on it, e.g. circle radius). For surfaces you can do the same with evSurfaceDefinition.

    Most custom features use these functions for very specific purposes and need to use the resulting value (not just print it as a string). I don't know of any generic infoDump() function available. But certainly one could be written!

  • ethan_keller924ethan_keller924 Member Posts: 15
    edited August 13
    @kevin_o_toole_1
    I was checking out the documentation and I can't find a way to see all variables within a context? Looks like I have to specify the name of the variable I am hunting for. Is there any FeatureScript trick around that?

    Also, how do I escape quotes in API calls? I want to send some FS, and I'm using strings in the FS. Looks like I can escape through here.

    Lastly, I was looking through the help section, and the part under "Evaluate FeatureScript" has a missing example that it says "is below"
  • kevin_o_toole_1kevin_o_toole_1 Onshape Employees, Developers Posts: 380
    edited August 13
    Hmm. I don't know of a trick around that. Currently you'll just need to use a set of known variable names.

    If you'd like that feature added, you can certainly submit an improvement request!

    Edit for your new questions:
    Escaping quotes in JSON should be correct.
    Can you link to the section of help with the missing example?
  • kevin_o_toole_1kevin_o_toole_1 Onshape Employees, Developers Posts: 380
    If I'm understanding your goal correctly, you could also use a custom feature like this:
    https://cad.onshape.com/documents/898eec6699d15ec450a438d9/w/2daaa579f5e2dc8da576d85b/e/9c7f060b0a844cb075b45a38
    annotation { "Feature Type Name" : "Set measurement" }
    export const setMeasurement = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            annotation { "Name" : "Name" }
            definition.name is string;
    
            annotation { "Name" : "Value" }
            isAnything(definition.value);
        }
        {
            var allValues = try silent (getVariable(context, "measurements"));
            if (allValues == undefined) allValues = {};
            allValues[definition.name] = definition.value;
            setVariable(context, "measurements", allValues);
        });
    

    ...which sets measurements not as separate variables, but as map entries on a common variable named "measurements".

    If you fork your favorite measure feature and change its "setVariable" code to something like the above, you'll also save the step of needing two different features to make a measurement and consolidate it.

    Depending on your usage, this workflow might be more or less difficult than simply having a common set of known values to look up. YMMV.

  • ethan_keller924ethan_keller924 Member Posts: 15
    This is perfect! You guessed it, I had wanted to put my measurements within a different namespace that would be available to context. Thanks! Also, the documentation that is missing is here under "Evaluate Featurescript" - there are no anchors, or at least I don't know how to anchor to that section, so just ctrl-f "evaluate featurescript"
  • kevin_o_toole_1kevin_o_toole_1 Onshape Employees, Developers Posts: 380
    Ah, yep, looks like anchors are broken on that page (so I can't link either :P)

    The section with the example is labelled "Feature Script evaluation", so you can ctrl-F for that instead.
  • ethan_keller924ethan_keller924 Member Posts: 15
    edited August 14
    For the record, I copied the Measure Distance document and added the function @kevin_o_toole_1 suggested. Now there is a "set measurement" function that is used internally and is responsible for updating a measurements context variable that points to a map that stores all the measurements taken. This way it doesn't pollute the global context variable namespace. To use a measurement within measurements, just specify anywhere that takes an expression with "#measurements.measurementName" and it should return your measurement.

    My measurements document is available here.

    The goal of this doc is to have a more robust measurement tool that can take volumes, areas, and complex lengths with a simple UI. If you're interested in helping with it, please collaborate via this issue and I can share the doc with you. 
  • Don_Van_ZileDon_Van_Zile Member Posts: 90 PRO
    edited August 14

    Thanks @ethan_keller924 (and of course @ilya_baran) for taking the time to develop this new Measure tool and sharing. I hope others who are code savvy will expand on this as well.

  • ethan_keller924ethan_keller924 Member Posts: 15
    @kevin_o_toole_1 this might warrant another thread, but I have a related question. Is there any way to access partStudio context from an assembly instance through the API? I'd like to link to a configurable PartStudio within an assembly. I may not have write access to the PS to which I'm linking, but I'd like to access the resulting 'measurements' that I stored in the context of the PartStudio based on the current configuration I passed in. Is there any way I could access the resulting "context" through the API without having to copy the workspace of the versioned part, change the configuration, and read the measurements variable?


  • kevin_o_toole_1kevin_o_toole_1 Onshape Employees, Developers Posts: 380
    Absolutely! You don't need a workspace or even edit permission to access all configurations of a Part Studio. You can access any configuration of a single version through the API.

    Step one, encode the configuration in question using the "Encode Configuration" endpoint i.e. /elements/d/:did/e/:eid/configurationencodings (Another win: the format of encodeConfiguration is a little less intense than the changeConfiguration command :tongue: )

    Step two, pass the resulting string as a query parameter to the endpoint you want e.g. /partstudios/d/:did/[wvm]/:wvm/e/:eid/featurescript?configuration=<encodedConfiguration>

    There is no step three - the API call just executes at the given configuration, and no actual edits to the Part Studio are made.

    If you run into issues, I'd verify that the string you're passing is HTML-encoded once and only once (your REST library likely does that by default but perhaps not).

    The implementation of the configurationencodings endpoint may seem very obvious to you the first glance, but be aware that for big configurations we assign a hard-coded id to the specific config you pass (rather than the human-readable string), and we might change how we encode things in the future. So don't try to mimic the endpoint without a real API call.

Sign In or Register to comment.