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