0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / AdvApp2Var / AdvApp2Var_ApproxAFunc2Var.cxx
CommitLineData
b311480e 1// Created on: 1996-07-03
2// Created by: Joelle CHAUVET
3// Copyright (c) 1996-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 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>
ec357c5c 44#include <Geom_BSplineSurface.hxx>
7fd59977 45
46
47//=======================================================================
48//function : AdvApp2Var_ApproxAFunc2Var
49//purpose :
50//=======================================================================
51
cbff1e55 52AdvApp2Var_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)
7fd59977 98{
99 myNumSubSpaces[0] = Num1DSS;
100 myNumSubSpaces[1] = Num2DSS;
101 myNumSubSpaces[2] = Num3DSS;
cbff1e55 102
7fd59977 103 Init();
41194117 104 Perform(UChoice, VChoice, Func);
7fd59977 105 ConvertBS();
106}
107
108//=======================================================================
109//function : AdvApp2Var_ApproxAFunc2Var
110//purpose :
111//=======================================================================
112
cbff1e55 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)
7fd59977 160{
161 myNumSubSpaces[0] = Num1DSS;
162 myNumSubSpaces[1] = Num2DSS;
163 myNumSubSpaces[2] = Num3DSS;
cbff1e55 164
7fd59977 165 Init();
41194117 166 Perform(UChoice, VChoice, Func, Crit);
7fd59977 167 ConvertBS();
168}
169
170//=======================================================================
171//function : Init
172//purpose : Initialisation of the approximation
173//=======================================================================
174
175void 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 :
9775fa61 200 throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : UContinuity Error");
7fd59977 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 :
9775fa61 213 throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : VContinuity Error");
7fd59977 214 }
215 ndu = Max(myMaxDegInU+1,2*iu+2);
216 ndv = Max(myMaxDegInV+1,2*iv+2);
217 if (ndu<2*iu+2)
9775fa61 218 throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : UMaxDegree Error");
7fd59977 219 if (ndv<2*iv+2)
9775fa61 220 throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : VMaxDegree Error");
7fd59977 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
243void AdvApp2Var_ApproxAFunc2Var::InitGrid(const Standard_Integer NbInt)
244{
245 Standard_Integer iu=myConditions.UOrder(),iv=myConditions.VOrder(),iint;
246
247 AdvApp2Var_Patch M0(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 AdvApp2Var_Node C1(UV1,iu,iv);
263 gp_XY UV2(myLastParInU,myFirstParInV);
264 AdvApp2Var_Node C2(UV2,iu,iv);
265 gp_XY UV4(myLastParInU,myLastParInV);
266 AdvApp2Var_Node C4(UV4,iu,iv);
267 gp_XY UV3(myFirstParInU,myLastParInV);
268 AdvApp2Var_Node C3(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 AdvApp2Var_Iso V0(GeomAbs_IsoV,myFirstParInV,
276 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
277 1,iu,iv);
278 AdvApp2Var_Iso V1(GeomAbs_IsoV,myLastParInV,
279 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
280 2,iu,iv);
281 AdvApp2Var_Iso U0(GeomAbs_IsoU,myFirstParInU,
282 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
283 3,iu,iv);
284 AdvApp2Var_Iso U1(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
0d969553 300// regular cutting if NbInt>1
7fd59977 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
318void 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
332void 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
348void 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
0d969553 359// complete the set of constraints
7fd59977 360 ComputeConstraints(UChoice, VChoice, Func);
361
0d969553 362// discretization of constraints relative to the square
7fd59977 363 myResult(FirstNA).Discretise(myConditions,myConstraints,Func);
364 if ( ! myResult(FirstNA).IsDiscretised() ) {
365 myHasResult = myDone = Standard_False;
9775fa61 366 throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Discretisation Error");
7fd59977 367 }
368
0d969553
Y
369// calculate the number and the type of autorized cuts
370// depending on the max number of squares and the validity of next cuts.
7fd59977 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
0d969553 393// approximation of the square
7fd59977 394 myResult(FirstNA).MakeApprox(myConditions,myConstraints,NumDec);
395
396 if ( ! myResult(FirstNA).IsApproximated() ) {
397 switch (myResult(FirstNA).CutSense()) {
398 case 0 :
0d969553 399// It is not possible to cut : the result is preserved
7fd59977 400 if ( myResult(FirstNA).HasResult()) {
401 myResult(FirstNA).OverwriteApprox();
402 }
403 else {
404 myHasResult = myDone = Standard_False;
9775fa61 405 throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
7fd59977 406 }
407 break;
408 case 1 :
0d969553 409// It is necessary to cut in U
7fd59977 410 myResult.UpdateInU(Udec);
411 myConstraints.UpdateInU(Udec);
412 break;
413 case 2 :
0d969553 414// It is necessary to cut in V
7fd59977 415 myResult.UpdateInV(Vdec);
416 myConstraints.UpdateInV(Vdec);
417 break;
418 case 3 :
0d969553 419// It is necesary to cut in U and V
7fd59977 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;
9775fa61 427 throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
7fd59977 428 }
429 }
430 }
431}
432
433//=======================================================================
434//function : ComputePatches
435//purpose : Computation of the polynomial approximations
436//=======================================================================
437
438void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice,
439 const AdvApprox_Cutting& VChoice,
440 const AdvApp2Var_EvaluatorFunc2Var& Func,
441 const AdvApp2Var_Criterion& Crit)
442{
96a95605 443 Standard_Real Udec, Vdec, CritValue, m1=0.;
7fd59977 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
0d969553 450// complete the set of constraints
7fd59977 451 ComputeConstraints(UChoice, VChoice, Func, Crit);
452 if (decision>0) {
7fd59977 453 m1 = 0.;
454 }
455
0d969553 456// discretize the constraints relative to the square
7fd59977 457 myResult(FirstNA).Discretise(myConditions,myConstraints,Func);
458 if ( ! myResult(FirstNA).IsDiscretised() ) {
459 myHasResult = myDone = Standard_False;
9775fa61 460 throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Discretisation Error");
7fd59977 461 }
462
0d969553
Y
463// calculate the number and type of autorized cuts
464// depending on the max number of squares and the validity of next cuts
7fd59977 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
0d969553 488// approximation of the square
7fd59977 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
0d969553 497// evaluation of the criterion on the square
7fd59977 498 if ( myResult(FirstNA).HasResult() ) {
499 Crit.Value(myResult(FirstNA),myConditions);
500 CritValue = myResult(FirstNA).CritValue();
501 if (m1<CritValue) m1 = CritValue;
502 }
0d969553 503// is it necessary to cut ?
7fd59977 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 :
0d969553 514// Impossible to cut : the result is preserved
7fd59977 515 if ( myResult(FirstNA).HasResult() ) {
516 myResult(FirstNA).OverwriteApprox();
517 }
518 else {
519 myHasResult = myDone = Standard_False;
9775fa61 520 throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
7fd59977 521 }
522 break;
523 case 1 :
0d969553 524// It is necessary to cut in U
7fd59977 525 myResult.UpdateInU(Udec);
526 myConstraints.UpdateInU(Udec);
527 break;
528 case 2 :
0d969553 529// It is necessary to cut in V
7fd59977 530 myResult.UpdateInV(Vdec);
531 myConstraints.UpdateInV(Vdec);
532 break;
533 case 3 :
0d969553 534// It is necessary to cut in U and V
7fd59977 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;
9775fa61 542 throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
7fd59977 543 }
544 }
545 }
546}
547
548//=======================================================================
549//function : ComputeConstraints without Criterion
550//purpose : Approximation of the constraints
551//=======================================================================
552
553void 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 AdvApp2Var_Iso Is;
561 Standard_Integer indN1, indN2;
562 Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
563 AdvApp2Var_Node N1(iu,iv), N2(iu,iv);
564
565 while ( myConstraints.FirstNotApprox(ind1, ind2, Is) ) {
566
0d969553 567// approximation of iso and calculation of constraints at extremities
7fd59977 568 indN1 = myConstraints.FirstNode(Is.Type(),ind1,ind2);
569 N1 = myConstraints.Node(indN1);
570 indN2 = myConstraints.LastNode(Is.Type(),ind1,ind2);
571 N2 = myConstraints.Node(indN2);
572
573 Is.MakeApprox(myConditions,
574 myFirstParInU, myLastParInU,
575 myFirstParInV, myLastParInV,
576 Func, N1 , N2);
577
578 if (Is.IsApproximated()) {
0d969553 579// iso is approached at the required tolerance
7fd59977 580 myConstraints.ChangeIso(ind1,ind2,Is);
581 myConstraints.ChangeNode(indN1) = N1;
582 myConstraints.ChangeNode(indN2) = N2;
583 }
584
585 else {
0d969553 586// Approximation is not satisfactory
7fd59977 587 NbU = myResult.NbPatchInU();
588 NbV = myResult.NbPatchInV();
589 if (Is.Type()==GeomAbs_IsoV) {
590 NbPatch = (NbU+1)*NbV;
591 more = UChoice.Value(Is.T0(),Is.T1(),dec);
592 }
593 else {
594 NbPatch = (NbV+1)*NbU;
595 more = VChoice.Value(Is.T0(),Is.T1(),dec);
596 }
597
598 if (NbPatch<=myMaxPatches && more) {
0d969553 599// It is possible to cut iso
7fd59977 600 if (Is.Type()==GeomAbs_IsoV) {
601 myResult.UpdateInU(dec);
602 myConstraints.UpdateInU(dec);
603 }
604 else {
605 myResult.UpdateInV(dec);
606 myConstraints.UpdateInV(dec);
607 }
608 }
609
610 else {
0d969553 611// It is not possible to cut : the result is preserved
7fd59977 612 if (Is.HasResult()) {
613 Is.OverwriteApprox();
614 myConstraints.ChangeIso(ind1,ind2,Is);
615 myConstraints.ChangeNode(indN1) = N1;
616 myConstraints.ChangeNode(indN2) = N2;
617 }
618 else {
619 myHasResult = myDone = Standard_False;
9775fa61 620 throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
7fd59977 621 }
622 }
623 }
624 }
625}
626
627
628//=======================================================================
629//function : ComputeConstraints with Criterion
630//purpose : Approximation of the constraints
631//=======================================================================
632
633void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UChoice,
634 const AdvApprox_Cutting& VChoice,
635 const AdvApp2Var_EvaluatorFunc2Var& Func,
636 const AdvApp2Var_Criterion& Crit)
637{
638 Standard_Real dec;
639 Standard_Boolean more, CritRel = (Crit.Type() == AdvApp2Var_Relative);
640 Standard_Integer ind1, ind2, NbPatch, NbU, NbV;
641 AdvApp2Var_Iso Is;
642 Standard_Integer indN1, indN2;
643 Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
644 AdvApp2Var_Node N1(iu,iv), N2(iu,iv);
645
646 while ( myConstraints.FirstNotApprox(ind1, ind2, Is) ) {
647
0d969553 648// approximation of the iso and calculation of constraints at the extremities
7fd59977 649 indN1 = myConstraints.FirstNode(Is.Type(),ind1,ind2);
650 N1 = myConstraints.Node(indN1);
651 indN2 = myConstraints.LastNode(Is.Type(),ind1,ind2);
652 N2 = myConstraints.Node(indN2);
653
654 Is.MakeApprox(myConditions,
655 myFirstParInU, myLastParInU,
656 myFirstParInV, myLastParInV,
657 Func, N1 , N2);
658
659 if (Is.IsApproximated()) {
0d969553 660// iso is approached at the required tolerance
7fd59977 661 myConstraints.ChangeIso(ind1,ind2,Is);
662 myConstraints.ChangeNode(indN1) = N1;
663 myConstraints.ChangeNode(indN2) = N2;
664 }
665
666 else {
0d969553 667// Approximation is not satisfactory
7fd59977 668 NbU = myResult.NbPatchInU();
669 NbV = myResult.NbPatchInV();
670 if (Is.Type()==GeomAbs_IsoV) {
671 NbPatch = (NbU+1)*NbV;
672 more = UChoice.Value(Is.T0(),Is.T1(),dec);
673 }
674 else {
675 NbPatch = (NbV+1)*NbU;
676 more = VChoice.Value(Is.T0(),Is.T1(),dec);
677 }
678
0d969553 679// To force Overwrite if the criterion is Absolute
7fd59977 680 more = more && (CritRel);
681
682 if (NbPatch<=myMaxPatches && more) {
0d969553 683// It is possible to cut iso
7fd59977 684 if (Is.Type()==GeomAbs_IsoV) {
685 myResult.UpdateInU(dec);
686 myConstraints.UpdateInU(dec);
687 }
688 else {
689 myResult.UpdateInV(dec);
690 myConstraints.UpdateInV(dec);
691 }
692 }
693
694 else {
0d969553 695// It is not possible to cut: the result is preserved
7fd59977 696 if (Is.HasResult()) {
697 Is.OverwriteApprox();
698 myConstraints.ChangeIso(ind1,ind2,Is);
699 myConstraints.ChangeNode(indN1) = N1;
700 myConstraints.ChangeNode(indN2) = N2;
701 }
702 else {
703 myHasResult = myDone = Standard_False;
9775fa61 704 throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
7fd59977 705 }
706 }
707 }
708 }
709}
710
711//=======================================================================
712//function : Compute3DErrors
713//purpose : Computation of the 3D errors
714//=======================================================================
715
716void AdvApp2Var_ApproxAFunc2Var::Compute3DErrors()
717{
718
719 Standard_Integer iesp,ipat;
720 Standard_Real error_max,error_moy,error_U0,error_V0,error_U1,error_V1;
721 Standard_Real Tol,F1Tol,F2Tol,F3Tol,F4Tol;
722 if ( myNumSubSpaces[2] > 0 ) {
723 my3DMaxError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
724 my3DAverageError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
725 my3DUFrontError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
726 my3DVFrontError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
727 for (iesp=1;iesp<=myNumSubSpaces[2];iesp++) {
728 error_max = 0;
729 error_moy = 0.;
730 error_U0 = 0.;
731 error_V0 = 0.;
732 error_U1 = 0.;
733 error_V1 = 0.;
734 Tol = my3DTolerances->Value(iesp);
735 F1Tol = my3DTolOnFront->Value(iesp,1);
736 F2Tol = my3DTolOnFront->Value(iesp,2);
737 F3Tol = my3DTolOnFront->Value(iesp,3);
738 F4Tol = my3DTolOnFront->Value(iesp,4);
739 for (ipat=1;ipat<=myResult.NbPatch();ipat++) {
740 error_max = Max((myResult(ipat).MaxErrors())->Value(iesp),error_max);
741 error_U0 = Max((myResult(ipat).IsoErrors())->Value(iesp,3),error_U0);
742 error_U1 = Max((myResult(ipat).IsoErrors())->Value(iesp,4),error_U1);
743 error_V0 = Max((myResult(ipat).IsoErrors())->Value(iesp,1),error_V0);
744 error_V1 = Max((myResult(ipat).IsoErrors())->Value(iesp,2),error_V1);
745 error_moy += (myResult(ipat).AverageErrors())->Value(iesp);
746 }
747 my3DMaxError->SetValue(iesp,error_max);
748 my3DUFrontError->SetValue(iesp,Max(error_U0,error_U1));
749 my3DVFrontError->SetValue(iesp,Max(error_V0,error_V1));
750 error_moy /= (Standard_Real) myResult.NbPatch();
751 my3DAverageError->SetValue(iesp,error_moy);
752 if ( error_max>Tol
753 || error_U0>F3Tol || error_U1>F4Tol
754 || error_V0>F1Tol || error_V1>F2Tol) {
755 myDone = Standard_False;
756 }
757 }
758 }
759}
760
761
762//=======================================================================
763//function : ComputeCritError
764//purpose : Computation of the max value of the Criterion
765//=======================================================================
766
767void AdvApp2Var_ApproxAFunc2Var::ComputeCritError()
768{
769
770 Standard_Integer iesp,ipat;
771 Standard_Real crit_max;
772 if ( myNumSubSpaces[2] > 0 ) {
773 for (iesp=1;iesp<=myNumSubSpaces[2];iesp++) {
774 crit_max = 0.;
775 for (ipat=1;ipat<=myResult.NbPatch();ipat++) {
776 crit_max = Max((myResult(ipat).CritValue()),crit_max);
777 }
778 myCriterionError = crit_max;
779 }
780 }
781}
782
783//=======================================================================
784//function : ConvertBS
785//purpose : Convertion of the approximation in BSpline Surface
786//=======================================================================
787
788void AdvApp2Var_ApproxAFunc2Var::ConvertBS()
789{
0d969553 790 // Homogeneization of degrees
7fd59977 791 Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
792 Standard_Integer ncfu = myConditions.ULimit(), ncfv = myConditions.VLimit();
793 myResult.SameDegree(iu,iv,ncfu,ncfv);
794 myDegreeInU = ncfu - 1;
795 myDegreeInV = ncfv - 1;
796
0d969553 797 // Calculate resulting surfaces
7fd59977 798 mySurfaces = new ( TColGeom_HArray1OfSurface) (1, myNumSubSpaces[2]);
799
800 Standard_Integer j;
801 TColStd_Array1OfReal UKnots (1, myResult.NbPatchInU()+1);
802 for (j=1; j<=UKnots.Length(); j++) { UKnots.SetValue(j, myResult.UParameter(j)); }
803
804 TColStd_Array1OfReal VKnots (1, myResult.NbPatchInV()+1);
805 for (j=1; j<=VKnots.Length(); j++) { VKnots.SetValue(j, myResult.VParameter(j)); }
806
0d969553 807 // Prepare data for conversion grid of polynoms --> poles
7fd59977 808 Handle(TColStd_HArray1OfReal) Uint1 =
809 new (TColStd_HArray1OfReal) (1,2);
810 Uint1->SetValue(1, -1);
811 Uint1->SetValue(2, 1);
812 Handle(TColStd_HArray1OfReal) Vint1 =
813 new (TColStd_HArray1OfReal) (1,2);
814 Vint1->SetValue(1, -1);
815 Vint1->SetValue(2, 1);
816
817 Handle(TColStd_HArray1OfReal) Uint2 =
818 new (TColStd_HArray1OfReal) (1,myResult.NbPatchInU()+1);
819 for (j=1; j<=Uint2->Length(); j++) { Uint2->SetValue(j, myResult.UParameter(j)); }
820 Handle(TColStd_HArray1OfReal) Vint2 =
821 new (TColStd_HArray1OfReal) (1,myResult.NbPatchInV()+1);
822 for (j=1; j<=Vint2->Length(); j++) { Vint2->SetValue(j, myResult.VParameter(j)); }
823
824 Standard_Integer nmax = myResult.NbPatchInU()*myResult.NbPatchInV(),
825 Size_eq = myConditions.ULimit() * myConditions.VLimit() * 3;
826
827 Handle(TColStd_HArray2OfInteger) NbCoeff =
828 new (TColStd_HArray2OfInteger) (1, nmax, 1, 2);
829 Handle(TColStd_HArray1OfReal) Poly =
830 new (TColStd_HArray1OfReal) (1, nmax * Size_eq);
831
832 Standard_Integer SSP, i;
833 for (SSP=1; SSP <= myNumSubSpaces[2]; SSP++) {
834
0d969553 835 // Creation of the grid of polynoms
7fd59977 836 Standard_Integer n=0,icf=1,ieq;
837 for (j=1; j<=myResult.NbPatchInV(); j++) {
838 for (i=1; i<=myResult.NbPatchInU(); i++) {
839 n++;
840 NbCoeff->SetValue(n,1, myResult.Patch(i,j).NbCoeffInU());
841 NbCoeff->SetValue(n,2, myResult.Patch(i,j).NbCoeffInV());
842 for (ieq=1; ieq<=Size_eq;ieq++) {
843 Poly->SetValue(icf,(myResult.Patch(i,j).Coefficients(SSP,myConditions))
844 ->Value(ieq));
845 icf++;
846 }
847 }
848 }
849
0d969553 850 // Conversion into poles
7fd59977 851 Convert_GridPolynomialToPoles CvP (myResult.NbPatchInU(),myResult.NbPatchInV(),
852 iu,iv,myMaxDegInU,myMaxDegInV,NbCoeff,
853 Poly,Uint1,Vint1,Uint2,Vint2);
854 if ( !CvP.IsDone() ) { myDone = Standard_False; }
855
0d969553 856 // Conversion into BSpline
7fd59977 857 mySurfaces->ChangeValue(SSP) = new (Geom_BSplineSurface)
858 ( CvP.Poles()->Array2(),
859 CvP.UKnots()->Array1(), CvP.VKnots()->Array1(),
860 CvP.UMultiplicities()->Array1(), CvP.VMultiplicities()->Array1(),
861 CvP.UDegree(), CvP.VDegree() );
862 }
863}
864
865//=======================================================================
866//function : MaxError
867//purpose :
868//=======================================================================
869
870Handle(TColStd_HArray1OfReal)
871 AdvApp2Var_ApproxAFunc2Var::MaxError(const Standard_Integer Dimension) const
872{
873 Handle (TColStd_HArray1OfReal) EPtr;
874 if (Dimension <1 || Dimension >3) {
9775fa61 875 throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::MaxError : Dimension must be equal to 1,2 or 3 !");
7fd59977 876 }
877 switch (Dimension) {
878 case 1:
879 EPtr = my1DMaxError;
880 break;
881 case 2:
882 EPtr = my2DMaxError;
883 break;
884 case 3:
885 EPtr = my3DMaxError;
886 break;
887 }
888 return EPtr;
889}
890
891//=======================================================================
892//function : AverageError
893//purpose :
894//=======================================================================
895
896Handle(TColStd_HArray1OfReal)
897 AdvApp2Var_ApproxAFunc2Var::AverageError(const Standard_Integer Dimension) const
898{
899 Handle (TColStd_HArray1OfReal) EPtr;
900 if (Dimension <1 || Dimension >3) {
9775fa61 901 throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::AverageError : Dimension must be equal to 1,2 or 3 !");
7fd59977 902 }
903 switch (Dimension) {
904 case 1:
905 EPtr = my1DAverageError;
906 break;
907 case 2:
908 EPtr = my2DAverageError;
909 break;
910 case 3:
911 EPtr = my3DAverageError;
912 break;
913 }
914 return EPtr;
915}
916
917//=======================================================================
918//function : UFrontError
919//purpose :
920//=======================================================================
921
922Handle(TColStd_HArray1OfReal)
923 AdvApp2Var_ApproxAFunc2Var::UFrontError(const Standard_Integer Dimension) const
924{
925 Handle (TColStd_HArray1OfReal) EPtr;
926 if (Dimension <1 || Dimension >3) {
9775fa61 927 throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::UFrontError : Dimension must be equal to 1,2 or 3 !");
7fd59977 928 }
929 switch (Dimension) {
930 case 1:
931 EPtr = my1DUFrontError;
932 break;
933 case 2:
934 EPtr = my2DUFrontError;
935 break;
936 case 3:
937 EPtr = my3DUFrontError;
938 break;
939 }
940 return EPtr;
941}
942
943//=======================================================================
944//function : VFrontError
945//purpose :
946//=======================================================================
947
948Handle(TColStd_HArray1OfReal)
949 AdvApp2Var_ApproxAFunc2Var::VFrontError(const Standard_Integer Dimension) const
950{
951 Handle (TColStd_HArray1OfReal) EPtr;
952 if (Dimension <=0 || Dimension >3) {
9775fa61 953 throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::VFrontError : Dimension must be equal to 1,2 or 3 !");
7fd59977 954 }
955 switch (Dimension) {
956 case 1:
957 EPtr = my1DVFrontError;
958 break;
959 case 2:
960 EPtr = my2DVFrontError;
961 break;
962 case 3:
963 EPtr = my3DVFrontError;
964 break;
965 }
966 return EPtr;
967}
968
969//=======================================================================
970//function : MaxError
971//purpose :
972//=======================================================================
973
974Standard_Real
975 AdvApp2Var_ApproxAFunc2Var::MaxError(const Standard_Integer Dimension,
976 const Standard_Integer SSPIndex) const
977{
978 if (Dimension !=3 || SSPIndex !=1) {
9775fa61 979 throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::MaxError: ONE Surface 3D only !");
7fd59977 980 }
981 Handle (TColStd_HArray1OfReal) EPtr = MaxError(Dimension);
982 return EPtr->Value(SSPIndex);
983}
984
985//=======================================================================
986//function : AverageError
987//purpose :
988//=======================================================================
989
990Standard_Real
991 AdvApp2Var_ApproxAFunc2Var::AverageError(const Standard_Integer Dimension,
992 const Standard_Integer SSPIndex) const
993{
994 if (Dimension !=3 || SSPIndex !=1) {
9775fa61 995 throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::AverageError : ONE Surface 3D only !");
7fd59977 996 }
997 Handle (TColStd_HArray1OfReal) EPtr = AverageError(Dimension);
998 return EPtr->Value(SSPIndex);
999}
1000
1001//=======================================================================
1002//function : UFrontError
1003//purpose :
1004//=======================================================================
1005
1006Standard_Real
1007 AdvApp2Var_ApproxAFunc2Var::UFrontError(const Standard_Integer Dimension,
1008 const Standard_Integer SSPIndex) const
1009{
1010 if (Dimension !=3 || SSPIndex !=1) {
9775fa61 1011 throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::UFrontError : ONE Surface 3D only !");
7fd59977 1012 }
1013 Handle (TColStd_HArray1OfReal) EPtr = UFrontError(Dimension);
1014 return EPtr->Value(SSPIndex);
1015}
1016
1017//=======================================================================
1018//function : VFrontError
1019//purpose :
1020//=======================================================================
1021
1022Standard_Real
1023 AdvApp2Var_ApproxAFunc2Var::VFrontError(const Standard_Integer Dimension,
1024 const Standard_Integer SSPIndex) const
1025{
1026 if (Dimension !=3 || SSPIndex !=1) {
9775fa61 1027 throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::VFrontError : ONE Surface 3D only !");
7fd59977 1028 }
1029 Handle (TColStd_HArray1OfReal) EPtr = VFrontError(Dimension);
1030 return EPtr->Value(SSPIndex);
1031}
1032
1033
1034//=======================================================================
1035//function : CritError
1036//purpose :
1037//=======================================================================
1038
1039Standard_Real
1040 AdvApp2Var_ApproxAFunc2Var::CritError(const Standard_Integer Dimension,
1041 const Standard_Integer SSPIndex) const
1042{
1043 if (Dimension !=3 || SSPIndex !=1) {
9775fa61 1044 throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::CritError: ONE Surface 3D only !");
7fd59977 1045 }
1046 return myCriterionError;
1047}
1048
1049//=======================================================================
1050//function : Dump
1051//purpose :
1052//=======================================================================
1053
1054void AdvApp2Var_ApproxAFunc2Var::Dump(Standard_OStream& o) const
1055{
1056 Standard_Integer iesp=1,NbKU,NbKV,ik;
04232180 1057 o<<std::endl;
1058 if (!myHasResult) { o<<"No result"<<std::endl; }
7fd59977 1059 else {
1060 o<<"There is a result";
1061 if (myDone) {
04232180 1062 o<<" within the requested tolerance "<<my3DTolerances->Value(iesp)<<std::endl;
7fd59977 1063 }
1064 else if (my3DMaxError->Value(iesp)>my3DTolerances->Value(iesp)) {
04232180 1065 o<<" WITHOUT the requested tolerance "<<my3DTolerances->Value(iesp)<<std::endl;
7fd59977 1066 }
1067 else {
04232180 1068 o<<" WITHOUT the requested continuities "<<std::endl;
7fd59977 1069 }
04232180 1070 o<<std::endl;
1071 o<<"Result max error :"<<my3DMaxError->Value(iesp)<<std::endl;
1072 o<<"Result average error :"<<my3DAverageError->Value(iesp)<<std::endl;
1073 o<<"Result max error on U frontiers :"<<my3DUFrontError->Value(iesp)<<std::endl;
1074 o<<"Result max error on V frontiers :"<<my3DVFrontError->Value(iesp)<<std::endl;
1075 o<<std::endl;
7fd59977 1076 o<<"Degree of Bezier patches in U : "<<myDegreeInU
04232180 1077 <<" in V : "<<myDegreeInV<<std::endl;
1078 o<<std::endl;
7fd59977 1079 Handle(Geom_BSplineSurface) S
1080 = Handle(Geom_BSplineSurface)::DownCast(mySurfaces->Value(iesp));
1081 o<<"Number of poles in U : "<<S->NbUPoles()
04232180 1082 <<" in V : "<<S->NbVPoles()<<std::endl;
1083 o<<std::endl;
7fd59977 1084 NbKU = S->NbUKnots();
1085 NbKV = S->NbVKnots();
04232180 1086 o<<"Number of knots in U : "<<NbKU<<std::endl;
7fd59977 1087 for (ik=1;ik<=NbKU;ik++) {
04232180 1088 o<<" "<<ik<<" : "<<S->UKnot(ik)<<" mult : "<<S->UMultiplicity(ik)<<std::endl;
7fd59977 1089 }
04232180 1090 o<<std::endl;
1091 o<<"Number of knots in V : "<<NbKV<<std::endl;
7fd59977 1092 for (ik=1;ik<=NbKV;ik++) {
04232180 1093 o<<" "<<ik<<" : "<<S->VKnot(ik)<<" mult : "<<S->VMultiplicity(ik)<<std::endl;
7fd59977 1094 }
04232180 1095 o<<std::endl;
7fd59977 1096 }
1097}