Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-11-11 18:09:28 +0300
committerHans Goudey <h.goudey@me.com>2022-11-11 18:09:28 +0300
commitdc8a1d38b73420428f9fb878386b99ebb69dd841 (patch)
tree0c2b203973ff5b52bbc72417d56c394350545e99
parenta304dfdb6917d80d5a5de6361c65f633114b2238 (diff)
parentff7645c5edd211c5317b5fd9e6d0320c20667a21 (diff)
Merge branch 'blender-v3.4-release'
-rw-r--r--source/blender/blenkernel/intern/customdata.cc23
-rw-r--r--source/blender/blenkernel/intern/object_dupli.cc43
2 files changed, 42 insertions, 24 deletions
diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index 84aa2207400..bccb625feb2 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -2799,6 +2799,14 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
int flag = 0;
+ /* Some layer types only support a single layer. */
+ if (!typeInfo->defaultname && CustomData_has_layer(data, type)) {
+ /* This function doesn't support dealing with existing layer data for these layer types when
+ * the layer already exists. */
+ BLI_assert(layerdata == nullptr);
+ return &data->layers[CustomData_get_layer_index(data, type)];
+ }
+
void *newlayerdata = nullptr;
switch (alloctype) {
case CD_SET_DEFAULT:
@@ -2851,21 +2859,6 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
break;
}
- /* Some layer types only support a single layer. */
- const bool reuse_existing_layer = !typeInfo->defaultname && CustomData_has_layer(data, type);
- if (reuse_existing_layer) {
- CustomDataLayer &layer = data->layers[CustomData_get_layer_index(data, type)];
- if (layer.data != nullptr) {
- if (typeInfo->free) {
- typeInfo->free(layer.data, totelem, typeInfo->size);
- }
- MEM_SAFE_FREE(layer.data);
- }
- layer.data = newlayerdata;
- layer.flag = flag;
- return &layer;
- }
-
int index = data->totlayer;
if (index >= data->maxlayer) {
if (!customData_resize(data, CUSTOMDATA_GROW)) {
diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc
index 5efd44c620b..54a26a897d8 100644
--- a/source/blender/blenkernel/intern/object_dupli.cc
+++ b/source/blender/blenkernel/intern/object_dupli.cc
@@ -79,6 +79,8 @@ namespace geo_log = blender::nodes::geo_eval_log;
/** \name Internal Duplicate Context
* \{ */
+static constexpr short GEOMETRY_SET_DUPLI_GENERATOR_TYPE = 1;
+
struct DupliContext {
Depsgraph *depsgraph;
/** XXX child objects are selected from this group if set, could be nicer. */
@@ -87,6 +89,9 @@ struct DupliContext {
Object *obedit;
Scene *scene;
+ /** Root parent object at the scene level. */
+ Object *root_object;
+ /** Immediate parent object in the context. */
Object *object;
float space_mat[4][4];
/**
@@ -106,6 +111,14 @@ struct DupliContext {
*/
Vector<Object *> *instance_stack;
+ /**
+ * Older code relies on the "dupli generator type" for various visibility or processing
+ * decisions. However, new code uses geometry instances in places that weren't using the dupli
+ * system previously. To fix this, keep track of the last dupli generator type that wasn't a
+ * geometry set instance.
+ * */
+ Vector<short> *dupli_gen_type_stack;
+
int persistent_id[MAX_DUPLI_RECUR];
int64_t instance_idx[MAX_DUPLI_RECUR];
const GeometrySet *instance_data[MAX_DUPLI_RECUR];
@@ -132,15 +145,18 @@ static void init_context(DupliContext *r_ctx,
Scene *scene,
Object *ob,
const float space_mat[4][4],
- Vector<Object *> &instance_stack)
+ Vector<Object *> &instance_stack,
+ Vector<short> &dupli_gen_type_stack)
{
r_ctx->depsgraph = depsgraph;
r_ctx->scene = scene;
r_ctx->collection = nullptr;
+ r_ctx->root_object = ob;
r_ctx->object = ob;
r_ctx->obedit = OBEDIT_FROM_OBACT(ob);
r_ctx->instance_stack = &instance_stack;
+ r_ctx->dupli_gen_type_stack = &dupli_gen_type_stack;
if (space_mat) {
copy_m4_m4(r_ctx->space_mat, space_mat);
}
@@ -150,6 +166,9 @@ static void init_context(DupliContext *r_ctx,
r_ctx->level = 0;
r_ctx->gen = get_dupli_generator(r_ctx);
+ if (r_ctx->gen && r_ctx->gen->type != GEOMETRY_SET_DUPLI_GENERATOR_TYPE) {
+ r_ctx->dupli_gen_type_stack->append(r_ctx->gen->type);
+ }
r_ctx->duplilist = nullptr;
r_ctx->preview_instance_index = -1;
@@ -191,6 +210,9 @@ static bool copy_dupli_context(DupliContext *r_ctx,
}
r_ctx->gen = get_dupli_generator(r_ctx);
+ if (r_ctx->gen && r_ctx->gen->type != GEOMETRY_SET_DUPLI_GENERATOR_TYPE) {
+ r_ctx->dupli_gen_type_stack->append(r_ctx->gen->type);
+ }
return true;
}
@@ -223,7 +245,7 @@ static DupliObject *make_dupli(const DupliContext *ctx,
dob->ob = ob;
dob->ob_data = const_cast<ID *>(object_data);
mul_m4_m4m4(dob->mat, (float(*)[4])ctx->space_mat, mat);
- dob->type = ctx->gen == nullptr ? 0 : ctx->gen->type;
+ dob->type = ctx->gen == nullptr ? 0 : ctx->dupli_gen_type_stack->last();
dob->preview_base_geometry = ctx->preview_base_geometry;
dob->preview_instance_index = ctx->preview_instance_index;
@@ -264,8 +286,9 @@ static DupliObject *make_dupli(const DupliContext *ctx,
dob->no_draw = true;
}
- /* Random number.
- * The logic here is designed to match Cycles. */
+ /* Random number per instance.
+ * The root object in the scene, persistent ID up to the instance object, and the instance object
+ * name together result in a unique random number. */
dob->random_id = BLI_hash_string(dob->ob->id.name + 2);
if (dob->persistent_id[0] != INT_MAX) {
@@ -277,8 +300,8 @@ static DupliObject *make_dupli(const DupliContext *ctx,
dob->random_id = BLI_hash_int_2d(dob->random_id, 0);
}
- if (ctx->object != ob) {
- dob->random_id ^= BLI_hash_int(BLI_hash_string(ctx->object->id.name + 2));
+ if (ctx->root_object != ob) {
+ dob->random_id ^= BLI_hash_int(BLI_hash_string(ctx->root_object->id.name + 2));
}
return dob;
@@ -991,7 +1014,7 @@ static void make_duplis_geometry_set(const DupliContext *ctx)
}
static const DupliGenerator gen_dupli_geometry_set = {
- 0,
+ GEOMETRY_SET_DUPLI_GENERATOR_TYPE,
make_duplis_geometry_set,
};
@@ -1712,8 +1735,9 @@ ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob)
ListBase *duplilist = MEM_cnew<ListBase>("duplilist");
DupliContext ctx;
Vector<Object *> instance_stack;
+ Vector<short> dupli_gen_type_stack({0});
instance_stack.append(ob);
- init_context(&ctx, depsgraph, sce, ob, nullptr, instance_stack);
+ init_context(&ctx, depsgraph, sce, ob, nullptr, instance_stack, dupli_gen_type_stack);
if (ctx.gen) {
ctx.duplilist = duplilist;
ctx.gen->make_duplis(&ctx);
@@ -1730,8 +1754,9 @@ ListBase *object_duplilist_preview(Depsgraph *depsgraph,
ListBase *duplilist = MEM_cnew<ListBase>("duplilist");
DupliContext ctx;
Vector<Object *> instance_stack;
+ Vector<short> dupli_gen_type_stack({0});
instance_stack.append(ob_eval);
- init_context(&ctx, depsgraph, sce, ob_eval, nullptr, instance_stack);
+ init_context(&ctx, depsgraph, sce, ob_eval, nullptr, instance_stack, dupli_gen_type_stack);
ctx.duplilist = duplilist;
Object *ob_orig = DEG_get_original_object(ob_eval);