973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
b311480e |
13 | |
42cf5bc1 |
14 | |
7fd59977 |
15 | #include <Bnd_Box.hxx> |
16 | #include <BRepBndLib.hxx> |
42cf5bc1 |
17 | #include <gp_Ax3.hxx> |
18 | #include <gp_Dir.hxx> |
19 | #include <gp_Pnt.hxx> |
20 | #include <gp_Trsf.hxx> |
21 | #include <gp_Vec.hxx> |
22 | #include <HLRAlgo_Projector.hxx> |
23 | #include <Precision.hxx> |
24 | #include <Standard_Type.hxx> |
7fd59977 |
25 | #include <TColgp_Array1OfPnt.hxx> |
26 | #include <TColgp_Array1OfVec.hxx> |
42cf5bc1 |
27 | #include <Vrml_Instancing.hxx> |
7fd59977 |
28 | #include <Vrml_MatrixTransform.hxx> |
42cf5bc1 |
29 | #include <Vrml_SFRotation.hxx> |
7fd59977 |
30 | #include <Vrml_TransformSeparator.hxx> |
42cf5bc1 |
31 | #include <VrmlConverter_Projector.hxx> |
7fd59977 |
32 | |
92efcf78 |
33 | IMPLEMENT_STANDARD_RTTIEXT(VrmlConverter_Projector,MMgt_TShared) |
34 | |
7fd59977 |
35 | VrmlConverter_Projector::VrmlConverter_Projector (const TopTools_Array1OfShape& Shapes, |
36 | const Quantity_Length Focus, |
37 | const Quantity_Length DX, |
38 | const Quantity_Length DY, |
39 | const Quantity_Length DZ, |
40 | const Quantity_Length XUp, |
41 | const Quantity_Length YUp, |
42 | const Quantity_Length ZUp, |
43 | const VrmlConverter_TypeOfCamera Camera, |
44 | const VrmlConverter_TypeOfLight Light) |
45 | |
46 | { |
47 | |
48 | myTypeOfCamera = Camera; |
49 | myTypeOfLight = Light; |
50 | |
51 | Standard_Integer i; |
52 | Bnd_Box box; |
53 | Standard_Real Xmin, Xmax, Ymin, Ymax, Zmin, Zmax, diagonal; |
54 | Standard_Real Xtarget, Ytarget, Ztarget, Angle, MaxAngle, Height, MaxHeight; |
55 | |
56 | for ( i=Shapes.Lower(); i <= Shapes.Upper(); i++) |
57 | { |
58 | BRepBndLib::AddClose(Shapes.Value(i), box); |
59 | } |
60 | |
61 | Standard_Real DistMax = 500000; |
62 | Standard_Real TolMin = 0.000001; |
63 | |
64 | box.Enlarge(TolMin); |
65 | box.Get( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax ); |
66 | |
67 | if (box.IsOpenXmin()) Xmin = -DistMax; |
68 | if (box.IsOpenXmax()) Xmax = DistMax; |
69 | if (box.IsOpenYmin()) Ymin = -DistMax; |
70 | if (box.IsOpenYmax()) Ymax = DistMax; |
71 | if (box.IsOpenZmin()) Zmin = -DistMax; |
72 | if (box.IsOpenZmax()) Zmax = DistMax; |
73 | |
74 | Standard_Real xx = (Xmax - Xmin); |
75 | Standard_Real yy = (Ymax - Ymin); |
76 | Standard_Real zz = (Zmax - Zmin); |
77 | |
78 | Xtarget = (Xmin + Xmax)/2; |
79 | Ytarget = (Ymin + Ymax)/2; |
80 | Ztarget = (Zmin + Zmax)/2; |
81 | |
82 | // cout << " target: " << endl; |
83 | // cout << " X: " << Xtarget << " Y: " << Ytarget << " Z: " << Ztarget << endl; |
84 | |
85 | // gp_Pnt Target(Xtarget, Ytarget, Ztarget); |
86 | // gp_Vec VTarget(Target.X(),Target.Y(),Target.Z()); |
87 | |
88 | gp_Dir Zpers (DX,DY,DZ); |
89 | gp_Vec V(Zpers); |
90 | |
91 | diagonal = Sqrt (xx*xx + yy*yy + zz*zz); |
92 | |
93 | gp_Vec aVec = V.Multiplied(0.5*diagonal+TolMin+Focus); |
94 | |
95 | gp_Pnt Source; |
96 | Source.SetX(Xtarget+aVec.X()); |
97 | Source.SetY(Ytarget+aVec.Y()); |
98 | Source.SetZ(Ztarget+aVec.Z()); |
99 | |
100 | // cout << " source: " << endl; |
101 | // cout << " X: " << Source.X() << " Y: " << Source.Y() << " Z: " << Source.Z() << endl; |
102 | |
103 | gp_Vec VSource(Source.X(),Source.Y(),Source.Z()); |
104 | |
105 | // gp_Vec Proj(Source,Target); |
106 | // cout << " Vec(source-target): " << endl; |
107 | // cout << " X: " << Proj.X() << " Y: " << Proj.Y() << " Z: " << Proj.Z() << endl; |
108 | |
109 | gp_Dir Ypers (XUp,YUp,ZUp); |
110 | |
111 | if( Ypers.IsParallel(Zpers,Precision::Angular()) ) |
112 | { |
9775fa61 |
113 | throw Standard_Failure("Projection Vector is Parallel to High Point Direction"); |
7fd59977 |
114 | } |
115 | gp_Dir Xpers = Ypers.Crossed(Zpers); |
116 | |
117 | // cout << " Dir(Zpers): " << endl; |
118 | // cout << " X: " << Zpers.X() << " Y: " << Zpers.Y() << " Z: " << Zpers.Z() << endl; |
119 | // cout << " Dir(Xpers): " << endl; |
120 | // cout << " X: " << Xpers.X() << " Y: " << Xpers.Y() << " Z: " << Xpers.Z() << endl; |
121 | |
122 | gp_Ax3 Axe (Source, Zpers, Xpers); |
123 | |
124 | gp_Trsf T; |
125 | |
126 | // Makes the transformation allowing passage from the basic |
127 | // coordinate system |
128 | // {P(0.,0.,0.), VX (1.,0.,0.), VY (0.,1.,0.), VZ (0., 0. ,1.) } |
129 | // to the local coordinate system defined with the Ax3 ToSystem. |
130 | // Same utilisation as the previous method. FromSystem1 is |
131 | // defaulted to the absolute coordinate system. |
132 | T.SetTransformation(Axe); |
133 | |
134 | Standard_Boolean Pers = Standard_False; |
135 | if (Camera == VrmlConverter_PerspectiveCamera) Pers = Standard_True; |
136 | |
137 | //build a Projector with automatic minmax directions |
138 | myProjector = HLRAlgo_Projector(T,Pers,Focus); |
139 | |
140 | gp_Trsf T3; |
141 | T3 = T.Inverted(); |
142 | // T3.SetTranslationPart(gp_Vec (0,0,0)); |
143 | |
144 | myMatrixTransform.SetMatrix(T3); |
145 | |
146 | // For VRweb1.3 |
147 | // gp_Trsf T1 = T; |
148 | // T1.SetTranslationPart(gp_Vec (0,0,0)); |
149 | // myMatrixTransform.SetMatrix(T1); |
150 | |
151 | // |
152 | //== definitions cameras and lights |
153 | // |
154 | |
155 | if (Light == VrmlConverter_DirectionLight) |
156 | { |
157 | myDirectionalLight.SetDirection(Zpers.Reversed()); |
158 | } |
159 | |
160 | if (Light == VrmlConverter_PointLight) |
161 | { |
162 | myPointLight.SetLocation(VSource); |
163 | } |
164 | |
165 | if (Light == VrmlConverter_SpotLight || Camera != VrmlConverter_NoCamera ) |
166 | { |
167 | |
168 | /* |
169 | gp_Dir Zmain (0,0,1); |
170 | gp_Dir Xmain (1,0,0); |
171 | |
172 | |
173 | gp_Dir Dturn; |
174 | Standard_Real AngleTurn; |
175 | |
176 | if( Zmain.IsParallel(Zpers,Precision::Angular()) ) |
177 | { |
178 | if ( Zmain.IsOpposite(Zpers,Precision::Angular()) ) |
179 | { |
180 | Dturn = Zpers; |
181 | AngleTurn = - Xmain.Angle(Xpers); |
182 | } |
183 | Dturn = Zpers; |
184 | AngleTurn = Xmain.Angle(Xpers); |
185 | } |
186 | else |
187 | { |
188 | Dturn = Zmain.Crossed(Zpers); |
189 | AngleTurn = Zmain.Angle(Zpers); |
190 | } |
191 | */ |
192 | |
193 | gp_Pnt CurP; |
194 | TColgp_Array1OfPnt ArrP(1,8); |
195 | |
196 | CurP.SetCoord(Xmin, Ymin, Zmin); |
197 | ArrP.SetValue(1,CurP); |
198 | CurP.SetCoord(Xmin+xx, Ymin, Zmin); |
199 | ArrP.SetValue(2,CurP); |
200 | CurP.SetCoord(Xmin+xx, Ymin+yy, Zmin); |
201 | ArrP.SetValue(3,CurP); |
202 | CurP.SetCoord(Xmin, Ymin+yy, Zmin); |
203 | ArrP.SetValue(4,CurP); |
204 | |
205 | CurP.SetCoord(Xmin, Ymin, Zmax); |
206 | ArrP.SetValue(5,CurP); |
207 | CurP.SetCoord(Xmin+xx, Ymin, Zmax); |
208 | ArrP.SetValue(6,CurP); |
209 | CurP.SetCoord(Xmin+xx, Ymin+yy, Zmax); |
210 | ArrP.SetValue(7,CurP); |
211 | CurP.SetCoord(Xmin, Ymin+yy, Zmax); |
212 | ArrP.SetValue(8,CurP); |
213 | |
214 | // |
215 | gp_Vec V1, V2; |
216 | gp_Pnt P1, P2; |
217 | |
218 | MaxHeight = TolMin; |
219 | MaxAngle = TolMin; |
220 | |
221 | for ( i=ArrP.Lower(); i <= ArrP.Upper(); i++) |
222 | { |
223 | P1 = ArrP.Value(i); |
224 | P2 = P1.Transformed (T); |
225 | |
226 | V1.SetX(P2.X()); |
227 | V1.SetY(P2.Y()); |
228 | V1.SetZ(P2.Z()); |
229 | |
230 | V2.SetX(P2.X()); |
231 | V2.SetY(0); |
232 | V2.SetZ(P2.Z()); |
233 | |
234 | // cout << " Angle: " << V1.Angle(V2) << endl; |
235 | // cout << " ****************** " << endl; |
236 | if ( Abs(V1.Angle(V2)) > Abs(MaxAngle) ) MaxAngle = Abs(V1.Angle(V2)); |
237 | |
238 | V2.SetX(0); |
239 | V2.SetY(P2.Y()); |
240 | V2.SetZ(P2.Z()); |
241 | |
242 | // cout << " Angle: " << V1.Angle(V2) << endl; |
243 | // cout << " ****************** " << endl; |
244 | if ( Abs(V1.Angle(V2)) > Abs(MaxAngle) ) MaxAngle = Abs(V1.Angle(V2)); |
245 | |
246 | if ( Abs(P2.Y()) > Abs(MaxHeight) ) |
247 | { |
248 | // cout << " Height Y: " << P2.Y() << endl; |
249 | // cout << " ****************** " << endl; |
250 | MaxHeight = Abs(P2.Y()); |
251 | } |
252 | |
253 | if ( Abs(P2.X()) > Abs(MaxHeight) ) |
254 | { |
255 | // cout << " Height X: " << P2.X() << endl; |
256 | // cout << " ****************** " << endl; |
257 | MaxHeight = Abs(P2.X()); |
258 | } |
259 | } |
260 | Height = MaxHeight; |
261 | // cout << " MaxHeight: " << Height << endl; |
262 | // cout << " ****************** " << endl; |
263 | |
264 | Angle = MaxAngle; |
265 | // cout << " MaxAngle: " << Angle << endl; |
266 | // cout << " ****************** " << endl; |
267 | |
268 | if (Light == VrmlConverter_SpotLight) |
269 | { |
270 | mySpotLight.SetLocation(VSource); |
271 | mySpotLight.SetDirection(Zpers.Reversed()); |
272 | mySpotLight.SetCutOffAngle(2*Angle); |
273 | } |
274 | |
275 | if (Camera == VrmlConverter_PerspectiveCamera) |
276 | { |
277 | // myPerspectiveCamera.SetPosition(VSource); |
278 | // myPerspectiveCamera.SetOrientation(Vrml_SFRotation (Dturn.X(),Dturn.Y(),Dturn.Z(),AngleTurn)); |
279 | myPerspectiveCamera.SetFocalDistance(Focus); |
280 | myPerspectiveCamera.SetAngle(2*Angle); |
281 | } |
282 | |
283 | if (Camera == VrmlConverter_OrthographicCamera) |
284 | { |
285 | // myOrthographicCamera.SetPosition(VSource); |
286 | // myOrthographicCamera.SetOrientation(Vrml_SFRotation (Dturn.X(),Dturn.Y(),Dturn.Z(),AngleTurn)); |
287 | myOrthographicCamera.SetFocalDistance(Focus); |
288 | myOrthographicCamera.SetHeight(2*Height); |
289 | } |
290 | |
291 | } |
292 | } |
293 | |
294 | void VrmlConverter_Projector::Add(Standard_OStream& anOStream) const |
295 | { |
296 | switch ( myTypeOfCamera ) |
297 | { |
298 | case VrmlConverter_NoCamera: break; |
299 | case VrmlConverter_PerspectiveCamera: |
300 | { |
301 | Vrml_TransformSeparator TS; |
302 | TS.Print(anOStream); |
303 | myMatrixTransform.Print(anOStream); |
304 | Vrml_Instancing I1 ("Perspective Camera"); |
305 | I1.DEF(anOStream); |
306 | myPerspectiveCamera.Print(anOStream); |
307 | TS.Print(anOStream); |
308 | } |
309 | break; |
310 | case VrmlConverter_OrthographicCamera: |
311 | { |
312 | Vrml_TransformSeparator TS; |
313 | TS.Print(anOStream); |
314 | myMatrixTransform.Print(anOStream); |
315 | Vrml_Instancing I2 ("Orthographic Camera"); |
316 | I2.DEF(anOStream); |
317 | myOrthographicCamera.Print(anOStream); |
318 | TS.Print(anOStream); |
319 | } |
320 | break; |
321 | } |
322 | |
323 | switch ( myTypeOfLight ) |
324 | { |
325 | case VrmlConverter_NoLight: break; |
326 | case VrmlConverter_DirectionLight: |
327 | { |
328 | myDirectionalLight.Print(anOStream); |
329 | } |
330 | break; |
331 | case VrmlConverter_PointLight: |
332 | { |
333 | myPointLight.Print(anOStream); |
334 | } |
335 | break; |
336 | case VrmlConverter_SpotLight: |
337 | { |
338 | mySpotLight.Print(anOStream); |
339 | } |
340 | break; |
341 | } |
342 | |
343 | } |
344 | |
345 | void VrmlConverter_Projector::SetCamera(const VrmlConverter_TypeOfCamera aCamera) |
346 | { |
347 | myTypeOfCamera = aCamera; |
348 | } |
349 | |
350 | VrmlConverter_TypeOfCamera VrmlConverter_Projector::Camera() const |
351 | { |
352 | return myTypeOfCamera; |
353 | } |
354 | |
355 | void VrmlConverter_Projector::SetLight(const VrmlConverter_TypeOfLight aLight) |
356 | { |
357 | myTypeOfLight = aLight; |
358 | } |
359 | |
360 | VrmlConverter_TypeOfLight VrmlConverter_Projector::Light() const |
361 | { |
362 | return myTypeOfLight; |
363 | } |
364 | |
365 | HLRAlgo_Projector VrmlConverter_Projector::Projector () const |
366 | { |
367 | return myProjector; |
368 | } |