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