Commit | Line | Data |
---|---|---|
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 | 34 | class 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 | ||
51 | void 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 | ||
62 | Approx_SweepApproximation:: | |
63 | Approx_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 | ||
73 | void 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 | //======================================================================== |
242 | void Approx_SweepApproximation:: | |
243 | Approximation(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 | ||
359 | Standard_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 | ||
382 | Standard_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 | ||
444 | Standard_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 | ||
521 | Standard_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 | ||
610 | void Approx_SweepApproximation:: | |
611 | SurfShape(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 | ||
626 | void Approx_SweepApproximation:: | |
627 | Surface(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 | ||
643 | Standard_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 | ||
692 | void 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 | ||
703 | void 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 | ||
727 | Standard_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 | } |