From 51f1457c71f0a799ff086ddb530d50fc899ee1e6 Mon Sep 17 00:00:00 2001 From: knosulko Date: Fri, 20 Aug 2021 12:39:26 +0300 Subject: [PATCH] 30046: Modeling Algorithms - Cannot find necessary projection of the curve move algorithm of obtaining results from function gproject to method ProjLib_CompProjectedCurve::Perform. --- .../GeometryTest_CurveCommands.cxx | 215 +++++++------ src/ProjLib/ProjLib_CompProjectedCurve.cxx | 291 ++++++++++++++++++ src/ProjLib/ProjLib_CompProjectedCurve.hxx | 89 ++++++ 3 files changed, 494 insertions(+), 101 deletions(-) diff --git a/src/GeometryTest/GeometryTest_CurveCommands.cxx b/src/GeometryTest/GeometryTest_CurveCommands.cxx index 1692201516..265098d9d0 100644 --- a/src/GeometryTest/GeometryTest_CurveCommands.cxx +++ b/src/GeometryTest/GeometryTest_CurveCommands.cxx @@ -261,134 +261,147 @@ static Standard_Integer to3d (Draw_Interpretor& , Standard_Integer n, const char static Standard_Integer gproject(Draw_Interpretor& di, Standard_Integer n, const char** a) { - + if ( n == 1) { + di << "gproject result curve surface maxdist tolerance"; + di << " [-c continuity][-d maxdegree][-s maxsegments][-2d only2d][-3d only3d]\n"; + di << " -c continuity : set curve continuity (C0, C1, C2, C3, CN, G1, G2) for approximation\n"; + di << " -d maxdegree : set max possible degree of result for approximation\n"; + di << " -s maxsegments : set max value of parametric intervals the projected curve for approximation\n"; + di << " -2d only2d : set necessity of only 2d results (0 or 1)\n"; + di << " -3d only3d : set necessity of only 3d results (0 or 1)\n"; + return 0; + } + char newname[1024]; char* temp = newname; char newname1[10]; char* temp1 = newname1; char name[100]; - Standard_Integer ONE = 1; - if (n == 3) - Sprintf(name,"p"); - else if (n == 4) { - Sprintf(name,"%s",a[1]); - ONE = 2; + if (n < 4) { + di << "gproject wait 3 or more arguments\n"; + return 1; } - else { - di << "gproject wait 2 or 3 arguments\n"; - return 1; - } - Handle(Geom_Curve) Cur = DrawTrSurf::GetCurve(a[ONE]); - Handle(Geom_Surface) Sur = DrawTrSurf::GetSurface(a[ONE+1]); + Sprintf(name, "%s", a[1]); + + Handle(Geom_Curve) Cur = DrawTrSurf::GetCurve(a[2]); + Handle(Geom_Surface) Sur = DrawTrSurf::GetSurface(a[3]); if (Cur.IsNull() || Sur.IsNull()) return 1; Handle(GeomAdaptor_Curve) hcur = new GeomAdaptor_Curve(Cur); Handle(GeomAdaptor_Surface) hsur = new GeomAdaptor_Surface(Sur); + Handle(ProjLib_HCompProjectedCurve) HProjector; - Standard_Real myTol3d = 1.e-6; - GeomAbs_Shape myContinuity = GeomAbs_C2; - Standard_Integer myMaxDegree = 14, myMaxSeg = 16; + Standard_Real aMaxDist = -1.0; + if (n > 4) { + aMaxDist = Draw::Atof(a[4]); + } + Standard_Real aTol3d = 1.e-6; + if (n > 5) { + aTol3d = Draw::Atof(a[5]); + } - Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve (hsur, hcur, myTol3d/10, myTol3d/10); + HProjector = new ProjLib_HCompProjectedCurve(hsur, hcur, aTol3d / 10, aTol3d / 10, aMaxDist); ProjLib_CompProjectedCurve& Projector = *HProjector; - Standard_Integer k; - Standard_Real Udeb, Ufin, UIso, VIso; - Standard_Boolean Only2d, Only3d; - gp_Pnt2d P2d, Pdeb, Pfin; - gp_Pnt P; - Handle(Adaptor2d_Curve2d) HPCur; - Handle(Geom2d_Curve) PCur2d; // Only for isoparametric projection - - for(k = 1; k <= Projector.NbCurves(); k++){ - Sprintf(newname,"%s_%d",name,k); - Sprintf(newname1,"%s2d_%d",name,k); - if(Projector.IsSinglePnt(k, P2d)){ -// std::cout<<"Part "<D0(P2d.X(), P2d.Y(), P); - DrawTrSurf::Set(temp, P); - DrawTrSurf::Set(temp1, P2d); - di< Ufin) { - Dir = gp_Dir2d(0, -1); - Udeb = - Udeb; - Ufin = - Ufin; - } - else Dir = gp_Dir2d(0, 1); - PCur2d = new Geom2d_TrimmedCurve(new Geom2d_Line(gp_Pnt2d(UIso, 0), Dir), Udeb, Ufin); - HPCur = new Geom2dAdaptor_Curve(PCur2d); - Only3d = Standard_True; + else if (a[index][1] == 'd') { + aMaxDegree = Draw::Atoi(a[index + 1]); + Projector.SetMaxDegree(aMaxDegree); + } + else if (a[index][1] == 's') { + aMaxSeg = Draw::Atoi(a[index + 1]); + Projector.SetMaxSeg(aMaxSeg); + } + else if (!strcmp(a[index], "-2d")) { + aOnly2d = Draw::Atoi(a[index + 1]); + Projector.SetOnly2d(aOnly2d); + } + else if (!strcmp(a[index], "-3d")) { + aOnly3d = Draw::Atoi(a[index + 1]); + Projector.SetOnly3d(aOnly3d); + } + + index += 2; + } + + Projector.Perform(); + + for (Standard_Integer k = 1; k <= Projector.NbCurves(); k++) { + Sprintf(newname, "%s_%d", name, k); + Sprintf(newname1, "%s2d_%d", name, k); + + if (Projector.ResultIsPoint(k)) { + if (Projector.GetOnly2d()) { + DrawTrSurf::Set(temp1, Projector.GetResult2dP(k)); + + di << temp1 << " is pcurve\n"; + di << " Error in 2d is " << Projector.GetResult2dUApproxError(k) + << "; " << Projector.GetResult2dVApproxError(k) << "\n"; } - else if(Projector.IsVIso(k, VIso)) { -// std::cout<<"Part "< Ufin) { - Dir = gp_Dir2d(-1, 0); - Udeb = - Udeb; - Ufin = - Ufin; - } - else Dir = gp_Dir2d(1, 0); - PCur2d = new Geom2d_TrimmedCurve(new Geom2d_Line(gp_Pnt2d(0, VIso), Dir), Udeb, Ufin); - HPCur = new Geom2dAdaptor_Curve(PCur2d); - Only3d = Standard_True; + if (Projector.GetOnly3d()) { + DrawTrSurf::Set(temp, Projector.GetResult3dP(k)); + + di << temp << " is 3d projected curve\n"; + di << " Error in 3d is " << Projector.GetResult3dApproxError(k) << "\n"; } - else HPCur = HProjector; - - if(Projector.MaxDistance(k) <= myTol3d) - Only2d = Standard_True; - - if(Only2d && Only3d) { - Handle(Geom_Curve) OutCur = new Geom_TrimmedCurve (GeomAdaptor::MakeCurve (*hcur), Ufin, Udeb); - DrawTrSurf::Set(temp, OutCur); - DrawTrSurf::Set(temp1, PCur2d); - di< #include #include +#include #include #include #include @@ -41,8 +42,13 @@ #include #include #include +#include +#include +#include #include +#include #include +#include #include #include @@ -1134,6 +1140,190 @@ void ProjLib_CompProjectedCurve::Init() } } } + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void ProjLib_CompProjectedCurve::Perform() +{ + if (myNbCurves == 0) { + return; + } + + Standard_Real Udeb, Ufin, UIso, VIso; + Standard_Boolean Only2d, Only3d; + gp_Pnt2d P2d, Pdeb, Pfin; + gp_Pnt P; + Handle(Adaptor2d_Curve2d) HPCur; + Handle(Geom2d_Curve) PCur2d; // Only for isoparametric projection + Handle(Geom_Curve) PCur3d; + + if (myOnly2d == Standard_True) { + myResult2dPoint = new TColgp_HArray1OfPnt2d(1, myNbCurves); + myResult2dCurve = new TColGeom2d_HArray1OfCurve(1, myNbCurves); + } + + if (myOnly3d == Standard_True) { + myResult3dPoint = new TColgp_HArray1OfPnt(1, myNbCurves); + myResult3dCurve = new TColGeom_HArray1OfCurve(1, myNbCurves); + } + + myResultIsPoint = new TColStd_HArray1OfBoolean(1, myNbCurves); + myResultIsPoint->Init(Standard_False); + + myResult3dApproxError = new TColStd_HArray1OfReal(1, myNbCurves); + myResult3dApproxError->Init(0.0); + + myResult2dUApproxError = new TColStd_HArray1OfReal(1, myNbCurves); + myResult2dUApproxError->Init(0.0); + + myResult2dVApproxError = new TColStd_HArray1OfReal(1, myNbCurves); + myResult2dVApproxError->Init(0.0); + + for (Standard_Integer k = 1; k <= myNbCurves; k++) { + if (IsSinglePnt(k, P2d)) { // Part k of the projection is punctual + GetSurface()->D0(P2d.X(), P2d.Y(), P); + if (myOnly2d == Standard_True) { + myResult2dPoint->SetValue(k, P2d); + } + if (myOnly3d == Standard_True) { + myResult3dPoint->SetValue(k, P); + } + myResultIsPoint->SetValue(k, Standard_True); + } + else { + Only2d = Only3d = Standard_False; + Bounds(k, Udeb, Ufin); + gp_Dir2d Dir; // Only for isoparametric projection + + if (IsUIso(k, UIso)) { // Part k of the projection is U-isoparametric curve + D0(Udeb, Pdeb); + D0(Ufin, Pfin); + Udeb = Pdeb.Y(); + Ufin = Pfin.Y(); + if (Udeb > Ufin) { + Dir = gp_Dir2d(0, -1); + Udeb = -Udeb; + Ufin = -Ufin; + } + else Dir = gp_Dir2d(0, 1); + PCur2d = new Geom2d_TrimmedCurve(new Geom2d_Line(gp_Pnt2d(UIso, 0), Dir), Udeb, Ufin); + + HPCur = new Geom2dAdaptor_Curve(PCur2d); + Only3d = Standard_True; + } + else if (IsVIso(k, VIso)) { // Part k of the projection is V-isoparametric curve + D0(Udeb, Pdeb); + D0(Ufin, Pfin); + Udeb = Pdeb.X(); + Ufin = Pfin.X(); + if (Udeb > Ufin) { + Dir = gp_Dir2d(-1, 0); + Udeb = -Udeb; + Ufin = -Ufin; + } + else Dir = gp_Dir2d(1, 0); + PCur2d = new Geom2d_TrimmedCurve(new Geom2d_Line(gp_Pnt2d(0, VIso), Dir), Udeb, Ufin); + HPCur = new Geom2dAdaptor_Curve(PCur2d); + Only3d = Standard_True; + } + else { + HPCur = this; + } + + if (MaxDistance(k) <= myTol3d) + Only2d = Standard_True; + + if (Only2d && Only3d) { + PCur3d = new Geom_TrimmedCurve(GeomAdaptor::MakeCurve(*myCurve), Ufin, Udeb); + } + else { + Approx_CurveOnSurface appr(HPCur, mySurface, Udeb, Ufin, myTol3d); + appr.Perform(myMaxSeg, myMaxDegree, myContinuity, Only3d, Only2d); + + if (!Only3d) { + PCur2d = appr.Curve2d(); + myResult2dUApproxError->SetValue(k, appr.MaxError2dU()); + myResult2dVApproxError->SetValue(k, appr.MaxError2dV()); + } + + if (Only2d) { + PCur3d = new Geom_TrimmedCurve(GeomAdaptor::MakeCurve(*myCurve), Ufin, Udeb); + } + else { + PCur3d = appr.Curve3d(); + myResult3dApproxError->SetValue(k, appr.MaxError3d()); + } + } + + if (myOnly2d == Standard_True) { + myResult2dCurve->SetValue(k, PCur2d); + } + + if (myOnly3d == Standard_True) { + myResult3dCurve->SetValue(k, PCur3d); + } + } + } +} + +//======================================================================= +//function : SetTol3d +//purpose : +//======================================================================= +void ProjLib_CompProjectedCurve::SetTol3d(const Standard_Real Tol3d) +{ + myTol3d = Tol3d; +} + +//======================================================================= +//function : SetContinuity +//purpose : +//======================================================================= +void ProjLib_CompProjectedCurve::SetContinuity(const GeomAbs_Shape Continuity) +{ + myContinuity = Continuity; +} + +//======================================================================= +//function : SetMaxDegree +//purpose : +//======================================================================= +void ProjLib_CompProjectedCurve::SetMaxDegree(const Standard_Integer MaxDegree) +{ + if (MaxDegree < 1) return; + myMaxDegree = MaxDegree; +} + +//======================================================================= +//function : SetMaxSeg +//purpose : +//======================================================================= +void ProjLib_CompProjectedCurve::SetMaxSeg(const Standard_Integer MaxSeg) +{ + if (MaxSeg < 1) return; + myMaxSeg = MaxSeg; +} + +//======================================================================= +//function : SetOnly3d +//purpose : +//======================================================================= +void ProjLib_CompProjectedCurve::SetOnly3d(const Standard_Boolean& Only3d) +{ + myOnly3d = Only3d; +} + +//======================================================================= +//function : SetOnly2d +//purpose : +//======================================================================= +void ProjLib_CompProjectedCurve::SetOnly2d(const Standard_Boolean& Only2d) +{ + myOnly2d = Only2d; +} + //======================================================================= //function : Load //purpose : @@ -1762,6 +1952,107 @@ GeomAbs_CurveType ProjLib_CompProjectedCurve::GetType() const return GeomAbs_OtherCurve; } +//======================================================================= +//function : ResultIsPoint +//purpose : +//======================================================================= + +Standard_Boolean ProjLib_CompProjectedCurve::ResultIsPoint(const Standard_Integer Index) const +{ + return myResultIsPoint->Value(Index); +} + +//======================================================================= +//function : GetResult2dUApproxError +//purpose : +//======================================================================= + +Standard_Real ProjLib_CompProjectedCurve::GetResult2dUApproxError(const Standard_Integer Index) const +{ + return myResult2dUApproxError->Value(Index); +} + +//======================================================================= +//function : GetResult2dVApproxError +//purpose : +//======================================================================= + +Standard_Real ProjLib_CompProjectedCurve::GetResult2dVApproxError(const Standard_Integer Index) const +{ + return myResult2dVApproxError->Value(Index); +} + +//======================================================================= +//function : GetResult3dApproxError +//purpose : +//======================================================================= + +Standard_Real ProjLib_CompProjectedCurve::GetResult3dApproxError(const Standard_Integer Index) const +{ + return myResult3dApproxError->Value(Index); +} + +//======================================================================= +//function : GetResult2dC +//purpose : +//======================================================================= + +Handle(Geom2d_Curve) ProjLib_CompProjectedCurve::GetResult2dC(const Standard_Integer Index) const +{ + return myResult2dCurve->Value(Index); +} + +//======================================================================= +//function : GetResult3dC +//purpose : +//======================================================================= + +Handle(Geom_Curve) ProjLib_CompProjectedCurve::GetResult3dC(const Standard_Integer Index) const +{ + return myResult3dCurve->Value(Index); +} + + +//======================================================================= +//function : GetResult2dP +//purpose : +//======================================================================= + +gp_Pnt2d ProjLib_CompProjectedCurve::GetResult2dP(const Standard_Integer Index) const +{ + return myResult2dPoint->Value(Index); +} + +//======================================================================= +//function : GetResult3dP +//purpose : +//======================================================================= + +gp_Pnt ProjLib_CompProjectedCurve::GetResult3dP(const Standard_Integer Index) const +{ + return myResult3dPoint->Value(Index); +} + +//======================================================================= +//function : GetOnly2d +//purpose : +//======================================================================= + +Standard_Boolean ProjLib_CompProjectedCurve::GetOnly2d() const +{ + return myOnly2d; +} + +//======================================================================= +//function : GetOnly3d +//purpose : +//======================================================================= + +Standard_Boolean ProjLib_CompProjectedCurve::GetOnly3d() const +{ + return myOnly3d; +} + //======================================================================= //function : UpdateTripleByTrapCriteria //purpose : diff --git a/src/ProjLib/ProjLib_CompProjectedCurve.hxx b/src/ProjLib/ProjLib_CompProjectedCurve.hxx index d086f7e6d2..9386598b71 100644 --- a/src/ProjLib/ProjLib_CompProjectedCurve.hxx +++ b/src/ProjLib/ProjLib_CompProjectedCurve.hxx @@ -20,8 +20,15 @@ #include #include #include +#include +#include +#include +#include +#include #include #include +#include +#include #include #include #include @@ -51,6 +58,35 @@ public: //! included in this set of points. Standard_EXPORT void Init(); + //! Performs projecting for given curve. + //! If projecting uses approximation, + //! approximation parameters can be set before by corresponding methods + //! SetTol3d(...), SeContinuity(...), SetMaxDegree(...), SetMaxSeg(...) + Standard_EXPORT void Perform(); + + //! Set the parameter, which defines 3d tolerance of approximation. + Standard_EXPORT void SetTol3d(const Standard_Real Tol3d); + + //! Set the parameter, which defines curve continuity. + //! Default value is GeomAbs_C2; + Standard_EXPORT void SetContinuity(const GeomAbs_Shape Continuity); + + //! Set max possible degree of result BSpline curve2d, which is got by approximation. + //! If MaxDegree < 0, algorithm uses values that are chosen depending of types curve 3d + //! and surface. + Standard_EXPORT void SetMaxDegree(const Standard_Integer MaxDegree); + + //! Set the parameter, which defines maximal value of parametric intervals the projected + //! curve can be cut for approximation. If MaxSeg < 0, algorithm uses default + //! value = 16. + Standard_EXPORT void SetMaxSeg(const Standard_Integer MaxSeg); + + //! Set the parameter, which defines necessity of only 2d results. + Standard_EXPORT void SetOnly3d(const Standard_Boolean& Only3d); + + //! Set the parameter, which defines necessity of only 3d results. + Standard_EXPORT void SetOnly2d(const Standard_Boolean& Only2d); + //! Changes the surface. Standard_EXPORT void Load (const Handle(Adaptor3d_Surface)& S); @@ -140,6 +176,44 @@ public: //! Parabola, BezierCurve, BSplineCurve, OtherCurve. Standard_EXPORT GeomAbs_CurveType GetType() const Standard_OVERRIDE; + //! Returns true if result of projecting of the curve interval + //! with number Index is point. + Standard_EXPORT Standard_Boolean ResultIsPoint(const Standard_Integer Index) const; + + //! Returns the error of approximation of U parameter 2d-curve as a result + //! projecting of the curve interval with number Index. + Standard_EXPORT Standard_Real GetResult2dUApproxError(const Standard_Integer Index) const; + + //! Returns the error of approximation of V parameter 2d-curve as a result + //! projecting of the curve interval with number Index. + Standard_EXPORT Standard_Real GetResult2dVApproxError(const Standard_Integer Index) const; + + //! Returns the error of approximation of 3d-curve as a result + //! projecting of the curve interval with number Index. + Standard_EXPORT Standard_Real GetResult3dApproxError(const Standard_Integer Index) const; + + //! Returns the resulting 2d-curve of projecting + //! of the curve interval with number Index. + Standard_EXPORT Handle(Geom2d_Curve) GetResult2dC(const Standard_Integer Index) const; + + //! Returns the resulting 3d-curve of projecting + //! of the curve interval with number Index. + Standard_EXPORT Handle(Geom_Curve) GetResult3dC(const Standard_Integer Index) const; + + //! Returns the resulting 2d-point of projecting + //! of the curve interval with number Index. + Standard_EXPORT gp_Pnt2d GetResult2dP(const Standard_Integer Index) const; + + //! Returns the resulting 3d-point of projecting + //! of the curve interval with number Index. + Standard_EXPORT gp_Pnt GetResult3dP(const Standard_Integer Index) const; + + //! Returns the parameter, which defines necessity of only 2d results. + Standard_EXPORT Standard_Boolean GetOnly2d() const; + + //! Returns the parameter, which defines necessity of only 3d results. + Standard_EXPORT Standard_Boolean GetOnly3d() const; + private: //! This method performs check possibility of optimization traps and tries to go out from them. @@ -162,6 +236,21 @@ private: Handle(TColStd_HArray1OfBoolean) mySnglPnts; Handle(TColStd_HArray1OfReal) myMaxDistance; Handle(TColStd_HArray1OfReal) myTabInt; + Standard_Real myTol3d = 1.e-6; + GeomAbs_Shape myContinuity = GeomAbs_C2; + Standard_Integer myMaxDegree = 14; + Standard_Integer myMaxSeg = 16; + Standard_Boolean myOnly2d = Standard_True; + Standard_Boolean myOnly3d = Standard_True; + + Handle(TColStd_HArray1OfBoolean) myResultIsPoint; + Handle(TColStd_HArray1OfReal) myResult2dUApproxError; + Handle(TColStd_HArray1OfReal) myResult2dVApproxError; + Handle(TColStd_HArray1OfReal) myResult3dApproxError; + Handle(TColgp_HArray1OfPnt) myResult3dPoint; + Handle(TColgp_HArray1OfPnt2d) myResult2dPoint; + Handle(TColGeom_HArray1OfCurve) myResult3dCurve; + Handle(TColGeom2d_HArray1OfCurve) myResult2dCurve; }; DEFINE_STANDARD_HANDLE(ProjLib_CompProjectedCurve, Adaptor2d_Curve2d) -- 2.39.5