1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
15 #include <Bnd_Box.hxx>
16 #include <BRepBndLib.hxx>
20 #include <gp_Trsf.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>
33 IMPLEMENT_STANDARD_RTTIEXT(VrmlConverter_Projector,Standard_Transient)
35 VrmlConverter_Projector::VrmlConverter_Projector (const TopTools_Array1OfShape& Shapes,
36 const Standard_Real Focus,
37 const Standard_Real DX,
38 const Standard_Real DY,
39 const Standard_Real DZ,
40 const Standard_Real XUp,
41 const Standard_Real YUp,
42 const Standard_Real ZUp,
43 const VrmlConverter_TypeOfCamera Camera,
44 const VrmlConverter_TypeOfLight Light)
48 myTypeOfCamera = Camera;
49 myTypeOfLight = Light;
53 Standard_Real Xmin, Xmax, Ymin, Ymax, Zmin, Zmax, diagonal;
54 Standard_Real Xtarget, Ytarget, Ztarget, Angle, MaxAngle, Height, MaxHeight;
56 for ( i=Shapes.Lower(); i <= Shapes.Upper(); i++)
58 BRepBndLib::AddClose(Shapes.Value(i), box);
61 Standard_Real DistMax = 500000;
62 Standard_Real TolMin = 0.000001;
65 box.Get( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax );
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;
74 Standard_Real xx = (Xmax - Xmin);
75 Standard_Real yy = (Ymax - Ymin);
76 Standard_Real zz = (Zmax - Zmin);
78 Xtarget = (Xmin + Xmax)/2;
79 Ytarget = (Ymin + Ymax)/2;
80 Ztarget = (Zmin + Zmax)/2;
82 // std::cout << " target: " << std::endl;
83 // std::cout << " X: " << Xtarget << " Y: " << Ytarget << " Z: " << Ztarget << std::endl;
85 // gp_Pnt Target(Xtarget, Ytarget, Ztarget);
86 // gp_Vec VTarget(Target.X(),Target.Y(),Target.Z());
88 gp_Dir Zpers (DX,DY,DZ);
91 diagonal = Sqrt (xx*xx + yy*yy + zz*zz);
93 gp_Vec aVec = V.Multiplied(0.5*diagonal+TolMin+Focus);
96 Source.SetX(Xtarget+aVec.X());
97 Source.SetY(Ytarget+aVec.Y());
98 Source.SetZ(Ztarget+aVec.Z());
100 // std::cout << " source: " << std::endl;
101 // std::cout << " X: " << Source.X() << " Y: " << Source.Y() << " Z: " << Source.Z() << std::endl;
103 gp_Vec VSource(Source.X(),Source.Y(),Source.Z());
105 // gp_Vec Proj(Source,Target);
106 // std::cout << " Vec(source-target): " << std::endl;
107 // std::cout << " X: " << Proj.X() << " Y: " << Proj.Y() << " Z: " << Proj.Z() << std::endl;
109 gp_Dir Ypers (XUp,YUp,ZUp);
111 if( Ypers.IsParallel(Zpers,Precision::Angular()) )
113 throw Standard_Failure("Projection Vector is Parallel to High Point Direction");
115 gp_Dir Xpers = Ypers.Crossed(Zpers);
117 // std::cout << " Dir(Zpers): " << std::endl;
118 // std::cout << " X: " << Zpers.X() << " Y: " << Zpers.Y() << " Z: " << Zpers.Z() << std::endl;
119 // std::cout << " Dir(Xpers): " << std::endl;
120 // std::cout << " X: " << Xpers.X() << " Y: " << Xpers.Y() << " Z: " << Xpers.Z() << std::endl;
122 gp_Ax3 Axe (Source, Zpers, Xpers);
126 // Makes the transformation allowing passage from the basic
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);
134 Standard_Boolean Pers = Standard_False;
135 if (Camera == VrmlConverter_PerspectiveCamera) Pers = Standard_True;
137 //build a Projector with automatic minmax directions
138 myProjector = HLRAlgo_Projector(T,Pers,Focus);
142 // T3.SetTranslationPart(gp_Vec (0,0,0));
144 myMatrixTransform.SetMatrix(T3);
148 // T1.SetTranslationPart(gp_Vec (0,0,0));
149 // myMatrixTransform.SetMatrix(T1);
152 //== definitions cameras and lights
155 if (Light == VrmlConverter_DirectionLight)
157 myDirectionalLight.SetDirection(Zpers.Reversed());
160 if (Light == VrmlConverter_PointLight)
162 myPointLight.SetLocation(VSource);
165 if (Light == VrmlConverter_SpotLight || Camera != VrmlConverter_NoCamera )
169 gp_Dir Zmain (0,0,1);
170 gp_Dir Xmain (1,0,0);
174 Standard_Real AngleTurn;
176 if( Zmain.IsParallel(Zpers,Precision::Angular()) )
178 if ( Zmain.IsOpposite(Zpers,Precision::Angular()) )
181 AngleTurn = - Xmain.Angle(Xpers);
184 AngleTurn = Xmain.Angle(Xpers);
188 Dturn = Zmain.Crossed(Zpers);
189 AngleTurn = Zmain.Angle(Zpers);
194 TColgp_Array1OfPnt ArrP(1,8);
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);
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);
221 for ( i=ArrP.Lower(); i <= ArrP.Upper(); i++)
224 P2 = P1.Transformed (T);
234 // std::cout << " Angle: " << V1.Angle(V2) << std::endl;
235 // std::cout << " ****************** " << std::endl;
236 if ( Abs(V1.Angle(V2)) > Abs(MaxAngle) ) MaxAngle = Abs(V1.Angle(V2));
242 // std::cout << " Angle: " << V1.Angle(V2) << std::endl;
243 // std::cout << " ****************** " << std::endl;
244 if ( Abs(V1.Angle(V2)) > Abs(MaxAngle) ) MaxAngle = Abs(V1.Angle(V2));
246 if ( Abs(P2.Y()) > Abs(MaxHeight) )
248 // std::cout << " Height Y: " << P2.Y() << std::endl;
249 // std::cout << " ****************** " << std::endl;
250 MaxHeight = Abs(P2.Y());
253 if ( Abs(P2.X()) > Abs(MaxHeight) )
255 // std::cout << " Height X: " << P2.X() << std::endl;
256 // std::cout << " ****************** " << std::endl;
257 MaxHeight = Abs(P2.X());
261 // std::cout << " MaxHeight: " << Height << std::endl;
262 // std::cout << " ****************** " << std::endl;
265 // std::cout << " MaxAngle: " << Angle << std::endl;
266 // std::cout << " ****************** " << std::endl;
268 if (Light == VrmlConverter_SpotLight)
270 mySpotLight.SetLocation(VSource);
271 mySpotLight.SetDirection(Zpers.Reversed());
272 mySpotLight.SetCutOffAngle(2*Angle);
275 if (Camera == VrmlConverter_PerspectiveCamera)
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);
283 if (Camera == VrmlConverter_OrthographicCamera)
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);
294 void VrmlConverter_Projector::Add(Standard_OStream& anOStream) const
296 switch ( myTypeOfCamera )
298 case VrmlConverter_NoCamera: break;
299 case VrmlConverter_PerspectiveCamera:
301 Vrml_TransformSeparator TS;
303 myMatrixTransform.Print(anOStream);
304 Vrml_Instancing I1 ("Perspective Camera");
306 myPerspectiveCamera.Print(anOStream);
310 case VrmlConverter_OrthographicCamera:
312 Vrml_TransformSeparator TS;
314 myMatrixTransform.Print(anOStream);
315 Vrml_Instancing I2 ("Orthographic Camera");
317 myOrthographicCamera.Print(anOStream);
323 switch ( myTypeOfLight )
325 case VrmlConverter_NoLight: break;
326 case VrmlConverter_DirectionLight:
328 myDirectionalLight.Print(anOStream);
331 case VrmlConverter_PointLight:
333 myPointLight.Print(anOStream);
336 case VrmlConverter_SpotLight:
338 mySpotLight.Print(anOStream);
345 void VrmlConverter_Projector::SetCamera(const VrmlConverter_TypeOfCamera aCamera)
347 myTypeOfCamera = aCamera;
350 VrmlConverter_TypeOfCamera VrmlConverter_Projector::Camera() const
352 return myTypeOfCamera;
355 void VrmlConverter_Projector::SetLight(const VrmlConverter_TypeOfLight aLight)
357 myTypeOfLight = aLight;
360 VrmlConverter_TypeOfLight VrmlConverter_Projector::Light() const
362 return myTypeOfLight;
365 HLRAlgo_Projector VrmlConverter_Projector::Projector () const