diff options
Diffstat (limited to 'source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c')
-rw-r--r-- | source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c index 28fd8ff01b9..0ee990e0f77 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c @@ -617,9 +617,14 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb) rb->chains.last = rb->chains.first = NULL; + int loop_id = 0; while ((ec = BLI_pophead(&swap)) != NULL) { ec->next = ec->prev = NULL; BLI_addtail(&rb->chains, ec); + + ec->loop_id = loop_id; + loop_id++; + LineartEdgeChainItem *first_eci = (LineartEdgeChainItem *)ec->chain.first; int fixed_occ = first_eci->occlusion; unsigned char fixed_mask = first_eci->material_mask_bits; @@ -651,6 +656,7 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb) new_ec = lineart_chain_create(rb); new_ec->chain.first = eci; new_ec->chain.last = ec->chain.last; + new_ec->loop_id = loop_id; ec->chain.last = eci->prev; ((LineartEdgeChainItem *)ec->chain.last)->next = 0; eci->prev = 0; @@ -743,6 +749,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf int occlusion, unsigned char material_mask_bits, unsigned char isec_mask, + int loop_id, float dist, float *result_new_len, LineartBoundingArea *caller_ba) @@ -791,7 +798,11 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf float new_len = rb->use_geometry_space_chain ? len_v3v3(cre->eci->gpos, eci->gpos) : len_v2v2(cre->eci->pos, eci->pos); - if (new_len < dist) { + /* Even if the vertex is not from the same contour loop, we try to chain it still if the + * distance is small enough. This way we can better chain smaller loops and smooth them out + * later. */ + if (((cre->ec->loop_id == loop_id) && (new_len < dist)) || + ((cre->ec->loop_id != loop_id) && (new_len < dist / 10))) { closest_cre = cre; dist = new_len; if (result_new_len) { @@ -815,6 +826,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf occlusion, \ material_mask_bits, \ isec_mask, \ + loop_id, \ dist, \ &adjacent_new_len, \ ba); \ @@ -844,7 +856,7 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb) LineartChainRegisterEntry *closest_cre_l, *closest_cre_r, *closest_cre; float dist = rb->chaining_image_threshold; float dist_l, dist_r; - int occlusion, reverse_main; + int occlusion, reverse_main, loop_id; unsigned char material_mask_bits, isec_mask; ListBase swap = {0}; @@ -863,6 +875,7 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb) continue; } BLI_addtail(&rb->chains, ec); + loop_id = ec->loop_id; if (ec->type == LRT_EDGE_FLAG_LOOSE && (!rb->use_loose_edge_chain)) { continue; @@ -876,10 +889,28 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb) eci_r = ec->chain.last; while ((ba_l = lineart_bounding_area_get_end_point(rb, eci_l)) && (ba_r = lineart_bounding_area_get_end_point(rb, eci_r))) { - closest_cre_l = lineart_chain_get_closest_cre( - rb, ba_l, ec, eci_l, occlusion, material_mask_bits, isec_mask, dist, &dist_l, NULL); - closest_cre_r = lineart_chain_get_closest_cre( - rb, ba_r, ec, eci_r, occlusion, material_mask_bits, isec_mask, dist, &dist_r, NULL); + closest_cre_l = lineart_chain_get_closest_cre(rb, + ba_l, + ec, + eci_l, + occlusion, + material_mask_bits, + isec_mask, + loop_id, + dist, + &dist_l, + NULL); + closest_cre_r = lineart_chain_get_closest_cre(rb, + ba_r, + ec, + eci_r, + occlusion, + material_mask_bits, + isec_mask, + loop_id, + dist, + &dist_r, + NULL); if (closest_cre_l && closest_cre_r) { if (dist_l < dist_r) { closest_cre = closest_cre_l; @@ -1192,6 +1223,8 @@ void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshol new_ec->object_ref = ec->object_ref; new_ec->type = ec->type; new_ec->level = ec->level; + new_ec->loop_id = ec->loop_id; + new_ec->intersection_mask = ec->intersection_mask; new_ec->material_mask_bits = ec->material_mask_bits; ec = new_ec; } |