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.
|
* \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.
|
* \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_rotation.h"
|
||||||
#include "BLI_math_vector.hh"
|
#include "BLI_math_vector.hh"
|
||||||
#include "BLI_rand.h"
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_set.hh"
|
||||||
#include "BLI_span.hh"
|
#include "BLI_span.hh"
|
||||||
#include "BLI_string_ref.hh"
|
#include "BLI_string_ref.hh"
|
||||||
#include "BLI_vector.hh"
|
#include "BLI_vector.hh"
|
||||||
@@ -71,6 +72,7 @@ using blender::Array;
|
|||||||
using blender::float2;
|
using blender::float2;
|
||||||
using blender::float3;
|
using blender::float3;
|
||||||
using blender::float4x4;
|
using blender::float4x4;
|
||||||
|
using blender::Set;
|
||||||
using blender::Span;
|
using blender::Span;
|
||||||
using blender::Vector;
|
using blender::Vector;
|
||||||
using blender::bke::GeometrySet;
|
using blender::bke::GeometrySet;
|
||||||
@@ -122,6 +124,11 @@ struct DupliContext {
|
|||||||
*/
|
*/
|
||||||
Vector<short> *dupli_gen_type_stack;
|
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];
|
int persistent_id[MAX_DUPLI_RECUR];
|
||||||
int64_t instance_idx[MAX_DUPLI_RECUR];
|
int64_t instance_idx[MAX_DUPLI_RECUR];
|
||||||
const GeometrySet *instance_data[MAX_DUPLI_RECUR];
|
const GeometrySet *instance_data[MAX_DUPLI_RECUR];
|
||||||
@@ -149,6 +156,7 @@ static void init_context(DupliContext *r_ctx,
|
|||||||
Scene *scene,
|
Scene *scene,
|
||||||
Object *ob,
|
Object *ob,
|
||||||
const float space_mat[4][4],
|
const float space_mat[4][4],
|
||||||
|
blender::Set<const Object *> *include_objects,
|
||||||
Vector<Object *> &instance_stack,
|
Vector<Object *> &instance_stack,
|
||||||
Vector<short> &dupli_gen_type_stack)
|
Vector<short> &dupli_gen_type_stack)
|
||||||
{
|
{
|
||||||
@@ -177,6 +185,8 @@ static void init_context(DupliContext *r_ctx,
|
|||||||
r_ctx->duplilist = nullptr;
|
r_ctx->duplilist = nullptr;
|
||||||
r_ctx->preview_instance_index = -1;
|
r_ctx->preview_instance_index = -1;
|
||||||
r_ctx->preview_base_geometry = nullptr;
|
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);
|
eEvaluationMode mode = DEG_get_mode(ctx->depsgraph);
|
||||||
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (collection, cob, mode) {
|
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (collection, cob, mode) {
|
||||||
if (cob != ob) {
|
if (cob == ob) {
|
||||||
float mat[4][4];
|
continue;
|
||||||
|
|
||||||
/* 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 (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;
|
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
|
||||||
}
|
}
|
||||||
@@ -1784,14 +1802,18 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
|
|||||||
/** \name Dupli-Container Implementation
|
/** \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");
|
ListBase *duplilist = MEM_callocN<ListBase>("duplilist");
|
||||||
DupliContext ctx;
|
DupliContext ctx;
|
||||||
Vector<Object *> instance_stack;
|
Vector<Object *> instance_stack;
|
||||||
Vector<short> dupli_gen_type_stack({0});
|
Vector<short> dupli_gen_type_stack({0});
|
||||||
instance_stack.append(ob);
|
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) {
|
if (ctx.gen) {
|
||||||
ctx.duplilist = duplilist;
|
ctx.duplilist = duplilist;
|
||||||
ctx.gen->make_duplis(&ctx);
|
ctx.gen->make_duplis(&ctx);
|
||||||
@@ -1810,7 +1832,8 @@ ListBase *object_duplilist_preview(Depsgraph *depsgraph,
|
|||||||
Vector<Object *> instance_stack;
|
Vector<Object *> instance_stack;
|
||||||
Vector<short> dupli_gen_type_stack({0});
|
Vector<short> dupli_gen_type_stack({0});
|
||||||
instance_stack.append(ob_eval);
|
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;
|
ctx.duplilist = duplilist;
|
||||||
|
|
||||||
Object *ob_orig = DEG_get_original(ob_eval);
|
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<Object *> instance_stack({&ob});
|
||||||
Vector<short> dupli_gen_type_stack({0});
|
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) {
|
if (ctx.gen == &gen_dupli_geometry_set) {
|
||||||
/* These are not legacy instances. */
|
/* These are not legacy instances. */
|
||||||
return {};
|
return {};
|
||||||
|
|||||||
@@ -286,7 +286,8 @@ bool deg_iterator_objects_step(DEGObjectIterData *data)
|
|||||||
((object->transflag & OB_DUPLI) || object->runtime->geometry_set_eval != nullptr))
|
((object->transflag & OB_DUPLI) || object->runtime->geometry_set_eval != nullptr))
|
||||||
{
|
{
|
||||||
BLI_assert(deg::deg_validate_eval_copy_datablock(&object->id));
|
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);
|
deg_iterator_duplis_init(data, object, duplis);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user