Confused about using BRepFeat_SplitShape

Hi All,

There is a long curve in model and I project it onto a Face and hope it can trim the Face into several sub Faces. I find an member function
void Add (const TopoDS_Edge &E, const TopoDS_Face &F)
in class BRepFeat_SplitShape. But I am confused about the second parameter. Why we need this parameter and how should I pass the "F". And whether exists any simple method to trim Face by Curve(s).

Bearloga's picture

BRepFeat_SplitShape can be used to split not only a face, but a more complex shape containing faces, therefore the method Add accepts two parameters: the first is the splitting edge, and the second is the shape to be split by this edge.
The edge must have 2d curve on this face. The edge must intersect the face from bound to bound, or be closed, otherwise the algorithm will raise an exception. If the edge coincides with a part of boundary, the second method Add must be called, which accepts an edge as the second parameter. If your edge has intersections or intervals of coincidence with the face boundary, it must be split on several edges before passing to the algorithm.

Cauchy Ding's picture

Thank you very much for your explanation and hint.
Best Regards.

Dirk B's picture

Hello!
Following your explanation I did the following:
gp_Pnt p1(0.,0.,0.);
gp_Pnt p2(1.,0.,0.);
gp_Pnt p3(1.,1.,0.);
gp_Pnt p4(0.,1.,0.);

TopoDS_Edge e1 = BRepBuilderAPI_MakeEdge( GC_MakeSegment(p1, p2) );
TopoDS_Edge e2 = BRepBuilderAPI_MakeEdge( GC_MakeSegment(p2, p3) );
TopoDS_Edge e3 = BRepBuilderAPI_MakeEdge( GC_MakeSegment(p3, p4) );
TopoDS_Edge e4 = BRepBuilderAPI_MakeEdge( GC_MakeSegment(p4, p1) );

TopoDS_Wire w = BRepBuilderAPI_MakeWire( e1, e2, e3, e4 );
TopoDS_Face f = BRepBuilderAPI_MakeFace( w );

TopoDS_Edge eSplit = BRepBuilderAPI_MakeEdge( GC_MakeSegment(p1, p3) );
BRepFeat_SplitShape bss( f );
Handle_Geom_Surface surf = BRep_Tool::Surface( f );
Standard_Real umin, umax;
Handle_Geom2d_Curve cuSplit = GeomProjLib::Curve2d( BRep_Tool::Curve( eSplit, umin, umax ), surf );

TopoDS_Edge eSplit2d = BRepBuilderAPI_MakeEdge( cuSplit, surf );
bss.Add( eSplit2d, f );
bss.Build();

After this bss.Left().Extent() is zero and bss1.Shape() is the same as f. What am I doing wrong?

Thanks,
Dirk

Bearloga's picture

You should restrict eSplit2d by boundaries of the face. In your case (direct line and planar face) values umin and umax will be suitable, but in general case you should intersect curve 2d of the edge by curves 2d of boundary edges of the face to get restriction parameters. Note that in general case this task is not so simple, because you can obtain several intersection points, or even interval interferences, and might need to create several section edges, if the boundary of the face is not convex, or the section curve is not direct line.

Dirk B's picture

Thanks for your comments Bearloga. Here is the working code:
Standard_Real umin, umax;
Handle_Geom_Curve curve = BRep_Tool::Curve( e, umin, umax );
Handle_Geom2d_Curve cu2d = GeomProjLib::Curve2d( curve, surf );
Handle_Geom2d_TrimmedCurve tcu2d = new Geom2d_TrimmedCurve( cu2d, umin, umax );
TopoDS_Edge eSplit2d = BRepBuilderAPI_MakeEdge( tcu2d, surf );
bss1.Add( eSplit2d, f );
bss1.Build();

But now if you use the generated faces of BRepFeat_SplitShape in either BRepAlgo or BRepAlgoAPI routines, occ just ends with a segmentation fault, so I guess I'll go back to sweeping the splitting edge to a face. A test showed that the boolean operations do not crash then.

Dirk

Bearloga's picture

Dirk, I didn't understand the phrase "sweeping the splitting edge to a face".
Segmentation fault may be caused by absence of 3d curve in the splitting edge. You should not construct the new edge with 2d curve, but add this 2d curve to the existing edge which already contains 3d curve. Use for that BRep_Builder::UpdateEdge().

Dirk B's picture

Bearloga,
here is the code that produces the segmentation fault:

void TestSplit::run2()
{
gp_Pnt p1(0.,0.,0.);
gp_Pnt p2(1.,0.,0.);
gp_Pnt p3(1.,1.,0.);
gp_Pnt p4(0.,1.,0.);

TopoDS_Edge e1 = BRepBuilderAPI_MakeEdge( GC_MakeSegment(p1, p2) );
TopoDS_Edge e2 = BRepBuilderAPI_MakeEdge( GC_MakeSegment(p2, p3) );
TopoDS_Edge e3 = BRepBuilderAPI_MakeEdge( GC_MakeSegment(p3, p4) );
TopoDS_Edge e4 = BRepBuilderAPI_MakeEdge( GC_MakeSegment(p4, p1) );

TopoDS_Wire w = BRepBuilderAPI_MakeWire( e1, e2, e3, e4 );
TopoDS_Face f = BRepBuilderAPI_MakeFace( w );

TopoDS_Edge eSplit = BRepBuilderAPI_MakeEdge( GC_MakeSegment(p1, p3) );

BRepFeat_SplitShape bss1( f );
Handle_Geom_Surface surf = BRep_Tool::Surface( f );

Standard_Real umin, umax;
Handle_Geom_Curve curve = BRep_Tool::Curve( eSplit, umin, umax );
Handle_Geom2d_Curve cu2d = GeomProjLib::Curve2d( curve, surf );
Handle_Geom2d_TrimmedCurve tcu2d = new Geom2d_TrimmedCurve( cu2d, umin, umax );
TopoDS_Edge eSplit2d = BRepBuilderAPI_MakeEdge( tcu2d, surf );
bss1.Add( eSplit2d, f );
bss1.Build();

TopoDS_Shape fLeft = bss1.Left().First();

//create a circle face
Handle_Geom_Circle circ = GC_MakeCircle( gp::Origin(), gp::DZ(), .5 );
BRepBuilderAPI_MakeEdge eCirc( circ );
BRepBuilderAPI_MakeWire wCirc( eCirc );
BRepBuilderAPI_MakeFace fCirc( wCirc );

BRepAlgoAPI_Common com( fLeft, fCirc ); // here the segmentation fault occurs
}

As to the "sweeping the splitting edge to a face": For splitting a face with another face I am currently testing the Partition_Spliter class from the geom project http://sourceforge.net/projects/salomegeometry/. If I use BRepOffsetAPI_MakePipe on eSplit to pipe it along the normal of the planar face and use Partition_Spliter on the two faces, everything works perfectly, and a later call to BRepAlgoAPI_Common also doesn't produce a segmentation fault. This is my workaround for now.

Dirk

Bearloga's picture

I already told a possible cause of exception and a way to overcome it in my previous post.

Dirk B's picture

Yes, it solved the problem.
Thanks,
Dirk