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