Refactor: move #object_usable_as_light() from #LightManager class to #Object

so that the function can also be used by other classes.
Also change `!bounds.valid()` to `!is_traceable()` so zero-sized objects
are skipped.
This commit is contained in:
Weizhen Huang
2023-04-03 10:54:17 +02:00
parent 4aed240b02
commit 1205111fe9
4 changed files with 34 additions and 35 deletions

View File

@@ -239,34 +239,6 @@ void LightManager::test_enabled_lights(Scene *scene)
}
}
bool LightManager::object_usable_as_light(Object *object)
{
Geometry *geom = object->get_geometry();
if (geom->geometry_type != Geometry::MESH && geom->geometry_type != Geometry::VOLUME) {
return false;
}
/* Skip objects with NaNs */
if (!object->bounds.valid()) {
return false;
}
/* Skip if we are not visible for BSDFs. */
if (!(object->get_visibility() & (PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY | PATH_RAY_TRANSMIT))) {
return false;
}
/* Skip if we have no emission shaders. */
/* TODO(sergey): Ideally we want to avoid such duplicated loop, since it'll
* iterate all geometry shaders twice (when counting and when calculating
* triangle area.
*/
foreach (Node *node, geom->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
if (shader->emission_sampling != EMISSION_SAMPLING_NONE) {
return true;
}
}
return false;
}
void LightManager::device_update_distribution(Device *,
DeviceScene *dscene,
Scene *scene,
@@ -284,7 +256,7 @@ void LightManager::device_update_distribution(Device *,
if (progress.get_cancel())
return;
if (!object_usable_as_light(object)) {
if (!object->usable_as_light()) {
continue;
}
@@ -329,7 +301,7 @@ void LightManager::device_update_distribution(Device *,
if (progress.get_cancel())
return;
if (!object_usable_as_light(object)) {
if (!object->usable_as_light()) {
j++;
continue;
}
@@ -510,7 +482,7 @@ void LightManager::device_update_tree(Device *,
if (progress.get_cancel())
return;
if (!object_usable_as_light(object)) {
if (!object->usable_as_light()) {
object_id++;
continue;
}

View File

@@ -21,7 +21,6 @@ CCL_NAMESPACE_BEGIN
class Device;
class DeviceScene;
class Object;
class Progress;
class Scene;
class Shader;
@@ -140,9 +139,6 @@ class LightManager {
Progress &progress);
void device_update_ies(DeviceScene *dscene);
/* Check whether light manager can use the object as a light-emissive. */
bool object_usable_as_light(Object *object);
struct IESSlot {
IESFile ies;
uint hash;

View File

@@ -370,6 +370,34 @@ int Object::get_device_index() const
return index;
}
bool Object::usable_as_light() const
{
Geometry *geom = get_geometry();
if (!geom->is_mesh() && !geom->is_volume()) {
return false;
}
/* Skip non-traceable objects. */
if (!is_traceable()) {
return false;
}
/* Skip if we are not visible for BSDFs. */
if (!(get_visibility() & (PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY | PATH_RAY_TRANSMIT))) {
return false;
}
/* Skip if we have no emission shaders. */
/* TODO(sergey): Ideally we want to avoid such duplicated loop, since it'll
* iterate all geometry shaders twice (when counting and when calculating
* triangle area.
*/
foreach (Node *node, geom->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
if (shader->emission_sampling != EMISSION_SAMPLING_NONE) {
return true;
}
}
return false;
}
/* Object Manager */
ObjectManager::ObjectManager()

View File

@@ -105,6 +105,9 @@ class Object : public Node {
/* Compute step size from attributes, shaders, transforms. */
float compute_volume_step_size() const;
/* Check whether this object can be used as light-emissive. */
bool usable_as_light() const;
protected:
/* Specifies the position of the object in scene->objects and
* in the device vectors. Gets set in device_update. */