0024428: Implementation of LGPL license
[occt.git] / src / Approx / Approx_SweepApproximation.cxx
CommitLineData
b311480e 1// Created on: 1997-06-25
2// Created by: Philippe MANGIN
3// Copyright (c) 1997-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//
973c2be1 8// This library is free software; you can redistribute it and / or modify it
9// under the terms of the GNU Lesser General Public 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.
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 <Approx_SweepApproximation.ixx>
18#include <gp_XYZ.hxx>
19#include <BSplCLib.hxx>
20
21#include <AdvApprox_ApproxAFunction.hxx>
22#include <AdvApprox_DichoCutting.hxx>
23#include <AdvApprox_PrefAndRec.hxx>
24
25#include <TColgp_Array1OfPnt.hxx>
26#include <TColgp_Array1OfPnt2d.hxx>
27#include <TColgp_Array1OfVec.hxx>
28#include <TColgp_Array1OfVec2d.hxx>
29
30#include <TColStd_Array1OfReal.hxx>
31
32#include <StdFail_NotDone.hxx>
33
34//=======================================================================
35//class : Approx_SweepApproximation_Eval
36//purpose: evaluator class for approximation
37//=======================================================================
38
39class Approx_SweepApproximation_Eval : public AdvApprox_EvaluatorFunction
40{
41 public:
42 Approx_SweepApproximation_Eval (Approx_SweepApproximation& theTool)
43 : Tool(theTool) {}
44
45 virtual void Evaluate (Standard_Integer *Dimension,
46 Standard_Real StartEnd[2],
47 Standard_Real *Parameter,
48 Standard_Integer *DerivativeRequest,
49 Standard_Real *Result, // [Dimension]
50 Standard_Integer *ErrorCode);
51
52 private:
53 Approx_SweepApproximation &Tool;
54};
55
56void Approx_SweepApproximation_Eval::Evaluate (Standard_Integer *,/*Dimension*/
57 Standard_Real StartEnd[2],
58 Standard_Real *Parameter,
59 Standard_Integer *DerivativeRequest,
60 Standard_Real *Result,// [Dimension]
61 Standard_Integer *ErrorCode)
62{
63 *ErrorCode = Tool.Eval (*Parameter, *DerivativeRequest,
64 StartEnd[0], StartEnd[1], Result[0]);
65}
66
67Approx_SweepApproximation::
68Approx_SweepApproximation(const Handle(Approx_SweepFunction)& Func)
69{
70 myFunc = Func;
0d969553 71 // Init of variables of control
7fd59977 72 myParam = 0;
73 myOrder = -1;
74 first = 1.e100; last = -1.e100;
75 done = Standard_False;
76}
77
78void Approx_SweepApproximation::Perform(const Standard_Real First,
79 const Standard_Real Last,
80 const Standard_Real Tol3d,
81 const Standard_Real BoundTol,
82 const Standard_Real Tol2d,
83 const Standard_Real TolAngular,
84 const GeomAbs_Shape Continuity,
85 const Standard_Integer Degmax,
86 const Standard_Integer Segmax)
87{
88 Standard_Integer NbPolSect, NbKnotSect, ii;
89 Standard_Real Tol, Tol3dMin = Tol3d, The3D2DTol=0 ;
90 GeomAbs_Shape continuity = Continuity;
91
0d969553 92// (1) Characteristics of a section
7fd59977 93 myFunc->SectionShape(NbPolSect, NbKnotSect, udeg);
94 Num2DSS = myFunc->Nb2dCurves();
95 tabUKnots = new (TColStd_HArray1OfReal) (1, NbKnotSect);
96 tabUMults = new (TColStd_HArray1OfInteger) (1, NbKnotSect);
97 myFunc->Knots(tabUKnots->ChangeArray1());
98 myFunc->Mults(tabUMults->ChangeArray1());
99
0d969553 100// (2) Decompositition into sub-spaces
7fd59977 101 Handle(TColStd_HArray1OfReal) OneDTol, TwoDTol, ThreeDTol;
102 Num3DSS = NbPolSect;
103
0d969553 104// (2.1) Tolerance 3d and 1d
7fd59977 105 OneDTol = new (TColStd_HArray1OfReal) (1, Num3DSS);
106 ThreeDTol = new (TColStd_HArray1OfReal) (1, Num3DSS);
107
108 myFunc->GetTolerance(BoundTol, Tol3d, TolAngular,
109 ThreeDTol->ChangeArray1());
110
111 for (ii=1; ii<=Num3DSS; ii++)
112 if (ThreeDTol->Value(ii) < Tol3dMin) Tol3dMin = ThreeDTol->Value(ii);
113
114 if (myFunc->IsRational()) {
115 Standard_Real Size;
116 Num1DSS = NbPolSect;
117 TColStd_Array1OfReal Wmin(1, Num1DSS);
118 myFunc->GetMinimalWeight(Wmin);
119 Size = myFunc->MaximalSection();
120 Translation.SetXYZ
121 (myFunc->BarycentreOfSurf().XYZ());
122 for (ii=1; ii<=Num3DSS; ii++) {
0d969553 123 Tol = ThreeDTol->Value(ii)/2; // To take accout of the error on the final result.
7fd59977 124 OneDTol->SetValue(ii, Tol * Wmin(ii) / Size);
0d969553 125 Tol *= Wmin(ii); //Factor of projection
7fd59977 126 ThreeDTol->SetValue(ii, Max(Tol, 1.e-20) );
127 }
128 }
129 else { Num1DSS = 0; }
130
131
0d969553 132// (2.2) Tolerance and Transformation 2d.
7fd59977 133 if (Num2DSS == 0) {TwoDTol.Nullify();}
134 else {
0d969553
Y
135 // for 2d define affinity using resolutions, to
136 // avoid homogenuous tolerance of approximation (u/v and 2d/3d)
7fd59977 137 Standard_Real res, tolu, tolv;
138 TwoDTol = new (TColStd_HArray1OfReal) (1, Num2DSS);
139 AAffin = new (Approx_HArray1OfGTrsf2d) (1, Num2DSS);
0d969553 140 The3D2DTol= 0.9*BoundTol; // 10% of security
7fd59977 141 for (ii=1; ii<=Num2DSS; ii++) {
142 myFunc->Resolution(ii, The3D2DTol, tolu, tolv);
143 if ( tolu> tolv ) {
144 res = tolv;
145 AAffin->ChangeValue(ii).SetValue(1,1, tolv/tolu);
146 }
147 else {
148 res = tolu;
149 AAffin->ChangeValue(ii).SetValue(2,2, tolu/tolv);
150 }
151 TwoDTol->SetValue(ii, Min( Tol2d, res));
152 }
153 }
154
155// (3) Approximation
156
157// Init
158 myPoles = new (TColgp_HArray1OfPnt)(1, Num3DSS);
159 myDPoles = new (TColgp_HArray1OfVec)(1, Num3DSS);
160 myD2Poles = new (TColgp_HArray1OfVec)(1, Num3DSS);
161
162 myWeigths = new (TColStd_HArray1OfReal)(1, Num3DSS);
163 myDWeigths = new (TColStd_HArray1OfReal)(1, Num3DSS);
164 myD2Weigths = new (TColStd_HArray1OfReal)(1, Num3DSS);
165
166 if (Num2DSS>0) {
167 myPoles2d = new (TColgp_HArray1OfPnt2d)(1, Num2DSS);
168 myDPoles2d = new (TColgp_HArray1OfVec2d)(1, Num2DSS);
169 myD2Poles2d = new (TColgp_HArray1OfVec2d)(1, Num2DSS);
170 COnSurfErr = new (TColStd_HArray1OfReal)(1, Num2DSS);
171 }
0d969553 172// Checks if myFunc->D2 is implemented
7fd59977 173 if (continuity >= GeomAbs_C2) {
174 Standard_Boolean B;
175 B = myFunc->D2(First, First, Last,
176 myPoles->ChangeArray1(), myDPoles->ChangeArray1(),
177 myD2Poles->ChangeArray1(),
178 myPoles2d->ChangeArray1(), myDPoles2d->ChangeArray1(),
179 myD2Poles2d->ChangeArray1(),
180 myWeigths->ChangeArray1(), myDWeigths->ChangeArray1(),
181 myD2Weigths->ChangeArray1());
182 if (!B) continuity = GeomAbs_C1;
183 }
0d969553 184// Checks if myFunc->D1 is implemented
7fd59977 185 if (continuity == GeomAbs_C1) {
186 Standard_Boolean B;
187 B = myFunc->D1(First, First, Last,
188 myPoles->ChangeArray1(), myDPoles->ChangeArray1(),
189 myPoles2d->ChangeArray1(), myDPoles2d->ChangeArray1(),
190 myWeigths->ChangeArray1(), myDWeigths->ChangeArray1());
191 if (!B) continuity = GeomAbs_C0;
192 }
193
0d969553 194// So that F was at least 20 times more exact than its approx
7fd59977 195 myFunc->SetTolerance(Tol3dMin/20, Tol2d/20);
196
197 Standard_Integer NbIntervalC2 = myFunc->NbIntervals(GeomAbs_C2);
198 Standard_Integer NbIntervalC3 = myFunc->NbIntervals(GeomAbs_C3);
199
200 if (NbIntervalC3 > 1) {
0d969553 201// (3.1) Approximation with preferential cut
7fd59977 202 TColStd_Array1OfReal Param_de_decoupeC2 (1, NbIntervalC2+1);
203 myFunc->Intervals(Param_de_decoupeC2, GeomAbs_C2);
204 TColStd_Array1OfReal Param_de_decoupeC3 (1, NbIntervalC3+1);
205 myFunc->Intervals(Param_de_decoupeC3, GeomAbs_C3);
206
207
208 AdvApprox_PrefAndRec Preferentiel(Param_de_decoupeC2,
209 Param_de_decoupeC3);
210
211 Approx_SweepApproximation_Eval ev (*this);
212 Approximation(OneDTol, TwoDTol, ThreeDTol,
213 The3D2DTol,
214 First, Last,
215 continuity,
216 Degmax, Segmax,
217 ev,
218 Preferentiel);
219 }
220 else {
0d969553 221// (3.2) Approximation without preferential cut
7fd59977 222 AdvApprox_DichoCutting Dichotomie;
223 Approx_SweepApproximation_Eval ev (*this);
224 Approximation(OneDTol, TwoDTol, ThreeDTol,
225 The3D2DTol,
226 First, Last,
227 continuity,
228 Degmax, Segmax,
229 ev,
230 Dichotomie);
231 }
232}
233
234//========================================================================
235//function : Approximation
0d969553 236//purpose : Call F(t) and store the results
7fd59977 237//========================================================================
238void Approx_SweepApproximation::
239Approximation(const Handle(TColStd_HArray1OfReal)& OneDTol,
240 const Handle(TColStd_HArray1OfReal)& TwoDTol,
241 const Handle(TColStd_HArray1OfReal)& ThreeDTol,
242 const Standard_Real BoundTol,
243 const Standard_Real First,const Standard_Real Last,
244 const GeomAbs_Shape Continuity,const Standard_Integer Degmax,
245 const Standard_Integer Segmax,
246 const AdvApprox_EvaluatorFunction& TheApproxFunction,
247 const AdvApprox_Cutting& TheCuttingTool)
248{
249 AdvApprox_ApproxAFunction Approx(Num1DSS,
250 Num2DSS,
251 Num3DSS,
252 OneDTol,
253 TwoDTol,
254 ThreeDTol,
255 First,
256 Last,
257 Continuity,
258 Degmax,
259 Segmax,
260 TheApproxFunction,
261 TheCuttingTool);
262 done = Approx.HasResult();
263
264 if (done) {
0d969553 265 // --> Fill Champs of the surface ----
7fd59977 266 Standard_Integer ii, jj;
267
268 vdeg = Approx.Degree();
0d969553
Y
269 // Unfortunately Adv_Approx stores the transposition of the required
270 // so, writing tabPoles = Approx.Poles() will give an erroneous result
271 // It is only possible to allocate and recopy term by term...
7fd59977 272 tabPoles = new (TColgp_HArray2OfPnt)
273 (1, Num3DSS, 1, Approx.NbPoles());
274 tabWeights = new (TColStd_HArray2OfReal)
275 (1, Num3DSS, 1, Approx.NbPoles());
276
277 if (Num1DSS == Num3DSS) {
278 Standard_Real wpoid;
279 gp_Pnt P;
280 for (ii=1; ii <=Num3DSS; ii++) {
281 for (jj=1; jj <=Approx.NbPoles() ; jj++) {
282 P = Approx.Poles()->Value(jj,ii);
283 wpoid = Approx.Poles1d()->Value(jj,ii);
0d969553 284 P.ChangeCoord() /= wpoid; // It is necessary to divide poles by weight
7fd59977 285 P.Translate(Translation);
286 tabPoles->SetValue (ii, jj, P);
287 tabWeights->SetValue(ii, jj, wpoid );
288 }
289 }
290 }
291 else {
292 tabWeights->Init(1);
293 for (ii=1; ii <=Num3DSS; ii++) {
294 for (jj=1; jj <=Approx.NbPoles() ; jj++) {
295 tabPoles->SetValue (ii, jj, Approx.Poles ()->Value(jj,ii) );
296 }
297 }
298 }
299
0d969553 300 // this is better
7fd59977 301 tabVKnots = Approx.Knots();
302 tabVMults = Approx.Multiplicities();
303
304
305
0d969553 306 // --> Filling of curves 2D ----------
7fd59977 307 if (Num2DSS>0) {
308 gp_GTrsf2d TrsfInv;
309 deg2d = vdeg;
310 tab2dKnots = Approx.Knots();
311 tab2dMults = Approx.Multiplicities();
312
313 for (ii=1; ii<=Num2DSS; ii++) {
314 TrsfInv = AAffin->Value(ii).Inverted();
315 Handle(TColgp_HArray1OfPnt2d) P2d =
316 new (TColgp_HArray1OfPnt2d) (1, Approx.NbPoles());
317 Approx.Poles2d( ii, P2d->ChangeArray1() );
0d969553 318 // do not forget to apply inverted homothety.
7fd59977 319 for (jj=1; jj<=Approx.NbPoles(); jj++) {
320 TrsfInv.Transforms(P2d->ChangeValue(jj).ChangeCoord());
321 }
322 seqPoles2d.Append(P2d);
323 }
324 }
0d969553 325 // ---> Filling of errors
7fd59977 326 MError3d = new (TColStd_HArray1OfReal) (1,Num3DSS);
327 AError3d = new (TColStd_HArray1OfReal) (1,Num3DSS);
328 for (ii=1; ii<=Num3DSS; ii++) {
329 MError3d->SetValue(ii, Approx.MaxError(3, ii));
330 AError3d->SetValue(ii, Approx.AverageError(3, ii));
331 }
332
333 if (myFunc->IsRational()) {
334 MError1d = new (TColStd_HArray1OfReal) (1,Num3DSS);
335 AError1d = new (TColStd_HArray1OfReal) (1,Num3DSS);
336 for (ii=1; ii<=Num1DSS; ii++) {
337 MError1d->SetValue(ii, Approx.MaxError(1, ii));
338 AError1d->SetValue(ii, Approx.AverageError(1, ii));
339 }
340 }
341
342 if (Num2DSS>0) {
343 tab2dError = new (TColStd_HArray1OfReal) (1,Num2DSS);
344 Ave2dError = new (TColStd_HArray1OfReal) (1,Num2DSS);
345 for (ii=1; ii<=Num2DSS; ii++) {
346 tab2dError->SetValue(ii, Approx.MaxError(2, ii));
347 Ave2dError->SetValue(ii, Approx.AverageError(2, ii));
348 COnSurfErr->SetValue(ii,
349 (tab2dError->Value(ii)/TwoDTol->Value(ii))*BoundTol);
350 }
351 }
352 }
353}
354
355Standard_Integer Approx_SweepApproximation::Eval(const Standard_Real Parameter,
356 const Standard_Integer DerivativeRequest,
357 const Standard_Real First,
358 const Standard_Real Last,
359 Standard_Real& Result)
360{
361 Standard_Integer ier=0;
362 switch (DerivativeRequest) {
363 case 0 :
364 ier = ( ! D0(Parameter, First, Last, Result));
365 break;
366 case 1 :
367 ier = ( ! D1(Parameter, First, Last, Result));
368 break;
369 case 2 :
370 ier = ( ! D2(Parameter, First, Last,Result));
371 break;
372 default :
373 ier = 2;
374 }
375 return ier;
376}
377
378Standard_Boolean Approx_SweepApproximation::D0(const Standard_Real Param,
379 const Standard_Real First,
380 const Standard_Real Last,
381 Standard_Real& Result)
382{
383 Standard_Integer index, ii;
384 Standard_Boolean Ok=Standard_True;
385 Standard_Real * LocalResult = &Result;
386
0d969553 387 // Management of limits
7fd59977 388 if ((first!=First) || (Last!=last)) {
389 myFunc->SetInterval(First, Last);
390 }
391
392 if (! ( (Param==myParam) && (myOrder>=0)
393 && (first==First) && (Last==last)) ) {
0d969553 394 // Positioning in case when the last operation is not repeated.
7fd59977 395 Ok = myFunc->D0(Param, First, Last,
396 myPoles->ChangeArray1(),
397 myPoles2d->ChangeArray1(),
398 myWeigths->ChangeArray1());
399
0d969553 400 // poles3d are multiplied by weight after tranlation.
7fd59977 401 for (ii=1; ii<=Num1DSS; ii++) {
402 myPoles->ChangeValue(ii).ChangeCoord()
403 -= Translation.XYZ();
404 myPoles->ChangeValue(ii).ChangeCoord()
405 *= myWeigths->Value(ii);
406 }
407
0d969553 408 // The transformation is applied to poles 2d.
7fd59977 409 for (ii=1; ii<=Num2DSS; ii++) {
410 AAffin->Value(ii).Transforms(myPoles2d->ChangeValue(ii).ChangeCoord());
411 }
412
0d969553 413 // Update variables of controle and return
7fd59977 414 first = First;
415 last = Last;
416 myOrder = 0;
417 myParam = Param;
418 }
419
0d969553 420 // Extraction of results
7fd59977 421 index = 0;
422 for (ii=1; ii<=Num1DSS; ii++) {
423 LocalResult[index] = myWeigths->Value(ii);
424 index++;
425 }
426 for (ii=1; ii<=Num2DSS; ii++) {
427 LocalResult[index] = myPoles2d->Value(ii).X();
428 LocalResult[index+1] = myPoles2d->Value(ii).Y();
429 index += 2;
430 }
431 for (ii=1; ii<=Num3DSS; ii++, index+=3) {
432 LocalResult[index] = myPoles->Value(ii).X();
433 LocalResult[index+1] = myPoles->Value(ii).Y();
434 LocalResult[index+2] = myPoles->Value(ii).Z();
435 }
436
437 return Ok;
438}
439
440Standard_Boolean Approx_SweepApproximation::D1(const Standard_Real Param,
441 const Standard_Real First,
442 const Standard_Real Last,
443 Standard_Real& Result)
444{
445 gp_XY Vcoord;
446 gp_Vec Vaux;
447 Standard_Integer index, ii;
448 Standard_Boolean Ok=Standard_True;
449 Standard_Real * LocalResult = &Result;
450
451
452 if ((first!=First) || (Last!=last)) {
453 myFunc->SetInterval(First, Last);
454 }
455
456 if (! ( (Param==myParam) && (myOrder>=1)
457 && (first==First) && (Last==last)) ){
458
0d969553 459 // Positioning
7fd59977 460 Ok = myFunc->D1(Param, First, Last,
461 myPoles->ChangeArray1(),
462 myDPoles->ChangeArray1(),
463 myPoles2d->ChangeArray1(),
464 myDPoles2d->ChangeArray1(),
465 myWeigths->ChangeArray1(),
466 myDWeigths->ChangeArray1());
467
0d969553
Y
468 // Take into account the multiplication of poles3d by weights.
469 // and the translation.
7fd59977 470 for ( ii=1; ii<=Num1DSS; ii++) {
0d969553 471 //Translation on the section
7fd59977 472 myPoles->ChangeValue(ii).ChangeCoord()
473 -= Translation.XYZ();
0d969553 474 // Homothety on all.
32ca7a51 475 const Standard_Real aWeight = myWeigths->Value(ii);
476 myDPoles->ChangeValue(ii) *= aWeight;
7fd59977 477 Vaux.SetXYZ( myPoles->Value(ii).Coord());
478 myDPoles->ChangeValue(ii) += myDWeigths->Value(ii)*Vaux;
32ca7a51 479 myPoles->ChangeValue(ii).ChangeCoord() *= aWeight; // for the cash
7fd59977 480 }
481
482
0d969553 483 // Apply transformation 2d to suitable vectors
7fd59977 484 for (ii=1; ii<=Num2DSS; ii++) {
485 Vcoord = myDPoles2d->Value(ii).XY();
486 AAffin->Value(ii).Transforms(Vcoord);
487 myDPoles2d->ChangeValue(ii).SetXY(Vcoord);
488 AAffin->Value(ii).Transforms(myPoles2d->ChangeValue(ii).ChangeCoord());
489 }
490
0d969553 491 // Update control variables and return
7fd59977 492 first = First;
493 last = Last;
494 myOrder = 1;
495 myParam = Param;
496 }
497
0d969553 498 // Extraction of results
7fd59977 499 index = 0;
500 for (ii=1; ii<=Num1DSS; ii++) {
501 LocalResult[index] = myDWeigths->Value(ii);
502 index++;
503 }
504 for (ii=1; ii<=Num2DSS; ii++) {
505 LocalResult[index] = myDPoles2d->Value(ii).X();
506 LocalResult[index+1] = myDPoles2d->Value(ii).Y();
507 index += 2;
508 }
509 for (ii=1; ii<=Num3DSS; ii++, index+=3) {
510 LocalResult[index] = myDPoles->Value(ii).X();
511 LocalResult[index+1] = myDPoles->Value(ii).Y();
512 LocalResult[index+2] = myDPoles->Value(ii).Z();
513 }
514 return Ok;
515}
516
517Standard_Boolean Approx_SweepApproximation::D2(const Standard_Real Param,
518 const Standard_Real First,
519 const Standard_Real Last,
520 Standard_Real& Result)
521{
522 gp_XY Vcoord;
523 gp_Vec Vaux;
524 Standard_Integer index, ii;
525 Standard_Boolean Ok=Standard_True;
526 Standard_Real * LocalResult = &Result;
527
0d969553 528 // management of limits
7fd59977 529 if ((first!=First) || (Last!=last)) {
530 myFunc->SetInterval(First, Last);
531 }
532
533 if (! ( (Param==myParam) && (myOrder>=2)
534 && (first==First) && (Last==last)) ) {
0d969553 535 // Positioning in case when the last operation is not repeated
7fd59977 536 Ok = myFunc->D2(Param, First, Last,
537 myPoles->ChangeArray1(),
538 myDPoles->ChangeArray1(),
539 myD2Poles->ChangeArray1(),
540 myPoles2d->ChangeArray1(),
541 myDPoles2d->ChangeArray1(),
542 myD2Poles2d->ChangeArray1(),
543 myWeigths->ChangeArray1(),
544 myDWeigths->ChangeArray1(),
545 myD2Weigths->ChangeArray1());
546
0d969553 547 // Multiply poles3d by the weight after tranlations.
7fd59977 548 for (ii=1; ii<=Num1DSS; ii++) {
0d969553 549 // First translate
7fd59977 550 myPoles->ChangeValue(ii).ChangeCoord()
551 -= Translation.XYZ();
552
0d969553 553 //Calculate the second derivative
7fd59977 554 myD2Poles->ChangeValue(ii) *= myWeigths->Value(ii);
555 Vaux.SetXYZ( myDPoles->Value(ii).XYZ());
556 myD2Poles->ChangeValue(ii) += (2*myDWeigths->Value(ii))*Vaux;
557 Vaux.SetXYZ( myPoles->Value(ii).Coord());
558 myD2Poles->ChangeValue(ii) += myD2Weigths->Value(ii)*Vaux;
559
0d969553 560 //Then the remainder for the cash
7fd59977 561 myDPoles->ChangeValue(ii) *= myWeigths->Value(ii);
562 Vaux.SetXYZ( myPoles->Value(ii).Coord());
563 myDPoles->ChangeValue(ii) += myDWeigths->Value(ii)*Vaux;
564 myPoles->ChangeValue(ii).ChangeCoord()
565 *= myWeigths->Value(ii);
566 }
567
0d969553 568 // Apply transformation to poles 2d.
7fd59977 569 for (ii=1; ii<=Num2DSS; ii++) {
570 Vcoord = myD2Poles2d->Value(ii).XY();
571 AAffin->Value(ii).Transforms(Vcoord);
572 myD2Poles2d->ChangeValue(ii).SetXY(Vcoord);
573 Vcoord = myDPoles2d->Value(ii).XY();
574 AAffin->Value(ii).Transforms(Vcoord);
575 myDPoles2d->ChangeValue(ii).SetXY(Vcoord);
576 AAffin->Value(ii).Transforms(myPoles2d->ChangeValue(ii).ChangeCoord());
577 }
578
0d969553 579 // Update variables of control and return
7fd59977 580 first = First;
581 last = Last;
582 myOrder = 2;
583 myParam = Param;
584 }
585
0d969553 586 // Extraction of results
7fd59977 587 index = 0;
588 for (ii=1; ii<=Num1DSS; ii++) {
589 LocalResult[index] = myD2Weigths->Value(ii);
590 index++;
591 }
592 for (ii=1; ii<=Num2DSS; ii++) {
593 LocalResult[index] = myD2Poles2d->Value(ii).X();
594 LocalResult[index+1] = myD2Poles2d->Value(ii).Y();
595 index += 2;
596 }
597 for (ii=1; ii<=Num3DSS; ii++, index+=3) {
598 LocalResult[index] = myD2Poles->Value(ii).X();
599 LocalResult[index+1] = myD2Poles->Value(ii).Y();
600 LocalResult[index+2] = myD2Poles->Value(ii).Z();
601 }
602
603 return Ok;
604}
605
606void Approx_SweepApproximation::
607SurfShape(Standard_Integer& UDegree,
608 Standard_Integer& VDegree,Standard_Integer& NbUPoles,
609 Standard_Integer& NbVPoles,
610 Standard_Integer& NbUKnots,
611 Standard_Integer& NbVKnots) const
612{
613 if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
614 UDegree = udeg;
615 VDegree = vdeg;
616 NbUPoles = tabPoles->ColLength();
617 NbVPoles = tabPoles->RowLength();
618 NbUKnots = tabUKnots->Length();
619 NbVKnots = tabVKnots->Length();
620}
621
622void Approx_SweepApproximation::
623Surface(TColgp_Array2OfPnt& TPoles,
624 TColStd_Array2OfReal& TWeights,
625 TColStd_Array1OfReal& TUKnots,
626 TColStd_Array1OfReal& TVKnots,
627 TColStd_Array1OfInteger& TUMults,
628 TColStd_Array1OfInteger& TVMults) const
629{
630 if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
631 TPoles = tabPoles->Array2();
632 TWeights = tabWeights->Array2();
633 TUKnots = tabUKnots->Array1();
634 TUMults = tabUMults->Array1();
635 TVKnots = tabVKnots->Array1();
636 TVMults = tabVMults->Array1();
637}
638
639Standard_Real Approx_SweepApproximation::MaxErrorOnSurf() const
640{
641 Standard_Integer ii;
642 Standard_Real MaxError = 0, err;
643 if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
644
645 if (myFunc->IsRational()) {
646 TColStd_Array1OfReal Wmin(1, Num1DSS);
647 myFunc->GetMinimalWeight(Wmin);
648 Standard_Real Size = myFunc->MaximalSection();
649 for (ii=1; ii<=Num3DSS; ii++) {
650 err = (Size*MError1d->Value(ii) + MError3d->Value(ii)) / Wmin(ii);
651 if (err>MaxError) MaxError = err;
652 }
653 }
654 else {
655 for (ii=1; ii<=Num3DSS; ii++) {
656 err = MError3d->Value(ii);
657 if (err>MaxError) MaxError = err;
658 }
659 }
660 return MaxError;
661}
662
663 Standard_Real Approx_SweepApproximation::AverageErrorOnSurf() const
664{
665 Standard_Integer ii;
666 Standard_Real MoyError = 0, err;
667 if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
668
669 if (myFunc->IsRational()) {
670 TColStd_Array1OfReal Wmin(1, Num1DSS);
671 myFunc->GetMinimalWeight(Wmin);
672 Standard_Real Size = myFunc->MaximalSection();
673 for (ii=1; ii<=Num3DSS; ii++) {
674 err = (Size*AError1d->Value(ii) + AError3d->Value(ii)) / Wmin(ii);
675 MoyError += err;
676 }
677 }
678 else {
679 for (ii=1; ii<=Num3DSS; ii++) {
680 err = AError3d->Value(ii);
681 MoyError += err;
682 }
683 }
684 return MoyError/Num3DSS;
685}
686
687
688void Approx_SweepApproximation::Curves2dShape(Standard_Integer& Degree,
689 Standard_Integer& NbPoles,
690 Standard_Integer& NbKnots) const
691{
692 if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
693 if (seqPoles2d.Length() == 0) {Standard_DomainError::Raise("Approx_SweepApproximation");}
694 Degree = deg2d;
695 NbPoles = seqPoles2d(1)->Length();
696 NbKnots = tab2dKnots->Length();
697}
698
699void Approx_SweepApproximation::Curve2d(const Standard_Integer Index,
700 TColgp_Array1OfPnt2d& TPoles,
701 TColStd_Array1OfReal& TKnots,
702 TColStd_Array1OfInteger& TMults) const
703{
704 if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
705 if (seqPoles2d.Length() == 0) {Standard_DomainError::Raise("Approx_SweepApproximation");}
706 TPoles = seqPoles2d(Index)->Array1();
707 TKnots = tab2dKnots->Array1();
708 TMults = tab2dMults->Array1();
709}
710
711 Standard_Real Approx_SweepApproximation::Max2dError(const Standard_Integer Index) const
712{
713 if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
714 return tab2dError->Value(Index);
715}
716
717 Standard_Real Approx_SweepApproximation::Average2dError(const Standard_Integer Index) const
718{
719 if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
720 return Ave2dError->Value(Index);
721}
722
723Standard_Real Approx_SweepApproximation::TolCurveOnSurf(const Standard_Integer Index) const
724{
725 if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
726 return COnSurfErr->Value(Index);
727}
728
729 void Approx_SweepApproximation::Dump(Standard_OStream& o) const
730{
731 o << "Dump of SweepApproximation" << endl;
732 if (done) {
733 o << "Error 3d = " << MaxErrorOnSurf() << endl;
734
735 if (Num2DSS>0) {
736 o << "Error 2d = ";
737 for (Standard_Integer ii=1; ii<=Num2DSS; ii++)
738 { o << Max2dError(ii);
739 if (ii < Num2DSS) o << " , " << endl;
740 }
741 cout << endl;
742 }
743 o << tabVKnots->Length()-1 <<" Segment(s) of degree " << vdeg << endl;
744 }
745 else cout << " Not Done " << endl;
746}