From: jgv Date: Mon, 9 Oct 2017 03:36:42 +0000 (+0300) Subject: Next version. X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2FCR29003_4;p=occt-copy.git Next version. --- diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.cxx b/src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.cxx index 638fb6b0c6..05c0eb2596 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.cxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.cxx @@ -45,7 +45,141 @@ #include //#include //#include +#include +#include +#include +#include +#include + +static void ProlongEdge(const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace, + gp_Pnt& theFirstPnt, + gp_Pnt& theLastPnt) +{ + BRepAdaptor_Curve2d BAcurve2d(theEdge, theFace); + gp_Pnt2d EndP2d [2]; + gp_Pnt2d StartP2d [2]; + gp_Vec2d StartVec [2]; + Handle(Geom2d_Curve) Ray [2], BoundLine [4]; + Geom2dAdaptor_Curve GAray [2], GAline [4]; + + BAcurve2d.D1(BAcurve2d.FirstParameter(), StartP2d[0], StartVec[0]); + StartVec[0].Reverse(); + BAcurve2d.D1(BAcurve2d.LastParameter(), StartP2d[1], StartVec[1]); + + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace); + Standard_Real Umin, Umax, Vmin, Vmax; + aSurf->Bounds(Umin, Umax, Vmin, Vmax); + BoundLine[0] = new Geom2d_Line(gp_Pnt2d( Umin, Vmin ), + gp_Dir2d( 1., 0. )); + BoundLine[0] = new Geom2d_TrimmedCurve(BoundLine[0], 0., Umax-Umin); + BoundLine[1] = new Geom2d_Line(gp_Pnt2d( Umax, Vmin ), + gp_Dir2d( 0., 1. )); + BoundLine[1] = new Geom2d_TrimmedCurve(BoundLine[1], 0., Vmax-Vmin); + BoundLine[2] = new Geom2d_Line(gp_Pnt2d( Umax, Vmax ), + gp_Dir2d( -1., 0. )); + BoundLine[2] = new Geom2d_TrimmedCurve(BoundLine[2], 0., Umax-Umin); + BoundLine[3] = new Geom2d_Line(gp_Pnt2d( Umin, Vmax ), + gp_Dir2d( 0., -1. )); + BoundLine[3] = new Geom2d_TrimmedCurve(BoundLine[3], 0., Vmax-Vmin); + + GAline[0].Load(BoundLine[0]); + GAline[1].Load(BoundLine[1]); + GAline[2].Load(BoundLine[2]); + GAline[3].Load(BoundLine[3]); + + for (Standard_Integer i = 0; i < 2; i++) + { + Ray[i] = new Geom2d_Line(StartP2d[i], StartVec[i]); + //Ray[i] = new Geom2d_TrimmedCurve(Ray[i], 0., Precision::Infinite()); + GAray[i].Load(Ray[i], 0., Precision::Infinite()); + for (Standard_Integer j = 0; j < 4; j++) + { + Geom2dInt_GInter Inters2d(GAray[i], GAline[j], + Precision::PConfusion(), Precision::PConfusion()); + if (Inters2d.IsDone() && Inters2d.NbPoints() > 0) + { + const IntRes2d_IntersectionPoint& ip = Inters2d.Point(1); + EndP2d[i] = ip.Value(); + break; + } + } + } + + BRepAdaptor_Surface BAsurf(theFace, Standard_False); + theFirstPnt = BAsurf.Value(EndP2d[0].X(), EndP2d[0].Y()); + theLastPnt = BAsurf.Value(EndP2d[1].X(), EndP2d[1].Y()); +} +static void UpdateVertexTol(TopoDS_Vertex& theVertex, + const TopoDS_Edge& theEdge1, + const TopoDS_Edge& theEdge2, + TColStd_SequenceOfReal& theIntParamsOnFirst, + TColStd_SequenceOfReal& theIntParamsOnSecond) +{ + BRepAdaptor_Curve BAcurve1(theEdge1); + BRepAdaptor_Curve BAcurve2(theEdge2); + //fpar = BAcurve.FirstParameter(); + //lpar = BAcurve.LastParameter(); + gp_Pnt PntVtx = BRep_Tool::Pnt(theVertex); + BRep_Builder BB; + + for (Standard_Integer i = 1; i <= theIntParamsOnFirst.Length(); i++) + { + Standard_Real aParamOnFirst = theIntParamsOnFirst(i); + Standard_Real aParamOnSecond = theIntParamsOnSecond(i); + if (aParamOnFirst <= BAcurve1.FirstParameter() || + aParamOnFirst >= BAcurve1.LastParameter() || + aParamOnSecond <= BAcurve2.FirstParameter() || + aParamOnSecond >= BAcurve2.LastParameter()) + continue; + + gp_Pnt aPnt = BAcurve1.Value(aParamOnFirst); + Standard_Real aDist = PntVtx.Distance(aPnt); + BB.UpdateVertex(theVertex, 1.001*aDist); + } +} + +static Standard_Real Project2dPointOnSegment(const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace, + const Standard_Real theFirstPar, + const Standard_Real theLastPar, + const gp_Pnt2d& theP2dRef, + Standard_Real& theParam, + gp_Pnt2d& theP2d) +{ + Standard_Real fpar, lpar; + Handle(Geom2d_Curve) PCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, fpar, lpar); + Geom2dAdaptor_Curve GAcurve2d(PCurve, theFirstPar, theLastPar); + + Extrema_ExtPC2d Projector(theP2dRef, GAcurve2d); + Standard_Real Param[4], dist[4], distmin; + gp_Pnt2d Pnt2d[4]; + Param[1] = theFirstPar; + Param[2] = theLastPar; + Projector.TrimmedSquareDistances(dist[1], dist[2], Pnt2d[1], Pnt2d[2]); + dist[3] = RealLast(); + if (Projector.IsDone() && Projector.NbExt() > 0) + { + Standard_Integer imin = 1; + for (Standard_Integer i = 2; i <= Projector.NbExt(); i++) + if (Projector.SquareDistance(i) < Projector.SquareDistance(imin)) + imin = i; + Param[3] = Projector.Point(imin).Parameter(); + dist[3] = Projector.SquareDistance(imin); + Pnt2d[3] = Projector.Point(imin).Value(); + } + + Standard_Integer imin = 1; + for (Standard_Integer i = 2; i <= 3; i++) + if (dist[i] < dist[imin]) + imin = i; + + theParam = Param[imin]; + theP2d = Pnt2d[imin]; + distmin = dist[imin]; + return distmin; +} static Standard_Boolean EdgeContains(const TopoDS_Edge& theEdge, const TopoDS_Vertex& theVertex) @@ -62,7 +196,7 @@ static void ProjectVertexOnAnotherEdge_2d(const TopoDS_Vertex& theVertex, const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2, const TopoDS_Face& theFace, - const gp_Pnt2d& theP2dRef, + const gp_Pnt2d& /*theP2dRef*/, Standard_Real& theSqDistReached, Standard_Real& theParamOnFirst, Standard_Real& theParamOnSecond) @@ -78,16 +212,17 @@ static void ProjectVertexOnAnotherEdge_2d(const TopoDS_Vertex& theVertex, Param[1] = SecondBAcurve2d.FirstParameter(); Param[2] = SecondBAcurve2d.LastParameter(); Projector.TrimmedSquareDistances(dist[1], dist[2], Pnt2d[1], Pnt2d[2]); - dist[1] = theP2dRef.SquareDistance(Pnt2d[1]); - dist[2] = theP2dRef.SquareDistance(Pnt2d[2]); + //dist[1] = theP2dRef.SquareDistance(Pnt2d[1]); + //dist[2] = theP2dRef.SquareDistance(Pnt2d[2]); dist[3] = RealLast(); if (Projector.IsDone()) { Standard_Integer imin = 0; for (Standard_Integer i = 1; i <= Projector.NbExt(); i++) { - gp_Pnt2d aPnt2dOnSecondEdge = Projector.Point(i).Value(); - Standard_Real aDist = theP2dRef.SquareDistance(aPnt2dOnSecondEdge); + //gp_Pnt2d aPnt2dOnSecondEdge = Projector.Point(i).Value(); + //Standard_Real aDist = theP2dRef.SquareDistance(aPnt2dOnSecondEdge); + Standard_Real aDist = Projector.SquareDistance(i); if (aDist < dist[3]) { dist[3] = aDist; @@ -136,7 +271,9 @@ static Standard_Boolean IntersectIn2d(const TopoDS_Vertex& theNewVertex, Standard_Real& theParamOnSecond, gp_Pnt& thePntSol, gp_Pnt& thePntOnFirst, - gp_Pnt& thePntOnSecond) + gp_Pnt& thePntOnSecond, + TColStd_SequenceOfReal& theIntParamsOnFirst, + TColStd_SequenceOfReal& theIntParamsOnSecond) { //Current range BRepAdaptor_Curve BAprevcurve(theEdge1); @@ -166,21 +303,63 @@ static Standard_Boolean IntersectIn2d(const TopoDS_Vertex& theNewVertex, Geom2dInt_GInter Inters2d(BAprevcurve2d, BAcurcurve2d, Precision::PConfusion(), Precision::PConfusion()); - if (Inters2d.IsDone() && Inters2d.NbSegments() == 0) + if (Inters2d.IsDone()) { - for (Standard_Integer iint = 1; iint <= Inters2d.NbPoints(); iint++) + for (Standard_Integer i = 1; i <= Inters2d.NbPoints(); i++) { - const IntRes2d_IntersectionPoint& ip = Inters2d.Point(iint); + const IntRes2d_IntersectionPoint& ip = Inters2d.Point(i); + Standard_Real ParOnFirst = ip.ParamOnFirst(); + Standard_Real ParOnSecond = ip.ParamOnSecond(); + theIntParamsOnFirst.Append(ParOnFirst); + theIntParamsOnSecond.Append(ParOnSecond); gp_Pnt2d Pint2d = ip.Value(); //Standard_Real aDist = Pnt2dOnNewEdge.SquareDistance(Pint2d); Standard_Real aDist = theP2dRef.SquareDistance(Pint2d); if (aDist < DistRef[1]) { DistRef[1] = aDist; - imin = iint; + imin = i; + ParOnPrev[1] = ParOnFirst; + ParOnCur[1] = ParOnSecond; } //gp_Pnt Pint = BAprevcurve.Value(ip.ParamOnFirst()); } + for (Standard_Integer i = 1; i <= Inters2d.NbSegments(); i++) + { + const IntRes2d_IntersectionSegment& iseg = Inters2d.Segment(i); + const IntRes2d_IntersectionPoint& FirstPoint = iseg.FirstPoint(); + const IntRes2d_IntersectionPoint& LastPoint = iseg.LastPoint(); + Standard_Real fparOnFirst = FirstPoint.ParamOnFirst(); + Standard_Real lparOnFirst = LastPoint.ParamOnFirst(); + Standard_Real fparOnSecond = FirstPoint.ParamOnSecond(); + Standard_Real lparOnSecond = LastPoint.ParamOnSecond(); + if (lparOnFirst < fparOnFirst) + { Standard_Real tmp = fparOnFirst; fparOnFirst = lparOnFirst; lparOnFirst = tmp; } + if (lparOnSecond < fparOnSecond) + { Standard_Real tmp = fparOnSecond; fparOnSecond = lparOnSecond; lparOnSecond = tmp; } + theIntParamsOnFirst.Append(fparOnFirst); + theIntParamsOnFirst.Append(lparOnFirst); + theIntParamsOnSecond.Append(fparOnSecond); + theIntParamsOnSecond.Append(lparOnSecond); + Standard_Real ParamOnFirst, ParamOnSecond; + gp_Pnt2d Pnt2dOnFirst, Pnt2dOnSecond; + Standard_Real aDist = Project2dPointOnSegment(theEdge1, theFace, + fparOnFirst, lparOnFirst, + theP2dRef, + ParamOnFirst, Pnt2dOnFirst); + Standard_Real aDistToSecond = Project2dPointOnSegment(theEdge2, theFace, + fparOnSecond, lparOnSecond, + Pnt2dOnFirst, + ParamOnSecond, Pnt2dOnSecond); + if (aDist < DistRef[1]) + { + DistRef[1] = aDist; + imin = i; + ParOnPrev[1] = ParamOnFirst; + ParOnCur[1] = ParamOnSecond; + } + } + /* if (imin != 0) { const IntRes2d_IntersectionPoint& ip = Inters2d.Point(imin); @@ -189,6 +368,7 @@ static Standard_Boolean IntersectIn2d(const TopoDS_Vertex& theNewVertex, //theParamOnFirst = ip.ParamOnFirst(); //theParamOnSecond = ip.ParamOnSecond(); } + */ } //Project @@ -243,7 +423,8 @@ static TopoDS_Edge MakeNewEdgeWithOldPcurvesOnNewSurfaces(const TopoDS_Edge& the BRep_Builder BB; Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, fpar, lpar); - aNewEdge = BRepLib_MakeEdge(aCurve, aCurve->FirstParameter(), aCurve->LastParameter()); //??? + //aNewEdge = BRepLib_MakeEdge(aCurve, aCurve->FirstParameter(), aCurve->LastParameter()); //??? + aNewEdge = BRepLib_MakeEdge(aCurve, fpar, lpar); TopoDS_Vertex V1, V2; TopExp::Vertices(aNewEdge, V1, V2); aNewEdge.Free(Standard_True); @@ -256,6 +437,62 @@ static TopoDS_Edge MakeNewEdgeWithOldPcurvesOnNewSurfaces(const TopoDS_Edge& the Handle(Geom2d_Curve) aPCurve2 = BRep_Tool::CurveOnSurface(theEdge, theOldFace2, fpar, lpar); BB.UpdateEdge(aNewEdge, aPCurve2, theNewFace2, Etol); + gp_Pnt Pnt1, Pnt2, Pnt3, Pnt4; + ProlongEdge(aNewEdge, theNewFace1, Pnt1, Pnt2); + ProlongEdge(aNewEdge, theNewFace2, Pnt3, Pnt4); + + BRepAdaptor_Curve BAcurve(aNewEdge); + gp_Pnt FirstPnt = BAcurve.Value(BAcurve.FirstParameter()); + gp_Pnt LastPnt = BAcurve.Value(BAcurve.LastParameter()); + + Standard_Real DistFirst1 = FirstPnt.SquareDistance(Pnt1); + Standard_Real DistFirst2 = FirstPnt.SquareDistance(Pnt3); + Standard_Real DistLast1 = LastPnt.SquareDistance(Pnt2); + Standard_Real DistLast2 = LastPnt.SquareDistance(Pnt4); + + gp_Pnt NewFirstPnt, NewLastPnt; + NewFirstPnt = (DistFirst1 < DistFirst2)? Pnt1 : Pnt3; + NewLastPnt = (DistLast1 < DistLast2)? Pnt2 : Pnt4; + + Handle(Geom_BoundedCurve) aTrCurve = new Geom_TrimmedCurve(aCurve, + BAcurve.FirstParameter(), + BAcurve.LastParameter()); + GeomLib::ExtendCurveToPoint(aTrCurve, NewFirstPnt, 1, Standard_False); //before + GeomLib::ExtendCurveToPoint(aTrCurve, NewLastPnt, 1, Standard_True); //after + + BB.UpdateEdge(aNewEdge, aTrCurve, Etol); + BB.Range(aNewEdge, aTrCurve->FirstParameter(), aTrCurve->LastParameter()); + + Handle(Geom_Surface) NewSurf1 = BRep_Tool::Surface(theNewFace1); + Handle(ShapeAnalysis_Surface) SAS1 = new ShapeAnalysis_Surface(NewSurf1); + ShapeConstruct_ProjectCurveOnSurface aToolProj; + aToolProj.Init(SAS1, Precision::Confusion()); + Handle(Geom2d_Curve) NewPCurve1; + aToolProj.Perform(aTrCurve, + aTrCurve->FirstParameter(), + aTrCurve->LastParameter(), + NewPCurve1); + Standard_Real TolReached = SAS1->Gap(); + //BB.UpdateEdge(anEdge, NullPCurve, aFace, 0.); + BB.UpdateEdge(aNewEdge, NewPCurve1, theNewFace1, TolReached); + + Handle(Geom_Surface) NewSurf2 = BRep_Tool::Surface(theNewFace2); + Handle(ShapeAnalysis_Surface) SAS2 = new ShapeAnalysis_Surface(NewSurf2); + aToolProj.Init(SAS2, Precision::Confusion()); + Handle(Geom2d_Curve) NewPCurve2; + aToolProj.Perform(aTrCurve, + aTrCurve->FirstParameter(), + aTrCurve->LastParameter(), + NewPCurve2); + TolReached = SAS2->Gap(); + BB.UpdateEdge(aNewEdge, NewPCurve2, theNewFace2, TolReached); + + Standard_Real ParamOfMaxDist; + BOPTools_AlgoTools::ComputeTolerance(theNewFace1, aNewEdge, TolReached, ParamOfMaxDist); + BB.UpdateEdge(aNewEdge, 1.001*TolReached); + BOPTools_AlgoTools::ComputeTolerance(theNewFace2, aNewEdge, TolReached, ParamOfMaxDist); + BB.UpdateEdge(aNewEdge, 1.001*TolReached); + return aNewEdge; } @@ -277,7 +514,10 @@ static void UpdateEdgeByProjectionOfPCurve(TopoDS_Edge& anEdge, Standard_Real TolReached = SAS->Gap(); //BB.UpdateEdge(anEdge, NullPCurve, aFace, 0.); BB.UpdateEdge(anEdge, NewPCurve, aBoundedNewFace, TolReached); - //Check + //Update tolerance for same parameter + Standard_Real ParamOfMaxDist; + BOPTools_AlgoTools::ComputeTolerance(aBoundedNewFace, anEdge, TolReached, ParamOfMaxDist); + /* Standard_Integer NCONTROL = 23; BRepAdaptor_Curve BAcurve(anEdge); BRepAdaptor_Curve BAcurveonsu(anEdge, aBoundedNewFace); @@ -290,6 +530,7 @@ static void UpdateEdgeByProjectionOfPCurve(TopoDS_Edge& anEdge, if (aDist > TolReached) TolReached = aDist; } + */ BB.UpdateEdge(anEdge, TolReached); /////// @@ -301,7 +542,8 @@ static void UpdateEdgeByProjectionOfPCurve(TopoDS_Edge& anEdge, static Standard_Real ProjectPointOnEdge(const gp_Pnt& thePoint, const TopoDS_Edge& theEdge, - Standard_Real& theParam) + Standard_Real& theParam, + gp_Pnt& thePnt) { BRepAdaptor_Curve BAcurve(theEdge); Extrema_ExtPC Projector(thePoint, BAcurve); @@ -328,7 +570,7 @@ static Standard_Real ProjectPointOnEdge(const gp_Pnt& thePoint, imin = i; theParam = Param[imin]; - //thePnt = Pnt[imin]; + thePnt = Pnt[imin]; Standard_Real MinSqDist = dist[imin]; return MinSqDist; } @@ -604,14 +846,14 @@ void BRepOffsetAPI_PatchFaces::AddPatchFace(const TopoDS_Face& theFace, void BRepOffsetAPI_PatchFaces::Build() { TopExp::MapShapesAndUniqueAncestors(myInitialShape, TopAbs_EDGE, TopAbs_FACE, myEFmap); - TopTools_IndexedDataMapOfShapeListOfShape VEmap; - TopExp::MapShapesAndUniqueAncestors(myInitialShape, TopAbs_VERTEX, TopAbs_EDGE, VEmap); - for (Standard_Integer i = 1; i <= VEmap.Extent(); i++) + //TopTools_IndexedDataMapOfShapeListOfShape VEmap; + TopExp::MapShapesAndUniqueAncestors(myInitialShape, TopAbs_VERTEX, TopAbs_EDGE, myVEmap); + for (Standard_Integer i = 1; i <= myVEmap.Extent(); i++) { - const TopoDS_Shape& aVertex = VEmap.FindKey(i); + const TopoDS_Shape& aVertex = myVEmap.FindKey(i); TopTools_ListOfShape aFaceList; TopTools_MapOfShape aFaceMap; - const TopTools_ListOfShape& Elist = VEmap(i); + const TopTools_ListOfShape& Elist = myVEmap(i); TopTools_ListIteratorOfListOfShape itl(Elist); for (; itl.More(); itl.Next()) { @@ -746,7 +988,7 @@ void BRepOffsetAPI_PatchFaces::Build() aNewEdge = MakeNewEdgeWithOldPcurvesOnNewSurfaces(anEdge, aFace, aBoundedNewFace, aNeighborFace, aBoundedNewNeighborFace); - + mySmoothEdges.Add(anEdge); myEdgeNewEdge.Bind(anEdge.Oriented(TopAbs_FORWARD), aNewEdge); continue; } @@ -775,11 +1017,12 @@ void BRepOffsetAPI_PatchFaces::Build() cout< by distances to inner points of intersection + UpdateVertexTol(CurNewVertex, thePrevNewEdge, theCurNewEdge, + IntParamsOnFirst, IntParamsOnSecond); } //two new edges: intersect else if (myEdgeNewEdge.IsBound(thePrevEdge) || myEdgeNewEdge.IsBound(theCurEdge)) //one constant edge: project point onto curve @@ -1102,9 +1395,12 @@ void BRepOffsetAPI_PatchFaces::UpdateEdgesAndVertex(const TopoDS_Edge& thePrevEd Pnt2dOnNewEdge, TolReached); //gp_Pnt Pint; + TColStd_SequenceOfReal IntParamsOnFirst, IntParamsOnSecond; + //if (!AreSmoothlyConnected(ConstantEdge, ModifiedEdge, theCurVertex, theFace)) IntersectIn2d(CurNewVertex, ConstantEdge, NewEdge, theBoundedNewFace, Pnt2dOnNewEdge, - ParamOnConstEdge, ParamOnNewEdge, PntSol, PntOnConstEdge, PntOnNewEdge); + ParamOnConstEdge, ParamOnNewEdge, PntSol, PntOnConstEdge, PntOnNewEdge, + IntParamsOnFirst, IntParamsOnSecond); gp_Pnt PntVtx = BRep_Tool::Pnt(CurNewVertex); TolReached = PntVtx.Distance(PntOnNewEdge); @@ -1134,8 +1430,11 @@ void BRepOffsetAPI_PatchFaces::UpdateEdgesAndVertex(const TopoDS_Edge& thePrevEd //if (!EdgeContains(NewEdge, CurNewVertex)) PutVertexToEdge(CurNewVertex, anOr, NewEdge, ModifiedEdge, - theFace, Pnt2dOnConstEdge, - ParamOnNewEdge); + theFace, Pnt2dOnConstEdge, ParamOnNewEdge); + + //Update tolerance of by distances to inner points of intersection + UpdateVertexTol(CurNewVertex, ConstantEdge, NewEdge, + IntParamsOnFirst, IntParamsOnSecond); } //else (one constant edge: project point onto curve) else //two constant edges { @@ -1180,27 +1479,17 @@ void BRepOffsetAPI_PatchFaces::PutVertexToEdge(const TopoDS_Vertex& theVerte TopoDS_Shape F_Edge = theEdge.Oriented(TopAbs_FORWARD); F_Edge.Free(Standard_True); BB.Add(F_Edge, theVertex.Oriented(anOr)); - } - - if (!Precision::IsInfinite(theParamOnEdge)) - { + Standard_Real fpar, lpar; BRep_Tool::Range(theEdge, fpar, lpar); - - if (EdgeContainsVertex) - { - //BRepAdaptor_Curve2d BAcurve2d(theEdge, theFace); - //gp_Pnt2d aPnt2d = BAcurve2d.Value((anOr == TopAbs_FORWARD)? fpar : lpar); - //Standard_Real aDist = Pnt2dOnConstEdge.Distance(aPnt2d); - //BB.UpdateVertex(theVertex, 1.001*aDist); - } + + Standard_Real NewFirst = fpar, NewLast = lpar; + if (anOr == TopAbs_FORWARD) + NewFirst = theParamOnEdge; else - { - if (anOr == TopAbs_FORWARD) - BB.Range(theEdge, theParamOnEdge, lpar); - else - BB.Range(theEdge, fpar, theParamOnEdge); - } + NewLast = theParamOnEdge; + + BB.Range(theEdge, NewFirst, NewLast); } } @@ -1293,3 +1582,56 @@ Standard_Boolean BRepOffsetAPI_PatchFaces::IsMoreThan3Edges(const TopoDS_Vertex& return Standard_False; } + +Standard_Boolean BRepOffsetAPI_PatchFaces::AreSmoothlyConnected(const TopoDS_Edge& theEdge1, + const TopoDS_Edge& theEdge2, + const TopoDS_Vertex& theVertex, + const TopoDS_Face& theFace, + TopoDS_Edge& theThirdEdge) +{ + TopoDS_Shape Face1, Face2; + TopTools_ListIteratorOfListOfShape itl; + + const TopTools_ListOfShape& Flist1 = myEFmap.FindFromKey(theEdge1); + for (itl.Initialize(Flist1); itl.More(); itl.Next()) + { + const TopoDS_Shape& aFace = itl.Value(); + if (!aFace.IsSame(theFace)) + { + Face1 = aFace; + break; + } + } + + const TopTools_ListOfShape& Flist2 = myEFmap.FindFromKey(theEdge2); + for (itl.Initialize(Flist2); itl.More(); itl.Next()) + { + const TopoDS_Shape& aFace = itl.Value(); + if (!aFace.IsSame(theFace)) + { + Face2 = aFace; + break; + } + } + + //TopoDS_Shape EdgeBetweenFaces; + const TopTools_ListOfShape& Elist = myVEmap.FindFromKey(theVertex); + for (itl.Initialize(Elist); itl.More(); itl.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value()); + if (anEdge.IsSame(theEdge1) || + anEdge.IsSame(theEdge2)) + continue; + const TopTools_ListOfShape& Flist = myEFmap.FindFromKey(anEdge); + if (Face1.IsSame(Flist.First()) && Face2.IsSame(Flist.Last()) || + Face1.IsSame(Flist.Last()) && Face2.IsSame(Flist.First())) + { + //EdgeBetweenFaces = anEdge; + theThirdEdge = anEdge; + break; + } + } + + //return (mySmoothEdges.Contains(EdgeBetweenFaces)); + return (mySmoothEdges.Contains(theThirdEdge)); +} diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.hxx b/src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.hxx index 62f2995992..d8560e8879 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.hxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.hxx @@ -31,6 +31,7 @@ #include #include #include +#include #include class TopoDS_Shape; @@ -97,6 +98,12 @@ private: Standard_EXPORT Standard_Boolean IsMoreThan3Edges(const TopoDS_Vertex& theVertex); + Standard_EXPORT Standard_Boolean AreSmoothlyConnected(const TopoDS_Edge& theEdge1, + const TopoDS_Edge& theEdge2, + const TopoDS_Vertex& theVertex, + const TopoDS_Face& theFace, + TopoDS_Edge& theThirdEdge); + TopoDS_Shape myInitialShape; @@ -107,8 +114,10 @@ private: //TopTools_DataMapOfOrientedShapeShape myOrientedEdgeNewEdge; TopTools_DataMapOfShapeShape myVertexNewVertex; TopTools_MapOfShape myTangentEdges; + TopTools_MapOfShape mySmoothEdges; TopTools_IndexedDataMapOfShapeListOfShape myEFmap; + TopTools_IndexedDataMapOfShapeListOfShape myVEmap; TopTools_DataMapOfShapeListOfShape myVFmap; }; diff --git a/tests/patchfaces/grids.list b/tests/patchfaces/grids.list index 55dee65f67..7592083f5a 100644 --- a/tests/patchfaces/grids.list +++ b/tests/patchfaces/grids.list @@ -1 +1,2 @@ 001 replace +002 replace_new \ No newline at end of file