Cut a box with a plane

Hello,

I tried to cut a shape with a plane but none of the methods I use works. Maybe I use it wrong. Below you find the three methods used and the problem with witch of them.

Method 1

// METHOD 1
TopoDS_Shape S = BRepPrimAPI_MakeBox(gp_Pnt (-100, -60, -80), 150, 200, 170);   
gp_Pnt point(0, 0, 20);
gp_Dir dir(0, 0, 1);
gp_Pln pln(point, dir);


BRepAlgoAPI_Section asect(S, pln, Standard_False);
asect.ComputePCurveOn1(Standard_True);
asect.Approximation(Standard_True);
asect.Build();
TopoDS_Shape R = asect.Shape();

BRepFeat_SplitShape asplit(S);

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);
        asplit.Add(E, F);
    }
}

asplit.Build();

BRep_Builder builder;
TopoDS_Compound Comp;
builder.MakeCompound(Comp);
TopTools_ListIteratorOfListOfShape theList = asplit.DirectLeft();

for (; theList.More(); theList.Next())
{
    builder.Add(Comp, TopoDS::Face(theList.Value()));
}

The resulted shape do not contains all the face of the first cube, and contains two face of the second cube (cf. picture "methode1) in one shape.

Method 2

// METHOD 2
gp_Pnt point(0, 0, 20);
gp_Dir dir(0, 0, 1);
gp_Pln pln(point, dir);
TopoDS_Shape planeShape = BRepBuilderAPI_MakeFace(pln).Face();
TopoDS_Shell box = BRepPrimAPI_MakeBox(gp_Pnt(-100, -60, -80), 150, 200, 170);
TopoDS_Shape cut = BRepAlgoAPI_Cut(box, planeShape);

The box must be a Shell I don't know why but it doesn't work with a Shape. And the result is the full box with cutted faces (cf picture "method2") but I need two separated shapes.

Method 3

// METHOD 3
TopoDS_Shape S = BRepPrimAPI_MakeBox(gp_Pnt(-100, -60, -80), 150, 200, 170);

gp_Pnt point(0, 0, 20);
gp_Dir dir(0, 0, 1);
gp_Pln pln(point, dir);
TopoDS_Shape planeShape = BRepBuilderAPI_MakeFace(pln).Face();
BOPAlgo_MakerVolume aMV;
TopTools_ListOfShape L1;
L1.Append(S);
L1.Append(planeShape);
aMV.SetArguments(L1);
aMV.SetIntersect(Standard_True);
aMV.SetAvoidInternalShapes(Standard_False);
aMV.Perform();

if (aMV.HasErrors())
    return;
}
const TopoDS_Shape& aResult = aMV.Shape(); 

This method return error. I do not have any result.

Is someone see whats wrong with this code ?

Regards,

Manon

Attachments: 
Thomas Anderson's picture

Make a half space (BRepPrimAPI_MakeHalfSpace) from your plane and then use BRepAlgoAPI_Cut.

Manon Jubert's picture

Hello Thomas,

Thanks, it seems to work better. However, the face at section level has not been created. Do we need to build it over?

gp_Pnt point(0, 0, 20);
gp_Dir dir(0, 0, 1);
gp_Pln pln(point, dir);
TopoDS_Face planeShape = BRepBuilderAPI_MakeFace(pln).Face();
TopoDS_Shape halfSpace = BRepPrimAPI_MakeHalfSpace(planeShape, point);
TopoDS_Shell box = BRepPrimAPI_MakeBox(gp_Pnt(-100, -60, -80), 150, 200, 170);
TopoDS_Shape cut = BRepAlgoAPI_Cut(box, halfSpace);

I attach a picture to show the result

Attachments: 
Manon Jubert's picture

I thought I resolve my problem by changing the "glue" method. Here is the code :

gp_Pnt point(0, 0, 20);
gp_Dir dir(0, 0, -1);
gp_Pln pln(point, dir);
TopoDS_Face planeShape = BRepBuilderAPI_MakeFace(pln).Face();
TopoDS_Shape halfSpace = BRepPrimAPI_MakeHalfSpace(planeShape, point);
TopoDS_Shell box = BRepPrimAPI_MakeBox(gp_Pnt(-100, -60, -80), 150, 200, 170);
BRepAlgoAPI_Cut cut(box, halfSpace);
cut.SetGlue(BOPAlgo_GlueShift);
cut.Build();
TopoDS_Shape res = cut.Shape();

but the shape glue the two parts together

Thomas Anderson's picture

The point used in the halfspace creation should NOT be the same point used to define the plane. The halfspace point needs to be off of the plane to indicate which side is the "inside".

Manon Jubert's picture

Hello Thomas,

I try with a point outside the plan (0,0,25) and (0,0,10), but the result is the same. The box is not closed, I still miss the face at the cut.

Thomas Anderson's picture

Are you still using 'glue'? You shouldn't be. Post your current code.