// Copyright (c) 2017 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_LightSet, Standard_Transient) namespace { //! Suffixes identifying light source type. static const char THE_LIGHT_KEY_LETTERS[Graphic3d_TypeOfLightSource_NB] = { 'a', // Graphic3d_TOLS_AMBIENT 'd', // Graphic3d_TOLS_DIRECTIONAL 'p', // Graphic3d_TOLS_POSITIONAL 's' // Graphic3d_TOLS_SPOT }; } // ======================================================================= // function : Graphic3d_LightSet // purpose : // ======================================================================= Graphic3d_LightSet::Graphic3d_LightSet() : myAmbient (0.0f, 0.0f, 0.0f, 0.0f), myNbEnabled (0), myRevision (1), myCacheRevision (0) { memset (myLightTypes, 0, sizeof(myLightTypes)); memset (myLightTypesEnabled, 0, sizeof(myLightTypesEnabled)); } // ======================================================================= // function : Add // purpose : // ======================================================================= Standard_Boolean Graphic3d_LightSet::Add (const Handle(Graphic3d_CLight)& theLight) { if (theLight.IsNull()) { throw Standard_ProgramError ("Graphic3d_LightSet::Add(), NULL argument"); } const Standard_Integer anOldExtent = myLights.Extent(); const Standard_Integer anIndex = myLights.Add (theLight, 0); if (anIndex <= anOldExtent) { return Standard_False; } myLightTypes[theLight->Type()] += 1; myLights.ChangeFromIndex (anIndex) = theLight->Revision(); ++myRevision; return Standard_True; } // ======================================================================= // function : Remove // purpose : // ======================================================================= Standard_Boolean Graphic3d_LightSet::Remove (const Handle(Graphic3d_CLight)& theLight) { const Standard_Integer anIndToRemove = myLights.FindIndex (theLight); if (anIndToRemove <= 0) { return Standard_False; } ++myRevision; myLights.RemoveFromIndex (anIndToRemove); myLightTypes[theLight->Type()] -= 1; return Standard_True; } // ======================================================================= // function : UpdateRevision // purpose : // ======================================================================= Standard_Size Graphic3d_LightSet::UpdateRevision() { if (myCacheRevision == myRevision) { // check implicit updates of light sources for (NCollection_IndexedDataMap::Iterator aLightIter (myLights); aLightIter.More(); aLightIter.Next()) { const Handle(Graphic3d_CLight)& aLight = aLightIter.Key(); if (aLightIter.Value() != aLight->Revision()) { ++myRevision; break; } } } if (myCacheRevision == myRevision) { return myRevision; } myCacheRevision = myRevision; myAmbient.SetValues (0.0f, 0.0f, 0.0f, 0.0f); memset (myLightTypesEnabled, 0, sizeof(myLightTypesEnabled)); NCollection_LocalArray aKeyLong (myLights.Extent() + 1); Standard_Integer aLightLast = 0; for (NCollection_IndexedDataMap::Iterator aLightIter (myLights); aLightIter.More(); aLightIter.Next()) { const Handle(Graphic3d_CLight)& aLight = aLightIter.Key(); aLightIter.ChangeValue() = aLight->Revision(); if (!aLight->IsEnabled()) { continue; } myLightTypesEnabled[aLight->Type()] += 1; if (aLight->Type() == Graphic3d_TOLS_AMBIENT) { myAmbient += aLight->PackedColor() * aLight->Intensity(); } else { aKeyLong[aLightLast++] = THE_LIGHT_KEY_LETTERS[aLight->Type()]; } } aKeyLong[aLightLast] = '\0'; myAmbient.a() = 1.0f; myNbEnabled = myLightTypesEnabled[Graphic3d_TOLS_DIRECTIONAL] + myLightTypesEnabled[Graphic3d_TOLS_POSITIONAL] + myLightTypesEnabled[Graphic3d_TOLS_SPOT]; myKeyEnabledLong = aKeyLong; myKeyEnabledShort = TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_DIRECTIONAL] > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_DIRECTIONAL] : '\0') + TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_POSITIONAL] > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_POSITIONAL] : '\0') + TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_SPOT] > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_SPOT] : '\0'); return myRevision; }