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