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