Cut a Face with a Curve

Hi All,

I posted somethings about this issue, but I had no success, yet.
So, my problems is:
I have a Face with 2 Holes (face.brep that comes with OCC). I also have a curve laying down this face perpendicularly.
My goal is to split this face in 2 faces using the curve.

I've tried to solve this problem with BRepAlgoAPI_Cut, BRepAlgoAPI_Section and BRepFeat_SplitShape. But, as I told, I had no success.

Could someone help me, please?

Thanks in Advance.
Regards,

Fotis Sioutis's picture

Hi !

I tested the functionality you ask for, using GEOMAlgo_Splitter from salome's GEOM project:

You can download the package at :
http://sourceforge.net/projects/salomegeometry

You can either directly use the class like :

GEOMAlgo_Splitter PS;

PS.AddShape(aShape);
PS.AddTool(aCutter);
PS.Perform();

theResult = PS.Shape();

or again you can study how the class works and implement your own variant :)

Greets !

Fotis

tmacedo29's picture

Hello Fotis Sioutis,

First, I'd like to thank you about your prompt answer! =)
I didn't try with SALOME code, yet. Is there some difference between BRepFeat_SplitShape and GEOMAlgo_Splitter?
My problem with BRepFeat_SplitShape is exception from the builder when I've tried to Build.
(With BRepAlgoAPI_Cut I have a ErrorStatus() returning 110)

Regards,

Fotis Sioutis's picture

Hello !

Unfortunatelly i never used BRepFeat_SplitShape, so i cannot say much about its usage.As far as i can tell GEOMAlgo_Splitter is a tottally different implementation for partinioning of "shapes".Even in complex shapes i have good results ! I think the usage of BRepAlgoAPI_Cut for partinioning is not the right method to use ! Anyway if you want you can build only the NTM... and the GEOMAlgo packages and give it a try !

Good luck !

PS:It would be good to post here if you will manage something out of it !

Fotis Sioutis's picture

Correction: I meant NMT* and GEOMAlgo packages

tmacedo29's picture

Hello Fotis Sioutis,

Again thank you for your prompt answer! =)

I can't use SALOME functions in my project. But I'll see how it's working!
Thank you very much for your help!

Best Regards,

Bearloga's picture

Please, tell us what are the operands of the call to BRepAlgoAPI_Cut? I they are a face and an edge then the result is expected. A face must be cut by a solid rather than an edge.

tmacedo29's picture

Hello Bearloga,

now I understood. I didn't know about it!
I will try to solve this problem creating a solid from this EDGE.

do you or someone have any idea about how to do this?

Thanks in advance.
Regards,

Bearloga's picture

In another branch I have told you that you need to make an extrusion of your edges to achieve a prism-like shape. If your edge is not a closed contour then it should be long enough in order its end points did not lie inside face. After making a prism, you will get a face or a shell. After that you should construct a solid with BRepPrimAPI_MakeHalfSpace. The reference point there defines the side of the shell that will be internal to the solid.
I agree with Fotis that it is not the best way for shape partitioning, I think in Salome the splitter was introduced to fill the lack of this functionality in OCC. But if you case is as simple as you tell, and you always need to get only the one part of the split shape, then cutting by prism is the right thing.
Good luck

tmacedo29's picture

Thank you Fotis Sioutis, and Bearloga!

I'll study the SALOME's code and try to do something similar, because that case is simple but I'll have more complex samples.

Thank again!
Regards,

Francois Lauzon's picture

Hello Thiago,
we have been using BRepFeat_SplitShape to do something similar with success. Here is a code sample :

BRepFeat_SplitShape splitter1(aFace);
splitter1.Add(aWire,aFace);
splitter1.Build();

aWire is really only an edge that sit on the face. Then, to get the result you could use the list of shape from DirectLeft(), Left() or Modified(aFace) (in this case, you will get two faces, one on each side of your wire).

TopTools_ListIteratorOfListOfShape iter(splitter1.Modified(aFace));
for (;iter.More();iter.Next()) {
// do something with it
iter.Value();
}

Note that you need to have an edge/wire that is projected onto the face (using BRepProj_Projection, BRepAlgoAPI_Section, ...)

Good Luck,
Francois.

tmacedo29's picture

Hello François,

Thank you again for your help.
I will try it too! =)
I think my problem was about the projected curve/edge/wire. When I have a "curved" surface (Cylindrical Surface) I'm not able to project a curve on it.
Could you also help me on this problem?

Thanks in Advance.
Regards,

Francois Lauzon's picture

Hello Thiago,
here is a sample code (extracted from something we do here, might not be exact but should be a really good starting point) to split a conical shell with a plane (could be a cylinder with another face build from your curve).
First I do a section between the two face, then a get a bunch of intersecting edge, and I do the link between those edges and faces for the Split operation. The faces that need to be split are split, and I get the result in the Shape() method, then I have to chose what to do with the new faces (in my case, I keep only faces on one side of the plane, but you might want to keep them on both sides...):

// do a section
BRepAlgoAPI_Section asect(aBody,aPlane, Standard_False);
asect.ComputePCurveOn1(Standard_True);
asect.Approximation(Standard_True);
asect.Build();

if (asect.IsDone()) {
// do a split
TopoDS_Shape R=asect.Shape();
QList edges;
BRepFeat_SplitShape asplit(aBody);
for (TopExp_Explorer Ex(R,TopAbs_EDGE); Ex.More(); Ex.Next()) {
TopoDS_Shape anEdge=Ex.Current();
TopoDS_Shape aFace;
if (asect.HasAncestorFaceOn1(anEdge,aFace)) {
TopoDS_Face F=TopoDS::Face(aFace);
TopoDS_Edge E=TopoDS::Edge(anEdge);
edges.append(E);
asplit.Add(E,F);
}
}
asplit.Build();

// no edge, shape stay the same, means no intersection between plane and body
if (edges.count()==0)
return;

// split is done
if (asplit.IsDone()) {

// go through all faces and keep those you want
// in my case, I keept all those that are one the positive side of my
// section plane
for (TopExp_Explorer iter(asplit.Shape(),TopAbs_FACE);iter.More();iter.Next()) {
if (iter.Current().ShapeType()==TopAbs_FACE) {

}
}
}
}

Good Luck,
francois.

tmacedo29's picture

Just another comment...

I tried to do the split operation using BRepFeat_SplitShape as you told me.
I added the EDGE into a WIRE, and use your code. I tried it using face.brep file that comes with OCC source/data and a line made by this 2 points:
gp_Pnt p5( 50., -100., 30.);
gp_Pnt p6(500., 500., 30.);

But, I had that exception (Standard_ConstructionError) again!
Thank you anyway!

Divya's picture

hi do u know whether opencascade browser is supported by visual studio9.0.?

Bearloga's picture

Dear Thiago,

I already told you in another discussion that SplitShape algorithm has some restrictions. It seems you did not understand that post. Therefore now I'll try to present a simple workaround of these restrictions in example draw script that plays with your data, and successfully splits face.brep.

restore face.brep f
axo;fit
vertex v1 50 -100 30
vertex v2 500 500 30
edge e v1 v2
# find extrema between f and e
distmini d f e
# make edge from projection vertices on the face boundaries
subshape d v 1
subshape d2 v 1
edge eproj d_1 d2_1
#split shape by projected edge
splitshape r f f eproj

And now no exception, the shape r contains two faces.

tmacedo29's picture

Dear Bearloga,

I've already understood what you said. But, our colleague Fotis Sioutis asked me to try again with BRepFeat_SplitShape. I'm not using this class anymore because these exceptions you told me.
Anyway thank you for your help again.
But, as I already told, my problem now is project a curve on a curved surface. (like face1.brep)

If you or someone could help in this issue too I'll appreciate! =)

Thanks in Advance!
Regards,

Fotis Sioutis's picture

I never asked to try again with BRepFeat_SplitShape.In fact i said "Unfortunatelly i never used BRepFeat_SplitShape, so i cannot say much about its usage".All i did was just to propose another more proper way (at my opinion) to solve your shape partitioning problem.

Good luck with your task !

Fotis

tmacedo29's picture

It's that I meant! =)

Thank you!

Bearloga's picture

As François said, you can use the class BRepProj_Projection if you know the direction of projection, otherwise have a look at BRepAlgo_NormalProjection.

Cauchy Ding's picture

If the curve is not printed on the face well, or not cross the face well, it's hard to trim the face properly. So I think the process is:
1. Extend curve properly and make sure the printed result can cross the face.
2. Project curve onto the face.
3. Trim the face using the projected curve as the trim tool. BRepFeat_SplitShape is proper.

Good luck.

Jun WANG's picture

Hi, Thiago, have you carried out the cut operation ??? If so, can you share me your codes? Thanks a lot.

Actually I use two methods to cut face with a curve:
(1)BRepFeat_SplitShape
(2)GEOMAlgo_Splitter

Method(1) performs quickly and sometimes there are some bug, i.e. the intersection boundary is jagged. And also, sometimes runs unsuccessfully.

Method(2) runs very slowly. And I can not get the result. I assume that the function-GEOMAlgo_Splitter::Generated() returns the split results, but I am not sure. Can anyone give me some suggestion ??? Fotis Sioutis, can you give me some advise???

Fotis Sioutis's picture

You can use GEOMAlgo_Splitter like :

GEOMAlgo_Splitter PS;

PS.AddShape(aShapeArg);
PS.AddTool(aToolArg);
PS.Perform();

aResult = PS.Shape();

Where the aResult keeps the aShapeArg with partirioned elements.

Be aware that the aToolArg must be in contact with the aShapeArg and this imposes that you may have to extrude your edge in order to create a face that intersects the aShapeArg, or create a new projected edge on tha face.

Jun WANG's picture

Thank you so much. I get it.

Jun WANG's picture

Hi, Sioutis. Thanks a lot. It works very well.
As you mentioned, prior to splitting, the projected edge should be obtained firstly. I use the BRepAlgoAPI_Section to get the projected edge. After lots of testing, there are some bugs with this API. That is, there are some unsuccessful instances. Therefore, I try to split a surface directly with a cylinder surface extracted from an edge, instead of getting the section edge(projected edge) firstly, by means of GEOMAlgo_Splitter. And it is working robustly. Here is the sample codes. Hopt it will be helpful.

Method #1: Create the projected firstly, then to split surface. (Sometimes it fails...)
-----------------------------------------------------------------------
TopoEdge aEdge = ...; // The original edge, which has not been projected yet.
gp_Vec vector = ...; // The axis vector of cylinder to be created;

// 1. Create the cylinder;
BRepSweep_Prism CylSurf (aEdge , vector, Standard_False);
TopoDS_Shape aCylinder = CylSurf.Shape();

// 2. Create the intersection curve;
BRepAlgoAPI_Section asect(aParentFace, aCylinder, FALSE);
asect.ComputePCurveOn1(TRUE);
asect.Approximation(TRUE);
asect.Build();
if(!asect.IsDone())
return;
TopoShape aInterCurve = asect.Shape();

// 3. Split surface with the intersection curve;
CArray edges;
edges.SetSize(0, -1);
BRepFeat_SplitShape asplit(aParentFace);
for (TopExp_Explorer Ex(aInterCurve,TopAbs_EDGE); Ex.More(); Ex.Next())
{
TopoDS_Shape anEdge=Ex.Current();
TopoDS_Shape aFace;
if (asect.HasAncestorFaceOn1(anEdge,aFace))
{
TopoDS_Face F=TopoDS::Face(aFace);
TopoDS_Edge E=TopoDS::Edge(anEdge);
edges.Add(E);
split.Add(E,F);
}
}
asplit.Build();

// 3.1 no edge: shape stay the same, means no intersection between plane and body;
if (edges.GetSize()==0)
return;

// 3.2 split is done;
if (asplit.IsDone())
{
...; // Do what you want...
}

-----------------------------------------------------------------------

Method #2: Split the surface by using cylinder directly (It work very robustly)
-----------------------------------------------------------------------
TopoEdge aEdge = ...; // The original edge, which has not been projected yet.
gp_Vec vector = ...; // The axis vector of cylinder to be created;

// 1. Create the cylinder;
BRepSweep_Prism CylSurf (aEdge , vector, Standard_False);
TopoDS_Shape aCylinder = CylSurf.Shape();

// 2. Split surface with created cylinder;
GEOMAlgo_Splitter PS;
PS.AddShape(aParentFace);
PS.AddTool(aCylinder);
PS.Perform();
TopTools_ListIteratorOfListOfShape iter(PS.Modified(aParentFace));
for (;iter.More();iter.Next())
{
TopoDS_Shape shape = iter.Value();
... // Do what you want...
}
-----------------------------------------------------------------------

By testing with lots of benchmark data, the Method #2 is much more robust than the Method #1.

By the way, does anyone know why ???

zhushunlai2012's picture

in the method #2£¬i got some doubts;
TopoEdge aEdge = ...; //
//if i draw one edge on the surface and intend to split the face by the edge,can this edge be the TopoEdge aEdge ?? if can,how to set the gp_Vec vector.can you give me some Inspires

another question is that if i want to split the face into several patches£¨more than two£©¡£
is method can be applied£¿
for a good understand my question please see the attach file¡£
thank you very much

Attachments: 
SunHongLei's picture

hello, Have you solve the problem? I have the same problem and i use BRepAlgoAPI_Section and BRepFeat_SplitShape ,but it does not work