1 // Copyright (c) 2017 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.
14 #include <Graphic3d_LightSet.hxx>
16 #include <NCollection_LocalArray.hxx>
18 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_LightSet, Standard_Transient)
22 //! Suffixes identifying light source type.
23 static const char THE_LIGHT_KEY_LETTERS[Graphic3d_TypeOfLightSource_NB] =
25 'a', // Graphic3d_TOLS_AMBIENT
26 'd', // Graphic3d_TOLS_DIRECTIONAL
27 'p', // Graphic3d_TOLS_POSITIONAL
28 's' // Graphic3d_TOLS_SPOT
32 // =======================================================================
33 // function : Graphic3d_LightSet
35 // =======================================================================
36 Graphic3d_LightSet::Graphic3d_LightSet()
37 : myAmbient (0.0f, 0.0f, 0.0f, 0.0f),
42 memset (myLightTypes, 0, sizeof(myLightTypes));
43 memset (myLightTypesEnabled, 0, sizeof(myLightTypesEnabled));
46 // =======================================================================
49 // =======================================================================
50 Standard_Boolean Graphic3d_LightSet::Add (const Handle(Graphic3d_CLight)& theLight)
52 if (theLight.IsNull())
54 throw Standard_ProgramError ("Graphic3d_LightSet::Add(), NULL argument");
57 const Standard_Integer anOldExtent = myLights.Extent();
58 const Standard_Integer anIndex = myLights.Add (theLight, 0);
59 if (anIndex <= anOldExtent)
61 return Standard_False;
64 myLightTypes[theLight->Type()] += 1;
65 myLights.ChangeFromIndex (anIndex) = theLight->Revision();
70 // =======================================================================
73 // =======================================================================
74 Standard_Boolean Graphic3d_LightSet::Remove (const Handle(Graphic3d_CLight)& theLight)
76 const Standard_Integer anIndToRemove = myLights.FindIndex (theLight);
77 if (anIndToRemove <= 0)
79 return Standard_False;
83 myLights.RemoveFromIndex (anIndToRemove);
84 myLightTypes[theLight->Type()] -= 1;
88 // =======================================================================
89 // function : UpdateRevision
91 // =======================================================================
92 Standard_Size Graphic3d_LightSet::UpdateRevision()
94 if (myCacheRevision == myRevision)
96 // check implicit updates of light sources
97 for (NCollection_IndexedDataMap<Handle(Graphic3d_CLight), Standard_Size>::Iterator aLightIter (myLights); aLightIter.More(); aLightIter.Next())
99 const Handle(Graphic3d_CLight)& aLight = aLightIter.Key();
100 if (aLightIter.Value() != aLight->Revision())
107 if (myCacheRevision == myRevision)
112 myCacheRevision = myRevision;
113 myAmbient.SetValues (0.0f, 0.0f, 0.0f, 0.0f);
114 memset (myLightTypesEnabled, 0, sizeof(myLightTypesEnabled));
115 NCollection_LocalArray<char, 32> aKeyLong (myLights.Extent() + 1);
116 Standard_Integer aLightLast = 0;
117 for (NCollection_IndexedDataMap<Handle(Graphic3d_CLight), Standard_Size>::Iterator aLightIter (myLights); aLightIter.More(); aLightIter.Next())
119 const Handle(Graphic3d_CLight)& aLight = aLightIter.Key();
120 aLightIter.ChangeValue() = aLight->Revision();
121 if (!aLight->IsEnabled())
126 myLightTypesEnabled[aLight->Type()] += 1;
127 if (aLight->Type() == Graphic3d_TOLS_AMBIENT)
129 myAmbient += aLight->PackedColor() * aLight->Intensity();
133 aKeyLong[aLightLast++] = THE_LIGHT_KEY_LETTERS[aLight->Type()];
136 aKeyLong[aLightLast] = '\0';
137 myAmbient.a() = 1.0f;
138 myNbEnabled = myLightTypesEnabled[Graphic3d_TOLS_DIRECTIONAL]
139 + myLightTypesEnabled[Graphic3d_TOLS_POSITIONAL]
140 + myLightTypesEnabled[Graphic3d_TOLS_SPOT];
141 myKeyEnabledLong = aKeyLong;
142 myKeyEnabledShort = TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_DIRECTIONAL] > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_DIRECTIONAL] : '\0')
143 + TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_POSITIONAL] > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_POSITIONAL] : '\0')
144 + TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_SPOT] > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_SPOT] : '\0');