How to cut a solid by a face into two sub solids using cut API only once

Hi All,

Now, to cut a solid by a face into two sub solids, I have to use API BRepAlgoAPI_Cut twice. One uses positive half space , and another uses negative half space. So it's somewhat stupid and low performance. My method is as follows:

bool Trim_FaceCutShell(const TopoDS_Face& trimFaceTool, const TopoDS_Shape& shellSolid, std::vector& resultShapes)
{
TopoDS_Solid solidPos, solidNeg;
TopoDS_Shape resultShape;

resultShapes.clear();
if(!Aux_MakeTwoHalfSpaceByFace(trimFaceTool, solidPos, solidNeg))
return false;
try
{
resultShape = BRepAlgoAPI_Cut (shellSolid, solidPos);
if(resultShape.ShapeType()==TopAbs_COMPOUND)
{
for(TopoDS_Iterator iter(resultShape); iter.More(); iter.Next())
resultShapes.push_back(iter.Value());
}
else
resultShapes.push_back(resultShape);
resultShape = BRepAlgoAPI_Cut (shellSolid, solidNeg);
if(resultShape.ShapeType()==TopAbs_COMPOUND)
{
for(TopoDS_Iterator iter(resultShape); iter.More(); iter.Next())
resultShapes.push_back(iter.Value());
}
else
resultShapes.push_back(resultShape);
}
catch (...)
{
resultShapes.clear();
return false;
}

return !resultShapes.empty();
}

I just wonder know how can I get the two sub solids by one time CUT operation. Does any API support it or is there any similar API DirectLeft() or DirectRight() to get any part of the cutting result.
Thanks in advance. Any suggestion is welcome.

-Ding

Evgeny Lodyzhehsky's picture

Dear Cauchy Ding .

1. If you prefer to use standard Boolean Operations you can increase the performance by the following trick.

...
TopoDS_Shape S1, S2, aRCm, aRCt;
BOPTools_DSFiller aDF;
//
S1=shellSolid;
S2=solidPos;
//
aDF.SetShapes (S1, S2);
if (!aDF.IsDone()) {
// ... some error handler
return;
}
//
aDF->Perform();
//
BRepAlgoAPI_Common aBCm(S1, S2, aDF);
if (!aBCm.IsDone()) {
aRCm=aBCm.Shape();
resultShapes.push_back(aRCm);
}
else {
// ... some error handler
return;
}
//
S2=solidNeg;
BRepAlgoAPI_Cut aBCt(S1, S2, aDF);
if (!aBCt.IsDone()) {
aRCt=aBCt.Shape();
resultShapes.push_back(aRCt);
}
else {
// ... some error handler
return;
}
...

Here you use the one (shared) DSFiller for two Boolean operations instead of the two as it was.

But again you have to use the two builders:

BRepAlgoAPI_Common aBCm(S1, S2, aDF);
BRepAlgoAPI_Cut aBCt(S1, S2, aDF);

The builders above are not so time consuming things as the DSFiller, so may be the way will be good for you.

2.If not. You can use the class GEOMAlgo_Splitter from Salome plarform.
The class allows to perform the things you want at once.
Furthermore you can use trimFaceTool directly as the argument of the operation.

Thomas Paviot's picture

The GEOMAlgo_Splitter class does the job pretty well. It can also be used to split a face from a curve (see http://www.opencascade.org/org/forum/thread_14379/).

Attached a python sample (pythonOCC actually wraps for both OCC and GEOM libraries), as well as 2 screenshots (input/output), that illustrates how to split a box with a plane face.

Regards,

Thomas

Attachments: 
Thomas Paviot's picture

The first screenshot (the box and the plane face)

Thomas Paviot's picture

And the second one (resulting shape)

Cauchy Ding's picture

Dear Thomas Paviot,

Thank you very much for your reply. I am sorry that my app can't use Salome platform directly. But still thanks to your detailed explanations.

Thank you.
Regards.

-Ding

Cauchy Ding's picture

Dear Lodyzhensky Evgeny Nicolaich,

Thank you so much for your detailed explanation. Your method is so nice and works very well now. The new method is about double faster than old method.
I think there is a minor bug in your pseudocode.
S2=solidNeg;
BRepAlgoAPI_Cut aBCt(S1, S2, aDF);
Here S2 should also be the "solidPos" instead of "solidNeg".

Thank you very much.

-Ding

Evgeny Lodyzhehsky's picture

Dear Cauchy Ding.

You are quite right.
...Here S2 should also be the "solidPos" instead of "solidNeg".
It is my misprint.

Vincent's picture

Dear Ding:
I come across the same question as you have,
but in OCC6.60,there is no BOPTools_DSFiller,
and can you tell me what the function Aux_MakeTwoHalfSpaceByFace is ?

Thanks very much!

Cauchy Ding's picture

Hi Vincent,

I am sorry and I don't know how to process this problem if BOPTools_DSFiller is lost. My platform only upgrade to OCC6.5.3.
Aux_MakeTwoHalfSpaceByFace just create two half space.
posPnt = pnt.XYZ() + normal.XYZ()*tol;
BRepPrimAPI_MakeHalfSpace mhs1(srcFace, posPnt);
solidPos = mhs1.Solid();

negPnt = pnt.XYZ() + normal.XYZ()*(-tol);
BRepPrimAPI_MakeHalfSpace mhs2(srcFace, negPnt);
solidNeg = mhs2.Solid();

Ding

Eugeny's picture

Dear Vincent,

There is a better way for splitting solid with a face in OCCT 6.6.0.
You can use class BOPAlgo_Builder:

BOPAlgo_Builder aBuilder;
//
aBuilder.AddArgument(aSol);
aBuilder.AddArgument(aFace);
//
aBuilder.Perform();
Standard_Integer iErr = aBuilder.ErrorStatus();
if (iErr) {
return iErr;
}
//
const TopoDS_Shape& aR = aBuilder.Shape();
//
TopoDS_Compound aResult;
BRep_Builder aBB;
//
aBB.MakeCompound(aResult);
TopExp_Explorer aExp (aResult, TopAbs_SOLID);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aRIm = aExp.Current();
aBB.Add(aResult, aRIm);
}

The shape aResult contains the splits of the solid.

Best Regards,
Eugeny.

Mariusz's picture

tiny patch
...
TopExp_Explorer aExp (aR, TopAbs_SOLID);
...

Best Regards

Rodrigo Castro Andrade's picture

Nice code, Eugeny.

Suppose I wanted to split a solid with 3 faces. Would add the other faces as arguments be enough? As in:

BOPAlgo_Builder aBuilder;
//
aBuilder.AddArgument(aSol);
aBuilder.AddArgument(aFace1);
aBuilder.AddArgument(aFace2);
aBuilder.AddArgument(aFace3);

Would the class correctly identify that I want to split the original solid in 4 parts?

Rodrigo Castro Andrade's picture

I tested and it works.

Thanks

Eugeny's picture

Hello,
this class just builds all possible splits of the arguments (see http://dev.opencascade.org/doc/overview/html/occt_user_guides__boolean_o...). You can also have the splits of your faces. Instead of exploding the result you can use the history information:
const TopTools_ListOfShape& aSolSplits = aBuilder.Modified(aSol);
const TopTools_ListOfShape& aFace1Splits = aBuilder.Modified(aFace1);

theRealSuperMario's picture

In case a python demo would be helpful (would have found it helpful myself), you can have a look here

https://github.com/theRealSuperMario/pythonocc-demos/blob/splitter_demo_...