1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <Approx_ParametrizationType.hxx>
16 #include Approx_ParLeastSquareOfMyGradient_hxx
17 #include <TColStd_Array1OfReal.hxx>
18 #include <TColgp_Array1OfPnt.hxx>
19 #include <TColgp_Array1OfPnt2d.hxx>
21 #include <gp_Pnt2d.hxx>
23 #include <gp_Vec2d.hxx>
24 #include <TColgp_Array1OfVec.hxx>
25 #include <TColgp_Array1OfVec2d.hxx>
26 #include <AppParCurves_Constraint.hxx>
27 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
28 #include <AppParCurves_MultiPoint.hxx>
29 #include <Precision.hxx>
30 #include <math_IntegerVector.hxx>
31 #include <math_Gauss.hxx>
32 #include <math_Uzawa.hxx>
33 #include <Approx_MCurvesToBSpCurve.hxx>
34 #include <AppParCurves_ConstraintCouple.hxx>
39 static Standard_Boolean mydebug = Standard_False;
41 #include <Geom_BezierCurve.hxx>
42 #include <Geom2d_BezierCurve.hxx>
44 #include <DrawTrSurf.hxx>
46 #include <Draw_Appli.hxx>
49 static void DUMP(const MultiLine& Line)
51 Standard_Integer i, j, nbP2d, nbP3d, firstP, lastP;
55 firstP = LineTool::FirstPoint(Line);
56 lastP = LineTool::LastPoint(Line);
58 nbP3d = LineTool::NbP3d(Line);
59 nbP2d = LineTool::NbP2d(Line);
60 Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
61 if (nbP3d == 0) mynbP3d = 1;
62 if (nbP2d == 0) mynbP2d = 1;
64 TColgp_Array1OfPnt tabP(1, mynbP3d);
65 TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
67 cout <<"DUMP de la MultiLine entre "<<firstP <<" et "<<lastP<<": "<<endl;
68 for (i = firstP; i <= lastP; i++) {
69 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabP, tabP2d);
70 else if (nbP2d != 0) LineTool::Value(Line, i, tabP2d);
71 else if (nbP3d != 0) LineTool::Value(Line, i, tabP);
73 cout << "point "<<i<<":"<< endl;
74 for (j = 1; j <= nbP3d; j++) {
76 cout <<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
78 for (j = 1; j <= nbP2d; j++) {
80 cout <<P12d.X()<<" "<<P12d.Y()<<endl;
86 static void DUMP(const AppParCurves_MultiCurve& C) {
87 static Standard_Integer nbappel = 0;
89 Standard_Integer nbpoles = C.NbPoles();
91 Handle(Geom_BezierCurve) BSp;
92 Handle(Geom2d_BezierCurve) BSp2d;
94 TColgp_Array1OfPnt tabPoles(1, nbpoles);
95 TColgp_Array1OfPnt2d tabPoles2d(1, nbpoles);
99 for (i = 1; i <= C.NbCurves(); i++) {
100 if (C.Dimension(i) == 3) {
101 C.Curve(i, tabPoles);
102 BSp = new Geom_BezierCurve(tabPoles);
103 sprintf(solname, "%s%i%s_%i", "c", i, "3d", nbappel);
105 char* Temp = solname;
106 DrawTrSurf::Set(Temp, BSp);
107 // DrawTrSurf::Set(solname, BSp);
111 C.Curve(i, tabPoles2d);
112 BSp2d = new Geom2d_BezierCurve(tabPoles2d);
113 sprintf(solname, "%s%i%s_%i", "c", i, "2d", nbappel);
115 char* Temp = solname;
116 DrawTrSurf::Set(Temp, BSp2d);
117 // DrawTrSurf::Set(solname, BSp2d);
128 static Standard_Boolean CheckMultiCurve(const AppParCurves_MultiCurve& theMultiCurve,
129 const MultiLine& theLine,
130 const Standard_Integer theIndfirst,
131 const Standard_Integer theIndlast,
132 Standard_Integer& theIndbad)
134 const Standard_Integer nbp3d = LineTool::NbP3d(theLine);
135 const Standard_Integer nbp2d = LineTool::NbP2d(theLine);
137 if (nbp3d > 1) //only simple cases are analysed
138 return Standard_True;
140 const Standard_Real MinScalProd = -0.9;
141 const Standard_Real SqTol3d = Precision::SquareConfusion();
144 Standard_Integer indbads [4];
145 indbads[1] = indbads[2] = indbads[3] = 0;
147 Standard_Integer NbCur = theMultiCurve.NbCurves();
148 Standard_Boolean LoopFound = Standard_False;
150 Standard_Integer aNbP3d = Max(nbp3d, 1);
151 Standard_Integer aNbP2d = Max(nbp2d, 1);
153 TColgp_Array1OfPnt tabP(1, aNbP3d);
154 TColgp_Array1OfPnt2d tabP2d(1, aNbP2d);
157 char* name = new char[100];
158 Standard_Integer nbbc = 1;
159 Standard_Integer indc = 1;
161 if (theMultiCurve.Dimension(1) == 3 /*myNbP3d == 1*/)
163 TColgp_Array1OfPnt aPoles(1, theMultiCurve.NbPoles());
164 theMultiCurve.Curve(1, aPoles);
166 Handle(Geom_Curve) theBezier = new Geom_BezierCurve(aPoles);
167 sprintf(name, "bc3d_%d_%d", indc, nbbc);
168 DrawTrSurf::Set(name, theBezier);
170 gp_Vec FirstVec, SecondVec;
171 Standard_Integer indp = 2;
172 while (indp <= aPoles.Upper())
174 FirstVec = gp_Vec(aPoles(1), aPoles(indp++));
175 Standard_Real aLength = FirstVec.Magnitude();
176 if (aLength > gp::Resolution())
182 gp_Pnt MidPnt = aPoles(indp-1);
183 //for (Standard_Integer k = 3; k <= aPoles.Upper(); k++)
184 while (indp <= aPoles.Upper())
186 SecondVec = gp_Vec(MidPnt, aPoles(indp));
187 Standard_Real aLength = SecondVec.Magnitude();
188 if (aLength <= gp::Resolution())
193 SecondVec /= aLength;
194 Standard_Real ScalProd = FirstVec * SecondVec;
195 if (ScalProd < MinScalProd)
198 cout<<"ScalProd("<<indp-2<<","<<indp-1<<")-("<<indp-1<<","<<indp<<") = "<<ScalProd<<endl;
200 LoopFound = Standard_True;
203 FirstVec = SecondVec;
204 MidPnt = aPoles(indp);
207 //Check: may be it is a real loop
210 for (Standard_Integer FirstInd = theIndfirst;
211 FirstInd <= theIndlast - 2; FirstInd++)
213 LineTool::Value(theLine, FirstInd, tabP);
214 gp_Pnt FirstPnt = tabP(1);
215 for (Standard_Integer k = FirstInd+1; k < theIndlast; k++)
217 LineTool::Value(theLine, k, tabP);
218 gp_Pnt Pnt1 = tabP(1);
219 LineTool::Value(theLine, k+1, tabP);
220 gp_Pnt Pnt2 = tabP(1);
221 if (FirstPnt.SquareDistance(Pnt1) <= SqTol3d ||
222 FirstPnt.SquareDistance(Pnt2) <= SqTol3d)
224 LoopFound = Standard_False;
227 gp_Vec Vec1(FirstPnt, Pnt1);
229 gp_Vec Vec2(FirstPnt, Pnt2);
231 Standard_Real ScalProd = Vec1 * Vec2;
232 if (ScalProd < MinScalProd)
234 LoopFound = Standard_False;
238 if (LoopFound == Standard_False)
245 Standard_Real MaxSqDist = 0.;
246 for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
248 LineTool::Value(theLine, k-1, tabP);
249 gp_Pnt PrevPnt = tabP(1);
250 LineTool::Value(theLine, k, tabP);
251 gp_Pnt CurPnt = tabP(1);
252 Standard_Real aSqDist = PrevPnt.SquareDistance(CurPnt);
253 if (aSqDist > MaxSqDist)
259 for (Standard_Integer indcur = 2; indcur <= NbCur; indcur++)
262 for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
264 LineTool::Value(theLine, k-1, tabP2d);
265 gp_Pnt2d PrevPnt = tabP2d(indcur-1);
266 LineTool::Value(theLine, k, tabP2d);
267 gp_Pnt2d CurPnt = tabP2d(indcur-1);
268 Standard_Real aSqDist = PrevPnt.SquareDistance(CurPnt);
269 if (aSqDist > MaxSqDist)
277 } //if (myNbP3d == 1)
280 TColgp_Array1OfPnt2d aPoles2d(1, theMultiCurve.NbPoles());
281 theMultiCurve.Curve(1, aPoles2d);
283 Handle(Geom2d_Curve) theBezier2d = new Geom2d_BezierCurve(aPoles2d);
284 sprintf(name, "bc2d_%d_%d", indc, nbbc);
285 DrawTrSurf::Set(name, theBezier2d);
287 gp_Vec2d FirstVec, SecondVec;
288 FirstVec = gp_Vec2d(aPoles2d(1), aPoles2d(2));
289 FirstVec.Normalize();
290 gp_Pnt2d MidPnt = aPoles2d(2);
291 for (Standard_Integer k = 3; k <= aPoles2d.Upper(); k++)
293 SecondVec = gp_Vec2d(MidPnt, aPoles2d(k));
294 SecondVec.Normalize();
295 Standard_Real ScalProd = FirstVec * SecondVec;
296 if (ScalProd < MinScalProd)
299 cout<<"ScalProd("<<k-2<<","<<k-1<<")-("<<k-1<<","<<k<<") = "<<ScalProd<<endl;
301 LoopFound = Standard_True;
304 FirstVec = SecondVec;
305 MidPnt = aPoles2d(k);
307 //Check: may be it is a real loop
310 for (Standard_Integer FirstInd = theIndfirst;
311 FirstInd <= theIndlast - 2; FirstInd++)
313 LineTool::Value(theLine, FirstInd, tabP2d);
314 gp_Pnt2d FirstPnt = tabP2d(1);
315 for (Standard_Integer k = FirstInd+1; k < theIndlast; k++)
317 LineTool::Value(theLine, k, tabP2d);
318 gp_Pnt2d Pnt1 = tabP2d(1);
319 LineTool::Value(theLine, k+1, tabP2d);
320 gp_Pnt2d Pnt2 = tabP2d(1);
321 if (FirstPnt.SquareDistance(Pnt1) <= SqTol3d ||
322 FirstPnt.SquareDistance(Pnt2) <= SqTol3d)
324 LoopFound = Standard_False;
327 gp_Vec2d Vec1(FirstPnt, Pnt1);
329 gp_Vec2d Vec2(FirstPnt, Pnt2);
331 Standard_Real ScalProd = Vec1 * Vec2;
332 if (ScalProd < MinScalProd)
334 LoopFound = Standard_False;
338 if (LoopFound == Standard_False)
345 for (Standard_Integer indcur = 1; indcur <= NbCur; indcur++)
347 Standard_Real MaxSqDist = 0.;
348 for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
350 LineTool::Value(theLine, k-1, tabP2d);
351 gp_Pnt2d PrevPnt = tabP2d(indcur);
352 LineTool::Value(theLine, k, tabP2d);
353 gp_Pnt2d CurPnt = tabP2d(indcur);
354 Standard_Real aSqDist = PrevPnt.SquareDistance(CurPnt);
355 if (aSqDist > MaxSqDist)
366 if (indbads[1] != 0 && indbads[2] != 0)
368 if (indbads[1] != indbads[2])
369 LoopFound = Standard_False;
370 else if (indbads[3] != 0 && indbads[1] != indbads[3])
371 LoopFound = Standard_False;
374 theIndbad = indbads[1];
379 void Approx_ComputeLine::FirstTangencyVector(const MultiLine& Line,
380 const Standard_Integer index,
381 math_Vector& V) const
384 Standard_Integer i, j, nbP2d, nbP3d;
385 nbP3d = LineTool::NbP3d(Line);
386 nbP2d = LineTool::NbP2d(Line);
387 Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
388 if (nbP3d == 0) mynbP3d = 1;
389 if (nbP2d == 0) mynbP2d = 1;
390 Standard_Boolean Ok=Standard_False;
391 TColgp_Array1OfVec TabV(1, mynbP3d);
392 TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
394 if (nbP3d != 0 && nbP2d != 0)
395 Ok = LineTool::Tangency(Line, index, TabV, TabV2d);
397 Ok = LineTool::Tangency(Line, index, TabV2d);
399 Ok = LineTool::Tangency(Line, index, TabV);
404 for (i = TabV.Lower(); i <= TabV.Upper(); i++) {
406 V(j+1) = TabV(i).Y();
407 V(j+2) = TabV(i).Z();
413 for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) {
414 V(j) = TabV2d(i).X();
415 V(j+1) = TabV2d(i).Y();
422 // recherche d un vecteur tangent par construction d une parabole:
423 AppParCurves_Constraint firstC, lastC;
424 firstC = lastC = AppParCurves_PassPoint;
425 Standard_Integer nbpoles = 3;
426 math_Vector mypar(index, index+2);
427 Parameters(Line, index, index+2, mypar);
428 Approx_ParLeastSquareOfMyGradient
429 LSQ(Line, index, index+2, firstC, lastC, mypar, nbpoles);
430 AppParCurves_MultiCurve C = LSQ.BezierValue();
437 for (i = 1; i <= nbP3d; i++) {
438 C.D1(i, 0.0, myP, myV);
445 for (i = nbP3d+1; i <= nbP3d+nbP2d; i++) {
446 C.D1(i, 0.0, myP2d, myV2d);
455 void Approx_ComputeLine::LastTangencyVector(const MultiLine& Line,
456 const Standard_Integer index,
457 math_Vector& V) const
459 Standard_Integer i, j, nbP2d, nbP3d;
460 nbP3d = LineTool::NbP3d(Line);
461 nbP2d = LineTool::NbP2d(Line);
462 Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
463 if (nbP3d == 0) mynbP3d = 1;
464 if (nbP2d == 0) mynbP2d = 1;
465 Standard_Boolean Ok=Standard_False;
466 TColgp_Array1OfVec TabV(1, mynbP3d);
467 TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
470 if (nbP3d != 0 && nbP2d != 0)
471 Ok = LineTool::Tangency(Line, index, TabV, TabV2d);
473 Ok = LineTool::Tangency(Line, index, TabV2d);
475 Ok = LineTool::Tangency(Line, index, TabV);
480 for (i = TabV.Lower(); i <= TabV.Upper(); i++) {
482 V(j+1) = TabV(i).Y();
483 V(j+2) = TabV(i).Z();
489 for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) {
490 V(j) = TabV2d(i).X();
491 V(j+1) = TabV2d(i).Y();
498 // recherche d un vecteur tangent par construction d une parabole:
499 AppParCurves_Constraint firstC, lastC;
500 firstC = lastC = AppParCurves_PassPoint;
501 Standard_Integer nbpoles = 3;
502 math_Vector mypar(index-2, index);
503 Parameters(Line, index-2, index, mypar);
504 Approx_ParLeastSquareOfMyGradient
505 LSQ(Line, index-2, index, firstC, lastC, mypar, nbpoles);
506 AppParCurves_MultiCurve C = LSQ.BezierValue();
513 for (i = 1; i <= nbP3d; i++) {
514 C.D1(i, 1.0, myP, myV);
521 for (i = nbP3d+1; i <= nbP3d+nbP2d; i++) {
522 C.D1(i, 1.0, myP2d, myV2d);
533 Standard_Real Approx_ComputeLine::
534 SearchFirstLambda(const MultiLine& Line,
535 const math_Vector& TheParam,
536 const math_Vector& V,
537 const Standard_Integer index) const
540 // dq/dw = lambda* V = (p2-p1)/(u2-u1)
542 Standard_Integer nbP2d, nbP3d;
545 nbP3d = LineTool::NbP3d(Line);
546 nbP2d = LineTool::NbP2d(Line);
547 Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
548 if (nbP3d == 0) mynbP3d = 1;
549 if (nbP2d == 0) mynbP2d = 1;
550 TColgp_Array1OfPnt tabP1(1, mynbP3d), tabP2(1, mynbP3d);
551 TColgp_Array1OfPnt2d tabP12d(1, mynbP2d), tabP22d(1, mynbP2d);
554 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP1, tabP12d);
555 else if (nbP2d != 0) LineTool::Value(Line, index, tabP12d);
556 else if (nbP3d != 0) LineTool::Value(Line, index, tabP1);
558 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index+1, tabP2, tabP22d);
559 else if (nbP2d != 0) LineTool::Value(Line, index+1, tabP22d);
560 else if (nbP3d != 0) LineTool::Value(Line, index+1, tabP2);
563 Standard_Real U1 = TheParam(index), U2 = TheParam(index+1);
564 Standard_Real lambda, S;
565 Standard_Integer low = V.Lower();
570 gp_Vec P1P2(P1, P2), myV;
571 myV.SetCoord(V(low), V(low+1), V(low+2));
572 lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
573 S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
578 gp_Vec2d P1P2(P12d, P22d), myV;
579 myV.SetCoord(V(low), V(low+1));
580 lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
581 S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
588 Standard_Real Approx_ComputeLine::
589 SearchLastLambda(const MultiLine& Line,
590 const math_Vector& TheParam,
591 const math_Vector& V,
592 const Standard_Integer index) const
594 // dq/dw = lambda* V = (p2-p1)/(u2-u1)
596 Standard_Integer nbP2d, nbP3d;
599 nbP3d = LineTool::NbP3d(Line);
600 nbP2d = LineTool::NbP2d(Line);
601 Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
602 if (nbP3d == 0) mynbP3d = 1;
603 if (nbP2d == 0) mynbP2d = 1;
604 TColgp_Array1OfPnt tabP(1, mynbP3d), tabP2(1, mynbP3d);
605 TColgp_Array1OfPnt2d tabP2d(1, mynbP2d), tabP22d(1, mynbP2d);
607 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index-1, tabP, tabP2d);
608 else if (nbP2d != 0) LineTool::Value(Line, index-1, tabP2d);
609 else if (nbP3d != 0) LineTool::Value(Line, index-1, tabP);
611 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP2, tabP22d);
612 else if (nbP2d != 0) LineTool::Value(Line, index, tabP22d);
613 else if (nbP3d != 0) LineTool::Value(Line, index, tabP2);
616 Standard_Real U1 = TheParam(index-1), U2 = TheParam(index);
617 Standard_Real lambda, S;
618 Standard_Integer low = V.Lower();
623 gp_Vec P1P2(P1, P2), myV;
624 myV.SetCoord(V(low), V(low+1), V(low+2));
625 lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
626 S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
631 gp_Vec2d P1P2(P12d, P22d), myV;
632 myV.SetCoord(V(low), V(low+1));
633 lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
634 S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
642 Approx_ComputeLine::Approx_ComputeLine
643 (const MultiLine& Line,
644 const math_Vector& Parameters,
645 const Standard_Integer degreemin,
646 const Standard_Integer degreemax,
647 const Standard_Real Tolerance3d,
648 const Standard_Real Tolerance2d,
649 const Standard_Integer NbIterations,
650 const Standard_Boolean cutting,
651 const Standard_Boolean Squares)
653 myNbPlusOnePoint (0),
654 myIsClear (Standard_False)
656 myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(),
658 for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) {
659 myfirstParam->SetValue(i, Parameters(i));
661 myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
662 Par = Approx_IsoParametric;
663 mydegremin = degreemin;
664 mydegremax = degreemax;
665 mytol3d = Tolerance3d;
666 mytol2d = Tolerance2d;
669 myitermax = NbIterations;
670 alldone = Standard_False;
671 myfirstC = AppParCurves_TangencyPoint;
672 mylastC = AppParCurves_TangencyPoint;
677 Approx_ComputeLine::Approx_ComputeLine
678 (const math_Vector& Parameters,
679 const Standard_Integer degreemin,
680 const Standard_Integer degreemax,
681 const Standard_Real Tolerance3d,
682 const Standard_Real Tolerance2d,
683 const Standard_Integer NbIterations,
684 const Standard_Boolean cutting,
685 const Standard_Boolean Squares)
687 myNbPlusOnePoint (0),
688 myIsClear (Standard_False)
690 myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(),
692 for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) {
693 myfirstParam->SetValue(i, Parameters(i));
695 myfirstC = AppParCurves_TangencyPoint;
696 mylastC = AppParCurves_TangencyPoint;
697 myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
698 Par = Approx_IsoParametric;
699 mydegremin = degreemin;
700 mydegremax = degreemax;
701 mytol3d = Tolerance3d;
702 mytol2d = Tolerance2d;
705 myitermax = NbIterations;
706 alldone = Standard_False;
709 Approx_ComputeLine::Approx_ComputeLine
710 (const Standard_Integer degreemin,
711 const Standard_Integer degreemax,
712 const Standard_Real Tolerance3d,
713 const Standard_Real Tolerance2d,
714 const Standard_Integer NbIterations,
715 const Standard_Boolean cutting,
716 const Approx_ParametrizationType parametrization,
717 const Standard_Boolean Squares)
719 myNbPlusOnePoint (0),
720 myIsClear (Standard_False)
722 myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
723 Par = parametrization;
724 mydegremin = degreemin;
725 mydegremax = degreemax;
726 mytol3d = Tolerance3d;
727 mytol2d = Tolerance2d;
730 myitermax = NbIterations;
731 myfirstC = AppParCurves_TangencyPoint;
732 mylastC = AppParCurves_TangencyPoint;
733 alldone = Standard_False;
737 Approx_ComputeLine::Approx_ComputeLine
738 (const MultiLine& Line,
739 const Standard_Integer degreemin,
740 const Standard_Integer degreemax,
741 const Standard_Real Tolerance3d,
742 const Standard_Real Tolerance2d,
743 const Standard_Integer NbIterations,
744 const Standard_Boolean cutting,
745 const Approx_ParametrizationType parametrization,
746 const Standard_Boolean Squares)
748 myNbPlusOnePoint (0),
749 myIsClear (Standard_False)
751 myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
752 alldone = Standard_False;
753 mydegremin = degreemin;
754 mydegremax = degreemax;
755 mytol3d = Tolerance3d;
756 mytol2d = Tolerance2d;
759 myitermax = NbIterations;
760 Par = parametrization;
761 myfirstC = AppParCurves_TangencyPoint;
762 mylastC = AppParCurves_TangencyPoint;
769 void Approx_ComputeLine::Perform(const MultiLine& Line)
772 if (mydebug) DUMP(Line);
776 myMultiCurves.Clear();
781 //myNbPlusOnePoint = 0;
783 else myIsClear = Standard_False;
785 Standard_Integer i, nbp, Thefirstpt, Thelastpt, oldlastpt;
786 Standard_Boolean Finish = Standard_False,
787 begin = Standard_True, Ok = Standard_False,
788 GoUp = Standard_False, Interpol;
789 Standard_Real thetol3d, thetol2d;
790 Approx_Status MyStatus;
791 // gp_Vec V13d, V23d;
793 Thefirstpt = LineTool::FirstPoint(Line);
794 Thelastpt = LineTool::LastPoint(Line);
795 Standard_Integer myfirstpt = Thefirstpt;
796 Standard_Integer mylastpt = Thelastpt;
798 AppParCurves_ConstraintCouple myCouple1(myfirstpt, myfirstC);
799 AppParCurves_ConstraintCouple myCouple2(mylastpt, mylastC);
800 myConstraints->SetValue(1, myCouple1);
801 myConstraints->SetValue(2, myCouple2);
803 math_Vector TheParam(Thefirstpt, Thelastpt);
807 if(myfirstParam.IsNull()) {
808 Parameters(Line, Thefirstpt, Thelastpt, TheParam);
811 for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) {
812 TheParam(i+Thefirstpt-1) = myfirstParam->Value(i);
815 TheMultiCurve = AppParCurves_MultiCurve();
816 MultiLine anOtherLine0;
817 Standard_Boolean isOtherLine0Made = Standard_False;
818 Standard_Integer indbad = 0;
819 alldone = Compute(Line, myfirstpt, mylastpt, TheParam, thetol3d, thetol2d, indbad);
822 isOtherLine0Made = LineTool::MakeMLOneMorePoint(Line, myfirstpt, mylastpt, indbad, anOtherLine0);
824 if (isOtherLine0Made)
826 myIsClear = Standard_True;
829 Perform(anOtherLine0);
830 alldone = Standard_True;
832 if(!alldone && TheMultiCurve.NbCurves() > 0) {
834 if (mydebug) DUMP(TheMultiCurve);
836 myMultiCurves.Append(TheMultiCurve);
837 Tolers3d.Append(currenttol3d);
838 Tolers2d.Append(currenttol2d);
839 Standard_Integer mylen = mylastpt-myfirstpt+1;
840 Standard_Integer myParLen = myParameters->Length();
841 Standard_Integer aLen = (myParLen > mylen)? myParLen : mylen;
842 Handle(TColStd_HArray1OfReal) ThePar =
843 new TColStd_HArray1OfReal(myfirstpt, myfirstpt+aLen-1);
844 for (i = 0; i < aLen; i++)
845 ThePar->SetValue(myfirstpt+i, myParameters->Value(myParameters->Lower()+i));
846 myPar.Append(ThePar);
851 oldlastpt = mylastpt;
852 // Gestion du decoupage de la multiline pour approximer:
856 // Calcul de la partie a approximer.
857 myfirstpt = mylastpt;
858 mylastpt = Thelastpt;
859 if (myfirstpt == Thelastpt) {
860 Finish = Standard_True;
861 alldone = Standard_True;
866 nbp = mylastpt - myfirstpt + 1;
867 MyStatus = LineTool::WhatStatus(Line, myfirstpt, mylastpt);
868 if (MyStatus == Approx_NoPointsAdded && nbp <= mydegremax+1) {
869 Interpol = ComputeCurve(Line, myfirstpt, mylastpt);
871 if (mylastpt == Thelastpt) {
872 Finish = Standard_True;
873 alldone = Standard_True;
878 mylastpt = Standard_Integer((myfirstpt + mylastpt)/2);
881 GoUp = Standard_False;
884 // Verification du nombre de points restants par rapport au degre
886 // ==============================================================
887 nbp = mylastpt - myfirstpt + 1;
888 MyStatus = LineTool::WhatStatus(Line, myfirstpt, mylastpt);
889 if (nbp <= mydegremax+5 ) {
890 // Rajout necessaire de points si possible.
891 // ========================================
892 GoUp = Standard_False;
894 if (MyStatus == Approx_PointsAdded) {
895 // Appel recursif du decoupage:
896 GoUp = Standard_True;
898 MultiLine anOtherLine1 = LineTool::MakeMLBetween(Line, myfirstpt, mylastpt, nbp-1);
900 Standard_Integer nbpdsotherligne = LineTool::FirstPoint (anOtherLine1) - LineTool::LastPoint (anOtherLine1);
902 //-- Si MakeML a echoue on retourne une ligne vide
903 if ((nbpdsotherligne == 0) || myMultiLineNb >= 3)
905 //-- cout<<" ** ApproxComputeLine MakeML Echec ** LBR lbr "<<endl;
906 if (myfirstpt == mylastpt) break; // Pour etre sur de ne pas
907 // planter la station !!
908 myCouple1.SetIndex(myfirstpt);
909 myCouple2.SetIndex(mylastpt);
910 myConstraints->SetValue(1, myCouple1);
911 myConstraints->SetValue(2, myCouple2);
913 math_Vector Param(myfirstpt, mylastpt);
914 Approx_ParametrizationType SavePar = Par;
915 Par = Approx_IsoParametric;
916 Parameters(Line, myfirstpt, mylastpt, Param);
917 TheMultiCurve = AppParCurves_MultiCurve();
918 MultiLine anOtherLine2;
919 Standard_Boolean isOtherLine2Made = Standard_False;
920 Standard_Integer indbad = 0;
921 Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d, indbad);
924 isOtherLine2Made = LineTool::MakeMLOneMorePoint(Line, myfirstpt, mylastpt, indbad, anOtherLine2);
926 if (isOtherLine2Made)
928 myIsClear = Standard_True;
932 Perform(anOtherLine2);
937 Standard_Real tt3d = currenttol3d, tt2d = currenttol2d;
938 Handle(TColStd_HArray1OfReal) saveParameters = myParameters;
939 AppParCurves_MultiCurve saveMultiCurve = TheMultiCurve;
941 if(SavePar != Approx_IsoParametric)
944 Par = Approx_ChordLength;
946 Parameters(Line, myfirstpt, mylastpt, Param);
947 isOtherLine2Made = Standard_False;
949 Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d, indbad);
952 isOtherLine2Made = LineTool::MakeMLOneMorePoint (Line, myfirstpt, mylastpt, indbad, anOtherLine2);
954 if (isOtherLine2Made)
956 myIsClear = Standard_True;
959 Perform (anOtherLine2);
963 if (!Ok && tt3d <= currenttol3d && tt2d <= currenttol2d) {
964 currenttol3d = tt3d; currenttol2d = tt2d;
965 myParameters = saveParameters;
966 TheMultiCurve = saveMultiCurve;
970 if (myfirstpt == Thelastpt)
972 Finish = Standard_True;
973 alldone = Standard_True;
977 oldlastpt = mylastpt;
979 tolreached = Standard_False;
980 if (TheMultiCurve.NbCurves() == 0) {
981 myMultiCurves.Clear();
985 if (mydebug) DUMP(TheMultiCurve);
987 MultiLine anOtherLine3;
988 Standard_Boolean isOtherLine3Made = Standard_False;
989 Standard_Integer indbad2 = 0;
990 if (!CheckMultiCurve(TheMultiCurve, Line,
994 isOtherLine3Made = LineTool::MakeMLOneMorePoint (Line, myfirstpt, mylastpt, indbad2, anOtherLine3);
996 if (isOtherLine3Made)
998 myIsClear = Standard_True;
1001 Perform(anOtherLine3);
1002 myfirstpt = mylastpt;
1003 mylastpt = Thelastpt;
1007 myMultiCurves.Append(TheMultiCurve);
1008 Tolers3d.Append(currenttol3d);
1009 Tolers2d.Append(currenttol2d);
1010 Standard_Integer mylen = oldlastpt-myfirstpt+1;
1011 Standard_Integer myParLen = myParameters->Length();
1012 Standard_Integer aLen = (myParLen > mylen)? myParLen : mylen;
1013 Handle(TColStd_HArray1OfReal) ThePar =
1014 new TColStd_HArray1OfReal(myfirstpt, myfirstpt+aLen-1);
1015 for (i = 0; i < aLen; i++)
1016 ThePar->SetValue(myfirstpt+i, myParameters->Value(myParameters->Lower()+i));
1017 myPar.Append(ThePar);
1020 myfirstpt = oldlastpt;
1021 mylastpt = Thelastpt;
1026 myIsClear = Standard_True;
1028 Perform(anOtherLine1);
1029 myfirstpt = mylastpt;
1030 mylastpt = Thelastpt;
1034 if (MyStatus == Approx_NoPointsAdded && !begin) {
1035 // On rend la meilleure approximation obtenue precedemment.
1036 // ========================================================
1037 GoUp = Standard_True;
1038 tolreached = Standard_False;
1039 if (TheMultiCurve.NbCurves() == 0) {
1040 myMultiCurves.Clear();
1044 if (mydebug) DUMP(TheMultiCurve);
1046 myMultiCurves.Append(TheMultiCurve);
1047 Tolers3d.Append(currenttol3d);
1048 Tolers2d.Append(currenttol2d);
1049 Standard_Integer mylen = oldlastpt-myfirstpt+1;
1050 Standard_Integer myParLen = myParameters->Length();
1051 Standard_Integer aLen = (myParLen > mylen)? myParLen : mylen;
1052 Handle(TColStd_HArray1OfReal) ThePar =
1053 new TColStd_HArray1OfReal(myfirstpt, myfirstpt+aLen-1);
1054 for (i = 0; i < aLen; i++)
1055 ThePar->SetValue(myfirstpt+i, myParameters->Value(myParameters->Lower()+i));
1056 myPar.Append(ThePar);
1058 myfirstpt = oldlastpt;
1059 mylastpt = Thelastpt;
1062 else if (MyStatus == Approx_NoApproximation) {
1063 // On ne fait pas d approximation entre myfirstpt et mylastpt.
1064 // ===========================================================
1065 // On stocke pour pouvoir en informer l utilisateur.
1066 GoUp = Standard_True;
1067 myfirstpt = mylastpt;
1068 mylastpt = Thelastpt;
1072 if (myfirstpt == Thelastpt) {
1073 Finish = Standard_True;
1074 alldone = Standard_True;
1078 if (myfirstpt == mylastpt) break; // Pour etre sur de ne pas
1079 // planter la station !!
1080 myCouple1.SetIndex(myfirstpt);
1081 myCouple2.SetIndex(mylastpt);
1082 myConstraints->SetValue(1, myCouple1);
1083 myConstraints->SetValue(2, myCouple2);
1085 // Calcul des parametres sur ce nouvel intervalle.
1086 // On recupere les parametres initiaux lors du decoupage.
1088 math_Vector Param(myfirstpt, mylastpt);
1090 if(myfirstParam.IsNull()) {
1091 Parameters(Line, myfirstpt, mylastpt, Param);
1094 for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) {
1095 Param(i) = myfirstParam->Value(i);
1097 myfirstParam.Nullify();
1100 begin = Standard_False;
1103 Standard_Real pfirst = TheParam.Value(myfirstpt);
1104 Standard_Real plast = TheParam.Value(mylastpt);
1105 for (i = myfirstpt; i <= mylastpt; i++) {
1106 Param(i) = (TheParam.Value(i)-pfirst)/(plast-pfirst);
1110 TheMultiCurve = AppParCurves_MultiCurve();
1111 MultiLine anOtherLine4;
1112 Standard_Boolean isOtherLine4Made = Standard_False;
1113 Standard_Integer indbad = 0;
1114 Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d, indbad);
1117 isOtherLine4Made = LineTool::MakeMLOneMorePoint (Line, myfirstpt, mylastpt, indbad, anOtherLine4);
1119 if (isOtherLine4Made)
1121 myIsClear = Standard_True;
1124 Perform (anOtherLine4);
1127 if (myfirstpt == Thelastpt)
1129 Finish = Standard_True;
1130 alldone = Standard_True;
1140 const TColStd_Array1OfReal& Approx_ComputeLine::Parameters(const Standard_Integer Index) const
1142 return (myPar.Value(Index))->Array1();
1146 Standard_Integer Approx_ComputeLine::NbMultiCurves()const
1148 return myMultiCurves.Length();
1151 AppParCurves_MultiCurve& Approx_ComputeLine::ChangeValue(const Standard_Integer Index)
1153 return myMultiCurves.ChangeValue(Index);
1157 const AppParCurves_MultiCurve& Approx_ComputeLine::Value(const Standard_Integer Index)
1160 return myMultiCurves.Value(Index);
1164 const AppParCurves_MultiBSpCurve& Approx_ComputeLine::SplineValue()
1166 Approx_MCurvesToBSpCurve Trans;
1167 Trans.Perform(myMultiCurves);
1168 myspline = Trans.Value();
1176 void Approx_ComputeLine::Parameters(const MultiLine& Line,
1177 const Standard_Integer firstP,
1178 const Standard_Integer lastP,
1179 math_Vector& TheParameters) const
1181 Standard_Integer i, j, nbP2d, nbP3d;
1184 gp_Pnt2d P12d, P22d;
1186 if (Par == Approx_ChordLength || Par == Approx_Centripetal) {
1187 nbP3d = LineTool::NbP3d(Line);
1188 nbP2d = LineTool::NbP2d(Line);
1189 Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
1190 if (nbP3d == 0) mynbP3d = 1;
1191 if (nbP2d == 0) mynbP2d = 1;
1193 TheParameters(firstP) = 0.0;
1195 TColgp_Array1OfPnt tabP(1, mynbP3d);
1196 TColgp_Array1OfPnt tabPP(1, mynbP3d);
1197 TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
1198 TColgp_Array1OfPnt2d tabPP2d(1, mynbP2d);
1200 for (i = firstP+1; i <= lastP; i++) {
1201 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i-1, tabP, tabP2d);
1202 else if (nbP2d != 0) LineTool::Value(Line, i-1, tabP2d);
1203 else if (nbP3d != 0) LineTool::Value(Line, i-1, tabP);
1205 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabPP, tabPP2d);
1206 else if (nbP2d != 0) LineTool::Value(Line, i, tabPP2d);
1207 else if (nbP3d != 0) LineTool::Value(Line, i, tabPP);
1209 for (j = 1; j <= nbP3d; j++) {
1212 dist += P2.Distance(P1);
1214 for (j = 1; j <= nbP2d; j++) {
1217 dist += P22d.Distance(P12d);
1219 if(Par == Approx_ChordLength)
1220 TheParameters(i) = TheParameters(i-1) + dist;
1221 else {// Par == Approx_Centripetal
1222 TheParameters(i) = TheParameters(i-1) + Sqrt(dist);
1225 for (i = firstP; i <= lastP; i++) TheParameters(i) /= TheParameters(lastP);
1228 for (i = firstP; i <= lastP; i++) {
1229 TheParameters(i) = (Standard_Real(i)-firstP)/
1230 (Standard_Real(lastP)-Standard_Real(firstP));
1236 Standard_Boolean Approx_ComputeLine::Compute(const MultiLine& Line,
1237 const Standard_Integer fpt,
1238 const Standard_Integer lpt,
1240 Standard_Real& TheTol3d,
1241 Standard_Real& TheTol2d,
1242 Standard_Integer& indbad)
1245 Standard_Integer deg, i;
1246 Standard_Boolean mydone;
1248 Standard_Integer nbp = lpt-fpt+1;
1250 math_Vector ParSav(Para.Lower(), Para.Upper());
1251 for (i = Para.Lower(); i <= Para.Upper(); i++) {
1252 ParSav(i) = Para(i);
1254 Standard_Integer Mdegmax = mydegremax;
1255 if(nbp < Mdegmax+5 && mycut) {
1258 if(Mdegmax < mydegremin) {
1259 Mdegmax = mydegremin;
1262 currenttol3d = currenttol2d = RealLast();
1263 for (deg = Min(nbp-1,mydegremin); deg <= Mdegmax; deg++) {
1264 AppParCurves_MultiCurve mySCU(deg+1);
1266 Approx_ParLeastSquareOfMyGradient SQ(Line, fpt, lpt,
1267 myfirstC, mylastC, Para, deg+1);
1268 mydone = SQ.IsDone();
1269 mySCU = SQ.BezierValue();
1270 SQ.Error(Fv, TheTol3d, TheTol2d);
1273 Approx_MyGradient GRAD(Line, fpt, lpt, myConstraints,
1274 Para, deg, mytol3d, mytol2d, myitermax);
1275 mydone = GRAD.IsDone();
1276 mySCU = GRAD.Value();
1277 if (mySCU.NbCurves() == 0)
1279 TheTol3d = GRAD.MaxError3d();
1280 TheTol2d = GRAD.MaxError2d();
1282 Standard_Real uu1 = Para(Para.Lower()), uu2;
1283 Standard_Boolean restau = Standard_False;
1284 for ( i = Para.Lower()+1; i <= Para.Upper(); i++) {
1287 restau = Standard_True;
1288 // cout << "restau = Standard_True" << endl;
1294 for (i = Para.Lower(); i <= Para.Upper(); i++) {
1295 Para(i) = ParSav(i);
1299 if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
1300 // Stockage de la multicurve approximee.
1301 tolreached = Standard_True;
1303 if (mydebug) DUMP(mySCU);
1305 if (myNbPlusOnePoint != 0 &&
1306 !CheckMultiCurve(mySCU, Line,
1310 return Standard_False;
1314 myMultiCurves.Append(mySCU);
1315 // Stockage des parametres de la partie de MultiLine approximee:
1316 // A ameliorer !! (bq trop de recopies)
1317 Handle(TColStd_HArray1OfReal) ThePar =
1318 new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
1319 for (i = Para.Lower(); i <= Para.Upper(); i++) {
1320 ThePar->SetValue(i, Para(i));
1322 myPar.Append(ThePar);
1323 Tolers3d.Append(TheTol3d);
1324 Tolers2d.Append(TheTol2d);
1325 return Standard_True;
1330 if (TheTol3d <= currenttol3d && TheTol2d <= currenttol2d) {
1331 TheMultiCurve = mySCU;
1332 currenttol3d = TheTol3d;
1333 currenttol2d = TheTol2d;
1334 myParameters = new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
1335 for (i = Para.Lower(); i <= Para.Upper(); i++) {
1336 myParameters->SetValue(i, Para(i));
1342 return Standard_False;
1348 Standard_Boolean Approx_ComputeLine::ComputeCurve(const MultiLine& Line,
1349 const Standard_Integer firstpt,
1350 const Standard_Integer lastpt)
1352 Standard_Integer i, j, nbP3d, nbP2d, deg;
1354 gp_Vec2d V12d, V22d;
1356 gp_Pnt2d P12d, P22d;
1357 Standard_Boolean Tangent1, Tangent2, mydone= Standard_False;
1359 Standard_Boolean Parallel;
1361 Standard_Integer myfirstpt = firstpt, mylastpt = lastpt;
1362 Standard_Integer nbp = lastpt-firstpt+1, Kopt = 0;
1363 math_Vector Para(firstpt, lastpt);
1365 Parameters(Line, firstpt, lastpt, Para);
1367 nbP3d = LineTool::NbP3d(Line);
1368 nbP2d = LineTool::NbP2d(Line);
1369 Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
1370 if (nbP3d == 0) mynbP3d = 1 ;
1371 if (nbP2d == 0) mynbP2d = 1 ;
1374 TColgp_Array1OfVec tabV1(1, mynbP3d), tabV2(1, mynbP3d);
1375 TColgp_Array1OfPnt tabP1(1, mynbP3d), tabP2(1, mynbP3d), tabP(1, mynbP3d);
1376 TColgp_Array1OfVec2d tabV12d(1, mynbP2d), tabV22d(1, mynbP2d);
1377 TColgp_Array1OfPnt2d tabP12d(1, mynbP2d), tabP22d(1, mynbP2d), tabP2d(1, mynbP2d);
1379 if (nbP3d != 0 && nbP2d != 0) {
1380 LineTool::Value(Line, myfirstpt,tabP1,tabP12d);
1381 LineTool::Value(Line, mylastpt,tabP2,tabP22d);
1382 Tangent1 = LineTool::Tangency(Line, myfirstpt,tabV1,tabV12d);
1383 Tangent2 = LineTool::Tangency(Line, mylastpt,tabV2,tabV22d);
1385 else if (nbP2d != 0) {
1386 LineTool::Value(Line, myfirstpt,tabP12d);
1387 LineTool::Value(Line, mylastpt,tabP22d);
1388 Tangent1 = LineTool::Tangency(Line, myfirstpt, tabV12d);
1389 Tangent2 = LineTool::Tangency(Line, mylastpt, tabV22d);
1392 LineTool::Value(Line, myfirstpt,tabP1);
1393 LineTool::Value(Line, mylastpt,tabP2);
1394 Tangent1 = LineTool::Tangency(Line, myfirstpt, tabV1);
1395 Tangent2 = LineTool::Tangency(Line, mylastpt, tabV2);
1398 if (Tangent1) Kopt++;
1399 if (Tangent2) Kopt++;
1403 // S il n y a que 2 points, on verifie quand meme que les tangentes sont
1406 Parallel = Standard_True;
1409 for (i = 1; i <= nbP3d; i++) {
1410 gp_Vec PVec(tabP1(i), tabP2(i));
1412 if (!PVec.IsParallel(V13d, Precision::Angular())) {
1414 Parallel = Standard_False;
1419 for (i = 1; i <= nbP2d; i++) {
1420 gp_Vec2d PVec2d(tabP12d(i), tabP22d(i));
1422 if (!PVec2d.IsParallel(V12d, Precision::Angular())) {
1424 Parallel = Standard_False;
1432 for (i = 1; i <= nbP3d; i++) {
1433 gp_Vec PVec(tabP1(i), tabP2(i));
1435 if (!PVec.IsParallel(V23d, Precision::Angular())) {
1437 Parallel = Standard_False;
1442 for (i = 1; i <= nbP2d; i++) {
1443 gp_Vec2d PVec2d(tabP12d(i), tabP22d(i));
1445 if (!PVec2d.IsParallel(V22d, Precision::Angular())) {
1447 Parallel = Standard_False;
1456 if (mydebug) cout <<"droite mais tangentes pas vraiment paralleles!!"<< endl;
1459 AppParCurves_MultiCurve mySCU(mydegremin+1);
1460 if (nbP3d != 0 && nbP2d != 0) {
1461 AppParCurves_MultiPoint MPole1(tabP1, tabP12d);
1462 AppParCurves_MultiPoint MPole2(tabP2, tabP22d);
1463 mySCU.SetValue(1, MPole1);
1464 mySCU.SetValue(mydegremin+1, MPole2);
1465 for (i = 2; i <= mydegremin; i++) {
1466 for (j = 1; j<= nbP3d; j++) {
1469 tabP(j).SetXYZ(P1.XYZ()+(i-1)*(P2.XYZ()-P1.XYZ())/mydegremin);
1471 for (j = 1; j<= nbP2d; j++) {
1474 tabP2d(j).SetXY(P12d.XY()+(i-1)*(P22d.XY()-P12d.XY())/mydegremin);
1476 AppParCurves_MultiPoint MPole(tabP, tabP2d);
1477 mySCU.SetValue(i, MPole);
1481 else if (nbP3d != 0) {
1482 AppParCurves_MultiPoint MPole1(tabP1);
1483 AppParCurves_MultiPoint MPole2(tabP2);
1484 mySCU.SetValue(1, MPole1);
1485 mySCU.SetValue(mydegremin+1, MPole2);
1486 for (i = 2; i <= mydegremin; i++) {
1487 for (j = 1; j<= nbP3d; j++) {
1490 tabP(j).SetXYZ(P1.XYZ()+(i-1)*(P2.XYZ()-P1.XYZ())/mydegremin);
1492 AppParCurves_MultiPoint MPole(tabP);
1493 mySCU.SetValue(i, MPole);
1496 else if (nbP2d != 0) {
1497 AppParCurves_MultiPoint MPole1(tabP12d);
1498 AppParCurves_MultiPoint MPole2(tabP22d);
1499 mySCU.SetValue(1, MPole1);
1500 mySCU.SetValue(mydegremin+1, MPole2);
1501 for (i = 2; i <= mydegremin; i++) {
1502 for (j = 1; j<= nbP2d; j++) {
1505 tabP2d(j).SetXY(P12d.XY()+(i-1)*(P22d.XY()-P12d.XY())/mydegremin);
1507 AppParCurves_MultiPoint MPole(tabP2d);
1508 mySCU.SetValue(i, MPole);
1511 mydone = Standard_True;
1512 // Stockage de la multicurve approximee.
1513 tolreached = Standard_True;
1515 if (mydebug) DUMP(mySCU);
1517 myMultiCurves.Append(mySCU);
1518 Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
1519 for (i = Para.Lower(); i <= Para.Upper(); i++) {
1520 ThePar->SetValue(i, Para(i));
1522 myPar.Append(ThePar);
1523 Tolers3d.Append(Precision::Confusion());
1524 Tolers2d.Append(Precision::PConfusion());
1528 // avec les tangentes.
1530 AppParCurves_MultiCurve mySCU(deg+1);
1531 AppParCurves_Constraint Cons = AppParCurves_TangencyPoint;
1532 Standard_Real lambda1, lambda2;
1533 math_Vector V1(1, nbP3d*3+nbP2d*2);
1534 math_Vector V2(1, nbP3d*3+nbP2d*2);
1535 FirstTangencyVector(Line, myfirstpt, V1);
1536 lambda1 = SearchFirstLambda(Line, Para, V1, myfirstpt);
1538 LastTangencyVector(Line, mylastpt, V2);
1539 lambda2 = SearchLastLambda(Line, Para, V2, mylastpt);
1541 Approx_ParLeastSquareOfMyGradient
1542 LSQ(Line, myfirstpt, mylastpt,
1543 Cons, Cons, Para, deg+1);
1545 lambda1 = lambda1/deg;
1546 lambda2 = lambda2/deg;
1547 LSQ.Perform(Para, V1, V2, lambda1, lambda2);
1548 mydone = LSQ.IsDone();
1549 mySCU = LSQ.BezierValue();
1552 Standard_Real Fv, TheTol3d, TheTol2d;
1553 LSQ.Error(Fv, TheTol3d, TheTol2d);
1555 // Stockage de la multicurve approximee.
1556 tolreached = Standard_True;
1558 if (mydebug) DUMP(mySCU);
1560 myMultiCurves.Append(mySCU);
1561 Handle(TColStd_HArray1OfReal) ThePar =
1562 new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
1563 for (i = Para.Lower(); i <= Para.Upper(); i++) {
1564 ThePar->SetValue(i, Para(i));
1566 myPar.Append(ThePar);
1567 Tolers3d.Append(TheTol3d);
1568 Tolers2d.Append(TheTol2d);
1569 return Standard_True;
1576 void Approx_ComputeLine::Init(const Standard_Integer degreemin,
1577 const Standard_Integer degreemax,
1578 const Standard_Real Tolerance3d,
1579 const Standard_Real Tolerance2d,
1580 const Standard_Integer NbIterations,
1581 const Standard_Boolean cutting,
1582 const Approx_ParametrizationType parametrization,
1583 const Standard_Boolean Squares)
1585 mydegremin = degreemin;
1586 mydegremax = degreemax;
1587 mytol3d = Tolerance3d;
1588 mytol2d = Tolerance2d;
1589 Par = parametrization;
1590 mysquares = Squares;
1592 myitermax = NbIterations;
1597 void Approx_ComputeLine::SetDegrees(const Standard_Integer degreemin,
1598 const Standard_Integer degreemax)
1600 mydegremin = degreemin;
1601 mydegremax = degreemax;
1605 void Approx_ComputeLine::SetTolerances(const Standard_Real Tolerance3d,
1606 const Standard_Real Tolerance2d)
1608 mytol3d = Tolerance3d;
1609 mytol2d = Tolerance2d;
1613 void Approx_ComputeLine::SetConstraints(const AppParCurves_Constraint FirstC,
1614 const AppParCurves_Constraint LastC)
1622 Standard_Boolean Approx_ComputeLine::IsAllApproximated()
1627 Standard_Boolean Approx_ComputeLine::IsToleranceReached()
1632 void Approx_ComputeLine::Error(const Standard_Integer Index,
1633 Standard_Real& tol3d,
1634 Standard_Real& tol2d) const
1636 tol3d = Tolers3d.Value(Index);
1637 tol2d = Tolers2d.Value(Index);
1640 Approx_ParametrizationType Approx_ComputeLine::Parametrization() const