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