Commit: 99c5c8befcfc319a4700384ff41e69bda1c66625
Author: Luca Rood
Date:   Tue Nov 22 14:38:43 2016 -0200
Branches: master
https://developer.blender.org/rB99c5c8befcfc319a4700384ff41e69bda1c66625

Fix T49718: Wrong "Make Duplicates Real" behavior with "Keep Hierarchy"

All objects were being parented to a single instance of each parent
object, instead of their respective instances, when using dupliverts or
dupligroups.

Behavior was caused by the `persistent_id[0]` (vertex/face id) being
ignored when computing `parent_gh` hash, which caused all instances to
have the same hash, and thus only the first one was included.

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D2370

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

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

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

diff --git a/source/blender/editors/object/object_add.c 
b/source/blender/editors/object/object_add.c
index 8e64cdc..6647102 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1253,10 +1253,10 @@ static void copy_object_set_idnew(bContext *C)
 /********************* Make Duplicates Real ************************/
 
 /**
- * \note regarding hashing dupli-objects, skip the first member of 
#DupliObject.persistent_id
+ * \note regarding hashing dupli-objects when using OB_DUPLIGROUP, skip the 
first member of #DupliObject.persistent_id
  * since its a unique index and we only want to know if the group objects are 
from the same dupli-group instance.
  */
-static unsigned int dupliobject_hash(const void *ptr)
+static unsigned int dupliobject_group_hash(const void *ptr)
 {
        const DupliObject *dob = ptr;
        unsigned int hash = BLI_ghashutil_ptrhash(dob->ob);
@@ -1267,7 +1267,20 @@ static unsigned int dupliobject_hash(const void *ptr)
        return hash;
 }
 
-static bool dupliobject_cmp(const void *a_, const void *b_)
+/**
+ * \note regarding hashing dupli-objects when NOT using OB_DUPLIGROUP, include 
the first member of #DupliObject.persistent_id
+ * since its the index of the vertex/face the object is instantiated on and we 
want to identify objects on the same vertex/face.
+ */
+static unsigned int dupliobject_hash(const void *ptr)
+{
+       const DupliObject *dob = ptr;
+       unsigned int hash = BLI_ghashutil_ptrhash(dob->ob);
+       hash ^= (dob->persistent_id[0] ^ 0);
+       return hash;
+}
+
+/* Compare function that matches dupliobject_group_hash */
+static bool dupliobject_group_cmp(const void *a_, const void *b_)
 {
        const DupliObject *a = a_;
        const DupliObject *b = b_;
@@ -1290,6 +1303,24 @@ static bool dupliobject_cmp(const void *a_, const void 
*b_)
        return false;
 }
 
+/* Compare function that matches dupliobject_hash */
+static bool dupliobject_cmp(const void *a_, const void *b_)
+{
+       const DupliObject *a = a_;
+       const DupliObject *b = b_;
+
+       if (a->ob != b->ob) {
+               return true;
+       }
+
+       if (a->persistent_id[0] != b->persistent_id[0]) {
+               return true;
+       }
+
+       /* matching */
+       return false;
+}
+
 static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
                                        const bool use_base_parent,
                                        const bool use_hierarchy)
@@ -1308,7 +1339,12 @@ static void make_object_duplilist_real(bContext *C, 
Scene *scene, Base *base,
        if (use_hierarchy || use_base_parent) {
                dupli_gh = BLI_ghash_ptr_new(__func__);
                if (use_hierarchy) {
-                       parent_gh = BLI_ghash_new(dupliobject_hash, 
dupliobject_cmp, __func__);
+                       if (base->object->transflag & OB_DUPLIGROUP) {
+                               parent_gh = 
BLI_ghash_new(dupliobject_group_hash, dupliobject_group_cmp, __func__);
+                       }
+                       else {
+                               parent_gh = BLI_ghash_new(dupliobject_hash, 
dupliobject_cmp, __func__);
+                       }
                }
        }
 
@@ -1376,9 +1412,14 @@ static void make_object_duplilist_real(bContext *C, 
Scene *scene, Base *base,
                                 * they won't be read, this is simply for a 
hash lookup. */
                                DupliObject dob_key;
                                dob_key.ob = ob_src_par;
-                               memcpy(&dob_key.persistent_id[1],
-                                      &dob->persistent_id[1],
-                                      sizeof(dob->persistent_id[1]) * 
(MAX_DUPLI_RECUR - 1));
+                               if (base->object->transflag & OB_DUPLIGROUP) {
+                                       memcpy(&dob_key.persistent_id[1],
+                                                  &dob->persistent_id[1],
+                                                  
sizeof(dob->persistent_id[1]) * (MAX_DUPLI_RECUR - 1));
+                               }
+                               else {
+                                       dob_key.persistent_id[0] = 
dob->persistent_id[0];
+                               }
                                ob_dst_par = BLI_ghash_lookup(parent_gh, 
&dob_key);
                        }

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

Reply via email to