Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.
First time visiting? Here are some places to start:- Looking for a certain topic? Check out the categories filter or use Search (upper right).
- Need support? Ask a question to our Community Support category.
- Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
- 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.
How does identity work?
juliaschatz
Member, Developers Posts: 8 EDU
I've been using Featurescript for a while but don't really understand how identity is determined.
Specifically, one featurescript I have extrudes each region of a sketch separately, even if they're joined. This will occasionally break if someone adds another region to the sketch used to define it. How can I make this script robust to changes in the sketch?
Another script I have generates a roller chain, and has options for Simplified and Realistic modes which in turn each call a different script. When the mode is changed, the new body has a different identity than the old one, which breaks anything that referenced it. How can I make both of these sub-features produce a body with the same identity?
Chain Path (line 743 for the start of the main feature).
1
Comments
To sum it up briefly: When you select an entity, Onshape generates a query for that entity. That query might look like "the face generated by the operation with id
id + "extrude1"
, and was a result of extruding the edge from a sketch with idid + "sketch1"
with sketch entity id"line7"
". If any of those ids change when you modify upstream features, that query will break, and the result is a feature running with a query for nothing (or, worse, a query for the wrong thing). Ids are not the only disambiguations used, but they are the most common and the ones that most rely on custom features behaving in a stable way.In the case of your "Extrude Individual" feature, you are losing selections for some changes because you create an operation with the id
id + ("extrudeRev" ~ safeId)
. Your "safeId"s, based on entity transient ids, may look more stable than a simple index, but in fact those transient ids can change when upstream operations are added and removed, so they are not stable in the face of most upstream changes.Luckly, FS has a built-in solution for this problem via the methods unstableIdComponent and setExternalDisambiguation.
unstableIdComponent(string) creates an id which will not be used to disambiguate any downstream features.
setExternalDisambiguation(context, id, entity) will ensure that the identity of "entity" will be used to disambiguate the operation with that id instead.
To tie it all together, here's a convenient forEachEntity(...) method for handling all this, explained via some very verbose documentation:
It can be used via the pattern explained in the documentation:
Now that it's written, hopefully this function is coming soon to an std near you! In the meantime feel free to import it from this public document I tested it in, or copy-paste it into yours, or simply mimic the pattern inside that function of unstableIdComponent and setExternalDisambiguation inside existing features.
Btw, nice features! I saw them used by many teams in the submissions we saw in the Robots to the Rescue competition. They are definitely simplifying some very useful work!
1) In a boolean union e.g. opBoolean(... qUnion( [ body1, body2] )), the first resolved body (i.e. body1) maintains its identity.
2) Bodies from operations based on sketches like opExtrude(... qSketchRegion(id + "sketch1")) maintain their identity if the sketch id is the same and at least one sketch id in the loop of edges around the region is there.
In your case, the first body of the boolean in your unsimplified code has an identity that's a variation of "The body extruded from id + "sketch1" touching either arc1, arc2, line1 or line2". The first body of the boolean in your simplified code has an identity that's a variation of "The body extruded from id + "sketch2" touching either arc1, arc2, line1 or line2".
So, changing those sketch ids to be consistent should resolve this issue.