BRepFeat_SplitShape

I am doing the intersection of 2 surfaces to produce a section and then I want to use that section to cut one of the surfaces. The section is correct but I can't seem to cut the surface using BRepFeat_SplitShape. Are the parameters correct? Anyone have ideas on what is happening?

display.EraseAll()

PL = gp_Pln( gp_Ax3( gp_XOY() ) )
aPlane = GC_MakePlane( PL ).Value()
aSurface1 = Geom_RectangularTrimmedSurface( aPlane, - 8., 8., - 12., 12., 1, 1 )
aFace1 = make_face(aSurface1.GetHandle())
#display.DisplayShape(aFace1)

PL = gp_Pln( gp_Ax3( gp_YOZ() ) )
aPlane = GC_MakePlane( PL ).Value()
aSurface2 = Geom_RectangularTrimmedSurface( aPlane, - 8., 8., - 12., 12., 1, 1 )
aFace2 = make_face(aSurface2.GetHandle())
#display.DisplayShape(aFace2)

aSection = BRepAlgoAPI_Section(aFace1, aFace2, False)
aSection.ComputePCurveOn1(True)
aSection.Approximation(True)
aSection.Build()
R = aSection.Shape()
#display.DisplayShape(R)

aSplit = BRepFeat_SplitShape(aFace2)

for edg in Topo(R).edges():
face = TopoDS_face(TopoDS_Shape())
if aSection.HasAncestorFaceOn1(edg, face):
aSplit.Add(edg, face)

aSplit.Build()

display.DisplayShape(aSplit.Shape())

AP's picture

Try any of these functions to see if it works on your sample, the AddNewSplit(TopoDS_Shape Stock, gp_Pln plane1) is more efficient than AddNewSplit(TopoDS_Shape Stock, TopoDS_Shape Tool)

you could either do :

TopoDS_Shape result = AddNewSplit(aFace2,aFace1);

or since you already have the plane:

aPlane = GC_MakePlane( gp_Pln( gp_Ax3( gp_XOY() ) ) ).Value()
TopoDS_Shape result = AddNewSplit(aFace2,aPlane);

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

// split stock with tool

TopoDS_Shape AddNewSplit(TopoDS_Shape Stock, TopoDS_Shape Tool)
{
TopoDS_Shape nullshape;
BRepAlgoAPI_Section asect(Stock, Tool,Standard_False);
asect.ComputePCurveOn1(Standard_True);
asect.Approximation(Standard_True);
asect.Build();
TopoDS_Shape R = asect.Shape();

if (!asect.ErrorStatus()== 0) return nullshape;
BRepFeat_SplitShape asplit(Stock);

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);
}
}

try
{
asplit.Build();
}

catch(...)
{
return nullshape;
}

if(!asplit.Shape().IsNull())
{
return asplit.Shape();
} else {

return nullshape;

}

}

// split stock with plane

TopoDS_Shape AddNewSplit(TopoDS_Shape Stock, gp_Pln plane1)
{
TopoDS_Shape nullshape;
BRepAlgoAPI_Section asect(Stock,plane1,Standard_False);

asect.ComputePCurveOn1(Standard_True);
asect.Approximation(Standard_True);
asect.Build();
TopoDS_Shape R = asect.Shape();

if (!asect.ErrorStatus()== 0) return nullshape;

BRepFeat_SplitShape asplit(Stock);

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);
}
}

try
{
asplit.Build();
}

catch(...)
{
return nullshape;
}

if(!asplit.Shape().IsNull())
{
return asplit.Shape();
} else {

return nullshape;
}

}

AP's picture

Are you using python? Your function looks very similar to mine. I wonder if there are differences in C++ version versus Python version.

Try specifying a point to the plane constructor, just to make sure both planes have the same origin.
even if the gp_XOY() and gp_YOZ() planes have the same origin try this:

PL1 = gp_Pln( gp_Pnt(0,0,0),gp_Vec(0,0,1));
PL2 = gp_Pln( gp_Pnt(0,0,0),gp_Vec(0,1,0));

Billy's picture

Hi AlexP,

I am using python because it is easier to try stuff out before I implement it in C++. Actually I managed to get the desired result but using a completely different approach:

display.EraseAll()

PL = gp_Pln( gp_Ax3( gp_XOY() ) )
aPlane = GC_MakePlane( PL ).Value()
aSurface1 = Geom_RectangularTrimmedSurface( aPlane, - 8., 8., - 12., 12., 1, 1 )
aFace1 = make_face(aSurface1.GetHandle())
#display.DisplayShape(aFace1)

PL = gp_Pln( gp_Ax3( gp_YOZ() ) )
aPlane = GC_MakePlane( PL ).Value()
aSurface2 = Geom_RectangularTrimmedSurface( aPlane, - 8., 8., - 12., 12., 1, 1 )
aFace2 = make_face(aSurface2.GetHandle())
#display.DisplayShape(aFace2)

aJoin = BRepAlgoAPI_Fuse(aFace1, aFace2)

for f in Topo(aJoin.Shape()).faces():
display.DisplayShape(f)

Basically I Fuse the 2 faces together, get a compound shape with all the surfaces split correctly. Maybe it is more computer intensive. I don't know. Your approach is very similar to mine but I always got an error or the shape wouldn't split. The error was Standard_NoSuchObject I think.

AP's picture

Also when you display the result of the split using :

display.DisplayShape(aSplit.Shape())

does it display something?

if it does display something, check that the result contains more than one face, because BRepFeat_SplitShape simply segments the object, you have to do a topological exploration against the faces of aSplit.Shape() that you want to keep.

if nothing is displaying than commentoff the code for splitting and display aface1 and aface2 in the viewport using the parameter values you have specified above, and visually inspect that the two surfaces are actually touching each other. If they are not touching change the parameters until they do and rerun the splitting.

if it still is not working... post your results...

Billy's picture

My code was based on the pythonocc example (see split_shape method):

http://code.google.com/p/pythonocc/source/browse/trunk/src/examples/Leve...

This code works OK. I don't understand why you need to pass the 2nd parameter of asplit.Add(edg, face) method. face is the parent of edge? Why does the edge need to belong to a face? Does the edge need to be closed?

My code would display nothing when error occurred in aSplit.Build() method or display the original shape with no error but the shape with no split. I just can't get it to work. Therefore I am using new approach (BRepAlgoAPI_Fuse). ^^^

AP's picture

Interesting....

well paste this in the Draw Test Harness:

pload ALL
plane yz 0 0 0 0 1 0 0 0 1
trim t1 yz -3 3 -3 3
mkface face1 t1
plane xy 0 0 0 1 0 0 0 1 0
trim t2 xy -3 3 -3 3
mkface face2 t2
cut cut1 face2 face1
vdisplay cut1
vdisplay face1
vdisplay face2

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

it showed the splits for me, if the fuse command works for you than... great..

anyways best of luck.

Cheers,

Alex

Billy's picture

Hi Alex,

You are right this makes the correct cut. The problem is I don't know how to translate this script to C++ code. Is this example using BRepFeat_SplitShape?

I didn't use draw test harness before but it looks pretty cool. Thanks for the script. Maybe I need to read more documentation about this.