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