Fix #136397: Line Art: Skip dupli objects with include_objects
Previously to handle unevaluated objects in line art "load all" iteration, a `include_objects` variable is added in depsgraph iteration settings, and this was only processed by object iterator but not for any of the dupli objects. Now `make_duplis_collection` will also handle `include_objects` The only case where this border case can lead to crash is that a line art grease pencil object is inside one of the dupli collection, which isn't a valid use in the first place. But this fix makes it more robust. Pull Request: https://projects.blender.org/blender/blender/pulls/137323
This commit is contained in:
@@ -26,7 +26,10 @@ struct ViewerPath;
|
||||
/**
|
||||
* \return a #ListBase of #DupliObject.
|
||||
*/
|
||||
ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob);
|
||||
ListBase *object_duplilist(Depsgraph *depsgraph,
|
||||
Scene *sce,
|
||||
Object *ob,
|
||||
blender::Set<const Object *> *include_objects = nullptr);
|
||||
/**
|
||||
* \return a #ListBase of #DupliObject for the preview geometry referenced by the #ViewerPath.
|
||||
*/
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "BLI_math_rotation.h"
|
||||
#include "BLI_math_vector.hh"
|
||||
#include "BLI_rand.h"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_vector.hh"
|
||||
@@ -71,6 +72,7 @@ using blender::Array;
|
||||
using blender::float2;
|
||||
using blender::float3;
|
||||
using blender::float4x4;
|
||||
using blender::Set;
|
||||
using blender::Span;
|
||||
using blender::Vector;
|
||||
using blender::bke::GeometrySet;
|
||||
@@ -122,6 +124,11 @@ struct DupliContext {
|
||||
*/
|
||||
Vector<short> *dupli_gen_type_stack;
|
||||
|
||||
/**
|
||||
* If not null, then only instance objects that are in this set.
|
||||
*/
|
||||
Set<const Object *> *include_objects;
|
||||
|
||||
int persistent_id[MAX_DUPLI_RECUR];
|
||||
int64_t instance_idx[MAX_DUPLI_RECUR];
|
||||
const GeometrySet *instance_data[MAX_DUPLI_RECUR];
|
||||
@@ -149,6 +156,7 @@ static void init_context(DupliContext *r_ctx,
|
||||
Scene *scene,
|
||||
Object *ob,
|
||||
const float space_mat[4][4],
|
||||
blender::Set<const Object *> *include_objects,
|
||||
Vector<Object *> &instance_stack,
|
||||
Vector<short> &dupli_gen_type_stack)
|
||||
{
|
||||
@@ -177,6 +185,8 @@ static void init_context(DupliContext *r_ctx,
|
||||
r_ctx->duplilist = nullptr;
|
||||
r_ctx->preview_instance_index = -1;
|
||||
r_ctx->preview_base_geometry = nullptr;
|
||||
|
||||
r_ctx->include_objects = include_objects;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -535,17 +545,25 @@ static void make_duplis_collection(const DupliContext *ctx)
|
||||
|
||||
eEvaluationMode mode = DEG_get_mode(ctx->depsgraph);
|
||||
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (collection, cob, mode) {
|
||||
if (cob != ob) {
|
||||
float mat[4][4];
|
||||
|
||||
/* Collection dupli-offset, should apply after everything else. */
|
||||
mul_m4_m4m4(mat, collection_mat, cob->object_to_world().ptr());
|
||||
|
||||
make_dupli(ctx, cob, mat, _base_id);
|
||||
|
||||
/* Recursion. */
|
||||
make_recursive_duplis(ctx, cob, collection_mat, _base_id);
|
||||
if (cob == ob) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ctx->include_objects) {
|
||||
if (!ctx->include_objects->contains(cob)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
float mat[4][4];
|
||||
|
||||
/* Collection dupli-offset, should apply after everything else. */
|
||||
mul_m4_m4m4(mat, collection_mat, cob->object_to_world().ptr());
|
||||
|
||||
make_dupli(ctx, cob, mat, _base_id);
|
||||
|
||||
/* Recursion. */
|
||||
make_recursive_duplis(ctx, cob, collection_mat, _base_id);
|
||||
}
|
||||
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
|
||||
}
|
||||
@@ -1784,14 +1802,18 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
|
||||
/** \name Dupli-Container Implementation
|
||||
* \{ */
|
||||
|
||||
ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob)
|
||||
ListBase *object_duplilist(Depsgraph *depsgraph,
|
||||
Scene *sce,
|
||||
Object *ob,
|
||||
Set<const Object *> *include_objects)
|
||||
{
|
||||
ListBase *duplilist = MEM_callocN<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, dupli_gen_type_stack);
|
||||
init_context(
|
||||
&ctx, depsgraph, sce, ob, nullptr, include_objects, instance_stack, dupli_gen_type_stack);
|
||||
if (ctx.gen) {
|
||||
ctx.duplilist = duplilist;
|
||||
ctx.gen->make_duplis(&ctx);
|
||||
@@ -1810,7 +1832,8 @@ ListBase *object_duplilist_preview(Depsgraph *depsgraph,
|
||||
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, dupli_gen_type_stack);
|
||||
init_context(
|
||||
&ctx, depsgraph, sce, ob_eval, nullptr, nullptr, instance_stack, dupli_gen_type_stack);
|
||||
ctx.duplilist = duplilist;
|
||||
|
||||
Object *ob_orig = DEG_get_original(ob_eval);
|
||||
@@ -1848,7 +1871,8 @@ blender::bke::Instances object_duplilist_legacy_instances(Depsgraph &depsgraph,
|
||||
Vector<Object *> instance_stack({&ob});
|
||||
Vector<short> dupli_gen_type_stack({0});
|
||||
|
||||
init_context(&ctx, &depsgraph, &scene, &ob, nullptr, instance_stack, dupli_gen_type_stack);
|
||||
init_context(
|
||||
&ctx, &depsgraph, &scene, &ob, nullptr, nullptr, instance_stack, dupli_gen_type_stack);
|
||||
if (ctx.gen == &gen_dupli_geometry_set) {
|
||||
/* These are not legacy instances. */
|
||||
return {};
|
||||
|
||||
@@ -286,7 +286,8 @@ bool deg_iterator_objects_step(DEGObjectIterData *data)
|
||||
((object->transflag & OB_DUPLI) || object->runtime->geometry_set_eval != nullptr))
|
||||
{
|
||||
BLI_assert(deg::deg_validate_eval_copy_datablock(&object->id));
|
||||
ListBase *duplis = object_duplilist(data->graph, data->scene, object);
|
||||
ListBase *duplis = object_duplilist(
|
||||
data->graph, data->scene, object, data->settings->included_objects);
|
||||
deg_iterator_duplis_init(data, object, duplis);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user