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.

Is it possible to intersect path and plane without using opPlane and deleteBodies

brad_phelanbrad_phelan Member Posts: 72 ✭✭
The below seems inefficient.

function CurveIntersectPlane(context is Context, id is Id, curve is Path, plane is Plane){
    var ppPlane = opPlane(context, id, {
            "plane" : plane,
       var r = evDistance(context, {
               "side0" : ppPlane,
               "side1" : qUnion(curve.edges)
       deleteBodies(context, id + "delete", ppPlane);

       return r;


Is this the correct way?


  • kevin_o_toole_1kevin_o_toole_1 Onshape Employees, Developers Posts: 335
    You're right, evDistance right now doesn't support a lot of non-query geometry types (Plane being the most obvious one). I agree it would be good for us to add. On our end I've created an issue for this in our internal tracking system.

    On your end, I think what you have is the most performant solution. evDistance is the right tool for the job, it just lacks the most natural interface in this case.

  • konstantin_shiriazdanovkonstantin_shiriazdanov Member Posts: 485 ✭✭✭
    edited February 12
    hi, try this numeric function, it should work ok for single intersection case

    function pathPlaneIntersection(path is Path, plane is Plane) returns Vector
    var distance = 1*meter;
    L = evPathLength(context, path);
    var parameter = 0;
    var point;

    while (distance > Tolerance.ZeroLength*millimeter)
    point = evPathTangentLines(context, path, [parameter]).tangentLines[0].origin;
    distance = abs(dot(point-plane.origin, plane.normal));

    return point;

  • brad_phelanbrad_phelan Member Posts: 72 ✭✭
    @konstantin_shiriazdanov ; Thanks that works a treat. I'll be using that.
    @kevin_o_toole_1 As a long term solution adding more numerical operations that don't require fiddling the feature tree will be great :smile:

  • ilya_baranilya_baran Onshape Employees, Developers Posts: 738
    Agreed with Kevin -- we'll add plane to the list of things evDistance can take.  If your path is planar, then I expect that getting the intersection line of the desired plane and the path plane (see intersection) would work best.  Otherwise, I would profile the two methods -- numerical methods are not terribly fast in FS and Konstantin's proposed method, while quite robust, does not have very good convergence properties.
    Ilya Baran \ Director of FeatureScript \ Onshape Inc
  • brad_phelanbrad_phelan Member Posts: 72 ✭✭
    @ilya_baran That is good to hear. Konstantins's method works and it gets the job done (I'm very pleased to have it ) but most of my code is spent in that function. I'll be happy to swap that out when a better/faster method becomes available.

  • ilya_baranilya_baran Onshape Employees, Developers Posts: 738
    I think you do have a planar case, so you should be able to compute and use a line -- that'll be fastest (be sure to precompute as much as possible when constructing the law curve, rather than when evaluating it).
    Barring, that, I did a little profiling on your code and replacing pathPlaneIntersection body with the following (passing through the feature id) speeds it up by around 10x:
            startFeature(context, id + "tempPlane");
            opPlane(context, id + "tempPlane", {
                    "plane" : plane,
                    "width" : 6 * inch,
                    "height" : 6 * inch
            var distance = evDistance(context, {
                    "side0" : qCreatedBy(id + "tempPlane", EntityType.FACE),
                    "extendSide0" : true,
                    "side1" : qUnion(path.edges)
            abortFeature(context, id + "tempPlane");
            return distance.sides[0].point;

    Ilya Baran \ Director of FeatureScript \ Onshape Inc
  • konstantin_shiriazdanovkonstantin_shiriazdanov Member Posts: 485 ✭✭✭
    edited February 13
    do startFeature()/abortFeature() give speed advantages compared to coping/creating geometry and deleting it?
    (and what if to change "Tolerance.ZeroLength*millimeter" to "Tolerance.ZeroLength*meter" :D )
  • ilya_baranilya_baran Onshape Employees, Developers Posts: 738
    I haven't timed the difference -- in this case, I'm using it because it allows me to reuse the subfeature id, rather than having to invent a new one each time.  Doing a bulk opPattern on the planes following a bulk opDelete might actually be faster here.  In any case, since he's got a planar path, using a line will be the fastest way.
    Ilya Baran \ Director of FeatureScript \ Onshape Inc
  • mahirmahir Member, Developers Posts: 571 ✭✭✭✭
    I'm with @ilya_baran. Using something like Newton's method for tracking a zero crossing might be more flexible, but it won't be very fast, taking longer for longer paths. I'd rather create and delete construction geometry vs iterating until tolerant zero. Better to do it analytically if possible.
Sign In or Register to comment.