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.

Measurement Tool Feature

ethan_keller924ethan_keller924 Member, csevp Posts: 42 PRO
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, HDM Posts: 565
    edited August 2018
    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:
      function(context, queries) {
      return evLength(context, { "entities" : queries.myQueryName }); }</code>{ "queries" : { "key" : "myQueryName",&nbsp;&nbsp;"value" : "myId" } }</pre>It will then be translated into a FeatureScript query you can use in your function:<br><pre class="CodeBlock"><code>

    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, csevp Posts: 42 PRO
    @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, HDM Posts: 565
    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, csevp Posts: 42 PRO
    edited August 2018
    @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, HDM Posts: 565
    edited August 2018
    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, HDM Posts: 565
    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, csevp Posts: 42 PRO
    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, HDM Posts: 565
    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, csevp Posts: 42 PRO
    edited August 2018
    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: 195 PRO
    edited August 2018

    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, csevp Posts: 42 PRO
    @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, HDM Posts: 565
    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.

  • ethan_keller924ethan_keller924 Member, csevp Posts: 42 PRO
    @kevin_o_toole_1
    This is cool! I hadn't realized that the configuration could be passed in as a query parameter! One more thing - is it possible to change the config params of instances within an assembly through the API? I posted about it here more than a month ago but I've heard nothing.
  • kevin_o_toole_1kevin_o_toole_1 Onshape Employees, Developers, HDM Posts: 565
    Hmm, you're right. Looks like that isn't exposed in the API at the moment. You can, of course, remove the instance and add it again at a new configuration, but that loses existing mates. Please post an improvement request to expose this functionality!
  • ethan_keller924ethan_keller924 Member, csevp Posts: 42 PRO
    Update: someone with the github handle @morgan_b21 posted a featurescript here that is a versatile implementation of the measure functionality. 
  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 2,039 ✭✭✭✭✭
    @ethan_keller924
    That's me
    mb - draftsman - also FS author: View FeatureScripts
    IR for AS/NZS 1100
Sign In or Register to comment.