Fix main part of T68646: Library overrides: Broken parenting (parent inverse matrix...
authorBastien Montagne <montagne29@wanadoo.fr>
Wed, 14 Aug 2019 15:25:40 +0000 (17:25 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Wed, 14 Aug 2019 15:27:34 +0000 (17:27 +0200)
We need a custom 'apply override' callback here to prevent resetting
the inverse parent matrix.

Things are now working for basic cases, but complex ones (in production
rigs e.g.) are still partially broken...

source/blender/makesrna/intern/rna_object.c

index 6069e78d874a905e3e462d5609bf39309838fd8d..d546c8d71479d23df831dfbedea75f8feb2478d2 100644 (file)
@@ -546,6 +546,46 @@ static void rna_Object_parent_set(PointerRNA *ptr,
   }
 }
 
+bool rna_Object_parent_override_apply(Main *UNUSED(bmain),
+                                      PointerRNA *ptr_dst,
+                                      PointerRNA *ptr_src,
+                                      PointerRNA *ptr_storage,
+                                      PropertyRNA *prop_dst,
+                                      PropertyRNA *prop_src,
+                                      PropertyRNA *UNUSED(prop_storage),
+                                      const int len_dst,
+                                      const int len_src,
+                                      const int len_storage,
+                                      PointerRNA *UNUSED(ptr_item_dst),
+                                      PointerRNA *UNUSED(ptr_item_src),
+                                      PointerRNA *UNUSED(ptr_item_storage),
+                                      IDOverrideLibraryPropertyOperation *opop)
+{
+  BLI_assert(len_dst == len_src && (!ptr_storage || len_dst == len_storage) && len_dst == 0);
+  BLI_assert(opop->operation == IDOVERRIDE_LIBRARY_OP_REPLACE &&
+             "Unsupported RNA override operation on animdata pointer");
+  UNUSED_VARS_NDEBUG(ptr_storage, len_dst, len_src, len_storage, opop);
+
+  /* We need a special handling here because setting parent resets pinvert parent matrix,
+   * which is evil in our case. */
+  Object *ob = (Object *)ptr_dst->data;
+  Object *parent_dst = RNA_property_pointer_get(ptr_dst, prop_dst).data;
+  Object *parent_src = RNA_property_pointer_get(ptr_src, prop_src).data;
+
+  if (parent_src == parent_dst) {
+    return false;
+  }
+
+  if (parent_src == NULL) {
+    /* The only case where we do want default behavior (with matrix reset). */
+    ED_object_parent(ob, parent_src, ob->partype, ob->parsubstr);
+  }
+  else {
+    ob->parent = parent_src;
+  }
+  return true;
+}
+
 static void rna_Object_parent_type_set(PointerRNA *ptr, int value)
 {
   Object *ob = (Object *)ptr->data;
@@ -2389,6 +2429,7 @@ static void rna_def_object(BlenderRNA *brna)
   RNA_def_property_pointer_funcs(prop, NULL, "rna_Object_parent_set", NULL, NULL);
   RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
   RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
+  RNA_def_property_override_funcs(prop, NULL, NULL, "rna_Object_parent_override_apply");
   RNA_def_property_ui_text(prop, "Parent", "Parent Object");
   RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_dependency_update");