From: aavtamon Date: Wed, 20 Jan 2021 11:46:17 +0000 (+0300) Subject: A new PCurve function. X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=20330c52b27b77661bfda6b7fa89b3f3c18363e8;p=occt-copy.git A new PCurve function. --- diff --git a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx index dc51c9c07d..059dea3182 100644 --- a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx +++ b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -1444,6 +1445,196 @@ static TopoDS_Edge GlueEdgesWithPCurves(const TopTools_SequenceOfShape& aChain, return ResEdge; } +//======================================================================= +//function : UnionPCurves +//purpose : +//======================================================================= + +static void UnionPCurves(const TopTools_SequenceOfShape& theChain, + TopoDS_Edge& theEdge) +{ + TColGeom_SequenceOfSurface aSurfSeq; + NCollection_Sequence aLocSeq; + + for (Standard_Integer anIndex = 1;; anIndex++) + { + Handle(Geom2d_Curve) aCurve; + Handle(Geom_Surface) aSurface; + TopLoc_Location aLocation; + Standard_Real aFirst, aLast; + TopoDS_Edge anEdge = TopoDS::Edge(theChain.Value(1)); + BRep_Tool::CurveOnSurface(anEdge, aCurve, aSurface, aLocation, aFirst, aLast, anIndex); + if (aCurve.IsNull()) + break; + + aSurfSeq.Append(aSurface); + aLocSeq.Append(aLocation); + } + + TColGeom2d_SequenceOfCurve ResPCurves; + TColStd_SequenceOfReal ResFirsts; + TColStd_SequenceOfReal ResLasts; + TopoDS_Vertex aPrevVertex; + TopoDS_Edge aPrevEdge; + for (Standard_Integer j = 1; j <= aSurfSeq.Length(); j++) + { + TColGeom2d_SequenceOfCurve aPCurveSeq; + TColStd_SequenceOfReal aFirstsSeq; + TColStd_SequenceOfReal aLastsSeq; + TColStd_SequenceOfBoolean aForwardsSeq; + GeomAbs_CurveType aCurrentType = GeomAbs_OtherCurve; + + Standard_Real aFirst, aLast; + for (Standard_Integer i = 1; i <= theChain.Length(); i++) + { + TopoDS_Edge anEdge = TopoDS::Edge(theChain.Value(i)); + Standard_Boolean isForward = (anEdge.Orientation() != TopAbs_REVERSED); + + Handle(Geom2d_Curve) aPCurve = + BRep_Tool::CurveOnSurface(anEdge, aSurfSeq(j), aLocSeq(j), aFirst, aLast); + if (aPCurve.IsNull()) + continue; + + Geom2dAdaptor_Curve anAdaptor(aPCurve); + GeomAbs_CurveType aType = anAdaptor.GetType(); + + if (aPCurveSeq.IsEmpty()) { + aPCurveSeq.Append(aPCurve); + aFirstsSeq.Append(aFirst); + aLastsSeq.Append(aLast); + aForwardsSeq.Append(isForward); + aCurrentType = aType; + continue; + } + Standard_Boolean isSameCurve = Standard_False; + Standard_Real aNewF = aFirstsSeq.Last(); + Standard_Real aNewL = aLastsSeq.Last(); + if (aPCurve == aPCurveSeq.Last()) { + isSameCurve = Standard_True; + } + else if (aType == aCurrentType) { + Geom2dAdaptor_Curve aPrevAdaptor(aPCurveSeq.Last()); + switch (aType) { + case GeomAbs_Line: { + gp_Lin2d aLin = anAdaptor.Line(); + gp_Lin2d aPrevLin = aPrevAdaptor.Line(); + if (aLin.Contains(aPrevLin.Location(), Precision::Confusion()) && + aLin.Direction().IsParallel(aPrevLin.Direction(), Precision::Angular())) { + isSameCurve = Standard_True; + gp_Pnt2d p1 = anAdaptor.Value(aFirst); + gp_Pnt2d p2 = anAdaptor.Value(aLast); + aNewF = ElCLib::Parameter(aPrevLin, p1); + aNewL = ElCLib::Parameter(aPrevLin, p2); + } + break; + } + case GeomAbs_Circle: { + gp_Circ2d aCirc = anAdaptor.Circle(); + gp_Circ2d aPrevCirc = aPrevAdaptor.Circle(); + if (aCirc.Location().Distance(aPrevCirc.Location()) <= Precision::Confusion() && + Abs(aCirc.Radius() - aPrevCirc.Radius()) <= Precision::Confusion()) { + isSameCurve = Standard_True; + gp_Pnt2d p1 = anAdaptor.Value(aFirst); + gp_Pnt2d p2 = anAdaptor.Value(aLast); + aNewF = ElCLib::Parameter(aPrevCirc, p1); + aNewL = ElCLib::Parameter(aPrevCirc, p2); + } + break; + } + default: + break; + } + } + if (isSameCurve) { + Standard_Boolean isSameDir = (isForward == aForwardsSeq.Last()); + if (!isSameDir) { + Standard_Real aTmp = aNewF; + aNewF = aNewL; + aNewL = aTmp; + } + if (aForwardsSeq.Last()) + aLastsSeq(aLastsSeq.Length()) = aNewL; + else + aFirstsSeq(aFirstsSeq.Length()) = aNewF; + } + else { + aPCurveSeq.Append(aPCurve); + aFirstsSeq.Append(aFirst); + aLastsSeq.Append(aLast); + aForwardsSeq.Append(isForward); + aCurrentType = aType; + } + } + + Handle(Geom2d_Curve) aResPCurve; + Standard_Real aResFirst, aResLast; + if (aPCurveSeq.Length() == 1) { + aResPCurve = aPCurveSeq.Last(); + aResFirst = aFirstsSeq.Last(); + aResLast = aLastsSeq.Last(); + } + else { + //C1 concatenation for PCurveSeq + TColGeom2d_Array1OfBSplineCurve tab_c2d(0, theChain.Length() - 1); + for (Standard_Integer i = 1; i <= theChain.Length(); i++) { + Handle(Geom2d_TrimmedCurve) aTrPCurve = new Geom2d_TrimmedCurve(aPCurveSeq(i), aFirstsSeq(i), aLastsSeq(i)); + tab_c2d(i - 1) = Geom2dConvert::CurveToBSplineCurve(aTrPCurve); + Geom2dConvert::C0BSplineToC1BSplineCurve(tab_c2d(i - 1), Precision::Confusion()); + if (!aForwardsSeq(i)) + tab_c2d(i - 1)->Reverse(); + } + + TColStd_Array1OfReal tabtolvertex(0, theChain.Length() - 1); + Standard_Real aMaxTol = 0.0; + TopoDS_Edge aPrevEdge = TopoDS::Edge(theChain(1)); + for (Standard_Integer i = 2; i <= theChain.Length(); i++) { + TopoDS_Edge anEdge = TopoDS::Edge(theChain(i)); + TopoDS_Vertex aV; + TopExp::CommonVertex(aPrevEdge, anEdge, aV); + Standard_Real aTol = BRep_Tool::Tolerance(aV); + tabtolvertex(i - 2) = aTol; + if (aTol - aMaxTol > 0.0) + aMaxTol = aTol; + } + + Handle(TColGeom2d_HArray1OfBSplineCurve) concatc2d; //array of the concatenated curves + Handle(TColStd_HArray1OfInteger) ArrayOfInd2d; //array of the remining Vertex + Standard_Boolean aClosedFlag = Standard_False; + Geom2dConvert::ConcatC1(tab_c2d, + tabtolvertex, + ArrayOfInd2d, + concatc2d, + aClosedFlag, + Precision::Confusion()); //C1 concatenation + + if (concatc2d->Length() > 1) + { + Geom2dConvert_CompCurveToBSplineCurve Concat2d(concatc2d->Value(concatc2d->Lower())); + + for (Standard_Integer i = concatc2d->Lower() + 1; i <= concatc2d->Upper(); i++) + Concat2d.Add(concatc2d->Value(i), aMaxTol, Standard_True); + + concatc2d->SetValue(concatc2d->Lower(), Concat2d.BSplineCurve()); + } + Handle(Geom2d_BSplineCurve) aBSplineCurve = concatc2d->Value(concatc2d->Lower()); + aResPCurve = aBSplineCurve; + aResFirst = aBSplineCurve->FirstParameter(); + aResLast = aBSplineCurve->LastParameter(); + } + ResPCurves.Append(aResPCurve); + ResFirsts.Append(aResFirst); + ResLasts.Append(aResLast); + } + + BRep_Builder aBuilder; + Standard_Real aTol = BRep_Tool::Tolerance(theEdge); + for (Standard_Integer j = 1; j <= ResPCurves.Length(); j++) + { + aBuilder.UpdateEdge(theEdge, ResPCurves(j), aSurfSeq(j), aLocSeq(j), aTol); + aBuilder.Range(theEdge, aSurfSeq(j), aLocSeq(j), ResFirsts(j), ResLasts(j)); + } +} + //======================================================================= //function : MergeSubSeq //purpose : Merges a sequence of edges into one edge if possible @@ -1583,6 +1774,7 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain, B.Add (E,V[0]); B.Add (E,V[1]); B.UpdateVertex(V[0], 0., E, 0.); B.UpdateVertex(V[1], dist, E, 0.); + UnionPCurves(theChain, E); OutEdge = E; return Standard_True; } @@ -1672,7 +1864,7 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain, Standard_Real lpar = Dir1.AngleWithRef(DirLastInChain, Vdir); if (lpar < 0.) lpar += 2*M_PI; - + Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(aNewCircle,0.,lpar); B.MakeEdge (E,tc,Precision::Confusion()); B.Add(E,V[0]); @@ -1680,6 +1872,7 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& theChain, B.UpdateVertex(V[0], 0., E, 0.); B.UpdateVertex(V[1], lpar, E, 0.); } + UnionPCurves(theChain, E); OutEdge = E; return Standard_True; }