diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2018-05-02 19:13:15 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2018-05-02 19:14:19 +0300 |
commit | 0fb5a39baf46440a1dfbef939bb46bbb2b610036 (patch) | |
tree | afb465fa28e5aec22231835fd3670e5eef8ea69b | |
parent | 6a9e6b1448be0f77291fdb9372587ba88421bf3b (diff) |
Static Override: add insertion for modifiers and one constraints, fix editing of inserted items in collections.
Now insertable collection items have a flag to say they are 'local' (and
hence can be freely edited).
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 2 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 13 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_constraint_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 9 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 19 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object.c | 51 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_pose.c | 49 |
8 files changed, 144 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 70d45e6a466..3ad385bb609 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -4530,7 +4530,7 @@ static bConstraint *add_new_constraint_internal(const char *name, short type) /* Set up a generic constraint datablock */ con->type = type; - con->flag |= CONSTRAINT_EXPAND; + con->flag |= CONSTRAINT_EXPAND | CONSTRAINT_STATICOVERRIDE_LOCAL; con->enforce = 1.0f; /* Determine a basic name, and info */ diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 6722ed2aab1..5153951d2a2 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -132,6 +132,7 @@ ModifierData *modifier_new(int type) md->type = type; md->mode = eModifierMode_Realtime | eModifierMode_Render | eModifierMode_Expanded; + md->flag = eModifierFlag_StaticOverride_Local; if (mti->flags & eModifierTypeFlag_EnableInEditmode) md->mode |= eModifierMode_Editmode; @@ -311,6 +312,7 @@ void modifier_copyData_ex(ModifierData *md, ModifierData *target, const int flag const ModifierTypeInfo *mti = modifierType_getInfo(md->type); target->mode = md->mode; + target->flag = md->flag; if (mti->copyData) { mti->copyData(md, target); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 05a74dc90c2..7b8f9db618d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3391,6 +3391,11 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist) } /* own ipo, all constraints have it */ con->ipo = newlibadr_us(fd, id->lib, con->ipo); // XXX deprecated - old animation system + + /* If linking from a library, clear 'local' static override flag. */ + if (id->lib != NULL) { + con->flag &= ~CONSTRAINT_STATICOVERRIDE_LOCAL; + } } /* relink all ID-blocks used by the constraints */ @@ -4784,6 +4789,14 @@ static void lib_link_modifiers__linkModifiers( static void lib_link_modifiers(FileData *fd, Object *ob) { modifiers_foreachIDLink(ob, lib_link_modifiers__linkModifiers, fd); + + /* If linking from a library, clear 'local' static override flag. */ + if (ob->id.lib != NULL) { + for (ModifierData *mod = ob->modifiers.first; mod != NULL; mod = mod->next) { + mod->flag &= ~eModifierFlag_StaticOverride_Local; + } + } + } static void lib_link_object(FileData *fd, Main *main) diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 9a87b64ac08..f0f8c3fe2bd 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -526,6 +526,8 @@ typedef enum eBConstraint_Flags { CONSTRAINT_OFF = (1<<9), /* use bbone curve shape when calculating headtail values */ CONSTRAINT_BBONE_SHAPE = (1<<10), + /* That constraint has been inserted in local override (i.e. it can be fully edited!). */ + CONSTRAINT_STATICOVERRIDE_LOCAL = (1 << 11), } eBConstraint_Flags; /* bConstraint->ownspace/tarspace */ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index a7f9acb8a42..cfa101b0b6e 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -105,7 +105,9 @@ typedef struct ModifierData { struct ModifierData *next, *prev; int type, mode; - int stackindex, pad; + int stackindex; + short flag; + short pad; char name[64]; /* MAX_NAME */ /* XXX for timing info set by caller... solve later? (ton) */ @@ -115,6 +117,11 @@ typedef struct ModifierData { } ModifierData; typedef enum { + /* This modifier has been inserted in local override, and hence can be fully edited. */ + eModifierFlag_StaticOverride_Local = (1 << 0), +} ModifierFlag; + +typedef enum { eSubsurfModifierFlag_Incremental = (1 << 0), eSubsurfModifierFlag_DebugIncr = (1 << 1), eSubsurfModifierFlag_ControlEdges = (1 << 2), diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 39815dbc3d2..7bf00ef65f6 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -34,6 +34,8 @@ #include "DNA_ID.h" #include "DNA_scene_types.h" +#include "DNA_constraint_types.h" +#include "DNA_modifier_types.h" #include "DNA_windowmanager_types.h" #include "BLI_blenlib.h" @@ -1966,9 +1968,24 @@ bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop) /** \note Does not take into account editable status, this has to be checked separately * (using RNA_property_edtiable_flag() usually). */ -bool RNA_property_overridable_get(PointerRNA *UNUSED(ptr), PropertyRNA *prop) +bool RNA_property_overridable_get(PointerRNA *ptr, PropertyRNA *prop) { if (prop->magic == RNA_MAGIC) { + /* Special handling for insertions of constraints or modifiers... */ + /* TODO Note We may want to add a more generic system to RNA (like a special property in struct of items) + * if we get more overrideable collections, for now we can live with those special-cases handling I think. */ + if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) { + bConstraint *con = ptr->data; + if (con->flag & CONSTRAINT_STATICOVERRIDE_LOCAL) { + return true; + } + } + else if (RNA_struct_is_a(ptr->type, &RNA_Modifier)) { + ModifierData *mod = ptr->data; + if (mod->flag & eModifierFlag_StaticOverride_Local) { + return true; + } + } /* If this is a RNA-defined property (real or 'virtual' IDProp), we want to use RNA prop flag. */ return !(prop->flag & PROP_NO_COMPARISON) && (prop->flag & PROP_OVERRIDABLE_STATIC); } diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 2d91ac28c5b..079f761ccdd 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -188,6 +188,7 @@ const EnumPropertyItem rna_enum_object_axis_items[] = { #include "BKE_object.h" #include "BKE_material.h" #include "BKE_mesh.h" +#include "BKE_modifier.h" #include "BKE_particle.h" #include "BKE_scene.h" #include "BKE_deform.h" @@ -1208,6 +1209,55 @@ static void rna_Object_modifier_clear(Object *object, bContext *C) WM_main_add_notifier(NC_OBJECT | ND_MODIFIER | NA_REMOVED, object); } +bool rna_Object_modifiers_override_apply( + PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *UNUSED(ptr_storage), + PropertyRNA *UNUSED(prop_dst), PropertyRNA *UNUSED(prop_src), PropertyRNA *UNUSED(prop_storage), + const int UNUSED(len_dst), const int UNUSED(len_src), const int UNUSED(len_storage), + IDOverrideStaticPropertyOperation *opop) +{ + BLI_assert(opop->operation == IDOVERRIDESTATIC_OP_INSERT_AFTER && + "Unsupported RNA override operation on modifiers collection"); + + Object *ob_dst = (Object *)ptr_dst->id.data; + Object *ob_src = (Object *)ptr_src->id.data; + + /* Remember that insertion operations are defined and stored in correct order, which means that + * even if we insert several items in a row, we alays insert first one, then second one, etc. + * So we should always find 'anchor' constraint in both _src *and* _dst> */ + ModifierData *mod_anchor = NULL; + if (opop->subitem_local_name && opop->subitem_local_name[0]) { + mod_anchor = BLI_findstring(&ob_dst->modifiers, opop->subitem_local_name, offsetof(ModifierData, name)); + } + if (mod_anchor == NULL && opop->subitem_local_index >= 0) { + mod_anchor = BLI_findlink(&ob_dst->modifiers, opop->subitem_local_index); + } + /* Otherwise we just insert in first position. */ + + ModifierData *mod_src = NULL; + if (opop->subitem_local_name && opop->subitem_local_name[0]) { + mod_src = BLI_findstring(&ob_src->modifiers, opop->subitem_local_name, offsetof(ModifierData, name)); + } + if (mod_src == NULL && opop->subitem_local_index >= 0) { + mod_src = BLI_findlink(&ob_src->modifiers, opop->subitem_local_index); + } + mod_src = mod_src ? mod_src->next : ob_src->modifiers.first; + + BLI_assert(mod_src != NULL); + + ModifierData *mod_dst = modifier_new(mod_src->type); + modifier_copyData(mod_src, mod_dst); + + /* This handles NULL anchor as expected by adding at head of list. */ + BLI_insertlinkafter(&ob_dst->modifiers, mod_anchor, mod_dst); + + /* This should actually *not* be needed in typical cases. However, if overridden source was edited, + * we *may* have some new conflicting names. */ + modifier_unique_name(&ob_dst->modifiers, mod_dst); + +// printf("%s: We inserted a modifier...\n", __func__); + return true; +} + static void rna_Object_boundbox_get(PointerRNA *ptr, float *values) { Object *ob = (Object *)ptr->id.data; @@ -2116,6 +2166,7 @@ static void rna_def_object(BlenderRNA *brna) prop = RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "Modifier"); RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting the geometric data of the object"); + RNA_def_property_override_funcs(prop, NULL, NULL, "rna_Object_modifiers_override_apply"); RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC | PROP_OVERRIDABLE_STATIC_INSERTION); rna_def_object_modifiers(brna, prop); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index df1e7a63bd9..8acf0f755f8 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -563,6 +563,54 @@ static void rna_PoseChannel_constraints_remove(ID *id, bPoseChannel *pchan, Repo } } +bool rna_PoseChannel_constraints_override_apply( + PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *UNUSED(ptr_storage), + PropertyRNA *UNUSED(prop_dst), PropertyRNA *UNUSED(prop_src), PropertyRNA *UNUSED(prop_storage), + const int UNUSED(len_dst), const int UNUSED(len_src), const int UNUSED(len_storage), + IDOverrideStaticPropertyOperation *opop) +{ + BLI_assert(opop->operation == IDOVERRIDESTATIC_OP_INSERT_AFTER && + "Unsupported RNA override operation on constraints collection"); + + bPoseChannel *pchan_dst = (bPoseChannel *)ptr_dst->data; + bPoseChannel *pchan_src = (bPoseChannel *)ptr_src->data; + + /* Remember that insertion operations are defined and stored in correct order, which means that + * even if we insert several items in a row, we alays insert first one, then second one, etc. + * So we should always find 'anchor' constraint in both _src *and* _dst> */ + bConstraint *con_anchor = NULL; + if (opop->subitem_local_name && opop->subitem_local_name[0]) { + con_anchor = BLI_findstring(&pchan_dst->constraints, opop->subitem_local_name, offsetof(bConstraint, name)); + } + if (con_anchor == NULL && opop->subitem_local_index >= 0) { + con_anchor = BLI_findlink(&pchan_dst->constraints, opop->subitem_local_index); + } + /* Otherwise we just insert in first position. */ + + bConstraint *con_src = NULL; + if (opop->subitem_local_name && opop->subitem_local_name[0]) { + con_src = BLI_findstring(&pchan_src->constraints, opop->subitem_local_name, offsetof(bConstraint, name)); + } + if (con_src == NULL && opop->subitem_local_index >= 0) { + con_src = BLI_findlink(&pchan_src->constraints, opop->subitem_local_index); + } + con_src = con_src ? con_src->next : pchan_src->constraints.first; + + BLI_assert(con_src != NULL); + + bConstraint *con_dst = BKE_constraint_duplicate_ex(con_src, 0, true); + + /* This handles NULL anchor as expected by adding at head of list. */ + BLI_insertlinkafter(&pchan_dst->constraints, con_anchor, con_dst); + + /* This should actually *not* be needed in typical cases. However, if overridden source was edited, + * we *may* have some new conflicting names. */ + BKE_constraint_unique_name(con_dst, &pchan_dst->constraints); + +// printf("%s: We inserted a constraint...\n", __func__); + return true; +} + static int rna_PoseChannel_proxy_editable(PointerRNA *ptr, const char **r_info) { Object *ob = (Object *)ptr->id.data; @@ -808,6 +856,7 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_struct_type(prop, "Constraint"); RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC | PROP_OVERRIDABLE_STATIC_INSERTION); RNA_def_property_ui_text(prop, "Constraints", "Constraints that act on this PoseChannel"); + RNA_def_property_override_funcs(prop, NULL, NULL, "rna_PoseChannel_constraints_override_apply"); rna_def_pose_channel_constraints(brna, prop); |