Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// 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 <Graphic3d_LightSet.hxx>
#include <NCollection_LocalArray.hxx>
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_TypeOfLightSource_Ambient
'd', // Graphic3d_TypeOfLightSource_Directional
'p', // Graphic3d_TypeOfLightSource_Positional
's' // Graphic3d_TypeOfLightSource_Spot
};
} // namespace
//=================================================================================================
Graphic3d_LightSet::Graphic3d_LightSet()
: myAmbient(0.0f, 0.0f, 0.0f, 0.0f),
myNbEnabled(0),
myNbCastShadows(0),
myRevision(1),
myCacheRevision(0)
{
memset(myLightTypes, 0, sizeof(myLightTypes));
memset(myLightTypesEnabled, 0, sizeof(myLightTypesEnabled));
}
//=================================================================================================
bool Graphic3d_LightSet::Add(const occ::handle<Graphic3d_CLight>& theLight)
{
if (theLight.IsNull())
{
throw Standard_ProgramError("Graphic3d_LightSet::Add(), NULL argument");
}
const int anOldExtent = myLights.Extent();
const int anIndex = myLights.Add(theLight, 0);
if (anIndex <= anOldExtent)
{
return false;
}
myLightTypes[theLight->Type()] += 1;
myLights.ChangeFromIndex(anIndex) = theLight->Revision();
++myRevision;
return true;
}
//=================================================================================================
bool Graphic3d_LightSet::Remove(const occ::handle<Graphic3d_CLight>& theLight)
{
const int anIndToRemove = myLights.FindIndex(theLight);
if (anIndToRemove <= 0)
{
return false;
}
++myRevision;
myLights.RemoveFromIndex(anIndToRemove);
myLightTypes[theLight->Type()] -= 1;
return true;
}
//=================================================================================================
size_t Graphic3d_LightSet::UpdateRevision()
{
if (myCacheRevision == myRevision)
{
// check implicit updates of light sources
for (NCollection_IndexedDataMap<occ::handle<Graphic3d_CLight>, size_t>::Iterator aLightIter(
myLights);
aLightIter.More();
aLightIter.Next())
{
const occ::handle<Graphic3d_CLight>& aLight = aLightIter.Key();
if (aLightIter.Value() != aLight->Revision())
{
++myRevision;
break;
}
}
}
if (myCacheRevision == myRevision)
{
return myRevision;
}
myCacheRevision = myRevision;
myNbCastShadows = 0;
myAmbient.SetValues(0.0f, 0.0f, 0.0f, 0.0f);
memset(myLightTypesEnabled, 0, sizeof(myLightTypesEnabled));
NCollection_LocalArray<char, 32> aKeyLong(myLights.Extent() + 1);
int aLightLast = 0;
for (NCollection_IndexedDataMap<occ::handle<Graphic3d_CLight>, size_t>::Iterator aLightIter(
myLights);
aLightIter.More();
aLightIter.Next())
{
const occ::handle<Graphic3d_CLight>& aLight = aLightIter.Key();
aLightIter.ChangeValue() = aLight->Revision();
if (!aLight->IsEnabled())
{
continue;
}
myLightTypesEnabled[aLight->Type()] += 1;
if (aLight->Type() == Graphic3d_TypeOfLightSource_Ambient)
{
myAmbient += aLight->PackedColor() * aLight->Intensity();
}
else
{
if (aLight->ToCastShadows())
{
++myNbCastShadows;
aKeyLong[aLightLast++] = UpperCase(THE_LIGHT_KEY_LETTERS[aLight->Type()]);
}
else
{
aKeyLong[aLightLast++] = THE_LIGHT_KEY_LETTERS[aLight->Type()];
}
}
}
aKeyLong[aLightLast] = '\0';
myAmbient.a() = 1.0f;
myNbEnabled = myLightTypesEnabled[Graphic3d_TypeOfLightSource_Directional]
+ myLightTypesEnabled[Graphic3d_TypeOfLightSource_Positional]
+ myLightTypesEnabled[Graphic3d_TypeOfLightSource_Spot];
myKeyEnabledLong = aKeyLong;
myKeyEnabledShort =
TCollection_AsciiString(myLightTypesEnabled[Graphic3d_TypeOfLightSource_Directional] > 0
? THE_LIGHT_KEY_LETTERS[Graphic3d_TypeOfLightSource_Directional]
: '\0')
+ TCollection_AsciiString(myLightTypesEnabled[Graphic3d_TypeOfLightSource_Positional] > 0
? THE_LIGHT_KEY_LETTERS[Graphic3d_TypeOfLightSource_Positional]
: '\0')
+ TCollection_AsciiString(myLightTypesEnabled[Graphic3d_TypeOfLightSource_Spot] > 0
? THE_LIGHT_KEY_LETTERS[Graphic3d_TypeOfLightSource_Spot]
: '\0');
return myRevision;
}