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.

Featurescript - Creating cylinder in context

Hugh_GoodbodyHugh_Goodbody Member Posts: 38 PRO
I am writing a featurescript to create a cylinder between two points (usually the centres of two circles). Currently I can create the cylinder between two vertices or mate connectors in a part studio, and this is all good.
I would also like this to work in context but doing it this way, I can only select the edges of circles. I have added the circle selection to the UI:

annotation { "Name" : "Start Point", "Filter" : EntityType.VERTEX || BodyType.MATE_CONNECTOR || (GeometryType.CIRCLE), "MaxNumberOfPicks" : 1 }
        definition.startVertex is Query;

So the result of the above is that I either have a vertext point, or a circle.
So my question is: Is the best way to resolve this by incorporating an IF statement, ie IF the user selects a circle, then evaluate the centre point and use this as the vertex? or is there a better way?
The second part to the question, is how do I test if the circle has been selected?
Thanks in advance!

Comments

  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 5,307
    Put evCurveDefinition in a try block to test for a circle (which will fail if it is not a curve)
    Senior Director, Technical Services, EMEAI
  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 5,307
        precondition
        {
            annotation { "Name" : "Start Point", "Filter" : EntityType.VERTEX || BodyType.MATE_CONNECTOR || (GeometryType.CIRCLE), "MaxNumberOfPicks" : 1 }
            definition.startVertex is Query;
        }
        {
            var startVertex;
    
            try silent
            {
                startVertex = evCurveDefinition(context, {
                                "edge" : definition.startVertex }).coordSystem.origin;
            }
            catch
            {
                startVertex = evVertexPoint(context, { "vertex" : definition.startVertex });
            }
    
            println(startVertex);
        });
    Senior Director, Technical Services, EMEAI
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,646
    edited August 2019
    Just to encourage good FS practices, the way we would do this for an official feature is as follows:

    precondition
    {
        annotation { ... }
        definition.start is Query;
    }
    {
        // Check if the user has supplied a query, or has left the box blank
        if (size(evaluateQuery(context, definition.start)) != 1)
        {
            // Arguments here are the error that will displayed if the user hovers over the feature, and the name of the 
            // selection box that should be turned red.  Note that it only turns red if a different box is focused; when it
            // is focused, it will always be blue.
            throw regenError("Select start point", ["start"]);
        }
    
        // Assuming that selecting a point is more common, you would want to check for that first to not waste compute cycles.    
        // The `try silent(...)` and `try(...)` expressions return what is evaluated inside them if there is no error thrown, or
        // return `undefined` if an error is thrown inside them.
        var startPosition = try silent(evVertexPoint(context, { "vertex" : definition.start }));
        if (startPosition == undefined)
        {
            startPosition = try silent(evCurveDefinition(context, { "edge" : definition.start }).coordSystem.origin);
        }
        if (startPosition == undefined)
        {
            // If both checks failed, throw a useful error.  In addition to the parameters described above, I am also passing 
            // definition.start as an error entity. This entity will be highlighted in red to show the user what is wrong.
            throw regenError("Start point should be a vertex, a mate connector, or a circular edge", ["start"], definition.start);
        }
    }

    Some info on all this try and try silent stuff:
    https://cad.onshape.com/FsDoc/exceptions.html

    Another tip for this: once you find the two positions that you care about, `fCylinder` is going to be your best friend.  It does exactly what you want (take two points and a radius and make a cylinder between them):
    https://cad.onshape.com/FsDoc/library.html#fCylinder-Context-Id-map
    Jake Rosenfeld - Modeling Team
  • Hugh_GoodbodyHugh_Goodbody Member Posts: 38 PRO
    Thanks Jake, will endeavour to incorporate!
Sign In or Register to comment.