1 /***********************************************************************
5 Classe V3d_DirectionalLight :
7 HISTORIQUE DES MODIFICATIONS :
8 --------------------------------
9 00-09-92 : GG ; Creation.
10 18-06-96 : FMN ; Ajout MyGraphicStructure1 pour sauvegarder snopick
11 24-12-97 : FMN ; Remplacement de math par MathGra
12 31-12-97 : CAL ; Suppression de MathGra
13 21-01-98 : CAL ; Window de Xw et WNT remplacee par Aspect_Window
14 23-02-98 : FMN ; Remplacement PI par Standard_PI
15 30-03-98 : ZOV ; PRO6774 (reconstruction of the class hierarchy and suppressing useless methods)
17 ************************************************************************/
19 /*----------------------------------------------------------------------*/
25 #include <V3d_DirectionalLight.ixx>
26 #include <Graphic3d_Vector.hxx>
27 #include <Graphic3d_Vertex.hxx>
28 #include <Graphic3d_Structure.hxx>
29 #include <Graphic3d_Group.hxx>
30 #include <Graphic3d_Array1OfVertex.hxx>
31 #include <Graphic3d_AspectMarker3d.hxx>
32 #include <Graphic3d_AspectLine3d.hxx>
33 #include <Graphic3d_AspectText3d.hxx>
34 #include <Visual3d_Light.hxx>
35 #include <Visual3d_ViewManager.hxx>
36 #include <Visual3d_ContextPick.hxx>
37 #include <Visual3d_PickDescriptor.hxx>
38 #include <Visual3d_HSequenceOfPickPath.hxx>
39 #include <Visual3d_PickPath.hxx>
40 #include <Viewer_BadValue.hxx>
45 #include <gp_Trsf.hxx>
46 #include <TColStd_Array2OfReal.hxx>
47 #include <Aspect_Window.hxx>
51 V3d_DirectionalLight::V3d_DirectionalLight(const Handle(V3d_Viewer)& VM, const
52 V3d_TypeOfOrientation Direction,const Quantity_NameOfColor Name,const Standard_Boolean Headlight):V3d_PositionLight(VM) {
53 Quantity_Color C(Name) ;
54 Graphic3d_Vertex T(0.,0.,0.) ;
56 Graphic3d_Vector V = V3d::GetProjAxis(Direction) ;
58 MyType = V3d_DIRECTIONAL ;
59 MyLight = new Visual3d_Light(C,V, Headlight) ;
60 // The initial target is chosen at random
63 P.SetCoord(-V.X(),-V.Y(),-V.Z());
64 MyDisplayPosition = P;
68 V3d_DirectionalLight::V3d_DirectionalLight(const Handle(V3d_Viewer)& VM,const Standard_Real Xt,const Standard_Real Yt,const Standard_Real Zt,const Standard_Real Xp,const Standard_Real Yp,const Standard_Real Zp,const Quantity_NameOfColor Name,const Standard_Boolean Headlight):V3d_PositionLight(VM) {
69 Quantity_Color C(Name) ;
70 Graphic3d_Vertex T(Xt,Yt,Zt) ;
71 Graphic3d_Vertex P(Xp,Yp,Zp) ;
72 Graphic3d_Vector V(P,T);
74 MyType = V3d_DIRECTIONAL ;
76 MyLight = new Visual3d_Light(C,V, Headlight) ;
78 MyDisplayPosition = P;
83 void V3d_DirectionalLight::SetDirection(const V3d_TypeOfOrientation Direction) {
85 Graphic3d_Vector V = V3d::GetProjAxis(Direction) ;
86 MyLight->SetDirection(V) ;
89 void V3d_DirectionalLight::SetDirection(const Standard_Real Vx, const Standard_Real Vy, const Standard_Real Vz) {
91 Viewer_BadValue_Raise_if( sqrt( Vx*Vx + Vy*Vy + Vz*Vz ) <= 0.,"V3d_DirectionalLight::SetDirection, null vector" );
93 Graphic3d_Vector V(Vx,Vy,Vz) ;
95 MyLight->SetDirection(V) ;
98 void V3d_DirectionalLight::SetDisplayPosition(const Standard_Real X, const Standard_Real Y, const Standard_Real Z) {
100 Standard_Real Xt,Yt,Zt;
102 MyDisplayPosition.SetCoord(X,Y,Z) ;
103 MyTarget.Coord(Xt,Yt,Zt);
104 SetDirection(Xt-X,Yt-Y,Zt-Z);
107 void V3d_DirectionalLight::SetPosition(const Standard_Real Xp, const Standard_Real Yp, const Standard_Real Zp) {
109 SetDisplayPosition (Xp,Yp,Zp);
112 void V3d_DirectionalLight::Position(Standard_Real& Xp, Standard_Real& Yp, Standard_Real& Zp)const {
114 DisplayPosition (Xp,Yp,Zp) ;
117 void V3d_DirectionalLight::DisplayPosition(Standard_Real& Xp, Standard_Real& Yp, Standard_Real& Zp)const {
119 MyDisplayPosition.Coord(Xp,Yp,Zp) ;
122 void V3d_DirectionalLight::Symbol (const Handle(Graphic3d_Group)& gsymbol, const Handle(V3d_View)& aView) const {
124 Standard_Real Xi,Yi,Zi,Xf,Yf,Zf,Rayon,PXT,PYT,X,Y,Z,XT,YT,ZT;
125 Standard_Real A,B,C,Dist,Beta,CosBeta,SinBeta,Coef,X1,Y1,Z1;
126 Standard_Real DX,DY,DZ,VX,VY,VZ;
127 Standard_Integer IXP,IYP,j;
128 TColStd_Array2OfReal MatRot(0,2,0,2);
129 Graphic3d_Array1OfVertex Line(0,1);
131 aView->Proj(VX,VY,VZ);
132 this->DisplayPosition(Xi,Yi,Zi);
133 Rayon = this->Radius();
134 aView->Project(Xi,Yi,Zi,PXT,PYT);
135 aView->Convert(PXT,PYT,IXP,IYP);
136 // Coordinated 3d in the plane of projection of the source.
137 aView->Convert(IXP,IYP,XT,YT,ZT);
138 aView->Convert(PXT,PYT+Rayon,IXP,IYP);
139 aView->Convert(IXP,IYP,X,Y,Z);
140 X = X+Xi-XT; Y = Y+Yi-YT; Z = Z+Zi-ZT;
141 Dist = Sqrt( Square(X-Xi) + Square(Y-Yi) + Square(Z-Zi) );
148 V3d::CircleInPlane(gsymbol,Xi,Yi,Zi,VX,VY,VZ,Rayon/40.);
149 for( j=1 ; j<=3 ; j++ ) {
150 Beta = j * M_PI / 4.;
154 MatRot(0,0) = A * A + (1. - A * A) * CosBeta;
155 MatRot(0,1) = -C * SinBeta + Coef * A * B;
156 MatRot(0,2) = B * SinBeta + Coef * A * C;
157 MatRot(1,0) = C * SinBeta + Coef * A * B;
158 MatRot(1,1) = B * B + (1. - B * B) * CosBeta;
159 MatRot(1,2) = -A * SinBeta + Coef * B * C;
160 MatRot(2,0) = -B * SinBeta + Coef * A * C;
161 MatRot(2,1) = A * SinBeta + Coef * B * C;
162 MatRot(2,2) = C * C + (1. - C * C) * CosBeta;
163 Xf = Xi * MatRot(0,0) + Yi * MatRot(0,1) + Zi * MatRot(0,2);
164 Yf = Xi * MatRot(1,0) + Yi * MatRot(1,1) + Zi * MatRot(1,2);
165 Zf = Xi * MatRot(2,0) + Yi * MatRot(2,1) + Zi * MatRot(2,2);
166 // Rotation of the normal
167 X1 = VX * MatRot(0,0) + VY * MatRot(0,1) + VZ * MatRot(0,2);
168 Y1 = VX * MatRot(1,0) + VY * MatRot(1,1) + VZ * MatRot(1,2);
169 Z1 = VX * MatRot(2,0) + VY * MatRot(2,1) + VZ * MatRot(2,2);
170 VX = X1 + Xi - Xf ; VY = Y1 + Yi - Yf ; VZ = Z1 + Zi - Zf;
171 V3d::CircleInPlane(gsymbol,Xi,Yi,Zi,VX,VY,VZ,Rayon/40.);
174 // The arrow is drawn
175 Rayon = this->Radius();
176 this->Direction(DX,DY,DZ);
177 X = Xi + DX*Rayon/10.; Y = Yi + DY*Rayon/10.; Z = Zi + DZ*Rayon/10.;
178 Line(0).SetCoord(Xi,Yi,Zi);
179 Line(1).SetCoord(X,Y,Z);
180 gsymbol->Polyline(Line);
181 V3d::ArrowOfRadius(gsymbol, X, Y, Z, DX, DY, DZ, M_PI / 15., Rayon / 20.);
184 void V3d_DirectionalLight::Display( const Handle(V3d_View)& aView,
185 const V3d_TypeOfRepresentation TPres) {
187 Standard_Real X,Y,Z,Rayon;
188 Standard_Real X0,Y0,Z0,VX,VY,VZ;
189 Standard_Real X1,Y1,Z1;
190 Standard_Real DXRef,DYRef,DZRef,DXini,DYini,DZini;
191 Standard_Real R1,G1,B1;
192 V3d_TypeOfRepresentation Pres;
193 V3d_TypeOfUpdate UpdSov;
195 // Creation of a structure of markable elements (position of the
196 // light, and the domain of lighting represented by a circle)
197 // Creation of a structure of non-markable elements (target, meridian and
201 Handle(V3d_Viewer) TheViewer = aView->Viewer();
202 UpdSov = TheViewer->UpdateMode();
203 TheViewer->SetUpdateMode(V3d_WAIT);
204 if (!MyGraphicStructure.IsNull()) {
205 MyGraphicStructure->Disconnect(MyGraphicStructure1);
206 MyGraphicStructure->Clear();
207 MyGraphicStructure1->Clear();
208 if (Pres == V3d_SAMELAST) Pres = MyTypeOfRepresentation;
211 if (Pres == V3d_SAMELAST) Pres = V3d_SIMPLE;
212 Handle(Graphic3d_Structure) slight = new Graphic3d_Structure(TheViewer->Viewer());
213 MyGraphicStructure = slight;
214 Handle(Graphic3d_Structure) snopick = new Graphic3d_Structure(TheViewer->Viewer());
215 MyGraphicStructure1 = snopick;
218 Handle(Graphic3d_Group) glight = new Graphic3d_Group(MyGraphicStructure);
219 Handle(Graphic3d_Group) gsphere;
220 if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) gsphere = new Graphic3d_Group(MyGraphicStructure);
222 Handle(Graphic3d_Group) gnopick = new Graphic3d_Group(MyGraphicStructure1);
223 MyGraphicStructure1->SetPick(Standard_False);
229 //Display of the position of the light.
231 this->Color(Quantity_TOC_RGB,R1,G1,B1);
232 Quantity_Color Col1(R1,G1,B1,Quantity_TOC_RGB);
233 Handle(Graphic3d_AspectLine3d) Asp1 = new Graphic3d_AspectLine3d();
234 Asp1->SetColor(Col1);
235 glight->SetPrimitivesAspect(Asp1);
236 this->Symbol(glight,aView);
238 // Display of the markable sphere (limit at the circle).
240 if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) {
242 Rayon = this->Radius();
243 aView->Proj(VX,VY,VZ);
244 V3d::CircleInPlane(gsphere,X0,Y0,Z0,VX,VY,VZ,Rayon);
246 //Display of the meridian
248 Quantity_Color Col2(Quantity_NOC_GREEN);
249 Handle(Graphic3d_AspectLine3d) Asp2 = new Graphic3d_AspectLine3d
250 (Col2,Aspect_TOL_SOLID,1.);
251 gnopick->SetPrimitivesAspect(Asp2);
253 // Definition of the axis of circle
254 aView->Up(DXRef,DYRef,DZRef);
255 this->DisplayPosition(X,Y,Z);
256 DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
257 VX = DYRef*DZini - DZRef*DYini;
258 VY = DZRef*DXini - DXRef*DZini;
259 VZ = DXRef*DYini - DYRef*DXini;
261 V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
263 // Display of the parallel
265 // Definition of the axis of circle
266 aView->Proj(VX,VY,VZ);
268 DXRef = VY * Z1 - VZ * Y1;
269 DYRef = VZ * X1 - VX * Z1;
270 DZRef = VX * Y1 - VY * X1;
271 this->DisplayPosition(X,Y,Z);
272 DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
273 VX = DYRef*DZini - DZRef*DYini;
274 VY = DZRef*DXini - DXRef*DZini;
275 VZ = DXRef*DYini - DYRef*DXini;
277 V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
281 MyGraphicStructure->Connect(MyGraphicStructure1,Graphic3d_TOC_DESCENDANT);
282 // cout << "MyGraphicStructure exploration \n" << flush; MyGraphicStructure->Exploration();
283 MyTypeOfRepresentation = Pres;
284 MyGraphicStructure->Display();
285 TheViewer->SetUpdateMode(UpdSov);
288 void V3d_DirectionalLight::Direction(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz)const {
293 MyLight->Values(C,V) ;