[Bf-blender-cvs] [3f9a040e457] temp-lineart-embree: LineArt: [NOT WORKING] Embree virtual triangle WIP
YimingWu
noreply at git.blender.org
Sun Mar 13 14:37:28 CET 2022
Commit: 3f9a040e457a18b4a7ee80079c3d0ace75e780ae
Author: YimingWu
Date: Sun Mar 13 21:37:05 2022 +0800
Branches: temp-lineart-embree
https://developer.blender.org/rB3f9a040e457a18b4a7ee80079c3d0ace75e780ae
LineArt: [NOT WORKING] Embree virtual triangle WIP
===================================================================
M source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
M source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
===================================================================
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 967d126853d..9d9f8a494ae 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -68,6 +68,7 @@ typedef enum eLineArtElementNodeFlag {
LRT_ELEMENT_IS_ADDITIONAL = (1 << 0),
LRT_ELEMENT_BORDER_ONLY = (1 << 1),
LRT_ELEMENT_NO_INTERSECTION = (1 << 2),
+ LRT_ELEMENT_IS_EDGE = (1 << 3),
} eLineArtElementNodeFlag;
typedef struct LineartElementLinkNode {
@@ -79,6 +80,9 @@ typedef struct LineartElementLinkNode {
/** Per object value, always set, if not enabled by #ObjectLineArt, then it's set to global. */
float crease_threshold;
+
+ /** Occlusion virtual triangle needs this postion as the 3rd point. */
+ double *cam_pos;
} LineartElementLinkNode;
typedef struct LineartEdgeSegment {
@@ -209,6 +213,7 @@ typedef struct LineartPointArrayFinal {
int numpoints;
struct MLoopTri *looptri; /* Refernce to original_me->runtime->looptri; */
struct MLoop *loop; /* Refernce to original_me->mloop; */
+ LineartElementLinkNode *eln_triangle;
} LineartPointArrayFinal;
typedef struct LineartMeshRecord {
@@ -221,6 +226,19 @@ typedef struct LineartMeshRecord {
uint32_t intersection_pair_next;
} LineartMeshRecord;
+typedef struct LineartOcclusionPair {
+ LineartElementLinkNode *eln_edge;
+ LineartElementLinkNode *eln_triangle;
+ LineartEdge *e;
+ LineartTriangle *t;
+} LineartOcclusionPair;
+
+typedef struct LineartOcclusionPairRecord {
+ LineartOcclusionPair *array;
+ uint32_t next;
+ uint32_t max_length;
+} LineartOcclusionPairRecord;
+
typedef struct LineartRenderBuffer {
struct LineartRenderBuffer *prev, *next;
@@ -273,6 +291,7 @@ typedef struct LineartRenderBuffer {
RTCScene rtcscene_view;
LineartMeshRecord mesh_record;
+ LineartOcclusionPairRecord occlusion_record;
/* Although using ListBase here, LineartEdge is single linked list.
* list.last is used to store worker progress along the list.
@@ -411,6 +430,8 @@ typedef struct LineartObjectInfo {
uint8_t override_intersection_mask;
int global_i_offset;
+ uint32_t embree_geom_id;
+
bool free_use_mesh;
/* Threads will add lines inside here, when all threads are done, we combine those into the
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index 19d14d66454..cd53f21ff99 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -96,10 +96,20 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *spl,
double *from,
double *to);
+static void OcclusionCollideFunc(void *userPtr,
+ struct RTCCollision *collisions,
+ unsigned int num_collisions);
+static void IntersectionCollideFunc(void *userPtr,
+ struct RTCCollision *collisions,
+ unsigned int num_collisions);
+
static void lineart_add_edge_to_list(LineartRenderBuffer *rb, LineartEdge *e);
static LineartCache *lineart_init_cache(void);
+static void lineart_embree_new_virtual_geometry(LineartRenderBuffer *rb,
+ LineartElementLinkNode *e_eln);
+
static void lineart_discard_segment(LineartRenderBuffer *rb, LineartEdgeSegment *es)
{
BLI_spin_lock(&rb->lock_cuts);
@@ -1426,6 +1436,7 @@ static void lineart_main_discard_out_of_frame_edges(LineartRenderBuffer *rb)
e[i].flags = LRT_EDGE_FLAG_CHAIN_PICKED;
}
}
+ lineart_embree_new_virtual_geometry(rb, eln);
}
}
@@ -1841,6 +1852,11 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu
eln->object_ref = orig_ob;
eln->flags |= (usage == OBJECT_LRT_NO_INTERSECTION ? LRT_ELEMENT_NO_INTERSECTION : 0);
+#ifdef LINEART_USE_EMBREE
+ RTCGeometry geom = rtcGetGeometry(rb->rtcscene_geom, obi->embree_geom_id);
+ rtcSetGeometryUserData(geom, eln);
+#endif
+
/* Note this memory is not from pool, will be deleted after culling. */
orta = MEM_callocN(sizeof(LineartTriangleAdjacent) * bm->totface, "LineartTriangleAdjacent");
/* Link is minimal so we use pool anyway. */
@@ -1938,6 +1954,8 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu
BLI_spin_unlock(&rb->lock_task);
eln->element_count = allocate_la_e;
eln->object_ref = orig_ob;
+ eln->cam_pos = rb->camera_pos;
+ eln->flags |= LRT_ELEMENT_IS_EDGE;
la_e = o_la_e;
la_s = o_la_s;
@@ -2150,6 +2168,12 @@ static void lineart_embree_clear_mesh_record(LineartRenderBuffer *rb)
}
rb->mesh_record.intersection_pair_max = rb->mesh_record.intersection_pair_next = 0;
+ if (rb->occlusion_record.array) {
+ MEM_freeN(rb->occlusion_record.array);
+ }
+ rb->occlusion_record.array = NULL;
+ rb->occlusion_record.max_length = rb->occlusion_record.next = 0;
+
if (rb->rtcdevice) {
rtcReleaseDevice(rb->rtcdevice);
rb->rtcdevice = NULL;
@@ -2158,6 +2182,10 @@ static void lineart_embree_clear_mesh_record(LineartRenderBuffer *rb)
rtcReleaseScene(rb->rtcscene_geom);
rb->rtcscene_geom = NULL;
}
+ if (rb->rtcscene_view) {
+ rtcReleaseScene(rb->rtcscene_view);
+ rb->rtcscene_view = NULL;
+ }
}
static void lineart_embree_init_mesh_record(LineartRenderBuffer *rb)
{
@@ -2167,6 +2195,7 @@ static void lineart_embree_init_mesh_record(LineartRenderBuffer *rb)
const char *config = "verbose=3";
rb->rtcdevice = rtcNewDevice(config);
rb->rtcscene_geom = rtcNewScene(rb->rtcdevice);
+ rb->rtcscene_view = rtcNewScene(rb->rtcdevice);
rb->mesh_record.max_length = 100;
rb->mesh_record.array = MEM_callocN(sizeof(LineartPointArrayFinal) * rb->mesh_record.max_length,
@@ -2174,6 +2203,10 @@ static void lineart_embree_init_mesh_record(LineartRenderBuffer *rb)
rb->mesh_record.intersection_pair_max = 100;
rb->mesh_record.intersection_record = MEM_callocN(
sizeof(float) * rb->mesh_record.intersection_pair_max * 6, "Lineart intersection_record");
+
+ rb->occlusion_record.max_length = 100;
+ rb->occlusion_record.array = MEM_callocN(
+ sizeof(LineartOcclusionPair) * rb->occlusion_record.max_length, "Lineart occlusion_record");
}
static void lineart_embree_mesh_bounds_func(const struct RTCBoundsFunctionArguments *args)
@@ -2190,12 +2223,32 @@ static void lineart_embree_mesh_bounds_func(const struct RTCBoundsFunctionArgume
o->lower_z = MIN3(p0[2], p1[2], p2[2]);
o->upper_z = MAX3(p0[2], p1[2], p2[2]);
}
-static void lineart_embree_transform_point_array(LineartRenderBuffer *rb, Object *ob, Mesh *me)
+static void lineart_embree_virtual_bounds_func(const struct RTCBoundsFunctionArguments *args)
+{
+ /* XXX: This doesn't actually take into account of LRT_CULL_DISCARD. */
+ LineartElementLinkNode *eln = args->geometryUserPtr;
+ LineartEdge *e = eln->pointer;
+ double *p0 = e[args->primID].v1->gloc;
+ double *p1 = e[args->primID].v2->gloc;
+ double *p2 = eln->cam_pos;
+ struct RTCBounds *o = args->bounds_o;
+ o->lower_x = MIN3(p0[0], p1[0], p2[0]);
+ o->upper_x = MAX3(p0[0], p1[0], p2[0]);
+ o->lower_y = MIN3(p0[1], p1[1], p2[1]);
+ o->upper_y = MAX3(p0[1], p1[1], p2[1]);
+ o->lower_z = MIN3(p0[2], p1[2], p2[2]);
+ o->upper_z = MAX3(p0[2], p1[2], p2[2]);
+}
+static void lineart_embree_transform_point_array(LineartRenderBuffer *rb,
+ Object *ob,
+ Mesh *me,
+ uint32_t *r_use_geom_id)
{
int pcount = me->totvert;
RTCGeometry geom = rtcNewGeometry(rb->rtcdevice, RTC_GEOMETRY_TYPE_USER);
uint32_t geom_id = rtcAttachGeometry(rb->rtcscene_geom, geom);
+ *r_use_geom_id = geom_id;
if (geom_id >= rb->mesh_record.max_length) {
LineartPointArrayFinal *new_array = MEM_callocN(sizeof(LineartPointArrayFinal) *
rb->mesh_record.max_length * 2,
@@ -2230,6 +2283,29 @@ static void lineart_embree_transform_point_array(LineartRenderBuffer *rb, Object
* automatically. */
rtcReleaseGeometry(geom);
}
+static void lineart_embree_new_virtual_geometry(LineartRenderBuffer *rb,
+ LineartElementLinkNode *e_eln)
+{
+ RTCGeometry geom = rtcNewGeometry(rb->rtcdevice, RTC_GEOMETRY_TYPE_USER);
+ uint32_t geom_id = rtcAttachGeometry(rb->rtcscene_geom, geom);
+
+ rtcSetGeometryUserData(geom, e_eln);
+ rtcSetGeometryUserPrimitiveCount(geom, e_eln->element_count);
+
+ rtcSetGeometryBoundsFunction(geom, lineart_embree_virtual_bounds_func, e_eln);
+ rtcCommitGeometry(geom);
+
+ /* Reduce the geom user count to 1, and when scene is destroyed the geom is destroyed
+ * automatically. */
+ rtcReleaseGeometry(geom);
+}
+/* Must be called after lineart_embree_do_intersections() because rb->rtcscene_geom is not
+ * committed until that. */
+static void lineart_embree_generate_occlusion_pairs(LineartRenderBuffer *rb)
+{
+ rtcCommitScene(rb->rtcscene_view);
+ rtcCollide(rb->rtcscene_view, rb->rtcscene_geom, OcclusionCollideFunc, rb);
+}
static void lineart_main_load_geometries(
Depsgraph *depsgraph,
@@ -2352,7 +2428,9 @@ static void lineart_main_load_geometries(
#ifdef LINEART_USE_EMBREE
/* Link vertices and faces to embree geometry. */
- lineart_embree_transform_point_array(rb, ob, use_mesh);
+ uint32_t use_geom_id = 0;
+ lineart_embree_transform_point_array(rb, ob, use_mesh, &use_geom_id);
+ obi->embree_geom_id = use_geom_id;
#endif
/* Make normal matrix. */
@@ -2417,10 +2495,36 @@ static void lineart_add_intersection_record_thread(LineartRenderBuffer *rb, floa
}
float *write = &rec->intersection_record[rec->intersection_pair_next * 6];
rec->intersection_pair_next++;
+ BLI_spin_unlock(&rb->lock_task);
copy_v3_v3(write,
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list