[Bf-blender-cvs] [51b467afe3c] temp-lineart-embree: LineArt: Use thread local stroage for occlusion pair results
YimingWu
noreply at git.blender.org
Fri Mar 25 12:38:56 CET 2022
Commit: 51b467afe3c4e09c2a4d56e5728188ace2f78935
Author: YimingWu
Date: Thu Mar 24 20:07:19 2022 +0800
Branches: temp-lineart-embree
https://developer.blender.org/rB51b467afe3c4e09c2a4d56e5728188ace2f78935
LineArt: Use thread local stroage for occlusion pair results
===================================================================
M source/blender/gpencil_modifiers/CMakeLists.txt
M source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
A source/blender/gpencil_modifiers/intern/lineart/lineart_cpp_bridge.cpp
M source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
===================================================================
diff --git a/source/blender/gpencil_modifiers/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt
index 8ed186d978d..6801c11a3ae 100644
--- a/source/blender/gpencil_modifiers/CMakeLists.txt
+++ b/source/blender/gpencil_modifiers/CMakeLists.txt
@@ -1,6 +1,18 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2018 Blender Foundation. All rights reserved.
+if(WITH_TBB)
+ add_definitions(-DWITH_TBB)
+
+ list(APPEND INC_SYS
+ ${TBB_INCLUDE_DIRS}
+ )
+
+ list(APPEND LIB
+ ${TBB_LIBRARIES}
+ )
+endif()
+
set(INC
.
intern
@@ -70,6 +82,7 @@ set(SRC
intern/MOD_gpencil_util.h
# Lineart code
+ intern/lineart/lineart_cpp_bridge.cpp
intern/lineart/lineart_chain.c
intern/lineart/lineart_cpu.c
intern/lineart/lineart_ops.c
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 38b5c53c32f..1b8684ad8c2 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -210,17 +210,17 @@ struct MLoopTri;
struct MLoop;
struct LineartRenderBuffer;
typedef struct LineartPointArrayFinal {
- float *points;
- int numpoints;
- struct MLoopTri *looptri; /* Refernce to original_me->runtime->looptri; */
- struct MLoop *loop; /* Refernce to original_me->mloop; */
+ // float *points;
+ // int numpoints;
+ // struct MLoopTri *looptri; /* Refernce to original_me->runtime->looptri; */
+ // struct MLoop *loop; /* Refernce to original_me->mloop; */
LineartElementLinkNode *eln_triangle;
struct LineartRenderBuffer *rb;
} LineartPointArrayFinal;
typedef struct LineartIntersectionRecord {
- float p1[3];
- float p2[3];
+ double p1[3];
+ double p2[3];
struct LineartTriangle *t1;
struct LineartTriangle *t2;
} LineartIntersectionRecord;
@@ -249,6 +249,8 @@ typedef struct LineartOcclusionPairRecord {
uint32_t scheduled_next;
} LineartOcclusionPairRecord;
+typedef struct LineartThreadOcclusionData LineartThreadOcclusionData;
+
typedef struct LineartRenderBuffer {
struct LineartRenderBuffer *prev, *next;
@@ -300,6 +302,7 @@ typedef struct LineartRenderBuffer {
RTCScene rtcscene_geom;
RTCScene rtcscene_view;
+ struct LineartThreadOcclusionData *thread_occlusion_data;
LineartMeshRecord mesh_record;
LineartOcclusionPairRecord occlusion_record;
@@ -780,3 +783,20 @@ void MOD_lineart_gpencil_generate(LineartCache *cache,
float MOD_lineart_chain_compute_length(LineartEdgeChain *ec);
void ED_operatortypes_lineart(void);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LineartThreadOcclusionData *lineart_thread_init_occlusion_result(void);
+void lineart_thread_add_occlusion_pair(LineartThreadOcclusionData *data,
+ LineartElementLinkNode *eln_edge,
+ LineartElementLinkNode *eln_triangle,
+ LineartEdge *e,
+ LineartTriangle *t);
+LineartOcclusionPair *lineart_thread_finalize_occlusion_result(LineartThreadOcclusionData *data,
+ int *result_count);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpp_bridge.cpp b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpp_bridge.cpp
new file mode 100644
index 00000000000..339a8050091
--- /dev/null
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpp_bridge.cpp
@@ -0,0 +1,47 @@
+
+#include "MOD_lineart.h"
+
+#include "lineart_intern.h"
+
+#include "BLI_enumerable_thread_specific.hh"
+#include "BLI_task.h"
+#include "BLI_utildefines.h"
+#include "BLI_vector.hh"
+
+using blender::Vector;
+using blender::threading::EnumerableThreadSpecific;
+
+typedef EnumerableThreadSpecific<Vector<LineartOcclusionPair>> _LineartThreadOcclusionData;
+typedef struct LineartThreadOcclusionData LineartThreadOcclusionData;
+
+LineartThreadOcclusionData *lineart_thread_init_occlusion_result()
+{
+ _LineartThreadOcclusionData *result = new _LineartThreadOcclusionData;
+ return (LineartThreadOcclusionData *)result;
+};
+
+void lineart_thread_add_occlusion_pair(LineartThreadOcclusionData *data,
+ LineartElementLinkNode *eln_edge,
+ LineartElementLinkNode *eln_triangle,
+ LineartEdge *e,
+ LineartTriangle *t)
+{
+ LineartOcclusionPair op;
+ op.e = e;
+ op.t = t;
+ op.eln_edge = eln_edge;
+ op.eln_triangle = eln_triangle;
+ ((_LineartThreadOcclusionData *)data)->local().append(op);
+}
+
+/* Memory returned by this needs to be freed manually. */
+LineartOcclusionPair *lineart_thread_finalize_occlusion_result(LineartThreadOcclusionData *data,
+ int *result_count)
+{
+ Vector<LineartOcclusionPair> *result = new Vector<LineartOcclusionPair>;
+ for (const Vector<LineartOcclusionPair> &local : (*(_LineartThreadOcclusionData *)data)) {
+ result->extend(local);
+ }
+ *result_count = result->size();
+ return (LineartOcclusionPair *)result->data();
+};
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index 40fb91dd15c..32a1b29c1df 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -98,6 +98,14 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *spl,
double *from,
double *to);
+static LineartVert *lineart_triangle_share_point(const LineartTriangle *l,
+ const LineartTriangle *r);
+
+static bool lineart_triangle_get_other_verts(const LineartTriangle *tri,
+ const LineartVert *vt,
+ LineartVert **l,
+ LineartVert **r);
+
static void OcclusionCollideFunc(void *userPtr,
struct RTCCollision *collisions,
unsigned int num_collisions);
@@ -2209,15 +2217,167 @@ static bool lineart_geometry_check_visible(double (*model_view_proj)[4],
return true;
}
-static void lineart_embree_clear_mesh_record(LineartRenderBuffer *rb)
+static bool lineart_embree_triangle_2v_intersection_test(LineartVert *v1,
+ LineartVert *v2,
+ LineartTriangle *tri,
+ LineartTriangle *testing,
+ double *last,
+ double *result)
{
- if (rb->mesh_record.array) {
- for (int i = 0; i < rb->mesh_record.max_length; i++) {
- LineartPointArrayFinal *rec = &rb->mesh_record.array[i];
- if (rec->points) {
- MEM_freeN(rec->points);
+ double Lv[3];
+ double Rv[3];
+ double dot_l, dot_r;
+ double gloc[3];
+ LineartVert *l = v1, *r = v2;
+
+ sub_v3_v3v3_db(Lv, l->gloc, testing->v[0]->gloc);
+ sub_v3_v3v3_db(Rv, r->gloc, testing->v[0]->gloc);
+
+ dot_l = dot_v3v3_db(Lv, testing->gn);
+ dot_r = dot_v3v3_db(Rv, testing->gn);
+
+ if (dot_l * dot_r > 0 || (!dot_l && !dot_r)) {
+ return false;
+ }
+
+ dot_l = fabs(dot_l);
+ dot_r = fabs(dot_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.
+ */
+ if (last && LRT_DOUBLE_CLOSE_ENOUGH(last[0], gloc[0]) &&
+ LRT_DOUBLE_CLOSE_ENOUGH(last[1], gloc[1]) && LRT_DOUBLE_CLOSE_ENOUGH(last[2], gloc[2])) {
+ return false;
+ }
+
+ if (!(lineart_point_inside_triangle3d(
+ gloc, testing->v[0]->gloc, testing->v[1]->gloc, testing->v[2]->gloc))) {
+ return false;
+ }
+
+ copy_v3_v3_db(result, gloc);
+
+ return true;
+}
+
+static bool lineart_embree_triangle_intersect(LineartTriangle *tri,
+ LineartTriangle *testing,
+ double *r_v1,
+ double *r_v2)
+{
+ double va1[3], va2[3];
+ double *v1 = va1, *v2 = va2;
+ double **next = &v1;
+ double E0T[3];
+ double E1T[3];
+ double E2T[3];
+ double TE0[3];
+ double TE1[3];
+ double TE2[3];
+ LineartVert *sv1, *sv2;
+ double cl[3];
+ bool isuccess;
+
+ LineartVert *share = lineart_triangle_share_point(testing, tri);
+
+ if (share) {
+ /* If triangles have sharing points like `abc` and `acd`, then we only need to detect `bc`
+ * against `acd` or `cd` against `abc`. */
+
+ LineartVert *new_share;
+ lineart_triangle_get_other_verts(tri, share, &sv1, &sv2);
+
+ new_share = share;
+ v1 = share->gloc;
+
+ isuccess = lineart_embree_triangle_2v_intersection_test(sv1, sv2, tri, testing, 0, v2);
+
+ if (!isuccess) {
+ lineart_triangle_get_other_verts(testing, share, &sv1, &sv2);
+ isuccess = lineart_embree_triangle_2v_intersection_test(sv1, sv2, testing, tri, 0, v2);
+ if (!isuccess) {
+ return false;
}
}
+ }
+ else {
+ /* If not sharing any points, then we need to try all the possibilities. */
+
+ int pcount = 0;
+
+ isuccess = lineart_embree_triangle_2v_intersection_test(
+ tri->v[0], tri->v[1], tri, testing, 0, E0T);
+ if (isuccess && (pcount < 2)) {
+ (*next) = E0T;
+ next = &v2;
+ pcount++;
+ }
+ isuccess = lineart_embree_triangle_2v_intersection_test(
+ tri->v[1], tri->v[2], tri, testing, v1, E1T);
+ if (isuccess && (pcount < 2)) {
+ (*next) = E1T;
+ next = &v2;
+ pcount++;
+ }
+ if (pcount < 2) {
+ isuccess = lineart_embree_triangle_2v_intersection_test(
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list