0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[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//
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
7fd59977 17
18#include <AdvApprox_ApproxAFunction.hxx>
42cf5bc1 19#include <AdvApprox_Cutting.hxx>
7fd59977 20#include <AdvApprox_DichoCutting.hxx>
21#include <AdvApprox_PrefAndRec.hxx>
42cf5bc1 22#include <Approx_SweepApproximation.hxx>
23#include <Approx_SweepFunction.hxx>
24#include <BSplCLib.hxx>
25#include <gp_XYZ.hxx>
26#include <Standard_DomainError.hxx>
27#include <Standard_OutOfRange.hxx>
28#include <StdFail_NotDone.hxx>
7fd59977 29#include <TColgp_Array1OfPnt.hxx>
30#include <TColgp_Array1OfPnt2d.hxx>
31#include <TColgp_Array1OfVec.hxx>
32#include <TColgp_Array1OfVec2d.hxx>
7fd59977 33#include <TColStd_Array1OfReal.hxx>
34
7fd59977 35//=======================================================================
36//class : Approx_SweepApproximation_Eval
37//purpose: evaluator class for approximation
38//=======================================================================
7fd59977 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
aff73fd5 166 if (Num2DSS>0)
167 {
7fd59977 168 myPoles2d = new (TColgp_HArray1OfPnt2d)(1, Num2DSS);
169 myDPoles2d = new (TColgp_HArray1OfVec2d)(1, Num2DSS);
170 myD2Poles2d = new (TColgp_HArray1OfVec2d)(1, Num2DSS);
171 COnSurfErr = new (TColStd_HArray1OfReal)(1, Num2DSS);
172 }
aff73fd5 173 else
174 {
175 myPoles2d = new TColgp_HArray1OfPnt2d();
176 myDPoles2d = new TColgp_HArray1OfVec2d();
177 myD2Poles2d = new TColgp_HArray1OfVec2d();
178 COnSurfErr = new TColStd_HArray1OfReal();
179 }
180
0d969553 181// Checks if myFunc->D2 is implemented
7fd59977 182 if (continuity >= GeomAbs_C2) {
183 Standard_Boolean B;
184 B = myFunc->D2(First, First, Last,
185 myPoles->ChangeArray1(), myDPoles->ChangeArray1(),
186 myD2Poles->ChangeArray1(),
187 myPoles2d->ChangeArray1(), myDPoles2d->ChangeArray1(),
188 myD2Poles2d->ChangeArray1(),
189 myWeigths->ChangeArray1(), myDWeigths->ChangeArray1(),
190 myD2Weigths->ChangeArray1());
191 if (!B) continuity = GeomAbs_C1;
192 }
0d969553 193// Checks if myFunc->D1 is implemented
7fd59977 194 if (continuity == GeomAbs_C1) {
195 Standard_Boolean B;
196 B = myFunc->D1(First, First, Last,
197 myPoles->ChangeArray1(), myDPoles->ChangeArray1(),
198 myPoles2d->ChangeArray1(), myDPoles2d->ChangeArray1(),
199 myWeigths->ChangeArray1(), myDWeigths->ChangeArray1());
200 if (!B) continuity = GeomAbs_C0;
201 }
202
0d969553 203// So that F was at least 20 times more exact than its approx
7fd59977 204 myFunc->SetTolerance(Tol3dMin/20, Tol2d/20);
205
206 Standard_Integer NbIntervalC2 = myFunc->NbIntervals(GeomAbs_C2);
207 Standard_Integer NbIntervalC3 = myFunc->NbIntervals(GeomAbs_C3);
208
209 if (NbIntervalC3 > 1) {
0d969553 210// (3.1) Approximation with preferential cut
7fd59977 211 TColStd_Array1OfReal Param_de_decoupeC2 (1, NbIntervalC2+1);
212 myFunc->Intervals(Param_de_decoupeC2, GeomAbs_C2);
213 TColStd_Array1OfReal Param_de_decoupeC3 (1, NbIntervalC3+1);
214 myFunc->Intervals(Param_de_decoupeC3, GeomAbs_C3);
215
216
217 AdvApprox_PrefAndRec Preferentiel(Param_de_decoupeC2,
218 Param_de_decoupeC3);
219
220 Approx_SweepApproximation_Eval ev (*this);
221 Approximation(OneDTol, TwoDTol, ThreeDTol,
222 The3D2DTol,
223 First, Last,
224 continuity,
225 Degmax, Segmax,
226 ev,
227 Preferentiel);
228 }
229 else {
0d969553 230// (3.2) Approximation without preferential cut
7fd59977 231 AdvApprox_DichoCutting Dichotomie;
232 Approx_SweepApproximation_Eval ev (*this);
233 Approximation(OneDTol, TwoDTol, ThreeDTol,
234 The3D2DTol,
235 First, Last,
236 continuity,
237 Degmax, Segmax,
238 ev,
239 Dichotomie);
240 }
241}
242
243//========================================================================
244//function : Approximation
0d969553 245//purpose : Call F(t) and store the results
7fd59977 246//========================================================================
247void Approx_SweepApproximation::
248Approximation(const Handle(TColStd_HArray1OfReal)& OneDTol,
249 const Handle(TColStd_HArray1OfReal)& TwoDTol,
250 const Handle(TColStd_HArray1OfReal)& ThreeDTol,
251 const Standard_Real BoundTol,
252 const Standard_Real First,const Standard_Real Last,
253 const GeomAbs_Shape Continuity,const Standard_Integer Degmax,
254 const Standard_Integer Segmax,
255 const AdvApprox_EvaluatorFunction& TheApproxFunction,
256 const AdvApprox_Cutting& TheCuttingTool)
257{
258 AdvApprox_ApproxAFunction Approx(Num1DSS,
259 Num2DSS,
260 Num3DSS,
261 OneDTol,
262 TwoDTol,
263 ThreeDTol,
264 First,
265 Last,
266 Continuity,
267 Degmax,
268 Segmax,
269 TheApproxFunction,
270 TheCuttingTool);
271 done = Approx.HasResult();
272
273 if (done) {
0d969553 274 // --> Fill Champs of the surface ----
7fd59977 275 Standard_Integer ii, jj;
276
277 vdeg = Approx.Degree();
0d969553
Y
278 // Unfortunately Adv_Approx stores the transposition of the required
279 // so, writing tabPoles = Approx.Poles() will give an erroneous result
280 // It is only possible to allocate and recopy term by term...
7fd59977 281 tabPoles = new (TColgp_HArray2OfPnt)
282 (1, Num3DSS, 1, Approx.NbPoles());
283 tabWeights = new (TColStd_HArray2OfReal)
284 (1, Num3DSS, 1, Approx.NbPoles());
285
286 if (Num1DSS == Num3DSS) {
287 Standard_Real wpoid;
288 gp_Pnt P;
289 for (ii=1; ii <=Num3DSS; ii++) {
290 for (jj=1; jj <=Approx.NbPoles() ; jj++) {
291 P = Approx.Poles()->Value(jj,ii);
292 wpoid = Approx.Poles1d()->Value(jj,ii);
0d969553 293 P.ChangeCoord() /= wpoid; // It is necessary to divide poles by weight
7fd59977 294 P.Translate(Translation);
295 tabPoles->SetValue (ii, jj, P);
296 tabWeights->SetValue(ii, jj, wpoid );
297 }
298 }
299 }
300 else {
301 tabWeights->Init(1);
302 for (ii=1; ii <=Num3DSS; ii++) {
303 for (jj=1; jj <=Approx.NbPoles() ; jj++) {
304 tabPoles->SetValue (ii, jj, Approx.Poles ()->Value(jj,ii) );
305 }
306 }
307 }
308
0d969553 309 // this is better
7fd59977 310 tabVKnots = Approx.Knots();
311 tabVMults = Approx.Multiplicities();
312
313
314
0d969553 315 // --> Filling of curves 2D ----------
7fd59977 316 if (Num2DSS>0) {
317 gp_GTrsf2d TrsfInv;
318 deg2d = vdeg;
319 tab2dKnots = Approx.Knots();
320 tab2dMults = Approx.Multiplicities();
321
322 for (ii=1; ii<=Num2DSS; ii++) {
323 TrsfInv = AAffin->Value(ii).Inverted();
324 Handle(TColgp_HArray1OfPnt2d) P2d =
325 new (TColgp_HArray1OfPnt2d) (1, Approx.NbPoles());
326 Approx.Poles2d( ii, P2d->ChangeArray1() );
0d969553 327 // do not forget to apply inverted homothety.
7fd59977 328 for (jj=1; jj<=Approx.NbPoles(); jj++) {
329 TrsfInv.Transforms(P2d->ChangeValue(jj).ChangeCoord());
330 }
331 seqPoles2d.Append(P2d);
332 }
333 }
0d969553 334 // ---> Filling of errors
7fd59977 335 MError3d = new (TColStd_HArray1OfReal) (1,Num3DSS);
336 AError3d = new (TColStd_HArray1OfReal) (1,Num3DSS);
337 for (ii=1; ii<=Num3DSS; ii++) {
338 MError3d->SetValue(ii, Approx.MaxError(3, ii));
339 AError3d->SetValue(ii, Approx.AverageError(3, ii));
340 }
341
342 if (myFunc->IsRational()) {
343 MError1d = new (TColStd_HArray1OfReal) (1,Num3DSS);
344 AError1d = new (TColStd_HArray1OfReal) (1,Num3DSS);
345 for (ii=1; ii<=Num1DSS; ii++) {
346 MError1d->SetValue(ii, Approx.MaxError(1, ii));
347 AError1d->SetValue(ii, Approx.AverageError(1, ii));
348 }
349 }
350
351 if (Num2DSS>0) {
352 tab2dError = new (TColStd_HArray1OfReal) (1,Num2DSS);
353 Ave2dError = new (TColStd_HArray1OfReal) (1,Num2DSS);
354 for (ii=1; ii<=Num2DSS; ii++) {
355 tab2dError->SetValue(ii, Approx.MaxError(2, ii));
356 Ave2dError->SetValue(ii, Approx.AverageError(2, ii));
357 COnSurfErr->SetValue(ii,
358 (tab2dError->Value(ii)/TwoDTol->Value(ii))*BoundTol);
359 }
360 }
361 }
362}
363
364Standard_Integer Approx_SweepApproximation::Eval(const Standard_Real Parameter,
365 const Standard_Integer DerivativeRequest,
366 const Standard_Real First,
367 const Standard_Real Last,
368 Standard_Real& Result)
369{
370 Standard_Integer ier=0;
371 switch (DerivativeRequest) {
372 case 0 :
373 ier = ( ! D0(Parameter, First, Last, Result));
374 break;
375 case 1 :
376 ier = ( ! D1(Parameter, First, Last, Result));
377 break;
378 case 2 :
379 ier = ( ! D2(Parameter, First, Last,Result));
380 break;
381 default :
382 ier = 2;
383 }
384 return ier;
385}
386
387Standard_Boolean Approx_SweepApproximation::D0(const Standard_Real Param,
388 const Standard_Real First,
389 const Standard_Real Last,
390 Standard_Real& Result)
391{
392 Standard_Integer index, ii;
393 Standard_Boolean Ok=Standard_True;
394 Standard_Real * LocalResult = &Result;
395
0d969553 396 // Management of limits
7fd59977 397 if ((first!=First) || (Last!=last)) {
398 myFunc->SetInterval(First, Last);
399 }
400
401 if (! ( (Param==myParam) && (myOrder>=0)
402 && (first==First) && (Last==last)) ) {
0d969553 403 // Positioning in case when the last operation is not repeated.
7fd59977 404 Ok = myFunc->D0(Param, First, Last,
405 myPoles->ChangeArray1(),
406 myPoles2d->ChangeArray1(),
407 myWeigths->ChangeArray1());
408
0d969553 409 // poles3d are multiplied by weight after tranlation.
7fd59977 410 for (ii=1; ii<=Num1DSS; ii++) {
411 myPoles->ChangeValue(ii).ChangeCoord()
412 -= Translation.XYZ();
413 myPoles->ChangeValue(ii).ChangeCoord()
414 *= myWeigths->Value(ii);
415 }
416
0d969553 417 // The transformation is applied to poles 2d.
7fd59977 418 for (ii=1; ii<=Num2DSS; ii++) {
419 AAffin->Value(ii).Transforms(myPoles2d->ChangeValue(ii).ChangeCoord());
420 }
421
0d969553 422 // Update variables of controle and return
7fd59977 423 first = First;
424 last = Last;
425 myOrder = 0;
426 myParam = Param;
427 }
428
0d969553 429 // Extraction of results
7fd59977 430 index = 0;
431 for (ii=1; ii<=Num1DSS; ii++) {
432 LocalResult[index] = myWeigths->Value(ii);
433 index++;
434 }
435 for (ii=1; ii<=Num2DSS; ii++) {
436 LocalResult[index] = myPoles2d->Value(ii).X();
437 LocalResult[index+1] = myPoles2d->Value(ii).Y();
438 index += 2;
439 }
440 for (ii=1; ii<=Num3DSS; ii++, index+=3) {
441 LocalResult[index] = myPoles->Value(ii).X();
442 LocalResult[index+1] = myPoles->Value(ii).Y();
443 LocalResult[index+2] = myPoles->Value(ii).Z();
444 }
445
446 return Ok;
447}
448
449Standard_Boolean Approx_SweepApproximation::D1(const Standard_Real Param,
450 const Standard_Real First,
451 const Standard_Real Last,
452 Standard_Real& Result)
453{
454 gp_XY Vcoord;
455 gp_Vec Vaux;
456 Standard_Integer index, ii;
457 Standard_Boolean Ok=Standard_True;
458 Standard_Real * LocalResult = &Result;
459
460
461 if ((first!=First) || (Last!=last)) {
462 myFunc->SetInterval(First, Last);
463 }
464
465 if (! ( (Param==myParam) && (myOrder>=1)
466 && (first==First) && (Last==last)) ){
467
0d969553 468 // Positioning
7fd59977 469 Ok = myFunc->D1(Param, First, Last,
470 myPoles->ChangeArray1(),
471 myDPoles->ChangeArray1(),
472 myPoles2d->ChangeArray1(),
473 myDPoles2d->ChangeArray1(),
474 myWeigths->ChangeArray1(),
475 myDWeigths->ChangeArray1());
476
0d969553
Y
477 // Take into account the multiplication of poles3d by weights.
478 // and the translation.
7fd59977 479 for ( ii=1; ii<=Num1DSS; ii++) {
0d969553 480 //Translation on the section
7fd59977 481 myPoles->ChangeValue(ii).ChangeCoord()
482 -= Translation.XYZ();
0d969553 483 // Homothety on all.
32ca7a51 484 const Standard_Real aWeight = myWeigths->Value(ii);
485 myDPoles->ChangeValue(ii) *= aWeight;
7fd59977 486 Vaux.SetXYZ( myPoles->Value(ii).Coord());
487 myDPoles->ChangeValue(ii) += myDWeigths->Value(ii)*Vaux;
32ca7a51 488 myPoles->ChangeValue(ii).ChangeCoord() *= aWeight; // for the cash
7fd59977 489 }
490
491
0d969553 492 // Apply transformation 2d to suitable vectors
7fd59977 493 for (ii=1; ii<=Num2DSS; ii++) {
494 Vcoord = myDPoles2d->Value(ii).XY();
495 AAffin->Value(ii).Transforms(Vcoord);
496 myDPoles2d->ChangeValue(ii).SetXY(Vcoord);
497 AAffin->Value(ii).Transforms(myPoles2d->ChangeValue(ii).ChangeCoord());
498 }
499
0d969553 500 // Update control variables and return
7fd59977 501 first = First;
502 last = Last;
503 myOrder = 1;
504 myParam = Param;
505 }
506
0d969553 507 // Extraction of results
7fd59977 508 index = 0;
509 for (ii=1; ii<=Num1DSS; ii++) {
510 LocalResult[index] = myDWeigths->Value(ii);
511 index++;
512 }
513 for (ii=1; ii<=Num2DSS; ii++) {
514 LocalResult[index] = myDPoles2d->Value(ii).X();
515 LocalResult[index+1] = myDPoles2d->Value(ii).Y();
516 index += 2;
517 }
518 for (ii=1; ii<=Num3DSS; ii++, index+=3) {
519 LocalResult[index] = myDPoles->Value(ii).X();
520 LocalResult[index+1] = myDPoles->Value(ii).Y();
521 LocalResult[index+2] = myDPoles->Value(ii).Z();
522 }
523 return Ok;
524}
525
526Standard_Boolean Approx_SweepApproximation::D2(const Standard_Real Param,
527 const Standard_Real First,
528 const Standard_Real Last,
529 Standard_Real& Result)
530{
531 gp_XY Vcoord;
532 gp_Vec Vaux;
533 Standard_Integer index, ii;
534 Standard_Boolean Ok=Standard_True;
535 Standard_Real * LocalResult = &Result;
536
0d969553 537 // management of limits
7fd59977 538 if ((first!=First) || (Last!=last)) {
539 myFunc->SetInterval(First, Last);
540 }
541
542 if (! ( (Param==myParam) && (myOrder>=2)
543 && (first==First) && (Last==last)) ) {
0d969553 544 // Positioning in case when the last operation is not repeated
7fd59977 545 Ok = myFunc->D2(Param, First, Last,
546 myPoles->ChangeArray1(),
547 myDPoles->ChangeArray1(),
548 myD2Poles->ChangeArray1(),
549 myPoles2d->ChangeArray1(),
550 myDPoles2d->ChangeArray1(),
551 myD2Poles2d->ChangeArray1(),
552 myWeigths->ChangeArray1(),
553 myDWeigths->ChangeArray1(),
554 myD2Weigths->ChangeArray1());
555
0d969553 556 // Multiply poles3d by the weight after tranlations.
7fd59977 557 for (ii=1; ii<=Num1DSS; ii++) {
0d969553 558 // First translate
7fd59977 559 myPoles->ChangeValue(ii).ChangeCoord()
560 -= Translation.XYZ();
561
0d969553 562 //Calculate the second derivative
7fd59977 563 myD2Poles->ChangeValue(ii) *= myWeigths->Value(ii);
564 Vaux.SetXYZ( myDPoles->Value(ii).XYZ());
565 myD2Poles->ChangeValue(ii) += (2*myDWeigths->Value(ii))*Vaux;
566 Vaux.SetXYZ( myPoles->Value(ii).Coord());
567 myD2Poles->ChangeValue(ii) += myD2Weigths->Value(ii)*Vaux;
568
0d969553 569 //Then the remainder for the cash
7fd59977 570 myDPoles->ChangeValue(ii) *= myWeigths->Value(ii);
571 Vaux.SetXYZ( myPoles->Value(ii).Coord());
572 myDPoles->ChangeValue(ii) += myDWeigths->Value(ii)*Vaux;
573 myPoles->ChangeValue(ii).ChangeCoord()
574 *= myWeigths->Value(ii);
575 }
576
0d969553 577 // Apply transformation to poles 2d.
7fd59977 578 for (ii=1; ii<=Num2DSS; ii++) {
579 Vcoord = myD2Poles2d->Value(ii).XY();
580 AAffin->Value(ii).Transforms(Vcoord);
581 myD2Poles2d->ChangeValue(ii).SetXY(Vcoord);
582 Vcoord = myDPoles2d->Value(ii).XY();
583 AAffin->Value(ii).Transforms(Vcoord);
584 myDPoles2d->ChangeValue(ii).SetXY(Vcoord);
585 AAffin->Value(ii).Transforms(myPoles2d->ChangeValue(ii).ChangeCoord());
586 }
587
0d969553 588 // Update variables of control and return
7fd59977 589 first = First;
590 last = Last;
591 myOrder = 2;
592 myParam = Param;
593 }
594
0d969553 595 // Extraction of results
7fd59977 596 index = 0;
597 for (ii=1; ii<=Num1DSS; ii++) {
598 LocalResult[index] = myD2Weigths->Value(ii);
599 index++;
600 }
601 for (ii=1; ii<=Num2DSS; ii++) {
602 LocalResult[index] = myD2Poles2d->Value(ii).X();
603 LocalResult[index+1] = myD2Poles2d->Value(ii).Y();
604 index += 2;
605 }
606 for (ii=1; ii<=Num3DSS; ii++, index+=3) {
607 LocalResult[index] = myD2Poles->Value(ii).X();
608 LocalResult[index+1] = myD2Poles->Value(ii).Y();
609 LocalResult[index+2] = myD2Poles->Value(ii).Z();
610 }
611
612 return Ok;
613}
614
615void Approx_SweepApproximation::
616SurfShape(Standard_Integer& UDegree,
617 Standard_Integer& VDegree,Standard_Integer& NbUPoles,
618 Standard_Integer& NbVPoles,
619 Standard_Integer& NbUKnots,
620 Standard_Integer& NbVKnots) const
621{
9775fa61 622 if (!done) {throw StdFail_NotDone("Approx_SweepApproximation");}
7fd59977 623 UDegree = udeg;
624 VDegree = vdeg;
625 NbUPoles = tabPoles->ColLength();
626 NbVPoles = tabPoles->RowLength();
627 NbUKnots = tabUKnots->Length();
628 NbVKnots = tabVKnots->Length();
629}
630
631void Approx_SweepApproximation::
632Surface(TColgp_Array2OfPnt& TPoles,
633 TColStd_Array2OfReal& TWeights,
634 TColStd_Array1OfReal& TUKnots,
635 TColStd_Array1OfReal& TVKnots,
636 TColStd_Array1OfInteger& TUMults,
637 TColStd_Array1OfInteger& TVMults) const
638{
9775fa61 639 if (!done) {throw StdFail_NotDone("Approx_SweepApproximation");}
7fd59977 640 TPoles = tabPoles->Array2();
641 TWeights = tabWeights->Array2();
642 TUKnots = tabUKnots->Array1();
643 TUMults = tabUMults->Array1();
644 TVKnots = tabVKnots->Array1();
645 TVMults = tabVMults->Array1();
646}
647
648Standard_Real Approx_SweepApproximation::MaxErrorOnSurf() const
649{
650 Standard_Integer ii;
651 Standard_Real MaxError = 0, err;
9775fa61 652 if (!done) {throw StdFail_NotDone("Approx_SweepApproximation");}
7fd59977 653
654 if (myFunc->IsRational()) {
655 TColStd_Array1OfReal Wmin(1, Num1DSS);
656 myFunc->GetMinimalWeight(Wmin);
657 Standard_Real Size = myFunc->MaximalSection();
658 for (ii=1; ii<=Num3DSS; ii++) {
659 err = (Size*MError1d->Value(ii) + MError3d->Value(ii)) / Wmin(ii);
660 if (err>MaxError) MaxError = err;
661 }
662 }
663 else {
664 for (ii=1; ii<=Num3DSS; ii++) {
665 err = MError3d->Value(ii);
666 if (err>MaxError) MaxError = err;
667 }
668 }
669 return MaxError;
670}
671
672 Standard_Real Approx_SweepApproximation::AverageErrorOnSurf() const
673{
674 Standard_Integer ii;
675 Standard_Real MoyError = 0, err;
9775fa61 676 if (!done) {throw StdFail_NotDone("Approx_SweepApproximation");}
7fd59977 677
678 if (myFunc->IsRational()) {
679 TColStd_Array1OfReal Wmin(1, Num1DSS);
680 myFunc->GetMinimalWeight(Wmin);
681 Standard_Real Size = myFunc->MaximalSection();
682 for (ii=1; ii<=Num3DSS; ii++) {
683 err = (Size*AError1d->Value(ii) + AError3d->Value(ii)) / Wmin(ii);
684 MoyError += err;
685 }
686 }
687 else {
688 for (ii=1; ii<=Num3DSS; ii++) {
689 err = AError3d->Value(ii);
690 MoyError += err;
691 }
692 }
693 return MoyError/Num3DSS;
694}
695
696
697void Approx_SweepApproximation::Curves2dShape(Standard_Integer& Degree,
698 Standard_Integer& NbPoles,
699 Standard_Integer& NbKnots) const
700{
9775fa61 701 if (!done) {throw StdFail_NotDone("Approx_SweepApproximation");}
702 if (seqPoles2d.Length() == 0) {throw Standard_DomainError("Approx_SweepApproximation");}
7fd59977 703 Degree = deg2d;
704 NbPoles = seqPoles2d(1)->Length();
705 NbKnots = tab2dKnots->Length();
706}
707
708void Approx_SweepApproximation::Curve2d(const Standard_Integer Index,
709 TColgp_Array1OfPnt2d& TPoles,
710 TColStd_Array1OfReal& TKnots,
711 TColStd_Array1OfInteger& TMults) const
712{
9775fa61 713 if (!done) {throw StdFail_NotDone("Approx_SweepApproximation");}
714 if (seqPoles2d.Length() == 0) {throw Standard_DomainError("Approx_SweepApproximation");}
7fd59977 715 TPoles = seqPoles2d(Index)->Array1();
716 TKnots = tab2dKnots->Array1();
717 TMults = tab2dMults->Array1();
718}
719
720 Standard_Real Approx_SweepApproximation::Max2dError(const Standard_Integer Index) const
721{
9775fa61 722 if (!done) {throw StdFail_NotDone("Approx_SweepApproximation");}
7fd59977 723 return tab2dError->Value(Index);
724}
725
726 Standard_Real Approx_SweepApproximation::Average2dError(const Standard_Integer Index) const
727{
9775fa61 728 if (!done) {throw StdFail_NotDone("Approx_SweepApproximation");}
7fd59977 729 return Ave2dError->Value(Index);
730}
731
732Standard_Real Approx_SweepApproximation::TolCurveOnSurf(const Standard_Integer Index) const
733{
9775fa61 734 if (!done) {throw StdFail_NotDone("Approx_SweepApproximation");}
7fd59977 735 return COnSurfErr->Value(Index);
736}
737
738 void Approx_SweepApproximation::Dump(Standard_OStream& o) const
739{
04232180 740 o << "Dump of SweepApproximation" << std::endl;
7fd59977 741 if (done) {
04232180 742 o << "Error 3d = " << MaxErrorOnSurf() << std::endl;
7fd59977 743
744 if (Num2DSS>0) {
745 o << "Error 2d = ";
746 for (Standard_Integer ii=1; ii<=Num2DSS; ii++)
747 { o << Max2dError(ii);
04232180 748 if (ii < Num2DSS) o << " , " << std::endl;
7fd59977 749 }
04232180 750 std::cout << std::endl;
7fd59977 751 }
04232180 752 o << tabVKnots->Length()-1 <<" Segment(s) of degree " << vdeg << std::endl;
7fd59977 753 }
04232180 754 else std::cout << " Not Done " << std::endl;
7fd59977 755}