Commit: 3cd8264505be135749454e640c64f99296b3490a
Author: Bastien Montagne
Date:   Tue Jan 16 17:04:53 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB3cd8264505be135749454e640c64f99296b3490a

Static override: enhance 'make override' operator.

Now when you make an override of a linked armature, code will
automatically also override objects using that armature (deformed by, or
children of), trying to replicate make_proxy results.

Also some initial code to replicate 'make_proxy' in case of instantiated
linked groups, but that is not working yet (and will also require some
work in RNA part of group's objects collection anyway).

===================================================================

M       source/blender/editors/object/object_relations.c

===================================================================

diff --git a/source/blender/editors/object/object_relations.c 
b/source/blender/editors/object/object_relations.c
index 93769b733de..a2d5f40cbd3 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -2335,17 +2335,160 @@ void OBJECT_OT_make_local(wmOperatorType *ot)
        ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
 }
 
-static int make_override_exec(bContext *C, wmOperator *UNUSED(op))
+
+static void make_override_tag_object(Object *obact, Object *ob)
+{
+       if (ob == obact) {
+               return;
+       }
+
+       if (!ID_IS_LINKED(ob)) {
+               return;
+       }
+
+       /* Note: all this is very case-by-case bad handling, ultimately we'll 
want a real full 'automatic', generic
+        * handling of all this, will probably require adding some 
override-aware stuff to library_query code... */
+
+       if (obact->type == OB_ARMATURE && ob->modifiers.first != NULL) {
+               for (ModifierData *md = ob->modifiers.first; md != NULL; md = 
md->next) {
+                       if (md->type == eModifierType_Armature) {
+                               ArmatureModifierData *amd = 
(ArmatureModifierData *)md;
+                               if (amd->object == obact) {
+                                       ob->id.tag |= LIB_TAG_DOIT;
+                                       break;
+                               }
+                       }
+               }
+       }
+       else if (ob->parent == obact) {
+               ob->id.tag |= LIB_TAG_DOIT;
+       }
+
+       if (ob->id.tag & LIB_TAG_DOIT) {
+               printf("Indirectly overriding %s for %s\n", ob->id.name, 
obact->id.name);
+       }
+}
+
+/* Set the object to override. */
+static int make_override_invoke(bContext *C, wmOperator *op, const wmEvent 
*event)
+{
+       Scene *scene = CTX_data_scene(C);
+       Object *obact = ED_object_active_context(C);
+
+       /* Sanity checks. */
+       if (!scene || ID_IS_LINKED(scene) || !obact) {
+               return OPERATOR_CANCELLED;
+       }
+
+       /* Get object to work on - use a menu if we need to... */
+       if (!ID_IS_LINKED(obact) && obact->dup_group != NULL && 
ID_IS_LINKED(obact->dup_group)) {
+               /* Gives menu with list of objects in group. */
+               WM_enum_search_invoke(C, op, event);
+               return OPERATOR_CANCELLED;
+       }
+       else if (ID_IS_LINKED(obact)) {
+               uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("OK?"), 
ICON_QUESTION);
+               uiLayout *layout = UI_popup_menu_layout(pup);
+
+               /* Create operator menu item with relevant properties filled 
in. */
+               PointerRNA opptr_dummy;
+               uiItemFullO_ptr(layout, op->type, op->type->name, ICON_NONE, 
NULL,
+                               WM_OP_EXEC_REGION_WIN, 0, &opptr_dummy);
+
+               /* Present the menu and be done... */
+               UI_popup_menu_end(C, pup);
+
+               /* This invoke just calls another instance of this operator... 
*/
+               return OPERATOR_INTERFACE;
+       }
+       else {
+               /* Error.. cannot continue. */
+               BKE_report(op->reports, RPT_ERROR, "Can only make static 
override for a referenced object or group");
+               return OPERATOR_CANCELLED;
+       }
+
+}
+
+static int make_override_exec(bContext *C, wmOperator *op)
 {
        Main *bmain = CTX_data_main(C);
-       Object *locobj, *refobj = CTX_data_active_object(C);
+       Object *obact = CTX_data_active_object(C);
+
+       bool success = false;
+
+       if (!ID_IS_LINKED(obact) && obact->dup_group != NULL && 
ID_IS_LINKED(obact->dup_group)) {
+#if 0  /* Not working yet! */
+               Base *base = 
BLI_findlink(&obact->dup_group->view_layer->object_bases, RNA_enum_get(op->ptr, 
"object"));
+               Object *obgroup = obact;
+               obact = base->object;
+
+               /* First, we make a static override of the linked group itself. 
*/
+               obgroup->dup_group->id.tag |= LIB_TAG_DOIT;
+
+               /* Then, we tag our 'main' object and its detected dependencies 
to be also overridden. */
+               obact->id.tag |= LIB_TAG_DOIT;
+
+               FOREACH_GROUP_OBJECT(obgroup->dup_group, ob)
+               {
+                       make_override_tag_object(obact, ob);
+               }
+               FOREACH_GROUP_OBJECT_END;
+
+               success = BKE_override_static_create_from_tag(bmain);
+
+               /* Intantiate our 'main' newly overridden object in scene, if 
not yet done. */
+               Scene *scene = CTX_data_scene(C);
+               ViewLayer *view_layer = CTX_data_view_layer(C);
+               Object *new_obact = (Object *)obact->id.newid;
+               if (new_obact != NULL && (base = 
BKE_view_layer_base_find(view_layer, new_obact)) == NULL) {
+                       BKE_collection_object_add_from(scene, obact, new_obact);
+                       base = BKE_view_layer_base_find(view_layer, new_obact);
+                       BKE_view_layer_base_select(view_layer, base);
+               }
+
+               /* Parent the group instantiating object to the new overridden 
one, or vice-versa, if possible. */
+               if (obgroup->parent == NULL) {
+                       obgroup->parent = new_obact;
+               }
+               else if (new_obact->parent == NULL) {
+                       new_obact->parent = obgroup;
+               }
 
-       locobj = (Object *)BKE_override_static_create_from_id(bmain, 
&refobj->id);
-       UNUSED_VARS(locobj);
+               /* Also, we'd likely want to lock by default things like 
transformations of implicitly overriden objects? */
+
+               /* Cleanup. */
+               BKE_main_id_clear_newpoins(bmain);
+               BKE_main_id_tag_listbase(&bmain->object, LIB_TAG_DOIT, false);
+#else
+               UNUSED_VARS(op);
+#endif
+       }
+       /* Else, poll func ensures us that ID_IS_LINKED(obact) is true. */
+       else if (obact->type == OB_ARMATURE) {
+               BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+
+               obact->id.tag |= LIB_TAG_DOIT;
+
+               for (Object *ob = bmain->object.first; ob != NULL; ob = 
ob->id.next) {
+                       make_override_tag_object(obact, ob);
+               }
+
+               success = BKE_override_static_create_from_tag(bmain);
+
+               /* Also, we'd likely want to lock by default things like 
transformations of implicitly overriden objects? */
+
+               /* Cleanup. */
+               BKE_main_id_clear_newpoins(bmain);
+               BKE_main_id_tag_listbase(&bmain->object, LIB_TAG_DOIT, false);
+       }
+       /* TODO: probably more cases where we want ot do automated smart things 
in the future! */
+       else {
+               success = (BKE_override_static_create_from_id(bmain, 
&obact->id) != NULL);
+       }
 
        WM_event_add_notifier(C, NC_WINDOW, NULL);
 
-       return OPERATOR_FINISHED;
+       return success ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
 }
 
 static int make_override_poll(bContext *C)
@@ -2353,7 +2496,9 @@ static int make_override_poll(bContext *C)
        Object *obact = CTX_data_active_object(C);
 
        /* Object must be directly linked to be overridable. */
-       return (ED_operator_objectmode(C) && obact && obact->id.lib != NULL && 
obact->id.tag & LIB_TAG_EXTERN);
+       return (ED_operator_objectmode(C) && obact != NULL &&
+               ((ID_IS_LINKED(obact) && obact->id.tag & LIB_TAG_EXTERN) ||
+                (!ID_IS_LINKED(obact) && obact->dup_group != NULL && 
ID_IS_LINKED(obact->dup_group))));
 }
 
 void OBJECT_OT_make_override(wmOperatorType *ot)
@@ -2364,6 +2509,7 @@ void OBJECT_OT_make_override(wmOperatorType *ot)
        ot->idname = "OBJECT_OT_make_override";
 
        /* api callbacks */
+       ot->invoke = make_override_invoke;
        ot->exec = make_override_exec;
        ot->poll = make_override_poll;
 
@@ -2371,6 +2517,12 @@ void OBJECT_OT_make_override(wmOperatorType *ot)
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 
        /* properties */
+       PropertyRNA *prop;
+       prop = RNA_def_enum(ot->srna, "object", DummyRNA_DEFAULT_items, 0, 
"Proxy Object",
+                           "Name of lib-linked/grouped object to make a proxy 
for");
+       RNA_def_enum_funcs(prop, proxy_group_object_itemf);
+       RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
+       ot->prop = prop;
 }
 
 enum {

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to