From c3cb810368ca0dc4ca7dc2bb4197584040283381 Mon Sep 17 00:00:00 2001 From: gka Date: Fri, 11 Mar 2016 11:29:21 +0300 Subject: [PATCH] 0027151: Exception is raised during performing command "splitshape" in the Test Harness Tolerance of vertices's of the degenerated edges are increased to value of tolerance of the splitting vertex for case when splitting vertex was projected on the degenerated edge. --- src/LocOpe/LocOpe_SplitShape.cxx | 51 +++++++++++------------ src/LocOpe/LocOpe_WiresOnShape.cxx | 65 ++++++++++++++++++------------ 2 files changed, 63 insertions(+), 53 deletions(-) diff --git a/src/LocOpe/LocOpe_SplitShape.cxx b/src/LocOpe/LocOpe_SplitShape.cxx index 98971c896a..163c393f6b 100644 --- a/src/LocOpe/LocOpe_SplitShape.cxx +++ b/src/LocOpe/LocOpe_SplitShape.cxx @@ -179,15 +179,14 @@ void LocOpe_SplitShape::Add(const TopoDS_Vertex& V, le.Remove(itl); if (V.Orientation() == TopAbs_FORWARD || V.Orientation() == TopAbs_REVERSED) { - //TopAbs_Orientation anOriEdge= edg.Orientation(); - ////// + edg.Orientation(TopAbs_FORWARD); TopoDS_Vertex aCurV1, aCurV2; TopExp::Vertices(edg, aCurV1, aCurV2); Standard_Real aPar1 = BRep_Tool::Parameter(aCurV1,edg); Standard_Real aPar2 = BRep_Tool::Parameter(aCurV2,edg); - ////////// + TopoDS_Shape aLocalShape = edg.EmptyCopied(); TopoDS_Edge E1 = TopoDS::Edge(aLocalShape); aLocalShape = edg.EmptyCopied(); @@ -197,23 +196,31 @@ void LocOpe_SplitShape::Add(const TopoDS_Vertex& V, E1.Orientation(TopAbs_FORWARD); E2.Orientation(TopAbs_FORWARD); TopoDS_Vertex newVtx = V; - + Standard_Real aTolSplitV = BRep_Tool::Tolerance(V); aCurV1.Orientation(TopAbs_FORWARD); B.Add(E1,aCurV1); - B.UpdateVertex(aCurV1,aPar1,E1,BRep_Tool::Tolerance(aCurV1)); + //for degenerated edges tolerance of vertices should be set to maximal value + //from tolerance of the vertex of the edge and tolerance of splitting vertex + Standard_Real aTolV1 = ( BRep_Tool::Degenerated(edg) ? + Max(BRep_Tool::Tolerance(aCurV1), aTolSplitV) : BRep_Tool::Tolerance(aCurV1)); + + B.UpdateVertex(aCurV1,aPar1,E1, aTolV1); newVtx.Orientation(TopAbs_REVERSED); B.Add(E1,newVtx); B.UpdateVertex(newVtx,P,E1,BRep_Tool::Tolerance(V)); - newVtx.Orientation(TopAbs_FORWARD); B.Add(E2,newVtx); B.UpdateVertex(newVtx,P,E2,BRep_Tool::Tolerance(V)); aCurV2.Orientation(TopAbs_REVERSED); B.Add(E2,aCurV2); - B.UpdateVertex(aCurV2,aPar2,E2,BRep_Tool::Tolerance(aCurV2)); + + //for degenerated edges tolerance of vertices should be set to maximal value + //from tolerance of the vertex of the edge and tolerance of splitting vertex + Standard_Real aTolV2 = ( BRep_Tool::Degenerated(edg) ? aTolV1 : BRep_Tool::Tolerance(aCurV2)); + B.UpdateVertex(aCurV2,aPar2,E2,aTolV2); aNewList.Append(E1); aNewList.Append(E2); @@ -591,6 +598,7 @@ Standard_Boolean LocOpe_SplitShape::Add(const TopoDS_Wire& W, } + //======================================================================= //function : AddClosedWire //purpose : @@ -618,7 +626,7 @@ Standard_Boolean LocOpe_SplitShape::AddClosedWire(const TopoDS_Wire& W, } BRep_Builder B; - + TopAbs_Orientation orWire = W.Orientation(); TopoDS_Shape aLocalFace = F.EmptyCopied(); TopoDS_Face newFace = TopoDS::Face(aLocalFace); @@ -692,16 +700,16 @@ Standard_Boolean LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W, toll = BRep_Tool::Tolerance(Vlast); tol1 = Max(tolf, toll); - + TopExp_Explorer exp,exp2; - + TopoDS_Wire wfirst,wlast; for (; itl.More(); itl.Next()) { TopoDS_Face fac = TopoDS::Face(itl.Value()); if (!IsInside(fac,W)) { continue; } - + fac.Orientation(TopAbs_FORWARD); Standard_Boolean ffound = Standard_False; Standard_Boolean lfound = Standard_False; @@ -776,6 +784,7 @@ Standard_Boolean LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W, TopTools_MapOfOrientedShape MapE; TopoDS_Vertex vdeb,vfin; Standard_Integer nbPoss; + // On recherche l`edge contenant Vlast TopoDS_Edge LastEdge; gp_Pnt2d pfirst,plast; @@ -794,7 +803,6 @@ Standard_Boolean LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W, if (exp2.More()) { LastEdge = edg; LastEdge.Orientation(edg.Orientation()); - break; } } @@ -826,8 +834,6 @@ Standard_Boolean LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W, } } aLocalFace = FaceRef.Oriented(wfirst.Orientation()); - - //TopoDS_Edge aStartEdge = LastEdge; GetDirection(LastEdge, TopoDS::Face(aLocalFace),plast , dlast, Standard_False); Standard_Boolean cond; @@ -839,7 +845,7 @@ Standard_Boolean LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W, else { cond = !(Vfirst.IsSame(Vlast)); } - + while (cond) { PossE.Clear(); @@ -852,16 +858,8 @@ Standard_Boolean LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W, TopExp::Vertices(edg,vdeb,vfin); if ((orient == TopAbs_FORWARD && Vlast.IsSame(vdeb)) || - (orient == TopAbs_REVERSED && Vlast.IsSame(vfin))) { - /* if(edg == aStartEdge) - { - PossE.Clear(); - PossE.Add(edg); - break; - }*/ - PossE.Add(edg); - - } + (orient == TopAbs_REVERSED && Vlast.IsSame(vfin))) + PossE.Add(edg); } nbPoss = PossE.Extent(); if (nbPoss == 0) @@ -893,9 +891,8 @@ Standard_Boolean LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W, return Standard_False; } - if (MapE.Contains(aNextEdge)) + if (MapE.Contains(aNextEdge)) break; - B.Add(newW1, aNextEdge); MapE.Add(aNextEdge); LastEdge = aNextEdge; diff --git a/src/LocOpe/LocOpe_WiresOnShape.cxx b/src/LocOpe/LocOpe_WiresOnShape.cxx index 106a2acb00..b037a1a046 100644 --- a/src/LocOpe/LocOpe_WiresOnShape.cxx +++ b/src/LocOpe/LocOpe_WiresOnShape.cxx @@ -239,7 +239,7 @@ void LocOpe_WiresOnShape::BindAll() continue; if (myCheckInterior) - FindInternalIntersections(edg, fac, Splits);//, myMap, theMap); + FindInternalIntersections(edg, fac, Splits); } for (Ind = 1; Ind <= Splits.Extent(); Ind++) @@ -280,15 +280,18 @@ void LocOpe_WiresOnShape::BindAll() Standard_Real prm = 0.; Standard_Boolean ok = Project(vtx, p2d, fac, Epro, prm); if (ok) { + for (exp2.Init(Epro,TopAbs_VERTEX); exp2.More(); exp2.Next()) { const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current()); if (vtx2.IsSame(vtx)) { break; } else if (BRepTools::Compare(vtx,vtx2)) { + Standard_Real aF1, aL1; + BRep_Tool::Range(Epro, fac, aF1, aL1); if (!BRep_Tool::Degenerated(Epro) || - Abs(prm-BAcurve2d.FirstParameter()) <= Precision::PConfusion() || - Abs(prm-BAcurve2d.LastParameter()) <= Precision::PConfusion()) + Abs(prm-aF1) <= Precision::PConfusion() || + Abs(prm-aL1) <= Precision::PConfusion()) { myMap.Bind(vtx,vtx2); break; @@ -456,13 +459,13 @@ Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V, TopoDS_Shape aShape = myMapEF.FindFromKey(EdgeFrom); if( aShape.ShapeType() == TopAbs_FACE) { - //// + TopoDS_Face aFace = TopoDS::Face(aShape); Standard_Real vtx_param = BRep_Tool::Parameter(V, EdgeFrom); BRepAdaptor_Curve2d BAcurve2d(EdgeFrom, aFace); gp_Pnt2d p2d = BAcurve2d.Value(vtx_param); - //// + prm = Project(V, p2d, Ed, aFace); } else @@ -519,15 +522,24 @@ Standard_Boolean Project(const TopoDS_Vertex& V, Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F); aSurf->D0(aPBound2d.X(), aPBound2d.Y(), aPBound); - gp_Pnt aPV; - aSurf->D0(p2d.X(), p2d.Y(), aPV); - Standard_Real aDist3d = aPV.Distance(aPBound); - - Standard_Real ttol = BRep_Tool::Tolerance(V) + BRep_Tool::Tolerance(theEdge); - if (aDist3d <= ttol) { + //point of vertex computed by pcurve of the splitting edge + gp_Pnt aPV2d; + aSurf->D0(p2d.X(), p2d.Y(), aPV2d); + //point of vertex in 3D splace + gp_Pnt aP3dV = BRep_Tool::Pnt(V); + + Standard_Real aDist3d2 = Max( aPV2d.SquareDistance(aPBound), aP3dV.SquareDistance(aPBound)); + Standard_Real aTolV = BRep_Tool::Tolerance(V); + Standard_Real ttol = aTolV + BRep_Tool::Tolerance(theEdge); + if (aDist3d2 <= ttol* ttol) { valret = Standard_True; + BRep_Builder B; - B.UpdateVertex(V, Max(aDist3d, BRep_Tool::Tolerance(V))); + if( aTolV * aTolV < aDist3d2) + { + Standard_Real aNewTol = sqrt(aDist3d2) + Precision::Confusion(); + B.UpdateVertex(V, aNewTol); + } } #ifdef OCCT_DEBUG_MESH else { @@ -1147,16 +1159,19 @@ void FindInternalIntersections(const TopoDS_Edge& theEdge, gp_Pnt thePnt [2]; thePnt[0] = BRep_Tool::Pnt(theVertices[0]); thePnt[1] = BRep_Tool::Pnt(theVertices[1]); - + Standard_Real aTolV[2]; + aTolV[0] =BRep_Tool::Tolerance(theVertices[0]); + aTolV[1] =BRep_Tool::Tolerance(theVertices[1]); + BRepAdaptor_Curve2d thePCurve(theEdge, theFace); Bnd_Box2d theBox; BndLib_Add2dCurve::Add(thePCurve, BRep_Tool::Tolerance(theEdge), theBox); Standard_Real thePar [2]; - Standard_Real /*theFpar, theLpar,*/ aFpar, aLpar; + Standard_Real aFpar, aLpar; const Handle(Geom_Curve)& theCurve = BRep_Tool::Curve(theEdge, thePar[0], thePar[1]); GeomAdaptor_Curve theGAcurve(theCurve, thePar[0], thePar[1]); - Standard_Real aDistMax = Precision::Confusion(); + Standard_Real aDistMax = Precision::Confusion() * Precision::Confusion(); TopExp_Explorer Explo(theFace, TopAbs_EDGE); for (; Explo.More(); Explo.Next()) { @@ -1178,29 +1193,28 @@ void FindInternalIntersections(const TopoDS_Edge& theEdge, aNbExt = anExtrema.NbExt(); Standard_Real MaxTol = Max(BRep_Tool::Tolerance(theEdge), BRep_Tool::Tolerance(anEdge)); + Standard_Real aMaxTol2 = MaxTol * MaxTol; for (i = 1; i <= aNbExt; i++) { - Standard_Real aDist = Sqrt(anExtrema.SquareDistance(i)); - if (aDist > MaxTol) + Standard_Real aDist = anExtrema.SquareDistance(i); + if (aDist > aMaxTol2) continue; Extrema_POnCurv aPOnC1, aPOnC2; anExtrema.Points(i, aPOnC1, aPOnC2); Standard_Real theIntPar = aPOnC1.Parameter(); Standard_Real anIntPar = aPOnC2.Parameter(); - //Standard_Boolean IntersFound = Standard_False; for (j = 0; j < 2; j++) //try to find intersection on an extremity of "theEdge" { if (Abs(theIntPar - thePar[j]) <= Precision::PConfusion()) break; - } //intersection found in the middle of the edge - if (j >= 2)//!IntersFound) //intersection is inside "theEdge" => split + if (j >= 2) //intersection is inside "theEdge" => split { gp_Pnt aPoint = aCurve->Value(anIntPar); - if (aPoint.Distance(thePnt[0]) > BRep_Tool::Tolerance(theVertices[0]) && - aPoint.Distance(thePnt[1]) > BRep_Tool::Tolerance(theVertices[1])) + if (aPoint.SquareDistance(thePnt[0]) > aTolV[0] * aTolV[0] && + aPoint.SquareDistance(thePnt[1]) > aTolV[1] * aTolV[1]) { SplitPars.Append(theIntPar); if( aDist > aDistMax) @@ -1228,7 +1242,7 @@ void FindInternalIntersections(const TopoDS_Edge& theEdge, { gp_Pnt Pnt1 = theCurve->Value(SplitPars(i)); gp_Pnt Pnt2 = theCurve->Value(SplitPars(i+1)); - if (Pnt1.Distance(Pnt2) <= Precision::Confusion()) + if (Pnt1.SquareDistance(Pnt2) <= Precision::Confusion()* Precision::Confusion()) SplitPars.Remove(i+1); else i++; @@ -1237,8 +1251,7 @@ void FindInternalIntersections(const TopoDS_Edge& theEdge, //Split TopTools_ListOfShape NewEdges; BRep_Builder BB; - //theVertices[0].Orientation(TopAbs_FORWARD); - //theVertices[1].Orientation(TopAbs_REVERSED); + TopoDS_Vertex FirstVertex = theVertices[0], LastVertex; Standard_Real FirstPar = thePar[0], LastPar; for (i = 1; i <= SplitPars.Length()+1; i++) @@ -1250,7 +1263,7 @@ void FindInternalIntersections(const TopoDS_Edge& theEdge, gp_Pnt LastPoint = theCurve->Value(LastPar); LastVertex = BRepLib_MakeVertex(LastPoint); BRep_Builder aB; - aB.UpdateVertex(LastVertex, aDistMax); + aB.UpdateVertex(LastVertex, sqrt(aDistMax)); } else { -- 2.39.5