Help in intersection between wire and plane

Good afternoon, I am trying to find the best way to find the point of intersection between a wire and a plane (perpendicular). I have tried 2 different approaches: - using the BRepAlgoAPI_Section. This provides the correct result but it takes around 40s to execute 800+ intersections - using GeomAPI_IntCS. This is faster (less than 4s for the same amount of intersections), but the results are not accurate. - using the GeomAPI_ExtremaCurveCurve produces the same inaccurate results like the previous method.

The code basically iterates through the edges of a wire and finds the edge that has an intersections. I can probably have some optimization is I jump directly to the right edge, without looping through all of them, but I think this will not have a huge impact in performances.

#region accurate intersection BRepAlgoAPI_Section

//var abscissaPoint = new GCPnts_AbscissaPoint(adaptorAl, station, adaptorAl.FirstParameter);
//adaptorAl.D0(abscissaPoint.Parameter, out var pointOnAlignment);

//var pntToProject = new gp_Pnt(station + _alignment.StartStation, 0, 0);

//var section = new BRepAlgoAPI_Section(wirePrf, new gp_Pln(pntToProject, gp_Dir.DX),false);
////section.ComputePCurveOn1(true);
////section.Approximation(true);
//section.Build();

//var result = section.Shape;
//var exp = new TopExp_Explorer(result, TopAbs_ShapeEnum.TopAbs_VERTEX);
//if (exp.More)
//{
//    var vertex = exp.Current as TopoDS_Vertex;
//    var projectedPoint = vertex?.Pnt;
//    profile3dPoints.Add(new gp_Pnt(
//        pointOnAlignment.X - _basePoint.X,
//        pointOnAlignment.Y - _basePoint.Y,
//        projectedPoint!.Y - _basePoint.Z
//        ));
//}
#endregion
#region not accurate intersection GeomAPI_IntCS
//var pntToProject = new gp_Pnt(station + _alignment.StartStation, 0, 0);

//var found = false;
//while (explorer.More && !found)
//{
//    var edge = explorer.Current;
//    var curve = new BRepAdaptor_Curve(edge);
//    var plane = new gp_Pln(pntToProject, gp_Dir.DX);
//    var intersection = new GeomAPI_IntCS (curve.Curve.Curve, new Geom_Plane(pntToProject, gp_Dir.DX));
//    if (intersection.IsDone && intersection.NbPoints > 0)
//    {
//        var abscissaPoint = new GCPnts_AbscissaPoint(adaptorAl, station, adaptorAl.FirstParameter);
//        adaptorAl.D0(abscissaPoint.Parameter, out var pointOnAlignment);

//        var pt = intersection.Point(1);

//        profile3dPoints.Add(new gp_Pnt(
//            pointOnAlignment.X - _basePoint.X, 
//            pointOnAlignment.Y-_basePoint.Y, 
//            pt.Y - _basePoint.Z
//            ));
//        explorer.Init(wirePrf);
//        found = true;
//    }
//    explorer.Next();
//}
#endregion
#region using GeomAPI_ExtremaCurveCurve
//var found = false;
//while (explorer.More && !found)
//{
//    var pntToProject = new gp_Pnt(station + _alignment.StartStation, 0, 0);

//    var edge = explorer.Current;
//    //var geomCurve = new BRepAdaptor_Curve(edge).Curve.Curve;
//    var geomCurve = BRep_Tool.Curve(edge, out var first, out var last);
//    var line = new gp_Lin(pntToProject, gp_Dir.DY);
//    var geomLine = new Geom_Line(line);

//    var extrema = new GeomAPI_ExtremaCurveCurve(geomLine, geomCurve);
//    if (extrema.NbExtrema > 0)
//    {
//        var abscissaPoint = new GCPnts_AbscissaPoint(adaptorAl, station, adaptorAl.FirstParameter);
//        adaptorAl.D0(abscissaPoint.Parameter, out var pointOnAlignment);

//        extrema.Points(1, out var p1, out var p2);
//        var distance = extrema.Distance(1);

//        profile3dPoints.Add(new gp_Pnt(
//            pointOnAlignment.X - _basePoint.X,
//            pointOnAlignment.Y - _basePoint.Y,
//            p2.Y - _basePoint.Z
//            ));
//        explorer.Init(wirePrf);
//        found = true;
//    }
//    explorer.Next();
//}
#endregion

I have performed the calculation in both Dynamo and Grasshopper (they both give me the same results), and both of them are lighting fast and definitely they don't take 40s.

Can someone give me some direction? What am I doing wrong? Is this the right way? Thanks!

Dmitrii Pasukhin's picture

Hi,

The first idea is fast filter possible edges by Bounding Box of each edge(just to check that they at least can be intersected).

Bnd_Box planeBoundingBox;
BRepBndLib::Add(plane, planeBoundingBox);

Bnd_Box curveBoundingBox;
BRepBndLib::Add(edge, curveBoundingBox);

Standard_Real xmin1, ymin1, zmin1, xmax1, ymax1, zmax1;
Standard_Real xmin2, ymin2, zmin2, xmax2, ymax2, zmax2;
planeBoundingBox.Get(xmin1, ymin1, zmin1, xmax1, ymax1, zmax1);
curveBoundingBox.Get(xmin2, ymin2, zmin2, xmax2, ymax2, zmax2);

if (xmax1 >= xmin2 && xmax2 >= xmin1 &&
    ymax1 >= ymin2 && ymax2 >= ymin1 &&
    zmax1 >= zmin2 && zmax2 >= zmin1)
{
  // perform any intersections 
}

Another thing I recommend to try the next class: GeomAPI_ExtremaCurveSurface. Geometry can be extracted from Edge and should be created as a Trimmered based on Edge start and end parameters.

Best regards, Dmitrii.

Cesare Caoduro's picture

I have a way to find which edge is going to be effected, the problem I have is that it takes too long using BRepAlgoAPI_Section and all the other methods are not accurate enough (including GeomAPI_ExtremaCurveSurface). I have attached an image to explain it better.