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.

Best method to select multiple sketches and iterate through them

seaelemseaelem Member, Developers Posts: 6
Hi Folks,

Having just started using feature Script, I was looking for guidance on how to select multiple sketches in order to do something useful with them.  The trivial example that I have seen discussed (but I'd not found an example of) was doing an extrusion operation on multiple sketches in one step.

I have posted my method of doing an extrusion on multiple sketches below in order to show:
  1. Use of the "EntityType.FACE" filter to select multiple faces for extrusion
  2. Use of "evaluateQuery" in order to break out that multi-select into useful transient queries.  From what I've read there's probably a better way of doing this but so far I can't make one work.
  3. Looping through each sketch query with an index and running the extrude feature method for each one.
Hopefully this is useful to someone and at the same time if anyone has input on whether there's a better way to break out sketch queries other than running the query evaluation method I'd be interested.  In all honesty I'm not clear on what that evaluation actually does - other than it seems to work!

/*
 * Who: Carl Morley
 * Date: 5 June 2016
 * Title: Extrude multiple sketches with the same depth simultaneously
 * Description: A simple method of extruding multiple sketches to the same depth at once.
 * Written only as experiment of how to do very basic multi-sketch selection and operations in Feature Script.
 */


annotation { "Feature Type Name" : "Multi-Extrude" }
export const myFeature = defineFeature(function(context is Context, id is Id, definition is map)
    precondition
    {
        // Capture user input on depth of extrusion and which faces to extrude.
        annotation { "Name" : "Depth" }
        isLength(definition.myDepth, LENGTH_BOUNDS);
        annotation { "Name" : "Faces and sketch regions to extrude", "Filter" : EntityType.FACE, "MaxNumberOfPicks" : 3 }
        definition.myFaces is Query;

    }
    {
        // Evaluate the user query of extrusion faces into a collection of temporary queries.
        // I suspect there's a better way to do use the 'myFaces' definition directly and does not require the evaluation call.
        // But at this stage not sure what that better method is!
        const allSketches = evaluateQuery(context, definition.myFaces);
        // Set a count to zero for id suffix
        var i = 0;
        // Loop through all the sketches and work on each one in turn
        for (var aSketch in allSketches)
        {
            // Increment the count
            i += 1;
            // Call the basic extrusion method, incrementing the id by 'i' and using each sketch and the universal 'myDepth'
            extrude(context, id + "extrude" + i, {
                        "entities" : aSketch,
                        "endBound" : BoundingType.BLIND,
                        "depth" : definition.myDepth
                    });
        }

    });
Kind regards,
Carl.

Comments

  • seaelemseaelem Member, Developers Posts: 6
    Hi Folks,

    Having just started using feature Script, I was looking for guidance on how to select multiple sketches in order to do something useful with them.  The trivial example that I have seen discussed (but I'd not found an example of) was doing an extrusion operation on multiple sketches in one step.

    I have posted my method of doing an extrusion on multiple sketches below in order to show:
    1. Use of the "EntityType.FACE" filter to select multiple faces for extrusion
    2. Use of "evaluateQuery" in order to break out that multi-select into useful transient queries.  From what I've read there's probably a better way of doing this but so far I can't make one work.
    3. Looping through each sketch query with an index and running the extrude feature method for each one.
    Hopefully this is useful to someone and at the same time if anyone has input on whether there's a better way to break out sketch queries other than running the query evaluation method I'd be interested.  In all honesty I'm not clear on what that evaluation actually does - other than it seems to work!

    /*
     * Who: Carl Morley
     * Date: 5 June 2016
     * Title: Extrude multiple sketches with the same depth simultaneously
     * Description: A simple method of extruding multiple sketches to the same depth at once.
     * Written only as experiment of how to do very basic multi-sketch selection and operations in Feature Script.
     */
    
    
    annotation { "Feature Type Name" : "Multi-Extrude" }
    export const myFeature = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            // Capture user input on depth of extrusion and which faces to extrude.
            annotation { "Name" : "Depth" }
            isLength(definition.myDepth, LENGTH_BOUNDS);
            annotation { "Name" : "Faces and sketch regions to extrude", "Filter" : EntityType.FACE, "MaxNumberOfPicks" : 3 }
            definition.myFaces is Query;
    
        }
        {
            // Evaluate the user query of extrusion faces into a collection of temporary queries.
            // I suspect there's a better way to do use the 'myFaces' definition directly and does not require the evaluation call.
            // But at this stage not sure what that better method is!
            const allSketches = evaluateQuery(context, definition.myFaces);
            // Set a count to zero for id suffix
            var i = 0;
            // Loop through all the sketches and work on each one in turn
            for (var aSketch in allSketches)
            {
                // Increment the count
                i += 1;
                // Call the basic extrusion method, incrementing the id by 'i' and using each sketch and the universal 'myDepth'
                extrude(context, id + "extrude" + i, {
                            "entities" : aSketch,
                            "endBound" : BoundingType.BLIND,
                            "depth" : definition.myDepth
                        });
            }
    
        });
    Kind regards,
    Carl.
  • kevin_o_toole_1kevin_o_toole_1 Onshape Employees, Developers, HDM Posts: 449
    Hi Carl,

    What you've got looks like the right pattern to be using, and pretty much exactly how I'd write it if you want that behavior, assuming that the behavior you want is for each region to be extruded normal to its face.

    Another way of writing the inner part of your loop (which is essentially what ends up getting called in the extrude feature that you've called directly) is:
    // Call the basic extrusion method, incrementing the id by 'i' and using each sketch and the universal 'myDepth'
    opExtrude(context, id + "extrude" + i, {
            "entities" : aSketch,
            "direction" : evOwnerSketchPlane(context, {"entity" : aSketch}).normal,
            "endBound" : BoundingType.BLIND,
            "endDepth" : definition.myDepth
    });
    
    Since the extrude direction for each entity is evaluated based on the sketch that that entity is in, it's important that aSketch refers directly to one and only one entity, which is used to determine the extrude direction. So, if you want each sketch to extrude normal to its own sketch plane, your current code is perfect.

    However, in most cases you don't need to split up a query before passing it into another feature or operation. 

    Let's say you instead wanted to extrude all the faces in the same direction, according to the sketch plane of the first face. You could then instead write your whole feature as:
    opExtrude(context, id + "singleExtrude", {
            "entities" : definition.myFaces,
            "direction" : evOwnerSketchPlane(context, {"entity" : qNthElement(definition.myFaces, 0)}).normal,
            "endBound" : BoundingType.BLIND,
            "endDepth" : definition.myDepth
    });
    
    The query definition.myFaces is passed directly into opExtrude, which extrudes all your faces in the direction of the first selected face.


    A few closing thoughts:
    • A query doesn't refer to a list of specific entities until it's evaluated, and if you need to do anything with specific entities you will need to evaluate it.
    • The same query may refer to different (or more) entities depending on *when* it's evaluated (specifically, depending on what's in the context when it's evaluated). For instance, a qEverything() will evaluated to more things as you add more geometry.
    • Operations that take in a query can take in an evaluated or an unevaluated query. Usually it's easier to just pass in a query directly, but if you do need items separated out, evaluating the query is the way to go.
    • One specific piece of feedback: Both versions of this will fail if the user passes in a non-sketch entity. So it's probably best to change your filter to "Filter" : EntityType.FACE && SketchObject.YES. Alternatively, you can allow non-sketch planes by using "Filter" : EntityType.FACE && GeometryType.PLANE, and  replace evOwnerSketchPlane with evPlane.


  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 928
    edited June 2016
    Welcome to FeatureScript!

    This looks right -- given that your faces may not be all parallel and extrude currently only extrudes in one direction, I don't think there's a better way to do what you are doing.

    Edit -- ah, I didn't see Kevin's much better response to the other copy of your post.
    Ilya Baran \ Director, Architecture and FeatureScript \ Onshape Inc
  • seaelemseaelem Member, Developers Posts: 6

    Thanks Ilya & Kevin,

    It's good to be on board and I'm enjoying getting my head around the concepts of FeatureScript.

    Confirmation that I need to evaluate a query in order to get to specific entities is really helpful and the SketchObject and GeometryType filters solve the next problem I was encountering, much appreciated.

    Kind regards,
    Carl

Sign In or Register to comment.