Fix T42838: Make dupli's real use_hierarchy fails

Regression since the dupli-object refactor.
This commit is contained in:
Campbell Barton 2014-12-08 16:13:27 +01:00
parent 7b6c9d23cf
commit 252bfc6f65
Notes: blender-bot 2023-02-14 09:44:53 +01:00
Referenced by issue #42838, bpy.ops.object.duplicates_make_real: use_hierarchy parameter doesn't work as expected
1 changed files with 50 additions and 7 deletions

View File

@ -1286,6 +1286,44 @@ static void copy_object_set_idnew(bContext *C, int dupflag)
/********************* Make Duplicates Real ************************/
/**
* \note regarding hashing dupli-objects, skip the first member of #DupliObject.persistent_id
* since its a unique index and we only wan't to know if the group objects are from the same dupli-group instance.
*/
static unsigned int dupliobject_hash(const void *ptr)
{
const DupliObject *dob = ptr;
unsigned int hash = BLI_ghashutil_ptrhash(dob->ob);
unsigned int i;
for (i = 1; (i < MAX_DUPLI_RECUR) && dob->persistent_id[i] != INT_MAX; i++) {
hash ^= (dob->persistent_id[i] ^ i);
}
return hash;
}
static bool dupliobject_cmp(const void *a_, const void *b_)
{
const DupliObject *a = a_;
const DupliObject *b = b_;
unsigned int i;
if (a->ob != b->ob) {
return true;
}
for (i = 1; (i < MAX_DUPLI_RECUR); i++) {
if (a->persistent_id[i] != b->persistent_id[i]) {
return true;
}
else if (a->persistent_id[i] == INT_MAX) {
break;
}
}
/* matching */
return false;
}
static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
const bool use_base_parent,
const bool use_hierarchy)
@ -1302,8 +1340,8 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
lb = object_duplilist(bmain->eval_ctx, scene, base->object);
if (use_hierarchy || use_base_parent) {
dupli_gh = BLI_ghash_ptr_new("make_object_duplilist_real dupli_gh");
parent_gh = BLI_ghash_pair_new("make_object_duplilist_real parent_gh");
dupli_gh = BLI_ghash_ptr_new(__func__);
parent_gh = BLI_ghash_new(dupliobject_hash, dupliobject_cmp, __func__);
}
for (dob = lb->first; dob; dob = dob->next) {
@ -1343,7 +1381,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
if (dupli_gh)
BLI_ghash_insert(dupli_gh, dob, ob);
if (parent_gh)
BLI_ghash_insert(parent_gh, BLI_ghashutil_pairalloc(dob->ob, SET_INT_IN_POINTER(dob->persistent_id[0])), ob);
BLI_ghash_insert(parent_gh, dob, ob);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
@ -1359,9 +1397,14 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
/* find parent that was also made real */
if (ob_src_par) {
GHashPair *pair = BLI_ghashutil_pairalloc(ob_src_par, SET_INT_IN_POINTER(dob->persistent_id[0]));
ob_dst_par = BLI_ghash_lookup(parent_gh, pair);
BLI_ghashutil_pairfree(pair);
/* OK to keep most of the members uninitialized,
* 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));
ob_dst_par = BLI_ghash_lookup(parent_gh, &dob_key);
}
if (ob_dst_par) {
@ -1424,7 +1467,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
if (dupli_gh)
BLI_ghash_free(dupli_gh, NULL, NULL);
if (parent_gh)
BLI_ghash_free(parent_gh, BLI_ghashutil_pairfree, NULL);
BLI_ghash_free(parent_gh, NULL, NULL);
copy_object_set_idnew(C, 0);