1 // File: AdvApp2Var_ApproxAFunc2Var.cxx
2 // Created: Wed Jul 3 15:34:08 1996
3 // Author: Joelle CHAUVET
5 // Modified: Wed Jan 15 10:04:41 1997
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
15 // GeomConvert_CompBezierSurfacesToBSplineSurface est remplace par
16 // Convert_GridPolynomialToPoles dans ConvertBS
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>
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>
38 #include <gp_Pnt2d.hxx>
40 #include <TColgp_HArray2OfPnt.hxx>
42 #include <Convert_GridPolynomialToPoles.hxx>
44 #include <Geom_BezierSurface.hxx>
47 //=======================================================================
48 //function : AdvApp2Var_ApproxAFunc2Var
50 //=======================================================================
52 AdvApp2Var_ApproxAFunc2Var::
53 AdvApp2Var_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) :
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),
89 myPrecisionCode(PrecisCode),
90 myMaxDegInU(MaxDegInU),
91 myMaxDegInV(MaxDegInV),
92 myMaxPatches(MaxPatch),
94 myDone(Standard_False),
95 myHasResult(Standard_False)
97 myNumSubSpaces[0] = Num1DSS;
98 myNumSubSpaces[1] = Num2DSS;
99 myNumSubSpaces[2] = Num3DSS;
101 Perform(UChoice,VChoice,Func);
105 //=======================================================================
106 //function : AdvApp2Var_ApproxAFunc2Var
108 //=======================================================================
110 AdvApp2Var_ApproxAFunc2Var::
111 AdvApp2Var_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) :
135 my1DTolerances(OneDTol),
136 my2DTolerances(TwoDTol),
137 my3DTolerances(ThreeDTol),
138 my1DTolOnFront(OneDTolFr),
139 my2DTolOnFront(TwoDTolFr),
140 my3DTolOnFront(ThreeDTolFr),
141 myFirstParInU(FirstInU),
142 myLastParInU(LastInU),
143 myFirstParInV(FirstInV),
144 myLastParInV(LastInV),
145 myFavoriteIso(FavorIso),
148 myPrecisionCode(PrecisCode),
149 myMaxDegInU(MaxDegInU),
150 myMaxDegInV(MaxDegInV),
151 myMaxPatches(MaxPatch),
153 myDone(Standard_False),
154 myHasResult(Standard_False)
156 myNumSubSpaces[0] = Num1DSS;
157 myNumSubSpaces[1] = Num2DSS;
158 myNumSubSpaces[2] = Num3DSS;
160 Perform(UChoice,VChoice,Func,Crit);
164 //=======================================================================
166 //purpose : Initialisation of the approximation
167 //=======================================================================
169 void AdvApp2Var_ApproxAFunc2Var::Init()
171 Standard_Integer ifav,iu=0,iv=0,ndu,ndv;
172 switch (myFavoriteIso) {
194 Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : UContinuity Error");
207 Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : VContinuity Error");
209 ndu = Max(myMaxDegInU+1,2*iu+2);
210 ndv = Max(myMaxDegInV+1,2*iv+2);
212 Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : UMaxDegree Error");
214 Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : VMaxDegree Error");
215 myPrecisionCode = Max(0,Min(myPrecisionCode,3));
216 AdvApp2Var_Context Conditions(ifav,iu,iv,ndu,ndv,
227 myConditions = Conditions;
232 //=======================================================================
233 //function : InitGrid
234 //purpose : Initialisation of the approximation with regular cuttings
235 //=======================================================================
237 void AdvApp2Var_ApproxAFunc2Var::InitGrid(const Standard_Integer NbInt)
239 Standard_Integer iu=myConditions.UOrder(),iv=myConditions.VOrder(),iint;
241 AdvApp2Var_Patch M0(myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,iu,iv);
243 AdvApp2Var_SequenceOfPatch Net;
246 TColStd_SequenceOfReal TheU,TheV;
247 TheU.Append(myFirstParInU);
248 TheV.Append(myFirstParInV);
249 TheU.Append(myLastParInU);
250 TheV.Append(myLastParInV);
252 AdvApp2Var_Network Result(Net,TheU,TheV);
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;
269 AdvApp2Var_Iso V0(GeomAbs_IsoV,myFirstParInV,
270 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
272 AdvApp2Var_Iso V1(GeomAbs_IsoV,myLastParInV,
273 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
275 AdvApp2Var_Iso U0(GeomAbs_IsoU,myFirstParInU,
276 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
278 AdvApp2Var_Iso U1(GeomAbs_IsoU,myLastParInU,
279 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
282 AdvApp2Var_Strip BU0,BV0;
288 AdvApp2Var_SequenceOfStrip UStrip,VStrip;
292 AdvApp2Var_Framework Constraints(Bag,UStrip,VStrip);
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);
304 myConstraints = Constraints;
307 //=======================================================================
309 //purpose : Computation of the approximation
310 //=======================================================================
312 void AdvApp2Var_ApproxAFunc2Var::Perform(const AdvApprox_Cutting& UChoice,
313 const AdvApprox_Cutting& VChoice,
314 const AdvApp2Var_EvaluatorFunc2Var& Func)
316 ComputePatches(UChoice,VChoice,Func);
317 myHasResult = myDone = Standard_True;
321 //=======================================================================
323 //purpose : Computation of the approximation
324 //=======================================================================
326 void AdvApp2Var_ApproxAFunc2Var::Perform(const AdvApprox_Cutting& UChoice,
327 const AdvApprox_Cutting& VChoice,
328 const AdvApp2Var_EvaluatorFunc2Var& Func,
329 const AdvApp2Var_Criterion& Crit)
331 ComputePatches(UChoice,VChoice,Func,Crit);
332 myHasResult = myDone = Standard_True;
337 //=======================================================================
338 //function : ComputePatches
339 //purpose : Computation of the polynomial approximations
340 //=======================================================================
342 void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice,
343 const AdvApprox_Cutting& VChoice,
344 const AdvApp2Var_EvaluatorFunc2Var& Func)
346 Standard_Real Udec, Vdec;
347 Standard_Boolean Umore, Vmore;
348 Standard_Integer NbPatch, NbU, NbV, NumDec;
349 Standard_Integer FirstNA;
351 while (myResult.FirstNotApprox(FirstNA)) {
353 // completude de l'ensemble des contraintes
354 ComputeConstraints(UChoice, VChoice, Func);
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");
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();
369 Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(),Udec);
370 Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(),Vdec);
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;
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;
388 // approximation du carreau
389 myResult(FirstNA).MakeApprox(myConditions,myConstraints,NumDec);
391 if ( ! myResult(FirstNA).IsApproximated() ) {
392 switch (myResult(FirstNA).CutSense()) {
394 // On ne peut plus decouper : on garde le resultat
395 if ( myResult(FirstNA).HasResult()) {
396 myResult(FirstNA).OverwriteApprox();
399 myHasResult = myDone = Standard_False;
400 Standard_ConstructionError::Raise
401 ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
405 // Il faut decouper en U
406 myResult.UpdateInU(Udec);
407 myConstraints.UpdateInU(Udec);
410 // Il faut decouper en V
411 myResult.UpdateInV(Vdec);
412 myConstraints.UpdateInV(Vdec);
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);
422 myHasResult = myDone = Standard_False;
423 Standard_ConstructionError::Raise
424 ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
430 //=======================================================================
431 //function : ComputePatches
432 //purpose : Computation of the polynomial approximations
433 //=======================================================================
435 void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice,
436 const AdvApprox_Cutting& VChoice,
437 const AdvApp2Var_EvaluatorFunc2Var& Func,
438 const AdvApp2Var_Criterion& Crit)
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;
445 while (myResult.FirstNotApprox(FirstNA)) {
447 // completude de l'ensemble des contraintes
448 ComputeConstraints(UChoice, VChoice, Func, Crit);
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");
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();
468 Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(),Udec);
469 Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(),Vdec);
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;
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;
487 // approximation du carreau
489 myResult(FirstNA).MakeApprox(myConditions,myConstraints,0);
492 myResult(FirstNA).MakeApprox(myConditions,myConstraints,NumDec);
494 if (NumDec>=3) NumDec = NumDec - 2;
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;
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) {
513 // On ne peut plus decouper : on garde le resultat
514 if ( myResult(FirstNA).HasResult() ) {
515 myResult(FirstNA).OverwriteApprox();
518 myHasResult = myDone = Standard_False;
519 Standard_ConstructionError::Raise
520 ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
524 // Il faut decouper en U
525 myResult.UpdateInU(Udec);
526 myConstraints.UpdateInU(Udec);
529 // Il faut decouper en V
530 myResult.UpdateInV(Vdec);
531 myConstraints.UpdateInV(Vdec);
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);
541 myHasResult = myDone = Standard_False;
542 Standard_ConstructionError::Raise
543 ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
549 //=======================================================================
550 //function : ComputeConstraints without Criterion
551 //purpose : Approximation of the constraints
552 //=======================================================================
554 void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UChoice,
555 const AdvApprox_Cutting& VChoice,
556 const AdvApp2Var_EvaluatorFunc2Var& Func)
559 Standard_Boolean more;
560 Standard_Integer ind1, ind2, NbPatch, NbU, NbV;
562 Standard_Integer indN1, indN2;
563 Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
564 AdvApp2Var_Node N1(iu,iv), N2(iu,iv);
566 while ( myConstraints.FirstNotApprox(ind1, ind2, Is) ) {
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);
574 Is.MakeApprox(myConditions,
575 myFirstParInU, myLastParInU,
576 myFirstParInV, myLastParInV,
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;
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);
595 NbPatch = (NbV+1)*NbU;
596 more = VChoice.Value(Is.T0(),Is.T1(),dec);
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);
606 myResult.UpdateInV(dec);
607 myConstraints.UpdateInV(dec);
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;
620 myHasResult = myDone = Standard_False;
621 Standard_ConstructionError::Raise
622 ("AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
630 //=======================================================================
631 //function : ComputeConstraints with Criterion
632 //purpose : Approximation of the constraints
633 //=======================================================================
635 void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UChoice,
636 const AdvApprox_Cutting& VChoice,
637 const AdvApp2Var_EvaluatorFunc2Var& Func,
638 const AdvApp2Var_Criterion& Crit)
641 Standard_Boolean more, CritRel = (Crit.Type() == AdvApp2Var_Relative);
642 Standard_Integer ind1, ind2, NbPatch, NbU, NbV;
644 Standard_Integer indN1, indN2;
645 Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
646 AdvApp2Var_Node N1(iu,iv), N2(iu,iv);
648 while ( myConstraints.FirstNotApprox(ind1, ind2, Is) ) {
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);
656 Is.MakeApprox(myConditions,
657 myFirstParInU, myLastParInU,
658 myFirstParInV, myLastParInV,
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;
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);
677 NbPatch = (NbV+1)*NbU;
678 more = VChoice.Value(Is.T0(),Is.T1(),dec);
681 // Pour forcer l'Overwrite si le critere est Absolu
682 more = more && (CritRel);
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);
691 myResult.UpdateInV(dec);
692 myConstraints.UpdateInV(dec);
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;
705 myHasResult = myDone = Standard_False;
706 Standard_ConstructionError::Raise
707 ("AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
714 //=======================================================================
715 //function : Compute3DErrors
716 //purpose : Computation of the 3D errors
717 //=======================================================================
719 void AdvApp2Var_ApproxAFunc2Var::Compute3DErrors()
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++) {
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);
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);
756 || error_U0>F3Tol || error_U1>F4Tol
757 || error_V0>F1Tol || error_V1>F2Tol) {
758 myDone = Standard_False;
765 //=======================================================================
766 //function : ComputeCritError
767 //purpose : Computation of the max value of the Criterion
768 //=======================================================================
770 void AdvApp2Var_ApproxAFunc2Var::ComputeCritError()
773 Standard_Integer iesp,ipat;
774 Standard_Real crit_max;
775 if ( myNumSubSpaces[2] > 0 ) {
776 for (iesp=1;iesp<=myNumSubSpaces[2];iesp++) {
778 for (ipat=1;ipat<=myResult.NbPatch();ipat++) {
779 crit_max = Max((myResult(ipat).CritValue()),crit_max);
781 myCriterionError = crit_max;
786 //=======================================================================
787 //function : ConvertBS
788 //purpose : Convertion of the approximation in BSpline Surface
789 //=======================================================================
791 void AdvApp2Var_ApproxAFunc2Var::ConvertBS()
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;
800 // Calcul des surfaces resultats
801 mySurfaces = new ( TColGeom_HArray1OfSurface) (1, myNumSubSpaces[2]);
804 TColStd_Array1OfReal UKnots (1, myResult.NbPatchInU()+1);
805 for (j=1; j<=UKnots.Length(); j++) { UKnots.SetValue(j, myResult.UParameter(j)); }
807 TColStd_Array1OfReal VKnots (1, myResult.NbPatchInV()+1);
808 for (j=1; j<=VKnots.Length(); j++) { VKnots.SetValue(j, myResult.VParameter(j)); }
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);
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)); }
827 Standard_Integer nmax = myResult.NbPatchInU()*myResult.NbPatchInV(),
828 Size_eq = myConditions.ULimit() * myConditions.VLimit() * 3;
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);
835 Standard_Integer SSP, i;
836 for (SSP=1; SSP <= myNumSubSpaces[2]; SSP++) {
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++) {
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))
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; }
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() );
868 //=======================================================================
869 //function : MaxError
871 //=======================================================================
873 Handle(TColStd_HArray1OfReal)
874 AdvApp2Var_ApproxAFunc2Var::MaxError(const Standard_Integer Dimension) const
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 !");
895 //=======================================================================
896 //function : AverageError
898 //=======================================================================
900 Handle(TColStd_HArray1OfReal)
901 AdvApp2Var_ApproxAFunc2Var::AverageError(const Standard_Integer Dimension) const
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 !");
910 EPtr = my1DAverageError;
913 EPtr = my2DAverageError;
916 EPtr = my3DAverageError;
922 //=======================================================================
923 //function : UFrontError
925 //=======================================================================
927 Handle(TColStd_HArray1OfReal)
928 AdvApp2Var_ApproxAFunc2Var::UFrontError(const Standard_Integer Dimension) const
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 !");
937 EPtr = my1DUFrontError;
940 EPtr = my2DUFrontError;
943 EPtr = my3DUFrontError;
949 //=======================================================================
950 //function : VFrontError
952 //=======================================================================
954 Handle(TColStd_HArray1OfReal)
955 AdvApp2Var_ApproxAFunc2Var::VFrontError(const Standard_Integer Dimension) const
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 !");
964 EPtr = my1DVFrontError;
967 EPtr = my2DVFrontError;
970 EPtr = my3DVFrontError;
976 //=======================================================================
977 //function : MaxError
979 //=======================================================================
982 AdvApp2Var_ApproxAFunc2Var::MaxError(const Standard_Integer Dimension,
983 const Standard_Integer SSPIndex) const
985 if (Dimension !=3 || SSPIndex !=1) {
986 Standard_OutOfRange::Raise
987 ("AdvApp2Var_ApproxAFunc2Var::MaxError: ONE Surface 3D only !");
989 Handle (TColStd_HArray1OfReal) EPtr = MaxError(Dimension);
990 return EPtr->Value(SSPIndex);
993 //=======================================================================
994 //function : AverageError
996 //=======================================================================
999 AdvApp2Var_ApproxAFunc2Var::AverageError(const Standard_Integer Dimension,
1000 const Standard_Integer SSPIndex) const
1002 if (Dimension !=3 || SSPIndex !=1) {
1003 Standard_OutOfRange::Raise
1004 ("AdvApp2Var_ApproxAFunc2Var::AverageError : ONE Surface 3D only !");
1006 Handle (TColStd_HArray1OfReal) EPtr = AverageError(Dimension);
1007 return EPtr->Value(SSPIndex);
1010 //=======================================================================
1011 //function : UFrontError
1013 //=======================================================================
1016 AdvApp2Var_ApproxAFunc2Var::UFrontError(const Standard_Integer Dimension,
1017 const Standard_Integer SSPIndex) const
1019 if (Dimension !=3 || SSPIndex !=1) {
1020 Standard_OutOfRange::Raise
1021 ("AdvApp2Var_ApproxAFunc2Var::UFrontError : ONE Surface 3D only !");
1023 Handle (TColStd_HArray1OfReal) EPtr = UFrontError(Dimension);
1024 return EPtr->Value(SSPIndex);
1027 //=======================================================================
1028 //function : VFrontError
1030 //=======================================================================
1033 AdvApp2Var_ApproxAFunc2Var::VFrontError(const Standard_Integer Dimension,
1034 const Standard_Integer SSPIndex) const
1036 if (Dimension !=3 || SSPIndex !=1) {
1037 Standard_OutOfRange::Raise
1038 ("AdvApp2Var_ApproxAFunc2Var::VFrontError : ONE Surface 3D only !");
1040 Handle (TColStd_HArray1OfReal) EPtr = VFrontError(Dimension);
1041 return EPtr->Value(SSPIndex);
1045 //=======================================================================
1046 //function : CritError
1048 //=======================================================================
1051 AdvApp2Var_ApproxAFunc2Var::CritError(const Standard_Integer Dimension,
1052 const Standard_Integer SSPIndex) const
1054 if (Dimension !=3 || SSPIndex !=1) {
1055 Standard_OutOfRange::Raise
1056 ("AdvApp2Var_ApproxAFunc2Var::CritError: ONE Surface 3D only !");
1058 return myCriterionError;
1061 //=======================================================================
1064 //=======================================================================
1066 void AdvApp2Var_ApproxAFunc2Var::Dump(Standard_OStream& o) const
1068 Standard_Integer iesp=1,NbKU,NbKV,ik;
1070 if (!myHasResult) { o<<"No result"<<endl; }
1072 o<<"There is a result";
1074 o<<" within the requested tolerance "<<my3DTolerances->Value(iesp)<<endl;
1076 else if (my3DMaxError->Value(iesp)>my3DTolerances->Value(iesp)) {
1077 o<<" WITHOUT the requested tolerance "<<my3DTolerances->Value(iesp)<<endl;
1080 o<<" WITHOUT the requested continuities "<<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;
1088 o<<"Degree of Bezier patches in U : "<<myDegreeInU
1089 <<" in V : "<<myDegreeInV<<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;
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;
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;