0027919: Visualization - support multiple transformation persistence groups within...
[occt.git] / src / Graphic3d / Graphic3d_CLight.cxx
CommitLineData
992ed6b3 1// Copyright (c) 2017 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#include <Graphic3d_CLight.hxx>
15
16#include <Standard_Atomic.hxx>
d84e8669 17#include <Standard_NotImplemented.hxx>
992ed6b3 18#include <Standard_OutOfRange.hxx>
19
20IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CLight, Standard_Transient)
21
22namespace
23{
24 static volatile Standard_Integer THE_LIGHT_COUNTER = 0;
25}
26
27// =======================================================================
28// function : makeId
29// purpose :
30// =======================================================================
31void Graphic3d_CLight::makeId()
32{
33 TCollection_AsciiString aTypeSuffix;
34 switch (myType)
35 {
06d40093 36 case Graphic3d_TypeOfLightSource_Ambient: aTypeSuffix = "amb"; break;
37 case Graphic3d_TypeOfLightSource_Directional: aTypeSuffix = "dir"; break;
38 case Graphic3d_TypeOfLightSource_Positional: aTypeSuffix = "pos"; break;
39 case Graphic3d_TypeOfLightSource_Spot: aTypeSuffix = "spot"; break;
992ed6b3 40 }
41
42 myId = TCollection_AsciiString ("Graphic3d_CLight_") + aTypeSuffix
43 + TCollection_AsciiString (Standard_Atomic_Increment (&THE_LIGHT_COUNTER));
44}
45
46// =======================================================================
47// function : Graphic3d_CLight
48// purpose :
49// =======================================================================
50Graphic3d_CLight::Graphic3d_CLight (Graphic3d_TypeOfLightSource theType)
51: myPosition (0.0, 0.0, 0.0),
52 myColor (1.0f, 1.0f, 1.0f, 1.0f),
53 myDirection (0.0f, 0.0f, 0.0f, 0.0f),
54 myParams (0.0f, 0.0f, 0.0f, 0.0f),
55 mySmoothness (0.0f),
56 myIntensity (1.0f),
57 myType (theType),
58 myRevision (0),
59 myIsHeadlight(false),
d84e8669 60 myIsEnabled (true),
61 myToCastShadows (false)
992ed6b3 62{
63 switch (theType)
64 {
06d40093 65 case Graphic3d_TypeOfLightSource_Ambient:
992ed6b3 66 {
67 break;
68 }
06d40093 69 case Graphic3d_TypeOfLightSource_Directional:
992ed6b3 70 {
71 mySmoothness = 0.2f;
72 myIntensity = 20.0f;
73 break;
74 }
06d40093 75 case Graphic3d_TypeOfLightSource_Positional:
992ed6b3 76 {
77 changeConstAttenuation() = 1.0f;
78 changeLinearAttenuation() = 0.0f;
79 break;
80 }
06d40093 81 case Graphic3d_TypeOfLightSource_Spot:
992ed6b3 82 {
83 changeConstAttenuation() = 1.0f;
84 changeLinearAttenuation() = 0.0f;
85 changeConcentration() = 1.0f;
86 changeAngle() = 0.523599f;
87 break;
88 }
89 }
90 makeId();
91}
92
06d40093 93// =======================================================================
94// function : CopyFrom
95// purpose :
96// =======================================================================
97void Graphic3d_CLight::CopyFrom (const Handle(Graphic3d_CLight)& theLight)
98{
99 myName = theLight->myName;
100 myIsEnabled = theLight->myIsEnabled;
101 myIntensity = theLight->myIntensity;
102 myColor = theLight->myColor;
103 if (myType != Graphic3d_TypeOfLightSource_Ambient)
104 {
105 myPosition = theLight->myPosition;
106 myIsHeadlight = theLight->myIsHeadlight;
107 }
108 if ((myType == Graphic3d_TypeOfLightSource_Spot
109 || myType == Graphic3d_TypeOfLightSource_Directional)
110 && (theLight->myType == Graphic3d_TypeOfLightSource_Spot
111 || theLight->myType == Graphic3d_TypeOfLightSource_Directional))
112 {
113 myDirection = theLight->myDirection;
114 }
115 if (myType == Graphic3d_TypeOfLightSource_Directional)
116 {
117 myToCastShadows = theLight->myToCastShadows;
118 }
119 if (myType == theLight->myType)
120 {
121 myParams = theLight->myParams;
122 mySmoothness = theLight->mySmoothness;
123 }
124}
125
992ed6b3 126// =======================================================================
127// function : SetColor
128// purpose :
129// =======================================================================
130void Graphic3d_CLight::SetColor (const Quantity_Color& theColor)
131{
132 updateRevisionIf (myColor.GetRGB().IsDifferent (theColor));
133 myColor.SetRGB (theColor);
134}
135
136// =======================================================================
137// function : SetEnabled
138// purpose :
139// =======================================================================
140void Graphic3d_CLight::SetEnabled (Standard_Boolean theIsOn)
141{
142 updateRevisionIf (myIsEnabled != theIsOn);
143 myIsEnabled = theIsOn;
144}
145
d84e8669 146// =======================================================================
147// function : SetCastShadows
148// purpose :
149// =======================================================================
150void Graphic3d_CLight::SetCastShadows (Standard_Boolean theToCast)
151{
06d40093 152 if (myType != Graphic3d_TypeOfLightSource_Directional)
d84e8669 153 {
154 throw Standard_NotImplemented ("Graphic3d_CLight::SetCastShadows() is not implemented for this light type");
155 }
156 updateRevisionIf (myToCastShadows != theToCast);
157 myToCastShadows = theToCast;
158}
159
992ed6b3 160// =======================================================================
161// function : SetHeadlight
162// purpose :
163// =======================================================================
164void Graphic3d_CLight::SetHeadlight (Standard_Boolean theValue)
165{
06d40093 166 if (myType == Graphic3d_TypeOfLightSource_Ambient)
37f80e16 167 {
168 throw Standard_ProgramError ("Graphic3d_CLight::SetHeadlight() is not applicable to ambient light");
169 }
992ed6b3 170 updateRevisionIf (myIsHeadlight != theValue);
171 myIsHeadlight = theValue;
172}
173
174// =======================================================================
175// function : SetDirection
176// purpose :
177// =======================================================================
178void Graphic3d_CLight::SetDirection (const gp_Dir& theDir)
179{
06d40093 180 Standard_ProgramError_Raise_if (myType != Graphic3d_TypeOfLightSource_Spot
181 && myType != Graphic3d_TypeOfLightSource_Directional,
992ed6b3 182 "Graphic3d_CLight::SetDirection(), incorrect light type");
183 updateRevisionIf (Abs (myDirection.x() - static_cast<Standard_ShortReal> (theDir.X())) > ShortRealEpsilon()
184 || Abs (myDirection.y() - static_cast<Standard_ShortReal> (theDir.Y())) > ShortRealEpsilon()
185 || Abs (myDirection.z() - static_cast<Standard_ShortReal> (theDir.Z())) > ShortRealEpsilon());
186
187 myDirection.x() = static_cast<Standard_ShortReal> (theDir.X());
188 myDirection.y() = static_cast<Standard_ShortReal> (theDir.Y());
189 myDirection.z() = static_cast<Standard_ShortReal> (theDir.Z());
190}
191
192// =======================================================================
193// function : SetPosition
194// purpose :
195// =======================================================================
196void Graphic3d_CLight::SetPosition (const gp_Pnt& thePosition)
197{
06d40093 198 Standard_ProgramError_Raise_if (myType != Graphic3d_TypeOfLightSource_Spot
199 && myType != Graphic3d_TypeOfLightSource_Positional,
2daa5d95 200 "Graphic3d_CLight::SetPosition(), incorrect light type");
201 updateRevisionIf (!myPosition.IsEqual (thePosition, gp::Resolution()));
202 myPosition = thePosition;
203}
204
205// =======================================================================
206// function : SetDisplayPosition
207// purpose :
208// =======================================================================
209void Graphic3d_CLight::SetDisplayPosition (const gp_Pnt& thePosition)
210{
06d40093 211 Standard_ProgramError_Raise_if (myType == Graphic3d_TypeOfLightSource_Ambient,
2daa5d95 212 "Graphic3d_CLight::SetDisplayPosition(), incorrect light type");
992ed6b3 213 updateRevisionIf (!myPosition.IsEqual (thePosition, gp::Resolution()));
214 myPosition = thePosition;
215}
216
217// =======================================================================
218// function : SetIntensity
219// purpose :
220// =======================================================================
221void Graphic3d_CLight::SetIntensity (Standard_ShortReal theValue)
222{
223 Standard_OutOfRange_Raise_if (theValue <= 0.0f, "Graphic3d_CLight::SetIntensity(), Negative value for intensity");
224 updateRevisionIf (Abs (myIntensity - theValue) > ShortRealEpsilon());
225 myIntensity = theValue;
226}
227
228// =======================================================================
229// function : SetAngle
230// purpose :
231// =======================================================================
232void Graphic3d_CLight::SetAngle (Standard_ShortReal theAngle)
233{
06d40093 234 Standard_ProgramError_Raise_if (myType != Graphic3d_TypeOfLightSource_Spot,
992ed6b3 235 "Graphic3d_CLight::SetAngle(), incorrect light type");
236 Standard_OutOfRange_Raise_if (theAngle <= 0.0 || theAngle >= M_PI,
237 "Graphic3d_CLight::SetAngle(), bad angle");
238 updateRevisionIf (Abs (changeAngle() - theAngle) > ShortRealEpsilon());
239 changeAngle() = theAngle;
240}
241
242// =======================================================================
243// function : SetAttenuation
244// purpose :
245// =======================================================================
246void Graphic3d_CLight::SetAttenuation (Standard_ShortReal theConstAttenuation,
247 Standard_ShortReal theLinearAttenuation)
248{
06d40093 249 Standard_ProgramError_Raise_if (myType != Graphic3d_TypeOfLightSource_Positional
250 && myType != Graphic3d_TypeOfLightSource_Spot,
992ed6b3 251 "Graphic3d_CLight::SetAttenuation(), incorrect light type");
252 Standard_OutOfRange_Raise_if (theConstAttenuation < 0.0f
253 || theLinearAttenuation < 0.0f
254 || theConstAttenuation + theLinearAttenuation == 0.0f, "Graphic3d_CLight::SetAttenuation(), bad coefficient");
255 updateRevisionIf (Abs (changeConstAttenuation() - theConstAttenuation) > ShortRealEpsilon()
256 || Abs (changeLinearAttenuation() - theLinearAttenuation) > ShortRealEpsilon());
257 changeConstAttenuation() = theConstAttenuation;
258 changeLinearAttenuation() = theLinearAttenuation;
259}
260
261// =======================================================================
262// function : SetConcentration
263// purpose :
264// =======================================================================
265void Graphic3d_CLight::SetConcentration (Standard_ShortReal theConcentration)
266{
06d40093 267 Standard_ProgramError_Raise_if (myType != Graphic3d_TypeOfLightSource_Spot, "Graphic3d_CLight::SetConcentration(), incorrect light type");
992ed6b3 268 Standard_OutOfRange_Raise_if (theConcentration < 0.0f || theConcentration > 1.0f,
269 "Graphic3d_CLight::SetConcentration(), bad coefficient");
270 updateRevisionIf (Abs (changeConcentration() - theConcentration) > ShortRealEpsilon());
271 changeConcentration() = theConcentration;
272}
273
274// =======================================================================
275// function : SetSmoothRadius
276// purpose :
277// =======================================================================
278void Graphic3d_CLight::SetSmoothRadius (Standard_ShortReal theValue)
279{
06d40093 280 Standard_ProgramError_Raise_if (myType != Graphic3d_TypeOfLightSource_Positional
281 && myType != Graphic3d_TypeOfLightSource_Spot,
992ed6b3 282 "Graphic3d_CLight::SetSmoothRadius(), incorrect light type");
283 Standard_OutOfRange_Raise_if (theValue < 0.0f, "Graphic3d_CLight::SetSmoothRadius(), Bad value for smoothing radius");
284 updateRevisionIf (Abs (mySmoothness - theValue) > ShortRealEpsilon());
285 mySmoothness = theValue;
286}
287
288// =======================================================================
289// function : SetSmoothAngle
290// purpose :
291// =======================================================================
292void Graphic3d_CLight::SetSmoothAngle (Standard_ShortReal theValue)
293{
06d40093 294 Standard_ProgramError_Raise_if (myType != Graphic3d_TypeOfLightSource_Directional,
992ed6b3 295 "Graphic3d_CLight::SetSmoothAngle(), incorrect light type");
296 Standard_OutOfRange_Raise_if (theValue < 0.0f || theValue > Standard_ShortReal(M_PI / 2.0),
297 "Graphic3d_CLight::SetSmoothAngle(), Bad value for smoothing angle");
298 updateRevisionIf (Abs (mySmoothness - theValue) > ShortRealEpsilon());
299 mySmoothness = theValue;
300}
88b312d3 301
302// =======================================================================
303// function : SetRange
304// purpose :
305// =======================================================================
306void Graphic3d_CLight::SetRange (Standard_ShortReal theValue)
307{
06d40093 308 Standard_ProgramError_Raise_if (myType != Graphic3d_TypeOfLightSource_Positional
309 && myType != Graphic3d_TypeOfLightSource_Spot,
88b312d3 310 "Graphic3d_CLight::SetRange(), incorrect light type");
311 Standard_OutOfRange_Raise_if (theValue < 0.0, "Graphic3d_CLight::SetRange(), Bad value for falloff range");
312 updateRevisionIf (Abs (Range() - theValue) > ShortRealEpsilon());
313 myDirection.w() = theValue;
a5162275 314};
315
316//=======================================================================
317//function : DumpJson
318//purpose :
319//=======================================================================
320void Graphic3d_CLight::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
321{
322 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
323 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, this)
324
325 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, myId)
326 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, myName)
327
06d40093 328 if (myType == Graphic3d_TypeOfLightSource_Spot || myType == Graphic3d_TypeOfLightSource_Positional)
a5162275 329 {
330 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myPosition)
331 }
332 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myColor)
333 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIntensity)
334
06d40093 335 if (myType == Graphic3d_TypeOfLightSource_Spot || myType == Graphic3d_TypeOfLightSource_Directional)
a5162275 336 {
337 gp_Dir aDirection = Direction();
338 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &aDirection)
339 }
06d40093 340 if (myType == Graphic3d_TypeOfLightSource_Positional || myType == Graphic3d_TypeOfLightSource_Spot)
a5162275 341 {
342 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, ConstAttenuation())
343 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, LinearAttenuation())
344 }
06d40093 345 if (myType == Graphic3d_TypeOfLightSource_Spot)
a5162275 346 {
347 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, Angle())
348 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, Concentration())
349 }
06d40093 350 if (myType == Graphic3d_TypeOfLightSource_Positional || myType == Graphic3d_TypeOfLightSource_Spot)
a5162275 351 {
352 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, Range())
353 }
354
355 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, mySmoothness)
356 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myType)
357 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myRevision)
358 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsHeadlight)
359 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsEnabled)
360}