Refactor: Move object foreach_id to new IDTypeInfo structure.
This commit is contained in:
parent
ce74df6248
commit
c732edbaa4
Notes:
blender-bot
2023-02-14 03:31:57 +01:00
Referenced by issue #76949, Crash When Selecting Materials Tab
|
@ -133,6 +133,9 @@ bool BKE_lib_query_foreachid_process(struct LibraryForeachIDData *data,
|
|||
struct ID **id_pp,
|
||||
int cb_flag);
|
||||
int BKE_lib_query_foreachid_process_flags_get(struct LibraryForeachIDData *data);
|
||||
int BKE_lib_query_foreachid_process_callback_flag_override(struct LibraryForeachIDData *data,
|
||||
const int cb_flag,
|
||||
const bool do_replace);
|
||||
|
||||
#define BKE_LIB_FOREACHID_PROCESS_ID(_data, _id, _cb_flag) \
|
||||
{ \
|
||||
|
|
|
@ -205,6 +205,20 @@ int BKE_lib_query_foreachid_process_flags_get(LibraryForeachIDData *data)
|
|||
return data->flag;
|
||||
}
|
||||
|
||||
int BKE_lib_query_foreachid_process_callback_flag_override(LibraryForeachIDData *data,
|
||||
const int cb_flag,
|
||||
const bool do_replace)
|
||||
{
|
||||
const int cb_flag_backup = data->cb_flag;
|
||||
if (do_replace) {
|
||||
data->cb_flag = cb_flag;
|
||||
}
|
||||
else {
|
||||
data->cb_flag |= cb_flag;
|
||||
}
|
||||
return cb_flag_backup;
|
||||
}
|
||||
|
||||
static void library_foreach_ID_link(Main *bmain,
|
||||
ID *id_owner,
|
||||
ID *id,
|
||||
|
@ -232,62 +246,6 @@ static void library_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNU
|
|||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_modifiersForeachIDLink(void *user_data,
|
||||
Object *UNUSED(object),
|
||||
ID **id_pointer,
|
||||
int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_gpencil_modifiersForeachIDLink(void *user_data,
|
||||
Object *UNUSED(object),
|
||||
ID **id_pointer,
|
||||
int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_shaderfxForeachIDLink(void *user_data,
|
||||
Object *UNUSED(object),
|
||||
ID **id_pointer,
|
||||
int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con),
|
||||
ID **id_pointer,
|
||||
bool is_reference,
|
||||
void *user_data)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
|
||||
const int cb_flag = is_reference ? IDWALK_CB_USER : IDWALK_CB_NOP;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_particlesystemsObjectLooper(ParticleSystem *UNUSED(psys),
|
||||
ID **id_pointer,
|
||||
void *user_data,
|
||||
int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_nla_strip(LibraryForeachIDData *data, NlaStrip *strip)
|
||||
{
|
||||
FOREACH_CALLBACK_INVOKE(data, strip->act, IDWALK_CB_USER);
|
||||
|
@ -396,7 +354,6 @@ static void library_foreach_ID_link(Main *bmain,
|
|||
LibraryForeachIDData *inherit_data)
|
||||
{
|
||||
LibraryForeachIDData data = {.bmain = bmain};
|
||||
int i;
|
||||
|
||||
BLI_assert(inherit_data == NULL || data.bmain == inherit_data->bmain);
|
||||
|
||||
|
@ -621,104 +578,7 @@ static void library_foreach_ID_link(Main *bmain,
|
|||
}
|
||||
|
||||
case ID_OB: {
|
||||
Object *object = (Object *)id;
|
||||
|
||||
/* Object is special, proxies make things hard... */
|
||||
const int data_cb_flag = data.cb_flag;
|
||||
const int proxy_cb_flag = ((data.flag & IDWALK_NO_INDIRECT_PROXY_DATA_USAGE) == 0 &&
|
||||
(object->proxy || object->proxy_group)) ?
|
||||
IDWALK_CB_INDIRECT_USAGE :
|
||||
0;
|
||||
|
||||
/* object data special case */
|
||||
data.cb_flag |= proxy_cb_flag;
|
||||
if (object->type == OB_EMPTY) {
|
||||
/* empty can have NULL or Image */
|
||||
CALLBACK_INVOKE_ID(object->data, IDWALK_CB_USER);
|
||||
}
|
||||
else {
|
||||
/* when set, this can't be NULL */
|
||||
if (object->data) {
|
||||
CALLBACK_INVOKE_ID(object->data, IDWALK_CB_USER | IDWALK_CB_NEVER_NULL);
|
||||
}
|
||||
}
|
||||
data.cb_flag = data_cb_flag;
|
||||
|
||||
CALLBACK_INVOKE(object->parent, IDWALK_CB_NEVER_SELF);
|
||||
CALLBACK_INVOKE(object->track, IDWALK_CB_NEVER_SELF);
|
||||
/* object->proxy is refcounted, but not object->proxy_group... *sigh* */
|
||||
CALLBACK_INVOKE(object->proxy, IDWALK_CB_USER | IDWALK_CB_NEVER_SELF);
|
||||
CALLBACK_INVOKE(object->proxy_group, IDWALK_CB_NOP);
|
||||
|
||||
/* Special case!
|
||||
* Since this field is set/owned by 'user' of this ID (and not ID itself),
|
||||
* it is only indirect usage if proxy object is linked... Twisted. */
|
||||
if (object->proxy_from) {
|
||||
data.cb_flag = ID_IS_LINKED(object->proxy_from) ? IDWALK_CB_INDIRECT_USAGE : 0;
|
||||
}
|
||||
CALLBACK_INVOKE(object->proxy_from, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF);
|
||||
data.cb_flag = data_cb_flag;
|
||||
|
||||
CALLBACK_INVOKE(object->poselib, IDWALK_CB_USER);
|
||||
|
||||
data.cb_flag |= proxy_cb_flag;
|
||||
for (i = 0; i < object->totcol; i++) {
|
||||
CALLBACK_INVOKE(object->mat[i], IDWALK_CB_USER);
|
||||
}
|
||||
data.cb_flag = data_cb_flag;
|
||||
|
||||
/* Note that ob->gpd is deprecated, so no need to handle it here. */
|
||||
CALLBACK_INVOKE(object->instance_collection, IDWALK_CB_USER);
|
||||
|
||||
if (object->pd) {
|
||||
CALLBACK_INVOKE(object->pd->tex, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(object->pd->f_source, IDWALK_CB_NOP);
|
||||
}
|
||||
/* Note that ob->effect is deprecated, so no need to handle it here. */
|
||||
|
||||
if (object->pose) {
|
||||
data.cb_flag |= proxy_cb_flag;
|
||||
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
|
||||
IDP_foreach_property(pchan->prop,
|
||||
IDP_TYPE_FILTER_ID,
|
||||
BKE_lib_query_idpropertiesForeachIDLink_callback,
|
||||
&data);
|
||||
CALLBACK_INVOKE(pchan->custom, IDWALK_CB_USER);
|
||||
BKE_constraints_id_loop(
|
||||
&pchan->constraints, library_foreach_constraintObjectLooper, &data);
|
||||
}
|
||||
data.cb_flag = data_cb_flag;
|
||||
}
|
||||
|
||||
if (object->rigidbody_constraint) {
|
||||
CALLBACK_INVOKE(object->rigidbody_constraint->ob1, IDWALK_CB_NEVER_SELF);
|
||||
CALLBACK_INVOKE(object->rigidbody_constraint->ob2, IDWALK_CB_NEVER_SELF);
|
||||
}
|
||||
|
||||
if (object->lodlevels.first) {
|
||||
LISTBASE_FOREACH (LodLevel *, level, &object->lodlevels) {
|
||||
CALLBACK_INVOKE(level->source, IDWALK_CB_NEVER_SELF);
|
||||
}
|
||||
}
|
||||
|
||||
BKE_modifiers_foreach_ID_link(object, library_foreach_modifiersForeachIDLink, &data);
|
||||
BKE_gpencil_modifiers_foreach_ID_link(
|
||||
object, library_foreach_gpencil_modifiersForeachIDLink, &data);
|
||||
BKE_constraints_id_loop(
|
||||
&object->constraints, library_foreach_constraintObjectLooper, &data);
|
||||
BKE_shaderfx_foreach_ID_link(object, library_foreach_shaderfxForeachIDLink, &data);
|
||||
|
||||
LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
|
||||
BKE_particlesystem_id_loop(psys, library_foreach_particlesystemsObjectLooper, &data);
|
||||
}
|
||||
|
||||
if (object->soft) {
|
||||
CALLBACK_INVOKE(object->soft->collision_group, IDWALK_CB_NOP);
|
||||
|
||||
if (object->soft->effector_weights) {
|
||||
CALLBACK_INVOKE(object->soft->effector_weights->group, IDWALK_CB_NOP);
|
||||
}
|
||||
}
|
||||
BLI_assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -375,6 +375,153 @@ static void object_make_local(Main *bmain, ID *id, const int flags)
|
|||
}
|
||||
}
|
||||
|
||||
static void library_foreach_modifiersForeachIDLink(void *user_data,
|
||||
Object *UNUSED(object),
|
||||
ID **id_pointer,
|
||||
int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
|
||||
BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
|
||||
}
|
||||
|
||||
static void library_foreach_gpencil_modifiersForeachIDLink(void *user_data,
|
||||
Object *UNUSED(object),
|
||||
ID **id_pointer,
|
||||
int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
|
||||
BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
|
||||
}
|
||||
|
||||
static void library_foreach_shaderfxForeachIDLink(void *user_data,
|
||||
Object *UNUSED(object),
|
||||
ID **id_pointer,
|
||||
int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
|
||||
BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
|
||||
}
|
||||
|
||||
static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con),
|
||||
ID **id_pointer,
|
||||
bool is_reference,
|
||||
void *user_data)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
|
||||
const int cb_flag = is_reference ? IDWALK_CB_USER : IDWALK_CB_NOP;
|
||||
BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
|
||||
}
|
||||
|
||||
static void library_foreach_particlesystemsObjectLooper(ParticleSystem *UNUSED(psys),
|
||||
ID **id_pointer,
|
||||
void *user_data,
|
||||
int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
|
||||
BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
|
||||
}
|
||||
|
||||
static void object_foreach_id(ID *id, LibraryForeachIDData *data)
|
||||
{
|
||||
Object *object = (Object *)id;
|
||||
|
||||
/* Object is special, proxies make things hard... */
|
||||
const int proxy_cb_flag = ((BKE_lib_query_foreachid_process_flags_get(data) &
|
||||
IDWALK_NO_INDIRECT_PROXY_DATA_USAGE) == 0 &&
|
||||
(object->proxy || object->proxy_group)) ?
|
||||
IDWALK_CB_INDIRECT_USAGE :
|
||||
0;
|
||||
|
||||
/* object data special case */
|
||||
if (object->type == OB_EMPTY) {
|
||||
/* empty can have NULL or Image */
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, object->data, proxy_cb_flag | IDWALK_CB_USER);
|
||||
}
|
||||
else {
|
||||
/* when set, this can't be NULL */
|
||||
if (object->data) {
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(
|
||||
data, object->data, proxy_cb_flag | IDWALK_CB_USER | IDWALK_CB_NEVER_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->parent, IDWALK_CB_NEVER_SELF);
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->track, IDWALK_CB_NEVER_SELF);
|
||||
/* object->proxy is refcounted, but not object->proxy_group... *sigh* */
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->proxy, IDWALK_CB_USER | IDWALK_CB_NEVER_SELF);
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->proxy_group, IDWALK_CB_NOP);
|
||||
|
||||
/* Special case!
|
||||
* Since this field is set/owned by 'user' of this ID (and not ID itself),
|
||||
* it is only indirect usage if proxy object is linked... Twisted. */
|
||||
{
|
||||
const int cb_flag_orig = BKE_lib_query_foreachid_process_callback_flag_override(
|
||||
data,
|
||||
(object->proxy_from != NULL && ID_IS_LINKED(object->proxy_from)) ?
|
||||
IDWALK_CB_INDIRECT_USAGE :
|
||||
0,
|
||||
true);
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->proxy_from, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF);
|
||||
BKE_lib_query_foreachid_process_callback_flag_override(data, cb_flag_orig, true);
|
||||
}
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->poselib, IDWALK_CB_USER);
|
||||
|
||||
for (int i = 0; i < object->totcol; i++) {
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->mat[i], proxy_cb_flag | IDWALK_CB_USER);
|
||||
}
|
||||
|
||||
/* Note that ob->gpd is deprecated, so no need to handle it here. */
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->instance_collection, IDWALK_CB_USER);
|
||||
|
||||
if (object->pd) {
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->pd->tex, IDWALK_CB_USER);
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->pd->f_source, IDWALK_CB_NOP);
|
||||
}
|
||||
/* Note that ob->effect is deprecated, so no need to handle it here. */
|
||||
|
||||
if (object->pose) {
|
||||
const int cb_flag_orig = BKE_lib_query_foreachid_process_callback_flag_override(
|
||||
data, proxy_cb_flag, false);
|
||||
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
|
||||
IDP_foreach_property(
|
||||
pchan->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
|
||||
BKE_LIB_FOREACHID_PROCESS(data, pchan->custom, IDWALK_CB_USER);
|
||||
BKE_constraints_id_loop(&pchan->constraints, library_foreach_constraintObjectLooper, data);
|
||||
}
|
||||
BKE_lib_query_foreachid_process_callback_flag_override(data, cb_flag_orig, true);
|
||||
}
|
||||
|
||||
if (object->rigidbody_constraint) {
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->rigidbody_constraint->ob1, IDWALK_CB_NEVER_SELF);
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->rigidbody_constraint->ob2, IDWALK_CB_NEVER_SELF);
|
||||
}
|
||||
|
||||
if (object->lodlevels.first) {
|
||||
LISTBASE_FOREACH (LodLevel *, level, &object->lodlevels) {
|
||||
BKE_LIB_FOREACHID_PROCESS(data, level->source, IDWALK_CB_NEVER_SELF);
|
||||
}
|
||||
}
|
||||
|
||||
BKE_modifiers_foreach_ID_link(object, library_foreach_modifiersForeachIDLink, data);
|
||||
BKE_gpencil_modifiers_foreach_ID_link(
|
||||
object, library_foreach_gpencil_modifiersForeachIDLink, &data);
|
||||
BKE_constraints_id_loop(&object->constraints, library_foreach_constraintObjectLooper, data);
|
||||
BKE_shaderfx_foreach_ID_link(object, library_foreach_shaderfxForeachIDLink, data);
|
||||
|
||||
LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
|
||||
BKE_particlesystem_id_loop(psys, library_foreach_particlesystemsObjectLooper, data);
|
||||
}
|
||||
|
||||
if (object->soft) {
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->soft->collision_group, IDWALK_CB_NOP);
|
||||
|
||||
if (object->soft->effector_weights) {
|
||||
BKE_LIB_FOREACHID_PROCESS(data, object->soft->effector_weights->group, IDWALK_CB_NOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IDTypeInfo IDType_ID_OB = {
|
||||
.id_code = ID_OB,
|
||||
.id_filter = FILTER_ID_OB,
|
||||
|
@ -389,6 +536,7 @@ IDTypeInfo IDType_ID_OB = {
|
|||
.copy_data = object_copy_data,
|
||||
.free_data = object_free_data,
|
||||
.make_local = object_make_local,
|
||||
.foreach_id = object_foreach_id,
|
||||
};
|
||||
|
||||
void BKE_object_workob_clear(Object *workob)
|
||||
|
|
Loading…
Reference in New Issue