0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / GeomFill / GeomFill_DraftTrihedron.cxx
1 // Created on: 1998-04-15
2 // Created by: Stephanie HUMEAU
3 // Copyright (c) 1998-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 <GeomFill_DraftTrihedron.ixx>
18
19 #include <Precision.hxx>
20 #include <GeomAbs_CurveType.hxx>
21 #include <Adaptor3d_HCurve.hxx>
22
23 //=======================================================================
24 //function : DDeriv
25 //purpose  : computes (F/|F|)''
26 //=======================================================================
27 static gp_Vec DDeriv(const gp_Vec& F, const gp_Vec& DF, const gp_Vec& D2F)
28 {
29   Standard_Real Norma = F.Magnitude();
30
31   gp_Vec Result = (D2F - 2*DF*(F*DF)/(Norma*Norma))/Norma - 
32      F*((DF.SquareMagnitude() + F*D2F 
33         - 3*(F*DF)*(F*DF)/(Norma*Norma))/(Norma*Norma*Norma));
34   return Result;
35 }
36
37 //=======================================================================
38 //function : DraftTrihedron
39 //purpose  : Constructor
40 //=======================================================================
41  GeomFill_DraftTrihedron::GeomFill_DraftTrihedron(const gp_Vec& BiNormal,
42                                                   const Standard_Real Angle)
43 {
44   B = BiNormal;
45   B.Normalize();
46   SetAngle(Angle);
47 }
48
49
50 //=======================================================================
51 //function : Setangle
52 //purpose  : 
53 //=======================================================================
54  void GeomFill_DraftTrihedron::SetAngle(const Standard_Real Angle)
55 {
56   myAngle = M_PI/2 + Angle;
57   myCos = Cos(myAngle);
58 }
59
60
61 //=======================================================================
62 //function : D0
63 //purpose  : calculation of trihedron
64 //=======================================================================
65  Standard_Boolean GeomFill_DraftTrihedron::D0(const Standard_Real Param,
66                                               gp_Vec& Tangent,
67                                               gp_Vec& Normal,
68                                               gp_Vec& BiNormal) 
69 {  
70   gp_Pnt P;
71   gp_Vec T;
72   myTrimmed->D1(Param,P,T);
73   T.Normalize();
74
75   gp_Vec b = T.Crossed(B);
76   Standard_Real normb = b.Magnitude();
77
78   b /=  normb;
79   if (normb < 1.e-12) 
80     return Standard_False;
81
82   gp_Vec v = b.Crossed(T);
83
84   Standard_Real mu = myCos ;
85   mu = myCos;
86
87   //La Normal est portee par la regle
88   Normal.SetLinearForm(Sqrt(1-mu*mu), b,  mu, v);
89  
90   // Le reste suit....
91   // La tangente est perpendiculaire a la normale et a la direction de depouille
92   Tangent =  Normal.Crossed(B);
93   Tangent.Normalize();
94
95   BiNormal = Tangent;
96   BiNormal.Cross(Normal);
97
98   return Standard_True; 
99 }
100
101 //=======================================================================
102 //function : D1
103 //purpose  :  calculation of trihedron and first derivative 
104 //=======================================================================
105  Standard_Boolean GeomFill_DraftTrihedron::D1(const Standard_Real Param, 
106                                               gp_Vec& Tangent,
107                                               gp_Vec& DTangent,
108                                               gp_Vec& Normal,
109                                               gp_Vec& DNormal,
110                                               gp_Vec& BiNormal,
111                                               gp_Vec& DBiNormal) 
112 {    
113   gp_Pnt P;
114   gp_Vec T, DT, aux;
115
116   myTrimmed->D2(Param, P, T, aux);
117
118   Standard_Real normT, normb;
119   normT = T.Magnitude();
120   T /=  normT;
121   DT.SetLinearForm(-(T.Dot(aux)), T, aux);
122   DT /=  normT;
123
124   gp_Vec db, b = T.Crossed(B);
125   normb = b.Magnitude();
126   if (normb < 1.e-12) 
127     return Standard_False;
128   b /=  normb;
129   aux = DT.Crossed(B);
130   db.SetLinearForm( -(b.Dot(aux)), b, aux);
131   db /=  normb;
132
133   gp_Vec v = b.Crossed(T);
134   gp_Vec dv = db.Crossed(T) + b.Crossed(DT);
135
136   Standard_Real mu = myCos;
137
138   Normal.SetLinearForm(Sqrt(1-mu*mu), b,  mu, v); 
139   DNormal.SetLinearForm(Sqrt(1-mu*mu), db,  mu, dv); 
140
141   Tangent =  Normal.Crossed(B);
142   normT = Tangent.Magnitude();
143   Tangent/= normT;
144   aux = DNormal.Crossed(B);
145   DTangent.SetLinearForm( -(Tangent.Dot(aux)), Tangent, aux);
146   DTangent /= normT;
147
148   BiNormal = Tangent;
149   BiNormal.Cross(Normal);
150   DBiNormal.SetLinearForm(DTangent.Crossed(Normal),Tangent.Crossed(DNormal)); 
151    
152   return Standard_True;
153 }
154
155 //=======================================================================
156 //function : D2
157 //purpose  : calculation of trihedron and derivatives 1 et 2
158 //=======================================================================
159 Standard_Boolean GeomFill_DraftTrihedron::D2(const Standard_Real Param, 
160                                                  gp_Vec& Tangent,
161                                                  gp_Vec& DTangent,
162                                                  gp_Vec& D2Tangent,
163                                                  gp_Vec& Normal,
164                                                  gp_Vec& DNormal,
165                                                  gp_Vec& D2Normal,
166                                                  gp_Vec& BiNormal,
167                                                  gp_Vec& DBiNormal,
168                                                  gp_Vec& D2BiNormal) 
169 {  
170   gp_Pnt P;
171   gp_Vec T, DT, D2T, aux, aux2;
172   Standard_Real dot;
173
174   myTrimmed->D3(Param, P, T, aux, aux2);
175
176   Standard_Real normT, normb;
177
178   D2T = DDeriv(T, aux, aux2);
179   normT = T.Magnitude();
180   T /=  normT;
181   dot = T.Dot(aux);
182   DT.SetLinearForm(-dot, T, aux);
183   DT /=  normT;
184                     
185   gp_Vec db, d2b, b = T.Crossed(B);
186   normb = b.Magnitude();
187   if (normb < 1.e-12) 
188     return Standard_False;
189
190   aux = DT.Crossed(B);  aux2 = D2T.Crossed(B);
191   d2b =  DDeriv(b, aux, aux2);
192   b /=  normb;
193   dot = b.Dot(aux);
194   db.SetLinearForm( -dot, b, aux);
195   db /=  normb;
196
197   gp_Vec v = b.Crossed(T);
198   gp_Vec dv = db.Crossed(T) + b.Crossed(DT);
199   gp_Vec d2v = d2b.Crossed(T) + 2*db.Crossed(DT) + b.Crossed(D2T);
200   
201
202   Standard_Real mu = myCos, rac;
203   rac = Sqrt(1-mu*mu);
204
205   Normal  .SetLinearForm( rac, b  ,  mu, v); 
206   DNormal .SetLinearForm( rac, db ,  mu, dv);
207   D2Normal.SetLinearForm( rac, d2b,  mu, d2v); 
208
209   Tangent =  Normal.Crossed(B);
210   normT = Tangent.Magnitude();
211
212   aux = DNormal.Crossed(B);  
213   aux2 = D2Normal.Crossed(B);
214   D2Tangent = DDeriv(Tangent, aux, aux2);
215   Tangent/= normT;
216   dot = Tangent.Dot(aux);
217   DTangent.SetLinearForm( -dot, Tangent, aux);
218   DTangent /= normT;
219
220   BiNormal = Tangent;
221   BiNormal.Cross(Normal);
222   DBiNormal.SetLinearForm(DTangent.Crossed(Normal),Tangent.Crossed(DNormal)); 
223   D2BiNormal.SetLinearForm(1, D2Tangent.Crossed(Normal),
224                            2,  DTangent.Crossed(DNormal),
225                            Tangent.Crossed(D2Normal));
226    
227   return Standard_True;
228 }
229
230
231 //=======================================================================
232 //function : Copy
233 //purpose  : 
234 //=======================================================================
235  Handle(GeomFill_TrihedronLaw) GeomFill_DraftTrihedron::Copy() const
236 {
237  Handle(GeomFill_DraftTrihedron) copy = 
238    new (GeomFill_DraftTrihedron) (B,myAngle-M_PI/2);
239  copy->SetCurve(myCurve);
240  return copy;
241
242
243 //=======================================================================
244 //function : NbIntervals
245 //purpose  : 
246 //=======================================================================
247  Standard_Integer GeomFill_DraftTrihedron::NbIntervals(const GeomAbs_Shape S) const
248 {
249   GeomAbs_Shape tmpS=GeomAbs_C0;
250   switch (S) {
251   case GeomAbs_C0: tmpS = GeomAbs_C2; break;
252   case GeomAbs_C1: tmpS = GeomAbs_C3; break;
253   case GeomAbs_C2:
254   case GeomAbs_C3:
255   case GeomAbs_CN: tmpS = GeomAbs_CN; break;
256   default: Standard_OutOfRange::Raise();
257   }
258   
259   return myCurve->NbIntervals(tmpS);
260 }
261
262 //======================================================================
263 //function :Intervals
264 //purpose  : 
265 //=======================================================================
266  void GeomFill_DraftTrihedron::Intervals(TColStd_Array1OfReal& TT,
267                                             const GeomAbs_Shape S) const
268 {
269   GeomAbs_Shape tmpS=GeomAbs_C0;
270   switch (S) {
271   case GeomAbs_C0: tmpS = GeomAbs_C2; break;
272   case GeomAbs_C1: tmpS = GeomAbs_C3; break;
273   case GeomAbs_C2:
274   case GeomAbs_C3:
275   case GeomAbs_CN: tmpS = GeomAbs_CN; break;
276   default: Standard_OutOfRange::Raise();
277   }
278   
279   myCurve->Intervals(TT, tmpS);
280 }
281
282 //=======================================================================
283 //function : GetAverageLaw
284 //purpose  : 
285 //=======================================================================
286  void GeomFill_DraftTrihedron::GetAverageLaw(gp_Vec& ATangent,
287                                              gp_Vec& ANormal,
288                                              gp_Vec& ABiNormal) 
289 {
290   Standard_Integer Num = 20; //order of digitalization
291   gp_Vec T, N, BN;
292   ATangent = gp_Vec(0, 0, 0);
293   ANormal = gp_Vec(0, 0, 0);
294   ABiNormal = gp_Vec(0, 0, 0);
295
296   Standard_Real Step = (myTrimmed->LastParameter() - 
297                         myTrimmed->FirstParameter()) / Num;
298   Standard_Real Param;
299   for (Standard_Integer i = 0; i <= Num; i++) {
300     Param = myTrimmed->FirstParameter() + i*Step;
301     if (Param > myTrimmed->LastParameter()) Param = myTrimmed->LastParameter();
302     D0(Param, T, N, BN);
303     ATangent += T;
304     ANormal += N;
305     ABiNormal += BN;
306   }
307
308   ANormal /= Num + 1;
309   ABiNormal /= Num + 1;
310   ATangent /= Num + 1;
311 }
312
313 //=======================================================================
314 //function : IsConstant
315 //purpose  : 
316 //=======================================================================
317  Standard_Boolean GeomFill_DraftTrihedron::IsConstant() const
318 {
319   return (myCurve->GetType() == GeomAbs_Line);
320 }
321
322 //=======================================================================
323 //function : IsOnlyBy3dCurve
324 //purpose  : 
325 //=======================================================================
326  Standard_Boolean GeomFill_DraftTrihedron::IsOnlyBy3dCurve() const
327 {
328     GeomAbs_CurveType TheType = myCurve->GetType();
329   gp_Ax1 TheAxe;
330
331   switch  (TheType) {
332   case GeomAbs_Circle:
333     {
334       TheAxe =  myCurve->Circle().Axis();
335       break;
336     }
337   case GeomAbs_Ellipse:
338     {
339       TheAxe =  myCurve->Ellipse().Axis();
340       break;
341     }
342   case GeomAbs_Hyperbola:
343     {
344       TheAxe =  myCurve->Hyperbola().Axis();
345       break;
346     }
347   case GeomAbs_Parabola:
348     {
349       TheAxe =  myCurve->Parabola().Axis();
350       break;
351     }
352   case GeomAbs_Line:
353     { //La normale du plan de la courbe est il perpendiculaire a la BiNormale ?
354      gp_Vec V;
355      V.SetXYZ(myCurve->Line().Direction().XYZ());
356      return V.IsParallel(B, Precision::Angular());
357     }
358   default:
359     return Standard_False; // pas de risques
360   }
361
362   // La normale du plan de la courbe est il // a la BiNormale ?
363   gp_Vec V;
364   V.SetXYZ(TheAxe.Direction().XYZ());
365   return V.IsParallel(B, Precision::Angular());
366 }
367
368
369
370
371
372
373
374
375
376