0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / VrmlConverter / VrmlConverter_Projector.cxx
CommitLineData
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 33IMPLEMENT_STANDARD_RTTIEXT(VrmlConverter_Projector,MMgt_TShared)
34
7fd59977 35VrmlConverter_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
155if (Light == VrmlConverter_DirectionLight)
156 {
157 myDirectionalLight.SetDirection(Zpers.Reversed());
158 }
159
160if (Light == VrmlConverter_PointLight)
161 {
162 myPointLight.SetLocation(VSource);
163 }
164
165if (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
268if (Light == VrmlConverter_SpotLight)
269 {
270 mySpotLight.SetLocation(VSource);
271 mySpotLight.SetDirection(Zpers.Reversed());
272 mySpotLight.SetCutOffAngle(2*Angle);
273 }
274
275if (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
283if (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
294void 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
345void VrmlConverter_Projector::SetCamera(const VrmlConverter_TypeOfCamera aCamera)
346{
347 myTypeOfCamera = aCamera;
348}
349
350VrmlConverter_TypeOfCamera VrmlConverter_Projector::Camera() const
351{
352 return myTypeOfCamera;
353}
354
355void VrmlConverter_Projector::SetLight(const VrmlConverter_TypeOfLight aLight)
356{
357 myTypeOfLight = aLight;
358}
359
360VrmlConverter_TypeOfLight VrmlConverter_Projector::Light() const
361{
362 return myTypeOfLight;
363}
364
365HLRAlgo_Projector VrmlConverter_Projector::Projector () const
366{
367 return myProjector;
368}