0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / VrmlConverter / VrmlConverter_Projector.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
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
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.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <Bnd_Box.hxx>
16 #include <BRepBndLib.hxx>
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>
25 #include <TColgp_Array1OfPnt.hxx>
26 #include <TColgp_Array1OfVec.hxx>
27 #include <Vrml_Instancing.hxx>
28 #include <Vrml_MatrixTransform.hxx>
29 #include <Vrml_SFRotation.hxx>
30 #include <Vrml_TransformSeparator.hxx>
31 #include <VrmlConverter_Projector.hxx>
32
33 IMPLEMENT_STANDARD_RTTIEXT(VrmlConverter_Projector,MMgt_TShared)
34
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     {
113       throw Standard_Failure("Projection Vector is Parallel to High Point Direction");
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 }