Integration of OCCT 6.5.0 from SVN
[occt.git] / src / GeomFill / GeomFill_ConstantBiNormal.cxx
1 // File:        GeomFill_ConstantNormal.cxx
2 // Created:     Tue Mar  3 09:32:04 1998
3 // Author:      Roman BORISOV
4 //              <rbv@ecolox.nnov.matra-dtv.fr>
5
6
7 #include <GeomFill_ConstantBiNormal.ixx>
8
9 #include <gp_Ax1.hxx>
10 #include <gp_Lin.hxx>
11
12 #include <Precision.hxx>
13
14 //=======================================================================
15 //function : FDeriv
16 //purpose  : computes (F/|F|)'
17 //=======================================================================
18 static gp_Vec FDeriv(const gp_Vec& F, const gp_Vec& DF)
19 {
20   Standard_Real Norma = F.Magnitude();
21   gp_Vec Result = (DF - F*(F*DF)/(Norma*Norma))/Norma;
22   return Result;
23 }
24
25 //=======================================================================
26 //function : DDeriv
27 //purpose  : computes (F/|F|)''
28 //=======================================================================
29 static gp_Vec DDeriv(const gp_Vec& F, const gp_Vec& DF, const gp_Vec& D2F)
30 {
31   Standard_Real Norma = F.Magnitude();
32   gp_Vec Result = (D2F - 2*DF*(F*DF)/(Norma*Norma))/Norma - 
33      F*((DF.SquareMagnitude() + F*D2F 
34         - 3*(F*DF)*(F*DF)/(Norma*Norma))/(Norma*Norma*Norma));
35   return Result;
36 }
37
38 GeomFill_ConstantBiNormal::GeomFill_ConstantBiNormal(const gp_Dir& BiNormal) : BN(BiNormal)
39 {
40   frenet = new GeomFill_Frenet();
41 }
42
43  Handle(GeomFill_TrihedronLaw) GeomFill_ConstantBiNormal::Copy() const
44 {
45   Handle(GeomFill_TrihedronLaw) copy = new GeomFill_ConstantBiNormal(gp_Dir(BN));
46   if (!myCurve.IsNull()) copy->SetCurve(myCurve);
47   return copy;
48 }
49
50  void GeomFill_ConstantBiNormal::SetCurve(const Handle(Adaptor3d_HCurve)& C) 
51 {
52   GeomFill_TrihedronLaw::SetCurve(C);
53     if (! C.IsNull()) { 
54     frenet->SetCurve(C);
55   }
56 }
57
58  Standard_Boolean GeomFill_ConstantBiNormal::D0(const Standard_Real Param,gp_Vec& Tangent,gp_Vec& Normal,gp_Vec& BiNormal) 
59 {
60 // if BN^T != 0 then N = (BN^T).Normalized ; T = N^BN  
61 // else T = (N^BN).Normalized ; N = BN^T
62
63   frenet->D0(Param, Tangent, Normal, BiNormal);
64   BiNormal = BN;
65   if(BiNormal.Crossed(Tangent).Magnitude() > Precision::Confusion()) {
66     Normal = BiNormal.Crossed(Tangent).Normalized();    
67     Tangent = Normal.Crossed(BiNormal);
68   }
69   else {
70     Tangent = Normal.Crossed(BiNormal).Normalized(); 
71     Normal = BiNormal.Crossed(Tangent);
72   }
73 /*for Test
74   gp_Vec DTangent, D2Tangent, DNormal, D2Normal, DBiNormal, D2BiNormal;
75   D2(Param, Tangent, DTangent, D2Tangent, 
76      Normal, DNormal, D2Normal, BiNormal, DBiNormal, D2BiNormal);
77 */
78   return Standard_True;
79 }
80
81  Standard_Boolean GeomFill_ConstantBiNormal::D1(const Standard_Real Param,gp_Vec& Tangent,gp_Vec& DTangent,gp_Vec& Normal,gp_Vec& DNormal,gp_Vec& BiNormal,gp_Vec& DBiNormal) 
82 {
83   gp_Vec F, DF;
84   frenet->D1(Param, Tangent, DTangent, Normal, DNormal, BiNormal, DBiNormal);
85   BiNormal = BN;
86   DBiNormal = gp_Vec(0, 0, 0);
87   if(BiNormal.Crossed(Tangent).Magnitude() > Precision::Confusion()) {
88     F = BiNormal.Crossed(Tangent);
89     DF = BiNormal.Crossed(DTangent);
90     Normal = F.Normalized();    
91     DNormal = FDeriv(F, DF);
92     
93     Tangent = Normal.Crossed(BiNormal);
94     DTangent = DNormal.Crossed(BiNormal);
95   }
96   else {
97     F = Normal.Crossed(BiNormal);
98     DF = DNormal.Crossed(BiNormal);
99     Tangent = F.Normalized();
100     DTangent = FDeriv(F, DF);
101
102     Normal = BiNormal.Crossed(Tangent);
103     DNormal = BiNormal.Crossed(DTangent);
104   }
105 /*test
106   Standard_Real h = 1.e-10;
107   gp_Vec cTangent, cNormal, cBiNormal, Tangent_, Normal_, BiNormal_;
108   D0(Param, cTangent, cNormal, cBiNormal);
109   D0(Param + h, Tangent_, Normal_, BiNormal_);
110   cTangent = (Tangent_ - cTangent)/h;
111   cNormal = (Normal_ - cNormal)/h;
112   cBiNormal = (BiNormal_ - cBiNormal)/h;
113   cout<<"DTangent = ("<<DTangent.X()<<", "<<DTangent.Y()<<", "<<DTangent.Z()<<")"<<endl;
114   cout<<"CTangent = ("<<cTangent.X()<<", "<<cTangent.Y()<<", "<<cTangent.Z()<<")"<<endl;
115   cout<<"DNormal = ("<<DNormal.X()<<", "<<DNormal.Y()<<", "<<DNormal.Z()<<")"<<endl;
116   cout<<"CNormal = ("<<cNormal.X()<<", "<<cNormal.Y()<<", "<<cNormal.Z()<<")"<<endl;
117   cout<<"DBiNormal = ("<<DBiNormal.X()<<", "<<DBiNormal.Y()<<", "<<DBiNormal.Z()<<")"<<endl;
118   cout<<"CBiNormal = ("<<cBiNormal.X()<<", "<<cBiNormal.Y()<<", "<<cBiNormal.Z()<<")"<<endl;
119 */
120   return Standard_True;
121 }
122
123  Standard_Boolean GeomFill_ConstantBiNormal::D2(const Standard_Real Param,
124                                                 gp_Vec& Tangent,
125                                                 gp_Vec& DTangent,
126                                                 gp_Vec& D2Tangent,
127                                                 gp_Vec& Normal,
128                                                 gp_Vec& DNormal,
129                                                 gp_Vec& D2Normal,
130                                                 gp_Vec& BiNormal,
131                                                 gp_Vec& DBiNormal,
132                                                 gp_Vec& D2BiNormal)
133 {
134   gp_Vec F, DF, D2F;
135   frenet->D2(Param, Tangent, DTangent, D2Tangent,
136              Normal, DNormal, D2Normal, 
137              BiNormal, DBiNormal, D2BiNormal);
138   BiNormal = BN;
139   DBiNormal = gp_Vec(0, 0, 0);
140   D2BiNormal = gp_Vec(0, 0, 0);
141   if(BiNormal.Crossed(Tangent).Magnitude() > Precision::Confusion()) {
142     F = BiNormal.Crossed(Tangent);
143     DF = BiNormal.Crossed(DTangent);
144     D2F = BiNormal.Crossed(D2Tangent);
145     Normal = F.Normalized();    
146     DNormal = FDeriv(F, DF);
147     D2Normal = DDeriv(F, DF, D2F);
148
149     Tangent = Normal.Crossed(BiNormal);
150     DTangent = DNormal.Crossed(BiNormal);
151     D2Tangent = D2Normal.Crossed(BiNormal);
152   }
153   else {
154     F = Normal.Crossed(BiNormal);
155     DF = DNormal.Crossed(BiNormal);
156     D2F = D2Normal.Crossed(BiNormal);
157     Tangent = F.Normalized();
158     DTangent = FDeriv(F, DF);
159     D2Tangent = DDeriv(F, DF, D2F);
160
161     Normal = BiNormal.Crossed(Tangent);
162     DNormal = BiNormal.Crossed(DTangent);
163     D2Normal = BiNormal.Crossed(D2Tangent);
164   }
165 /*  cout<<"Param = "<<Param<<endl;
166   cout<<"Tangent = ("<<Tangent.X()<<", "<<Tangent.Y()<<", "<<Tangent.Z()<<")"<<endl;
167   cout<<"DTangent = ("<<DTangent.X()<<", "<<DTangent.Y()<<", "<<DTangent.Z()<<")"<<endl;
168   cout<<"D2Tangent = ("<<D2Tangent.X()<<", "<<D2Tangent.Y()<<", "<<D2Tangent.Z()<<")"<<endl;
169
170   cout<<"BiNormal = ("<<BiNormal.X()<<", "<<BiNormal.Y()<<", "<<BiNormal.Z()<<")"<<endl;
171   cout<<"DBiNormal = ("<<DBiNormal.X()<<", "<<DBiNormal.Y()<<", "<<DBiNormal.Z()<<")"<<endl;
172   cout<<"D2BiNormal = ("<<D2BiNormal.X()<<", "<<D2BiNormal.Y()<<", "<<D2BiNormal.Z()<<")"<<endl;
173 */  
174   return Standard_True;
175 }
176
177  Standard_Integer GeomFill_ConstantBiNormal::NbIntervals(const GeomAbs_Shape S) const
178 {
179   return frenet->NbIntervals(S);
180 }
181
182  void GeomFill_ConstantBiNormal::Intervals(TColStd_Array1OfReal& T,const GeomAbs_Shape S) const
183 {
184   frenet->Intervals(T, S);
185 }
186
187  void GeomFill_ConstantBiNormal::GetAverageLaw(gp_Vec& ATangent,gp_Vec& ANormal,gp_Vec& ABiNormal) 
188 {
189   frenet->GetAverageLaw(ATangent, ANormal, ABiNormal);
190   ABiNormal = BN;
191   if(ABiNormal.Crossed(ATangent).Magnitude() > Precision::Confusion()) {
192     ANormal = ABiNormal.Crossed(ATangent).Normalized();    
193     ATangent = ANormal.Crossed(ABiNormal);
194   }
195   else {
196     ATangent = ANormal.Crossed(ABiNormal).Normalized(); 
197     ANormal = ABiNormal.Crossed(ATangent);
198   }
199 }
200
201  Standard_Boolean GeomFill_ConstantBiNormal::IsConstant() const
202 {
203   return frenet->IsConstant();
204 }
205
206  Standard_Boolean GeomFill_ConstantBiNormal::IsOnlyBy3dCurve() const
207 {
208   GeomAbs_CurveType TheType = myCurve->GetType();
209   gp_Ax1 TheAxe;
210
211   switch  (TheType) {
212   case GeomAbs_Circle:
213     {
214       TheAxe =  myCurve->Circle().Axis();
215       break;
216     }
217   case GeomAbs_Ellipse:
218     {
219       TheAxe =  myCurve->Ellipse().Axis();
220       break;
221     }
222   case GeomAbs_Hyperbola:
223     {
224       TheAxe =  myCurve->Hyperbola().Axis();
225       break;
226     }
227   case GeomAbs_Parabola:
228     {
229       TheAxe =  myCurve->Parabola().Axis();
230       break;
231     }
232   case GeomAbs_Line:
233     { //La normale du plan de la courbe est il perpendiculaire a la BiNormale ?
234      gp_Vec V;
235      V.SetXYZ(myCurve->Line().Direction().XYZ());
236      return V.IsNormal(BN, Precision::Angular());
237     }
238   default:
239     return Standard_False; // pas de risques
240   }
241
242   // La normale du plan de la courbe est il // a la BiNormale ?
243   gp_Vec V;
244   V.SetXYZ(TheAxe.Direction().XYZ());
245   return V.IsParallel(BN, Precision::Angular());
246 }