1 // Created on: 1996-07-03
2 // Created by: Joelle CHAUVET
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <AdvApp2Var_ApproxAFunc2Var.hxx>
18 #include <AdvApp2Var_EvaluatorFunc2Var.hxx>
19 #include <AdvApp2Var_Criterion.hxx>
20 #include <AdvApp2Var_Context.hxx>
21 #include <AdvApp2Var_Patch.hxx>
22 #include <AdvApp2Var_Network.hxx>
23 #include <AdvApp2Var_Node.hxx>
24 #include <AdvApp2Var_Iso.hxx>
25 #include <AdvApp2Var_Strip.hxx>
26 #include <AdvApp2Var_Framework.hxx>
27 #include <AdvApprox_Cutting.hxx>
29 #include <Standard_ConstructionError.hxx>
30 #include <Standard_OutOfRange.hxx>
31 #include <TColStd_HArray1OfInteger.hxx>
32 #include <TColStd_HArray2OfInteger.hxx>
33 #include <TColStd_HArray1OfReal.hxx>
34 #include <TColStd_HArray2OfReal.hxx>
37 #include <gp_Pnt2d.hxx>
39 #include <TColgp_HArray2OfPnt.hxx>
41 #include <Convert_GridPolynomialToPoles.hxx>
43 #include <Geom_BezierSurface.hxx>
46 //=======================================================================
47 //function : AdvApp2Var_ApproxAFunc2Var
49 //=======================================================================
51 AdvApp2Var_ApproxAFunc2Var::
52 AdvApp2Var_ApproxAFunc2Var(const Standard_Integer Num1DSS,
53 const Standard_Integer Num2DSS,
54 const Standard_Integer Num3DSS,
55 const Handle(TColStd_HArray1OfReal)& OneDTol,
56 const Handle(TColStd_HArray1OfReal)& TwoDTol,
57 const Handle(TColStd_HArray1OfReal)& ThreeDTol,
58 const Handle(TColStd_HArray2OfReal)& OneDTolFr,
59 const Handle(TColStd_HArray2OfReal)& TwoDTolFr,
60 const Handle(TColStd_HArray2OfReal)& ThreeDTolFr,
61 const Standard_Real FirstInU,
62 const Standard_Real LastInU,
63 const Standard_Real FirstInV,
64 const Standard_Real LastInV,
65 const GeomAbs_IsoType FavorIso,
66 const GeomAbs_Shape ContInU,
67 const GeomAbs_Shape ContInV,
68 const Standard_Integer PrecisCode,
69 const Standard_Integer MaxDegInU,
70 const Standard_Integer MaxDegInV,
71 const Standard_Integer MaxPatch,
72 const AdvApp2Var_EvaluatorFunc2Var& Func,
73 AdvApprox_Cutting& UChoice,
74 AdvApprox_Cutting& VChoice) :
75 my1DTolerances(OneDTol),
76 my2DTolerances(TwoDTol),
77 my3DTolerances(ThreeDTol),
78 my1DTolOnFront(OneDTolFr),
79 my2DTolOnFront(TwoDTolFr),
80 my3DTolOnFront(ThreeDTolFr),
81 myFirstParInU(FirstInU),
82 myLastParInU(LastInU),
83 myFirstParInV(FirstInV),
84 myLastParInV(LastInV),
85 myFavoriteIso(FavorIso),
88 myPrecisionCode(PrecisCode),
89 myMaxDegInU(MaxDegInU),
90 myMaxDegInV(MaxDegInV),
91 myMaxPatches(MaxPatch),
92 myDone(Standard_False),
93 myHasResult(Standard_False),
96 myNumSubSpaces[0] = Num1DSS;
97 myNumSubSpaces[1] = Num2DSS;
98 myNumSubSpaces[2] = Num3DSS;
100 Perform(UChoice, VChoice, Func);
104 //=======================================================================
105 //function : AdvApp2Var_ApproxAFunc2Var
107 //=======================================================================
109 AdvApp2Var_ApproxAFunc2Var::
110 AdvApp2Var_ApproxAFunc2Var(const Standard_Integer Num1DSS,
111 const Standard_Integer Num2DSS,
112 const Standard_Integer Num3DSS,
113 const Handle(TColStd_HArray1OfReal)& OneDTol,
114 const Handle(TColStd_HArray1OfReal)& TwoDTol,
115 const Handle(TColStd_HArray1OfReal)& ThreeDTol,
116 const Handle(TColStd_HArray2OfReal)& OneDTolFr,
117 const Handle(TColStd_HArray2OfReal)& TwoDTolFr,
118 const Handle(TColStd_HArray2OfReal)& ThreeDTolFr,
119 const Standard_Real FirstInU,
120 const Standard_Real LastInU,
121 const Standard_Real FirstInV,
122 const Standard_Real LastInV,
123 const GeomAbs_IsoType FavorIso,
124 const GeomAbs_Shape ContInU,
125 const GeomAbs_Shape ContInV,
126 const Standard_Integer PrecisCode,
127 const Standard_Integer MaxDegInU,
128 const Standard_Integer MaxDegInV,
129 const Standard_Integer MaxPatch,
130 const AdvApp2Var_EvaluatorFunc2Var& Func,
131 const AdvApp2Var_Criterion& Crit,
132 AdvApprox_Cutting& UChoice,
133 AdvApprox_Cutting& VChoice) :
134 my1DTolerances(OneDTol),
135 my2DTolerances(TwoDTol),
136 my3DTolerances(ThreeDTol),
137 my1DTolOnFront(OneDTolFr),
138 my2DTolOnFront(TwoDTolFr),
139 my3DTolOnFront(ThreeDTolFr),
140 myFirstParInU(FirstInU),
141 myLastParInU(LastInU),
142 myFirstParInV(FirstInV),
143 myLastParInV(LastInV),
144 myFavoriteIso(FavorIso),
147 myPrecisionCode(PrecisCode),
148 myMaxDegInU(MaxDegInU),
149 myMaxDegInV(MaxDegInV),
150 myMaxPatches(MaxPatch),
151 myDone(Standard_False),
152 myHasResult(Standard_False)
154 myNumSubSpaces[0] = Num1DSS;
155 myNumSubSpaces[1] = Num2DSS;
156 myNumSubSpaces[2] = Num3DSS;
158 Perform(UChoice, VChoice, Func, Crit);
162 //=======================================================================
164 //purpose : Initialisation of the approximation
165 //=======================================================================
167 void AdvApp2Var_ApproxAFunc2Var::Init()
169 Standard_Integer ifav,iu=0,iv=0,ndu,ndv;
170 switch (myFavoriteIso) {
192 Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : UContinuity Error");
205 Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : VContinuity Error");
207 ndu = Max(myMaxDegInU+1,2*iu+2);
208 ndv = Max(myMaxDegInV+1,2*iv+2);
210 Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : UMaxDegree Error");
212 Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : VMaxDegree Error");
213 myPrecisionCode = Max(0,Min(myPrecisionCode,3));
214 AdvApp2Var_Context Conditions(ifav,iu,iv,ndu,ndv,
225 myConditions = Conditions;
230 //=======================================================================
231 //function : InitGrid
232 //purpose : Initialisation of the approximation with regular cuttings
233 //=======================================================================
235 void AdvApp2Var_ApproxAFunc2Var::InitGrid(const Standard_Integer NbInt)
237 Standard_Integer iu=myConditions.UOrder(),iv=myConditions.VOrder(),iint;
239 AdvApp2Var_Patch M0(myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,iu,iv);
241 AdvApp2Var_SequenceOfPatch Net;
244 TColStd_SequenceOfReal TheU,TheV;
245 TheU.Append(myFirstParInU);
246 TheV.Append(myFirstParInV);
247 TheU.Append(myLastParInU);
248 TheV.Append(myLastParInV);
250 AdvApp2Var_Network Result(Net,TheU,TheV);
253 gp_XY UV1(myFirstParInU,myFirstParInV);
254 AdvApp2Var_Node C1(UV1,iu,iv);
255 gp_XY UV2(myLastParInU,myFirstParInV);
256 AdvApp2Var_Node C2(UV2,iu,iv);
257 gp_XY UV4(myLastParInU,myLastParInV);
258 AdvApp2Var_Node C4(UV4,iu,iv);
259 gp_XY UV3(myFirstParInU,myLastParInV);
260 AdvApp2Var_Node C3(UV3,iu,iv);
261 AdvApp2Var_SequenceOfNode Bag;
267 AdvApp2Var_Iso V0(GeomAbs_IsoV,myFirstParInV,
268 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
270 AdvApp2Var_Iso V1(GeomAbs_IsoV,myLastParInV,
271 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
273 AdvApp2Var_Iso U0(GeomAbs_IsoU,myFirstParInU,
274 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
276 AdvApp2Var_Iso U1(GeomAbs_IsoU,myLastParInU,
277 myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,
280 AdvApp2Var_Strip BU0,BV0;
286 AdvApp2Var_SequenceOfStrip UStrip,VStrip;
290 AdvApp2Var_Framework Constraints(Bag,UStrip,VStrip);
292 // regular cutting if NbInt>1
293 Standard_Real deltu = (myLastParInU-myFirstParInU)/NbInt,
294 deltv = (myLastParInV-myFirstParInV)/NbInt;
295 for (iint=1;iint<=NbInt-1;iint++) {
296 Result.UpdateInU(myFirstParInU+iint*deltu);
297 Constraints.UpdateInU(myFirstParInU+iint*deltu);
298 Result.UpdateInV(myFirstParInV+iint*deltv);
299 Constraints.UpdateInV(myFirstParInV+iint*deltv);
302 myConstraints = Constraints;
305 //=======================================================================
307 //purpose : Computation of the approximation
308 //=======================================================================
310 void AdvApp2Var_ApproxAFunc2Var::Perform(const AdvApprox_Cutting& UChoice,
311 const AdvApprox_Cutting& VChoice,
312 const AdvApp2Var_EvaluatorFunc2Var& Func)
314 ComputePatches(UChoice,VChoice,Func);
315 myHasResult = myDone = Standard_True;
319 //=======================================================================
321 //purpose : Computation of the approximation
322 //=======================================================================
324 void AdvApp2Var_ApproxAFunc2Var::Perform(const AdvApprox_Cutting& UChoice,
325 const AdvApprox_Cutting& VChoice,
326 const AdvApp2Var_EvaluatorFunc2Var& Func,
327 const AdvApp2Var_Criterion& Crit)
329 ComputePatches(UChoice,VChoice,Func,Crit);
330 myHasResult = myDone = Standard_True;
335 //=======================================================================
336 //function : ComputePatches
337 //purpose : Computation of the polynomial approximations
338 //=======================================================================
340 void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice,
341 const AdvApprox_Cutting& VChoice,
342 const AdvApp2Var_EvaluatorFunc2Var& Func)
344 Standard_Real Udec, Vdec;
345 Standard_Boolean Umore, Vmore;
346 Standard_Integer NbPatch, NbU, NbV, NumDec;
347 Standard_Integer FirstNA;
349 while (myResult.FirstNotApprox(FirstNA)) {
351 // complete the set of constraints
352 ComputeConstraints(UChoice, VChoice, Func);
354 // discretization of constraints relative to the square
355 myResult(FirstNA).Discretise(myConditions,myConstraints,Func);
356 if ( ! myResult(FirstNA).IsDiscretised() ) {
357 myHasResult = myDone = Standard_False;
358 Standard_ConstructionError::Raise
359 ("AdvApp2Var_ApproxAFunc2Var : Surface Discretisation Error");
362 // calculate the number and the type of autorized cuts
363 // depending on the max number of squares and the validity of next cuts.
364 NbU = myResult.NbPatchInU();
365 NbV = myResult.NbPatchInV();
367 Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(),Udec);
368 Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(),Vdec);
371 if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)>myMaxPatches)
372 && (Umore) ) NumDec = 1;
373 if ( ((NbPatch+NbV)>myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches)
374 && (Vmore) ) NumDec = 2;
375 if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches) ) {
376 if ( Umore ) NumDec = 3;
377 if ( (NbV>NbU) && Vmore ) NumDec = 4;
379 if ( (NbU+1)*(NbV+1)<=myMaxPatches ) {
380 if ( !Umore && !Vmore ) NumDec=0;
381 if ( Umore && !Vmore ) NumDec=3;
382 if ( !Umore && Vmore ) NumDec=4;
383 if ( Umore && Vmore ) NumDec=5;
386 // approximation of the square
387 myResult(FirstNA).MakeApprox(myConditions,myConstraints,NumDec);
389 if ( ! myResult(FirstNA).IsApproximated() ) {
390 switch (myResult(FirstNA).CutSense()) {
392 // It is not possible to cut : the result is preserved
393 if ( myResult(FirstNA).HasResult()) {
394 myResult(FirstNA).OverwriteApprox();
397 myHasResult = myDone = Standard_False;
398 Standard_ConstructionError::Raise
399 ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
403 // It is necessary to cut in U
404 myResult.UpdateInU(Udec);
405 myConstraints.UpdateInU(Udec);
408 // It is necessary to cut in V
409 myResult.UpdateInV(Vdec);
410 myConstraints.UpdateInV(Vdec);
413 // It is necesary to cut in U and V
414 myResult.UpdateInU(Udec);
415 myConstraints.UpdateInU(Udec);
416 myResult.UpdateInV(Vdec);
417 myConstraints.UpdateInV(Vdec);
420 myHasResult = myDone = Standard_False;
421 Standard_ConstructionError::Raise
422 ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
428 //=======================================================================
429 //function : ComputePatches
430 //purpose : Computation of the polynomial approximations
431 //=======================================================================
433 void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice,
434 const AdvApprox_Cutting& VChoice,
435 const AdvApp2Var_EvaluatorFunc2Var& Func,
436 const AdvApp2Var_Criterion& Crit)
438 Standard_Real Udec, Vdec, CritValue, m1=0.;
439 Standard_Boolean Umore, Vmore, CritAbs = (Crit.Type() == AdvApp2Var_Absolute);
440 Standard_Integer NbPatch, NbU, NbV, NbInt, NumDec;
441 Standard_Integer FirstNA, decision=0;
443 while (myResult.FirstNotApprox(FirstNA)) {
445 // complete the set of constraints
446 ComputeConstraints(UChoice, VChoice, Func, Crit);
451 // discretize the constraints relative to the square
452 myResult(FirstNA).Discretise(myConditions,myConstraints,Func);
453 if ( ! myResult(FirstNA).IsDiscretised() ) {
454 myHasResult = myDone = Standard_False;
455 Standard_ConstructionError::Raise
456 ("AdvApp2Var_ApproxAFunc2Var : Surface Discretisation Error");
459 // calculate the number and type of autorized cuts
460 // depending on the max number of squares and the validity of next cuts
461 NbU = myResult.NbPatchInU();
462 NbV = myResult.NbPatchInV();
465 Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(),Udec);
466 Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(),Vdec);
469 if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)>myMaxPatches)
470 && (Umore) ) NumDec = 1;
471 if ( ((NbPatch+NbV)>myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches)
472 && (Vmore) ) NumDec = 2;
473 if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches) ) {
474 if ( Umore ) NumDec = 3;
475 if ( (NbV>NbU) && Vmore ) NumDec = 4;
477 if ( (NbU+1)*(NbV+1)<=myMaxPatches ) {
478 if ( !Umore && !Vmore ) NumDec=0;
479 if ( Umore && !Vmore ) NumDec=1;
480 if ( !Umore && Vmore ) NumDec=2;
481 if ( Umore && Vmore ) NumDec=5;
484 // approximation of the square
486 myResult(FirstNA).MakeApprox(myConditions,myConstraints,0);
489 myResult(FirstNA).MakeApprox(myConditions,myConstraints,NumDec);
491 if (NumDec>=3) NumDec = NumDec - 2;
493 // evaluation of the criterion on the square
494 if ( myResult(FirstNA).HasResult() ) {
495 Crit.Value(myResult(FirstNA),myConditions);
496 CritValue = myResult(FirstNA).CritValue();
497 if (m1<CritValue) m1 = CritValue;
499 // is it necessary to cut ?
500 decision = myResult(FirstNA).CutSense(Crit,NumDec);
501 Standard_Boolean Regular = (Crit.Repartition() == AdvApp2Var_Regular);
502 // Standard_Boolean Regular = Standard_True;
503 if (Regular && decision>0) {
510 // Impossible to cut : the result is preserved
511 if ( myResult(FirstNA).HasResult() ) {
512 myResult(FirstNA).OverwriteApprox();
515 myHasResult = myDone = Standard_False;
516 Standard_ConstructionError::Raise
517 ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
521 // It is necessary to cut in U
522 myResult.UpdateInU(Udec);
523 myConstraints.UpdateInU(Udec);
526 // It is necessary to cut in V
527 myResult.UpdateInV(Vdec);
528 myConstraints.UpdateInV(Vdec);
531 // It is necessary to cut in U and V
532 myResult.UpdateInU(Udec);
533 myConstraints.UpdateInU(Udec);
534 myResult.UpdateInV(Vdec);
535 myConstraints.UpdateInV(Vdec);
538 myHasResult = myDone = Standard_False;
539 Standard_ConstructionError::Raise
540 ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
546 //=======================================================================
547 //function : ComputeConstraints without Criterion
548 //purpose : Approximation of the constraints
549 //=======================================================================
551 void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UChoice,
552 const AdvApprox_Cutting& VChoice,
553 const AdvApp2Var_EvaluatorFunc2Var& Func)
556 Standard_Boolean more;
557 Standard_Integer ind1, ind2, NbPatch, NbU, NbV;
559 Standard_Integer indN1, indN2;
560 Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
561 AdvApp2Var_Node N1(iu,iv), N2(iu,iv);
563 while ( myConstraints.FirstNotApprox(ind1, ind2, Is) ) {
565 // approximation of iso and calculation of constraints at extremities
566 indN1 = myConstraints.FirstNode(Is.Type(),ind1,ind2);
567 N1 = myConstraints.Node(indN1);
568 indN2 = myConstraints.LastNode(Is.Type(),ind1,ind2);
569 N2 = myConstraints.Node(indN2);
571 Is.MakeApprox(myConditions,
572 myFirstParInU, myLastParInU,
573 myFirstParInV, myLastParInV,
576 if (Is.IsApproximated()) {
577 // iso is approached at the required tolerance
578 myConstraints.ChangeIso(ind1,ind2,Is);
579 myConstraints.ChangeNode(indN1) = N1;
580 myConstraints.ChangeNode(indN2) = N2;
584 // Approximation is not satisfactory
585 NbU = myResult.NbPatchInU();
586 NbV = myResult.NbPatchInV();
587 if (Is.Type()==GeomAbs_IsoV) {
588 NbPatch = (NbU+1)*NbV;
589 more = UChoice.Value(Is.T0(),Is.T1(),dec);
592 NbPatch = (NbV+1)*NbU;
593 more = VChoice.Value(Is.T0(),Is.T1(),dec);
596 if (NbPatch<=myMaxPatches && more) {
597 // It is possible to cut iso
598 if (Is.Type()==GeomAbs_IsoV) {
599 myResult.UpdateInU(dec);
600 myConstraints.UpdateInU(dec);
603 myResult.UpdateInV(dec);
604 myConstraints.UpdateInV(dec);
609 // It is not possible to cut : the result is preserved
610 if (Is.HasResult()) {
611 Is.OverwriteApprox();
612 myConstraints.ChangeIso(ind1,ind2,Is);
613 myConstraints.ChangeNode(indN1) = N1;
614 myConstraints.ChangeNode(indN2) = N2;
617 myHasResult = myDone = Standard_False;
618 Standard_ConstructionError::Raise
619 ("AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
627 //=======================================================================
628 //function : ComputeConstraints with Criterion
629 //purpose : Approximation of the constraints
630 //=======================================================================
632 void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UChoice,
633 const AdvApprox_Cutting& VChoice,
634 const AdvApp2Var_EvaluatorFunc2Var& Func,
635 const AdvApp2Var_Criterion& Crit)
638 Standard_Boolean more, CritRel = (Crit.Type() == AdvApp2Var_Relative);
639 Standard_Integer ind1, ind2, NbPatch, NbU, NbV;
641 Standard_Integer indN1, indN2;
642 Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
643 AdvApp2Var_Node N1(iu,iv), N2(iu,iv);
645 while ( myConstraints.FirstNotApprox(ind1, ind2, Is) ) {
647 // approximation of the iso and calculation of constraints at the extremities
648 indN1 = myConstraints.FirstNode(Is.Type(),ind1,ind2);
649 N1 = myConstraints.Node(indN1);
650 indN2 = myConstraints.LastNode(Is.Type(),ind1,ind2);
651 N2 = myConstraints.Node(indN2);
653 Is.MakeApprox(myConditions,
654 myFirstParInU, myLastParInU,
655 myFirstParInV, myLastParInV,
658 if (Is.IsApproximated()) {
659 // iso is approached at the required tolerance
660 myConstraints.ChangeIso(ind1,ind2,Is);
661 myConstraints.ChangeNode(indN1) = N1;
662 myConstraints.ChangeNode(indN2) = N2;
666 // Approximation is not satisfactory
667 NbU = myResult.NbPatchInU();
668 NbV = myResult.NbPatchInV();
669 if (Is.Type()==GeomAbs_IsoV) {
670 NbPatch = (NbU+1)*NbV;
671 more = UChoice.Value(Is.T0(),Is.T1(),dec);
674 NbPatch = (NbV+1)*NbU;
675 more = VChoice.Value(Is.T0(),Is.T1(),dec);
678 // To force Overwrite if the criterion is Absolute
679 more = more && (CritRel);
681 if (NbPatch<=myMaxPatches && more) {
682 // It is possible to cut iso
683 if (Is.Type()==GeomAbs_IsoV) {
684 myResult.UpdateInU(dec);
685 myConstraints.UpdateInU(dec);
688 myResult.UpdateInV(dec);
689 myConstraints.UpdateInV(dec);
694 // It is not possible to cut: the result is preserved
695 if (Is.HasResult()) {
696 Is.OverwriteApprox();
697 myConstraints.ChangeIso(ind1,ind2,Is);
698 myConstraints.ChangeNode(indN1) = N1;
699 myConstraints.ChangeNode(indN2) = N2;
702 myHasResult = myDone = Standard_False;
703 Standard_ConstructionError::Raise
704 ("AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
711 //=======================================================================
712 //function : Compute3DErrors
713 //purpose : Computation of the 3D errors
714 //=======================================================================
716 void AdvApp2Var_ApproxAFunc2Var::Compute3DErrors()
719 Standard_Integer iesp,ipat;
720 Standard_Real error_max,error_moy,error_U0,error_V0,error_U1,error_V1;
721 Standard_Real Tol,F1Tol,F2Tol,F3Tol,F4Tol;
722 if ( myNumSubSpaces[2] > 0 ) {
723 my3DMaxError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
724 my3DAverageError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
725 my3DUFrontError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
726 my3DVFrontError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]);
727 for (iesp=1;iesp<=myNumSubSpaces[2];iesp++) {
734 Tol = my3DTolerances->Value(iesp);
735 F1Tol = my3DTolOnFront->Value(iesp,1);
736 F2Tol = my3DTolOnFront->Value(iesp,2);
737 F3Tol = my3DTolOnFront->Value(iesp,3);
738 F4Tol = my3DTolOnFront->Value(iesp,4);
739 for (ipat=1;ipat<=myResult.NbPatch();ipat++) {
740 error_max = Max((myResult(ipat).MaxErrors())->Value(iesp),error_max);
741 error_U0 = Max((myResult(ipat).IsoErrors())->Value(iesp,3),error_U0);
742 error_U1 = Max((myResult(ipat).IsoErrors())->Value(iesp,4),error_U1);
743 error_V0 = Max((myResult(ipat).IsoErrors())->Value(iesp,1),error_V0);
744 error_V1 = Max((myResult(ipat).IsoErrors())->Value(iesp,2),error_V1);
745 error_moy += (myResult(ipat).AverageErrors())->Value(iesp);
747 my3DMaxError->SetValue(iesp,error_max);
748 my3DUFrontError->SetValue(iesp,Max(error_U0,error_U1));
749 my3DVFrontError->SetValue(iesp,Max(error_V0,error_V1));
750 error_moy /= (Standard_Real) myResult.NbPatch();
751 my3DAverageError->SetValue(iesp,error_moy);
753 || error_U0>F3Tol || error_U1>F4Tol
754 || error_V0>F1Tol || error_V1>F2Tol) {
755 myDone = Standard_False;
762 //=======================================================================
763 //function : ComputeCritError
764 //purpose : Computation of the max value of the Criterion
765 //=======================================================================
767 void AdvApp2Var_ApproxAFunc2Var::ComputeCritError()
770 Standard_Integer iesp,ipat;
771 Standard_Real crit_max;
772 if ( myNumSubSpaces[2] > 0 ) {
773 for (iesp=1;iesp<=myNumSubSpaces[2];iesp++) {
775 for (ipat=1;ipat<=myResult.NbPatch();ipat++) {
776 crit_max = Max((myResult(ipat).CritValue()),crit_max);
778 myCriterionError = crit_max;
783 //=======================================================================
784 //function : ConvertBS
785 //purpose : Convertion of the approximation in BSpline Surface
786 //=======================================================================
788 void AdvApp2Var_ApproxAFunc2Var::ConvertBS()
790 // Homogeneization of degrees
791 Standard_Integer iu = myConditions.UOrder(), iv = myConditions.VOrder();
792 Standard_Integer ncfu = myConditions.ULimit(), ncfv = myConditions.VLimit();
793 myResult.SameDegree(iu,iv,ncfu,ncfv);
794 myDegreeInU = ncfu - 1;
795 myDegreeInV = ncfv - 1;
797 // Calculate resulting surfaces
798 mySurfaces = new ( TColGeom_HArray1OfSurface) (1, myNumSubSpaces[2]);
801 TColStd_Array1OfReal UKnots (1, myResult.NbPatchInU()+1);
802 for (j=1; j<=UKnots.Length(); j++) { UKnots.SetValue(j, myResult.UParameter(j)); }
804 TColStd_Array1OfReal VKnots (1, myResult.NbPatchInV()+1);
805 for (j=1; j<=VKnots.Length(); j++) { VKnots.SetValue(j, myResult.VParameter(j)); }
807 // Prepare data for conversion grid of polynoms --> poles
808 Handle(TColStd_HArray1OfReal) Uint1 =
809 new (TColStd_HArray1OfReal) (1,2);
810 Uint1->SetValue(1, -1);
811 Uint1->SetValue(2, 1);
812 Handle(TColStd_HArray1OfReal) Vint1 =
813 new (TColStd_HArray1OfReal) (1,2);
814 Vint1->SetValue(1, -1);
815 Vint1->SetValue(2, 1);
817 Handle(TColStd_HArray1OfReal) Uint2 =
818 new (TColStd_HArray1OfReal) (1,myResult.NbPatchInU()+1);
819 for (j=1; j<=Uint2->Length(); j++) { Uint2->SetValue(j, myResult.UParameter(j)); }
820 Handle(TColStd_HArray1OfReal) Vint2 =
821 new (TColStd_HArray1OfReal) (1,myResult.NbPatchInV()+1);
822 for (j=1; j<=Vint2->Length(); j++) { Vint2->SetValue(j, myResult.VParameter(j)); }
824 Standard_Integer nmax = myResult.NbPatchInU()*myResult.NbPatchInV(),
825 Size_eq = myConditions.ULimit() * myConditions.VLimit() * 3;
827 Handle(TColStd_HArray2OfInteger) NbCoeff =
828 new (TColStd_HArray2OfInteger) (1, nmax, 1, 2);
829 Handle(TColStd_HArray1OfReal) Poly =
830 new (TColStd_HArray1OfReal) (1, nmax * Size_eq);
832 Standard_Integer SSP, i;
833 for (SSP=1; SSP <= myNumSubSpaces[2]; SSP++) {
835 // Creation of the grid of polynoms
836 Standard_Integer n=0,icf=1,ieq;
837 for (j=1; j<=myResult.NbPatchInV(); j++) {
838 for (i=1; i<=myResult.NbPatchInU(); i++) {
840 NbCoeff->SetValue(n,1, myResult.Patch(i,j).NbCoeffInU());
841 NbCoeff->SetValue(n,2, myResult.Patch(i,j).NbCoeffInV());
842 for (ieq=1; ieq<=Size_eq;ieq++) {
843 Poly->SetValue(icf,(myResult.Patch(i,j).Coefficients(SSP,myConditions))
850 // Conversion into poles
851 Convert_GridPolynomialToPoles CvP (myResult.NbPatchInU(),myResult.NbPatchInV(),
852 iu,iv,myMaxDegInU,myMaxDegInV,NbCoeff,
853 Poly,Uint1,Vint1,Uint2,Vint2);
854 if ( !CvP.IsDone() ) { myDone = Standard_False; }
856 // Conversion into BSpline
857 mySurfaces->ChangeValue(SSP) = new (Geom_BSplineSurface)
858 ( CvP.Poles()->Array2(),
859 CvP.UKnots()->Array1(), CvP.VKnots()->Array1(),
860 CvP.UMultiplicities()->Array1(), CvP.VMultiplicities()->Array1(),
861 CvP.UDegree(), CvP.VDegree() );
865 //=======================================================================
866 //function : MaxError
868 //=======================================================================
870 Handle(TColStd_HArray1OfReal)
871 AdvApp2Var_ApproxAFunc2Var::MaxError(const Standard_Integer Dimension) const
873 Handle (TColStd_HArray1OfReal) EPtr;
874 if (Dimension <1 || Dimension >3) {
875 Standard_OutOfRange::Raise
876 ("AdvApp2Var_ApproxAFunc2Var::MaxError : Dimension must be equal to 1,2 or 3 !");
892 //=======================================================================
893 //function : AverageError
895 //=======================================================================
897 Handle(TColStd_HArray1OfReal)
898 AdvApp2Var_ApproxAFunc2Var::AverageError(const Standard_Integer Dimension) const
900 Handle (TColStd_HArray1OfReal) EPtr;
901 if (Dimension <1 || Dimension >3) {
902 Standard_OutOfRange::Raise
903 ("AdvApp2Var_ApproxAFunc2Var::AverageError : Dimension must be equal to 1,2 or 3 !");
907 EPtr = my1DAverageError;
910 EPtr = my2DAverageError;
913 EPtr = my3DAverageError;
919 //=======================================================================
920 //function : UFrontError
922 //=======================================================================
924 Handle(TColStd_HArray1OfReal)
925 AdvApp2Var_ApproxAFunc2Var::UFrontError(const Standard_Integer Dimension) const
927 Handle (TColStd_HArray1OfReal) EPtr;
928 if (Dimension <1 || Dimension >3) {
929 Standard_OutOfRange::Raise
930 ("AdvApp2Var_ApproxAFunc2Var::UFrontError : Dimension must be equal to 1,2 or 3 !");
934 EPtr = my1DUFrontError;
937 EPtr = my2DUFrontError;
940 EPtr = my3DUFrontError;
946 //=======================================================================
947 //function : VFrontError
949 //=======================================================================
951 Handle(TColStd_HArray1OfReal)
952 AdvApp2Var_ApproxAFunc2Var::VFrontError(const Standard_Integer Dimension) const
954 Handle (TColStd_HArray1OfReal) EPtr;
955 if (Dimension <=0 || Dimension >3) {
956 Standard_OutOfRange::Raise
957 ("AdvApp2Var_ApproxAFunc2Var::VFrontError : Dimension must be equal to 1,2 or 3 !");
961 EPtr = my1DVFrontError;
964 EPtr = my2DVFrontError;
967 EPtr = my3DVFrontError;
973 //=======================================================================
974 //function : MaxError
976 //=======================================================================
979 AdvApp2Var_ApproxAFunc2Var::MaxError(const Standard_Integer Dimension,
980 const Standard_Integer SSPIndex) const
982 if (Dimension !=3 || SSPIndex !=1) {
983 Standard_OutOfRange::Raise
984 ("AdvApp2Var_ApproxAFunc2Var::MaxError: ONE Surface 3D only !");
986 Handle (TColStd_HArray1OfReal) EPtr = MaxError(Dimension);
987 return EPtr->Value(SSPIndex);
990 //=======================================================================
991 //function : AverageError
993 //=======================================================================
996 AdvApp2Var_ApproxAFunc2Var::AverageError(const Standard_Integer Dimension,
997 const Standard_Integer SSPIndex) const
999 if (Dimension !=3 || SSPIndex !=1) {
1000 Standard_OutOfRange::Raise
1001 ("AdvApp2Var_ApproxAFunc2Var::AverageError : ONE Surface 3D only !");
1003 Handle (TColStd_HArray1OfReal) EPtr = AverageError(Dimension);
1004 return EPtr->Value(SSPIndex);
1007 //=======================================================================
1008 //function : UFrontError
1010 //=======================================================================
1013 AdvApp2Var_ApproxAFunc2Var::UFrontError(const Standard_Integer Dimension,
1014 const Standard_Integer SSPIndex) const
1016 if (Dimension !=3 || SSPIndex !=1) {
1017 Standard_OutOfRange::Raise
1018 ("AdvApp2Var_ApproxAFunc2Var::UFrontError : ONE Surface 3D only !");
1020 Handle (TColStd_HArray1OfReal) EPtr = UFrontError(Dimension);
1021 return EPtr->Value(SSPIndex);
1024 //=======================================================================
1025 //function : VFrontError
1027 //=======================================================================
1030 AdvApp2Var_ApproxAFunc2Var::VFrontError(const Standard_Integer Dimension,
1031 const Standard_Integer SSPIndex) const
1033 if (Dimension !=3 || SSPIndex !=1) {
1034 Standard_OutOfRange::Raise
1035 ("AdvApp2Var_ApproxAFunc2Var::VFrontError : ONE Surface 3D only !");
1037 Handle (TColStd_HArray1OfReal) EPtr = VFrontError(Dimension);
1038 return EPtr->Value(SSPIndex);
1042 //=======================================================================
1043 //function : CritError
1045 //=======================================================================
1048 AdvApp2Var_ApproxAFunc2Var::CritError(const Standard_Integer Dimension,
1049 const Standard_Integer SSPIndex) const
1051 if (Dimension !=3 || SSPIndex !=1) {
1052 Standard_OutOfRange::Raise
1053 ("AdvApp2Var_ApproxAFunc2Var::CritError: ONE Surface 3D only !");
1055 return myCriterionError;
1058 //=======================================================================
1061 //=======================================================================
1063 void AdvApp2Var_ApproxAFunc2Var::Dump(Standard_OStream& o) const
1065 Standard_Integer iesp=1,NbKU,NbKV,ik;
1067 if (!myHasResult) { o<<"No result"<<endl; }
1069 o<<"There is a result";
1071 o<<" within the requested tolerance "<<my3DTolerances->Value(iesp)<<endl;
1073 else if (my3DMaxError->Value(iesp)>my3DTolerances->Value(iesp)) {
1074 o<<" WITHOUT the requested tolerance "<<my3DTolerances->Value(iesp)<<endl;
1077 o<<" WITHOUT the requested continuities "<<endl;
1080 o<<"Result max error :"<<my3DMaxError->Value(iesp)<<endl;
1081 o<<"Result average error :"<<my3DAverageError->Value(iesp)<<endl;
1082 o<<"Result max error on U frontiers :"<<my3DUFrontError->Value(iesp)<<endl;
1083 o<<"Result max error on V frontiers :"<<my3DVFrontError->Value(iesp)<<endl;
1085 o<<"Degree of Bezier patches in U : "<<myDegreeInU
1086 <<" in V : "<<myDegreeInV<<endl;
1088 Handle(Geom_BSplineSurface) S
1089 = Handle(Geom_BSplineSurface)::DownCast(mySurfaces->Value(iesp));
1090 o<<"Number of poles in U : "<<S->NbUPoles()
1091 <<" in V : "<<S->NbVPoles()<<endl;
1093 NbKU = S->NbUKnots();
1094 NbKV = S->NbVKnots();
1095 o<<"Number of knots in U : "<<NbKU<<endl;
1096 for (ik=1;ik<=NbKU;ik++) {
1097 o<<" "<<ik<<" : "<<S->UKnot(ik)<<" mult : "<<S->UMultiplicity(ik)<<endl;
1100 o<<"Number of knots in V : "<<NbKV<<endl;
1101 for (ik=1;ik<=NbKV;ik++) {
1102 o<<" "<<ik<<" : "<<S->VKnot(ik)<<" mult : "<<S->VMultiplicity(ik)<<endl;