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.

"Fixing" a query so it doesn't change

jack_gregoryjack_gregory Member Posts: 3
First post.  I have a sketch point that I am using for a kind of fancy counterbore feature.  Essentially, I take the point, and drill a hole there (normal to the planar face the point must be on).  When I first get the face, I also get its owning solid so I can do the boolean later.  But of course that solid is a query, not a thing, and later operations result in more solids being found that match the original faceContainsPoint.  Then my boolean fails.
So I want to somehow "lock" that first query, which does get the one solid I want to be the target.
I know I can probably subtract the new solids I have created from the query.  But that seems pretty painful when I have the culprit at the very beginning of the script.
Any hints appreciated.  I am willing to work for it, but am on the steep part of the learning curve right now.  Reading the std hole feature is mind-boggling-complex, even though I know it does almost exactly what I want.


  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,624
    edited January 2019

    If we make the assumption that the body is not going to be split or destroyed, you call this code before making modifications to get a more "solid" (pun intended) reference to the body you care about:
    const transientBodyQ = evaluateQuery(context, bodyQ)[0];
    Here is the documentation for evaluateQuery:

    In essence, it returns an array of queries, each representing exactly one entity which the query resolves to.  It represents each entity using a transient id, which may change if the body is altered in some major way (splitting is a good example).

    A more robust query to represent that body may look as follows:
    const transientBodyQ = evaluateQuery(context, bodyQ)[0];
    const robustBodyQ = qUnion([transientBodyQ, startTracking(context, transientBodyQ)]);
    transientBodyQ will resolve to the body if its transient id HAS NOT changed.  The tracking query will resolve to the body if its transient id HAS changed.  So, unioning those queries together will ensure that you have a reference to that exact body whether or not its transient id changes.

    You'll probably be fine with the first approach, and can incorporate the second approach if the first seems to lose the body along the way.

    Hope this helps!
    Jake Rosenfeld - Modeling Team
  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 1,945 EDU
    Or, if you have multiple bodies, you can use
    const transientBodyQ = qUnion(evaluateQuery(context, bodyQ));
    const robustBodyQ = qUnion([transientBodyQ, startTracking(context, transientBodyQ)]);

    MB - I make FeatureScripts: View FeatureScripts
  • pmdpmd Member, Developers Posts: 43 PRO
    When I ran into this problem in the past I did just subtract the items I made since everything created by the featurescript itself can be found just by calling qCreatedBy(id) no matter how many things you made via different logic paths etc.

  • jack_gregoryjack_gregory Member Posts: 3
    Thanks for everyone's response.  The addition of the tracking aspect was insightful, because the very next position caused a split that made the simple method fail.  When it happened, I had a good idea of what it was.  So I learned a lot here.

Sign In or Register to comment.