0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / GeomFill / GeomFill_ConstantBiNormal.cxx
CommitLineData
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 31IMPLEMENT_STANDARD_RTTIEXT(GeomFill_ConstantBiNormal,GeomFill_TrihedronLaw)
32
7fd59977 33//=======================================================================
34//function : FDeriv
35//purpose : computes (F/|F|)'
36//=======================================================================
37static 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//=======================================================================
48static 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
57GeomFill_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}