54bool is_valid_input_id(
const ID &
id)
76class LightSetIDManager {
80 explicit LightSetIDManager(
const Scene &scene) : scene_(scene) {}
90 const uint64_t light_set_id = light_set_id_map_.lookup_or_add_cb(light_set, [&]() {
91 const uint64_t new_light_set_id = next_light_set_id_++;
94 printf(
"Maximum number of light linking sets (%d) exceeded scene \"%s\".\n",
99 return new_light_set_id;
146 emitter_data_map_.clear();
147 next_collection_id_ = 0;
154 const Collection *collection = get_collection(emitter);
166 EmitterData &emitter_data = emitter_data_map_.lookup_or_add_cb(collection, [&]() {
167 const uint64_t collection_id = next_collection_id_++;
173 printf(
"Maximum number of light linking collections (%d) exceeded in scene \"%s\".\n",
183 return new_emitter_data;
190 return &emitter_data;
195 const Collection *collection_eval = get_collection(emitter);
197 if (!collection_eval) {
203 return emitter_data_map_.lookup_ptr(collection_orig);
210 const Collection *collection = get_collection(emitter);
216 return emitter_data_map_.contains(collection);
223 light_linked_sets_.clear();
224 object_light_sets_.clear();
231 LightSet &light_set = ensure_light_set_for(
object);
233 switch (link_state) {
250 return light_linked_sets_.lookup_or_add_as(&
object);
253void LinkingData::clear_after_build()
255 light_linked_sets_.clear();
260 LightSetIDManager light_set_id_manager(scene);
262 for (
const auto it : light_linked_sets_.items()) {
263 const Object *receiver = it.key;
267 if (!light_set_id_manager.get(light_set, light_set_id)) {
273 object_light_sets_.add(receiver, light_set_id);
275 update_emitters_membership(emitter_data_map, light_set, light_set_mask);
281void LinkingData::update_emitters_membership(
EmitterDataMap &emitter_data_map,
318 foreach_light_collection_object_inner(
319 collection_light_linking, *collection_child->collection, callback);
323 callback(collection_light_linking, *collection_object->ob);
336void foreach_light_collection_object(
const Collection &collection, Proc &&callback)
339 foreach_light_collection_object_inner(
340 collection_child->light_linking, *collection_child->collection, callback);
344 callback(collection_object->light_linking, *collection_object->ob);
352 light_emitter_data_map_.clear();
353 shadow_emitter_data_map_.clear();
355 light_linking_.clear();
356 shadow_linking_.clear();
363 add_light_linking_emitter(scene, emitter);
364 add_shadow_linking_emitter(scene, emitter);
367void Cache::add_light_linking_emitter(
const Scene &scene,
const Object &emitter)
377 if (light_emitter_data) {
378 foreach_light_collection_object(
381 add_receiver_object(*light_emitter_data, collection_light_linking, receiver);
386void Cache::add_shadow_linking_emitter(
const Scene &scene,
const Object &emitter)
394 const EmitterData *shadow_emitter_data = shadow_emitter_data_map_.ensure_data_if_possible(
396 if (shadow_emitter_data) {
397 foreach_light_collection_object(
400 add_blocker_object(*shadow_emitter_data, collection_light_linking, receiver);
405void Cache::add_receiver_object(
const EmitterData &emitter_data,
411 light_linking_.link_object(
415void Cache::add_blocker_object(
const EmitterData &emitter_data,
421 shadow_linking_.link_object(
427 if (!has_light_linking()) {
431 light_linking_.end_build(scene, light_emitter_data_map_);
432 shadow_linking_.end_build(scene, shadow_emitter_data_map_);
440 if (!has_light_linking()) {
456 const EmitterData *light_emitter_data = light_emitter_data_map_.get_data(object_eval);
457 if (light_emitter_data) {
464 const EmitterData *shadow_emitter_data = shadow_emitter_data_map_.get_data(object_eval);
465 if (shadow_emitter_data) {
472 const bool need_runtime = (memcmp(&runtime, &runtime_no_links,
sizeof(runtime)) != 0);
483 else if (need_runtime) {
void BKE_light_linking_free_if_empty(struct Object *object)
void BKE_light_linking_ensure(struct Object *object)
#define LISTBASE_FOREACH(type, var, list)
bool DEG_is_original(const T *id)
T * DEG_get_original(T *id)
Object groups, one object can be in many groups at once.
eCollectionLightLinkingState
@ COLLECTION_LIGHT_LINKING_STATE_EXCLUDE
@ COLLECTION_LIGHT_LINKING_STATE_INCLUDE
struct CollectionObject CollectionObject
struct CollectionLightLinking CollectionLightLinking
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
BPy_StructRNA * depsgraph
unsigned long long int uint64_t
void eval_runtime_data(Object &object_eval) const
void add_emitter(const Scene &scene, const Object &emitter)
void end_build(const Scene &scene)
bool can_skip_emitter(const Object &emitter) const
EmitterData * ensure_data_if_possible(const Scene &scene, const Object &emitter)
MapType::MutableValueIterator values()
const EmitterData * get_data(const Object &emitter) const
static constexpr int MAX_COLLECTION_ID
EmitterSetMembership light_membership
EmitterSetMembership shadow_membership
uint64_t get_mask() const
static constexpr uint64_t SET_MEMBERSHIP_ALL
uint64_t included_sets_mask
uint64_t excluded_sets_mask
uint64_t include_collection_mask
static constexpr int MAX_ID
bool operator==(const LightSet &other) const
uint64_t exclude_collection_mask
static constexpr int DEFAULT_ID
uint64_t get_light_set_for(const Object &object) const
void end_build(const Scene &scene, EmitterDataMap &emitter_data_map)
void link_object(const EmitterData &emitter_data, eCollectionLightLinkingState link_state, const Object &object)
internal::LightSet LightSet
internal::EmitterSetMembership EmitterSetMembership
void eval_runtime_data(const ::Depsgraph *depsgraph, Object &object_eval)
internal::EmitterData EmitterData
internal::LinkingData LinkingData
internal::EmitterDataMap EmitterDataMap
uint64_t get_default_hash(const T &v, const Args &...args)
uint8_t blocker_shadow_set
uint8_t receiver_light_set
uint64_t light_set_membership
uint64_t shadow_set_membership
struct Collection * blocker_collection
LightLinkingRuntime runtime
struct Collection * receiver_collection
LightLinking * light_linking
light_linking::Cache light_linking_cache