Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1998-12-14 |
2 | // Created by: Joelle CHAUVET | |
3 | // Copyright (c) 1998-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 | // Modified: Fri Jan 8 15:47:20 1999 |
7fd59977 | 18 | // enfin un calcul exact pour D1 et D2 |
19 | // le calcul par differ. finies est garde dans verifD1 et verifD2 | |
20 | // Modified: Mon Jan 18 11:06:46 1999 | |
7fd59977 | 21 | // mise au point de D1, D2 et IsConstant |
22 | ||
42cf5bc1 | 23 | #include <BSplCLib.hxx> |
7fd59977 | 24 | #include <Convert_ParameterisationType.hxx> |
42cf5bc1 | 25 | #include <GCPnts_AbscissaPoint.hxx> |
7fd59977 | 26 | #include <Geom_BSplineCurve.hxx> |
42cf5bc1 | 27 | #include <Geom_BSplineSurface.hxx> |
7fd59977 | 28 | #include <Geom_Circle.hxx> |
42cf5bc1 | 29 | #include <Geom_Curve.hxx> |
30 | #include <Geom_Geometry.hxx> | |
31 | #include <Geom_Surface.hxx> | |
32 | #include <Geom_TrimmedCurve.hxx> | |
7fd59977 | 33 | #include <GeomAdaptor_Curve.hxx> |
34 | #include <GeomAdaptor_Surface.hxx> | |
42cf5bc1 | 35 | #include <GeomConvert.hxx> |
36 | #include <GeomFill_AppSurf.hxx> | |
37 | #include <GeomFill_Line.hxx> | |
38 | #include <GeomFill_NSections.hxx> | |
39 | #include <GeomFill_SectionGenerator.hxx> | |
40 | #include <gp_Circ.hxx> | |
41 | #include <gp_Lin.hxx> | |
42 | #include <gp_Pnt.hxx> | |
43 | #include <Precision.hxx> | |
44 | #include <Standard_OutOfRange.hxx> | |
45 | #include <Standard_Type.hxx> | |
7fd59977 | 46 | #include <TColGeom_Array1OfCurve.hxx> |
42cf5bc1 | 47 | #include <TColgp_Array2OfPnt.hxx> |
7fd59977 | 48 | #include <TColStd_Array1OfInteger.hxx> |
42cf5bc1 | 49 | #include <TColStd_Array1OfReal.hxx> |
7fd59977 | 50 | |
42cf5bc1 | 51 | #include <stdio.h> |
92efcf78 | 52 | IMPLEMENT_STANDARD_RTTIEXT(GeomFill_NSections,GeomFill_SectionLaw) |
53 | ||
0797d9d3 | 54 | #ifdef OCCT_DEBUG |
7fd59977 | 55 | # ifdef DRAW |
56 | # include <DrawTrSurf.hxx> | |
ec357c5c | 57 | #include <Geom_Curve.hxx> |
7fd59977 | 58 | # endif |
59 | static Standard_Boolean Affich = 0; | |
60 | static Standard_Integer NbSurf = 0; | |
61 | #endif | |
62 | ||
0797d9d3 | 63 | #ifdef OCCT_DEBUG |
7fd59977 | 64 | // verification des fonctions de derivation D1 et D2 par differences finies |
e83d440f | 65 | static Standard_Boolean verifD1(const TColgp_Array1OfPnt& P1, |
7fd59977 | 66 | const TColStd_Array1OfReal& W1, |
67 | const TColgp_Array1OfPnt& P2, | |
68 | const TColStd_Array1OfReal& W2, | |
69 | const TColgp_Array1OfVec& DPoles, | |
70 | const TColStd_Array1OfReal& DWeights, | |
71 | const Standard_Real pTol, | |
72 | const Standard_Real wTol, | |
73 | const Standard_Real pas) | |
74 | { | |
75 | Standard_Boolean ok = Standard_True; | |
76 | Standard_Integer ii, L = P1.Length(); | |
77 | Standard_Real dw; | |
78 | gp_Vec dP; | |
79 | for (ii=1; ii<=L; ii++) { | |
80 | dw = (W2(ii)-W1(ii)) / pas; | |
81 | if (Abs(dw-DWeights(ii))>wTol) { | |
82 | if (Affich) { | |
04232180 | 83 | std::cout<<"erreur dans la derivee 1ere du poids pour l'indice "<<ii<<std::endl; |
84 | std::cout<<"par diff finies : "<<dw<<std::endl; | |
85 | std::cout<<"resultat obtenu : "<<DWeights(ii)<<std::endl; | |
7fd59977 | 86 | } |
87 | ok = Standard_False; | |
88 | } | |
89 | dP.SetXYZ( (P2(ii).XYZ()- P1(ii).XYZ()) /pas ); | |
90 | gp_Vec diff = dP - DPoles(ii); | |
91 | if (diff.Magnitude()>pTol) { | |
92 | if (Affich) { | |
04232180 | 93 | std::cout<<"erreur dans la derivee 1ere du pole pour l'indice "<<ii<<std::endl; |
94 | std::cout<<"par diff finies : ("<<dP.X() | |
7fd59977 | 95 | <<" "<<dP.Y() |
04232180 | 96 | <<" "<<dP.Z()<<")"<<std::endl; |
97 | std::cout<<"resultat obtenu : ("<<DPoles(ii).X() | |
7fd59977 | 98 | <<" "<<DPoles(ii).Y() |
04232180 | 99 | <<" "<<DPoles(ii).Z()<<")"<<std::endl; |
7fd59977 | 100 | } |
101 | ok = Standard_False; | |
102 | } | |
103 | } | |
104 | return ok; | |
105 | } | |
106 | ||
e83d440f | 107 | static Standard_Boolean verifD2(const TColgp_Array1OfVec& DP1, |
7fd59977 | 108 | const TColStd_Array1OfReal& DW1, |
109 | const TColgp_Array1OfVec& DP2, | |
110 | const TColStd_Array1OfReal& DW2, | |
111 | const TColgp_Array1OfVec& D2Poles, | |
112 | const TColStd_Array1OfReal& D2Weights, | |
113 | const Standard_Real pTol, | |
114 | const Standard_Real wTol, | |
115 | const Standard_Real pas) | |
116 | { | |
8c2d3314 | 117 | Standard_Boolean ok = Standard_True; |
7fd59977 | 118 | Standard_Integer ii, L = DP1.Length(); |
119 | Standard_Real d2w; | |
120 | gp_Vec d2P; | |
121 | for (ii=1; ii<=L; ii++) { | |
122 | Standard_Real dw1 = DW1(ii), dw2 = DW2(ii); | |
123 | d2w = (dw2-dw1) / pas; | |
124 | if (Abs(d2w-D2Weights(ii))>wTol) { | |
125 | if (Affich) { | |
04232180 | 126 | std::cout<<"erreur dans la derivee 2nde du poids pour l'indice "<<ii<<std::endl; |
127 | std::cout<<"par diff finies : "<<d2w<<std::endl; | |
128 | std::cout<<"resultat obtenu : "<<D2Weights(ii)<<std::endl; | |
7fd59977 | 129 | } |
130 | ok = Standard_False; | |
131 | } | |
132 | d2P.SetXYZ( (DP2(ii).XYZ()- DP1(ii).XYZ()) /pas ); | |
133 | gp_Vec diff = d2P - D2Poles(ii); | |
134 | if (diff.Magnitude()>pTol) { | |
135 | if (Affich) { | |
04232180 | 136 | std::cout<<"erreur dans la derivee 2nde du pole pour l'indice "<<ii<<std::endl; |
137 | std::cout<<"par diff finies : ("<<d2P.X() | |
7fd59977 | 138 | <<" "<<d2P.Y() |
04232180 | 139 | <<" "<<d2P.Z()<<")"<<std::endl; |
140 | std::cout<<"resultat obtenu : ("<<D2Poles(ii).X() | |
7fd59977 | 141 | <<" "<<D2Poles(ii).Y() |
04232180 | 142 | <<" "<<D2Poles(ii).Z()<<")"<<std::endl; |
7fd59977 | 143 | } |
144 | ok = Standard_False; | |
145 | } | |
146 | } | |
147 | return ok; | |
148 | } | |
149 | #endif | |
150 | ||
151 | // fonction d'evaluation des poles et des poids de mySurface pour D1 et D2 | |
857ffd5e | 152 | static void ResultEval(const Handle(Geom_BSplineSurface)& surf, |
7fd59977 | 153 | const Standard_Real V, |
154 | const Standard_Integer deriv, | |
155 | TColStd_Array1OfReal& Result) | |
156 | { | |
157 | Standard_Boolean rational = surf->IsVRational() ; | |
158 | Standard_Integer gap = 3; | |
159 | if ( rational ) gap++; | |
160 | Standard_Integer Cdeg = surf->VDegree(), | |
161 | Cdim = surf->NbUPoles() * gap, | |
162 | NbP = surf->NbVPoles(); | |
163 | ||
164 | // les noeuds plats | |
165 | Standard_Integer Ksize = NbP + Cdeg + 1; | |
166 | TColStd_Array1OfReal FKnots(1,Ksize); | |
167 | surf->VKnotSequence(FKnots); | |
168 | ||
169 | // les poles | |
170 | Standard_Integer Psize = Cdim * NbP; | |
171 | TColStd_Array1OfReal SPoles(1,Psize); | |
172 | Standard_Integer ii, jj, ipole=1; | |
173 | for (jj=1;jj<=NbP;jj++) { | |
174 | for (ii=1;ii<=surf->NbUPoles();ii++) { | |
175 | SPoles(ipole) = surf->Pole(ii,jj).X(); | |
176 | SPoles(ipole+1) = surf->Pole(ii,jj).Y(); | |
177 | SPoles(ipole+2) = surf->Pole(ii,jj).Z(); | |
178 | if (rational) { | |
179 | SPoles(ipole+3) = surf->Weight(ii,jj); | |
180 | SPoles(ipole) *= SPoles(ipole+3); | |
181 | SPoles(ipole+1) *= SPoles(ipole+3); | |
182 | SPoles(ipole+2) *= SPoles(ipole+3); | |
183 | } | |
184 | ipole+=gap; | |
185 | } | |
186 | } | |
187 | Standard_Real * Padr = (Standard_Real *) &SPoles(1); | |
188 | ||
189 | Standard_Boolean periodic_flag = Standard_False ; | |
190 | Standard_Integer extrap_mode[2]; | |
191 | extrap_mode[0] = extrap_mode[1] = Cdeg; | |
192 | TColStd_Array1OfReal EvalBS(1, Cdim * (deriv+1)) ; | |
193 | Standard_Real * Eadr = (Standard_Real *) &EvalBS(1) ; | |
194 | BSplCLib::Eval(V,periodic_flag,deriv,extrap_mode[0], | |
195 | Cdeg,FKnots,Cdim,*Padr,*Eadr); | |
196 | ||
197 | for (ii=1;ii<=Cdim;ii++) { | |
198 | Result(ii) = EvalBS(ii+deriv*Cdim); | |
199 | } | |
200 | } | |
201 | ||
202 | ||
203 | //======================================================================= | |
204 | //function : GeomFill_NSections | |
205 | //purpose : | |
206 | //======================================================================= | |
207 | ||
208 | GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC) | |
209 | { | |
210 | mySections = NC; | |
05607219 | 211 | UFirst = 0.; |
212 | ULast = 1.; | |
213 | VFirst = 0.; | |
214 | VLast = 1.; | |
7fd59977 | 215 | myRefSurf.Nullify(); |
216 | ComputeSurface(); | |
217 | } | |
218 | ||
219 | //======================================================================= | |
220 | //function : GeomFill_NSections | |
221 | //purpose : | |
222 | //======================================================================= | |
223 | ||
224 | GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC, | |
225 | const TColStd_SequenceOfReal& NP) | |
226 | { | |
227 | mySections = NC; | |
228 | myParams = NP; | |
229 | UFirst = 0.; | |
230 | ULast = 1.; | |
231 | VFirst = 0.; | |
232 | VLast = 1.; | |
233 | myRefSurf.Nullify(); | |
234 | ComputeSurface(); | |
235 | } | |
236 | ||
237 | //======================================================================= | |
238 | //function : GeomFill_NSections | |
239 | //purpose : | |
240 | //======================================================================= | |
241 | ||
242 | GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC, | |
243 | const TColStd_SequenceOfReal& NP, | |
244 | const Standard_Real UF, | |
245 | const Standard_Real UL, | |
246 | const Standard_Real VF, | |
247 | const Standard_Real VL) | |
248 | { | |
249 | mySections = NC; | |
250 | myParams = NP; | |
251 | UFirst = UF; | |
252 | ULast = UL; | |
253 | VFirst = VF; | |
254 | VLast = VL; | |
255 | myRefSurf.Nullify(); | |
256 | ComputeSurface(); | |
257 | } | |
258 | ||
259 | //======================================================================= | |
260 | //function : GeomFill_NSections | |
261 | //purpose : | |
262 | //======================================================================= | |
263 | ||
264 | GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC, | |
98dbbeb4 | 265 | const GeomFill_SequenceOfTrsf& Trsfs, |
7fd59977 | 266 | const TColStd_SequenceOfReal& NP, |
267 | const Standard_Real UF, | |
268 | const Standard_Real UL, | |
269 | const Standard_Real VF, | |
270 | const Standard_Real VL, | |
271 | const Handle(Geom_BSplineSurface)& Surf) | |
272 | { | |
273 | mySections = NC; | |
98dbbeb4 | 274 | myTrsfs = Trsfs; |
7fd59977 | 275 | myParams = NP; |
276 | UFirst = UF; | |
277 | ULast = UL; | |
278 | VFirst = VF; | |
279 | VLast = VL; | |
280 | myRefSurf = Surf; | |
281 | ComputeSurface(); | |
282 | } | |
283 | ||
284 | //======================================================= | |
285 | // Purpose :D0 | |
286 | //======================================================= | |
287 | Standard_Boolean GeomFill_NSections::D0(const Standard_Real V, | |
288 | TColgp_Array1OfPnt& Poles, | |
289 | TColStd_Array1OfReal& Weights) | |
290 | { | |
291 | if (mySurface.IsNull()) { | |
292 | return Standard_False; | |
293 | } | |
294 | else { | |
295 | Handle(Geom_BSplineCurve) Curve | |
296 | = Handle(Geom_BSplineCurve)::DownCast(mySurface->VIso( V, Standard_False )); | |
297 | TColgp_Array1OfPnt poles(1,mySurface->NbUPoles()); | |
298 | TColStd_Array1OfReal weights(1,mySurface->NbUPoles()); | |
299 | Curve->Poles(poles); | |
300 | Curve->Weights(weights); | |
301 | Standard_Integer ii, L = Poles.Length(); | |
302 | for (ii=1; ii<=L; ii++) { | |
303 | Poles(ii).SetXYZ(poles(ii).XYZ()); | |
304 | Weights(ii) = weights(ii); | |
305 | } | |
306 | } | |
307 | return Standard_True; | |
308 | } | |
309 | ||
310 | //======================================================= | |
311 | // Purpose :D1 | |
312 | //======================================================= | |
313 | Standard_Boolean GeomFill_NSections::D1(const Standard_Real V, | |
314 | TColgp_Array1OfPnt& Poles, | |
315 | TColgp_Array1OfVec& DPoles, | |
316 | TColStd_Array1OfReal& Weights, | |
317 | TColStd_Array1OfReal& DWeights) | |
318 | { | |
319 | if (mySurface.IsNull() ) return Standard_False; | |
320 | ||
321 | Standard_Boolean ok = D0(V,Poles,Weights); | |
322 | if (!ok) return Standard_False; | |
323 | ||
324 | Standard_Integer L = Poles.Length(), derivative_request = 1; | |
325 | Standard_Boolean rational = mySurface->IsVRational() ; | |
326 | Standard_Integer gap = 3; | |
327 | if (rational) gap++; | |
328 | ||
329 | Standard_Integer dimResult = mySurface->NbUPoles() * gap; | |
330 | Handle(Geom_BSplineSurface) surf_deper; | |
331 | if (mySurface->IsVPeriodic()) { | |
332 | surf_deper = Handle(Geom_BSplineSurface)::DownCast(mySurface->Copy()); | |
333 | surf_deper->SetVNotPeriodic(); | |
334 | dimResult = surf_deper->NbUPoles() * gap; | |
335 | } | |
336 | TColStd_Array1OfReal Result(1,dimResult); | |
337 | if (mySurface->IsVPeriodic()) { | |
338 | ResultEval(surf_deper,V,derivative_request,Result); | |
339 | } | |
340 | else { | |
341 | ResultEval(mySurface,V,derivative_request,Result); | |
342 | } | |
343 | ||
344 | ||
345 | Standard_Real ww, EpsW = 10*Precision::PConfusion(); | |
346 | Standard_Boolean NullWeight = Standard_False; | |
347 | if (!rational) DWeights.Init(0.); | |
348 | Standard_Integer indice = 1, ii; | |
349 | ||
350 | // recopie des poles du resultat sous forme de points 3D et de poids | |
351 | for (ii=1; ii<=L && (!NullWeight) ; ii++) { | |
352 | DPoles(ii).SetX( Result(indice) ); | |
353 | DPoles(ii).SetY( Result(indice+1) ); | |
354 | DPoles(ii).SetZ( Result(indice+2) ); | |
355 | if (rational) { | |
356 | ww = Weights(ii); | |
357 | if (ww < EpsW) { | |
358 | NullWeight = Standard_True; | |
359 | } | |
360 | else { | |
361 | DWeights(ii) = Result(indice+3); | |
362 | DPoles(ii) | |
363 | .SetXYZ( ( DPoles(ii).XYZ()-DWeights(ii)*Poles(ii).Coord() ) / ww ); | |
364 | } | |
365 | } | |
366 | indice += gap; | |
367 | } | |
368 | if (NullWeight) return Standard_False; | |
369 | ||
370 | // verif par diff finies sous debug sauf pour les surfaces periodiques | |
0797d9d3 | 371 | #ifdef OCCT_DEBUG |
7fd59977 | 372 | if (!mySurface->IsVPeriodic()) { |
373 | Standard_Real pas = 1.e-6, wTol = 1.e-4, pTol = 1.e-3; | |
374 | Standard_Real V1,V2; | |
375 | Standard_Boolean ok1,ok2; | |
376 | TColStd_Array1OfReal W1(1,L),W2(1,L); | |
377 | TColgp_Array1OfPnt P1(1,L),P2(1,L); | |
378 | gp_Pnt nul(0.,0.,0.); | |
379 | W1.Init(0.); | |
380 | W2.Init(0.); | |
381 | P1.Init(nul); | |
382 | P2.Init(nul); | |
383 | ||
384 | V1 = V; | |
385 | V2 = V+pas; | |
386 | ok1 = D0(V1,P1,W1); | |
387 | ok2 = D0(V2,P2,W2); | |
04232180 | 388 | if (!ok1 || !ok2) std::cout<<"probleme en D0"<<std::endl; |
7fd59977 | 389 | Standard_Boolean check = verifD1(P1,W1,P2,W2,DPoles,DWeights,pTol,wTol,pas); |
04232180 | 390 | if (!check) std::cout<<"D1 incorrecte en V = "<<V<<std::endl; |
7fd59977 | 391 | } |
392 | #endif | |
393 | ||
394 | return Standard_True; | |
395 | } | |
396 | ||
397 | //======================================================= | |
398 | // Purpose :D2 | |
399 | //======================================================= | |
400 | Standard_Boolean GeomFill_NSections::D2(const Standard_Real V, | |
401 | TColgp_Array1OfPnt& Poles, | |
402 | TColgp_Array1OfVec& DPoles, | |
403 | TColgp_Array1OfVec& D2Poles, | |
404 | TColStd_Array1OfReal& Weights, | |
405 | TColStd_Array1OfReal& DWeights, | |
406 | TColStd_Array1OfReal& D2Weights) | |
407 | { | |
408 | if (mySurface.IsNull() ) return Standard_False; | |
409 | ||
410 | // pb dans BSplCLib::Eval() pour les surfaces rationnelles de degre 1 | |
411 | // si l'ordre de derivation est egal a 2. | |
412 | if (mySurface->VDegree()<2) return Standard_False; | |
413 | ||
414 | Standard_Boolean ok = D1(V,Poles,DPoles,Weights,DWeights); | |
415 | if (!ok) return Standard_False; | |
416 | ||
417 | Standard_Integer L = Poles.Length(), derivative_request = 2; | |
418 | Standard_Boolean rational = mySurface->IsVRational() ; | |
419 | Standard_Integer gap = 3; | |
420 | if (rational) gap++; | |
421 | ||
422 | Standard_Integer dimResult = mySurface->NbUPoles() * gap; | |
423 | Handle(Geom_BSplineSurface) surf_deper; | |
424 | if (mySurface->IsVPeriodic()) { | |
425 | surf_deper = Handle(Geom_BSplineSurface)::DownCast(mySurface->Copy()); | |
426 | surf_deper->SetVNotPeriodic(); | |
427 | dimResult = surf_deper->NbUPoles() * gap; | |
428 | } | |
429 | TColStd_Array1OfReal Result(1,dimResult); | |
430 | if (mySurface->IsVPeriodic()) { | |
431 | ResultEval(surf_deper,V,derivative_request,Result); | |
432 | } | |
433 | else { | |
434 | ResultEval(mySurface,V,derivative_request,Result); | |
435 | } | |
436 | ||
437 | ||
438 | Standard_Real ww, EpsW = 10*Precision::PConfusion(); | |
439 | Standard_Boolean NullWeight = Standard_False; | |
440 | if (!rational) D2Weights.Init(0.); | |
441 | Standard_Integer indice = 1, ii; | |
442 | ||
443 | // recopie des poles du resultat sous forme de points 3D et de poids | |
444 | for (ii=1; ii<=L && (!NullWeight) ; ii++) { | |
445 | D2Poles(ii).SetX( Result(indice) ); | |
446 | D2Poles(ii).SetY( Result(indice+1) ); | |
447 | D2Poles(ii).SetZ( Result(indice+2) ); | |
448 | if (rational) { | |
449 | ww = Weights(ii); | |
450 | if (ww < EpsW) { | |
451 | NullWeight = Standard_True; | |
452 | } | |
453 | else { | |
454 | D2Weights(ii) = Result(indice+3); | |
455 | D2Poles(ii) | |
456 | .SetXYZ( ( D2Poles(ii).XYZ() - D2Weights(ii)*Poles(ii).Coord() | |
457 | - 2*DWeights(ii)*DPoles(ii).XYZ() ) / ww ); | |
458 | } | |
459 | } | |
460 | indice += gap; | |
461 | } | |
462 | if (NullWeight) return Standard_False; | |
463 | ||
464 | // verif par diff finies sous debug sauf pour les surfaces periodiques | |
0797d9d3 | 465 | #ifdef OCCT_DEBUG |
7fd59977 | 466 | if (!mySurface->IsVPeriodic()) { |
467 | Standard_Real V1,V2; | |
468 | Standard_Boolean ok1,ok2; | |
469 | Standard_Real pas = 1.e-6, wTol = 1.e-4, pTol = 1.e-3; | |
470 | TColStd_Array1OfReal W1(1,L),W2(1,L),DW1(1,L),DW2(1,L); | |
471 | TColgp_Array1OfPnt P1(1,L),P2(1,L); | |
472 | TColgp_Array1OfVec DP1(1,L),DP2(1,L); | |
473 | gp_Pnt nul(0.,0.,0.); | |
474 | gp_Vec Vnul(0.,0.,0.); | |
475 | W1.Init(0.); | |
476 | W2.Init(0.); | |
477 | DW1.Init(0.); | |
478 | DW2.Init(0.); | |
479 | P1.Init(nul); | |
480 | P2.Init(nul); | |
481 | DP1.Init(Vnul); | |
482 | DP2.Init(Vnul); | |
483 | ||
484 | V1 = V; | |
485 | V2 = V+pas; | |
486 | ok1 = D1(V1,P1,DP1,W1,DW1); | |
487 | ok2 = D1(V2,P2,DP2,W2,DW2); | |
04232180 | 488 | if (!ok1 || !ok2) std::cout<<"probleme en D0 ou en D1"<<std::endl; |
7fd59977 | 489 | Standard_Boolean check = verifD2(DP1,DW1,DP2,DW2,D2Poles,D2Weights,pTol,wTol,pas); |
04232180 | 490 | if (!check) std::cout<<"D2 incorrecte en V = "<<V<<std::endl; |
7fd59977 | 491 | } |
492 | #endif | |
493 | ||
494 | return Standard_True; | |
495 | } | |
496 | ||
497 | //======================================================= | |
498 | // Purpose :BSplineSurface() | |
499 | //======================================================= | |
500 | Handle(Geom_BSplineSurface) | |
501 | GeomFill_NSections::BSplineSurface() const | |
502 | { | |
503 | return mySurface; | |
504 | } | |
505 | ||
506 | ||
507 | //======================================================= | |
508 | // Purpose :SetSurface() | |
509 | //======================================================= | |
510 | void GeomFill_NSections::SetSurface(const Handle(Geom_BSplineSurface)& RefSurf) | |
511 | { | |
512 | myRefSurf = RefSurf; | |
513 | } | |
514 | ||
515 | //======================================================= | |
516 | // Purpose :ComputeSurface() | |
517 | //======================================================= | |
518 | void GeomFill_NSections::ComputeSurface() | |
519 | { | |
520 | ||
521 | Handle(Geom_BSplineSurface) BS; | |
522 | if (myRefSurf.IsNull()) { | |
7fd59977 | 523 | |
9046e4fc | 524 | Standard_Real myPres3d = 1.e-06; |
7fd59977 | 525 | Standard_Integer i,j,jdeb=1,jfin=mySections.Length(); |
526 | ||
84bd2552 | 527 | if (jfin <= jdeb) |
528 | { | |
529 | //We will not be able to create surface from single curve. | |
530 | return; | |
531 | } | |
532 | ||
7fd59977 | 533 | GeomFill_SectionGenerator section; |
534 | Handle(Geom_BSplineSurface) surface; | |
7fd59977 | 535 | |
7fd59977 | 536 | for (j=jdeb; j<=jfin; j++) { |
9046e4fc | 537 | |
7fd59977 | 538 | // read the j-th curve |
5e5b6f81 | 539 | Handle(Geom_Curve) curv = mySections(j); |
7fd59977 | 540 | |
5e5b6f81 | 541 | // transformation to BSpline reparametrized to [UFirst,ULast] |
542 | Handle(Geom_BSplineCurve) curvBS = Handle(Geom_BSplineCurve)::DownCast (curv); | |
543 | if (curvBS.IsNull()) | |
544 | { | |
545 | curvBS = GeomConvert::CurveToBSplineCurve (curv, Convert_QuasiAngular); | |
7fd59977 | 546 | } |
5e5b6f81 | 547 | |
7fd59977 | 548 | TColStd_Array1OfReal BSK(1,curvBS->NbKnots()); |
549 | curvBS->Knots(BSK); | |
550 | BSplCLib::Reparametrize(UFirst,ULast,BSK); | |
551 | curvBS->SetKnots(BSK); | |
7fd59977 | 552 | |
9046e4fc | 553 | section.AddCurve(curvBS); |
7fd59977 | 554 | } |
555 | ||
9046e4fc | 556 | /* |
7fd59977 | 557 | if (s2Point) { |
558 | curv = mySections(jfin+1); | |
559 | first = curv->FirstParameter(); | |
560 | last = curv->LastParameter(); | |
561 | TColgp_Array1OfPnt Extremities(1,2); | |
562 | Extremities(1) = curv->Value(first); | |
563 | Extremities(2) = curv->Value(last); | |
564 | TColStd_Array1OfReal Bounds(1,2); | |
565 | Bounds(1) = UFirst; | |
566 | Bounds(2) = ULast; | |
567 | Standard_Real Deg = 1; | |
568 | TColStd_Array1OfInteger Mult(1,2); | |
569 | Mult(1) = (Standard_Integer ) Deg+1; | |
570 | Mult(2) = (Standard_Integer ) Deg+1; | |
571 | Handle(Geom_BSplineCurve) BSPoint | |
572 | = new Geom_BSplineCurve(Extremities,Bounds,Mult,(Standard_Integer ) Deg); | |
573 | section.AddCurve(BSPoint); | |
9046e4fc | 574 | }*/ |
7fd59977 | 575 | |
576 | Standard_Integer Nbcurves = mySections.Length(); | |
577 | Standard_Integer Nbpar = myParams.Length(); | |
05607219 | 578 | if (Nbpar > 0) |
579 | { | |
580 | Handle(TColStd_HArray1OfReal) HPar | |
581 | = new TColStd_HArray1OfReal(1, Nbpar); | |
582 | for (i = 1; i <= Nbpar; i++) { | |
583 | HPar->SetValue(i, myParams(i)); | |
584 | } | |
585 | section.SetParam(HPar); | |
7fd59977 | 586 | } |
7fd59977 | 587 | section.Perform(Precision::PConfusion()); |
05607219 | 588 | |
7fd59977 | 589 | Handle(GeomFill_Line) line = new GeomFill_Line(Nbcurves); |
590 | Standard_Integer nbIt = 0, degmin = 2, degmax = 6; | |
05607219 | 591 | Standard_Boolean knownP = Nbpar > 0; |
7fd59977 | 592 | GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt, knownP); |
d1775ee9 | 593 | anApprox.SetContinuity(GeomAbs_C1); |
7fd59977 | 594 | Standard_Boolean SpApprox = Standard_True; |
595 | anApprox.Perform(line, section, SpApprox); | |
596 | ||
597 | BS = | |
598 | new Geom_BSplineSurface(anApprox.SurfPoles(), anApprox.SurfWeights(), | |
599 | anApprox.SurfUKnots(), anApprox.SurfVKnots(), | |
600 | anApprox.SurfUMults(), anApprox.SurfVMults(), | |
5445eaee | 601 | anApprox.UDegree(), anApprox.VDegree(), |
602 | section.IsPeriodic()); | |
7fd59977 | 603 | } |
604 | ||
605 | else { | |
606 | ||
607 | // segmentation de myRefSurf | |
608 | Standard_Real Ui1, Ui2, V0, V1; | |
609 | BS = Handle(Geom_BSplineSurface)::DownCast(myRefSurf->Copy()); | |
610 | Ui1 = UFirst; | |
611 | Ui2 = ULast; | |
612 | Standard_Integer i1, i2; | |
613 | myRefSurf->LocateU( Ui1, Precision::PConfusion(), i1, i2 ); | |
614 | if (Abs(Ui1 - myRefSurf->UKnot(i1)) <= Precision::PConfusion()) | |
615 | Ui1 = myRefSurf->UKnot(i1); | |
616 | if (Abs(Ui1 - myRefSurf->UKnot(i2)) <= Precision::PConfusion()) | |
617 | Ui1 = myRefSurf->UKnot(i2); | |
618 | myRefSurf->LocateU( Ui2, Precision::PConfusion(), i1, i2 ); | |
619 | if (Abs(Ui2 - myRefSurf->UKnot(i1)) <= Precision::PConfusion()) | |
620 | Ui2 = myRefSurf->UKnot(i1); | |
621 | if (Abs(Ui2 - myRefSurf->UKnot(i2)) <= Precision::PConfusion()) | |
622 | Ui2 = myRefSurf->UKnot(i2); | |
623 | V0 = myRefSurf->VKnot(myRefSurf->FirstVKnotIndex()); | |
624 | V1 = myRefSurf->VKnot(myRefSurf->LastVKnotIndex()); | |
625 | BS->CheckAndSegment(Ui1,Ui2,V0,V1); | |
626 | } | |
627 | mySurface = BS; | |
628 | // On augmente le degre pour que le positionnement D2 soit correct | |
629 | if (mySurface->VDegree()<2) { | |
630 | mySurface->IncreaseDegree(mySurface->UDegree(),2); | |
631 | } | |
0797d9d3 | 632 | #ifdef OCCT_DEBUG |
7fd59977 | 633 | NbSurf++; |
634 | if (Affich) { | |
635 | #ifdef DRAW | |
636 | char name[256]; | |
637 | sprintf(name,"NS_Surf_%d",NbSurf); | |
638 | DrawTrSurf::Set(name,BS); | |
04232180 | 639 | std::cout<<std::endl<<"RESULTAT de ComputeSurface : NS_Surf_"<<NbSurf<<std::endl<<std::endl; |
7fd59977 | 640 | #endif |
641 | } | |
642 | #endif | |
643 | } | |
644 | ||
645 | //======================================================= | |
646 | // Purpose :SectionShape | |
647 | //======================================================= | |
648 | void GeomFill_NSections::SectionShape(Standard_Integer& NbPoles, | |
649 | Standard_Integer& NbKnots, | |
650 | Standard_Integer& Degree) const | |
651 | { | |
84bd2552 | 652 | if (mySurface.IsNull()) |
653 | return; | |
654 | ||
655 | NbPoles = mySurface->NbUPoles(); | |
656 | NbKnots = mySurface->NbUKnots(); | |
657 | Degree = mySurface->UDegree(); | |
7fd59977 | 658 | } |
659 | ||
660 | //======================================================= | |
661 | // Purpose :Knots | |
662 | //======================================================= | |
663 | void GeomFill_NSections::Knots(TColStd_Array1OfReal& TKnots) const | |
664 | { | |
84bd2552 | 665 | if (!mySurface.IsNull()) |
666 | mySurface->UKnots(TKnots); | |
7fd59977 | 667 | } |
668 | ||
669 | //======================================================= | |
670 | // Purpose :Mults | |
671 | //======================================================= | |
672 | void GeomFill_NSections::Mults(TColStd_Array1OfInteger& TMults) const | |
673 | { | |
84bd2552 | 674 | if (!mySurface.IsNull()) |
675 | mySurface->UMultiplicities(TMults); | |
7fd59977 | 676 | } |
677 | ||
678 | ||
679 | //======================================================= | |
680 | // Purpose :IsRational | |
681 | //======================================================= | |
682 | Standard_Boolean GeomFill_NSections::IsRational() const | |
683 | { | |
84bd2552 | 684 | if (!mySurface.IsNull()) |
685 | return mySurface->IsURational(); | |
686 | ||
687 | return Standard_False; | |
7fd59977 | 688 | } |
689 | ||
690 | //======================================================= | |
691 | // Purpose :IsUPeriodic | |
692 | //======================================================= | |
693 | Standard_Boolean GeomFill_NSections::IsUPeriodic() const | |
694 | { | |
84bd2552 | 695 | if (!mySurface.IsNull()) |
696 | return mySurface->IsUPeriodic(); | |
697 | ||
698 | return Standard_False; | |
7fd59977 | 699 | } |
700 | ||
701 | //======================================================= | |
702 | // Purpose :IsVPeriodic | |
703 | //======================================================= | |
704 | Standard_Boolean GeomFill_NSections::IsVPeriodic() const | |
705 | { | |
84bd2552 | 706 | if (!mySurface.IsNull()) |
707 | return mySurface->IsVPeriodic(); | |
708 | ||
709 | return Standard_False; | |
7fd59977 | 710 | } |
711 | ||
712 | //======================================================= | |
713 | // Purpose :NbIntervals | |
714 | //======================================================= | |
715 | Standard_Integer GeomFill_NSections::NbIntervals(const GeomAbs_Shape S) const | |
716 | { | |
84bd2552 | 717 | if (mySurface.IsNull()) |
718 | return 0; | |
719 | ||
7fd59977 | 720 | GeomAdaptor_Surface AdS(mySurface); |
721 | return AdS.NbVIntervals(S); | |
722 | } | |
723 | ||
724 | ||
725 | //======================================================= | |
726 | // Purpose :Intervals | |
727 | //======================================================= | |
728 | void GeomFill_NSections::Intervals(TColStd_Array1OfReal& T, | |
729 | const GeomAbs_Shape S) const | |
730 | { | |
84bd2552 | 731 | if (mySurface.IsNull()) |
732 | return; | |
733 | ||
7fd59977 | 734 | GeomAdaptor_Surface AdS(mySurface); |
735 | AdS.VIntervals(T,S); | |
736 | } | |
737 | ||
738 | ||
739 | //======================================================= | |
740 | // Purpose : SetInterval | |
741 | //======================================================= | |
742 | // void GeomFill_NSections::SetInterval(const Standard_Real F, | |
743 | void GeomFill_NSections::SetInterval(const Standard_Real , | |
744 | // const Standard_Real L) | |
745 | const Standard_Real ) | |
746 | { | |
747 | // rien a faire : mySurface est supposee Cn en V | |
748 | } | |
749 | ||
750 | //======================================================= | |
751 | // Purpose : GetInterval | |
752 | //======================================================= | |
753 | void GeomFill_NSections::GetInterval(Standard_Real& F, | |
754 | Standard_Real& L) const | |
755 | { | |
756 | F = VFirst; | |
757 | L = VLast; | |
758 | } | |
759 | ||
760 | //======================================================= | |
761 | // Purpose : GetDomain | |
762 | //======================================================= | |
763 | void GeomFill_NSections::GetDomain(Standard_Real& F, | |
764 | Standard_Real& L) const | |
765 | { | |
766 | F = VFirst; | |
767 | L = VLast; | |
768 | } | |
769 | ||
770 | //======================================================= | |
771 | // Purpose : GetTolerance | |
772 | //======================================================= | |
773 | void GeomFill_NSections::GetTolerance(const Standard_Real BoundTol, | |
774 | const Standard_Real SurfTol, | |
775 | // const Standard_Real AngleTol, | |
776 | const Standard_Real , | |
777 | TColStd_Array1OfReal& Tol3d) const | |
778 | { | |
779 | Tol3d.Init(SurfTol); | |
780 | if (BoundTol<SurfTol) { | |
781 | Tol3d(Tol3d.Lower()) = BoundTol; | |
782 | Tol3d(Tol3d.Upper()) = BoundTol; | |
783 | } | |
784 | } | |
785 | ||
786 | //======================================================= | |
787 | // Purpose : BarycentreOfSurf | |
788 | //======================================================= | |
789 | gp_Pnt GeomFill_NSections::BarycentreOfSurf() const | |
790 | { | |
791 | gp_Pnt P, Bary; | |
792 | Bary.SetCoord(0., 0., 0.); | |
793 | ||
84bd2552 | 794 | if (mySurface.IsNull()) |
795 | return Bary; | |
796 | ||
7fd59977 | 797 | Standard_Integer ii,jj; |
798 | Standard_Real U0, U1, V0, V1; | |
799 | mySurface->Bounds(U0,U1,V0,V1); | |
800 | Standard_Real V = V0, DeltaV = ( V1 - V0 ) / 20; | |
801 | Standard_Real U = U0, DeltaU = ( U1 - U0 ) / 20; | |
802 | for(jj=0;jj<=20;jj++,V+=DeltaV) { | |
803 | for (ii=0 ; ii <=20; ii++, U+=DeltaU) { | |
804 | P = mySurface->Value(U,V); | |
805 | Bary.ChangeCoord() += P.XYZ(); | |
806 | } | |
807 | } | |
808 | ||
809 | Bary.ChangeCoord() /= (21*21); | |
810 | return Bary; | |
811 | } | |
812 | ||
813 | ||
814 | //======================================================= | |
815 | // Purpose : MaximalSection | |
816 | //======================================================= | |
817 | Standard_Real GeomFill_NSections::MaximalSection() const | |
818 | { | |
819 | Standard_Real L, Lmax=0.; | |
820 | Standard_Integer ii; | |
821 | for (ii=1; ii <=mySections.Length(); ii++) { | |
822 | GeomAdaptor_Curve AC (mySections(ii)); | |
823 | L = GCPnts_AbscissaPoint::Length(AC); | |
824 | if (L>Lmax) Lmax = L; | |
825 | } | |
826 | return Lmax; | |
827 | } | |
828 | ||
829 | ||
830 | //======================================================= | |
831 | // Purpose : GetMinimalWeight | |
832 | //======================================================= | |
833 | void GeomFill_NSections::GetMinimalWeight(TColStd_Array1OfReal& Weights) const | |
834 | { | |
84bd2552 | 835 | if (mySurface.IsNull()) |
836 | return; | |
837 | ||
7fd59977 | 838 | if (mySurface->IsURational()) { |
839 | Standard_Integer NbU = mySurface->NbUPoles(), | |
840 | NbV = mySurface->NbVPoles(); | |
841 | TColStd_Array2OfReal WSurf(1,NbU,1,NbV); | |
842 | mySurface->Weights(WSurf); | |
843 | Standard_Integer i,j; | |
844 | for (i=1;i<=NbU;i++) { | |
845 | Standard_Real min = WSurf(i,1); | |
846 | for (j=2;j<=NbV;j++) { | |
847 | if (min> WSurf(i,j)) min = WSurf(i,j); | |
848 | } | |
849 | Weights.SetValue(i,min); | |
850 | } | |
851 | } | |
852 | else { | |
853 | Weights.Init(1); | |
854 | } | |
855 | ||
856 | } | |
857 | ||
858 | ||
859 | //======================================================= | |
860 | // Purpose : IsConstant | |
861 | //======================================================= | |
862 | Standard_Boolean GeomFill_NSections::IsConstant(Standard_Real& Error) const | |
863 | { | |
864 | // on se limite a 2 sections | |
865 | Standard_Boolean isconst = (mySections.Length()==2); | |
866 | Standard_Real Err = 0.; | |
867 | ||
868 | if (isconst) { | |
869 | GeomAdaptor_Curve AC1(mySections(1)); | |
870 | GeomAbs_CurveType CType = AC1.GetType(); | |
871 | GeomAdaptor_Curve AC2(mySections(2)); | |
872 | // les sections doivent avoir le meme type | |
873 | isconst = ( AC2.GetType() == CType); | |
874 | ||
875 | if (isconst) { | |
876 | if (CType == GeomAbs_Circle) { | |
877 | gp_Circ C1 = AC1.Circle(); | |
878 | gp_Circ C2 = AC2.Circle(); | |
879 | Standard_Real Tol = 1.e-7; | |
880 | Standard_Boolean samedir, samerad, samepos; | |
881 | samedir = (C1.Axis().IsParallel(C2.Axis(),1.e-4)); | |
882 | samerad = (Abs(C1.Radius()-C2.Radius())<Tol); | |
883 | samepos = (C1.Location().Distance(C2.Location())<Tol); | |
884 | if (!samepos) { | |
885 | gp_Ax1 D(C1.Location(),gp_Vec(C1.Location(),C2.Location())); | |
886 | samepos = (C1.Axis().IsParallel(D,1.e-4)); | |
887 | } | |
888 | isconst = samedir && samerad && samepos; | |
889 | } | |
890 | else if (CType == GeomAbs_Line) { | |
891 | gp_Lin L1 = AC1.Line(); | |
892 | gp_Lin L2 = AC2.Line(); | |
893 | Standard_Real Tol = 1.e-7; | |
894 | Standard_Boolean samedir, samelength, samepos; | |
895 | samedir = (L1.Direction().IsParallel(L2.Direction(),1.e-4)); | |
896 | gp_Pnt P11 = AC1.Value(AC1.FirstParameter()), | |
897 | P12 = AC1.Value(AC1.LastParameter()), | |
898 | P21 = AC2.Value(AC2.FirstParameter()), | |
899 | P22 = AC2.Value(AC2.LastParameter()); | |
900 | samelength = (Abs(P11.Distance(P12)-P21.Distance(P22))<Tol); | |
901 | // l'ecart entre les 2 sections ne compte pas | |
902 | samepos = ( ( P11.Distance(P21)<Tol && P12.Distance(P22)<Tol ) | |
903 | || ( P12.Distance(P21)<Tol && P11.Distance(P22)<Tol ) ); | |
904 | //samepos = Standard_True; | |
905 | isconst = samedir && samelength && samepos; | |
906 | } | |
907 | else { | |
908 | isconst = Standard_False; | |
909 | } | |
910 | } | |
911 | ||
912 | } | |
913 | ||
914 | Error = Err; | |
915 | return isconst; | |
916 | } | |
917 | ||
918 | ||
919 | //======================================================= | |
920 | // Purpose : ConstantSection | |
921 | //======================================================= | |
922 | Handle(Geom_Curve) GeomFill_NSections::ConstantSection() const | |
923 | { | |
924 | // Standard_Real Err; | |
9775fa61 | 925 | // if (!IsConstant(Err)) throw StdFail_NotDone("The Law is not Constant!"); |
7fd59977 | 926 | Handle(Geom_Curve) C; |
927 | C = Handle(Geom_Curve)::DownCast( mySections(1)->Copy()); | |
928 | return C; | |
929 | } | |
930 | ||
931 | ||
932 | //======================================================= | |
933 | // Purpose : IsConicalLaw | |
934 | //======================================================= | |
935 | Standard_Boolean GeomFill_NSections::IsConicalLaw(Standard_Real& Error) const | |
936 | { | |
937 | Standard_Boolean isconic = (mySections.Length()==2); | |
938 | Standard_Real Err = 0.; | |
939 | if (isconic) { | |
940 | GeomAdaptor_Curve AC1(mySections(1)); | |
941 | GeomAdaptor_Curve AC2(mySections(2)); | |
942 | isconic = ( AC1.GetType() == GeomAbs_Circle ) | |
943 | && ( AC2.GetType() == GeomAbs_Circle ) ; | |
944 | if (isconic) { | |
945 | gp_Circ C1 = AC1.Circle(); | |
98dbbeb4 J |
946 | if (!myTrsfs.IsEmpty()) |
947 | C1.Transform(myTrsfs(1).Inverted()); | |
7fd59977 | 948 | gp_Circ C2 = AC2.Circle(); |
98dbbeb4 J |
949 | if (!myTrsfs.IsEmpty()) |
950 | C2.Transform(myTrsfs(2).Inverted()); | |
7fd59977 | 951 | Standard_Real Tol = 1.e-7; |
98dbbeb4 J |
952 | //Standard_Boolean samedir, linearrad, sameaxis; |
953 | isconic = (C1.Axis().IsParallel(C2.Axis(),1.e-4)); | |
7fd59977 | 954 | // pour 2 sections, la variation du rayon est forcement lineaire |
98dbbeb4 | 955 | //linearrad = Standard_True; |
7fd59977 | 956 | // formule plus generale pour 3 sections au moins |
957 | // Standard_Real param0 = C2.Radius()*myParams(1) - C1.Radius()*myParams(2); | |
958 | // param0 = param0 / (C2.Radius()-C1.Radius()) ; | |
959 | // linearrad = ( Abs( C3.Radius()*myParams(1)-C1.Radius()*myParams(3) | |
960 | // - param0*(C3.Radius()-C1.Radius()) ) < Tol); | |
98dbbeb4 J |
961 | if (isconic) |
962 | { | |
963 | gp_Lin Line1(C1.Axis()); | |
964 | isconic = (Line1.Distance(C2.Location()) < Tol); | |
965 | /* | |
966 | sameaxis = (C1.Location().Distance(C2.Location())<Tol); | |
967 | if (!sameaxis) { | |
7fd59977 | 968 | gp_Ax1 D(C1.Location(),gp_Vec(C1.Location(),C2.Location())); |
969 | sameaxis = (C1.Axis().IsParallel(D,1.e-4)); | |
98dbbeb4 J |
970 | } |
971 | isconic = samedir && linearrad && sameaxis; | |
972 | */ | |
973 | if (isconic) | |
974 | { | |
975 | //// Modified by jgv, 18.02.2009 for OCC20866 //// | |
976 | Standard_Real first1 = AC1.FirstParameter(), last1 = AC1.LastParameter(); | |
977 | Standard_Real first2 = AC2.FirstParameter(), last2 = AC2.LastParameter(); | |
978 | isconic = (Abs(first1-first2) <= Precision::PConfusion() && | |
979 | Abs(last1-last2) <= Precision::PConfusion()); | |
980 | ////////////////////////////////////////////////// | |
981 | } | |
7fd59977 | 982 | } |
7fd59977 | 983 | } |
984 | } | |
985 | ||
986 | Error = Err; | |
987 | return isconic; | |
988 | } | |
989 | ||
990 | ||
991 | //======================================================= | |
992 | // Purpose : CirclSection | |
993 | //======================================================= | |
994 | Handle(Geom_Curve) GeomFill_NSections::CirclSection(const Standard_Real V) const | |
995 | { | |
996 | Standard_Real Err; | |
9775fa61 | 997 | if (!IsConicalLaw(Err)) throw StdFail_NotDone("The Law is not Conical!"); |
7fd59977 | 998 | |
999 | GeomAdaptor_Curve AC1(mySections(1)); | |
1000 | GeomAdaptor_Curve AC2(mySections(mySections.Length())); | |
1001 | gp_Circ C1 = AC1.Circle(); | |
1002 | gp_Circ C2 = AC2.Circle(); | |
1003 | ||
1004 | Standard_Real p1 = myParams(1), p2 = myParams(myParams.Length()); | |
1005 | Standard_Real radius = ( C2.Radius() - C1.Radius() ) * (V - p1) / (p2 - p1) | |
1006 | + C1.Radius(); | |
1007 | ||
1008 | C1.SetRadius(radius); | |
1009 | Handle(Geom_Curve) C = new (Geom_Circle) (C1); | |
ff3f0387 | 1010 | |
1011 | const Standard_Real aParF = AC1.FirstParameter(); | |
1012 | const Standard_Real aParL = AC1.LastParameter(); | |
1013 | const Standard_Real aPeriod = AC1.IsPeriodic() ? AC1.Period() : 0.0; | |
1014 | ||
1015 | if ((aPeriod == 0.0) || (Abs(aParL - aParF - aPeriod) > Precision::PConfusion())) | |
1016 | { | |
1017 | Handle(Geom_Curve) Cbis = new Geom_TrimmedCurve(C, aParF, aParL); | |
7fd59977 | 1018 | C = Cbis; |
1019 | } | |
1020 | return C; | |
1021 | } |