Difference between BRepAlgoAPI_Section and GeomAPI_IntSS for Shell-Plane Intersection

Hi, I am trying to compute the intersection between a shell and a plane with OCCT 7.9. I tested two approaches:

  1. Using BRepAlgoAPI_Section
  2. Using GeomAPI_IntSS with the plane surface

Both methods were applied to the same shell with the same plane.

  • With BRepAlgoAPI_Section, the resulting section edges look correct and smoothly follow the boundary of the intersection.
  • With GeomAPI_IntSS, the result contains strange wavy or distorted curves that do not match the smooth boundary of the shell.

Why does this difference occur? Is it a limitation of GeomAPI_IntSS, or am I misusing it? Are there recommended practices or alternative APIs for obtaining clean intersection curves ?

I have attached images for comparison.

  • The first image shows the result of BRepAlgoAPI_Section, which looks correct and smooth.
  • The next two images show the result of GeomAPI_IntSS. In these, one of the intersection curves is obviously incorrect — it looks wavy and does not match the smooth boundary of the shell.

and the code is 

Dmitrii Pasukhin's picture

Hello. Could you please share the files, to reproduce them on our side. I assume it is a bug of SS realisation. In simple scenario BRepAlgoAPI_Section is better to use with plane. But for some complex it is only possible by SS intersection. Is the original surface contains BSpline surface or surface of revolution?

Best regards, Dmitrii.

vio liu's picture

Thank you for your reply. I am unable to upload the complete file, but I can share the test model file and the code snippet. The issue remains the same as previously described.

    void getShell(const std::vector<TopoDS_Face> &faces)
    {
        BRep_Builder builder;
        builder.MakeShell(shell);  // The shell is defined as a global variable.

        for (const auto &face : faces)
        {
            builder.Add(shell, face);
        }
    }
   
    void test() 
    {
        getShell(faces); // The faces are manually selected in the model
        double offsetDistance = 1.125;

        BRepOffsetAPI_MakeOffsetShape offsetMaker;
        offsetMaker.PerformByJoin(shell, offsetDistance, 1.0e-6);

        if (!offsetMaker.IsDone()) 
        {
            std::cerr << "Error: Offset operation failed!" << std::endl;
            return;
        }
        else
        {
            TopoDS_Shape offsetShape = offsetMaker.Shape();
            shell = TopoDS::Shell(offsetShape);
            ocafdoc->addShape(shell);
            // occtviewer->addShape(shell);
            // occtviewer->View()->Redraw();
        }

        gp_Dir slice_dir(0,1,0);
        double distance = 214.525;
        gp_Vec vec(slice_dir);
        vec.Multiply(distance);
        gp_Pnt location(vec.X(), vec.Y(), vec.Z());
        gp_Pln plane(location, slice_dir);
        
        { // BRepAlgoAPI_Section
            BRepAlgoAPI_Section section(shell, plane);
            section.SetRunParallel(Standard_True);
            section.ComputePCurveOn2(Standard_True);
            section.Approximation(Standard_True);
            section.Build();
            ocafdoc->addShape(section.Shape());
            // occtviewer->addShape(shell);
            // occtviewer->View()->Redraw();
        }

        { // GeomAPI_IntSS
            BRep_Builder builder;
            TopoDS_Compound result;
            builder.MakeCompound(result);

            for (TopExp_Explorer exp(shell, TopAbs_FACE); exp.More(); exp.Next()) 
            {
                TopoDS_Face face = TopoDS::Face(exp.Current());

                std::vector<TopoDS_Edge> edges;
                BRepAdaptor_Surface surf(face);
                Handle(Geom_Surface) geomSurf = surf.Surface().Surface();
                Handle(Geom_Plane) geomPlane = new Geom_Plane(plane);
                GeomAPI_IntSS inter(geomSurf, geomPlane, Precision::Confusion());
                if (!inter.IsDone()) 
                {
                    std::cerr << "failed!" << std::endl;
                    return;
                }
                int nbCurves = inter.NbLines();
                for (int i = 1; i <= nbCurves; i++) {
                    Handle(Geom_Curve) curve = inter.Line(i);
                    if (!curve.IsNull()) {
                        TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(curve);
                        edges.push_back(edge);
                    }
                }

                for (const auto& edge : edges) {
                    builder.Add(result, edge);
                }
            }
            ocafdoc->addShape(result);
            // occtviewer->addShape(result);
            // occtviewer->View()->Redraw();
        }
    }

Attachments: