diff --git a/samples/tcl/snowflake.tcl b/samples/tcl/snowflake.tcl index 06eb89faf3..47dbe29bd9 100644 --- a/samples/tcl/snowflake.tcl +++ b/samples/tcl/snowflake.tcl @@ -59,12 +59,10 @@ prism f4 l2 0 -1 0 compound f1 f2 f3 bc bfuse r bc f4 bcut r r f5 -explode r e -wire w r_4 r_1 r_20 r_21 r_22 r_23 r_24 r_25 r_26 r_7 r_30 r_31 r_32 r_33 r_27 r_28 r_29 r_11 r_38 r_34 r_35 r_36 r_37 r_16 r_17 -tcopy w w1 -tmirror w1 -6 0 0 0 1 0 -wire w w w1 -mkface w p w +tcopy r r1 +tmirror r1 -6 0 0 0 1 0 +bfuse w r r1 +unifysamedom w w donly w # construct complete snowflake diff --git a/src/BOPAlgo/BOPAlgo_BOP.cxx b/src/BOPAlgo/BOPAlgo_BOP.cxx index 1182d3c5f7..4ae1cb0a16 100644 --- a/src/BOPAlgo/BOPAlgo_BOP.cxx +++ b/src/BOPAlgo/BOPAlgo_BOP.cxx @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -777,9 +778,11 @@ void BOPAlgo_BOP::BuildShape() } // make containers BOPCol_ListOfShape aLCRes; + BOPCol_MapOfShape aMInpFence; aItLS.Initialize(aLSC); for (; aItLS.More(); aItLS.Next()) { const TopoDS_Shape& aSC = aItLS.Value(); + aMInpFence.Add(aSC); // BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC); // @@ -861,19 +864,44 @@ void BOPAlgo_BOP::BuildShape() for (; aItLS.More(); aItLS.Next()) { aBB.Add(aResult, aItLS.Value()); } - // - // add the rest of the shapes into result + + // create map of containers BOPCol_MapOfShape aMSResult; BOPTools::MapShapes(aResult, aMSResult); - // - aIt.Initialize(myRC); - for (; aIt.More(); aIt.Next()) { - const TopoDS_Shape& aS = aIt.Value(); - if (aMSResult.Add(aS)) { - aBB.Add(aResult, aS); + + // get input non-container shapes + BOPCol_ListOfShape aLSNonCont; + for (i = 0; i < 2; ++i) + { + const BOPCol_ListOfShape& aLS = !i ? myArguments : myTools; + aItLS.Initialize(aLS); + for (; aItLS.More(); aItLS.Next()) + { + const TopoDS_Shape& aS = aItLS.Value(); + BOPAlgo_Tools::TreatCompound(aS, aMInpFence, aLSNonCont); } } - // + + // put non-container shapes in the result + aItLS.Initialize(aLSNonCont); + for (; aItLS.More(); aItLS.Next()) + { + const TopoDS_Shape& aS = aItLS.Value(); + if (myImages.IsBound(aS)) + { + const BOPCol_ListOfShape& aLSIm = myImages.Find(aS); + aItLSIm.Initialize(aLSIm); + for (; aItLSIm.More(); aItLSIm.Next()) + { + const TopoDS_Shape& aSIm = aItLSIm.Value(); + if (aMSRC.Contains(aSIm) && aMSResult.Add(aSIm)) + aBB.Add(aResult, aSIm); + } + } + else if (aMSRC.Contains(aS) && aMSResult.Add(aS)) + aBB.Add(aResult, aS); + } + myShape = aResult; } //======================================================================= diff --git a/src/BOPAlgo/BOPAlgo_Builder_3.cxx b/src/BOPAlgo/BOPAlgo_Builder_3.cxx index 31ff3a3ac3..a5035bd811 100644 --- a/src/BOPAlgo/BOPAlgo_Builder_3.cxx +++ b/src/BOPAlgo/BOPAlgo_Builder_3.cxx @@ -64,6 +64,7 @@ #include // #include +#include #include #include @@ -74,11 +75,6 @@ static void OwnInternalShapes(const TopoDS_Shape& , BOPCol_IndexedMapOfShape& ); -static - void TreatCompound(const TopoDS_Shape& theS, - BOPCol_MapOfShape& aMFence, - BOPCol_ListOfShape& theLS); - //======================================================================= // BOPAlgo_BuilderSolid // @@ -941,7 +937,7 @@ void BOPAlgo_Builder::FillInternalShapes() aIt.Initialize(aArguments); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aS=aIt.Value(); - TreatCompound(aS, aMFence, aLSC); + BOPAlgo_Tools::TreatCompound(aS, aMFence, aLSC); } aIt.Initialize(aLSC); for (; aIt.More(); aIt.Next()) { @@ -1146,29 +1142,3 @@ void OwnInternalShapes(const TopoDS_Shape& theS, } } } -//======================================================================= -//function : TreatCompound -//purpose : -//======================================================================= -void TreatCompound(const TopoDS_Shape& theS, - BOPCol_MapOfShape& aMFence, - BOPCol_ListOfShape& theLS) -{ - TopAbs_ShapeEnum aType; - // - aType = theS.ShapeType(); - if (aType != TopAbs_COMPOUND) { - if (aMFence.Add(theS)) { - theLS.Append(theS); - } - return; - } - // - TopoDS_Iterator aIt; - // - aIt.Initialize(theS); - for (; aIt.More(); aIt.Next()) { - const TopoDS_Shape& aS = aIt.Value(); - TreatCompound(aS, aMFence, theLS); - } -} diff --git a/src/BOPAlgo/BOPAlgo_MakerVolume.cxx b/src/BOPAlgo/BOPAlgo_MakerVolume.cxx index 695118a397..2a7afbcbc9 100644 --- a/src/BOPAlgo/BOPAlgo_MakerVolume.cxx +++ b/src/BOPAlgo/BOPAlgo_MakerVolume.cxx @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -29,10 +30,6 @@ static void AddFace(const TopoDS_Shape& theF, BOPCol_ListOfShape& theLF); -static - void TreatCompound(const TopoDS_Shape& theS, - BOPCol_MapOfShape& aMFence, - BOPCol_ListOfShape& theLS); //======================================================================= //function : CheckData @@ -352,7 +349,7 @@ void BOPAlgo_MakerVolume::FillInternalShapes(const BOPCol_ListOfShape& theLSR) aIt.Initialize(anArguments); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aS = aIt.Value(); - TreatCompound(aS, aMFence, aLSC); + BOPAlgo_Tools::TreatCompound(aS, aMFence, aLSC); } // aIt.Initialize(aLSC); @@ -440,26 +437,3 @@ void AddFace(const TopoDS_Shape& theF, aFF.Orientation(TopAbs_REVERSED); theLF.Append(aFF); } - -//======================================================================= -//function : TreatCompound -//purpose : -//======================================================================= -void TreatCompound(const TopoDS_Shape& theS, - BOPCol_MapOfShape& aMFence, - BOPCol_ListOfShape& theLS) -{ - TopAbs_ShapeEnum aType = theS.ShapeType(); - if (aType != TopAbs_COMPOUND) { - if (aMFence.Add(theS)) { - theLS.Append(theS); - } - return; - } - // - TopoDS_Iterator aIt(theS); - for (; aIt.More(); aIt.Next()) { - const TopoDS_Shape& aS = aIt.Value(); - TreatCompound(aS, aMFence, theLS); - } -} diff --git a/src/BOPAlgo/BOPAlgo_Tools.cxx b/src/BOPAlgo/BOPAlgo_Tools.cxx index 4a4484a74c..59490a7ff5 100644 --- a/src/BOPAlgo/BOPAlgo_Tools.cxx +++ b/src/BOPAlgo/BOPAlgo_Tools.cxx @@ -1089,3 +1089,26 @@ void BOPAlgo_Tools::IntersectVertices(const BOPCol_IndexedDataMapOfShapeReal& th } } } + +//======================================================================= +//function : TreatCompound +//purpose : +//======================================================================= +void BOPAlgo_Tools::TreatCompound(const TopoDS_Shape& theS, + BOPCol_MapOfShape& aMFence, + BOPCol_ListOfShape& theLS) +{ + TopAbs_ShapeEnum aType = theS.ShapeType(); + if (aType != TopAbs_COMPOUND) + { + if (aMFence.Add(theS)) + theLS.Append(theS); + return; + } + TopoDS_Iterator aIt(theS); + for (; aIt.More(); aIt.Next()) + { + const TopoDS_Shape& aS = aIt.Value(); + TreatCompound(aS, aMFence, theLS); + } +} diff --git a/src/BOPAlgo/BOPAlgo_Tools.hxx b/src/BOPAlgo/BOPAlgo_Tools.hxx index a43ab1f008..36a8a79bd3 100644 --- a/src/BOPAlgo/BOPAlgo_Tools.hxx +++ b/src/BOPAlgo/BOPAlgo_Tools.hxx @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -155,6 +157,12 @@ public: const Standard_Real theFuzzyValue, BOPCol_ListOfListOfShape& theChains); + //! Collect in the output list recursively all non-compound subshapes of the first level + //! of the given shape theS. If a shape presents in the map theMFence it is skipped. + //! All shapes put in the output are also added into theMFence. + Standard_EXPORT static void TreatCompound(const TopoDS_Shape& theS, + BOPCol_MapOfShape& theMFence, + BOPCol_ListOfShape& theLS); }; #endif // _BOPAlgo_Tools_HeaderFile diff --git a/src/BRepAlgo/BRepAlgo_NormalProjection.cxx b/src/BRepAlgo/BRepAlgo_NormalProjection.cxx index 768ff46899..319f0da32c 100644 --- a/src/BRepAlgo/BRepAlgo_NormalProjection.cxx +++ b/src/BRepAlgo/BRepAlgo_NormalProjection.cxx @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -481,9 +481,9 @@ void BRepAlgo_NormalProjection::SetDefaultParams() if (!Degenerated) { // Perform Boolean COMMON operation to get parts of projected edge // inside the face - BRepAlgoAPI_Common aCommon(Faces->Value(j), prj); - if (aCommon.IsDone()) { - const TopoDS_Shape& aRC = aCommon.Shape(); + BRepAlgoAPI_Section aSection(Faces->Value(j), prj); + if (aSection.IsDone()) { + const TopoDS_Shape& aRC = aSection.Shape(); // TopExp_Explorer aExpE(aRC, TopAbs_EDGE); for (; aExpE.More(); aExpE.Next()) { diff --git a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx index 0ce6b76eb9..5c2960fa1d 100644 --- a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx +++ b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx @@ -125,41 +125,6 @@ static Standard_Boolean IsLikeSeam(const TopoDS_Edge& anEdge, return Standard_False; } -static Standard_Boolean CheckSharedEdgeOri(const TopoDS_Face& theF1, - const TopoDS_Face& theF2, - const TopoDS_Edge& theE) -{ - TopAbs_Orientation anEOri = theE.Orientation(); - if (anEOri == TopAbs_EXTERNAL || anEOri == TopAbs_INTERNAL) - return Standard_False; - - TopExp_Explorer Exp(theF1, TopAbs_EDGE); - for (;Exp.More();Exp.Next()) - { - const TopoDS_Shape& aCE = Exp.Current(); - if (aCE.IsSame(theE)) - { - anEOri = aCE.Orientation(); - break; - } - } - - for (Exp.Init(theF2, TopAbs_EDGE);Exp.More();Exp.Next()) - { - const TopoDS_Shape& aCE = Exp.Current(); - if (aCE.IsSame(theE)) - { - if (aCE.Orientation() == TopAbs::Reverse(anEOri)) - return Standard_True; - else - return Standard_False; - } - } - - return Standard_False; - -} - //======================================================================= //function : AddOrdinaryEdges //purpose : auxilary @@ -1234,7 +1199,7 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() // unify faces in each shell separately TopExp_Explorer exps; for (exps.Init(myShape, TopAbs_SHELL); exps.More(); exps.Next()) - IntUnifyFaces(exps.Current(), aGMapEdgeFaces, Standard_False); + IntUnifyFaces(exps.Current(), aGMapEdgeFaces); // gather all faces out of shells in one compound and unify them at once BRep_Builder aBB; @@ -1245,7 +1210,7 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() aBB.Add(aCmp, exps.Current()); if (nbf > 0) - IntUnifyFaces(aCmp, aGMapEdgeFaces, Standard_True); + IntUnifyFaces(aCmp, aGMapEdgeFaces); myShape = myContext->Apply(myShape); } @@ -1274,8 +1239,7 @@ static void SetFixWireModes(ShapeFix_Face& theSff) //======================================================================= void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape, - TopTools_IndexedDataMapOfShapeListOfShape& theGMapEdgeFaces, - Standard_Boolean IsCheckSharedEdgeOri) + TopTools_IndexedDataMapOfShapeListOfShape& theGMapEdgeFaces) { // creating map of edge faces for the shape TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces; @@ -1356,9 +1320,6 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape if (aProcessed.Contains(anCheckedFace)) continue; - if (IsCheckSharedEdgeOri && !CheckSharedEdgeOri(aFace, anCheckedFace, edge) ) - continue; - if (bCheckNormals) { // get normal of checked face using the same parameter on edge gp_Dir aDN2; diff --git a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx index 13f8c95559..ea2db40e2a 100644 --- a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx +++ b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx @@ -133,8 +133,7 @@ protected: Standard_EXPORT void UnifyEdges(); void IntUnifyFaces(const TopoDS_Shape& theInpShape, - TopTools_IndexedDataMapOfShapeListOfShape& theGMapEdgeFaces, - Standard_Boolean IsCheckSharedEdgeOri); + TopTools_IndexedDataMapOfShapeListOfShape& theGMapEdgeFaces); //! Fills the history of the modifications during the operation. Standard_EXPORT void FillHistory(); diff --git a/tests/bugs/modalg_7/bug29234 b/tests/bugs/modalg_7/bug29234 new file mode 100644 index 0000000000..00870d32ac --- /dev/null +++ b/tests/bugs/modalg_7/bug29234 @@ -0,0 +1,31 @@ +puts "========" +puts "OCC29234" +puts "========" +puts "" +################################################# +# BRepOffsetAPI_NormalProjection produces INTERNAL edges and vertices +################################################# + +restore [locate_data_file bug29234_cyl_n_wire.brep] a +explode a +renamevar a_1 f +renamevar a_2 w +nproject r w f +foreach e [explode r e] { + if [regexp "INTERNAL" [dtyp $e]] { + puts "Error: projection result contains edges oriented INTERNAL" + break + } +} +don r +fit +checknbshapes r -m "projection result" -edge 4 +checkview -display r -2d -path ${imagedir}/${test_image}_1.png + +bcommon r1 f r +foreach e [explode r1 e] { + if [regexp "INTERNAL" [dtyp $e]] { + puts "Error: result of common between face and edge contains edges oriented INTERNAL" + break + } +}