[Bf-blender-cvs] [82e0783f608] temp-lineart-embree: LineArt: Workable embree intersection stage.
YimingWu
noreply at git.blender.org
Sun Mar 13 14:37:27 CET 2022
Commit: 82e0783f608bccd3c2814a0f009e39a25c703b09
Author: YimingWu
Date: Sun Jan 16 20:49:00 2022 +0800
Branches: temp-lineart-embree
https://developer.blender.org/rB82e0783f608bccd3c2814a0f009e39a25c703b09
LineArt: Workable embree intersection stage.
===================================================================
M source/blender/gpencil_modifiers/CMakeLists.txt
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/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt
index 5ee75619259..d02a01fe8fb 100644
--- a/source/blender/gpencil_modifiers/CMakeLists.txt
+++ b/source/blender/gpencil_modifiers/CMakeLists.txt
@@ -44,6 +44,15 @@ set(INC_SYS
${ZLIB_INCLUDE_DIRS}
)
+if(WITH_CYCLES_EMBREE)
+ add_definitions(-DWITH_EMBREE)
+ add_definitions(-DEMBREE_STATIC_LIB)
+ include_directories(
+ SYSTEM
+ ${EMBREE_INCLUDE_DIRS}
+ )
+endif()
+
set(SRC
intern/MOD_gpencil_ui_common.c
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 8c5820c9667..2eab9490676 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -28,6 +28,8 @@
#include "BLI_math.h" /* Needed here for inline functions. */
#include "BLI_threads.h"
+#include <embree3/rtcore.h>
+
#include <math.h>
typedef struct LineartStaticMemPoolNode {
@@ -216,6 +218,25 @@ enum eLineArtTileRecursiveLimit {
#define LRT_TILE_SPLITTING_TRIANGLE_LIMIT 100
#define LRT_TILE_EDGE_COUNT_INITIAL 32
+struct MLoopTri;
+struct MLoop;
+typedef struct LineartPointArrayFinal {
+ float *points;
+ int numpoints;
+ struct MLoopTri *looptri; /* Refernce to original_me->runtime->looptri; */
+ struct MLoop *loop; /* Refernce to original_me->mloop; */
+} LineartPointArrayFinal;
+
+typedef struct LineartMeshRecord {
+ LineartPointArrayFinal *array;
+ uint32_t next;
+ uint32_t max_length;
+
+ float *intersection_record;
+ uint32_t intersection_pair_max;
+ uint32_t intersection_pair_next;
+} LineartMeshRecord;
+
typedef struct LineartRenderBuffer {
struct LineartRenderBuffer *prev, *next;
@@ -260,6 +281,15 @@ typedef struct LineartRenderBuffer {
int triangle_size;
+ RTCDevice rtcdevice;
+ /* According to embree manual, geometries and buffers are destroyed when their reference count
+ * drops to 0, so in principle we don't need to retain pointers to them if we destroy the scene
+ * at once. */
+ RTCScene rtcscene_geom;
+ RTCScene rtcscene_view;
+
+ LineartMeshRecord mesh_record;
+
/* Although using ListBase here, LineartEdge is single linked list.
* list.last is used to store worker progress along the list.
* See lineart_main_occlusion_begin() for more info. */
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index f08d35891ce..7fea53934d5 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -44,6 +44,7 @@
#include "BKE_lib_id.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_object.h"
#include "BKE_pointcache.h"
#include "BKE_scene.h"
@@ -64,6 +65,8 @@
#include "lineart_intern.h"
+#define LINEART_USE_EMBREE
+
static LineartBoundingArea *lineart_edge_first_bounding_area(LineartRenderBuffer *rb,
LineartEdge *e);
@@ -1719,7 +1722,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu
}
if (obi->free_use_mesh) {
- BKE_id_free(NULL, obi->original_me);
+ // BKE_id_free(NULL, obi->original_me);
}
if (rb->remove_doubles) {
@@ -2087,6 +2090,105 @@ static bool lineart_geometry_check_visible(double (*model_view_proj)[4],
return true;
}
+static void lineart_embree_clear_mesh_record(LineartRenderBuffer *rb)
+{
+ 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);
+ }
+ }
+ MEM_freeN(rb->mesh_record.array);
+ }
+ rb->mesh_record.max_length = 0;
+
+ if (rb->mesh_record.intersection_record) {
+ MEM_freeN(rb->mesh_record.intersection_record);
+ }
+ rb->mesh_record.intersection_pair_max = rb->mesh_record.intersection_pair_next = 0;
+
+ if (rb->rtcdevice) {
+ rtcReleaseDevice(rb->rtcdevice);
+ rb->rtcdevice = NULL;
+ }
+ if (rb->rtcscene_geom) {
+ rtcReleaseScene(rb->rtcscene_geom);
+ rb->rtcscene_geom = NULL;
+ }
+}
+static void lineart_embree_init_mesh_record(LineartRenderBuffer *rb)
+{
+ /* In case anything dirty. */
+ lineart_embree_clear_mesh_record(rb);
+
+ const char *config = "verbose=3";
+ rb->rtcdevice = rtcNewDevice(config);
+ rb->rtcscene_geom = rtcNewScene(rb->rtcdevice);
+
+ rb->mesh_record.max_length = 100;
+ rb->mesh_record.array = MEM_callocN(sizeof(LineartPointArrayFinal) * rb->mesh_record.max_length,
+ "LineartPointArrayFinal");
+ 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");
+}
+
+static void lineart_embree_mesh_bounds_func(const struct RTCBoundsFunctionArguments *args)
+{
+ LineartPointArrayFinal *rec = args->geometryUserPtr;
+ float *p0 = &rec->points[rec->loop[rec->looptri[args->primID].tri[0]].v * 3];
+ float *p1 = &rec->points[rec->loop[rec->looptri[args->primID].tri[1]].v * 3];
+ float *p2 = &rec->points[rec->loop[rec->looptri[args->primID].tri[2]].v * 3];
+ 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)
+{
+ int pcount = me->totvert;
+
+ RTCGeometry geom = rtcNewGeometry(rb->rtcdevice, RTC_GEOMETRY_TYPE_USER);
+ uint32_t geom_id = rtcAttachGeometry(rb->rtcscene_geom, geom);
+ if (geom_id >= rb->mesh_record.max_length) {
+ LineartPointArrayFinal *new_array = MEM_callocN(sizeof(LineartPointArrayFinal) *
+ rb->mesh_record.max_length * 2,
+ "new LineartPointArrayFinal");
+ memcpy(new_array,
+ rb->mesh_record.array,
+ sizeof(LineartPointArrayFinal) * rb->mesh_record.max_length);
+ MEM_freeN(rb->mesh_record.array);
+ rb->mesh_record.max_length *= 2;
+ rb->mesh_record.array = new_array;
+ }
+ /* Because in the collide callback, only geom_id is available so it needs to be the same as the
+ * array index for convenience of lookup. */
+ LineartPointArrayFinal *rec = &rb->mesh_record.array[geom_id];
+ rb->mesh_record.next = geom_id + 1;
+
+ if (!me->runtime.looptris.array) {
+ BKE_mesh_runtime_looptri_recalc(me);
+ }
+
+ rec->numpoints = pcount;
+ rec->looptri = me->runtime.looptris.array;
+ rec->loop = me->mloop;
+ rec->points = MEM_mallocN(sizeof(float) * 3 * pcount, "LineartPointArrayFinal::points");
+ for (int i = 0; i < pcount; i++) {
+ mul_v3_m4v3(&rec->points[i * 3], ob->obmat, me->mvert[i].co);
+ }
+
+ /* Only user typed geometry supports rtcCollide(). */
+ rtcSetGeometryUserPrimitiveCount(geom, me->runtime.looptris.len);
+ /* Reduce the geom user count to 1, and when scene is destroyed the geom is destroyed
+ * automatically. */
+ rtcReleaseGeometry(geom);
+}
+
static void lineart_main_load_geometries(
Depsgraph *depsgraph,
Scene *scene,
@@ -2151,12 +2253,16 @@ static void lineart_main_load_geometries(
bool is_render = DEG_get_mode(depsgraph) == DAG_EVAL_RENDER;
+#ifdef LINEART_USE_EMBREE
+ lineart_embree_init_mesh_record(rb);
+#endif
+
DEG_OBJECT_ITER_BEGIN (depsgraph, ob, flags) {
LineartObjectInfo *obi = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartObjectInfo));
obi->usage = lineart_usage_check(scene->master_collection, ob, is_render);
obi->override_intersection_mask = lineart_intersection_mask_check(scene->master_collection,
ob);
- Mesh *use_mesh;
+ Mesh *use_mesh = NULL;
if (obi->usage == OBJECT_LRT_EXCLUDE) {
continue;
@@ -2189,7 +2295,7 @@ static void lineart_main_load_geometries(
if (allow_duplicates) {
continue;
}
- use_mesh = BKE_mesh_new_from_object(depsgraph, use_ob, true, true);
+ // use_mesh = BKE_mesh_new_from_object(depsgraph, use_ob, true, true);
}
/* In case we still can not get any mesh geometry data from the object */
@@ -2201,6 +2307,11 @@ static void lineart_main_load_geometries(
obi->free_use_mesh = true;
}
+#ifdef LINEART_USE_EMBREE
+ /* Link vertices and faces to embree geometry. */
+ lineart_embree_transform_point_array(rb, ob, use_mesh);
+#endif
+
/* Make normal matrix. */
float imat[4][4];
invert_m4_m4(imat, ob->obmat);
@@ -2249,6 +2360,140 @@ static void lineart_main_load_geometries(
}
}
+static void lineart_add_intersection_record_thread(LineartRenderBuffer *rb, float *i1, float *i2)
+{
+ LineartMeshRecord *rec = &rb->mesh_record;
+ BLI_spin_lock(&rb->lock_task);
+ if (rec->intersection_pair_next >= rec->intersection_pair_max) {
+ float *new_array = MEM_mallocN(sizeof(float) * 6 * rec->intersection_pair_max * 2,
+ "new intersection_record");
+ memcpy(new_array, rec->intersection_record, sizeof(float) * 6 * rec->intersection_pair_max);
+ MEM_freeN(rec->intersection_record);
+ rec->intersection_record = new_array;
+ rec->intersection_pair_max *= 2;
+ }
+ float *write = &rec->intersection_record[rec->intersection_pair_next * 6];
+ rec->intersection_pair_next++;
+
+ copy_v3_v3(write, i1);
+ copy_v3_v3(&write[3], i2);
+ BLI_spin_unlock(&rb->lock_task);
+}
+
+static bool lineart_triangle_share_edge_generic(const float *a0,
+ const float *a1,
+ const float *a2,
+ const float *b0,
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list