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
path: root/source
diff options
context:
space:
mode:
authorYimingWu <xp8110@outlook.com>2022-05-13 19:03:40 +0300
committerYimingWu <xp8110@outlook.com>2022-05-13 19:04:16 +0300
commit870ad7d05db2e14164d818cd5320345fd8110a69 (patch)
treea5fb156e616ff6df071230974d9cad65d74fcb83 /source
parent5baa3ecda66337c0584f0bc6c6e7af0a6c0f6320 (diff)
Fix T96781: LineArt proper object iterator.
This patch get rid of the _incorrectly used_ DG iterator in object loading, and uses scene objects iteration to prevent problems. Reviewed By: Sebastian Parborg (zeddb) Differential Revision: https://developer.blender.org/D14907
Diffstat (limited to 'source')
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c25
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c144
2 files changed, 93 insertions, 76 deletions
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
index 0e7df2a136d..a07ef2eb195 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
@@ -218,9 +218,18 @@ static void add_this_collection(Collection *c,
if (!c) {
return;
}
+ bool default_add = true;
+ /* Do not do nested collection usage check, this is consistent with lineart calculation, because
+ * collection usage doesn't have a INHERIT mode. This might initially be derived from the fact
+ * that an object can be inside multiple collections, but might be irrelevant now with the way
+ * objects are iterated. Keep this logic for now. */
+ if (c->lineart_usage & COLLECTION_LRT_EXCLUDE) {
+ default_add = false;
+ }
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (c, ob, mode) {
if (ELEM(ob->type, OB_MESH, OB_MBALL, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
- if (ob->lineart.usage != OBJECT_LRT_EXCLUDE) {
+ if ((ob->lineart.usage == OBJECT_LRT_INHERIT && default_add) ||
+ ob->lineart.usage != OBJECT_LRT_EXCLUDE) {
DEG_add_object_relation(ctx->node, ob, DEG_OB_COMP_GEOMETRY, "Line Art Modifier");
DEG_add_object_relation(ctx->node, ob, DEG_OB_COMP_TRANSFORM, "Line Art Modifier");
}
@@ -239,15 +248,11 @@ static void updateDepsgraph(GpencilModifierData *md,
DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Line Art Modifier");
LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md;
- if (lmd->source_type == LRT_SOURCE_OBJECT && lmd->source_object) {
- DEG_add_object_relation(
- ctx->node, lmd->source_object, DEG_OB_COMP_GEOMETRY, "Line Art Modifier");
- DEG_add_object_relation(
- ctx->node, lmd->source_object, DEG_OB_COMP_TRANSFORM, "Line Art Modifier");
- }
- else {
- add_this_collection(ctx->scene->master_collection, ctx, mode);
- }
+
+ /* Always add whole master collection because line art will need the whole scene for
+ * visibility computation. Line art exclusion is handled inside #add_this_collection. */
+ add_this_collection(ctx->scene->master_collection, ctx, mode);
+
if (lmd->calculation_flags & LRT_USE_CUSTOM_CAMERA && lmd->source_camera) {
DEG_add_object_relation(
ctx->node, lmd->source_camera, DEG_OB_COMP_TRANSFORM, "Line Art Modifier");
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index b09bb15ce81..11d368b819c 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -21,6 +21,7 @@
#include "BKE_collection.h"
#include "BKE_customdata.h"
#include "BKE_deform.h"
+#include "BKE_duplilist.h"
#include "BKE_editmesh.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
@@ -2398,6 +2399,64 @@ static bool lineart_geometry_check_visible(double (*model_view_proj)[4],
return true;
}
+static void lineart_object_load_single_instance(LineartRenderBuffer *rb,
+ Depsgraph *depsgraph,
+ Scene *scene,
+ Object *ob,
+ Object *ref_ob,
+ float use_mat[4][4],
+ bool is_render,
+ LineartObjectLoadTaskInfo *olti,
+ int thread_count)
+{
+ LineartObjectInfo *obi = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartObjectInfo));
+ obi->usage = lineart_usage_check(scene->master_collection, ob, is_render);
+ obi->override_intersection_mask = lineart_intersection_mask_check(scene->master_collection, ob);
+ Mesh *use_mesh;
+
+ if (obi->usage == OBJECT_LRT_EXCLUDE) {
+ return;
+ }
+
+ /* Prepare the matrix used for transforming this specific object (instance). This has to be
+ * done before mesh boundbox check because the function needs that. */
+ mul_m4db_m4db_m4fl_uniq(obi->model_view_proj, rb->view_projection, use_mat);
+ mul_m4db_m4db_m4fl_uniq(obi->model_view, rb->view, use_mat);
+
+ if (!ELEM(ob->type, OB_MESH, OB_MBALL, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
+ return;
+ }
+ if (ob->type == OB_MESH) {
+ use_mesh = BKE_object_get_evaluated_mesh(ob);
+ }
+ else {
+ use_mesh = BKE_mesh_new_from_object(depsgraph, ob, true, true);
+ }
+
+ /* In case we still can not get any mesh geometry data from the object */
+ if (!use_mesh) {
+ return;
+ }
+
+ if (!lineart_geometry_check_visible(obi->model_view_proj, rb->shift_x, rb->shift_y, use_mesh)) {
+ return;
+ }
+
+ if (ob->type != OB_MESH) {
+ obi->free_use_mesh = true;
+ }
+
+ /* Make normal matrix. */
+ float imat[4][4];
+ invert_m4_m4(imat, use_mat);
+ transpose_m4(imat);
+ copy_m4d_m4(obi->normal, imat);
+
+ obi->original_me = use_mesh;
+ obi->original_ob = (ref_ob->id.orig_id ? (Object *)ref_ob->id.orig_id : (Object *)ref_ob);
+ lineart_geometry_load_assign_thread(olti, obi, thread_count, use_mesh->totpoly);
+}
+
static void lineart_main_load_geometries(
Depsgraph *depsgraph,
Scene *scene,
@@ -2446,14 +2505,6 @@ static void lineart_main_load_geometries(
BLI_listbase_clear(&rb->triangle_buffer_pointers);
BLI_listbase_clear(&rb->vertex_buffer_pointers);
- int flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
- DEG_ITER_OBJECT_FLAG_VISIBLE;
-
- /* Instance duplicated & particles. */
- if (allow_duplicates) {
- flags |= DEG_ITER_OBJECT_FLAG_DUPLI;
- }
-
int thread_count = rb->thread_count;
/* This memory is in render buffer memory pool. so we don't need to free those after loading.
@@ -2461,73 +2512,34 @@ static void lineart_main_load_geometries(
LineartObjectLoadTaskInfo *olti = lineart_mem_acquire(
&rb->render_data_pool, sizeof(LineartObjectLoadTaskInfo) * thread_count);
- bool is_render = DEG_get_mode(depsgraph) == DAG_EVAL_RENDER;
-
- DEG_OBJECT_ITER_BEGIN (depsgraph, ob, flags) {
- LineartObjectInfo *obi = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartObjectInfo));
- obi->usage = lineart_usage_check(scene->master_collection, ob, is_render);
- obi->override_intersection_mask = lineart_intersection_mask_check(scene->master_collection,
- ob);
- Mesh *use_mesh;
-
- if (obi->usage == OBJECT_LRT_EXCLUDE) {
- continue;
- }
+ eEvaluationMode eval_mode = DEG_get_mode(depsgraph);
+ bool is_render = eval_mode == DAG_EVAL_RENDER;
- Object *use_ob = DEG_get_evaluated_object(depsgraph, ob);
- /* Prepare the matrix used for transforming this specific object (instance). This has to be
- * done before mesh boundbox check because the function needs that. */
- mul_m4db_m4db_m4fl_uniq(obi->model_view_proj, rb->view_projection, ob->obmat);
- mul_m4db_m4db_m4fl_uniq(obi->model_view, rb->view, ob->obmat);
+ FOREACH_SCENE_OBJECT_BEGIN (scene, ob) {
+ Object *eval_ob = DEG_get_evaluated_object(depsgraph, ob);
- if (!ELEM(use_ob->type, OB_MESH, OB_MBALL, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
+ if (!eval_ob) {
continue;
}
- if (use_ob->type == OB_MESH) {
- use_mesh = BKE_object_get_evaluated_mesh(use_ob);
- }
- else {
- /* If DEG_ITER_OBJECT_FLAG_DUPLI is set, some curve objects may also have an evaluated mesh
- * object in the list. To avoid adding duplicate geometry, ignore evaluated curve objects
- * in those cases. */
- if (allow_duplicates && BKE_object_get_evaluated_mesh(ob) != NULL) {
- continue;
- }
- use_mesh = BKE_mesh_new_from_object(depsgraph, use_ob, true, true);
+ if (BKE_object_visibility(eval_ob, eval_mode) & OB_VISIBLE_SELF) {
+ lineart_object_load_single_instance(
+ rb, depsgraph, scene, eval_ob, eval_ob, eval_ob->obmat, is_render, olti, thread_count);
}
-
- /* In case we still can not get any mesh geometry data from the object */
- if (!use_mesh) {
- continue;
- }
-
- if (!lineart_geometry_check_visible(
- obi->model_view_proj, rb->shift_x, rb->shift_y, use_mesh)) {
- if (ob->type != OB_MESH) {
- BKE_id_free(NULL, use_mesh);
- }
- if (G.debug_value == 4000) {
- bound_box_discard_count++;
+ if (allow_duplicates) {
+ ListBase *dupli = object_duplilist(depsgraph, scene, eval_ob);
+ LISTBASE_FOREACH (DupliObject *, dob, dupli) {
+ if (BKE_object_visibility(eval_ob, eval_mode) &
+ (OB_VISIBLE_PARTICLES | OB_VISIBLE_INSTANCES)) {
+ Object *ob_ref = (dob->type & OB_DUPLIPARTS) ? eval_ob : dob->ob;
+ lineart_object_load_single_instance(
+ rb, depsgraph, scene, dob->ob, ob_ref, dob->mat, is_render, olti, thread_count);
+ }
}
- continue;
- }
-
- if (ob->type != OB_MESH) {
- obi->free_use_mesh = true;
+ free_object_duplilist(dupli);
}
-
- /* Make normal matrix. */
- float imat[4][4];
- invert_m4_m4(imat, ob->obmat);
- transpose_m4(imat);
- copy_m4d_m4(obi->normal, imat);
-
- obi->original_me = use_mesh;
- obi->original_ob = (ob->id.orig_id ? (Object *)ob->id.orig_id : (Object *)ob);
- lineart_geometry_load_assign_thread(olti, obi, thread_count, use_mesh->totpoly);
}
- DEG_OBJECT_ITER_END;
+ FOREACH_SCENE_OBJECT_END;
TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH);