diff --git a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx index 5b1d742945..23d6603178 100644 --- a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx +++ b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx @@ -85,6 +85,7 @@ #include #include #include +#include struct SubSequenceOfEdges { @@ -1006,6 +1007,37 @@ void ShapeUpgrade_UnifySameDomain::Initialize(const TopoDS_Shape& aShape, //myGenerated.Clear(); } +//======================================================================= +//function : putIntWires +//purpose : Add internal wires that are classified inside the face as a subshape, +// and remove them from the sequence +//======================================================================= +static void putIntWires(TopoDS_Shape& theFace, TopTools_SequenceOfShape& theWires) +{ + TopoDS_Face& aFace = TopoDS::Face(theFace); + for (Standard_Integer i=1; i <= theWires.Length(); i++) + { + TopoDS_Shape aWire = theWires(i); + gp_Pnt2d aP2d; + Standard_Boolean isP2d = Standard_False; + for (TopoDS_Iterator it(aWire); it.More() && !isP2d; it.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge(it.Value()); + Standard_Real aFirst, aLast; + Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aFace, aFirst, aLast); + aC2d->D0((aFirst + aLast) * 0.5, aP2d); + isP2d = Standard_True; + } + BRepClass_FaceClassifier aClass(aFace, aP2d, Precision::PConfusion()); + if (aClass.State() == TopAbs_IN) + { + BRep_Builder().Add(aFace, aWire); + theWires.Remove(i); + i--; + } + } +} + //======================================================================= //function : UnifyFaces //purpose : @@ -1124,6 +1156,8 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() TopoDS_Edge anEdge = TopoDS::Edge(edges(1)); edges.Remove(1); + // collect internal edges in separate wires + Standard_Boolean isInternal = (anEdge.Orientation() == TopAbs_INTERNAL); isEdge3d |= !BRep_Tool::Degenerated(anEdge); B.Add(aWire,anEdge); @@ -1137,6 +1171,10 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() isNewFound = Standard_False; for(Standard_Integer j = 1; j <= edges.Length(); j++) { anEdge = TopoDS::Edge(edges(j)); + // check if the current edge orientation corresponds to the first one + Standard_Boolean isCurrInternal = (anEdge.Orientation() == TopAbs_INTERNAL); + if (isCurrInternal != isInternal) + continue; TopExp::Vertices(anEdge,V1,V2); if(aVertices.Contains(V1) || aVertices.Contains(V2)) { isEdge3d |= !BRep_Tool::Degenerated(anEdge); @@ -1283,13 +1321,26 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() //CompShell.SetContext( aContext ); CompShell.SetContext( myContext ); - TopTools_SequenceOfShape parts; + TopTools_SequenceOfShape parts, anIntWires; ShapeFix_SequenceOfWireSegment wires; for(TopExp_Explorer W_Exp(aCurrent,TopAbs_WIRE);W_Exp.More();W_Exp.Next()) { - Handle(ShapeExtend_WireData) sbwd = - new ShapeExtend_WireData ( TopoDS::Wire(W_Exp.Current() )); - ShapeFix_WireSegment seg ( sbwd, TopAbs_REVERSED ); - wires.Append(seg); + const TopoDS_Wire& aWire = TopoDS::Wire(W_Exp.Current()); + // check if the wire is ordinary (contains non-internal edges) + Standard_Boolean isInternal = Standard_True; + for (TopoDS_Iterator it(aWire); it.More() && isInternal; it.Next()) + isInternal = (it.Value().Orientation() == TopAbs_INTERNAL); + if (isInternal) + { + // place internal wire separately + anIntWires.Append(aWire); + } + else + { + Handle(ShapeExtend_WireData) sbwd = + new ShapeExtend_WireData (aWire); + ShapeFix_WireSegment seg ( sbwd, TopAbs_REVERSED ); + wires.Append(seg); + } } CompShell.DispatchWires ( parts,wires ); @@ -1298,10 +1349,12 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() //aFixOrient.SetContext(aContext); aFixOrient.SetContext(myContext); aFixOrient.FixOrientation(); + // put internal wires to faces + putIntWires(parts(j), anIntWires); } TopoDS_Shape CompRes; - if ( faces.Length() !=1 ) { + if ( parts.Length() !=1 ) { TopoDS_Shell S; B.MakeShell ( S ); for ( i=1; i <= parts.Length(); i++ ) diff --git a/tests/bugs/heal/bug26489_4 b/tests/bugs/heal/bug26489_4 index 3c48723eef..5d3af85c02 100755 --- a/tests/bugs/heal/bug26489_4 +++ b/tests/bugs/heal/bug26489_4 @@ -39,11 +39,11 @@ Number of shapes in shape EDGE : 4 WIRE : 1 FACE : 1 - SHELL : 1 + SHELL : 0 SOLID : 0 COMPSOLID : 0 COMPOUND : 0 - SHAPE : 11 + SHAPE : 10 " checknbshapes x1 -ref ${nbshapes_expected} -t -m "x1 result provided by the class ShapeUpgrade_UnifySameDomain" checknbshapes x2 -ref ${nbshapes_expected} -t -m "x2 result provided by the class ShapeUpgrade_UnifySameDomain" diff --git a/tests/bugs/heal/bug26635 b/tests/bugs/heal/bug26635 new file mode 100644 index 0000000000..a4db759fca --- /dev/null +++ b/tests/bugs/heal/bug26635 @@ -0,0 +1,25 @@ +puts "========" +puts "OCC26635" +puts "========" +puts "" +######################################## +# UnifySameDomain loses internal edges +######################################## + +restore [locate_data_file OCC26635_t0.brep] t0 +restore [locate_data_file OCC26635_t1.brep] t1 +restore [locate_data_file OCC26635_t2.brep] t2 + +bclear +baddobjects t0 t1 +baddtools t2 +bfillds +bbop r 1 + +unifysamedom ru r +set bug_info [bopargcheck ru #F] + +if {$bug_info != "Shape(s) seem(s) to be valid for BOP.\n"} { + puts "ERROR: OCC26635 is reproduced." +} +