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')
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c291
1 files changed, 62 insertions, 229 deletions
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index dd08fc6493f..88ac80e153f 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -1514,7 +1514,6 @@ typedef struct EdgeFeatData {
LineartRenderBuffer *rb;
Mesh *me;
const MLoopTri *mlooptri;
- EdgeFacePair *edge_pair_arr;
LineartTriangle *tri_array;
LineartVert *v_array;
float crease_threshold;
@@ -1522,6 +1521,7 @@ typedef struct EdgeFeatData {
bool use_auto_smooth;
bool use_freestyle_face;
int freestyle_face_index;
+ LineartEdgeNeighbor *en;
} EdgeFeatData;
typedef struct EdgeFeatReduceData {
@@ -1537,18 +1537,22 @@ static void feat_data_sum_reduce(const void *__restrict UNUSED(userdata),
feat_chunk_join->feat_edges += feat_chunk->feat_edges;
}
-static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
- const int i,
- const TaskParallelTLS *__restrict tls)
+__attribute__((optimize("O0"))) static void lineart_identify_mlooptri_feature_edges(
+ void *__restrict userdata, const int i, const TaskParallelTLS *__restrict tls)
{
EdgeFeatData *e_feat_data = (EdgeFeatData *)userdata;
- EdgeFacePair *e_f_pair = &e_feat_data->edge_pair_arr[i];
EdgeFeatReduceData *reduce_data = (EdgeFeatReduceData *)tls->userdata_chunk;
Mesh *me = e_feat_data->me;
+ LineartEdgeNeighbor *en = e_feat_data->en;
const MLoopTri *mlooptri = e_feat_data->mlooptri;
uint16_t edge_flag_result = 0;
+ /* Only add one from two pairs of mlooptri edges. */
+ if (i < en[i].e) {
+ return;
+ }
+
FreestyleEdge *fel, *fer;
bool face_mark_filtered = false;
bool enable_face_mark = (e_feat_data->use_freestyle_face && e_feat_data->rb->filter_face_mark);
@@ -1556,10 +1560,10 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
if (enable_face_mark) {
int index = e_feat_data->freestyle_face_index;
if (index > -1) {
- fel = &((FreestyleEdge *)me->pdata.layers[index].data)[mlooptri[e_f_pair->f1].poly];
+ fel = &((FreestyleEdge *)me->pdata.layers[index].data)[mlooptri[i / 3].poly];
}
- if (e_f_pair->f2 != -1) {
- fer = &((FreestyleEdge *)me->pdata.layers[index].data)[mlooptri[e_f_pair->f2].poly];
+ if (en[i].e > -1) {
+ fer = &((FreestyleEdge *)me->pdata.layers[index].data)[mlooptri[en[i].e / 3].poly];
}
else {
/* Handles mesh boundary case */
@@ -1579,7 +1583,7 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
face_mark_filtered = !face_mark_filtered;
}
if (!face_mark_filtered) {
- e_f_pair->eflag = LRT_EDGE_FLAG_INHIBIT;
+ en[i].flags = LRT_EDGE_FLAG_INHIBIT;
if (e_feat_data->rb->filter_face_mark_keep_contour) {
only_contour = true;
}
@@ -1592,8 +1596,8 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
else {
/* Mesh boundary */
- if (e_f_pair->f2 == -1) {
- e_f_pair->eflag = LRT_EDGE_FLAG_CONTOUR;
+ if (en[i].e == -1) {
+ en[i].flags = LRT_EDGE_FLAG_CONTOUR;
reduce_data->feat_edges += 1;
return;
}
@@ -1602,11 +1606,13 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
LineartVert *vert;
LineartRenderBuffer *rb = e_feat_data->rb;
+ int f1 = i / 3, f2 = en[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, e_f_pair->f1);
- tri2 = lineart_triangle_from_index(rb, e_feat_data->tri_array, e_f_pair->f2);
+ tri1 = lineart_triangle_from_index(rb, e_feat_data->tri_array, f1);
+ tri2 = lineart_triangle_from_index(rb, e_feat_data->tri_array, f2);
- vert = &e_feat_data->v_array[e_f_pair->v1];
+ vert = &e_feat_data->v_array[en[i].v1];
double vv[3];
double *view_vector = vv;
@@ -1632,8 +1638,8 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
if (rb->use_crease) {
bool do_crease = true;
if (!rb->force_crease && !e_feat_data->use_auto_smooth &&
- (me->mpoly[mlooptri[e_f_pair->f1].poly].flag & ME_SMOOTH) &&
- (me->mpoly[mlooptri[e_f_pair->f2].poly].flag & ME_SMOOTH)) {
+ (me->mpoly[mlooptri[f1].poly].flag & ME_SMOOTH) &&
+ (me->mpoly[mlooptri[f2].poly].flag & ME_SMOOTH)) {
do_crease = false;
}
if (do_crease && (dot_v3v3_db(tri1->gn, tri2->gn) < e_feat_data->crease_threshold)) {
@@ -1641,8 +1647,8 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
}
}
- int mat1 = me->mpoly[mlooptri[e_f_pair->f1].poly].mat_nr;
- int mat2 = me->mpoly[mlooptri[e_f_pair->f2].poly].mat_nr;
+ int mat1 = me->mpoly[mlooptri[f1].poly].mat_nr;
+ int mat2 = me->mpoly[mlooptri[f2].poly].mat_nr;
if (rb->use_material && mat1 != mat2) {
edge_flag_result |= LRT_EDGE_FLAG_MATERIAL;
@@ -1654,7 +1660,7 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
}
}
- e_f_pair->eflag = edge_flag_result;
+ en[i].flags = edge_flag_result;
if (edge_flag_result) {
/* Only allocate for feature edge (instead of all edges) to save memory.
@@ -1708,23 +1714,20 @@ __attribute__((optimize("O0"))) static uint16_t lineart_identify_feature_line_me
MPoly *ll = NULL, *lr = NULL;
- int t1i = -1, t1e = -1, t2i = -1;
+ int t1i = eindex / 3, t2i = -1;
if (en[eindex].e >= 0) {
- t1i = en[eindex].e / 3;
- t1e = en[eindex].e;
- }
- if (t1e >= 0 && en[t1e].e >= 0) {
- t2i = en[t1e].e / 3;
+ t2i = en[t1i].e / 3;
}
- if (t1i >= 0) {
- ll = &me->mpoly[me->runtime.looptris.array[t1i].poly];
- }
+ ll = &me->mpoly[me->runtime.looptris.array[t1i].poly];
+
if (t2i >= 0) {
lr = &me->mpoly[me->runtime.looptris.array[t2i].poly];
}
- if (t1i < 0 && t2i < 0) {
+ /* Because this function is called through looptris, so it's not really possible that both
+ * adjacent triangles are not present. */
+ if (UNLIKELY(t1i < 0 && t2i < 0)) {
if (!rb->use_loose_as_contour) {
if (use_freestyle_face && rb->filter_face_mark) {
if (rb->filter_face_mark_invert) {
@@ -1925,16 +1928,8 @@ typedef struct TriData {
LineartTriangle *tri_arr;
int lineart_triangle_size;
LineartTriangleAdjacent *tri_adj;
- LineartEdgeNeighbor *en;
} TriData;
-typedef struct TriDataReduce {
- EdgeHash *edge_hash;
- EdgeFacePair *edge_pair_arr;
- int arr_cur_len;
- int arr_alloc_len;
-} TriDataReduce;
-
static void lineart_load_tri_task(void *__restrict userdata,
const int i,
const TaskParallelTLS *__restrict tls)
@@ -1983,91 +1978,6 @@ static void lineart_load_tri_task(void *__restrict userdata,
/* Re-use this field to refer to adjacent info, will be cleared after culling stage. */
tri->intersecting_verts = (void *)&tri_task_data->tri_adj[i];
-
- TriDataReduce *reduce_data = (TriDataReduce *)tls->userdata_chunk;
- /* Initialize the edgehash if it hasn't been allocated already. */
- if (reduce_data->edge_hash == NULL) {
- reduce_data->edge_hash = BLI_edgehash_new_ex("lineart mesh conv", 256);
- }
- if (reduce_data->edge_pair_arr == NULL) {
- reduce_data->edge_pair_arr = MEM_mallocN(sizeof(EdgeFacePair) * 256, "lineart tri_pair_arr");
- reduce_data->arr_alloc_len = 256;
- }
- EdgeFacePair *edge_pair_arr = reduce_data->edge_pair_arr;
-
- /* Add the triangle edge to the edge hash. */
- for (int e = 0; e < 3; e++) {
- v1 = me->mloop[mlooptri->tri[e]].v;
- v2 = me->mloop[mlooptri->tri[(e + 1) % 3]].v;
- void **eval;
- if (!BLI_edgehash_ensure_p(reduce_data->edge_hash, v1, v2, &eval)) {
- int pair_idx = reduce_data->arr_cur_len++;
- /* Edge has not been added before, create a new pair. */
- EdgeFacePair *pair = &edge_pair_arr[pair_idx];
- pair->v1 = v1;
- pair->v2 = v2;
- pair->f1 = i;
- pair->f2 = -1;
- pair->eflag = 0;
- *eval = POINTER_FROM_INT(pair_idx);
-
- if (reduce_data->arr_cur_len == reduce_data->arr_alloc_len) {
- /* Allocate more space for our array. */
- reduce_data->arr_alloc_len *= 2;
- void *arr_tmp = MEM_mallocN(sizeof(EdgeFacePair) * reduce_data->arr_alloc_len,
- "lineart tri_pair_arr");
- memcpy(arr_tmp, edge_pair_arr, sizeof(EdgeFacePair) * reduce_data->arr_cur_len);
- MEM_freeN(edge_pair_arr);
- reduce_data->edge_pair_arr = edge_pair_arr = arr_tmp;
- }
- }
- else {
- /* The edge has already been added, set the second triangle to the current one. */
- EdgeFacePair *val = &edge_pair_arr[POINTER_AS_INT(*eval)];
- val->f2 = i;
- }
- }
-}
-
-static void lineart_load_tri_reduce(const void *__restrict UNUSED(userdata),
- void *__restrict chunk_join,
- void *__restrict chunk)
-{
- TriDataReduce *data_reduce = (TriDataReduce *)chunk;
- TriDataReduce *data_reduce_join = (TriDataReduce *)chunk_join;
- EdgeFacePair *edge_pair = data_reduce->edge_pair_arr;
-
- for (int i = 0; i < data_reduce->arr_cur_len; i++, edge_pair++) {
- void **eval;
- if (!BLI_edgehash_ensure_p(data_reduce_join->edge_hash, edge_pair->v1, edge_pair->v2, &eval)) {
- int pair_idx = data_reduce_join->arr_cur_len++;
- /* Edge has not been added in the other thread, add the pair. */
- EdgeFacePair *pair = &data_reduce_join->edge_pair_arr[pair_idx];
- memcpy(pair, edge_pair, sizeof(EdgeFacePair));
- *eval = POINTER_FROM_INT(pair_idx);
-
- if (data_reduce_join->arr_cur_len == data_reduce_join->arr_alloc_len) {
- /* Allocate more space for our array. */
- data_reduce_join->arr_alloc_len *= 2;
- void *arr_tmp = MEM_mallocN(sizeof(EdgeFacePair) * data_reduce_join->arr_alloc_len,
- "lineart tri_pair_arr");
- memcpy(arr_tmp,
- data_reduce_join->edge_pair_arr,
- sizeof(EdgeFacePair) * data_reduce_join->arr_cur_len);
- MEM_freeN(data_reduce_join->edge_pair_arr);
- data_reduce_join->edge_pair_arr = arr_tmp;
- }
- }
- else {
- /* The edge has already been added from an other thread, update the second triangle. */
- EdgeFacePair *val = &data_reduce_join->edge_pair_arr[POINTER_AS_INT(*eval)];
- val->f2 = edge_pair->f1;
- }
- }
-
- /* Free data from the chunk that will be left behind. */
- MEM_freeN(data_reduce->edge_pair_arr);
- BLI_edgehash_free(data_reduce->edge_hash, NULL);
}
static int cmp_adjacent_items(const void *ps1, const void *ps2)
@@ -2122,8 +2032,8 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge
return en;
}
-static void lineart_geometry_object_load_no_bmesh(LineartObjectInfo *ob_info,
- LineartRenderBuffer *re_buf)
+__attribute__((optimize("O0"))) static void lineart_geometry_object_load_no_bmesh(
+ LineartObjectInfo *ob_info, LineartRenderBuffer *re_buf)
{
LineartElementLinkNode *elem_link_node;
LineartVert *la_v_arr;
@@ -2243,11 +2153,6 @@ static void lineart_geometry_object_load_no_bmesh(LineartObjectInfo *ob_info,
/* Set the minimum amount of triangles a thread has to process. */
tri_settings.min_iter_per_thread = 4000;
- TriDataReduce reduce_data = {0};
- tri_settings.userdata_chunk = &reduce_data;
- tri_settings.userdata_chunk_size = sizeof(TriDataReduce);
- tri_settings.func_reduce = lineart_load_tri_reduce;
-
TriData tri_data;
tri_data.ob_info = ob_info;
tri_data.mlooptri = mlooptri;
@@ -2256,16 +2161,10 @@ static void lineart_geometry_object_load_no_bmesh(LineartObjectInfo *ob_info,
tri_data.lineart_triangle_size = re_buf->triangle_size;
tri_data.tri_adj = tri_adj;
- unsigned int total_edges = me->runtime.looptris.len * 3;
- tri_data.en = lineart_build_edge_neighbor(me, total_edges);
+ unsigned int total_edges = tot_tri * 3;
BLI_task_parallel_range(0, tot_tri, &tri_data, lineart_load_tri_task, &tri_settings);
- EdgeHash *edge_hash = reduce_data.edge_hash;
- EdgeFacePair *edge_pair_arr = reduce_data.edge_pair_arr;
- int edge_pair_arr_len = reduce_data.arr_cur_len;
- int edge_pair_alloc_len = reduce_data.arr_alloc_len;
-
/* Check for contour lines in the mesh.
* IE check if the triangle edges lies in area where the triangles go from front facing to back
* facing.
@@ -2284,7 +2183,7 @@ static void lineart_geometry_object_load_no_bmesh(LineartObjectInfo *ob_info,
edge_feat_data.rb = re_buf;
edge_feat_data.me = me;
edge_feat_data.mlooptri = mlooptri;
- edge_feat_data.edge_pair_arr = edge_pair_arr;
+ edge_feat_data.en = lineart_build_edge_neighbor(me, total_edges);
edge_feat_data.tri_array = la_tri_arr;
edge_feat_data.v_array = la_v_arr;
edge_feat_data.crease_threshold = use_crease;
@@ -2296,85 +2195,17 @@ static void lineart_geometry_object_load_no_bmesh(LineartObjectInfo *ob_info,
}
BLI_task_parallel_range(0,
- edge_pair_arr_len,
+ total_edges,
&edge_feat_data,
lineart_identify_mlooptri_feature_edges,
&edge_feat_settings);
int allocate_la_e = edge_reduce.feat_edges;
- if (!edge_pair_arr) {
- edge_pair_alloc_len = 256;
- edge_pair_arr = MEM_mallocN(sizeof(EdgeFacePair) * edge_pair_alloc_len,
- "lineart edge_pair arr");
- }
-
- /* Check for edge marks that would create feature edges. */
+ /* Only counting floating edges at this point because other edges has been taken care of inside
+ * #lineart_identify_mlooptri_feature_edges function. */
for (int i = 0; i < me->totedge; i++) {
- MEdge *medge = &me->medge[i];
- uint16_t eflag = lineart_identify_medge_feature_edges(
- re_buf,
- me,
- i,
- medge,
- can_find_freestyle_edge ? CustomData_get_layer_index(&me->edata, CD_FREESTYLE_EDGE) : -1);
-
- bool inhibit_feature_line = false;
-
- if (eflag) {
- int min_edges_to_add = 0;
- void **eval;
- if (edge_hash == NULL || !BLI_edgehash_ensure_p(edge_hash, medge->v1, medge->v2, &eval)) {
- int pair_idx = edge_pair_arr_len++;
- /* Edge has not been added before, create a new pair. */
- EdgeFacePair *pair = &edge_pair_arr[pair_idx];
- /* This must be a loose edge, no faces are connected. */
- pair->v1 = medge->v1;
- pair->v2 = medge->v2;
- pair->f1 = -1;
- pair->f2 = -1;
- pair->eflag = eflag;
- if (edge_hash) {
- *eval = POINTER_FROM_INT(pair_idx);
- }
- min_edges_to_add = 1;
-
- if (edge_pair_arr_len == edge_pair_alloc_len) {
- /* Allocate more space for our array. */
- edge_pair_alloc_len *= 2;
- void *arr_tmp = MEM_mallocN(sizeof(EdgeFacePair) * edge_pair_alloc_len,
- "lineart tri_pair_arr");
- memcpy(arr_tmp, edge_pair_arr, sizeof(EdgeFacePair) * edge_pair_arr_len);
- MEM_freeN(edge_pair_arr);
- edge_pair_arr = arr_tmp;
- }
- }
- else {
- /* The edge has already been added, update the eflags. */
- EdgeFacePair *val = &edge_pair_arr[POINTER_AS_INT(*eval)];
- if (val->eflag & LRT_EDGE_FLAG_INHIBIT) {
- inhibit_feature_line = true;
- }
- else {
- if (val->eflag == 0) {
- min_edges_to_add = 1;
- }
- val->eflag |= eflag;
- }
- }
- /* Only allocate for feature lines (instead of all lines) to save memory.
- * If allow duplicated edges, one edge gets added multiple times if it has multiple types.
- */
- if (!inhibit_feature_line) {
- allocate_la_e += re_buf->allow_duplicated_types ?
- lineart_edge_type_duplication_count(eflag) :
- min_edges_to_add;
- }
- }
- }
-
- if (edge_hash) {
- BLI_edgehash_free(edge_hash, NULL);
+ /* TODO. */
}
la_edge_arr = lineart_mem_acquire_thread(&re_buf->render_data_pool,
@@ -2396,11 +2227,15 @@ static void lineart_geometry_object_load_no_bmesh(LineartObjectInfo *ob_info,
la_edge = la_edge_arr;
la_seg = la_seg_arr;
- for (int i = 0; i < edge_pair_arr_len; i++) {
- EdgeFacePair *e_f_pair = &edge_pair_arr[i];
+ for (int i = 0; i < total_edges; i++) {
+ LineartEdgeNeighbor *en = &edge_feat_data.en[i];
+
+ if (i < en->e) {
+ continue;
+ }
/* Not a feature line, so we skip. */
- if (e_f_pair->eflag == 0) {
+ if (en->flags == 0) {
continue;
}
@@ -2409,26 +2244,24 @@ static void lineart_geometry_object_load_no_bmesh(LineartObjectInfo *ob_info,
/* See eLineartEdgeFlag for details. */
for (int flag_bit = 0; flag_bit < 6; flag_bit++) {
char use_type = 1 << flag_bit;
- if (!(use_type & e_f_pair->eflag)) {
+ if (!(use_type & en->flags)) {
continue;
}
- la_edge->v1 = &la_v_arr[e_f_pair->v1];
- la_edge->v2 = &la_v_arr[e_f_pair->v2];
+ la_edge->v1 = &la_v_arr[en->v1];
+ la_edge->v2 = &la_v_arr[en->v2];
la_edge->v1_obindex = la_edge->v1->index;
la_edge->v2_obindex = la_edge->v2->index;
- if (e_f_pair->f1 != -1) {
- int findex = e_f_pair->f1;
- la_edge->t1 = lineart_triangle_from_index(re_buf, la_tri_arr, findex);
+ int findex = i / 3;
+ la_edge->t1 = lineart_triangle_from_index(re_buf, la_tri_arr, findex);
+ if (!edge_added) {
+ lineart_triangle_adjacent_assign(la_edge->t1, &tri_adj[findex], la_edge);
+ }
+ if (en->e != -1) {
+ findex = en->e / 3;
+ la_edge->t2 = lineart_triangle_from_index(re_buf, la_tri_arr, findex);
if (!edge_added) {
- lineart_triangle_adjacent_assign(la_edge->t1, &tri_adj[findex], la_edge);
- }
- if (e_f_pair->f2 != -1) {
- findex = e_f_pair->f2;
- la_edge->t2 = lineart_triangle_from_index(re_buf, la_tri_arr, findex);
- if (!edge_added) {
- lineart_triangle_adjacent_assign(la_edge->t2, &tri_adj[findex], la_edge);
- }
+ lineart_triangle_adjacent_assign(la_edge->t2, &tri_adj[findex], la_edge);
}
}
la_edge->flags = use_type;
@@ -2450,7 +2283,7 @@ static void lineart_geometry_object_load_no_bmesh(LineartObjectInfo *ob_info,
}
}
- MEM_freeN(edge_pair_arr);
+ MEM_freeN(edge_feat_data.en);
if (ob_info->free_use_mesh) {
BKE_id_free(NULL, me);
@@ -2728,8 +2561,8 @@ 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_no_bmesh(obi, olti->rb);
- lineart_geometry_object_load_edge_neighbor(obi, olti->rb);
+ lineart_geometry_object_load_no_bmesh(obi, olti->rb);
+ // lineart_geometry_object_load_edge_neighbor(obi, olti->rb);
// lineart_geometry_object_load(obi, olti->rb);
printf("thread id: %d processed: %d\n", olti->thread_id, obi->original_me->totpoly);
}