1 // File AppParCurves_Variational.gxx
2 // Jeannine PANCIATICI le 06/06/96
3 // Igor FEOKTISTOV 14/12/98 - correction of Approximate() and Init().
4 // Approximation d une MultiLine de points decrite par le tool MLineTool.
5 // avec criteres variationnels
8 #define No_Standard_RangeError
9 #define No_Standard_OutOfRange
10 #define No_Standard_DimensionError
11 #define No_Standard_ConstructionError
13 #include <Standard_Stream.hxx>
15 #include <AppParCurves.hxx>
16 #include <AppParCurves_Constraint.hxx>
17 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
18 #include <AppParCurves_Array1OfMultiPoint.hxx>
19 #include <AppParCurves_MultiPoint.hxx>
20 #include <AppParCurves_MultiBSpCurve.hxx>
21 #include <Convert_CompPolynomialToPoles.hxx>
23 #include <gp_Pnt2d.hxx>
25 #include <gp_Vec2d.hxx>
26 #include <TColgp_Array1OfPnt.hxx>
27 #include <TColgp_Array1OfPnt2d.hxx>
28 #include <TColgp_Array1OfVec.hxx>
29 #include <TColgp_Array1OfVec2d.hxx>
30 #include <TColStd_Array1OfInteger.hxx>
31 #include <TColStd_HArray1OfInteger.hxx>
32 #include <TColStd_Array1OfReal.hxx>
33 #include <TColStd_HArray1OfReal.hxx>
34 #include <TColStd_HArray2OfReal.hxx>
35 #include <StdFail_NotDone.hxx>
36 #include <Standard_SStream.hxx>
37 #include <Standard_NoSuchObject.hxx>
38 #include <Precision.hxx>
39 //#include <Smoothing.h>
48 //=======================================================================
49 //function : AppParCurves_Variational
50 //purpose : Initialization of the fields.
51 //=======================================================================
53 AppParCurves_Variational::AppParCurves_Variational(const MultiLine& SSP,
54 const Standard_Integer FirstPoint,
55 const Standard_Integer LastPoint,
56 const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
57 const Standard_Integer MaxDegree,
58 const Standard_Integer MaxSegment,
59 const GeomAbs_Shape Continuity,
60 const Standard_Boolean WithMinMax,
61 const Standard_Boolean WithCutting,
62 const Standard_Real Tolerance,
63 const Standard_Integer NbIterations):
65 myFirstPoint(FirstPoint),
66 myLastPoint(LastPoint),
67 myConstraints(TheConstraints),
68 myMaxDegree(MaxDegree),
69 myMaxSegment(MaxSegment),
70 myNbIterations(NbIterations),
71 myTolerance(Tolerance),
72 myContinuity(Continuity),
73 myWithMinMax(WithMinMax),
74 myWithCutting(WithCutting)
79 if (myMaxDegree < 1) Standard_DomainError::Raise();
80 myMaxDegree = Min (30, myMaxDegree);
82 if (myMaxSegment < 1) Standard_DomainError::Raise();
84 if (myWithMinMax != 0 && myWithMinMax !=1 ) Standard_DomainError::Raise();
85 if (myWithCutting != 0 && myWithCutting !=1 ) Standard_DomainError::Raise();
87 myIsOverConstr = Standard_False;
88 myIsCreated = Standard_False;
89 myIsDone = Standard_False;
90 switch (myContinuity) {
101 Standard_ConstructionError::Raise();
104 myNbP2d = ToolLine::NbP2d(SSP);
105 myNbP3d = ToolLine::NbP3d(SSP);
106 myDimension = 2 * myNbP2d + 3* myNbP3d ;
111 myKnots= new TColStd_HArray1OfReal(1,2);
112 myKnots->SetValue(1,0.);
113 myKnots->SetValue(2,1.);
117 mySmoothCriterion = new AppParCurves_MyCriterion(mySSP, myFirstPoint, myLastPoint);
118 myParameters = new TColStd_HArray1OfReal(myFirstPoint, myLastPoint);
119 myNbPoints=myLastPoint-myFirstPoint+1;
120 if (myNbPoints <= 0) Standard_ConstructionError::Raise();
122 myTabPoints= new TColStd_HArray1OfReal(1,myDimension*myNbPoints);
124 // Table of Points initialization
126 Standard_Integer ipoint,jp2d,jp3d,index;
127 TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
128 TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
133 for ( ipoint = myFirstPoint ; ipoint <= myLastPoint ; ipoint++)
136 if(myNbP2d !=0 && myNbP3d ==0 ) {
137 ToolLine::Value(mySSP,ipoint,TabP2d);
139 for ( jp2d = 1 ; jp2d <= myNbP2d ;jp2d++)
140 { P2d = TabP2d.Value(jp2d);
142 myTabPoints->SetValue(index++,P2d.X());
143 myTabPoints->SetValue(index++,P2d.Y());
146 if(myNbP3d !=0 && myNbP2d == 0 ) {
147 ToolLine::Value(mySSP,ipoint,TabP3d);
149 for ( jp3d = 1 ; jp3d <= myNbP3d ; jp3d++)
151 { P3d=TabP3d.Value(jp3d);
153 myTabPoints->SetValue(index++,P3d.X());
154 myTabPoints->SetValue(index++,P3d.Y());
155 myTabPoints->SetValue(index++,P3d.Z());
159 if(myNbP3d !=0 && myNbP2d != 0 ) {
160 ToolLine::Value(mySSP,ipoint,TabP3d,TabP2d);
162 for ( jp3d = 1 ; jp3d <= myNbP3d ; jp3d++)
164 { P3d=TabP3d.Value(jp3d);
166 myTabPoints->SetValue(index++,P3d.X());
167 myTabPoints->SetValue(index++,P3d.Y());
168 myTabPoints->SetValue(index++,P3d.Z());
171 for ( jp2d = 1 ; jp2d <= myNbP2d ; jp2d++)
173 { P2d=TabP2d.Value(jp2d);
175 myTabPoints->SetValue(index++,P2d.X());
176 myTabPoints->SetValue(index++,P2d.Y());
183 //=======================================================================
185 //purpose : Initializes the tables of constraints
186 // and verifies if the problem is not over-constrained.
187 // This method is used in the Create and the method SetConstraint.
188 //=======================================================================
190 void AppParCurves_Variational::Init()
193 Standard_Integer ipoint,jp2d,jp3d,index,jndex;
194 Standard_Integer CurMultyPoint;
195 TColgp_Array1OfVec TabV3d(1, Max(1,myNbP3d));
196 TColgp_Array1OfVec2d TabV2d(1, Max(1,myNbP2d));
197 TColgp_Array1OfVec TabV3dcurv(1, Max(1,myNbP3d));
198 TColgp_Array1OfVec2d TabV2dcurv(1, Max(1,myNbP2d));
203 myNbConstraints=myConstraints->Length();
204 if (myNbConstraints < 0) Standard_ConstructionError::Raise();
206 myTypConstraints = new TColStd_HArray1OfInteger(1,Max(1,2*myNbConstraints));
207 myTabConstraints = new TColStd_HArray1OfReal(1,Max(1,2*myDimension*myNbConstraints));
208 myTtheta = new TColStd_HArray1OfReal(1,Max(1,(2 * myNbP2d + 6 * myNbP3d) * myNbConstraints));
209 myTfthet = new TColStd_HArray1OfReal(1,Max(1,(2 * myNbP2d + 6 * myNbP3d) * myNbConstraints));
213 // Table of types initialization
214 Standard_Integer iconstr;
221 AppParCurves_Constraint valcontr;
223 for ( iconstr = myConstraints->Lower() ; iconstr <= myConstraints->Upper() ; iconstr++)
225 ipoint=(myConstraints->Value(iconstr)).Index();
227 valcontr=(myConstraints->Value(iconstr)).Constraint();
229 case AppParCurves_NoConstraint:
230 CurMultyPoint -= myNbP3d * 6 + myNbP2d * 2;
232 case AppParCurves_PassPoint:
233 myTypConstraints->SetValue(index++,ipoint);
234 myTypConstraints->SetValue(index++,0);
236 if(myNbP2d !=0 ) jndex=jndex+4*myNbP2d;
237 if(myNbP3d !=0 ) jndex=jndex+6*myNbP3d;
239 case AppParCurves_TangencyPoint:
240 myTypConstraints->SetValue(index++,ipoint);
241 myTypConstraints->SetValue(index++,1);
243 if(myNbP2d !=0 && myNbP3d == 0 )
245 if (ToolLine::Tangency(mySSP,ipoint,TabV2d) == Standard_False)
246 Standard_ConstructionError::Raise();
247 for (jp2d=1;jp2d<=myNbP2d;jp2d++)
249 Vt2d=TabV2d.Value(jp2d);
251 myTabConstraints->SetValue(jndex++,Vt2d.X());
252 myTabConstraints->SetValue(jndex++,Vt2d.Y());
254 InitTthetaF(2, valcontr, CurMultyPoint + (jp2d - 1) * 2, jndex - 4);
257 if(myNbP3d !=0 && myNbP2d == 0)
259 if (ToolLine::Tangency(mySSP,ipoint,TabV3d) == Standard_False)
260 Standard_ConstructionError::Raise();
261 for (jp3d=1;jp3d<=myNbP3d;jp3d++)
263 Vt3d=TabV3d.Value(jp3d);
265 myTabConstraints->SetValue(jndex++,Vt3d.X());
267 myTabConstraints->SetValue(jndex++,Vt3d.Y());
269 myTabConstraints->SetValue(jndex++,Vt3d.Z());
271 InitTthetaF(3, valcontr, CurMultyPoint + (jp3d - 1) * 6, jndex - 6);
274 if(myNbP3d !=0 && myNbP2d != 0)
276 if (ToolLine::Tangency(mySSP,ipoint,TabV3d,TabV2d) == Standard_False)
277 Standard_ConstructionError::Raise();
278 for (jp3d=1;jp3d<=myNbP3d;jp3d++)
280 Vt3d=TabV3d.Value(jp3d);
282 myTabConstraints->SetValue(jndex++,Vt3d.X());
283 myTabConstraints->SetValue(jndex++,Vt3d.Y());
284 myTabConstraints->SetValue(jndex++,Vt3d.Z());
286 InitTthetaF(3, valcontr, CurMultyPoint + (jp3d - 1) * 6, jndex - 6);
289 for (jp2d=1;jp2d<=myNbP2d;jp2d++)
291 Vt2d=TabV2d.Value(jp2d);
293 myTabConstraints->SetValue(jndex++,Vt2d.X());
294 myTabConstraints->SetValue(jndex++,Vt2d.Y());
296 InitTthetaF(2, valcontr, CurMultyPoint + (jp2d - 1) * 2 + myNbP3d * 6, jndex - 4);
303 case AppParCurves_CurvaturePoint:
304 myTypConstraints->SetValue(index++,ipoint);
305 myTypConstraints->SetValue(index++,2);
307 if(myNbP2d !=0 && myNbP3d == 0)
309 if (ToolLine::Tangency(mySSP,ipoint,TabV2d) == Standard_False )
310 Standard_ConstructionError::Raise();
311 if (ToolLine::Curvature(mySSP,ipoint,TabV2dcurv) == Standard_False)
312 Standard_ConstructionError::Raise();
313 for (jp2d=1;jp2d<=myNbP2d;jp2d++)
315 Vt2d=TabV2d.Value(jp2d);
317 Vc2d=TabV2dcurv.Value(jp2d);
318 if (Abs(Abs(Vc2d.Angle(Vt2d)) - PI/2.) > Precision::Angular())
319 Standard_ConstructionError::Raise();
320 myTabConstraints->SetValue(jndex++,Vt2d.X());
321 myTabConstraints->SetValue(jndex++,Vt2d.Y());
322 myTabConstraints->SetValue(jndex++,Vc2d.X());
323 myTabConstraints->SetValue(jndex++,Vc2d.Y());
324 InitTthetaF(2, valcontr, CurMultyPoint + (jp2d - 1) * 2, jndex - 4);
328 if(myNbP3d !=0 && myNbP2d == 0 )
330 if (ToolLine::Tangency(mySSP,ipoint,TabV3d) == Standard_False )
331 Standard_ConstructionError::Raise();
332 if (ToolLine::Curvature(mySSP,ipoint,TabV3dcurv) == Standard_False)
333 Standard_ConstructionError::Raise();
334 for (jp3d=1;jp3d<=myNbP3d;jp3d++)
336 Vt3d=TabV3d.Value(jp3d);
338 Vc3d=TabV3dcurv.Value(jp3d);
339 if ( (Vc3d.Normalized()).IsNormal(Vt3d,Precision::Angular()) == Standard_False)
340 Standard_ConstructionError::Raise();
341 myTabConstraints->SetValue(jndex++,Vt3d.X());
342 myTabConstraints->SetValue(jndex++,Vt3d.Y());
343 myTabConstraints->SetValue(jndex++,Vt3d.Z());
344 myTabConstraints->SetValue(jndex++,Vc3d.X());
345 myTabConstraints->SetValue(jndex++,Vc3d.Y());
346 myTabConstraints->SetValue(jndex++,Vc3d.Z());
347 InitTthetaF(3, valcontr, CurMultyPoint + (jp3d - 1) * 6, jndex - 6);
350 if(myNbP3d !=0 && myNbP2d != 0 )
352 if (ToolLine::Tangency(mySSP,ipoint,TabV3d,TabV2d) == Standard_False )
353 Standard_ConstructionError::Raise();
354 if (ToolLine::Curvature(mySSP,ipoint,TabV3dcurv,TabV2dcurv) == Standard_False)
355 Standard_ConstructionError::Raise();
356 for (jp3d=1;jp3d<=myNbP3d;jp3d++)
358 Vt3d=TabV3d.Value(jp3d);
360 Vc3d=TabV3dcurv.Value(jp3d);
361 if ( (Vc3d.Normalized()).IsNormal(Vt3d,Precision::Angular()) == Standard_False)
362 Standard_ConstructionError::Raise();
363 myTabConstraints->SetValue(jndex++,Vt3d.X());
364 myTabConstraints->SetValue(jndex++,Vt3d.Y());
365 myTabConstraints->SetValue(jndex++,Vt3d.Z());
366 myTabConstraints->SetValue(jndex++,Vc3d.X());
367 myTabConstraints->SetValue(jndex++,Vc3d.Y());
368 myTabConstraints->SetValue(jndex++,Vc3d.Z());
369 InitTthetaF(3, valcontr, CurMultyPoint + (jp3d - 1) * 6, jndex - 6);
371 for (jp2d=1;jp2d<=myNbP2d;jp2d++)
373 Vt2d=TabV2d.Value(jp2d);
375 Vc2d=TabV2dcurv.Value(jp2d);
376 if (Abs(Abs(Vc2d.Angle(Vt2d)) - PI/2.) > Precision::Angular())
377 Standard_ConstructionError::Raise();
378 myTabConstraints->SetValue(jndex++,Vt2d.X());
379 myTabConstraints->SetValue(jndex++,Vt2d.Y());
380 myTabConstraints->SetValue(jndex++,Vc2d.X());
381 myTabConstraints->SetValue(jndex++,Vc2d.Y());
382 InitTthetaF(2, valcontr, CurMultyPoint + (jp2d - 1) * 2 + myNbP3d * 6, jndex - 4);
388 Standard_ConstructionError::Raise();
390 CurMultyPoint += myNbP3d * 6 + myNbP2d * 2;
392 // OverConstraint Detection
393 Standard_Integer MaxSeg;
394 if(myWithCutting == Standard_True) MaxSeg = myMaxSegment ;
396 if (((myMaxDegree-myNivCont)*MaxSeg-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
398 myIsOverConstr =Standard_True;
399 myIsCreated = Standard_False;
402 InitSmoothCriterion();
403 myIsCreated = Standard_True;
409 //=======================================================================
410 //function : Approximate
411 //purpose : Makes the approximation with the current fields.
412 //=======================================================================
414 void AppParCurves_Variational::Approximate()
417 if (myIsCreated == Standard_False ) StdFail_NotDone:: Raise();
420 Standard_Real WQuadratic, WQuality;
422 TColStd_Array1OfReal Ecarts(myFirstPoint, myLastPoint);
424 mySmoothCriterion->GetWeight(WQuadratic, WQuality);
426 Handle(FEmTool_Curve) TheCurve;
428 mySmoothCriterion->GetCurve(TheCurve);
430 //---------------------------------------------------------------------
432 TheMotor(mySmoothCriterion, WQuadratic, WQuality, TheCurve, Ecarts);
435 if(myWithMinMax && myTolerance < myMaxError)
436 Adjusting(mySmoothCriterion, WQuadratic, WQuality, TheCurve, Ecarts);
438 //---------------------------------------------------------------------
440 Standard_Integer jp2d,jp3d,index,ipole,
441 NbElem = TheCurve->NbElements();
443 TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
444 TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
445 Standard_Real debfin[2] = {-1., 1};
453 Handle(TColStd_HArray2OfReal) PolynomialIntervalsPtr =
454 new TColStd_HArray2OfReal(1,NbElem,1,2) ;
456 Handle(TColStd_HArray1OfInteger) NbCoeffPtr =
457 new TColStd_HArray1OfInteger(1, myMaxSegment);
459 Standard_Integer size = myMaxSegment * (myMaxDegree + 1) * myDimension ;
460 Handle(TColStd_HArray1OfReal) CoeffPtr = new TColStd_HArray1OfReal(1,size);
464 Handle(TColStd_HArray1OfReal) IntervallesPtr =
465 new TColStd_HArray1OfReal(1, NbElem + 1);
467 IntervallesPtr->ChangeArray1() = TheCurve->Knots();
469 TheCurve->GetPolynom(CoeffPtr->ChangeArray1());
473 for(ii = 1; ii <= NbElem; ii++)
474 NbCoeffPtr->SetValue(ii, TheCurve->Degree(ii)+1);
477 for (ii = PolynomialIntervalsPtr->LowerRow() ;
478 ii <= PolynomialIntervalsPtr->UpperRow() ;ii++)
480 PolynomialIntervalsPtr->SetValue(ii,1,debfin[0]) ;
481 PolynomialIntervalsPtr->SetValue(ii,2,debfin[1]) ;
484 printf("\n =========== Parameters for converting\n");
485 printf("nb_courbes : %d \n", NbElem);
486 printf("tab_option[4] : %d \n", myNivCont);
487 printf("myDimension : %d \n", myDimension);
488 printf("myMaxDegree : %d \n", myMaxDegree);
489 printf("\n NbcoeffPtr :\n");
490 for(ii = 1; ii <= NbElem; ii++) printf("NbCoeffPtr(%d) = %d \n", ii, NbCoeffPtr->Value(ii));
491 size = NbElem*(myMaxDegree + 1) * myDimension;
492 printf("\n CoeffPtr :\n");
493 for(ii = 1; ii <= size; ii++) printf("CoeffPtr(%d) = %.8e \n", ii, CoeffPtr->Value(ii));
494 printf("\n PolinimialIntervalsPtr :\n");
495 for (ii = PolynomialIntervalsPtr->LowerRow() ;
496 ii <= PolynomialIntervalsPtr->UpperRow() ;ii++)
498 printf(" %d : [%f, %f] \n", ii, PolynomialIntervalsPtr->Value(ii,1),
499 PolynomialIntervalsPtr->Value(ii,2)) ;
501 printf("\n IntervallesPtr :\n");
502 for (ii = IntervallesPtr->Lower();
503 ii <= IntervallesPtr->Upper() - 1; ii++)
505 printf(" %d : [%f, %f] \n", ii, IntervallesPtr->Value(ii),
506 IntervallesPtr->Value(ii+1)) ;
509 Convert_CompPolynomialToPoles AConverter(NbElem,
515 PolynomialIntervalsPtr,
517 if (AConverter.IsDone())
519 Handle(TColStd_HArray2OfReal) PolesPtr ;
520 Handle(TColStd_HArray1OfInteger) Mults;
521 Standard_Integer NbPoles=AConverter.NbPoles();
522 // Standard_Integer Deg=AConverter.Degree();
523 AppParCurves_Array1OfMultiPoint TabMU(1,NbPoles);
524 AConverter.Poles(PolesPtr) ;
525 AConverter.Knots(myKnots) ;
526 AConverter.Multiplicities(Mults) ;
528 for (ipole=PolesPtr->LowerRow();ipole<=PolesPtr->UpperRow();ipole++)
530 index=PolesPtr->LowerCol();
533 for (jp2d=1;jp2d<=myNbP2d;jp2d++)
535 P2d.SetX(PolesPtr->Value(ipole,index++));
536 P2d.SetY(PolesPtr->Value(ipole,index++));
537 TabP2d.SetValue(jp2d,P2d);
542 for (jp3d=1;jp3d<=myNbP3d;jp3d++)
544 // cout << "\n Poles(ipole,1)" << PolesPtr->Value(ipole,index);
545 P3d.SetX(PolesPtr->Value(ipole,index++));
546 // cout << "\n Poles(ipole,1)" << PolesPtr->Value(ipole,index);
547 P3d.SetY(PolesPtr->Value(ipole,index++));
548 // cout << "\n Poles(ipole,1)" << PolesPtr->Value(ipole,index);
549 P3d.SetZ(PolesPtr->Value(ipole,index++));
550 TabP3d.SetValue(jp3d,P3d);
555 for (jp2d=1;jp2d<=myNbP2d;jp2d++)
557 P2d.SetX(PolesPtr->Value(ipole,index++));
558 P2d.SetY(PolesPtr->Value(ipole,index++));
559 TabP2d.SetValue(jp2d,P2d);
562 if(myNbP2d !=0 && myNbP3d !=0)
564 AppParCurves_MultiPoint aMultiPoint(TabP3d,TabP2d);
565 TabMU.SetValue(ipole,aMultiPoint);
567 else if (myNbP2d !=0)
569 AppParCurves_MultiPoint aMultiPoint(TabP2d);
570 TabMU.SetValue(ipole,aMultiPoint);
575 AppParCurves_MultiPoint aMultiPoint(TabP3d);
576 TabMU.SetValue(ipole,aMultiPoint);
580 AppParCurves_MultiBSpCurve aCurve(TabMU,myKnots->Array1(),Mults->Array1());
582 myIsDone = Standard_True;
588 //=======================================================================
589 //function : IsCreated
590 //purpose : returns True if the creation is done
591 //=======================================================================
593 Standard_Boolean AppParCurves_Variational::IsCreated() const
598 //=======================================================================
600 //purpose : returns True if the approximation is ok
601 //=======================================================================
603 Standard_Boolean AppParCurves_Variational::IsDone() const
608 //=======================================================================
609 //function : IsOverConstrained
610 //purpose : returns True if the problem is overconstrained
611 // in this case, approximation cannot be done.
612 //=======================================================================
614 Standard_Boolean AppParCurves_Variational::IsOverConstrained() const
616 return myIsOverConstr;
619 //=======================================================================
621 //purpose : returns all the BSpline curves approximating the
622 // MultiLine SSP after minimization of the parameter.
624 //=======================================================================
626 AppParCurves_MultiBSpCurve AppParCurves_Variational::Value() const
628 if (myIsDone == Standard_False) StdFail_NotDone::Raise();
633 //=======================================================================
634 //function : MaxError
635 //purpose : returns the maximum of the distances between
636 // the points of the multiline and the approximation
638 //=======================================================================
640 Standard_Real AppParCurves_Variational::MaxError() const
642 if (myIsDone == Standard_False) StdFail_NotDone::Raise();
646 //=======================================================================
647 //function : MaxErrorIndex
648 //purpose : returns the index of the MultiPoint of ErrorMax
649 //=======================================================================
651 Standard_Integer AppParCurves_Variational::MaxErrorIndex() const
653 if (myIsDone == Standard_False) StdFail_NotDone::Raise();
654 return myMaxErrorIndex;
657 //=======================================================================
658 //function : QuadraticError
659 //purpose : returns the quadratic average of the distances between
660 // the points of the multiline and the approximation
662 //=======================================================================
664 Standard_Real AppParCurves_Variational::QuadraticError() const
666 if (myIsDone == Standard_False) StdFail_NotDone::Raise();
667 return myCriterium[0];
670 //=======================================================================
671 //function : Distance
672 //purpose : returns the distances between the points of the
673 // multiline and the approximation curves.
674 //=======================================================================
676 void AppParCurves_Variational::Distance(math_Matrix& mat)
679 if (myIsDone == Standard_False) StdFail_NotDone::Raise();
680 Standard_Integer ipoint,jp2d,jp3d,index;
681 TColgp_Array1OfPnt TabP3d(1,Max(1,myNbP3d));
682 TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
683 Standard_Integer j0 = mat.LowerCol() - myFirstPoint;
692 for ( ipoint = myFirstPoint ; ipoint <= myLastPoint ; ipoint++)
696 ToolLine::Value(mySSP,ipoint,TabP3d);
698 for ( jp3d = 1 ; jp3d <= myNbP3d ; jp3d++)
700 { P3d=TabP3d.Value(jp3d);
701 myMBSpCurve.Value(index,myParameters->Value(ipoint),Pt3d);
702 mat(index++, j0 + ipoint)=P3d.Distance(Pt3d);
707 if(myNbP3d == 0 ) ToolLine::Value(mySSP,ipoint,TabP2d);
708 else ToolLine::Value(mySSP,ipoint,TabP3d,TabP2d);
709 for ( jp2d = 1 ; jp2d <= myNbP2d ;jp2d++)
711 { P2d = TabP2d.Value(jp2d);
712 myMBSpCurve.Value(index,myParameters->Value(ipoint),Pt2d);
713 mat(index++, j0 + ipoint)=P2d.Distance(Pt2d);
720 //=======================================================================
721 //function : AverageError
722 //purpose : returns the average error between
723 // the MultiLine and the approximation.
724 //=======================================================================
726 Standard_Real AppParCurves_Variational::AverageError() const
728 if (myIsDone == Standard_False) StdFail_NotDone::Raise();
729 return myAverageError;
732 //=======================================================================
733 //function : Parameters
734 //purpose : returns the parameters uses to the approximations
735 //=======================================================================
737 const Handle(TColStd_HArray1OfReal)& AppParCurves_Variational::Parameters() const
739 if (myIsDone == Standard_False) StdFail_NotDone::Raise();
743 //=======================================================================
745 //purpose : returns the knots uses to the approximations
746 //=======================================================================
748 const Handle(TColStd_HArray1OfReal)& AppParCurves_Variational::Knots() const
750 if (myIsDone == Standard_False) StdFail_NotDone::Raise();
754 //=======================================================================
755 //function : Criterium
756 //purpose : returns the values of the quality criterium.
757 //=======================================================================
759 void AppParCurves_Variational::Criterium(Standard_Real& VFirstOrder, Standard_Real& VSecondOrder, Standard_Real& VThirdOrder) const
761 if (myIsDone == Standard_False) StdFail_NotDone::Raise();
762 VFirstOrder=myCriterium[1] ;
763 VSecondOrder=myCriterium[2];
764 VThirdOrder=myCriterium[3];
767 //=======================================================================
768 //function : CriteriumWeight
769 //purpose : returns the Weights (as percent) associed to the criterium used in
771 //=======================================================================
773 void AppParCurves_Variational::CriteriumWeight(Standard_Real& Percent1, Standard_Real& Percent2, Standard_Real& Percent3) const
775 Percent1 = myPercent[0];
776 Percent2 = myPercent[1];
777 Percent3 = myPercent[2] ;
780 //=======================================================================
781 //function : MaxDegree
782 //purpose : returns the Maximum Degree used in the approximation
783 //=======================================================================
785 Standard_Integer AppParCurves_Variational::MaxDegree() const
790 //=======================================================================
791 //function : MaxSegment
792 //purpose : returns the Maximum of segment used in the approximation
793 //=======================================================================
795 Standard_Integer AppParCurves_Variational::MaxSegment() const
800 //=======================================================================
801 //function : Continuity
802 //purpose : returns the Continuity used in the approximation
803 //=======================================================================
805 GeomAbs_Shape AppParCurves_Variational::Continuity() const
810 //=======================================================================
811 //function : WithMinMax
812 //purpose : returns if the approximation search to minimize the
813 // maximum Error or not.
814 //=======================================================================
816 Standard_Boolean AppParCurves_Variational::WithMinMax() const
821 //=======================================================================
822 //function : WithCutting
823 //purpose : returns if the approximation can insert new Knots or not.
824 //=======================================================================
826 Standard_Boolean AppParCurves_Variational::WithCutting() const
828 return myWithCutting;
831 //=======================================================================
832 //function : Tolerance
833 //purpose : returns the tolerance used in the approximation.
834 //=======================================================================
836 Standard_Real AppParCurves_Variational::Tolerance() const
841 //=======================================================================
842 //function : NbIterations
843 //purpose : returns the number of iterations used in the approximation.
844 //=======================================================================
846 Standard_Integer AppParCurves_Variational::NbIterations() const
848 return myNbIterations;
851 //=======================================================================
853 //purpose : Prints on the stream o information on the current state
855 //=======================================================================
857 void AppParCurves_Variational::Dump(Standard_OStream& o) const
859 o << " \nVariational Smoothing " << endl;
860 o << " Number of multipoints " << myNbPoints << endl;
861 o << " Number of 2d par multipoint " << myNbP2d << endl;
862 o << " Nombre of 3d par multipoint " << myNbP3d << endl;
863 o << " Number of PassagePoint " << myNbPassPoints << endl;
864 o << " Number of TangencyPoints " << myNbTangPoints << endl;
865 o << " Number of CurvaturePoints " << myNbCurvPoints << endl;
866 o << " \nTolerance " << o.setf(ios::scientific) << setprecision(3) << setw(9) << myTolerance;
867 if ( WithMinMax()) { o << " as Max Error." << endl;}
868 else { o << " as size Error." << endl;}
869 o << "CriteriumWeights : " << myPercent[0] << " , "
870 << myPercent[1] << " , " << myPercent[2] << endl;
873 o << " MaxError " << setprecision(3) << setw(9) << myMaxError << endl;
874 o << " Index of MaxError " << myMaxErrorIndex << endl;
875 o << " Average Error " << setprecision(3) << setw(9) << myAverageError << endl;
876 o << " Quadratic Error " << setprecision(3) << setw(9) << myCriterium[0] << endl;
877 o << " Tension Criterium " << setprecision(3) << setw(9) << myCriterium[1] << endl;
878 o << " Flexion Criterium " << setprecision(3) << setw(9) << myCriterium[2] << endl;
879 o << " Jerk Criterium " << setprecision(3) << setw(9) << myCriterium[3] << endl;
880 o << " NbSegments " << myKnots->Length()-1 << endl;
883 { if (myIsOverConstr) o << "The probleme is overconstraint " << endl;
884 else o << " Erreur dans l''approximation" << endl;
888 //=======================================================================
889 //function : SetConstraints
890 //purpose : Define the constraints to approximate
891 // If this value is incompatible with the others fields
892 // this method modify nothing and returns false
893 //=======================================================================
895 Standard_Boolean AppParCurves_Variational::SetConstraints(const Handle(AppParCurves_HArray1OfConstraintCouple)& aConstraint)
898 myConstraints=aConstraint;
900 if (myIsOverConstr ) return Standard_False;
901 else return Standard_True;
904 //=======================================================================
905 //function : SetParameters
906 //purpose : Defines the parameters used by the approximations.
907 //=======================================================================
909 void AppParCurves_Variational::SetParameters(const Handle(TColStd_HArray1OfReal)& param)
911 myParameters->ChangeArray1() = param->Array1();
914 //=======================================================================
915 //function : SetKnots
916 //purpose : Defines the knots used by the approximations
917 // -- If this value is incompatible with the others fields
918 // -- this method modify nothing and returns false
919 //=======================================================================
921 Standard_Boolean AppParCurves_Variational::SetKnots(const Handle(TColStd_HArray1OfReal)& knots)
923 myKnots->ChangeArray1() = knots->Array1();
924 return Standard_True;
927 //=======================================================================
928 //function : SetMaxDegree
929 //purpose : Define the Maximum Degree used in the approximation
930 // If this value is incompatible with the others fields
931 // this method modify nothing and returns false
932 //=======================================================================
934 Standard_Boolean AppParCurves_Variational::SetMaxDegree(const Standard_Integer Degree)
936 if (((Degree-myNivCont)*myMaxSegment-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
937 return Standard_False;
942 InitSmoothCriterion();
944 return Standard_True;
949 //=======================================================================
950 //function : SetMaxSegment
951 //purpose : Define the maximum number of segments used in the approximation
952 // If this value is incompatible with the others fields
953 // this method modify nothing and returns false
954 //=======================================================================
956 Standard_Boolean AppParCurves_Variational::SetMaxSegment(const Standard_Integer NbSegment)
958 if ( myWithCutting == Standard_True &&
959 ((myMaxDegree-myNivCont)*NbSegment-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
960 return Standard_False;
963 myMaxSegment=NbSegment;
964 return Standard_True;
968 //=======================================================================
969 //function : SetContinuity
970 //purpose : Define the Continuity used in the approximation
971 // If this value is incompatible with the others fields
972 // this method modify nothing and returns false
973 //=======================================================================
975 Standard_Boolean AppParCurves_Variational::SetContinuity(const GeomAbs_Shape C)
977 Standard_Integer NivCont=0;
989 Standard_ConstructionError::Raise();
991 if (((myMaxDegree-NivCont)*myMaxSegment-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
992 return Standard_False;
998 InitSmoothCriterion();
999 return Standard_True;
1003 //=======================================================================
1004 //function : SetWithMinMax
1005 //purpose : Define if the approximation search to minimize the
1006 // maximum Error or not.
1007 //=======================================================================
1009 void AppParCurves_Variational::SetWithMinMax(const Standard_Boolean MinMax)
1011 myWithMinMax=MinMax;
1013 InitSmoothCriterion();
1016 //=======================================================================
1017 //function : SetWithCutting
1018 //purpose : Define if the approximation can insert new Knots or not.
1019 // If this value is incompatible with the others fields
1020 // this method modify nothing and returns false
1021 //=======================================================================
1023 Standard_Boolean AppParCurves_Variational::SetWithCutting(const Standard_Boolean Cutting)
1025 if (Cutting == Standard_False)
1027 if (((myMaxDegree-myNivCont)*myKnots->Length()-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
1028 return Standard_False;
1032 myWithCutting=Cutting;
1033 InitSmoothCriterion();
1034 return Standard_True;
1039 if (((myMaxDegree-myNivCont)*myMaxSegment-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
1040 return Standard_False;
1044 myWithCutting=Cutting;
1045 InitSmoothCriterion();
1046 return Standard_True;
1051 //=======================================================================
1052 //function : SetCriteriumWeight
1053 //purpose : define the Weights (as percent) associed to the criterium used in
1054 // the optimization.
1055 //=======================================================================
1057 void AppParCurves_Variational::SetCriteriumWeight(const Standard_Real Percent1, const Standard_Real Percent2, const Standard_Real Percent3)
1059 if (Percent1 < 0 || Percent2 < 0 || Percent3 < 0 ) Standard_DomainError::Raise();
1060 Standard_Real Total = Percent1 + Percent2 + Percent3;
1061 myPercent[0] = Percent1/Total;
1062 myPercent[1] = Percent2/Total;
1063 myPercent[2] = Percent3/Total;
1065 InitSmoothCriterion();
1068 //=======================================================================
1069 //function : SetCriteriumWeight
1070 //purpose : define the Weight (as percent) associed to the
1071 // criterium Order used in the optimization : Others
1072 // weights are updated.
1073 //=======================================================================
1075 void AppParCurves_Variational::SetCriteriumWeight(const Standard_Integer Order, const Standard_Real Percent)
1077 if ( Percent < 0 ) Standard_DomainError::Raise();
1078 if ( Order < 1 || Order > 3 ) Standard_ConstructionError::Raise();
1079 myPercent[Order-1] = Percent;
1080 Standard_Real Total = myPercent[0] + myPercent[1] + myPercent[2];
1081 myPercent[0] = myPercent[0] / Total;
1082 myPercent[1] = myPercent[1] / Total;
1083 myPercent[2] = myPercent[2] / Total;
1085 InitSmoothCriterion();
1089 //=======================================================================
1090 //function : SetTolerance
1091 //purpose : define the tolerance used in the approximation.
1092 //=======================================================================
1094 void AppParCurves_Variational::SetTolerance(const Standard_Real Tol)
1097 InitSmoothCriterion();
1100 //=======================================================================
1101 //function : SetNbIterations
1102 //purpose : define the number of iterations used in the approximation.
1103 //=======================================================================
1105 void AppParCurves_Variational::SetNbIterations(const Standard_Integer Iter)
1107 myNbIterations=Iter;
1112 #include <AppParCurves_Variational_1.gxx> // TheMotor
1113 #include <AppParCurves_Variational_2.gxx> // Optimization
1114 #include <AppParCurves_Variational_3.gxx> // Project
1115 #include <AppParCurves_Variational_4.gxx> // ACR
1116 #include <AppParCurves_Variational_5.gxx> // SplitCurve
1117 #include <AppParCurves_Variational_6.gxx> // InitSmoothCriterion and other Init... methods
1118 #include <AppParCurves_Variational_7.gxx> // Adjusting
1119 #include <AppParCurves_Variational_8.gxx> // AssemblingConstraints
1120 #include <AppParCurves_Variational_9.gxx> // InitTtheta and InitTfthet methods