b311480e |
1 | // Created on: 1993-06-04 |
2 | // Created by: Bruno DUMORTIER |
3 | // Copyright (c) 1993-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 | // 20/02/97 : PMN -> Positionement local sur BSpline (PRO6902) |
18 | // 10/07/97 : PMN -> Pas de calcul de resolution dans Nb(Intervals) (PRO9248) |
19 | // 20/10/97 : JPI -> traitement des offset curves |
20 | |
21 | #define No_Standard_RangeError |
22 | #define No_Standard_OutOfRange |
23 | |
24 | #include <Geom2dAdaptor_Curve.ixx> |
25 | #include <Geom2d_OffsetCurve.hxx> |
26 | #include <Geom2dAdaptor_HCurve.hxx> |
27 | #include <Adaptor2d_HCurve2d.hxx> |
28 | #include <BSplCLib.hxx> |
29 | #include <GeomAbs_Shape.hxx> |
30 | #include <TColgp_Array1OfPnt2d.hxx> |
31 | #include <TColStd_Array1OfReal.hxx> |
32 | #include <TColStd_Array1OfInteger.hxx> |
33 | #include <TColStd_HArray1OfInteger.hxx> |
34 | #include <Precision.hxx> |
35 | #include <gp.hxx> |
36 | #include <Geom2d_TrimmedCurve.hxx> |
37 | #include <Geom2d_Circle.hxx> |
38 | #include <Geom2d_Line.hxx> |
39 | #include <Geom2d_TrimmedCurve.hxx> |
40 | #include <Geom2d_BezierCurve.hxx> |
41 | #include <Geom2d_BSplineCurve.hxx> |
42 | #include <Geom2d_Ellipse.hxx> |
43 | #include <Geom2d_Parabola.hxx> |
44 | #include <Geom2d_Hyperbola.hxx> |
45 | //#include <Geom2dConvert_BSplineCurveKnotSplitting.hxx> |
46 | |
47 | #include <Standard_OutOfRange.hxx> |
48 | #include <Standard_NoSuchObject.hxx> |
041bfce9 |
49 | #include <Standard_NullObject.hxx> |
7fd59977 |
50 | #include <Standard_NotImplemented.hxx> |
51 | |
52 | #define myBspl (*((Handle(Geom2d_BSplineCurve)*)&myCurve)) |
53 | #define PosTol Precision::PConfusion()/2 |
54 | |
55 | //======================================================================= |
56 | //function : LocalContinuity |
57 | //purpose : Computes the Continuity of a BSplineCurve |
58 | // between the parameters U1 and U2 |
59 | // The continuity is C(d-m) |
60 | // with d = degree, |
61 | // m = max multiplicity of the Knots between U1 and U2 |
62 | //======================================================================= |
63 | |
64 | GeomAbs_Shape Geom2dAdaptor_Curve::LocalContinuity(const Standard_Real U1, |
65 | const Standard_Real U2) |
66 | const { |
67 | |
68 | Standard_NoSuchObject_Raise_if(myTypeCurve!=GeomAbs_BSplineCurve," "); |
69 | Standard_Integer Nb = myBspl->NbKnots(); |
70 | Standard_Integer Index1 = 0; |
71 | Standard_Integer Index2 = 0; |
72 | Standard_Real newFirst, newLast; |
73 | TColStd_Array1OfReal TK(1,Nb); |
74 | TColStd_Array1OfInteger TM(1,Nb); |
75 | myBspl->Knots(TK); |
76 | myBspl->Multiplicities(TM); |
77 | BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,U1,myBspl->IsPeriodic(), |
78 | 1,Nb,Index1,newFirst); |
79 | BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,U2,myBspl->IsPeriodic(), |
80 | 1,Nb,Index2,newLast); |
81 | if ( Abs(newFirst-TK(Index1+1))<Precision::PConfusion()) { |
82 | if (Index1 < Nb)Index1++; |
83 | } |
84 | if ( Abs(newLast-TK(Index2))<Precision::PConfusion()) |
85 | Index2--; |
86 | Standard_Integer MultMax; |
87 | // attention aux courbes peridiques. |
88 | if ( (myBspl->IsPeriodic()) && (Index1 == Nb) ) |
89 | Index1 = 1; |
90 | |
91 | if ( Index2 - Index1 <= 0) { |
92 | MultMax = 100; // CN entre 2 Noeuds consecutifs |
93 | } |
94 | else { |
95 | MultMax = TM(Index1+1); |
96 | for(Standard_Integer i = Index1+1;i<=Index2;i++) { |
97 | if ( TM(i)>MultMax) MultMax=TM(i); |
98 | } |
99 | MultMax = myBspl->Degree() - MultMax; |
100 | } |
101 | if ( MultMax <= 0) { |
102 | return GeomAbs_C0; |
103 | } |
104 | else if ( MultMax == 1) { |
105 | return GeomAbs_C1; |
106 | } |
107 | else if ( MultMax == 2) { |
108 | return GeomAbs_C2; |
109 | } |
110 | else if ( MultMax == 3) { |
111 | return GeomAbs_C3; |
112 | } |
113 | else { |
114 | return GeomAbs_CN; |
115 | } |
116 | } |
117 | |
118 | |
119 | //======================================================================= |
120 | //function : Geom2dAdaptor_Curve |
121 | //purpose : |
122 | //======================================================================= |
123 | |
124 | Geom2dAdaptor_Curve::Geom2dAdaptor_Curve() |
cbff1e55 |
125 | : myTypeCurve(GeomAbs_OtherCurve), |
126 | myFirst (0.0), |
127 | myLast (0.0) |
7fd59977 |
128 | { |
129 | } |
130 | |
131 | //======================================================================= |
132 | //function : Geom2dAdaptor_Curve |
133 | //purpose : |
134 | //======================================================================= |
135 | |
cbff1e55 |
136 | Geom2dAdaptor_Curve::Geom2dAdaptor_Curve(const Handle(Geom2d_Curve)& theCrv) |
137 | : myTypeCurve(GeomAbs_OtherCurve), |
138 | myFirst (0.0), |
139 | myLast (0.0) |
041bfce9 |
140 | { |
cbff1e55 |
141 | Load(theCrv); |
7fd59977 |
142 | } |
143 | |
144 | //======================================================================= |
145 | //function : Geom2dAdaptor_Curve |
146 | //purpose : |
147 | //======================================================================= |
148 | |
cbff1e55 |
149 | Geom2dAdaptor_Curve::Geom2dAdaptor_Curve(const Handle(Geom2d_Curve)& theCrv, |
150 | const Standard_Real theUFirst, |
151 | const Standard_Real theULast) |
152 | : myTypeCurve(GeomAbs_OtherCurve), |
153 | myFirst (theUFirst), |
154 | myLast (theULast) |
041bfce9 |
155 | { |
cbff1e55 |
156 | Load(theCrv, theUFirst, theULast); |
7fd59977 |
157 | } |
158 | |
7fd59977 |
159 | |
160 | //======================================================================= |
161 | //function : Load |
162 | //purpose : |
163 | //======================================================================= |
164 | |
041bfce9 |
165 | void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C, |
166 | const Standard_Real UFirst, |
167 | const Standard_Real ULast) |
168 | { |
7fd59977 |
169 | myFirst = UFirst; |
170 | myLast = ULast; |
171 | |
172 | if ( myCurve != C) { |
173 | myCurve = C; |
174 | |
175 | Handle(Standard_Type) TheType = C->DynamicType(); |
176 | if ( TheType == STANDARD_TYPE(Geom2d_TrimmedCurve)) { |
177 | Load((*((Handle(Geom2d_TrimmedCurve)*)&C))->BasisCurve(), |
178 | UFirst,ULast); |
179 | } |
180 | else if ( TheType == STANDARD_TYPE(Geom2d_Circle)) { |
181 | myTypeCurve = GeomAbs_Circle; |
182 | } |
183 | else if ( TheType ==STANDARD_TYPE(Geom2d_Line)) { |
184 | myTypeCurve = GeomAbs_Line; |
185 | } |
186 | else if ( TheType == STANDARD_TYPE(Geom2d_Ellipse)) { |
187 | myTypeCurve = GeomAbs_Ellipse; |
188 | } |
189 | else if ( TheType == STANDARD_TYPE(Geom2d_Parabola)) { |
190 | myTypeCurve = GeomAbs_Parabola; |
191 | } |
192 | else if ( TheType == STANDARD_TYPE(Geom2d_Hyperbola)) { |
193 | myTypeCurve = GeomAbs_Hyperbola; |
194 | } |
195 | else if ( TheType == STANDARD_TYPE(Geom2d_BezierCurve)) { |
196 | myTypeCurve = GeomAbs_BezierCurve; |
197 | } |
198 | else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) { |
199 | myTypeCurve = GeomAbs_BSplineCurve; |
200 | } |
201 | else { |
202 | myTypeCurve = GeomAbs_OtherCurve; |
203 | } |
204 | } |
205 | } |
206 | |
207 | // -- |
208 | // -- Global methods - Apply to the whole curve. |
209 | // -- |
210 | |
211 | //======================================================================= |
212 | //function : Continuity |
213 | //purpose : |
214 | //======================================================================= |
215 | |
216 | GeomAbs_Shape Geom2dAdaptor_Curve::Continuity() const |
217 | { |
218 | if (myTypeCurve == GeomAbs_BSplineCurve) { |
219 | return LocalContinuity(myFirst, myLast); |
220 | } |
221 | else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){ |
222 | GeomAbs_Shape S = |
3d58dc49 |
223 | (*((Handle(Geom2d_OffsetCurve)*)&myCurve))->GetBasisCurveContinuity(); |
7fd59977 |
224 | switch(S){ |
225 | case GeomAbs_CN: return GeomAbs_CN; |
226 | case GeomAbs_C3: return GeomAbs_C2; |
227 | case GeomAbs_C2: return GeomAbs_C1; |
228 | case GeomAbs_C1: return GeomAbs_C0; |
3d58dc49 |
229 | case GeomAbs_G1: return GeomAbs_G1; |
230 | case GeomAbs_G2: return GeomAbs_G2; |
231 | |
7fd59977 |
232 | default: |
233 | Standard_NoSuchObject::Raise("Geom2dAdaptor_Curve::Continuity"); |
234 | } |
235 | } |
236 | |
237 | else if (myTypeCurve == GeomAbs_OtherCurve) { |
238 | Standard_NoSuchObject::Raise("Geom2dAdaptor_Curve::Continuity"); |
239 | } |
240 | else { |
241 | return GeomAbs_CN; |
242 | } |
243 | |
244 | // portage WNT |
245 | return GeomAbs_CN; |
246 | } |
247 | |
248 | //======================================================================= |
249 | //function : NbIntervals |
250 | //purpose : |
251 | //======================================================================= |
252 | |
253 | Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const |
254 | { |
255 | Standard_Integer myNbIntervals = 1; |
256 | Standard_Integer NbSplit; |
257 | if (myTypeCurve == GeomAbs_BSplineCurve) { |
258 | Standard_Integer FirstIndex = myBspl->FirstUKnotIndex(); |
259 | Standard_Integer LastIndex = myBspl->LastUKnotIndex(); |
260 | TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1); |
261 | if ( S > Continuity()) { |
262 | Standard_Integer Cont; |
263 | switch ( S) { |
264 | case GeomAbs_G1: |
265 | case GeomAbs_G2: |
266 | Standard_DomainError::Raise("Geom2dAdaptor_Curve::NbIntervals"); |
267 | break; |
268 | case GeomAbs_C0: |
269 | myNbIntervals = 1; |
270 | break; |
271 | case GeomAbs_C1: |
272 | case GeomAbs_C2: |
273 | case GeomAbs_C3: |
274 | case GeomAbs_CN: |
275 | { |
276 | if ( S == GeomAbs_C1) Cont = 1; |
277 | else if ( S == GeomAbs_C2) Cont = 2; |
278 | else if ( S == GeomAbs_C3) Cont = 3; |
279 | else Cont = myBspl->Degree(); |
280 | Standard_Integer Degree = myBspl->Degree(); |
281 | Standard_Integer NbKnots = myBspl->NbKnots(); |
282 | TColStd_Array1OfInteger Mults (1, NbKnots); |
283 | myBspl->Multiplicities (Mults); |
284 | NbSplit = 1; |
285 | Standard_Integer Index = FirstIndex; |
286 | Inter (NbSplit) = Index; |
287 | Index++; |
288 | NbSplit++; |
289 | while (Index < LastIndex) |
290 | { |
291 | if (Degree - Mults (Index) < Cont) |
292 | { |
293 | Inter (NbSplit) = Index; |
294 | NbSplit++; |
295 | } |
296 | Index++; |
297 | } |
298 | Inter (NbSplit) = Index; |
299 | |
300 | Standard_Integer NbInt = NbSplit-1; |
301 | |
302 | Standard_Integer Nb = myBspl->NbKnots(); |
303 | Standard_Integer Index1 = 0; |
304 | Standard_Integer Index2 = 0; |
305 | Standard_Real newFirst, newLast; |
306 | TColStd_Array1OfReal TK(1,Nb); |
307 | TColStd_Array1OfInteger TM(1,Nb); |
308 | myBspl->Knots(TK); |
309 | myBspl->Multiplicities(TM); |
310 | BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myFirst, |
311 | myBspl->IsPeriodic(), |
312 | 1,Nb,Index1,newFirst); |
313 | BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myLast, |
314 | myBspl->IsPeriodic(), |
315 | 1,Nb,Index2,newLast); |
316 | |
317 | // On decale eventuellement les indices |
318 | // On utilise une "petite" tolerance, la resolution ne doit |
319 | // servir que pour les tres longue courbes....(PRO9248) |
320 | Standard_Real Eps = Min(Resolution(Precision::Confusion()), |
321 | Precision::PConfusion()); |
322 | if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++; |
323 | if ( newLast-TK(Index2)> Eps) Index2++; |
324 | |
325 | myNbIntervals = 1; |
326 | for ( Standard_Integer i=1; i<=NbInt; i++) |
327 | if (Inter(i)>Index1 && Inter(i)<Index2) myNbIntervals++; |
328 | } |
329 | break; |
330 | } |
331 | } |
332 | } |
333 | else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){ |
334 | GeomAbs_Shape BaseS=GeomAbs_C0; |
335 | switch(S){ |
336 | case GeomAbs_G1: |
337 | case GeomAbs_G2: |
338 | Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals"); |
339 | break; |
340 | case GeomAbs_C0: BaseS = GeomAbs_C1; break; |
341 | case GeomAbs_C1: BaseS = GeomAbs_C2; break; |
342 | case GeomAbs_C2: BaseS = GeomAbs_C3; break; |
343 | default: BaseS = GeomAbs_CN; |
344 | } |
345 | Geom2dAdaptor_Curve C |
346 | ((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve()); |
347 | myNbIntervals = C.NbIntervals(BaseS); |
348 | } |
349 | |
350 | return myNbIntervals; |
351 | } |
352 | |
353 | //======================================================================= |
354 | //function : Intervals |
355 | //purpose : |
356 | //======================================================================= |
357 | |
358 | void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T, |
359 | const GeomAbs_Shape S ) const |
360 | { |
361 | Standard_Integer myNbIntervals = 1; |
362 | Standard_Integer NbSplit; |
363 | if (myTypeCurve == GeomAbs_BSplineCurve) { |
364 | Standard_Integer FirstIndex = myBspl->FirstUKnotIndex(); |
365 | Standard_Integer LastIndex = myBspl->LastUKnotIndex(); |
366 | TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1); |
367 | if ( S > Continuity()) { |
368 | Standard_Integer Cont; |
369 | switch ( S) { |
370 | case GeomAbs_G1: |
371 | case GeomAbs_G2: |
372 | Standard_DomainError::Raise("Geom2dAdaptor_Curve::NbIntervals"); |
373 | break; |
374 | case GeomAbs_C0: |
375 | myNbIntervals = 1; |
376 | break; |
377 | case GeomAbs_C1: |
378 | case GeomAbs_C2: |
379 | case GeomAbs_C3: |
380 | case GeomAbs_CN: |
381 | { |
382 | if ( S == GeomAbs_C1) Cont = 1; |
383 | else if ( S == GeomAbs_C2) Cont = 2; |
384 | else if ( S == GeomAbs_C3) Cont = 3; |
385 | else Cont = myBspl->Degree(); |
386 | Standard_Integer Degree = myBspl->Degree(); |
387 | Standard_Integer NbKnots = myBspl->NbKnots(); |
388 | TColStd_Array1OfInteger Mults (1, NbKnots); |
389 | myBspl->Multiplicities (Mults); |
390 | NbSplit = 1; |
391 | Standard_Integer Index = FirstIndex; |
392 | Inter (NbSplit) = Index; |
393 | Index++; |
394 | NbSplit++; |
395 | while (Index < LastIndex) |
396 | { |
397 | if (Degree - Mults (Index) < Cont) |
398 | { |
399 | Inter (NbSplit) = Index; |
400 | NbSplit++; |
401 | } |
402 | Index++; |
403 | } |
404 | Inter (NbSplit) = Index; |
405 | Standard_Integer NbInt = NbSplit-1; |
406 | |
407 | Standard_Integer Nb = myBspl->NbKnots(); |
408 | Standard_Integer Index1 = 0; |
409 | Standard_Integer Index2 = 0; |
410 | Standard_Real newFirst, newLast; |
411 | TColStd_Array1OfReal TK(1,Nb); |
412 | TColStd_Array1OfInteger TM(1,Nb); |
413 | myBspl->Knots(TK); |
414 | myBspl->Multiplicities(TM); |
415 | BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myFirst, |
416 | myBspl->IsPeriodic(), |
417 | 1,Nb,Index1,newFirst); |
418 | BSplCLib::LocateParameter(myBspl->Degree(),TK,TM,myLast, |
419 | myBspl->IsPeriodic(), |
420 | 1,Nb,Index2,newLast); |
421 | |
422 | |
423 | // On decale eventuellement les indices |
424 | // On utilise une "petite" tolerance, la resolution ne doit |
425 | // servir que pour les tres longue courbes....(PRO9248) |
426 | Standard_Real Eps = Min(Resolution(Precision::Confusion()), |
427 | Precision::PConfusion()); |
428 | if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++; |
429 | if ( newLast-TK(Index2)> Eps) Index2++; |
430 | |
431 | Inter( 1) = Index1; |
432 | myNbIntervals = 1; |
433 | for ( Standard_Integer i=1; i<=NbInt; i++) { |
434 | if (Inter(i) > Index1 && Inter(i)<Index2 ) { |
435 | myNbIntervals++; |
436 | Inter(myNbIntervals) = Inter(i); |
437 | } |
438 | } |
439 | Inter(myNbIntervals+1) = Index2; |
440 | |
441 | Standard_Integer ii = T.Lower() - 1; |
442 | for (Standard_Integer I=1;I<=myNbIntervals+1;I++) { |
443 | T(ii + I) = TK(Inter(I)); |
444 | } |
445 | } |
446 | break; |
447 | } |
448 | } |
449 | } |
450 | else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){ |
451 | GeomAbs_Shape BaseS=GeomAbs_C0; |
452 | switch(S){ |
453 | case GeomAbs_G1: |
454 | case GeomAbs_G2: |
455 | Standard_DomainError::Raise("GeomAdaptor_Curve::NbIntervals"); |
456 | break; |
457 | case GeomAbs_C0: BaseS = GeomAbs_C1; break; |
458 | case GeomAbs_C1: BaseS = GeomAbs_C2; break; |
459 | case GeomAbs_C2: BaseS = GeomAbs_C3; break; |
460 | default: BaseS = GeomAbs_CN; |
461 | } |
462 | Geom2dAdaptor_Curve C |
463 | ((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve()); |
464 | myNbIntervals = C.NbIntervals(BaseS); |
465 | C.Intervals(T, BaseS); |
466 | } |
467 | |
468 | T( T.Lower() ) = myFirst; |
469 | T( T.Lower() + myNbIntervals ) = myLast; |
470 | } |
471 | |
472 | //======================================================================= |
473 | //function : Trim |
474 | //purpose : |
475 | //======================================================================= |
476 | |
477 | Handle(Adaptor2d_HCurve2d) Geom2dAdaptor_Curve::Trim |
478 | (const Standard_Real First, |
479 | const Standard_Real Last, |
480 | // const Standard_Real Tol) const |
481 | const Standard_Real ) const |
482 | { |
483 | Handle(Geom2dAdaptor_HCurve) HE = new Geom2dAdaptor_HCurve(myCurve,First,Last); |
484 | return HE; |
485 | } |
486 | |
487 | |
488 | //======================================================================= |
489 | //function : IsClosed |
490 | //purpose : |
491 | //======================================================================= |
492 | |
493 | Standard_Boolean Geom2dAdaptor_Curve::IsClosed() const |
494 | { |
495 | if (!Precision::IsPositiveInfinite(myLast) && |
496 | !Precision::IsNegativeInfinite(myFirst)) { |
497 | gp_Pnt2d Pd = Value(myFirst); |
498 | gp_Pnt2d Pf = Value(myLast); |
499 | return ( Pd.Distance(Pf) <= Precision::Confusion()); |
500 | } |
501 | else |
502 | return Standard_False; |
503 | } |
504 | |
505 | //======================================================================= |
506 | //function : IsPeriodic |
507 | //purpose : |
508 | //======================================================================= |
509 | |
510 | Standard_Boolean Geom2dAdaptor_Curve::IsPeriodic() const |
511 | { |
512 | if (myCurve->IsPeriodic()) |
513 | return IsClosed(); |
514 | else |
515 | return Standard_False; |
516 | } |
517 | |
518 | //======================================================================= |
519 | //function : Period |
520 | //purpose : |
521 | //======================================================================= |
522 | |
523 | Standard_Real Geom2dAdaptor_Curve::Period() const |
524 | { |
525 | return myCurve->LastParameter() - myCurve->FirstParameter(); |
526 | } |
527 | |
528 | //======================================================================= |
529 | //function : Value |
530 | //purpose : |
531 | //======================================================================= |
532 | |
533 | gp_Pnt2d Geom2dAdaptor_Curve::Value(const Standard_Real U) const |
534 | { |
535 | if ( (myTypeCurve == GeomAbs_BSplineCurve)&& |
536 | (U==myFirst || U==myLast) ) { |
1d47d8d0 |
537 | Standard_Integer Ideb = 0, Ifin = 0; |
7fd59977 |
538 | if (U==myFirst) { |
539 | myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); |
540 | if (Ideb<1) Ideb=1; |
541 | if (Ideb>=Ifin) Ifin = Ideb+1; |
542 | } |
543 | if (U==myLast) { |
544 | myBspl->LocateU(myLast, PosTol, Ideb, Ifin); |
545 | if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); |
546 | if (Ideb>=Ifin) Ideb = Ifin-1; |
547 | } |
548 | return myBspl->LocalValue(U, Ideb, Ifin); |
549 | } |
550 | else { |
551 | return myCurve->Value( U); |
552 | } |
553 | } |
554 | |
555 | //======================================================================= |
556 | //function : D0 |
557 | //purpose : |
558 | //======================================================================= |
559 | |
560 | void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const |
561 | { |
562 | if ( (myTypeCurve == GeomAbs_BSplineCurve)&& |
563 | (U==myFirst || U==myLast) ) { |
1d47d8d0 |
564 | Standard_Integer Ideb = 0, Ifin = 0; |
7fd59977 |
565 | if (U==myFirst) { |
566 | myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); |
567 | if (Ideb<1) Ideb=1; |
568 | if (Ideb>=Ifin) Ifin = Ideb+1; |
569 | } |
570 | if (U==myLast) { |
571 | myBspl->LocateU(myLast, PosTol, Ideb, Ifin); |
572 | if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); |
573 | if (Ideb>=Ifin) Ideb = Ifin-1; |
574 | } |
575 | myBspl->LocalD0( U, Ideb, Ifin, P); |
576 | } |
577 | else { |
578 | myCurve->D0(U, P); |
579 | } |
580 | } |
581 | |
582 | //======================================================================= |
583 | //function : D1 |
584 | //purpose : |
585 | //======================================================================= |
586 | |
587 | void Geom2dAdaptor_Curve::D1(const Standard_Real U, |
588 | gp_Pnt2d& P, gp_Vec2d& V) const |
589 | { |
590 | if ( (myTypeCurve == GeomAbs_BSplineCurve)&& |
591 | (U==myFirst || U==myLast) ) { |
1d47d8d0 |
592 | Standard_Integer Ideb = 0, Ifin = 0; |
7fd59977 |
593 | if (U==myFirst) { |
594 | myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); |
595 | if (Ideb<1) Ideb=1; |
596 | if (Ideb>=Ifin) Ifin = Ideb+1; |
597 | } |
598 | if (U==myLast) { |
599 | myBspl->LocateU(myLast, PosTol, Ideb, Ifin); |
600 | if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); |
601 | if (Ideb>=Ifin) Ideb = Ifin-1; |
602 | } |
603 | myBspl->LocalD1( U, Ideb, Ifin, P, V); |
604 | } |
605 | else { |
606 | myCurve->D1( U, P, V); |
607 | } |
608 | } |
609 | |
610 | //======================================================================= |
611 | //function : D2 |
612 | //purpose : |
613 | //======================================================================= |
614 | |
615 | void Geom2dAdaptor_Curve::D2(const Standard_Real U, |
616 | gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const |
617 | { |
618 | if ( (myTypeCurve == GeomAbs_BSplineCurve)&& |
619 | (U==myFirst || U==myLast) ) { |
1d47d8d0 |
620 | Standard_Integer Ideb = 0, Ifin = 0; |
7fd59977 |
621 | if (U==myFirst) { |
622 | myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); |
623 | if (Ideb<1) Ideb=1; |
624 | if (Ideb>=Ifin) Ifin = Ideb+1; |
625 | } |
626 | if (U==myLast) { |
627 | myBspl->LocateU(myLast, PosTol, Ideb, Ifin); |
628 | if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); |
629 | if (Ideb>=Ifin) Ideb = Ifin-1; |
630 | } |
631 | myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2); |
632 | } |
633 | else { |
634 | myCurve->D2( U, P, V1, V2); |
635 | } |
636 | } |
637 | |
638 | //======================================================================= |
639 | //function : D3 |
640 | //purpose : |
641 | //======================================================================= |
642 | |
643 | void Geom2dAdaptor_Curve::D3(const Standard_Real U, |
644 | gp_Pnt2d& P, gp_Vec2d& V1, |
645 | gp_Vec2d& V2, gp_Vec2d& V3) const |
646 | { |
647 | if ( (myTypeCurve == GeomAbs_BSplineCurve) && |
648 | (U==myFirst || U==myLast) ) { |
1d47d8d0 |
649 | Standard_Integer Ideb = 0, Ifin = 0; |
7fd59977 |
650 | if (U==myFirst) { |
651 | myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); |
652 | if (Ideb<1) Ideb=1; |
653 | if (Ideb>=Ifin) Ifin = Ideb+1; |
654 | } |
655 | if (U==myLast) { |
656 | myBspl->LocateU(myLast, PosTol, Ideb, Ifin); |
657 | if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); |
658 | if (Ideb>=Ifin) Ideb = Ifin-1; |
659 | } |
660 | myBspl->LocalD3( U, Ideb, Ifin, P, V1, V2, V3); |
661 | } |
662 | else { |
663 | myCurve->D3( U, P, V1, V2, V3); |
664 | } |
665 | } |
666 | |
667 | //======================================================================= |
668 | //function : DN |
669 | //purpose : |
670 | //======================================================================= |
671 | |
672 | gp_Vec2d Geom2dAdaptor_Curve::DN(const Standard_Real U, |
673 | const Standard_Integer N) const |
674 | { |
675 | if ( (myTypeCurve == GeomAbs_BSplineCurve) && |
676 | (U==myFirst || U==myLast) ) { |
1d47d8d0 |
677 | Standard_Integer Ideb = 0, Ifin = 0; |
7fd59977 |
678 | if (U==myFirst) { |
679 | myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); |
680 | if (Ideb<1) Ideb=1; |
681 | if (Ideb>=Ifin) Ifin = Ideb+1; |
682 | } |
683 | if (U==myLast) { |
684 | myBspl->LocateU(myLast, PosTol, Ideb, Ifin); |
685 | if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); |
686 | if (Ideb>=Ifin) Ideb = Ifin-1; |
687 | } |
688 | return myBspl->LocalDN( U, Ideb, Ifin, N); |
689 | } |
690 | else { |
691 | return myCurve->DN( U, N); |
692 | } |
693 | } |
694 | |
695 | //======================================================================= |
696 | //function : Resolution |
697 | //purpose : |
698 | //======================================================================= |
699 | |
700 | Standard_Real Geom2dAdaptor_Curve::Resolution(const Standard_Real Ruv) const { |
701 | switch ( myTypeCurve) { |
702 | case GeomAbs_Line : |
703 | return Ruv; |
704 | case GeomAbs_Circle: { |
705 | Standard_Real R = (*((Handle(Geom2d_Circle)*)&myCurve))->Circ2d().Radius(); |
706 | if ( R > Ruv/2.) |
707 | return 2*ASin(Ruv/(2*R)); |
708 | else |
c6541a0c |
709 | return 2*M_PI; |
7fd59977 |
710 | } |
711 | case GeomAbs_Ellipse: { |
712 | return Ruv / (*((Handle(Geom2d_Ellipse)*)&myCurve))->MajorRadius(); |
713 | } |
714 | case GeomAbs_BezierCurve: { |
715 | Standard_Real res; |
716 | (*((Handle(Geom2d_BezierCurve)*)&myCurve))->Resolution(Ruv,res); |
717 | return res; |
718 | } |
719 | case GeomAbs_BSplineCurve: { |
720 | Standard_Real res; |
721 | (*((Handle(Geom2d_BSplineCurve)*)&myCurve))->Resolution(Ruv,res); |
722 | return res; |
723 | } |
724 | default: |
725 | return Precision::Parametric(Ruv); |
726 | } |
727 | } |
728 | |
729 | |
730 | // -- |
731 | // -- The following methods must be called when GetType returned |
732 | // -- the corresponding type. |
733 | // -- |
734 | |
735 | //======================================================================= |
736 | //function : Line |
737 | //purpose : |
738 | //======================================================================= |
739 | |
740 | gp_Lin2d Geom2dAdaptor_Curve::Line() const |
741 | { |
742 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Line, ""); |
743 | return (*((Handle(Geom2d_Line)*)&myCurve))->Lin2d(); |
744 | } |
745 | |
746 | //======================================================================= |
747 | //function : Circle |
748 | //purpose : |
749 | //======================================================================= |
750 | |
751 | gp_Circ2d Geom2dAdaptor_Curve::Circle() const |
752 | { |
753 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Circle, ""); |
754 | return (*((Handle(Geom2d_Circle)*)&myCurve))->Circ2d(); |
755 | } |
756 | |
757 | //======================================================================= |
758 | //function : Ellipse |
759 | //purpose : |
760 | //======================================================================= |
761 | |
762 | gp_Elips2d Geom2dAdaptor_Curve::Ellipse() const |
763 | { |
764 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Ellipse, ""); |
765 | return (*((Handle(Geom2d_Ellipse)*)&myCurve))->Elips2d(); |
766 | } |
767 | |
768 | //======================================================================= |
769 | //function : Hyperbola |
770 | //purpose : |
771 | //======================================================================= |
772 | |
773 | gp_Hypr2d Geom2dAdaptor_Curve::Hyperbola() const |
774 | { |
775 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Hyperbola, ""); |
776 | return (*((Handle(Geom2d_Hyperbola)*)&myCurve))->Hypr2d(); |
777 | } |
778 | |
779 | //======================================================================= |
780 | //function : Parabola |
781 | //purpose : |
782 | //======================================================================= |
783 | |
784 | gp_Parab2d Geom2dAdaptor_Curve::Parabola() const |
785 | { |
786 | Standard_NoSuchObject_Raise_if(myTypeCurve != GeomAbs_Parabola, ""); |
787 | return (*((Handle(Geom2d_Parabola)*)&myCurve))->Parab2d(); |
788 | } |
789 | |
790 | //======================================================================= |
791 | //function : Degree |
792 | //purpose : |
793 | //======================================================================= |
794 | |
795 | Standard_Integer Geom2dAdaptor_Curve::Degree() const |
796 | { |
797 | if (myTypeCurve == GeomAbs_BezierCurve) |
798 | return (*((Handle(Geom2d_BezierCurve)*)&myCurve))->Degree(); |
799 | else if (myTypeCurve == GeomAbs_BSplineCurve) |
800 | return (*((Handle(Geom2d_BSplineCurve)*)&myCurve))->Degree(); |
801 | else |
802 | Standard_NoSuchObject::Raise(); |
803 | // portage WNT |
804 | return 0; |
805 | } |
806 | |
807 | //======================================================================= |
808 | //function : IsRational |
809 | //purpose : |
810 | //======================================================================= |
811 | |
812 | Standard_Boolean Geom2dAdaptor_Curve::IsRational() const { |
813 | switch( myTypeCurve) { |
814 | case GeomAbs_BSplineCurve: |
815 | return (*((Handle(Geom2d_BSplineCurve)*)&myCurve))->IsRational(); |
816 | case GeomAbs_BezierCurve: |
817 | return (*((Handle(Geom2d_BezierCurve)*)&myCurve))->IsRational(); |
818 | default: |
819 | return Standard_False; |
820 | } |
821 | } |
822 | |
823 | //======================================================================= |
824 | //function : NbPoles |
825 | //purpose : |
826 | //======================================================================= |
827 | |
828 | Standard_Integer Geom2dAdaptor_Curve::NbPoles() const |
829 | { |
830 | if (myTypeCurve == GeomAbs_BezierCurve) |
831 | return (*((Handle(Geom2d_BezierCurve)*)&myCurve))->NbPoles(); |
832 | else if (myTypeCurve == GeomAbs_BSplineCurve) |
833 | return (*((Handle(Geom2d_BSplineCurve)*)&myCurve))->NbPoles(); |
834 | else |
835 | Standard_NoSuchObject::Raise(); |
836 | // portage WNT |
837 | return 0; |
838 | } |
839 | |
840 | //======================================================================= |
841 | //function : NbKnots |
842 | //purpose : |
843 | //======================================================================= |
844 | |
845 | Standard_Integer Geom2dAdaptor_Curve::NbKnots() const { |
846 | if ( myTypeCurve != GeomAbs_BSplineCurve) |
847 | Standard_NoSuchObject::Raise("Geom2dAdaptor_Curve::NbKnots"); |
848 | return (*((Handle(Geom2d_BSplineCurve)*)&myCurve))->NbKnots(); |
849 | |
850 | } |
851 | |
852 | //======================================================================= |
853 | //function : Bezier |
854 | //purpose : |
855 | //======================================================================= |
856 | |
857 | Handle(Geom2d_BezierCurve) Geom2dAdaptor_Curve::Bezier() const |
858 | { |
859 | return *((Handle(Geom2d_BezierCurve)*)&myCurve); |
860 | } |
861 | |
862 | //======================================================================= |
863 | //function : BSpline |
864 | //purpose : |
865 | //======================================================================= |
866 | |
867 | Handle(Geom2d_BSplineCurve) Geom2dAdaptor_Curve::BSpline() const |
868 | { |
869 | return *((Handle(Geom2d_BSplineCurve)*)&myCurve); |
870 | } |
871 | |
a874a4a0 |
872 | static Standard_Integer nbPoints(const Handle(Geom2d_Curve)& theCurve) |
873 | { |
874 | |
875 | Standard_Integer nbs = 10; |
876 | |
877 | if(theCurve->IsKind(STANDARD_TYPE( Geom2d_Line)) ) |
878 | nbs = 2; |
879 | else if(theCurve->IsKind(STANDARD_TYPE( Geom2d_BezierCurve))) |
880 | { |
881 | nbs = 3 + (*((Handle(Geom2d_BezierCurve)*)&theCurve))->NbPoles(); |
882 | } |
883 | else if(theCurve->IsKind(STANDARD_TYPE( Geom2d_BSplineCurve))) { |
884 | nbs = (*((Handle(Geom2d_BSplineCurve)*)&theCurve))->NbKnots(); |
885 | nbs*= (*((Handle(Geom2d_BSplineCurve)*)&theCurve))->Degree(); |
886 | if(nbs < 2.0) nbs=2; |
887 | } |
888 | else if (theCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) |
889 | { |
890 | Handle(Geom2d_Curve) aCurve = (*((Handle(Geom2d_OffsetCurve)*)&theCurve))->BasisCurve(); |
891 | return Max(nbs, nbPoints(aCurve)); |
892 | } |
893 | |
894 | else if (theCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) |
895 | { |
896 | Handle(Geom2d_Curve) aCurve = (*((Handle(Geom2d_TrimmedCurve)*)&theCurve))->BasisCurve(); |
897 | return Max(nbs, nbPoints(aCurve)); |
898 | } |
899 | if(nbs>300) |
900 | nbs = 300; |
901 | return nbs; |
902 | |
903 | } |
904 | |
905 | Standard_Integer Geom2dAdaptor_Curve::NbSamples() const |
906 | { |
907 | return nbPoints(myCurve); |
908 | } |