0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
[occt.git] / src / GeomFill / GeomFill_GuideTrihedronAC.cxx
1 // Created by: Stephanie HUMEAU
2 // Copyright (c) 1998-1999 Matra Datavision
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 // Creted:      Tue Jun 23 15:39:24 1998
17
18 #include <Adaptor3d_Curve.hxx>
19 #include <Adaptor3d_HCurve.hxx>
20 #include <Approx_CurvlinFunc.hxx>
21 #include <GeomAdaptor.hxx>
22 #include <GeomAdaptor_HCurve.hxx>
23 #include <GeomFill_Frenet.hxx>
24 #include <GeomFill_GuideTrihedronAC.hxx>
25 #include <GeomFill_TrihedronLaw.hxx>
26 #include <GeomLib.hxx>
27 #include <gp_Dir.hxx>
28 #include <gp_Pnt.hxx>
29 #include <gp_Vec.hxx>
30 #include <Precision.hxx>
31 #include <Standard_ConstructionError.hxx>
32 #include <Standard_OutOfRange.hxx>
33 #include <Standard_Type.hxx>
34 #include <TColStd_SequenceOfReal.hxx>
35
36 IMPLEMENT_STANDARD_RTTIEXT(GeomFill_GuideTrihedronAC,GeomFill_TrihedronWithGuide)
37
38 //=======================================================================
39 //function : GuideTrihedron
40 //purpose  : Constructor
41 //=======================================================================
42 GeomFill_GuideTrihedronAC::GeomFill_GuideTrihedronAC(const Handle(Adaptor3d_HCurve) & guide)
43 {
44   myCurve.Nullify();
45   myGuide =  guide;
46   myTrimG =  guide;
47   myGuideAC = new (Approx_CurvlinFunc) (myGuide,1.e-7);
48   Lguide = myGuideAC->GetLength(); 
49   UTol = STol = Precision::PConfusion();
50   Orig1 = 0; // origines pour le cas path multi-edges
51   Orig2 = 1;
52 }
53
54 //=======================================================================
55 //function : Guide
56 //purpose  : calculation of trihedron
57 //=======================================================================
58
59  Handle(Adaptor3d_HCurve) GeomFill_GuideTrihedronAC::Guide()const
60 {
61   return myGuide;
62 }
63
64 //=======================================================================
65 //function : D0
66 //purpose  : calculation of trihedron
67 //=======================================================================
68  Standard_Boolean GeomFill_GuideTrihedronAC::D0(const Standard_Real Param,
69                                                 gp_Vec& Tangent,
70                                                 gp_Vec& Normal,
71                                                 gp_Vec& BiNormal) 
72
73   Standard_Real s = myCurveAC->GetSParameter(Param); // abscisse curviligne <=> Param
74   Standard_Real OrigG = Orig1 + s*(Orig2-Orig1); // abscisse curv sur le guide (cas multi-edges)
75   Standard_Real tG = myGuideAC->GetUParameter(myGuide->GetCurve(), OrigG, 1); // param <=> s sur theGuide
76
77   gp_Pnt P, PG;
78   gp_Vec To, B;
79   myTrimmed->D1(Param, P, To);//point et derivee au parametre Param sur myCurve
80   myTrimG->D0(tG, PG);// point au parametre tG sur myGuide
81   myCurPointOnGuide = PG;
82  
83   gp_Vec n (P, PG); // vecteur definissant la normale
84   
85   Normal = n.Normalized();
86   B = To.Crossed(Normal);
87   BiNormal = B/B.Magnitude();
88   Tangent = Normal.Crossed(BiNormal);
89   Tangent.Normalize();
90
91   return Standard_True;
92 }
93
94 //=======================================================================
95 //function : D1
96 //purpose  : calculation of trihedron and first derivative
97 //=======================================================================
98  Standard_Boolean GeomFill_GuideTrihedronAC::D1(const Standard_Real Param,
99                                                 gp_Vec& Tangent,
100                                                 gp_Vec& DTangent,
101                                                 gp_Vec& Normal,
102                                                 gp_Vec& DNormal,
103                                                 gp_Vec& BiNormal,          
104                                                 gp_Vec& DBiNormal) 
105
106 //triedre
107   Standard_Real s, OrigG, tG, dtg; 
108  // abscisse curviligne <=> Param
109   s = myCurveAC->GetSParameter(Param);
110   // parametre <=> s sur theGuide
111   OrigG = Orig1 + s*(Orig2-Orig1); 
112   // parametre <=> s sur  theGuide
113   tG = myGuideAC->GetUParameter(myGuide->GetCurve(), OrigG, 1); 
114
115   gp_Pnt P, PG;
116   gp_Vec To, DTo, TG, B, BPrim;
117   
118   myTrimmed->D2(Param, P, To, DTo);
119   myTrimG->D1(tG, PG, TG);
120   myCurPointOnGuide = PG;
121   
122   gp_Vec n (P, PG), dn; 
123   Standard_Real Norm = n.Magnitude();
124   if (Norm < 1.e-12) {
125     Norm = 1;
126 #ifdef OCCT_DEBUG
127     cout << "GuideTrihedronAC : Normal indefinie" << endl;
128 #endif
129   }
130   
131   n /= Norm;
132   //derivee de n par rapport a Param
133   dtg = (Orig2-Orig1)*(To.Magnitude()/TG.Magnitude())*(Lguide/L);
134   dn.SetLinearForm(dtg, TG, -1, To);
135   dn /= Norm;
136
137 // triedre
138   Normal = n;
139   B = To.Crossed(Normal);
140   Standard_Real NormB = B.Magnitude();
141   B/= NormB;
142
143   BiNormal = B; 
144
145   Tangent = Normal.Crossed(BiNormal);
146   Tangent.Normalize();
147
148 // derivee premiere
149   DNormal.SetLinearForm(-(n.Dot(dn)), n, dn);  
150  
151   BPrim.SetLinearForm(DTo.Crossed(Normal), To.Crossed(DNormal));
152
153   DBiNormal.SetLinearForm(-(B.Dot(BPrim)), B, BPrim);
154   DBiNormal /= NormB;
155
156   DTangent.SetLinearForm(Normal.Crossed(DBiNormal), DNormal.Crossed(BiNormal));
157
158   return Standard_True;
159 }
160
161
162 //=======================================================================
163 //function : D2
164 //purpose  : calculation of trihedron and derivatives
165 //=======================================================================
166  Standard_Boolean GeomFill_GuideTrihedronAC::D2(const Standard_Real Param,
167                                                 gp_Vec& Tangent,
168                                                 gp_Vec& DTangent,
169                                                 gp_Vec& D2Tangent,
170                                                 gp_Vec& Normal,
171                                                 gp_Vec& DNormal,
172                                                 gp_Vec& D2Normal,
173                                                 gp_Vec& BiNormal,                         
174                                                 gp_Vec& DBiNormal,                
175                                                 gp_Vec& D2BiNormal) 
176
177   // abscisse curviligne <=> Param
178   Standard_Real s = myCurveAC->GetSParameter(Param); 
179   // parametre <=> s sur theGuide
180   Standard_Real OrigG = Orig1 + s*(Orig2-Orig1); 
181   Standard_Real tG = myGuideAC->GetUParameter(myGuide->GetCurve(), 
182                                               OrigG, 1); 
183
184   gp_Pnt P,PG;
185   gp_Vec TG,DTG;
186 //  gp_Vec To,DTo,D2To,B;
187   gp_Vec To,DTo,D2To;
188   
189   myTrimmed->D3(Param, P, To, DTo, D2To);
190   myTrimG->D2(tG, PG, TG, DTG);
191   myCurPointOnGuide = PG;
192
193   Standard_Real NTo = To.Magnitude();
194   Standard_Real N2To = To.SquareMagnitude();
195   Standard_Real NTG = TG.Magnitude();
196   Standard_Real N2Tp = TG.SquareMagnitude();
197   Standard_Real d2tp_dt2, dtg_dt; 
198   dtg_dt = (Orig2-Orig1)*(NTo/NTG)*(Lguide/L);
199
200   gp_Vec n(P, PG); // vecteur definissant la normale
201   Standard_Real Norm = n.Magnitude(), ndn;
202   //derivee de n par rapport a Param
203   gp_Vec dn, d2n;
204   dn.SetLinearForm(dtg_dt, TG, -1, To);
205
206   //derivee seconde de tG par rapport a Param
207   d2tp_dt2 = (Orig2-Orig1)*(Lguide/L) * 
208     ( DTo.Dot(To) / (NTo*NTG) - N2To*TG*DTG*(Lguide/L) / (N2Tp*N2Tp));
209   //derivee seconde de n par rapport a Param
210   d2n.SetLinearForm(dtg_dt*dtg_dt,DTG, d2tp_dt2, TG, -1, DTo);
211
212   if (Norm > 1.e-9) {
213     n /= Norm;
214     dn /= Norm;
215     d2n /= Norm;
216   }
217 //triedre
218   Normal = n;
219
220   gp_Vec TN, DTN, D2TN;
221   TN  = To.Crossed(Normal);
222
223
224   Standard_Real Norma = TN.Magnitude();
225   if (Norma > 1.e-9) TN /= Norma;
226
227   BiNormal = TN; 
228
229   Tangent = Normal.Crossed(BiNormal);
230 //  Tangent.Normalize();
231
232 // derivee premiere du triedre
233 //  gp_Vec DTN = DTo.Crossed(Normal);
234 //  gp_Vec TDN = To.Crossed(DNormal);
235 //  gp_Vec DT = DTN + TDN;
236
237   ndn = n.Dot(dn);
238   DNormal.SetLinearForm(-ndn, n, dn); 
239
240   DTN.SetLinearForm(DTo.Crossed(Normal),  To.Crossed(DNormal));
241   DTN /= Norma;
242   Standard_Real TNDTN = TN.Dot(DTN);
243
244   DBiNormal.SetLinearForm(-TNDTN, TN, DTN);
245
246   DTangent.SetLinearForm(Normal.Crossed(DBiNormal),
247                          DNormal.Crossed(BiNormal));
248
249
250 //derivee seconde du triedre
251 #ifdef OCCT_DEBUG
252   gp_Vec DTDN = DTo.Crossed(DNormal); (void)DTDN;
253 #endif
254   Standard_Real TN2 = TN.SquareMagnitude();
255
256   D2Normal.SetLinearForm(-2*ndn, dn, 
257                          3*ndn*ndn - (dn.SquareMagnitude() + n.Dot(d2n)),n,
258                          d2n);
259                          
260
261   D2TN.SetLinearForm(1, D2To.Crossed(Normal), 
262                      2, DTo.Crossed(DNormal),
263                      To.Crossed(D2Normal));
264   D2TN /= Norma;
265
266   D2BiNormal.SetLinearForm(-2*TNDTN, DTN, 
267                            3*TNDTN*TNDTN - (TN2 + TN.Dot(D2TN)), TN,
268                            D2TN);
269     
270   D2Tangent.SetLinearForm(1, D2Normal.Crossed(BiNormal),
271                           2, DNormal.Crossed(DBiNormal), 
272                           Normal.Crossed(D2BiNormal) );
273
274 //  return Standard_True;
275   return Standard_False;
276
277 }
278
279
280 //=======================================================================
281 //function : Copy
282 //purpose  : 
283 //=======================================================================
284  Handle(GeomFill_TrihedronLaw) GeomFill_GuideTrihedronAC::Copy() const
285 {
286  Handle(GeomFill_GuideTrihedronAC) copy = 
287    new (GeomFill_GuideTrihedronAC) (myGuide);
288  copy->SetCurve(myCurve);
289  copy->Origine(Orig1,Orig2);
290  return copy;
291
292
293 //=======================================================================
294 //function : SetCurve
295 //purpose  : 
296 //=======================================================================
297  void GeomFill_GuideTrihedronAC::SetCurve(const Handle(Adaptor3d_HCurve)& C) 
298 {
299   myCurve = C;
300   myTrimmed = C;
301   if (!myCurve.IsNull()) {
302     myCurveAC = new (Approx_CurvlinFunc) (C,1.e-7);
303     L = myCurveAC->GetLength();
304 //    CorrectOrient(myGuide);
305   }
306 }
307
308
309 //=======================================================================
310 //function : NbIntervals
311 //purpose  : 
312 //=======================================================================
313  Standard_Integer GeomFill_GuideTrihedronAC::NbIntervals(const GeomAbs_Shape S) const
314 {
315   Standard_Integer Nb;
316   Nb = myCurveAC->NbIntervals(S);
317   TColStd_Array1OfReal DiscC(1, Nb+1);
318   myCurveAC->Intervals(DiscC, S);
319   Nb =  myGuideAC->NbIntervals(S);
320   TColStd_Array1OfReal DiscG(1, Nb+1);
321   myGuideAC->Intervals(DiscG, S);
322
323   TColStd_SequenceOfReal Seq;
324   GeomLib::FuseIntervals(DiscC, DiscG, Seq);
325   
326   return Seq.Length()-1;
327
328 }
329
330 //======================================================================
331 //function :Intervals
332 //purpose  : 
333 //=======================================================================
334  void GeomFill_GuideTrihedronAC::Intervals(TColStd_Array1OfReal& TT,
335                                            const GeomAbs_Shape S) const
336 {
337   Standard_Integer Nb, ii;
338   Nb = myCurveAC->NbIntervals(S);
339   TColStd_Array1OfReal DiscC(1, Nb+1);
340   myCurveAC->Intervals(DiscC, S);
341   Nb =  myGuideAC->NbIntervals(S);
342   TColStd_Array1OfReal DiscG(1, Nb+1);
343   myGuideAC->Intervals(DiscG, S);
344
345   TColStd_SequenceOfReal Seq;
346   GeomLib::FuseIntervals(DiscC, DiscG, Seq); 
347   Nb = Seq.Length();
348
349   for (ii=1; ii<=Nb; ii++) {
350     TT(ii) =  myCurveAC->GetUParameter(myCurve->GetCurve(), Seq(ii), 1);
351   }
352
353 }
354
355 //======================================================================
356 //function :SetInterval
357 //purpose  : 
358 //=======================================================================
359 void GeomFill_GuideTrihedronAC::SetInterval(const Standard_Real First,
360                                             const Standard_Real Last) 
361 {
362   myTrimmed = myCurve->Trim(First, Last, UTol); 
363   Standard_Real Sf, Sl, U;
364
365   Sf = myCurveAC->GetSParameter(First);
366   Sl = myCurveAC->GetSParameter(Last);
367 //  if (Sl>1) Sl=1;
368 //  myCurveAC->Trim(Sf, Sl, UTol);
369
370   U = Orig1 + Sf*(Orig2-Orig1);
371   Sf = myGuideAC->GetUParameter(myGuide->GetCurve(), U, 1);
372   U = Orig1 + Sl*(Orig2-Orig1);
373   Sl = myGuideAC->GetUParameter(myGuide->GetCurve(), U, 1);
374   myTrimG = myGuide->Trim(Sf, Sl, UTol); 
375 }
376
377
378
379 //=======================================================================
380 //function : GetAverageLaw
381 //purpose  : 
382 //=======================================================================
383  void GeomFill_GuideTrihedronAC::GetAverageLaw(gp_Vec& ATangent,
384                                                gp_Vec& ANormal,
385                                                gp_Vec& ABiNormal) 
386 {
387   Standard_Integer ii;
388   Standard_Real t, Delta = (myCurve->LastParameter() - 
389                             myCurve->FirstParameter())/20.001;
390
391   ATangent.SetCoord(0.,0.,0.);
392   ANormal.SetCoord(0.,0.,0.);
393   ABiNormal.SetCoord(0.,0.,0.);
394   gp_Vec T, N, B;
395   
396   for (ii=1; ii<=20; ii++) {
397     t = myCurve->FirstParameter() +(ii-1)*Delta;
398     D0(t, T, N, B);
399     ATangent +=T;
400     ANormal  +=N;
401     ABiNormal+=B;
402   }
403   ATangent  /= 20;
404   ANormal   /= 20;
405   ABiNormal /= 20; 
406 }
407
408 //=======================================================================
409 //function : IsConstant
410 //purpose  : 
411 //=======================================================================
412  Standard_Boolean GeomFill_GuideTrihedronAC::IsConstant() const
413 {
414   return  Standard_False;
415 }
416
417 //=======================================================================
418 //function : IsOnlyBy3dCurve
419 //purpose  : 
420 //=======================================================================
421  Standard_Boolean GeomFill_GuideTrihedronAC::IsOnlyBy3dCurve() const
422 {
423   return Standard_False;
424 }
425
426 //=======================================================================
427 //function : Origine
428 //purpose  : 
429 //=======================================================================
430  void GeomFill_GuideTrihedronAC::Origine(const Standard_Real OrACR1,
431                                          const Standard_Real OrACR2)
432 {
433   Orig1 = OrACR1;
434   Orig2 = OrACR2;
435 }