Merge branch 'blender-v2.93-release'

This commit is contained in:
Jacques Lucke 2021-04-27 12:35:48 +02:00
commit e240d94191
1 changed files with 23 additions and 2 deletions

View File

@ -36,6 +36,7 @@
#include "BLI_math.h"
#include "BLI_rand.h"
#include "BLI_span.hh"
#include "BLI_vector.hh"
#include "DNA_anim_types.h"
#include "DNA_collection_types.h"
@ -73,6 +74,7 @@ using blender::Array;
using blender::float3;
using blender::float4x4;
using blender::Span;
using blender::Vector;
/* -------------------------------------------------------------------- */
/** \name Internal Duplicate Context
@ -90,6 +92,13 @@ struct DupliContext {
Object *object;
float space_mat[4][4];
/**
* A stack that contains all the "parent" objects of a particular instance when recursive
* instancing is used. This is used to prevent objects from instancing themselves accidentally.
* Use a vector instead of a stack because we want to use the #contains method.
*/
Vector<Object *> *instance_stack;
int persistent_id[MAX_DUPLI_RECUR];
int level;
@ -113,7 +122,8 @@ static void init_context(DupliContext *r_ctx,
Depsgraph *depsgraph,
Scene *scene,
Object *ob,
const float space_mat[4][4])
const float space_mat[4][4],
Vector<Object *> &instance_stack)
{
r_ctx->depsgraph = depsgraph;
r_ctx->scene = scene;
@ -122,6 +132,7 @@ static void init_context(DupliContext *r_ctx,
r_ctx->object = ob;
r_ctx->obedit = OBEDIT_FROM_OBACT(ob);
r_ctx->instance_stack = &instance_stack;
if (space_mat) {
copy_m4_m4(r_ctx->space_mat, space_mat);
}
@ -150,6 +161,7 @@ static void copy_dupli_context(
}
r_ctx->object = ob;
r_ctx->instance_stack = ctx->instance_stack;
if (mat) {
mul_m4_m4m4(r_ctx->space_mat, (float(*)[4])ctx->space_mat, mat);
}
@ -235,12 +247,19 @@ static void make_recursive_duplis(const DupliContext *ctx,
const float space_mat[4][4],
int index)
{
if (ctx->instance_stack->contains(ob)) {
/* Avoid recursive instances. */
printf("Warning: '%s' object is trying to instance itself.\n", ob->id.name + 2);
return;
}
/* Simple preventing of too deep nested collections with #MAX_DUPLI_RECUR. */
if (ctx->level < MAX_DUPLI_RECUR) {
DupliContext rctx;
copy_dupli_context(&rctx, ctx, ob, space_mat, index);
if (rctx.gen) {
ctx->instance_stack->append(ob);
rctx.gen->make_duplis(&rctx);
ctx->instance_stack->remove_last();
}
}
}
@ -1588,7 +1607,9 @@ ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob)
{
ListBase *duplilist = (ListBase *)MEM_callocN(sizeof(ListBase), "duplilist");
DupliContext ctx;
init_context(&ctx, depsgraph, sce, ob, nullptr);
Vector<Object *> instance_stack;
instance_stack.append(ob);
init_context(&ctx, depsgraph, sce, ob, nullptr, instance_stack);
if (ctx.gen) {
ctx.duplilist = duplilist;
ctx.gen->make_duplis(&ctx);