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.

PLEASE explain "externally disambiguated" / "transient" / "robust" / "tracked" / "unstable" ID's etc

christopher_dziubachristopher_dziuba Member Posts: 93 ✭✭

It has been years and we still don't have foundational knowledge of how featurescript operates.
From what I can see in the forums most of us dev's have been wasting hours upon hours guessing and testing.
This post and others are "weak-sauce" at best. We all know about:
-"forEachEntity"
-"makeRobustQuery"
etc, etc and may have some idea on how to use them effectively but no solid understanding on exactly what's happening.
And please for the love of all that is good NO METAPHORS OR ANAOGIES! just tell us exactly what is happening.

If I have to decode one more post that starts with "Look at this way", "Imagine it like this", "It's sort of like", "I always picture it like this" then I'm lighting my PC on fire.
We're big boys we can handle the complexity without cryptic stories and riddles.

Tagged:

Best Answers

  • lanalana Onshape Employees Posts: 736
    edited August 29 Answer ✓

    This Onshape Live presentation had ( a very simplified ) explanation of how queries work inside Onshape. For each topology created by an operation there is a record of its dependencies allowing us to identify this topology. When downstream references this topology, query (an encoding) of this record is generated. Query evaluation is a patten matching of the query with current state of history. One of the first matches is operation id. If we introduce an unstable component into ids of some operations, it means that results of those operations will all be considered when evaluating a query generated for one of them. E.g. If we have a set of operation ids fId0,op0, fId1.*id0.op, fid1.*id1.op, fid1.*id2.op .. , when evaluating a query for topology created by e.g. fid1.*id1.op , we'll consider all fid1.*.op operations. This way reference is stable to order and number of input selections. If the dependencies are not enough to disambiguate results of these operations, external disambiguation is used. At the time of query evaluation external reference replaces the unstable component. I hope this gives you a mental model for the future. This is not going to give you a complete clarity without knowing the way each operation handles its history records. I don't think we are going to expose those details any time soon.

    All of that is supposed to work in theory, but sequence of opSplit where results of previous step are passed into the next does not. I can't say that there is a theoretical reason why it could not, but so far we've fallen short of getting there. I'll add your example to an issue we have for addressing this scenario.

    In meantime If instead of split you could use opThicken to create the skins and opBoolean subtraction to reduce the original body, this should give you a more stable behavior. Sorry about the hassle.

  • lanalana Onshape Employees Posts: 736
    Answer ✓

    @Derek_Van_Allen_BD I think they mean use "opThicken" to create the individual skins then shape them with "opSplit" and in doing so we'd have more reliable solid body ID's for each skin downstream.

    I was rather thinking of opReplaceFace for side faces. You can use qCapEntity query with thicken to find the original face and its offset.

Answers

  • Derek_Van_Allen_BDDerek_Van_Allen_BD Member Posts: 194 PRO

    To be honest I wish there were more first party documentation of featurescript period. I think I've found a sum total of 3 official tutorials in my browsing of the Onshape site and they all stop at what I would consider to be very barebones level features. My whole world revolves around sheet metal and frames too, which has been an uphill climb discovering all of the quirks of both of those feature sets and how they work.

  • Lindsay_EarlyLindsay_Early Member, Onshape Employees, Developers Posts: 26
    edited August 26

    Hello! Please check out the training course I made a couple years ago. It starts with basics and gets into more advanced FeatureScript topics. https://learn.onshape.com/courses/featurescript-fundamentals

  • lanalana Onshape Employees Posts: 736

    This document has some simple illustrations :

    https://cad.onshape.com/documents/c11f5ce0511835f1be75e532/w/59249a8509a24c1f0c0bd39c/e/bdef6ab7c01a141dc56cc795

    Screenshot 2025-08-25 at 6.59.00 PM.png

    Transient queries are simple handles (transientId field is the important one) which we use to identify topology in current state. They are transient because as soon as something changes, the handles might also change.

    Spheres simple and spheres stable illustrate use of forEachEntity ( which is a convenient wrapper for unstable component and external disambiguation) . In simple case red sphere "jumps" if we delete first vertex, in stable case it does not.

    Screenshot 2025-08-25 at 6.53.22 PM.png Screenshot 2025-08-25 at 6.53.33 PM.png Screenshot 2025-08-25 at 6.57.15 PM.png Screenshot 2025-08-25 at 6.57.28 PM.png

    I know - this is short of explaining what is happening internally, but that is a much longer story - I'll come to it later.

  • christopher_dziubachristopher_dziuba Member Posts: 93 ✭✭

    @Lindsay_Early

    image.png

    This is what happens when I click your link.

  • christopher_dziubachristopher_dziuba Member Posts: 93 ✭✭

    @lana I linked to an explanation of "forEachEntity" and said we have some idea of how to use it effectively. But here's the problem I am now working on a script that has a nested "forEachEntity" loop and I'm getting bizarre behaviour. When I select a downstream entity it now automatically selects multiple sometimes. Without fundamental knowledge of what is happening I can't fix this:
    https://cad.onshape.com/documents/02e253006c3b752eb13303a7/v/4dcf3ee7787edd58af4658d0/e/e71817feee96d860dd0d7d58

    I appreciate the attempt though but I'm wanting is all-encompassing.

  • lanalana Onshape Employees Posts: 736

    @christopher_dziuba I took only a brief look at your feature.I see nothing wrong with your code. If you could point out the problem entities, I'll try to figure out what is going on.

  • Lindsay_EarlyLindsay_Early Member, Onshape Employees, Developers Posts: 26

    Sorry about that. I fixed the original link in my comment now. Period is removed and it works.

  • christopher_dziubachristopher_dziuba Member Posts: 93 ✭✭

    @Lindsay_Early thanks for following up and I did have a look at your coarse. Although I think it's invaluable for new comers that is very much not what I am asking for. Also the fact that it's a designed for beginners, comes of as an insult to me, although I'm sure it's not meant that way.

    @lana Thanks for looking at my code! That's exactly my problem everything seems fine and then this happens:

    Parts Multiselect.gif

    For some damn reason selecting one of the resulting parts force selects multiple parts sometimes! On top of that the skins are still not robust to upstream changes. In other words if I modify which faces are skins anything that referenced those skins either switches what skin was selected or completely breaks! All I want is robust selection after making skin and it's impossible without fundamental knowledge of how ID's are handled in the background.

  • lanalana Onshape Employees Posts: 736
    edited August 29 Answer ✓

    This Onshape Live presentation had ( a very simplified ) explanation of how queries work inside Onshape. For each topology created by an operation there is a record of its dependencies allowing us to identify this topology. When downstream references this topology, query (an encoding) of this record is generated. Query evaluation is a patten matching of the query with current state of history. One of the first matches is operation id. If we introduce an unstable component into ids of some operations, it means that results of those operations will all be considered when evaluating a query generated for one of them. E.g. If we have a set of operation ids fId0,op0, fId1.*id0.op, fid1.*id1.op, fid1.*id2.op .. , when evaluating a query for topology created by e.g. fid1.*id1.op , we'll consider all fid1.*.op operations. This way reference is stable to order and number of input selections. If the dependencies are not enough to disambiguate results of these operations, external disambiguation is used. At the time of query evaluation external reference replaces the unstable component. I hope this gives you a mental model for the future. This is not going to give you a complete clarity without knowing the way each operation handles its history records. I don't think we are going to expose those details any time soon.

    All of that is supposed to work in theory, but sequence of opSplit where results of previous step are passed into the next does not. I can't say that there is a theoretical reason why it could not, but so far we've fallen short of getting there. I'll add your example to an issue we have for addressing this scenario.

    In meantime If instead of split you could use opThicken to create the skins and opBoolean subtraction to reduce the original body, this should give you a more stable behavior. Sorry about the hassle.

  • Derek_Van_Allen_BDDerek_Van_Allen_BD Member Posts: 194 PRO

    @lana opThicken isn't a viable replacement for this feature unfortunately because it'll lead to issues with corner geometry where there are non-90-degree angles between faces.

  • christopher_dziubachristopher_dziuba Member Posts: 93 ✭✭

    @lana an absolute perfect answer thank you! So it looks like there is a fuzzy line between what we can know and what we're allowed to know about the exact functioning of ID's. But at least now I may have enough to play with.

    @Derek_Van_Allen_BD I think they mean use "opThicken" to create the individual skins then shape them with "opSplit" and in doing so we'd have more reliable solid body ID's for each skin downstream.

  • lanalana Onshape Employees Posts: 736
    Answer ✓

    @Derek_Van_Allen_BD I think they mean use "opThicken" to create the individual skins then shape them with "opSplit" and in doing so we'd have more reliable solid body ID's for each skin downstream.

    I was rather thinking of opReplaceFace for side faces. You can use qCapEntity query with thicken to find the original face and its offset.

Sign In or Register to comment.