From 2102c85e9fd4e4f3fd73b0f475526a9f67eb721a Mon Sep 17 00:00:00 2001 From: emv Date: Tue, 7 Jul 2015 14:18:28 +0300 Subject: [PATCH] 3D Offset algorithm extension for the cases with the shapes having the faces connected only by the VERTEX. --- src/BRepOffset/BRepOffset_Inter2d.cdl | 37 +- src/BRepOffset/BRepOffset_Inter2d.cxx | 46 +- src/BRepOffset/BRepOffset_Inter3d.cxx | 618 ++++++++++++++--------- src/BRepOffset/BRepOffset_MakeOffset.cxx | 533 +++++++++++++------ 4 files changed, 790 insertions(+), 444 deletions(-) diff --git a/src/BRepOffset/BRepOffset_Inter2d.cdl b/src/BRepOffset/BRepOffset_Inter2d.cdl index d3929ae1e2..30ea15943a 100644 --- a/src/BRepOffset/BRepOffset_Inter2d.cdl +++ b/src/BRepOffset/BRepOffset_Inter2d.cdl @@ -18,8 +18,8 @@ class Inter2d from BRepOffset - ---Purpose: Computes the intersections betwwen edges on a face - -- stores result is SD as AsDes from BRepOffset. + ---Purpose: Computes the intersections betwwen edges on a face + -- stores result is SD as AsDes from BRepOffset. uses AsDes from BRepAlgo, @@ -30,27 +30,28 @@ uses Real from Standard is - Compute(myclass ; AsDes : AsDes from BRepAlgo; - F : Face from TopoDS; - NewEdges : IndexedMapOfShape from TopTools; - Tol : Real from Standard); - - ---Purpose: Computes the intersections between the edges stored - -- is AsDes as descendants of . Intersections is computed - -- between two edges if one of them is bound in NewEdges. + Compute(myclass ; AsDes : AsDes from BRepAlgo; + F : Face from TopoDS; + NewEdges : IndexedMapOfShape from TopTools; + Tol : Real from Standard); + + ---Purpose: Computes the intersections between the edges stored + -- is AsDes as descendants of . Intersections is computed + -- between two edges if one of them is bound in NewEdges. -- Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 Begin -- Add another parameter: offset value. ConnexIntByInt(myclass ; - FI : Face from TopoDS; - OFI : in out Offset from BRepOffset; - MES : in out DataMapOfShapeShape from TopTools; - Build : DataMapOfShapeShape from TopTools; - AsDes : AsDes from BRepAlgo; - Offset: Real from Standard; - Tol : Real from Standard); + FI : Face from TopoDS; + OFI : in out Offset from BRepOffset; + MES : in out DataMapOfShapeShape from TopTools; + Build : DataMapOfShapeShape from TopTools; + AsDes : AsDes from BRepAlgo; + AsDes2d : AsDes from BRepAlgo; + Offset : Real from Standard; + Tol : Real from Standard); -- Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 End - + end Inter2d; diff --git a/src/BRepOffset/BRepOffset_Inter2d.cxx b/src/BRepOffset/BRepOffset_Inter2d.cxx index 7e694d9f14..43d7e32f7f 100644 --- a/src/BRepOffset/BRepOffset_Inter2d.cxx +++ b/src/BRepOffset/BRepOffset_Inter2d.cxx @@ -805,7 +805,6 @@ static void RefEdgeInter(const TopoDS_Face& F, } } - //====================================================================== //function : EvaluateMaxSegment //purpose : return MaxSegment to pass in approximation @@ -1465,7 +1464,8 @@ void BRepOffset_Inter2d::ConnexIntByInt BRepOffset_Offset& OFI, TopTools_DataMapOfShapeShape& MES, const TopTools_DataMapOfShapeShape& Build, - const Handle(BRepAlgo_AsDes)& AsDes, + const Handle(BRepAlgo_AsDes)& AsDes, + const Handle(BRepAlgo_AsDes)& AsDes2d, const Standard_Real Offset, const Standard_Real Tol) // Modified by skv - Fri Dec 26 16:53:18 2003 OCC4455 End @@ -1503,10 +1503,18 @@ void BRepOffset_Inter2d::ConnexIntByInt } } } - + TopoDS_Face FIO = TopoDS::Face(OFI.Face()); if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO)); - + // + TopTools_MapOfShape aME; + const TopTools_ListOfShape& aLE = AsDes->Descendant(FIO); + TopTools_ListIteratorOfListOfShape aItLE(aLE); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aE = aItLE.Value(); + aME.Add(aE); + } + // BRepAdaptor_Surface BAsurf(FIO); TopExp_Explorer exp(FI.Oriented(TopAbs_FORWARD),TopAbs_WIRE); @@ -1573,7 +1581,28 @@ void BRepOffset_Inter2d::ConnexIntByInt for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) { for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) { RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()), - AsDes,Tol,Standard_True/*Standard_False*/, Pref); + AsDes2d,Tol,Standard_True/*Standard_False*/, Pref); + } + } + // + if (Build.IsBound(Vref)) { + TopoDS_Shape NE3 = Build(Vref); + // + for (Exp2.Init(NE3,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) { + const TopoDS_Edge& aE3 = *(TopoDS_Edge*)&Exp2.Current(); + if (!aME.Contains(aE3)) { + continue; + } + // + for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) { + RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3, + AsDes2d,Tol,Standard_True/*Standard_False*/, Pref); + } + // + for (Exp1.Init(NE2,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) { + RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3, + AsDes2d,Tol,Standard_True/*Standard_False*/, Pref); + } } } } @@ -1581,18 +1610,15 @@ void BRepOffset_Inter2d::ConnexIntByInt if (MES.IsBound(CEO)) { TopoDS_Vertex V = CommonVertex(CEO,NEO); UpdateVertex (V,CEO,TopoDS::Edge(MES(CEO)),Tol); - AsDes->Add (MES(CEO),V); + AsDes2d->Add (MES(CEO),V); } else if (MES.IsBound(NEO)) { TopoDS_Vertex V = CommonVertex(CEO,NEO); UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol); - AsDes->Add (MES(NEO),V); + AsDes2d->Add (MES(NEO),V); } } CurE = NextE; } } } - - - diff --git a/src/BRepOffset/BRepOffset_Inter3d.cxx b/src/BRepOffset/BRepOffset_Inter3d.cxx index 37c632ab16..342747fd94 100644 --- a/src/BRepOffset/BRepOffset_Inter3d.cxx +++ b/src/BRepOffset/BRepOffset_Inter3d.cxx @@ -40,6 +40,7 @@ #include #include #include +#include @@ -97,110 +98,53 @@ static void ExtentEdge(const TopoDS_Face& /*F*/, //function : SelectEdge //purpose : //======================================================================= - -static void SelectEdge (const TopoDS_Face& /*F*/, - const TopoDS_Face& /*EF*/, - const TopoDS_Edge& E, - TopTools_ListOfShape& LInt) +static void SelectEdge (const TopoDS_Shape& theS, + TopTools_ListOfShape& theLE) { - //------------------------------------------------------------ - // Proofing on the intersections on periodical faces - //------------------------------------------------------------ - TopTools_ListIteratorOfListOfShape it(LInt); -// Modified by Sergey KHROMOV - Wed Jun 5 11:43:04 2002 Begin -// Standard_Real dU = 1.0e100; - Standard_Real dU = RealLast(); -// Modified by Sergey KHROMOV - Wed Jun 5 11:43:05 2002 End - TopoDS_Edge GE; - - Standard_Real Fst, Lst, tmp; - BRep_Tool::Range(E, Fst, Lst); - BRepAdaptor_Curve Ad1(E); - - gp_Pnt PFirst = Ad1.Value( Fst ); - gp_Pnt PLast = Ad1.Value( Lst ); - -// Modified by Sergey KHROMOV - Wed Jun 5 11:23:10 2002 Begin - Extrema_ExtPC anExt; -// Modified by Sergey KHROMOV - Wed Jun 5 11:23:11 2002 End - //---------------------------------------------------------------------- - // Selection of edge that coversmost of the domain of the initial edge. - //---------------------------------------------------------------------- - for (; it.More(); it.Next()) { - const TopoDS_Edge& EI = TopoDS::Edge(it.Value()); - - BRep_Tool::Range(EI, Fst, Lst); - BRepAdaptor_Curve Ad2(EI); - -// Modified by Sergey KHROMOV - Wed Jun 5 11:25:03 2002 Begin - Standard_Integer i; - Standard_Real aTol = BRep_Tool::Tolerance(EI); - Standard_Boolean isMinFound = Standard_False; - Standard_Real aSqrDist1 = Precision::Infinite(); - Standard_Real aSqrDist2 = Precision::Infinite(); - - anExt.Initialize(Ad2, Fst, Lst, aTol); - -// Seek for the min distance for PFirst: - anExt.Perform(PFirst); - if (anExt.IsDone()) { - for (i = 1; i <= anExt.NbExt(); i++) { - if (anExt.IsMin(i)) { - const gp_Pnt &aPMin = anExt.Point(i).Value(); - - aSqrDist1 = PFirst.SquareDistance(aPMin); - isMinFound = Standard_True; - - break; - } + Standard_Real aT1, aT2, aDist, aDistMin; + TopExp_Explorer aExp; + TopTools_ListIteratorOfListOfShape aIt; + GeomAPI_ProjectPointOnCurve aProjPC; + gp_Pnt aPE1, aPE2; + TopoDS_Edge aRE; + // + aDistMin = RealLast(); + // + aIt.Initialize(theLE); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Edge& aE = *(TopoDS_Edge*)&aIt.Value(); + // + const Handle(Geom_Curve)& aC = BRep_Tool::Curve(aE, aT1, aT2); + // + aProjPC.Init(aC, aT1, aT2); + aPE1 = aC->Value(aT1); + aPE2 = aC->Value(aT2); + // + aDist = 0.; + aExp.Init(theS, TopAbs_VERTEX); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aExp.Current(); + const gp_Pnt aP = BRep_Tool::Pnt(aV); + // + aProjPC.Perform(aP); + if (aProjPC.NbPoints()) { + aDist += aProjPC.LowerDistance(); } - } - if (!isMinFound) { - gp_Pnt aP1 = Ad2.Value(Fst); - gp_Pnt aP2 = Ad2.Value(Lst); - - aSqrDist1 = Min(aP1.SquareDistance(PFirst), aP2.SquareDistance(PFirst)); - } - -// Seek for the min distance for PLast: - isMinFound = Standard_False; - anExt.Perform(PLast); - if (anExt.IsDone()) { - for (i = 1; i <= anExt.NbExt(); i++) { - if (anExt.IsMin(i)) { - const gp_Pnt &aPMin = anExt.Point(i).Value(); - - aSqrDist2 = PLast.SquareDistance(aPMin); - isMinFound = Standard_True; - - break; - } + else { + aDist += Min(aP.Distance(aPE1), aP.Distance(aPE2)); } } - if (!isMinFound) { - gp_Pnt aP1 = Ad2.Value(Fst); - gp_Pnt aP2 = Ad2.Value(Lst); - - aSqrDist2 = Min(aP1.SquareDistance(PLast), aP2.SquareDistance(PLast)); + // + if (aDist < aDistMin) { + aDistMin = aDist; + aRE = aE; } - - tmp = aSqrDist1 + aSqrDist2; -// gp_Pnt P1 = Ad2.Value(Fst); -// gp_Pnt P2 = Ad2.Value(Lst); - -// tmp = P1.Distance(PFirst) + P2.Distance(PLast); - if( tmp <= dU ) { - dU = tmp; - GE = EI; - } -// Modified by Sergey KHROMOV - Wed Jun 5 11:24:54 2002 End - } - LInt.Clear(); - LInt.Append(GE); + // + theLE.Clear(); + theLE.Append(aRE); } - //======================================================================= //function : CompletInt //purpose : @@ -482,103 +426,213 @@ void BRepOffset_Inter3d::ConnexIntByInt TopTools_ListOfShape& Failed) { //TopExp_Explorer Exp(SI,TopAbs_EDGE); - TopTools_IndexedMapOfShape Emap; - TopExp::MapShapes( SI, TopAbs_EDGE, Emap ); + TopTools_IndexedMapOfShape VEmap; + TopTools_IndexedDataMapOfShapeListOfShape aMVF; TopoDS_Face F1,F2,OF1,OF2,NF1,NF2; TopAbs_State CurSide = mySide; BRep_Builder B; - TopTools_ListIteratorOfListOfShape it; - - //for (; Exp.More(); Exp.Next()) { - for (Standard_Integer i = 1; i <= Emap.Extent(); i++) { - //const TopoDS_Edge& E = TopoDS::Edge(Exp.Current()); - const TopoDS_Edge& E = TopoDS::Edge(Emap(i)); - const BRepOffset_ListOfInterval& L = Analyse.Type(E); - if (!L.IsEmpty()) { + Standard_Boolean bEdge; + Standard_Integer i, aNb; + TopTools_ListIteratorOfListOfShape it, it1, itF1, itF2; + // + TopExp::MapShapes(SI, TopAbs_EDGE , VEmap); + TopExp::MapShapes(SI, TopAbs_VERTEX, VEmap); + TopExp::MapShapesAndAncestors(SI, TopAbs_VERTEX, TopAbs_FACE, aMVF); + // + aNb = VEmap.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aS = VEmap(i); + // + TopoDS_Edge E; + TopTools_ListOfShape aLF1, aLF2; + // + bEdge = (aS.ShapeType() == TopAbs_EDGE); + if (bEdge) { + // faces connected by the edge + E = *(TopoDS_Edge*)&aS; + // + const BRepOffset_ListOfInterval& L = Analyse.Type(E); + if (L.IsEmpty()) { + continue; + } + // BRepOffset_Type OT = L.First().Type(); - if (OT == BRepOffset_Convex || OT == BRepOffset_Concave) { - if (OT == BRepOffset_Concave) CurSide = TopAbs_IN; - else CurSide = TopAbs_OUT; - //----------------------------------------------------------- - // edge is of the proper type, return adjacent faces. - //----------------------------------------------------------- - const TopTools_ListOfShape& Anc = Analyse.Ancestors(E); - if (Anc.Extent() != 2) continue; - F1 = TopoDS::Face(Anc.First()); - F2 = TopoDS::Face(Anc.Last ()); - OF1 = TopoDS::Face(MapSF(F1).Face()); OF2 = TopoDS::Face(MapSF(F2).Face()); - if (!MES.IsBound(OF1)) { - Standard_Boolean enlargeU = Standard_True; - Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True; - BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast ); - BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast); - MES.Bind(OF1,NF1); + if (OT != BRepOffset_Convex && OT != BRepOffset_Concave) { + continue; + } + // + if (OT == BRepOffset_Concave) CurSide = TopAbs_IN; + else CurSide = TopAbs_OUT; + //----------------------------------------------------------- + // edge is of the proper type, return adjacent faces. + //----------------------------------------------------------- + const TopTools_ListOfShape& Anc = Analyse.Ancestors(E); + if (Anc.Extent() != 2) { + continue; + } + // + F1 = TopoDS::Face(Anc.First()); + F2 = TopoDS::Face(Anc.Last ()); + // + aLF1.Append(F1); + aLF2.Append(F2); + } + else { + // faces connected by the vertex + const TopTools_ListOfShape& aLF = aMVF.FindFromKey(aS); + if (aLF.Extent() < 2) { + continue; + } + // + Standard_Boolean bVertexOnly = Standard_False; + TopTools_MapOfShape aMFence; + // + it.Initialize(aLF); + for (; it.More(); it.Next()) { + const TopoDS_Face& aFV1 = *(TopoDS_Face*)&it.Value(); + if (!aMFence.Add(aFV1)) { + continue; } - else { - NF1 = TopoDS::Face(MES(OF1)); + // + TopTools_MapOfShape aME; + TopExp_Explorer aExp(aFV1, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + aME.Add(aExp.Current()); } - if (!MES.IsBound(OF2)) { - Standard_Boolean enlargeU = Standard_True; - Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True; - BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast ); - BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast); - MES.Bind(OF2,NF2); + // + it1.Initialize(aLF); + for (it1.Next(); it1.More(); it1.Next()) { + const TopoDS_Face& aFV2 = *(TopoDS_Face*)&it1.Value(); + if (aMFence.Contains(aFV2)) { + continue; + } + // + bVertexOnly = Standard_True; + aExp.Init(aFV2, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aEV2 = aExp.Current(); + if (aME.Contains(aEV2)) { + bVertexOnly = Standard_False; + break; + } + } + // + if (bVertexOnly) { + aLF1.Append(aFV1); + aLF2.Append(aFV2); + aMFence.Add(aFV2); + } } - else { - NF2 = TopoDS::Face(MES(OF2)); + } + // + if (aLF1.IsEmpty()) { + continue; + } + // + CurSide = mySide; + } + // + itF1.Initialize(aLF1); + itF2.Initialize(aLF2); + for (; itF1.More() && itF2.More(); itF1.Next(), itF2.Next()) { + F1 = TopoDS::Face(itF1.Value()); + F2 = TopoDS::Face(itF2.Value()); + // + OF1 = TopoDS::Face(MapSF(F1).Face()); + OF2 = TopoDS::Face(MapSF(F2).Face()); + if (!MES.IsBound(OF1)) { + Standard_Boolean enlargeU = Standard_True; + Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True; + BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast ); + BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast); + MES.Bind(OF1,NF1); + } + else { + NF1 = TopoDS::Face(MES(OF1)); + } + // + if (!MES.IsBound(OF2)) { + Standard_Boolean enlargeU = Standard_True; + Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True; + BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast ); + BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast); + MES.Bind(OF2,NF2); + } + else { + NF2 = TopoDS::Face(MES(OF2)); + } + // + if (!IsDone(NF1,NF2)) { + TopTools_ListOfShape LInt1,LInt2; + BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,bEdge); + if (LInt1.Extent() > 1) { + // intersection is in seceral edges (free sewing) + SelectEdge(aS, LInt1); + SelectEdge(aS, LInt2); } - if (!IsDone(NF1,NF2)) { - TopTools_ListOfShape LInt1,LInt2; - BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,Standard_True); - if (LInt1.Extent() > 1) - { - // intersection is in seceral edges (free sewing) - SelectEdge( NF1, NF2, E, LInt1 ); - SelectEdge( NF1, NF2, E, LInt2 ); - } - SetDone(NF1,NF2); - if (!LInt1.IsEmpty()) { - Store (NF1,NF2,LInt1,LInt2); - TopoDS_Compound C; - B.MakeCompound(C); - for (it.Initialize(LInt1) ; it.More(); it.Next()) { - B.Add(C,it.Value()); + SetDone(NF1,NF2); + if (!LInt1.IsEmpty()) { + Store (NF1,NF2,LInt1,LInt2); + // + TopoDS_Compound C; + B.MakeCompound(C); + // + if (Build.IsBound(aS)) { + const TopoDS_Shape& aSE = Build(aS); + TopExp_Explorer aExp(aSE, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aNE = aExp.Current(); + B.Add(C, aNE); } - Build.Bind(E,C); } - else { - Failed.Append(E); + // + it.Initialize(LInt1); + for (; it.More(); it.Next()) { + const TopoDS_Shape& aNE = it.Value(); + B.Add(C, aNE); } - } else { // IsDone(NF1,NF2) - // Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin - const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1); - const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2); - - if (!aLInt1.IsEmpty()) { - TopoDS_Compound C; - TopTools_ListIteratorOfListOfShape anIt2; - - B.MakeCompound(C); - - for (it.Initialize(aLInt1) ; it.More(); it.Next()) { - const TopoDS_Shape &anE1 = it.Value(); - - for (anIt2.Initialize(aLInt2) ; anIt2.More(); anIt2.Next()) { - const TopoDS_Shape &anE2 = anIt2.Value(); - - if (anE1.IsSame(anE2)) - B.Add(C, anE1); - } + // + Build.Bind(aS,C); + } + else { + Failed.Append(aS); + } + } else { // IsDone(NF1,NF2) + // Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin + const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1); + const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2); + + if (!aLInt1.IsEmpty()) { + TopoDS_Compound C; + B.MakeCompound(C); + // + if (Build.IsBound(aS)) { + const TopoDS_Shape& aSE = Build(aS); + TopExp_Explorer aExp(aSE, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aNE = aExp.Current(); + B.Add(C, aNE); } - Build.Bind(E,C); } - else { - Failed.Append(E); + // + for (it.Initialize(aLInt1) ; it.More(); it.Next()) { + const TopoDS_Shape &anE1 = it.Value(); + // + for (it1.Initialize(aLInt2) ; it1.More(); it1.Next()) { + const TopoDS_Shape &anE2 = it1.Value(); + + if (anE1.IsSame(anE2)) + B.Add(C, anE1); + } } + Build.Bind(aS,C); } - // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End - } + else { + Failed.Append(aS); + } + } } + // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End } } @@ -603,10 +657,12 @@ void BRepOffset_Inter3d::ContextIntByInt TopoDS_Edge OE; TopoDS_Compound C; BRep_Builder B; - TopTools_ListIteratorOfListOfShape it; - Standard_Integer i; - - for (i = 1; i <= ContextFaces.Extent(); i++) { + TopTools_ListIteratorOfListOfShape it, itF; + Standard_Integer i, j, aNb, aNbVE; + Standard_Boolean bEdge; + + aNb = ContextFaces.Extent(); + for (i = 1; i <= aNb; i++) { const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i)); myTouched.Add(CF); if (ExtentContext) { @@ -616,89 +672,153 @@ void BRepOffset_Inter3d::ContextIntByInt } TopAbs_State Side = TopAbs_OUT; - for (i = 1; i <= ContextFaces.Extent(); i++) { + for (i = 1; i <= aNb; i++) { const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i)); if (ExtentContext) WCF = TopoDS::Face(MES(CF)); else WCF = CF; - for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - exp.More(); exp.Next()) { - const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); - if (!Analyse.HasAncestor(E)) { - //---------------------------------------------------------------- - // the edges of faces of context that are not in the initial shape - // can appear in the result. - //---------------------------------------------------------------- - if (!ExtentContext) { - myAsDes->Add(CF,E); - myNewEdges.Add(E); - } - else { - if (!MES.IsBound(E)) { - TopoDS_Edge NE; - Standard_Real f,l,Tol; - BRep_Tool::Range(E,f,l); - Tol = BRep_Tool::Tolerance(E); - ExtentEdge(CF,E,NE); - TopoDS_Vertex V1,V2; - TopExp::Vertices(E,V1,V2); - NE.Orientation(TopAbs_FORWARD); - myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED)); - myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD)); - TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL); - B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol); - aLocalShape = V2.Oriented(TopAbs_INTERNAL); - B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol); -// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol); -// B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol); - NE.Orientation(E.Orientation()); - myAsDes->Add(CF,NE); - myNewEdges.Add(NE); - MES.Bind(E,NE); + TopTools_IndexedMapOfShape VEmap; + TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap); + TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap); + // + aNbVE = VEmap.Extent(); + for (j = 1; j <= aNbVE; ++j) { + const TopoDS_Shape& aS = VEmap(j); + // + bEdge = (aS.ShapeType() == TopAbs_EDGE); + // + TopoDS_Edge E; + TopTools_ListOfShape Anc; + // + if (bEdge) { + // faces connected by the edge + // + E = *(TopoDS_Edge*)&aS; + if (!Analyse.HasAncestor(E)) { + //---------------------------------------------------------------- + // the edges of faces of context that are not in the initial shape + // can appear in the result. + //---------------------------------------------------------------- + if (!ExtentContext) { + myAsDes->Add(CF,E); + myNewEdges.Add(E); } else { - TopoDS_Shape NE = MES(E); - TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation()); - myAsDes->Add(CF,aLocalShape); + if (!MES.IsBound(E)) { + TopoDS_Edge NE; + Standard_Real f,l,Tol; + BRep_Tool::Range(E,f,l); + Tol = BRep_Tool::Tolerance(E); + ExtentEdge(CF,E,NE); + TopoDS_Vertex V1,V2; + TopExp::Vertices(E,V1,V2); + NE.Orientation(TopAbs_FORWARD); + myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED)); + myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD)); + TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL); + B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol); + aLocalShape = V2.Oriented(TopAbs_INTERNAL); + B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol); +// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol); +// B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol); + NE.Orientation(E.Orientation()); + myAsDes->Add(CF,NE); + myNewEdges.Add(NE); + MES.Bind(E,NE); + } + else { + TopoDS_Shape NE = MES(E); + TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation()); + myAsDes->Add(CF,aLocalShape); // myAsDes->Add(CF,NE.Oriented(E.Orientation())); + } } - } - continue; - } - const TopTools_ListOfShape& Anc = Analyse.Ancestors(E); - const TopoDS_Face& F = TopoDS::Face(Anc.First()); - OF = TopoDS::Face(MapSF(F).Face()); - TopoDS_Shape aLocalShape = MapSF(F).Generated(E); - OE = TopoDS::Edge(aLocalShape); -// OE = TopoDS::Edge(MapSF(F).Generated(E)); - if (!MES.IsBound(OF)) { - BRepOffset_Tool::EnLargeFace(OF,NF,1,1); - MES.Bind(OF,NF); + continue; + } + Anc = Analyse.Ancestors(E); } else { - NF = TopoDS::Face(MES(OF)); - } - if (!IsDone(NF,CF)) { - TopTools_ListOfShape LInt1,LInt2; - TopTools_ListOfShape LOE; - LOE.Append(OE); - BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,Standard_True); - SetDone(NF,CF); - if (!LInt1.IsEmpty()) { - Store (CF,NF,LInt1,LInt2); - if (LInt1.Extent() == 1) { - Build.Bind(E,LInt1.First()); + // faces connected by the vertex + // + if (!Analyse.HasAncestor(aS)) { + continue; + } + // + const TopTools_ListOfShape& aLE = Analyse.Ancestors(aS); + it.Initialize(aLE); + for (; it.More(); it.Next()) { + const TopoDS_Edge& aE = *(TopoDS_Edge*)&it.Value(); + // + if (BRep_Tool::Degenerated(aE)) { + continue; } - else { - B.MakeCompound(C); - for (it.Initialize(LInt1) ; it.More(); it.Next()) { - B.Add(C,it.Value()); + // + if (VEmap.Contains(aE)) { + continue; + } + // + const TopTools_ListOfShape& aLF = Analyse.Ancestors(aE); + itF.Initialize(aLF); + for (; itF.More(); itF.Next()) { + const TopoDS_Shape& aF = itF.Value(); + Standard_Boolean bAdd = Standard_True; + exp.Init(aF, TopAbs_EDGE); + for (; exp.More() && bAdd; exp.Next()) { + const TopoDS_Shape& aEF = exp.Current(); + bAdd = !VEmap.Contains(aEF); + } + if (bAdd) { + Anc.Append(aF); } - Build.Bind(E,C); } } + } + // + itF.Initialize(Anc); + for (; itF.More(); itF.Next()) { + const TopoDS_Face& F = TopoDS::Face(itF.Value()); + OF = TopoDS::Face(MapSF(F).Face()); + TopoDS_Shape aLocalShape = MapSF(F).Generated(E); + OE = TopoDS::Edge(aLocalShape); +// OE = TopoDS::Edge(MapSF(F).Generated(E)); + if (!MES.IsBound(OF)) { + BRepOffset_Tool::EnLargeFace(OF,NF,1,1); + MES.Bind(OF,NF); + } else { - Failed.Append(E); + NF = TopoDS::Face(MES(OF)); + } + if (!IsDone(NF,CF)) { + TopTools_ListOfShape LInt1,LInt2; + TopTools_ListOfShape LOE; + LOE.Append(OE); + BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,bEdge); + SetDone(NF,CF); + if (!LInt1.IsEmpty()) { + Store (CF,NF,LInt1,LInt2); + if ((LInt1.Extent() == 1) && !Build.IsBound(aS)) { + Build.Bind(aS,LInt1.First()); + } + else { + B.MakeCompound(C); + if (Build.IsBound(aS)) { + const TopoDS_Shape& aSE = Build(aS); + exp.Init(aSE, TopAbs_EDGE); + for (; exp.More(); exp.Next()) { + const TopoDS_Shape& aNE = exp.Current(); + B.Add(C, aNE); + } + } + // + for (it.Initialize(LInt1) ; it.More(); it.Next()) { + B.Add(C,it.Value()); + } + Build.Bind(aS,C); + } + } + else { + Failed.Append(aS); + } } } } diff --git a/src/BRepOffset/BRepOffset_MakeOffset.cxx b/src/BRepOffset/BRepOffset_MakeOffset.cxx index 8e5e4aaa32..6bb8342992 100644 --- a/src/BRepOffset/BRepOffset_MakeOffset.cxx +++ b/src/BRepOffset/BRepOffset_MakeOffset.cxx @@ -901,7 +901,9 @@ static void TrimEdge (TopoDS_Edge& NE, Standard_Real UMax = -UMin; const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE); - + // + Standard_Boolean bTrim = Standard_False; + // if (LE.Extent() > 1) { TopTools_ListIteratorOfListOfShape it (LE); for (; it.More(); it.Next()) { @@ -909,16 +911,15 @@ static void TrimEdge (TopoDS_Edge& NE, if (NE.Orientation() == TopAbs_REVERSED) V.Reverse(); //V.Orientation(TopAbs_INTERNAL); - if (!FindParameter(V, NE, U)) - { - Standard_Real f, l; - Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l); - gp_Pnt thePoint = BRep_Tool::Pnt(V); - GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve); - if (Projector.NbPoints() == 0) - Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection"); - U = Projector.LowerDistanceParameter(); - } + if (!FindParameter(V, NE, U)) { + Standard_Real f, l; + Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l); + gp_Pnt thePoint = BRep_Tool::Pnt(V); + GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve); + if (Projector.NbPoints() == 0) + Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection"); + U = Projector.LowerDistanceParameter(); + } if (U < UMin) { UMin = U; V1 = V; } @@ -926,6 +927,7 @@ static void TrimEdge (TopoDS_Edge& NE, UMax = U; V2 = V; } } + // if (V1.IsNull() || V2.IsNull()) { Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge"); } @@ -945,6 +947,19 @@ static void TrimEdge (TopoDS_Edge& NE, AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD)); AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED)); BRepLib::SameParameter(NE, aSameParTol, Standard_True); + // + bTrim = Standard_True; + } + } + // + if (!bTrim) { + if (!BRep_Tool::Degenerated(NE)) { + BRepAdaptor_Curve aBAC(NE); + if (!aBAC.IsClosed()) { + if (AsDes->HasAscendant(NE)) { + AsDes->Remove(NE); + } + } } } } @@ -961,6 +976,10 @@ static void TrimEdge (TopoDS_Edge& NE, #include #include #include +#include +#include +#include +#include //======================================================================= //function : SortFaces @@ -1032,7 +1051,7 @@ static void SortFaces(const TopTools_ListOfShape& theLIm, TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF); } // - // find outer edges and check if they touche the first part of edges + // find outer edges and check if they touch the first part of edges aItLF.Initialize(aLFTmp); for (; aItLF.More(); aItLF.Next()) { const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); @@ -1044,8 +1063,7 @@ static void SortFaces(const TopTools_ListOfShape& theLIm, TopoDS_Vertex aV1, aV2; TopExp::Vertices(aE, aV1, aV2); // - bFlag = aMV.Contains(aV1) || - aMV.Contains(aV2); + bFlag = aMV.Contains(aV1) || aMV.Contains(aV2); } } // @@ -1192,6 +1210,64 @@ static void UpdateOrigins(TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, } } +//======================================================================= +//function : IsMicroEdge +//purpose : +//======================================================================= +static Standard_Boolean IsMicroEdge (const TopoDS_Edge& theEdge, + const Handle(IntTools_Context)& theCtx, + Standard_Real& theFuzz) +{ + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(theEdge, aV1, aV2); + Standard_Boolean bNull = aV1.IsNull() || aV2.IsNull(); + if (bNull) { + return Standard_False; + } + // + Standard_Boolean bMicro; + Standard_Real aT1, aT2; + IntTools_ShrunkRange aSR; + // + BRepAdaptor_Curve aBAC(theEdge); + // + aT1 = BRep_Tool::Parameter(aV1, theEdge); + aT2 = BRep_Tool::Parameter(aV2, theEdge); + if (aT2 < aT1) { + Standard_Real aTmp = aT1; + aT1 = aT2; + aT2 = aTmp; + } + // + aSR.SetContext(theCtx); + aSR.SetData(theEdge, aT1, aT2, aV1, aV2); + aSR.Perform(); + bMicro = (aSR.ErrorStatus() != 0); + if (!bMicro) { + Standard_Real anEps, aTS1, aTS2, aTolV1, aTolV2; + // + aTolV1 = BRep_Tool::Tolerance(aV1); + aTolV2 = BRep_Tool::Tolerance(aV2); + // + anEps = aBAC.Resolution(aTolV1 + aTolV2); + if (anEps < 1.e-8) { + anEps = 1.e-8; + } + // + aSR.ShrunkRange(aTS1, aTS2); + bMicro = (aTS2 - aTS1) <= anEps; + } + // + if (bMicro) { + Standard_Real aLen = CPnts_AbscissaPoint::Length(aBAC); + if (aLen > theFuzz) { + theFuzz = aLen; + } + } + // + return bMicro; +} + //======================================================================= //function : BuildSplitsOfFaces //purpose : @@ -1208,8 +1284,15 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces BOPCol_ListIteratorOfListOfShape aIt; TopTools_ListIteratorOfListOfShape aItLF, aItLE, aItLE1; TopTools_DataMapOfShapeListOfShape anEImages; + BRep_Builder aBB; + TopoDS_Compound aFaces; + // + aBB.MakeCompound(aFaces); // // firstly it is necessary to fuse all the edges + Standard_Real aFuzz = 0.; + Handle(IntTools_Context) aCtx = new IntTools_Context(); + // aItLF.Initialize(theLF); for (; aItLF.More(); aItLF.Next()) { const TopoDS_Shape& aF = aItLF.Value(); @@ -1221,41 +1304,41 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces if (BRep_Tool::Degenerated(aE)) { continue; } + // + if (IsMicroEdge(aE, aCtx, aFuzz)) { + continue; + } + // aLS.Append(aE); } } // if (aLS.Extent() > 1) { - BOPAlgo_PaveFiller aPF; + BOPAlgo_Builder aGFE; // - aPF.SetArguments(aLS); - aPF.Perform(); - if (aPF.ErrorStatus() == 0) { - BOPAlgo_Builder aGFE; - // - aGFE.SetArguments(aLS); - aGFE.PerformWithFiller(aPF); - if (aGFE.ErrorStatus() == 0) { - // fill map with edges images - aIt.Initialize(aLS); - for (; aIt.More(); aIt.Next()) { - const TopoDS_Shape& aE = aIt.Value(); - // - const TopTools_ListOfShape& aLEIm = aGFE.Modified(aE); - if (aLEIm.Extent()) { - anEImages.Bind(aE, aLEIm); - } - } + aGFE.SetArguments(aLS); + aGFE.SetFuzzyValue(aFuzz); + aGFE.Perform(); + if (aGFE.ErrorStatus() == 0) { + // fill map with edges images + aIt.Initialize(aLS); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aE = aIt.Value(); // - UpdateOrigins(theOrigins, aGFE); + const TopTools_ListOfShape& aLEIm = aGFE.Modified(aE); + if (aLEIm.Extent()) { + anEImages.Bind(aE, aLEIm); + } } + // + UpdateOrigins(theOrigins, aGFE); } } // // now we can split the faces aItLF.Initialize(theLF); for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Shape& aF = aItLF.Value(); + const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value(); // // the offset face aLS.Clear(); @@ -1279,6 +1362,7 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces } } // + aFuzz = 0.; // the edges by which the offset face should be split const TopTools_ListOfShape& aLE = theAsDes->Descendant(aF); aItLE.Initialize(aLE); @@ -1292,7 +1376,12 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces const TopTools_ListOfShape& aLEIm = anEImages.Find(aE); aItLE1.Initialize(aLEIm); for (; aItLE1.More(); aItLE1.Next()) { - const TopoDS_Shape& aEIm = aItLE1.Value(); + const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aItLE1.Value(); + // check for micro edge + if (IsMicroEdge(aEIm, aCtx, aFuzz)) { + continue; + } + // aLS.Append(aEIm); if (!aMFE.Contains(aEIm)) { ++iCountE; @@ -1300,6 +1389,9 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces } } else { + if (IsMicroEdge(aE, aCtx, aFuzz)) { + continue; + } aLS.Append(aE); if (!aMFE.Contains(aE)) { ++iCountE; @@ -1313,12 +1405,14 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces if (!iCountE) { aLFImages.Append(aF); theImage.Bind(aF, aLFImages); + aBB.Add(aFaces, aF); continue; } // BOPAlgo_Builder aGF; // aGF.SetArguments(aLS); + aGF.SetFuzzyValue(aFuzz); aGF.Perform(); if (aGF.ErrorStatus()) { theLFailed.Append(aF); @@ -1397,6 +1491,11 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces aExp.Init(aFIm, TopAbs_EDGE); for (bKeep = Standard_True; aExp.More() && bKeep; aExp.Next()) { const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current(); + // + if (BRep_Tool::Degenerated(aE)) { + continue; + } + // bKeep = aME.Contains(aE); } // @@ -1431,11 +1530,20 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces for (; aExp.More(); aExp.Next()) { const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current(); // + if (BRep_Tool::Degenerated(aEIm)) { + continue; + } + // if (!theOrigins.Contains(aEIm)) { continue; } // const TopTools_ListOfShape& aLEOr = theOrigins.FindFromKey(aEIm); + const TopoDS_Shape& aSOr = aLEOr.First(); + if (aSOr.ShapeType() != TopAbs_EDGE) { + bRem = Standard_False; + break; + } // if (aLEOr.Extent() > 1) { TopTools_MapOfShape aME, aMV; @@ -1494,11 +1602,11 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces } } // - if (bRem) { + if (bRem && !bKeep) { aLFImages.Remove(aItLE); } else { - if (bKeep) { + if (!bRem && bKeep) { aLFKeep.Append(aFIm); } aItLE.Next(); @@ -1531,20 +1639,41 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces theImage.Bind(aF, aLFImages); } else { - theLFailed.Append(aF); + BRepAdaptor_Surface aBAS(aF, Standard_False); + if (aBAS.GetType() != GeomAbs_Plane) { + theLFailed.Append(aF); + } + } + // + aItLE.Initialize(aLFImages); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aFIm = aItLE.Value(); + aBB.Add(aFaces, aFIm); } } // // fill history for edges + TopTools_IndexedMapOfShape aMFE; + TopExp::MapShapes(aFaces, TopAbs_EDGE, aMFE); + // TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItEIm(anEImages); for (; aItEIm.More(); aItEIm.Next()) { const TopoDS_Shape& aE = aItEIm.Key(); const TopTools_ListOfShape& aLEIm = aItEIm.Value(); - if (theImage.HasImage(aE)) { - theImage.Add(aE, aLEIm); - } - else { - theImage.Bind(aE, aLEIm); + // + Standard_Boolean bHasImage = theImage.HasImage(aE); + aItLE.Initialize(aLEIm); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aEIm = aItLE.Value(); + if (aMFE.Contains(aEIm)) { + if (bHasImage) { + theImage.Add(aE, aEIm); + } + else { + theImage.Bind(aE, aEIm); + bHasImage = Standard_True; + } + } } } } @@ -1645,7 +1774,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() const TopoDS_Face& FI = TopoDS::Face(Exp.Current()); // Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455 Begin // BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myTol); - BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myOffset, myTol); + BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes,AsDes2d,myOffset, myTol); // Modified by skv - Mon Jan 12 11:50:03 2004 OCC4455 End } //----------------------------------------------------------- @@ -1661,78 +1790,95 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { const TopoDS_Face& FI = TopoDS::Face(Exp.Current()); NF = MapSF(FI).Face(); - if (MES.IsBound(NF)) {NF = TopoDS::Face(MES(NF));} + if (MES.IsBound(NF)) { + NF = TopoDS::Face(MES(NF)); + } + // TopTools_MapOfShape View; - for (Exp2.Init(FI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); Exp2.More(); Exp2.Next()) { - const TopoDS_Edge& EI = TopoDS::Edge(Exp2.Current()); - if (View.Add(EI)) { - if (Build.IsBound(EI)) { - NE = Build(EI); - if (NE.ShapeType() == TopAbs_EDGE) { - if (anOrigins.Contains(NE)) { - anOrigins.ChangeFromKey(NE).Append(EI); - } - else { - TopTools_ListOfShape aLSx; - aLSx.Append(EI); - anOrigins.Add(NE, aLSx); - } - // - if (NewEdges.Add(NE)) { - TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes); - } + TopTools_IndexedMapOfShape VEmap; + Standard_Integer i, aNb; + // + TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap); + TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap); + // + aNb = VEmap.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aS = VEmap(i); + if (!View.Add(aS)) { + continue; + } + // + if (Build.IsBound(aS)) { + NE = Build(aS); + if (NE.ShapeType() == TopAbs_EDGE) { + if (anOrigins.Contains(NE)) { + anOrigins.ChangeFromKey(NE).Append(aS); } else { - //------------------------------------------------------------ - // The Intersections are on several edges. - // The pieces without intersections with neighbors - // are removed from AsDes. - //------------------------------------------------------------ - for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) { - TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current()); - if (NewEdges.Add(NEC)) { - NEC.Free(Standard_True); - if (anOrigins.Contains(NEC)) { - anOrigins.ChangeFromKey(NEC).Append(EI); - } - else { - TopTools_ListOfShape aLSx; - aLSx.Append(EI); - anOrigins.Add(NEC, aLSx); - } - // - if (!AsDes2d->Descendant(NEC).IsEmpty()) { - TrimEdge (NEC,AsDes2d,AsDes); - } - else { + TopTools_ListOfShape aLSx; + aLSx.Append(aS); + anOrigins.Add(NE, aLSx); + } + // + if (NewEdges.Add(NE)) { + TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes); + } + } + else { + //------------------------------------------------------------ + // The Intersections are on several edges. + // The pieces without intersections with neighbors + // are removed from AsDes. + //------------------------------------------------------------ + for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) { + TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current()); + if (NewEdges.Add(NEC)) { + NEC.Free(Standard_True); + if (anOrigins.Contains(NEC)) { + anOrigins.ChangeFromKey(NEC).Append(aS); + } + else { + TopTools_ListOfShape aLSx; + aLSx.Append(aS); + anOrigins.Add(NEC, aLSx); + } + // + if (!AsDes2d->Descendant(NEC).IsEmpty()) { + TrimEdge (NEC,AsDes2d,AsDes); + } + else { + if (AsDes->HasAscendant(NEC)) { AsDes->Remove(NEC); } } } } } - else { - NE = MapSF(FI).Generated(EI); - - //// modified by jgv, 19.12.03 for OCC4455 //// - NE.Orientation( EI.Orientation() ); - if (anOrigins.Contains(NE)) { - anOrigins.ChangeFromKey(NE).Append(EI); - } - else { - TopTools_ListOfShape aLSx; - aLSx.Append(EI); - anOrigins.Add(NE, aLSx); - } - /////////////////////////////////////////////// - if (MES.IsBound(NE)) { - NE = MES(NE); - NE.Orientation(EI.Orientation()); - if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);} - } - AsDes->Add(NF,NE); - } } + else { + if (aS.ShapeType() != TopAbs_EDGE) { + continue; + } + // + NE = MapSF(FI).Generated(aS); + //// modified by jgv, 19.12.03 for OCC4455 //// + NE.Orientation(aS.Orientation()); + if (anOrigins.Contains(NE)) { + anOrigins.ChangeFromKey(NE).Append(aS); + } + else { + TopTools_ListOfShape aLSx; + aLSx.Append(aS); + anOrigins.Add(NE, aLSx); + } + // + if (MES.IsBound(NE)) { + NE = MES(NE); + NE.Orientation(aS.Orientation()); + if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);} + } + AsDes->Add(NF,NE); + } } } @@ -3558,96 +3704,149 @@ void BRepOffset_MakeOffset::MakeShells() } }*/ // + Standard_Boolean bFaces = !myFaces.IsEmpty(); + // if ((myJoin == GeomAbs_Intersection) && myInter) { Standard_Integer i, aNb; TopTools_ListIteratorOfListOfShape aItLS, aItLS1; + BRep_Builder aBB; + // + TopoDS_Compound aCSF; + aBB.MakeCompound(aCSF); // BOPAlgo_Builder aGF; // aGF.SetArguments(aLSF); aGF.Perform(); - if (aGF.ErrorStatus() == 0) { + bDone = (aGF.ErrorStatus() == 0); + if (bDone) { const TopoDS_Shape& aR = aGF.Shape(); TopExp_Explorer aExp(aR, TopAbs_FACE); aLSF.Clear(); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape& aF = aExp.Current(); aLSF.Append(aF); + aBB.Add(aCSF, aF); } // - UpdateOrigins(anOrigins, aGF); - } - // - if (myFaces.IsEmpty()) { - BOPAlgo_MakerVolume aMV1; - // - aMV1.SetArguments(aLSF); - aMV1.SetIntersect(Standard_False); - // - aMV1.Perform(); - bDone = (aMV1.ErrorStatus() == 0); + bDone = (myOffset > 0); if (bDone) { - TopoDS_Compound aShells; - BRep_Builder aBB; + UpdateOrigins(anOrigins, aGF); + // + BOPAlgo_MakerVolume aMV1; // - aBB.MakeCompound(aShells); + aMV1.AddArgument(aCSF); + aMV1.SetIntersect(Standard_False); // - TopoDS_Shape aResult = aMV1.Shape(); - if (aResult.ShapeType() == TopAbs_COMPOUND) { - // collect faces attached to only one solid - BOPCol_IndexedDataMapOfShapeListOfShape aMFS; - BOPCol_ListOfShape aLSF2; + if (bFaces) { + aNb = myFaces.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aFEx = myFaces(i); + aMV1.AddArgument(aFEx); + } + aMV1.SetIntersect(Standard_True); + } + // + aMV1.Perform(); + bDone = (aMV1.ErrorStatus() == 0); + if (bDone) { + TopoDS_Compound aShells; // - BOPTools::MapShapesAndAncestors(aResult, TopAbs_FACE, TopAbs_SOLID, aMFS); - aNb = aMFS.Extent(); - bDone = (aNb > 0); + aBB.MakeCompound(aShells); // - if (bDone) { - for (i = 1; i <= aNb; ++i) { - const TopoDS_Shape& aFx = aMFS.FindKey(i); - const BOPCol_ListOfShape& aLSx = aMFS(i); - if (aLSx.Extent() == 1) { - // check orientation - const TopoDS_Face& aF = *(TopoDS_Face*)&aFx; - if (!anOrigins.Contains(aF)) { - aLSF2.Append(aFx); - continue; - } - // - const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aFx); - aItLS.Initialize(aLFOr); - for (; aItLS.More(); aItLS.Next()) { - const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value(); - // - if (CheckNormals(aF, aFOr)) { + TopoDS_Shape aResult = aMV1.Shape(); + // + // collect images of the faces + TopTools_MapOfShape aMFaces; + aNb = myFaces.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aFEx = myFaces(i); + const TopTools_ListOfShape& aLFEx = aMV1.Modified(aFEx); + if (!aLFEx.IsEmpty()) { + aItLS.Initialize(aLFEx); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Face& aFExIm = *(TopoDS_Face*)&aItLS.Value(); + aMFaces.Add(aFExIm); + } + } + else { + aMFaces.Add(aFEx); + } + } + // + if (aResult.ShapeType() == TopAbs_COMPOUND) { + // collect faces attached to only one solid + BOPCol_IndexedDataMapOfShapeListOfShape aMFS; + BOPCol_ListOfShape aLSF2; + // + BOPTools::MapShapesAndAncestors(aResult, TopAbs_FACE, TopAbs_SOLID, aMFS); + aNb = aMFS.Extent(); + bDone = (aNb > 0); + // + if (bDone) { + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aFx = aMFS.FindKey(i); + const BOPCol_ListOfShape& aLSx = aMFS(i); + if (aLSx.Extent() == 1) { + // check orientation + const TopoDS_Face& aF = *(TopoDS_Face*)&aFx; + if (!anOrigins.Contains(aF)) { aLSF2.Append(aFx); - break; + continue; + } + // + const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aFx); + aItLS.Initialize(aLFOr); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value(); + // + if (CheckNormals(aF, aFOr)) { + aLSF2.Append(aFx); + break; + } } } } + // + // make solid containing most outer faces + BOPAlgo_MakerVolume aMV2; + // + aMV2.SetArguments(aLSF2); + aMV2.SetIntersect(Standard_False); + // + aMV2.Perform(); + bDone = (aMV2.ErrorStatus() == 0); + if (bDone) { + aResult = aMV2.Shape(); + } } + } + // + TopExp_Explorer aExp(aResult, TopAbs_SHELL); + bDone = aExp.More(); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shell& aSh = *(TopoDS_Shell*)&aExp.Current(); // - // make solid containing most outer faces - BOPAlgo_MakerVolume aMV2; - // - aMV2.SetArguments(aLSF2); - aMV2.SetIntersect(Standard_False); - // - aMV2.Perform(); - bDone = (aMV2.ErrorStatus() == 0); - if (bDone) { - aResult = aMV2.Shape(); + TopoDS_Shell aShellNew; + if (bFaces) { + aBB.MakeShell(aShellNew); + // + TopExp_Explorer aExp(aSh, TopAbs_FACE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Face& aFSh = *(TopoDS_Face*)&aExp.Current(); + if (!aMFaces.Contains(aFSh)) { + aBB.Add(aShellNew, aFSh); + } + } + } + else { + aShellNew = aSh; } + // + aBB.Add(aShells, aShellNew); } + myOffsetShape = aShells; } - // - TopExp_Explorer aExp(aResult, TopAbs_SHELL); - bDone = aExp.More(); - for (; aExp.More(); aExp.Next()) { - const TopoDS_Shape& aSh = aExp.Current(); - aBB.Add(aShells, aSh); - } - myOffsetShape = aShells; } } } -- 2.39.5