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