Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1996-03-05 |
2 | // Created by: Joelle CHAUVET | |
3 | // Copyright (c) 1996-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
12 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
b311480e | 16 | |
7fd59977 | 17 | #include <GeomPlate_MakeApprox.ixx> |
18 | #include <GeomPlate_Surface.hxx> | |
19 | #include <GeomPlate_PlateG0Criterion.hxx> | |
20 | #include <GeomPlate_PlateG1Criterion.hxx> | |
21 | ||
22 | #include <Geom_BSplineSurface.hxx> | |
23 | #include <Geom_Surface.hxx> | |
24 | ||
25 | #include <TColgp_SequenceOfXY.hxx> | |
26 | #include <TColgp_SequenceOfXYZ.hxx> | |
27 | #include <gp_Vec.hxx> | |
28 | #include <gp_Pnt.hxx> | |
29 | #include <gp_XY.hxx> | |
30 | #include <PLib.hxx> | |
31 | ||
32 | #include <TColStd_HArray1OfReal.hxx> | |
33 | #include <TColStd_HArray1OfInteger.hxx> | |
34 | #include <TColStd_HArray2OfReal.hxx> | |
7fd59977 | 35 | |
36 | #include <AdvApp2Var_Criterion.hxx> | |
37 | #include <AdvApp2Var_ApproxAFunc2Var.hxx> | |
38 | #include <AdvApprox_PrefCutting.hxx> | |
39 | #include <AdvApprox_Cutting.hxx> | |
40 | #include <AdvApprox_DichoCutting.hxx> | |
41 | ||
42 | #include <Plate_Plate.hxx> | |
43 | ||
41194117 K |
44 | class GeomPlate_MakeApprox_Eval : public AdvApp2Var_EvaluatorFunc2Var |
45 | { | |
46 | ||
47 | public: | |
48 | ||
49 | GeomPlate_MakeApprox_Eval (const Handle(Geom_Surface)& theSurf) | |
50 | : mySurf (theSurf) {} | |
51 | ||
52 | virtual void Evaluate (Standard_Integer* theDimension, | |
53 | Standard_Real* theUStartEnd, | |
54 | Standard_Real* theVStartEnd, | |
55 | Standard_Integer* theFavorIso, | |
56 | Standard_Real* theConstParam, | |
57 | Standard_Integer* theNbParams, | |
58 | Standard_Real* theParameters, | |
59 | Standard_Integer* theUOrder, | |
60 | Standard_Integer* theVOrder, | |
61 | Standard_Real* theResult, | |
62 | Standard_Integer* theErrorCode) const; | |
7fd59977 | 63 | |
41194117 | 64 | private: |
7fd59977 | 65 | |
41194117 K |
66 | Handle(Geom_Surface) mySurf; |
67 | ||
68 | }; | |
69 | ||
70 | void GeomPlate_MakeApprox_Eval::Evaluate (Standard_Integer * Dimension, | |
7fd59977 | 71 | // Dimension |
72 | Standard_Real * UStartEnd, | |
73 | // StartEnd[2] in U | |
74 | Standard_Real * VStartEnd, | |
75 | // StartEnd[2] in V | |
76 | Standard_Integer * FavorIso, | |
77 | // Choice of constante, 1 for U, 2 for V | |
78 | Standard_Real * ConstParam, | |
79 | // Value of constant parameter | |
80 | Standard_Integer * NbParams, | |
81 | // Number of parameters N | |
82 | Standard_Real * Parameters, | |
83 | // Values of parameters, | |
84 | Standard_Integer * UOrder, | |
85 | // Derivative Request in U | |
86 | Standard_Integer * VOrder, | |
87 | // Derivative Request in V | |
88 | Standard_Real * Result, | |
89 | // Result[Dimension,N] | |
41194117 | 90 | Standard_Integer * ErrorCode) const |
7fd59977 | 91 | // Error Code |
41194117 | 92 | { |
7fd59977 | 93 | *ErrorCode = 0; |
94 | Standard_Integer idim,jpar; | |
95 | Standard_Real Upar,Vpar; | |
96 | ||
97 | // Dimension incorrecte | |
98 | if (*Dimension!=3) { | |
99 | *ErrorCode = 1; | |
100 | } | |
101 | ||
102 | // Parametres incorrects | |
103 | if (*FavorIso==1) { | |
104 | Upar = *ConstParam; | |
105 | if (( Upar < UStartEnd[0] ) || ( Upar > UStartEnd[1] )) { | |
106 | *ErrorCode = 2; | |
107 | } | |
108 | for (jpar=1;jpar<=*NbParams;jpar++) { | |
109 | Vpar = Parameters[jpar-1]; | |
110 | if (( Vpar < VStartEnd[0] ) || ( Vpar > VStartEnd[1] )) { | |
111 | *ErrorCode = 2; | |
112 | } | |
113 | } | |
114 | } | |
115 | else { | |
116 | Vpar = *ConstParam; | |
117 | if (( Vpar < VStartEnd[0] ) || ( Vpar > VStartEnd[1] )) { | |
118 | *ErrorCode = 2; | |
119 | } | |
120 | for (jpar=1;jpar<=*NbParams;jpar++) { | |
121 | Upar = Parameters[jpar-1]; | |
122 | if (( Upar < UStartEnd[0] ) || ( Upar > UStartEnd[1] )) { | |
123 | *ErrorCode = 2; | |
124 | } | |
125 | } | |
126 | } | |
127 | ||
128 | // Initialisation | |
129 | for (idim=1;idim<=*Dimension;idim++) { | |
130 | for (jpar=1;jpar<=*NbParams;jpar++) { | |
131 | Result[idim-1+(jpar-1)*(*Dimension)] = 0.; | |
132 | } | |
133 | } | |
134 | ||
135 | ||
136 | Standard_Integer Order = *UOrder + *VOrder; | |
137 | gp_Pnt pnt; | |
138 | // gp_Vec vect, v1, v2, v3, v4, v5, v6, v7, v8, v9; | |
139 | gp_Vec v1, v2, v3, v4, v5; | |
140 | ||
141 | if (*FavorIso==1) { | |
142 | Upar = *ConstParam; | |
143 | switch (Order) { | |
144 | case 0 : | |
145 | for (jpar=1;jpar<=*NbParams;jpar++) { | |
146 | Vpar = Parameters[jpar-1]; | |
41194117 | 147 | pnt = mySurf->Value (Upar, Vpar); |
7fd59977 | 148 | Result[(jpar-1)*(*Dimension)] = pnt.X(); |
149 | Result[1+(jpar-1)*(*Dimension)] = pnt.Y(); | |
150 | Result[2+(jpar-1)*(*Dimension)] = pnt.Z(); | |
151 | } | |
152 | break; | |
153 | case 1 : | |
154 | for (jpar=1;jpar<=*NbParams;jpar++) { | |
155 | Vpar = Parameters[jpar-1]; | |
41194117 | 156 | mySurf->D1 (Upar, Vpar, pnt, v1, v2); |
7fd59977 | 157 | if (*UOrder==1) { |
158 | Result[(jpar-1)*(*Dimension)] = v1.X(); | |
159 | Result[1+(jpar-1)*(*Dimension)] = v1.Y(); | |
160 | Result[2+(jpar-1)*(*Dimension)] = v1.Z(); | |
161 | } | |
162 | else { | |
163 | Result[(jpar-1)*(*Dimension)] = v2.X(); | |
164 | Result[1+(jpar-1)*(*Dimension)] = v2.Y(); | |
165 | Result[2+(jpar-1)*(*Dimension)] = v2.Z(); | |
166 | } | |
167 | } | |
168 | break; | |
169 | case 2 : | |
170 | for (jpar=1;jpar<=*NbParams;jpar++) { | |
171 | Vpar = Parameters[jpar-1]; | |
41194117 | 172 | mySurf->D2 (Upar, Vpar, pnt, v1, v2, v3, v4, v5); |
7fd59977 | 173 | if (*UOrder==2) { |
174 | Result[(jpar-1)*(*Dimension)] = v3.X(); | |
175 | Result[1+(jpar-1)*(*Dimension)] = v3.Y(); | |
176 | Result[2+(jpar-1)*(*Dimension)] = v3.Z(); | |
177 | } | |
178 | else if (*UOrder==1) { | |
179 | Result[(jpar-1)*(*Dimension)] = v5.X(); | |
180 | Result[1+(jpar-1)*(*Dimension)] = v5.Y(); | |
181 | Result[2+(jpar-1)*(*Dimension)] = v5.Z(); | |
182 | } | |
183 | else if (*UOrder==0) { | |
184 | Result[(jpar-1)*(*Dimension)] = v4.X(); | |
185 | Result[1+(jpar-1)*(*Dimension)] = v4.Y(); | |
186 | Result[2+(jpar-1)*(*Dimension)] = v4.Z(); | |
187 | } | |
188 | } | |
189 | break; | |
190 | } | |
191 | } | |
192 | else { | |
193 | Vpar = *ConstParam; | |
194 | switch (Order) { | |
195 | case 0 : | |
196 | for (jpar=1;jpar<=*NbParams;jpar++) { | |
197 | Upar = Parameters[jpar-1]; | |
41194117 | 198 | pnt = mySurf->Value (Upar, Vpar); |
7fd59977 | 199 | Result[(jpar-1)*(*Dimension)] = pnt.X(); |
200 | Result[1+(jpar-1)*(*Dimension)] = pnt.Y(); | |
201 | Result[2+(jpar-1)*(*Dimension)] = pnt.Z(); | |
202 | } | |
203 | break; | |
204 | case 1 : | |
205 | for (jpar=1;jpar<=*NbParams;jpar++) { | |
206 | Upar = Parameters[jpar-1]; | |
41194117 | 207 | mySurf->D1 (Upar, Vpar, pnt, v1, v2); |
7fd59977 | 208 | if (*UOrder==1) { |
209 | Result[(jpar-1)*(*Dimension)] = v1.X(); | |
210 | Result[1+(jpar-1)*(*Dimension)] = v1.Y(); | |
211 | Result[2+(jpar-1)*(*Dimension)] = v1.Z(); | |
212 | } | |
213 | else { | |
214 | Result[(jpar-1)*(*Dimension)] = v2.X(); | |
215 | Result[1+(jpar-1)*(*Dimension)] = v2.Y(); | |
216 | Result[2+(jpar-1)*(*Dimension)] = v2.Z(); | |
217 | } | |
218 | } | |
219 | break; | |
220 | case 2 : | |
221 | for (jpar=1;jpar<=*NbParams;jpar++) { | |
222 | Upar = Parameters[jpar-1]; | |
41194117 | 223 | mySurf->D2 (Upar, Vpar, pnt, v1, v2, v3, v4, v5); |
7fd59977 | 224 | if (*UOrder==2) { |
225 | Result[(jpar-1)*(*Dimension)] = v3.X(); | |
226 | Result[1+(jpar-1)*(*Dimension)] = v3.Y(); | |
227 | Result[2+(jpar-1)*(*Dimension)] = v3.Z(); | |
228 | } | |
229 | else if (*UOrder==1) { | |
230 | Result[(jpar-1)*(*Dimension)] = v5.X(); | |
231 | Result[1+(jpar-1)*(*Dimension)] = v5.Y(); | |
232 | Result[2+(jpar-1)*(*Dimension)] = v5.Z(); | |
233 | } | |
234 | else if (*UOrder==0) { | |
235 | Result[(jpar-1)*(*Dimension)] = v4.X(); | |
236 | Result[1+(jpar-1)*(*Dimension)] = v4.Y(); | |
237 | Result[2+(jpar-1)*(*Dimension)] = v4.Z(); | |
238 | } | |
239 | } | |
240 | break; | |
241 | } | |
242 | } | |
243 | ||
244 | } | |
245 | ||
246 | ||
247 | //======================================================================= | |
248 | //function : GeomPlate_MakeApprox | |
249 | //purpose : | |
250 | //======================================================================= | |
251 | ||
252 | GeomPlate_MakeApprox::GeomPlate_MakeApprox(const Handle(GeomPlate_Surface)& SurfPlate, | |
253 | const AdvApp2Var_Criterion& PlateCrit, | |
254 | const Standard_Real Tol3d, | |
255 | const Standard_Integer Nbmax, | |
256 | const Standard_Integer dgmax, | |
257 | const GeomAbs_Shape Continuity, | |
258 | const Standard_Real EnlargeCoeff) | |
259 | { | |
260 | myPlate = SurfPlate; | |
7fd59977 | 261 | |
262 | Standard_Real U0=0., U1=0., V0=0., V1=0.; | |
263 | myPlate->RealBounds(U0, U1, V0, V1); | |
264 | U0 = EnlargeCoeff * U0; | |
265 | U1 = EnlargeCoeff * U1; | |
266 | V0 = EnlargeCoeff * V0; | |
267 | V1 = EnlargeCoeff * V1; | |
268 | ||
269 | Standard_Integer nb1 = 0, nb2 = 0, nb3 = 1; | |
270 | Handle(TColStd_HArray1OfReal) nul1 = | |
271 | new TColStd_HArray1OfReal(1,1); | |
272 | nul1->Init(0.); | |
273 | Handle(TColStd_HArray2OfReal) nul2 = | |
274 | new TColStd_HArray2OfReal(1,1,1,4); | |
275 | nul2->Init(0.); | |
276 | Handle(TColStd_HArray1OfReal) eps3D = | |
277 | new TColStd_HArray1OfReal(1,1); | |
278 | eps3D->Init(Tol3d); | |
279 | Handle(TColStd_HArray2OfReal) epsfr = | |
280 | new TColStd_HArray2OfReal(1,1,1,4); | |
281 | epsfr->Init(Tol3d); | |
282 | GeomAbs_IsoType myType = GeomAbs_IsoV; | |
283 | Standard_Integer myPrec = 0; | |
284 | ||
285 | AdvApprox_DichoCutting myDec; | |
286 | ||
287 | //POP pour WNT | |
41194117 | 288 | GeomPlate_MakeApprox_Eval ev (myPlate); |
7fd59977 | 289 | AdvApp2Var_ApproxAFunc2Var AppPlate(nb1, nb2, nb3, |
290 | nul1,nul1,eps3D, | |
291 | nul2,nul2,epsfr, | |
292 | U0,U1,V0,V1, | |
293 | myType, | |
294 | Continuity, Continuity, | |
295 | myPrec, | |
296 | dgmax,dgmax,Nbmax,ev, | |
297 | // dgmax,dgmax,Nbmax,myPlateSurfEval, | |
298 | PlateCrit,myDec,myDec); | |
299 | mySurface = AppPlate.Surface(1); | |
300 | myAppError = AppPlate.MaxError(3,1); | |
301 | myCritError = AppPlate.CritError(3,1); | |
0797d9d3 | 302 | #ifdef OCCT_DEBUG |
7fd59977 | 303 | cout<<"Approximation results"<<endl; |
304 | cout<<" Approximation error : "<<myAppError<<endl; | |
305 | cout<<" Criterium error : "<<myCritError<<endl; | |
306 | #endif | |
307 | } | |
308 | ||
309 | ||
310 | //======================================================================= | |
311 | //function : GeomPlate_MakeApprox | |
312 | //purpose : | |
313 | //======================================================================= | |
314 | ||
315 | GeomPlate_MakeApprox::GeomPlate_MakeApprox(const Handle(GeomPlate_Surface)& SurfPlate, | |
316 | const Standard_Real Tol3d, | |
317 | const Standard_Integer Nbmax, | |
318 | const Standard_Integer dgmax, | |
319 | const Standard_Real dmax, | |
320 | const Standard_Integer CritOrder, | |
321 | const GeomAbs_Shape Continuity, | |
322 | const Standard_Real EnlargeCoeff) | |
323 | { | |
324 | myPlate = SurfPlate; | |
7fd59977 | 325 | |
326 | TColgp_SequenceOfXY Seq2d; | |
327 | TColgp_SequenceOfXYZ Seq3d; | |
328 | ||
329 | if (CritOrder>=0) { | |
330 | ||
331 | // contraintes 2d d'ordre 0 | |
332 | myPlate->Constraints(Seq2d); | |
333 | ||
334 | // contraintes 3d correspondantes sur plate | |
335 | Standard_Integer i,nbp=Seq2d.Length(); | |
336 | for(i=1;i<=nbp;i++){ | |
337 | gp_XY P2d=Seq2d.Value(i); | |
338 | gp_Pnt PP; | |
339 | gp_Vec v1h,v2h,v3h; | |
340 | if (CritOrder==0) { | |
341 | // a l'ordre 0 | |
41194117 | 342 | myPlate->D0 (P2d.X(), P2d.Y(), PP); |
7fd59977 | 343 | gp_XYZ P3d(PP.X(),PP.Y(),PP.Z()); |
344 | Seq3d.Append(P3d); | |
345 | } | |
346 | else { | |
347 | // a l'ordre 1 | |
41194117 | 348 | myPlate->D1 (P2d.X(), P2d.Y(), PP, v1h, v2h); |
7fd59977 | 349 | v3h=v1h^v2h; |
350 | gp_XYZ P3d(v3h.X(),v3h.Y(),v3h.Z()); | |
351 | Seq3d.Append(P3d); | |
352 | } | |
353 | } | |
354 | } | |
355 | ||
356 | Standard_Real U0=0., U1=0., V0=0., V1=0.; | |
357 | myPlate->RealBounds(U0, U1, V0, V1); | |
358 | U0 = EnlargeCoeff * U0; | |
359 | U1 = EnlargeCoeff * U1; | |
360 | V0 = EnlargeCoeff * V0; | |
361 | V1 = EnlargeCoeff * V1; | |
362 | ||
363 | Standard_Real seuil = Tol3d; | |
364 | if (CritOrder==0&&Tol3d<10*dmax) { | |
365 | seuil=10*dmax; | |
0797d9d3 | 366 | #ifdef OCCT_DEBUG |
7fd59977 | 367 | cout<<"Seuil G0 choisi trop faible par rapport au contour. On prend "<<seuil<<endl; |
368 | #endif | |
369 | } | |
370 | if (CritOrder==1&&Tol3d<10*dmax) { | |
371 | seuil=10*dmax; | |
0797d9d3 | 372 | #ifdef OCCT_DEBUG |
7fd59977 | 373 | cout<<"Seuil G1 choisi trop faible par rapport au contour. On prend "<<seuil<<endl; |
374 | #endif | |
375 | } | |
376 | Standard_Integer nb1 = 0, nb2 = 0, nb3 = 1; | |
377 | Handle(TColStd_HArray1OfReal) nul1 = | |
378 | new TColStd_HArray1OfReal(1,1); | |
379 | nul1->Init(0.); | |
380 | Handle(TColStd_HArray2OfReal) nul2 = | |
381 | new TColStd_HArray2OfReal(1,1,1,4); | |
382 | nul2->Init(0.); | |
383 | Handle(TColStd_HArray1OfReal) eps3D = | |
384 | new TColStd_HArray1OfReal(1,1); | |
385 | eps3D->Init(Tol3d); | |
386 | Handle(TColStd_HArray2OfReal) epsfr = | |
387 | new TColStd_HArray2OfReal(1,1,1,4); | |
388 | epsfr->Init(Tol3d); | |
389 | ||
390 | GeomAbs_IsoType myType = GeomAbs_IsoV; | |
391 | Standard_Integer myPrec = 0; | |
392 | ||
393 | AdvApprox_DichoCutting myDec; | |
394 | ||
395 | if (CritOrder==-1) { | |
396 | myPrec = 1; | |
397 | // POP pour NT | |
41194117 | 398 | GeomPlate_MakeApprox_Eval ev (myPlate); |
7fd59977 | 399 | AdvApp2Var_ApproxAFunc2Var AppPlate(nb1, nb2, nb3, |
400 | nul1,nul1,eps3D, | |
401 | nul2,nul2,epsfr, | |
402 | U0,U1,V0,V1, | |
403 | myType, | |
404 | Continuity, Continuity, | |
405 | myPrec, | |
406 | dgmax,dgmax,Nbmax,ev, | |
407 | myDec,myDec); | |
408 | mySurface = AppPlate.Surface(1); | |
409 | myAppError = AppPlate.MaxError(3,1); | |
410 | myCritError = 0.; | |
0797d9d3 | 411 | #ifdef OCCT_DEBUG |
7fd59977 | 412 | cout<<"Approximation results"<<endl; |
413 | cout<<" Approximation error : "<<myAppError<<endl; | |
414 | #endif | |
415 | } | |
416 | else if (CritOrder==0) { | |
417 | GeomPlate_PlateG0Criterion Crit0(Seq2d,Seq3d,seuil); | |
418 | // POP pour NT | |
41194117 | 419 | GeomPlate_MakeApprox_Eval ev (myPlate); |
7fd59977 | 420 | AdvApp2Var_ApproxAFunc2Var AppPlate(nb1, nb2, nb3, |
421 | nul1,nul1,eps3D, | |
422 | nul2,nul2,epsfr, | |
423 | U0,U1,V0,V1, | |
424 | myType, | |
425 | Continuity, Continuity, | |
426 | myPrec, | |
427 | dgmax,dgmax,Nbmax,ev, | |
428 | // dgmax,dgmax,Nbmax,myPlateSurfEval, | |
429 | Crit0,myDec,myDec); | |
430 | mySurface = AppPlate.Surface(1); | |
431 | myAppError = AppPlate.MaxError(3,1); | |
432 | myCritError = AppPlate.CritError(3,1); | |
0797d9d3 | 433 | #ifdef OCCT_DEBUG |
7fd59977 | 434 | cout<<"Approximation results"<<endl; |
435 | cout<<" Approximation error : "<<myAppError<<endl; | |
436 | cout<<" Criterium error : "<<myCritError<<endl; | |
437 | #endif | |
438 | } | |
439 | else if (CritOrder==1) { | |
440 | GeomPlate_PlateG1Criterion Crit1(Seq2d,Seq3d,seuil); | |
441 | // POP pour NT | |
41194117 | 442 | GeomPlate_MakeApprox_Eval ev (myPlate); |
7fd59977 | 443 | AdvApp2Var_ApproxAFunc2Var AppPlate(nb1, nb2, nb3, |
444 | nul1,nul1,eps3D, | |
445 | nul2,nul2,epsfr, | |
446 | U0,U1,V0,V1, | |
447 | myType, | |
448 | Continuity, Continuity, | |
449 | myPrec, | |
450 | dgmax,dgmax,Nbmax,ev, | |
451 | // dgmax,dgmax,Nbmax,myPlateSurfEval, | |
452 | Crit1,myDec,myDec); | |
453 | mySurface = AppPlate.Surface(1); | |
454 | myAppError = AppPlate.MaxError(3,1); | |
455 | myCritError = AppPlate.CritError(3,1); | |
0797d9d3 | 456 | #ifdef OCCT_DEBUG |
7fd59977 | 457 | cout<<"Approximation results"<<endl; |
458 | cout<<" Approximation error : "<<myAppError<<endl; | |
459 | cout<<" Criterium error : "<<myCritError<<endl; | |
460 | #endif | |
461 | } | |
462 | } | |
463 | ||
464 | ||
465 | ||
466 | //======================================================================= | |
467 | //function : Surface | |
468 | //purpose : | |
469 | //======================================================================= | |
470 | ||
471 | Handle(Geom_BSplineSurface) GeomPlate_MakeApprox::Surface() const | |
472 | { | |
473 | return mySurface; | |
474 | } | |
475 | ||
476 | ||
477 | //======================================================================= | |
478 | //function : ApproxError | |
479 | //purpose : | |
480 | //======================================================================= | |
481 | ||
482 | Standard_Real GeomPlate_MakeApprox::ApproxError() const | |
483 | { | |
484 | return myAppError; | |
485 | } | |
486 | ||
487 | ||
488 | //======================================================================= | |
489 | //function : CriterionError | |
490 | //purpose : | |
491 | //======================================================================= | |
492 | ||
493 | Standard_Real GeomPlate_MakeApprox::CriterionError() const | |
494 | { | |
495 | return myCritError; | |
496 | } |