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