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