[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