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:
Diffstat (limited to 'source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c')
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c1600
1 files changed, 794 insertions, 806 deletions
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index 621531d29e3..c08bf3e0fe9 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -46,10 +46,6 @@
#include "DNA_scene_types.h"
#include "MEM_guardedalloc.h"
-#include "bmesh.h"
-#include "bmesh_class.h"
-#include "bmesh_tools.h"
-
#include "lineart_intern.h"
typedef struct LineartIsecSingle {
@@ -73,19 +69,18 @@ typedef struct LineartIsecThread {
int count_test;
/* For individual thread reference.*/
- LineartRenderBuffer *rb;
+ LineartData *ld;
} LineartIsecThread;
typedef struct LineartIsecData {
- LineartRenderBuffer *rb;
+ LineartData *ld;
LineartIsecThread *threads;
int thread_count;
} LineartIsecData;
-static LineartBoundingArea *lineart_edge_first_bounding_area(LineartRenderBuffer *rb,
- LineartEdge *e);
+static LineartBoundingArea *lineart_edge_first_bounding_area(LineartData *ld, LineartEdge *e);
-static void lineart_bounding_area_link_edge(LineartRenderBuffer *rb,
+static void lineart_bounding_area_link_edge(LineartData *ld,
LineartBoundingArea *root_ba,
LineartEdge *e);
@@ -99,12 +94,8 @@ static LineartBoundingArea *lineart_bounding_area_next(LineartBoundingArea *this
double *next_x,
double *next_y);
-static bool lineart_get_edge_bounding_areas(LineartRenderBuffer *rb,
- LineartEdge *e,
- int *rowbegin,
- int *rowend,
- int *colbegin,
- int *colend);
+static bool lineart_get_edge_bounding_areas(
+ LineartData *ld, LineartEdge *e, int *rowbegin, int *rowend, int *colbegin, int *colend);
static bool lineart_triangle_edge_image_space_occlusion(SpinLock *spl,
const LineartTriangle *tri,
@@ -121,7 +112,7 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *spl,
static void lineart_add_edge_to_array(LineartPendingEdges *pe, LineartEdge *e);
-static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb,
+static void lineart_bounding_area_link_triangle(LineartData *ld,
LineartBoundingArea *root_ba,
LineartTriangle *tri,
double *LRUB,
@@ -132,54 +123,54 @@ static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb,
static void lineart_free_bounding_area_memory(LineartBoundingArea *ba, bool recursive);
-static void lineart_free_bounding_area_memories(LineartRenderBuffer *rb);
+static void lineart_free_bounding_area_memories(LineartData *ld);
static LineartCache *lineart_init_cache(void);
-static void lineart_discard_segment(LineartRenderBuffer *rb, LineartEdgeSegment *es)
+static void lineart_discard_segment(LineartData *ld, LineartEdgeSegment *es)
{
- BLI_spin_lock(&rb->lock_cuts);
+ BLI_spin_lock(&ld->lock_cuts);
memset(es, 0, sizeof(LineartEdgeSegment));
/* Storing the node for potentially reuse the memory for new segment data.
* Line Art data is not freed after all calculations are done. */
- BLI_addtail(&rb->wasted_cuts, es);
+ BLI_addtail(&ld->wasted_cuts, es);
- BLI_spin_unlock(&rb->lock_cuts);
+ BLI_spin_unlock(&ld->lock_cuts);
}
-static LineartEdgeSegment *lineart_give_segment(LineartRenderBuffer *rb)
+static LineartEdgeSegment *lineart_give_segment(LineartData *ld)
{
- BLI_spin_lock(&rb->lock_cuts);
+ BLI_spin_lock(&ld->lock_cuts);
/* See if there is any already allocated memory we can reuse. */
- if (rb->wasted_cuts.first) {
- LineartEdgeSegment *es = (LineartEdgeSegment *)BLI_pophead(&rb->wasted_cuts);
- BLI_spin_unlock(&rb->lock_cuts);
+ if (ld->wasted_cuts.first) {
+ LineartEdgeSegment *es = (LineartEdgeSegment *)BLI_pophead(&ld->wasted_cuts);
+ BLI_spin_unlock(&ld->lock_cuts);
memset(es, 0, sizeof(LineartEdgeSegment));
return es;
}
- BLI_spin_unlock(&rb->lock_cuts);
+ BLI_spin_unlock(&ld->lock_cuts);
/* Otherwise allocate some new memory. */
- return (LineartEdgeSegment *)lineart_mem_acquire_thread(&rb->render_data_pool,
+ return (LineartEdgeSegment *)lineart_mem_acquire_thread(&ld->render_data_pool,
sizeof(LineartEdgeSegment));
}
/**
* Cuts the edge in image space and mark occlusion level for each segment.
*/
-static void lineart_edge_cut(LineartRenderBuffer *rb,
+static void lineart_edge_cut(LineartData *ld,
LineartEdge *e,
double start,
double end,
uchar material_mask_bits,
uchar mat_occlusion)
{
- LineartEdgeSegment *es, *ies, *next_es, *prev_es;
+ LineartEdgeSegment *seg, *i_seg, *next_seg, *prev_seg;
LineartEdgeSegment *cut_start_before = 0, *cut_end_before = 0;
- LineartEdgeSegment *ns = 0, *ns2 = 0;
+ LineartEdgeSegment *new_seg1 = 0, *new_seg2 = 0;
int untouched = 0;
/* If for some reason the occlusion function may give a result that has zero length, or reversed
@@ -206,132 +197,136 @@ static void lineart_edge_cut(LineartRenderBuffer *rb,
/* Begin looking for starting position of the segment. */
/* Not using a list iteration macro because of it more clear when using for loops to iterate
* through the segments. */
- for (es = e->segments.first; es; es = es->next) {
- if (LRT_DOUBLE_CLOSE_ENOUGH(es->at, start)) {
- cut_start_before = es;
- ns = cut_start_before;
+ for (seg = e->segments.first; seg; seg = seg->next) {
+ if (LRT_DOUBLE_CLOSE_ENOUGH(seg->at, start)) {
+ cut_start_before = seg;
+ new_seg1 = cut_start_before;
break;
}
- if (es->next == NULL) {
+ if (seg->next == NULL) {
break;
}
- ies = es->next;
- if (ies->at > start + 1e-09 && start > es->at) {
- cut_start_before = ies;
- ns = lineart_give_segment(rb);
+ i_seg = seg->next;
+ if (i_seg->at > start + 1e-09 && start > seg->at) {
+ cut_start_before = i_seg;
+ new_seg1 = lineart_give_segment(ld);
break;
}
}
if (!cut_start_before && LRT_DOUBLE_CLOSE_ENOUGH(1, end)) {
untouched = 1;
}
- for (es = cut_start_before; es; es = es->next) {
+ for (seg = cut_start_before; seg; seg = seg->next) {
/* We tried to cut at existing cutting point (e.g. where the line's occluded by a triangle
* strip). */
- if (LRT_DOUBLE_CLOSE_ENOUGH(es->at, end)) {
- cut_end_before = es;
- ns2 = cut_end_before;
+ if (LRT_DOUBLE_CLOSE_ENOUGH(seg->at, end)) {
+ cut_end_before = seg;
+ new_seg2 = cut_end_before;
break;
}
/* This check is to prevent `es->at == 1.0` (where we don't need to cut because we are at the
* end point). */
- if (!es->next && LRT_DOUBLE_CLOSE_ENOUGH(1, end)) {
- cut_end_before = es;
- ns2 = cut_end_before;
+ if (!seg->next && LRT_DOUBLE_CLOSE_ENOUGH(1, end)) {
+ cut_end_before = seg;
+ new_seg2 = cut_end_before;
untouched = 1;
break;
}
/* When an actual cut is needed in the line. */
- if (es->at > end) {
- cut_end_before = es;
- ns2 = lineart_give_segment(rb);
+ if (seg->at > end) {
+ cut_end_before = seg;
+ new_seg2 = lineart_give_segment(ld);
break;
}
}
/* When we still can't find any existing cut in the line, we allocate new ones. */
- if (ns == NULL) {
- ns = lineart_give_segment(rb);
+ if (new_seg1 == NULL) {
+ new_seg1 = lineart_give_segment(ld);
}
- if (ns2 == NULL) {
+ if (new_seg2 == NULL) {
if (untouched) {
- ns2 = ns;
- cut_end_before = ns2;
+ new_seg2 = new_seg1;
+ cut_end_before = new_seg2;
}
else {
- ns2 = lineart_give_segment(rb);
+ new_seg2 = lineart_give_segment(ld);
}
}
if (cut_start_before) {
- if (cut_start_before != ns) {
+ if (cut_start_before != new_seg1) {
/* Insert cutting points for when a new cut is needed. */
- ies = cut_start_before->prev ? cut_start_before->prev : NULL;
- ns->occlusion = ies ? ies->occlusion : 0;
- ns->material_mask_bits = ies->material_mask_bits;
- BLI_insertlinkbefore(&e->segments, cut_start_before, ns);
+ i_seg = cut_start_before->prev ? cut_start_before->prev : NULL;
+ if (i_seg) {
+ new_seg1->occlusion = i_seg->occlusion;
+ new_seg1->material_mask_bits = i_seg->material_mask_bits;
+ }
+ BLI_insertlinkbefore(&e->segments, cut_start_before, new_seg1);
}
/* Otherwise we already found a existing cutting point, no need to insert a new one. */
}
else {
/* We have yet to reach a existing cutting point even after we searched the whole line, so we
* append the new cut to the end. */
- ies = e->segments.last;
- ns->occlusion = ies->occlusion;
- ns->material_mask_bits = ies->material_mask_bits;
- BLI_addtail(&e->segments, ns);
+ i_seg = e->segments.last;
+ new_seg1->occlusion = i_seg->occlusion;
+ new_seg1->material_mask_bits = i_seg->material_mask_bits;
+ BLI_addtail(&e->segments, new_seg1);
}
if (cut_end_before) {
/* The same manipulation as on "cut_start_before". */
- if (cut_end_before != ns2) {
- ies = cut_end_before->prev ? cut_end_before->prev : NULL;
- ns2->occlusion = ies ? ies->occlusion : 0;
- ns2->material_mask_bits = ies ? ies->material_mask_bits : 0;
- BLI_insertlinkbefore(&e->segments, cut_end_before, ns2);
+ if (cut_end_before != new_seg2) {
+ i_seg = cut_end_before->prev ? cut_end_before->prev : NULL;
+ if (i_seg) {
+ new_seg2->occlusion = i_seg->occlusion;
+ new_seg2->material_mask_bits = i_seg->material_mask_bits;
+ }
+ BLI_insertlinkbefore(&e->segments, cut_end_before, new_seg2);
}
}
else {
- ies = e->segments.last;
- ns2->occlusion = ies->occlusion;
- ns2->material_mask_bits = ies->material_mask_bits;
- BLI_addtail(&e->segments, ns2);
+ i_seg = e->segments.last;
+ new_seg2->occlusion = i_seg->occlusion;
+ new_seg2->material_mask_bits = i_seg->material_mask_bits;
+ BLI_addtail(&e->segments, new_seg2);
}
/* If we touched the cut list, we assign the new cut position based on new cut position,
* this way we accommodate precision lost due to multiple cut inserts. */
- ns->at = start;
+ new_seg1->at = start;
if (!untouched) {
- ns2->at = end;
+ new_seg2->at = end;
}
else {
/* For the convenience of the loop below. */
- ns2 = ns2->next;
+ new_seg2 = new_seg2->next;
}
/* Register 1 level of occlusion for all touched segments. */
- for (es = ns; es && es != ns2; es = es->next) {
- es->occlusion += mat_occlusion;
- es->material_mask_bits |= material_mask_bits;
+ for (seg = new_seg1; seg && seg != new_seg2; seg = seg->next) {
+ seg->occlusion += mat_occlusion;
+ seg->material_mask_bits |= material_mask_bits;
}
/* Reduce adjacent cutting points of the same level, which saves memory. */
- char min_occ = 127;
- prev_es = NULL;
- for (es = e->segments.first; es; es = next_es) {
- next_es = es->next;
-
- if (prev_es && prev_es->occlusion == es->occlusion &&
- prev_es->material_mask_bits == es->material_mask_bits) {
- BLI_remlink(&e->segments, es);
+ int8_t min_occ = 127;
+ prev_seg = NULL;
+ for (seg = e->segments.first; seg; seg = next_seg) {
+ next_seg = seg->next;
+
+ if (prev_seg && prev_seg->occlusion == seg->occlusion &&
+ prev_seg->material_mask_bits == seg->material_mask_bits) {
+ BLI_remlink(&e->segments, seg);
/* This puts the node back to the render buffer, if more cut happens, these unused nodes get
* picked first. */
- lineart_discard_segment(rb, es);
+ lineart_discard_segment(ld, seg);
continue;
}
- min_occ = MIN2(min_occ, es->occlusion);
+ min_occ = MIN2(min_occ, seg->occlusion);
- prev_es = es;
+ prev_seg = seg;
}
e->min_occ = min_occ;
}
@@ -374,10 +369,10 @@ static void lineart_bounding_area_line_add(LineartBoundingArea *ba, LineartEdge
ba->line_count++;
}
-static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge *e, int thread_id)
+static void lineart_occlusion_single_line(LineartData *ld, LineartEdge *e, int thread_id)
{
double x = e->v1->fbcoord[0], y = e->v1->fbcoord[1];
- LineartBoundingArea *ba = lineart_edge_first_bounding_area(rb, e);
+ LineartBoundingArea *ba = lineart_edge_first_bounding_area(ld, e);
LineartBoundingArea *nba = ba;
LineartTriangleThread *tri;
@@ -406,20 +401,20 @@ static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge *
continue;
}
tri->testing_e[thread_id] = e;
- if (lineart_triangle_edge_image_space_occlusion(&rb->lock_task,
+ if (lineart_triangle_edge_image_space_occlusion(&ld->lock_task,
(const LineartTriangle *)tri,
e,
- rb->camera_pos,
- rb->cam_is_persp,
- rb->allow_overlapping_edges,
- rb->view_projection,
- rb->view_vector,
- rb->shift_x,
- rb->shift_y,
+ ld->conf.camera_pos,
+ ld->conf.cam_is_persp,
+ ld->conf.allow_overlapping_edges,
+ ld->conf.view_projection,
+ ld->conf.view_vector,
+ ld->conf.shift_x,
+ ld->conf.shift_y,
&l,
&r)) {
- lineart_edge_cut(rb, e, l, r, tri->base.material_mask_bits, tri->base.mat_occlusion);
- if (e->min_occ > rb->max_occlusion_level) {
+ lineart_edge_cut(ld, e, l, r, tri->base.material_mask_bits, tri->base.mat_occlusion);
+ if (e->min_occ > ld->conf.max_occlusion_level) {
/* No need to calculate any longer on this line because no level more than set value is
* going to show up in the rendered result. */
return;
@@ -431,24 +426,24 @@ static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge *
}
}
-static int lineart_occlusion_make_task_info(LineartRenderBuffer *rb, LineartRenderTaskInfo *rti)
+static int lineart_occlusion_make_task_info(LineartData *ld, LineartRenderTaskInfo *rti)
{
int res = 0;
int starting_index;
- BLI_spin_lock(&rb->lock_task);
+ BLI_spin_lock(&ld->lock_task);
- starting_index = rb->scheduled_count;
- rb->scheduled_count += LRT_THREAD_EDGE_COUNT;
+ starting_index = ld->scheduled_count;
+ ld->scheduled_count += LRT_THREAD_EDGE_COUNT;
- BLI_spin_unlock(&rb->lock_task);
+ BLI_spin_unlock(&ld->lock_task);
- if (starting_index >= rb->pending_edges.next) {
+ if (starting_index >= ld->pending_edges.next) {
res = 0;
}
else {
- rti->pending_edges.array = &rb->pending_edges.array[starting_index];
- int remaining = rb->pending_edges.next - starting_index;
+ rti->pending_edges.array = &ld->pending_edges.array[starting_index];
+ int remaining = ld->pending_edges.next - starting_index;
rti->pending_edges.max = MIN2(remaining, LRT_THREAD_EDGE_COUNT);
res = 1;
}
@@ -458,13 +453,13 @@ static int lineart_occlusion_make_task_info(LineartRenderBuffer *rb, LineartRend
static void lineart_occlusion_worker(TaskPool *__restrict UNUSED(pool), LineartRenderTaskInfo *rti)
{
- LineartRenderBuffer *rb = rti->rb;
+ LineartData *ld = rti->ld;
LineartEdge *eip;
- while (lineart_occlusion_make_task_info(rb, rti)) {
+ while (lineart_occlusion_make_task_info(ld, rti)) {
for (int i = 0; i < rti->pending_edges.max; i++) {
eip = rti->pending_edges.array[i];
- lineart_occlusion_single_line(rb, eip, rti->thread_id);
+ lineart_occlusion_single_line(ld, eip, rti->thread_id);
}
}
}
@@ -474,9 +469,9 @@ static void lineart_occlusion_worker(TaskPool *__restrict UNUSED(pool), LineartR
* #MOD_lineart_compute_feature_lines function.
* This function handles all occlusion calculation.
*/
-static void lineart_main_occlusion_begin(LineartRenderBuffer *rb)
+static void lineart_main_occlusion_begin(LineartData *ld)
{
- int thread_count = rb->thread_count;
+ int thread_count = ld->thread_count;
LineartRenderTaskInfo *rti = MEM_callocN(sizeof(LineartRenderTaskInfo) * thread_count,
"Task Pool");
int i;
@@ -485,7 +480,7 @@ static void lineart_main_occlusion_begin(LineartRenderBuffer *rb)
for (i = 0; i < thread_count; i++) {
rti[i].thread_id = i;
- rti[i].rb = rb;
+ rti[i].ld = ld;
BLI_task_pool_push(tp, (TaskRunFunction)lineart_occlusion_worker, &rti[i], 0, NULL);
}
BLI_task_pool_work_and_wait(tp);
@@ -575,6 +570,12 @@ static int lineart_point_on_line_segment(double v[2], double v0[2], double v1[2]
return 0;
}
+enum LineartPointTri {
+ LRT_OUTSIDE_TRIANGLE = 0,
+ LRT_ON_TRIANGLE = 1,
+ LRT_INSIDE_TRIANGLE = 2,
+};
+
/**
* Same algorithm as lineart_point_inside_triangle(), but returns differently:
* 0-outside 1-on the edge 2-inside.
@@ -585,7 +586,7 @@ static int lineart_point_triangle_relation(double v[2], double v0[2], double v1[
double r;
if (lineart_point_on_line_segment(v, v0, v1) || lineart_point_on_line_segment(v, v1, v2) ||
lineart_point_on_line_segment(v, v2, v0)) {
- return 1;
+ return LRT_ON_TRIANGLE;
}
cl = (v0[0] - v[0]) * (v1[1] - v[1]) - (v0[1] - v[1]) * (v1[0] - v[0]);
@@ -593,28 +594,28 @@ static int lineart_point_triangle_relation(double v[2], double v0[2], double v1[
cl = (v1[0] - v[0]) * (v2[1] - v[1]) - (v1[1] - v[1]) * (v2[0] - v[0]);
if ((r = c * cl) < 0) {
- return 0;
+ return LRT_OUTSIDE_TRIANGLE;
}
c = cl;
cl = (v2[0] - v[0]) * (v0[1] - v[1]) - (v2[1] - v[1]) * (v0[0] - v[0]);
if ((r = c * cl) < 0) {
- return 0;
+ return LRT_OUTSIDE_TRIANGLE;
}
c = cl;
cl = (v0[0] - v[0]) * (v1[1] - v[1]) - (v0[1] - v[1]) * (v1[0] - v[0]);
if ((r = c * cl) < 0) {
- return 0;
+ return LRT_OUTSIDE_TRIANGLE;
}
if (r == 0) {
- return 1;
+ return LRT_ON_TRIANGLE;
}
- return 2;
+ return LRT_INSIDE_TRIANGLE;
}
/**
@@ -662,17 +663,17 @@ static bool lineart_point_inside_triangle3d(double v[3], double v0[3], double v1
* The following `lineart_memory_get_XXX_space` functions are for allocating new memory for some
* modified geometries in the culling stage.
*/
-static LineartElementLinkNode *lineart_memory_get_triangle_space(LineartRenderBuffer *rb)
+static LineartElementLinkNode *lineart_memory_get_triangle_space(LineartData *ld)
{
LineartElementLinkNode *eln;
/* We don't need to allocate a whole bunch of triangles because the amount of clipped triangles
* are relatively small. */
- LineartTriangle *render_triangles = lineart_mem_acquire(&rb->render_data_pool,
- 64 * rb->triangle_size);
+ LineartTriangle *render_triangles = lineart_mem_acquire(&ld->render_data_pool,
+ 64 * ld->sizeof_triangle);
- eln = lineart_list_append_pointer_pool_sized(&rb->triangle_buffer_pointers,
- &rb->render_data_pool,
+ eln = lineart_list_append_pointer_pool_sized(&ld->geom.triangle_buffer_pointers,
+ &ld->render_data_pool,
render_triangles,
sizeof(LineartElementLinkNode));
eln->element_count = 64;
@@ -681,15 +682,15 @@ static LineartElementLinkNode *lineart_memory_get_triangle_space(LineartRenderBu
return eln;
}
-static LineartElementLinkNode *lineart_memory_get_vert_space(LineartRenderBuffer *rb)
+static LineartElementLinkNode *lineart_memory_get_vert_space(LineartData *ld)
{
LineartElementLinkNode *eln;
- LineartVert *render_vertices = lineart_mem_acquire(&rb->render_data_pool,
+ LineartVert *render_vertices = lineart_mem_acquire(&ld->render_data_pool,
sizeof(LineartVert) * 64);
- eln = lineart_list_append_pointer_pool_sized(&rb->vertex_buffer_pointers,
- &rb->render_data_pool,
+ eln = lineart_list_append_pointer_pool_sized(&ld->geom.vertex_buffer_pointers,
+ &ld->render_data_pool,
render_vertices,
sizeof(LineartElementLinkNode));
eln->element_count = 64;
@@ -698,18 +699,18 @@ static LineartElementLinkNode *lineart_memory_get_vert_space(LineartRenderBuffer
return eln;
}
-static LineartElementLinkNode *lineart_memory_get_edge_space(LineartRenderBuffer *rb)
+static LineartElementLinkNode *lineart_memory_get_edge_space(LineartData *ld)
{
LineartElementLinkNode *eln;
- LineartEdge *render_edges = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdge) * 64);
+ LineartEdge *render_edges = lineart_mem_acquire(&ld->render_data_pool, sizeof(LineartEdge) * 64);
- eln = lineart_list_append_pointer_pool_sized(&rb->line_buffer_pointers,
- &rb->render_data_pool,
+ eln = lineart_list_append_pointer_pool_sized(&ld->geom.line_buffer_pointers,
+ &ld->render_data_pool,
render_edges,
sizeof(LineartElementLinkNode));
eln->element_count = 64;
- eln->crease_threshold = rb->crease_threshold;
+ eln->crease_threshold = ld->conf.crease_threshold;
eln->flags |= LRT_ELEMENT_IS_ADDITIONAL;
return eln;
@@ -751,7 +752,7 @@ static void lineart_discard_duplicated_edges(LineartEdge *old_e)
* Does near-plane cut on 1 triangle only. When cutting with far-plane, the camera vectors gets
* reversed by the caller so don't need to implement one in a different direction.
*/
-static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
+static void lineart_triangle_cull_single(LineartData *ld,
LineartTriangle *tri,
int in0,
int in1,
@@ -768,7 +769,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
LineartElementLinkNode *e_eln,
LineartElementLinkNode *t_eln)
{
- double vv1[3], vv2[3], dot1, dot2;
+ double span_v1[3], span_v2[3], dot_v1, dot_v2;
double a;
int v_count = *r_v_count;
int e_count = *r_e_count;
@@ -777,7 +778,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
LineartEdge *new_e, *e, *old_e;
LineartEdgeSegment *es;
- LineartTriangleAdjacent *ta;
+ LineartTriangleAdjacent *tri_adj;
if (tri->flags & (LRT_CULL_USED | LRT_CULL_GENERATED | LRT_CULL_DISCARD)) {
return;
@@ -785,11 +786,12 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
/* See definition of tri->intersecting_verts and the usage in
* lineart_geometry_object_load() for details. */
- ta = (void *)tri->intersecting_verts;
+ tri_adj = (void *)tri->intersecting_verts;
LineartVert *vt = &((LineartVert *)v_eln->pointer)[v_count];
- LineartTriangle *tri1 = (void *)(((uchar *)t_eln->pointer) + rb->triangle_size * t_count);
- LineartTriangle *tri2 = (void *)(((uchar *)t_eln->pointer) + rb->triangle_size * (t_count + 1));
+ LineartTriangle *tri1 = (void *)(((uchar *)t_eln->pointer) + ld->sizeof_triangle * t_count);
+ LineartTriangle *tri2 = (void *)(((uchar *)t_eln->pointer) +
+ ld->sizeof_triangle * (t_count + 1));
new_e = &((LineartEdge *)e_eln->pointer)[e_count];
/* Init `edge` to the last `edge` entry. */
@@ -799,12 +801,12 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
new_e = &((LineartEdge *)e_eln->pointer)[e_count]; \
e_count++; \
e = new_e; \
- es = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdgeSegment)); \
+ es = lineart_mem_acquire(&ld->render_data_pool, sizeof(LineartEdgeSegment)); \
BLI_addtail(&e->segments, es);
#define SELECT_EDGE(e_num, v1_link, v2_link, new_tri) \
- if (ta->e[e_num]) { \
- old_e = ta->e[e_num]; \
+ if (tri_adj->e[e_num]) { \
+ old_e = tri_adj->e[e_num]; \
new_flag = old_e->flags; \
old_e->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
lineart_discard_duplicated_edges(old_e); \
@@ -817,28 +819,28 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
e->object_ref = ob; \
e->t1 = ((old_e->t1 == tri) ? (new_tri) : (old_e->t1)); \
e->t2 = ((old_e->t2 == tri) ? (new_tri) : (old_e->t2)); \
- lineart_add_edge_to_array(&rb->pending_edges, e); \
+ lineart_add_edge_to_array(&ld->pending_edges, e); \
}
#define RELINK_EDGE(e_num, new_tri) \
- if (ta->e[e_num]) { \
- old_e = ta->e[e_num]; \
+ if (tri_adj->e[e_num]) { \
+ old_e = tri_adj->e[e_num]; \
old_e->t1 = ((old_e->t1 == tri) ? (new_tri) : (old_e->t1)); \
old_e->t2 = ((old_e->t2 == tri) ? (new_tri) : (old_e->t2)); \
}
#define REMOVE_TRIANGLE_EDGE \
- if (ta->e[0]) { \
- ta->e[0]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
- lineart_discard_duplicated_edges(ta->e[0]); \
+ if (tri_adj->e[0]) { \
+ tri_adj->e[0]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
+ lineart_discard_duplicated_edges(tri_adj->e[0]); \
} \
- if (ta->e[1]) { \
- ta->e[1]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
- lineart_discard_duplicated_edges(ta->e[1]); \
+ if (tri_adj->e[1]) { \
+ tri_adj->e[1]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
+ lineart_discard_duplicated_edges(tri_adj->e[1]); \
} \
- if (ta->e[2]) { \
- ta->e[2]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
- lineart_discard_duplicated_edges(ta->e[2]); \
+ if (tri_adj->e[2]) { \
+ tri_adj->e[2]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
+ lineart_discard_duplicated_edges(tri_adj->e[2]); \
}
switch (in0 + in1 + in2) {
@@ -878,22 +880,22 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
if (!in0) {
/* Cut point for line 2---|-----0. */
- sub_v3_v3v3_db(vv1, tri->v[0]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, tri->v[2]->gloc);
- dot1 = dot_v3v3_db(vv1, view_dir);
- dot2 = dot_v3v3_db(vv2, view_dir);
- a = dot1 / (dot1 + dot2);
+ sub_v3_v3v3_db(span_v1, tri->v[0]->gloc, cam_pos);
+ sub_v3_v3v3_db(span_v2, cam_pos, tri->v[2]->gloc);
+ dot_v1 = dot_v3v3_db(span_v1, view_dir);
+ dot_v2 = dot_v3v3_db(span_v2, view_dir);
+ a = dot_v1 / (dot_v1 + dot_v2);
/* Assign it to a new point. */
interp_v3_v3v3_db(vt[0].gloc, tri->v[0]->gloc, tri->v[2]->gloc, a);
mul_v4_m4v3_db(vt[0].fbcoord, vp, vt[0].gloc);
vt[0].index = tri->v[2]->index;
/* Cut point for line 1---|-----0. */
- sub_v3_v3v3_db(vv1, tri->v[0]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, tri->v[1]->gloc);
- dot1 = dot_v3v3_db(vv1, view_dir);
- dot2 = dot_v3v3_db(vv2, view_dir);
- a = dot1 / (dot1 + dot2);
+ sub_v3_v3v3_db(span_v1, tri->v[0]->gloc, cam_pos);
+ sub_v3_v3v3_db(span_v2, cam_pos, tri->v[1]->gloc);
+ dot_v1 = dot_v3v3_db(span_v1, view_dir);
+ dot_v2 = dot_v3v3_db(span_v2, view_dir);
+ a = dot_v1 / (dot_v1 + dot_v2);
/* Assign it to another new point. */
interp_v3_v3v3_db(vt[1].gloc, tri->v[0]->gloc, tri->v[1]->gloc, a);
mul_v4_m4v3_db(vt[1].fbcoord, vp, vt[1].gloc);
@@ -903,7 +905,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
INCREASE_EDGE
if (allow_boundaries) {
e->flags = LRT_EDGE_FLAG_CONTOUR;
- lineart_add_edge_to_array(&rb->pending_edges, e);
+ lineart_add_edge_to_array(&ld->pending_edges, e);
}
/* NOTE: inverting `e->v1/v2` (left/right point) doesn't matter as long as
* `tri->edge` and `tri->v` has the same sequence. and the winding direction
@@ -931,20 +933,20 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
t_count += 1;
}
else if (!in2) {
- sub_v3_v3v3_db(vv1, tri->v[2]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, tri->v[0]->gloc);
- dot1 = dot_v3v3_db(vv1, view_dir);
- dot2 = dot_v3v3_db(vv2, view_dir);
- a = dot1 / (dot1 + dot2);
+ sub_v3_v3v3_db(span_v1, tri->v[2]->gloc, cam_pos);
+ sub_v3_v3v3_db(span_v2, cam_pos, tri->v[0]->gloc);
+ dot_v1 = dot_v3v3_db(span_v1, view_dir);
+ dot_v2 = dot_v3v3_db(span_v2, view_dir);
+ a = dot_v1 / (dot_v1 + dot_v2);
interp_v3_v3v3_db(vt[0].gloc, tri->v[2]->gloc, tri->v[0]->gloc, a);
mul_v4_m4v3_db(vt[0].fbcoord, vp, vt[0].gloc);
vt[0].index = tri->v[0]->index;
- sub_v3_v3v3_db(vv1, tri->v[2]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, tri->v[1]->gloc);
- dot1 = dot_v3v3_db(vv1, view_dir);
- dot2 = dot_v3v3_db(vv2, view_dir);
- a = dot1 / (dot1 + dot2);
+ sub_v3_v3v3_db(span_v1, tri->v[2]->gloc, cam_pos);
+ sub_v3_v3v3_db(span_v2, cam_pos, tri->v[1]->gloc);
+ dot_v1 = dot_v3v3_db(span_v1, view_dir);
+ dot_v2 = dot_v3v3_db(span_v2, view_dir);
+ a = dot_v1 / (dot_v1 + dot_v2);
interp_v3_v3v3_db(vt[1].gloc, tri->v[2]->gloc, tri->v[1]->gloc, a);
mul_v4_m4v3_db(vt[1].fbcoord, vp, vt[1].gloc);
vt[1].index = tri->v[1]->index;
@@ -952,7 +954,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
INCREASE_EDGE
if (allow_boundaries) {
e->flags = LRT_EDGE_FLAG_CONTOUR;
- lineart_add_edge_to_array(&rb->pending_edges, e);
+ lineart_add_edge_to_array(&ld->pending_edges, e);
}
e->v1 = &vt[0];
e->v2 = &vt[1];
@@ -972,20 +974,20 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
t_count += 1;
}
else if (!in1) {
- sub_v3_v3v3_db(vv1, tri->v[1]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, tri->v[2]->gloc);
- dot1 = dot_v3v3_db(vv1, view_dir);
- dot2 = dot_v3v3_db(vv2, view_dir);
- a = dot1 / (dot1 + dot2);
+ sub_v3_v3v3_db(span_v1, tri->v[1]->gloc, cam_pos);
+ sub_v3_v3v3_db(span_v2, cam_pos, tri->v[2]->gloc);
+ dot_v1 = dot_v3v3_db(span_v1, view_dir);
+ dot_v2 = dot_v3v3_db(span_v2, view_dir);
+ a = dot_v1 / (dot_v1 + dot_v2);
interp_v3_v3v3_db(vt[0].gloc, tri->v[1]->gloc, tri->v[2]->gloc, a);
mul_v4_m4v3_db(vt[0].fbcoord, vp, vt[0].gloc);
vt[0].index = tri->v[2]->index;
- sub_v3_v3v3_db(vv1, tri->v[1]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, tri->v[0]->gloc);
- dot1 = dot_v3v3_db(vv1, view_dir);
- dot2 = dot_v3v3_db(vv2, view_dir);
- a = dot1 / (dot1 + dot2);
+ sub_v3_v3v3_db(span_v1, tri->v[1]->gloc, cam_pos);
+ sub_v3_v3v3_db(span_v2, cam_pos, tri->v[0]->gloc);
+ dot_v1 = dot_v3v3_db(span_v1, view_dir);
+ dot_v2 = dot_v3v3_db(span_v2, view_dir);
+ a = dot_v1 / (dot_v1 + dot_v2);
interp_v3_v3v3_db(vt[1].gloc, tri->v[1]->gloc, tri->v[0]->gloc, a);
mul_v4_m4v3_db(vt[1].fbcoord, vp, vt[1].gloc);
vt[1].index = tri->v[0]->index;
@@ -993,7 +995,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
INCREASE_EDGE
if (allow_boundaries) {
e->flags = LRT_EDGE_FLAG_CONTOUR;
- lineart_add_edge_to_array(&rb->pending_edges, e);
+ lineart_add_edge_to_array(&ld->pending_edges, e);
}
e->v1 = &vt[1];
e->v2 = &vt[0];
@@ -1043,22 +1045,22 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
*/
if (in0) {
/* Cut point for line 0---|------1. */
- sub_v3_v3v3_db(vv1, tri->v[1]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, tri->v[0]->gloc);
- dot1 = dot_v3v3_db(vv1, view_dir);
- dot2 = dot_v3v3_db(vv2, view_dir);
- a = dot2 / (dot1 + dot2);
+ sub_v3_v3v3_db(span_v1, tri->v[1]->gloc, cam_pos);
+ sub_v3_v3v3_db(span_v2, cam_pos, tri->v[0]->gloc);
+ dot_v1 = dot_v3v3_db(span_v1, view_dir);
+ dot_v2 = dot_v3v3_db(span_v2, view_dir);
+ a = dot_v2 / (dot_v1 + dot_v2);
/* Assign to a new point. */
interp_v3_v3v3_db(vt[0].gloc, tri->v[0]->gloc, tri->v[1]->gloc, a);
mul_v4_m4v3_db(vt[0].fbcoord, vp, vt[0].gloc);
vt[0].index = tri->v[0]->index;
/* Cut point for line 0---|------2. */
- sub_v3_v3v3_db(vv1, tri->v[2]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, tri->v[0]->gloc);
- dot1 = dot_v3v3_db(vv1, view_dir);
- dot2 = dot_v3v3_db(vv2, view_dir);
- a = dot2 / (dot1 + dot2);
+ sub_v3_v3v3_db(span_v1, tri->v[2]->gloc, cam_pos);
+ sub_v3_v3v3_db(span_v2, cam_pos, tri->v[0]->gloc);
+ dot_v1 = dot_v3v3_db(span_v1, view_dir);
+ dot_v2 = dot_v3v3_db(span_v2, view_dir);
+ a = dot_v2 / (dot_v1 + dot_v2);
/* Assign to other new point. */
interp_v3_v3v3_db(vt[1].gloc, tri->v[0]->gloc, tri->v[2]->gloc, a);
mul_v4_m4v3_db(vt[1].fbcoord, vp, vt[1].gloc);
@@ -1068,7 +1070,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
INCREASE_EDGE
if (allow_boundaries) {
e->flags = LRT_EDGE_FLAG_CONTOUR;
- lineart_add_edge_to_array(&rb->pending_edges, e);
+ lineart_add_edge_to_array(&ld->pending_edges, e);
}
e->v1 = &vt[1];
e->v2 = &vt[0];
@@ -1099,20 +1101,20 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
}
else if (in1) {
- sub_v3_v3v3_db(vv1, tri->v[1]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, tri->v[2]->gloc);
- dot1 = dot_v3v3_db(vv1, view_dir);
- dot2 = dot_v3v3_db(vv2, view_dir);
- a = dot1 / (dot1 + dot2);
+ sub_v3_v3v3_db(span_v1, tri->v[1]->gloc, cam_pos);
+ sub_v3_v3v3_db(span_v2, cam_pos, tri->v[2]->gloc);
+ dot_v1 = dot_v3v3_db(span_v1, view_dir);
+ dot_v2 = dot_v3v3_db(span_v2, view_dir);
+ a = dot_v1 / (dot_v1 + dot_v2);
interp_v3_v3v3_db(vt[0].gloc, tri->v[1]->gloc, tri->v[2]->gloc, a);
mul_v4_m4v3_db(vt[0].fbcoord, vp, vt[0].gloc);
vt[0].index = tri->v[1]->index;
- sub_v3_v3v3_db(vv1, tri->v[1]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, tri->v[0]->gloc);
- dot1 = dot_v3v3_db(vv1, view_dir);
- dot2 = dot_v3v3_db(vv2, view_dir);
- a = dot1 / (dot1 + dot2);
+ sub_v3_v3v3_db(span_v1, tri->v[1]->gloc, cam_pos);
+ sub_v3_v3v3_db(span_v2, cam_pos, tri->v[0]->gloc);
+ dot_v1 = dot_v3v3_db(span_v1, view_dir);
+ dot_v2 = dot_v3v3_db(span_v2, view_dir);
+ a = dot_v1 / (dot_v1 + dot_v2);
interp_v3_v3v3_db(vt[1].gloc, tri->v[1]->gloc, tri->v[0]->gloc, a);
mul_v4_m4v3_db(vt[1].fbcoord, vp, vt[1].gloc);
vt[1].index = tri->v[1]->index;
@@ -1120,7 +1122,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
INCREASE_EDGE
if (allow_boundaries) {
e->flags = LRT_EDGE_FLAG_CONTOUR;
- lineart_add_edge_to_array(&rb->pending_edges, e);
+ lineart_add_edge_to_array(&ld->pending_edges, e);
}
e->v1 = &vt[1];
e->v2 = &vt[0];
@@ -1148,20 +1150,20 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
}
else if (in2) {
- sub_v3_v3v3_db(vv1, tri->v[2]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, tri->v[0]->gloc);
- dot1 = dot_v3v3_db(vv1, view_dir);
- dot2 = dot_v3v3_db(vv2, view_dir);
- a = dot1 / (dot1 + dot2);
+ sub_v3_v3v3_db(span_v1, tri->v[2]->gloc, cam_pos);
+ sub_v3_v3v3_db(span_v2, cam_pos, tri->v[0]->gloc);
+ dot_v1 = dot_v3v3_db(span_v1, view_dir);
+ dot_v2 = dot_v3v3_db(span_v2, view_dir);
+ a = dot_v1 / (dot_v1 + dot_v2);
interp_v3_v3v3_db(vt[0].gloc, tri->v[2]->gloc, tri->v[0]->gloc, a);
mul_v4_m4v3_db(vt[0].fbcoord, vp, vt[0].gloc);
vt[0].index = tri->v[2]->index;
- sub_v3_v3v3_db(vv1, tri->v[2]->gloc, cam_pos);
- sub_v3_v3v3_db(vv2, cam_pos, tri->v[1]->gloc);
- dot1 = dot_v3v3_db(vv1, view_dir);
- dot2 = dot_v3v3_db(vv2, view_dir);
- a = dot1 / (dot1 + dot2);
+ sub_v3_v3v3_db(span_v1, tri->v[2]->gloc, cam_pos);
+ sub_v3_v3v3_db(span_v2, cam_pos, tri->v[1]->gloc);
+ dot_v1 = dot_v3v3_db(span_v1, view_dir);
+ dot_v2 = dot_v3v3_db(span_v2, view_dir);
+ a = dot_v1 / (dot_v1 + dot_v2);
interp_v3_v3v3_db(vt[1].gloc, tri->v[2]->gloc, tri->v[1]->gloc, a);
mul_v4_m4v3_db(vt[1].fbcoord, vp, vt[1].gloc);
vt[1].index = tri->v[2]->index;
@@ -1169,7 +1171,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
INCREASE_EDGE
if (allow_boundaries) {
e->flags = LRT_EDGE_FLAG_CONTOUR;
- lineart_add_edge_to_array(&rb->pending_edges, e);
+ lineart_add_edge_to_array(&ld->pending_edges, e);
}
e->v1 = &vt[1];
e->v2 = &vt[0];
@@ -1213,22 +1215,22 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
* new topology that represents the trimmed triangle. (which then became a triangle or a square
* formed by two triangles)
*/
-static void lineart_main_cull_triangles(LineartRenderBuffer *rb, bool clip_far)
+static void lineart_main_cull_triangles(LineartData *ld, bool clip_far)
{
LineartTriangle *tri;
LineartElementLinkNode *v_eln, *t_eln, *e_eln;
- double(*vp)[4] = rb->view_projection;
+ double(*vp)[4] = ld->conf.view_projection;
int i;
int v_count = 0, t_count = 0, e_count = 0;
Object *ob;
- bool allow_boundaries = rb->allow_boundaries;
+ bool allow_boundaries = ld->conf.allow_boundaries;
double cam_pos[3];
- double clip_start = rb->near_clip, clip_end = rb->far_clip;
+ double clip_start = ld->conf.near_clip, clip_end = ld->conf.far_clip;
double view_dir[3], clip_advance[3];
- copy_v3_v3_db(view_dir, rb->view_vector);
- copy_v3_v3_db(clip_advance, rb->view_vector);
- copy_v3_v3_db(cam_pos, rb->camera_pos);
+ copy_v3_v3_db(view_dir, ld->conf.view_vector);
+ copy_v3_v3_db(clip_advance, ld->conf.view_vector);
+ copy_v3_v3_db(cam_pos, ld->conf.camera_pos);
if (clip_far) {
/* Move starting point to end plane. */
@@ -1244,25 +1246,25 @@ static void lineart_main_cull_triangles(LineartRenderBuffer *rb, bool clip_far)
add_v3_v3_db(cam_pos, clip_advance);
}
- v_eln = lineart_memory_get_vert_space(rb);
- t_eln = lineart_memory_get_triangle_space(rb);
- e_eln = lineart_memory_get_edge_space(rb);
+ v_eln = lineart_memory_get_vert_space(ld);
+ t_eln = lineart_memory_get_triangle_space(ld);
+ e_eln = lineart_memory_get_edge_space(ld);
/* Additional memory space for storing generated points and triangles. */
#define LRT_CULL_ENSURE_MEMORY \
if (v_count > 60) { \
v_eln->element_count = v_count; \
- v_eln = lineart_memory_get_vert_space(rb); \
+ v_eln = lineart_memory_get_vert_space(ld); \
v_count = 0; \
} \
if (t_count > 60) { \
t_eln->element_count = t_count; \
- t_eln = lineart_memory_get_triangle_space(rb); \
+ t_eln = lineart_memory_get_triangle_space(ld); \
t_count = 0; \
} \
if (e_count > 60) { \
e_eln->element_count = e_count; \
- e_eln = lineart_memory_get_edge_space(rb); \
+ e_eln = lineart_memory_get_edge_space(ld); \
e_count = 0; \
}
@@ -1297,21 +1299,21 @@ static void lineart_main_cull_triangles(LineartRenderBuffer *rb, bool clip_far)
int use_w = 3;
int in0 = 0, in1 = 0, in2 = 0;
- if (!rb->cam_is_persp) {
+ if (!ld->conf.cam_is_persp) {
clip_start = -1;
clip_end = 1;
use_w = 2;
}
/* Then go through all the other triangles. */
- LISTBASE_FOREACH (LineartElementLinkNode *, eln, &rb->triangle_buffer_pointers) {
+ LISTBASE_FOREACH (LineartElementLinkNode *, eln, &ld->geom.triangle_buffer_pointers) {
if (eln->flags & LRT_ELEMENT_IS_ADDITIONAL) {
continue;
}
ob = eln->object_ref;
for (i = 0; i < eln->element_count; i++) {
/* Select the triangle in the array. */
- tri = (void *)(((uchar *)eln->pointer) + rb->triangle_size * i);
+ tri = (void *)(((uchar *)eln->pointer) + ld->sizeof_triangle * i);
if (tri->flags & LRT_CULL_DISCARD) {
continue;
@@ -1319,7 +1321,7 @@ static void lineart_main_cull_triangles(LineartRenderBuffer *rb, bool clip_far)
LRT_CULL_DECIDE_INSIDE
LRT_CULL_ENSURE_MEMORY
- lineart_triangle_cull_single(rb,
+ lineart_triangle_cull_single(ld,
tri,
in0,
in1,
@@ -1348,33 +1350,33 @@ static void lineart_main_cull_triangles(LineartRenderBuffer *rb, bool clip_far)
* Adjacent data is only used during the initial stages of computing.
* So we can free it using this function when it is not needed anymore.
*/
-static void lineart_main_free_adjacent_data(LineartRenderBuffer *rb)
+static void lineart_main_free_adjacent_data(LineartData *ld)
{
- LinkData *ld;
- while ((ld = BLI_pophead(&rb->triangle_adjacent_pointers)) != NULL) {
- MEM_freeN(ld->data);
+ LinkData *link;
+ while ((link = BLI_pophead(&ld->geom.triangle_adjacent_pointers)) != NULL) {
+ MEM_freeN(link->data);
}
- LISTBASE_FOREACH (LineartElementLinkNode *, eln, &rb->triangle_buffer_pointers) {
+ LISTBASE_FOREACH (LineartElementLinkNode *, eln, &ld->geom.triangle_buffer_pointers) {
LineartTriangle *tri = eln->pointer;
int i;
for (i = 0; i < eln->element_count; i++) {
/* See definition of tri->intersecting_verts and the usage in
* lineart_geometry_object_load() for detailed. */
tri->intersecting_verts = NULL;
- tri = (LineartTriangle *)(((uchar *)tri) + rb->triangle_size);
+ tri = (LineartTriangle *)(((uchar *)tri) + ld->sizeof_triangle);
}
}
}
-static void lineart_main_perspective_division(LineartRenderBuffer *rb)
+static void lineart_main_perspective_division(LineartData *ld)
{
LineartVert *vt;
int i;
- LISTBASE_FOREACH (LineartElementLinkNode *, eln, &rb->vertex_buffer_pointers) {
+ LISTBASE_FOREACH (LineartElementLinkNode *, eln, &ld->geom.vertex_buffer_pointers) {
vt = eln->pointer;
for (i = 0; i < eln->element_count; i++) {
- if (rb->cam_is_persp) {
+ if (ld->conf.cam_is_persp) {
/* Do not divide Z, we use Z to back transform cut points in later chaining process. */
vt[i].fbcoord[0] /= vt[i].fbcoord[3];
vt[i].fbcoord[1] /= vt[i].fbcoord[3];
@@ -1385,13 +1387,13 @@ static void lineart_main_perspective_division(LineartRenderBuffer *rb)
// `vt[i].fbcoord[2] = -2 * vt[i].fbcoord[2] / (far - near) - (far + near) / (far - near);
}
/* Shifting is always needed. */
- vt[i].fbcoord[0] -= rb->shift_x * 2;
- vt[i].fbcoord[1] -= rb->shift_y * 2;
+ vt[i].fbcoord[0] -= ld->conf.shift_x * 2;
+ vt[i].fbcoord[1] -= ld->conf.shift_y * 2;
}
}
}
-static void lineart_main_discard_out_of_frame_edges(LineartRenderBuffer *rb)
+static void lineart_main_discard_out_of_frame_edges(LineartData *ld)
{
LineartEdge *e;
int i;
@@ -1399,7 +1401,7 @@ static void lineart_main_discard_out_of_frame_edges(LineartRenderBuffer *rb)
#define LRT_VERT_OUT_OF_BOUND(v) \
(v && (v->fbcoord[0] < -1 || v->fbcoord[0] > 1 || v->fbcoord[1] < -1 || v->fbcoord[1] > 1))
- LISTBASE_FOREACH (LineartElementLinkNode *, eln, &rb->line_buffer_pointers) {
+ LISTBASE_FOREACH (LineartElementLinkNode *, eln, &ld->geom.line_buffer_pointers) {
e = (LineartEdge *)eln->pointer;
for (i = 0; i < eln->element_count; i++) {
if ((LRT_VERT_OUT_OF_BOUND(e[i].v1) && LRT_VERT_OUT_OF_BOUND(e[i].v2))) {
@@ -1436,14 +1438,22 @@ static void lineart_mvert_transform_task(void *__restrict userdata,
v->index = i;
}
-#define LRT_EDGE_FLAG_TYPE_MAX_BITS 6
+static const int LRT_MESH_EDGE_TYPES[] = {
+ LRT_EDGE_FLAG_EDGE_MARK,
+ LRT_EDGE_FLAG_CONTOUR,
+ LRT_EDGE_FLAG_CREASE,
+ LRT_EDGE_FLAG_MATERIAL,
+ LRT_EDGE_FLAG_LOOSE,
+};
+
+#define LRT_MESH_EDGE_TYPES_COUNT 5
-static int lineart_edge_type_duplication_count(char eflag)
+static int lineart_edge_type_duplication_count(int eflag)
{
int count = 0;
/* See eLineartEdgeFlag for details. */
- for (int i = 0; i < LRT_EDGE_FLAG_TYPE_MAX_BITS; i++) {
- if (eflag & (1 << i)) {
+ for (int i = 0; i < LRT_MESH_EDGE_TYPES_COUNT; i++) {
+ if (eflag & LRT_MESH_EDGE_TYPES[i]) {
count++;
}
}
@@ -1454,17 +1464,17 @@ static int lineart_edge_type_duplication_count(char eflag)
* Because we have a variable size for #LineartTriangle, we need an access helper.
* See #LineartTriangleThread for more info.
*/
-static LineartTriangle *lineart_triangle_from_index(LineartRenderBuffer *rb,
+static LineartTriangle *lineart_triangle_from_index(LineartData *ld,
LineartTriangle *rt_array,
int index)
{
- char *b = (char *)rt_array;
- b += (index * rb->triangle_size);
+ int8_t *b = (int8_t *)rt_array;
+ b += (index * ld->sizeof_triangle);
return (LineartTriangle *)b;
}
typedef struct EdgeFeatData {
- LineartRenderBuffer *rb;
+ LineartData *ld;
Mesh *me;
const MLoopTri *mlooptri;
LineartTriangle *tri_array;
@@ -1510,7 +1520,8 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
}
bool face_mark_filtered = false;
- bool enable_face_mark = (e_feat_data->use_freestyle_face && e_feat_data->rb->filter_face_mark);
+ bool enable_face_mark = (e_feat_data->use_freestyle_face &&
+ e_feat_data->ld->conf.filter_face_mark);
bool only_contour = false;
if (enable_face_mark) {
FreestyleFace *ff1, *ff2;
@@ -1527,7 +1538,8 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
* path is simper when it's assuming both ff1 and ff2 not NULL. */
ff2 = ff1;
}
- if (e_feat_data->rb->filter_face_mark_boundaries ^ e_feat_data->rb->filter_face_mark_invert) {
+ if (e_feat_data->ld->conf.filter_face_mark_boundaries ^
+ e_feat_data->ld->conf.filter_face_mark_invert) {
if ((ff1->flag & FREESTYLE_FACE_MARK) || (ff2->flag & FREESTYLE_FACE_MARK)) {
face_mark_filtered = true;
}
@@ -1537,12 +1549,12 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
face_mark_filtered = true;
}
}
- if (e_feat_data->rb->filter_face_mark_invert) {
+ if (e_feat_data->ld->conf.filter_face_mark_invert) {
face_mark_filtered = !face_mark_filtered;
}
if (!face_mark_filtered) {
edge_nabr[i].flags = LRT_EDGE_FLAG_INHIBIT;
- if (e_feat_data->rb->filter_face_mark_keep_contour) {
+ if (e_feat_data->ld->conf.filter_face_mark_keep_contour) {
only_contour = true;
}
}
@@ -1561,50 +1573,50 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
LineartTriangle *tri1, *tri2;
LineartVert *vert;
- LineartRenderBuffer *rb = e_feat_data->rb;
+ LineartData *ld = e_feat_data->ld;
int f1 = i / 3, f2 = edge_nabr[i].e / 3;
/* The mesh should already be triangulated now, so we can assume each face is a triangle. */
- tri1 = lineart_triangle_from_index(rb, e_feat_data->tri_array, f1);
- tri2 = lineart_triangle_from_index(rb, e_feat_data->tri_array, f2);
+ tri1 = lineart_triangle_from_index(ld, e_feat_data->tri_array, f1);
+ tri2 = lineart_triangle_from_index(ld, e_feat_data->tri_array, f2);
vert = &e_feat_data->v_array[edge_nabr[i].v1];
double view_vector_persp[3];
double *view_vector = view_vector_persp;
- double dot_1 = 0, dot_2 = 0;
+ double dot_v1 = 0, dot_v2 = 0;
double result;
bool material_back_face = ((tri1->flags | tri2->flags) & LRT_TRIANGLE_MAT_BACK_FACE_CULLING);
- if (rb->use_contour || rb->use_back_face_culling || material_back_face) {
- if (rb->cam_is_persp) {
- sub_v3_v3v3_db(view_vector, rb->camera_pos, vert->gloc);
+ if (ld->conf.use_contour || ld->conf.use_back_face_culling || material_back_face) {
+ if (ld->conf.cam_is_persp) {
+ sub_v3_v3v3_db(view_vector, ld->conf.camera_pos, vert->gloc);
}
else {
- view_vector = rb->view_vector;
+ view_vector = ld->conf.view_vector;
}
- dot_1 = dot_v3v3_db(view_vector, tri1->gn);
- dot_2 = dot_v3v3_db(view_vector, tri2->gn);
+ dot_v1 = dot_v3v3_db(view_vector, tri1->gn);
+ dot_v2 = dot_v3v3_db(view_vector, tri2->gn);
- if ((result = dot_1 * dot_2) <= 0 && (dot_1 + dot_2)) {
+ if ((result = dot_v1 * dot_v2) <= 0 && (dot_v1 + dot_v2)) {
edge_flag_result |= LRT_EDGE_FLAG_CONTOUR;
}
- if (rb->use_back_face_culling) {
- if (dot_1 < 0) {
+ if (ld->conf.use_back_face_culling) {
+ if (dot_v1 < 0) {
tri1->flags |= LRT_CULL_DISCARD;
}
- if (dot_2 < 0) {
+ if (dot_v2 < 0) {
tri2->flags |= LRT_CULL_DISCARD;
}
}
if (material_back_face) {
- if (tri1->flags & LRT_TRIANGLE_MAT_BACK_FACE_CULLING && dot_1 < 0) {
+ if (tri1->flags & LRT_TRIANGLE_MAT_BACK_FACE_CULLING && dot_v1 < 0) {
tri1->flags |= LRT_CULL_DISCARD;
}
- if (tri2->flags & LRT_TRIANGLE_MAT_BACK_FACE_CULLING && dot_2 < 0) {
+ if (tri2->flags & LRT_TRIANGLE_MAT_BACK_FACE_CULLING && dot_v2 < 0) {
tri2->flags |= LRT_CULL_DISCARD;
}
}
@@ -1612,9 +1624,9 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
if (!only_contour) {
- if (rb->use_crease) {
+ if (ld->conf.use_crease) {
bool do_crease = true;
- if (!rb->force_crease && !e_feat_data->use_auto_smooth &&
+ if (!ld->conf.force_crease && !e_feat_data->use_auto_smooth &&
(me->mpoly[mlooptri[f1].poly].flag & ME_SMOOTH) &&
(me->mpoly[mlooptri[f2].poly].flag & ME_SMOOTH)) {
do_crease = false;
@@ -1627,7 +1639,7 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
int mat1 = me->mpoly[mlooptri[f1].poly].mat_nr;
int mat2 = me->mpoly[mlooptri[f2].poly].mat_nr;
- if (rb->use_material && mat1 != mat2) {
+ if (ld->conf.use_material && mat1 != mat2) {
edge_flag_result |= LRT_EDGE_FLAG_MATERIAL;
}
}
@@ -1643,11 +1655,11 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
if (real_edges[i % 3] >= 0) {
MEdge *medge = &me->medge[real_edges[i % 3]];
- if (rb->use_crease && rb->sharp_as_crease && (medge->flag & ME_SHARP)) {
+ if (ld->conf.use_crease && ld->conf.sharp_as_crease && (medge->flag & ME_SHARP)) {
edge_flag_result |= LRT_EDGE_FLAG_CREASE;
}
- if (rb->use_edge_marks && e_feat_data->use_freestyle_edge) {
+ if (ld->conf.use_edge_marks && e_feat_data->use_freestyle_edge) {
FreestyleEdge *fe;
int index = e_feat_data->freestyle_edge_index;
fe = &((FreestyleEdge *)me->edata.layers[index].data)[real_edges[i % 3]];
@@ -1663,7 +1675,7 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
/* Only allocate for feature edge (instead of all edges) to save memory.
* If allow duplicated edges, one edge gets added multiple times if it has multiple types.
*/
- reduce_data->feat_edges += e_feat_data->rb->allow_duplicated_types ?
+ reduce_data->feat_edges += e_feat_data->ld->conf.allow_duplicated_types ?
lineart_edge_type_duplication_count(edge_flag_result) :
1;
}
@@ -1789,17 +1801,17 @@ static void lineart_finalize_object_edge_array(LineartPendingEdges *pe, LineartO
}
static void lineart_triangle_adjacent_assign(LineartTriangle *tri,
- LineartTriangleAdjacent *ta,
+ LineartTriangleAdjacent *tri_adj,
LineartEdge *e)
{
if (lineart_edge_match(tri, e, 0, 1)) {
- ta->e[0] = e;
+ tri_adj->e[0] = e;
}
else if (lineart_edge_match(tri, e, 1, 2)) {
- ta->e[1] = e;
+ tri_adj->e[1] = e;
}
else if (lineart_edge_match(tri, e, 2, 0)) {
- ta->e[2] = e;
+ tri_adj->e[2] = e;
}
}
@@ -1885,7 +1897,7 @@ static void lineart_edge_neighbor_init_task(void *__restrict userdata,
adj_e->v1 = mloop[looptri->tri[i % 3]].v;
adj_e->v2 = mloop[looptri->tri[(i + 1) % 3]].v;
if (adj_e->v1 > adj_e->v2) {
- SWAP(unsigned int, adj_e->v1, adj_e->v2);
+ SWAP(uint32_t, adj_e->v1, adj_e->v2);
}
edge_nabr->e = -1;
@@ -1931,7 +1943,7 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge
return edge_nabr;
}
-static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRenderBuffer *re_buf)
+static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartData *la_data)
{
LineartElementLinkNode *elem_link_node;
LineartVert *la_v_arr;
@@ -1965,19 +1977,20 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend
/* If we allow duplicated edges, one edge should get added multiple times if is has been
* classified as more than one edge type. This is so we can create multiple different line type
* chains containing the same edge. */
- la_v_arr = lineart_mem_acquire_thread(&re_buf->render_data_pool,
+ la_v_arr = lineart_mem_acquire_thread(&la_data->render_data_pool,
sizeof(LineartVert) * me->totvert);
- la_tri_arr = lineart_mem_acquire_thread(&re_buf->render_data_pool,
- tot_tri * re_buf->triangle_size);
+ la_tri_arr = lineart_mem_acquire_thread(&la_data->render_data_pool,
+ tot_tri * la_data->sizeof_triangle);
Object *orig_ob = ob_info->original_ob;
- BLI_spin_lock(&re_buf->lock_task);
- elem_link_node = lineart_list_append_pointer_pool_sized_thread(&re_buf->vertex_buffer_pointers,
- &re_buf->render_data_pool,
- la_v_arr,
- sizeof(LineartElementLinkNode));
- BLI_spin_unlock(&re_buf->lock_task);
+ BLI_spin_lock(&la_data->lock_task);
+ elem_link_node = lineart_list_append_pointer_pool_sized_thread(
+ &la_data->geom.vertex_buffer_pointers,
+ &la_data->render_data_pool,
+ la_v_arr,
+ sizeof(LineartElementLinkNode));
+ BLI_spin_unlock(&la_data->lock_task);
elem_link_node->element_count = me->totvert;
elem_link_node->object_ref = orig_ob;
@@ -1993,7 +2006,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend
use_auto_smooth = true;
}
else {
- crease_angle = re_buf->crease_threshold;
+ crease_angle = la_data->conf.crease_threshold;
}
/* FIXME(Yiming): Hack for getting clean 3D text, the seam that extruded text object creates
@@ -2002,12 +2015,13 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend
elem_link_node->flags |= LRT_ELEMENT_BORDER_ONLY;
}
- BLI_spin_lock(&re_buf->lock_task);
- elem_link_node = lineart_list_append_pointer_pool_sized_thread(&re_buf->triangle_buffer_pointers,
- &re_buf->render_data_pool,
- la_tri_arr,
- sizeof(LineartElementLinkNode));
- BLI_spin_unlock(&re_buf->lock_task);
+ BLI_spin_lock(&la_data->lock_task);
+ elem_link_node = lineart_list_append_pointer_pool_sized_thread(
+ &la_data->geom.triangle_buffer_pointers,
+ &la_data->render_data_pool,
+ la_tri_arr,
+ sizeof(LineartElementLinkNode));
+ BLI_spin_unlock(&la_data->lock_task);
int usage = ob_info->usage;
@@ -2019,10 +2033,10 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend
LineartTriangleAdjacent *tri_adj = MEM_callocN(sizeof(LineartTriangleAdjacent) * tot_tri,
"LineartTriangleAdjacent");
/* Link is minimal so we use pool anyway. */
- BLI_spin_lock(&re_buf->lock_task);
+ BLI_spin_lock(&la_data->lock_task);
lineart_list_append_pointer_pool_thread(
- &re_buf->triangle_adjacent_pointers, &re_buf->render_data_pool, tri_adj);
- BLI_spin_unlock(&re_buf->lock_task);
+ &la_data->geom.triangle_adjacent_pointers, &la_data->render_data_pool, tri_adj);
+ BLI_spin_unlock(&la_data->lock_task);
/* Convert all vertices to lineart verts. */
TaskParallelSettings vert_settings;
@@ -2051,10 +2065,10 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend
tri_data.mlooptri = mlooptri;
tri_data.vert_arr = la_v_arr;
tri_data.tri_arr = la_tri_arr;
- tri_data.lineart_triangle_size = re_buf->triangle_size;
+ tri_data.lineart_triangle_size = la_data->sizeof_triangle;
tri_data.tri_adj = tri_adj;
- unsigned int total_edges = tot_tri * 3;
+ uint32_t total_edges = tot_tri * 3;
BLI_task_parallel_range(0, tot_tri, &tri_data, lineart_load_tri_task, &tri_settings);
@@ -2072,7 +2086,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend
edge_feat_settings.func_reduce = feat_data_sum_reduce;
EdgeFeatData edge_feat_data = {0};
- edge_feat_data.rb = re_buf;
+ edge_feat_data.ld = la_data;
edge_feat_data.me = me;
edge_feat_data.mlooptri = mlooptri;
edge_feat_data.edge_nabr = lineart_build_edge_neighbor(me, total_edges);
@@ -2098,7 +2112,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend
&edge_feat_settings);
LooseEdgeData loose_data = {0};
- if (re_buf->use_loose) {
+ if (la_data->conf.use_loose) {
/* Only identifying floating edges at this point because other edges has been taken care of
* inside #lineart_identify_mlooptri_feature_edges function. */
TaskParallelSettings edge_loose_settings;
@@ -2114,16 +2128,17 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend
int allocate_la_e = edge_reduce.feat_edges + loose_data.loose_count;
- la_edge_arr = lineart_mem_acquire_thread(&re_buf->render_data_pool,
+ la_edge_arr = lineart_mem_acquire_thread(&la_data->render_data_pool,
sizeof(LineartEdge) * allocate_la_e);
- la_seg_arr = lineart_mem_acquire_thread(&re_buf->render_data_pool,
+ la_seg_arr = lineart_mem_acquire_thread(&la_data->render_data_pool,
sizeof(LineartEdgeSegment) * allocate_la_e);
- BLI_spin_lock(&re_buf->lock_task);
- elem_link_node = lineart_list_append_pointer_pool_sized_thread(&re_buf->line_buffer_pointers,
- &re_buf->render_data_pool,
- la_edge_arr,
- sizeof(LineartElementLinkNode));
- BLI_spin_unlock(&re_buf->lock_task);
+ BLI_spin_lock(&la_data->lock_task);
+ elem_link_node = lineart_list_append_pointer_pool_sized_thread(
+ &la_data->geom.line_buffer_pointers,
+ &la_data->render_data_pool,
+ la_edge_arr,
+ sizeof(LineartElementLinkNode));
+ BLI_spin_unlock(&la_data->lock_task);
elem_link_node->element_count = allocate_la_e;
elem_link_node->object_ref = orig_ob;
@@ -2148,8 +2163,8 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend
LineartEdge *edge_added = NULL;
/* See eLineartEdgeFlag for details. */
- for (int flag_bit = 0; flag_bit < LRT_EDGE_FLAG_TYPE_MAX_BITS; flag_bit++) {
- char use_type = 1 << flag_bit;
+ for (int flag_bit = 0; flag_bit < LRT_MESH_EDGE_TYPES_COUNT; flag_bit++) {
+ int use_type = LRT_MESH_EDGE_TYPES[flag_bit];
if (!(use_type & edge_nabr->flags)) {
continue;
}
@@ -2157,13 +2172,13 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend
la_edge->v1 = &la_v_arr[edge_nabr->v1];
la_edge->v2 = &la_v_arr[edge_nabr->v2];
int findex = i / 3;
- la_edge->t1 = lineart_triangle_from_index(re_buf, la_tri_arr, findex);
+ la_edge->t1 = lineart_triangle_from_index(la_data, la_tri_arr, findex);
if (!edge_added) {
lineart_triangle_adjacent_assign(la_edge->t1, &tri_adj[findex], la_edge);
}
if (edge_nabr->e != -1) {
findex = edge_nabr->e / 3;
- la_edge->t2 = lineart_triangle_from_index(re_buf, la_tri_arr, findex);
+ la_edge->t2 = lineart_triangle_from_index(la_data, la_tri_arr, findex);
if (!edge_added) {
lineart_triangle_adjacent_assign(la_edge->t2, &tri_adj[findex], la_edge);
}
@@ -2185,7 +2200,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend
la_edge++;
la_seg++;
- if (!re_buf->allow_duplicated_types) {
+ if (!la_data->conf.allow_duplicated_types) {
break;
}
}
@@ -2219,10 +2234,7 @@ static void lineart_object_load_worker(TaskPool *__restrict UNUSED(pool),
LineartObjectLoadTaskInfo *olti)
{
for (LineartObjectInfo *obi = olti->pending; obi; obi = obi->next) {
- lineart_geometry_object_load(obi, olti->rb);
- if (G.debug_value == 4000) {
- printf("thread id: %d processed: %d\n", olti->thread_id, obi->original_me->totpoly);
- }
+ lineart_geometry_object_load(obi, olti->ld);
}
}
@@ -2300,7 +2312,7 @@ static void lineart_geometry_load_assign_thread(LineartObjectLoadTaskInfo *olti_
int this_face_count)
{
LineartObjectLoadTaskInfo *use_olti = olti_list;
- long unsigned int min_face = use_olti->total_faces;
+ uint64_t min_face = use_olti->total_faces;
for (int i = 0; i < thread_count; i++) {
if (olti_list[i].total_faces < min_face) {
min_face = olti_list[i].total_faces;
@@ -2356,7 +2368,7 @@ static bool lineart_geometry_check_visible(double (*model_view_proj)[4],
return true;
}
-static void lineart_object_load_single_instance(LineartRenderBuffer *rb,
+static void lineart_object_load_single_instance(LineartData *ld,
Depsgraph *depsgraph,
Scene *scene,
Object *ob,
@@ -2366,7 +2378,7 @@ static void lineart_object_load_single_instance(LineartRenderBuffer *rb,
LineartObjectLoadTaskInfo *olti,
int thread_count)
{
- LineartObjectInfo *obi = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartObjectInfo));
+ LineartObjectInfo *obi = lineart_mem_acquire(&ld->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;
@@ -2377,8 +2389,8 @@ static void lineart_object_load_single_instance(LineartRenderBuffer *rb,
/* Prepare the matrix used for transforming this specific object (instance). This has to be
* done before mesh boundbox check because the function needs that. */
- mul_m4db_m4db_m4fl_uniq(obi->model_view_proj, rb->view_projection, use_mat);
- mul_m4db_m4db_m4fl_uniq(obi->model_view, rb->view, use_mat);
+ mul_m4db_m4db_m4fl_uniq(obi->model_view_proj, ld->conf.view_projection, use_mat);
+ mul_m4db_m4db_m4fl_uniq(obi->model_view, ld->conf.view, use_mat);
if (!ELEM(ob->type, OB_MESH, OB_MBALL, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
return;
@@ -2400,7 +2412,8 @@ static void lineart_object_load_single_instance(LineartRenderBuffer *rb,
return;
}
- if (!lineart_geometry_check_visible(obi->model_view_proj, rb->shift_x, rb->shift_y, use_mesh)) {
+ if (!lineart_geometry_check_visible(
+ obi->model_view_proj, ld->conf.shift_x, ld->conf.shift_y, use_mesh)) {
return;
}
@@ -2423,15 +2436,15 @@ static void lineart_main_load_geometries(
Depsgraph *depsgraph,
Scene *scene,
Object *camera /* Still use camera arg for convenience. */,
- LineartRenderBuffer *rb,
+ LineartData *ld,
bool allow_duplicates)
{
double proj[4][4], view[4][4], result[4][4];
float inv[4][4];
Camera *cam = camera->data;
float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
- int fit = BKE_camera_sensor_fit(cam->sensor_fit, rb->w, rb->h);
- double asp = ((double)rb->w / (double)rb->h);
+ int fit = BKE_camera_sensor_fit(cam->sensor_fit, ld->w, ld->h);
+ double asp = ((double)ld->w / (double)ld->h);
int bound_box_discard_count = 0;
@@ -2442,7 +2455,7 @@ static void lineart_main_load_geometries(
if (fit == CAMERA_SENSOR_FIT_HOR && asp < 1) {
sensor /= asp;
}
- const double fov = focallength_to_fov(cam->lens / (1 + rb->overscan), sensor);
+ const double fov = focallength_to_fov(cam->lens / (1 + ld->conf.overscan), sensor);
lineart_matrix_perspective_44d(proj, fov, asp, cam->clip_start, cam->clip_end);
}
else if (cam->type == CAM_ORTHO) {
@@ -2450,29 +2463,27 @@ static void lineart_main_load_geometries(
lineart_matrix_ortho_44d(proj, -w, w, -w / asp, w / asp, cam->clip_start, cam->clip_end);
}
- double t_start;
-
- if (G.debug_value == 4000) {
- t_start = PIL_check_seconds_timer();
- }
-
- invert_m4_m4(inv, rb->cam_obmat);
+ invert_m4_m4(inv, ld->conf.cam_obmat);
mul_m4db_m4db_m4fl_uniq(result, proj, inv);
copy_m4_m4_db(proj, result);
- copy_m4_m4_db(rb->view_projection, proj);
+ copy_m4_m4_db(ld->conf.view_projection, proj);
unit_m4_db(view);
- copy_m4_m4_db(rb->view, view);
+ copy_m4_m4_db(ld->conf.view, view);
- BLI_listbase_clear(&rb->triangle_buffer_pointers);
- BLI_listbase_clear(&rb->vertex_buffer_pointers);
+ BLI_listbase_clear(&ld->geom.triangle_buffer_pointers);
+ BLI_listbase_clear(&ld->geom.vertex_buffer_pointers);
+
+ double t_start;
+ if (G.debug_value == 4000) {
+ t_start = PIL_check_seconds_timer();
+ }
- int thread_count = rb->thread_count;
+ int thread_count = ld->thread_count;
- /* This memory is in render buffer memory pool. so we don't need to free those after loading.
- */
+ /* This memory is in render buffer memory pool. So we don't need to free those after loading. */
LineartObjectLoadTaskInfo *olti = lineart_mem_acquire(
- &rb->render_data_pool, sizeof(LineartObjectLoadTaskInfo) * thread_count);
+ &ld->render_data_pool, sizeof(LineartObjectLoadTaskInfo) * thread_count);
eEvaluationMode eval_mode = DEG_get_mode(depsgraph);
bool is_render = eval_mode == DAG_EVAL_RENDER;
@@ -2502,7 +2513,7 @@ static void lineart_main_load_geometries(
if (BKE_object_visibility(eval_ob, eval_mode) & OB_VISIBLE_SELF) {
lineart_object_load_single_instance(
- rb, depsgraph, scene, eval_ob, eval_ob, eval_ob->obmat, is_render, olti, thread_count);
+ ld, depsgraph, scene, eval_ob, eval_ob, eval_ob->obmat, is_render, olti, thread_count);
}
}
DEG_OBJECT_ITER_END;
@@ -2513,7 +2524,7 @@ static void lineart_main_load_geometries(
printf("thread count: %d\n", thread_count);
}
for (int i = 0; i < thread_count; i++) {
- olti[i].rb = rb;
+ olti[i].ld = ld;
olti[i].thread_id = i;
BLI_task_pool_push(tp, (TaskRunFunction)lineart_object_load_worker, &olti[i], 0, NULL);
}
@@ -2533,7 +2544,7 @@ static void lineart_main_load_geometries(
edge_count += obi->pending_edges.next;
}
}
- lineart_finalize_object_edge_array_reserve(&rb->pending_edges, edge_count);
+ lineart_finalize_object_edge_array_reserve(&ld->pending_edges, edge_count);
for (int i = 0; i < thread_count; i++) {
for (LineartObjectInfo *obi = olti[i].pending; obi; obi = obi->next) {
@@ -2551,7 +2562,7 @@ static void lineart_main_load_geometries(
* same numeric index to come close together. */
obi->global_i_offset = global_i;
global_i += v_count;
- lineart_finalize_object_edge_array(&rb->pending_edges, obi);
+ lineart_finalize_object_edge_array(&ld->pending_edges, obi);
}
}
@@ -2645,6 +2656,9 @@ static bool lineart_edge_from_triangle(const LineartTriangle *tri,
(num > is[order[1]] ? order[1] : (num > is[order[0]] ? order[0] : -1))); \
}
+#define LRT_ISEC(index) (index == 0 ? isec_e1 : (index == 1 ? isec_e2 : isec_e3))
+#define LRT_PARALLEL(index) (index == 0 ? para_e1 : (index == 1 ? para_e2 : para_e3))
+
/**
* This is the main function to calculate
* the occlusion status between 1(one) triangle and 1(one) line.
@@ -2658,7 +2672,7 @@ static bool lineart_edge_from_triangle(const LineartTriangle *tri,
* extruding from one of the triangle's point. To get the information using one math process can
* solve this problem.
*
- * 2) Currently using discrete a/b/c/pa/pb/pc/is[3] values for storing
+ * 2) Currently using discrete a/b/c/para_e1/para_e2/para_e3/is[3] values for storing
* intersection/edge_aligned/intersection_order info, which isn't optimal, needs a better
* representation (likely a struct) for readability and clarity of code path.
*
@@ -2680,18 +2694,20 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *UNUSED(spl),
double *from,
double *to)
{
- double is[3] = {0};
- int order[3];
- int LCross = -1, RCross = -1;
- int a, b, c; /* Crossing info. */
- bool pa, pb, pc; /* Parallel info. */
- int st_l = 0, st_r = 0;
-
- double Lv[3];
- double Rv[3];
- double vd4[4];
- double Cv[3];
- double dot_l, dot_r, dot_la, dot_ra;
+ double cross_ratios[3] = {0};
+ int cross_order[3];
+ int cross_v1 = -1, cross_v2 = -1;
+ /* If the edge intersects with the triangle edges (including extensions). */
+ int isec_e1, isec_e2, isec_e3;
+ /* If edge is parallel to one of the edges in the triangle. */
+ bool para_e1, para_e2, para_e3;
+ enum LineartPointTri state_v1 = 0, state_v2 = 0;
+
+ double dir_v1[3];
+ double dir_v2[3];
+ double view_vector[4];
+ double dir_cam[3];
+ double dot_v1, dot_v2, dot_v1a, dot_v2a;
double dot_f;
double gloc[4], trans[4];
double cut = -1;
@@ -2714,31 +2730,25 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *UNUSED(spl),
}
/* Check if the line visually crosses one of the edge in the triangle. */
- a = lineart_intersect_seg_seg(LFBC, RFBC, FBC0, FBC1, &is[0], &pa);
- b = lineart_intersect_seg_seg(LFBC, RFBC, FBC1, FBC2, &is[1], &pb);
- c = lineart_intersect_seg_seg(LFBC, RFBC, FBC2, FBC0, &is[2], &pc);
+ isec_e1 = lineart_intersect_seg_seg(LFBC, RFBC, FBC0, FBC1, &cross_ratios[0], &para_e1);
+ isec_e2 = lineart_intersect_seg_seg(LFBC, RFBC, FBC1, FBC2, &cross_ratios[1], &para_e2);
+ isec_e3 = lineart_intersect_seg_seg(LFBC, RFBC, FBC2, FBC0, &cross_ratios[2], &para_e3);
/* Sort the intersection distance. */
- INTERSECT_SORT_MIN_TO_MAX_3(is[0], is[1], is[2], order);
-
- sub_v3_v3v3_db(Lv, e->v1->gloc, tri->v[0]->gloc);
- sub_v3_v3v3_db(Rv, e->v2->gloc, tri->v[0]->gloc);
+ INTERSECT_SORT_MIN_TO_MAX_3(cross_ratios[0], cross_ratios[1], cross_ratios[2], cross_order);
- copy_v3_v3_db(Cv, camera_dir);
+ sub_v3_v3v3_db(dir_v1, e->v1->gloc, tri->v[0]->gloc);
+ sub_v3_v3v3_db(dir_v2, e->v2->gloc, tri->v[0]->gloc);
+ copy_v3_v3_db(dir_cam, camera_dir);
+ copy_v3_v3_db(view_vector, override_camera_loc);
if (override_cam_is_persp) {
- copy_v3_v3_db(vd4, override_camera_loc);
- }
- else {
- copy_v4_v4_db(vd4, override_camera_loc);
- }
- if (override_cam_is_persp) {
- sub_v3_v3v3_db(Cv, vd4, tri->v[0]->gloc);
+ sub_v3_v3v3_db(dir_cam, view_vector, tri->v[0]->gloc);
}
- dot_l = dot_v3v3_db(Lv, tri->gn);
- dot_r = dot_v3v3_db(Rv, tri->gn);
- dot_f = dot_v3v3_db(Cv, tri->gn);
+ dot_v1 = dot_v3v3_db(dir_v1, tri->gn);
+ dot_v2 = dot_v3v3_db(dir_v2, tri->gn);
+ dot_f = dot_v3v3_db(dir_cam, tri->gn);
/* NOTE(Yiming): When we don't use `dot_f==0` here, it's theoretically possible that _some_
* faces in perspective mode would get erroneously caught in this condition where they really
@@ -2749,40 +2759,39 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *UNUSED(spl),
return false;
}
+ /* Whether two end points are inside/on_the_edge/outside of the triangle. */
+ state_v1 = lineart_point_triangle_relation(LFBC, FBC0, FBC1, FBC2);
+ state_v2 = lineart_point_triangle_relation(RFBC, FBC0, FBC1, FBC2);
+
/* If the edge doesn't visually cross any edge of the triangle... */
- if (!a && !b && !c) {
+ if (!isec_e1 && !isec_e2 && !isec_e3) {
/* And if both end point from the edge is outside of the triangle... */
- if (!(st_l = lineart_point_triangle_relation(LFBC, FBC0, FBC1, FBC2)) &&
- !(st_r = lineart_point_triangle_relation(RFBC, FBC0, FBC1, FBC2))) {
+ if ((!state_v1) && (!state_v2)) {
return 0; /* We don't have any occlusion. */
}
}
- /* Whether two end points are inside/on_the_edge/outside of the triangle. */
- st_l = lineart_point_triangle_relation(LFBC, FBC0, FBC1, FBC2);
- st_r = lineart_point_triangle_relation(RFBC, FBC0, FBC1, FBC2);
-
/* Determine the cut position. */
- dot_la = fabs(dot_l);
- if (dot_la < DBL_EPSILON) {
- dot_la = 0;
- dot_l = 0;
+ dot_v1a = fabs(dot_v1);
+ if (dot_v1a < DBL_EPSILON) {
+ dot_v1a = 0;
+ dot_v1 = 0;
}
- dot_ra = fabs(dot_r);
- if (dot_ra < DBL_EPSILON) {
- dot_ra = 0;
- dot_r = 0;
+ dot_v2a = fabs(dot_v2);
+ if (dot_v2a < DBL_EPSILON) {
+ dot_v2a = 0;
+ dot_v2 = 0;
}
- if (dot_l - dot_r == 0) {
+ if (dot_v1 - dot_v2 == 0) {
cut = 100000;
}
- else if (dot_l * dot_r <= 0) {
- cut = dot_la / fabs(dot_l - dot_r);
+ else if (dot_v1 * dot_v2 <= 0) {
+ cut = dot_v1a / fabs(dot_v1 - dot_v2);
}
else {
- cut = fabs(dot_r + dot_l) / fabs(dot_l - dot_r);
- cut = dot_ra > dot_la ? 1 - cut : cut;
+ cut = fabs(dot_v2 + dot_v1) / fabs(dot_v1 - dot_v2);
+ cut = dot_v2a > dot_v1a ? 1 - cut : cut;
}
/* Transform the cut from geometry space to image space. */
@@ -2803,7 +2812,7 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *UNUSED(spl),
}
#define LRT_GUARD_NOT_FOUND \
- if (LCross < 0 || RCross < 0) { \
+ if (cross_v1 < 0 || cross_v2 < 0) { \
return false; \
}
@@ -2811,95 +2820,97 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *UNUSED(spl),
* indicates triangle boundary. DBL_TRIANGLE_LIM is needed to for floating point precision
* tolerance. */
- if (st_l == 2) {
+ if (state_v1 == LRT_INSIDE_TRIANGLE) {
/* Left side is in the triangle. */
- if (st_r == 2) {
+ if (state_v2 == LRT_INSIDE_TRIANGLE) {
/* | l---r | */
- INTERSECT_JUST_SMALLER(is, order, DBL_TRIANGLE_LIM, LCross);
- INTERSECT_JUST_GREATER(is, order, 1 - DBL_TRIANGLE_LIM, RCross);
+ INTERSECT_JUST_SMALLER(cross_ratios, cross_order, DBL_TRIANGLE_LIM, cross_v1);
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, 1 - DBL_TRIANGLE_LIM, cross_v2);
}
- else if (st_r == 1) {
+ else if (state_v2 == LRT_ON_TRIANGLE) {
/* | l------r| */
- INTERSECT_JUST_SMALLER(is, order, DBL_TRIANGLE_LIM, LCross);
- INTERSECT_JUST_GREATER(is, order, 1 - DBL_TRIANGLE_LIM, RCross);
+ INTERSECT_JUST_SMALLER(cross_ratios, cross_order, DBL_TRIANGLE_LIM, cross_v1);
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, 1 - DBL_TRIANGLE_LIM, cross_v2);
}
- else if (st_r == 0) {
+ else if (state_v2 == LRT_OUTSIDE_TRIANGLE) {
/* | l-------|------r */
- INTERSECT_JUST_SMALLER(is, order, DBL_TRIANGLE_LIM, LCross);
- INTERSECT_JUST_GREATER(is, order, 0, RCross);
+ INTERSECT_JUST_SMALLER(cross_ratios, cross_order, DBL_TRIANGLE_LIM, cross_v1);
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, 0, cross_v2);
}
}
- else if (st_l == 1) {
+ else if (state_v1 == LRT_ON_TRIANGLE) {
/* Left side is on some edge of the triangle. */
- if (st_r == 2) {
+ if (state_v2 == LRT_INSIDE_TRIANGLE) {
/* |l------r | */
- INTERSECT_JUST_SMALLER(is, order, DBL_TRIANGLE_LIM, LCross);
- INTERSECT_JUST_GREATER(is, order, 1 - DBL_TRIANGLE_LIM, RCross);
+ INTERSECT_JUST_SMALLER(cross_ratios, cross_order, DBL_TRIANGLE_LIM, cross_v1);
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, 1 - DBL_TRIANGLE_LIM, cross_v2);
}
- else if (st_r == 1) {
+ else if (state_v2 == LRT_ON_TRIANGLE) {
/* |l---------r| */
- INTERSECT_JUST_SMALLER(is, order, DBL_TRIANGLE_LIM, LCross);
- INTERSECT_JUST_GREATER(is, order, 1 - DBL_TRIANGLE_LIM, RCross);
+ INTERSECT_JUST_SMALLER(cross_ratios, cross_order, DBL_TRIANGLE_LIM, cross_v1);
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, 1 - DBL_TRIANGLE_LIM, cross_v2);
}
- else if (st_r == 0) {
+ else if (state_v2 == LRT_OUTSIDE_TRIANGLE) {
/* |l----------|-------r (crossing the triangle) [OR]
* r---------|l | (not crossing the triangle) */
- INTERSECT_JUST_GREATER(is, order, DBL_TRIANGLE_LIM, RCross);
- if (RCross >= 0 && LRT_ABC(RCross) && is[RCross] > (DBL_TRIANGLE_LIM)) {
- INTERSECT_JUST_SMALLER(is, order, DBL_TRIANGLE_LIM, LCross);
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, DBL_TRIANGLE_LIM, cross_v2);
+ if (cross_v2 >= 0 && LRT_ISEC(cross_v2) && cross_ratios[cross_v2] > (DBL_TRIANGLE_LIM)) {
+ INTERSECT_JUST_SMALLER(cross_ratios, cross_order, DBL_TRIANGLE_LIM, cross_v1);
}
else {
- INTERSECT_JUST_SMALLER(is, order, DBL_TRIANGLE_LIM, RCross);
- if (RCross > 0) {
- INTERSECT_JUST_SMALLER(is, order, is[RCross], LCross);
+ INTERSECT_JUST_SMALLER(cross_ratios, cross_order, DBL_TRIANGLE_LIM, cross_v2);
+ if (cross_v2 > 0) {
+ INTERSECT_JUST_SMALLER(cross_ratios, cross_order, cross_ratios[cross_v2], cross_v1);
}
}
LRT_GUARD_NOT_FOUND
/* We could have the edge being completely parallel to the triangle where there isn't a
* viable occlusion result. */
- if ((LRT_PABC(LCross) && !LRT_ABC(LCross)) || (LRT_PABC(RCross) && !LRT_ABC(RCross))) {
+ if ((LRT_PARALLEL(cross_v1) && !LRT_ISEC(cross_v1)) ||
+ (LRT_PARALLEL(cross_v2) && !LRT_ISEC(cross_v2))) {
return false;
}
}
}
- else if (st_l == 0) {
+ else if (state_v1 == LRT_OUTSIDE_TRIANGLE) {
/* Left side is outside of the triangle. */
- if (st_r == 2) {
+ if (state_v2 == LRT_INSIDE_TRIANGLE) {
/* l---|---r | */
- INTERSECT_JUST_SMALLER(is, order, 1 - DBL_TRIANGLE_LIM, LCross);
- INTERSECT_JUST_GREATER(is, order, 1 - DBL_TRIANGLE_LIM, RCross);
+ INTERSECT_JUST_SMALLER(cross_ratios, cross_order, 1 - DBL_TRIANGLE_LIM, cross_v1);
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, 1 - DBL_TRIANGLE_LIM, cross_v2);
}
- else if (st_r == 1) {
+ else if (state_v2 == LRT_ON_TRIANGLE) {
/* |r----------|-------l (crossing the triangle) [OR]
* l---------|r | (not crossing the triangle) */
- INTERSECT_JUST_SMALLER(is, order, 1 - DBL_TRIANGLE_LIM, LCross);
- if (LCross >= 0 && LRT_ABC(LCross) && is[LCross] < (1 - DBL_TRIANGLE_LIM)) {
- INTERSECT_JUST_GREATER(is, order, 1 - DBL_TRIANGLE_LIM, RCross);
+ INTERSECT_JUST_SMALLER(cross_ratios, cross_order, 1 - DBL_TRIANGLE_LIM, cross_v1);
+ if (cross_v1 >= 0 && LRT_ISEC(cross_v1) && cross_ratios[cross_v1] < (1 - DBL_TRIANGLE_LIM)) {
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, 1 - DBL_TRIANGLE_LIM, cross_v2);
}
else {
- INTERSECT_JUST_GREATER(is, order, 1 - DBL_TRIANGLE_LIM, LCross);
- if (LCross > 0) {
- INTERSECT_JUST_GREATER(is, order, is[LCross], RCross);
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, 1 - DBL_TRIANGLE_LIM, cross_v1);
+ if (cross_v1 > 0) {
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, cross_ratios[cross_v1], cross_v2);
}
}
LRT_GUARD_NOT_FOUND
/* The same logic applies as above case. */
- if ((LRT_PABC(LCross) && !LRT_ABC(LCross)) || (LRT_PABC(RCross) && !LRT_ABC(RCross))) {
+ if ((LRT_PARALLEL(cross_v1) && !LRT_ISEC(cross_v1)) ||
+ (LRT_PARALLEL(cross_v2) && !LRT_ISEC(cross_v2))) {
return false;
}
}
- else if (st_r == 0) {
+ else if (state_v2 == LRT_OUTSIDE_TRIANGLE) {
/* l---|----|----r (crossing the triangle) [OR]
* l----r | | (not crossing the triangle) */
- INTERSECT_JUST_GREATER(is, order, -DBL_TRIANGLE_LIM, LCross);
- if (LCross >= 0 && LRT_ABC(LCross)) {
- INTERSECT_JUST_GREATER(is, order, is[LCross], RCross);
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, -DBL_TRIANGLE_LIM, cross_v1);
+ if (cross_v1 >= 0 && LRT_ISEC(cross_v1)) {
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, cross_ratios[cross_v1], cross_v2);
}
else {
- if (LCross >= 0) {
- INTERSECT_JUST_GREATER(is, order, is[LCross], LCross);
- if (LCross >= 0) {
- INTERSECT_JUST_GREATER(is, order, is[LCross], RCross);
+ if (cross_v1 >= 0) {
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, cross_ratios[cross_v1], cross_v1);
+ if (cross_v1 >= 0) {
+ INTERSECT_JUST_GREATER(cross_ratios, cross_order, cross_ratios[cross_v1], cross_v2);
}
}
}
@@ -2908,28 +2919,28 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *UNUSED(spl),
LRT_GUARD_NOT_FOUND
- double LF = dot_l * dot_f, RF = dot_r * dot_f;
+ double dot_1f = dot_v1 * dot_f, dot_2f = dot_v2 * dot_f;
/* Determine the start and end point of image space cut on a line. */
- if (LF <= 0 && RF <= 0 && (dot_l || dot_r)) {
- *from = MAX2(0, is[LCross]);
- *to = MIN2(1, is[RCross]);
+ if (dot_1f <= 0 && dot_2f <= 0 && (dot_v1 || dot_v2)) {
+ *from = MAX2(0, cross_ratios[cross_v1]);
+ *to = MIN2(1, cross_ratios[cross_v2]);
if (*from >= *to) {
return false;
}
return true;
}
- if (LF >= 0 && RF <= 0 && (dot_l || dot_r)) {
- *from = MAX2(cut, is[LCross]);
- *to = MIN2(1, is[RCross]);
+ if (dot_1f >= 0 && dot_2f <= 0 && (dot_v1 || dot_v2)) {
+ *from = MAX2(cut, cross_ratios[cross_v1]);
+ *to = MIN2(1, cross_ratios[cross_v2]);
if (*from >= *to) {
return false;
}
return true;
}
- if (LF <= 0 && RF >= 0 && (dot_l || dot_r)) {
- *from = MAX2(0, is[LCross]);
- *to = MIN2(cut, is[RCross]);
+ if (dot_1f <= 0 && dot_2f >= 0 && (dot_v1 || dot_v2)) {
+ *from = MAX2(0, cross_ratios[cross_v1]);
+ *to = MIN2(cut, cross_ratios[cross_v2]);
if (*from >= *to) {
return false;
}
@@ -2943,6 +2954,8 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *UNUSED(spl),
#undef INTERSECT_SORT_MIN_TO_MAX_3
#undef INTERSECT_JUST_GREATER
#undef INTERSECT_JUST_SMALLER
+#undef LRT_ISEC
+#undef LRT_PARALLEL
/**
* At this stage of the computation we don't have triangle adjacent info anymore,
@@ -3025,37 +3038,37 @@ static LineartVert *lineart_triangle_share_point(const LineartTriangle *l,
}
static bool lineart_triangle_2v_intersection_math(
- LineartVert *v1, LineartVert *v2, LineartTriangle *t2, double *last, double *rv)
+ LineartVert *v1, LineartVert *v2, LineartTriangle *tri, double *last, double *rv)
{
- double Lv[3];
- double Rv[3];
- double dot_l, dot_r;
+ /* Direction vectors for the edge verts. We will check if the verts are on the same side of the
+ * triangle or not. */
+ double dir_v1[3], dir_v2[3];
+ double dot_v1, dot_v2;
double gloc[3];
- LineartVert *l = v1, *r = v2;
- sub_v3_v3v3_db(Lv, l->gloc, t2->v[0]->gloc);
- sub_v3_v3v3_db(Rv, r->gloc, t2->v[0]->gloc);
+ sub_v3_v3v3_db(dir_v1, v1->gloc, tri->v[0]->gloc);
+ sub_v3_v3v3_db(dir_v2, v2->gloc, tri->v[0]->gloc);
- dot_l = dot_v3v3_db(Lv, t2->gn);
- dot_r = dot_v3v3_db(Rv, t2->gn);
+ dot_v1 = dot_v3v3_db(dir_v1, tri->gn);
+ dot_v2 = dot_v3v3_db(dir_v2, tri->gn);
- if (dot_l * dot_r > 0 || (!dot_l && !dot_r)) {
+ if (dot_v1 * dot_v2 > 0 || (!dot_v1 && !dot_v2)) {
return false;
}
- dot_l = fabs(dot_l);
- dot_r = fabs(dot_r);
+ dot_v1 = fabs(dot_v1);
+ dot_v2 = fabs(dot_v2);
- interp_v3_v3v3_db(gloc, l->gloc, r->gloc, dot_l / (dot_l + dot_r));
+ interp_v3_v3v3_db(gloc, v1->gloc, v2->gloc, dot_v1 / (dot_v1 + dot_v2));
- /* 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[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, t2->v[0]->gloc, t2->v[1]->gloc, t2->v[2]->gloc))) {
+ if (!(lineart_point_inside_triangle3d(
+ gloc, tri->v[0]->gloc, tri->v[1]->gloc, tri->v[2]->gloc))) {
return false;
}
@@ -3152,11 +3165,11 @@ static void lineart_add_isec_thread(LineartIsecThread *th,
MEM_freeN(th->array);
th->array = new_array;
}
- LineartIsecSingle *is = &th->array[th->current];
- copy_v3fl_v3db(is->v1, v1);
- copy_v3fl_v3db(is->v2, v2);
- is->tri1 = tri1;
- is->tri2 = tri2;
+ LineartIsecSingle *isec_single = &th->array[th->current];
+ copy_v3fl_v3db(isec_single->v1, v1);
+ copy_v3fl_v3db(isec_single->v2, v2);
+ isec_single->tri1 = tri1;
+ isec_single->tri2 = tri2;
th->current++;
}
@@ -3164,38 +3177,38 @@ static void lineart_add_isec_thread(LineartIsecThread *th,
static bool lineart_schedule_new_triangle_task(LineartIsecThread *th)
{
- LineartRenderBuffer *rb = th->rb;
+ LineartData *ld = th->ld;
int remaining = LRT_ISECT_TRIANGLE_PER_THREAD;
- BLI_spin_lock(&rb->lock_task);
- LineartElementLinkNode *eln = rb->isect_scheduled_up_to;
+ BLI_spin_lock(&ld->lock_task);
+ LineartElementLinkNode *eln = ld->isect_scheduled_up_to;
if (!eln) {
- BLI_spin_unlock(&rb->lock_task);
+ BLI_spin_unlock(&ld->lock_task);
return false;
}
th->pending_from = eln;
- th->index_from = rb->isect_scheduled_up_to_index;
+ th->index_from = ld->isect_scheduled_up_to_index;
while (remaining > 0 && eln) {
- int remaining_this_eln = eln->element_count - rb->isect_scheduled_up_to_index;
+ int remaining_this_eln = eln->element_count - ld->isect_scheduled_up_to_index;
int added_count = MIN2(remaining, remaining_this_eln);
remaining -= added_count;
if (remaining || added_count == remaining_this_eln) {
eln = eln->next;
- rb->isect_scheduled_up_to = eln;
- rb->isect_scheduled_up_to_index = 0;
+ ld->isect_scheduled_up_to = eln;
+ ld->isect_scheduled_up_to_index = 0;
}
else {
- rb->isect_scheduled_up_to_index += added_count;
+ ld->isect_scheduled_up_to_index += added_count;
}
}
- th->pending_to = eln ? eln : rb->triangle_buffer_pointers.last;
- th->index_to = rb->isect_scheduled_up_to_index;
+ th->pending_to = eln ? eln : ld->geom.triangle_buffer_pointers.last;
+ th->index_to = ld->isect_scheduled_up_to_index;
- BLI_spin_unlock(&rb->lock_task);
+ BLI_spin_unlock(&ld->lock_task);
return true;
}
@@ -3205,14 +3218,14 @@ static bool lineart_schedule_new_triangle_task(LineartIsecThread *th)
* 2) Per-thread intersection result array. Does not store actual #LineartEdge, these results will
* be finalized by #lineart_create_edges_from_isec_data
*/
-static void lineart_init_isec_thread(LineartIsecData *d, LineartRenderBuffer *rb, int thread_count)
+static void lineart_init_isec_thread(LineartIsecData *d, LineartData *ld, int thread_count)
{
d->threads = MEM_callocN(sizeof(LineartIsecThread) * thread_count, "LineartIsecThread arr");
- d->rb = rb;
+ d->ld = ld;
d->thread_count = thread_count;
- rb->isect_scheduled_up_to = rb->triangle_buffer_pointers.first;
- rb->isect_scheduled_up_to_index = 0;
+ ld->isect_scheduled_up_to = ld->geom.triangle_buffer_pointers.first;
+ ld->isect_scheduled_up_to_index = 0;
for (int i = 0; i < thread_count; i++) {
LineartIsecThread *it = &d->threads[i];
@@ -3220,7 +3233,7 @@ static void lineart_init_isec_thread(LineartIsecData *d, LineartRenderBuffer *rb
it->max = 100;
it->current = 0;
it->thread_id = i;
- it->rb = rb;
+ it->ld = ld;
}
}
@@ -3290,14 +3303,14 @@ static void lineart_triangle_intersect_in_bounding_area(LineartTriangle *tri,
/**
* The calculated view vector will point towards the far-plane from the camera position.
*/
-static void lineart_main_get_view_vector(LineartRenderBuffer *rb)
+static void lineart_main_get_view_vector(LineartData *ld)
{
float direction[3] = {0, 0, 1};
float trans[3];
float inv[4][4];
float obmat_no_scale[4][4];
- copy_m4_m4(obmat_no_scale, rb->cam_obmat);
+ copy_m4_m4(obmat_no_scale, ld->conf.cam_obmat);
normalize_v3(obmat_no_scale[0]);
normalize_v3(obmat_no_scale[1]);
@@ -3305,45 +3318,45 @@ static void lineart_main_get_view_vector(LineartRenderBuffer *rb)
invert_m4_m4(inv, obmat_no_scale);
transpose_m4(inv);
mul_v3_mat3_m4v3(trans, inv, direction);
- copy_m4_m4(rb->cam_obmat, obmat_no_scale);
- copy_v3db_v3fl(rb->view_vector, trans);
+ copy_m4_m4(ld->conf.cam_obmat, obmat_no_scale);
+ copy_v3db_v3fl(ld->conf.view_vector, trans);
}
-static void lineart_destroy_render_data(LineartRenderBuffer *rb)
+static void lineart_destroy_render_data(LineartData *ld)
{
- if (rb == NULL) {
+ if (ld == NULL) {
return;
}
- BLI_listbase_clear(&rb->chains);
- BLI_listbase_clear(&rb->wasted_cuts);
+ BLI_listbase_clear(&ld->chains);
+ BLI_listbase_clear(&ld->wasted_cuts);
- BLI_listbase_clear(&rb->vertex_buffer_pointers);
- BLI_listbase_clear(&rb->line_buffer_pointers);
- BLI_listbase_clear(&rb->triangle_buffer_pointers);
+ BLI_listbase_clear(&ld->geom.vertex_buffer_pointers);
+ BLI_listbase_clear(&ld->geom.line_buffer_pointers);
+ BLI_listbase_clear(&ld->geom.triangle_buffer_pointers);
- BLI_spin_end(&rb->lock_task);
- BLI_spin_end(&rb->lock_cuts);
- BLI_spin_end(&rb->render_data_pool.lock_mem);
+ BLI_spin_end(&ld->lock_task);
+ BLI_spin_end(&ld->lock_cuts);
+ BLI_spin_end(&ld->render_data_pool.lock_mem);
- if (rb->pending_edges.array) {
- MEM_freeN(rb->pending_edges.array);
+ if (ld->pending_edges.array) {
+ MEM_freeN(ld->pending_edges.array);
}
- lineart_free_bounding_area_memories(rb);
+ lineart_free_bounding_area_memories(ld);
- lineart_mem_destroy(&rb->render_data_pool);
+ lineart_mem_destroy(&ld->render_data_pool);
}
void MOD_lineart_destroy_render_data(LineartGpencilModifierData *lmd)
{
- LineartRenderBuffer *rb = lmd->render_buffer_ptr;
+ LineartData *ld = lmd->la_data_ptr;
- lineart_destroy_render_data(rb);
+ lineart_destroy_render_data(ld);
- if (rb) {
- MEM_freeN(rb);
- lmd->render_buffer_ptr = NULL;
+ if (ld) {
+ MEM_freeN(ld);
+ lmd->la_data_ptr = NULL;
}
if (G.debug_value == 4000) {
@@ -3367,16 +3380,16 @@ void MOD_lineart_clear_cache(struct LineartCache **lc)
(*lc) = NULL;
}
-static LineartRenderBuffer *lineart_create_render_buffer(Scene *scene,
- LineartGpencilModifierData *lmd,
- Object *camera,
- Object *active_camera,
- LineartCache *lc)
+static LineartData *lineart_create_render_buffer(Scene *scene,
+ LineartGpencilModifierData *lmd,
+ Object *camera,
+ Object *active_camera,
+ LineartCache *lc)
{
- LineartRenderBuffer *rb = MEM_callocN(sizeof(LineartRenderBuffer), "Line Art render buffer");
+ LineartData *ld = MEM_callocN(sizeof(LineartData), "Line Art render buffer");
lmd->cache = lc;
- lmd->render_buffer_ptr = rb;
+ lmd->la_data_ptr = ld;
lc->rb_edge_types = lmd->edge_types_override;
if (!scene || !camera || !lc) {
@@ -3390,97 +3403,98 @@ static LineartRenderBuffer *lineart_create_render_buffer(Scene *scene,
clipping_offset = 0.0001;
}
- copy_v3db_v3fl(rb->camera_pos, camera->obmat[3]);
+ copy_v3db_v3fl(ld->conf.camera_pos, camera->obmat[3]);
if (active_camera) {
- copy_v3db_v3fl(rb->active_camera_pos, active_camera->obmat[3]);
+ copy_v3db_v3fl(ld->conf.active_camera_pos, active_camera->obmat[3]);
}
- copy_m4_m4(rb->cam_obmat, camera->obmat);
- rb->cam_is_persp = (c->type == CAM_PERSP);
- rb->near_clip = c->clip_start + clipping_offset;
- rb->far_clip = c->clip_end - clipping_offset;
- rb->w = scene->r.xsch;
- rb->h = scene->r.ysch;
+ copy_m4_m4(ld->conf.cam_obmat, camera->obmat);
+
+ ld->conf.cam_is_persp = (c->type == CAM_PERSP);
+ ld->conf.near_clip = c->clip_start + clipping_offset;
+ ld->conf.far_clip = c->clip_end - clipping_offset;
+ ld->w = scene->r.xsch;
+ ld->h = scene->r.ysch;
- if (rb->cam_is_persp) {
- rb->tile_recursive_level = LRT_TILE_RECURSIVE_PERSPECTIVE;
+ if (ld->conf.cam_is_persp) {
+ ld->qtree.recursive_level = LRT_TILE_RECURSIVE_PERSPECTIVE;
}
else {
- rb->tile_recursive_level = LRT_TILE_RECURSIVE_ORTHO;
+ ld->qtree.recursive_level = LRT_TILE_RECURSIVE_ORTHO;
}
- double asp = ((double)rb->w / (double)rb->h);
- int fit = BKE_camera_sensor_fit(c->sensor_fit, rb->w, rb->h);
- rb->shift_x = fit == CAMERA_SENSOR_FIT_HOR ? c->shiftx : c->shiftx / asp;
- rb->shift_y = fit == CAMERA_SENSOR_FIT_VERT ? c->shifty : c->shifty * asp;
+ double asp = ((double)ld->w / (double)ld->h);
+ int fit = BKE_camera_sensor_fit(c->sensor_fit, ld->w, ld->h);
+ ld->conf.shift_x = fit == CAMERA_SENSOR_FIT_HOR ? c->shiftx : c->shiftx / asp;
+ ld->conf.shift_y = fit == CAMERA_SENSOR_FIT_VERT ? c->shifty : c->shifty * asp;
- rb->overscan = lmd->overscan;
+ ld->conf.overscan = lmd->overscan;
- rb->shift_x /= (1 + rb->overscan);
- rb->shift_y /= (1 + rb->overscan);
+ ld->conf.shift_x /= (1 + ld->conf.overscan);
+ ld->conf.shift_y /= (1 + ld->conf.overscan);
- rb->crease_threshold = cos(M_PI - lmd->crease_threshold);
- rb->chaining_image_threshold = lmd->chaining_image_threshold;
- rb->angle_splitting_threshold = lmd->angle_splitting_threshold;
- rb->chain_smooth_tolerance = lmd->chain_smooth_tolerance;
+ ld->conf.crease_threshold = cos(M_PI - lmd->crease_threshold);
+ ld->conf.chaining_image_threshold = lmd->chaining_image_threshold;
+ ld->conf.angle_splitting_threshold = lmd->angle_splitting_threshold;
+ ld->conf.chain_smooth_tolerance = lmd->chain_smooth_tolerance;
- rb->fuzzy_intersections = (lmd->calculation_flags & LRT_INTERSECTION_AS_CONTOUR) != 0;
- rb->fuzzy_everything = (lmd->calculation_flags & LRT_EVERYTHING_AS_CONTOUR) != 0;
- rb->allow_boundaries = (lmd->calculation_flags & LRT_ALLOW_CLIPPING_BOUNDARIES) != 0;
- rb->use_loose_as_contour = (lmd->calculation_flags & LRT_LOOSE_AS_CONTOUR) != 0;
- rb->use_loose_edge_chain = (lmd->calculation_flags & LRT_CHAIN_LOOSE_EDGES) != 0;
- rb->use_geometry_space_chain = (lmd->calculation_flags & LRT_CHAIN_GEOMETRY_SPACE) != 0;
- rb->use_image_boundary_trimming = (lmd->calculation_flags & LRT_USE_IMAGE_BOUNDARY_TRIMMING) !=
- 0;
+ ld->conf.fuzzy_intersections = (lmd->calculation_flags & LRT_INTERSECTION_AS_CONTOUR) != 0;
+ ld->conf.fuzzy_everything = (lmd->calculation_flags & LRT_EVERYTHING_AS_CONTOUR) != 0;
+ ld->conf.allow_boundaries = (lmd->calculation_flags & LRT_ALLOW_CLIPPING_BOUNDARIES) != 0;
+ ld->conf.use_loose_as_contour = (lmd->calculation_flags & LRT_LOOSE_AS_CONTOUR) != 0;
+ ld->conf.use_loose_edge_chain = (lmd->calculation_flags & LRT_CHAIN_LOOSE_EDGES) != 0;
+ ld->conf.use_geometry_space_chain = (lmd->calculation_flags & LRT_CHAIN_GEOMETRY_SPACE) != 0;
+ ld->conf.use_image_boundary_trimming = (lmd->calculation_flags &
+ LRT_USE_IMAGE_BOUNDARY_TRIMMING) != 0;
/* See lineart_edge_from_triangle() for how this option may impact performance. */
- rb->allow_overlapping_edges = (lmd->calculation_flags & LRT_ALLOW_OVERLAPPING_EDGES) != 0;
+ ld->conf.allow_overlapping_edges = (lmd->calculation_flags & LRT_ALLOW_OVERLAPPING_EDGES) != 0;
- rb->allow_duplicated_types = (lmd->calculation_flags & LRT_ALLOW_OVERLAP_EDGE_TYPES) != 0;
+ ld->conf.allow_duplicated_types = (lmd->calculation_flags & LRT_ALLOW_OVERLAP_EDGE_TYPES) != 0;
- rb->force_crease = (lmd->calculation_flags & LRT_USE_CREASE_ON_SMOOTH_SURFACES) != 0;
- rb->sharp_as_crease = (lmd->calculation_flags & LRT_USE_CREASE_ON_SHARP_EDGES) != 0;
+ ld->conf.force_crease = (lmd->calculation_flags & LRT_USE_CREASE_ON_SMOOTH_SURFACES) != 0;
+ ld->conf.sharp_as_crease = (lmd->calculation_flags & LRT_USE_CREASE_ON_SHARP_EDGES) != 0;
- rb->chain_preserve_details = (lmd->calculation_flags & LRT_CHAIN_PRESERVE_DETAILS) != 0;
+ ld->conf.chain_preserve_details = (lmd->calculation_flags & LRT_CHAIN_PRESERVE_DETAILS) != 0;
/* This is used to limit calculation to a certain level to save time, lines who have higher
* occlusion levels will get ignored. */
- rb->max_occlusion_level = lmd->level_end_override;
+ ld->conf.max_occlusion_level = lmd->level_end_override;
- rb->use_back_face_culling = (lmd->calculation_flags & LRT_USE_BACK_FACE_CULLING) != 0;
+ ld->conf.use_back_face_culling = (lmd->calculation_flags & LRT_USE_BACK_FACE_CULLING) != 0;
int16_t edge_types = lmd->edge_types_override;
- rb->use_contour = (edge_types & LRT_EDGE_FLAG_CONTOUR) != 0;
- rb->use_crease = (edge_types & LRT_EDGE_FLAG_CREASE) != 0;
- rb->use_material = (edge_types & LRT_EDGE_FLAG_MATERIAL) != 0;
- rb->use_edge_marks = (edge_types & LRT_EDGE_FLAG_EDGE_MARK) != 0;
- rb->use_intersections = (edge_types & LRT_EDGE_FLAG_INTERSECTION) != 0;
- rb->use_loose = (edge_types & LRT_EDGE_FLAG_LOOSE) != 0;
+ ld->conf.use_contour = (edge_types & LRT_EDGE_FLAG_CONTOUR) != 0;
+ ld->conf.use_crease = (edge_types & LRT_EDGE_FLAG_CREASE) != 0;
+ ld->conf.use_material = (edge_types & LRT_EDGE_FLAG_MATERIAL) != 0;
+ ld->conf.use_edge_marks = (edge_types & LRT_EDGE_FLAG_EDGE_MARK) != 0;
+ ld->conf.use_intersections = (edge_types & LRT_EDGE_FLAG_INTERSECTION) != 0;
+ ld->conf.use_loose = (edge_types & LRT_EDGE_FLAG_LOOSE) != 0;
- rb->filter_face_mark_invert = (lmd->calculation_flags & LRT_FILTER_FACE_MARK_INVERT) != 0;
- rb->filter_face_mark = (lmd->calculation_flags & LRT_FILTER_FACE_MARK) != 0;
- rb->filter_face_mark_boundaries = (lmd->calculation_flags & LRT_FILTER_FACE_MARK_BOUNDARIES) !=
- 0;
- rb->filter_face_mark_keep_contour = (lmd->calculation_flags &
- LRT_FILTER_FACE_MARK_KEEP_CONTOUR) != 0;
+ ld->conf.filter_face_mark_invert = (lmd->calculation_flags & LRT_FILTER_FACE_MARK_INVERT) != 0;
+ ld->conf.filter_face_mark = (lmd->calculation_flags & LRT_FILTER_FACE_MARK) != 0;
+ ld->conf.filter_face_mark_boundaries = (lmd->calculation_flags &
+ LRT_FILTER_FACE_MARK_BOUNDARIES) != 0;
+ ld->conf.filter_face_mark_keep_contour = (lmd->calculation_flags &
+ LRT_FILTER_FACE_MARK_KEEP_CONTOUR) != 0;
- rb->chain_data_pool = &lc->chain_data_pool;
+ ld->chain_data_pool = &lc->chain_data_pool;
- BLI_spin_init(&rb->lock_task);
- BLI_spin_init(&rb->lock_cuts);
- BLI_spin_init(&rb->render_data_pool.lock_mem);
+ BLI_spin_init(&ld->lock_task);
+ BLI_spin_init(&ld->lock_cuts);
+ BLI_spin_init(&ld->render_data_pool.lock_mem);
- rb->thread_count = BKE_render_num_threads(&scene->r);
+ ld->thread_count = BKE_render_num_threads(&scene->r);
- return rb;
+ return ld;
}
-static int lineart_triangle_size_get(LineartRenderBuffer *rb)
+static int lineart_triangle_size_get(LineartData *ld)
{
- return sizeof(LineartTriangle) + (sizeof(LineartEdge *) * (rb->thread_count));
+ return sizeof(LineartTriangle) + (sizeof(LineartEdge *) * (ld->thread_count));
}
-static void lineart_main_bounding_area_make_initial(LineartRenderBuffer *rb)
+static void lineart_main_bounding_area_make_initial(LineartData *ld)
{
/* Initial tile split is defined as 4 (subdivided as 4*4), increasing the value allows the
* algorithm to build the acceleration structure for bigger scenes a little faster but not as
@@ -3491,11 +3505,11 @@ static void lineart_main_bounding_area_make_initial(LineartRenderBuffer *rb)
LineartBoundingArea *ba;
/* Always make sure the shortest side has at least LRT_BA_ROWS tiles. */
- if (rb->w > rb->h) {
- sp_w = sp_h * rb->w / rb->h;
+ if (ld->w > ld->h) {
+ sp_w = sp_h * ld->w / ld->h;
}
else {
- sp_h = sp_w * rb->h / rb->w;
+ sp_h = sp_w * ld->h / ld->w;
}
/* Because NDC (Normalized Device Coordinates) range is (-1,1),
@@ -3503,19 +3517,19 @@ static void lineart_main_bounding_area_make_initial(LineartRenderBuffer *rb)
double span_w = (double)1 / sp_w * 2.0;
double span_h = (double)1 / sp_h * 2.0;
- rb->tile_count_x = sp_w;
- rb->tile_count_y = sp_h;
- rb->width_per_tile = span_w;
- rb->height_per_tile = span_h;
+ ld->qtree.count_x = sp_w;
+ ld->qtree.count_y = sp_h;
+ ld->qtree.tile_width = span_w;
+ ld->qtree.tile_height = span_h;
- rb->bounding_area_count = sp_w * sp_h;
- rb->initial_bounding_areas = lineart_mem_acquire(
- &rb->render_data_pool, sizeof(LineartBoundingArea) * rb->bounding_area_count);
+ ld->qtree.tile_count = sp_w * sp_h;
+ ld->qtree.initials = lineart_mem_acquire(&ld->render_data_pool,
+ sizeof(LineartBoundingArea) * ld->qtree.tile_count);
/* Initialize tiles. */
for (row = 0; row < sp_h; row++) {
for (col = 0; col < sp_w; col++) {
- ba = &rb->initial_bounding_areas[row * rb->tile_count_x + col];
+ ba = &ld->qtree.initials[row * ld->qtree.count_x + col];
/* Set the four direction limits. */
ba->l = span_w * col - 1.0;
@@ -3542,11 +3556,11 @@ static void lineart_main_bounding_area_make_initial(LineartRenderBuffer *rb)
/**
* Re-link adjacent tiles after one gets subdivided.
*/
-static void lineart_bounding_areas_connect_new(LineartRenderBuffer *rb, LineartBoundingArea *root)
+static void lineart_bounding_areas_connect_new(LineartData *ld, LineartBoundingArea *root)
{
LineartBoundingArea *ba = root->child, *tba;
LinkData *lip2, *next_lip;
- LineartStaticMemPool *mph = &rb->render_data_pool;
+ LineartStaticMemPool *mph = &ld->render_data_pool;
/* Inter-connection with newly created 4 child bounding areas. */
lineart_list_append_pointer_pool(&ba[1].rp, mph, &ba[0]);
@@ -3682,54 +3696,45 @@ static void lineart_bounding_areas_connect_new(LineartRenderBuffer *rb, LineartB
BLI_listbase_clear(&root->bp);
}
-static void lineart_bounding_areas_connect_recursive(LineartRenderBuffer *rb,
- LineartBoundingArea *root)
+static void lineart_bounding_areas_connect_recursive(LineartData *ld, LineartBoundingArea *root)
{
if (root->child) {
- lineart_bounding_areas_connect_new(rb, root);
+ lineart_bounding_areas_connect_new(ld, root);
for (int i = 0; i < 4; i++) {
- lineart_bounding_areas_connect_recursive(rb, &root->child[i]);
+ lineart_bounding_areas_connect_recursive(ld, &root->child[i]);
}
}
}
-static void lineart_main_bounding_areas_connect_post(LineartRenderBuffer *rb)
+static void lineart_main_bounding_areas_connect_post(LineartData *ld)
{
- int total_tile_initial = rb->tile_count_x * rb->tile_count_y;
- int tiles_per_row = rb->tile_count_x;
+ int total_tile_initial = ld->qtree.count_x * ld->qtree.count_y;
+ int tiles_per_row = ld->qtree.count_x;
- for (int row = 0; row < rb->tile_count_y; row++) {
- for (int col = 0; col < rb->tile_count_x; col++) {
- LineartBoundingArea *ba = &rb->initial_bounding_areas[row * tiles_per_row + col];
+ for (int row = 0; row < ld->qtree.count_y; row++) {
+ for (int col = 0; col < ld->qtree.count_x; col++) {
+ LineartBoundingArea *ba = &ld->qtree.initials[row * tiles_per_row + col];
/* Link adjacent ones. */
if (row) {
lineart_list_append_pointer_pool(
- &ba->up,
- &rb->render_data_pool,
- &rb->initial_bounding_areas[(row - 1) * tiles_per_row + col]);
+ &ba->up, &ld->render_data_pool, &ld->qtree.initials[(row - 1) * tiles_per_row + col]);
}
if (col) {
lineart_list_append_pointer_pool(
- &ba->lp,
- &rb->render_data_pool,
- &rb->initial_bounding_areas[row * tiles_per_row + col - 1]);
+ &ba->lp, &ld->render_data_pool, &ld->qtree.initials[row * tiles_per_row + col - 1]);
}
- if (row != rb->tile_count_y - 1) {
+ if (row != ld->qtree.count_y - 1) {
lineart_list_append_pointer_pool(
- &ba->bp,
- &rb->render_data_pool,
- &rb->initial_bounding_areas[(row + 1) * tiles_per_row + col]);
+ &ba->bp, &ld->render_data_pool, &ld->qtree.initials[(row + 1) * tiles_per_row + col]);
}
- if (col != rb->tile_count_x - 1) {
+ if (col != ld->qtree.count_x - 1) {
lineart_list_append_pointer_pool(
- &ba->rp,
- &rb->render_data_pool,
- &rb->initial_bounding_areas[row * tiles_per_row + col + 1]);
+ &ba->rp, &ld->render_data_pool, &ld->qtree.initials[row * tiles_per_row + col + 1]);
}
}
}
for (int i = 0; i < total_tile_initial; i++) {
- lineart_bounding_areas_connect_recursive(rb, &rb->initial_bounding_areas[i]);
+ lineart_bounding_areas_connect_recursive(ld, &ld->qtree.initials[i]);
}
}
@@ -3737,12 +3742,12 @@ static void lineart_main_bounding_areas_connect_post(LineartRenderBuffer *rb)
* Subdivide a tile after one tile contains too many triangles, then re-link triangles into all the
* child tiles.
*/
-static void lineart_bounding_area_split(LineartRenderBuffer *rb,
+static void lineart_bounding_area_split(LineartData *ld,
LineartBoundingArea *root,
int recursive_level)
{
- LineartBoundingArea *ba = lineart_mem_acquire_thread(&rb->render_data_pool,
+ LineartBoundingArea *ba = lineart_mem_acquire_thread(&ld->render_data_pool,
sizeof(LineartBoundingArea) * 4);
ba[0].l = root->cx;
ba[0].r = root->r;
@@ -3795,16 +3800,16 @@ static void lineart_bounding_area_split(LineartRenderBuffer *rb,
/* Re-link triangles into child tiles, not doing intersection lines during this because this
* batch of triangles are all tested with each other for intersections. */
if (LRT_BOUND_AREA_CROSSES(b, &ba[0].l)) {
- lineart_bounding_area_link_triangle(rb, &ba[0], tri, b, 0, recursive_level + 1, false, NULL);
+ lineart_bounding_area_link_triangle(ld, &ba[0], tri, b, 0, recursive_level + 1, false, NULL);
}
if (LRT_BOUND_AREA_CROSSES(b, &ba[1].l)) {
- lineart_bounding_area_link_triangle(rb, &ba[1], tri, b, 0, recursive_level + 1, false, NULL);
+ lineart_bounding_area_link_triangle(ld, &ba[1], tri, b, 0, recursive_level + 1, false, NULL);
}
if (LRT_BOUND_AREA_CROSSES(b, &ba[2].l)) {
- lineart_bounding_area_link_triangle(rb, &ba[2], tri, b, 0, recursive_level + 1, false, NULL);
+ lineart_bounding_area_link_triangle(ld, &ba[2], tri, b, 0, recursive_level + 1, false, NULL);
}
if (LRT_BOUND_AREA_CROSSES(b, &ba[3].l)) {
- lineart_bounding_area_link_triangle(rb, &ba[3], tri, b, 0, recursive_level + 1, false, NULL);
+ lineart_bounding_area_link_triangle(ld, &ba[3], tri, b, 0, recursive_level + 1, false, NULL);
}
}
@@ -3812,15 +3817,15 @@ static void lineart_bounding_area_split(LineartRenderBuffer *rb,
* inserted, so assign root->child for #lineart_bounding_area_link_triangle to use. */
root->child = ba;
- rb->bounding_area_count += 3;
+ ld->qtree.tile_count += 3;
}
-static bool lineart_bounding_area_edge_intersect(LineartRenderBuffer *UNUSED(fb),
+static bool lineart_bounding_area_edge_intersect(LineartData *UNUSED(fb),
const double l[2],
const double r[2],
LineartBoundingArea *ba)
{
- double vx, vy;
+ double dx, dy;
double converted[4];
double c1, c;
@@ -3831,25 +3836,25 @@ static bool lineart_bounding_area_edge_intersect(LineartRenderBuffer *UNUSED(fb)
return false;
}
- vx = l[0] - r[0];
- vy = l[1] - r[1];
+ dx = l[0] - r[0];
+ dy = l[1] - r[1];
- c1 = vx * (converted[2] - l[1]) - vy * (converted[0] - l[0]);
+ c1 = dx * (converted[2] - l[1]) - dy * (converted[0] - l[0]);
c = c1;
- c1 = vx * (converted[2] - l[1]) - vy * (converted[1] - l[0]);
+ c1 = dx * (converted[2] - l[1]) - dy * (converted[1] - l[0]);
if (c1 * c <= 0) {
return true;
}
c = c1;
- c1 = vx * (converted[3] - l[1]) - vy * (converted[0] - l[0]);
+ c1 = dx * (converted[3] - l[1]) - dy * (converted[0] - l[0]);
if (c1 * c <= 0) {
return true;
}
c = c1;
- c1 = vx * (converted[3] - l[1]) - vy * (converted[1] - l[0]);
+ c1 = dx * (converted[3] - l[1]) - dy * (converted[1] - l[0]);
if (c1 * c <= 0) {
return true;
}
@@ -3858,7 +3863,7 @@ static bool lineart_bounding_area_edge_intersect(LineartRenderBuffer *UNUSED(fb)
return false;
}
-static bool lineart_bounding_area_triangle_intersect(LineartRenderBuffer *fb,
+static bool lineart_bounding_area_triangle_intersect(LineartData *fb,
LineartTriangle *tri,
LineartBoundingArea *ba)
{
@@ -3895,7 +3900,7 @@ static bool lineart_bounding_area_triangle_intersect(LineartRenderBuffer *fb,
/**
* This function does two things:
*
- * 1) Builds a quad-tree under rb->InitialBoundingAreas to achieve good geometry separation for
+ * 1) Builds a quad-tree under ld->InitialBoundingAreas to achieve good geometry separation for
* fast overlapping test between triangles and lines. This acceleration structure makes the
* occlusion stage much faster.
*
@@ -3905,7 +3910,7 @@ static bool lineart_bounding_area_triangle_intersect(LineartRenderBuffer *fb,
* duplicated intersection lines.
*
*/
-static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb,
+static void lineart_bounding_area_link_triangle(LineartData *ld,
LineartBoundingArea *root_ba,
LineartTriangle *tri,
double *LRUB,
@@ -3914,7 +3919,7 @@ static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb,
bool do_intersection,
struct LineartIsecThread *th)
{
- if (!lineart_bounding_area_triangle_intersect(rb, tri, root_ba)) {
+ if (!lineart_bounding_area_triangle_intersect(ld, tri, root_ba)) {
return;
}
@@ -3935,7 +3940,7 @@ static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb,
for (int iba = 0; iba < 4; iba++) {
if (LRT_BOUND_AREA_CROSSES(B1, &old_ba->child[iba].l)) {
lineart_bounding_area_link_triangle(
- rb, &old_ba->child[iba], tri, B1, recursive, recursive_level + 1, do_intersection, th);
+ ld, &old_ba->child[iba], tri, B1, recursive, recursive_level + 1, do_intersection, th);
}
}
return;
@@ -3954,7 +3959,7 @@ static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb,
old_ba->linked_triangles[old_ba->triangle_count++] = tri;
/* Do intersections in place. */
- if (do_intersection && rb->use_intersections) {
+ if (do_intersection && ld->conf.use_intersections) {
lineart_triangle_intersect_in_bounding_area(tri, old_ba, th, old_tri_count);
}
@@ -3964,10 +3969,10 @@ static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb,
}
else { /* We need to wait for either splitting or array extension to be done. */
- if (recursive_level < rb->tile_recursive_level) {
+ if (recursive_level < ld->qtree.recursive_level) {
if (!old_ba->child) {
/* old_ba->child==NULL, means we are the thread that's doing the splitting. */
- lineart_bounding_area_split(rb, old_ba, recursive_level);
+ lineart_bounding_area_split(ld, old_ba, recursive_level);
} /* Otherwise other thread has completed the splitting process. */
}
else {
@@ -3984,7 +3989,7 @@ static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb,
/* Of course we still have our own triangle needs to be added. */
lineart_bounding_area_link_triangle(
- rb, root_ba, tri, LRUB, recursive, recursive_level, do_intersection, th);
+ ld, root_ba, tri, LRUB, recursive, recursive_level, do_intersection, th);
}
}
@@ -4003,17 +4008,16 @@ static void lineart_free_bounding_area_memory(LineartBoundingArea *ba, bool recu
}
}
}
-static void lineart_free_bounding_area_memories(LineartRenderBuffer *rb)
+static void lineart_free_bounding_area_memories(LineartData *ld)
{
- for (int i = 0; i < rb->tile_count_y; i++) {
- for (int j = 0; j < rb->tile_count_x; j++) {
- lineart_free_bounding_area_memory(&rb->initial_bounding_areas[i * rb->tile_count_x + j],
- true);
+ for (int i = 0; i < ld->qtree.count_y; i++) {
+ for (int j = 0; j < ld->qtree.count_x; j++) {
+ lineart_free_bounding_area_memory(&ld->qtree.initials[i * ld->qtree.count_x + j], true);
}
}
}
-static void lineart_bounding_area_link_edge(LineartRenderBuffer *rb,
+static void lineart_bounding_area_link_edge(LineartData *ld,
LineartBoundingArea *root_ba,
LineartEdge *e)
{
@@ -4022,20 +4026,20 @@ static void lineart_bounding_area_link_edge(LineartRenderBuffer *rb,
}
else {
if (lineart_bounding_area_edge_intersect(
- rb, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[0])) {
- lineart_bounding_area_link_edge(rb, &root_ba->child[0], e);
+ ld, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[0])) {
+ lineart_bounding_area_link_edge(ld, &root_ba->child[0], e);
}
if (lineart_bounding_area_edge_intersect(
- rb, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[1])) {
- lineart_bounding_area_link_edge(rb, &root_ba->child[1], e);
+ ld, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[1])) {
+ lineart_bounding_area_link_edge(ld, &root_ba->child[1], e);
}
if (lineart_bounding_area_edge_intersect(
- rb, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[2])) {
- lineart_bounding_area_link_edge(rb, &root_ba->child[2], e);
+ ld, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[2])) {
+ lineart_bounding_area_link_edge(ld, &root_ba->child[2], e);
}
if (lineart_bounding_area_edge_intersect(
- rb, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[3])) {
- lineart_bounding_area_link_edge(rb, &root_ba->child[3], e);
+ ld, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[3])) {
+ lineart_bounding_area_link_edge(ld, &root_ba->child[3], e);
}
}
}
@@ -4043,16 +4047,16 @@ static void lineart_bounding_area_link_edge(LineartRenderBuffer *rb,
/**
* Link lines to their respective bounding areas.
*/
-static void lineart_main_link_lines(LineartRenderBuffer *rb)
+static void lineart_main_link_lines(LineartData *ld)
{
LRT_ITER_ALL_LINES_BEGIN
{
int r1, r2, c1, c2, row, col;
- if (lineart_get_edge_bounding_areas(rb, e, &r1, &r2, &c1, &c2)) {
+ if (lineart_get_edge_bounding_areas(ld, e, &r1, &r2, &c1, &c2)) {
for (row = r1; row != r2 + 1; row++) {
for (col = c1; col != c2 + 1; col++) {
lineart_bounding_area_link_edge(
- rb, &rb->initial_bounding_areas[row * rb->tile_count_x + col], e);
+ ld, &ld->qtree.initials[row * ld->qtree.count_x + col], e);
}
}
}
@@ -4060,14 +4064,10 @@ static void lineart_main_link_lines(LineartRenderBuffer *rb)
LRT_ITER_ALL_LINES_END
}
-static bool lineart_get_triangle_bounding_areas(LineartRenderBuffer *rb,
- LineartTriangle *tri,
- int *rowbegin,
- int *rowend,
- int *colbegin,
- int *colend)
+static bool lineart_get_triangle_bounding_areas(
+ LineartData *ld, LineartTriangle *tri, int *rowbegin, int *rowend, int *colbegin, int *colend)
{
- double sp_w = rb->width_per_tile, sp_h = rb->height_per_tile;
+ double sp_w = ld->qtree.tile_width, sp_h = ld->qtree.tile_height;
double b[4];
if (!tri->v[0] || !tri->v[1] || !tri->v[2]) {
@@ -4085,14 +4085,14 @@ static bool lineart_get_triangle_bounding_areas(LineartRenderBuffer *rb,
(*colbegin) = (int)((b[0] + 1.0) / sp_w);
(*colend) = (int)((b[1] + 1.0) / sp_w);
- (*rowend) = rb->tile_count_y - (int)((b[2] + 1.0) / sp_h) - 1;
- (*rowbegin) = rb->tile_count_y - (int)((b[3] + 1.0) / sp_h) - 1;
+ (*rowend) = ld->qtree.count_y - (int)((b[2] + 1.0) / sp_h) - 1;
+ (*rowbegin) = ld->qtree.count_y - (int)((b[3] + 1.0) / sp_h) - 1;
- if ((*colend) >= rb->tile_count_x) {
- (*colend) = rb->tile_count_x - 1;
+ if ((*colend) >= ld->qtree.count_x) {
+ (*colend) = ld->qtree.count_x - 1;
}
- if ((*rowend) >= rb->tile_count_y) {
- (*rowend) = rb->tile_count_y - 1;
+ if ((*rowend) >= ld->qtree.count_y) {
+ (*rowend) = ld->qtree.count_y - 1;
}
if ((*colbegin) < 0) {
(*colbegin) = 0;
@@ -4104,14 +4104,10 @@ static bool lineart_get_triangle_bounding_areas(LineartRenderBuffer *rb,
return true;
}
-static bool lineart_get_edge_bounding_areas(LineartRenderBuffer *rb,
- LineartEdge *e,
- int *rowbegin,
- int *rowend,
- int *colbegin,
- int *colend)
+static bool lineart_get_edge_bounding_areas(
+ LineartData *ld, LineartEdge *e, int *rowbegin, int *rowend, int *colbegin, int *colend)
{
- double sp_w = rb->width_per_tile, sp_h = rb->height_per_tile;
+ double sp_w = ld->qtree.tile_width, sp_h = ld->qtree.tile_height;
double b[4];
if (!e->v1 || !e->v2) {
@@ -4133,31 +4129,29 @@ static bool lineart_get_edge_bounding_areas(LineartRenderBuffer *rb,
(*colbegin) = (int)((b[0] + 1.0) / sp_w);
(*colend) = (int)((b[1] + 1.0) / sp_w);
- (*rowend) = rb->tile_count_y - (int)((b[2] + 1.0) / sp_h) - 1;
- (*rowbegin) = rb->tile_count_y - (int)((b[3] + 1.0) / sp_h) - 1;
+ (*rowend) = ld->qtree.count_y - (int)((b[2] + 1.0) / sp_h) - 1;
+ (*rowbegin) = ld->qtree.count_y - (int)((b[3] + 1.0) / sp_h) - 1;
/* It's possible that the line stretches too much out to the side, resulting negative value. */
if ((*rowend) < (*rowbegin)) {
- (*rowend) = rb->tile_count_y - 1;
+ (*rowend) = ld->qtree.count_y - 1;
}
if ((*colend) < (*colbegin)) {
- (*colend) = rb->tile_count_x - 1;
+ (*colend) = ld->qtree.count_x - 1;
}
- CLAMP((*colbegin), 0, rb->tile_count_x - 1);
- CLAMP((*rowbegin), 0, rb->tile_count_y - 1);
- CLAMP((*colend), 0, rb->tile_count_x - 1);
- CLAMP((*rowend), 0, rb->tile_count_y - 1);
+ CLAMP((*colbegin), 0, ld->qtree.count_x - 1);
+ CLAMP((*rowbegin), 0, ld->qtree.count_y - 1);
+ CLAMP((*colend), 0, ld->qtree.count_x - 1);
+ CLAMP((*rowend), 0, ld->qtree.count_y - 1);
return true;
}
-LineartBoundingArea *MOD_lineart_get_parent_bounding_area(LineartRenderBuffer *rb,
- double x,
- double y)
+LineartBoundingArea *MOD_lineart_get_parent_bounding_area(LineartData *ld, double x, double y)
{
- double sp_w = rb->width_per_tile, sp_h = rb->height_per_tile;
+ double sp_w = ld->qtree.tile_width, sp_h = ld->qtree.tile_height;
int col, row;
if (x > 1 || x < -1 || y > 1 || y < -1) {
@@ -4165,13 +4159,13 @@ LineartBoundingArea *MOD_lineart_get_parent_bounding_area(LineartRenderBuffer *r
}
col = (int)((x + 1.0) / sp_w);
- row = rb->tile_count_y - (int)((y + 1.0) / sp_h) - 1;
+ row = ld->qtree.count_y - (int)((y + 1.0) / sp_h) - 1;
- if (col >= rb->tile_count_x) {
- col = rb->tile_count_x - 1;
+ if (col >= ld->qtree.count_x) {
+ col = ld->qtree.count_x - 1;
}
- if (row >= rb->tile_count_y) {
- row = rb->tile_count_y - 1;
+ if (row >= ld->qtree.count_y) {
+ row = ld->qtree.count_y - 1;
}
if (col < 0) {
col = 0;
@@ -4180,29 +4174,29 @@ LineartBoundingArea *MOD_lineart_get_parent_bounding_area(LineartRenderBuffer *r
row = 0;
}
- return &rb->initial_bounding_areas[row * rb->tile_count_x + col];
+ return &ld->qtree.initials[row * ld->qtree.count_x + col];
}
-static LineartBoundingArea *lineart_get_bounding_area(LineartRenderBuffer *rb, double x, double y)
+static LineartBoundingArea *lineart_get_bounding_area(LineartData *ld, double x, double y)
{
LineartBoundingArea *iba;
- double sp_w = rb->width_per_tile, sp_h = rb->height_per_tile;
+ double sp_w = ld->qtree.tile_width, sp_h = ld->qtree.tile_height;
int c = (int)((x + 1.0) / sp_w);
- int r = rb->tile_count_y - (int)((y + 1.0) / sp_h) - 1;
+ int r = ld->qtree.count_y - (int)((y + 1.0) / sp_h) - 1;
if (r < 0) {
r = 0;
}
if (c < 0) {
c = 0;
}
- if (r >= rb->tile_count_y) {
- r = rb->tile_count_y - 1;
+ if (r >= ld->qtree.count_y) {
+ r = ld->qtree.count_y - 1;
}
- if (c >= rb->tile_count_x) {
- c = rb->tile_count_x - 1;
+ if (c >= ld->qtree.count_x) {
+ c = ld->qtree.count_x - 1;
}
- iba = &rb->initial_bounding_areas[r * rb->tile_count_x + c];
+ iba = &ld->qtree.initials[r * ld->qtree.count_x + c];
while (iba->child) {
if (x > iba->cx) {
if (y > iba->cy) {
@@ -4224,49 +4218,48 @@ static LineartBoundingArea *lineart_get_bounding_area(LineartRenderBuffer *rb, d
return iba;
}
-LineartBoundingArea *MOD_lineart_get_bounding_area(LineartRenderBuffer *rb, double x, double y)
+LineartBoundingArea *MOD_lineart_get_bounding_area(LineartData *ld, double x, double y)
{
LineartBoundingArea *ba;
- if ((ba = MOD_lineart_get_parent_bounding_area(rb, x, y)) != NULL) {
- return lineart_get_bounding_area(rb, x, y);
+ if ((ba = MOD_lineart_get_parent_bounding_area(ld, x, y)) != NULL) {
+ return lineart_get_bounding_area(ld, x, y);
}
return NULL;
}
static void lineart_add_triangles_worker(TaskPool *__restrict UNUSED(pool), LineartIsecThread *th)
{
- LineartRenderBuffer *rb = th->rb;
+ LineartData *ld = th->ld;
int _dir_control = 0;
while (lineart_schedule_new_triangle_task(th)) {
for (LineartElementLinkNode *eln = th->pending_from; eln != th->pending_to->next;
eln = eln->next) {
int index_start = eln == th->pending_from ? th->index_from : 0;
int index_end = eln == th->pending_to ? th->index_to : eln->element_count;
- LineartTriangle *tri = (void *)(((uchar *)eln->pointer) + rb->triangle_size * index_start);
+ LineartTriangle *tri = (void *)(((uchar *)eln->pointer) + ld->sizeof_triangle * index_start);
for (int ei = index_start; ei < index_end; ei++) {
int x1, x2, y1, y2;
int r, co;
if ((tri->flags & LRT_CULL_USED) || (tri->flags & LRT_CULL_DISCARD)) {
- tri = (void *)(((uchar *)tri) + rb->triangle_size);
+ tri = (void *)(((uchar *)tri) + ld->sizeof_triangle);
continue;
}
- if (lineart_get_triangle_bounding_areas(rb, tri, &y1, &y2, &x1, &x2)) {
+ if (lineart_get_triangle_bounding_areas(ld, tri, &y1, &y2, &x1, &x2)) {
_dir_control++;
for (co = x1; co <= x2; co++) {
for (r = y1; r <= y2; r++) {
- lineart_bounding_area_link_triangle(
- rb,
- &rb->initial_bounding_areas[r * rb->tile_count_x + co],
- tri,
- 0,
- 1,
- 0,
- (!(tri->flags & LRT_TRIANGLE_NO_INTERSECTION)),
- th);
+ lineart_bounding_area_link_triangle(ld,
+ &ld->qtree.initials[r * ld->qtree.count_x + co],
+ tri,
+ 0,
+ 1,
+ 0,
+ (!(tri->flags & LRT_TRIANGLE_NO_INTERSECTION)),
+ th);
}
}
} /* Else throw away. */
- tri = (void *)(((uchar *)tri) + rb->triangle_size);
+ tri = (void *)(((uchar *)tri) + ld->sizeof_triangle);
}
}
}
@@ -4274,9 +4267,9 @@ static void lineart_add_triangles_worker(TaskPool *__restrict UNUSED(pool), Line
static void lineart_create_edges_from_isec_data(LineartIsecData *d)
{
- LineartRenderBuffer *rb = d->rb;
- double ZMax = rb->far_clip;
- double ZMin = rb->near_clip;
+ LineartData *ld = d->ld;
+ double ZMax = ld->conf.far_clip;
+ double ZMin = ld->conf.near_clip;
for (int i = 0; i < d->thread_count; i++) {
LineartIsecThread *th = &d->threads[i];
@@ -4289,9 +4282,9 @@ static void lineart_create_edges_from_isec_data(LineartIsecData *d)
/* We don't care about removing duplicated vert in this method, chaining can handle that,
* and it saves us from using locks and look up tables. */
LineartVertIntersection *v = lineart_mem_acquire(
- &rb->render_data_pool, sizeof(LineartVertIntersection) * th->current * 2);
- LineartEdge *e = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdge) * th->current);
- LineartEdgeSegment *es = lineart_mem_acquire(&rb->render_data_pool,
+ &ld->render_data_pool, sizeof(LineartVertIntersection) * th->current * 2);
+ LineartEdge *e = lineart_mem_acquire(&ld->render_data_pool, sizeof(LineartEdge) * th->current);
+ LineartEdgeSegment *es = lineart_mem_acquire(&ld->render_data_pool,
sizeof(LineartEdgeSegment) * th->current);
for (int j = 0; j < th->current; j++) {
LineartVertIntersection *v1i = v;
@@ -4307,15 +4300,15 @@ static void lineart_create_edges_from_isec_data(LineartIsecData *d)
copy_v3db_v3fl(v2->gloc, is->v2);
/* 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_v4_m4v3_db(v1->fbcoord, ld->conf.view_projection, v1->gloc);
+ mul_v4_m4v3_db(v2->fbcoord, ld->conf.view_projection, v2->gloc);
mul_v3db_db(v1->fbcoord, (1 / v1->fbcoord[3]));
mul_v3db_db(v2->fbcoord, (1 / v2->fbcoord[3]));
- v1->fbcoord[0] -= rb->shift_x * 2;
- v1->fbcoord[1] -= rb->shift_y * 2;
- v2->fbcoord[0] -= rb->shift_x * 2;
- v2->fbcoord[1] -= rb->shift_y * 2;
+ v1->fbcoord[0] -= ld->conf.shift_x * 2;
+ v1->fbcoord[1] -= ld->conf.shift_y * 2;
+ v2->fbcoord[0] -= ld->conf.shift_x * 2;
+ v2->fbcoord[1] -= ld->conf.shift_y * 2;
/* This z transformation is not the same as the rest of the part, because the data don't go
* through normal perspective division calls in the pipeline, but this way the 3D result and
@@ -4331,7 +4324,7 @@ static void lineart_create_edges_from_isec_data(LineartIsecData *d)
e->intersection_mask = (is->tri1->intersection_mask | is->tri2->intersection_mask);
BLI_addtail(&e->segments, es);
- lineart_add_edge_to_array(&rb->pending_edges, e);
+ lineart_add_edge_to_array(&ld->pending_edges, e);
v += 2;
e++;
@@ -4344,7 +4337,7 @@ static void lineart_create_edges_from_isec_data(LineartIsecData *d)
* Sequentially add triangles into render buffer, intersection lines between those triangles will
* also be computed at the same time.
*/
-static void lineart_main_add_triangles(LineartRenderBuffer *rb)
+static void lineart_main_add_triangles(LineartData *ld)
{
double t_start;
if (G.debug_value == 4000) {
@@ -4354,10 +4347,10 @@ static void lineart_main_add_triangles(LineartRenderBuffer *rb)
/* Initialize per-thread data for thread task scheduling information and storing intersection
* results. */
LineartIsecData d = {0};
- lineart_init_isec_thread(&d, rb, rb->thread_count);
+ lineart_init_isec_thread(&d, ld, ld->thread_count);
TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH);
- for (int i = 0; i < rb->thread_count; i++) {
+ for (int i = 0; i < ld->thread_count; i++) {
BLI_task_pool_push(tp, (TaskRunFunction)lineart_add_triangles_worker, &d.threads[i], 0, NULL);
}
BLI_task_pool_work_and_wait(tp);
@@ -4378,8 +4371,7 @@ static void lineart_main_add_triangles(LineartRenderBuffer *rb)
* This function gets the tile for the point `e->v1`, and later use #lineart_bounding_area_next()
* to get next along the way.
*/
-static LineartBoundingArea *lineart_edge_first_bounding_area(LineartRenderBuffer *rb,
- LineartEdge *e)
+static LineartBoundingArea *lineart_edge_first_bounding_area(LineartData *ld, LineartEdge *e)
{
double data[2] = {e->v1->fbcoord[0], e->v1->fbcoord[1]};
double LU[2] = {-1, 1}, RU[2] = {1, 1}, LB[2] = {-1, -1}, RB[2] = {1, -1};
@@ -4387,7 +4379,7 @@ static LineartBoundingArea *lineart_edge_first_bounding_area(LineartRenderBuffer
bool p_unused;
if (data[0] > -1 && data[0] < 1 && data[1] > -1 && data[1] < 1) {
- return lineart_get_bounding_area(rb, data[0], data[1]);
+ return lineart_get_bounding_area(ld, data[0], data[1]);
}
if (lineart_intersect_seg_seg(e->v1->fbcoord, e->v2->fbcoord, LU, RU, &sr, &p_unused) &&
@@ -4408,7 +4400,7 @@ static LineartBoundingArea *lineart_edge_first_bounding_area(LineartRenderBuffer
}
interp_v2_v2v2_db(data, e->v1->fbcoord, e->v2->fbcoord, r);
- return lineart_get_bounding_area(rb, data[0], data[1]);
+ return lineart_get_bounding_area(ld, data[0], data[1]);
}
/**
@@ -4639,7 +4631,7 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph,
LineartCache **cached_result,
bool enable_stroke_depth_offset)
{
- LineartRenderBuffer *rb;
+ LineartData *ld;
Scene *scene = DEG_get_evaluated_scene(depsgraph);
int intersections_only = 0; /* Not used right now, but preserve for future. */
Object *use_camera;
@@ -4650,8 +4642,6 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph,
t_start = PIL_check_seconds_timer();
}
- BKE_scene_camera_switch_update(scene);
-
if (lmd->calculation_flags & LRT_USE_CUSTOM_CAMERA) {
if (!lmd->source_camera ||
(use_camera = DEG_get_evaluated_object(depsgraph, lmd->source_camera))->type !=
@@ -4660,6 +4650,9 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph,
}
}
else {
+
+ BKE_scene_camera_switch_update(scene);
+
if (!scene->camera) {
return false;
}
@@ -4669,58 +4662,53 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph,
LineartCache *lc = lineart_init_cache();
*cached_result = lc;
- rb = lineart_create_render_buffer(scene, lmd, use_camera, scene->camera, lc);
+ ld = lineart_create_render_buffer(scene, lmd, use_camera, scene->camera, lc);
/* Triangle thread testing data size varies depending on the thread count.
* See definition of LineartTriangleThread for details. */
- rb->triangle_size = lineart_triangle_size_get(rb);
-
- /* FIXME(Yiming): See definition of int #LineartRenderBuffer::_source_type for detailed. */
- rb->_source_type = lmd->source_type;
- rb->_source_collection = lmd->source_collection;
- rb->_source_object = lmd->source_object;
+ ld->sizeof_triangle = lineart_triangle_size_get(ld);
/* Get view vector before loading geometries, because we detect feature lines there. */
- lineart_main_get_view_vector(rb);
+ lineart_main_get_view_vector(ld);
lineart_main_load_geometries(
- depsgraph, scene, use_camera, rb, lmd->calculation_flags & LRT_ALLOW_DUPLI_OBJECTS);
+ depsgraph, scene, use_camera, ld, lmd->calculation_flags & LRT_ALLOW_DUPLI_OBJECTS);
- if (!rb->vertex_buffer_pointers.first) {
+ if (!ld->geom.vertex_buffer_pointers.first) {
/* No geometry loaded, return early. */
return true;
}
/* Initialize the bounding box acceleration structure, it's a lot like BVH in 3D. */
- lineart_main_bounding_area_make_initial(rb);
+ lineart_main_bounding_area_make_initial(ld);
/* We need to get cut into triangles that are crossing near/far plans, only this way can we get
* correct coordinates of those clipped lines. Done in two steps,
* setting clip_far==false for near plane. */
- lineart_main_cull_triangles(rb, false);
+ lineart_main_cull_triangles(ld, false);
/* `clip_far == true` for far plane. */
- lineart_main_cull_triangles(rb, true);
+ lineart_main_cull_triangles(ld, true);
/* At this point triangle adjacent info pointers is no longer needed, free them. */
- lineart_main_free_adjacent_data(rb);
+ lineart_main_free_adjacent_data(ld);
/* Do the perspective division after clipping is done. */
- lineart_main_perspective_division(rb);
+ lineart_main_perspective_division(ld);
- lineart_main_discard_out_of_frame_edges(rb);
+ lineart_main_discard_out_of_frame_edges(ld);
/* 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. */
- lineart_main_add_triangles(rb);
+ lineart_main_add_triangles(ld);
/* Re-link bounding areas because they have been subdivided by worker threads and we need
* adjacent info. */
- lineart_main_bounding_areas_connect_post(rb);
+ lineart_main_bounding_areas_connect_post(ld);
/* 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);
+ lineart_main_link_lines(ld);
/* "intersection_only" is preserved for being called in a standalone fashion.
* If so the data will already be available at the stage. Otherwise we do the occlusion and
@@ -4729,54 +4717,54 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph,
if (!intersections_only) {
/* Occlusion is work-and-wait. This call will not return before work is completed. */
- lineart_main_occlusion_begin(rb);
+ lineart_main_occlusion_begin(ld);
/* 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. */
- MOD_lineart_chain_feature_lines(rb);
+ MOD_lineart_chain_feature_lines(ld);
/* 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);
+ MOD_lineart_chain_split_for_fixed_occlusion(ld);
/* Then we connect chains based on the _proximity_ of their end points in image space, here's
* the place threshold value gets involved. */
- MOD_lineart_chain_connect(rb);
+ MOD_lineart_chain_connect(ld);
float *t_image = &lmd->chaining_image_threshold;
/* This configuration ensures there won't be accidental lost of short unchained segments. */
- MOD_lineart_chain_discard_short(rb, MIN2(*t_image, 0.001f) - FLT_EPSILON);
+ MOD_lineart_chain_discard_short(ld, MIN2(*t_image, 0.001f) - FLT_EPSILON);
- if (rb->chain_smooth_tolerance > FLT_EPSILON) {
+ if (ld->conf.chain_smooth_tolerance > FLT_EPSILON) {
/* Keeping UI range of 0-1 for ease of read while scaling down the actual value for best
* effective range in image-space (Coordinate only goes from -1 to 1). This value is
* somewhat arbitrary, but works best for the moment. */
- MOD_lineart_smooth_chains(rb, rb->chain_smooth_tolerance / 50);
+ MOD_lineart_smooth_chains(ld, ld->conf.chain_smooth_tolerance / 50);
}
- if (rb->use_image_boundary_trimming) {
- MOD_lineart_chain_clip_at_border(rb);
+ if (ld->conf.use_image_boundary_trimming) {
+ MOD_lineart_chain_clip_at_border(ld);
}
- if (rb->angle_splitting_threshold > FLT_EPSILON) {
- MOD_lineart_chain_split_angle(rb, rb->angle_splitting_threshold);
+ if (ld->conf.angle_splitting_threshold > FLT_EPSILON) {
+ MOD_lineart_chain_split_angle(ld, ld->conf.angle_splitting_threshold);
}
if (enable_stroke_depth_offset && lmd->stroke_depth_offset > FLT_EPSILON) {
MOD_lineart_chain_offset_towards_camera(
- rb, lmd->stroke_depth_offset, lmd->flags & LRT_GPENCIL_OFFSET_TOWARDS_CUSTOM_CAMERA);
+ ld, lmd->stroke_depth_offset, lmd->flags & LRT_GPENCIL_OFFSET_TOWARDS_CUSTOM_CAMERA);
}
/* Finally transfer the result list into cache. */
- memcpy(&lc->chains, &rb->chains, sizeof(ListBase));
+ memcpy(&lc->chains, &ld->chains, sizeof(ListBase));
/* At last, we need to clear flags so we don't confuse GPencil generation calls. */
MOD_lineart_chain_clear_picked_flag(lc);
}
if (G.debug_value == 4000) {
- lineart_count_and_print_render_buffer_memory(rb);
+ lineart_count_and_print_render_buffer_memory(ld);
double t_elapsed = PIL_check_seconds_timer() - t_start;
printf("Line art total time: %lf\n", t_elapsed);
@@ -4785,15 +4773,15 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph,
return true;
}
-static int UNUSED_FUNCTION(lineart_rb_edge_types)(LineartRenderBuffer *rb)
+static int UNUSED_FUNCTION(lineart_rb_edge_types)(LineartData *ld)
{
int types = 0;
- types |= rb->use_contour ? LRT_EDGE_FLAG_CONTOUR : 0;
- types |= rb->use_crease ? LRT_EDGE_FLAG_CREASE : 0;
- types |= rb->use_material ? LRT_EDGE_FLAG_MATERIAL : 0;
- types |= rb->use_edge_marks ? LRT_EDGE_FLAG_EDGE_MARK : 0;
- types |= rb->use_intersections ? LRT_EDGE_FLAG_INTERSECTION : 0;
- types |= rb->use_loose ? LRT_EDGE_FLAG_LOOSE : 0;
+ types |= ld->conf.use_contour ? LRT_EDGE_FLAG_CONTOUR : 0;
+ types |= ld->conf.use_crease ? LRT_EDGE_FLAG_CREASE : 0;
+ types |= ld->conf.use_material ? LRT_EDGE_FLAG_MATERIAL : 0;
+ types |= ld->conf.use_edge_marks ? LRT_EDGE_FLAG_EDGE_MARK : 0;
+ types |= ld->conf.use_intersections ? LRT_EDGE_FLAG_INTERSECTION : 0;
+ types |= ld->conf.use_loose ? LRT_EDGE_FLAG_LOOSE : 0;
return types;
}
@@ -4812,7 +4800,7 @@ static void lineart_gpencil_generate(LineartCache *cache,
uchar mask_switches,
uchar material_mask_bits,
uchar intersection_mask,
- short thickness,
+ int16_t thickness,
float opacity,
const char *source_vgname,
const char *vgname,
@@ -4971,16 +4959,16 @@ void MOD_lineart_gpencil_generate(LineartCache *cache,
Object *ob,
bGPDlayer *gpl,
bGPDframe *gpf,
- char source_type,
+ int8_t source_type,
void *source_reference,
int level_start,
int level_end,
int mat_nr,
- short edge_types,
+ int16_t edge_types,
uchar mask_switches,
uchar material_mask_bits,
uchar intersection_mask,
- short thickness,
+ int16_t thickness,
float opacity,
const char *source_vgname,
const char *vgname,
@@ -4993,7 +4981,7 @@ void MOD_lineart_gpencil_generate(LineartCache *cache,
Object *source_object = NULL;
Collection *source_collection = NULL;
- short use_types = 0;
+ int16_t use_types = 0;
if (source_type == LRT_SOURCE_OBJECT) {
if (!source_reference) {
return;