b311480e |
1 | // Created on: 1998-03-03 |
2 | // Created by: Roman BORISOV |
3 | // Copyright (c) 1998-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
7fd59977 |
17 | |
42cf5bc1 |
18 | #include <Adaptor3d_HCurve.hxx> |
19 | #include <GeomFill_ConstantBiNormal.hxx> |
20 | #include <GeomFill_Frenet.hxx> |
21 | #include <GeomFill_TrihedronLaw.hxx> |
7fd59977 |
22 | #include <gp_Ax1.hxx> |
42cf5bc1 |
23 | #include <gp_Dir.hxx> |
7fd59977 |
24 | #include <gp_Lin.hxx> |
42cf5bc1 |
25 | #include <gp_Vec.hxx> |
7fd59977 |
26 | #include <Precision.hxx> |
42cf5bc1 |
27 | #include <Standard_ConstructionError.hxx> |
28 | #include <Standard_OutOfRange.hxx> |
29 | #include <Standard_Type.hxx> |
7fd59977 |
30 | |
92efcf78 |
31 | IMPLEMENT_STANDARD_RTTIEXT(GeomFill_ConstantBiNormal,GeomFill_TrihedronLaw) |
32 | |
7fd59977 |
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; |
04232180 |
132 | std::cout<<"DTangent = ("<<DTangent.X()<<", "<<DTangent.Y()<<", "<<DTangent.Z()<<")"<<std::endl; |
133 | std::cout<<"CTangent = ("<<cTangent.X()<<", "<<cTangent.Y()<<", "<<cTangent.Z()<<")"<<std::endl; |
134 | std::cout<<"DNormal = ("<<DNormal.X()<<", "<<DNormal.Y()<<", "<<DNormal.Z()<<")"<<std::endl; |
135 | std::cout<<"CNormal = ("<<cNormal.X()<<", "<<cNormal.Y()<<", "<<cNormal.Z()<<")"<<std::endl; |
136 | std::cout<<"DBiNormal = ("<<DBiNormal.X()<<", "<<DBiNormal.Y()<<", "<<DBiNormal.Z()<<")"<<std::endl; |
137 | std::cout<<"CBiNormal = ("<<cBiNormal.X()<<", "<<cBiNormal.Y()<<", "<<cBiNormal.Z()<<")"<<std::endl; |
7fd59977 |
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 | } |
04232180 |
184 | /* std::cout<<"Param = "<<Param<<std::endl; |
185 | std::cout<<"Tangent = ("<<Tangent.X()<<", "<<Tangent.Y()<<", "<<Tangent.Z()<<")"<<std::endl; |
186 | std::cout<<"DTangent = ("<<DTangent.X()<<", "<<DTangent.Y()<<", "<<DTangent.Z()<<")"<<std::endl; |
187 | std::cout<<"D2Tangent = ("<<D2Tangent.X()<<", "<<D2Tangent.Y()<<", "<<D2Tangent.Z()<<")"<<std::endl; |
188 | |
189 | std::cout<<"BiNormal = ("<<BiNormal.X()<<", "<<BiNormal.Y()<<", "<<BiNormal.Z()<<")"<<std::endl; |
190 | std::cout<<"DBiNormal = ("<<DBiNormal.X()<<", "<<DBiNormal.Y()<<", "<<DBiNormal.Z()<<")"<<std::endl; |
191 | std::cout<<"D2BiNormal = ("<<D2BiNormal.X()<<", "<<D2BiNormal.Y()<<", "<<D2BiNormal.Z()<<")"<<std::endl; |
7fd59977 |
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 | } |