Surface invisible after BRepFeat_SplitShape

Hi,

I use a plane to split a TopoDS_Face in my project. Most of the time following code works fine except few faces. I've exported one such face in STEP file and attached here. I'm using OCC 6.5.3 version for this sample code. For this particular face the split works but splitted faces are invisible in shaded mode. If I change to wireframe mode the faces appear on screen.

Please find the sample code used for splitting and attached powerpoint file showing wireframe mode of splitted faces.

Greatly appreciate any help.

TIA,
Ashish

TopoDS_Shape l_tdShape = aSeqOfShape->Value(i);//this is imported from STEP file
TopExp_Explorer l_tdExp;
for(l_tdExp.Init(l_tdShape, TopAbs_FACE); l_tdExp.More(); l_tdExp.Next())
{
TopoDS_Shape l_tdFace = l_tdExp.Current();
//make plane face
gp_Pln l_gpCutPln(gp_Pnt(11.6,-10.0,154.8),gp_Dir(0.,0.,1.0));
double l_dSize = 35.0;
double l_dHalfSize = l_dSize/2;
gp_Pnt l_gpCent = l_gpCutPln.Location();
gp_Dir l_gpXDir = l_gpCutPln.XAxis().Direction();
gp_Dir l_gpYDir = l_gpCutPln.YAxis().Direction();
gp_Dir l_gpZDir = l_gpCutPln.Axis().Direction();
//go half length in x direction
gp_Pnt l_gpNext(l_gpCent.X()+(l_gpXDir.X()*l_dHalfSize),
l_gpCent.Y()+(l_gpXDir.Y()*l_dHalfSize),
l_gpCent.Z()+(l_gpXDir.Z()*l_dHalfSize));
//get first segment points by going along Ydir two times in opposite dir
gp_Pnt l_gpPnt1(l_gpNext.X()+(l_gpYDir.X()*l_dHalfSize),
l_gpNext.Y()+(l_gpYDir.Y()*l_dHalfSize),
l_gpNext.Z()+(l_gpYDir.Z()*l_dHalfSize));
gp_Pnt l_gpPnt2(l_gpNext.X()-(l_gpYDir.X()*l_dHalfSize),
l_gpNext.Y()-(l_gpYDir.Y()*l_dHalfSize),
l_gpNext.Z()-(l_gpYDir.Z()*l_dHalfSize));
gp_Pnt l_gpPnt3(l_gpPnt2.X()-(l_gpXDir.X()*l_dSize),
l_gpPnt2.Y()-(l_gpXDir.Y()*l_dSize),
l_gpPnt2.Z()-(l_gpXDir.Z()*l_dSize));
gp_Pnt l_gpPnt4(l_gpPnt3.X()+(l_gpYDir.X()*l_dSize),
l_gpPnt3.Y()+(l_gpYDir.Y()*l_dSize),
l_gpPnt3.Z()+(l_gpYDir.Z()*l_dSize));

GC_MakeSegment l_gcSeg1(l_gpPnt1, l_gpPnt2);
Handle(Geom_TrimmedCurve) l_hSeg1 = l_gcSeg1.Value();
//get other segments
GC_MakeSegment l_gcSeg2(l_gpPnt2, l_gpPnt3);
Handle(Geom_TrimmedCurve) l_hSeg2 = l_gcSeg2.Value();
GC_MakeSegment l_gcSeg3(l_gpPnt3, l_gpPnt4);
Handle(Geom_TrimmedCurve) l_hSeg3 = l_gcSeg3.Value();
GC_MakeSegment l_gcSeg4(l_gpPnt4, l_gpPnt1);
Handle(Geom_TrimmedCurve) l_hSeg4 = l_gcSeg4.Value();

TopoDS_Edge l_tdE1 = BRepBuilderAPI_MakeEdge(l_hSeg1);
TopoDS_Edge l_tdE2 = BRepBuilderAPI_MakeEdge(l_hSeg2);
TopoDS_Edge l_tdE3 = BRepBuilderAPI_MakeEdge(l_hSeg3);
TopoDS_Edge l_tdE4 = BRepBuilderAPI_MakeEdge(l_hSeg4);

TopoDS_Wire l_tdW = BRepBuilderAPI_MakeWire(l_tdE1,l_tdE2,l_tdE3,l_tdE4);
TopoDS_Face l_tdF = BRepBuilderAPI_MakeFace(l_gpCutPln,l_tdW);

//display plane
myAISContext->Display(new AIS_Shape(l_tdF));

try
{
//cut shape by cut plane
BRepAlgoAPI_Section l_brepSec(l_tdFace,l_tdF,Standard_False);
l_brepSec.ComputePCurveOn1(Standard_True);
l_brepSec.Approximation(Standard_True);
l_brepSec.Build();
if (l_brepSec.IsDone() && !l_brepSec.Shape().IsNull() && BRepAlgo::IsValid(l_brepSec.Shape()))
{
TopoDS_Shape l_tdSec = l_brepSec.Shape();
//use splitter
BRepFeat_SplitShape l_brepSplit(l_tdFace);
bool l_bVoid = true;
//get cut shapes
TopTools_SequenceOfShape l_seqCutEdgeTemp;
for(TopExp_Explorer l_tpExp(l_tdSec,TopAbs_EDGE); l_tpExp.More(); l_tpExp.Next())
{
TopoDS_Shape l_tdNewEd = l_tpExp.Current();
TopoDS_Shape l_tdFace1;
if(l_brepSec.HasAncestorFaceOn1(l_tdNewEd,l_tdFace1))
{
TopoDS_Edge l_tdE = TopoDS::Edge(l_tdNewEd);
TopoDS_Face l_tdF = TopoDS::Face(l_tdFace1);
//add section curves and its face in splitter
l_brepSplit.Add(l_tdE,l_tdF);
l_bVoid = false;

//add this edge in collection to return
l_seqCutEdgeTemp.Append(l_tdE);
}
}
if(!l_bVoid)
{
//get split shape
TopoDS_Shape l_tdSplitShape = l_brepSplit.Shape();
//get faces after split of this face
Handle(TopoDS_TShape) l_htdTFace = l_tdFace.TShape();

//remove old face
}
}
}
catch(Standard_ConstructionError)
{
//some faces may be cut half
int i=0;
}
catch(Standard_Failure)
{
//some faces may be cut half
int i=0;
}
}

Ashish's picture

I'm attaching a powerpoint file showing split faces in wireframe mode.

Ashish's picture

I see that the triangulation of new faces fail because of open wire. See the picture attached showing call stack

Forum supervisor's picture

Dear Ashish,
The problem is not reproducible with the provided airsolid_3Pass_strip.stp file.
See the attached pictures as for OCCT6.5.3 as for OCCT6.6.0
Regards

Ashish's picture

Hi,

This is the complete sample code. I modified ImportExport sample. This should reproduce the error in 6.5.3.

void CImportExportDoc::OnFileImportStep()
{
Handle(TopTools_HSequenceOfShape) aSeqOfShape = CImportExport::ReadSTEP();
/*for(int i=1;i<= aSeqOfShape->Length();i++)
{
m_pcoloredshapeList->Add(Quantity_NOC_YELLOW, aSeqOfShape->Value(i));
m_pcoloredshapeList->Display(myAISContext);
}*/

Handle(AIS_Shape) l_hIntObj = NULL;
if (!aSeqOfShape.IsNull())
{
for(int i=1;i<= aSeqOfShape->Length();i++)
{
l_hIntObj = new AIS_Shape(aSeqOfShape->Value(i));
myAISContext->Display(l_hIntObj, Standard_False);
}
}

//split
TopoDS_Shape l_tdShape = aSeqOfShape->Value(1);//this is imported from STEP file
TopExp_Explorer l_tdExp;
for(l_tdExp.Init(l_tdShape, TopAbs_FACE); l_tdExp.More(); l_tdExp.Next())
{
TopoDS_Shape l_tdFace = l_tdExp.Current();
//make plane face
gp_Pln l_gpCutPln(gp_Pnt(11.6,-10.0,154.8),gp_Dir(0.,0.,1.0));
double l_dSize = 35.0;
double l_dHalfSize = l_dSize/2;
gp_Pnt l_gpCent = l_gpCutPln.Location();
gp_Dir l_gpXDir = l_gpCutPln.XAxis().Direction();
gp_Dir l_gpYDir = l_gpCutPln.YAxis().Direction();
gp_Dir l_gpZDir = l_gpCutPln.Axis().Direction();
//go half length in x direction
gp_Pnt l_gpNext(l_gpCent.X()+(l_gpXDir.X()*l_dHalfSize),
l_gpCent.Y()+(l_gpXDir.Y()*l_dHalfSize),
l_gpCent.Z()+(l_gpXDir.Z()*l_dHalfSize));
//get first segment points by going along Ydir two times in opposite dir
gp_Pnt l_gpPnt1(l_gpNext.X()+(l_gpYDir.X()*l_dHalfSize),
l_gpNext.Y()+(l_gpYDir.Y()*l_dHalfSize),
l_gpNext.Z()+(l_gpYDir.Z()*l_dHalfSize));
gp_Pnt l_gpPnt2(l_gpNext.X()-(l_gpYDir.X()*l_dHalfSize),
l_gpNext.Y()-(l_gpYDir.Y()*l_dHalfSize),
l_gpNext.Z()-(l_gpYDir.Z()*l_dHalfSize));
gp_Pnt l_gpPnt3(l_gpPnt2.X()-(l_gpXDir.X()*l_dSize),
l_gpPnt2.Y()-(l_gpXDir.Y()*l_dSize),
l_gpPnt2.Z()-(l_gpXDir.Z()*l_dSize));
gp_Pnt l_gpPnt4(l_gpPnt3.X()+(l_gpYDir.X()*l_dSize),
l_gpPnt3.Y()+(l_gpYDir.Y()*l_dSize),
l_gpPnt3.Z()+(l_gpYDir.Z()*l_dSize));

GC_MakeSegment l_gcSeg1(l_gpPnt1, l_gpPnt2);
Handle(Geom_TrimmedCurve) l_hSeg1 = l_gcSeg1.Value();
//get other segments
GC_MakeSegment l_gcSeg2(l_gpPnt2, l_gpPnt3);
Handle(Geom_TrimmedCurve) l_hSeg2 = l_gcSeg2.Value();
GC_MakeSegment l_gcSeg3(l_gpPnt3, l_gpPnt4);
Handle(Geom_TrimmedCurve) l_hSeg3 = l_gcSeg3.Value();
GC_MakeSegment l_gcSeg4(l_gpPnt4, l_gpPnt1);
Handle(Geom_TrimmedCurve) l_hSeg4 = l_gcSeg4.Value();

TopoDS_Edge l_tdE1 = BRepBuilderAPI_MakeEdge(l_hSeg1);
TopoDS_Edge l_tdE2 = BRepBuilderAPI_MakeEdge(l_hSeg2);
TopoDS_Edge l_tdE3 = BRepBuilderAPI_MakeEdge(l_hSeg3);
TopoDS_Edge l_tdE4 = BRepBuilderAPI_MakeEdge(l_hSeg4);

TopoDS_Wire l_tdW = BRepBuilderAPI_MakeWire(l_tdE1,l_tdE2,l_tdE3,l_tdE4);
TopoDS_Face l_tdF = BRepBuilderAPI_MakeFace(l_gpCutPln,l_tdW);

//display plane
myAISContext->Display(new AIS_Shape(l_tdF));

try
{
//cut shape by cut plane
BRepAlgoAPI_Section l_brepSec(l_tdFace,l_tdF,Standard_False);
l_brepSec.ComputePCurveOn1(Standard_True);
l_brepSec.Approximation(Standard_True);
l_brepSec.Build();
if (l_brepSec.IsDone() && !l_brepSec.Shape().IsNull() && BRepAlgo::IsValid(l_brepSec.Shape()))
{
TopoDS_Shape l_tdSec = l_brepSec.Shape();
//use splitter
BRepFeat_SplitShape l_brepSplit(l_tdFace);
bool l_bVoid = true;
//get cut shapes
TopTools_SequenceOfShape l_seqCutEdgeTemp;
for(TopExp_Explorer l_tpExp(l_tdSec,TopAbs_EDGE); l_tpExp.More(); l_tpExp.Next())
{
TopoDS_Shape l_tdNewEd = l_tpExp.Current();
TopoDS_Shape l_tdFace1;
if(l_brepSec.HasAncestorFaceOn1(l_tdNewEd,l_tdFace1))
{
TopoDS_Edge l_tdE = TopoDS::Edge(l_tdNewEd);
TopoDS_Face l_tdF = TopoDS::Face(l_tdFace1);
//add section curves and its face in splitter
l_brepSplit.Add(l_tdE,l_tdF);
l_bVoid = false;

//add this edge in collection to return
l_seqCutEdgeTemp.Append(l_tdE);
}
}
if(!l_bVoid)
{
//get split shape
TopoDS_Shape l_tdSplitShape = l_brepSplit.Shape();
//get faces after split of this face
Handle(TopoDS_TShape) l_htdTFace = l_tdFace.TShape();

BRep_Builder l_bldrComp;
TopoDS_Compound l_tdComp;
l_bldrComp.MakeCompound(l_tdComp);
for(TopExp_Explorer l_tpExp(l_tdSplitShape,TopAbs_FACE); l_tpExp.More(); l_tpExp.Next())
{
TopoDS_Shape l_tdNewFace = l_tpExp.Current();

l_bldrComp.Add(l_tdComp,l_tdNewFace);
}

l_hIntObj->Set(l_tdComp);
myAISContext->Redisplay(l_hIntObj);

}
}
}
catch(Standard_ConstructionError)
{
//some faces may be cut half
int i=0;
}
catch(Standard_Failure)
{
//some faces may be cut half
int i=0;
}
}

Fit();
}

Forum supervisor's picture

Dear Ashish,
Very probably the problem is in your code,
because the standard ImportExport Sample of OCCT6.5.3 perfectly
produces the expected shaded shape (see the attached picture).
Regards

Ashish's picture

Dear Forum Supervisor,

Thanks for reply.

I believe you are displaying original surface after importing from STEP file. Please split this surface by a plane [gp_Pln(gp_Pnt(11.6,-10.0,154.8),gp_Dir(0.,0.,1.0))] and set output surfaces in original AIS_Shape object. Then redisplay this interactive object.

I could not see split edge as part of highlighted object in your attached picture. That's the reason I believe that it is original surface not a result of split. Could you please confirm that?

Thanks,
Ashish

Forum supervisor's picture

Dear Ashish,
I suggest you to attach the resulting shape of the split operation.
I will try to check it.
Regards

Ashish's picture

Hi,

I'm unable to export the resulting shape because it has open wire in face. The splitting operation did not work but still it passes the checks I have in code. This is the check

if (l_brepSec.IsDone() && !l_brepSec.Shape().IsNull() && BRepAlgo::IsValid(l_brepSec.Shape()))

You can see complete code in above post.

Thanks,
Ashish

Forum supervisor's picture

Dear Ashish,
In this case (splitting operation doesn't work) I just can suggest you to contact us via the Contact Form http://www.opencascade.org/about/contacts/ and try to use our professional support services.
We will try to find a solution/workaround acceptable for you.
Regards

Ashish's picture

Hi,

I think, I have found a quick fix. I used ShapeFix_Wireframe class to fill the gap after split. Please find the modified code.

Thanks,
Ashish

void CImportExportDoc::OnFileImportStep()
{
Handle(TopTools_HSequenceOfShape) aSeqOfShape = CImportExport::ReadSTEP();
/*for(int i=1;i<= aSeqOfShape->Length();i++)
{
m_pcoloredshapeList->Add(Quantity_NOC_YELLOW, aSeqOfShape->Value(i));
m_pcoloredshapeList->Display(myAISContext);
}*/

Handle(AIS_Shape) l_hIntObj = NULL;
if (!aSeqOfShape.IsNull())
{
for(int i=1;i<= aSeqOfShape->Length();i++)
{
l_hIntObj = new AIS_Shape(aSeqOfShape->Value(i));
myAISContext->Display(l_hIntObj, Standard_False);
}
}

//split
TopoDS_Shape l_tdShape = aSeqOfShape->Value(1);//this is imported from STEP file
TopExp_Explorer l_tdExp;
for(l_tdExp.Init(l_tdShape, TopAbs_FACE); l_tdExp.More(); l_tdExp.Next())
{
TopoDS_Shape l_tdFace = l_tdExp.Current();
//make plane face
gp_Pln l_gpCutPln(gp_Pnt(11.6,-10.0,154.8),gp_Dir(0.,0.,1.0));
double l_dSize = 35.0;
double l_dHalfSize = l_dSize/2;
gp_Pnt l_gpCent = l_gpCutPln.Location();
gp_Dir l_gpXDir = l_gpCutPln.XAxis().Direction();
gp_Dir l_gpYDir = l_gpCutPln.YAxis().Direction();
gp_Dir l_gpZDir = l_gpCutPln.Axis().Direction();
//go half length in x direction
gp_Pnt l_gpNext(l_gpCent.X()+(l_gpXDir.X()*l_dHalfSize),
l_gpCent.Y()+(l_gpXDir.Y()*l_dHalfSize),
l_gpCent.Z()+(l_gpXDir.Z()*l_dHalfSize));
//get first segment points by going along Ydir two times in opposite dir
gp_Pnt l_gpPnt1(l_gpNext.X()+(l_gpYDir.X()*l_dHalfSize),
l_gpNext.Y()+(l_gpYDir.Y()*l_dHalfSize),
l_gpNext.Z()+(l_gpYDir.Z()*l_dHalfSize));
gp_Pnt l_gpPnt2(l_gpNext.X()-(l_gpYDir.X()*l_dHalfSize),
l_gpNext.Y()-(l_gpYDir.Y()*l_dHalfSize),
l_gpNext.Z()-(l_gpYDir.Z()*l_dHalfSize));
gp_Pnt l_gpPnt3(l_gpPnt2.X()-(l_gpXDir.X()*l_dSize),
l_gpPnt2.Y()-(l_gpXDir.Y()*l_dSize),
l_gpPnt2.Z()-(l_gpXDir.Z()*l_dSize));
gp_Pnt l_gpPnt4(l_gpPnt3.X()+(l_gpYDir.X()*l_dSize),
l_gpPnt3.Y()+(l_gpYDir.Y()*l_dSize),
l_gpPnt3.Z()+(l_gpYDir.Z()*l_dSize));

GC_MakeSegment l_gcSeg1(l_gpPnt1, l_gpPnt2);
Handle(Geom_TrimmedCurve) l_hSeg1 = l_gcSeg1.Value();
//get other segments
GC_MakeSegment l_gcSeg2(l_gpPnt2, l_gpPnt3);
Handle(Geom_TrimmedCurve) l_hSeg2 = l_gcSeg2.Value();
GC_MakeSegment l_gcSeg3(l_gpPnt3, l_gpPnt4);
Handle(Geom_TrimmedCurve) l_hSeg3 = l_gcSeg3.Value();
GC_MakeSegment l_gcSeg4(l_gpPnt4, l_gpPnt1);
Handle(Geom_TrimmedCurve) l_hSeg4 = l_gcSeg4.Value();

TopoDS_Edge l_tdE1 = BRepBuilderAPI_MakeEdge(l_hSeg1);
TopoDS_Edge l_tdE2 = BRepBuilderAPI_MakeEdge(l_hSeg2);
TopoDS_Edge l_tdE3 = BRepBuilderAPI_MakeEdge(l_hSeg3);
TopoDS_Edge l_tdE4 = BRepBuilderAPI_MakeEdge(l_hSeg4);

TopoDS_Wire l_tdW = BRepBuilderAPI_MakeWire(l_tdE1,l_tdE2,l_tdE3,l_tdE4);
TopoDS_Face l_tdF = BRepBuilderAPI_MakeFace(l_gpCutPln,l_tdW);

//display plane
myAISContext->Display(new AIS_Shape(l_tdF));

try
{
//cut shape by cut plane
BRepAlgoAPI_Section l_brepSec(l_tdFace,l_tdF,Standard_False);
l_brepSec.ComputePCurveOn1(Standard_True);
l_brepSec.Approximation(Standard_True);
l_brepSec.Build();
if (l_brepSec.IsDone() && !l_brepSec.Shape().IsNull() && BRepAlgo::IsValid(l_brepSec.Shape()))
{
TopoDS_Shape l_tdSec = l_brepSec.Shape();

//use splitter
BRepFeat_SplitShape l_brepSplit(l_tdFace);
bool l_bVoid = true;
//get cut shapes
TopTools_SequenceOfShape l_seqCutEdgeTemp;
for(TopExp_Explorer l_tpExp(l_tdSec,TopAbs_EDGE); l_tpExp.More(); l_tpExp.Next())
{
TopoDS_Shape l_tdNewEd = l_tpExp.Current();
TopoDS_Shape l_tdFace1;
if(l_brepSec.HasAncestorFaceOn1(l_tdNewEd,l_tdFace1))
{
TopoDS_Edge l_tdE = TopoDS::Edge(l_tdNewEd);
TopoDS_Face l_tdF = TopoDS::Face(l_tdFace1);
//add section curves and its face in splitter
l_brepSplit.Add(l_tdE,l_tdF);
l_bVoid = false;

//add this edge in collection to return
l_seqCutEdgeTemp.Append(l_tdE);
}
}
if(!l_bVoid)
{
//get split shape
TopoDS_Shape l_tdSplitShape = l_brepSplit.Shape();
//get faces after split of this face
Handle(TopoDS_TShape) l_htdTFace = l_tdFace.TShape();

BRep_Builder l_bldrComp;
TopoDS_Compound l_tdComp;
l_bldrComp.MakeCompound(l_tdComp);
for(TopExp_Explorer l_tpExp(l_tdSplitShape,TopAbs_FACE); l_tpExp.More(); l_tpExp.Next())
{
TopoDS_Shape l_tdNewFace = l_tpExp.Current();

//is closed
Standard_Boolean l_bClose = BRep_Tool::IsClosed(l_tdNewFace);
if(false == l_bClose)
{
ShapeFix_Wireframe l_shFix(l_tdNewFace);
if(l_shFix.FixWireGaps())
{
l_tdNewFace = l_shFix.Shape();
}
}
int l_nE=0;
for(TopExp_Explorer l_tpExpE(l_tdNewFace,TopAbs_EDGE); l_tpExpE.More(); l_tpExpE.Next())
l_nE++;

l_bldrComp.Add(l_tdComp,l_tdNewFace);
}

l_hIntObj->Set(l_tdComp);
myAISContext->Redisplay(l_hIntObj);

}
}
}
catch(Standard_ConstructionError)
{
//some faces may be cut half
int i=0;
}
catch(Standard_Failure)
{
//some faces may be cut half
int i=0;
}
}

Fit();
}