0023024: Update headers of OCCT files
[occt.git] / src / Adaptor3d / Adaptor3d_OffsetCurve.cxx
CommitLineData
b311480e 1// Copyright (c) 1999-2012 OPEN CASCADE SAS
2//
3// The content of this file is subject to the Open CASCADE Technology Public
4// License Version 6.5 (the "License"). You may not use the content of this file
5// except in compliance with the License. Please obtain a copy of the License
6// at http://www.opencascade.org and read it completely before using this file.
7//
8// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10//
11// The Original Code and all software distributed under the License is
12// distributed on an "AS IS" basis, without warranty of any kind, and the
13// Initial Developer hereby disclaims all such warranties, including without
14// limitation, any warranties of merchantability, fitness for a particular
15// purpose or non-infringement. Please see the License for the specific terms
16// and conditions governing the rights and limitations under the License.
17
7fd59977 18#include <Adaptor3d_OffsetCurve.ixx>
19
20#include <Adaptor3d_HOffsetCurve.hxx>
21#include <GeomAbs_SurfaceType.hxx>
22#include <Standard_NoSuchObject.hxx>
23#include <Standard_NotImplemented.hxx>
24#include <gp_VectorWithNullMagnitude.hxx>
25#include <Precision.hxx>
26#include <gp_Ax22d.hxx>
27#include <gp_Dir2d.hxx>
28#include <gp.hxx>
29
30//=======================================================================
31//function : Adaptor3d_OffsetCurve
32//purpose :
33//=======================================================================
34
35Adaptor3d_OffsetCurve::Adaptor3d_OffsetCurve() :
36 myOffset( 0.)
37{}
38
39//=======================================================================
40//function : Adaptor3d_OffsetCurve
41//purpose :
42//=======================================================================
43
44Adaptor3d_OffsetCurve::Adaptor3d_OffsetCurve(const Handle(Adaptor2d_HCurve2d)& C)
45{
46 Load(C);
47}
48
49//=======================================================================
50//function : Adaptor3d_OffsetCurve
51//purpose :
52//=======================================================================
53
54Adaptor3d_OffsetCurve::Adaptor3d_OffsetCurve(const Handle(Adaptor2d_HCurve2d)& C,
55 const Standard_Real Offset)
56{
57 Load(C);
58 Load(Offset);
59}
60
61//=======================================================================
62//function : Adaptor3d_OffsetCurve
63//purpose :
64//=======================================================================
65
66Adaptor3d_OffsetCurve::Adaptor3d_OffsetCurve(const Handle(Adaptor2d_HCurve2d)& C,
67 const Standard_Real Offset,
68 const Standard_Real WFirst,
69 const Standard_Real WLast)
70{
71 Load(C);
72 Load(Offset,WFirst,WLast);
73}
74
75//=======================================================================
76//function : Load
77//purpose :
78//=======================================================================
79
80void Adaptor3d_OffsetCurve::Load(const Handle(Adaptor2d_HCurve2d)& C )
81{
82 myCurve = C;
83 myOffset = 0.;
84}
85
86//=======================================================================
87//function : Load
88//purpose :
89//=======================================================================
90
91void Adaptor3d_OffsetCurve::Load( const Standard_Real Offset)
92{
93 myOffset = Offset;
94 myFirst = myCurve->FirstParameter();
95 myLast = myCurve->LastParameter();
96
97}
98
99//=======================================================================
100//function : Load
101//purpose :
102//=======================================================================
103
104void Adaptor3d_OffsetCurve::Load(const Standard_Real Offset,
105 const Standard_Real WFirst,
106 const Standard_Real WLast)
107{
108 myOffset = Offset;
109 myFirst = WFirst;
110 myLast = WLast;
111}
112
113//=======================================================================
114//function : Continuity
115//purpose :
116//=======================================================================
117
118GeomAbs_Shape Adaptor3d_OffsetCurve::Continuity() const
119{
120 switch (myCurve->Continuity()) {
121 case GeomAbs_CN: return GeomAbs_CN;
122 case GeomAbs_C3: return GeomAbs_C2;
123 case GeomAbs_C2: return GeomAbs_G2;
124 case GeomAbs_G2: return GeomAbs_C1;
125 case GeomAbs_C1: return GeomAbs_G1;
126 case GeomAbs_G1: return GeomAbs_C0;
127 case GeomAbs_C0:
128// No Continuity !!
129 Standard_TypeMismatch::Raise("Adaptor3d_OffsetCurve::IntervalContinuity");
130 break;
131 }
132
133 //portage WNT
134 return GeomAbs_C0;
135}
136
137//=======================================================================
138//function : NbIntervals
139//purpose :
140//=======================================================================
141
142Standard_Integer Adaptor3d_OffsetCurve::NbIntervals(const GeomAbs_Shape S) const
143{
144 GeomAbs_Shape Sh;
145 if ( S >= GeomAbs_C2) Sh = GeomAbs_CN;
146 else
147 Sh = (GeomAbs_Shape)((Standard_Integer)S + 2);
148
149 Standard_Integer nbInter = myCurve->NbIntervals(Sh);
150
151 if(nbInter == 1) return nbInter;
152
153 TColStd_Array1OfReal T(1,nbInter+1);
154
155 myCurve->Intervals(T,Sh);
156
157 Standard_Integer first = 1;
158 while (T(first) <= myFirst) first++;
159 Standard_Integer last = nbInter+1;
160 while (T(last) >= myLast) last--;
161 return (last - first + 2);
162}
163
164//=======================================================================
165//function : Intervals
166//purpose :
167//=======================================================================
168
169void Adaptor3d_OffsetCurve::Intervals(TColStd_Array1OfReal& TI,
170 const GeomAbs_Shape S) const
171{
172 GeomAbs_Shape Sh;
173 if ( S >= GeomAbs_C2) Sh = GeomAbs_CN;
174 else
175 Sh = (GeomAbs_Shape)((Standard_Integer)S + 2);
176
177 Standard_Integer nbInter = myCurve->NbIntervals(Sh);
178
179
180 if(nbInter == 1) {
181 TI(TI.Lower()) = myFirst ;
182 TI(TI.Lower() + 1) = myLast ;
183 return;
184 }
185
186 TColStd_Array1OfReal T(1,nbInter+1);
187 myCurve->Intervals(T,Sh);
188
189 Standard_Integer first = 1;
190 while (T(first) <= myFirst) first++;
191 Standard_Integer last = nbInter+1;
192 while (T(last) >= myLast) last--;
193
194 Standard_Integer i = TI.Lower(), j;
195 for (j = first-1; j <= last+1; j++) {
196 TI(i) = T(j);
197 i++;
198 }
199
200 TI(TI.Lower()) = myFirst ;
201 TI(TI.Lower() + last-first + 2) = myLast ;
202
203}
204
205
206//=======================================================================
207//function : Trim
208//purpose :
209//=======================================================================
210
211Handle(Adaptor2d_HCurve2d) Adaptor3d_OffsetCurve::Trim
212(const Standard_Real First,
213 const Standard_Real Last,
214 const Standard_Real) const
215{
216 Handle(Adaptor3d_HOffsetCurve) HO = new Adaptor3d_HOffsetCurve(*this);
217 HO->ChangeCurve2d().Load(myOffset,First,Last);
218 return HO;
219}
220
221
222//=======================================================================
223//function : IsClosed
224//purpose :
225//=======================================================================
226
227Standard_Boolean Adaptor3d_OffsetCurve::IsClosed() const
228{
229 if ( myOffset == 0.) {
230 return myCurve->IsClosed();
231 }
232 else {
233 if (myCurve->Continuity() == GeomAbs_C0)
234 return Standard_False;
235 else {
236 if ( myCurve->IsClosed()) {
237 gp_Vec2d Dummy[2];
238 gp_Pnt2d P;
239 myCurve->D1
240 (myCurve->FirstParameter(),P,Dummy[0]);
241 myCurve->D1
242 (myCurve->LastParameter(),P,Dummy[1]);
243 if (Dummy[0].IsParallel(Dummy[1],Precision::Angular()) &&
244 !(Dummy[0].IsOpposite(Dummy[1],Precision::Angular())))
245 return Standard_True;
246 else
247 return Standard_False;
248 }
249 else
250 return Standard_False;
251 }
252 }
253}
254
255//=======================================================================
256//function : IsPeriodic
257//purpose :
258//=======================================================================
259
260Standard_Boolean Adaptor3d_OffsetCurve::IsPeriodic() const
261{
262 return myCurve->IsPeriodic();
263}
264
265//=======================================================================
266//function : Period
267//purpose :
268//=======================================================================
269
270Standard_Real Adaptor3d_OffsetCurve::Period() const
271{
272 return myCurve->Period();
273}
274
275//=======================================================================
276//function : Value
277//purpose :
278//=======================================================================
279
280gp_Pnt2d Adaptor3d_OffsetCurve::Value(const Standard_Real U) const
281{
282 if ( myOffset != 0.) {
283 gp_Pnt2d P;
284 gp_Vec2d V;
285 Standard_Real Norme;
286 myCurve->D1(U, P, V);
287 Norme = V.Magnitude();
288 V.SetCoord(-V.Y(),V.X());
289 if (Norme >= gp::Resolution()) {
290 return gp_Pnt2d(P.XY()+myOffset*V.XY()/Norme);
291 }
292 else {
293 gp_VectorWithNullMagnitude::Raise("Adaptor3d_OffsetCurve::Value");
294 return gp_Pnt2d();
295 }
296 }
297 else {
298 return myCurve->Value(U);
299 }
300}
301
302//=======================================================================
303//function : D0
304//purpose :
305//=======================================================================
306
307void Adaptor3d_OffsetCurve::D0(const Standard_Real U, gp_Pnt2d& P) const
308{
309 P = Value( U);
310}
311
312//=======================================================================
313//function : D1
314//purpose :
315//=======================================================================
316
317void Adaptor3d_OffsetCurve::D1
318 (const Standard_Real U, gp_Pnt2d& P, gp_Vec2d& V) const
319{
320 gp_Vec2d V1,V2,V3;
321 gp_Pnt2d PP;
322 Standard_Real Norme;
323 if ( myOffset != 0. ) {
324 myCurve->D2(U,PP,V1,V2);
325 Norme = V1.Magnitude();
326 V3.SetCoord( -V1.Y(),V1.X());
327 V2.SetCoord( -V2.Y(),V2.X());
328 if ( Norme >= gp::Resolution()) {
329 P = gp_Pnt2d( PP.XY()+myOffset*V3.XY()/Norme);
330 V = gp_Vec2d( V1.XY()+
331 (myOffset/Norme)*(V2.XY()-V3.XY()*
332 (V2.XY()*V3.XY())/(Norme*Norme)));
333 }
334 else {
335 gp_VectorWithNullMagnitude::Raise("Adaptor3d_OffsetCurve::D1");
336 }
337 }
338 else {
339 myCurve->D1(U,P,V);
340 }
341}
342
343//=======================================================================
344//function : D2
345//purpose :
346//=======================================================================
347
348void Adaptor3d_OffsetCurve::D2
349 (const Standard_Real U, gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
350{
351 if ( myOffset != 0.) {
352 gp_Vec2d T1,T2,T3;
353 gp_Pnt2d PP;
354 Standard_Real Norme;
355 myCurve->D3(U,PP,T1,T2,T3);
356
357 Norme = T1.Magnitude();
358 if ( Norme >= gp::Resolution()) {
359 gp_Vec2d N1,N2,N3; // Ni = Z ^ Ti
360 N1.SetCoord( -T1.Y(), T1.X());
361 N2.SetCoord( -T2.Y(), T2.X());
362 N3.SetCoord( -T3.Y(), T3.X());
363 Standard_Real d12,d13,d22,Nor3,Nor11;
364 d12 = T1*T2;
365 d22 = T2*T2;
366 d13 = T1*T3;
367 Nor3 = Norme*Norme*Norme;
368 Nor11 = Nor3*Nor3*Nor3*Norme*Norme;
369 V2 = gp_Vec2d( -1 * ( (d22+d13)/Nor3 + 3*d12*d12/Nor11) * N1.XY());
370 V2 = gp_Vec2d( V2.XY() - (2*d12/Nor3)*N2.XY() + N3.XY()/Norme);
371 V2 = gp_Vec2d( myOffset*V2.XY() + T2.XY());
372
373 D1( U,P,V1);
374 }
375 else {
376 gp_VectorWithNullMagnitude::Raise("Adaptor3d_OffsetCurve::D2");
377 }
378 }
379 else {
380 myCurve->D2(U,P,V1,V2);
381 }
382}
383
384//=======================================================================
385//function : D3
386//purpose :
387//=======================================================================
388
389//void Adaptor3d_OffsetCurve::D3
390// (const Standard_Real T,
391// gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2, gp_Vec2d& V3) const
392void Adaptor3d_OffsetCurve::D3
393 (const Standard_Real ,
394 gp_Pnt2d& , gp_Vec2d& , gp_Vec2d& , gp_Vec2d& ) const
395{
396 Standard_NotImplemented::Raise("Adaptor3d_OffsetCurve::D3");
397}
398
399//=======================================================================
400//function : DN
401//purpose :
402//=======================================================================
403
404gp_Vec2d Adaptor3d_OffsetCurve::DN
405// (const Standard_Real T, const Standard_Integer N) const
406 (const Standard_Real , const Standard_Integer ) const
407{
408 Standard_NotImplemented::Raise("Adaptor3d_OffsetCurve::DN");
409 return gp_Vec2d();
410}
411
412
413//=======================================================================
414//function : Resolution
415//purpose :
416//=======================================================================
417
418Standard_Real Adaptor3d_OffsetCurve::Resolution(const Standard_Real R3d) const
419{
420 return Precision::PConfusion(R3d);
421}
422
423
424//=======================================================================
425//function : GetType
426//purpose :
427//=======================================================================
428
429GeomAbs_CurveType Adaptor3d_OffsetCurve::GetType() const {
430
431 if ( myOffset == 0.) {
432 return myCurve->GetType();
433 }
434 else {
435 switch (myCurve->GetType()) {
436
437 case GeomAbs_Line:
438 return GeomAbs_Line;
439
440 case GeomAbs_Circle:
441 return GeomAbs_Circle;
442
443 default:
444 return GeomAbs_OtherCurve;
445
446 }
447 }
448}
449
450//=======================================================================
451//function : Line
452//purpose :
453//=======================================================================
454
455gp_Lin2d Adaptor3d_OffsetCurve::Line() const
456{
457 if ( GetType() == GeomAbs_Line) {
458 gp_Pnt2d P;
459 gp_Vec2d V;
460 D1(0,P,V);
461 return gp_Lin2d(P,V);
462 }
463 else {
464 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve::Line");
465 return gp_Lin2d();
466 }
467}
468
469
470//=======================================================================
471//function : Circle
472//purpose :
473//=======================================================================
474
475gp_Circ2d Adaptor3d_OffsetCurve::Circle() const
476{
477 if ( GetType() == GeomAbs_Circle) {
478 if (myOffset == 0.) {
479 return myCurve->Circle();
480 }
481 else {
482 gp_Circ2d C1( myCurve->Circle());
483 Standard_Real radius = C1.Radius();
484 gp_Ax22d axes( C1.Axis());
485 gp_Dir2d Xd = axes.XDirection();
486 gp_Dir2d Yd = axes.YDirection();
487 Standard_Real Crossed = Xd.X()*Yd.Y()-Xd.Y()*Yd.X();
488 Standard_Real Signe = ( Crossed > 0.) ? 1. : -1.;
489
490 radius += Signe*myOffset;
491 if ( radius > 0.) {
492 return gp_Circ2d( axes,radius);
493 }
494 else if ( radius < 0.) {
495 radius = - radius;
496 axes.SetXDirection( (axes.XDirection()).Reversed());
497 return gp_Circ2d( axes,radius);
498 }
499 else { // Cercle de rayon Nul
500 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve::Circle");
501 }
502 }
503 }
504 else {
505 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve::Circle");
506 }
507 // portage WNT
508 return gp_Circ2d();
509}
510
511//=======================================================================
512//function : Ellipse
513//purpose :
514//=======================================================================
515
516gp_Elips2d Adaptor3d_OffsetCurve::Ellipse() const
517{
518 if (myCurve->GetType() == GeomAbs_Ellipse && myOffset == 0.) {
519 return myCurve->Ellipse();;
520 }
521 else {
522 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve:Ellipse");
523 }
524 // portage WNT
525 return gp_Elips2d();
526}
527
528//=======================================================================
529//function : Hyperbola
530//purpose :
531//=======================================================================
532
533gp_Hypr2d Adaptor3d_OffsetCurve::Hyperbola() const
534{
535 if (myCurve->GetType()==GeomAbs_Hyperbola && myOffset==0.) {
536 return myCurve->Hyperbola();
537 }
538 else {
539 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve:Hyperbola");
540 }
541 // portage WNT
542 return gp_Hypr2d();
543}
544
545//=======================================================================
546//function : Parabola
547//purpose :
548//=======================================================================
549
550gp_Parab2d Adaptor3d_OffsetCurve::Parabola() const
551{
552 if (myCurve->GetType() == GeomAbs_Parabola && myOffset == 0.) {
553 return myCurve->Parabola();
554 }
555 else {
556 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve:Parabola");
557 }
558 // portage WNT
559 return gp_Parab2d();
560}
561//=======================================================================
562//function : Degree
563//purpose :
564//=======================================================================
565
566Standard_Integer Adaptor3d_OffsetCurve::Degree() const
567{
568 GeomAbs_CurveType type = myCurve->GetType();
569 if ( (type==GeomAbs_BezierCurve || type==GeomAbs_BSplineCurve)
570 && myOffset == 0.) {
571 return myCurve->Degree();
572 }
573 else {
574 Standard_NoSuchObject::Raise("Adaptor3d_offsetCurve::Degree");
575 return 0;
576 }
577}
578//=======================================================================
579//function : IsRational
580//purpose :
581//=======================================================================
582
583Standard_Boolean Adaptor3d_OffsetCurve::IsRational() const
584{
585 if ( myOffset == 0.) {
586 return myCurve->IsRational();
587 }
588 return Standard_False;
589}
590//=======================================================================
591//function : NbPoles
592//purpose :
593//=======================================================================
594
595Standard_Integer Adaptor3d_OffsetCurve::NbPoles() const
596{
597 GeomAbs_CurveType type = myCurve->GetType();
598 if ( (type==GeomAbs_BezierCurve || type==GeomAbs_BSplineCurve)
599 && myOffset == 0.) {
600 return myCurve->NbPoles();
601 }
602 else {
603 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve::NbPoles");
604 return 0;
605 }
606}
607
608//=======================================================================
609//function : NbKnots
610//purpose :
611//=======================================================================
612
613Standard_Integer Adaptor3d_OffsetCurve::NbKnots() const
614{
615 if( myOffset == 0.) {
616 return myCurve->NbKnots();
617 }
618 else {
619 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve::NbKnots");
620 return 0;
621 }
622}
623
624//=======================================================================
625//function : Bezier
626//purpose :
627//=======================================================================
628
629Handle(Geom2d_BezierCurve) Adaptor3d_OffsetCurve::Bezier() const
630{
631 Standard_NoSuchObject_Raise_if
632 ( myOffset != 0.0e0 || GetType() != GeomAbs_BezierCurve, "");
633 return myCurve->Bezier();
634}
635
636
637//=======================================================================
638//function : BSpline
639//purpose :
640//=======================================================================
641
642Handle(Geom2d_BSplineCurve) Adaptor3d_OffsetCurve::BSpline() const
643{
644 Standard_NoSuchObject_Raise_if
645 ( myOffset != 0.0e0 || GetType() != GeomAbs_BSplineCurve, "");
646
647 return myCurve->BSpline();
648}
649
650