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.


Proper way to extract/query face/vertex/edge out of a rectangle extrude (body) in Featurescript

sven_kautlenbachsven_kautlenbach Member Posts: 3
edited October 2017 in FeatureScript

Trying to build some simple parts as of now and have some features already in stock.
For example a rectangle extrude.

I would like to build some other sketches and features upon a certain face (currently the one marked with red vertices). I have a code where I can get the face/vertices/edges for next operations:
        opExtrude(context, id + "extrude1", {
                "entities" : qSketchRegion(id + "rect", false),
                "direction" : plane.normal,
                "endBound" : BoundingType.BLIND,
                "endDepth" : definition.thickness
        var q = qCreatedBy(id + "extrude1", EntityType.FACE);
        debug(context, q);
        var t = qNthElement(q, 3);
        var te = qEdgeAdjacent(t, EntityType.EDGE);
        var tp = qVertexAdjacent(t, EntityType.VERTEX);
        debug(context, tp);
The problem I see is the line having,
qNthElement(q, 3);
since the "3" is a numb (or dumb) constant as of now, can I be sure that the underlying std functionality will keep this behavior after every build and in the future versions? If not, should I refactor to some other approach extracting a specific face(or any other vertex/edge) out of a body?

Thanks in advance.


  • Options
    Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,646
    Hi @sven_kautlenbach !

    I think the right query for you may be something along the lines of:
    var desiredFace = qContainsPoint(qCreatedBy(id + "extrude1", EntityType.FACE), somePointInSpace);
    where creating somePointInSpace looks something like:
    var somePointInSpace = vector(1, 2, 3) * inch;
    but replaced with the point that you're looking for.  If you can't calculate some point that falls on your face in advance, I can come up with other suggestions, but this is the simplest/easiest way.
    Jake Rosenfeld - Modeling Team
  • Options
    sven_kautlenbachsven_kautlenbach Member Posts: 3

    It works

    Resulting code:

            opExtrude(context, id + "extrude1", {
                    "entities" : qSketchRegion(id + "rect", false),
                    "direction" : plane.normal,
                    "endBound" : BoundingType.BLIND,
                    "endDepth" : definition.thickness
            var h = vector(definition.length, -definition.thickness / 2, definition.height / 2);
            debug(context, h);
            var desiredFace = qContainsPoint(qCreatedBy(id + "extrude1", EntityType.FACE), h);
            debug(context, desiredFace);

    But I do want to elaborate more. See, I like kinda object handling oriented (does not have to be classical OOP language mechanisms) solution to my code, where some data is simply hidden/separated from other code entities (does not have to be technically but a model wise). Right now when generating the point in space, definition map members are used to easily calculate the point where the desired face is. But I would like to keep this information separately (although I can easily use it everywhere in this feature). The data and object handling I would like to have could be summarized as:
    1) User input -> part studio parameters object (definition)
    2) definition -> rect sketch
    3) rect -> extrude
    4) extrude -> some operations -> desired face

    Maybe it is overkill, but is there a way to achieve this without "hacking" static-ish vectors in the code? Something like I wanted to achieve in my first example.


  • Options
    Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,646
    edited November 2017

    You could always do something like the following:
    function createBlock(centerPoint is vector, planeNormal is Vector, width is ValueWithUnits, depth is ValueWithUnits, height is ValueWithUnits) returns Query
        1. sketch a recctangle using centerPoint, planeNormal, width, and depth
        2. extrude the rectangle by height
        3. calculate a point on the face you want based on the center point, width, depth, and height
        4. return a query for the face in question
    If you do something like this, you could pass in any centerPoint and set of dimensions and not have it rely on the definition to calculate your point.  Chances are that you'll pass in definition variables to the method, but I think what you're getting at here is that you'd rather have modular functionality (like this) rather than hard-coding dependencies on the definition.

    You may also be interested in qCapEntity(...) ( https://cad.onshape.com/FsDoc/library.html#qCapEntity-Id-boolean ).  This can get you the top or bottom cap of the extrude, or all of the side faces of the extrude with:
    var capFaces = qUnion([qCapEntity(id + "extrude", true), qCapEntity(id + "extrude", false)]);
    var sideFaces = qSubtraction(qCreatedBy(id + "extrude", EntityType.FACE), capFaces);

    Jake Rosenfeld - Modeling Team
  • Options
    lanalana Onshape Employees Posts: 703
    Here is a geometry-independent solution.
    If you create sketch lines of the rectangle sketch explicitly, you know the sketch id of the line you are interested in. Then you can use tracking query to find side face corresponding to that line:
    skLine(sketch, "theLineToTrack", {..});
    var lineTrackingQ = startTracking(context, id + "rectangle", "theLineToTrack");
    var t = qEntityFilter(lineTrackingQ, EntityType.FACE);

    If you evaluate lineTrackingQ after extrude, you'll get side face and two cap edges corresponding to this line.
Sign In or Register to comment.