0022550: Fixing data races
[occt.git] / src / AdvApp2Var / AdvApp2Var_ApproxAFunc2Var.cxx
1 // File:        AdvApp2Var_ApproxAFunc2Var.cxx
2 // Created:     Wed Jul  3 15:34:08 1996
3 // Author:      Joelle CHAUVET
4 //              <jct@sgi38>
5
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>
17
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>
24
25 #include <gp_XY.hxx>
26 #include <gp_Pnt2d.hxx>
27 #include <gp_Pnt.hxx>
28 #include <TColgp_HArray2OfPnt.hxx>
29
30 #include <Convert_GridPolynomialToPoles.hxx>
31
32 #include <Geom_BezierSurface.hxx>
33
34
35 //=======================================================================
36 //function : AdvApp2Var_ApproxAFunc2Var
37 //purpose  : 
38 //=======================================================================
39
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),
75 myContInU(ContInU),
76 myContInV(ContInV),
77 myPrecisionCode(PrecisCode),
78 myMaxDegInU(MaxDegInU),
79 myMaxDegInV(MaxDegInV),
80 myMaxPatches(MaxPatch),
81 myDone(Standard_False),
82 myHasResult(Standard_False)
83 {
84   myNumSubSpaces[0] = Num1DSS;
85   myNumSubSpaces[1] = Num2DSS;
86   myNumSubSpaces[2] = Num3DSS;
87   Init();
88   Perform(UChoice, VChoice, Func);
89   ConvertBS();
90 }
91
92 //=======================================================================
93 //function : AdvApp2Var_ApproxAFunc2Var
94 //purpose  : 
95 //=======================================================================
96
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),
133 myContInU(ContInU),
134 myContInV(ContInV),
135 myPrecisionCode(PrecisCode),
136 myMaxDegInU(MaxDegInU),
137 myMaxDegInV(MaxDegInV),
138 myMaxPatches(MaxPatch),
139 myDone(Standard_False),
140 myHasResult(Standard_False)
141 {
142   myNumSubSpaces[0] = Num1DSS;
143   myNumSubSpaces[1] = Num2DSS;
144   myNumSubSpaces[2] = Num3DSS;
145   Init();
146   Perform(UChoice, VChoice, Func, Crit);
147   ConvertBS();
148 }
149
150 //=======================================================================
151 //function : Init
152 //purpose  : Initialisation of the approximation
153 //=======================================================================
154
155 void AdvApp2Var_ApproxAFunc2Var::Init()
156 {
157   Standard_Integer ifav,iu=0,iv=0,ndu,ndv;
158   switch (myFavoriteIso) {
159   case GeomAbs_IsoU :
160     ifav = 1;
161     break;
162   case GeomAbs_IsoV :
163     ifav = 2;
164     break;
165   default :
166     ifav = 2;
167     break;
168   }
169   switch (myContInU) {
170   case GeomAbs_C0 :
171     iu = 0;
172     break;
173   case GeomAbs_C1 :
174     iu = 1;
175     break;
176   case GeomAbs_C2 :
177     iu = 2;
178     break;
179   default :
180     Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : UContinuity Error");
181   }
182   switch (myContInV) {
183   case GeomAbs_C0 :
184     iv = 0;
185     break;
186   case GeomAbs_C1 :
187     iv = 1;
188     break;
189   case GeomAbs_C2 :
190     iv = 2;
191     break;
192   default :
193     Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : VContinuity Error");
194   }
195   ndu = Max(myMaxDegInU+1,2*iu+2);
196   ndv = Max(myMaxDegInV+1,2*iv+2);
197   if (ndu<2*iu+2)
198     Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : UMaxDegree Error");
199   if (ndv<2*iv+2)
200     Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : VMaxDegree Error");
201   myPrecisionCode = Max(0,Min(myPrecisionCode,3));
202   AdvApp2Var_Context Conditions(ifav,iu,iv,ndu,ndv,
203                                 myPrecisionCode,
204                                 myNumSubSpaces[0],
205                                 myNumSubSpaces[1],
206                                 myNumSubSpaces[2],
207                                 my1DTolerances,
208                                 my2DTolerances,
209                                 my3DTolerances,
210                                 my1DTolOnFront,
211                                 my2DTolOnFront,
212                                 my3DTolOnFront);
213   myConditions = Conditions;
214   InitGrid(1);
215 }
216
217
218 //=======================================================================
219 //function : InitGrid
220 //purpose  : Initialisation of the approximation with regular cuttings
221 //=======================================================================
222
223 void AdvApp2Var_ApproxAFunc2Var::InitGrid(const Standard_Integer NbInt)
224 {
225   Standard_Integer iu=myConditions.UOrder(),iv=myConditions.VOrder(),iint;
226
227   AdvApp2Var_Patch M0(myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,iu,iv);
228
229   AdvApp2Var_SequenceOfPatch Net;
230   Net.Append(M0);
231
232   TColStd_SequenceOfReal TheU,TheV;
233   TheU.Append(myFirstParInU);
234   TheV.Append(myFirstParInV);
235   TheU.Append(myLastParInU);
236   TheV.Append(myLastParInV);
237
238   AdvApp2Var_Network Result(Net,TheU,TheV);
239
240
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;
250   Bag.Append(C1);
251   Bag.Append(C2);
252   Bag.Append(C3);
253   Bag.Append(C4);
254
255   AdvApp2Var_Iso V0(GeomAbs_IsoV,myFirstParInV,
256                     myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
257                     1,iu,iv);
258   AdvApp2Var_Iso V1(GeomAbs_IsoV,myLastParInV,
259                     myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
260                     2,iu,iv);
261   AdvApp2Var_Iso U0(GeomAbs_IsoU,myFirstParInU,
262                     myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
263                     3,iu,iv);
264   AdvApp2Var_Iso U1(GeomAbs_IsoU,myLastParInU,
265                     myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
266                     4,iu,iv);
267
268   AdvApp2Var_Strip BU0,BV0;
269   BU0.Append(V0);
270   BU0.Append(V1);
271   BV0.Append(U0);
272   BV0.Append(U1);
273
274   AdvApp2Var_SequenceOfStrip UStrip,VStrip;
275   UStrip.Append(BU0);
276   VStrip.Append(BV0);
277
278   AdvApp2Var_Framework Constraints(Bag,UStrip,VStrip);
279
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);
288   }
289   myResult = Result;
290   myConstraints = Constraints;
291 }
292
293 //=======================================================================
294 //function : Perform
295 //purpose  : Computation of the approximation
296 //=======================================================================
297
298 void AdvApp2Var_ApproxAFunc2Var::Perform(const AdvApprox_Cutting& UChoice,
299                                          const AdvApprox_Cutting& VChoice,
300                                          const AdvApp2Var_EvaluatorFunc2Var& Func)
301 {
302   ComputePatches(UChoice,VChoice,Func);
303   myHasResult = myDone = Standard_True;
304   Compute3DErrors();
305 }
306
307 //=======================================================================
308 //function : Perform
309 //purpose  : Computation of the approximation
310 //=======================================================================
311
312 void AdvApp2Var_ApproxAFunc2Var::Perform(const AdvApprox_Cutting& UChoice,
313                                          const AdvApprox_Cutting& VChoice,
314                                          const AdvApp2Var_EvaluatorFunc2Var& Func,
315                                          const AdvApp2Var_Criterion& Crit)
316 {
317   ComputePatches(UChoice,VChoice,Func,Crit);
318   myHasResult = myDone = Standard_True;
319   Compute3DErrors();
320   ComputeCritError();
321 }
322
323 //=======================================================================
324 //function : ComputePatches
325 //purpose  : Computation of the polynomial approximations
326 //=======================================================================
327
328 void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice,
329                                                 const AdvApprox_Cutting& VChoice,
330                                          const AdvApp2Var_EvaluatorFunc2Var& Func)
331 {
332   Standard_Real Udec, Vdec;
333   Standard_Boolean Umore, Vmore;
334   Standard_Integer NbPatch, NbU, NbV, NumDec;
335   Standard_Integer FirstNA;
336
337   while (myResult.FirstNotApprox(FirstNA)) {
338
339 // complete the set of constraints 
340     ComputeConstraints(UChoice, VChoice, Func);
341
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");
348     }
349
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();
354     NbPatch = NbU*NbV;
355     Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(),Udec);
356     Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(),Vdec);
357
358     NumDec = 0;
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;
366     }
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;
372     }
373
374 // approximation of the square
375     myResult(FirstNA).MakeApprox(myConditions,myConstraints,NumDec);
376
377     if ( ! myResult(FirstNA).IsApproximated() ) {
378       switch (myResult(FirstNA).CutSense()) {
379       case 0 :
380 //      It is not possible to cut : the result is preserved
381         if ( myResult(FirstNA).HasResult()) {
382           myResult(FirstNA).OverwriteApprox();
383         }
384         else {
385           myHasResult =  myDone = Standard_False;
386           Standard_ConstructionError::Raise
387               ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
388         }
389         break;
390       case 1 :
391 //      It is necessary to cut in U
392         myResult.UpdateInU(Udec);
393         myConstraints.UpdateInU(Udec);
394         break;
395       case 2 :
396 //      It is necessary to cut in V
397         myResult.UpdateInV(Vdec);
398         myConstraints.UpdateInV(Vdec);
399         break;
400       case 3 :
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);
406         break;
407       default :
408         myHasResult =  myDone = Standard_False;
409         Standard_ConstructionError::Raise
410               ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
411       }
412     }
413   }
414 }
415
416 //=======================================================================
417 //function : ComputePatches
418 //purpose  : Computation of the polynomial approximations
419 //=======================================================================
420
421 void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice,
422                                          const AdvApprox_Cutting& VChoice,
423                                          const AdvApp2Var_EvaluatorFunc2Var& Func,
424                                          const AdvApp2Var_Criterion& Crit)
425 {
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;
430
431   while (myResult.FirstNotApprox(FirstNA)) {
432
433 // complete the set of constraints 
434     ComputeConstraints(UChoice, VChoice, Func, Crit);
435     if (decision>0) {
436       m0 = m1;
437       m1 = 0.;
438     }
439
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");
446     }
447
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();
452     NbPatch = NbU*NbV;
453     NbInt = NbU;
454     Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(),Udec);
455     Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(),Vdec);
456
457     NumDec = 0;
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;
465     }
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;
471     }
472
473 // approximation of the square
474     if ( CritAbs ) {
475       myResult(FirstNA).MakeApprox(myConditions,myConstraints,0);
476     }
477     else {
478       myResult(FirstNA).MakeApprox(myConditions,myConstraints,NumDec);
479     }
480     if (NumDec>=3) NumDec = NumDec - 2;
481
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;
487     }
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) {
493       NbInt++;
494       InitGrid(NbInt);
495     }
496     else {
497       switch (decision) {
498       case 0 :
499 //      Impossible to cut : the result is preserved
500         if ( myResult(FirstNA).HasResult() ) {
501           myResult(FirstNA).OverwriteApprox();
502         }
503         else {
504           myHasResult =  myDone = Standard_False;
505           Standard_ConstructionError::Raise
506             ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
507         }
508         break;
509       case 1 :
510 //      It is necessary to cut in U
511         myResult.UpdateInU(Udec);
512         myConstraints.UpdateInU(Udec);
513         break;
514       case 2 :
515 //      It is necessary to cut in V
516         myResult.UpdateInV(Vdec);
517         myConstraints.UpdateInV(Vdec);
518         break;
519       case 3 :
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);
525         break;
526         default :
527         myHasResult =  myDone = Standard_False;
528         Standard_ConstructionError::Raise
529           ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
530       }
531     }
532   }
533 }
534
535 //=======================================================================
536 //function : ComputeConstraints without Criterion
537 //purpose  : Approximation of the constraints
538 //=======================================================================
539
540 void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UChoice,
541                                          const AdvApprox_Cutting& VChoice,
542                                          const AdvApp2Var_EvaluatorFunc2Var& Func)
543 {
544   Standard_Real dec;
545   Standard_Boolean more;
546   Standard_Integer ind1, ind2, NbPatch, NbU, NbV;
547   AdvApp2Var_Iso Is;
548   Standard_Integer indN1, indN2;
549   Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
550   AdvApp2Var_Node N1(iu,iv), N2(iu,iv);
551
552   while ( myConstraints.FirstNotApprox(ind1, ind2, Is) ) {
553
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);
559
560     Is.MakeApprox(myConditions,
561                   myFirstParInU, myLastParInU,
562                   myFirstParInV, myLastParInV,
563                   Func, N1 , N2);
564
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;
570     }
571
572     else {
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);
579       }
580       else {
581         NbPatch = (NbV+1)*NbU;
582         more = VChoice.Value(Is.T0(),Is.T1(),dec);
583       }
584
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);
590         }
591         else {
592           myResult.UpdateInV(dec);
593           myConstraints.UpdateInV(dec);
594         }
595       }
596
597       else {
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; 
604         }
605         else {
606           myHasResult =  myDone = Standard_False;
607           Standard_ConstructionError::Raise
608             ("AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
609         }
610       }
611     }
612   }
613 }
614
615
616 //=======================================================================
617 //function : ComputeConstraints with Criterion
618 //purpose  : Approximation of the constraints
619 //=======================================================================
620
621 void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UChoice,
622                                          const AdvApprox_Cutting& VChoice,
623                                          const AdvApp2Var_EvaluatorFunc2Var& Func,
624                                          const AdvApp2Var_Criterion& Crit)
625 {
626   Standard_Real dec;
627   Standard_Boolean more, CritRel = (Crit.Type() == AdvApp2Var_Relative);
628   Standard_Integer ind1, ind2, NbPatch, NbU, NbV;
629   AdvApp2Var_Iso Is;
630   Standard_Integer indN1, indN2;
631   Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
632   AdvApp2Var_Node N1(iu,iv), N2(iu,iv);
633
634     while ( myConstraints.FirstNotApprox(ind1, ind2, Is) ) {
635
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);
641
642       Is.MakeApprox(myConditions,
643                     myFirstParInU, myLastParInU,
644                     myFirstParInV, myLastParInV,
645                     Func, N1 , N2);
646
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;
652       }
653
654       else {
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);
661         }
662         else {
663           NbPatch = (NbV+1)*NbU;
664           more = VChoice.Value(Is.T0(),Is.T1(),dec);
665         }
666
667 //      To force Overwrite if the criterion is Absolute
668         more = more && (CritRel);
669
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);
675           }
676           else {
677             myResult.UpdateInV(dec);
678             myConstraints.UpdateInV(dec);
679           }
680         }
681
682         else {
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;       
689           }
690           else {
691             myHasResult =  myDone = Standard_False;
692             Standard_ConstructionError::Raise
693               ("AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
694           }
695         }
696       }
697     }
698 }
699
700 //=======================================================================
701 //function : Compute3DErrors
702 //purpose  : Computation of the 3D errors
703 //=======================================================================
704
705 void AdvApp2Var_ApproxAFunc2Var::Compute3DErrors()
706 {
707
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++) {
717       error_max = 0;
718       error_moy = 0.;
719       error_U0 = 0.;
720       error_V0 = 0.;
721       error_U1 = 0.;
722       error_V1 = 0.;
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);
735       }
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);
741       if ( error_max>Tol 
742           || error_U0>F3Tol || error_U1>F4Tol 
743           || error_V0>F1Tol || error_V1>F2Tol) {
744         myDone = Standard_False;
745       }
746     }
747   }
748 }
749
750
751 //=======================================================================
752 //function : ComputeCritError
753 //purpose  : Computation of the max value of the Criterion
754 //=======================================================================
755
756 void AdvApp2Var_ApproxAFunc2Var::ComputeCritError()
757 {
758
759   Standard_Integer iesp,ipat;
760   Standard_Real crit_max;
761   if ( myNumSubSpaces[2] > 0 ) {
762     for (iesp=1;iesp<=myNumSubSpaces[2];iesp++) {
763       crit_max = 0.;
764       for (ipat=1;ipat<=myResult.NbPatch();ipat++) {
765         crit_max = Max((myResult(ipat).CritValue()),crit_max);
766       }
767       myCriterionError = crit_max;
768     }
769   }
770 }
771
772 //=======================================================================
773 //function : ConvertBS
774 //purpose  : Convertion of the approximation in BSpline Surface
775 //=======================================================================
776
777 void AdvApp2Var_ApproxAFunc2Var::ConvertBS()
778 {
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;
785
786  // Calculate resulting surfaces 
787   mySurfaces = new ( TColGeom_HArray1OfSurface) (1,  myNumSubSpaces[2]);
788
789   Standard_Integer j;
790   TColStd_Array1OfReal UKnots (1, myResult.NbPatchInU()+1);
791   for (j=1; j<=UKnots.Length(); j++) { UKnots.SetValue(j, myResult.UParameter(j)); } 
792  
793   TColStd_Array1OfReal VKnots (1, myResult.NbPatchInV()+1);
794   for (j=1; j<=VKnots.Length(); j++) { VKnots.SetValue(j, myResult.VParameter(j)); }
795
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);
805
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)); } 
812
813   Standard_Integer nmax = myResult.NbPatchInU()*myResult.NbPatchInV(),
814                    Size_eq = myConditions.ULimit() * myConditions.VLimit() * 3;
815
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);
820
821   Standard_Integer SSP, i;
822   for (SSP=1; SSP <= myNumSubSpaces[2]; SSP++) { 
823
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++) {
828         n++;
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))
833                                   ->Value(ieq));
834           icf++;
835         }
836       }
837     }
838   
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; }
844    
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() );
851   }
852 }
853
854 //=======================================================================
855 //function : MaxError
856 //purpose  : 
857 //=======================================================================
858
859 Handle(TColStd_HArray1OfReal)
860  AdvApp2Var_ApproxAFunc2Var::MaxError(const Standard_Integer Dimension) const
861 {
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 !");
866   }
867   switch (Dimension) {
868   case 1:
869     EPtr = my1DMaxError;
870     break;
871   case 2:
872     EPtr = my2DMaxError;
873     break;
874   case 3:
875     EPtr = my3DMaxError;
876     break;
877   }
878   return EPtr;
879 }
880
881 //=======================================================================
882 //function : AverageError
883 //purpose  : 
884 //=======================================================================
885
886 Handle(TColStd_HArray1OfReal)
887  AdvApp2Var_ApproxAFunc2Var::AverageError(const Standard_Integer Dimension) const 
888 {
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 !");
893   }
894   switch (Dimension) {
895   case 1:
896     EPtr = my1DAverageError;
897     break;
898   case 2:
899     EPtr = my2DAverageError;
900     break;
901   case 3:
902     EPtr = my3DAverageError;
903     break;
904   }
905   return EPtr;
906 }
907
908 //=======================================================================
909 //function : UFrontError
910 //purpose  : 
911 //=======================================================================
912
913 Handle(TColStd_HArray1OfReal)
914  AdvApp2Var_ApproxAFunc2Var::UFrontError(const Standard_Integer Dimension) const 
915 {
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 !");
920   }
921   switch (Dimension) {
922   case 1:
923     EPtr = my1DUFrontError;
924     break;
925   case 2:
926     EPtr = my2DUFrontError;
927     break;
928   case 3:
929     EPtr = my3DUFrontError;
930     break;
931   }
932   return EPtr;
933 }
934
935 //=======================================================================
936 //function : VFrontError
937 //purpose  : 
938 //=======================================================================
939
940 Handle(TColStd_HArray1OfReal)
941  AdvApp2Var_ApproxAFunc2Var::VFrontError(const Standard_Integer Dimension) const 
942 {
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 !");
947   }
948   switch (Dimension) {
949   case 1:
950     EPtr = my1DVFrontError;
951     break;
952   case 2:
953     EPtr = my2DVFrontError;
954     break;
955   case 3:
956     EPtr = my3DVFrontError;
957     break;
958   }
959   return EPtr;
960 }
961
962 //=======================================================================
963 //function : MaxError
964 //purpose  : 
965 //=======================================================================
966
967 Standard_Real
968  AdvApp2Var_ApproxAFunc2Var::MaxError(const Standard_Integer Dimension,
969                                       const Standard_Integer SSPIndex) const 
970 {
971   if (Dimension !=3 || SSPIndex !=1) {
972     Standard_OutOfRange::Raise
973       ("AdvApp2Var_ApproxAFunc2Var::MaxError: ONE Surface 3D only !");
974   }
975   Handle (TColStd_HArray1OfReal) EPtr = MaxError(Dimension);
976   return EPtr->Value(SSPIndex);
977 }
978
979 //=======================================================================
980 //function : AverageError
981 //purpose  : 
982 //=======================================================================
983
984 Standard_Real
985  AdvApp2Var_ApproxAFunc2Var::AverageError(const Standard_Integer Dimension,
986                                           const Standard_Integer SSPIndex) const 
987 {
988   if (Dimension !=3 || SSPIndex !=1) {
989     Standard_OutOfRange::Raise
990       ("AdvApp2Var_ApproxAFunc2Var::AverageError : ONE Surface 3D only !");
991   }
992   Handle (TColStd_HArray1OfReal) EPtr = AverageError(Dimension);
993   return EPtr->Value(SSPIndex);
994 }
995
996 //=======================================================================
997 //function : UFrontError
998 //purpose  : 
999 //=======================================================================
1000
1001 Standard_Real
1002  AdvApp2Var_ApproxAFunc2Var::UFrontError(const Standard_Integer Dimension,
1003                                          const Standard_Integer SSPIndex) const 
1004 {
1005   if (Dimension !=3 || SSPIndex !=1) {
1006     Standard_OutOfRange::Raise
1007       ("AdvApp2Var_ApproxAFunc2Var::UFrontError : ONE Surface 3D only !");
1008   }
1009   Handle (TColStd_HArray1OfReal) EPtr = UFrontError(Dimension);
1010   return EPtr->Value(SSPIndex);
1011 }
1012
1013 //=======================================================================
1014 //function : VFrontError
1015 //purpose  : 
1016 //=======================================================================
1017
1018 Standard_Real
1019  AdvApp2Var_ApproxAFunc2Var::VFrontError(const Standard_Integer Dimension,
1020                                          const Standard_Integer SSPIndex) const 
1021 {
1022   if (Dimension !=3 || SSPIndex !=1) {
1023     Standard_OutOfRange::Raise
1024       ("AdvApp2Var_ApproxAFunc2Var::VFrontError : ONE Surface 3D only !");
1025   }
1026   Handle (TColStd_HArray1OfReal) EPtr = VFrontError(Dimension);
1027   return EPtr->Value(SSPIndex);
1028 }
1029
1030
1031 //=======================================================================
1032 //function : CritError
1033 //purpose  : 
1034 //=======================================================================
1035
1036 Standard_Real
1037  AdvApp2Var_ApproxAFunc2Var::CritError(const Standard_Integer Dimension,
1038                                        const Standard_Integer SSPIndex) const 
1039 {
1040   if (Dimension !=3 || SSPIndex !=1) {
1041     Standard_OutOfRange::Raise
1042       ("AdvApp2Var_ApproxAFunc2Var::CritError: ONE Surface 3D only !");
1043   }
1044   return myCriterionError;
1045 }
1046
1047 //=======================================================================
1048 //function : Dump
1049 //purpose  : 
1050 //=======================================================================
1051
1052 void AdvApp2Var_ApproxAFunc2Var::Dump(Standard_OStream& o) const 
1053 {
1054   Standard_Integer iesp=1,NbKU,NbKV,ik;
1055   o<<endl;
1056   if (!myHasResult) { o<<"No result"<<endl; }
1057   else {
1058     o<<"There is a result";
1059     if (myDone) {
1060       o<<" within the requested tolerance "<<my3DTolerances->Value(iesp)<<endl;
1061     }
1062     else if (my3DMaxError->Value(iesp)>my3DTolerances->Value(iesp)) {
1063       o<<" WITHOUT the requested tolerance "<<my3DTolerances->Value(iesp)<<endl;
1064     }
1065     else {
1066       o<<" WITHOUT the requested continuities "<<endl;
1067     }
1068     o<<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;
1073     o<<endl;
1074     o<<"Degree of Bezier patches in U : "<<myDegreeInU
1075       <<"  in V : "<<myDegreeInV<<endl;
1076     o<<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;
1081     o<<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;
1087     }
1088     o<<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;
1092     }
1093     o<<endl;
1094   }
1095 }