44047a657f485b9883e24fc15abc35ced1ad4c27
[occt.git] / src / V3d / V3d_SpotLight.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
7 //
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10 //
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
17
18 /***********************************************************************
19  
20      FONCTION :
21      ----------
22         Classe V3d_SpotLight :
23  
24      HISTORIQUE DES MODIFICATIONS   :
25      --------------------------------
26       00-09-92 : GG  ; Creation.
27       18-06-96 : FMN ; Ajout MyGraphicStructure1 pour sauvegarder snopick
28       30-03-98 : ZOV ; PRO6774 (reconstruction of the class hierarchy and suppressing useless methods)
29       02.15.100 : JR : Clutter
30
31 ************************************************************************/
32
33 /*----------------------------------------------------------------------*/
34 /*
35  * Includes
36  */
37
38 #include <V3d.hxx>
39 #include <V3d_SpotLight.ixx>
40 #include <Graphic3d_Vector.hxx>
41 #include <Graphic3d_Vertex.hxx>
42 #include <Graphic3d_Structure.hxx>
43 #include <Graphic3d_Group.hxx>
44 #include <Graphic3d_ArrayOfSegments.hxx>
45 #include <Graphic3d_AspectMarker3d.hxx>
46 #include <Graphic3d_AspectLine3d.hxx>
47 #include <Graphic3d_AspectText3d.hxx>
48 #include <Visual3d_Light.hxx>
49 #include <Visual3d_ViewManager.hxx>
50 #include <Visual3d_ContextPick.hxx>
51 #include <Visual3d_PickDescriptor.hxx>
52 #include <Visual3d_HSequenceOfPickPath.hxx>
53 #include <Visual3d_PickPath.hxx>
54 #include <gp_Dir.hxx>
55 #include <gp_Ax1.hxx>
56 #include <gp_Vec.hxx>
57 #include <gp_Pnt.hxx>
58 #include <gp_Trsf.hxx>
59 #include <TCollection_AsciiString.hxx>
60
61 #ifdef WNT
62 # include <WNT_Window.hxx>
63 #else
64 # include <Xw_Window.hxx>
65 #endif
66
67
68 V3d_SpotLight::V3d_SpotLight(const Handle(V3d_Viewer)& VM, const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const V3d_TypeOfOrientation Direction, const Quantity_NameOfColor Name, const Standard_Real A1, const Standard_Real A2, const Standard_Real CN, const Standard_Real AN):V3d_PositionLight(VM) {
69
70   V3d_BadValue_Raise_if( A1 < 0 || A1 > 1. || A2 < 0 || A2 > 1  
71                         || AN < 0. || AN > M_PI, "V3d_SpotLight, bad coefficient or angle");
72
73   Quantity_Color C(Name) ;
74   Graphic3d_Vector D = V3d::GetProjAxis(Direction) ;
75   Graphic3d_Vertex P(X,Y,Z) ;
76   Graphic3d_Vertex T;
77
78   MyType = V3d_SPOT ;
79   MyLight = new Visual3d_Light(C,P,D,CN,A1,A2,AN) ;
80   // The target is fixed, starting from the light position and the direction.
81   T.SetCoord(X + D.X(), Y + D.Y(), Z + D.Z());
82   MyTarget = T;
83
84
85 V3d_SpotLight::V3d_SpotLight(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_Real A1, const Standard_Real A2, const Standard_Real CN, const Standard_Real AN):V3d_PositionLight(VM) {
86
87   V3d_BadValue_Raise_if( A1 < 0 || A1 > 1. || A2 < 0 || A2 > 1  
88                         || AN < 0. || AN > M_PI, "V3d_SpotLight, bad coefficient or angle");
89
90   Quantity_Color C(Name) ;
91   Graphic3d_Vertex T(Xt,Yt,Zt) ;
92   Graphic3d_Vertex P(Xp,Yp,Zp) ;
93   Graphic3d_Vector D(P,T);
94
95   MyType = V3d_SPOT ;
96   D.Normalize();
97   MyLight = new Visual3d_Light(C,P,D,CN,A1,A2,AN) ;
98   MyTarget = T;
99   // La Structure graphique sera initialisee lors de l'affichage.
100 }
101
102
103 //-Methods, in order
104
105 void V3d_SpotLight::SetPosition(const Standard_Real Xp, const Standard_Real Yp, const Standard_Real Zp) {
106   MyLight->SetPosition (Graphic3d_Vertex (Xp,Yp,Zp));
107 }
108
109 void V3d_SpotLight::SetDirection(const Standard_Real Vx, const Standard_Real Vy, const Standard_Real Vz) {
110
111   Graphic3d_Vector D ;
112   D.SetCoord(Vx,Vy,Vz) ; D.Normalize() ;
113   MyLight->SetDirection(D) ;
114 }
115
116 void V3d_SpotLight::SetDirection(const V3d_TypeOfOrientation Direction) {
117
118   Graphic3d_Vector D = V3d::GetProjAxis(Direction) ;
119   MyLight->SetDirection(D) ;
120 }
121
122 void V3d_SpotLight::SetAttenuation(const Standard_Real A1, const Standard_Real A2) {
123
124   V3d_BadValue_Raise_if( A1 < 0 || A1 > 1. || A2 < 0 || A2 > 1 ,
125                         "V3d_SpotLight::SetAttenuation, bad coefficients");
126
127   MyLight->SetAttenuation1(A1) ;
128   MyLight->SetAttenuation2(A2) ;
129 }
130
131 void V3d_SpotLight::SetConcentration(const Standard_Real C) {
132
133   
134   V3d_BadValue_Raise_if( C < 0 || C > 1.,
135                         "V3d_SpotLight::SetConcentration, bad coefficient");
136
137   MyLight->SetConcentration(C) ;
138 }
139
140 void V3d_SpotLight::SetAngle(const Standard_Real Angle) {
141
142   V3d_BadValue_Raise_if( Angle <= 0. || Angle >= M_PI,
143                         "V3d_SpotLight::SetAngle, bad angle");
144   MyLight->SetAngle(Angle) ;
145
146 }
147
148 void V3d_SpotLight::Direction(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz)const  {
149
150   Quantity_Color C ;
151   Graphic3d_Vector D ;
152   Graphic3d_Vertex P ;
153   Standard_Real CN,A1,A2,AN ;
154
155   MyLight->Values(C,P,D,CN,A1,A2,AN) ;
156   D.Coord(Vx,Vy,Vz) ;
157 }
158
159 void V3d_SpotLight::Position(Standard_Real& Xp, Standard_Real& Yp, Standard_Real& Zp)const  {
160   
161   Quantity_Color C ;
162   Graphic3d_Vector D ;
163   Graphic3d_Vertex P ;
164   Standard_Real CN,A1,A2,AN ;
165
166   MyLight->Values(C,P,D,CN,A1,A2,AN) ;
167   P.Coord(Xp,Yp,Zp) ;
168 }
169
170 void V3d_SpotLight::Attenuation(Standard_Real& A1, Standard_Real& A2) const  {
171     Quantity_Color C ;
172     Graphic3d_Vector D ;
173     Graphic3d_Vertex P ;
174     Standard_Real CN,AN ;
175     
176     MyLight->Values(C,P,D,CN,A1,A2,AN) ;
177 }
178
179 Standard_Real V3d_SpotLight::Concentration()const
180 {
181   Quantity_Color C ;
182   Graphic3d_Vector D ;
183   Graphic3d_Vertex P ;
184   Standard_Real AN,A1,A2,CN ;
185   
186   MyLight->Values(C,P,D,CN,A1,A2,AN) ;
187   return CN ;
188 }
189
190 Standard_Real V3d_SpotLight::Angle()const
191 {
192   Quantity_Color C ;
193   Graphic3d_Vector D ;
194   Graphic3d_Vertex P ;
195   Standard_Real CN,A1,A2,AN ;
196   
197   MyLight->Values(C,P,D,CN,A1,A2,AN) ;
198   return AN ;
199 }
200
201 void V3d_SpotLight::Symbol (const Handle(Graphic3d_Group)& gsymbol,
202                             const Handle(V3d_View)& ) const
203 {
204   Standard_Real X,Y,Z;
205   Standard_Real DX,DY,DZ;
206   this->Position(X,Y,Z);
207   this->Direction(DX,DY,DZ);
208
209   V3d::ArrowOfRadius(gsymbol,X,Y,Z,-DX,-DY,-DZ,M_PI/8.,this->Radius()/15.);
210 }
211     
212 void V3d_SpotLight::Display( const Handle(V3d_View)& aView,
213                              const V3d_TypeOfRepresentation TPres)
214 {
215   Graphic3d_Vertex PText ;
216   Standard_Real X,Y,Z,Rayon;
217   Standard_Real X0,Y0,Z0,VX,VY,VZ;
218   Standard_Real X1,Y1,Z1;
219   Standard_Real DXRef,DYRef,DZRef,DXini,DYini,DZini;
220   Standard_Real R1,G1,B1;
221   V3d_TypeOfRepresentation Pres;
222   V3d_TypeOfUpdate UpdSov;
223
224 //  Creation of a structure slight of markable elements (position of the
225 //  light, and the domain of lighting represented by a circle)
226 //  Creation of a structure snopick of non-markable elements (target, meridian and 
227 //  parallel).// 
228
229   Pres = TPres;
230   Handle(V3d_Viewer) TheViewer = aView->Viewer();
231   UpdSov = TheViewer->UpdateMode();
232   TheViewer->SetUpdateMode(V3d_WAIT);
233   if (!MyGraphicStructure.IsNull()) {
234     MyGraphicStructure->Disconnect(MyGraphicStructure1);
235     MyGraphicStructure->Clear();
236     MyGraphicStructure1->Clear();
237     if (Pres == V3d_SAMELAST) Pres = MyTypeOfRepresentation;
238   }
239   else {
240     if (Pres == V3d_SAMELAST) Pres = V3d_SIMPLE;
241     Handle(Graphic3d_Structure) slight = new Graphic3d_Structure(TheViewer->Viewer());
242     MyGraphicStructure = slight;
243     Handle(Graphic3d_Structure) snopick = new Graphic3d_Structure(TheViewer->Viewer()); 
244     MyGraphicStructure1 = snopick;
245   }
246
247   Handle(Graphic3d_Group) gradius;
248   Handle(Graphic3d_Group) gExtArrow;
249   Handle(Graphic3d_Group) gIntArrow;
250   if (Pres == V3d_COMPLETE) {
251     gradius = new Graphic3d_Group(MyGraphicStructure);
252     gExtArrow = new Graphic3d_Group(MyGraphicStructure);
253     gIntArrow = new Graphic3d_Group(MyGraphicStructure);
254   }
255   Handle(Graphic3d_Group) glight  = new Graphic3d_Group(MyGraphicStructure);
256   Handle(Graphic3d_Group) gsphere;
257   if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) gsphere = new Graphic3d_Group(MyGraphicStructure);
258   
259   Handle(Graphic3d_Group) gnopick = new Graphic3d_Group(MyGraphicStructure1);
260   MyGraphicStructure1->SetPick(Standard_False);
261   
262   X0 = MyTarget.X();
263   Y0 = MyTarget.Y();
264   Z0 = MyTarget.Z();
265   
266 //Display of the position of the light.
267
268   this->Color(Quantity_TOC_RGB,R1,G1,B1);
269   Quantity_Color Col1(R1,G1,B1,Quantity_TOC_RGB);
270   Handle(Graphic3d_AspectLine3d) Asp1 = new Graphic3d_AspectLine3d();
271   Asp1->SetColor(Col1);
272   glight->SetPrimitivesAspect(Asp1);
273   this->Symbol(glight,aView);
274   
275 // Display of the reference sphere (limited by circle).
276
277   if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) {
278     
279     Rayon = this->Radius(); 
280     aView->Proj(VX,VY,VZ);
281     V3d::CircleInPlane(gsphere,X0,Y0,Z0,VX,VY,VZ,Rayon);
282
283 // Display of the radius of the sphere (line + text)
284
285     if (Pres == V3d_COMPLETE) {
286       this->Position(X,Y,Z);
287       Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
288       aPrims->AddVertex(X0,Y0,Z0);
289       aPrims->AddVertex(X,Y,Z);
290       gnopick->AddPrimitiveArray(aPrims);
291       V3d::ArrowOfRadius(gExtArrow,X-.1*(X-X0),Y-.1*(Y-Y0),Z-.1*(Z-Z0),X-X0,Y-Y0,Z-Z0,M_PI/15.,Rayon/20.);
292       V3d::ArrowOfRadius(gIntArrow,X0,Y0,Z0,X0-X,Y0-Y,Z0-Z,M_PI/15.,Rayon/20.);
293       TCollection_AsciiString ValOfRadius(Rayon);
294       PText.SetCoord( .5*(X0+X), .5*(Y0+Y), .5*(Z0+Z) );
295       gradius->Text(ValOfRadius.ToCString(),PText,0.01);
296     }
297     
298 // Display of the meridian
299
300     Quantity_Color Col2(Quantity_NOC_GREEN);
301     Handle(Graphic3d_AspectLine3d) Asp2 = new Graphic3d_AspectLine3d(Col2,Aspect_TOL_SOLID,1.);
302     gnopick->SetPrimitivesAspect(Asp2);
303     
304 //    Definition of the axis of the circle
305     aView->Up(DXRef,DYRef,DZRef);
306     this->Position(X,Y,Z);
307     DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
308     VX = DYRef*DZini - DZRef*DYini;
309     VY = DZRef*DXini - DXRef*DZini;
310     VZ = DXRef*DYini - DYRef*DXini;
311     
312     V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
313
314 //    Display of the parallel
315
316 //    Definition of the axis of the circle
317     aView->Proj(VX,VY,VZ);
318     aView->Up(X1,Y1,Z1);
319     DXRef = VY * Z1 - VZ * Y1;
320     DYRef = VZ * X1 - VX * Z1;
321     DZRef = VX * Y1 - VY * X1;
322     this->Position(X,Y,Z);
323     DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
324     VX = DYRef*DZini - DZRef*DYini;
325     VY = DZRef*DXini - DXRef*DZini;
326     VZ = DXRef*DYini - DYRef*DXini;
327     
328     V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
329   }
330   
331   MyGraphicStructure->Connect(MyGraphicStructure1,Graphic3d_TOC_DESCENDANT);
332   MyTypeOfRepresentation = Pres;
333   MyGraphicStructure->Display();
334   TheViewer->SetUpdateMode(UpdSov);
335 }