From 2c26a53d859acbc0d8d4985c209df0df6c13d312 Mon Sep 17 00:00:00 2001 From: jgv Date: Mon, 20 Mar 2017 14:43:32 +0300 Subject: [PATCH] 0027079: Bad approximation of intersection curves with variable curvature 1. Method Approx_ComputeLine::Perform is modified: now it contains also recursive calls after new line computation made by new method ApproxInt_MultiLine::MakeMLOneMorePoint. 2. New method MakeMLOneMorePoint is added to ApproxInt_MultiLine: it builds new sub-line as a part of main line with new point added into the middle of the longest interval between existing points. 3. Method ShapeConstruct_ProjectCurveOnSurface::ApproxPCurve is modified to avoid regressions: now it takes care of the set of initial points to be enough close to each other so that an interval between two adjacent points is less than half-period of the surface. 4. Modification in ShapeConstruct_ProjectCurveOnSurface: correction of pcurves of edges which extremities are in the singularities of surface. --- dox/dev_guides/upgrade/upgrade.md | 4 + src/AppDef/AppDef_Compute.hxx | 10 +- src/AppDef/AppDef_MyLineTool.cxx | 27 +- src/AppDef/AppDef_MyLineTool.hxx | 12 +- src/Approx/Approx_ComputeLine.gxx | 455 +++++++++++++-- src/ApproxInt/ApproxInt_Approx.gxx | 15 +- src/ApproxInt/ApproxInt_ImpPrmSvSurfaces.gxx | 320 +++++++---- src/ApproxInt/ApproxInt_MultiLine.gxx | 221 ++++++- src/ApproxInt/ApproxInt_MultiLineTool.lxx | 9 + src/ApproxInt/ApproxInt_PrmPrmSvSurfaces.gxx | 32 +- src/ApproxInt/ApproxInt_SvSurfaces.hxx | 34 +- ...RepApprox_TheComputeLineBezierOfApprox.hxx | 9 +- ...BRepApprox_TheImpPrmSvSurfacesOfApprox.hxx | 20 +- .../BRepApprox_TheMultiLineOfApprox.hxx | 52 +- .../BRepApprox_TheMultiLineToolOfApprox.hxx | 7 + ...BRepApprox_ThePrmPrmSvSurfacesOfApprox.hxx | 9 +- ...GeomInt_TheComputeLineBezierOfWLApprox.hxx | 9 +- .../GeomInt_TheImpPrmSvSurfacesOfWLApprox.hxx | 21 +- .../GeomInt_TheMultiLineOfWLApprox.hxx | 50 +- .../GeomInt_TheMultiLineToolOfWLApprox.hxx | 7 + .../GeomInt_ThePrmPrmSvSurfacesOfWLApprox.hxx | 9 +- src/LocOpe/LocOpe_WiresOnShape.cxx | 11 +- src/ShapeAnalysis/ShapeAnalysis_Surface.cxx | 4 +- src/ShapeAnalysis/ShapeAnalysis_Surface.hxx | 57 +- .../ShapeConstruct_ProjectCurveOnSurface.cxx | 538 ++++++++++++------ .../ShapeConstruct_ProjectCurveOnSurface.hxx | 90 ++- src/ShapeFix/ShapeFix_Edge.cxx | 10 +- tests/bugs/modalg_6/bug27079_1 | 23 + tests/bugs/modalg_6/bug27079_2 | 21 + 29 files changed, 1626 insertions(+), 460 deletions(-) create mode 100644 tests/bugs/modalg_6/bug27079_1 create mode 100644 tests/bugs/modalg_6/bug27079_2 diff --git a/dox/dev_guides/upgrade/upgrade.md b/dox/dev_guides/upgrade/upgrade.md index 6c317a4aba..35d1f6b7d2 100644 --- a/dox/dev_guides/upgrade/upgrade.md +++ b/dox/dev_guides/upgrade/upgrade.md @@ -1143,6 +1143,10 @@ The following obsolete features have been removed: - *NextStartingPointsResearch2*; - *TriangleComparePSP*; - *StartPointsCalcul*. +* The method PerformAdvanced of the *ShapeConstruct_ProjectCurveOnSurface* class has been removed as unused. +* The method Perform of the *ShapeConstruct_ProjectCurveOnSurface* class is modified: + - input arguments *continuity*, *maxdeg*, *nbinterval* have been removed as unused; + - input arguments *TolFirst*, *TolLast* have been added at the end of arguments' list. @subsection upgrade_occt720_correction_of_Offset_API Corrections in BRepOffset API diff --git a/src/AppDef/AppDef_Compute.hxx b/src/AppDef/AppDef_Compute.hxx index a65bbd343a..bf37a6fc15 100644 --- a/src/AppDef/AppDef_Compute.hxx +++ b/src/AppDef/AppDef_Compute.hxx @@ -124,7 +124,6 @@ public: - protected: @@ -135,7 +134,13 @@ private: //! is internally used in the algorithm. - Standard_EXPORT Standard_Boolean Compute (const AppDef_MultiLine& Line, const Standard_Integer fpt, const Standard_Integer lpt, math_Vector& Para, Standard_Real& TheTol3d, Standard_Real& TheTol2d); + Standard_EXPORT Standard_Boolean Compute (const AppDef_MultiLine& Line, + const Standard_Integer fpt, + const Standard_Integer lpt, + math_Vector& Para, + Standard_Real& TheTol3d, + Standard_Real& TheTol2d, + Standard_Integer& indbad); //! is internally used in the algorithm. Standard_EXPORT Standard_Boolean ComputeCurve (const AppDef_MultiLine& Line, const Standard_Integer firspt, const Standard_Integer lastpt); @@ -176,6 +181,7 @@ private: AppParCurves_Constraint myfirstC; AppParCurves_Constraint mylastC; Standard_Integer myMultiLineNb; + Standard_Integer myNbPlusOnePoint; Standard_Boolean myIsClear; diff --git a/src/AppDef/AppDef_MyLineTool.cxx b/src/AppDef/AppDef_MyLineTool.cxx index 1e3aa579a1..93827b115e 100644 --- a/src/AppDef/AppDef_MyLineTool.cxx +++ b/src/AppDef/AppDef_MyLineTool.cxx @@ -59,9 +59,11 @@ void AppDef_MyLineTool::Value(const AppDef_MultiLine& ML, TColgp_Array1OfPnt2d& tabPt2d) { AppDef_MultiPointConstraint MPC = ML.Value(MPointIndex); - Standard_Integer nbp2d = MPC.NbPoints2d(), low = tabPt2d.Lower(); + Standard_Integer nbp3d = MPC.NbPoints(); + Standard_Integer nbp2d = MPC.NbPoints2d(); + Standard_Integer low = tabPt2d.Lower(); for (Standard_Integer i = 1; i <= nbp2d; i++) { - tabPt2d(i+low-1) = MPC.Point2d(i); + tabPt2d(i+low-1) = MPC.Point2d(nbp3d+i); } } @@ -102,10 +104,12 @@ Standard_Boolean AppDef_MyLineTool::Tangency(const AppDef_MultiLine& ML, TColgp_Array1OfVec2d& tabV2d) { AppDef_MultiPointConstraint MPC = ML.Value(MPointIndex); - if (MPC.IsTangencyPoint()) { + if (MPC.IsTangencyPoint()) + { + Standard_Integer nbp3d = MPC.NbPoints(); Standard_Integer nbp2d = MPC.NbPoints2d(), low = tabV2d.Lower(); for (Standard_Integer i = 1; i <= nbp2d; i++) { - tabV2d(i+low-1) = MPC.Tang2d(i); + tabV2d(i+low-1) = MPC.Tang2d(nbp3d+i); } return Standard_True; } @@ -142,6 +146,15 @@ AppDef_MultiLine& AppDef_MyLineTool::MakeMLBetween(const AppDef_MultiLine&, return *((AppDef_MultiLine*) 0); } +Standard_Boolean AppDef_MyLineTool::MakeMLOneMorePoint(const AppDef_MultiLine& , + const Standard_Integer, + const Standard_Integer, + const Standard_Integer, + AppDef_MultiLine&) +{ + return Standard_False; +} + Approx_Status AppDef_MyLineTool::WhatStatus(const AppDef_MultiLine&, const Standard_Integer, const Standard_Integer) @@ -170,10 +183,12 @@ Standard_Boolean AppDef_MyLineTool::Curvature(const AppDef_MultiLine& ML, TColgp_Array1OfVec2d& tabV2d) { AppDef_MultiPointConstraint MPC = ML.Value(MPointIndex); - if (MPC.IsCurvaturePoint()) { + if (MPC.IsCurvaturePoint()) + { + Standard_Integer nbp3d = MPC.NbPoints(); Standard_Integer nbp2d = MPC.NbPoints2d(), low = tabV2d.Lower(); for (Standard_Integer i = 1; i <= nbp2d; i++) { - tabV2d(i+low-1) = MPC.Curv2d(i); + tabV2d(i+low-1) = MPC.Curv2d(nbp3d+i); } return Standard_True; } diff --git a/src/AppDef/AppDef_MyLineTool.hxx b/src/AppDef/AppDef_MyLineTool.hxx index 5e6881f8c4..7f6917751f 100644 --- a/src/AppDef/AppDef_MyLineTool.hxx +++ b/src/AppDef/AppDef_MyLineTool.hxx @@ -94,8 +94,18 @@ public: //! Is never called in the algorithms. //! Nothing is done. - Standard_EXPORT static AppDef_MultiLine& MakeMLBetween (const AppDef_MultiLine& ML, const Standard_Integer I1, const Standard_Integer I2, const Standard_Integer NbPMin); + Standard_EXPORT static AppDef_MultiLine& MakeMLBetween (const AppDef_MultiLine& ML, + const Standard_Integer I1, + const Standard_Integer I2, + const Standard_Integer NbPMin); + //! Is never called in the algorithms. + //! Nothing is done. + Standard_EXPORT static Standard_Boolean MakeMLOneMorePoint (const AppDef_MultiLine& ML, + const Standard_Integer I1, + const Standard_Integer I2, + const Standard_Integer indbad, + AppDef_MultiLine& OtherLine); diff --git a/src/Approx/Approx_ComputeLine.gxx b/src/Approx/Approx_ComputeLine.gxx index edc6086e24..229ac6e787 100644 --- a/src/Approx/Approx_ComputeLine.gxx +++ b/src/Approx/Approx_ComputeLine.gxx @@ -45,6 +45,7 @@ static Standard_Boolean mydebug = Standard_False; #include #include #endif + static void DUMP(const MultiLine& Line) { Standard_Integer i, j, nbP2d, nbP3d, firstP, lastP; @@ -82,7 +83,6 @@ static void DUMP(const MultiLine& Line) } - static void DUMP(const AppParCurves_MultiCurve& C) { static Standard_Integer nbappel = 0; Standard_Integer i; @@ -123,9 +123,259 @@ static void DUMP(const AppParCurves_MultiCurve& C) { #endif } - #endif +static Standard_Boolean CheckMultiCurve(const AppParCurves_MultiCurve& theMultiCurve, + const MultiLine& theLine, + const Standard_Integer theIndfirst, + const Standard_Integer theIndlast, + Standard_Integer& theIndbad) +{ + const Standard_Integer nbp3d = LineTool::NbP3d(theLine); + const Standard_Integer nbp2d = LineTool::NbP2d(theLine); + + if (nbp3d > 1) //only simple cases are analysed + return Standard_True; + + const Standard_Real MinScalProd = -0.9; + const Standard_Real SqTol3d = Precision::SquareConfusion(); + + theIndbad = 0; + Standard_Integer indbads [4]; + indbads[1] = indbads[2] = indbads[3] = 0; + + Standard_Integer NbCur = theMultiCurve.NbCurves(); + Standard_Boolean LoopFound = Standard_False; + + Standard_Integer aNbP3d = Max(nbp3d, 1); + Standard_Integer aNbP2d = Max(nbp2d, 1); + + TColgp_Array1OfPnt tabP(1, aNbP3d); + TColgp_Array1OfPnt2d tabP2d(1, aNbP2d); + +#ifdef DRAW + char* name = new char[100]; + Standard_Integer nbbc = 1; + Standard_Integer indc = 1; +#endif + if (theMultiCurve.Dimension(1) == 3 /*myNbP3d == 1*/) + { + TColgp_Array1OfPnt aPoles(1, theMultiCurve.NbPoles()); + theMultiCurve.Curve(1, aPoles); +#ifdef DRAW + Handle(Geom_Curve) theBezier = new Geom_BezierCurve(aPoles); + sprintf(name, "bc3d_%d_%d", indc, nbbc); + DrawTrSurf::Set(name, theBezier); +#endif + gp_Vec FirstVec, SecondVec; + Standard_Integer indp = 2; + while (indp <= aPoles.Upper()) + { + FirstVec = gp_Vec(aPoles(1), aPoles(indp++)); + Standard_Real aLength = FirstVec.Magnitude(); + if (aLength > gp::Resolution()) + { + FirstVec /= aLength; + break; + } + } + gp_Pnt MidPnt = aPoles(indp-1); + //for (Standard_Integer k = 3; k <= aPoles.Upper(); k++) + while (indp <= aPoles.Upper()) + { + SecondVec = gp_Vec(MidPnt, aPoles(indp)); + Standard_Real aLength = SecondVec.Magnitude(); + if (aLength <= gp::Resolution()) + { + indp++; + continue; + } + SecondVec /= aLength; + Standard_Real ScalProd = FirstVec * SecondVec; + if (ScalProd < MinScalProd) + { +#ifdef DRAW + cout<<"ScalProd("< + Standard_Real MaxSqDist = 0.; + for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++) + { + LineTool::Value(theLine, k-1, tabP); + gp_Pnt PrevPnt = tabP(1); + LineTool::Value(theLine, k, tabP); + gp_Pnt CurPnt = tabP(1); + Standard_Real aSqDist = PrevPnt.SquareDistance(CurPnt); + if (aSqDist > MaxSqDist) + { + MaxSqDist = aSqDist; + indbads[1] = k; + } + } + for (Standard_Integer indcur = 2; indcur <= NbCur; indcur++) + { + MaxSqDist = 0.; + for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++) + { + LineTool::Value(theLine, k-1, tabP2d); + gp_Pnt2d PrevPnt = tabP2d(indcur-1); + LineTool::Value(theLine, k, tabP2d); + gp_Pnt2d CurPnt = tabP2d(indcur-1); + Standard_Real aSqDist = PrevPnt.SquareDistance(CurPnt); + if (aSqDist > MaxSqDist) + { + MaxSqDist = aSqDist; + indbads[indcur] = k; + } + } + } + } + } //if (myNbP3d == 1) + else //2d case + { + TColgp_Array1OfPnt2d aPoles2d(1, theMultiCurve.NbPoles()); + theMultiCurve.Curve(1, aPoles2d); +#ifdef DRAW + Handle(Geom2d_Curve) theBezier2d = new Geom2d_BezierCurve(aPoles2d); + sprintf(name, "bc2d_%d_%d", indc, nbbc); + DrawTrSurf::Set(name, theBezier2d); +#endif + gp_Vec2d FirstVec, SecondVec; + FirstVec = gp_Vec2d(aPoles2d(1), aPoles2d(2)); + FirstVec.Normalize(); + gp_Pnt2d MidPnt = aPoles2d(2); + for (Standard_Integer k = 3; k <= aPoles2d.Upper(); k++) + { + SecondVec = gp_Vec2d(MidPnt, aPoles2d(k)); + SecondVec.Normalize(); + Standard_Real ScalProd = FirstVec * SecondVec; + if (ScalProd < MinScalProd) + { +#ifdef DRAW + cout<<"ScalProd("< + for (Standard_Integer indcur = 1; indcur <= NbCur; indcur++) + { + Standard_Real MaxSqDist = 0.; + for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++) + { + LineTool::Value(theLine, k-1, tabP2d); + gp_Pnt2d PrevPnt = tabP2d(indcur); + LineTool::Value(theLine, k, tabP2d); + gp_Pnt2d CurPnt = tabP2d(indcur); + Standard_Real aSqDist = PrevPnt.SquareDistance(CurPnt); + if (aSqDist > MaxSqDist) + { + MaxSqDist = aSqDist; + indbads[indcur] = k; + } + } + } + } + } + + //Define + if (indbads[1] != 0 && indbads[2] != 0) + { + if (indbads[1] != indbads[2]) + LoopFound = Standard_False; + else if (indbads[3] != 0 && indbads[1] != indbads[3]) + LoopFound = Standard_False; + } + if (LoopFound) + theIndbad = indbads[1]; + + return (!LoopFound); +} + void Approx_ComputeLine::FirstTangencyVector(const MultiLine& Line, const Standard_Integer index, math_Vector& V) const @@ -400,6 +650,7 @@ Approx_ComputeLine::Approx_ComputeLine const Standard_Boolean cutting, const Standard_Boolean Squares) : myMultiLineNb (0), + myNbPlusOnePoint (0), myIsClear (Standard_False) { myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(), @@ -433,6 +684,7 @@ Approx_ComputeLine::Approx_ComputeLine const Standard_Boolean cutting, const Standard_Boolean Squares) : myMultiLineNb (0), + myNbPlusOnePoint (0), myIsClear (Standard_False) { myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(), @@ -464,6 +716,7 @@ Approx_ComputeLine::Approx_ComputeLine const Approx_ParametrizationType parametrization, const Standard_Boolean Squares) : myMultiLineNb (0), + myNbPlusOnePoint (0), myIsClear (Standard_False) { myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2); @@ -492,6 +745,7 @@ Approx_ComputeLine::Approx_ComputeLine const Approx_ParametrizationType parametrization, const Standard_Boolean Squares) : myMultiLineNb (0), + myNbPlusOnePoint (0), myIsClear (Standard_False) { myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2); @@ -524,6 +778,7 @@ void Approx_ComputeLine::Perform(const MultiLine& Line) Tolers3d.Clear(); Tolers2d.Clear(); myMultiLineNb = 0; + //myNbPlusOnePoint = 0; } else myIsClear = Standard_False; @@ -558,7 +813,22 @@ void Approx_ComputeLine::Perform(const MultiLine& Line) } } TheMultiCurve = AppParCurves_MultiCurve(); - alldone = Compute(Line, myfirstpt, mylastpt, TheParam, thetol3d, thetol2d); + MultiLine anOtherLine0; + Standard_Boolean isOtherLine0Made = Standard_False; + Standard_Integer indbad = 0; + alldone = Compute(Line, myfirstpt, mylastpt, TheParam, thetol3d, thetol2d, indbad); + if (indbad != 0) + { + isOtherLine0Made = LineTool::MakeMLOneMorePoint(Line, myfirstpt, mylastpt, indbad, anOtherLine0); + } + if (isOtherLine0Made) + { + myIsClear = Standard_True; + //++myMultiLineNb; + myNbPlusOnePoint++; + Perform(anOtherLine0); + alldone = Standard_True; + } if(!alldone && TheMultiCurve.NbCurves() > 0) { #ifdef OCCT_DEBUG if (mydebug) DUMP(TheMultiCurve); @@ -566,10 +836,13 @@ void Approx_ComputeLine::Perform(const MultiLine& Line) myMultiCurves.Append(TheMultiCurve); Tolers3d.Append(currenttol3d); Tolers2d.Append(currenttol2d); - Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, mylastpt); - for (i = myfirstpt; i <= mylastpt; i++) { - ThePar->SetValue(i, myParameters->Value(i)); - } + Standard_Integer mylen = mylastpt-myfirstpt+1; + Standard_Integer myParLen = myParameters->Length(); + Standard_Integer aLen = (myParLen > mylen)? myParLen : mylen; + Handle(TColStd_HArray1OfReal) ThePar = + new TColStd_HArray1OfReal(myfirstpt, myfirstpt+aLen-1); + for (i = 0; i < aLen; i++) + ThePar->SetValue(myfirstpt+i, myParameters->Value(myParameters->Lower()+i)); myPar.Append(ThePar); } } @@ -622,11 +895,9 @@ void Approx_ComputeLine::Perform(const MultiLine& Line) // Appel recursif du decoupage: GoUp = Standard_True; - MultiLine OtherLine =LineTool::MakeMLBetween(Line, myfirstpt, - mylastpt, nbp-1); + MultiLine anOtherLine1 = LineTool::MakeMLBetween(Line, myfirstpt, mylastpt, nbp-1); - Standard_Integer nbpdsotherligne = LineTool::FirstPoint(OtherLine) - -LineTool::LastPoint(OtherLine); + Standard_Integer nbpdsotherligne = LineTool::FirstPoint (anOtherLine1) - LineTool::LastPoint (anOtherLine1); //-- Si MakeML a echoue on retourne une ligne vide if ((nbpdsotherligne == 0) || myMultiLineNb >= 3) @@ -644,7 +915,23 @@ void Approx_ComputeLine::Perform(const MultiLine& Line) Par = Approx_IsoParametric; Parameters(Line, myfirstpt, mylastpt, Param); TheMultiCurve = AppParCurves_MultiCurve(); - Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d); + MultiLine anOtherLine2; + Standard_Boolean isOtherLine2Made = Standard_False; + Standard_Integer indbad = 0; + Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d, indbad); + if (indbad != 0) + { + isOtherLine2Made = LineTool::MakeMLOneMorePoint(Line, myfirstpt, mylastpt, indbad, anOtherLine2); + } + if (isOtherLine2Made) + { + myIsClear = Standard_True; + //++myMultiLineNb; + myNbPlusOnePoint++; + Par = SavePar; + Perform(anOtherLine2); + Ok = Standard_True; + } if (!Ok) { Standard_Real tt3d = currenttol3d, tt2d = currenttol2d; @@ -657,7 +944,21 @@ void Approx_ComputeLine::Perform(const MultiLine& Line) Par = Approx_ChordLength; Parameters(Line, myfirstpt, mylastpt, Param); - Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d); + isOtherLine2Made = Standard_False; + indbad = 0; + Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d, indbad); + if (indbad != 0) + { + isOtherLine2Made = LineTool::MakeMLOneMorePoint (Line, myfirstpt, mylastpt, indbad, anOtherLine2); + } + if (isOtherLine2Made) + { + myIsClear = Standard_True; + //++myMultiLineNb; + myNbPlusOnePoint++; + Perform (anOtherLine2); + Ok = Standard_True; + } if (!Ok && tt3d <= currenttol3d && tt2d <= currenttol2d) { currenttol3d = tt3d; currenttol2d = tt2d; @@ -666,6 +967,12 @@ void Approx_ComputeLine::Perform(const MultiLine& Line) } } Par = SavePar; + if (myfirstpt == Thelastpt) + { + Finish = Standard_True; + alldone = Standard_True; + return; + } oldlastpt = mylastpt; if (!Ok) { @@ -675,17 +982,40 @@ void Approx_ComputeLine::Perform(const MultiLine& Line) return; } #ifdef OCCT_DEBUG - if (mydebug) DUMP(TheMultiCurve); + if (mydebug) DUMP(TheMultiCurve); #endif - myMultiCurves.Append(TheMultiCurve); - Tolers3d.Append(currenttol3d); - Tolers2d.Append(currenttol2d); - - Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, oldlastpt); - for (i = myfirstpt; i <= oldlastpt; i++) { - ThePar->SetValue(i, myParameters->Value(i)); - } - myPar.Append(ThePar); + MultiLine anOtherLine3; + Standard_Boolean isOtherLine3Made = Standard_False; + Standard_Integer indbad2 = 0; + if (!CheckMultiCurve(TheMultiCurve, Line, + myfirstpt, mylastpt, + indbad2)) + { + isOtherLine3Made = LineTool::MakeMLOneMorePoint (Line, myfirstpt, mylastpt, indbad2, anOtherLine3); + } + if (isOtherLine3Made) + { + myIsClear = Standard_True; + //++myMultiLineNb; + myNbPlusOnePoint++; + Perform(anOtherLine3); + myfirstpt = mylastpt; + mylastpt = Thelastpt; + } + else + { + myMultiCurves.Append(TheMultiCurve); + Tolers3d.Append(currenttol3d); + Tolers2d.Append(currenttol2d); + Standard_Integer mylen = oldlastpt-myfirstpt+1; + Standard_Integer myParLen = myParameters->Length(); + Standard_Integer aLen = (myParLen > mylen)? myParLen : mylen; + Handle(TColStd_HArray1OfReal) ThePar = + new TColStd_HArray1OfReal(myfirstpt, myfirstpt+aLen-1); + for (i = 0; i < aLen; i++) + ThePar->SetValue(myfirstpt+i, myParameters->Value(myParameters->Lower()+i)); + myPar.Append(ThePar); + } } myfirstpt = oldlastpt; mylastpt = Thelastpt; @@ -695,7 +1025,7 @@ void Approx_ComputeLine::Perform(const MultiLine& Line) { myIsClear = Standard_True; ++myMultiLineNb; - Perform(OtherLine); + Perform(anOtherLine1); myfirstpt = mylastpt; mylastpt = Thelastpt; } @@ -716,11 +1046,13 @@ void Approx_ComputeLine::Perform(const MultiLine& Line) myMultiCurves.Append(TheMultiCurve); Tolers3d.Append(currenttol3d); Tolers2d.Append(currenttol2d); - - Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, oldlastpt); - for (i = myfirstpt; i <= oldlastpt; i++) { - ThePar->SetValue(i, myParameters->Value(i)); - } + Standard_Integer mylen = oldlastpt-myfirstpt+1; + Standard_Integer myParLen = myParameters->Length(); + Standard_Integer aLen = (myParLen > mylen)? myParLen : mylen; + Handle(TColStd_HArray1OfReal) ThePar = + new TColStd_HArray1OfReal(myfirstpt, myfirstpt+aLen-1); + for (i = 0; i < aLen; i++) + ThePar->SetValue(myfirstpt+i, myParameters->Value(myParameters->Lower()+i)); myPar.Append(ThePar); myfirstpt = oldlastpt; @@ -776,8 +1108,28 @@ void Approx_ComputeLine::Perform(const MultiLine& Line) } TheMultiCurve = AppParCurves_MultiCurve(); - Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d); - + MultiLine anOtherLine4; + Standard_Boolean isOtherLine4Made = Standard_False; + Standard_Integer indbad = 0; + Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d, indbad); + if (indbad != 0) + { + isOtherLine4Made = LineTool::MakeMLOneMorePoint (Line, myfirstpt, mylastpt, indbad, anOtherLine4); + } + if (isOtherLine4Made) + { + myIsClear = Standard_True; + //++myMultiLineNb; + myNbPlusOnePoint++; + Perform (anOtherLine4); + Ok = Standard_True; + } + if (myfirstpt == Thelastpt) + { + Finish = Standard_True; + alldone = Standard_True; + return; + } } } } @@ -886,9 +1238,10 @@ Standard_Boolean Approx_ComputeLine::Compute(const MultiLine& Line, const Standard_Integer lpt, math_Vector& Para, Standard_Real& TheTol3d, - Standard_Real& TheTol2d) + Standard_Real& TheTol2d, + Standard_Integer& indbad) { - + indbad = 0; Standard_Integer deg, i; Standard_Boolean mydone; Standard_Real Fv; @@ -947,20 +1300,30 @@ Standard_Boolean Approx_ComputeLine::Compute(const MultiLine& Line, // Stockage de la multicurve approximee. tolreached = Standard_True; #ifdef OCCT_DEBUG - if (mydebug) DUMP(mySCU); + if (mydebug) DUMP(mySCU); #endif - myMultiCurves.Append(mySCU); - // Stockage des parametres de la partie de MultiLine approximee: - // A ameliorer !! (bq trop de recopies) - Handle(TColStd_HArray1OfReal) ThePar = - new TColStd_HArray1OfReal(Para.Lower(), Para.Upper()); - for (i = Para.Lower(); i <= Para.Upper(); i++) { - ThePar->SetValue(i, Para(i)); - } - myPar.Append(ThePar); - Tolers3d.Append(TheTol3d); - Tolers2d.Append(TheTol2d); - return Standard_True; + if (myNbPlusOnePoint != 0 && + !CheckMultiCurve(mySCU, Line, + fpt, lpt, + indbad)) + { + return Standard_False; + } + else + { + myMultiCurves.Append(mySCU); + // Stockage des parametres de la partie de MultiLine approximee: + // A ameliorer !! (bq trop de recopies) + Handle(TColStd_HArray1OfReal) ThePar = + new TColStd_HArray1OfReal(Para.Lower(), Para.Upper()); + for (i = Para.Lower(); i <= Para.Upper(); i++) { + ThePar->SetValue(i, Para(i)); + } + myPar.Append(ThePar); + Tolers3d.Append(TheTol3d); + Tolers2d.Append(TheTol2d); + return Standard_True; + } } } diff --git a/src/ApproxInt/ApproxInt_Approx.gxx b/src/ApproxInt/ApproxInt_Approx.gxx index a59c2cf8e6..bbaa775d02 100644 --- a/src/ApproxInt/ApproxInt_Approx.gxx +++ b/src/ApproxInt/ApproxInt_Approx.gxx @@ -557,8 +557,8 @@ void ApproxInt_Approx::buildKnots(const Handle(TheWLine)& theline, const ApproxInt_TheMultiLine aTestLine( theline, thePtrSVSurf, ((myData.ApproxXYZ)? 1 : 0), - ((myData.ApproxU1V1)? 1: 0) + - ((myData.ApproxU2V2)? 1: 0), + ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0), + myData.ApproxU1V1, myData.ApproxU2V2, myData.Xo, myData.Yo, myData.Zo, myData.U1o, myData.V1o, myData.U2o, myData.V2o, myData.ApproxU1V1, @@ -631,10 +631,11 @@ void ApproxInt_Approx::buildCurve(const Handle(TheWLine)& theline, imin = myKnots(kind); imax = myKnots(kind+1); ApproxInt_TheMultiLine myMultiLine(theline, thePtrSVSurf, - ((myData.ApproxXYZ)? 1 : 0), - ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0), - myData.Xo, myData.Yo, myData.Zo, myData.U1o, myData.V1o, - myData.U2o, myData.V2o, myData.ApproxU1V1, imin, imax); + ((myData.ApproxXYZ)? 1 : 0), + ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0), + myData.ApproxU1V1, myData.ApproxU2V2, + myData.Xo, myData.Yo, myData.Zo, myData.U1o, myData.V1o, + myData.U2o, myData.V2o, myData.ApproxU1V1, imin, imax); if(myData.myBezierApprox) { @@ -716,4 +717,4 @@ void ApproxInt_Approx::buildCurve(const Handle(TheWLine)& theline, { myBezToBSpl.Perform(); } -} \ No newline at end of file +} diff --git a/src/ApproxInt/ApproxInt_ImpPrmSvSurfaces.gxx b/src/ApproxInt/ApproxInt_ImpPrmSvSurfaces.gxx index 74eb09d898..8501520616 100644 --- a/src/ApproxInt/ApproxInt_ImpPrmSvSurfaces.gxx +++ b/src/ApproxInt/ApproxInt_ImpPrmSvSurfaces.gxx @@ -14,6 +14,7 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include #include #include #include @@ -489,12 +490,10 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1, } } - Standard_Real aBornInf[2],aBornSup[2],aF[1],aX[2],aTolerance[2]; - math_Vector BornInf(aBornInf,1,2),BornSup(aBornSup,1,2),F(aF,1,1), - X(aX,1,2),Tolerance(aTolerance,1,2); - Standard_Real aD[1][2]; - math_Matrix D(aD,1, 1, 1, 2); - + math_Vector X(1,2); + math_Vector BornInf(1,2), BornSup(1,2), Tolerance(1,2); + //--- ThePSurfaceTool::GetResolution(aPSurf,Tolerance(1),Tolerance(2)); + Tolerance(1) = 1.0e-8; Tolerance(2) = 1.0e-8; Standard_Real binfu,bsupu,binfv,bsupv; binfu = ThePSurfaceTool::FirstUParameter(aPSurf); binfv = ThePSurfaceTool::FirstVParameter(aPSurf); @@ -502,124 +501,23 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1, bsupv = ThePSurfaceTool::LastVParameter(aPSurf); BornInf(1) = binfu; BornSup(1) = bsupu; BornInf(2) = binfv; BornSup(2) = bsupv; - - //--- ThePSurfaceTool::GetResolution(aPSurf,Tolerance(1),Tolerance(2)); - Tolerance(1) = 1.0e-8; Tolerance(2) = 1.0e-8; - - Standard_Real TranslationU=0.0; - Standard_Real TranslationV=0.0; - - math_FunctionSetRoot Rsnld(MyZerImpFunc); - Rsnld.SetTolerance(Tolerance); - if(MyImplicitFirst) { - if(u2bsupu+0.0000000001) { - if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { - Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf); - do { TranslationU-=d; } while(u2+TranslationU > bsupu); - } - else { - MyIsTangent=MyIsTangentbis=Standard_False; - MyHasBeenComputed = MyHasBeenComputedbis = Standard_False; - return(Standard_False); - } - } - if(v2bsupv+0.0000000001) { - if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { - Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf); - do { TranslationV-=d; } while(v2+TranslationV > bsupv); - } - else { - MyIsTangent=MyIsTangentbis=Standard_False; - MyHasBeenComputed = MyHasBeenComputedbis = Standard_False; - return(Standard_False); - } - } - X(1) = u2+TranslationU; - X(2) = v2+TranslationV; - } - else { - if(u1bsupu+0.0000000001) { - if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { - Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf); - do { TranslationU-=d; } while(u1+TranslationU > bsupu); - } - else { - MyIsTangent=MyIsTangentbis=Standard_False; - MyHasBeenComputed = MyHasBeenComputedbis = Standard_False; - return(Standard_False); - } - } - if(v1bsupv+0.0000000001) { - if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { - Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf); - do { TranslationV-=d; } while(v1+TranslationV > bsupv); - } - else { - MyIsTangent=MyIsTangentbis=Standard_False; - MyHasBeenComputed = MyHasBeenComputedbis = Standard_False; - return(Standard_False); - } - } - X(1) = u1+TranslationU; - X(2) = v1+TranslationV; - } - - //---------------------------------------------------- - //Make a small step from boundaries in order to avoid - //finding "outboundaried" solution (Rsnld -> NotDone). - if(X(1)-0.0000000001 <= binfu) X(1)=X(1)+0.0000001; - if(X(1)+0.0000000001 >= bsupu) X(1)=X(1)-0.0000001; - if(X(2)-0.0000000001 <= binfv) X(2)=X(2)+0.0000001; - if(X(2)+0.0000000001 >= bsupv) X(2)=X(2)-0.0000001; + Standard_Real TranslationU = 0., TranslationV = 0.; + if (!FillInitialVectorOfSolution(u1, v1, u2, v2, + binfu, bsupu, binfv, bsupv, + X, + TranslationU, TranslationV)) + { + MyIsTangent=MyIsTangentbis=Standard_False; + MyHasBeenComputed = MyHasBeenComputedbis = Standard_False; + return(Standard_False); + } Standard_Real PourTesterU = X(1); Standard_Real PourTesterV = X(2); - + + math_FunctionSetRoot Rsnld(MyZerImpFunc); + Rsnld.SetTolerance(Tolerance); Rsnld.Perform(MyZerImpFunc,X,BornInf,BornSup); if(Rsnld.IsDone()) { MyHasBeenComputed = Standard_True; @@ -826,9 +724,189 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1, } } +//======================================================================= +//function : SeekPoint +//purpose : Computes point on curve and +// parameters on the surfaces. +//======================================================================= +Standard_Boolean ApproxInt_ImpPrmSvSurfaces::SeekPoint(const Standard_Real u1, + const Standard_Real v1, + const Standard_Real u2, + const Standard_Real v2, + IntSurf_PntOn2S& Point) { + gp_Pnt aP; + gp_Vec aT; + gp_Vec2d aTS1,aTS2; + const IntSurf_Quadric& aQSurf = MyZerImpFunc.ISurface(); + const ThePSurface& aPSurf = MyZerImpFunc.PSurface(); + + math_Vector X(1,2); + math_Vector BornInf(1,2), BornSup(1,2), Tolerance(1,2); + //--- ThePSurfaceTool::GetResolution(aPSurf,Tolerance(1),Tolerance(2)); + Tolerance(1) = 1.0e-8; Tolerance(2) = 1.0e-8; + Standard_Real binfu,bsupu,binfv,bsupv; + binfu = ThePSurfaceTool::FirstUParameter(aPSurf); + binfv = ThePSurfaceTool::FirstVParameter(aPSurf); + bsupu = ThePSurfaceTool::LastUParameter(aPSurf); + bsupv = ThePSurfaceTool::LastVParameter(aPSurf); + BornInf(1) = binfu; BornSup(1) = bsupu; + BornInf(2) = binfv; BornSup(2) = bsupv; + Standard_Real TranslationU = 0., TranslationV = 0.; + + if (!FillInitialVectorOfSolution(u1, v1, u2, v2, + binfu, bsupu, binfv, bsupv, + X, + TranslationU, TranslationV)) + return Standard_False; + + Standard_Real NewU1, NewV1, NewU2, NewV2; + + math_FunctionSetRoot Rsnld(MyZerImpFunc); + Rsnld.SetTolerance(Tolerance); + Rsnld.Perform(MyZerImpFunc,X,BornInf,BornSup); + if(Rsnld.IsDone()) { + MyHasBeenComputed = Standard_True; + Rsnld.Root(X); + + MyPnt = ThePSurfaceTool::Value(aPSurf, X(1), X(2)); + + if(MyImplicitFirst) + { + NewU2 = X(1)-TranslationU; + NewV2 = X(2)-TranslationV; + + aQSurf.Parameters(MyPnt, NewU1, NewV1); + //adjust U + if (aQSurf.TypeQuadric() != GeomAbs_Plane) + { + Standard_Real sign = (NewU1 > u1)? -1 : 1; + while (Abs(u1 - NewU1) > M_PI) + NewU1 += sign*(M_PI+M_PI); + } + } + else + { + NewU1 = X(1)-TranslationU; + NewV1 = X(2)-TranslationV; + + aQSurf.Parameters(MyPnt, NewU2, NewV2); + //adjust U + if (aQSurf.TypeQuadric() != GeomAbs_Plane) + { + Standard_Real sign = (NewU2 > u2)? -1 : 1; + while (Abs(u2 - NewU2) > M_PI) + NewU2 += sign*(M_PI+M_PI); + } + } + } + else + return Standard_False; + + Point.SetValue(MyPnt, NewU1, NewV1, NewU2, NewV2); + return Standard_True; +} //-------------------------------------------------------------------------------- +Standard_Boolean +ApproxInt_ImpPrmSvSurfaces::FillInitialVectorOfSolution(const Standard_Real u1, + const Standard_Real v1, + const Standard_Real u2, + const Standard_Real v2, + const Standard_Real binfu, + const Standard_Real bsupu, + const Standard_Real binfv, + const Standard_Real bsupv, + math_Vector& X, + Standard_Real& TranslationU, + Standard_Real& TranslationV) +{ + const ThePSurface& aPSurf = MyZerImpFunc.PSurface(); + math_Vector F(1,1); + TranslationU = 0.0; + TranslationV = 0.0; - + if(MyImplicitFirst) { + if(u2bsupu+0.0000000001) { + if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { + Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf); + do { TranslationU-=d; } while(u2+TranslationU > bsupu); + } + else + return(Standard_False); + } + if(v2bsupv+0.0000000001) { + if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { + Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf); + do { TranslationV-=d; } while(v2+TranslationV > bsupv); + } + else + return(Standard_False); + } + X(1) = u2+TranslationU; + X(2) = v2+TranslationV; + } + else { + if(u1bsupu+0.0000000001) { + if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { + Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf); + do { TranslationU-=d; } while(u1+TranslationU > bsupu); + } + else + return(Standard_False); + } + if(v1bsupv+0.0000000001) { + if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { + Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf); + do { TranslationV-=d; } while(v1+TranslationV > bsupv); + } + else + return(Standard_False); + } + X(1) = u1+TranslationU; + X(2) = v1+TranslationV; + } + + //---------------------------------------------------- + //Make a small step from boundaries in order to avoid + //finding "outboundaried" solution (Rsnld -> NotDone). + if(X(1)-0.0000000001 <= binfu) X(1)=X(1)+0.0000001; + if(X(1)+0.0000000001 >= bsupu) X(1)=X(1)-0.0000001; + if(X(2)-0.0000000001 <= binfv) X(2)=X(2)+0.0000001; + if(X(2)+0.0000000001 >= bsupv) X(2)=X(2)-0.0000001; + + return Standard_True; +} diff --git a/src/ApproxInt/ApproxInt_MultiLine.gxx b/src/ApproxInt/ApproxInt_MultiLine.gxx index d6f2e64e36..d19952fb98 100644 --- a/src/ApproxInt/ApproxInt_MultiLine.gxx +++ b/src/ApproxInt/ApproxInt_MultiLine.gxx @@ -20,6 +20,36 @@ #include #include #include +#include +#include + +#ifdef DRAW +#include +#endif + +//======================================================================= +//function : Constructor +//purpose : +//======================================================================= +ApproxInt_MultiLine::ApproxInt_MultiLine() +{ + PtrOnmySvSurfaces = NULL; + myLine = NULL; + indicemin = 0; + indicemax = 0; + nbp3d = 0; + nbp2d = 0; + myApproxU1V1 = Standard_False; + myApproxU2V2 = Standard_False; + p2donfirst = Standard_True; + Xo = 0.; + Yo = 0.; + Zo = 0.; + U1o = 0.; + V1o = 0.; + U2o = 0.; + V2o = 0.; +} //======================================================================= //function : Constructor @@ -30,6 +60,8 @@ ApproxInt_MultiLine:: const Standard_Address svsurf, const Standard_Integer NbP3d, const Standard_Integer NbP2d, + const Standard_Boolean ApproxU1V1, + const Standard_Boolean ApproxU2V2, const Standard_Real xo, const Standard_Real yo, const Standard_Real zo, @@ -44,6 +76,8 @@ ApproxInt_MultiLine:: indicemin(Min(IndMin, IndMax)), indicemax(Max(IndMin, IndMax)), nbp3d(NbP3d), nbp2d(NbP2d), + myApproxU1V1(ApproxU1V1), + myApproxU2V2(ApproxU2V2), p2donfirst(P2DOnFirst), Xo(xo), Yo(yo), Zo(zo), U1o(u1o), V1o(v1o), @@ -66,6 +100,8 @@ ApproxInt_MultiLine:: ApproxInt_MultiLine(const Handle_TheLine& line, const Standard_Integer NbP3d, const Standard_Integer NbP2d, + const Standard_Boolean ApproxU1V1, + const Standard_Boolean ApproxU2V2, const Standard_Real xo, const Standard_Real yo, const Standard_Real zo, @@ -80,6 +116,8 @@ ApproxInt_MultiLine:: indicemin(Min(IndMin, IndMax)), indicemax(Max(IndMin, IndMax)), nbp3d(NbP3d), nbp2d(NbP2d), + myApproxU1V1(ApproxU1V1), + myApproxU2V2(ApproxU2V2), p2donfirst(P2DOnFirst), Xo(xo), Yo(yo), Zo(zo), U1o(u1o), V1o(v1o), @@ -95,26 +133,26 @@ ApproxInt_MultiLine:: //-------------------------------------------------------------------------------- Standard_Integer ApproxInt_MultiLine::FirstPoint() const { - return(indicemin); + return indicemin; } //-------------------------------------------------------------------------------- Standard_Integer ApproxInt_MultiLine::LastPoint() const { - return(indicemax); + return indicemax; } //-------------------------------------------------------------------------------- Approx_Status ApproxInt_MultiLine::WhatStatus() const { if(PtrOnmySvSurfaces) - return(Approx_PointsAdded); + return Approx_PointsAdded; else - return(Approx_NoPointsAdded); + return Approx_NoPointsAdded; } //-------------------------------------------------------------------------------- Standard_Integer ApproxInt_MultiLine::NbP3d() const { - return(nbp3d); + return nbp3d; } //-------------------------------------------------------------------------------- Standard_Integer ApproxInt_MultiLine::NbP2d() const { - return(nbp2d); + return nbp2d; } //================================================================================ void ApproxInt_MultiLine::Value(const Standard_Integer Index, @@ -268,13 +306,14 @@ ApproxInt_MultiLine //-- cout<<"\n Erreur dans : ApproxInt_MultiLine ApproxInt_MultiLine::MakeMLBetween "<NbPnts() >= NbPntsToInsert + High - Low + 1) && (CodeErreur==0)) { - return(ApproxInt_MultiLine( temp, - (High-Low>10)? PtrOnmySvSurfaces : NULL, - nbp3d, - nbp2d, - Xo,Yo,Zo, - U1o,V1o, - U2o,V2o, - p2donfirst, - 1,ResultPntOn2SLine->NbPoints())); + return (ApproxInt_MultiLine( temp, + (High-Low>10)? PtrOnmySvSurfaces : NULL, + nbp3d, + nbp2d, + myApproxU1V1, myApproxU2V2, + Xo,Yo,Zo, + U1o,V1o, + U2o,V2o, + p2donfirst, + 1,ResultPntOn2SLine->NbPoints())); } else { @@ -541,18 +581,139 @@ ApproxInt_MultiLine //-- cout<<" Pas de Rajout de points ds1min = "<NbPoints()); + return Standard_True; +} + //======================================================================= //function : Dump //purpose : diff --git a/src/ApproxInt/ApproxInt_MultiLineTool.lxx b/src/ApproxInt/ApproxInt_MultiLineTool.lxx index a14a07e211..c047e781a1 100644 --- a/src/ApproxInt/ApproxInt_MultiLineTool.lxx +++ b/src/ApproxInt/ApproxInt_MultiLineTool.lxx @@ -115,6 +115,15 @@ inline TheMultiLine ApproxInt_MultiLineTool::MakeMLBetween(const TheMultiLine& M return(ML.MakeMLBetween(I1,I2,NbPMin)); } +//-------------------------------------------------------------------------------- +inline Standard_Boolean ApproxInt_MultiLineTool::MakeMLOneMorePoint(const TheMultiLine& ML, + const Standard_Integer I1, + const Standard_Integer I2, + const Standard_Integer indbad, + TheMultiLine& OtherLine) +{ + return (ML.MakeMLOneMorePoint(I1,I2,indbad,OtherLine)); +} inline void ApproxInt_MultiLineTool::Dump(const TheMultiLine& ML) { diff --git a/src/ApproxInt/ApproxInt_PrmPrmSvSurfaces.gxx b/src/ApproxInt/ApproxInt_PrmPrmSvSurfaces.gxx index 74f6b8c727..c4534f9d55 100644 --- a/src/ApproxInt/ApproxInt_PrmPrmSvSurfaces.gxx +++ b/src/ApproxInt/ApproxInt_PrmPrmSvSurfaces.gxx @@ -34,7 +34,12 @@ ApproxInt_PrmPrmSvSurfaces::ApproxInt_PrmPrmSvSurfaces( const ThePSurface& Surf1 MyIntersectionOn2S(Surf1,Surf2,TOLTANGENCY) { } -//-------------------------------------------------------------------------------- + +//======================================================================= +//function : Compute +//purpose : Computes point on curve, 3D and 2D-tangents of a curve and +// parameters on the surfaces. +//======================================================================= Standard_Boolean ApproxInt_PrmPrmSvSurfaces::Compute( Standard_Real& u1 ,Standard_Real& v1 ,Standard_Real& u2 @@ -221,6 +226,31 @@ void ApproxInt_PrmPrmSvSurfaces::Pnt(const Standard_Real u1, this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2); P=MyPnt; } + +//======================================================================= +//function : SeekPoint +//purpose : Computes point on curve and +// parameters on the surfaces. +//======================================================================= +Standard_Boolean ApproxInt_PrmPrmSvSurfaces::SeekPoint(const Standard_Real u1, + const Standard_Real v1, + const Standard_Real u2, + const Standard_Real v2, + IntSurf_PntOn2S& Point) +{ + gp_Pnt aP; + gp_Vec aT; + gp_Vec2d aTS1,aTS2; + Standard_Real tu1=u1; + Standard_Real tu2=u2; + Standard_Real tv1=v1; + Standard_Real tv2=v2; + if (!Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2)) + return Standard_False; + + Point.SetValue(aP, tu1,tv1,tu2,tv2); + return Standard_True; +} //-------------------------------------------------------------------------------- Standard_Boolean ApproxInt_PrmPrmSvSurfaces::Tangency(const Standard_Real u1, const Standard_Real v1, diff --git a/src/ApproxInt/ApproxInt_SvSurfaces.hxx b/src/ApproxInt/ApproxInt_SvSurfaces.hxx index 825ba24c3f..f2ad4fd1c7 100644 --- a/src/ApproxInt/ApproxInt_SvSurfaces.hxx +++ b/src/ApproxInt/ApproxInt_SvSurfaces.hxx @@ -26,7 +26,7 @@ class gp_Pnt; class gp_Vec; class gp_Vec2d; - +class IntSurf_PntOn2S; class ApproxInt_SvSurfaces @@ -37,15 +37,37 @@ public: //! returns True if Tg,Tguv1 Tguv2 can be computed. - Standard_EXPORT virtual Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2) = 0; + Standard_EXPORT virtual Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, + Standard_Real& u2, Standard_Real& v2, + gp_Pnt& Pt, + gp_Vec& Tg, + gp_Vec2d& Tguv1, + gp_Vec2d& Tguv2) = 0; - Standard_EXPORT virtual void Pnt (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Pnt& P) = 0; + Standard_EXPORT virtual void Pnt (const Standard_Real u1, const Standard_Real v1, + const Standard_Real u2, const Standard_Real v2, + gp_Pnt& P) = 0; + + //! computes point on curve and parameters on the surfaces + Standard_EXPORT virtual Standard_Boolean SeekPoint(const Standard_Real u1, const Standard_Real v1, + const Standard_Real u2, const Standard_Real v2, + IntSurf_PntOn2S& Point) = 0; - Standard_EXPORT virtual Standard_Boolean Tangency (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec& Tg) = 0; + Standard_EXPORT virtual Standard_Boolean Tangency (const Standard_Real u1, const Standard_Real v1, + const Standard_Real u2, const Standard_Real v2, + gp_Vec& Tg) = 0; - Standard_EXPORT virtual Standard_Boolean TangencyOnSurf1 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg) = 0; + Standard_EXPORT virtual Standard_Boolean TangencyOnSurf1 (const Standard_Real u1, + const Standard_Real v1, + const Standard_Real u2, + const Standard_Real v2, + gp_Vec2d& Tg) = 0; - Standard_EXPORT virtual Standard_Boolean TangencyOnSurf2 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg) = 0; + Standard_EXPORT virtual Standard_Boolean TangencyOnSurf2 (const Standard_Real u1, + const Standard_Real v1, + const Standard_Real u2, + const Standard_Real v2, + gp_Vec2d& Tg) = 0; Standard_EXPORT virtual ~ApproxInt_SvSurfaces(); diff --git a/src/BRepApprox/BRepApprox_TheComputeLineBezierOfApprox.hxx b/src/BRepApprox/BRepApprox_TheComputeLineBezierOfApprox.hxx index 1e7f39c54e..a75b0ae3ab 100644 --- a/src/BRepApprox/BRepApprox_TheComputeLineBezierOfApprox.hxx +++ b/src/BRepApprox/BRepApprox_TheComputeLineBezierOfApprox.hxx @@ -132,7 +132,13 @@ private: //! is internally used in the algorithm. - Standard_EXPORT Standard_Boolean Compute (const BRepApprox_TheMultiLineOfApprox& Line, const Standard_Integer fpt, const Standard_Integer lpt, math_Vector& Para, Standard_Real& TheTol3d, Standard_Real& TheTol2d); + Standard_EXPORT Standard_Boolean Compute (const BRepApprox_TheMultiLineOfApprox& Line, + const Standard_Integer fpt, + const Standard_Integer lpt, + math_Vector& Para, + Standard_Real& TheTol3d, + Standard_Real& TheTol2d, + Standard_Integer& indbad); //! is internally used in the algorithm. Standard_EXPORT Standard_Boolean ComputeCurve (const BRepApprox_TheMultiLineOfApprox& Line, const Standard_Integer firspt, const Standard_Integer lastpt); @@ -173,6 +179,7 @@ private: AppParCurves_Constraint myfirstC; AppParCurves_Constraint mylastC; Standard_Integer myMultiLineNb; + Standard_Integer myNbPlusOnePoint; Standard_Boolean myIsClear; diff --git a/src/BRepApprox/BRepApprox_TheImpPrmSvSurfacesOfApprox.hxx b/src/BRepApprox/BRepApprox_TheImpPrmSvSurfacesOfApprox.hxx index d711bc0f28..4f2e3366eb 100644 --- a/src/BRepApprox/BRepApprox_TheImpPrmSvSurfacesOfApprox.hxx +++ b/src/BRepApprox/BRepApprox_TheImpPrmSvSurfacesOfApprox.hxx @@ -53,16 +53,34 @@ public: Standard_EXPORT BRepApprox_TheImpPrmSvSurfacesOfApprox(const IntSurf_Quadric& Surf1, const BRepAdaptor_Surface& Surf2); //! returns True if Tg,Tguv1 Tguv2 can be computed. - Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2); + Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, + gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2); Standard_EXPORT void Pnt (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Pnt& P); + Standard_EXPORT Standard_Boolean SeekPoint(const Standard_Real u1, + const Standard_Real v1, + const Standard_Real u2, + const Standard_Real v2, + IntSurf_PntOn2S& Point); + Standard_EXPORT Standard_Boolean Tangency (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec& Tg); Standard_EXPORT Standard_Boolean TangencyOnSurf1 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg); Standard_EXPORT Standard_Boolean TangencyOnSurf2 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg); + Standard_Boolean FillInitialVectorOfSolution(const Standard_Real u1, + const Standard_Real v1, + const Standard_Real u2, + const Standard_Real v2, + const Standard_Real binfu, + const Standard_Real bsupu, + const Standard_Real binfv, + const Standard_Real bsupv, + math_Vector& X, + Standard_Real& TranslationU, + Standard_Real& TranslationV); diff --git a/src/BRepApprox/BRepApprox_TheMultiLineOfApprox.hxx b/src/BRepApprox/BRepApprox_TheMultiLineOfApprox.hxx index 40d91b079c..a8d89f4fb3 100644 --- a/src/BRepApprox/BRepApprox_TheMultiLineOfApprox.hxx +++ b/src/BRepApprox/BRepApprox_TheMultiLineOfApprox.hxx @@ -41,6 +41,8 @@ public: DEFINE_STANDARD_ALLOC + Standard_EXPORT BRepApprox_TheMultiLineOfApprox(); + //! The class SvSurfaces is used when the approximation algorithm //! needs some extra points on the line . //! A New line is then created which shares the same surfaces and functions. @@ -51,6 +53,8 @@ public: const Standard_Address PtrSvSurfaces, const Standard_Integer NbP3d, const Standard_Integer NbP2d, + const Standard_Boolean ApproxU1V1, + const Standard_Boolean ApproxU2V2, const Standard_Real xo, const Standard_Real yo, const Standard_Real zo, @@ -66,6 +70,8 @@ public: Standard_EXPORT BRepApprox_TheMultiLineOfApprox(const Handle(BRepApprox_ApproxLine)& line, const Standard_Integer NbP3d, const Standard_Integer NbP2d, + const Standard_Boolean ApproxU1V1, + const Standard_Boolean ApproxU2V2, const Standard_Real xo, const Standard_Real yo, const Standard_Real zo, @@ -106,30 +112,42 @@ public: //! Returns the 3d and 2d points of the multipoint . Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec& tabV, TColgp_Array1OfVec2d& tabV2d) const; + + //! Tries to make a sub-line between and points of this line + //! by adding new points + Standard_EXPORT BRepApprox_TheMultiLineOfApprox MakeMLBetween (const Standard_Integer Low, + const Standard_Integer High, + const Standard_Integer NbPointsToInsert) const; - Standard_EXPORT BRepApprox_TheMultiLineOfApprox MakeMLBetween (const Standard_Integer Low, const Standard_Integer High, const Standard_Integer NbPointsToInsert) const; - + //! Tries to make a sub-line between and points of this line + //! by adding one more point between (indbad-1)-th and indbad-th points + Standard_EXPORT Standard_Boolean MakeMLOneMorePoint (const Standard_Integer Low, + const Standard_Integer High, + const Standard_Integer indbad, + BRepApprox_TheMultiLineOfApprox& OtherLine) const; + //! Dump of the current multi-line. Standard_EXPORT void Dump() const; protected: - BRepApprox_TheMultiLineOfApprox operator=(BRepApprox_TheMultiLineOfApprox&); private: - const Standard_Address PtrOnmySvSurfaces; - const Handle(BRepApprox_ApproxLine) myLine; - const Standard_Integer indicemin; - const Standard_Integer indicemax; - const Standard_Integer nbp3d; - const Standard_Integer nbp2d; - const Standard_Boolean p2donfirst; - const Standard_Real Xo; - const Standard_Real Yo; - const Standard_Real Zo; - const Standard_Real U1o; - const Standard_Real V1o; - const Standard_Real U2o; - const Standard_Real V2o; + Standard_Address PtrOnmySvSurfaces; + Handle(BRepApprox_ApproxLine) myLine; + Standard_Integer indicemin; + Standard_Integer indicemax; + Standard_Integer nbp3d; + Standard_Integer nbp2d; + Standard_Boolean myApproxU1V1; + Standard_Boolean myApproxU2V2; + Standard_Boolean p2donfirst; + Standard_Real Xo; + Standard_Real Yo; + Standard_Real Zo; + Standard_Real U1o; + Standard_Real V1o; + Standard_Real U2o; + Standard_Real V2o; }; diff --git a/src/BRepApprox/BRepApprox_TheMultiLineToolOfApprox.hxx b/src/BRepApprox/BRepApprox_TheMultiLineToolOfApprox.hxx index 4cceba14bf..1fcb02fe2d 100644 --- a/src/BRepApprox/BRepApprox_TheMultiLineToolOfApprox.hxx +++ b/src/BRepApprox/BRepApprox_TheMultiLineToolOfApprox.hxx @@ -92,6 +92,13 @@ public: //! Is called if WhatStatus returned "PointsAdded". static BRepApprox_TheMultiLineOfApprox MakeMLBetween (const BRepApprox_TheMultiLineOfApprox& ML, const Standard_Integer I1, const Standard_Integer I2, const Standard_Integer NbPMin); + //! Is called when the Bezier curve contains a loop + static Standard_Boolean MakeMLOneMorePoint (const BRepApprox_TheMultiLineOfApprox& ML, + const Standard_Integer I1, + const Standard_Integer I2, + const Standard_Integer indbad, + BRepApprox_TheMultiLineOfApprox& OtherLine); + static Approx_Status WhatStatus (const BRepApprox_TheMultiLineOfApprox& ML, const Standard_Integer I1, const Standard_Integer I2); //! Dump of the current multi-line. diff --git a/src/BRepApprox/BRepApprox_ThePrmPrmSvSurfacesOfApprox.hxx b/src/BRepApprox/BRepApprox_ThePrmPrmSvSurfacesOfApprox.hxx index 76a35d6d16..97dcf4a0f5 100644 --- a/src/BRepApprox/BRepApprox_ThePrmPrmSvSurfacesOfApprox.hxx +++ b/src/BRepApprox/BRepApprox_ThePrmPrmSvSurfacesOfApprox.hxx @@ -50,10 +50,17 @@ public: Standard_EXPORT BRepApprox_ThePrmPrmSvSurfacesOfApprox(const BRepAdaptor_Surface& Surf1, const BRepAdaptor_Surface& Surf2); //! returns True if Tg,Tguv1 Tguv2 can be computed. - Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2); + Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, + gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2); Standard_EXPORT void Pnt (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Pnt& P); + Standard_EXPORT Standard_Boolean SeekPoint(const Standard_Real u1, + const Standard_Real v1, + const Standard_Real u2, + const Standard_Real v2, + IntSurf_PntOn2S& Point); + Standard_EXPORT Standard_Boolean Tangency (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec& Tg); Standard_EXPORT Standard_Boolean TangencyOnSurf1 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg); diff --git a/src/GeomInt/GeomInt_TheComputeLineBezierOfWLApprox.hxx b/src/GeomInt/GeomInt_TheComputeLineBezierOfWLApprox.hxx index 7de0869ebb..acc5e5da2e 100644 --- a/src/GeomInt/GeomInt_TheComputeLineBezierOfWLApprox.hxx +++ b/src/GeomInt/GeomInt_TheComputeLineBezierOfWLApprox.hxx @@ -135,7 +135,13 @@ private: //! is internally used in the algorithm. - Standard_EXPORT Standard_Boolean Compute (const GeomInt_TheMultiLineOfWLApprox& Line, const Standard_Integer fpt, const Standard_Integer lpt, math_Vector& Para, Standard_Real& TheTol3d, Standard_Real& TheTol2d); + Standard_EXPORT Standard_Boolean Compute (const GeomInt_TheMultiLineOfWLApprox& Line, + const Standard_Integer fpt, + const Standard_Integer lpt, + math_Vector& Para, + Standard_Real& TheTol3d, + Standard_Real& TheTol2d, + Standard_Integer& indbad); //! is internally used in the algorithm. Standard_EXPORT Standard_Boolean ComputeCurve (const GeomInt_TheMultiLineOfWLApprox& Line, const Standard_Integer firspt, const Standard_Integer lastpt); @@ -176,6 +182,7 @@ private: AppParCurves_Constraint myfirstC; AppParCurves_Constraint mylastC; Standard_Integer myMultiLineNb; + Standard_Integer myNbPlusOnePoint; Standard_Boolean myIsClear; diff --git a/src/GeomInt/GeomInt_TheImpPrmSvSurfacesOfWLApprox.hxx b/src/GeomInt/GeomInt_TheImpPrmSvSurfacesOfWLApprox.hxx index 6fd664e90d..3d9bdffddd 100644 --- a/src/GeomInt/GeomInt_TheImpPrmSvSurfacesOfWLApprox.hxx +++ b/src/GeomInt/GeomInt_TheImpPrmSvSurfacesOfWLApprox.hxx @@ -53,17 +53,34 @@ public: Standard_EXPORT GeomInt_TheImpPrmSvSurfacesOfWLApprox(const IntSurf_Quadric& Surf1, const Handle(Adaptor3d_HSurface)& Surf2); //! returns True if Tg,Tguv1 Tguv2 can be computed. - Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2); + Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, + gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2); Standard_EXPORT void Pnt (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Pnt& P); + Standard_EXPORT Standard_Boolean SeekPoint(const Standard_Real u1, + const Standard_Real v1, + const Standard_Real u2, + const Standard_Real v2, + IntSurf_PntOn2S& Point); + Standard_EXPORT Standard_Boolean Tangency (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec& Tg); Standard_EXPORT Standard_Boolean TangencyOnSurf1 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg); Standard_EXPORT Standard_Boolean TangencyOnSurf2 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg); - + Standard_Boolean FillInitialVectorOfSolution(const Standard_Real u1, + const Standard_Real v1, + const Standard_Real u2, + const Standard_Real v2, + const Standard_Real binfu, + const Standard_Real bsupu, + const Standard_Real binfv, + const Standard_Real bsupv, + math_Vector& X, + Standard_Real& TranslationU, + Standard_Real& TranslationV); protected: diff --git a/src/GeomInt/GeomInt_TheMultiLineOfWLApprox.hxx b/src/GeomInt/GeomInt_TheMultiLineOfWLApprox.hxx index 78095b219b..619598d096 100644 --- a/src/GeomInt/GeomInt_TheMultiLineOfWLApprox.hxx +++ b/src/GeomInt/GeomInt_TheMultiLineOfWLApprox.hxx @@ -41,6 +41,8 @@ public: DEFINE_STANDARD_ALLOC + Standard_EXPORT GeomInt_TheMultiLineOfWLApprox(); + //! The class SvSurfaces is used when the approximation algorithm //! needs some extra points on the line . //! A New line is then created which shares the same surfaces and functions. @@ -51,6 +53,8 @@ public: const Standard_Address PtrSvSurfaces, const Standard_Integer NbP3d, const Standard_Integer NbP2d, + const Standard_Boolean ApproxU1V1, + const Standard_Boolean ApproxU2V2, const Standard_Real xo, const Standard_Real yo, const Standard_Real zo, @@ -66,6 +70,8 @@ public: Standard_EXPORT GeomInt_TheMultiLineOfWLApprox( const Handle(IntPatch_WLine)& line, const Standard_Integer NbP3d, const Standard_Integer NbP2d, + const Standard_Boolean ApproxU1V1, + const Standard_Boolean ApproxU2V2, const Standard_Real xo, const Standard_Real yo, const Standard_Real zo, @@ -112,8 +118,19 @@ public: //! Returns the 3d and 2d points of the multipoint . Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec& tabV, TColgp_Array1OfVec2d& tabV2d) const; - Standard_EXPORT GeomInt_TheMultiLineOfWLApprox MakeMLBetween (const Standard_Integer Low, const Standard_Integer High, const Standard_Integer NbPointsToInsert) const; + //! Tries to make a sub-line between and points of this line + //! by adding new points + Standard_EXPORT GeomInt_TheMultiLineOfWLApprox MakeMLBetween (const Standard_Integer Low, + const Standard_Integer High, + const Standard_Integer NbPointsToInsert) const; + //! Tries to make a sub-line between and points of this line + //! by adding one more point between (indbad-1)-th and indbad-th points + Standard_EXPORT Standard_Boolean MakeMLOneMorePoint (const Standard_Integer Low, + const Standard_Integer High, + const Standard_Integer indbad, + GeomInt_TheMultiLineOfWLApprox& OtherLine) const; + //! Dump of the current multi-line. Standard_EXPORT void Dump() const; @@ -121,23 +138,24 @@ public: protected: - GeomInt_TheMultiLineOfWLApprox operator=(GeomInt_TheMultiLineOfWLApprox&); private: - const Standard_Address PtrOnmySvSurfaces; - const Handle(IntPatch_WLine) myLine; - const Standard_Integer indicemin; - const Standard_Integer indicemax; - const Standard_Integer nbp3d; - const Standard_Integer nbp2d; - const Standard_Boolean p2donfirst; - const Standard_Real Xo; - const Standard_Real Yo; - const Standard_Real Zo; - const Standard_Real U1o; - const Standard_Real V1o; - const Standard_Real U2o; - const Standard_Real V2o; + Standard_Address PtrOnmySvSurfaces; + Handle(IntPatch_WLine) myLine; + Standard_Integer indicemin; + Standard_Integer indicemax; + Standard_Integer nbp3d; + Standard_Integer nbp2d; + Standard_Boolean myApproxU1V1; + Standard_Boolean myApproxU2V2; + Standard_Boolean p2donfirst; + Standard_Real Xo; + Standard_Real Yo; + Standard_Real Zo; + Standard_Real U1o; + Standard_Real V1o; + Standard_Real U2o; + Standard_Real V2o; }; diff --git a/src/GeomInt/GeomInt_TheMultiLineToolOfWLApprox.hxx b/src/GeomInt/GeomInt_TheMultiLineToolOfWLApprox.hxx index 565c1e2717..3d6e8b0ef3 100644 --- a/src/GeomInt/GeomInt_TheMultiLineToolOfWLApprox.hxx +++ b/src/GeomInt/GeomInt_TheMultiLineToolOfWLApprox.hxx @@ -92,6 +92,13 @@ public: //! Is called if WhatStatus returned "PointsAdded". static GeomInt_TheMultiLineOfWLApprox MakeMLBetween (const GeomInt_TheMultiLineOfWLApprox& ML, const Standard_Integer I1, const Standard_Integer I2, const Standard_Integer NbPMin); + //! Is called when the Bezier curve contains a loop + static Standard_Boolean MakeMLOneMorePoint (const GeomInt_TheMultiLineOfWLApprox& ML, + const Standard_Integer I1, + const Standard_Integer I2, + const Standard_Integer indbad, + GeomInt_TheMultiLineOfWLApprox& OtherLine); + static Approx_Status WhatStatus (const GeomInt_TheMultiLineOfWLApprox& ML, const Standard_Integer I1, const Standard_Integer I2); //! Dump of the current multi-line. diff --git a/src/GeomInt/GeomInt_ThePrmPrmSvSurfacesOfWLApprox.hxx b/src/GeomInt/GeomInt_ThePrmPrmSvSurfacesOfWLApprox.hxx index 1c7cfe91d1..5c292fe41b 100644 --- a/src/GeomInt/GeomInt_ThePrmPrmSvSurfacesOfWLApprox.hxx +++ b/src/GeomInt/GeomInt_ThePrmPrmSvSurfacesOfWLApprox.hxx @@ -50,10 +50,17 @@ public: Standard_EXPORT GeomInt_ThePrmPrmSvSurfacesOfWLApprox(const Handle(Adaptor3d_HSurface)& Surf1, const Handle(Adaptor3d_HSurface)& Surf2); //! returns True if Tg,Tguv1 Tguv2 can be computed. - Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2); + Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, + gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2); Standard_EXPORT void Pnt (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Pnt& P); + Standard_EXPORT Standard_Boolean SeekPoint(const Standard_Real u1, + const Standard_Real v1, + const Standard_Real u2, + const Standard_Real v2, + IntSurf_PntOn2S& Point); + Standard_EXPORT Standard_Boolean Tangency (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec& Tg); Standard_EXPORT Standard_Boolean TangencyOnSurf1 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg); diff --git a/src/LocOpe/LocOpe_WiresOnShape.cxx b/src/LocOpe/LocOpe_WiresOnShape.cxx index e6fb054c17..1174606274 100644 --- a/src/LocOpe/LocOpe_WiresOnShape.cxx +++ b/src/LocOpe/LocOpe_WiresOnShape.cxx @@ -803,12 +803,20 @@ void PutPCurve(const TopoDS_Edge& Edg, S = BRep_Tool::Surface(Fac); + Standard_Real TolFirst = -1, TolLast = -1; + TopoDS_Vertex V1, V2; + TopExp::Vertices(Edg, V1, V2); + if (!V1.IsNull()) + TolFirst = BRep_Tool::Tolerance(V1); + if (!V2.IsNull()) + TolLast = BRep_Tool::Tolerance(V2); + Standard_Real tol2d = Precision::Confusion(); Handle(Geom2d_Curve) C2d; ShapeConstruct_ProjectCurveOnSurface aToolProj; aToolProj.Init(S, tol2d); - aToolProj.Perform(C,f,l, C2d); + aToolProj.Perform(C,f,l,C2d,TolFirst,TolLast); if (C2d.IsNull()) { return; @@ -819,7 +827,6 @@ void PutPCurve(const TopoDS_Edge& Edg, gp_Pnt PF,PL; S->D0(pf.X(),pf.Y(),PF); S->D0(pl.X(),pl.Y(),PL); - TopoDS_Vertex V1,V2; if (Edg.Orientation() == TopAbs_REVERSED) { V1 = TopExp::LastVertex(Edg); V1.Reverse(); diff --git a/src/ShapeAnalysis/ShapeAnalysis_Surface.cxx b/src/ShapeAnalysis/ShapeAnalysis_Surface.cxx index 8b46ddea3b..6411b7a3f2 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_Surface.cxx +++ b/src/ShapeAnalysis/ShapeAnalysis_Surface.cxx @@ -376,8 +376,8 @@ Standard_Boolean ShapeAnalysis_Surface::ProjectDegenerated(const gp_Pnt& P3d, //======================================================================= Standard_Boolean ShapeAnalysis_Surface::ProjectDegenerated(const Standard_Integer nbrPnt, - const TColgp_Array1OfPnt& points, - TColgp_Array1OfPnt2d& pnt2d, + const TColgp_SequenceOfPnt& points, + TColgp_SequenceOfPnt2d& pnt2d, const Standard_Real preci, const Standard_Boolean direct) { diff --git a/src/ShapeAnalysis/ShapeAnalysis_Surface.hxx b/src/ShapeAnalysis/ShapeAnalysis_Surface.hxx index e4ac811a60..e41fa2ef8e 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_Surface.hxx +++ b/src/ShapeAnalysis/ShapeAnalysis_Surface.hxx @@ -29,8 +29,8 @@ #include #include #include -#include -#include +#include +#include class Geom_Surface; class GeomAdaptor_HSurface; class Geom_Curve; @@ -82,7 +82,8 @@ public: //! Reads all the data from another Surface, without recomputing Standard_EXPORT void Init (const Handle(ShapeAnalysis_Surface)& other); - Standard_EXPORT void SetDomain (const Standard_Real U1, const Standard_Real U2, const Standard_Real V1, const Standard_Real V2); + Standard_EXPORT void SetDomain (const Standard_Real U1, const Standard_Real U2, + const Standard_Real V1, const Standard_Real V2); //! Returns a surface being analyzed const Handle(Geom_Surface)& Surface() const; @@ -138,7 +139,14 @@ public: //! uisodeg: if the degenerated iso-line is U-iso (True) or //! V-iso (False). //! Returns False if is out of range, else returns True. - Standard_EXPORT Standard_Boolean Singularity (const Standard_Integer num, Standard_Real& preci, gp_Pnt& P3d, gp_Pnt2d& firstP2d, gp_Pnt2d& lastP2d, Standard_Real& firstpar, Standard_Real& lastpar, Standard_Boolean& uisodeg); + Standard_EXPORT Standard_Boolean Singularity (const Standard_Integer num, + Standard_Real& preci, + gp_Pnt& P3d, + gp_Pnt2d& firstP2d, + gp_Pnt2d& lastP2d, + Standard_Real& firstpar, + Standard_Real& lastpar, + Standard_Boolean& uisodeg); //! Returns True if there is at least one surface boundary which //! is considered as degenerated with and distance @@ -152,7 +160,13 @@ public: //! (like IsDegenerated). //! Returns characteristics of the first found boundary matching //! those criteria. - Standard_EXPORT Standard_Boolean DegeneratedValues (const gp_Pnt& P3d, const Standard_Real preci, gp_Pnt2d& firstP2d, gp_Pnt2d& lastP2d, Standard_Real& firstpar, Standard_Real& lastpar, const Standard_Boolean forward = Standard_True); + Standard_EXPORT Standard_Boolean DegeneratedValues (const gp_Pnt& P3d, + const Standard_Real preci, + gp_Pnt2d& firstP2d, + gp_Pnt2d& lastP2d, + Standard_Real& firstpar, + Standard_Real& lastpar, + const Standard_Boolean forward = Standard_True); //! Projects a point on a singularity by computing //! one of the coordinates of preliminary computed . @@ -166,14 +180,20 @@ public: //! resolution (computed from by Geom_Adaptor). //! Then sets not yet computed 's coordinate taking it //! from and returns True. - Standard_EXPORT Standard_Boolean ProjectDegenerated (const gp_Pnt& P3d, const Standard_Real preci, const gp_Pnt2d& neighbour, gp_Pnt2d& result); + Standard_EXPORT Standard_Boolean ProjectDegenerated (const gp_Pnt& P3d, + const Standard_Real preci, + const gp_Pnt2d& neighbour, + gp_Pnt2d& result); //! Checks points at the beginning (direct is True) or end //! (direct is False) of array to lie in singularity of //! surface, and if yes, adjusts the indeterminate 2d coordinate //! of these points by nearest point which is not in singularity. //! Returns True if some points were adjusted. - Standard_EXPORT Standard_Boolean ProjectDegenerated (const Standard_Integer nbrPnt, const TColgp_Array1OfPnt& points, TColgp_Array1OfPnt2d& pnt2d, const Standard_Real preci, const Standard_Boolean direct); + Standard_EXPORT Standard_Boolean ProjectDegenerated (const Standard_Integer nbrPnt, + const TColgp_SequenceOfPnt& points, + TColgp_SequenceOfPnt2d& pnt2d, + const Standard_Real preci, const Standard_Boolean direct); //! Returns True if straight pcurve going from point p2d1 to p2d2 //! is degenerate, i.e. lies in the singularity of the surface. @@ -188,11 +208,15 @@ public: //! the Resolution computed from max distance in 3d //! (max3d < tol && max2d > ratio * Resolution(max3d)) //! NOTE: should be >1 (e.g. 10) - Standard_EXPORT Standard_Boolean IsDegenerated (const gp_Pnt2d& p2d1, const gp_Pnt2d& p2d2, const Standard_Real tol, const Standard_Real ratio); + Standard_EXPORT Standard_Boolean IsDegenerated (const gp_Pnt2d& p2d1, + const gp_Pnt2d& p2d2, + const Standard_Real tol, + const Standard_Real ratio); //! Returns the bounds of the surface //! (from Bounds from Surface, but buffered) - void Bounds (Standard_Real& ufirst, Standard_Real& ulast, Standard_Real& vfirst, Standard_Real& vlast) const; + void Bounds (Standard_Real& ufirst, Standard_Real& ulast, + Standard_Real& vfirst, Standard_Real& vlast) const; //! Computes bound isos (protected against exceptions) Standard_EXPORT void ComputeBoundIsos(); @@ -257,7 +281,10 @@ public: //! P3D is greater than , that solution is considered //! as bad, and ValueOfUV() is used. //! If not succeded, calls ValueOfUV() - Standard_EXPORT gp_Pnt2d NextValueOfUV (const gp_Pnt2d& p2dPrev, const gp_Pnt& P3D, const Standard_Real preci, const Standard_Real maxpreci = -1.0); + Standard_EXPORT gp_Pnt2d NextValueOfUV (const gp_Pnt2d& p2dPrev, + const gp_Pnt& P3D, + const Standard_Real preci, + const Standard_Real maxpreci = -1.0); //! Tries a refinement of an already computed couple (U,V) by //! using projecting 3D point on iso-lines: @@ -268,7 +295,10 @@ public: //! direction) //! Returns the best resulting distance between P3D and Value(U,V) //! in the case of success. Else, returns a very great value - Standard_EXPORT Standard_Real UVFromIso (const gp_Pnt& P3D, const Standard_Real preci, Standard_Real& U, Standard_Real& V); + Standard_EXPORT Standard_Real UVFromIso (const gp_Pnt& P3D, + const Standard_Real preci, + Standard_Real& U, + Standard_Real& V); //! Returns minimum value to consider the surface as U-closed Standard_Real UCloseVal() const; @@ -349,7 +379,10 @@ private: Standard_EXPORT void ComputeBoxes(); //! @return 0, 1 or 2. - Standard_EXPORT Standard_Integer SurfaceNewton (const gp_Pnt2d& p2dPrev, const gp_Pnt& P3D, const Standard_Real preci, gp_Pnt2d& sol); + Standard_EXPORT Standard_Integer SurfaceNewton (const gp_Pnt2d& p2dPrev, + const gp_Pnt& P3D, + const Standard_Real preci, + gp_Pnt2d& sol); Standard_EXPORT void SortSingularities(); diff --git a/src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.cxx b/src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.cxx index 14e52f4484..507a00bb16 100644 --- a/src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.cxx +++ b/src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.cxx @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -73,12 +74,38 @@ #include #include #include +#include +#include #include IMPLEMENT_STANDARD_RTTIEXT(ShapeConstruct_ProjectCurveOnSurface,MMgt_TShared) #define NCONTROL 23 + +static void AdjustSecondPointToFirstPoint(const gp_Pnt2d& theFirstPoint, + gp_Pnt2d& theSecondPoint, + const Handle(Geom_Surface)& theSurf) +{ + if (theSurf->IsUPeriodic()) + { + Standard_Real UPeriod = theSurf->UPeriod(); + Standard_Real NewU = ElCLib::InPeriod(theSecondPoint.X(), + theFirstPoint.X() - UPeriod/2, + theFirstPoint.X() + UPeriod/2); + theSecondPoint.SetX(NewU); + } + if (theSurf->IsVPeriodic()) + { + Standard_Real VPeriod = theSurf->VPeriod(); + Standard_Real NewV = ElCLib::InPeriod(theSecondPoint.Y(), + theFirstPoint.Y() - VPeriod/2, + theFirstPoint.Y() + VPeriod/2); + theSecondPoint.SetY(NewV); + } +} + + //======================================================================= //function : ShapeConstruct_ProjectCurveOnSurface //purpose : @@ -167,29 +194,6 @@ ShapeConstruct_ProjectCurveOnSurface::ShapeConstruct_ProjectCurveOnSurface() return myAdjustOverDegen; } - -//======================================================================= -//function : NbSurfIntervals -//purpose : work-around of bug in standard method -// GeomAdaptor_Surface->NbIntervals() (PRO16346) -//======================================================================= - -static Standard_Integer NbSurfIntervals(const Handle(GeomAdaptor_HSurface)& GAS, const GeomAbs_Shape cont) -{ - Standard_Integer NbU = 0; - if (GAS->GetType() == GeomAbs_SurfaceOfExtrusion) { - // extract the surface - Handle(Geom_SurfaceOfLinearExtrusion) surf = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(GAS->ChangeSurface().Surface()); - // build a 3d adaptor curve - GeomAdaptor_Curve Adaptor3dCurve(surf->BasisCurve(), GAS->FirstUParameter(), GAS->LastUParameter()); - if (Adaptor3dCurve.GetType() == GeomAbs_BSplineCurve) - NbU = Adaptor3dCurve.NbIntervals(cont); - } - if (NbU == 0) - NbU = GAS->NbUIntervals(cont); - return NbU * (GAS->NbVIntervals(cont)); -} - //======================================================================= //function : Status //purpose : @@ -208,9 +212,8 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Perform (Handle(Geom_Curv const Standard_Real First, const Standard_Real Last, Handle(Geom2d_Curve)& c2d, - const GeomAbs_Shape, - const Standard_Integer, - const Standard_Integer) + const Standard_Real TolFirst, + const Standard_Real TolLast) { myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); //Standard_Boolean OK = Standard_True; //szv#4:S4163:12Mar99 not needed @@ -251,7 +254,10 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Perform (Handle(Geom_Curv if ( ! bspl.IsNull() ) { Standard_Integer nint = 0; for ( Standard_Integer i=1; i < bspl->NbKnots(); i++ ) - if ( bspl->Knot(i+1) > First && bspl->Knot(i) < Last ) nint++; + { + if ( bspl->Knot(i+1) > First && bspl->Knot(i) < Last ) + nint++; + } Standard_Integer minPnt = nint * ( bspl->Degree() + 1 ); while ( nbPini < minPnt ) nbPini += NCONTROL - 1; #ifdef OCCT_DEBUG @@ -263,8 +269,8 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Perform (Handle(Geom_Curv // $$$$ end :92 (big BSplineCurve C0) // this number should be "parametric dependent" - TColgp_Array1OfPnt points(1, nbPini); - TColStd_Array1OfReal params(1, nbPini); + TColgp_SequenceOfPnt points; + TColStd_SequenceOfReal params; NCollection_Sequence aKnotCoeffs; gp_Pnt p3d; Standard_Integer iPnt; @@ -363,13 +369,15 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Perform (Handle(Geom_Curv else t = First + (iPnt - 1) * deltaT; c3d->D0 (t, p3d); - points(iPnt) = p3d; - params(iPnt) = t; + points.Append(p3d); + params.Append(t); } // CALCUL par approximation - TColgp_Array1OfPnt2d pnt2d(1, nbrPnt); - ApproxPCurve (nbrPnt,points,params,pnt2d,c2d); //szv#4:S4163:12Mar99 OK not needed + TColgp_SequenceOfPnt2d pnt2d; + ApproxPCurve (nbrPnt,c3d,TolFirst,TolLast, + points,params,pnt2d,c2d); //szv#4:S4163:12Mar99 OK not needed + nbPini = points.Length(); if (!c2d.IsNull()) { myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE2); return Standard_True; @@ -483,36 +491,6 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformByProjLib(Handle(G return Standard_False; } -//======================================================================= -//function : PerformAdvanced -//purpose : -//======================================================================= - -Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(Geom_Curve)& c3d, - const Standard_Real First, - const Standard_Real Last, - Handle(Geom2d_Curve)& c2d) -{ - Standard_Boolean hasResult = Standard_False; - Standard_Integer nbintervals; - - Standard_Boolean isStandard = (mySurf->Adaptor3d()->GetType() != GeomAbs_Cylinder); -// && (mySurf->Adaptor3d()->GetType() != GeomAbs_SurfaceOfRevolution); - - if (isStandard) isStandard = !mySurf->HasSingularities(myPreci); - if (isStandard) { - Handle(GeomAdaptor_HSurface) GAS = mySurf->Adaptor3d(); - Handle(GeomAdaptor_HCurve) GAC = new GeomAdaptor_HCurve (c3d,First,Last); - nbintervals = NbSurfIntervals(GAS, GeomAbs_C1);//+GAC->NbIntervals(GeomAbs_C3); - isStandard = (nbintervals < 2); - } - if (isStandard) { - hasResult = PerformByProjLib(c3d, First, Last, c2d); - } - if (!hasResult) hasResult = Perform (c3d, First, Last, c2d); - return hasResult; -} - //======================================================================= //function : ProjectAnalytic //purpose : @@ -665,9 +643,9 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G //======================================================================= Handle(Geom2d_Curve) ShapeConstruct_ProjectCurveOnSurface::getLine( - const TColgp_Array1OfPnt& thepoints, - const TColStd_Array1OfReal& theparams, - TColgp_Array1OfPnt2d& thePnt2ds, + const TColgp_SequenceOfPnt& thepoints, + const TColStd_SequenceOfReal& theparams, + TColgp_SequenceOfPnt2d& thePnt2ds, Standard_Real theTol, Standard_Boolean &isRecompute, Standard_Boolean &isFromCashe) const @@ -703,7 +681,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G for( ; i < 4; i +=3) { Standard_Integer j; - for (j = 0; j < myNbCashe; ++j) + for (j = 0; j < myNbCashe; j++) { if ( myCashe3d[j].SquareDistance (aP[i] ) < aTol2) { @@ -715,27 +693,23 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G break; } } - + if (j >= myNbCashe) - { aP2d[i] = mySurf->ValueOfUV(aP[i], theTol); - } - + Standard_Real aDist = mySurf->Gap(); Standard_Real aCurDist = aDist * aDist; - if (aTol2 < aDist * aDist) - { + if( aTol2 < aDist * aDist) aTol2 = aCurDist; - } } - + if ( isPeriodicU || isPeriodicV ) { // Compute second and last but one c2d points. for(i = 1; i < 3; i++) { Standard_Integer j; - for (j = 0; j < myNbCashe; ++j) + for (j = 0; j < myNbCashe; j++) { if ( myCashe3d[j].SquareDistance (aP[i] ) < aTol2) { @@ -745,18 +719,14 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G break; } } - + if (j >= myNbCashe) - { aP2d[i] = mySurf->ValueOfUV(aP[i], theTol); - } - + Standard_Real aDist = mySurf->Gap(); Standard_Real aCurDist = aDist * aDist; - if (aTol2 < aDist * aDist) - { + if( aTol2 < aDist * aDist) aTol2 = aCurDist; - } } if (isPeriodicU) @@ -858,14 +828,22 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G //======================================================================= Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::ApproxPCurve(const Standard_Integer nbrPnt, - const TColgp_Array1OfPnt& points, - const TColStd_Array1OfReal& params, - TColgp_Array1OfPnt2d& pnt2d, - Handle(Geom2d_Curve)& c2d) + const Handle(Geom_Curve)& c3d, + const Standard_Real TolFirst, + const Standard_Real TolLast, + TColgp_SequenceOfPnt& points, + TColStd_SequenceOfReal& params, + TColgp_SequenceOfPnt2d& pnt2d, + Handle(Geom2d_Curve)& c2d) { // for performance, first try to handle typical case when pcurve is straight Standard_Boolean isRecompute = Standard_False; Standard_Boolean isFromCasheLine = Standard_False; + for (Standard_Integer iseq = 1; iseq <= nbrPnt; iseq++) + { + gp_Pnt2d aP2d(0.,0.); + pnt2d.Append(aP2d); + } c2d = getLine(points, params, pnt2d, myPreci, isRecompute, isFromCasheLine); if(!c2d.IsNull()) { @@ -914,7 +892,6 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G gp_Pnt p3d; gp_Pnt2d p2d; - Standard_Integer i; Standard_Real isoValue=0., isoPar1=0., isoPar2=0., tPar=0., tdeb,tfin; Standard_Real Cf, Cl, parf, parl; //szv#4:S4163:12Mar99 dist not needed @@ -1007,29 +984,26 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G ChangeCycle = Standard_True; //for( i = 1; i <= nbrPnt; i ++) { for(Standard_Integer ii=1; ii<=nbrPnt; ii++) { - if(ChangeCycle) //skl for OCC3430 - i=nbrPnt-ii+1; - else - i=ii; - p3d = points(i); + const Standard_Integer aPntIndex = ChangeCycle ? (nbrPnt - ii + 1) : ii; + p3d = points (aPntIndex); if (isoParam) { if (isoPar2d3d) { - if (isoPar2 > isoPar1) tPar = params(i); - else tPar = t1 + t2 - params(i); + if (isoPar2 > isoPar1) tPar = params (aPntIndex); + else tPar = t1 + t2 - params(aPntIndex); } else if (!isAnalytic) { // projection to iso - if (i==1) tPar = isoPar1; - else if (i==nbrPnt) tPar = isoPar2; + if (aPntIndex == 1) tPar = isoPar1; + else if (aPntIndex == nbrPnt) tPar = isoPar2; else { - tPar = pout(i); + tPar = pout(aPntIndex); //:S4030 ShapeAnalysis_Curve().Project (cIso,p3d,myPreci,pt,tPar,Cf,Cl); //szv#4:S4163:12Mar99 `dist=` not needed } } if (!isoPar2d3d && isAnalytic) { - if (i == 1) p2d = valueP1; - else if (i == nbrPnt) p2d = valueP2; + if (aPntIndex == 1) p2d = valueP1; + else if (aPntIndex == nbrPnt) p2d = valueP2; else { p2d = mySurf->NextValueOfUV(p2d,p3d, myPreci, //%12 pdn 15.02.99 optimizing Precision::Confusion()+1000*gap); //:q1 @@ -1042,17 +1016,17 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G } else { - if ( (i == 1) && p1OnIso) p2d = valueP1; - else if( (i == nbrPnt) && p2OnIso) p2d = valueP2; + if ( (aPntIndex == 1) && p1OnIso) p2d = valueP1; + else if( (aPntIndex == nbrPnt) && p2OnIso) p2d = valueP2; else {// general case (not an iso) mais attention aux singularites ! // first and last points are already computed by getLine() - if ( (i == 1 || i == nbrPnt)) + if (aPntIndex == 1 || aPntIndex == nbrPnt) { if (!isRecompute) { - p2d = pnt2d(i); + p2d = pnt2d (aPntIndex); gap = mySurf->Gap(); - if (i == 1) { + if (aPntIndex == 1) { isFromCashe = isFromCasheLine; aSavedPoint = p2d; } @@ -1067,7 +1041,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G if ( myCashe3d[j].SquareDistance ( p3d ) < myPreci*myPreci ) { p2d = mySurf->NextValueOfUV (myCashe2d[j], p3d, myPreci, Precision::Confusion()+gap); - if (i == 1) + if (aPntIndex == 1) { isFromCashe = Standard_True; aSavedPoint = myCashe2d[j]; @@ -1088,12 +1062,12 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G gap = mySurf->Gap(); } } - pnt2d (i) = p2d; + pnt2d (aPntIndex) = p2d; if ( ii > 1 ) { if(ChangeCycle) - p2d.SetXY ( 2. * p2d.XY() - pnt2d(i+1).XY() ); + p2d.SetXY ( 2. * p2d.XY() - pnt2d(aPntIndex + 1).XY() ); else - p2d.SetXY ( 2. * p2d.XY() - pnt2d(i-1).XY() ); + p2d.SetXY ( 2. * p2d.XY() - pnt2d(aPntIndex - 1).XY() ); } } @@ -1102,6 +1076,37 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G mySurf->ProjectDegenerated(nbrPnt,points,pnt2d,myPreci,Standard_True); mySurf->ProjectDegenerated(nbrPnt,points,pnt2d,myPreci,Standard_False); } + + //Check the extremities of 3d curve for coinciding with singularities of surf + //Standard_Integer NbSing = mySurf->NbSingularities(Precision::Confusion()); + gp_Pnt PointFirst = points.First(), PointLast = points.Last(); + Standard_Real aTolFirst = (TolFirst == -1)? Precision::Confusion() : TolFirst; + Standard_Real aTolLast = (TolLast == -1)? Precision::Confusion() : TolLast; + for (Standard_Integer i = 1; ; i++) + { + Standard_Real aPreci, aFirstPar, aLastPar; + gp_Pnt aP3d; + gp_Pnt2d aFirstP2d, aLastP2d; + Standard_Boolean IsUiso; + if (!mySurf->Singularity(i, aPreci, aP3d, aFirstP2d, aLastP2d, aFirstPar, aLastPar, IsUiso)) + break; + if (aPreci <= Precision::Confusion() && + PointFirst.Distance(aP3d) <= aTolFirst) + { + CorrectExtremity(c3d, params, pnt2d, + Standard_True, //first point + aFirstP2d, + IsUiso); + } + if (aPreci <= Precision::Confusion() && + PointLast.Distance(aP3d) <= aTolLast) + { + CorrectExtremity(c3d, params, pnt2d, + Standard_False, //last point + aFirstP2d, + IsUiso); + } + } // attention aux singularites ... (hors cas iso qui les traite deja) // if (!isoParam) { @@ -1118,6 +1123,8 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G Standard_Real Up = ul - uf; Standard_Real Vp = vl - vf; Standard_Real dist2d; + const Standard_Real TolOnUPeriod = Precision::Confusion() * Up; + const Standard_Real TolOnVPeriod = Precision::Confusion() * Vp; #ifdef OCCT_DEBUG if (mySurf->IsUClosed(myPreci) && mySurf->IsVClosed(myPreci)) {//#78 rln 12.03.99 S4135 cout << "WARNING : Recadrage incertain sur U & VClosed" << endl; @@ -1151,19 +1158,21 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G //:97 abv 1 Feb 98: treat case when curve is whole out of surface bounds Standard_Real minX = firstX, maxX = firstX; + Standard_Boolean ToAdjust = Standard_False; // On decalle toujours le suivant - for (i = 2; i <= nbrPnt; i++) { - // dist2d = pnt2d (i-1).Distance(pnt2d (i)); - Standard_Real CurX = pnt2d (i).X(); + for (Standard_Integer aPntIter = 2; aPntIter <= pnt2d.Length(); ++aPntIter) + { + // dist2d = pnt2d (aPntIter - 1).Distance(pnt2d (aPntIter)); + Standard_Real CurX = pnt2d (aPntIter).X(); dist2d = Abs (CurX - prevX); - if (dist2d > ( Up / 2) ) { - if (CurX > prevX + Up/2) { - while (CurX > prevX + Up/2) { CurX -= Up; pnt2d (i).SetX (CurX); } - } else if (CurX < prevX - Up/2) { - while (CurX < prevX - Up/2) { CurX += Up; pnt2d (i).SetX (CurX); } - } - + if (dist2d > ( Up / 2) ) + { + InsertAdditionalPointOrAdjust(ToAdjust, 1, Up, TolOnUPeriod, + CurX, prevX, + c3d, + aPntIter, + points, params, pnt2d); } prevX = CurX; if ( minX > CurX ) minX = CurX; //:97 @@ -1178,7 +1187,8 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G if ( midX > ul ) shiftX = -Up; else if ( midX < uf ) shiftX = Up; if ( shiftX != 0. ) - for ( i=1; i <= nbrPnt; i++ ) pnt2d(i).SetX ( pnt2d(i).X() + shiftX ); + for (Standard_Integer aPntIter = 1; aPntIter <= pnt2d.Length(); ++aPntIter) + pnt2d (aPntIter).SetX ( pnt2d (aPntIter).X() + shiftX ); } } // Si la surface est VCLosed, on recadre les points @@ -1215,18 +1225,21 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G //:97 abv 1 Feb 98: treat case when curve is whole out of surface bounds Standard_Real minY = firstY, maxY = firstY; + Standard_Boolean ToAdjust = Standard_False; // On decalle toujours le suivant - for (i = 2; i <= nbrPnt; i ++) { + for (Standard_Integer aPntIter = 2; aPntIter <= pnt2d.Length(); ++aPntIter) + { // dist2d = pnt2d (i-1).Distance(pnt2d (i)); - Standard_Real CurY = pnt2d (i).Y(); + Standard_Real CurY = pnt2d (aPntIter).Y(); dist2d = Abs (CurY - prevY); - if (dist2d > ( Vp / 2) ) { - if (CurY > prevY + Vp/2) { - while (CurY > prevY + Vp/2) { CurY -= Vp; pnt2d (i).SetY (CurY); } - } else if (CurY < prevY - Vp/2) { - while (CurY < prevY - Vp/2) { CurY += Vp; pnt2d (i).SetY (CurY); } - } + if (dist2d > ( Vp / 2) ) + { + InsertAdditionalPointOrAdjust(ToAdjust, 2, Vp, TolOnVPeriod, + CurY, prevY, + c3d, + aPntIter, + points, params, pnt2d); } prevY = CurY; if ( minY > CurY ) minY = CurY; //:97 @@ -1241,16 +1254,17 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G if ( midY > vl ) shiftY = -Vp; else if ( midY < vf ) shiftY = Vp; if ( shiftY != 0. ) - for ( i=1; i <= nbrPnt; i++ ) pnt2d(i).SetY ( pnt2d(i).Y() + shiftY ); + for (Standard_Integer aPntIter = 1; aPntIter <= pnt2d.Length(); ++aPntIter) + pnt2d(aPntIter).SetY ( pnt2d(aPntIter).Y() + shiftY ); } } //#69 rln 01.03.99 S4135 bm2_sd_t4-A.stp entity 30 //#78 rln 12.03.99 S4135 if (mySurf->IsVClosed(myPreci) || mySurf->Surface()->IsKind (STANDARD_TYPE (Geom_SphericalSurface))) { - for (i = 2; i <= nbrPnt; i++) { + for (Standard_Integer aPntIter = 2; aPntIter <= pnt2d.Length(); ++aPntIter) { //#1 rln 11/02/98 ca_exhaust.stp entity #9869 dist2d = pnt2d (i-1).Distance(pnt2d (i)); - dist2d = Abs (pnt2d(i).Y() - pnt2d(i - 1).Y()); + dist2d = Abs (pnt2d (aPntIter).Y() - pnt2d (aPntIter - 1).Y()); if (dist2d > ( Vp / 2) ) { // ATTENTION : il faut regarder ou le decalage se fait. // si plusieurs points sont decalles, il faut plusieurs passes @@ -1266,10 +1280,10 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G Standard_Boolean currOnLast = Standard_False; // .X ? plutot .Y , non ? - Standard_Real distPrevVF = Abs(pnt2d (i-1).Y() - vf); - Standard_Real distPrevVL = Abs(pnt2d (i-1).Y() - vl); - Standard_Real distCurrVF = Abs(pnt2d (i).Y() - vf); - Standard_Real distCurrVL = Abs(pnt2d (i).Y() - vl); + Standard_Real distPrevVF = Abs(pnt2d (aPntIter - 1).Y() - vf); + Standard_Real distPrevVL = Abs(pnt2d (aPntIter - 1).Y() - vl); + Standard_Real distCurrVF = Abs(pnt2d (aPntIter).Y() - vf); + Standard_Real distCurrVL = Abs(pnt2d (aPntIter).Y() - vl); Standard_Real theMin = distPrevVF; prevOnFirst = Standard_True; @@ -1293,28 +1307,28 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G } // Modifs RLN/Nijni 3-DEC-1997 if (prevOnFirst) { - // on decalle le point (i-1) en V Last - gp_Pnt2d newPrev(pnt2d (i-1).X(), vf); // instead of vl RLN/Nijni - pnt2d (i-1) = newPrev; + // on decalle le point (aPntIter - 1) en V Last + gp_Pnt2d newPrev(pnt2d (aPntIter - 1).X(), vf); // instead of vl RLN/Nijni + pnt2d (aPntIter - 1) = newPrev; } else if (prevOnLast) { - // on decalle le point (i-1) en V first - gp_Pnt2d newPrev(pnt2d (i-1).X(), vl); // instead of vf RLN/Nijni - pnt2d (i-1) = newPrev; + // on decalle le point (aPntIter - 1) en V first + gp_Pnt2d newPrev(pnt2d (aPntIter - 1).X(), vl); // instead of vf RLN/Nijni + pnt2d (aPntIter - 1) = newPrev; } else if (currOnFirst) { - // on decalle le point (i) en V Last - gp_Pnt2d newCurr(pnt2d (i).X(),vf); // instead of vl RLN/Nijni - pnt2d (i) = newCurr; + // on decalle le point (aPntIter) en V Last + gp_Pnt2d newCurr(pnt2d (aPntIter).X(),vf); // instead of vl RLN/Nijni + pnt2d (aPntIter) = newCurr; } else if (currOnLast) { - // on decalle le point (i) en V First - gp_Pnt2d newCurr(pnt2d (i).X(), vl); // instead of vf RLN/Nijni - pnt2d (i) = newCurr; + // on decalle le point (aPntIter) en V First + gp_Pnt2d newCurr(pnt2d (aPntIter).X(), vl); // instead of vf RLN/Nijni + pnt2d (aPntIter) = newCurr; } // on verifie #ifdef OCCT_DEBUG - dist2d = pnt2d (i-1).Distance(pnt2d (i)); + dist2d = pnt2d (aPntIter - 1).Distance(pnt2d (aPntIter)); if (dist2d > ( Vp / 2) ) { cout << "Echec dans le recadrage" << endl; } @@ -1348,7 +1362,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G Standard_Integer OnBound=0, PrevOnBound=0; Standard_Integer ind; // svv #1 Standard_Boolean start = Standard_True; - for ( ind=1; ind <= nbrPnt; ind++ ) { + for ( ind=1; ind <= pnt2d.Length(); ind++ ) { Standard_Real CurX = pnt2d(ind).X(); // abv 16 Mar 00: trj3_s1-ug.stp #697: ignore points in singularity if ( mySurf->IsDegenerated ( points(ind), Precision::Confusion() ) ) @@ -1362,7 +1376,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G PrevOnBound = OnBound; } // if found, adjust seam part - if ( ind <= nbrPnt ) { + if ( ind <= pnt2d.Length() ) { PrevX = ( myAdjustOverDegen ? uf : ul ); Standard_Real dU = Up/2 + Precision::PConfusion(); if ( PrevOnBound ) { @@ -1375,7 +1389,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G } else if ( OnBound ) { pnt2d(ind).SetX ( PrevX ); - for ( Standard_Integer j=ind+1; j <= nbrPnt; j++ ) { + for ( Standard_Integer j=ind+1; j <= pnt2d.Length(); j++ ) { Standard_Real CurX = pnt2d(j).X(); while ( CurX < PrevX - dU ) pnt2d(j).SetX ( CurX += Up ); while ( CurX > PrevX + dU ) pnt2d(j).SetX ( CurX -= Up ); @@ -1393,7 +1407,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G Standard_Integer OnBound=0, PrevOnBound=0; Standard_Integer ind; // svv #1 Standard_Boolean start = Standard_True; - for ( ind=1; ind <= nbrPnt; ind++ ) { + for ( ind=1; ind <= pnt2d.Length(); ind++ ) { Standard_Real CurY = pnt2d(ind).Y(); // abv 16 Mar 00: trj3_s1-ug.stp #697: ignore points in singularity if ( mySurf->IsDegenerated ( points(ind), Precision::Confusion() ) ) @@ -1407,7 +1421,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G PrevOnBound = OnBound; } // if found, adjust seam part - if ( ind <= nbrPnt ) { + if ( ind <= pnt2d.Length() ) { PrevY = ( myAdjustOverDegen ? vf : vl ); Standard_Real dV = Vp/2 + Precision::PConfusion(); if ( PrevOnBound ) { @@ -1420,7 +1434,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G } else if ( OnBound ) { pnt2d(ind).SetY ( PrevY ); - for ( Standard_Integer j=ind+1; j <= nbrPnt; j++ ) { + for ( Standard_Integer j=ind+1; j <= pnt2d.Length(); j++ ) { Standard_Real CurY = pnt2d(j).Y(); while ( CurY < PrevY - dV ) pnt2d(j).SetY ( CurY += Vp ); while ( CurY > PrevY + dV ) pnt2d(j).SetY ( CurY -= Vp ); @@ -1438,15 +1452,15 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G //if(myCashe3d[0].Distance(points(1))>Precision::Confusion() && // myCashe3d[1].Distance(points(1))>Precision::Confusion()) { myCashe3d[0] = points(1); - myCashe3d[1] = points(nbrPnt); + myCashe3d[1] = points.Last(); myCashe2d[0] = pnt2d(1); - myCashe2d[1] = pnt2d(nbrPnt); + myCashe2d[1] = pnt2d.Last(); } else { myCashe3d[1] = points(1); - myCashe3d[0] = points(nbrPnt); + myCashe3d[0] = points.Last(); myCashe2d[1] = pnt2d(1); - myCashe2d[0] = pnt2d(nbrPnt); + myCashe2d[0] = pnt2d.Last(); } return isDone; } @@ -1599,6 +1613,207 @@ Handle(Geom_Curve) ShapeConstruct_ProjectCurveOnSurface::InterpolateCurve3d(cons return C3d; } +//============================================================================================ +//function : CorrectExtremity +//purpose : corrects first or last 2d point of future curve +// in the case when it coincids with a singularity of surface +//============================================================================================ + +void ShapeConstruct_ProjectCurveOnSurface::CorrectExtremity(const Handle(Geom_Curve)& theC3d, + const TColStd_SequenceOfReal& theParams, + TColgp_SequenceOfPnt2d& thePnt2d, + const Standard_Boolean theIsFirstPoint, + const gp_Pnt2d& thePointOnIsoLine, + const Standard_Boolean theIsUiso) +{ + Standard_Integer NbPnt = thePnt2d.Length(); + Standard_Integer IndCoord = (theIsUiso)? 2 : 1; + Standard_Real SingularityCoord = thePointOnIsoLine.Coord(3-IndCoord); + gp_Pnt2d EndPoint = (theIsFirstPoint)? thePnt2d(1) : thePnt2d(NbPnt); + Standard_Real FinishCoord = EndPoint.Coord(3-IndCoord); //the constant coord of isoline + + gp_Dir2d aDir = (theIsUiso)? gp::DY2d() : gp::DX2d(); + gp_Lin2d anIsoLine(EndPoint, aDir); + IntRes2d_Domain Dom1, Dom2; + + Standard_Boolean IsPeriodic = (theIsUiso)? + mySurf->Surface()->IsVPeriodic() : mySurf->Surface()->IsUPeriodic(); + + gp_Pnt2d FirstPointOfLine, SecondPointOfLine; + Standard_Real FinishParam, FirstParam, SecondParam; + + if (theIsFirstPoint) + { + FirstPointOfLine = thePnt2d(3); + SecondPointOfLine = thePnt2d(2); + FinishParam = theParams(1); + FirstParam = theParams(3); + SecondParam = theParams(2); + } + else //last point + { + FirstPointOfLine = thePnt2d(NbPnt-2); + SecondPointOfLine = thePnt2d(NbPnt-1); + FinishParam = theParams(NbPnt); + FirstParam = theParams(NbPnt-2); + SecondParam = theParams(NbPnt-1); + } + + if (SingularityCoord > FinishCoord && + SecondPointOfLine.Coord(3-IndCoord) > FinishCoord) + return; //the curve passes through the singularity, do nothing + if (SingularityCoord < FinishCoord && + SecondPointOfLine.Coord(3-IndCoord) < FinishCoord) + return; //the curve passes through the singularity, do nothing + //Check correctness of + { + const Standard_Real aPrevDist = Abs(SecondPointOfLine.Coord(IndCoord) - FirstPointOfLine.Coord(IndCoord)); + const Standard_Real aCurDist = Abs(EndPoint.Coord(IndCoord) - SecondPointOfLine.Coord(IndCoord)); + if (aCurDist <= 2 * aPrevDist) + return; + } + + gp_Pnt2d FinishPoint = (theIsUiso)? gp_Pnt2d(FinishCoord, SecondPointOfLine.Y()) : + gp_Pnt2d(SecondPointOfLine.X(), FinishCoord); //first approximation of + + for (;;) + { + if (Abs(SecondPointOfLine.Coord(3-IndCoord) - FinishCoord) <= 2*Precision::PConfusion()) + break; + + gp_Vec2d aVec(FirstPointOfLine, SecondPointOfLine); + Standard_Real aSqMagnitude = aVec.SquareMagnitude(); + if (aSqMagnitude <= 1.e-32) + break; + aDir.SetCoord(aVec.X(), aVec.Y()); + + gp_Lin2d aLine(FirstPointOfLine, aDir); + IntCurve_IntConicConic Intersector(anIsoLine, Dom1, + aLine, Dom2, + 1.e-10, 1.e-10); + if (Intersector.IsDone() && !Intersector.IsEmpty()) + { + IntRes2d_IntersectionPoint IntPoint = Intersector.Point(1); + FinishPoint = IntPoint.Value(); + } + else + FinishPoint = (theIsUiso)? gp_Pnt2d(FinishCoord, SecondPointOfLine.Y()) : + gp_Pnt2d(SecondPointOfLine.X(), FinishCoord); + + gp_Pnt2d PrevPoint = FirstPointOfLine; + FirstPointOfLine = SecondPointOfLine; + FirstParam = SecondParam; + SecondParam = (FirstParam + FinishParam)/2; + if (Abs(SecondParam - FirstParam) <= 2*Precision::PConfusion()) + break; + gp_Pnt aP3d; + theC3d->D0(SecondParam, aP3d); + SecondPointOfLine = mySurf->NextValueOfUV(FirstPointOfLine, aP3d, + myPreci, Precision::Confusion()); + if (IsPeriodic) + AdjustSecondPointToFirstPoint(FirstPointOfLine, SecondPointOfLine, mySurf->Surface()); + + //Check to be enough close to + //because when a projected point is too close to singularity, + //the non-constant coordinate becomes random. + const Standard_Real aPrevDist = Abs(FirstPointOfLine.Coord(IndCoord) - PrevPoint.Coord(IndCoord)); + const Standard_Real aCurDist = Abs(SecondPointOfLine.Coord(IndCoord) - FirstPointOfLine.Coord(IndCoord)); + if (aCurDist > 2 * aPrevDist) + break; + } + + if (theIsFirstPoint) + thePnt2d(1) = FinishPoint; + else + thePnt2d(NbPnt) = FinishPoint; +} + +//============================================================================================ +//function : InsertAdditionalPointOrAdjust +//purpose : If the current point is too far from the previous point +// (more than half-period of surface), it can happen in two cases: +// 1. Real current step on corresponding coordinate is small, all we need is adjust; +// 2. Current step on corresponding coordinate is really bigger than half-period of +// surface in this parametric direction, so we must add additional point to exclude +// such big intervals between points in 2d space. +//============================================================================================ + +void ShapeConstruct_ProjectCurveOnSurface:: +InsertAdditionalPointOrAdjust(Standard_Boolean& ToAdjust, + const Standard_Integer theIndCoord, + const Standard_Real Period, + const Standard_Real TolOnPeriod, + Standard_Real& CurCoord, + const Standard_Real prevCoord, + const Handle(Geom_Curve)& c3d, + Standard_Integer& theIndex, + TColgp_SequenceOfPnt& points, + TColStd_SequenceOfReal& params, + TColgp_SequenceOfPnt2d& pnt2d) +{ + Standard_Real CorrectedCurCoord = ElCLib::InPeriod(CurCoord, + prevCoord - Period/2, + prevCoord + Period/2); + if (!ToAdjust) + { + Standard_Real CurPar = params(theIndex); + Standard_Real PrevPar = params(theIndex-1); + Standard_Real MidPar = (PrevPar + CurPar)/2; + gp_Pnt MidP3d; + c3d->D0(MidPar, MidP3d); + gp_Pnt2d MidP2d = mySurf->ValueOfUV(MidP3d, myPreci); + Standard_Real MidCoord = MidP2d.Coord(theIndCoord); + MidCoord = ElCLib::InPeriod(MidCoord, prevCoord - Period/2, prevCoord + Period/2); + Standard_Real FirstCoord = prevCoord, LastCoord = CorrectedCurCoord; + if (LastCoord < FirstCoord) + {Standard_Real tmp = FirstCoord; FirstCoord = LastCoord; LastCoord = tmp;} + if (LastCoord - FirstCoord <= TolOnPeriod) + ToAdjust = Standard_True; + else if (FirstCoord <= MidCoord && MidCoord <= LastCoord) + ToAdjust = Standard_True; + else //add mid point + { + //Standard_Real RefU = prevX; + Standard_Boolean Success = Standard_True; + Standard_Real FirstT = PrevPar; //params(i-1) + Standard_Real LastT = CurPar; //params(i) + MidCoord = MidP2d.Coord(theIndCoord); + while (Abs(MidCoord - prevCoord) >= Period/2 - TolOnPeriod || + Abs(CurCoord - MidCoord) >= Period/2 - TolOnPeriod) + { + if (MidPar - FirstT <= Precision::PConfusion() || + LastT - MidPar <= Precision::PConfusion()) + { + Success = Standard_False; + break; //wrong choice + } + if (Abs(MidCoord - prevCoord) >= Period/2 - TolOnPeriod) + LastT = (FirstT + LastT)/2; + else + FirstT = (FirstT + LastT)/2; + MidPar = (FirstT + LastT)/2; + c3d->D0(MidPar, MidP3d); + MidP2d = mySurf->ValueOfUV(MidP3d, myPreci); + MidCoord = MidP2d.Coord(theIndCoord); + } + if (Success) + { + points.InsertBefore(theIndex, MidP3d); + params.InsertBefore(theIndex, MidPar); + pnt2d.InsertBefore(theIndex, MidP2d); + theIndex++; + } + else + ToAdjust = Standard_True; + } //add mid point + } //if (!ToAdjust) + if (ToAdjust) + { + CurCoord = CorrectedCurCoord; + pnt2d(theIndex).SetCoord (theIndCoord, CurCoord); + } +} + //======================================================================= //function : CheckPoints //purpose : @@ -1614,7 +1829,8 @@ Handle(Geom_Curve) ShapeConstruct_ProjectCurveOnSurface::InterpolateCurve3d(cons // will store 0 when the point is to be removed, 1 otherwise TColStd_Array1OfInteger tmpParam(firstElem, lastElem); - for (i = firstElem; i<=lastElem ; i++) tmpParam.SetValue(i,1); + for (i = firstElem; i<=lastElem ; i++) + tmpParam.SetValue(i,1); Standard_Real DistMin2 = RealLast(); gp_Pnt Prev = points->Value (lastValid); gp_Pnt Curr; @@ -1759,8 +1975,8 @@ Handle(Geom_Curve) ShapeConstruct_ProjectCurveOnSurface::InterpolateCurve3d(cons //:p9 abv 11 Mar 99: PRO7226 #489490: find nearest boundary instead of first one Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::IsAnIsoparametric(const Standard_Integer nbrPnt, - const TColgp_Array1OfPnt& points, - const TColStd_Array1OfReal& params, + const TColgp_SequenceOfPnt& points, + const TColStd_SequenceOfReal& params, Standard_Boolean& isoTypeU, Standard_Boolean& p1OnIso, gp_Pnt2d& valueP1, diff --git a/src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.hxx b/src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.hxx index 0fc9b6c859..6f2a46f566 100644 --- a/src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.hxx +++ b/src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.hxx @@ -28,12 +28,12 @@ #include #include #include -#include #include -#include #include -#include #include +#include +#include +#include class ShapeAnalysis_Surface; class Geom_Surface; class Geom_Curve; @@ -107,14 +107,17 @@ public: //! Computes the projection of 3d curve onto a surface using the //! specialized algorithm. Returns False if projector fails, //! otherwise, if pcurve computed successfully, returns True. - //! The continuity, maxdeg and nbinterval are parameters of call - //! to Approx_CurveOnSurface. If nbinterval is equal to -1 - //! (default), this value is computed depending on source 3d curve - //! and surface. The output curve 2D is guaranteed to be same-parameter + //! The output curve 2D is guaranteed to be same-parameter //! with input curve 3D on the interval [First, Last]. If the output curve //! lies on a direct line the infinite line is returned, in the case //! same-parameter condition is satisfied. - Standard_EXPORT virtual Standard_Boolean Perform (Handle(Geom_Curve)& c3d, const Standard_Real First, const Standard_Real Last, Handle(Geom2d_Curve)& c2d, const GeomAbs_Shape continuity = GeomAbs_C1, const Standard_Integer maxdeg = 12, const Standard_Integer nbinterval = -1); + //! TolFirst and TolLast are the tolerances at the ends of input curve 3D. + Standard_EXPORT virtual Standard_Boolean Perform (Handle(Geom_Curve)& c3d, + const Standard_Real First, + const Standard_Real Last, + Handle(Geom2d_Curve)& c2d, + const Standard_Real TolFirst = -1, + const Standard_Real TolLast = -1); //! Computes the projection of 3d curve onto a surface using the //! standard algorithm from ProjLib. Returns False if standard @@ -125,17 +128,14 @@ public: //! to Approx_CurveOnSurface. If nbinterval is equal to -1 //! (default), this value is computed depending on source 3d curve //! and surface. - Standard_EXPORT Standard_Boolean PerformByProjLib (Handle(Geom_Curve)& c3d, const Standard_Real First, const Standard_Real Last, Handle(Geom2d_Curve)& c2d, const GeomAbs_Shape continuity = GeomAbs_C1, const Standard_Integer maxdeg = 12, const Standard_Integer nbinterval = -1); + Standard_EXPORT Standard_Boolean PerformByProjLib (Handle(Geom_Curve)& c3d, + const Standard_Real First, + const Standard_Real Last, + Handle(Geom2d_Curve)& c2d, + const GeomAbs_Shape continuity = GeomAbs_C1, + const Standard_Integer maxdeg = 12, + const Standard_Integer nbinterval = -1); - //! Computes the projection of 3d curve onto a surface using - //! either standard projector (method PerformByProjLib()) or - //! internal one (method Perform()). The selection is done by - //! analyzing the surface and 3d curve and is aimed to filter - //! the cases potentially dangerous for the standard projector. - //! If the standard projector fails, internal one is used. - Standard_EXPORT Standard_Boolean PerformAdvanced (Handle(Geom_Curve)& c3d, const Standard_Real First, const Standard_Real Last, Handle(Geom2d_Curve)& c2d); - - DEFINE_STANDARD_RTTIEXT(ShapeConstruct_ProjectCurveOnSurface,MMgt_TShared) @@ -150,7 +150,12 @@ protected: //! points2d - 2d points lies on line in parametric space //! theTol - tolerance used for compare initial points 3d and //! 3d points obtained from line lying in parameric space of surface - Standard_EXPORT Handle(Geom2d_Curve) getLine (const TColgp_Array1OfPnt& points, const TColStd_Array1OfReal& params, TColgp_Array1OfPnt2d& points2d, const Standard_Real theTol, Standard_Boolean& IsRecompute, Standard_Boolean &isFromCashe) const; + Standard_EXPORT Handle(Geom2d_Curve) getLine (const TColgp_SequenceOfPnt& points, + const TColStd_SequenceOfReal& params, + TColgp_SequenceOfPnt2d& points2d, + const Standard_Real theTol, + Standard_Boolean& IsRecompute, + Standard_Boolean &isFromCashe) const; Handle(ShapeAnalysis_Surface) mySurf; Standard_Real myPreci; @@ -167,9 +172,38 @@ private: Standard_EXPORT Handle(Geom2d_Curve) ProjectAnalytic (const Handle(Geom_Curve)& c3d) const; - Standard_EXPORT Standard_Boolean ApproxPCurve (const Standard_Integer nbrPnt, const TColgp_Array1OfPnt& points, const TColStd_Array1OfReal& params, TColgp_Array1OfPnt2d& points2d, Handle(Geom2d_Curve)& c2d); + Standard_EXPORT Standard_Boolean ApproxPCurve (const Standard_Integer nbrPnt, + const Handle(Geom_Curve)& c3d, + const Standard_Real TolFirst, + const Standard_Real TolLast, + TColgp_SequenceOfPnt& points, + TColStd_SequenceOfReal& params, + TColgp_SequenceOfPnt2d& points2d, + Handle(Geom2d_Curve)& c2d); + + Standard_EXPORT void CorrectExtremity(const Handle(Geom_Curve)& theC3d, + const TColStd_SequenceOfReal& theParams, + TColgp_SequenceOfPnt2d& thePnt2d, + const Standard_Boolean theIsFirstPoint, + const gp_Pnt2d& thePointOnIsoLine, + const Standard_Boolean theIsUiso); - Standard_EXPORT Handle(Geom2d_Curve) InterpolatePCurve (const Standard_Integer nbrPnt, Handle(TColgp_HArray1OfPnt2d)& points2d, Handle(TColStd_HArray1OfReal)& params, const Handle(Geom_Curve)& orig) const; + Standard_EXPORT void InsertAdditionalPointOrAdjust(Standard_Boolean& ToAdjust, + const Standard_Integer theIndCoord, + const Standard_Real Period, + const Standard_Real TolOnPeriod, + Standard_Real& CurCoord, + const Standard_Real prevCoord, + const Handle(Geom_Curve)& c3d, + Standard_Integer& theIndex, + TColgp_SequenceOfPnt& points, + TColStd_SequenceOfReal& params, + TColgp_SequenceOfPnt2d& pnt2d); + + Standard_EXPORT Handle(Geom2d_Curve) InterpolatePCurve (const Standard_Integer nbrPnt, + Handle(TColgp_HArray1OfPnt2d)& points2d, + Handle(TColStd_HArray1OfReal)& params, + const Handle(Geom_Curve)& orig) const; Standard_EXPORT Handle(Geom2d_Curve) ApproximatePCurve (const Standard_Integer nbrPnt, Handle(TColgp_HArray1OfPnt2d)& points2d, Handle(TColStd_HArray1OfReal)& params, const Handle(Geom_Curve)& orig) const; @@ -179,7 +213,19 @@ private: Standard_EXPORT void CheckPoints2d (Handle(TColgp_HArray1OfPnt2d)& points, Handle(TColStd_HArray1OfReal)& params, Standard_Real& preci) const; - Standard_EXPORT Standard_Boolean IsAnIsoparametric (const Standard_Integer nbrPnt, const TColgp_Array1OfPnt& points, const TColStd_Array1OfReal& params, Standard_Boolean& isoTypeU, Standard_Boolean& p1OnIso, gp_Pnt2d& valueP1, Standard_Boolean& p2OnIso, gp_Pnt2d& valueP2, Standard_Boolean& isoPar2d3d, Handle(Geom_Curve)& cIso, Standard_Real& t1, Standard_Real& t2, TColStd_Array1OfReal& pout) const; + Standard_EXPORT Standard_Boolean IsAnIsoparametric (const Standard_Integer nbrPnt, + const TColgp_SequenceOfPnt& points, + const TColStd_SequenceOfReal& params, + Standard_Boolean& isoTypeU, + Standard_Boolean& p1OnIso, + gp_Pnt2d& valueP1, + Standard_Boolean& p2OnIso, + gp_Pnt2d& valueP2, + Standard_Boolean& isoPar2d3d, + Handle(Geom_Curve)& cIso, + Standard_Real& t1, + Standard_Real& t2, + TColStd_Array1OfReal& pout) const; diff --git a/src/ShapeFix/ShapeFix_Edge.cxx b/src/ShapeFix/ShapeFix_Edge.cxx index 830865f82a..34f43ba732 100644 --- a/src/ShapeFix/ShapeFix_Edge.cxx +++ b/src/ShapeFix/ShapeFix_Edge.cxx @@ -489,8 +489,16 @@ Standard_Boolean ShapeFix_Edge::FixAddPCurve (const TopoDS_Edge& edge, Handle(Geom2d_Curve) c2d; Standard_Real a1, b1; if ( ! sae.HasPCurve (edge, surf, location)) { + Standard_Real TolFirst = -1, TolLast = -1; + TopoDS_Vertex V1, V2; + TopExp::Vertices(edge, V1, V2); + if (!V1.IsNull()) + TolFirst = BRep_Tool::Tolerance(V1); + if (!V2.IsNull()) + TolLast = BRep_Tool::Tolerance(V2); + myProjector->Init ( sas, preci ); - myProjector->Perform (c3d,First,Last,c2d); + myProjector->Perform (c3d,First,Last,c2d,TolFirst,TolLast); // stat = 2 : reinterpoler la c3d ? if ( myProjector->Status ( ShapeExtend_DONE4 ) ) myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE2); diff --git a/tests/bugs/modalg_6/bug27079_1 b/tests/bugs/modalg_6/bug27079_1 new file mode 100644 index 0000000000..121b0eb68e --- /dev/null +++ b/tests/bugs/modalg_6/bug27079_1 @@ -0,0 +1,23 @@ +puts "============" +puts "OCC27079" +puts "============" +puts "" +################################################################## +# Bad approximation of intersection curves with variable curvature +################################################################## + +restore [locate_data_file bug27079_s1.draw] s1 +restore [locate_data_file bug27079_s2.draw] s2 + +clpoles s2 + +smallview +donly s2 +fit + +intersect result s1 s2 + +checklength result_1 -l 6.8873540591440428 +checklength result_2 -l 6.8873330997321212 + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug27079_2 b/tests/bugs/modalg_6/bug27079_2 new file mode 100644 index 0000000000..99ea9b7bcd --- /dev/null +++ b/tests/bugs/modalg_6/bug27079_2 @@ -0,0 +1,21 @@ +puts "============" +puts "OCC27079" +puts "============" +puts "" +################################################################## +# Bad approximation of intersection curves with variable curvature +################################################################## + +restore [locate_data_file bug27079_s3.draw] s3 +restore [locate_data_file bug27079_s4.draw] s4 + +smallview +donly s4 +fit + +intersect result s3 s4 + +checklength result_1 -l 4.2844275555620923 +checklength result_2 -l 4.2844275531269931 + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png