0024169: Eliminate CLang compiler warning -Wunused-value
[occt.git] / src / GeomFill / GeomFill_GuideTrihedronPlan.cxx
1 // Created on: 1998-07-02
2 // Created by: Stephanie HUMEAU
3 // Copyright (c) 1998-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 <GeomFill_GuideTrihedronPlan.ixx>
24
25 #include <gp_Pnt.hxx>
26 #include <gp_Pnt2d.hxx>
27 //#include <gp_Trsf2d.hxx>
28 //#include <Bnd_Box2d.hxx>
29 #include <ElCLib.hxx>
30
31 #include <Adaptor3d_Curve.hxx>
32 #include <GeomAdaptor_HCurve.hxx>
33 #include <GeomAdaptor_HSurface.hxx>
34
35 #include <Geom_Plane.hxx>
36
37 #include <IntCurveSurface_IntersectionPoint.hxx>
38 #include <IntCurveSurface_HInter.hxx>
39
40 #include <GeomFill_Frenet.hxx>
41 #include <GeomFill_PlanFunc.hxx>
42
43 #include <math_Vector.hxx>
44
45 #include <math_FunctionRoot.hxx>
46 #include <math_Matrix.hxx>
47
48 #include <Precision.hxx>
49
50 #if DRAW
51 #include <DrawTrSurf.hxx>
52 #endif
53
54 #if DEB
55 static void TracePlan(const Handle(Geom_Surface)& /*Plan*/)
56 {
57   cout << "Pas d'intersection Guide/Plan" << endl;      
58 #if DRAW
59   char* Temp = "ThePlan" ;
60   DrawTrSurf::Set(Temp, Plan);
61 //  DrawTrSurf::Set("ThePlan", Plan);
62 #endif 
63 }
64 #endif
65
66 //==================================================================
67 //Function: InGoodPeriod
68 //Purpose : Recadre un paramtere
69 //==================================================================
70 static void InGoodPeriod(const Standard_Real Prec,
71                          const Standard_Real  Period,
72                          Standard_Real& Current)
73 {
74   Standard_Real Diff=Current-Prec;
75   Standard_Integer nb = (Standard_Integer ) IntegerPart(Diff/Period);
76   Current -= nb*Period;
77   Diff = Current-Prec;
78   if (Diff > Period/2) Current -= Period;
79   else if (Diff < -Period/2) Current += Period;
80 }
81
82 //=======================================================================
83 //function : GuideTrihedronPlan
84 //purpose  : Constructor
85 //=======================================================================
86 GeomFill_GuideTrihedronPlan::GeomFill_GuideTrihedronPlan (const Handle(Adaptor3d_HCurve)& theGuide) :
87                                                           X(1,1),  
88                                                           XTol(1,1),
89                                                           Inf(1,1), Sup(1,1),
90                                                           myStatus(GeomFill_PipeOk)
91 {
92   myCurve.Nullify();
93   myGuide = theGuide; // guide
94   myTrimG = theGuide;
95   myNbPts = 20;     // nb points pour calculs
96   Pole = new (TColgp_HArray2OfPnt2d)(1,1,1,myNbPts);//tab pr stocker Pprime (pt sur guide)
97   frenet = new (GeomFill_Frenet)();
98   XTol.Init(1.e-6);
99   XTol(1) = myGuide->Resolution(1.e-6);
100 }
101
102 //=======================================================================
103 //function : Init
104 //purpose  : calcule myNbPts points sur la courbe guide (<=> normale)
105 //=======================================================================
106  void GeomFill_GuideTrihedronPlan::Init()
107 {
108   myStatus = GeomFill_PipeOk;
109   gp_Pnt P;
110 //  Bnd_Box2d Box;
111 //  Box.Update(-0.1, -0.1, 0.1, 0.1); // Taille minimal
112   gp_Vec Tangent,Normal,BiNormal;
113   Standard_Integer ii;
114   Standard_Real t, DeltaG, w = 0.;
115   Standard_Real f = myCurve->FirstParameter();
116   Standard_Real l = myCurve->LastParameter();
117   
118
119
120   Handle(Geom_Plane) Plan;
121   Handle(GeomAdaptor_HSurface) Pl;
122   IntCurveSurface_IntersectionPoint PInt;
123   IntCurveSurface_HInter Int;
124   frenet->SetCurve(myCurve);
125   DeltaG = (myGuide->LastParameter() -  myGuide->FirstParameter())/2;
126   
127   Inf(1) = myGuide->FirstParameter() - DeltaG;
128   Sup(1) = myGuide->LastParameter() + DeltaG;
129
130   if (!myGuide->IsPeriodic()) {
131     myTrimG = myGuide->Trim(myGuide->FirstParameter()- DeltaG/100, 
132                             myGuide->LastParameter() + DeltaG/100, 
133                             DeltaG*1.e-7);
134   }
135   else {
136     myTrimG = myGuide; 
137   }
138 //  Standard_Real Step = DeltaG/100;
139   DeltaG /= 3;
140   for (ii=1; ii<=myNbPts; ii++) 
141     {
142       t = Standard_Real(myNbPts - ii)*f + Standard_Real(ii - 1)*l;
143       t /= (myNbPts-1);
144       myCurve->D0(t, P); 
145       frenet->D0(t, Tangent, Normal, BiNormal);
146       Plan = new (Geom_Plane) (P, Tangent);
147       Pl = new(GeomAdaptor_HSurface) (Plan);
148
149       Int.Perform(myTrimG, Pl); // intersection plan / guide 
150       if (Int.NbPoints() == 0) {
151 #if DEB
152         TracePlan(Plan);
153 #endif
154         w = (fabs(myGuide->LastParameter() -w) > fabs(myGuide->FirstParameter()-w) ? myGuide->FirstParameter() : myGuide->LastParameter());
155                                                                                    
156         myStatus = GeomFill_PlaneNotIntersectGuide;
157         //return;
158       }
159       else 
160         {
161           gp_Pnt Pmin;
162           PInt = Int.Point(1);
163           Pmin = PInt.Pnt();
164           Standard_Real Dmin = P.Distance(Pmin);
165           for (Standard_Integer jj=2;jj<=Int.NbPoints();jj++)
166             {
167               Pmin = Int.Point(jj).Pnt();
168               if (P.Distance(Pmin) < Dmin) 
169                 {
170                   PInt = Int.Point(jj);
171                   Dmin = P.Distance(Pmin);
172                 }
173             }//for_jj
174           
175           w = PInt.W();
176         }
177       if (ii>1) {
178         Standard_Real Diff = w -  Pole->Value(1, ii-1).Y();
179         if (Abs(Diff) > DeltaG) {
180           if (myGuide->IsPeriodic()) {
181             InGoodPeriod (Pole->Value(1, ii-1).Y(),
182                           myGuide->Period(), w);
183             
184             Diff =  w -  Pole->Value(1, ii-1).Y();
185           }
186         }
187         
188 #if DEB         
189         if (Abs(Diff) > DeltaG) {
190           cout << "Trihedron Plan Diff on Guide : " << 
191             Diff << endl;
192         }
193 #endif
194       }
195       
196       gp_Pnt2d p1(t, w); // on stocke les parametres
197       Pole->SetValue(1, ii, p1);
198       
199     }// for_ii
200 }
201
202 //=======================================================================
203 //function : SetCurve
204 //purpose  : calculation of trihedron
205 //=======================================================================
206 void GeomFill_GuideTrihedronPlan::SetCurve(const Handle(Adaptor3d_HCurve)& C)
207 {
208   myCurve = C;
209   if (!myCurve.IsNull()) Init();
210 }
211
212 //=======================================================================
213 //function : Guide
214 //purpose  : calculation of trihedron
215 //=======================================================================
216
217  Handle(Adaptor3d_HCurve) GeomFill_GuideTrihedronPlan::Guide()const
218 {
219   return myGuide;
220 }
221
222 //=======================================================================
223 //function : D0
224 //purpose  : calculation of trihedron
225 //=======================================================================
226  Standard_Boolean GeomFill_GuideTrihedronPlan::D0(const Standard_Real Param,
227                                                   gp_Vec& Tangent,
228                                                   gp_Vec& Normal,
229                                                   gp_Vec& BiNormal) 
230
231   gp_Pnt P, Pprime;
232 //  gp_Vec To;
233
234   myCurve->D0(Param, P); 
235
236   frenet->D0(Param,Tangent,Normal,BiNormal);
237   
238   //initialisation de la recherche
239   InitX(Param);
240       
241   Standard_Integer Iter = 50;
242   
243   // fonction dont il faut trouver la racine : G(W)-Pl(U,V)=0
244   GeomFill_PlanFunc E(P, Tangent, myGuide);
245   
246   // resolution
247   math_FunctionRoot Result(E, X(1), XTol(1), 
248                            Inf(1), Sup(1), Iter); 
249   
250   if (Result.IsDone()) 
251     {
252       Standard_Real Res = Result.Root();
253 //      R = Result.Root();    // solution    
254    
255       Pprime = myTrimG->Value(Res); // pt sur courbe guide 
256       gp_Vec n (P, Pprime); // vecteur definissant la normale du triedre 
257             
258       Normal = n.Normalized();
259       BiNormal = Tangent.Crossed(Normal);
260       BiNormal.Normalized();   
261     }
262   else { // Erreur...
263 #if DEB
264     cout << "D0 :";
265     // plan ortho a la trajectoire pour determiner Pprime
266     Handle(Geom_Plane) Plan = new (Geom_Plane)(P, Tangent);
267     TracePlan(Plan);
268 #endif
269     myStatus = GeomFill_PlaneNotIntersectGuide;
270     return Standard_False;
271   }
272   
273   return Standard_True;
274 }
275
276 //=======================================================================
277 //function : D1
278 //purpose  : calculation of trihedron and first derivative
279 //=======================================================================
280  Standard_Boolean GeomFill_GuideTrihedronPlan::D1(const Standard_Real Param,
281                                                   gp_Vec& Tangent,
282                                                   gp_Vec& DTangent,
283                                                   gp_Vec& Normal,
284                                                   gp_Vec& DNormal,
285                                                   gp_Vec& BiNormal,        
286                                                   gp_Vec& DBiNormal) 
287
288 //  return Standard_False;
289   gp_Pnt P, PG;
290   gp_Vec To,TG;
291
292
293   
294   // triedre de frenet sur la trajectoire
295   myCurve->D1(Param, P, To);
296   frenet->D1(Param,Tangent,DTangent,Normal,DNormal,BiNormal,DBiNormal);
297
298  
299   // tolerance sur E
300   Standard_Integer Iter = 50;
301
302   // fonction dont il faut trouver la racine : G(W)-Pl(U,V)=0
303   InitX(Param);
304   GeomFill_PlanFunc E(P, Tangent, myGuide);
305
306   // resolution
307   math_FunctionRoot Result(E, X(1), XTol(1), 
308                            Inf(1), Sup(1), Iter);
309
310   if (Result.IsDone()) 
311     {
312       Standard_Real Res =  Result.Root();
313 //      R = Result.Root();    // solution  
314       myTrimG->D1(Res, PG, TG);
315       gp_Vec n (P, PG), dn; // vecteur definissant la normale du triedre
316       Standard_Real Norm = n.Magnitude();
317       if (Norm < 1.e-12) {
318         Norm = 1.0;
319       }
320       n /=Norm;
321
322       
323       Normal = n; 
324       BiNormal = Tangent.Crossed(Normal);
325
326 // derivee premiere du triedre
327       Standard_Real dedx, dedt, dtg_dt;
328       E.Derivative(Res, dedx);
329       E.DEDT(Res, To, DTangent, dedt);
330       dtg_dt = -dedt/dedx;
331
332
333 /*      Standard_Real h=1.e-7, e, etg, etc;
334       E.Value(Res, e);
335       E.Value(Res+h, etg);
336       if ( Abs( (etg-e)/h - dedx) > 1.e-4) {
337         cout << "err :" <<  (etg-e)/h - dedx << endl;
338       }
339       gp_Pnt pdbg;
340       gp_Vec td, nb, bnb;
341       myCurve->D0(Param+h, pdbg);      
342       frenet->D0(Param+h,td, nb, bnb);
343
344       GeomFill_PlanFunc Edeb(pdbg, td, myGuide); 
345       Edeb.Value(Res, etc);
346       if ( Abs( (etc-e)/h - dedt) > 1.e-4) {
347         cout << "err :" <<  (etc-e)/h - dedt << endl;
348       } */           
349
350       dn.SetLinearForm(dtg_dt, TG, -1, To);
351       
352       DNormal.SetLinearForm(-(n*dn), n, dn);
353       DNormal /= Norm;
354       DBiNormal.SetLinearForm(Tangent.Crossed(DNormal),
355                               DTangent.Crossed(Normal));
356     }
357   else {// Erreur...
358 #if DEB
359     cout << "D1 :";
360     // plan ortho a la trajectoire
361     Handle(Geom_Plane) Plan = new (Geom_Plane)(P, Tangent);
362     TracePlan(Plan);
363 #endif
364     myStatus = GeomFill_PlaneNotIntersectGuide;
365     return Standard_False;
366   }
367  
368   return Standard_True; 
369 }
370
371
372 //=======================================================================
373 //function : D2
374 //purpose  : calculation of trihedron and derivatives
375 //=======================================================================
376  Standard_Boolean GeomFill_GuideTrihedronPlan::D2(const Standard_Real Param,
377                                                   gp_Vec& Tangent,
378                                                   gp_Vec& DTangent,
379                                                   gp_Vec& D2Tangent,
380                                                   gp_Vec& Normal,
381                                                   gp_Vec& DNormal,
382                                                   gp_Vec& D2Normal,
383                                                   gp_Vec& BiNormal,                       
384                                                   gp_Vec& DBiNormal,              
385                                                   gp_Vec& D2BiNormal) 
386
387 //  gp_Pnt P, PG;
388   gp_Pnt P;
389 //  gp_Vec To,DTo,TG,DTG;
390   gp_Vec To,DTo;
391
392   myCurve->D2(Param, P, To, DTo); 
393
394   // triedre de Frenet sur la trajectoire
395   frenet->D2(Param,Tangent,DTangent,D2Tangent,
396              Normal,DNormal,D2Normal,
397              BiNormal,DBiNormal,D2BiNormal);
398
399 /*
400   // plan ortho a Tangent pour trouver la pt Pprime sur le guide
401   Handle(Geom_Plane) Plan = new (Geom_Plane)(P, Tangent); 
402   Handle(GeomAdaptor_HSurface) Pl= new(GeomAdaptor_HSurface)(Plan);
403   
404
405   Standard_Integer Iter = 50;
406   // fonction dont il faut trouver la racine : G(W) - Pl(U,V)=0
407   GeomFill_FunctionPipe E(Pl , myGuide);
408   InitX(Param);
409   
410   // resolution
411   math_FunctionSetRoot Result(E, X, XTol, 
412                                     Inf, Sup, Iter); 
413   if (Result.IsDone()) 
414     {
415       math_Vector R(1,3); 
416       R = Result.Root();    // solution 
417       myTrimG->D2(R(1), PG, TG, DTG); 
418
419       gp_Vec n (P, PG); // vecteur definissant la normale du triedre
420       Standard_Real Norm = n.Magnitude();
421       n /= Norm;      
422       Normal = n.Normalized(); 
423       BiNormal = Tangent.Crossed(Normal);
424
425  
426
427    // derivee premiere du triedre 
428       Standard_Real dtp_dt;
429       dtp_dt = (To*Tangent - Norm*(n*DTangent))/(Tangent*TG);
430       gp_Vec dn, d2n;
431       dn.SetLinearForm(dtp_dt, TG, -1,  To);
432       
433       DNormal.SetLinearForm(-(n*dn), n, dn);
434       DNormal /= Norm;  
435       DBiNormal = Tangent.Crossed(DNormal) + DTangent.Crossed(Normal);
436   
437     // derivee seconde du triedre
438       Standard_Real d2tp_dt2;
439       d2tp_dt2 = (DTo*Tangent+To*DTangent - dn*DTangent-Norm*n*D2Tangent)/(TG*Tangent)
440         - (To*Tangent-Norm*n*DTangent) * (DTG*dtp_dt*Tangent+TG*DTangent)
441           / ((TG*Tangent)*(TG*Tangent));
442
443
444       d2n.SetLinearForm(dtp_dt*dtp_dt, DTG, d2tp_dt2, TG, -DTo);
445       dn/=Norm;
446       d2n/=Norm;
447
448       D2Normal.SetLinearForm(3*Pow(n*dn,2)- (dn.SquareMagnitude() + n*d2n), n,
449                              -2*(n*dn), dn,
450                              d2n);
451  
452       D2BiNormal.SetLinearForm(1, D2Tangent.Crossed(Normal),
453                                2, DTangent.Crossed(DNormal), 
454                                Tangent.Crossed(D2Normal));
455     }
456   else {// Erreur...
457 #if DEB
458     cout << "D2 :";
459     TracePlan(Plan);
460 #endif
461     myStatus = GeomFill_PlaneNotIntersectGuide;
462     return Standard_False;
463    }
464 */
465 //  return Standard_True;
466  return Standard_False;
467 }
468
469
470 //=======================================================================
471 //function : Copy
472 //purpose  : 
473 //=======================================================================
474  Handle(GeomFill_TrihedronLaw) GeomFill_GuideTrihedronPlan::Copy() const
475 {
476  Handle(GeomFill_GuideTrihedronPlan) copy = 
477    new (GeomFill_GuideTrihedronPlan) (myGuide);
478  copy->SetCurve(myCurve);
479  return copy;
480 }
481
482 //=======================================================================
483 //function : ErrorStatus
484 //purpose  : 
485 //=======================================================================
486  GeomFill_PipeError GeomFill_GuideTrihedronPlan::ErrorStatus() const
487 {
488   return myStatus;
489 }
490  
491
492 //=======================================================================
493 //function : NbIntervals
494 //purpose  : Version provisoire : Il faut tenir compte du guide
495 //=======================================================================
496  Standard_Integer GeomFill_GuideTrihedronPlan::NbIntervals(const GeomAbs_Shape S)const
497 {
498   Standard_Integer Nb;
499   GeomAbs_Shape tmpS;
500   switch (S) {
501   case GeomAbs_C0: tmpS = GeomAbs_C1; break;
502   case GeomAbs_C1: tmpS = GeomAbs_C2; break;
503   case GeomAbs_C2: tmpS = GeomAbs_C3; break;
504   default: tmpS = GeomAbs_CN;
505   }  
506
507   Nb = myCurve->NbIntervals(tmpS);
508   return Nb;
509 }
510 //======================================================================
511 //function :Intervals
512 //purpose  : 
513 //=======================================================================
514  void GeomFill_GuideTrihedronPlan::Intervals(TColStd_Array1OfReal& TT,
515                                             const GeomAbs_Shape S) const
516 {
517   GeomAbs_Shape tmpS;
518   switch (S) {
519   case GeomAbs_C0: tmpS = GeomAbs_C1; break;
520   case GeomAbs_C1: tmpS = GeomAbs_C2; break;
521   case GeomAbs_C2: tmpS = GeomAbs_C3; break;
522   default: tmpS = GeomAbs_CN;
523   }
524   myCurve->Intervals(TT, tmpS);
525 }
526
527 //======================================================================
528 //function :SetInterval
529 //purpose  : 
530 //=======================================================================
531 void GeomFill_GuideTrihedronPlan::SetInterval(const Standard_Real First,
532                                               const Standard_Real Last) 
533 {
534   myTrimmed = myCurve->Trim(First, Last, Precision::Confusion());  
535 }
536
537
538 //=======================================================================
539 //function : GetAverageLaw
540 //purpose  : 
541 //=======================================================================
542  void GeomFill_GuideTrihedronPlan::GetAverageLaw(gp_Vec& ATangent,
543                                     gp_Vec& ANormal,
544                                     gp_Vec& ABiNormal) 
545 {
546   Standard_Integer ii;
547   Standard_Real t, Delta = (myCurve->LastParameter() - 
548                             myCurve->FirstParameter())/20.001;
549
550   ATangent.SetCoord(0.,0.,0.);
551   ANormal.SetCoord(0.,0.,0.);
552   ABiNormal.SetCoord(0.,0.,0.);
553   gp_Vec T, N, B;
554   
555   for (ii=1; ii<=20; ii++) {
556     t = myCurve->FirstParameter() +(ii-1)*Delta;
557     D0(t, T, N, B);
558     ATangent +=T;
559     ANormal  +=N;
560     ABiNormal+=B;
561   }
562   ATangent  /= 20;
563   ANormal   /= 20;
564   ABiNormal /= 20; 
565 }
566
567 //=======================================================================
568 //function : IsConstant
569 //purpose  : 
570 //=======================================================================
571  Standard_Boolean GeomFill_GuideTrihedronPlan::IsConstant() const
572 {
573   if ((myCurve->GetType() == GeomAbs_Line) &&
574       (myGuide->GetType() == GeomAbs_Line)) {
575     Standard_Real Angle;
576     Angle = myCurve->Line().Angle(myGuide->Line());
577     if ((Angle<1.e-12) || ((2*M_PI-Angle)<1.e-12) )
578       return Standard_True;
579   }
580
581   return Standard_False;
582 }
583
584 //=======================================================================
585 //function : IsOnlyBy3dCurve
586 //purpose  : 
587 //=======================================================================
588  Standard_Boolean GeomFill_GuideTrihedronPlan::IsOnlyBy3dCurve() const
589 {
590   return Standard_False;
591 }
592
593 //=======================================================================
594 //function : Origine
595 //purpose  : Nothing!!
596 //=======================================================================
597 void  GeomFill_GuideTrihedronPlan::Origine(const Standard_Real ,
598                                            const Standard_Real  )
599 {
600 }
601
602 //==================================================================
603 //Function : InitX
604 //Purpose : recherche par interpolation d'une valeur initiale
605 //==================================================================
606 void GeomFill_GuideTrihedronPlan::InitX(const Standard_Real Param)
607 {
608
609   Standard_Integer Ideb = 1, Ifin =  Pole->RowLength(), Idemi;
610   Standard_Real Valeur, t1, t2;
611
612   
613   Valeur = Pole->Value(1, Ideb).X();
614   if (Param == Valeur) {
615     Ifin = Ideb+1; 
616   }
617   
618   Valeur =  Pole->Value(1, Ifin).X();
619   if (Param == Valeur) {
620     Ideb = Ifin-1; 
621   } 
622   
623   while ( Ideb+1 != Ifin) {
624     Idemi = (Ideb+Ifin)/2;
625     Valeur = Pole->Value(1, Idemi).X();
626     if (Valeur < Param) {
627       Ideb = Idemi;
628     }
629     else { 
630       if ( Valeur > Param) { Ifin = Idemi;}
631       else { 
632         Ideb = Idemi;                
633         Ifin = Ideb+1;
634       }
635     }
636   }
637
638   t1 = Pole->Value(1,Ideb).X();
639   t2 = Pole->Value(1,Ifin).X();
640   Standard_Real diff = t2-t1;
641   if (diff > 1.e-7) {
642     Standard_Real b = (Param-t1) / diff,
643     a = (t2-Param) / diff;
644
645     X(1) = Pole->Value(1,Ideb).Coord(2) * a 
646       + Pole->Value(1,Ifin).Coord(2) * b; //param guide 
647   }
648   else {
649     X(1) = (Pole->Value(1, Ideb).Coord(2) + 
650             Pole->Value(1, Ifin).Coord(2)) / 2;
651   }
652   if (myGuide->IsPeriodic()) {
653     X(1) = ElCLib::InPeriod(X(1), myGuide->FirstParameter(), 
654                                   myGuide->LastParameter());
655   }
656 }