Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape, CAD, maker project and design.

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.

Orient a sketch

fmafma Posts: 57Member
Hi!

I'm writing a FeatureScript to help designing repetitive tasks for metal sheet lasercut:

https://cad.onshape.com/documents/9fcacffa14bbcb794a372061/w/1cf9683d04a93c666f667b13/e/66c6c1aab8f0abe0ba69579d

This idea of this script is to generate the M3 nut trap for the assembly. See this for usage:

https://cad.onshape.com/documents/9fcacffa14bbcb794a372061/w/1cf9683d04a93c666f667b13/e/27132e161bac5e17cedb66ba

I generate the cut profile with a polyline, but I need to turn it so the cut is normal to the edge of the part. How can I automatically orient the polyline sketch? are the selected point/part enough the do that?

Thanks for your help.

Comments

  • lanalana Posts: 144Onshape Employees
    @fma ;
    If you create the sketch with newSketchOnPlane() than you can control coordinate system of the sketch plane. Align xDir of the plane with the direction of the edge (or normal to it).

    Alternative is to use opTransform on bodies created by sketch (qCreatedBy(id + "sketch1", EntityType.BODY) ).

  • fmafma Posts: 57Member
    Sorry, my question was not well asked. My problem is to actually find the normal to the side of the part, at the given point, so I can set the correct xDir vector of the newSketchOnPlane()...
  • lanalana Posts: 144Onshape Employees
    Sorry, misunderstood you.  Still not sure what "side of the part" is . If it is a face you can use

    evFaceTangentPlane().normal . If it is an edge, var edgeDir = evEdgeTangentLine().direction would give you edge direction

    cross(sketchPlane.normal, edgeDir) will give you direction in sketch plane normal to edgeDir.

    Hope now I'm closer to the answer.

  • fmafma Posts: 57Member
    edited May 17
    Well, I'm still unable to retreive all the objects I need to do the maths... Let me explain in a better way.

    Step 1: sketch

    step 2: extrusion (metal sheet)

    step 3: cut

    As you see, I give the vertices and the body to cut. But I don't know how to re-orient my polyline.
    (in this function, I give 'vertex' and 'part'):

        const center = evVertexPoint(context, {"vertex" : vertex});
        const plane1 = plane(center, vector(0, 0, 1), vector(1, 0, 0));  // <<< need to give the correct x direction
        opPlane(context, id + "plane1", {"plane": plane1});
        const sketch1 = newSketchOnPlane(context, id + "sketch1", {
            'sketchPlane': plane1
        });
        skPolyline(sketch1, "polyline1", {
            'points': [
                vector(-3.1 / 2,  0) * millimeter,
                vector(-3.1 / 2, -3) * millimeter,
                vector(-5.55 / 2, -3) * millimeter,
                vector(-5.55 / 2, -7) * millimeter,
                vector(-3.1 / 2, -7) * millimeter,
                vector(-3.1 / 2, -9) * millimeter,

                vector( 3.1 / 2, -9) * millimeter,
                vector( 3.1 / 2, -7) * millimeter,
                vector( 5.55 / 2, -7) * millimeter,
                vector( 5.55 / 2, -3) * millimeter,
                vector( 3.1 / 2, -3) * millimeter,
                vector( 3.1 / 2,  0) * millimeter,

                vector(-3.1 / 2,  0) * millimeter,
            ]
        });
        skSolve(sketch1);

        // Extrude (remove)
        extrude(context, id + "extrude1", {
            "entities": qCreatedBy(id + "sketch1", EntityType.FACE),
            "endBound": BoundingType.BLIND,
            "depth": 3 * millimeter,
            'operationType': NewBodyOperationType.REMOVE,
            'defaultScope': false,
            'booleanScope': part
        });
     
  • lanalana Posts: 144Onshape Employees
    edited May 17
    please try qContainsPoint(qSketchFilter(qEverything(EntityType.EDGE), SketchObject.YES), center) to recover the sketch edge .
    It is not ideal, but if it gives you only one edge , that is the edge you want. If we had something like qCreatedByTheSameOp() query, you could've narrowed it down to the sketch supplying the point.

    As a way of making your feature more general you can call

    evOwnerSketchPlane(context, {'entity' : vertex}); to recover original sketch plane.

    And I don't think call opPlane(context, id + "plane1", {"plane": plane1}); is needed.

  • fmafma Posts: 57Member
    Ok, thanks for the tips!
  • konstantin_shiriazdanovkonstantin_shiriazdanov Posts: 218Member ✭✭✭
    edited May 17
    assuming vertices to be the query containing all the sketch points you need:

    vertexList = evaluateQuery(vertices);
    allEdges = qSketchFilter(qGeometry(qEverything(), GeometryType.LINE), SketchObject.YES);
    for vertex in vertexList do
    {
    zVector = evOwnerSketchPlane(context, vertex);
    vertexPoint = evVertexPoint(vertex);
    edge = qContainsPoint(allEdges, vertex);
    xVector = evLine(context, edge).direction;
    workPlane = plane(vertexPoint, zVector, xVector);
    ....
    }

  • fmafma Posts: 57Member
    We are close:

    but the xVector is not correctly oriented ; any idea how to retreive the correct direction?
  • NeilCookeNeilCooke Posts: 861Moderator, Onshape Employees
    edited May 17
    There is no way to tell unless you use something like qContainsPoint to see if the opposite end of your nut cut is touching the sheet metal body. 
  • konstantin_shiriazdanovkonstantin_shiriazdanov Posts: 218Member ✭✭✭
    edited May 17
    this should give a correct y vector
    yVector = -filter(evaluateQuery(qEdgeAdjacent(edge, EntityType.FACE)), function(face){
    return !parallelVectors(evPlane(face).normal, zVector)})[0];
    xVector = cross(yVector, zVector)
  • lanalana Posts: 144Onshape Employees

    wrap the allEdges query above into sheet body filter

    var allEdges = qBodyType(qSketchFilter(qGeometry(qEverything(), GeometryType.LINE), SketchObject.YES), BodyType.SHEET); 

    Once you got the edge:

    var face = qEdgeAdjacent(edge, EntityType.FACE);

    var edgeDir = evEdgeTangentLine(context , {'edge' : edge, 'parameter' : 0.5, 'face' : face}).direction //will give you "oriented" direction of the edge in the face  - face is to the left of the edge.

    var xVector = cross(evPlane(face).normal, edgeDir);  // Is normal to edge pointing into the face.



  • fmafma Posts: 57Member
    Ok, I finally got something working! Thank you all for your propositions. Lana's last code gives the answer (in my case, the needed xVector is edgeDir, but it is just the way I defined my polyline).

    function process(context is Context, id is Id, part, vertex)
    {
        const zVector = evOwnerSketchPlane(context, {'entity': vertex}).normal;
        const vertexPoint = evVertexPoint(context, {'vertex': vertex});
        const edges = qBodyType(qSketchFilter(qGeometry(qEverything(), GeometryType.LINE), SketchObject.YES), BodyType.SHEET); 
        const edge = qContainsPoint(edges, vertexPoint);
        const face = qEdgeAdjacent(edge, EntityType.FACE);
        const edgeDir = evEdgeTangentLine(context , {'edge' : edge, 'parameter' : 0.5, 'face' : face}).direction;
        const plane1 = plane(vertexPoint, zVector, -edgeDir);

        const sketch1 = newSketchOnPlane(context, id + "sketch1", {
            'sketchPlane': plane1
        });
        skPolyline(sketch1, "polyline1", {
            'points': [
                vector(-3.1 / 2,  0) * millimeter,
                vector(-3.1 / 2, -3) * millimeter,
                vector(-5.55 / 2, -3) * millimeter,
                vector(-5.55 / 2, -7) * millimeter,
                vector(-3.1 / 2, -7) * millimeter,
                vector(-3.1 / 2, -9) * millimeter,

                vector( 3.1 / 2, -9) * millimeter,
                vector( 3.1 / 2, -7) * millimeter,
                vector( 5.55 / 2, -7) * millimeter,
                vector( 5.55 / 2, -3) * millimeter,
                vector( 3.1 / 2, -3) * millimeter,
                vector( 3.1 / 2,  0) * millimeter,

                vector(-3.1 / 2,  0) * millimeter,
            ]
        });
        skSolve(sketch1);

        // Extrude (remove)
        extrude(context, id + "extrude1", {
            "entities": qCreatedBy(id + "sketch1", EntityType.FACE),
            "endBound": BoundingType.BLIND,
            "depth": 3 * millimeter,
            'operationType': NewBodyOperationType.REMOVE,
            'defaultScope': false,
            'booleanScope': part
        });

        opDeleteBodies(context, id + "delete1", {
            'entities': qUnion([
                qCreatedBy(id + "sketch1")
            ])
        });
    }

  • owen_sparksowen_sparks Posts: 571Member, Developers PRO
    Forgive me butting in.

    Presumably you'll have a 2nd part that bolts perpendicular to the face you have your input vertex on?

    If so would it make sense to have the input vertex coincident with the centre line of the bolt's axis rather than the bottom edge?  Presumably you'd have that position defined already so it'd be less reference geometry to build.  You could also have the feature make the round through hole in the 2nd plate perhaps?  (Similar to the cam an dowel FS.)

    Just thinking out loud, forgive the intrusion.

    Cheers, Owen S.
    Production Engineer
    HWM-Water Ltd
  • fmafma Posts: 57Member
    Yes, there is a 2nd part perpendicular (have a look at my top 2nd link).

    But I don't need to define the bolt axis, and it will be more work to do that. The reason is the parts are lasercut metal sheets. So, a 2D sketch is all we need to define geometry; the width is constant (3mm).

    I wanted to write a few 3D tools to move out all boring tasks outside of the sketch, where we only focus on the global assembly. This include:

    - M3 nuts trap
    - angles cut (for easier assembly)

    So, for this script, I only need to put a point on the sketch, where we need to make the M3 nut trap.
  • owen_sparksowen_sparks Posts: 571Member, Developers PRO
    edited May 18
    Understood.

    Sorry, I'd assumed you were using multi-part modeling in a partstudio, or in context editing from an assembly.  So ultimately you could have a single feature that says here's a bunch of points, I want to put a M4 bolts here, with washers, though this part, (so make bolts, washers and through holes) then make the nut cutouts in the other parts and add the nuts.

    Owen S.
    Production Engineer
    HWM-Water Ltd
  • fmafma Posts: 57Member
    In fact, we are migrating a design started 3 years ago, with Librecad, a Free 2D software. So, we imported DXF, and just extruded them.

    Our next step is to fully constrain the DXF sketches, and start using these 3D tools.

    But ultimately, you're right, it would be much better to make a multi-parts PartStudio, et adapt the 3D tools the way you mentioned.
  • owen_sparksowen_sparks Posts: 571Member, Developers PRO
    Sounds like fun.  Very nice project by the way.
    O.S.
    Production Engineer
    HWM-Water Ltd
  • fmafma Posts: 57Member
    Thanks!

    This is a nice collaborative work, and we have to say that Onshape is really great for such community projects. Most of use started to learn Onshape only a few months ago, and we made this migration in only a few weeks, on our free time. Amazing! I love this software!
  • lanalana Posts: 144Onshape Employees
    @fma
    Cheers! I'm glad Onshape is working out for you. Thank you for putting time and effort into mastering FeatureScript.
  • billy2billy2 Posts: 807Member, OS Professional, Mentor, Developers PRO
    Maybe I'm too late, but here's a way to produce a sketch anywhere & any orientation.

    https://forum.onshape.com/discussion/5824/sketch-plane-using-3-vectors#latest


Sign In or Register to comment.