Remove internal proxy code, and deprecate related DNA data.

Part of T91671.

Not much else to say, this is mainly a massive deletion of code.

Note that a few cleanups possible after this proxy removal were kept out
of this commit to try to reduce a bit its size.

Reviewed By: sergey, brecht

Maniphest Tasks: T91671

Differential Revision: https://developer.blender.org/D13995
This commit is contained in:
Bastien Montagne
2022-02-03 17:57:40 +01:00
committed by Bastien Montagne
parent 5a4eadc2e7
commit e9fc25835f
59 changed files with 69 additions and 1299 deletions

View File

@@ -365,7 +365,6 @@ void what_does_obaction(struct Object *ob,
char groupname[],
const struct AnimationEvalContext *anim_eval_context);
/* for proxy */
void BKE_pose_copy_pchan_result(struct bPoseChannel *pchanto,
const struct bPoseChannel *pchanfrom);
/**

View File

@@ -619,14 +619,6 @@ void BKE_pose_eval_cleanup(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *object);
void BKE_pose_eval_proxy_init(struct Depsgraph *depsgraph, struct Object *object);
void BKE_pose_eval_proxy_done(struct Depsgraph *depsgraph, struct Object *object);
void BKE_pose_eval_proxy_cleanup(struct Depsgraph *depsgraph, struct Object *object);
void BKE_pose_eval_proxy_copy_bone(struct Depsgraph *depsgraph,
struct Object *object,
int pchan_index);
/* -------------------------------------------------------------------- */
/** \name Deform 3D Coordinates by Armature (armature_deform.c)
* \{ */

View File

@@ -278,18 +278,6 @@ bool BKE_constraint_apply_and_remove_for_pose(struct Depsgraph *depsgraph,
void BKE_constraint_panel_expand(struct bConstraint *con);
/* Constraints + Proxies function prototypes */
/**
* Rescue all constraints tagged as being #CONSTRAINT_PROXY_LOCAL
* (i.e. added to bone that's proxy-synced in this file).
*/
void BKE_constraints_proxylocal_extract(struct ListBase *dst, struct ListBase *src);
/**
* Returns if the owner of the constraint is proxy-protected.
*/
bool BKE_constraints_proxylocked_owner(struct Object *ob, struct bPoseChannel *pchan);
/* Constraint Evaluation function prototypes */
/**

View File

@@ -376,10 +376,6 @@ enum {
/** Clear asset data (in case the ID can actually be made local, in copy case asset data is never
* copied over). */
LIB_ID_MAKELOCAL_ASSET_DATA_CLEAR = 1 << 3,
/* Special type-specific options. */
/** For Objects, do not clear the proxy pointers while making the data-block local. */
LIB_ID_MAKELOCAL_OBJECT_NO_PROXY_CLEARING = 1 << 16,
};
/**

View File

@@ -63,7 +63,7 @@ enum {
/**
* That ID is not really used by its owner, it's just an internal hint/helper.
* This addresses Their Highest Ugliness the 'from' pointers: Object->from_proxy and Key->from.
* This marks the 'from' pointers issue, like Key->from.
* How to handle that kind of cases totally depends on what caller code is doing... */
IDWALK_CB_LOOPBACK = (1 << 4),
@@ -135,7 +135,6 @@ enum {
/** Do not process ID pointers inside embedded IDs. Needed by depsgraph processing e.g. */
IDWALK_IGNORE_EMBEDDED_ID = (1 << 3),
IDWALK_NO_INDIRECT_PROXY_DATA_USAGE = (1 << 8), /* Ugly special case :(((( */
/** Also process internal ID pointers like `ID.newid` or `ID.orig_id`.
* WARNING: Dangerous, use with caution. */
IDWALK_DO_INTERNAL_RUNTIME_POINTERS = (1 << 9),

View File

@@ -68,15 +68,6 @@ enum {
* and can cause crashes very easily!
*/
ID_REMAP_FORCE_NEVER_NULL_USAGE = 1 << 3,
/**
* Do not consider proxy/_group pointers of local objects as indirect usages...
* Our oh-so-beloved proxies again...
* Do not consider data used by local proxy object as indirect usage.
* This is needed e.g. in reload scenario,
* since we have to ensure remapping of Armature data of local proxy
* is also performed. Usual nightmare...
*/
ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE = 1 << 4,
/** Do not remap library override pointers. */
ID_REMAP_SKIP_OVERRIDE_LIBRARY = 1 << 5,
/** Don't touch the user count (use for low level actions such as swapping pointers). */

View File

@@ -144,18 +144,6 @@ void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_sr
void BKE_object_free_modifiers(struct Object *ob, int flag);
void BKE_object_free_shaderfx(struct Object *ob, int flag);
/**
* Proxy rule:
* - `lib_object->proxy_from` == the one we borrow from, set temporally while object_update.
* - `local_object->proxy` == pointer to library object, saved in files and read.
* - `local_object->proxy_group` == pointer to collection dupli-object, saved in files and read.
*/
void BKE_object_make_proxy(struct Main *bmain,
struct Object *ob,
struct Object *target,
struct Object *cob);
void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target);
bool BKE_object_exists_check(struct Main *bmain, const struct Object *obtest);
/**
* Actual check for internal data, not context or flags.
@@ -444,7 +432,6 @@ void BKE_object_eval_constraints(struct Depsgraph *depsgraph,
struct Object *ob);
void BKE_object_eval_transform_final(struct Depsgraph *depsgraph, struct Object *ob);
bool BKE_object_eval_proxy_copy(struct Depsgraph *depsgraph, struct Object *object);
void BKE_object_eval_uber_transform(struct Depsgraph *depsgraph, struct Object *ob);
void BKE_object_eval_uber_data(struct Depsgraph *depsgraph,
struct Scene *scene,
@@ -486,12 +473,6 @@ void BKE_object_handle_data_update(struct Depsgraph *depsgraph,
*/
void BKE_object_handle_update(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
/**
* Proxy rule:
* - lib_object->proxy_from == the one we borrow from, only set temporal and cleared here.
* - local_object->proxy == pointer to library object, saved in files and read.
*
* Function below is polluted with proxy exceptions, cleanup will follow!
*
* The main object update call, for object matrix, constraints, keys and #DispList (modifiers)
* requires flags to be set!
*
@@ -501,8 +482,7 @@ void BKE_object_handle_update(struct Depsgraph *depsgraph, struct Scene *scene,
void BKE_object_handle_update_ex(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob,
struct RigidBodyWorld *rbw,
bool do_proxy_update);
struct RigidBodyWorld *rbw);
void BKE_object_sculpt_data_create(struct Object *ob);

View File

@@ -1956,30 +1956,15 @@ void BKE_pose_blend_read_lib(BlendLibReader *reader, Object *ob, bPose *pose)
return;
}
/* always rebuild to match proxy or lib changes, but on Undo */
/* Always rebuild to match library changes, except on Undo. */
bool rebuild = false;
if (!BLO_read_lib_is_undo(reader)) {
if (ob->proxy || ob->id.lib != arm->id.lib) {
if (ob->id.lib != arm->id.lib) {
rebuild = true;
}
}
if (ob->proxy) {
/* sync proxy layer */
if (pose->proxy_layer) {
arm->layer = pose->proxy_layer;
}
/* sync proxy active bone */
if (pose->proxy_act_bone[0]) {
Bone *bone = BKE_armature_find_bone_name(arm, pose->proxy_act_bone);
if (bone) {
arm->act_bone = bone;
}
}
}
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
BKE_constraint_blend_read_lib(reader, (ID *)ob, &pchan->constraints);

View File

@@ -2296,161 +2296,6 @@ void BKE_armature_where_is(bArmature *arm)
/** \name Pose Rebuild
* \{ */
/* if bone layer is protected, copy the data from from->pose
* when used with linked libraries this copies from the linked pose into the local pose */
static void pose_proxy_sync(Object *ob, Object *from, int layer_protected)
{
bPose *pose = ob->pose, *frompose = from->pose;
bPoseChannel *pchan, *pchanp;
bConstraint *con;
int error = 0;
if (frompose == NULL) {
return;
}
/* in some cases when rigs change, we can't synchronize
* to avoid crashing check for possible errors here */
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone->layer & layer_protected) {
if (BKE_pose_channel_find_name(frompose, pchan->name) == NULL) {
CLOG_ERROR(&LOG,
"failed to sync proxy armature because '%s' is missing pose channel '%s'",
from->id.name,
pchan->name);
error = 1;
}
}
}
if (error) {
return;
}
/* clear all transformation values from library */
BKE_pose_rest(frompose, false);
/* copy over all of the proxy's bone groups */
/* TODO: for later
* - implement 'local' bone groups as for constraints
* NOTE: this isn't trivial, as bones reference groups by index not by pointer,
* so syncing things correctly needs careful attention */
BLI_freelistN(&pose->agroups);
BLI_duplicatelist(&pose->agroups, &frompose->agroups);
pose->active_group = frompose->active_group;
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
pchanp = BKE_pose_channel_find_name(frompose, pchan->name);
if (UNLIKELY(pchanp == NULL)) {
/* happens for proxies that become invalid because of a missing link
* for regular cases it shouldn't happen at all */
}
else if (pchan->bone->layer & layer_protected) {
ListBase proxylocal_constraints = {NULL, NULL};
bPoseChannel pchanw;
/* copy posechannel to temp, but restore important pointers */
pchanw = *pchanp;
pchanw.bone = pchan->bone;
pchanw.prev = pchan->prev;
pchanw.next = pchan->next;
pchanw.parent = pchan->parent;
pchanw.child = pchan->child;
pchanw.custom_tx = pchan->custom_tx;
pchanw.bbone_prev = pchan->bbone_prev;
pchanw.bbone_next = pchan->bbone_next;
pchanw.mpath = pchan->mpath;
pchan->mpath = NULL;
/* Reset runtime data, we don't want to share that with the proxy. */
BKE_pose_channel_runtime_reset_on_copy(&pchanw.runtime);
/* this is freed so copy a copy, else undo crashes */
if (pchanw.prop) {
pchanw.prop = IDP_CopyProperty(pchanw.prop);
/* use the values from the existing props */
if (pchan->prop) {
IDP_SyncGroupValues(pchanw.prop, pchan->prop);
}
}
/* Constraints - proxy constraints are flushed... local ones are added after
* 1: extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints.
* 2: copy proxy-pchan's constraints on-to new.
* 3: add extracted local constraints back on top.
*
* Note for BKE_constraints_copy:
* When copying constraints, disable 'do_extern' otherwise
* we get the libs direct linked in this blend.
*/
BKE_constraints_proxylocal_extract(&proxylocal_constraints, &pchan->constraints);
BKE_constraints_copy(&pchanw.constraints, &pchanp->constraints, false);
BLI_movelisttolist(&pchanw.constraints, &proxylocal_constraints);
/* constraints - set target ob pointer to own object */
for (con = pchanw.constraints.first; con; con = con->next) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
for (ct = targets.first; ct; ct = ct->next) {
if (ct->tar == from) {
ct->tar = ob;
}
}
if (cti->flush_constraint_targets) {
cti->flush_constraint_targets(con, &targets, 0);
}
}
}
/* free stuff from current channel */
BKE_pose_channel_free(pchan);
/* copy data in temp back over to the cleaned-out (but still allocated) original channel */
*pchan = pchanw;
if (pchan->custom) {
id_us_plus(&pchan->custom->id);
}
}
else {
/* always copy custom shape */
pchan->custom = pchanp->custom;
if (pchan->custom) {
id_us_plus(&pchan->custom->id);
}
if (pchanp->custom_tx) {
pchan->custom_tx = BKE_pose_channel_find_name(pose, pchanp->custom_tx->name);
}
/* ID-Property Syncing */
{
IDProperty *prop_orig = pchan->prop;
if (pchanp->prop) {
pchan->prop = IDP_CopyProperty(pchanp->prop);
if (prop_orig) {
/* copy existing values across when types match */
IDP_SyncGroupValues(pchan->prop, prop_orig);
}
}
else {
pchan->prop = NULL;
}
if (prop_orig) {
IDP_FreeProperty(prop_orig);
}
}
}
}
}
/**
* \param r_last_visited_bone_p: The last bone handled by the last call to this function.
*/
@@ -2579,16 +2424,6 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_
// printf("rebuild pose %s, %d bones\n", ob->id.name, counter);
/* synchronize protected layers with proxy */
/* HACK! To preserve 2.7x behavior that you always can pose even locked bones,
* do not do any restoration if this is a COW temp copy! */
/* Switched back to just NO_MAIN tag, for some reasons (c)
* using COW tag was working this morning, but not anymore... */
if (ob->proxy != NULL && (ob->id.tag & LIB_TAG_NO_MAIN) == 0) {
BKE_object_copy_proxy_drivers(ob, ob->proxy);
pose_proxy_sync(ob, ob->proxy, arm->layer_protected);
}
BKE_pose_update_constraint_flags(pose); /* for IK detection for example */
pose->flag &= ~POSE_RECALC;

View File

@@ -850,10 +850,6 @@ void BKE_pose_eval_init(struct Depsgraph *depsgraph, Scene *UNUSED(scene), Objec
}
BLI_assert(pose->chan_array != NULL || BLI_listbase_is_empty(&pose->chanbase));
if (object->proxy != NULL) {
object->proxy->proxy_from = object;
}
}
void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph, Scene *scene, Object *object)
@@ -1070,57 +1066,3 @@ void BKE_pose_eval_cleanup(struct Depsgraph *depsgraph, Scene *scene, Object *ob
BIK_release_tree(scene, object, ctime);
pose_eval_cleanup_common(object);
}
void BKE_pose_eval_proxy_init(struct Depsgraph *depsgraph, Object *object)
{
BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL);
DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
BLI_assert(object->pose->chan_array != NULL || BLI_listbase_is_empty(&object->pose->chanbase));
}
void BKE_pose_eval_proxy_done(struct Depsgraph *depsgraph, Object *object)
{
BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL);
DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
}
void BKE_pose_eval_proxy_cleanup(struct Depsgraph *depsgraph, Object *object)
{
BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL);
DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
pose_eval_cleanup_common(object);
}
void BKE_pose_eval_proxy_copy_bone(struct Depsgraph *depsgraph, Object *object, int pchan_index)
{
const bArmature *armature = (bArmature *)object->data;
if (armature->edbo != NULL) {
return;
}
BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL);
bPoseChannel *pchan = pose_pchan_get_indexed(object, pchan_index);
BLI_assert(pchan != NULL);
DEG_debug_print_eval_subdata(
depsgraph, __func__, object->id.name, object, "pchan", pchan->name, pchan);
/* TODO(sergey): Use indexed lookup, once it's guaranteed to be kept
* around for the time while proxies are evaluating.
*/
#if 0
bPoseChannel *pchan_from = pose_pchan_get_indexed(object->proxy_from, pchan_index);
#else
bPoseChannel *pchan_from = BKE_pose_channel_find_name(object->proxy_from->pose, pchan->name);
#endif
if (pchan_from == NULL) {
printf(
"WARNING: Could not find bone %s in linked ID anymore... "
"You should delete and re-generate your proxy.\n",
pchan->name);
return;
}
BKE_pose_copy_pchan_result(pchan, pchan_from);
copy_dq_dq(&pchan->runtime.deform_dual_quat, &pchan_from->runtime.deform_dual_quat);
BKE_pchan_bbone_segments_cache_copy(pchan, pchan_from);
pose_channel_flush_to_orig_if_needed(depsgraph, object, pchan);
}

View File

@@ -1061,10 +1061,6 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *
if (item->action != LINK_APPEND_ACT_UNSET) {
/* Already set, pass. */
}
if (GS(id->name) == ID_OB && ((Object *)id)->proxy_from != NULL) {
CLOG_INFO(&LOG, 3, "Appended ID '%s' is proxified, keeping it linked...", id->name);
item->action = LINK_APPEND_ACT_KEEP_LINKED;
}
else if (do_reuse_local_id && existing_local_id != NULL) {
CLOG_INFO(&LOG, 3, "Appended ID '%s' as a matching local one, re-using it...", id->name);
item->action = LINK_APPEND_ACT_REUSE_LOCAL;
@@ -1119,10 +1115,7 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *
local_appended_new_id = id->newid;
break;
case LINK_APPEND_ACT_MAKE_LOCAL:
BKE_lib_id_make_local(bmain,
id,
make_local_common_flags | LIB_ID_MAKELOCAL_FORCE_LOCAL |
LIB_ID_MAKELOCAL_OBJECT_NO_PROXY_CLEARING);
BKE_lib_id_make_local(bmain, id, make_local_common_flags | LIB_ID_MAKELOCAL_FORCE_LOCAL);
BLI_assert(id->newid == NULL);
local_appended_new_id = id;
break;
@@ -1231,52 +1224,6 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *
continue;
}
BLI_assert(ID_IS_LINKED(id));
/* Attempt to re-link copied proxy objects. This allows appending of an entire scene
* from another blend file into this one, even when that blend file contains proxified
* armatures that have local references. Since the proxified object needs to be linked
* (not local), this will only work when the "Localize all" checkbox is disabled.
* TL;DR: this is a dirty hack on top of an already weak feature (proxies). */
if (GS(id->name) == ID_OB && ((Object *)id)->proxy != NULL) {
Object *ob = (Object *)id;
Object *ob_new = (Object *)id->newid;
bool is_local = false, is_lib = false;
/* Proxies only work when the proxified object is linked-in from a library. */
if (!ID_IS_LINKED(ob->proxy)) {
CLOG_WARN(&LOG,
"Proxy object %s will lose its link to %s, because the "
"proxified object is local",
id->newid->name,
ob->proxy->id.name);
continue;
}
BKE_library_ID_test_usages(bmain, id, &is_local, &is_lib);
/* We can only switch the proxy'ing to a made-local proxy if it is no longer
* referred to from a library. Not checking for local use; if new local proxy
* was not used locally would be a nasty bug! */
if (is_local || is_lib) {
CLOG_WARN(&LOG,
"Made-local proxy object %s will lose its link to %s, "
"because the linked-in proxy is referenced (is_local=%i, is_lib=%i)",
id->newid->name,
ob->proxy->id.name,
is_local,
is_lib);
}
else {
/* we can switch the proxy'ing from the linked-in to the made-local proxy.
* BKE_object_make_proxy() shouldn't be used here, as it allocates memory that
* was already allocated by object_make_local() (which called BKE_object_copy). */
ob_new->proxy = ob->proxy;
ob_new->proxy_group = ob->proxy_group;
ob_new->proxy_from = ob->proxy_from;
ob_new->proxy->proxy_from = ob_new;
ob->proxy = ob->proxy_from = ob->proxy_group = NULL;
}
}
}
BKE_main_id_newptr_and_tag_clear(bmain);
@@ -1568,7 +1515,6 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
/* Note that in reload case, we also want to replace indirect usages. */
const short remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE |
ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE |
(do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE);
for (item_idx = 0, itemlink = lapp_context->items.list; itemlink;
item_idx++, itemlink = itemlink->next) {

View File

@@ -5850,14 +5850,6 @@ static void add_new_constraint_to_list(Object *ob, bPoseChannel *pchan, bConstra
BLI_addtail(list, con);
BKE_constraint_unique_name(con, list);
/* if the target list is a list on some PoseChannel belonging to a proxy-protected
* Armature layer, we must tag newly added constraints with a flag which allows them
* to persist after proxy syncing has been done
*/
if (BKE_constraints_proxylocked_owner(ob, pchan)) {
con->flag |= CONSTRAINT_PROXY_LOCAL;
}
/* make this constraint the active one */
BKE_constraints_active_set(list, con);
}
@@ -6213,45 +6205,6 @@ bool BKE_constraint_is_nonlocal_in_liboverride(const Object *ob, const bConstrai
(con == NULL || (con->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) == 0));
}
/* -------- Constraints and Proxies ------- */
void BKE_constraints_proxylocal_extract(ListBase *dst, ListBase *src)
{
bConstraint *con, *next;
/* for each tagged constraint, remove from src and move to dst */
for (con = src->first; con; con = next) {
next = con->next;
/* check if tagged */
if (con->flag & CONSTRAINT_PROXY_LOCAL) {
BLI_remlink(src, con);
BLI_addtail(dst, con);
}
}
}
bool BKE_constraints_proxylocked_owner(Object *ob, bPoseChannel *pchan)
{
/* Currently, constraints can only be on object or bone level */
if (ob && ob->proxy) {
if (ob->pose && pchan) {
bArmature *arm = ob->data;
/* On bone-level, check if bone is on proxy-protected layer */
if ((pchan->bone) && (pchan->bone->layer & arm->layer_protected)) {
return true;
}
}
else {
/* FIXME: constraints on object-level are not handled well yet */
return true;
}
}
return false;
}
/* -------- Target-Matrix Stuff ------- */
void BKE_constraint_target_matrix_get(struct Depsgraph *depsgraph,

View File

@@ -88,14 +88,6 @@ typedef struct DriverVarTypeInfo {
/** \name Driver Target Utilities
* \{ */
static ID *dtar_id_ensure_proxy_from(ID *id)
{
if (id && GS(id->name) == ID_OB && ((Object *)id)->proxy_from) {
return (ID *)(((Object *)id)->proxy_from);
}
return id;
}
/**
* Helper function to obtain a value using RNA from the specified source
* (for evaluating drivers).
@@ -113,7 +105,7 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
return 0.0f;
}
id = dtar_id_ensure_proxy_from(dtar->id);
id = dtar->id;
/* Error check for missing pointer. */
if (id == NULL) {
@@ -217,7 +209,7 @@ bool driver_get_variable_property(ChannelDriver *driver,
return false;
}
id = dtar_id_ensure_proxy_from(dtar->id);
id = dtar->id;
/* Error check for missing pointer. */
if (id == NULL) {
@@ -273,7 +265,7 @@ static short driver_check_valid_targets(ChannelDriver *driver, DriverVar *dvar)
short valid_targets = 0;
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id);
Object *ob = (Object *)dtar->id;
/* Check if this target has valid data. */
if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
@@ -328,7 +320,7 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
for (int i = 0; i < 2; i++) {
/* Get pointer to loc values to store in. */
DriverTarget *dtar = &dvar->targets[i];
Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id);
Object *ob = (Object *)dtar->id;
bPoseChannel *pchan;
/* After the checks above, the targets should be valid here. */
@@ -389,7 +381,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
/* NOTE: for now, these are all just world-space */
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
/* Get pointer to loc values to store in. */
Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id);
Object *ob = (Object *)dtar->id;
bPoseChannel *pchan;
float tmp_loc[3];
@@ -472,7 +464,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
{
DriverTarget *dtar = &dvar->targets[0];
Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id);
Object *ob = (Object *)dtar->id;
bPoseChannel *pchan;
float mat[4][4];
float oldEul[3] = {0.0f, 0.0f, 0.0f};

View File

@@ -1918,7 +1918,6 @@ void BKE_library_make_local(Main *bmain,
* but complicates slightly the pre-processing of relations between IDs at step 2... */
else if (!do_skip && id->tag & (LIB_TAG_EXTERN | LIB_TAG_INDIRECT | LIB_TAG_NEW) &&
ELEM(lib, NULL, id->lib) &&
!(GS(id->name) == ID_OB && ((Object *)id)->proxy_from != NULL) &&
((untagged_only == false) || !(id->tag & LIB_TAG_PRE_EXISTING))) {
BLI_linklist_prepend_arena(&todo_ids, id, linklist_mem);
id->tag |= LIB_TAG_DOIT;
@@ -1982,12 +1981,8 @@ void BKE_library_make_local(Main *bmain,
}
}
else {
/* In this specific case, we do want to make ID local even if it has no local usage yet...
* Note that for objects, we don't want proxy pointers to be cleared yet. This will happen
* down the road in this function.
*/
BKE_lib_id_make_local(
bmain, id, LIB_ID_MAKELOCAL_FULL_LIBRARY | LIB_ID_MAKELOCAL_OBJECT_NO_PROXY_CLEARING);
/* In this specific case, we do want to make ID local even if it has no local usage yet... */
BKE_lib_id_make_local(bmain, id, LIB_ID_MAKELOCAL_FULL_LIBRARY);
if (id->newid) {
if (GS(id->newid->name) == ID_OB) {
@@ -2049,62 +2044,6 @@ void BKE_library_make_local(Main *bmain,
TIMEIT_VALUE_PRINT(make_local);
#endif
/* Step 5: proxy 'remapping' hack. */
for (LinkNode *it = copied_ids; it; it = it->next) {
ID *id = it->link;
/* Attempt to re-link copied proxy objects. This allows appending of an entire scene
* from another blend file into this one, even when that blend file contains proxified
* armatures that have local references. Since the proxified object needs to be linked
* (not local), this will only work when the "Localize all" checkbox is disabled.
* TL;DR: this is a dirty hack on top of an already weak feature (proxies). */
if (GS(id->name) == ID_OB && ((Object *)id)->proxy != NULL) {
Object *ob = (Object *)id;
Object *ob_new = (Object *)id->newid;
bool is_local = false, is_lib = false;
/* Proxies only work when the proxified object is linked-in from a library. */
if (!ID_IS_LINKED(ob->proxy)) {
CLOG_WARN(&LOG,
"proxy object %s will lose its link to %s, because the "
"proxified object is local.",
id->newid->name,
ob->proxy->id.name);
continue;
}
BKE_library_ID_test_usages(bmain, id, &is_local, &is_lib);
/* We can only switch the proxy'ing to a made-local proxy if it is no longer
* referred to from a library. Not checking for local use; if new local proxy
* was not used locally would be a nasty bug! */
if (is_local || is_lib) {
CLOG_WARN(&LOG,
"made-local proxy object %s will lose its link to %s, "
"because the linked-in proxy is referenced (is_local=%i, is_lib=%i).",
id->newid->name,
ob->proxy->id.name,
is_local,
is_lib);
}
else {
/* we can switch the proxy'ing from the linked-in to the made-local proxy.
* BKE_object_make_proxy() shouldn't be used here, as it allocates memory that
* was already allocated by object_make_local() (which called BKE_object_copy). */
ob_new->proxy = ob->proxy;
ob_new->proxy_group = ob->proxy_group;
ob_new->proxy_from = ob->proxy_from;
ob_new->proxy->proxy_from = ob_new;
ob->proxy = ob->proxy_from = ob->proxy_group = NULL;
}
}
}
#ifdef DEBUG_TIME
printf("Step 5: Proxy 'remapping' hack: Done.\n");
TIMEIT_VALUE_PRINT(make_local);
#endif
/* This is probably more of a hack than something we should do here, but...
* Issue is, the whole copying + remapping done in complex cases above may leave pose-channels
* of armatures in complete invalid state (more precisely, the bone pointers of the

View File

@@ -265,8 +265,8 @@ static size_t id_delete(Main *bmain, const bool do_tagged_deletion)
}
for (id = last_remapped_id->next; id; id = id->next) {
/* Will tag 'never NULL' users of this ID too.
* Note that we cannot use BKE_libblock_unlink() here,
* since it would ignore indirect (and proxy!)
*
* NOTE: #BKE_libblock_unlink() cannot be used here, since it would ignore indirect
* links, this can lead to nasty crashing here in second, actual deleting loop.
* Also, this will also flag users of deleted data that cannot be unlinked
* (object using deleted obdata, etc.), so that they also get deleted. */
@@ -315,9 +315,9 @@ static size_t id_delete(Main *bmain, const bool do_tagged_deletion)
}
/* Will tag 'never NULL' users of this ID too.
* Note that we cannot use BKE_libblock_unlink() here, since it would ignore indirect
* (and proxy!) links, this can lead to nasty crashing here in second,
* actual deleting loop.
*
* NOTE: #BKE_libblock_unlink() cannot be used here, since it would ignore indirect
* links, this can lead to nasty crashing here in second, actual deleting loop.
* Also, this will also flag users of deleted data that cannot be unlinked
* (object using deleted obdata, etc.), so that they also get deleted. */
BKE_libblock_remap_multiple_locked(bmain,

View File

@@ -27,6 +27,9 @@
#include "BLI_linklist.h"
/* Required for proxy to liboverrides conversion code. */
#define DNA_DEPRECATED_ALLOW
#include "DNA_ID.h"
#include "DNA_collection_types.h"
#include "DNA_object_types.h"

View File

@@ -517,7 +517,7 @@ static int foreach_libblock_id_users_callback(LibraryIDLinkCallbackData *cb_data
IDUsersIter *iter = cb_data->user_data;
if (*id_p) {
/* 'Loopback' ID pointers (the ugly 'from' ones, Object->proxy_from and Key->from).
/* 'Loopback' ID pointers (the ugly 'from' ones, like Key->from).
* Those are not actually ID usage, we can ignore them here.
*/
if (cb_flag & IDWALK_CB_LOOPBACK) {
@@ -768,7 +768,7 @@ static int foreach_libblock_used_linked_data_tag_clear_cb(LibraryIDLinkCallbackD
bool *is_changed = cb_data->user_data;
if (*id_p) {
/* The infamous 'from' pointers (Key.from, Object.proxy_from, ...).
/* The infamous 'from' pointers (Key.from, ...).
* those are not actually ID usage, so we ignore them here. */
if (cb_flag & IDWALK_CB_LOOPBACK) {
return IDWALK_RET_NOP;

View File

@@ -91,26 +91,18 @@ enum {
ID_REMAP_IS_USER_ONE_SKIPPED = 1 << 1, /* There was some skipped 'user_one' usages of old_id. */
};
static void foreach_libblock_remap_callback_skip(const ID *id_owner,
ID **id_ptr,
static void foreach_libblock_remap_callback_skip(const ID *UNUSED(id_owner),
ID **UNUSED(id_ptr),
IDRemap *id_remap_data,
const int cb_flag,
const bool is_indirect,
const bool is_reference,
const bool is_never_null,
const bool is_obj,
const bool UNUSED(is_obj),
const bool is_obj_editmode)
{
if (is_indirect) {
id_remap_data->skipped_indirect++;
if (is_obj) {
Object *ob = (Object *)id_owner;
if (ob->data == *id_ptr && ob->proxy != NULL) {
/* And another 'Proudly brought to you by Proxy Hell' hack!
* This will allow us to avoid clearing 'LIB_EXTERN' flag of obdata of proxies... */
id_remap_data->skipped_direct++;
}
}
}
else if (is_never_null || is_obj_editmode || is_reference) {
id_remap_data->skipped_direct++;
@@ -136,8 +128,7 @@ static void foreach_libblock_remap_callback_apply(ID *id_owner,
const int cb_flag,
const bool is_indirect,
const bool is_never_null,
const bool force_user_refcount,
const bool is_obj_proxy)
const bool force_user_refcount)
{
if (!is_never_null) {
*id_ptr = new_id;
@@ -170,16 +161,9 @@ static void foreach_libblock_remap_callback_apply(ID *id_owner,
/* We cannot affect old_id->us directly, LIB_TAG_EXTRAUSER(_SET)
* are assumed to be set as needed, that extra user is processed in final handling. */
}
if (!is_indirect || is_obj_proxy) {
if (!is_indirect) {
id_remap_data->status |= ID_REMAP_IS_LINKED_DIRECT;
}
/* We need to remap proxy_from pointer of remapped proxy... sigh. */
if (is_obj_proxy && new_id != NULL) {
Object *ob = (Object *)id_owner;
if (ob->proxy == (Object *)new_id) {
ob->proxy->proxy_from = ob;
}
}
}
static int foreach_libblock_remap_callback(LibraryIDLinkCallbackData *cb_data)
@@ -221,12 +205,9 @@ static int foreach_libblock_remap_callback(LibraryIDLinkCallbackData *cb_data)
const bool is_reference = (cb_flag & IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE) != 0;
const bool is_indirect = (cb_flag & IDWALK_CB_INDIRECT_USAGE) != 0;
const bool skip_indirect = (id_remap_data->flag & ID_REMAP_SKIP_INDIRECT_USAGE) != 0;
/* NOTE: proxy usage implies LIB_TAG_EXTERN, so on this aspect it is direct,
* on the other hand since they get reset to lib data on file open/reload it is indirect too.
* Edit Mode is also a 'skip direct' case. */
const bool is_obj = (GS(id_owner->name) == ID_OB);
const bool is_obj_proxy = (is_obj &&
(((Object *)id_owner)->proxy || ((Object *)id_owner)->proxy_group));
/* NOTE: Edit Mode is a 'skip direct' case, unless specifically requested, obdata should not be
* remapped in this situation. */
const bool is_obj_editmode = (is_obj && BKE_object_is_in_editmode((Object *)id_owner) &&
(id_remap_data->flag & ID_REMAP_FORCE_OBDATA_IN_EDITMODE) == 0);
const bool is_never_null = ((cb_flag & IDWALK_CB_NEVER_NULL) && (new_id == NULL) &&
@@ -281,8 +262,7 @@ static int foreach_libblock_remap_callback(LibraryIDLinkCallbackData *cb_data)
cb_flag,
is_indirect,
is_never_null,
force_user_refcount,
is_obj_proxy);
force_user_refcount);
}
return IDWALK_RET_NOP;
@@ -430,10 +410,7 @@ static void libblock_remap_data(
Main *bmain, ID *id, ID *old_id, ID *new_id, const short remap_flags, IDRemap *r_id_remap_data)
{
IDRemap id_remap_data;
const int foreach_id_flags = ((remap_flags & ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE) != 0 ?
IDWALK_NO_INDIRECT_PROXY_DATA_USAGE :
IDWALK_NOP) |
((remap_flags & ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS) != 0 ?
const int foreach_id_flags = ((remap_flags & ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS) != 0 ?
IDWALK_DO_INTERNAL_RUNTIME_POINTERS :
IDWALK_NOP);

View File

@@ -333,7 +333,6 @@ static void object_make_local(Main *bmain, ID *id, const int flags)
Object *ob = (Object *)id;
const bool lib_local = (flags & LIB_ID_MAKELOCAL_FULL_LIBRARY) != 0;
const bool clear_proxy = (flags & LIB_ID_MAKELOCAL_OBJECT_NO_PROXY_CLEARING) == 0;
bool force_local, force_copy;
BKE_lib_id_make_local_generic_action_define(bmain, id, flags, &force_local, &force_copy);
@@ -341,20 +340,11 @@ static void object_make_local(Main *bmain, ID *id, const int flags)
if (force_local) {
BKE_lib_id_clear_library_data(bmain, &ob->id, flags);
BKE_lib_id_expand_local(bmain, &ob->id, flags);
if (clear_proxy) {
if (ob->proxy_from != nullptr) {
ob->proxy_from->proxy = nullptr;
ob->proxy_from->proxy_group = nullptr;
}
ob->proxy = ob->proxy_from = ob->proxy_group = nullptr;
}
}
else if (force_copy) {
Object *ob_new = (Object *)BKE_id_copy(bmain, &ob->id);
id_us_min(&ob_new->id);
ob_new->proxy = ob_new->proxy_from = ob_new->proxy_group = nullptr;
/* setting newid is mandatory for complex make_lib_local logic... */
ID_NEW_SET(ob, ob_new);
@@ -419,51 +409,25 @@ 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 nullptr or Image */
BKE_LIB_FOREACHID_PROCESS_ID(data, object->data, proxy_cb_flag | IDWALK_CB_USER);
BKE_LIB_FOREACHID_PROCESS_ID(data, object->data, IDWALK_CB_USER);
}
else {
/* when set, this can't be nullptr */
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_ID(data, object->data, IDWALK_CB_USER | IDWALK_CB_NEVER_NULL);
}
}
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, object->parent, IDWALK_CB_NEVER_SELF);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, object->track, IDWALK_CB_NEVER_SELF);
/* object->proxy is refcounted, but not object->proxy_group... *sigh* */
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, object->proxy, IDWALK_CB_USER | IDWALK_CB_NEVER_SELF);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(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 != nullptr && ID_IS_LINKED(object->proxy_from)) ?
IDWALK_CB_INDIRECT_USAGE :
0,
true);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(
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_IDSUPER(data, object->poselib, IDWALK_CB_USER);
for (int i = 0; i < object->totcol; i++) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, object->mat[i], proxy_cb_flag | IDWALK_CB_USER);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, object->mat[i], IDWALK_CB_USER);
}
/* Note that ob->gpd is deprecated, so no need to handle it here. */
@@ -476,8 +440,6 @@ static void object_foreach_id(ID *id, LibraryForeachIDData *data)
/* 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) {
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
data,
@@ -492,7 +454,6 @@ static void object_foreach_id(ID *id, LibraryForeachIDData *data)
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) {
@@ -627,9 +588,6 @@ static void object_blend_write(BlendWriter *writer, ID *id, const void *id_addre
bArmature *arm = nullptr;
if (ob->type == OB_ARMATURE) {
arm = (bArmature *)ob->data;
if (arm && ob->pose && arm->act_bone) {
BLI_strncpy(ob->pose->proxy_act_bone, arm->act_bone->name, sizeof(ob->pose->proxy_act_bone));
}
}
BKE_pose_blend_write(writer, ob->pose, arm);
@@ -2873,161 +2831,6 @@ bool BKE_object_obdata_is_libdata(const Object *ob)
return (ob && ob->data && ID_IS_LINKED(ob->data));
}
/* -------------------------------------------------------------------- */
/** \name Object Proxy API
* \{ */
/* when you make proxy, ensure the exposed layers are extern */
static void armature_set_id_extern(Object *ob)
{
bArmature *arm = (bArmature *)ob->data;
unsigned int lay = arm->layer_protected;
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
if (!(pchan->bone->layer & lay)) {
id_lib_extern((ID *)pchan->custom);
}
}
}
void BKE_object_copy_proxy_drivers(Object *ob, Object *target)
{
if ((target->adt) && (target->adt->drivers.first)) {
/* add new animdata block */
if (!ob->adt) {
ob->adt = BKE_animdata_ensure_id(&ob->id);
}
/* make a copy of all the drivers (for now), then correct any links that need fixing */
BKE_fcurves_free(&ob->adt->drivers);
BKE_fcurves_copy(&ob->adt->drivers, &target->adt->drivers);
LISTBASE_FOREACH (FCurve *, fcu, &ob->adt->drivers) {
ChannelDriver *driver = fcu->driver;
LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
/* all drivers */
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
if (dtar->id) {
if ((Object *)dtar->id == target) {
dtar->id = (ID *)ob;
}
else {
/* only on local objects because this causes indirect links
* 'a -> b -> c', blend to point directly to a.blend
* when a.blend has a proxy that's linked into `c.blend`. */
if (!ID_IS_LINKED(ob)) {
id_lib_extern((ID *)dtar->id);
}
}
}
}
DRIVER_TARGETS_LOOPER_END;
}
}
}
}
void BKE_object_make_proxy(Main *bmain, Object *ob, Object *target, Object *cob)
{
/* paranoia checks */
if (ID_IS_LINKED(ob) || !ID_IS_LINKED(target)) {
CLOG_ERROR(&LOG, "cannot make proxy");
return;
}
ob->proxy = target;
id_us_plus(&target->id);
ob->proxy_group = cob;
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
DEG_id_tag_update(&target->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
/* copy transform
* - cob means this proxy comes from a collection, just apply the matrix
* so the object won't move from its dupli-transform.
*
* - no cob means this is being made from a linked object,
* this is closer to making a copy of the object - in-place. */
if (cob) {
ob->rotmode = target->rotmode;
mul_m4_m4m4(ob->obmat, cob->obmat, target->obmat);
if (cob->instance_collection) { /* should always be true */
float tvec[3];
mul_v3_mat3_m4v3(tvec, ob->obmat, cob->instance_collection->instance_offset);
sub_v3_v3(ob->obmat[3], tvec);
}
BKE_object_apply_mat4(ob, ob->obmat, false, true);
}
else {
BKE_object_transform_copy(ob, target);
ob->parent = target->parent; /* libdata */
copy_m4_m4(ob->parentinv, target->parentinv);
}
/* copy animdata stuff - drivers only for now... */
BKE_object_copy_proxy_drivers(ob, target);
/* skip constraints? */
/* FIXME: this is considered by many as a bug */
/* set object type and link to data */
ob->type = target->type;
ob->data = target->data;
id_us_plus((ID *)ob->data); /* ensures lib data becomes LIB_TAG_EXTERN */
/* copy material and index information */
ob->actcol = ob->totcol = 0;
if (ob->mat) {
MEM_freeN(ob->mat);
}
if (ob->matbits) {
MEM_freeN(ob->matbits);
}
ob->mat = nullptr;
ob->matbits = nullptr;
if ((target->totcol) && (target->mat) && OB_TYPE_SUPPORT_MATERIAL(ob->type)) {
int i;
ob->actcol = target->actcol;
ob->totcol = target->totcol;
ob->mat = (Material **)MEM_dupallocN(target->mat);
ob->matbits = (char *)MEM_dupallocN(target->matbits);
for (i = 0; i < target->totcol; i++) {
/* don't need to run BKE_object_materials_test
* since we know this object is new and not used elsewhere */
id_us_plus((ID *)ob->mat[i]);
}
}
/* type conversions */
if (target->type == OB_ARMATURE) {
copy_object_pose(ob, target, 0); /* data copy, object pointers in constraints */
BKE_pose_rest(ob->pose, false); /* clear all transforms in channels */
BKE_pose_rebuild(bmain, ob, (bArmature *)ob->data, true); /* set all internal links */
armature_set_id_extern(ob);
}
else if (target->type == OB_EMPTY) {
ob->empty_drawtype = target->empty_drawtype;
ob->empty_drawsize = target->empty_drawsize;
}
/* copy IDProperties */
if (ob->id.properties) {
IDP_FreeProperty(ob->id.properties);
ob->id.properties = nullptr;
}
if (target->id.properties) {
ob->id.properties = IDP_CopyProperty(target->id.properties);
}
/* copy drawtype info */
ob->dt = target->dt;
}
void BKE_object_obdata_size_init(struct Object *ob, const float size)
{
/* apply radius as a scale to types that support it */
@@ -3069,8 +2872,6 @@ void BKE_object_obdata_size_init(struct Object *ob, const float size)
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Object Matrix Get/Set API
* \{ */
@@ -4362,33 +4163,10 @@ void BKE_object_tfm_restore(Object *ob, void *obtfm_pt)
/** \name Object Evaluation/Update API
* \{ */
static void object_handle_update_proxy(Depsgraph *depsgraph,
Scene *scene,
Object *object,
const bool do_proxy_update)
{
/* The case when this is a collection proxy, object_update is called in collection.c */
if (object->proxy == nullptr) {
return;
}
/* set pointer in library proxy target, for copying, but restore it */
object->proxy->proxy_from = object;
// printf("set proxy pointer for later collection stuff %s\n", ob->id.name);
/* the no-group proxy case, we call update */
if (object->proxy_group == nullptr) {
if (do_proxy_update) {
// printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name);
BKE_object_handle_update(depsgraph, scene, object->proxy);
}
}
}
void BKE_object_handle_update_ex(Depsgraph *depsgraph,
Scene *scene,
Object *ob,
RigidBodyWorld *rbw,
const bool do_proxy_update)
RigidBodyWorld *rbw)
{
const ID *object_data = (ID *)ob->data;
const bool recalc_object = (ob->id.recalc & ID_RECALC_ALL) != 0;
@@ -4396,7 +4174,6 @@ void BKE_object_handle_update_ex(Depsgraph *depsgraph,
((object_data->recalc & ID_RECALC_ALL) != 0) :
false;
if (!recalc_object && !recalc_data) {
object_handle_update_proxy(depsgraph, scene, ob, do_proxy_update);
return;
}
/* Speed optimization for animation lookups. */
@@ -4425,22 +4202,17 @@ void BKE_object_handle_update_ex(Depsgraph *depsgraph,
if (G.debug & G_DEBUG_DEPSGRAPH_EVAL) {
printf("recalcob %s\n", ob->id.name + 2);
}
/* Handle proxy copy for target. */
if (!BKE_object_eval_proxy_copy(depsgraph, ob)) {
BKE_object_where_is_calc_ex(depsgraph, scene, rbw, ob, nullptr);
}
}
if (recalc_data) {
BKE_object_handle_data_update(depsgraph, scene, ob);
}
object_handle_update_proxy(depsgraph, scene, ob, do_proxy_update);
}
void BKE_object_handle_update(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
BKE_object_handle_update_ex(depsgraph, scene, ob, nullptr, true);
BKE_object_handle_update_ex(depsgraph, scene, ob, nullptr);
}
void BKE_object_sculpt_data_create(Object *ob)

View File

@@ -190,16 +190,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
break;
}
case OB_ARMATURE:
if (ID_IS_LINKED(ob) && ob->proxy_from) {
if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) {
printf("Proxy copy error, lib Object: %s proxy Object: %s\n",
ob->id.name + 2,
ob->proxy_from->id.name + 2);
}
}
else {
BKE_pose_where_is(depsgraph, scene, ob);
}
break;
case OB_MBALL:
@@ -311,33 +302,9 @@ void BKE_object_sync_to_original(Depsgraph *depsgraph, Object *object)
object_sync_boundbox_to_original(object_orig, object);
}
bool BKE_object_eval_proxy_copy(Depsgraph *depsgraph, Object *object)
void BKE_object_eval_uber_transform(Depsgraph *UNUSED(depsgraph), Object *UNUSED(object))
{
/* Handle proxy copy for target, */
if (ID_IS_LINKED(object) && object->proxy_from) {
DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
if (object->proxy_from->proxy_group) {
/* Transform proxy into group space. */
Object *obg = object->proxy_from->proxy_group;
float imat[4][4];
invert_m4_m4(imat, obg->obmat);
mul_m4_m4m4(object->obmat, imat, object->proxy_from->obmat);
/* Should always be true. */
if (obg->instance_collection) {
add_v3_v3(object->obmat[3], obg->instance_collection->instance_offset);
}
}
else {
copy_m4_m4(object->obmat, object->proxy_from->obmat);
}
return true;
}
return false;
}
void BKE_object_eval_uber_transform(Depsgraph *depsgraph, Object *object)
{
BKE_object_eval_proxy_copy(depsgraph, object);
return;
}
void BKE_object_data_batch_cache_dirty_tag(ID *object_data)

View File

@@ -419,9 +419,6 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain,
fd->skip_flags = params->skip_flags;
BLI_strncpy(fd->relabase, filename, sizeof(fd->relabase));
/* clear ob->proxy_from pointers in old main */
blo_clear_proxy_pointers_from_lib(oldmain);
/* separate libraries from old main */
blo_split_main(&old_mainlist, oldmain);
/* add the library pointers in oldmap lookup */

View File

@@ -1580,15 +1580,6 @@ static void change_link_placeholder_to_real_ID_pointer(ListBase *mainlist,
}
}
void blo_clear_proxy_pointers_from_lib(Main *oldmain)
{
LISTBASE_FOREACH (Object *, ob, &oldmain->objects) {
if (ID_IS_LINKED(ob) && ob->proxy_from != NULL && !ID_IS_LINKED(ob->proxy_from)) {
ob->proxy_from = NULL;
}
}
}
/* XXX disabled this feature - packed files also belong in temp saves and quit.blend,
* to make restore work. */
@@ -3207,18 +3198,8 @@ static void read_libblock_undo_restore_identical(
id_old->recalc |= direct_link_id_restore_recalc_exceptions(id_old);
id_old->recalc_after_undo_push = 0;
/* As usual, proxies require some special love...
* In `blo_clear_proxy_pointers_from_lib()` we clear all `proxy_from` pointers to local IDs, for
* undo. This is required since we do not re-read linked data in that case, so we also do not
* re-'lib_link' their pointers.
* Those `proxy_from` pointers are then re-defined properly when lib_linking the newly read local
* object. However, in case of re-used data 'as-is', we never lib_link it again, so we have to
* fix those backward pointers here. */
if (GS(id_old->name) == ID_OB) {
Object *ob = (Object *)id_old;
if (ob->proxy != NULL) {
ob->proxy->proxy_from = ob;
}
/* For undo we stay in object mode during undo presses, so keep editmode disabled for re-used
* data-blocks too. */
ob->mode &= ~OB_MODE_EDIT;

View File

@@ -144,14 +144,6 @@ FileData *blo_filedata_from_memfile(struct MemFile *memfile,
const struct BlendFileReadParams *params,
struct BlendFileReadReport *reports);
/**
* Lib linked proxy objects point to our local data, we need
* to clear that pointer before reading the undo memfile since
* the object might be removed, it is set again in reading
* if the local object still exists.
* This is only valid for local proxy objects though, linked ones should not be affected here.
*/
void blo_clear_proxy_pointers_from_lib(struct Main *oldmain);
void blo_make_packed_pointer_map(FileData *fd, struct Main *oldmain);
/**
* Set old main packed data to zero if it has been restored

View File

@@ -111,9 +111,6 @@ typedef enum eDepsObjectComponentType {
/* Parameters Component - Default when nothing else fits
* (i.e. just SDNA property setting). */
DEG_OB_COMP_PARAMETERS,
/* Generic "Proxy-Inherit" Component.
* TODO(sergey): Also for instancing of subgraphs? */
DEG_OB_COMP_PROXY,
/* Animation Component.
*
* TODO(sergey): merge in with parameters? */

View File

@@ -125,10 +125,6 @@ bool DepsgraphBuilder::check_pchan_has_bbone(Object *object, const bPoseChannel
bool DepsgraphBuilder::check_pchan_has_bbone_segments(Object *object, const bPoseChannel *pchan)
{
/* Proxies don't have BONE_SEGMENTS */
if (ID_IS_LINKED(object) && object->proxy_from != nullptr) {
return false;
}
return check_pchan_has_bbone(object, pchan);
}

View File

@@ -726,9 +726,6 @@ void DepsgraphNodeBuilder::build_object(int base_index,
eDepsNode_LinkedState_Type linked_state,
bool is_visible)
{
if (object->proxy != nullptr) {
object->proxy->proxy_from = object;
}
const bool has_object = built_map_.checkIsBuiltAndTag(object);
/* When there is already object in the dependency graph accumulate visibility an linked state
@@ -819,9 +816,6 @@ void DepsgraphNodeBuilder::build_object(int base_index,
(object->pd->tex != nullptr)) {
build_texture(object->pd->tex);
}
/* Proxy object to copy from. */
build_object_proxy_from(object, is_visible);
build_object_proxy_group(object, is_visible);
/* Object dupligroup. */
if (object->instance_collection != nullptr) {
build_object_instance_collection(object, is_visible);
@@ -875,22 +869,6 @@ void DepsgraphNodeBuilder::build_object_flags(int base_index,
});
}
void DepsgraphNodeBuilder::build_object_proxy_from(Object *object, bool is_object_visible)
{
if (object->proxy_from == nullptr) {
return;
}
build_object(-1, object->proxy_from, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
}
void DepsgraphNodeBuilder::build_object_proxy_group(Object *object, bool is_object_visible)
{
if (object->proxy_group == nullptr) {
return;
}
build_object(-1, object->proxy_group, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
}
void DepsgraphNodeBuilder::build_object_instance_collection(Object *object, bool is_object_visible)
{
if (object->instance_collection == nullptr) {
@@ -922,12 +900,7 @@ void DepsgraphNodeBuilder::build_object_data(Object *object)
build_object_data_geometry(object);
break;
case OB_ARMATURE:
if (ID_IS_LINKED(object) && object->proxy_from != nullptr) {
build_proxy_rig(object);
}
else {
build_rig(object);
}
break;
case OB_LAMP:
build_object_data_light(object);
@@ -1183,12 +1156,6 @@ void DepsgraphNodeBuilder::build_driver_variables(ID *id, FCurve *fcurve)
}
build_id(dtar->id);
build_driver_id_property(dtar->id, dtar->rna_path);
/* Corresponds to dtar_id_ensure_proxy_from(). */
if ((GS(dtar->id->name) == ID_OB) && (((Object *)dtar->id)->proxy_from != nullptr)) {
Object *proxy_from = ((Object *)dtar->id)->proxy_from;
build_id(&proxy_from->id);
build_driver_id_property(&proxy_from->id, dtar->rna_path);
}
}
DRIVER_TARGETS_LOOPER_END;
}

View File

@@ -184,8 +184,6 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
Object *object,
eDepsNode_LinkedState_Type linked_state,
bool is_visible);
virtual void build_object_proxy_from(Object *object, bool is_object_visible);
virtual void build_object_proxy_group(Object *object, bool is_object_visible);
virtual void build_object_instance_collection(Object *object, bool is_object_visible);
virtual void build_object_from_layer(int base_index,
Object *object,
@@ -232,7 +230,6 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
virtual void build_ik_pose(Object *object, bPoseChannel *pchan, bConstraint *con);
virtual void build_splineik_pose(Object *object, bPoseChannel *pchan, bConstraint *con);
virtual void build_rig(Object *object);
virtual void build_proxy_rig(Object *object);
virtual void build_armature(bArmature *armature);
virtual void build_armature_bones(ListBase *bones);
virtual void build_shapekeys(Key *key);

View File

@@ -306,72 +306,4 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
}
}
void DepsgraphNodeBuilder::build_proxy_rig(Object *object)
{
bArmature *armature = (bArmature *)object->data;
OperationNode *op_node;
Object *object_cow = get_cow_datablock(object);
/* Sanity check. */
BLI_assert(object->pose != nullptr);
/* Armature. */
build_armature(armature);
/* speed optimization for animation lookups */
BKE_pose_channels_hash_ensure(object->pose);
if (object->pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
BKE_pose_update_constraint_flags(object->pose);
}
op_node = add_operation_node(
&object->id,
NodeType::EVAL_POSE,
OperationCode::POSE_INIT,
[object_cow](::Depsgraph *depsgraph) { BKE_pose_eval_proxy_init(depsgraph, object_cow); });
op_node->set_as_entry();
int pchan_index = 0;
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
op_node = add_operation_node(
&object->id, NodeType::BONE, pchan->name, OperationCode::BONE_LOCAL);
op_node->set_as_entry();
/* Bone is ready for solvers. */
add_operation_node(&object->id, NodeType::BONE, pchan->name, OperationCode::BONE_READY);
/* Bone is fully evaluated. */
op_node = add_operation_node(&object->id,
NodeType::BONE,
pchan->name,
OperationCode::BONE_DONE,
[object_cow, pchan_index](::Depsgraph *depsgraph) {
BKE_pose_eval_proxy_copy_bone(
depsgraph, object_cow, pchan_index);
});
op_node->set_as_exit();
/* Custom properties. */
if (pchan->prop != nullptr) {
build_idproperties(pchan->prop);
add_operation_node(
&object->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, nullptr, pchan->name);
}
/* Custom shape. */
if (pchan->custom != nullptr) {
/* NOTE: The relation builder will ensure visibility of the custom shape object. */
build_object(-1, pchan->custom, DEG_ID_LINKED_INDIRECTLY, false);
}
pchan_index++;
}
op_node = add_operation_node(&object->id,
NodeType::EVAL_POSE,
OperationCode::POSE_CLEANUP,
[object_cow](::Depsgraph *depsgraph) {
BKE_pose_eval_proxy_cleanup(depsgraph, object_cow);
});
op_node = add_operation_node(
&object->id,
NodeType::EVAL_POSE,
OperationCode::POSE_DONE,
[object_cow](::Depsgraph *depsgraph) { BKE_pose_eval_proxy_done(depsgraph, object_cow); });
op_node->set_as_exit();
}
} // namespace blender::deg

View File

@@ -787,9 +787,6 @@ void DepsgraphRelationBuilder::build_object(Object *object)
(object->pd->tex != nullptr)) {
build_texture(object->pd->tex);
}
/* Proxy object to copy from. */
build_object_proxy_from(object);
build_object_proxy_group(object);
/* Object dupligroup. */
if (object->instance_collection != nullptr) {
build_collection(nullptr, object, object->instance_collection);
@@ -804,31 +801,6 @@ void DepsgraphRelationBuilder::build_object(Object *object)
build_parameters(&object->id);
}
void DepsgraphRelationBuilder::build_object_proxy_from(Object *object)
{
if (object->proxy_from == nullptr) {
return;
}
/* Object is linked here (comes from the library). */
build_object(object->proxy_from);
ComponentKey ob_transform_key(&object->proxy_from->id, NodeType::TRANSFORM);
ComponentKey proxy_transform_key(&object->id, NodeType::TRANSFORM);
add_relation(ob_transform_key, proxy_transform_key, "Proxy Transform");
}
void DepsgraphRelationBuilder::build_object_proxy_group(Object *object)
{
if (ELEM(object->proxy_group, nullptr, object->proxy)) {
return;
}
/* Object is local here (local in .blend file, users interacts with it). */
build_object(object->proxy_group);
OperationKey proxy_group_eval_key(
&object->proxy_group->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_EVAL);
OperationKey transform_eval_key(&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_EVAL);
add_relation(proxy_group_eval_key, transform_eval_key, "Proxy Group Transform");
}
void DepsgraphRelationBuilder::build_object_from_layer_relations(Object *object)
{
OperationKey object_from_layer_entry_key(
@@ -895,12 +867,7 @@ void DepsgraphRelationBuilder::build_object_data(Object *object)
break;
}
case OB_ARMATURE:
if (ID_IS_LINKED(object) && object->proxy_from != nullptr) {
build_proxy_rig(object);
}
else {
build_rig(object);
}
break;
case OB_LAMP:
build_object_data_light(object);
@@ -1663,18 +1630,9 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
}
build_id(target_id);
build_driver_id_property(target_id, dtar->rna_path);
/* Look up the proxy - matches dtar_id_ensure_proxy_from during evaluation. */
Object *object = nullptr;
if (GS(target_id->name) == ID_OB) {
object = (Object *)target_id;
if (object->proxy_from != nullptr) {
/* Redirect the target to the proxy, like in evaluation. */
object = object->proxy_from;
target_id = &object->id;
/* Prepare the redirected target. */
build_id(target_id);
build_driver_id_property(target_id, dtar->rna_path);
}
}
/* Special handling for directly-named bones. */
if ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (object && object->type == OB_ARMATURE) &&

View File

@@ -216,8 +216,6 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
Object *object,
Collection *collection);
virtual void build_object(Object *object);
virtual void build_object_proxy_from(Object *object);
virtual void build_object_proxy_group(Object *object);
virtual void build_object_from_layer_relations(Object *object);
virtual void build_object_data(Object *object);
virtual void build_object_data_camera(Object *object);
@@ -273,7 +271,6 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
const bPoseChannel *rootchan,
const RootPChanMap *root_map);
virtual void build_rig(Object *object);
virtual void build_proxy_rig(Object *object);
virtual void build_shapekeys(Key *key);
virtual void build_armature(bArmature *armature);
virtual void build_armature_bones(ListBase *bones);

View File

@@ -471,65 +471,4 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
}
}
void DepsgraphRelationBuilder::build_proxy_rig(Object *object)
{
bArmature *armature = (bArmature *)object->data;
Object *proxy_from = object->proxy_from;
build_armature(armature);
OperationKey pose_init_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_INIT);
OperationKey pose_done_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE);
OperationKey pose_cleanup_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_CLEANUP);
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
build_idproperties(pchan->prop);
OperationKey bone_local_key(
&object->id, NodeType::BONE, pchan->name, OperationCode::BONE_LOCAL);
OperationKey bone_ready_key(
&object->id, NodeType::BONE, pchan->name, OperationCode::BONE_READY);
OperationKey bone_done_key(&object->id, NodeType::BONE, pchan->name, OperationCode::BONE_DONE);
OperationKey from_bone_done_key(
&proxy_from->id, NodeType::BONE, pchan->name, OperationCode::BONE_DONE);
add_relation(pose_init_key, bone_local_key, "Pose Init -> Bone Local");
add_relation(bone_local_key, bone_ready_key, "Local -> Ready");
add_relation(bone_ready_key, bone_done_key, "Ready -> Done");
add_relation(bone_done_key, pose_cleanup_key, "Bone Done -> Pose Cleanup");
add_relation(bone_done_key, pose_done_key, "Bone Done -> Pose Done", RELATION_FLAG_GODMODE);
/* Make sure bone in the proxy is not done before its FROM is done. */
if (check_pchan_has_bbone(object, pchan)) {
OperationKey from_bone_segments_key(
&proxy_from->id, NodeType::BONE, pchan->name, OperationCode::BONE_SEGMENTS);
add_relation(from_bone_segments_key,
bone_done_key,
"Bone Segments -> Bone Done",
RELATION_FLAG_GODMODE);
}
else {
add_relation(from_bone_done_key, bone_done_key, "Bone Done -> Bone Done");
}
/* Parent relation: even though the proxy bone itself doesn't need
* the parent bone, some users expect the parent to be ready if the
* bone itself is (e.g. for computing the local space matrix).
*/
if (pchan->parent != nullptr) {
OperationKey parent_key(
&object->id, NodeType::BONE, pchan->parent->name, OperationCode::BONE_DONE);
add_relation(parent_key, bone_done_key, "Parent Bone -> Child Bone");
}
if (pchan->prop != nullptr) {
OperationKey bone_parameters(
&object->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, pchan->name);
OperationKey from_bone_parameters(
&proxy_from->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, pchan->name);
add_relation(from_bone_parameters, bone_parameters, "Proxy Bone Parameters");
}
/* Custom shape. */
if (pchan->custom != nullptr) {
build_object(pchan->custom);
add_visibility_relation(&pchan->custom->id, &armature->id);
}
}
}
} // namespace blender::deg

View File

@@ -63,17 +63,6 @@ class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder {
return DepsgraphNodeBuilder::need_pull_base_into_graph(base);
}
void build_object_proxy_group(Object *object, bool is_visible) override
{
if (object->proxy_group == nullptr) {
return;
}
if (!filter_.contains(&object->proxy_group->id)) {
return;
}
DepsgraphNodeBuilder::build_object_proxy_group(object, is_visible);
}
protected:
DepsgraphFromIDsFilter filter_;
};
@@ -96,17 +85,6 @@ class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder {
return DepsgraphRelationBuilder::need_pull_base_into_graph(base);
}
void build_object_proxy_group(Object *object) override
{
if (object->proxy_group == nullptr) {
return;
}
if (!filter_.contains(&object->proxy_group->id)) {
return;
}
DepsgraphRelationBuilder::build_object_proxy_group(object);
}
protected:
DepsgraphFromIDsFilter filter_;
};

View File

@@ -36,10 +36,7 @@ namespace deg {
* visibility and other flags assigned to the objects.
* All other bases (the ones which points to object which is outside of the set of IDs) are
* completely ignored.
*
* - Proxy groups pointing to objects which are outside of the IDs set are also ignored.
* This way we avoid high-poly character body pulled into the dependency graph when it's coming
* from a library into an animation file and the dependency graph constructed for a proxy rig. */
*/
class FromIDsBuilderPipeline : public AbstractBuilderPipeline {
public:

View File

@@ -99,7 +99,6 @@ static const int deg_debug_node_type_color_map[][2] = {
/* Outer Types */
{NodeType::PARAMETERS, 2},
{NodeType::PROXY, 3},
{NodeType::ANIMATION, 4},
{NodeType::TRANSFORM, 5},
{NodeType::GEOMETRY, 6},
@@ -404,7 +403,6 @@ static void deg_debug_graphviz_node(DotExportContext &ctx,
case NodeType::PARAMETERS:
case NodeType::ANIMATION:
case NodeType::TRANSFORM:
case NodeType::PROXY:
case NodeType::GEOMETRY:
case NodeType::SEQUENCER:
case NodeType::EVAL_POSE:

View File

@@ -526,12 +526,6 @@ void graph_tag_ids_for_visible_update(Depsgraph *graph)
* this. */
for (deg::IDNode *id_node : graph->id_nodes) {
const ID_Type id_type = GS(id_node->id_orig->name);
if (id_type == ID_OB) {
Object *object_orig = reinterpret_cast<Object *>(id_node->id_orig);
if (object_orig->proxy != nullptr) {
object_orig->proxy->proxy_from = object_orig;
}
}
if (!id_node->visible_components_mask) {
/* ID has no components which affects anything visible.

View File

@@ -708,25 +708,6 @@ void update_animation_data_after_copy(const ID *id_orig, ID *id_cow)
update_nla_tracks_orig_pointers(&anim_data_orig->nla_tracks, &anim_data_cow->nla_tracks);
}
/* Some builders (like motion path one) will ignore proxies from being built. This code makes it so
* proxy and proxy_group pointers never point to an original objects, preventing evaluation code
* from assign evaluated pointer to an original proxy->proxy_from. */
void update_proxy_pointers_after_copy(const Depsgraph *depsgraph,
const Object *object_orig,
Object *object_cow)
{
if (object_cow->proxy != nullptr) {
if (!deg_check_id_in_depsgraph(depsgraph, &object_orig->proxy->id)) {
object_cow->proxy = nullptr;
}
}
if (object_cow->proxy_group != nullptr) {
if (!deg_check_id_in_depsgraph(depsgraph, &object_orig->proxy_group->id)) {
object_cow->proxy_group = nullptr;
}
}
}
/* Do some special treatment of data transfer from original ID to its
* CoW complementary part.
*
@@ -760,7 +741,6 @@ void update_id_after_copy(const Depsgraph *depsgraph,
BKE_gpencil_update_orig_pointers(object_orig, object_cow);
}
update_particles_after_copy(depsgraph, object_orig, object_cow);
update_proxy_pointers_after_copy(depsgraph, object_orig, object_cow);
break;
}
case ID_SCE: {

View File

@@ -67,8 +67,6 @@ const char *nodeTypeAsString(NodeType type)
/* **** Outer Types **** */
case NodeType::PARAMETERS:
return "PARAMETERS";
case NodeType::PROXY:
return "PROXY";
case NodeType::ANIMATION:
return "ANIMATION";
case NodeType::TRANSFORM:
@@ -174,7 +172,6 @@ eDepsSceneComponentType nodeTypeToSceneComponent(NodeType type)
case NodeType::BONE:
case NodeType::SHADING:
case NodeType::CACHE:
case NodeType::PROXY:
case NodeType::SIMULATION:
case NodeType::NTREE_OUTPUT:
return DEG_SCENE_COMP_PARAMETERS;
@@ -194,8 +191,6 @@ NodeType nodeTypeFromObjectComponent(eDepsObjectComponentType component_type)
return NodeType::UNDEFINED;
case DEG_OB_COMP_PARAMETERS:
return NodeType::PARAMETERS;
case DEG_OB_COMP_PROXY:
return NodeType::PROXY;
case DEG_OB_COMP_ANIMATION:
return NodeType::ANIMATION;
case DEG_OB_COMP_TRANSFORM:
@@ -219,8 +214,6 @@ eDepsObjectComponentType nodeTypeToObjectComponent(NodeType type)
switch (type) {
case NodeType::PARAMETERS:
return DEG_OB_COMP_PARAMETERS;
case NodeType::PROXY:
return DEG_OB_COMP_PROXY;
case NodeType::ANIMATION:
return DEG_OB_COMP_ANIMATION;
case NodeType::TRANSFORM:

View File

@@ -77,8 +77,6 @@ enum class NodeType {
/* Parameters Component - Default when nothing else fits
* (i.e. just SDNA property setting). */
PARAMETERS,
/* Generic "Proxy-Inherit" Component. */
PROXY,
/* Animation Component */
ANIMATION,
/* Transform Component (Parenting/Constraints) */

View File

@@ -339,7 +339,6 @@ DEG_COMPONENT_NODE_DEFINE(Particles, PARTICLE_SYSTEM, ID_RECALC_GEOMETRY);
DEG_COMPONENT_NODE_DEFINE(ParticleSettings, PARTICLE_SETTINGS, 0);
DEG_COMPONENT_NODE_DEFINE(PointCache, POINT_CACHE, 0);
DEG_COMPONENT_NODE_DEFINE(Pose, EVAL_POSE, ID_RECALC_GEOMETRY);
DEG_COMPONENT_NODE_DEFINE(Proxy, PROXY, ID_RECALC_GEOMETRY);
DEG_COMPONENT_NODE_DEFINE(Sequencer, SEQUENCER, 0);
DEG_COMPONENT_NODE_DEFINE(Shading, SHADING, ID_RECALC_SHADING);
DEG_COMPONENT_NODE_DEFINE(Transform, TRANSFORM, ID_RECALC_TRANSFORM);
@@ -373,7 +372,6 @@ void deg_register_component_depsnodes()
register_node_typeinfo(&DNTI_PARTICLE_SETTINGS);
register_node_typeinfo(&DNTI_POINT_CACHE);
register_node_typeinfo(&DNTI_IMAGE_ANIMATION);
register_node_typeinfo(&DNTI_PROXY);
register_node_typeinfo(&DNTI_EVAL_POSE);
register_node_typeinfo(&DNTI_SEQUENCER);
register_node_typeinfo(&DNTI_SHADING);

View File

@@ -192,7 +192,6 @@ DEG_COMPONENT_NODE_DECLARE_GENERIC(Particles);
DEG_COMPONENT_NODE_DECLARE_GENERIC(ParticleSettings);
DEG_COMPONENT_NODE_DECLARE_GENERIC(Pose);
DEG_COMPONENT_NODE_DECLARE_GENERIC(PointCache);
DEG_COMPONENT_NODE_DECLARE_GENERIC(Proxy);
DEG_COMPONENT_NODE_DECLARE_GENERIC(Sequencer);
DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(Shading);
DEG_COMPONENT_NODE_DECLARE_GENERIC(ShadingParameters);

View File

@@ -2374,9 +2374,6 @@ static bool POSE_is_driven_by_active_armature(Object *ob)
if (ob_arm) {
const DRWContextState *draw_ctx = DRW_context_state_get();
bool is_active = OVERLAY_armature_is_pose_mode(ob_arm, draw_ctx);
if (!is_active && ob_arm->proxy_from) {
is_active = OVERLAY_armature_is_pose_mode(ob_arm->proxy_from, draw_ctx);
}
return is_active;
}

View File

@@ -149,36 +149,6 @@ bool ED_object_posemode_exit(bContext *C, Object *ob)
return ok;
}
/* if a selected or active bone is protected, throw error (only if warn == 1) and return 1 */
/* only_selected == 1: the active bone is allowed to be protected */
#if 0 /* UNUSED 2.5 */
static bool pose_has_protected_selected(Object *ob, short warn)
{
/* check protection */
if (ob->proxy) {
bPoseChannel *pchan;
bArmature *arm = ob->data;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone && BKE_pose_is_layer_visible(arm, pchan)) {
if (pchan->bone->layer & arm->layer_protected) {
if (pchan->bone->flag & BONE_SELECTED) {
break;
}
}
}
}
if (pchan) {
if (warn) {
error("Cannot change Proxy protected bones");
}
return 1;
}
}
return 0;
}
#endif
/* ********************************************** */
/* Motion Paths */
@@ -1056,10 +1026,6 @@ static int pose_hide_exec(bContext *C, wmOperator *op)
Object *ob_iter = objects[ob_index];
bArmature *arm = ob_iter->data;
if (ob_iter->proxy != NULL) {
BKE_report(op->reports, RPT_INFO, "Undo of hiding can only be done with Reveal Selected");
}
bool changed = bone_looper(ob_iter, arm->bonebase.first, hide_select_p, hide_pose_bone_fn) !=
0;
if (changed) {

View File

@@ -62,8 +62,8 @@ static bool pose_group_poll(bContext *C)
}
Object *obpose = ED_pose_object_from_context(C);
if ((obpose->proxy != NULL) || (obpose->proxy_group != NULL) || ID_IS_OVERRIDE_LIBRARY(obpose)) {
CTX_wm_operator_poll_msg_set(C, "Cannot edit bone groups for proxies or library overrides");
if (ID_IS_OVERRIDE_LIBRARY(obpose)) {
CTX_wm_operator_poll_msg_set(C, "Cannot edit bone groups for library overrides");
return false;
}

View File

@@ -2672,18 +2672,6 @@ static void constraint_ops_extra_draw(bContext *C, uiLayout *layout, void *con_v
static void draw_constraint_header(uiLayout *layout, Object *ob, bConstraint *con)
{
bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob);
short proxy_protected, xco = 0, yco = 0;
// int rb_col; // UNUSED
/* determine whether constraint is proxy protected or not */
if (BKE_constraints_proxylocked_owner(ob, pchan)) {
proxy_protected = (con->flag & CONSTRAINT_PROXY_LOCAL) == 0;
}
else {
proxy_protected = 0;
}
/* unless button has own callback, it adds this callback to button */
uiBlock *block = uiLayoutGetBlock(layout);
UI_block_func_set(block, constraint_active_func, ob, con);
@@ -2708,51 +2696,8 @@ static void draw_constraint_header(uiLayout *layout, Object *ob, bConstraint *co
uiLayout *row = uiLayoutRow(layout, true);
if (proxy_protected == 0) {
uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
}
else {
uiItemL(row, IFACE_(con->name), ICON_NONE);
}
/* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
if (proxy_protected) {
UI_block_emboss_set(block, UI_EMBOSS_NONE);
/* draw a ghost icon (for proxy) and also a lock beside it,
* to show that constraint is "proxy locked" */
uiDefIconBut(block,
UI_BTYPE_BUT,
0,
ICON_GHOST_ENABLED,
xco + 12.2f * UI_UNIT_X,
yco,
0.95f * UI_UNIT_X,
0.95f * UI_UNIT_Y,
NULL,
0.0,
0.0,
0.0,
0.0,
TIP_("Proxy Protected"));
uiDefIconBut(block,
UI_BTYPE_BUT,
0,
ICON_LOCKED,
xco + 13.1f * UI_UNIT_X,
yco,
0.95f * UI_UNIT_X,
0.95f * UI_UNIT_Y,
NULL,
0.0,
0.0,
0.0,
0.0,
TIP_("Proxy Protected"));
UI_block_emboss_set(block, UI_EMBOSS);
}
else {
/* Enabled eye icon. */
uiItemR(row, &ptr, "enabled", 0, "", ICON_NONE);
@@ -2764,16 +2709,10 @@ static void draw_constraint_header(uiLayout *layout, Object *ob, bConstraint *co
uiLayoutSetEmboss(sub, UI_EMBOSS_NONE);
uiLayoutSetOperatorContext(sub, WM_OP_INVOKE_DEFAULT);
uiItemO(sub, "", ICON_X, "CONSTRAINT_OT_delete");
}
/* Some extra padding at the end, so the 'x' icon isn't too close to drag button. */
uiItemS(layout);
/* Set but-locks for protected settings (magic numbers are used here!) */
if (proxy_protected) {
UI_block_lock_set(block, true, TIP_("Cannot edit Proxy-Protected Constraint"));
}
/* clear any locks set up for proxies/lib-linking */
UI_block_lock_clear(block);
}

View File

@@ -2347,11 +2347,6 @@ static void make_object_duplilist_real(bContext *C,
BKE_animdata_free(&ob_dst->id, true);
ob_dst->adt = NULL;
/* Proxies are not to be copied. */
ob_dst->proxy_from = NULL;
ob_dst->proxy_group = NULL;
ob_dst->proxy = NULL;
ob_dst->parent = NULL;
BKE_constraints_free(&ob_dst->constraints);
ob_dst->runtime.curve_cache = NULL;
@@ -2466,13 +2461,6 @@ static void make_object_duplilist_real(bContext *C,
}
if (base->object->transflag & OB_DUPLICOLLECTION && base->object->instance_collection) {
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
if (ob->proxy_group == base->object) {
ob->proxy = NULL;
ob->proxy_from = NULL;
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
}
}
base->object->instance_collection = NULL;
}

View File

@@ -1356,15 +1356,6 @@ void ED_object_constraint_update(Main *bmain, Object *ob)
static void object_pose_tag_update(Main *bmain, Object *ob)
{
BKE_pose_tag_recalc(bmain, ob->pose); /* Checks & sort pose channels. */
if (ob->proxy && ob->adt) {
/* We need to make use of ugly #POSE_ANIMATION_WORKAROUND here too,
* else anim data are not reloaded after calling `BKE_pose_rebuild()`,
* which causes T43872.
* Note that this is a bit wide here, since we cannot be sure whether there are some locked
* proxy bones or not.
* XXX Temp hack until new depsgraph hopefully solves this. */
DEG_id_tag_update(&ob->id, ID_RECALC_ANIMATION);
}
}
void ED_object_constraint_dependency_update(Main *bmain, Object *ob)
@@ -2453,12 +2444,6 @@ static int constraint_add_exec(
if ((ob->type == OB_ARMATURE) && (pchan)) {
BKE_pose_tag_recalc(bmain, ob->pose); /* sort pose channels */
if (BKE_constraints_proxylocked_owner(ob, pchan) && ob->adt) {
/* We need to make use of ugly POSE_ANIMATION_WORKAROUND here too,
* else anim data are not reloaded after calling `BKE_pose_rebuild()`, which causes T43872.
* XXX Temp hack until new depsgraph hopefully solves this. */
DEG_id_tag_update(&ob->id, ID_RECALC_ANIMATION);
}
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_TRANSFORM);
}
else {

View File

@@ -2480,9 +2480,6 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
case TSE_POSE_CHANNEL:
data.icon = ICON_BONE_DATA;
break;
case TSE_PROXY:
data.icon = ICON_GHOST_ENABLED;
break;
case TSE_R_LAYER_BASE:
data.icon = ICON_RENDERLAYERS;
break;

View File

@@ -302,10 +302,6 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
/* FIXME: add a special type for this. */
outliner_add_element(space_outliner, &te->subtree, ob->poselib, te, TSE_SOME_ID, 0);
if (ob->proxy && !ID_IS_LINKED(ob)) {
outliner_add_element(space_outliner, &te->subtree, ob->proxy, te, TSE_PROXY, 0);
}
outliner_add_element(space_outliner, &te->subtree, ob->data, te, TSE_SOME_ID, 0);
if (ob->pose) {

View File

@@ -478,9 +478,6 @@ typedef struct bPose {
short flag;
char _pad[2];
/** Proxy layer: copy from armature, gets synced. */
unsigned int proxy_layer;
char _pad1[4];
/** Local action time of this pose. */
float ctime;
@@ -503,8 +500,6 @@ typedef struct bPose {
/** Settings for visualization of bone animation. */
bAnimVizSettings avs;
/** Proxy active bone name, MAXBONENAME. */
char proxy_act_bone[64];
} bPose;
/* Pose->flag */

View File

@@ -714,8 +714,6 @@ typedef enum eBConstraint_Flags {
CONSTRAINT_SPACEONCE = (1 << 6),
/* influence ipo is on constraint itself, not in action channel */
CONSTRAINT_OWN_IPO = (1 << 7),
/* indicates that constraint was added locally (i.e. didn't come from the proxy-lib) */
CONSTRAINT_PROXY_LOCAL = (1 << 8),
/* indicates that constraint is temporarily disabled (only used in GE) */
CONSTRAINT_OFF = (1 << 9),
/* use bbone curve shape when calculating headtail values (also used by dependency graph!) */

View File

@@ -263,9 +263,10 @@ typedef struct Object {
/** String describing subobject info, MAX_ID_NAME-2. */
char parsubstr[64];
struct Object *parent, *track;
/* If `ob->proxy` (or proxy_group), this object is proxy for object `ob->proxy`. */
/* proxy_from is set in target back to the proxy. */
struct Object *proxy, *proxy_group, *proxy_from;
/* Proxy pointer are deprecated, only kept for conversion to liboverrides. */
struct Object *proxy DNA_DEPRECATED;
struct Object *proxy_group DNA_DEPRECATED;
struct Object *proxy_from DNA_DEPRECATED;
/** Old animation system, deprecated for 2.5. */
struct Ipo *ipo DNA_DEPRECATED;
/* struct Path *path; */

View File

@@ -101,7 +101,7 @@ typedef enum eTreeStoreElemType {
TSE_DRIVER_BASE = 16, /* NO ID */
/* TSE_DRIVER = 17, */ /* UNUSED */
TSE_PROXY = 18,
/* TSE_PROXY = 18, */ /* UNUSED */
TSE_R_LAYER_BASE = 19,
TSE_R_LAYER = 20,
/* TSE_R_PASS = 21, */ /* UNUSED */

View File

@@ -322,7 +322,7 @@ typedef enum PropertyFlag {
* FREE FLAGS: 2, 3, 4, 5, 6, 7, 8, 9, 12 and above.
*/
typedef enum PropertyOverrideFlag {
/** Means the property can be overridden by a local 'proxy' of some linked datablock. */
/** Means that the property can be overridden by a local override of some linked datablock. */
PROPOVERRIDE_OVERRIDABLE_LIBRARY = (1 << 0),
/**

View File

@@ -949,9 +949,9 @@ static void rna_ID_user_remap(ID *id, Main *bmain, ID *new_id)
}
}
static struct ID *rna_ID_make_local(struct ID *self, Main *bmain, bool clear_proxy)
static struct ID *rna_ID_make_local(struct ID *self, Main *bmain, bool UNUSED(clear_proxy))
{
BKE_lib_id_make_local(bmain, self, clear_proxy ? 0 : LIB_ID_MAKELOCAL_OBJECT_NO_PROXY_CLEARING);
BKE_lib_id_make_local(bmain, self, 0);
ID *ret_id = self->newid ? self->newid : self;
BKE_id_newptr_and_tag_clear(self);
@@ -2089,13 +2089,7 @@ static void rna_def_ID(BlenderRNA *brna)
"Make this datablock local, return local one "
"(may be a copy of the original, in case it is also indirectly used)");
RNA_def_function_flag(func, FUNC_USE_MAIN);
parm = RNA_def_boolean(
func,
"clear_proxy",
true,
"",
"Whether to clear proxies (the default behavior, "
"note that if object has to be duplicated to be made local, proxies are always cleared)");
parm = RNA_def_boolean(func, "clear_proxy", true, "", "Deprecated, has no effect");
parm = RNA_def_pointer(func, "id", "ID", "", "This ID, or the new ID if it was copied");
RNA_def_function_return(func, parm);

View File

@@ -151,18 +151,9 @@ static void rna_Armature_edit_bone_remove(bArmature *arm,
RNA_POINTER_INVALIDATE(ebone_ptr);
}
static void rna_Armature_update_layers(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
static void rna_Armature_update_layers(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
bArmature *arm = (bArmature *)ptr->owner_id;
Object *ob;
/* proxy lib exception, store it here so we can restore layers on file
* load, since it would otherwise get lost due to being linked data */
for (ob = bmain->objects.first; ob; ob = ob->id.next) {
if (ob->data == arm && ob->pose) {
ob->pose->proxy_layer = arm->layer;
}
}
DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
WM_main_add_notifier(NC_GEOM | ND_DATA, arm);

View File

@@ -3543,14 +3543,6 @@ void RNA_def_constraint(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_ACTIVE);
RNA_def_property_ui_text(prop, "Active", "Constraint is the one being edited");
prop = RNA_def_property(srna, "is_proxy_local", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_PROXY_LOCAL);
RNA_def_property_ui_text(
prop,
"Proxy Local",
"Constraint was added in this proxy instance (i.e. did not belong to source Armature)");
/* values */
prop = RNA_def_property(srna, "influence", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "enforce");

View File

@@ -3150,19 +3150,6 @@ static void rna_def_object(BlenderRNA *brna)
"Align to Vertex Normal is enabled)");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
/* proxy */
prop = RNA_def_property(srna, "proxy", PROP_POINTER, PROP_NONE);
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_override_clear_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_ui_text(prop, "Proxy", "Library object this proxy object controls");
prop = RNA_def_property(srna, "proxy_collection", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "proxy_group");
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_override_clear_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_ui_text(
prop, "Proxy Collection", "Library collection duplicator object this proxy object controls");
/* materials */
prop = RNA_def_property(srna, "material_slots", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "MaterialSlot");

View File

@@ -140,7 +140,7 @@ static char *rna_PoseBone_path(PointerRNA *ptr)
static bool rna_bone_group_poll(Object *ob, ReportList *reports)
{
if ((ob->proxy != NULL) || (ob->proxy_group != NULL) || ID_IS_OVERRIDE_LIBRARY(ob)) {
if (ID_IS_OVERRIDE_LIBRARY(ob)) {
BKE_report(reports, RPT_ERROR, "Cannot edit bone groups for proxies or library overrides");
return false;
}
@@ -717,7 +717,7 @@ static int rna_PoseChannel_proxy_editable(PointerRNA *ptr, const char **r_info)
bArmature *arm = ob->data;
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
if (ob->proxy && pchan->bone && (pchan->bone->layer & arm->layer_protected)) {
if (false && pchan->bone && (pchan->bone->layer & arm->layer_protected)) {
*r_info = "Can't edit property of a proxy on a protected layer";
return 0;
}

View File

@@ -94,7 +94,7 @@ static int foreach_libblock_id_user_map_callback(LibraryIDLinkCallbackData *cb_d
}
if (cb_flag & IDWALK_CB_LOOPBACK) {
/* We skip loop-back pointers like Object.proxy_from or Key.from here,
/* We skip loop-back pointers like Key.from here,
* since it's some internal pointer which is not relevant info for py/API level. */
return IDWALK_RET_NOP;
}