1 // File: AdvApp2Var_ApproxAFunc2Var.cxx
2 // Created: Wed Jul 3 15:34:08 1996
3 // Author: Joelle CHAUVET
6 #include <AdvApp2Var_ApproxAFunc2Var.hxx>
7 #include <AdvApp2Var_EvaluatorFunc2Var.hxx>
8 #include <AdvApp2Var_Criterion.hxx>
9 #include <AdvApp2Var_Context.hxx>
10 #include <AdvApp2Var_Patch.hxx>
11 #include <AdvApp2Var_Network.hxx>
12 #include <AdvApp2Var_Node.hxx>
13 #include <AdvApp2Var_Iso.hxx>
14 #include <AdvApp2Var_Strip.hxx>
15 #include <AdvApp2Var_Framework.hxx>
16 #include <AdvApprox_Cutting.hxx>
18 #include <Standard_ConstructionError.hxx>
19 #include <Standard_OutOfRange.hxx>
20 #include <TColStd_HArray1OfInteger.hxx>
21 #include <TColStd_HArray2OfInteger.hxx>
22 #include <TColStd_HArray1OfReal.hxx>
23 #include <TColStd_HArray2OfReal.hxx>
26 #include <gp_Pnt2d.hxx>
28 #include <TColgp_HArray2OfPnt.hxx>
30 #include <Convert_GridPolynomialToPoles.hxx>
32 #include <Geom_BezierSurface.hxx>
35 //=======================================================================
36 //function : AdvApp2Var_ApproxAFunc2Var
38 //=======================================================================
40 AdvApp2Var_ApproxAFunc2Var::
41 AdvApp2Var_ApproxAFunc2Var(const Standard_Integer Num1DSS,
42 const Standard_Integer Num2DSS,
43 const Standard_Integer Num3DSS,
44 const Handle(TColStd_HArray1OfReal)& OneDTol,
45 const Handle(TColStd_HArray1OfReal)& TwoDTol,
46 const Handle(TColStd_HArray1OfReal)& ThreeDTol,
47 const Handle(TColStd_HArray2OfReal)& OneDTolFr,
48 const Handle(TColStd_HArray2OfReal)& TwoDTolFr,
49 const Handle(TColStd_HArray2OfReal)& ThreeDTolFr,
50 const Standard_Real FirstInU,
51 const Standard_Real LastInU,
52 const Standard_Real FirstInV,
53 const Standard_Real LastInV,
54 const GeomAbs_IsoType FavorIso,
55 const GeomAbs_Shape ContInU,
56 const GeomAbs_Shape ContInV,
57 const Standard_Integer PrecisCode,
58 const Standard_Integer MaxDegInU,
59 const Standard_Integer MaxDegInV,
60 const Standard_Integer MaxPatch,
61 const AdvApp2Var_EvaluatorFunc2Var& Func,
62 AdvApprox_Cutting& UChoice,
63 AdvApprox_Cutting& VChoice) :
64 my1DTolerances(OneDTol),
65 my2DTolerances(TwoDTol),
66 my3DTolerances(ThreeDTol),
67 my1DTolOnFront(OneDTolFr),
68 my2DTolOnFront(TwoDTolFr),
69 my3DTolOnFront(ThreeDTolFr),
70 myFirstParInU(FirstInU),
71 myLastParInU(LastInU),
72 myFirstParInV(FirstInV),
73 myLastParInV(LastInV),
74 myFavoriteIso(FavorIso),
77 myPrecisionCode(PrecisCode),
78 myMaxDegInU(MaxDegInU),
79 myMaxDegInV(MaxDegInV),
80 myMaxPatches(MaxPatch),
81 myDone(Standard_False),
82 myHasResult(Standard_False)
84 myNumSubSpaces[0] = Num1DSS;
85 myNumSubSpaces[1] = Num2DSS;
86 myNumSubSpaces[2] = Num3DSS;
88 Perform(UChoice, VChoice, Func);
92 //=======================================================================
93 //function : AdvApp2Var_ApproxAFunc2Var
95 //=======================================================================
97 AdvApp2Var_ApproxAFunc2Var::
98 AdvApp2Var_ApproxAFunc2Var(const Standard_Integer Num1DSS,
99 const Standard_Integer Num2DSS,
100 const Standard_Integer Num3DSS,
101 const Handle(TColStd_HArray1OfReal)& OneDTol,
102 const Handle(TColStd_HArray1OfReal)& TwoDTol,
103 const Handle(TColStd_HArray1OfReal)& ThreeDTol,
104 const Handle(TColStd_HArray2OfReal)& OneDTolFr,
105 const Handle(TColStd_HArray2OfReal)& TwoDTolFr,
106 const Handle(TColStd_HArray2OfReal)& ThreeDTolFr,
107 const Standard_Real FirstInU,
108 const Standard_Real LastInU,
109 const Standard_Real FirstInV,
110 const Standard_Real LastInV,
111 const GeomAbs_IsoType FavorIso,
112 const GeomAbs_Shape ContInU,
113 const GeomAbs_Shape ContInV,
114 const Standard_Integer PrecisCode,
115 const Standard_Integer MaxDegInU,
116 const Standard_Integer MaxDegInV,
117 const Standard_Integer MaxPatch,
118 const AdvApp2Var_EvaluatorFunc2Var& Func,
119 const AdvApp2Var_Criterion& Crit,
120 AdvApprox_Cutting& UChoice,
121 AdvApprox_Cutting& VChoice) :
122 my1DTolerances(OneDTol),
123 my2DTolerances(TwoDTol),
124 my3DTolerances(ThreeDTol),
125 my1DTolOnFront(OneDTolFr),
126 my2DTolOnFront(TwoDTolFr),
127 my3DTolOnFront(ThreeDTolFr),
128 myFirstParInU(FirstInU),
129 myLastParInU(LastInU),
130 myFirstParInV(FirstInV),
131 myLastParInV(LastInV),
132 myFavoriteIso(FavorIso),
135 myPrecisionCode(PrecisCode),
136 myMaxDegInU(MaxDegInU),
137 myMaxDegInV(MaxDegInV),
138 myMaxPatches(MaxPatch),
139 myDone(Standard_False),
140 myHasResult(Standard_False)
142 myNumSubSpaces[0] = Num1DSS;
143 myNumSubSpaces[1] = Num2DSS;
144 myNumSubSpaces[2] = Num3DSS;
146 Perform(UChoice, VChoice, Func, Crit);
150 //=======================================================================
152 //purpose : Initialisation of the approximation
153 //=======================================================================
155 void AdvApp2Var_ApproxAFunc2Var::Init()
157 Standard_Integer ifav,iu=0,iv=0,ndu,ndv;
158 switch (myFavoriteIso) {
180 Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : UContinuity Error");
193 Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : VContinuity Error");
195 ndu = Max(myMaxDegInU+1,2*iu+2);
196 ndv = Max(myMaxDegInV+1,2*iv+2);
198 Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : UMaxDegree Error");
200 Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : VMaxDegree Error");
201 myPrecisionCode = Max(0,Min(myPrecisionCode,3));
202 AdvApp2Var_Context Conditions(ifav,iu,iv,ndu,ndv,
213 myConditions = Conditions;
218 //=======================================================================
219 //function : InitGrid
220 //purpose : Initialisation of the approximation with regular cuttings
221 //=======================================================================
223 void AdvApp2Var_ApproxAFunc2Var::InitGrid(const Standard_Integer NbInt)
225 Standard_Integer iu=myConditions.UOrder(),iv=myConditions.VOrder(),iint;
227 AdvApp2Var_Patch M0(myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,iu,iv);
229 AdvApp2Var_SequenceOfPatch Net;
232 TColStd_SequenceOfReal TheU,TheV;
233 TheU.Append(myFirstParInU);
234 TheV.Append(myFirstParInV);
235 TheU.Append(myLastParInU);
236 TheV.Append(myLastParInV);
238 AdvApp2Var_Network Result(Net,TheU,TheV);
241 gp_XY UV1(myFirstParInU,myFirstParInV);
242 AdvApp2Var_Node C1(UV1,iu,iv);
243 gp_XY UV2(myLastParInU,myFirstParInV);
244 AdvApp2Var_Node C2(UV2,iu,iv);
245 gp_XY UV4(myLastParInU,myLastParInV);
246 AdvApp2Var_Node C4(UV4,iu,iv);
247 gp_XY UV3(myFirstParInU,myLastParInV);
248 AdvApp2Var_Node C3(UV3,iu,iv);
249 AdvApp2Var_SequenceOfNode Bag;
255 AdvApp2Var_Iso V0(GeomAbs_IsoV,myFirstParInV,
256 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
258 AdvApp2Var_Iso V1(GeomAbs_IsoV,myLastParInV,
259 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
261 AdvApp2Var_Iso U0(GeomAbs_IsoU,myFirstParInU,
262 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
264 AdvApp2Var_Iso U1(GeomAbs_IsoU,myLastParInU,
265 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
268 AdvApp2Var_Strip BU0,BV0;
274 AdvApp2Var_SequenceOfStrip UStrip,VStrip;
278 AdvApp2Var_Framework Constraints(Bag,UStrip,VStrip);
280 // regular cutting if NbInt>1
281 Standard_Real deltu = (myLastParInU-myFirstParInU)/NbInt,
282 deltv = (myLastParInV-myFirstParInV)/NbInt;
283 for (iint=1;iint<=NbInt-1;iint++) {
284 Result.UpdateInU(myFirstParInU+iint*deltu);
285 Constraints.UpdateInU(myFirstParInU+iint*deltu);
286 Result.UpdateInV(myFirstParInV+iint*deltv);
287 Constraints.UpdateInV(myFirstParInV+iint*deltv);
290 myConstraints = Constraints;
293 //=======================================================================
295 //purpose : Computation of the approximation
296 //=======================================================================
298 void AdvApp2Var_ApproxAFunc2Var::Perform(const AdvApprox_Cutting& UChoice,
299 const AdvApprox_Cutting& VChoice,
300 const AdvApp2Var_EvaluatorFunc2Var& Func)
302 ComputePatches(UChoice,VChoice,Func);
303 myHasResult = myDone = Standard_True;
307 //=======================================================================
309 //purpose : Computation of the approximation
310 //=======================================================================
312 void AdvApp2Var_ApproxAFunc2Var::Perform(const AdvApprox_Cutting& UChoice,
313 const AdvApprox_Cutting& VChoice,
314 const AdvApp2Var_EvaluatorFunc2Var& Func,
315 const AdvApp2Var_Criterion& Crit)
317 ComputePatches(UChoice,VChoice,Func,Crit);
318 myHasResult = myDone = Standard_True;
323 //=======================================================================
324 //function : ComputePatches
325 //purpose : Computation of the polynomial approximations
326 //=======================================================================
328 void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice,
329 const AdvApprox_Cutting& VChoice,
330 const AdvApp2Var_EvaluatorFunc2Var& Func)
332 Standard_Real Udec, Vdec;
333 Standard_Boolean Umore, Vmore;
334 Standard_Integer NbPatch, NbU, NbV, NumDec;
335 Standard_Integer FirstNA;
337 while (myResult.FirstNotApprox(FirstNA)) {
339 // complete the set of constraints
340 ComputeConstraints(UChoice, VChoice, Func);
342 // discretization of constraints relative to the square
343 myResult(FirstNA).Discretise(myConditions,myConstraints,Func);
344 if ( ! myResult(FirstNA).IsDiscretised() ) {
345 myHasResult = myDone = Standard_False;
346 Standard_ConstructionError::Raise
347 ("AdvApp2Var_ApproxAFunc2Var : Surface Discretisation Error");
350 // calculate the number and the type of autorized cuts
351 // depending on the max number of squares and the validity of next cuts.
352 NbU = myResult.NbPatchInU();
353 NbV = myResult.NbPatchInV();
355 Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(),Udec);
356 Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(),Vdec);
359 if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)>myMaxPatches)
360 && (Umore) ) NumDec = 1;
361 if ( ((NbPatch+NbV)>myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches)
362 && (Vmore) ) NumDec = 2;
363 if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches) ) {
364 if ( Umore ) NumDec = 3;
365 if ( (NbV>NbU) && Vmore ) NumDec = 4;
367 if ( (NbU+1)*(NbV+1)<=myMaxPatches ) {
368 if ( !Umore && !Vmore ) NumDec=0;
369 if ( Umore && !Vmore ) NumDec=3;
370 if ( !Umore && Vmore ) NumDec=4;
371 if ( Umore && Vmore ) NumDec=5;
374 // approximation of the square
375 myResult(FirstNA).MakeApprox(myConditions,myConstraints,NumDec);
377 if ( ! myResult(FirstNA).IsApproximated() ) {
378 switch (myResult(FirstNA).CutSense()) {
380 // It is not possible to cut : the result is preserved
381 if ( myResult(FirstNA).HasResult()) {
382 myResult(FirstNA).OverwriteApprox();
385 myHasResult = myDone = Standard_False;
386 Standard_ConstructionError::Raise
387 ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
391 // It is necessary to cut in U
392 myResult.UpdateInU(Udec);
393 myConstraints.UpdateInU(Udec);
396 // It is necessary to cut in V
397 myResult.UpdateInV(Vdec);
398 myConstraints.UpdateInV(Vdec);
401 // It is necesary to cut in U and V
402 myResult.UpdateInU(Udec);
403 myConstraints.UpdateInU(Udec);
404 myResult.UpdateInV(Vdec);
405 myConstraints.UpdateInV(Vdec);
408 myHasResult = myDone = Standard_False;
409 Standard_ConstructionError::Raise
410 ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
416 //=======================================================================
417 //function : ComputePatches
418 //purpose : Computation of the polynomial approximations
419 //=======================================================================
421 void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice,
422 const AdvApprox_Cutting& VChoice,
423 const AdvApp2Var_EvaluatorFunc2Var& Func,
424 const AdvApp2Var_Criterion& Crit)
426 Standard_Real Udec, Vdec, CritValue, m0=0., m1=0.;
427 Standard_Boolean Umore, Vmore, CritAbs = (Crit.Type() == AdvApp2Var_Absolute);
428 Standard_Integer NbPatch, NbU, NbV, NbInt, NumDec;
429 Standard_Integer FirstNA, decision=0;
431 while (myResult.FirstNotApprox(FirstNA)) {
433 // complete the set of constraints
434 ComputeConstraints(UChoice, VChoice, Func, Crit);
440 // discretize the constraints relative to the square
441 myResult(FirstNA).Discretise(myConditions,myConstraints,Func);
442 if ( ! myResult(FirstNA).IsDiscretised() ) {
443 myHasResult = myDone = Standard_False;
444 Standard_ConstructionError::Raise
445 ("AdvApp2Var_ApproxAFunc2Var : Surface Discretisation Error");
448 // calculate the number and type of autorized cuts
449 // depending on the max number of squares and the validity of next cuts
450 NbU = myResult.NbPatchInU();
451 NbV = myResult.NbPatchInV();
454 Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(),Udec);
455 Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(),Vdec);
458 if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)>myMaxPatches)
459 && (Umore) ) NumDec = 1;
460 if ( ((NbPatch+NbV)>myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches)
461 && (Vmore) ) NumDec = 2;
462 if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches) ) {
463 if ( Umore ) NumDec = 3;
464 if ( (NbV>NbU) && Vmore ) NumDec = 4;
466 if ( (NbU+1)*(NbV+1)<=myMaxPatches ) {
467 if ( !Umore && !Vmore ) NumDec=0;
468 if ( Umore && !Vmore ) NumDec=1;
469 if ( !Umore && Vmore ) NumDec=2;
470 if ( Umore && Vmore ) NumDec=5;
473 // approximation of the square
475 myResult(FirstNA).MakeApprox(myConditions,myConstraints,0);
478 myResult(FirstNA).MakeApprox(myConditions,myConstraints,NumDec);
480 if (NumDec>=3) NumDec = NumDec - 2;
482 // evaluation of the criterion on the square
483 if ( myResult(FirstNA).HasResult() ) {
484 Crit.Value(myResult(FirstNA),myConditions);
485 CritValue = myResult(FirstNA).CritValue();
486 if (m1<CritValue) m1 = CritValue;
488 // is it necessary to cut ?
489 decision = myResult(FirstNA).CutSense(Crit,NumDec);
490 Standard_Boolean Regular = (Crit.Repartition() == AdvApp2Var_Regular);
491 // Standard_Boolean Regular = Standard_True;
492 if (Regular && decision>0) {
499 // Impossible to cut : the result is preserved
500 if ( myResult(FirstNA).HasResult() ) {
501 myResult(FirstNA).OverwriteApprox();
504 myHasResult = myDone = Standard_False;
505 Standard_ConstructionError::Raise
506 ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
510 // It is necessary to cut in U
511 myResult.UpdateInU(Udec);
512 myConstraints.UpdateInU(Udec);
515 // It is necessary to cut in V
516 myResult.UpdateInV(Vdec);
517 myConstraints.UpdateInV(Vdec);
520 // It is necessary to cut in U and V
521 myResult.UpdateInU(Udec);
522 myConstraints.UpdateInU(Udec);
523 myResult.UpdateInV(Vdec);
524 myConstraints.UpdateInV(Vdec);
527 myHasResult = myDone = Standard_False;
528 Standard_ConstructionError::Raise
529 ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
535 //=======================================================================
536 //function : ComputeConstraints without Criterion
537 //purpose : Approximation of the constraints
538 //=======================================================================
540 void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UChoice,
541 const AdvApprox_Cutting& VChoice,
542 const AdvApp2Var_EvaluatorFunc2Var& Func)
545 Standard_Boolean more;
546 Standard_Integer ind1, ind2, NbPatch, NbU, NbV;
548 Standard_Integer indN1, indN2;
549 Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
550 AdvApp2Var_Node N1(iu,iv), N2(iu,iv);
552 while ( myConstraints.FirstNotApprox(ind1, ind2, Is) ) {
554 // approximation of iso and calculation of constraints at extremities
555 indN1 = myConstraints.FirstNode(Is.Type(),ind1,ind2);
556 N1 = myConstraints.Node(indN1);
557 indN2 = myConstraints.LastNode(Is.Type(),ind1,ind2);
558 N2 = myConstraints.Node(indN2);
560 Is.MakeApprox(myConditions,
561 myFirstParInU, myLastParInU,
562 myFirstParInV, myLastParInV,
565 if (Is.IsApproximated()) {
566 // iso is approached at the required tolerance
567 myConstraints.ChangeIso(ind1,ind2,Is);
568 myConstraints.ChangeNode(indN1) = N1;
569 myConstraints.ChangeNode(indN2) = N2;
573 // Approximation is not satisfactory
574 NbU = myResult.NbPatchInU();
575 NbV = myResult.NbPatchInV();
576 if (Is.Type()==GeomAbs_IsoV) {
577 NbPatch = (NbU+1)*NbV;
578 more = UChoice.Value(Is.T0(),Is.T1(),dec);
581 NbPatch = (NbV+1)*NbU;
582 more = VChoice.Value(Is.T0(),Is.T1(),dec);
585 if (NbPatch<=myMaxPatches && more) {
586 // It is possible to cut iso
587 if (Is.Type()==GeomAbs_IsoV) {
588 myResult.UpdateInU(dec);
589 myConstraints.UpdateInU(dec);
592 myResult.UpdateInV(dec);
593 myConstraints.UpdateInV(dec);
598 // It is not possible to cut : the result is preserved
599 if (Is.HasResult()) {
600 Is.OverwriteApprox();
601 myConstraints.ChangeIso(ind1,ind2,Is);
602 myConstraints.ChangeNode(indN1) = N1;
603 myConstraints.ChangeNode(indN2) = N2;
606 myHasResult = myDone = Standard_False;
607 Standard_ConstructionError::Raise
608 ("AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
616 //=======================================================================
617 //function : ComputeConstraints with Criterion
618 //purpose : Approximation of the constraints
619 //=======================================================================
621 void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UChoice,
622 const AdvApprox_Cutting& VChoice,
623 const AdvApp2Var_EvaluatorFunc2Var& Func,
624 const AdvApp2Var_Criterion& Crit)
627 Standard_Boolean more, CritRel = (Crit.Type() == AdvApp2Var_Relative);
628 Standard_Integer ind1, ind2, NbPatch, NbU, NbV;
630 Standard_Integer indN1, indN2;
631 Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
632 AdvApp2Var_Node N1(iu,iv), N2(iu,iv);
634 while ( myConstraints.FirstNotApprox(ind1, ind2, Is) ) {
636 // approximation of the iso and calculation of constraints at the extremities
637 indN1 = myConstraints.FirstNode(Is.Type(),ind1,ind2);
638 N1 = myConstraints.Node(indN1);
639 indN2 = myConstraints.LastNode(Is.Type(),ind1,ind2);
640 N2 = myConstraints.Node(indN2);
642 Is.MakeApprox(myConditions,
643 myFirstParInU, myLastParInU,
644 myFirstParInV, myLastParInV,
647 if (Is.IsApproximated()) {
648 // iso is approached at the required tolerance
649 myConstraints.ChangeIso(ind1,ind2,Is);
650 myConstraints.ChangeNode(indN1) = N1;
651 myConstraints.ChangeNode(indN2) = N2;
655 // Approximation is not satisfactory
656 NbU = myResult.NbPatchInU();
657 NbV = myResult.NbPatchInV();
658 if (Is.Type()==GeomAbs_IsoV) {
659 NbPatch = (NbU+1)*NbV;
660 more = UChoice.Value(Is.T0(),Is.T1(),dec);
663 NbPatch = (NbV+1)*NbU;
664 more = VChoice.Value(Is.T0(),Is.T1(),dec);
667 // To force Overwrite if the criterion is Absolute
668 more = more && (CritRel);
670 if (NbPatch<=myMaxPatches && more) {
671 // It is possible to cut iso
672 if (Is.Type()==GeomAbs_IsoV) {
673 myResult.UpdateInU(dec);
674 myConstraints.UpdateInU(dec);
677 myResult.UpdateInV(dec);
678 myConstraints.UpdateInV(dec);
683 // It is not possible to cut: the result is preserved
684 if (Is.HasResult()) {
685 Is.OverwriteApprox();
686 myConstraints.ChangeIso(ind1,ind2,Is);
687 myConstraints.ChangeNode(indN1) = N1;
688 myConstraints.ChangeNode(indN2) = N2;
691 myHasResult = myDone = Standard_False;
692 Standard_ConstructionError::Raise
693 ("AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
700 //=======================================================================
701 //function : Compute3DErrors
702 //purpose : Computation of the 3D errors
703 //=======================================================================
705 void AdvApp2Var_ApproxAFunc2Var::Compute3DErrors()
708 Standard_Integer iesp,ipat;
709 Standard_Real error_max,error_moy,error_U0,error_V0,error_U1,error_V1;
710 Standard_Real Tol,F1Tol,F2Tol,F3Tol,F4Tol;
711 if ( myNumSubSpaces[2] > 0 ) {
712 my3DMaxError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
713 my3DAverageError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
714 my3DUFrontError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
715 my3DVFrontError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
716 for (iesp=1;iesp<=myNumSubSpaces[2];iesp++) {
723 Tol = my3DTolerances->Value(iesp);
724 F1Tol = my3DTolOnFront->Value(iesp,1);
725 F2Tol = my3DTolOnFront->Value(iesp,2);
726 F3Tol = my3DTolOnFront->Value(iesp,3);
727 F4Tol = my3DTolOnFront->Value(iesp,4);
728 for (ipat=1;ipat<=myResult.NbPatch();ipat++) {
729 error_max = Max((myResult(ipat).MaxErrors())->Value(iesp),error_max);
730 error_U0 = Max((myResult(ipat).IsoErrors())->Value(iesp,3),error_U0);
731 error_U1 = Max((myResult(ipat).IsoErrors())->Value(iesp,4),error_U1);
732 error_V0 = Max((myResult(ipat).IsoErrors())->Value(iesp,1),error_V0);
733 error_V1 = Max((myResult(ipat).IsoErrors())->Value(iesp,2),error_V1);
734 error_moy += (myResult(ipat).AverageErrors())->Value(iesp);
736 my3DMaxError->SetValue(iesp,error_max);
737 my3DUFrontError->SetValue(iesp,Max(error_U0,error_U1));
738 my3DVFrontError->SetValue(iesp,Max(error_V0,error_V1));
739 error_moy /= (Standard_Real) myResult.NbPatch();
740 my3DAverageError->SetValue(iesp,error_moy);
742 || error_U0>F3Tol || error_U1>F4Tol
743 || error_V0>F1Tol || error_V1>F2Tol) {
744 myDone = Standard_False;
751 //=======================================================================
752 //function : ComputeCritError
753 //purpose : Computation of the max value of the Criterion
754 //=======================================================================
756 void AdvApp2Var_ApproxAFunc2Var::ComputeCritError()
759 Standard_Integer iesp,ipat;
760 Standard_Real crit_max;
761 if ( myNumSubSpaces[2] > 0 ) {
762 for (iesp=1;iesp<=myNumSubSpaces[2];iesp++) {
764 for (ipat=1;ipat<=myResult.NbPatch();ipat++) {
765 crit_max = Max((myResult(ipat).CritValue()),crit_max);
767 myCriterionError = crit_max;
772 //=======================================================================
773 //function : ConvertBS
774 //purpose : Convertion of the approximation in BSpline Surface
775 //=======================================================================
777 void AdvApp2Var_ApproxAFunc2Var::ConvertBS()
779 // Homogeneization of degrees
780 Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
781 Standard_Integer ncfu = myConditions.ULimit(), ncfv = myConditions.VLimit();
782 myResult.SameDegree(iu,iv,ncfu,ncfv);
783 myDegreeInU = ncfu - 1;
784 myDegreeInV = ncfv - 1;
786 // Calculate resulting surfaces
787 mySurfaces = new ( TColGeom_HArray1OfSurface) (1, myNumSubSpaces[2]);
790 TColStd_Array1OfReal UKnots (1, myResult.NbPatchInU()+1);
791 for (j=1; j<=UKnots.Length(); j++) { UKnots.SetValue(j, myResult.UParameter(j)); }
793 TColStd_Array1OfReal VKnots (1, myResult.NbPatchInV()+1);
794 for (j=1; j<=VKnots.Length(); j++) { VKnots.SetValue(j, myResult.VParameter(j)); }
796 // Prepare data for conversion grid of polynoms --> poles
797 Handle(TColStd_HArray1OfReal) Uint1 =
798 new (TColStd_HArray1OfReal) (1,2);
799 Uint1->SetValue(1, -1);
800 Uint1->SetValue(2, 1);
801 Handle(TColStd_HArray1OfReal) Vint1 =
802 new (TColStd_HArray1OfReal) (1,2);
803 Vint1->SetValue(1, -1);
804 Vint1->SetValue(2, 1);
806 Handle(TColStd_HArray1OfReal) Uint2 =
807 new (TColStd_HArray1OfReal) (1,myResult.NbPatchInU()+1);
808 for (j=1; j<=Uint2->Length(); j++) { Uint2->SetValue(j, myResult.UParameter(j)); }
809 Handle(TColStd_HArray1OfReal) Vint2 =
810 new (TColStd_HArray1OfReal) (1,myResult.NbPatchInV()+1);
811 for (j=1; j<=Vint2->Length(); j++) { Vint2->SetValue(j, myResult.VParameter(j)); }
813 Standard_Integer nmax = myResult.NbPatchInU()*myResult.NbPatchInV(),
814 Size_eq = myConditions.ULimit() * myConditions.VLimit() * 3;
816 Handle(TColStd_HArray2OfInteger) NbCoeff =
817 new (TColStd_HArray2OfInteger) (1, nmax, 1, 2);
818 Handle(TColStd_HArray1OfReal) Poly =
819 new (TColStd_HArray1OfReal) (1, nmax * Size_eq);
821 Standard_Integer SSP, i;
822 for (SSP=1; SSP <= myNumSubSpaces[2]; SSP++) {
824 // Creation of the grid of polynoms
825 Standard_Integer n=0,icf=1,ieq;
826 for (j=1; j<=myResult.NbPatchInV(); j++) {
827 for (i=1; i<=myResult.NbPatchInU(); i++) {
829 NbCoeff->SetValue(n,1, myResult.Patch(i,j).NbCoeffInU());
830 NbCoeff->SetValue(n,2, myResult.Patch(i,j).NbCoeffInV());
831 for (ieq=1; ieq<=Size_eq;ieq++) {
832 Poly->SetValue(icf,(myResult.Patch(i,j).Coefficients(SSP,myConditions))
839 // Conversion into poles
840 Convert_GridPolynomialToPoles CvP (myResult.NbPatchInU(),myResult.NbPatchInV(),
841 iu,iv,myMaxDegInU,myMaxDegInV,NbCoeff,
842 Poly,Uint1,Vint1,Uint2,Vint2);
843 if ( !CvP.IsDone() ) { myDone = Standard_False; }
845 // Conversion into BSpline
846 mySurfaces->ChangeValue(SSP) = new (Geom_BSplineSurface)
847 ( CvP.Poles()->Array2(),
848 CvP.UKnots()->Array1(), CvP.VKnots()->Array1(),
849 CvP.UMultiplicities()->Array1(), CvP.VMultiplicities()->Array1(),
850 CvP.UDegree(), CvP.VDegree() );
854 //=======================================================================
855 //function : MaxError
857 //=======================================================================
859 Handle(TColStd_HArray1OfReal)
860 AdvApp2Var_ApproxAFunc2Var::MaxError(const Standard_Integer Dimension) const
862 Handle (TColStd_HArray1OfReal) EPtr;
863 if (Dimension <1 || Dimension >3) {
864 Standard_OutOfRange::Raise
865 ("AdvApp2Var_ApproxAFunc2Var::MaxError : Dimension must be equal to 1,2 or 3 !");
881 //=======================================================================
882 //function : AverageError
884 //=======================================================================
886 Handle(TColStd_HArray1OfReal)
887 AdvApp2Var_ApproxAFunc2Var::AverageError(const Standard_Integer Dimension) const
889 Handle (TColStd_HArray1OfReal) EPtr;
890 if (Dimension <1 || Dimension >3) {
891 Standard_OutOfRange::Raise
892 ("AdvApp2Var_ApproxAFunc2Var::AverageError : Dimension must be equal to 1,2 or 3 !");
896 EPtr = my1DAverageError;
899 EPtr = my2DAverageError;
902 EPtr = my3DAverageError;
908 //=======================================================================
909 //function : UFrontError
911 //=======================================================================
913 Handle(TColStd_HArray1OfReal)
914 AdvApp2Var_ApproxAFunc2Var::UFrontError(const Standard_Integer Dimension) const
916 Handle (TColStd_HArray1OfReal) EPtr;
917 if (Dimension <1 || Dimension >3) {
918 Standard_OutOfRange::Raise
919 ("AdvApp2Var_ApproxAFunc2Var::UFrontError : Dimension must be equal to 1,2 or 3 !");
923 EPtr = my1DUFrontError;
926 EPtr = my2DUFrontError;
929 EPtr = my3DUFrontError;
935 //=======================================================================
936 //function : VFrontError
938 //=======================================================================
940 Handle(TColStd_HArray1OfReal)
941 AdvApp2Var_ApproxAFunc2Var::VFrontError(const Standard_Integer Dimension) const
943 Handle (TColStd_HArray1OfReal) EPtr;
944 if (Dimension <=0 || Dimension >3) {
945 Standard_OutOfRange::Raise
946 ("AdvApp2Var_ApproxAFunc2Var::VFrontError : Dimension must be equal to 1,2 or 3 !");
950 EPtr = my1DVFrontError;
953 EPtr = my2DVFrontError;
956 EPtr = my3DVFrontError;
962 //=======================================================================
963 //function : MaxError
965 //=======================================================================
968 AdvApp2Var_ApproxAFunc2Var::MaxError(const Standard_Integer Dimension,
969 const Standard_Integer SSPIndex) const
971 if (Dimension !=3 || SSPIndex !=1) {
972 Standard_OutOfRange::Raise
973 ("AdvApp2Var_ApproxAFunc2Var::MaxError: ONE Surface 3D only !");
975 Handle (TColStd_HArray1OfReal) EPtr = MaxError(Dimension);
976 return EPtr->Value(SSPIndex);
979 //=======================================================================
980 //function : AverageError
982 //=======================================================================
985 AdvApp2Var_ApproxAFunc2Var::AverageError(const Standard_Integer Dimension,
986 const Standard_Integer SSPIndex) const
988 if (Dimension !=3 || SSPIndex !=1) {
989 Standard_OutOfRange::Raise
990 ("AdvApp2Var_ApproxAFunc2Var::AverageError : ONE Surface 3D only !");
992 Handle (TColStd_HArray1OfReal) EPtr = AverageError(Dimension);
993 return EPtr->Value(SSPIndex);
996 //=======================================================================
997 //function : UFrontError
999 //=======================================================================
1002 AdvApp2Var_ApproxAFunc2Var::UFrontError(const Standard_Integer Dimension,
1003 const Standard_Integer SSPIndex) const
1005 if (Dimension !=3 || SSPIndex !=1) {
1006 Standard_OutOfRange::Raise
1007 ("AdvApp2Var_ApproxAFunc2Var::UFrontError : ONE Surface 3D only !");
1009 Handle (TColStd_HArray1OfReal) EPtr = UFrontError(Dimension);
1010 return EPtr->Value(SSPIndex);
1013 //=======================================================================
1014 //function : VFrontError
1016 //=======================================================================
1019 AdvApp2Var_ApproxAFunc2Var::VFrontError(const Standard_Integer Dimension,
1020 const Standard_Integer SSPIndex) const
1022 if (Dimension !=3 || SSPIndex !=1) {
1023 Standard_OutOfRange::Raise
1024 ("AdvApp2Var_ApproxAFunc2Var::VFrontError : ONE Surface 3D only !");
1026 Handle (TColStd_HArray1OfReal) EPtr = VFrontError(Dimension);
1027 return EPtr->Value(SSPIndex);
1031 //=======================================================================
1032 //function : CritError
1034 //=======================================================================
1037 AdvApp2Var_ApproxAFunc2Var::CritError(const Standard_Integer Dimension,
1038 const Standard_Integer SSPIndex) const
1040 if (Dimension !=3 || SSPIndex !=1) {
1041 Standard_OutOfRange::Raise
1042 ("AdvApp2Var_ApproxAFunc2Var::CritError: ONE Surface 3D only !");
1044 return myCriterionError;
1047 //=======================================================================
1050 //=======================================================================
1052 void AdvApp2Var_ApproxAFunc2Var::Dump(Standard_OStream& o) const
1054 Standard_Integer iesp=1,NbKU,NbKV,ik;
1056 if (!myHasResult) { o<<"No result"<<endl; }
1058 o<<"There is a result";
1060 o<<" within the requested tolerance "<<my3DTolerances->Value(iesp)<<endl;
1062 else if (my3DMaxError->Value(iesp)>my3DTolerances->Value(iesp)) {
1063 o<<" WITHOUT the requested tolerance "<<my3DTolerances->Value(iesp)<<endl;
1066 o<<" WITHOUT the requested continuities "<<endl;
1069 o<<"Result max error :"<<my3DMaxError->Value(iesp)<<endl;
1070 o<<"Result average error :"<<my3DAverageError->Value(iesp)<<endl;
1071 o<<"Result max error on U frontiers :"<<my3DUFrontError->Value(iesp)<<endl;
1072 o<<"Result max error on V frontiers :"<<my3DVFrontError->Value(iesp)<<endl;
1074 o<<"Degree of Bezier patches in U : "<<myDegreeInU
1075 <<" in V : "<<myDegreeInV<<endl;
1077 Handle(Geom_BSplineSurface) S
1078 = Handle(Geom_BSplineSurface)::DownCast(mySurfaces->Value(iesp));
1079 o<<"Number of poles in U : "<<S->NbUPoles()
1080 <<" in V : "<<S->NbVPoles()<<endl;
1082 NbKU = S->NbUKnots();
1083 NbKV = S->NbVKnots();
1084 o<<"Number of knots in U : "<<NbKU<<endl;
1085 for (ik=1;ik<=NbKU;ik++) {
1086 o<<" "<<ik<<" : "<<S->UKnot(ik)<<" mult : "<<S->UMultiplicity(ik)<<endl;
1089 o<<"Number of knots in V : "<<NbKV<<endl;
1090 for (ik=1;ik<=NbKV;ik++) {
1091 o<<" "<<ik<<" : "<<S->VKnot(ik)<<" mult : "<<S->VMultiplicity(ik)<<endl;