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:
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h17
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c95
2 files changed, 81 insertions, 31 deletions
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index c523809a4ad..97f4459072f 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -193,7 +193,7 @@ typedef struct LineartChainRegisterEntry {
LineartLineChainItem *rlci;
char picked;
- /** left/right mark.
+ /* left/right mark.
* Because we revert list in chaining so we need the flag. */
char is_left;
} LineartChainRegisterEntry;
@@ -220,7 +220,7 @@ typedef struct LineartRenderBuffer {
ListBase triangle_adjacent_pointers;
ListBase intersecting_vertex_buffer;
- /** Use the one comes with Line Art. */
+ /* Use the one comes with Line Art. */
LineartStaticMemPool render_data_pool;
ListBase wasted_cuts;
SpinLock lock_cuts;
@@ -258,7 +258,7 @@ typedef struct LineartRenderBuffer {
ListBase chains;
- /** For managing calculation tasks for multiple threads. */
+ /* For managing calculation tasks for multiple threads. */
SpinLock lock_task;
/* settings */
@@ -281,7 +281,7 @@ typedef struct LineartRenderBuffer {
bool allow_overlapping_edges;
bool remove_doubles;
- /** Keep an copy of these data so when line art is running it's self-contained. */
+ /* Keep an copy of these data so when line art is running it's self-contained. */
bool cam_is_persp;
float cam_obmat[4][4];
double camera_pos[3];
@@ -291,6 +291,15 @@ typedef struct LineartRenderBuffer {
float chaining_image_threshold;
float chaining_geometry_threshold;
float angle_splitting_threshold;
+
+ /* FIXME: (Yiming) Temporary solution for speeding up calculation by not including lines that
+ * are not in the selected source. This will not be needed after we have a proper scene-wise
+ * cache running because multiple modifiers can then select results from that without further
+ * calculation. */
+ int _source_type;
+ struct Collection *_source_collection;
+ struct Object *_source_object;
+
} LineartRenderBuffer;
#define DBL_TRIANGLE_LIM 1e-8
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index 6c638478983..41b269c836d 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -1719,18 +1719,35 @@ static void lineart_geometry_object_load(Depsgraph *dg,
#undef LRT_MESH_FINISH
}
+static bool _lineart_object_not_in_source_collection(Collection *source, Object *ob)
+{
+ CollectionChild *cc;
+ Collection *c = source->id.orig_id ? (Collection *)source->id.orig_id : source;
+ if (BKE_collection_has_object(c, (Object *)(ob->id.orig_id))) {
+ return false;
+ }
+ for (cc = source->children.first; cc; cc = cc->next) {
+ if (!_lineart_object_not_in_source_collection(cc->collection, ob)) {
+ return false;
+ }
+ }
+ return true;
+}
+
/* See if this object in such collection is used for generating line art,
- * Disabling a collection for line art will diable all objects inside. */
-static int lineart_usage_check(Collection *c, Object *ob)
+ * Disabling a collection for line art will diable all objects inside.
+ * "_rb" is used to provide source selection info. See the definition of rb->_source_type for
+ * details. */
+static int lineart_usage_check(Collection *c, Object *ob, LineartRenderBuffer *_rb)
{
if (!c) {
return OBJECT_LRT_INHERENT;
}
- int object_is_used = (ob->lineart.usage != OBJECT_LRT_INHERENT);
+ int object_has_special_usage = (ob->lineart.usage != OBJECT_LRT_INHERENT);
- if (object_is_used) {
+ if (object_has_special_usage) {
return ob->lineart.usage;
}
@@ -1755,12 +1772,25 @@ static int lineart_usage_check(Collection *c, Object *ob)
}
LISTBASE_FOREACH (CollectionChild *, cc, &c->children) {
- int result = lineart_usage_check(cc->collection, ob);
+ int result = lineart_usage_check(cc->collection, ob, _rb);
if (result > OBJECT_LRT_INHERENT) {
return result;
}
}
+ /* Temp solution to speed up calculation in the modifier without cache. See the definition of
+ * rb->_source_type for details. */
+ if (_rb->_source_type == LRT_SOURCE_OBJECT) {
+ if (ob != _rb->_source_object) {
+ return OBJECT_LRT_OCCLUSION_ONLY;
+ }
+ }
+ else if (_rb->_source_type == LRT_SOURCE_COLLECTION) {
+ if (_lineart_object_not_in_source_collection(_rb->_source_collection, ob)) {
+ return OBJECT_LRT_OCCLUSION_ONLY;
+ }
+ }
+
return OBJECT_LRT_INHERENT;
}
@@ -1813,7 +1843,7 @@ static void lineart_main_load_geometries(
int global_i = 0;
DEG_OBJECT_ITER_BEGIN (depsgraph, ob, flags) {
- int usage = lineart_usage_check(scene->master_collection, ob);
+ int usage = lineart_usage_check(scene->master_collection, ob, rb);
lineart_geometry_object_load(depsgraph, ob, view, proj, rb, usage, &global_i);
}
@@ -2228,8 +2258,10 @@ static void lineart_vert_set_intersection_2v(LineartVert *rv, LineartVert *v1, L
irv->isec2 = v2->index;
}
-/* This tests a triangle against a virtual line represented by v1---v2. The vertices returned after
- * repeated calls to this function is then used to create a triangle/triangle intersection line. */
+/* This tests a triangle against a virtual line represented by v1---v2. The vertices returned
+ * after
+ * repeated calls to this function is then used to create a triangle/triangle intersection line.
+ */
static LineartVert *lineart_triangle_2v_intersection_test(LineartRenderBuffer *rb,
LineartVert *v1,
LineartVert *v2,
@@ -2268,7 +2300,8 @@ static LineartVert *lineart_triangle_2v_intersection_test(LineartRenderBuffer *r
interp_v3_v3v3_db(gloc, l->gloc, r->gloc, dot_l / (dot_l + dot_r));
- /* Due to precision issue, we might end up with the same point as the one we already detected. */
+ /* Due to precision issue, we might end up with the same point as the one we already detected.
+ */
if (last && LRT_DOUBLE_CLOSE_ENOUGH(last->gloc[0], gloc[0]) &&
LRT_DOUBLE_CLOSE_ENOUGH(last->gloc[1], gloc[1]) &&
LRT_DOUBLE_CLOSE_ENOUGH(last->gloc[2], gloc[2])) {
@@ -2401,8 +2434,8 @@ static LineartEdge *lineart_triangle_intersect(LineartRenderBuffer *rb,
}
}
- /* The intersection line has been generated only in geometry space, so we need to transform them
- * as well. */
+ /* The intersection line has been generated only in geometry space, so we need to transform
+ * them as well. */
mul_v4_m4v3_db(v1->fbcoord, rb->view_projection, v1->gloc);
mul_v4_m4v3_db(v2->fbcoord, rb->view_projection, v2->gloc);
mul_v3db_db(v1->fbcoord, (1 / v1->fbcoord[3]));
@@ -2476,25 +2509,28 @@ static void lineart_triangle_intersect_in_bounding_area(LineartRenderBuffer *rb,
testing_triangle = lip->data;
rtt = (LineartTriangleThread *)testing_triangle;
- if (testing_triangle == rt || rtt->testing_e[0] == (LineartEdge *)rt ||
- (testing_triangle->flags & LRT_TRIANGLE_NO_INTERSECTION) ||
+ if (testing_triangle == rt || rtt->testing_e[0] == (LineartEdge *)rt) {
+ continue;
+ }
+ rtt->testing_e[0] = (LineartEdge *)rt;
+
+ if ((testing_triangle->flags & LRT_TRIANGLE_NO_INTERSECTION) ||
((testing_triangle->flags & LRT_TRIANGLE_INTERSECTION_ONLY) &&
- (rt->flags & LRT_TRIANGLE_INTERSECTION_ONLY)) ||
- lineart_triangle_share_edge(rt, testing_triangle)) {
+ (rt->flags & LRT_TRIANGLE_INTERSECTION_ONLY))) {
continue;
}
- rtt->testing_e[0] = (LineartEdge *)rt;
double *RG0 = testing_triangle->v[0]->gloc, *RG1 = testing_triangle->v[1]->gloc,
*RG2 = testing_triangle->v[2]->gloc;
- /* Bounding box not overlapping, not potential of intersecting. */
+ /* Bounding box not overlapping or triangles share edges, not potential of intersecting. */
if ((MIN3(G0[2], G1[2], G2[2]) > MAX3(RG0[2], RG1[2], RG2[2])) ||
(MAX3(G0[2], G1[2], G2[2]) < MIN3(RG0[2], RG1[2], RG2[2])) ||
(MIN3(G0[0], G1[0], G2[0]) > MAX3(RG0[0], RG1[0], RG2[0])) ||
(MAX3(G0[0], G1[0], G2[0]) < MIN3(RG0[0], RG1[0], RG2[0])) ||
(MIN3(G0[1], G1[1], G2[1]) > MAX3(RG0[1], RG1[1], RG2[1])) ||
- (MAX3(G0[1], G1[1], G2[1]) < MIN3(RG0[1], RG1[1], RG2[1]))) {
+ (MAX3(G0[1], G1[1], G2[1]) < MIN3(RG0[1], RG1[1], RG2[1])) ||
+ lineart_triangle_share_edge(rt, testing_triangle)) {
continue;
}
@@ -3581,6 +3617,11 @@ int MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, LineartGpencilModifi
* occlusion levels will get ignored. */
rb->max_occlusion_level = MAX2(lmd->level_start, lmd->level_end);
+ /* FIXME: (Yiming) See definition of int LineartRenderBuffer::_source_type for detailes. */
+ rb->_source_type = lmd->source_type;
+ rb->_source_collection = lmd->source_collection;
+ rb->_source_object = lmd->source_object;
+
/* Get view vector before loading geometries, because we detect feature lines there. */
lineart_main_get_view_vector(rb);
lineart_main_load_geometries(
@@ -3608,13 +3649,13 @@ int MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, LineartGpencilModifi
lineart_main_perspective_division(rb);
/* Triangle intersections are done here during sequential adding of them. Only after this,
- * triangles and lines are all linked with acceleration structure, and the 2D occlusion stage can
- * do its job. */
+ * triangles and lines are all linked with acceleration structure, and the 2D occlusion stage
+ * can do its job. */
lineart_main_add_triangles(rb);
- /* Link lines to acceleration structure, this can only be done after perspective division, if we
- * do it after triangles being added, the acceleration structure has already been subdivided,
- * this way we do less list manipulations. */
+ /* Link lines to acceleration structure, this can only be done after perspective division, if
+ * we do it after triangles being added, the acceleration structure has already been
+ * subdivided, this way we do less list manipulations. */
lineart_main_link_lines(rb);
/* "intersection_only" is preserved for being called in a standalone fashion.
@@ -3627,12 +3668,12 @@ int MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, LineartGpencilModifi
lineart_main_occlusion_begin(rb);
/* Chaining is all single threaded. See lineart_chain.c
- * In this particular call, only lines that are geometrically connected (share the _exact_ same
- * end point) will be chained together. */
+ * In this particular call, only lines that are geometrically connected (share the _exact_
+ * same end point) will be chained together. */
MOD_lineart_chain_feature_lines(rb);
- /* We are unable to take care of occlusion if we only connect end points, so here we do a spit,
- * where the splitting point could be any cut in e->segments. */
+ /* We are unable to take care of occlusion if we only connect end points, so here we do a
+ * spit, where the splitting point could be any cut in e->segments. */
MOD_lineart_chain_split_for_fixed_occlusion(rb);
/* Then we connect chains based on the _proximity_ of their end points in geometry or image