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.

Prevent selecting origin point in Featurescript entity parameter

George_AndersonGeorge_Anderson Member Posts: 71 PRO
Is there a way to prevent the origin point from being selectable in a Featurescript entity parameter, while allowing other points created by opPoint to be selectable? Roughly, I have a set of features where the user adds "points", manipulates them over the course of several features, and then I use them to generate a geometry. I create point objects with opPoint, and then I want these specific objects to be selectable in later features. When one of these points is coincident with the origin (which happens naturally in virtually every model), the origin always remains the top-most selectable object, and you have to know to right-click, "select other" to correctly select the special object. One obvious but expensive way around is to always do evVertexPoint on every selection and see if it's at the origin, but I was hoping there might be a more logical/attribute based way.
Tagged:

Comments

  • George_AndersonGeorge_Anderson Member Posts: 71 PRO
    (I also know you can hide the origin, it's just a bad user experience to have to explain that to users.)
  • alan_baljeualan_baljeu Member, User Group Leader Posts: 111 ✭✭
    Seems like OnShape should make origin the last of the selection options rather than the first.  If anything is on the origin, you probabaly want to pick that.
    Creating knowledge-driven design automation software, for molds, etc.
    www.virtualmold.com

  • Alex_KempenAlex_Kempen Member Posts: 221 EDU
    edited May 2021
    Adding an editing logic function which automatically checks if a newly selected entity is the origin and tries to add a nearby point object instead is one fairly easy way to accomplish the desired behavior. I know it seems like evVertexPoint and the like can be clunky or expensive, but if you check it using the profiler, it's actually really fast (easily < 10 ms). Nevertheless, it probably isn't necessary for your case since you can simply use queries to figure out if the selected entity is the origin and then look for a proper point to replace it with. Thus, something like the following in your editing logic should work fairly well:
    export function myEditLogic(context is Context, id is Id, oldDefinition is map, definition is map, isCreating is boolean) returns map
    {
       if (oldDefinition.myQuery != definition.myQuery && 
        size(evaluateQuery(context, definition.myQuery)) > size(evaluateQuery(context, oldDefinition.myQuery)))
        {
            const addedEntity = qSymmetricDifference(definition.myQuery, oldDefinition.myQuery);
            if (evaluateQuery(context, qIntersection(qCreatedBy(makeId("Origin")), addedEntity) != [])
            {
                try
                {
                    const point = // query for the point, using qHasAttribute->qContainsPoint->qNthElement or some other method
                    definition.myQuery = qUnion(definition.myQuery->qSubtraction(addedEntity), point);
                }
            }
        }
        return definition;
    }<br>
    If you do go this route, I would also check if definition.myQuery contains the origin in the feature body, and add an appropriate warning for that case as well.
  • George_AndersonGeorge_Anderson Member Posts: 71 PRO

    Thanks, this is a great approach and also has the advantage of being able to filter selections based on stored attributes, which I was also wondering how to do. One downside is that I have a suite of features that all allow you to select these points, so it becomes a lot of editing logic mess to maintain. A direct builtin way to filter selections on attributes would be incredible! But the approach is very feasible and extensible, so I like it.

    P.S. I want to draw attention to the mental trap of saying that 10ms is "really fast". 10 ms (or even 1 ms) to return a point location is an eternity! If I select 100 points on 10 features in a row, I've lost 10 seconds of my life on each full regen! In any case, Onshape has to compute the location of *all* the points to even render them, so it can't possibly use something so slow. I am aware that evVertexPoint does more than return a prestored value, and there's a lot of overhead just to get there. This is probably why for a handful of functions there are parallel "plural" versions (e.g. evFaceTangentPlanes) that let you get lots of the same thing at once, to reduce the overhead.

    In fact most of the Featurescript functions are painless when you do them once, and are suddenly embarrassing once they are in a loop. For some of my math-heavy scripts, I've had to rewrite a number of standard library math functions (e.g. dot, project, intersect, etc.) and can easily make them twice as fast, usually just by simply removing units before doing overloaded +/- operations. I had the same discouraging experience in Matlab 10 years ago.

  • Alex_KempenAlex_Kempen Member Posts: 221 EDU
    You’re not wrong about performance stack up, although I think it’s worth pointing out that editing logic has the advantage of only running when the feature is directly edited by a user. And even then, a condition is used to prevent unnecessary overhead (in the example I posted, the first of condition checks if the query has changed, and if it has, it then checks to see if the size of the query has increased).
  • George_AndersonGeorge_Anderson Member Posts: 71 PRO
    Seems like OnShape should make origin the last of the selection options rather than the first.  If anything is on the origin, you probabaly want to pick that.
    I'm guessing this would depend a lot on context. I think there are many times I'd want to reference the origin, not the corner of something I drew there. I think the point is that when designing a feature, there are incredibly useful filters like EntityType and BodyType and ConstructionObject and SketchObject, that can narrow down specifically what you want your user to select. To me the origin seems like a special type of object, distinct from other point objects, so I wish there were an "OriginObject" enum, or some other way to exclude it. 

  • George_AndersonGeorge_Anderson Member Posts: 71 PRO
    @Alex_Kempen That's a good point, I had forgotten that EL functions only run while being edited.
Sign In or Register to comment.