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:
Diffstat (limited to 'source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c')
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c91
1 files changed, 63 insertions, 28 deletions
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index 06d63c3ddab..3796e374db7 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 @@
* \ingroup editors
*/
+#include "MOD_gpencil_lineart.h"
#include "MOD_lineart.h"
#include "BLI_linklist.h"
@@ -42,6 +43,7 @@
#include "BKE_gpencil_modifier.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
+#include "BKE_pointcache.h"
#include "BKE_scene.h"
#include "DEG_depsgraph_query.h"
#include "DNA_camera_types.h"
@@ -107,6 +109,8 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *spl,
static void lineart_add_edge_to_list(LineartRenderBuffer *rb, LineartEdge *e);
+static LineartCache *lineart_init_cache(void);
+
static void lineart_discard_segment(LineartRenderBuffer *rb, LineartEdgeSegment *es)
{
BLI_spin_lock(&rb->lock_cuts);
@@ -482,7 +486,7 @@ static void lineart_main_occlusion_begin(LineartRenderBuffer *rb)
rb->material.last = rb->material.first;
rb->edge_mark.last = rb->edge_mark.first;
- TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON);
+ TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH);
for (i = 0; i < thread_count; i++) {
rti[i].thread_id = i;
@@ -1987,7 +1991,7 @@ static void lineart_main_load_geometries(
}
DEG_OBJECT_ITER_END;
- TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON);
+ TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH);
for (int i = 0; i < thread_count; i++) {
olti[i].rb = rb;
@@ -2771,13 +2775,13 @@ static void lineart_destroy_render_data(LineartRenderBuffer *rb)
void MOD_lineart_destroy_render_data(LineartGpencilModifierData *lmd)
{
- LineartRenderBuffer *rb = lmd->render_buffer;
+ LineartRenderBuffer *rb = lmd->render_buffer_ptr;
lineart_destroy_render_data(rb);
if (rb) {
MEM_freeN(rb);
- lmd->render_buffer = NULL;
+ lmd->render_buffer_ptr = NULL;
}
if (G.debug_value == 4000) {
@@ -2785,14 +2789,33 @@ void MOD_lineart_destroy_render_data(LineartGpencilModifierData *lmd)
}
}
+static LineartCache *lineart_init_cache()
+{
+ LineartCache *lc = MEM_callocN(sizeof(LineartCache), "Lineart Cache");
+ return lc;
+}
+
+void MOD_lineart_clear_cache(struct LineartCache **lc)
+{
+ if (!(*lc)) {
+ return;
+ }
+ lineart_mem_destroy(&((*lc)->chain_data_pool));
+ MEM_freeN(*lc);
+ (*lc) = NULL;
+}
+
static LineartRenderBuffer *lineart_create_render_buffer(Scene *scene,
- LineartGpencilModifierData *lmd)
+ LineartGpencilModifierData *lmd,
+ LineartCache *lc)
{
LineartRenderBuffer *rb = MEM_callocN(sizeof(LineartRenderBuffer), "Line Art render buffer");
- lmd->render_buffer = rb;
+ lmd->cache = lc;
+ lmd->render_buffer_ptr = rb;
+ lc->rb_edge_types = lmd->edge_types_override;
- if (!scene || !scene->camera) {
+ if (!scene || !scene->camera || !lc) {
return NULL;
}
Camera *c = scene->camera->data;
@@ -2835,11 +2858,15 @@ static LineartRenderBuffer *lineart_create_render_buffer(Scene *scene,
/* See lineart_edge_from_triangle() for how this option may impact performance. */
rb->allow_overlapping_edges = (lmd->calculation_flags & LRT_ALLOW_OVERLAPPING_EDGES) != 0;
- rb->use_contour = (lmd->edge_types & LRT_EDGE_FLAG_CONTOUR) != 0;
- rb->use_crease = (lmd->edge_types & LRT_EDGE_FLAG_CREASE) != 0;
- rb->use_material = (lmd->edge_types & LRT_EDGE_FLAG_MATERIAL) != 0;
- rb->use_edge_marks = (lmd->edge_types & LRT_EDGE_FLAG_EDGE_MARK) != 0;
- rb->use_intersections = (lmd->edge_types & LRT_EDGE_FLAG_INTERSECTION) != 0;
+ int16_t edge_types = lmd->edge_types_override;
+
+ rb->use_contour = (edge_types & LRT_EDGE_FLAG_CONTOUR) != 0;
+ rb->use_crease = (edge_types & LRT_EDGE_FLAG_CREASE) != 0;
+ rb->use_material = (edge_types & LRT_EDGE_FLAG_MATERIAL) != 0;
+ rb->use_edge_marks = (edge_types & LRT_EDGE_FLAG_EDGE_MARK) != 0;
+ rb->use_intersections = (edge_types & LRT_EDGE_FLAG_INTERSECTION) != 0;
+
+ rb->chain_data_pool = &lc->chain_data_pool;
BLI_spin_init(&rb->lock_task);
BLI_spin_init(&rb->lock_cuts);
@@ -3818,7 +3845,9 @@ static LineartBoundingArea *lineart_bounding_area_next(LineartBoundingArea *this
*
* \return True when a change is made.
*/
-bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, LineartGpencilModifierData *lmd)
+bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph,
+ LineartGpencilModifierData *lmd,
+ LineartCache **cached_result)
{
LineartRenderBuffer *rb;
Scene *scene = DEG_get_evaluated_scene(depsgraph);
@@ -3836,7 +3865,10 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, LineartGpencilModif
return false;
}
- rb = lineart_create_render_buffer(scene, lmd);
+ LineartCache *lc = lineart_init_cache();
+ *cached_result = lc;
+
+ rb = lineart_create_render_buffer(scene, lmd, lc);
/* Triangle thread testing data size varies depending on the thread count.
* See definition of LineartTriangleThread for details. */
@@ -3844,7 +3876,9 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, LineartGpencilModif
/* This is used to limit calculation to a certain level to save time, lines who have higher
* occlusion levels will get ignored. */
- rb->max_occlusion_level = MAX2(lmd->level_start, lmd->level_end);
+ rb->max_occlusion_level = (lmd->flags & LRT_GPENCIL_USE_CACHE) ?
+ lmd->level_end_override :
+ (lmd->use_multiple_levels ? lmd->level_end : lmd->level_start);
/* FIXME(Yiming): See definition of int #LineartRenderBuffer::_source_type for detailed. */
rb->_source_type = lmd->source_type;
@@ -3907,13 +3941,8 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, LineartGpencilModif
/* Then we connect chains based on the _proximity_ of their end points in image space, here's
* the place threshold value gets involved. */
-
- /* do_geometry_space = true. */
MOD_lineart_chain_connect(rb);
- /* After chaining, we need to clear flags so we don't confuse GPencil generation calls. */
- MOD_lineart_chain_clear_picked_flag(rb);
-
float *t_image = &lmd->chaining_image_threshold;
/* This configuration ensures there won't be accidental lost of short unchained segments. */
MOD_lineart_chain_discard_short(rb, MIN2(*t_image, 0.001f) - FLT_EPSILON);
@@ -3921,6 +3950,12 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, LineartGpencilModif
if (rb->angle_splitting_threshold > FLT_EPSILON) {
MOD_lineart_chain_split_angle(rb, rb->angle_splitting_threshold);
}
+
+ /* Finally transfer the result list into cache. */
+ memcpy(&lc->chains, &rb->chains, sizeof(ListBase));
+
+ /* At last, we need to clear flags so we don't confuse GPencil generation calls. */
+ MOD_lineart_chain_clear_picked_flag(lc);
}
if (G.debug_value == 4000) {
@@ -3933,7 +3968,7 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, LineartGpencilModif
return true;
}
-static int lineart_rb_edge_types(LineartRenderBuffer *rb)
+static int UNUSED_FUNCTION(lineart_rb_edge_types)(LineartRenderBuffer *rb)
{
int types = 0;
types |= rb->use_contour ? LRT_EDGE_FLAG_CONTOUR : 0;
@@ -3944,7 +3979,7 @@ static int lineart_rb_edge_types(LineartRenderBuffer *rb)
return types;
}
-static void lineart_gpencil_generate(LineartRenderBuffer *rb,
+static void lineart_gpencil_generate(LineartCache *cache,
Depsgraph *depsgraph,
Object *gpencil_object,
float (*gp_obmat_inverse)[4],
@@ -3964,9 +3999,9 @@ static void lineart_gpencil_generate(LineartRenderBuffer *rb,
const char *vgname,
int modifier_flags)
{
- if (rb == NULL) {
+ if (cache == NULL) {
if (G.debug_value == 4000) {
- printf("NULL Lineart rb!\n");
+ printf("NULL Lineart cache!\n");
}
return;
}
@@ -3990,11 +4025,11 @@ static void lineart_gpencil_generate(LineartRenderBuffer *rb,
float mat[4][4];
unit_m4(mat);
- int enabled_types = lineart_rb_edge_types(rb);
+ int enabled_types = cache->rb_edge_types;
bool invert_input = modifier_flags & LRT_GPENCIL_INVERT_SOURCE_VGROUP;
bool match_output = modifier_flags & LRT_GPENCIL_MATCH_OUTPUT_VGROUP;
- LISTBASE_FOREACH (LineartEdgeChain *, ec, &rb->chains) {
+ LISTBASE_FOREACH (LineartEdgeChain *, ec, &cache->chains) {
if (ec->picked) {
continue;
@@ -4108,7 +4143,7 @@ static void lineart_gpencil_generate(LineartRenderBuffer *rb,
/**
* Wrapper for external calls.
*/
-void MOD_lineart_gpencil_generate(LineartRenderBuffer *rb,
+void MOD_lineart_gpencil_generate(LineartCache *cache,
Depsgraph *depsgraph,
Object *ob,
bGPDlayer *gpl,
@@ -4156,7 +4191,7 @@ void MOD_lineart_gpencil_generate(LineartRenderBuffer *rb,
}
float gp_obmat_inverse[4][4];
invert_m4_m4(gp_obmat_inverse, ob->obmat);
- lineart_gpencil_generate(rb,
+ lineart_gpencil_generate(cache,
depsgraph,
ob,
gp_obmat_inverse,