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