0031004: Coding - eliminate warnings issued by gcc 9.1.0
[occt.git] / src / AdvApp2Var / AdvApp2Var_ApproxAFunc2Var.cxx
1 // Created on: 1996-07-03
2 // Created by: Joelle CHAUVET
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <AdvApp2Var_ApproxAFunc2Var.hxx>
18 #include <AdvApp2Var_EvaluatorFunc2Var.hxx>
19 #include <AdvApp2Var_Criterion.hxx>
20 #include <AdvApp2Var_Context.hxx>
21 #include <AdvApp2Var_Patch.hxx>
22 #include <AdvApp2Var_Network.hxx>
23 #include <AdvApp2Var_Node.hxx>
24 #include <AdvApp2Var_Iso.hxx>
25 #include <AdvApp2Var_Strip.hxx>
26 #include <AdvApp2Var_Framework.hxx>
27 #include <AdvApprox_Cutting.hxx>
28
29 #include <Standard_ConstructionError.hxx>
30 #include <Standard_OutOfRange.hxx>
31 #include <TColStd_HArray1OfInteger.hxx>
32 #include <TColStd_HArray2OfInteger.hxx>
33 #include <TColStd_HArray1OfReal.hxx>
34 #include <TColStd_HArray2OfReal.hxx>
35
36 #include <gp_XY.hxx>
37 #include <gp_Pnt2d.hxx>
38 #include <gp_Pnt.hxx>
39 #include <TColgp_HArray2OfPnt.hxx>
40
41 #include <Convert_GridPolynomialToPoles.hxx>
42
43 #include <Geom_BezierSurface.hxx>
44 #include <Geom_BSplineSurface.hxx>
45
46
47 //=======================================================================
48 //function : AdvApp2Var_ApproxAFunc2Var
49 //purpose  : 
50 //=======================================================================
51
52 AdvApp2Var_ApproxAFunc2Var::AdvApp2Var_ApproxAFunc2Var(
53                            const Standard_Integer Num1DSS,
54                            const Standard_Integer Num2DSS,
55                            const Standard_Integer Num3DSS,
56                            const Handle(TColStd_HArray1OfReal)& OneDTol,
57                            const Handle(TColStd_HArray1OfReal)& TwoDTol,
58                            const Handle(TColStd_HArray1OfReal)& ThreeDTol,
59                            const Handle(TColStd_HArray2OfReal)& OneDTolFr,
60                            const Handle(TColStd_HArray2OfReal)& TwoDTolFr,
61                            const Handle(TColStd_HArray2OfReal)& ThreeDTolFr,
62                            const Standard_Real FirstInU,
63                            const Standard_Real LastInU,
64                            const Standard_Real FirstInV,
65                            const Standard_Real LastInV,
66                            const GeomAbs_IsoType FavorIso,
67                            const GeomAbs_Shape ContInU,
68                            const GeomAbs_Shape ContInV,
69                            const Standard_Integer PrecisCode,
70                            const Standard_Integer MaxDegInU,
71                            const Standard_Integer MaxDegInV,
72                            const Standard_Integer MaxPatch,
73                            const AdvApp2Var_EvaluatorFunc2Var& Func,
74                            AdvApprox_Cutting& UChoice,
75                            AdvApprox_Cutting& VChoice)
76 : my1DTolerances  (OneDTol),
77   my2DTolerances  (TwoDTol),
78   my3DTolerances  (ThreeDTol),
79   my1DTolOnFront  (OneDTolFr),
80   my2DTolOnFront  (TwoDTolFr),
81   my3DTolOnFront  (ThreeDTolFr),
82   myFirstParInU   (FirstInU),
83   myLastParInU    (LastInU),
84   myFirstParInV   (FirstInV),
85   myLastParInV    (LastInV),
86   myFavoriteIso   (FavorIso),
87   myContInU       (ContInU),
88   myContInV       (ContInV),
89   myPrecisionCode (PrecisCode),
90   myMaxDegInU     (MaxDegInU),
91   myMaxDegInV     (MaxDegInV),
92   myMaxPatches    (MaxPatch),
93   myDone          (Standard_False),
94   myHasResult     (Standard_False),
95   myDegreeInU     (0),
96   myDegreeInV     (0),
97   myCriterionError(0.0)
98 {
99   myNumSubSpaces[0] = Num1DSS;
100   myNumSubSpaces[1] = Num2DSS;
101   myNumSubSpaces[2] = Num3DSS;
102
103   Init();
104   Perform(UChoice, VChoice, Func);
105   ConvertBS();
106 }
107
108 //=======================================================================
109 //function : AdvApp2Var_ApproxAFunc2Var
110 //purpose  : 
111 //=======================================================================
112
113  AdvApp2Var_ApproxAFunc2Var::AdvApp2Var_ApproxAFunc2Var(
114                       const Standard_Integer Num1DSS,
115                       const Standard_Integer Num2DSS,
116                       const Standard_Integer Num3DSS,
117                       const Handle(TColStd_HArray1OfReal)& OneDTol,
118                       const Handle(TColStd_HArray1OfReal)& TwoDTol,
119                       const Handle(TColStd_HArray1OfReal)& ThreeDTol,
120                       const Handle(TColStd_HArray2OfReal)& OneDTolFr,
121                       const Handle(TColStd_HArray2OfReal)& TwoDTolFr,
122                       const Handle(TColStd_HArray2OfReal)& ThreeDTolFr,
123                       const Standard_Real FirstInU,
124                       const Standard_Real LastInU,
125                       const Standard_Real FirstInV,
126                       const Standard_Real LastInV,
127                       const GeomAbs_IsoType FavorIso,
128                       const GeomAbs_Shape ContInU,
129                       const GeomAbs_Shape ContInV,
130                       const Standard_Integer PrecisCode,
131                       const Standard_Integer MaxDegInU,
132                       const Standard_Integer MaxDegInV,
133                       const Standard_Integer MaxPatch,
134                       const AdvApp2Var_EvaluatorFunc2Var& Func,
135                       const AdvApp2Var_Criterion& Crit,
136                       AdvApprox_Cutting& UChoice,
137                       AdvApprox_Cutting& VChoice)
138 : my1DTolerances  (OneDTol),
139   my2DTolerances  (TwoDTol),
140   my3DTolerances  (ThreeDTol),
141   my1DTolOnFront  (OneDTolFr),
142   my2DTolOnFront  (TwoDTolFr),
143   my3DTolOnFront  (ThreeDTolFr),
144   myFirstParInU   (FirstInU),
145   myLastParInU    (LastInU),
146   myFirstParInV   (FirstInV),
147   myLastParInV    (LastInV),
148   myFavoriteIso   (FavorIso),
149   myContInU       (ContInU),
150   myContInV       (ContInV),
151   myPrecisionCode (PrecisCode),
152   myMaxDegInU     (MaxDegInU),
153   myMaxDegInV     (MaxDegInV),
154   myMaxPatches    (MaxPatch),
155   myDone          (Standard_False),
156   myHasResult     (Standard_False),
157   myDegreeInU     (0),
158   myDegreeInV     (0),
159   myCriterionError(0.0)
160 {
161   myNumSubSpaces[0] = Num1DSS;
162   myNumSubSpaces[1] = Num2DSS;
163   myNumSubSpaces[2] = Num3DSS;
164
165   Init();
166   Perform(UChoice, VChoice, Func, Crit);
167   ConvertBS();
168 }
169
170 //=======================================================================
171 //function : Init
172 //purpose  : Initialisation of the approximation
173 //=======================================================================
174
175 void AdvApp2Var_ApproxAFunc2Var::Init()
176 {
177   Standard_Integer ifav,iu=0,iv=0,ndu,ndv;
178   switch (myFavoriteIso) {
179   case GeomAbs_IsoU :
180     ifav = 1;
181     break;
182   case GeomAbs_IsoV :
183     ifav = 2;
184     break;
185   default :
186     ifav = 2;
187     break;
188   }
189   switch (myContInU) {
190   case GeomAbs_C0 :
191     iu = 0;
192     break;
193   case GeomAbs_C1 :
194     iu = 1;
195     break;
196   case GeomAbs_C2 :
197     iu = 2;
198     break;
199   default :
200     throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : UContinuity Error");
201   }
202   switch (myContInV) {
203   case GeomAbs_C0 :
204     iv = 0;
205     break;
206   case GeomAbs_C1 :
207     iv = 1;
208     break;
209   case GeomAbs_C2 :
210     iv = 2;
211     break;
212   default :
213     throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : VContinuity Error");
214   }
215   ndu = Max(myMaxDegInU+1,2*iu+2);
216   ndv = Max(myMaxDegInV+1,2*iv+2);
217   if (ndu<2*iu+2)
218     throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : UMaxDegree Error");
219   if (ndv<2*iv+2)
220     throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : VMaxDegree Error");
221   myPrecisionCode = Max(0,Min(myPrecisionCode,3));
222   AdvApp2Var_Context Conditions(ifav,iu,iv,ndu,ndv,
223                                 myPrecisionCode,
224                                 myNumSubSpaces[0],
225                                 myNumSubSpaces[1],
226                                 myNumSubSpaces[2],
227                                 my1DTolerances,
228                                 my2DTolerances,
229                                 my3DTolerances,
230                                 my1DTolOnFront,
231                                 my2DTolOnFront,
232                                 my3DTolOnFront);
233   myConditions = Conditions;
234   InitGrid(1);
235 }
236
237
238 //=======================================================================
239 //function : InitGrid
240 //purpose  : Initialisation of the approximation with regular cuttings
241 //=======================================================================
242
243 void AdvApp2Var_ApproxAFunc2Var::InitGrid(const Standard_Integer NbInt)
244 {
245   Standard_Integer iu=myConditions.UOrder(),iv=myConditions.VOrder(),iint;
246
247   Handle(AdvApp2Var_Patch) M0 = new AdvApp2Var_Patch (myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,iu,iv);
248
249   AdvApp2Var_SequenceOfPatch Net;
250   Net.Append(M0);
251
252   TColStd_SequenceOfReal TheU,TheV;
253   TheU.Append(myFirstParInU);
254   TheV.Append(myFirstParInV);
255   TheU.Append(myLastParInU);
256   TheV.Append(myLastParInV);
257
258   AdvApp2Var_Network Result(Net,TheU,TheV);
259
260
261   gp_XY UV1(myFirstParInU,myFirstParInV);
262   Handle(AdvApp2Var_Node) C1 = new AdvApp2Var_Node (UV1,iu,iv);
263   gp_XY UV2(myLastParInU,myFirstParInV);
264   Handle(AdvApp2Var_Node) C2 = new AdvApp2Var_Node (UV2,iu,iv);
265   gp_XY UV4(myLastParInU,myLastParInV);
266   Handle(AdvApp2Var_Node) C4 = new AdvApp2Var_Node (UV4,iu,iv);
267   gp_XY UV3(myFirstParInU,myLastParInV);
268   Handle(AdvApp2Var_Node) C3 = new AdvApp2Var_Node (UV3,iu,iv);
269   AdvApp2Var_SequenceOfNode Bag;
270   Bag.Append(C1);
271   Bag.Append(C2);
272   Bag.Append(C3);
273   Bag.Append(C4);
274
275   Handle(AdvApp2Var_Iso) V0 = new AdvApp2Var_Iso (GeomAbs_IsoV,myFirstParInV,
276                     myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
277                     1,iu,iv);
278   Handle(AdvApp2Var_Iso) V1 = new AdvApp2Var_Iso (GeomAbs_IsoV,myLastParInV,
279                     myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
280                     2,iu,iv);
281   Handle(AdvApp2Var_Iso) U0 = new AdvApp2Var_Iso (GeomAbs_IsoU,myFirstParInU,
282                     myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
283                     3,iu,iv);
284   Handle(AdvApp2Var_Iso) U1 = new AdvApp2Var_Iso (GeomAbs_IsoU,myLastParInU,
285                     myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
286                     4,iu,iv);
287
288   AdvApp2Var_Strip BU0,BV0;
289   BU0.Append(V0);
290   BU0.Append(V1);
291   BV0.Append(U0);
292   BV0.Append(U1);
293
294   AdvApp2Var_SequenceOfStrip UStrip,VStrip;
295   UStrip.Append(BU0);
296   VStrip.Append(BV0);
297
298   AdvApp2Var_Framework Constraints(Bag,UStrip,VStrip);
299
300 // regular cutting if NbInt>1
301   Standard_Real deltu = (myLastParInU-myFirstParInU)/NbInt,
302                 deltv = (myLastParInV-myFirstParInV)/NbInt;
303   for (iint=1;iint<=NbInt-1;iint++) {
304     Result.UpdateInU(myFirstParInU+iint*deltu);
305     Constraints.UpdateInU(myFirstParInU+iint*deltu);
306     Result.UpdateInV(myFirstParInV+iint*deltv);
307     Constraints.UpdateInV(myFirstParInV+iint*deltv);
308   }
309   myResult = Result;
310   myConstraints = Constraints;
311 }
312
313 //=======================================================================
314 //function : Perform
315 //purpose  : Computation of the approximation
316 //=======================================================================
317
318 void AdvApp2Var_ApproxAFunc2Var::Perform(const AdvApprox_Cutting& UChoice,
319                                          const AdvApprox_Cutting& VChoice,
320                                          const AdvApp2Var_EvaluatorFunc2Var& Func)
321 {
322   ComputePatches(UChoice,VChoice,Func);
323   myHasResult = myDone = Standard_True;
324   Compute3DErrors();
325 }
326
327 //=======================================================================
328 //function : Perform
329 //purpose  : Computation of the approximation
330 //=======================================================================
331
332 void AdvApp2Var_ApproxAFunc2Var::Perform(const AdvApprox_Cutting& UChoice,
333                                          const AdvApprox_Cutting& VChoice,
334                                          const AdvApp2Var_EvaluatorFunc2Var& Func,
335                                          const AdvApp2Var_Criterion& Crit)
336 {
337   ComputePatches(UChoice,VChoice,Func,Crit);
338   myHasResult = myDone = Standard_True;
339   Compute3DErrors();
340   ComputeCritError();
341 }
342
343 //=======================================================================
344 //function : ComputePatches
345 //purpose  : Computation of the polynomial approximations
346 //=======================================================================
347
348 void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice,
349                                                 const AdvApprox_Cutting& VChoice,
350                                          const AdvApp2Var_EvaluatorFunc2Var& Func)
351 {
352   Standard_Real Udec, Vdec;
353   Standard_Boolean Umore, Vmore;
354   Standard_Integer NbPatch, NbU, NbV, NumDec;
355   Standard_Integer FirstNA;
356
357   while (myResult.FirstNotApprox(FirstNA)) {
358
359 // complete the set of constraints 
360     ComputeConstraints(UChoice, VChoice, Func);
361
362 // discretization of constraints relative to the square
363     myResult(FirstNA).Discretise(myConditions,myConstraints,Func);
364     if ( ! myResult(FirstNA).IsDiscretised() ) {
365       myHasResult =  myDone = Standard_False;
366       throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Discretisation Error");
367     }
368
369 // calculate the number and the type of autorized cuts
370 // depending on the max number of squares and the validity of next cuts.
371     NbU = myResult.NbPatchInU();
372     NbV = myResult.NbPatchInV();
373     NbPatch = NbU*NbV;
374     Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(),Udec);
375     Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(),Vdec);
376
377     NumDec = 0;
378     if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)>myMaxPatches)
379          && (Umore) ) NumDec = 1;
380     if ( ((NbPatch+NbV)>myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches) 
381          && (Vmore) ) NumDec = 2;
382     if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches) ) {
383       if ( Umore ) NumDec = 3;
384       if ( (NbV>NbU) && Vmore ) NumDec = 4;
385     }
386     if ( (NbU+1)*(NbV+1)<=myMaxPatches ) {
387       if ( !Umore && !Vmore ) NumDec=0;
388       if ( Umore && !Vmore ) NumDec=3;
389       if ( !Umore && Vmore ) NumDec=4;
390       if ( Umore && Vmore ) NumDec=5;
391     }
392
393 // approximation of the square
394     myResult(FirstNA).MakeApprox(myConditions,myConstraints,NumDec);
395
396     if ( ! myResult(FirstNA).IsApproximated() ) {
397       switch (myResult(FirstNA).CutSense()) {
398       case 0 :
399 //      It is not possible to cut : the result is preserved
400         if ( myResult(FirstNA).HasResult()) {
401           myResult(FirstNA).OverwriteApprox();
402         }
403         else {
404           myHasResult =  myDone = Standard_False;
405           throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
406         }
407         break;
408       case 1 :
409 //      It is necessary to cut in U
410         myResult.UpdateInU(Udec);
411         myConstraints.UpdateInU(Udec);
412         break;
413       case 2 :
414 //      It is necessary to cut in V
415         myResult.UpdateInV(Vdec);
416         myConstraints.UpdateInV(Vdec);
417         break;
418       case 3 :
419 //      It is necesary to cut in U and V
420         myResult.UpdateInU(Udec);
421         myConstraints.UpdateInU(Udec);
422         myResult.UpdateInV(Vdec);
423         myConstraints.UpdateInV(Vdec);
424         break;
425       default :
426         myHasResult =  myDone = Standard_False;
427         throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
428       }
429     }
430   }
431 }
432
433 //=======================================================================
434 //function : ComputePatches
435 //purpose  : Computation of the polynomial approximations
436 //=======================================================================
437
438 void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice,
439                                          const AdvApprox_Cutting& VChoice,
440                                          const AdvApp2Var_EvaluatorFunc2Var& Func,
441                                          const AdvApp2Var_Criterion& Crit)
442 {
443   Standard_Real Udec, Vdec, CritValue, m1=0.;
444   Standard_Boolean Umore, Vmore, CritAbs = (Crit.Type() == AdvApp2Var_Absolute);
445   Standard_Integer NbPatch, NbU, NbV, NbInt, NumDec;
446   Standard_Integer FirstNA, decision=0;
447
448   while (myResult.FirstNotApprox(FirstNA)) {
449
450 // complete the set of constraints 
451     ComputeConstraints(UChoice, VChoice, Func, Crit);
452     if (decision>0) {
453       m1 = 0.;
454     }
455
456 // discretize the constraints relative to the square
457     myResult(FirstNA).Discretise(myConditions,myConstraints,Func);
458     if ( ! myResult(FirstNA).IsDiscretised() ) {
459       myHasResult =  myDone = Standard_False;
460       throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Discretisation Error");
461     }
462
463 // calculate the number and type of autorized cuts
464 // depending on the max number of squares and the validity of next cuts
465     NbU = myResult.NbPatchInU();
466     NbV = myResult.NbPatchInV();
467     NbPatch = NbU*NbV;
468     NbInt = NbU;
469     Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(),Udec);
470     Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(),Vdec);
471
472     NumDec = 0;
473     if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)>myMaxPatches)
474          && (Umore) ) NumDec = 1;
475     if ( ((NbPatch+NbV)>myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches) 
476          && (Vmore) ) NumDec = 2;
477     if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches) ) {
478       if ( Umore ) NumDec = 3;
479       if ( (NbV>NbU) && Vmore ) NumDec = 4;
480     }
481     if ( (NbU+1)*(NbV+1)<=myMaxPatches ) {
482       if ( !Umore && !Vmore ) NumDec=0;
483       if ( Umore && !Vmore ) NumDec=1;
484       if ( !Umore && Vmore ) NumDec=2;
485       if ( Umore && Vmore ) NumDec=5;
486     }
487
488 // approximation of the square
489     if ( CritAbs ) {
490       myResult(FirstNA).MakeApprox(myConditions,myConstraints,0);
491     }
492     else {
493       myResult(FirstNA).MakeApprox(myConditions,myConstraints,NumDec);
494     }
495     if (NumDec>=3) NumDec = NumDec - 2;
496
497 // evaluation of the criterion on the square
498     if ( myResult(FirstNA).HasResult() ) {
499       Crit.Value(myResult(FirstNA),myConditions);
500       CritValue = myResult(FirstNA).CritValue();
501       if (m1<CritValue) m1 = CritValue;
502     }
503 // is it necessary to cut ?
504     decision = myResult(FirstNA).CutSense(Crit,NumDec);
505     Standard_Boolean Regular = (Crit.Repartition() ==  AdvApp2Var_Regular);
506 //    Standard_Boolean Regular = Standard_True;
507     if (Regular && decision>0) {
508       NbInt++;
509       InitGrid(NbInt);
510     }
511     else {
512       switch (decision) {
513       case 0 :
514 //      Impossible to cut : the result is preserved
515         if ( myResult(FirstNA).HasResult() ) {
516           myResult(FirstNA).OverwriteApprox();
517         }
518         else {
519           myHasResult =  myDone = Standard_False;
520           throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
521         }
522         break;
523       case 1 :
524 //      It is necessary to cut in U
525         myResult.UpdateInU(Udec);
526         myConstraints.UpdateInU(Udec);
527         break;
528       case 2 :
529 //      It is necessary to cut in V
530         myResult.UpdateInV(Vdec);
531         myConstraints.UpdateInV(Vdec);
532         break;
533       case 3 :
534 //      It is necessary to cut in U and V
535         myResult.UpdateInU(Udec);
536         myConstraints.UpdateInU(Udec);
537         myResult.UpdateInV(Vdec);
538         myConstraints.UpdateInV(Vdec);
539         break;
540         default :
541         myHasResult =  myDone = Standard_False;
542         throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
543       }
544     }
545   }
546 }
547
548 //=======================================================================
549 //function : ComputeConstraints without Criterion
550 //purpose  : Approximation of the constraints
551 //=======================================================================
552
553 void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UChoice,
554                                          const AdvApprox_Cutting& VChoice,
555                                          const AdvApp2Var_EvaluatorFunc2Var& Func)
556 {
557   Standard_Real dec;
558   Standard_Boolean more;
559   Standard_Integer ind1, ind2, NbPatch, NbU, NbV;
560   Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
561   AdvApp2Var_Node N1(iu,iv), N2(iu,iv);
562
563   for (Handle(AdvApp2Var_Iso) anIso = myConstraints.FirstNotApprox(ind1, ind2); !anIso.IsNull(); anIso = myConstraints.FirstNotApprox(ind1, ind2))
564   {
565     // approximation of iso and calculation of constraints at extremities
566     const Standard_Integer indN1 = myConstraints.FirstNode(anIso->Type(),ind1,ind2);
567     N1 = *myConstraints.Node(indN1);
568     const Standard_Integer indN2 = myConstraints.LastNode(anIso->Type(),ind1,ind2);
569     N2 = *myConstraints.Node(indN2);
570
571     // note that old code attempted to make copy of anIso here (but copy was incomplete)
572     anIso->MakeApprox (myConditions,
573                        myFirstParInU, myLastParInU,
574                        myFirstParInV, myLastParInV,
575                        Func, N1 , N2);
576     if (anIso->IsApproximated())
577     {
578       // iso is approached at the required tolerance
579       myConstraints.ChangeIso(ind1,ind2,anIso);
580       *myConstraints.Node(indN1) = N1;
581       *myConstraints.Node(indN2) = N2;
582     }
583     else
584     {
585       // Approximation is not satisfactory
586       NbU = myResult.NbPatchInU();
587       NbV = myResult.NbPatchInV();
588       if (anIso->Type()==GeomAbs_IsoV)
589       {
590         NbPatch = (NbU+1)*NbV;
591         more = UChoice.Value(anIso->T0(), anIso->T1(), dec);
592       }
593       else
594       {
595         NbPatch = (NbV+1)*NbU;
596         more = VChoice.Value(anIso->T0(),anIso->T1(),dec);
597       }
598
599       if (NbPatch<=myMaxPatches && more)
600       {
601         // It is possible to cut iso
602         if (anIso->Type()==GeomAbs_IsoV)
603         {
604           myResult.UpdateInU(dec);
605           myConstraints.UpdateInU(dec);
606         }
607         else
608         {
609           myResult.UpdateInV(dec);
610           myConstraints.UpdateInV(dec);
611         }
612       }
613       else
614       {
615         // It is not possible to cut : the result is preserved
616         if (anIso->HasResult())
617         {
618           anIso->OverwriteApprox();
619           myConstraints.ChangeIso(ind1,ind2,anIso);
620           *myConstraints.Node(indN1) = N1;
621           *myConstraints.Node(indN2) = N2;
622         }
623         else
624         {
625           myHasResult =  myDone = Standard_False;
626           throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
627         }
628       }
629     }
630   }
631 }
632
633
634 //=======================================================================
635 //function : ComputeConstraints with Criterion
636 //purpose  : Approximation of the constraints
637 //=======================================================================
638
639 void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UChoice,
640                                          const AdvApprox_Cutting& VChoice,
641                                          const AdvApp2Var_EvaluatorFunc2Var& Func,
642                                          const AdvApp2Var_Criterion& Crit)
643 {
644   Standard_Real dec;
645   Standard_Boolean more, CritRel = (Crit.Type() == AdvApp2Var_Relative);
646   Standard_Integer ind1, ind2, NbPatch, NbU, NbV;
647   Standard_Integer indN1, indN2;
648   Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
649   AdvApp2Var_Node N1(iu,iv), N2(iu,iv);
650
651   for (Handle(AdvApp2Var_Iso) anIso = myConstraints.FirstNotApprox(ind1, ind2); !anIso.IsNull(); anIso = myConstraints.FirstNotApprox(ind1, ind2))
652   {
653     // approximation of the iso and calculation of constraints at the extremities
654     indN1 = myConstraints.FirstNode(anIso->Type(),ind1,ind2);
655     N1 = *myConstraints.Node(indN1);
656     indN2 = myConstraints.LastNode(anIso->Type(),ind1,ind2);
657     N2 = *myConstraints.Node(indN2);
658
659     // note that old code attempted to make copy of anIso here (but copy was incomplete)
660     anIso->MakeApprox (myConditions,
661                        myFirstParInU, myLastParInU,
662                        myFirstParInV, myLastParInV,
663                        Func, N1 , N2);
664
665     if (anIso->IsApproximated())
666     {
667       // iso is approached at the required tolerance
668       myConstraints.ChangeIso(ind1,ind2,anIso);
669       *myConstraints.Node(indN1) = N1;
670       *myConstraints.Node(indN2) = N2;
671     }
672     else
673     {
674       // Approximation is not satisfactory
675       NbU = myResult.NbPatchInU();
676       NbV = myResult.NbPatchInV();
677       if (anIso->Type()==GeomAbs_IsoV)
678       {
679         NbPatch = (NbU+1)*NbV;
680         more = UChoice.Value(anIso->T0(),anIso->T1(),dec);
681       }
682       else
683       {
684         NbPatch = (NbV+1)*NbU;
685         more = VChoice.Value(anIso->T0(),anIso->T1(),dec);
686       }
687
688       // To force Overwrite if the criterion is Absolute
689       more = more && (CritRel);
690
691       if (NbPatch<=myMaxPatches && more)
692       {
693         // It is possible to cut iso
694         if (anIso->Type()==GeomAbs_IsoV)
695         {
696           myResult.UpdateInU(dec);
697           myConstraints.UpdateInU(dec);
698         }
699         else
700         {
701           myResult.UpdateInV(dec);
702           myConstraints.UpdateInV(dec);
703         }
704       }
705       else
706       {
707         // It is not possible to cut: the result is preserved
708         if (anIso->HasResult())
709         {
710           anIso->OverwriteApprox();
711           myConstraints.ChangeIso(ind1,ind2,anIso);
712           *myConstraints.Node(indN1) = N1;
713           *myConstraints.Node(indN2) = N2;
714         }
715         else
716         {
717           myHasResult =  myDone = Standard_False;
718           throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
719         }
720       }
721     }
722   }
723 }
724
725 //=======================================================================
726 //function : Compute3DErrors
727 //purpose  : Computation of the 3D errors
728 //=======================================================================
729
730 void AdvApp2Var_ApproxAFunc2Var::Compute3DErrors()
731 {
732
733   Standard_Integer iesp,ipat;
734   Standard_Real error_max,error_moy,error_U0,error_V0,error_U1,error_V1;
735   Standard_Real Tol,F1Tol,F2Tol,F3Tol,F4Tol;
736   if ( myNumSubSpaces[2] > 0 ) {
737     my3DMaxError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
738     my3DAverageError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
739     my3DUFrontError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
740     my3DVFrontError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
741     for (iesp=1;iesp<=myNumSubSpaces[2];iesp++) {
742       error_max = 0;
743       error_moy = 0.;
744       error_U0 = 0.;
745       error_V0 = 0.;
746       error_U1 = 0.;
747       error_V1 = 0.;
748       Tol = my3DTolerances->Value(iesp);
749       F1Tol = my3DTolOnFront->Value(iesp,1);
750       F2Tol = my3DTolOnFront->Value(iesp,2);
751       F3Tol = my3DTolOnFront->Value(iesp,3);
752       F4Tol = my3DTolOnFront->Value(iesp,4);
753       for (ipat=1;ipat<=myResult.NbPatch();ipat++) {
754         error_max = Max((myResult(ipat).MaxErrors())->Value(iesp),error_max);
755         error_U0 = Max((myResult(ipat).IsoErrors())->Value(iesp,3),error_U0);
756         error_U1 = Max((myResult(ipat).IsoErrors())->Value(iesp,4),error_U1);
757         error_V0 = Max((myResult(ipat).IsoErrors())->Value(iesp,1),error_V0);
758         error_V1 = Max((myResult(ipat).IsoErrors())->Value(iesp,2),error_V1);
759         error_moy += (myResult(ipat).AverageErrors())->Value(iesp);
760       }
761       my3DMaxError->SetValue(iesp,error_max);
762       my3DUFrontError->SetValue(iesp,Max(error_U0,error_U1));
763       my3DVFrontError->SetValue(iesp,Max(error_V0,error_V1));
764       error_moy /= (Standard_Real) myResult.NbPatch();
765       my3DAverageError->SetValue(iesp,error_moy);
766       if ( error_max>Tol 
767           || error_U0>F3Tol || error_U1>F4Tol 
768           || error_V0>F1Tol || error_V1>F2Tol) {
769         myDone = Standard_False;
770       }
771     }
772   }
773 }
774
775
776 //=======================================================================
777 //function : ComputeCritError
778 //purpose  : Computation of the max value of the Criterion
779 //=======================================================================
780
781 void AdvApp2Var_ApproxAFunc2Var::ComputeCritError()
782 {
783
784   Standard_Integer iesp,ipat;
785   Standard_Real crit_max;
786   if ( myNumSubSpaces[2] > 0 ) {
787     for (iesp=1;iesp<=myNumSubSpaces[2];iesp++) {
788       crit_max = 0.;
789       for (ipat=1;ipat<=myResult.NbPatch();ipat++) {
790         crit_max = Max((myResult(ipat).CritValue()),crit_max);
791       }
792       myCriterionError = crit_max;
793     }
794   }
795 }
796
797 //=======================================================================
798 //function : ConvertBS
799 //purpose  : Convertion of the approximation in BSpline Surface
800 //=======================================================================
801
802 void AdvApp2Var_ApproxAFunc2Var::ConvertBS()
803 {
804  // Homogeneization of degrees
805   Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
806   Standard_Integer ncfu = myConditions.ULimit(), ncfv = myConditions.VLimit();
807   myResult.SameDegree(iu,iv,ncfu,ncfv);
808   myDegreeInU = ncfu - 1;
809   myDegreeInV = ncfv - 1;
810
811  // Calculate resulting surfaces 
812   mySurfaces = new ( TColGeom_HArray1OfSurface) (1,  myNumSubSpaces[2]);
813
814   Standard_Integer j;
815   TColStd_Array1OfReal UKnots (1, myResult.NbPatchInU()+1);
816   for (j=1; j<=UKnots.Length(); j++) { UKnots.SetValue(j, myResult.UParameter(j)); } 
817  
818   TColStd_Array1OfReal VKnots (1, myResult.NbPatchInV()+1);
819   for (j=1; j<=VKnots.Length(); j++) { VKnots.SetValue(j, myResult.VParameter(j)); }
820
821  // Prepare data for conversion grid of polynoms --> poles
822   Handle(TColStd_HArray1OfReal) Uint1 = 
823     new (TColStd_HArray1OfReal) (1,2);
824   Uint1->SetValue(1, -1);
825   Uint1->SetValue(2, 1);
826   Handle(TColStd_HArray1OfReal) Vint1 = 
827     new (TColStd_HArray1OfReal) (1,2);
828   Vint1->SetValue(1, -1);
829   Vint1->SetValue(2, 1);
830
831   Handle(TColStd_HArray1OfReal) Uint2 = 
832     new (TColStd_HArray1OfReal) (1,myResult.NbPatchInU()+1);
833   for (j=1; j<=Uint2->Length(); j++) { Uint2->SetValue(j, myResult.UParameter(j)); } 
834   Handle(TColStd_HArray1OfReal) Vint2 = 
835     new (TColStd_HArray1OfReal) (1,myResult.NbPatchInV()+1);
836   for (j=1; j<=Vint2->Length(); j++) { Vint2->SetValue(j, myResult.VParameter(j)); } 
837
838   Standard_Integer nmax = myResult.NbPatchInU()*myResult.NbPatchInV(),
839                    Size_eq = myConditions.ULimit() * myConditions.VLimit() * 3;
840
841   Handle(TColStd_HArray2OfInteger) NbCoeff = 
842     new (TColStd_HArray2OfInteger) (1, nmax, 1, 2);
843   Handle(TColStd_HArray1OfReal) Poly = 
844     new (TColStd_HArray1OfReal) (1, nmax * Size_eq);
845
846   Standard_Integer SSP, i;
847   for (SSP=1; SSP <= myNumSubSpaces[2]; SSP++) { 
848
849     // Creation of the grid of polynoms
850     Standard_Integer n=0,icf=1,ieq;
851     for (j=1; j<=myResult.NbPatchInV(); j++) {
852       for (i=1; i<=myResult.NbPatchInU(); i++) {
853         n++;
854         NbCoeff->SetValue(n,1, myResult.Patch(i,j).NbCoeffInU());
855         NbCoeff->SetValue(n,2, myResult.Patch(i,j).NbCoeffInV());
856         for (ieq=1; ieq<=Size_eq;ieq++) {
857           Poly->SetValue(icf,(myResult.Patch(i,j).Coefficients(SSP,myConditions))
858                                   ->Value(ieq));
859           icf++;
860         }
861       }
862     }
863   
864     // Conversion into poles
865     Convert_GridPolynomialToPoles CvP (myResult.NbPatchInU(),myResult.NbPatchInV(),
866                                        iu,iv,myMaxDegInU,myMaxDegInV,NbCoeff,
867                                        Poly,Uint1,Vint1,Uint2,Vint2);
868     if ( !CvP.IsDone() ) { myDone = Standard_False; }
869    
870     // Conversion into BSpline
871     mySurfaces->ChangeValue(SSP) = new (Geom_BSplineSurface) 
872         ( CvP.Poles()->Array2(),   
873           CvP.UKnots()->Array1(),  CvP.VKnots()->Array1(),
874           CvP.UMultiplicities()->Array1(), CvP.VMultiplicities()->Array1(),
875           CvP.UDegree(), CvP.VDegree() );
876   }
877 }
878
879 //=======================================================================
880 //function : MaxError
881 //purpose  : 
882 //=======================================================================
883
884 Handle(TColStd_HArray1OfReal)
885  AdvApp2Var_ApproxAFunc2Var::MaxError(const Standard_Integer Dimension) const
886 {
887   Handle (TColStd_HArray1OfReal) EPtr;
888   if (Dimension <1 || Dimension >3) {
889     throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::MaxError : Dimension must be equal to 1,2 or 3 !");
890   }
891   switch (Dimension) {
892   case 1:
893     EPtr = my1DMaxError;
894     break;
895   case 2:
896     EPtr = my2DMaxError;
897     break;
898   case 3:
899     EPtr = my3DMaxError;
900     break;
901   }
902   return EPtr;
903 }
904
905 //=======================================================================
906 //function : AverageError
907 //purpose  : 
908 //=======================================================================
909
910 Handle(TColStd_HArray1OfReal)
911  AdvApp2Var_ApproxAFunc2Var::AverageError(const Standard_Integer Dimension) const 
912 {
913   Handle (TColStd_HArray1OfReal) EPtr;
914   if (Dimension <1 || Dimension >3) {
915     throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::AverageError : Dimension must be equal to 1,2 or 3 !");
916   }
917   switch (Dimension) {
918   case 1:
919     EPtr = my1DAverageError;
920     break;
921   case 2:
922     EPtr = my2DAverageError;
923     break;
924   case 3:
925     EPtr = my3DAverageError;
926     break;
927   }
928   return EPtr;
929 }
930
931 //=======================================================================
932 //function : UFrontError
933 //purpose  : 
934 //=======================================================================
935
936 Handle(TColStd_HArray1OfReal)
937  AdvApp2Var_ApproxAFunc2Var::UFrontError(const Standard_Integer Dimension) const 
938 {
939   Handle (TColStd_HArray1OfReal) EPtr;
940   if (Dimension <1 || Dimension >3) {
941     throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::UFrontError : Dimension must be equal to 1,2 or 3 !");
942   }
943   switch (Dimension) {
944   case 1:
945     EPtr = my1DUFrontError;
946     break;
947   case 2:
948     EPtr = my2DUFrontError;
949     break;
950   case 3:
951     EPtr = my3DUFrontError;
952     break;
953   }
954   return EPtr;
955 }
956
957 //=======================================================================
958 //function : VFrontError
959 //purpose  : 
960 //=======================================================================
961
962 Handle(TColStd_HArray1OfReal)
963  AdvApp2Var_ApproxAFunc2Var::VFrontError(const Standard_Integer Dimension) const 
964 {
965   Handle (TColStd_HArray1OfReal) EPtr;
966   if (Dimension <=0 || Dimension >3) {
967     throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::VFrontError : Dimension must be equal to 1,2 or 3 !");
968   }
969   switch (Dimension) {
970   case 1:
971     EPtr = my1DVFrontError;
972     break;
973   case 2:
974     EPtr = my2DVFrontError;
975     break;
976   case 3:
977     EPtr = my3DVFrontError;
978     break;
979   }
980   return EPtr;
981 }
982
983 //=======================================================================
984 //function : MaxError
985 //purpose  : 
986 //=======================================================================
987
988 Standard_Real
989  AdvApp2Var_ApproxAFunc2Var::MaxError(const Standard_Integer Dimension,
990                                       const Standard_Integer SSPIndex) const 
991 {
992   if (Dimension !=3 || SSPIndex !=1) {
993     throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::MaxError: ONE Surface 3D only !");
994   }
995   Handle (TColStd_HArray1OfReal) EPtr = MaxError(Dimension);
996   return EPtr->Value(SSPIndex);
997 }
998
999 //=======================================================================
1000 //function : AverageError
1001 //purpose  : 
1002 //=======================================================================
1003
1004 Standard_Real
1005  AdvApp2Var_ApproxAFunc2Var::AverageError(const Standard_Integer Dimension,
1006                                           const Standard_Integer SSPIndex) const 
1007 {
1008   if (Dimension !=3 || SSPIndex !=1) {
1009     throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::AverageError : ONE Surface 3D only !");
1010   }
1011   Handle (TColStd_HArray1OfReal) EPtr = AverageError(Dimension);
1012   return EPtr->Value(SSPIndex);
1013 }
1014
1015 //=======================================================================
1016 //function : UFrontError
1017 //purpose  : 
1018 //=======================================================================
1019
1020 Standard_Real
1021  AdvApp2Var_ApproxAFunc2Var::UFrontError(const Standard_Integer Dimension,
1022                                          const Standard_Integer SSPIndex) const 
1023 {
1024   if (Dimension !=3 || SSPIndex !=1) {
1025     throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::UFrontError : ONE Surface 3D only !");
1026   }
1027   Handle (TColStd_HArray1OfReal) EPtr = UFrontError(Dimension);
1028   return EPtr->Value(SSPIndex);
1029 }
1030
1031 //=======================================================================
1032 //function : VFrontError
1033 //purpose  : 
1034 //=======================================================================
1035
1036 Standard_Real
1037  AdvApp2Var_ApproxAFunc2Var::VFrontError(const Standard_Integer Dimension,
1038                                          const Standard_Integer SSPIndex) const 
1039 {
1040   if (Dimension !=3 || SSPIndex !=1) {
1041     throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::VFrontError : ONE Surface 3D only !");
1042   }
1043   Handle (TColStd_HArray1OfReal) EPtr = VFrontError(Dimension);
1044   return EPtr->Value(SSPIndex);
1045 }
1046
1047
1048 //=======================================================================
1049 //function : CritError
1050 //purpose  : 
1051 //=======================================================================
1052
1053 Standard_Real
1054  AdvApp2Var_ApproxAFunc2Var::CritError(const Standard_Integer Dimension,
1055                                        const Standard_Integer SSPIndex) const 
1056 {
1057   if (Dimension !=3 || SSPIndex !=1) {
1058     throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::CritError: ONE Surface 3D only !");
1059   }
1060   return myCriterionError;
1061 }
1062
1063 //=======================================================================
1064 //function : Dump
1065 //purpose  : 
1066 //=======================================================================
1067
1068 void AdvApp2Var_ApproxAFunc2Var::Dump(Standard_OStream& o) const 
1069 {
1070   Standard_Integer iesp=1,NbKU,NbKV,ik;
1071   o<<std::endl;
1072   if (!myHasResult) { o<<"No result"<<std::endl; }
1073   else {
1074     o<<"There is a result";
1075     if (myDone) {
1076       o<<" within the requested tolerance "<<my3DTolerances->Value(iesp)<<std::endl;
1077     }
1078     else if (my3DMaxError->Value(iesp)>my3DTolerances->Value(iesp)) {
1079       o<<" WITHOUT the requested tolerance "<<my3DTolerances->Value(iesp)<<std::endl;
1080     }
1081     else {
1082       o<<" WITHOUT the requested continuities "<<std::endl;
1083     }
1084     o<<std::endl;
1085     o<<"Result max error :"<<my3DMaxError->Value(iesp)<<std::endl;
1086     o<<"Result average error :"<<my3DAverageError->Value(iesp)<<std::endl;
1087     o<<"Result max error on U frontiers :"<<my3DUFrontError->Value(iesp)<<std::endl;
1088     o<<"Result max error on V frontiers :"<<my3DVFrontError->Value(iesp)<<std::endl;
1089     o<<std::endl;
1090     o<<"Degree of Bezier patches in U : "<<myDegreeInU
1091       <<"  in V : "<<myDegreeInV<<std::endl;
1092     o<<std::endl;
1093     Handle(Geom_BSplineSurface) S
1094       = Handle(Geom_BSplineSurface)::DownCast(mySurfaces->Value(iesp));
1095     o<<"Number of poles in U : "<<S->NbUPoles()
1096       <<"  in V : "<<S->NbVPoles()<<std::endl;
1097     o<<std::endl;
1098     NbKU = S->NbUKnots();
1099     NbKV = S->NbVKnots();
1100     o<<"Number of knots in U : "<<NbKU<<std::endl;
1101     for (ik=1;ik<=NbKU;ik++) {
1102       o<<"   "<<ik<<" : "<<S->UKnot(ik)<<"   mult : "<<S->UMultiplicity(ik)<<std::endl;
1103     }
1104     o<<std::endl;
1105     o<<"Number of knots in V : "<<NbKV<<std::endl;
1106     for (ik=1;ik<=NbKV;ik++) {
1107       o<<"   "<<ik<<" : "<<S->VKnot(ik)<<"   mult : "<<S->VMultiplicity(ik)<<std::endl;
1108     }
1109     o<<std::endl;
1110   }
1111 }