Refactor: LightLinking: Add creation/copy/delete API for Object data.

Similar to what we do with modifiers, constraints, and so on. Avoids
spreading knowledge about internal data handling in several parts of the
code.

Pull Request: https://projects.blender.org/blender/blender/pulls/147122
This commit is contained in:
Bastien Montagne
2025-10-01 15:03:41 +02:00
committed by Bastien Montagne
parent 04166ea0ea
commit 3f6ef965b9
5 changed files with 63 additions and 11 deletions

View File

@@ -25,6 +25,29 @@ typedef enum LightLinkingType {
LIGHT_LINKING_BLOCKER,
} LightLinkingType;
/**
* Add an empty LightLinking data to an Object.
*/
void BKE_light_linking_ensure(struct Object *object);
/**
* Copy the LightLinking data from `object_src` to `object_dst`.
*
* \param copy_flags Flags controlling the copy process, see e.g. #LIB_ID_CREATE_NO_USER_REFCOUNT
* and related flags in the same enum.
*/
void BKE_light_linking_copy(struct Object *object_dst,
const struct Object *object_src,
const int copy_flags);
/**
* Free the LightLinking data from the object.
*
* \param copy_flags Flags controlling the copy process, see e.g. #LIB_ID_CREATE_NO_USER_REFCOUNT
* and related flags in the same enum.
*/
void BKE_light_linking_delete(struct Object *object, const int delete_flags);
/**
* Free object's light_linking if it is not needed to hold any of collections.
*/

View File

@@ -27,12 +27,43 @@
#include "DEG_depsgraph.hh"
#include "DEG_depsgraph_build.hh"
void BKE_light_linking_ensure(struct Object *object)
{
if (object->light_linking == nullptr) {
object->light_linking = MEM_callocN<LightLinking>(__func__);
}
}
void BKE_light_linking_copy(Object *object_dst, const Object *object_src, const int copy_flags)
{
BLI_assert(ELEM(object_dst->light_linking, nullptr, object_src->light_linking));
if (object_src->light_linking) {
object_dst->light_linking = MEM_dupallocN<LightLinking>(__func__,
*(object_src->light_linking));
if ((copy_flags & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
id_us_plus(blender::id_cast<ID *>(object_dst->light_linking->receiver_collection));
id_us_plus(blender::id_cast<ID *>(object_dst->light_linking->blocker_collection));
}
}
}
void BKE_light_linking_delete(struct Object *object, const int delete_flags)
{
if (object->light_linking) {
if ((delete_flags & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
id_us_min(blender::id_cast<ID *>(object->light_linking->receiver_collection));
id_us_min(blender::id_cast<ID *>(object->light_linking->blocker_collection));
}
MEM_SAFE_FREE(object->light_linking);
}
}
void BKE_light_linking_free_if_empty(Object *object)
{
if (object->light_linking->receiver_collection == nullptr &&
object->light_linking->blocker_collection == nullptr)
{
MEM_SAFE_FREE(object->light_linking);
BKE_light_linking_delete(object, LIB_ID_CREATE_NO_USER_REFCOUNT);
}
}
@@ -97,8 +128,8 @@ void BKE_light_linking_collection_assign_only(Object *object,
}
/* Allocate light linking on demand. */
if (new_collection && !object->light_linking) {
object->light_linking = MEM_callocN<LightLinking>(__func__);
if (new_collection) {
BKE_light_linking_ensure(object);
}
if (object->light_linking) {

View File

@@ -101,6 +101,7 @@
#include "BKE_lib_remap.hh"
#include "BKE_library.hh"
#include "BKE_light.h"
#include "BKE_light_linking.h"
#include "BKE_lightprobe.h"
#include "BKE_linestyle.h"
#include "BKE_main.hh"
@@ -266,9 +267,7 @@ static void object_copy_data(Main *bmain,
if (ob_src->lightgroup) {
ob_dst->lightgroup = (LightgroupMembership *)MEM_dupallocN(ob_src->lightgroup);
}
if (ob_src->light_linking) {
ob_dst->light_linking = (LightLinking *)MEM_dupallocN(ob_src->light_linking);
}
BKE_light_linking_copy(ob_dst, ob_src, flag_subdata);
if ((flag & LIB_ID_COPY_SET_COPIED_ON_WRITE) != 0) {
if (ob_src->lightprobe_cache) {
@@ -332,7 +331,7 @@ static void object_free_data(ID *id)
BKE_previewimg_free(&ob->preview);
MEM_SAFE_FREE(ob->lightgroup);
MEM_SAFE_FREE(ob->light_linking);
BKE_light_linking_delete(ob, LIB_ID_CREATE_NO_USER_REFCOUNT);
BKE_lightprobe_cache_free(ob);

View File

@@ -481,7 +481,7 @@ void Cache::eval_runtime_data(Object &object_eval) const
}
}
else if (need_runtime) {
object_eval.light_linking = MEM_callocN<LightLinking>(__func__);
BKE_light_linking_ensure(&object_eval);
object_eval.light_linking->runtime = runtime;
}
}

View File

@@ -17,6 +17,7 @@
#include "BLI_listbase.h"
#include "BKE_action.hh"
#include "BKE_light_linking.h"
#include "BKE_mesh_types.hh"
#include "BKE_modifier.hh"
#include "BKE_object.hh"
@@ -131,9 +132,7 @@ void ObjectRuntimeBackup::restore_to_object(Object *object)
if (light_linking_runtime) {
/* Lazily allocate light linking on the evaluated object for the cases when the object is only
* a receiver or a blocker and does not need its own LightLinking on the original object. */
if (!object->light_linking) {
object->light_linking = MEM_callocN<LightLinking>(__func__);
}
BKE_light_linking_ensure(object);
object->light_linking->runtime = *light_linking_runtime;
}