From bad76cfc7aa4e3801e4feb3d47ced5a5a8e108cc Mon Sep 17 00:00:00 2001 From: jgv Date: Tue, 23 Jan 2018 17:54:06 +0300 Subject: [PATCH] 0028903: BRepOffset_MakeOffset produces invalid shape (thickshell) in Intersection mode 1. Method BRepOffset_Tool::Inter3D is modified: now selection of proper edges is performed here, they are not concatenated into one edge if they go through a vertex on a boundary. 2. Method BRepOffset_Inter3d::ConnexIntByInt is modified: selection of edges is eliminated. 3. Method BRepOffset_Inter2d::ConnexIntByInt is corrected to be able to process seam edges correct. --- src/BRepAlgo/BRepAlgo_Loop.cxx | 9 + src/BRepOffset/BRepOffset_Inter2d.cxx | 45 +- src/BRepOffset/BRepOffset_Inter3d.cxx | 56 -- src/BRepOffset/BRepOffset_MakeOffset.cxx | 44 +- src/BRepOffset/BRepOffset_Tool.cxx | 968 ++++++++++------------- src/BRepOffset/BRepOffset_Tool.hxx | 90 ++- tests/bugs/modalg_2/bug5805_18 | 6 +- tests/bugs/modalg_2/bug5805_41 | 6 +- tests/bugs/modalg_2/bug5805_42 | 7 +- tests/bugs/modalg_2/bug5805_43 | 7 +- tests/bugs/modalg_6/bug26233 | 23 +- tests/bugs/modalg_7/bug28903 | 20 + tests/offset/faces_type_i/C9 | 4 +- tests/offset/faces_type_i/E3 | 2 +- tests/offset/faces_type_i/E5 | 1 - tests/offset/shape_type_i/C5 | 6 +- tests/offset/with_intersect_80/J9 | 4 - 17 files changed, 625 insertions(+), 673 deletions(-) create mode 100644 tests/bugs/modalg_7/bug28903 diff --git a/src/BRepAlgo/BRepAlgo_Loop.cxx b/src/BRepAlgo/BRepAlgo_Loop.cxx index 9510e4cd38..2126f4674d 100644 --- a/src/BRepAlgo/BRepAlgo_Loop.cxx +++ b/src/BRepAlgo/BRepAlgo_Loop.cxx @@ -88,6 +88,15 @@ void BRepAlgo_Loop::Init(const TopoDS_Face& F) static void Bubble(const TopoDS_Edge& E, TopTools_SequenceOfShape& Seq) { + //Remove duplicates + for (Standard_Integer i = 1; i < Seq.Length(); i++) + for (Standard_Integer j = i+1; j <= Seq.Length(); j++) + if (Seq(i) == Seq(j)) + { + Seq.Remove(j); + j--; + } + Standard_Boolean Invert = Standard_True; Standard_Integer NbPoints = Seq.Length(); Standard_Real U1,U2; diff --git a/src/BRepOffset/BRepOffset_Inter2d.cxx b/src/BRepOffset/BRepOffset_Inter2d.cxx index e12dd8233e..2af3660608 100644 --- a/src/BRepOffset/BRepOffset_Inter2d.cxx +++ b/src/BRepOffset/BRepOffset_Inter2d.cxx @@ -112,6 +112,28 @@ static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1, return V; } +static Standard_Boolean IsOrientationChanged(TopTools_IndexedMapOfShape& theMap, + const TopoDS_Edge& theEdge) +{ + Standard_Boolean IsOrChanged = Standard_False; + + if (!theMap.Contains(theEdge)) + theMap.Add(theEdge); + else + { + Standard_Integer anInd = theMap.FindIndex(theEdge); + const TopoDS_Shape& anEdge = theMap(anInd); + if (theEdge.Orientation() != anEdge.Orientation()) + { + theMap.Substitute( anInd, theEdge ); + IsOrChanged = Standard_True; + } + } + + return IsOrChanged; +} + + //======================================================================= //function : Store //purpose : Store the vertices into AsDes for the edge . @@ -1479,7 +1501,10 @@ void BRepOffset_Inter2d::ConnexIntByInt wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace)); if (!wexp.More()) continue; // Protection from case when explorer does not contain edges. - CurE = FirstE = wexp.Current(); + CurE = FirstE = wexp.Current(); + TopTools_IndexedMapOfShape Edges; + Standard_Boolean ToReverse1, ToReverse2; + ToReverse1 = IsOrientationChanged(Edges, CurE); while (!end) { wexp.Next(); if (wexp.More()) { @@ -1490,6 +1515,8 @@ void BRepOffset_Inter2d::ConnexIntByInt } if (CurE.IsSame(NextE)) continue; + ToReverse2 = IsOrientationChanged(Edges, NextE); + TopoDS_Vertex Vref = CommonVertex(CurE, NextE); gp_Pnt Pref = BRep_Tool::Pnt(Vref); @@ -1515,6 +1542,9 @@ void BRepOffset_Inter2d::ConnexIntByInt else if (Build.IsBound(NextE) && MES.IsBound(CEO)) { NE1 = Build(NextE); NE2 = MES(CEO); + Standard_Boolean Tmp = ToReverse1; + ToReverse1 = ToReverse2; + ToReverse2 = Tmp; } else { DoInter = 0; @@ -1526,9 +1556,17 @@ void BRepOffset_Inter2d::ConnexIntByInt Standard_Boolean bCoincide; TopExp_Explorer Exp1, Exp2; for (Exp1.Init(NE1, TopAbs_EDGE); Exp1.More(); Exp1.Next()) { - const TopoDS_Edge& aE1 = TopoDS::Edge(Exp1.Current()); + TopoDS_Edge aE1 = TopoDS::Edge(Exp1.Current()); for (Exp2.Init(NE2, TopAbs_EDGE); Exp2.More(); Exp2.Next()) { - const TopoDS_Edge& aE2 = TopoDS::Edge(Exp2.Current()); + TopoDS_Edge aE2 = TopoDS::Edge(Exp2.Current()); + + //Correct orientation of edges + if (ToReverse1) + aE1.Reverse(); + if (ToReverse2) + aE2.Reverse(); + ////////////////////////////// + RefEdgeInter(FIO, BAsurf, aE1, aE2, AsDes2d, Tol, Standard_True, Pref, theDMVV, bCoincide); } @@ -1553,6 +1591,7 @@ void BRepOffset_Inter2d::ConnexIntByInt } } CurE = NextE; + ToReverse1 = ToReverse2; } } } diff --git a/src/BRepOffset/BRepOffset_Inter3d.cxx b/src/BRepOffset/BRepOffset_Inter3d.cxx index 269fbdf57d..7a2e6368cc 100644 --- a/src/BRepOffset/BRepOffset_Inter3d.cxx +++ b/src/BRepOffset/BRepOffset_Inter3d.cxx @@ -100,57 +100,6 @@ static void ExtentEdge(const TopoDS_Face& /*F*/, } -//======================================================================= -//function : SelectEdge -//purpose : -//======================================================================= -static void SelectEdge (const TopoDS_Shape& theS, - TopTools_ListOfShape& theLE) -{ - 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(); - } - else { - aDist += Min(aP.Distance(aPE1), aP.Distance(aPE2)); - } - } - // - if (aDist < aDistMin) { - aDistMin = aDist; - aRE = aE; - } - } - // - theLE.Clear(); - theLE.Append(aRE); -} - //======================================================================= //function : CompletInt //purpose : @@ -617,11 +566,6 @@ void BRepOffset_Inter3d::ConnexIntByInt 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); - } SetDone(NF1,NF2); if (!LInt1.IsEmpty()) { Store (NF1,NF2,LInt1,LInt2); diff --git a/src/BRepOffset/BRepOffset_MakeOffset.cxx b/src/BRepOffset/BRepOffset_MakeOffset.cxx index 3ae17a9035..29b3a1b905 100644 --- a/src/BRepOffset/BRepOffset_MakeOffset.cxx +++ b/src/BRepOffset/BRepOffset_MakeOffset.cxx @@ -320,6 +320,26 @@ static Standard_Real ComputeMaxDist(const gp_Pln& thePlane, static void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList); //--------------------------------------------------------------------- + +static TopAbs_Orientation OrientationOfEdgeInFace(const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace) +{ + TopAbs_Orientation anOr = TopAbs_EXTERNAL; + + TopExp_Explorer Explo(theFace, TopAbs_EDGE); + for (; Explo.More(); Explo.Next()) + { + const TopoDS_Shape& anEdge = Explo.Current(); + if (anEdge.IsSame(theEdge)) + { + anOr = anEdge.Orientation(); + break; + } + } + + return anOr; +} + // static Standard_Boolean FindParameter(const TopoDS_Vertex& V, const TopoDS_Edge& E, @@ -480,7 +500,7 @@ static void GetEdgePoints(const TopoDS_Edge& anEdge, //======================================================================= static void FillContours(const TopoDS_Shape& aShape, const BRepOffset_Analyse& Analyser, - TopTools_DataMapOfShapeListOfShape& Contours, + TopTools_IndexedDataMapOfShapeListOfShape& Contours, TopTools_DataMapOfShapeShape& MapEF) { TopTools_ListOfShape Edges; @@ -533,7 +553,7 @@ static void FillContours(const TopoDS_Shape& aShape, break; } } - Contours.Bind(StartVertex, aContour); + Contours.Add(StartVertex, aContour); } } @@ -2497,18 +2517,17 @@ static void UpdateInitOffset (BRepAlgo_Image& myInitOffset, //======================================================================= void BRepOffset_MakeOffset::MakeMissingWalls () { - TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary) + TopTools_IndexedDataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary) TopTools_DataMapOfShapeShape MapEF; //Edges of contours: edge + face Standard_Real OffsetVal = Abs(myOffset); FillContours(myShape, myAnalyse, Contours, MapEF); - TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter(Contours); - for (; iter.More(); iter.Next()) + for (Standard_Integer ic = 1; ic <= Contours.Extent(); ic++) { - TopoDS_Vertex StartVertex = TopoDS::Vertex(iter.Key()); + TopoDS_Vertex StartVertex = TopoDS::Vertex(Contours.FindKey(ic)); TopoDS_Edge StartEdge; - const TopTools_ListOfShape& aContour = iter.Value(); + const TopTools_ListOfShape& aContour = Contours(ic); TopTools_ListIteratorOfListOfShape itl(aContour); Standard_Boolean FirstStep = Standard_True; TopoDS_Edge PrevEdge; @@ -2517,6 +2536,7 @@ void BRepOffset_MakeOffset::MakeMissingWalls () for (; itl.More(); itl.Next()) { TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); + TopoDS_Face aFaceOfEdge = TopoDS::Face(MapEF(anEdge)); // Check for offset existence. if (!myInitOffsetEdge.HasImage(anEdge)) @@ -2856,6 +2876,12 @@ void BRepOffset_MakeOffset::MakeMissingWalls () } BRepLib::SameParameter(NewFace); BRepTools::Update(NewFace); + //Check orientation + TopAbs_Orientation anOr = OrientationOfEdgeInFace(anEdge, aFaceOfEdge); + TopAbs_Orientation OrInNewFace = OrientationOfEdgeInFace(anEdge, NewFace); + if (OrInNewFace != TopAbs::Reverse(anOr)) + NewFace.Reverse(); + /////////////////// myWalls.Append(NewFace); if (ArcOnV2) { @@ -2938,7 +2964,9 @@ void BRepOffset_MakeOffset::MakeShells () TopTools_ListIteratorOfListOfShape it(R); // for (; it.More(); it.Next()) { - const TopoDS_Shape& aF = it.Value(); + TopoDS_Shape aF = it.Value(); + if (myThickening) //offsetted faces must change their orientations + aF.Reverse(); // TopTools_ListOfShape Image; myImageOffset.LastImage(aF,Image); diff --git a/src/BRepOffset/BRepOffset_Tool.cxx b/src/BRepOffset/BRepOffset_Tool.cxx index 0dcbcf3ac8..f0d32609b0 100644 --- a/src/BRepOffset/BRepOffset_Tool.cxx +++ b/src/BRepOffset/BRepOffset_Tool.cxx @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -137,7 +138,6 @@ const Standard_Real TheInfini = 1.e+7; #ifdef DRAW #include #include -#include #include Standard_Boolean AffichInter = Standard_False; static Standard_Integer NbNewEdges = 1; @@ -158,6 +158,8 @@ static TopTools_ListOfShape& theL1, TopTools_ListOfShape& theL2); +static void UpdateVertexTolerances(const TopoDS_Face& theFace); + inline Standard_Boolean IsInf(const Standard_Real theVal); @@ -198,7 +200,6 @@ TopAbs_Orientation BRepOffset_Tool::OriEdgeInFace (const TopoDS_Edge& E, throw Standard_ConstructionError("BRepOffset_Tool::OriEdgeInFace"); } - //======================================================================= //function : FindPeriod //purpose : @@ -799,6 +800,31 @@ void BRepOffset_Tool::PipeInter(const TopoDS_Face& F1, } } +//======================================================================= +//function : IsAutonomVertex +//purpose : Checks wether a vertex is "autonom" or not +//======================================================================= + +static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& theVertex, + const BOPDS_PDS& thePDS, + const TopoDS_Face& theFace1, + const TopoDS_Face& theFace2) +{ + Standard_Integer nV = thePDS->Index(theVertex); + Standard_Integer nF [2]; + nF[0] = thePDS->Index(theFace1); + nF[1] = thePDS->Index(theFace2); + + for (Standard_Integer i = 0; i < 2; i++) + { + const BOPDS_FaceInfo& aFaceInfo = thePDS->FaceInfo(nF[i]); + const TColStd_MapOfInteger& IndMap = aFaceInfo.VerticesOn(); + if (IndMap.Contains(nV)) + return Standard_False; + } + + return Standard_True; +} //======================================================================= //function : IsAutonomVertex @@ -874,8 +900,7 @@ static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& aVertex, //======================================================================= static Standard_Boolean AreConnex(const TopoDS_Wire& W1, - const TopoDS_Wire& W2, - const BOPDS_PDS& pDS) + const TopoDS_Wire& W2) { TopoDS_Vertex V11, V12, V21, V22; TopExp::Vertices( W1, V11, V12 ); @@ -883,55 +908,7 @@ static Standard_Boolean AreConnex(const TopoDS_Wire& W1, if (V11.IsSame(V21) || V11.IsSame(V22) || V12.IsSame(V21) || V12.IsSame(V22)) - { - Standard_Boolean isCV1 = V11.IsSame(V21) || V11.IsSame(V22); - Standard_Boolean isCV2 = V12.IsSame(V21) || V12.IsSame(V22); - if (isCV1 && !IsAutonomVertex(V11, pDS)) - { - if (!isCV2) - return Standard_False; - if (!IsAutonomVertex(V12, pDS)) - return Standard_False; - } - if (!isCV1 && !IsAutonomVertex(V12, pDS)) - return Standard_False; - - TopoDS_Vertex CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12; - TopoDS_Edge E1, E2; - TopoDS_Iterator itw( W1 ); - for (; itw.More(); itw.Next()) - { - E1 = TopoDS::Edge(itw.Value()); - TopoDS_Vertex V1, V2; - TopExp::Vertices( E1, V1, V2 ); - if (V1.IsSame(CV) || V2.IsSame(CV)) - break; - } - itw.Initialize( W2 ); - E2 = TopoDS::Edge(itw.Value()); - - Standard_Real f, l; - Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, f, l ); - if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) - C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve(); - - Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, f, l ); - if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) - C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve(); - - if (C1->IsInstance(STANDARD_TYPE(Geom_Line)) && - C2->IsInstance(STANDARD_TYPE(Geom_Line))) - { - Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast (C1); - gp_Ax1 Axis1 = L1->Position(); - Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast (C2); - gp_Ax1 Axis2 = L2->Position(); - if (! Axis1.IsParallel( Axis2, Precision::Angular() )) - return Standard_False; - } - - return Standard_True; - } + return Standard_True; return Standard_False; } @@ -1190,6 +1167,8 @@ static TopoDS_Edge Glue(const TopoDS_Edge& E1, const Standard_Boolean addPCurve2, const Standard_Real theGlueTol) { + TopoDS_Edge newEdge; + Standard_Real Tol = 1.e-7; GeomAbs_Shape Continuity = GeomAbs_C1; Standard_Integer MaxDeg = 14; @@ -1226,7 +1205,8 @@ static TopoDS_Edge Glue(const TopoDS_Edge& E1, Handle(Geom_TrimmedCurve) TC1 = new Geom_TrimmedCurve( C1, first1, last1 ); Handle(Geom_TrimmedCurve) TC2 = new Geom_TrimmedCurve( C2, first2, last2 ); GeomConvert_CompCurveToBSplineCurve Concat( TC1 ); - Concat.Add( TC2, theGlueTol, After ); + if (!Concat.Add( TC2, theGlueTol, After )) + return newEdge; newCurve = Concat.BSplineCurve(); if (newCurve->Continuity() < GeomAbs_C1) { @@ -1238,7 +1218,6 @@ static TopoDS_Edge Glue(const TopoDS_Edge& E1, lparam = newCurve->LastParameter(); } - TopoDS_Edge newEdge; BRep_Builder BB; if (IsCanonic) @@ -1263,242 +1242,82 @@ static TopoDS_Edge Glue(const TopoDS_Edge& E1, return newEdge; } - -//======================================================================= -//function : FindNewVerticesOnBoundsOfFace -//purpose : -//======================================================================= - -static void FindNewVerticesOnBoundsOfFace(const BOPDS_PDS& pDS, - const TopoDS_Face& aFace, - TopTools_DataMapOfShapeShape& VEmap) -{ - TopTools_IndexedMapOfShape OldVertices; - TopExp::MapShapes( aFace, TopAbs_VERTEX, OldVertices ); - BOPDS_ListIteratorOfListOfPaveBlock aItLPB; - TopoDS_Vertex V1, V2; - - TopExp_Explorer Explo( aFace, TopAbs_EDGE ); - for (; Explo.More(); Explo.Next()) { - const TopoDS_Shape& aE = Explo.Current(); - Standard_Integer nE = pDS->Index(aE); - // - const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(nE); - aItLPB.Initialize(aLPB); - for (; aItLPB.More(); aItLPB.Next()) { - const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); - const TopoDS_Edge& aESp = *(TopoDS_Edge*)&pDS->Shape(aPB->Edge()); - // - TopExp::Vertices( aESp, V1, V2 ); - if (!OldVertices.Contains( V1 )) { - VEmap.Bind( V1, aE ); - } - // - if (!OldVertices.Contains( V2 )) { - VEmap.Bind( V2, aE ); - } -} - } -} - //======================================================================= //function : CheckIntersFF //purpose : //======================================================================= -static Standard_Boolean CheckIntersFF(const BOPDS_PDS& pDS, - const TopoDS_Edge& RefEdge, - const TopoDS_Face& F1, - const TopoDS_Face& F2, - TopTools_IndexedMapOfShape& TrueEdges) +static void CheckIntersFF(const BOPDS_PDS& pDS, + const TopoDS_Edge& RefEdge, + TopTools_IndexedMapOfShape& TrueEdges) { - Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False; - Standard_Boolean isPlane1 = Standard_False, isPlane2 = Standard_False; - - Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1); - if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) - aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface(); - if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane))) - isPlane1 = Standard_True; - else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface))) - isEl1 = Standard_True; - - aSurf = BRep_Tool::Surface(F2); - if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) - aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface(); - if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane))) - isPlane2 = Standard_True; - else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface))) - isEl2 = Standard_True; - - if (isPlane1 || isPlane2) - return Standard_True; - - if (isEl1 && isEl2) - return Standard_True; - BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF(); Standard_Integer aNb = aFFs.Length(); Standard_Integer i, j, nbe = 0; - TopTools_SequenceOfShape Edges; + TopoDS_Compound Edges; + BRep_Builder BB; + BB.MakeCompound(Edges); for (i = 0; i < aNb; ++i) - { - BOPDS_InterfFF& aFFi=aFFs(i); - const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves(); + { + BOPDS_InterfFF& aFFi=aFFs(i); + const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves(); Standard_Integer aNbCurves = aBCurves.Length(); - - for (j = 0; j < aNbCurves; ++j) - { - const BOPDS_Curve& aBC=aBCurves(j); - const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks(); - - BOPDS_ListIteratorOfListOfPaveBlock aPBIt; - aPBIt.Initialize(aSectEdges); - - for (; aPBIt.More(); aPBIt.Next()) - { - const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value(); - Standard_Integer nSect = aPB->Edge(); - const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect); - Edges.Append( anEdge ); - nbe++; - } - } - } - - if (nbe <= 1) - return Standard_True; - - //define tangents of RefEdge on start and on end - BRepAdaptor_Curve cref(RefEdge); - gp_Vec RefTangFirst = cref.DN(cref.FirstParameter(), 1); - gp_Vec RefTangLast = cref.DN(cref.LastParameter(), 1); - - //find the start edge and take it from Edges - TopoDS_Edge StartEdge; //, StartEonF1, StartEonF2, EndEonF1, EndEonF2; - - TopTools_DataMapOfShapeShape VEmapF1, VEmapF2; - FindNewVerticesOnBoundsOfFace( pDS, F1, VEmapF1 ); - FindNewVerticesOnBoundsOfFace( pDS, F2, VEmapF2 ); - - Standard_Real AngTol = 0.1; - Standard_Boolean V1onBound = Standard_False; - Standard_Boolean V2onBound = Standard_False; - TopoDS_Vertex V1, V2, Vcur; - gp_Vec TangFirst, TangLast, TangCur; - for (i = 1; i <= Edges.Length(); i++) + + for (j = 0; j < aNbCurves; ++j) { - StartEdge = TopoDS::Edge(Edges(i)); - TopExp::Vertices( StartEdge, V1, V2 ); - V1onBound = VEmapF1.IsBound(V1) || VEmapF2.IsBound(V1); // && ? - V2onBound = VEmapF1.IsBound(V2) || VEmapF2.IsBound(V2); // && ? - if (V1onBound || V2onBound) - { - BRepAdaptor_Curve CE(StartEdge); - TangFirst = CE.DN( CE.FirstParameter(), 1 ); - TangLast = CE.DN( CE.LastParameter(), 1 ); - if (V1onBound) - { - if (TangFirst.IsParallel( RefTangFirst, AngTol ) || - TangFirst.IsParallel( RefTangLast, AngTol )) - break; //start edged found - } - else if (V2onBound) - { - if (TangLast.IsParallel( RefTangLast, AngTol ) || - TangLast.IsParallel( RefTangFirst, AngTol )) - break; //start edged found - } - } + const BOPDS_Curve& aBC=aBCurves(j); + const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks(); + + BOPDS_ListIteratorOfListOfPaveBlock aPBIt; + aPBIt.Initialize(aSectEdges); + + for (; aPBIt.More(); aPBIt.Next()) + { + const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value(); + Standard_Integer nSect = aPB->Edge(); + const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect); + BB.Add(Edges, anEdge); + nbe++; + } } + } - if (i > Edges.Length()) //start edged not found - return Standard_False; + if (nbe == 0) + return; + + TopTools_ListOfShape CompList; + BOPTools_AlgoTools::MakeConnexityBlocks(Edges, TopAbs_VERTEX, TopAbs_EDGE, CompList); - if (V1onBound && V2onBound) + TopoDS_Shape NearestCompound; + if (CompList.Extent() == 1) + NearestCompound = CompList.First(); + else + { + BRepAdaptor_Curve BAcurve(RefEdge); + gp_Pnt Pref = BAcurve.Value((BAcurve.FirstParameter()+BAcurve.LastParameter())/2); + TopoDS_Vertex Vref = BRepLib_MakeVertex(Pref); + Standard_Real MinDist = RealLast(); + TopTools_ListIteratorOfListOfShape itl(CompList); + for (; itl.More(); itl.Next()) { - if ((TangFirst.IsParallel(RefTangFirst,AngTol) && TangLast.IsParallel(RefTangLast,AngTol)) || - (TangFirst.IsParallel(RefTangLast,AngTol) && TangLast.IsParallel(RefTangFirst,AngTol))) + const TopoDS_Shape& aCompound = itl.Value(); + + BRepExtrema_DistShapeShape Projector(Vref, aCompound); + if (!Projector.IsDone() || Projector.NbSolution() == 0) + continue; + + Standard_Real aDist = Projector.Value(); + if (aDist < MinDist) { - TrueEdges.Add( Edges(i) ); - return Standard_True; + MinDist = aDist; + NearestCompound = aCompound; } - else - return Standard_False; } + } - //StartEonF1 = (V1onBound)? VEmapF1( V1 ) : VEmapF1( V2 ); - //StartEonF2 = (V1onBound)? VEmapF2( V1 ) : VEmapF2( V2 ); - - TrueEdges.Add( Edges(i) ); - Edges.Remove(i); - Vcur = (V1onBound)? V2 : V1; - TangCur = (V1onBound)? TangLast : TangFirst; - if (V2onBound) - TangCur.Reverse(); - - //build the chain from StartEdge till the opposite bound of face - for (;;) - { - TColStd_SequenceOfInteger Candidates; - for (i = 1; i <= Edges.Length(); i++) - { - TopoDS_Edge anEdge = TopoDS::Edge(Edges(i)); - TopExp::Vertices( anEdge, V1, V2 ); - if (V1.IsSame(Vcur) || V2.IsSame(Vcur)) - Candidates.Append(i); - } - if (Candidates.IsEmpty()) - { - TrueEdges.Clear(); - return Standard_False; - } - - Standard_Integer minind = 1; - if (Candidates.Length() > 1) - { - Standard_Real MinAngle = RealLast(); - for (i = 1; i <= Candidates.Length(); i++) - { - TopoDS_Edge anEdge = TopoDS::Edge(Edges(Candidates(i))); - TopExp::Vertices( anEdge, V1, V2 ); - Standard_Boolean ConnectByFirst = (Vcur.IsSame(V1))? Standard_True : Standard_False; - BRepAdaptor_Curve CE(anEdge); - gp_Vec aTang = (ConnectByFirst)? - CE.DN( CE.FirstParameter(), 1 ) : CE.DN( CE.LastParameter(), 1 ); - if (!ConnectByFirst) - aTang.Reverse(); - Standard_Real anAngle = TangCur.Angle(aTang); - if (anAngle < MinAngle) - { - MinAngle = anAngle; - minind = i; - } - } - } - TopoDS_Edge CurEdge = TopoDS::Edge(Edges(Candidates(minind))); - TrueEdges.Add( CurEdge ); - Edges.Remove(Candidates(minind)); - TopExp::Vertices( CurEdge, V1, V2 ); - Standard_Boolean ConnectByFirst = (Vcur.IsSame(V1))? Standard_True : Standard_False; - Vcur = (ConnectByFirst)? V2 : V1; - BRepAdaptor_Curve CE(CurEdge); - TangCur = (ConnectByFirst)? CE.DN( CE.LastParameter(), 1 ) : CE.DN( CE.FirstParameter(), 1 ); - if (!ConnectByFirst) - TangCur.Reverse(); - //check if Vcur is on bounds of faces - if (VEmapF1.IsBound(Vcur) || VEmapF2.IsBound(Vcur)) - break; - } //end of for (;;) - - if (TangCur.IsParallel( RefTangFirst, AngTol ) || - TangCur.IsParallel( RefTangLast, AngTol )) - return Standard_True; - - TrueEdges.Clear(); - return Standard_False; + TopExp::MapShapes(NearestCompound, TopAbs_EDGE, TrueEdges); } //======================================================================= @@ -1507,67 +1326,83 @@ static Standard_Boolean CheckIntersFF(const BOPDS_PDS& pDS, //======================================================================= static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS, - const TopoDS_Face& F1, - const TopoDS_Face& F2, - const Standard_Boolean addPCurve1, - const Standard_Boolean addPCurve2, - const TopTools_SequenceOfShape& EdgesForConcat) + const TopoDS_Face& F1, + const TopoDS_Face& F2, + const Standard_Boolean addPCurve1, + const Standard_Boolean addPCurve2, + const TopTools_SequenceOfShape& EdgesForConcat) { + TopoDS_Edge NullEdge; TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) ); Standard_Real aGlueTol = Precision::Confusion(); + for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++) + { + TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) ); + Standard_Boolean After = Standard_False; + TopoDS_Vertex Vfirst, Vlast; + Standard_Boolean AreClosedWire = AreClosed( CurEdge, anEdge ); + if (AreClosedWire) { - TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) ); - Standard_Boolean After = Standard_False; - TopoDS_Vertex Vfirst, Vlast; - if (AreClosed( CurEdge, anEdge )) - { - TopoDS_Vertex V1, V2; - TopExp::Vertices( CurEdge, V1, V2 ); - if (IsAutonomVertex( V1, pDS )) - { - After = Standard_False; - Vfirst = Vlast = V2; - } - else - { - After = Standard_True; - Vfirst = Vlast = V1; - } - } + TopoDS_Vertex V1, V2; + TopExp::Vertices( CurEdge, V1, V2 ); + Standard_Boolean IsAutonomV1 = IsAutonomVertex( V1, pDS, F1, F2 ); + Standard_Boolean IsAutonomV2 = IsAutonomVertex( V2, pDS, F1, F2 ); + if (IsAutonomV1) + { + After = Standard_False; + Vfirst = Vlast = V2; + } + else if (IsAutonomV2) + { + After = Standard_True; + Vfirst = Vlast = V1; + } else - { - TopoDS_Vertex CV, V11, V12, V21, V22; - TopExp::CommonVertex( CurEdge, anEdge, CV ); - aGlueTol = BRep_Tool::Tolerance(CV); - TopExp::Vertices( CurEdge, V11, V12 ); - TopExp::Vertices( anEdge, V21, V22 ); - if (V11.IsSame(CV) && V21.IsSame(CV)) - { - Vfirst = V22; - Vlast = V12; - } - else if (V11.IsSame(CV) && V22.IsSame(CV)) - { - Vfirst = V21; - Vlast = V12; - } - else if (V12.IsSame(CV) && V21.IsSame(CV)) - { - Vfirst = V11; - Vlast = V22; - } - else - { - Vfirst = V11; - Vlast = V21; - } - } //end of else (open wire) - - TopoDS_Edge NewEdge = Glue(CurEdge, anEdge, Vfirst, Vlast, After, - F1, addPCurve1, F2, addPCurve2, aGlueTol); + return NullEdge; + } + else + { + TopoDS_Vertex CV, V11, V12, V21, V22; + TopExp::CommonVertex( CurEdge, anEdge, CV ); + Standard_Boolean IsAutonomCV = IsAutonomVertex( CV, pDS, F1, F2 ); + if (IsAutonomCV) + { + aGlueTol = BRep_Tool::Tolerance(CV); + TopExp::Vertices( CurEdge, V11, V12 ); + TopExp::Vertices( anEdge, V21, V22 ); + if (V11.IsSame(CV) && V21.IsSame(CV)) + { + Vfirst = V22; + Vlast = V12; + } + else if (V11.IsSame(CV) && V22.IsSame(CV)) + { + Vfirst = V21; + Vlast = V12; + } + else if (V12.IsSame(CV) && V21.IsSame(CV)) + { + Vfirst = V11; + Vlast = V22; + } + else + { + Vfirst = V11; + Vlast = V21; + } + } + else + return NullEdge; + } //end of else (open wire) + + TopoDS_Edge NewEdge = Glue(CurEdge, anEdge, Vfirst, Vlast, After, + F1, addPCurve1, F2, addPCurve2, aGlueTol); + if (NewEdge.IsNull()) + return NullEdge; + else CurEdge = NewEdge; - } //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++) + } //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++) return CurEdge; } @@ -1610,49 +1445,38 @@ void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1, } } } - // - TopoDS_Face cpF1=F1; - TopoDS_Face cpF2=F2; + // create 3D curves on faces - BRepLib::BuildCurves3d(cpF1); - BRepLib::BuildCurves3d(cpF2); + BRepLib::BuildCurves3d(F1); + BRepLib::BuildCurves3d(F2); + UpdateVertexTolerances(F1); + UpdateVertexTolerances(F2); - BOPAlgo_PaveFiller aPF1, aPF2; + BOPAlgo_PaveFiller aPF; TopTools_ListOfShape aLS; - aLS.Append(cpF1); - aLS.Append(cpF2); - aPF1.SetArguments(aLS); + aLS.Append(F1); + aLS.Append(F2); + aPF.SetArguments(aLS); // - aPF1.Perform(); + aPF.Perform(); - BOPAlgo_PaveFiller *pPF = &aPF1; - - aLS.Clear(); TopTools_IndexedMapOfShape TrueEdges; - if (IsRefEdgeDefined && !CheckIntersFF( pPF->PDS(), RefEdge, cpF1, cpF2, TrueEdges )) - { - cpF1 = F2; - cpF2 = F1; - aLS.Append(cpF1); - aLS.Append(cpF2); - aPF2.SetArguments(aLS); - aPF2.Perform(); - pPF = &aPF2; - CheckIntersFF( pPF->PDS(), RefEdge, cpF1, cpF2, TrueEdges ); - } + if (IsRefEdgeDefined) + CheckIntersFF( aPF.PDS(), RefEdge, TrueEdges ); Standard_Boolean addPCurve1 = 1; Standard_Boolean addPCurve2 = 1; - const BOPDS_PDS& pDS = pPF->PDS(); + const BOPDS_PDS& pDS = aPF.PDS(); BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF(); Standard_Integer aNb = aFFs.Length(); Standard_Integer i = 0, j = 0, k; // Store Result L1.Clear(); L2.Clear(); TopAbs_Orientation O1,O2; + BRep_Builder BB; // - const Handle(IntTools_Context)& aContext = pPF->Context(); + const Handle(IntTools_Context)& aContext = aPF.Context(); // for (i = 0; i < aNb; i++) { BOPDS_InterfFF& aFFi=aFFs(i); @@ -1681,39 +1505,38 @@ void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1, if(!aC3DE.IsNull()) aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l); - BRep_Builder aBB; Standard_Real aTolEdge = BRep_Tool::Tolerance(anEdge); - if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, cpF1)) { + if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F1)) { Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d(); if(!aC3DETrim.IsNull()) { Handle(Geom2d_Curve) aC2dNew; if(aC3DE->IsPeriodic()) { - BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF1, f, l, aC2d, aC2dNew, aContext); + BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, f, l, aC2d, aC2dNew, aContext); } else { - BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF1, aC3DETrim, aC2d, aC2dNew, aContext); + BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, aC3DETrim, aC2d, aC2dNew, aContext); } aC2d = aC2dNew; } - aBB.UpdateEdge(anEdge, aC2d, cpF1, aTolEdge); + BB.UpdateEdge(anEdge, aC2d, F1, aTolEdge); } - if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, cpF2)) { + if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F2)) { Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d(); if(!aC3DETrim.IsNull()) { Handle(Geom2d_Curve) aC2dNew; if(aC3DE->IsPeriodic()) { - BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF2, f, l, aC2d, aC2dNew, aContext); + BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, f, l, aC2d, aC2dNew, aContext); } else { - BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF2, aC3DETrim, aC2d, aC2dNew, aContext); + BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, aC3DETrim, aC2d, aC2dNew, aContext); } aC2d = aC2dNew; } - aBB.UpdateEdge(anEdge, aC2d, cpF2, aTolEdge); + BB.UpdateEdge(anEdge, aC2d, F2, aTolEdge); } OrientSection (anEdge, F1, F2, O1, O2); @@ -1740,7 +1563,7 @@ void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1, Standard_Real aSameParTol = Precision::Confusion(); Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False; - Handle(Geom_Surface) aSurf = BRep_Tool::Surface(cpF1); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1); if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface(); if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane))) @@ -1748,7 +1571,7 @@ void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1, else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface))) isEl1 = Standard_True; - aSurf = BRep_Tool::Surface(cpF2); + aSurf = BRep_Tool::Surface(F2); if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface(); if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane))) @@ -1759,204 +1582,214 @@ void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1, if (L1.Extent() > 1 && (!isEl1 || !isEl2)) { TopTools_SequenceOfShape eseq; TopTools_SequenceOfShape EdgesForConcat; - + if (!TrueEdges.IsEmpty()) - { - for (i = TrueEdges.Extent(); i >= 1; i--) - EdgesForConcat.Append( TrueEdges(i) ); - TopoDS_Edge theEdge = - AssembleEdge( pDS, cpF1, cpF2, addPCurve1, addPCurve2, EdgesForConcat ); - eseq.Append(theEdge); - } + { + for (i = TrueEdges.Extent(); i >= 1; i--) + EdgesForConcat.Append( TrueEdges(i) ); + TopoDS_Edge AssembledEdge = + AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, EdgesForConcat ); + if (AssembledEdge.IsNull()) + for (i = TrueEdges.Extent(); i >= 1; i--) + eseq.Append( TrueEdges(i) ); + else + eseq.Append(AssembledEdge); + } else + { + TopTools_SequenceOfShape wseq; + TopTools_SequenceOfShape edges; + TopTools_ListIteratorOfListOfShape itl(L1); + for (; itl.More(); itl.Next()) + edges.Append( itl.Value() ); + while (!edges.IsEmpty()) { + TopoDS_Edge anEdge = TopoDS::Edge( edges.First() ); + TopoDS_Wire aWire, resWire; + BB.MakeWire(aWire); + BB.Add( aWire, anEdge ); + TColStd_SequenceOfInteger Candidates; + for (k = 1; k <= wseq.Length(); k++) + { + resWire = TopoDS::Wire(wseq(k)); + if (AreConnex( resWire, aWire )) + { + Candidates.Append( 1 ); + break; + } + } + if (Candidates.IsEmpty()) + { + wseq.Append( aWire ); + edges.Remove(1); + } + else + { + for (j = 2; j <= edges.Length(); j++) + { + anEdge = TopoDS::Edge( edges(j) ); + aWire.Nullify(); + BB.MakeWire(aWire); + BB.Add( aWire, anEdge ); + if (AreConnex( resWire, aWire )) + Candidates.Append( j ); + } + Standard_Integer minind = 1; + if (Candidates.Length() > 1) + { + Standard_Real MinAngle = RealLast(); + for (j = 1; j <= Candidates.Length(); j++) + { + anEdge = TopoDS::Edge( edges(Candidates(j)) ); + Standard_Real anAngle = AngleWireEdge( resWire, anEdge ); + if (anAngle < MinAngle) + { + MinAngle = anAngle; + minind = j; + } + } + } + BB.Add( resWire, TopoDS::Edge(edges(Candidates(minind))) ); + wseq(k) = resWire; + edges.Remove(Candidates(minind)); + } + } //end of while (!edges.IsEmpty()) + + for (i = 1; i <= wseq.Length(); i++) + { + TopoDS_Wire aWire = TopoDS::Wire(wseq(i)); + TopTools_SequenceOfShape aLocalEdgesForConcat; + if (aWire.Closed()) + { + TopoDS_Vertex StartVertex; + TopoDS_Edge StartEdge; + Standard_Boolean StartFound = Standard_False; + TopTools_ListOfShape Elist; + + TopoDS_Iterator itw(aWire); + for (; itw.More(); itw.Next()) + { + TopoDS_Edge anEdge = TopoDS::Edge(itw.Value()); + if (StartFound) + Elist.Append(anEdge); + else + { + TopoDS_Vertex V1, V2; + TopExp::Vertices( anEdge, V1, V2 ); + if (!IsAutonomVertex( V1, pDS )) + { + StartVertex = V2; + StartEdge = anEdge; + StartFound = Standard_True; + } + else if (!IsAutonomVertex( V2, pDS )) + { + StartVertex = V1; + StartEdge = anEdge; + StartFound = Standard_True; + } + else + Elist.Append(anEdge); + } + } //end of for (; itw.More(); itw.Next()) + if (!StartFound) + { + itl.Initialize(Elist); + StartEdge = TopoDS::Edge(itl.Value()); + Elist.Remove(itl); + TopoDS_Vertex V1, V2; + TopExp::Vertices( StartEdge, V1, V2 ); + StartVertex = V1; + } + aLocalEdgesForConcat.Append( StartEdge ); + while (!Elist.IsEmpty()) + { + for (itl.Initialize(Elist); itl.More(); itl.Next()) + { + TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); + TopoDS_Vertex V1, V2; + TopExp::Vertices( anEdge, V1, V2 ); + if (V1.IsSame(StartVertex)) + { + StartVertex = V2; + aLocalEdgesForConcat.Append( anEdge ); + Elist.Remove(itl); + break; + } + else if (V2.IsSame(StartVertex)) + { + StartVertex = V1; + aLocalEdgesForConcat.Append( anEdge ); + Elist.Remove(itl); + break; + } + } + } //end of while (!Elist.IsEmpty()) + } //end of if (aWire.Closed()) + else + { + BRepTools_WireExplorer Wexp( aWire ); + for (; Wexp.More(); Wexp.Next()) + aLocalEdgesForConcat.Append( Wexp.Current() ); + } - TopTools_SequenceOfShape wseq; - TopTools_SequenceOfShape edges; - TopTools_ListIteratorOfListOfShape itl(L1); - for (; itl.More(); itl.Next()) - edges.Append( itl.Value() ); - while (!edges.IsEmpty()) - { - TopoDS_Edge anEdge = TopoDS::Edge( edges.First() ); - TopoDS_Wire aWire = BRepLib_MakeWire( anEdge ), resWire; - TColStd_SequenceOfInteger Candidates; - for (k = 1; k <= wseq.Length(); k++) - { - resWire = TopoDS::Wire(wseq(k)); - if (AreConnex( resWire, aWire, pDS )) - { - Candidates.Append( 1 ); - break; - } - } - if (Candidates.IsEmpty()) - { - wseq.Append( aWire ); - edges.Remove(1); - } - else - { - for (j = 2; j <= edges.Length(); j++) - { - anEdge = TopoDS::Edge( edges(j) ); - //if (anEdge.IsSame(edges(Candidates.First()))) - //continue; - aWire = BRepLib_MakeWire( anEdge ); - if (AreConnex( resWire, aWire, pDS )) - Candidates.Append( j ); - } - Standard_Integer minind = 1; - if (Candidates.Length() > 1) - { - Standard_Real MinAngle = RealLast(); - for (j = 1; j <= Candidates.Length(); j++) - { - anEdge = TopoDS::Edge( edges(Candidates(j)) ); - Standard_Real anAngle = AngleWireEdge( resWire, anEdge ); - if (anAngle < MinAngle) - { - MinAngle = anAngle; - minind = j; - } - } - } - TopoDS_Wire NewWire = BRepLib_MakeWire( resWire, TopoDS::Edge(edges(Candidates(minind))) ); - wseq(k) = NewWire; - edges.Remove(Candidates(minind)); - } - } //end of while (!edges.IsEmpty()) - - for (i = 1; i <= wseq.Length(); i++) - { - TopoDS_Wire aWire = TopoDS::Wire(wseq(i)); - TopTools_SequenceOfShape aLocalEdgesForConcat; - if (aWire.Closed()) - { - TopoDS_Vertex StartVertex; - TopoDS_Edge StartEdge; - Standard_Boolean StartFound = Standard_False; - TopTools_ListOfShape Elist; - - TopoDS_Iterator itw(aWire); - for (; itw.More(); itw.Next()) - { - TopoDS_Edge anEdge = TopoDS::Edge(itw.Value()); - if (StartFound) - Elist.Append(anEdge); - else - { - TopoDS_Vertex V1, V2; - TopExp::Vertices( anEdge, V1, V2 ); - if (!IsAutonomVertex( V1, pDS )) - { - StartVertex = V2; - StartEdge = anEdge; - StartFound = Standard_True; - } - else if (!IsAutonomVertex( V2, pDS )) - { - StartVertex = V1; - StartEdge = anEdge; - StartFound = Standard_True; - } - else - Elist.Append(anEdge); - } - } //end of for (; itw.More(); itw.Next()) - if (!StartFound) - { - itl.Initialize(Elist); - StartEdge = TopoDS::Edge(itl.Value()); - Elist.Remove(itl); - TopoDS_Vertex V1, V2; - TopExp::Vertices( StartEdge, V1, V2 ); - StartVertex = V1; - } - aLocalEdgesForConcat.Append( StartEdge ); - while (!Elist.IsEmpty()) - { - for (itl.Initialize(Elist); itl.More(); itl.Next()) - { - TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); - TopoDS_Vertex V1, V2; - TopExp::Vertices( anEdge, V1, V2 ); - if (V1.IsSame(StartVertex)) - { - StartVertex = V2; - aLocalEdgesForConcat.Append( anEdge ); - Elist.Remove(itl); - break; - } - else if (V2.IsSame(StartVertex)) - { - StartVertex = V1; - aLocalEdgesForConcat.Append( anEdge ); - Elist.Remove(itl); - break; - } - } - } //end of while (!Elist.IsEmpty()) - } //end of if (aWire.Closed()) - else - { - BRepTools_WireExplorer Wexp( aWire ); - for (; Wexp.More(); Wexp.Next()) - aLocalEdgesForConcat.Append( Wexp.Current() ); - } - - TopoDS_Edge theEdge = - AssembleEdge( pDS, cpF1, cpF2, addPCurve1, addPCurve2, aLocalEdgesForConcat ); - eseq.Append( theEdge ); - } - } //end of else (when TrueEdges is empty) + TopoDS_Edge AssembledEdge = + AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, aLocalEdgesForConcat ); + if (AssembledEdge.IsNull()) + for (j = aLocalEdgesForConcat.Length(); j >= 1; j--) + eseq.Append( aLocalEdgesForConcat(j) ); + else + eseq.Append( AssembledEdge ); + } + } //end of else (when TrueEdges is empty) if (eseq.Length() < L1.Extent()) + { + L1.Clear(); + L2.Clear(); + for (i = 1; i <= eseq.Length(); i++) { - L1.Clear(); - L2.Clear(); - for (i = 1; i <= eseq.Length(); i++) - { - TopoDS_Edge anEdge = TopoDS::Edge(eseq(i)); - BRepLib::SameParameter(anEdge, aSameParTol, Standard_True); - Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge); + TopoDS_Shape aShape = eseq(i); + TopoDS_Edge anEdge = TopoDS::Edge(eseq(i)); + BRepLib::SameParameter(anEdge, aSameParTol, Standard_True); + Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge); #ifdef OCCT_DEBUG - cout<<"Tolerance of glued E = "< 2.e-7} { + puts "Error: bad tolerance of result" } + +checkprops result -v 1.38649e+006 diff --git a/tests/bugs/modalg_7/bug28903 b/tests/bugs/modalg_7/bug28903 new file mode 100644 index 0000000000..13a267f66f --- /dev/null +++ b/tests/bugs/modalg_7/bug28903 @@ -0,0 +1,20 @@ +puts "============" +puts "OCC28903" +puts "============" +puts "" +################################################################################## +# BRepOffset_MakeOffset produces invalid shape (thickshell) in Intersection mode +################################################################################## + +restore [locate_data_file bug28903_Fuse_3.brep] a + +thickshell result a 10 i +donly result + +checkshape result + +checknbshapes result -solid 1 -shell 1 -face 6 -wire 7 -edge 12 -vertex 7 -shape 34 + +checkmaxtol result -min_tol 0.0015 + +checkprops result -v 1.1845e+006 diff --git a/tests/offset/faces_type_i/C9 b/tests/offset/faces_type_i/C9 index 0cf1d58eb9..6a79959219 100644 --- a/tests/offset/faces_type_i/C9 +++ b/tests/offset/faces_type_i/C9 @@ -1,8 +1,6 @@ puts "TODO OCC23748 ALL: ERROR. offsetperform operation not done." -puts "TODO OCC23748 ALL: Error: The command cannot be built" puts "TODO OCC23748 ALL: Error : The offset cannot be built." + psphere s 15 270 OFFSETSHAPE 1 {s_2} $calcul $type - -checkprops result -v 0 diff --git a/tests/offset/faces_type_i/E3 b/tests/offset/faces_type_i/E3 index fab3bdfdfe..fe509d5d6c 100644 --- a/tests/offset/faces_type_i/E3 +++ b/tests/offset/faces_type_i/E3 @@ -2,4 +2,4 @@ ptorus s 20 5 270 OFFSETSHAPE 1 {s_2} $calcul $type -checkprops result -v -296.088 +checkprops result -v 3370.13 diff --git a/tests/offset/faces_type_i/E5 b/tests/offset/faces_type_i/E5 index 88ea057663..8031e2b66f 100644 --- a/tests/offset/faces_type_i/E5 +++ b/tests/offset/faces_type_i/E5 @@ -1,4 +1,3 @@ -puts "TODO OCC23068 ALL: Faulty shapes in variables faulty_1 to faulty_2 " ptorus s 20 5 270 OFFSETSHAPE 1 {s_2 s_3} $calcul $type diff --git a/tests/offset/shape_type_i/C5 b/tests/offset/shape_type_i/C5 index af39420776..551b6a5c52 100644 --- a/tests/offset/shape_type_i/C5 +++ b/tests/offset/shape_type_i/C5 @@ -1,8 +1,8 @@ puts "TODO OCC24156 MacOS: \\*\\* Exception \\*\\*.*" puts "TODO OCC24156 MacOS: An exception was caught" puts "TODO OCC24156 MacOS: TEST INCOMPLETE" -puts "TODO OCC23068 ALL: Error : The volume of result shape is" -puts "TODO OCC25406 ALL: Error: bsection of the result and s is not equal to zero" +puts "TODO OCC23068 ALL: Faulty shapes in variables faulty_1 to faulty_" +puts "TODO OCC23068 ALL: Error : The area of face result_3 of the resulting shape is negative." ellipse w1 0 0 0 15 10 mkedge w1 w1 0 pi/2 @@ -13,5 +13,3 @@ mkplane w w revol s w 0 0 0 0 0 1 90 OFFSETSHAPE 1 {} $calcul $type - -checkprops result -v 0 diff --git a/tests/offset/with_intersect_80/J9 b/tests/offset/with_intersect_80/J9 index 5c5f4e7904..bee5a06b09 100644 --- a/tests/offset/with_intersect_80/J9 +++ b/tests/offset/with_intersect_80/J9 @@ -1,7 +1,3 @@ -puts "TODO OCC26578 All:An exception was caught" -puts "TODO OCC26578 All:\\*\\* Exception \\*\\*" -puts "TODO OCC26578 All:TEST INCOMPLETE" restore [locate_data_file bug26663_test_offset_J9.brep] s OFFSETSHAPE ${off_param} {} ${calcul} ${type} -checknbshapes result -ref [lrange [nbshapes s] 8 19] -- 2.20.1