diff options
Diffstat (limited to 'source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c')
-rw-r--r-- | source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c | 951 |
1 files changed, 463 insertions, 488 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..bf9303529b4 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -73,19 +73,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 +98,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 +116,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,45 +127,45 @@ 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, @@ -218,7 +213,7 @@ static void lineart_edge_cut(LineartRenderBuffer *rb, ies = es->next; if (ies->at > start + 1e-09 && start > es->at) { cut_start_before = ies; - ns = lineart_give_segment(rb); + ns = lineart_give_segment(ld); break; } } @@ -244,14 +239,14 @@ static void lineart_edge_cut(LineartRenderBuffer *rb, /* When an actual cut is needed in the line. */ if (es->at > end) { cut_end_before = es; - ns2 = lineart_give_segment(rb); + ns2 = 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); + ns = lineart_give_segment(ld); } if (ns2 == NULL) { if (untouched) { @@ -259,7 +254,7 @@ static void lineart_edge_cut(LineartRenderBuffer *rb, cut_end_before = ns2; } else { - ns2 = lineart_give_segment(rb); + ns2 = lineart_give_segment(ld); } } @@ -325,7 +320,7 @@ static void lineart_edge_cut(LineartRenderBuffer *rb, BLI_remlink(&e->segments, es); /* 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, es); continue; } @@ -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); @@ -662,17 +657,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 +676,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 +693,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 +746,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, @@ -788,8 +783,9 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb, ta = (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,7 +795,7 @@ 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) \ @@ -817,7 +813,7 @@ 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) \ @@ -903,7 +899,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 @@ -952,7 +948,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]; @@ -993,7 +989,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]; @@ -1068,7 +1064,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]; @@ -1120,7 +1116,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]; @@ -1169,7 +1165,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 +1209,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 +1240,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 +1293,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 +1315,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 +1344,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 +1381,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 +1395,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))) { @@ -1454,17 +1450,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); + 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 +1506,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 +1524,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 +1535,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,13 +1559,13 @@ 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]; @@ -1577,12 +1575,12 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, 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); @@ -1592,7 +1590,7 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, edge_flag_result |= LRT_EDGE_FLAG_CONTOUR; } - if (rb->use_back_face_culling) { + if (ld->conf.use_back_face_culling) { if (dot_1 < 0) { tri1->flags |= LRT_CULL_DISCARD; } @@ -1612,9 +1610,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 +1625,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 +1641,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 +1661,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; } @@ -1931,7 +1929,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 +1963,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 +1992,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 +2001,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 +2019,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,7 +2051,7 @@ 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; @@ -2072,7 +2072,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 +2098,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 +2114,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; @@ -2157,13 +2158,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 +2186,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,7 +2220,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); + lineart_geometry_object_load(obi, olti->ld); if (G.debug_value == 4000) { printf("thread id: %d processed: %d\n", olti->thread_id, obi->original_me->totpoly); } @@ -2356,7 +2357,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 +2367,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 +2378,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 +2401,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 +2425,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 +2444,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) { @@ -2456,23 +2458,23 @@ static void lineart_main_load_geometries( 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); - 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. */ 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 +2504,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 +2515,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 +2535,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 +2553,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); } } @@ -3164,38 +3166,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 +3207,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 +3222,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 +3292,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 +3307,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 +3369,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 +3392,97 @@ 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 +3493,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 +3505,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 +3544,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 +3684,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 +3730,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 +3788,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,10 +3805,10 @@ 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) @@ -3858,7 +3851,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 +3888,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 +3898,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 +3907,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 +3928,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 +3947,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 +3957,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 +3977,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 +3996,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 +4014,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 +4035,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 +4052,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 +4073,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 +4092,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 +4117,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 +4147,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 +4162,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 +4206,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 +4255,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 +4270,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 +4288,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 +4312,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 +4325,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 +4335,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 +4359,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 +4367,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 +4388,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 +4619,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; @@ -4669,58 +4649,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 +4704,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 +4760,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; } |