0024023: Revamp the OCCT Handle -- general
[occt.git] / src / Geom / Geom_SurfaceOfLinearExtrusion.cxx
1 // Created on: 1993-03-10
2 // Created by: JCV
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <GeomAbs_CurveType.hxx>
18 #include <Geom_SurfaceOfLinearExtrusion.ixx>
19 #include <Precision.hxx>
20 #include <gp.hxx>
21 #include <gp_Ax2d.hxx>
22 #include <gp_XYZ.hxx>
23 #include <gp_Lin.hxx>
24 #include <Geom_Line.hxx>
25 #include <Geom_Circle.hxx>
26 #include <Geom_Ellipse.hxx>
27 #include <Geom_Hyperbola.hxx>
28 #include <Geom_Parabola.hxx>
29 #include <Geom_BezierCurve.hxx>
30 #include <Geom_BSplineCurve.hxx>
31 #include <Geom_TrimmedCurve.hxx>
32 #include <Geom_OffsetCurve.hxx>
33 #include <BSplSLib.hxx>
34 #include <BSplCLib.hxx>
35 #include <Standard_RangeError.hxx>
36 #include <Geom_Curve.hxx>
37
38 #define  POLES    (poles->Array2())
39 #define  WEIGHTS  (weights->Array2())
40 #define  UKNOTS   (uknots->Array1())
41 #define  VKNOTS   (vknots->Array1())
42 #define  UFKNOTS  (ufknots->Array1())
43 #define  VFKNOTS  (vfknots->Array1())
44 #define  FMULTS   (BSplCLib::NoMults())
45
46 typedef Geom_SurfaceOfLinearExtrusion         SurfaceOfLinearExtrusion;
47 typedef Geom_Curve                            Curve;
48 typedef gp_Dir  Dir;
49 typedef gp_Pnt  Pnt;
50 typedef gp_Trsf Trsf;
51 typedef gp_Vec  Vec;
52 typedef gp_XYZ  XYZ;
53
54 static void LocateSide(const Standard_Real U,
55                        const Standard_Integer Side,
56                        const Handle(Geom_BSplineCurve)& BSplC,
57                        const Standard_Integer NDir,
58                        gp_Pnt& P,
59                        gp_Vec& D1U,
60                        gp_Vec& D2U,
61                        gp_Vec& D3U) 
62
63   Standard_Integer Ideb, Ifin;
64   Standard_Real ParTol=Precision::PConfusion()/2;
65   BSplC->Geom_BSplineCurve::LocateU(U,ParTol,Ideb,Ifin,Standard_False);   
66   if(Side == 1)
67     {
68       if(Ideb<1) Ideb=1;
69       if ((Ideb>=Ifin))  Ifin = Ideb+1;
70     }else
71   if(Side ==-1)
72         { 
73           if(Ifin > BSplC -> NbKnots()) Ifin=BSplC->NbKnots();
74           if ((Ideb>=Ifin))  Ideb = Ifin-1;
75         }
76
77   switch(NDir)
78        {
79        case 0 :  BSplC->Geom_BSplineCurve::LocalD0(U,Ideb,Ifin,P); break;
80        case 1 :  BSplC->Geom_BSplineCurve::LocalD1(U,Ideb,Ifin,P,D1U); break;
81        case 2 :  BSplC->Geom_BSplineCurve::LocalD2(U,Ideb,Ifin,P,D1U,D2U); break;
82        case 3 :  BSplC->Geom_BSplineCurve::LocalD3(U,Ideb,Ifin,P,D1U,D2U,D3U);break;
83         }
84    
85 }
86
87 static gp_Vec LocateSideN(const Standard_Real U,
88                           const Standard_Integer Side,
89                           const Handle(Geom_BSplineCurve)& BSplC,
90                           const Standard_Integer Nu,
91 //                        const Standard_Integer  Nv ) 
92                           const Standard_Integer ) 
93
94   Standard_Integer Ideb, Ifin;
95   Standard_Real ParTol=Precision::PConfusion()/2;
96   BSplC->Geom_BSplineCurve::LocateU(U,ParTol,Ideb,Ifin,Standard_False);   
97   if(Side == 1)
98     {
99       if(Ideb<1) Ideb=1;
100       if ((Ideb>=Ifin))  Ifin = Ideb+1;
101     }else
102       if(Side ==-1)
103         { 
104           if(Ifin > BSplC -> NbKnots()) Ifin=BSplC->NbKnots();
105           if ((Ideb>=Ifin))  Ideb = Ifin-1;
106         }
107   return BSplC->Geom_BSplineCurve::LocalDN(U,Ideb,Ifin,Nu);
108 }
109
110
111
112 //=======================================================================
113 //function : Copy
114 //purpose  : 
115 //=======================================================================
116
117 Handle(Geom_Geometry) Geom_SurfaceOfLinearExtrusion::Copy () const 
118 {
119   
120   Handle(Geom_SurfaceOfLinearExtrusion) Sr;
121   Sr = new SurfaceOfLinearExtrusion (basisCurve, direction);
122   return Sr;
123 }
124
125
126 //=======================================================================
127 //function : Geom_SurfaceOfLinearExtrusion
128 //purpose  : 
129 //=======================================================================
130
131 Geom_SurfaceOfLinearExtrusion::Geom_SurfaceOfLinearExtrusion 
132   ( const Handle(Geom_Curve)& C, 
133     const Dir& V) {
134
135    basisCurve = Handle(Geom_Curve)::DownCast(C->Copy());  // Copy 10-03-93
136    direction  = V;
137    smooth     = C->Continuity();
138  }
139
140
141 //=======================================================================
142 //function : UReverse
143 //purpose  : 
144 //=======================================================================
145
146 void Geom_SurfaceOfLinearExtrusion::UReverse () { 
147
148   basisCurve->Reverse(); 
149 }
150
151
152 //=======================================================================
153 //function : UReversedParameter
154 //purpose  : 
155 //=======================================================================
156
157 Standard_Real Geom_SurfaceOfLinearExtrusion::UReversedParameter(const Standard_Real U) const {
158
159   return basisCurve->ReversedParameter(U);
160 }
161
162
163 //=======================================================================
164 //function : VReverse
165 //purpose  : 
166 //=======================================================================
167
168 void Geom_SurfaceOfLinearExtrusion::VReverse () {
169
170   direction.Reverse(); 
171 }
172
173
174 //=======================================================================
175 //function : VReversedParameter
176 //purpose  : 
177 //=======================================================================
178
179 Standard_Real Geom_SurfaceOfLinearExtrusion::VReversedParameter( const Standard_Real V) const {
180
181   return (-V);
182 }
183
184
185 //=======================================================================
186 //function : SetDirection
187 //purpose  : 
188 //=======================================================================
189
190 void Geom_SurfaceOfLinearExtrusion::SetDirection (const Dir& V) {
191
192    Handle(Geom_Curve) C;
193    direction = V;
194    C         = basisCurve;
195  }
196
197
198 //=======================================================================
199 //function : SetBasisCurve
200 //purpose  : 
201 //=======================================================================
202
203 void Geom_SurfaceOfLinearExtrusion::SetBasisCurve (const Handle(Geom_Curve)& C) {
204
205    smooth = C->Continuity();
206    basisCurve = Handle(Geom_Curve)::DownCast(C->Copy());  // Copy 10-03-93
207 }
208
209
210 //=======================================================================
211 //function : Bounds
212 //purpose  : 
213 //=======================================================================
214
215 void Geom_SurfaceOfLinearExtrusion::Bounds ( Standard_Real& U1, 
216                                              Standard_Real& U2,
217                                              Standard_Real& V1, 
218                                              Standard_Real& V2 ) const {
219
220   V1 = -Precision::Infinite();  V2 = Precision::Infinite();
221   U1 = basisCurve->FirstParameter();  U2 = basisCurve->LastParameter();
222 }
223
224
225 //=======================================================================
226 //function : D0
227 //purpose  : 
228 //=======================================================================
229
230 void Geom_SurfaceOfLinearExtrusion::D0 (const Standard_Real U, const Standard_Real V, 
231                                               Pnt& P               )  const {
232   
233   XYZ Pxyz = direction.XYZ();
234   Pxyz.Multiply (V);
235   Pxyz.Add (basisCurve->Value (U).XYZ());
236   P.SetXYZ(Pxyz);      
237 }
238
239
240 //=======================================================================
241 //function : D1
242 //purpose  : 
243 //=======================================================================
244
245 void Geom_SurfaceOfLinearExtrusion::D1 ( const Standard_Real U  , 
246                                          const Standard_Real V  , 
247                                                Pnt& P  , 
248                                                Vec& D1U, Vec& D1V) const {
249
250    basisCurve->D1 (U, P, D1U);
251    D1V = direction;
252    XYZ Pxyz = direction.XYZ();
253    Pxyz.Multiply (V);
254    Pxyz.Add (P.XYZ());
255    P.SetXYZ (Pxyz);
256 }
257
258
259 //=======================================================================
260 //function : D2
261 //purpose  : 
262 //=======================================================================
263
264 void Geom_SurfaceOfLinearExtrusion::D2 ( const Standard_Real U  , 
265                                          const Standard_Real V  ,
266                                                Pnt& P  ,
267                                                Vec& D1U, Vec& D1V,
268                                                Vec& D2U, Vec& D2V, Vec& D2UV)
269 const {
270
271    basisCurve->D2 (U, P, D1U, D2U);
272    D1V = direction;
273    D2V.SetCoord  (0.0, 0.0, 0.0);
274    D2UV.SetCoord (0.0, 0.0, 0.0);
275    XYZ Pxyz = direction.XYZ();
276    Pxyz.Multiply (V);
277    Pxyz.Add (P.XYZ());
278    P.SetXYZ (Pxyz);
279 }
280
281
282 //=======================================================================
283 //function : D3
284 //purpose  : 
285 //=======================================================================
286
287 void Geom_SurfaceOfLinearExtrusion::D3 
288   ( const Standard_Real U, const Standard_Real V,
289     Pnt& P,
290     Vec& D1U, Vec& D1V,
291     Vec& D2U, Vec& D2V, Vec& D2UV,
292     Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV ) const {
293
294
295    basisCurve->D3 (U, P, D1U, D2U, D3U);
296    D1V = direction;
297    D2V.SetCoord   (0.0, 0.0, 0.0);
298    D3V.SetCoord   (0.0, 0.0, 0.0);
299    D3UUV.SetCoord (0.0, 0.0, 0.0);
300    D3UVV.SetCoord (0.0, 0.0, 0.0);
301    D2UV.SetCoord  (0.0, 0.0, 0.0);
302    XYZ Pxyz = direction.XYZ();
303    Pxyz.Multiply (V);
304    Pxyz.Add (P.XYZ());
305    P.SetXYZ (Pxyz);
306 }
307 //=======================================================================
308 //function : DN
309 //purpose  : 
310 //=======================================================================
311
312 Vec Geom_SurfaceOfLinearExtrusion::DN 
313   ( const Standard_Real     U, const Standard_Real , 
314     const Standard_Integer Nu, const Standard_Integer Nv) const {
315
316   Standard_RangeError_Raise_if (Nu + Nv < 1 || Nu < 0 || Nv <0, " ");
317   if (Nu == 0 && Nv == 1)  return Vec (direction);
318   else if (Nv == 0)        return basisCurve->DN (U, Nu);
319   else                     return Vec (0.0, 0.0, 0.0);
320 }
321
322
323 //=======================================================================
324 //function : LocalD0
325 //purpose  : 
326 //=======================================================================
327
328 void Geom_SurfaceOfLinearExtrusion::LocalD0 (const Standard_Real    U,
329                                              const Standard_Real    V, 
330                                              const Standard_Integer USide,
331                                              gp_Pnt&          P     )  const
332
333   if((USide != 0) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) 
334     { 
335       Vec D1U,D2U,D3U;
336       Handle( Geom_BSplineCurve) BSplC;
337       BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
338
339       LocateSide(U,USide,BSplC,0,P,D1U,D2U,D3U);
340       XYZ Pxyz = direction.XYZ();
341       Pxyz.Multiply (V);
342       Pxyz.Add (P.XYZ());
343       P.SetXYZ (Pxyz);
344     }
345   else D0(U,V,P);
346 }        
347
348 //=======================================================================
349 //function : LocalD1
350 //purpose  : 
351 //=======================================================================
352
353 void Geom_SurfaceOfLinearExtrusion::LocalD1 (const Standard_Real    U, 
354                                    const Standard_Real    V,
355                                    const Standard_Integer USide, 
356                                          gp_Pnt&          P,
357                                          gp_Vec&          D1U, 
358                                          gp_Vec&          D1V)     const
359
360   if((USide != 0) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) 
361     { 
362       Vec D2U,D3U;
363       Handle( Geom_BSplineCurve) BSplC;
364       BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
365
366           LocateSide(U,USide,BSplC,1,P,D1U,D2U,D3U);
367           D1V = direction;
368           XYZ Pxyz = direction.XYZ();
369           Pxyz.Multiply (V);
370           Pxyz.Add (P.XYZ());
371           P.SetXYZ (Pxyz);
372     }
373   else D1(U,V,P,D1U,D1V);
374 }
375
376 //=======================================================================
377 //function : LocalD2
378 //purpose  : 
379 //=======================================================================
380
381 void Geom_SurfaceOfLinearExtrusion::LocalD2 (const Standard_Real    U,
382                                    const Standard_Real    V,
383                                    const Standard_Integer USide,
384                                          gp_Pnt&          P,
385                                          gp_Vec&          D1U,
386                                          gp_Vec&          D1V,
387                                          gp_Vec&          D2U,
388                                          gp_Vec&          D2V,
389                                          gp_Vec&          D2UV) const
390 {
391  if((USide != 0) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) 
392     { 
393       Vec D3U;
394       Handle( Geom_BSplineCurve) BSplC;
395       BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
396
397           LocateSide(U,USide,BSplC,2,P,D1U,D2U,D3U);
398           D1V = direction;
399           D2V.SetCoord  (0.0, 0.0, 0.0);
400           D2UV.SetCoord (0.0, 0.0, 0.0);
401           XYZ Pxyz = direction.XYZ();
402           Pxyz.Multiply (V);
403           Pxyz.Add (P.XYZ());
404           P.SetXYZ (Pxyz); 
405     }
406   else D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
407 }
408
409 //=======================================================================
410 //function : LocalD3
411 //purpose  : 
412 //=======================================================================
413
414 void Geom_SurfaceOfLinearExtrusion::LocalD3 (const Standard_Real    U, 
415                                    const Standard_Real    V,
416                                    const Standard_Integer USide, 
417                                          gp_Pnt&          P,
418                                          gp_Vec&          D1U,
419                                          gp_Vec&          D1V, 
420                                          gp_Vec&          D2U, 
421                                          gp_Vec&          D2V, 
422                                          gp_Vec&          D2UV, 
423                                          gp_Vec&          D3U,
424                                          gp_Vec&          D3V,
425                                          gp_Vec&          D3UUV,
426                                          gp_Vec&          D3UVV) const
427 {
428   if((USide != 0) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) 
429     { 
430       Handle( Geom_BSplineCurve) BSplC;
431       BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
432
433           LocateSide(U,USide,BSplC,3,P,D1U,D2U,D3U);
434           D1V = direction;
435           D2V.SetCoord   (0.0, 0.0, 0.0);
436           D3V.SetCoord   (0.0, 0.0, 0.0);
437           D3UUV.SetCoord (0.0, 0.0, 0.0);
438           D3UVV.SetCoord (0.0, 0.0, 0.0);
439           D2UV.SetCoord  (0.0, 0.0, 0.0);
440           XYZ Pxyz = direction.XYZ();
441           Pxyz.Multiply (V);
442           Pxyz.Add (P.XYZ());
443           P.SetXYZ (Pxyz);
444     }
445   else D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
446
447 }
448
449 //=======================================================================
450 //function : LocalDN
451 //purpose  : 
452 //=======================================================================
453
454 gp_Vec Geom_SurfaceOfLinearExtrusion::LocalDN  (const Standard_Real    U, 
455                                       const Standard_Real    V,
456                                       const Standard_Integer USide,
457                                       const Standard_Integer Nu,
458                                       const Standard_Integer Nv) const
459 {
460   Standard_RangeError_Raise_if (Nu + Nv < 1 || Nu < 0 || Nv <0, " ");
461   if (Nu == 0 && Nv == 1)  return Vec (direction);
462   else if (Nv == 0) {
463     if((USide != 0) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) { 
464       Handle( Geom_BSplineCurve) BSplC;
465       BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
466       return LocateSideN(U,USide,BSplC,Nu,Nv);
467     }
468     else
469       return DN(U,V,Nu,Nv);
470   }      
471   return Vec (0.0, 0.0, 0.0);
472 }
473
474 //=======================================================================
475 //function : UIso
476 //purpose  : 
477 //=======================================================================
478
479 Handle(Geom_Curve) Geom_SurfaceOfLinearExtrusion::UIso (const Standard_Real U) const {
480
481   Handle(Geom_Line) L; 
482   L = new Geom_Line (basisCurve->Value (U), direction);
483   return L;
484 }
485
486
487 //=======================================================================
488 //function : VIso
489 //purpose  : 
490 //=======================================================================
491
492 Handle(Geom_Curve) Geom_SurfaceOfLinearExtrusion::VIso (const Standard_Real V) const {
493     
494   Vec Vdir (direction);
495   Vdir.Multiply (V);
496   Handle(Geom_Curve) C;
497   C = Handle(Geom_Curve)::DownCast(basisCurve->Translated(Vdir));
498   return C;
499 }
500
501
502 //=======================================================================
503 //function : IsCNu
504 //purpose  : 
505 //=======================================================================
506
507 Standard_Boolean Geom_SurfaceOfLinearExtrusion::IsCNu (const Standard_Integer N) const {
508
509   Standard_RangeError_Raise_if (N < 0, " ");
510   return basisCurve->IsCN (N);
511 }
512
513
514 //=======================================================================
515 //function : IsCNv
516 //purpose  : 
517 //=======================================================================
518
519 Standard_Boolean Geom_SurfaceOfLinearExtrusion::IsCNv (const Standard_Integer ) const {
520
521   return Standard_True;
522 }
523
524
525 //=======================================================================
526 //function : Transform
527 //purpose  : 
528 //=======================================================================
529
530 void Geom_SurfaceOfLinearExtrusion::Transform (const Trsf& T) {
531
532    direction.Transform   (T);
533    basisCurve->Transform (T);
534 }
535
536
537
538 //=======================================================================
539 //function : IsUClosed
540 //purpose  : 
541 //=======================================================================
542
543 Standard_Boolean Geom_SurfaceOfLinearExtrusion::IsUClosed () const { 
544
545   return basisCurve->IsClosed ();
546 }
547
548
549 //=======================================================================
550 //function : IsUPeriodic
551 //purpose  : 
552 //=======================================================================
553
554 Standard_Boolean Geom_SurfaceOfLinearExtrusion::IsUPeriodic () const { 
555
556   return basisCurve->IsPeriodic ();
557 }
558
559 //=======================================================================
560 //function : IsVClosed
561 //purpose  : 
562 //=======================================================================
563
564 Standard_Boolean Geom_SurfaceOfLinearExtrusion::IsVClosed () const  {
565
566   return Standard_False; 
567 }
568
569 //=======================================================================
570 //function : IsVPeriodic
571 //purpose  : 
572 //=======================================================================
573
574 Standard_Boolean Geom_SurfaceOfLinearExtrusion::IsVPeriodic () const { 
575
576   return Standard_False;
577 }
578
579 //=======================================================================
580 //function : TransformParameters
581 //purpose  : 
582 //=======================================================================
583
584 void Geom_SurfaceOfLinearExtrusion::TransformParameters(Standard_Real& U,
585                                                         Standard_Real& V,
586                                                         const gp_Trsf& T) 
587 const
588 {
589   U = basisCurve->TransformedParameter(U,T);
590   if (!Precision::IsInfinite(V)) V *= Abs(T.ScaleFactor());
591 }
592
593 //=======================================================================
594 //function : ParametricTransformation
595 //purpose  : 
596 //=======================================================================
597
598 gp_GTrsf2d Geom_SurfaceOfLinearExtrusion::ParametricTransformation
599 (const gp_Trsf& T) const
600 {
601   // transformation in the V Direction
602   gp_GTrsf2d TV;
603   gp_Ax2d Axis(gp::Origin2d(),gp::DX2d());
604   TV.SetAffinity(Axis, Abs(T.ScaleFactor()));
605   // transformation in the U Direction
606   gp_GTrsf2d TU;
607   Axis = gp_Ax2d(gp::Origin2d(),gp::DY2d());
608   TU.SetAffinity(Axis, basisCurve->ParametricTransformation(T));
609  
610   return TU * TV;
611 }