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