Commit: 62c2b377fd26e255c340a89695ae6c9a4c63fc7a Author: YimingWu Date: Sat Sep 11 17:13:45 2021 +0800 Branches: temp-lineart-contained https://developer.blender.org/rB62c2b377fd26e255c340a89695ae6c9a4c63fc7a
LineArt: Better smoothing algo. =================================================================== M release/datafiles/locale M release/scripts/addons M release/scripts/addons_contrib M source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h M source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c M source/blender/makesdna/DNA_gpencil_modifier_defaults.h M source/tools =================================================================== diff --git a/release/datafiles/locale b/release/datafiles/locale index 8a05b618f03..4833954c0ac 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 8a05b618f031582c006c6f62b9e60619ab3eef8b +Subproject commit 4833954c0ac85cc407e1d5a153aa11b1d1823ec0 diff --git a/release/scripts/addons b/release/scripts/addons index 67f1fbca148..f86f25e6221 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 67f1fbca1482d9d9362a4001332e785c3fd5d230 +Subproject commit f86f25e62217264495d05f116ccb09d575fe9841 diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index ef6ef414d22..5a82baad9f9 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit ef6ef414d22c2578fad99327743b925ab640a99c +Subproject commit 5a82baad9f986722104280e8354a4427d8e9eab1 diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h index 6f01e3a2fa8..a5860698cba 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h +++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h @@ -174,6 +174,8 @@ typedef struct LineartEdgeChain { /** Chain now only contains one type of segments */ int type; + /** Will only connect chains that has the same loop id. */ + int loop_id; unsigned char material_mask_bits; unsigned char intersection_mask; diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c index e798477d70b..e9afc88813d 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c @@ -582,9 +582,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; @@ -609,6 +614,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; @@ -699,6 +705,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) @@ -747,7 +754,10 @@ 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) { + /* If the vertex is not from the same contour loop, then we tighten up the range, this way we + * could chain small loops better and later smooth out. */ + 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) { @@ -771,6 +781,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf occlusion, \ material_mask_bits, \ isec_mask, \ + loop_id, \ dist, \ &adjacent_new_len, \ ba); \ @@ -805,7 +816,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}; @@ -824,6 +835,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; @@ -837,10 +849,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; @@ -932,27 +962,50 @@ void MOD_lineart_chain_clear_picked_flag(LineartCache *lc) void MOD_lineart_smooth_chains(LineartRenderBuffer *rb, float tolerance) { LISTBASE_FOREACH (LineartEdgeChain *, ec, &rb->chains) { - LineartEdgeChainItem *next_eci; - for (LineartEdgeChainItem *eci = ec->chain.first; eci; eci = next_eci) { - next_eci = eci->next; - LineartEdgeChainItem *eci2, *eci3, *eci4; - - /* Not enough point to do simplify. */ - if ((!(eci2 = eci->next)) || (!(eci3 = eci2->next))) { - continue; - } + for (int times = 0; times < 2; times++) { + for (LineartEdgeChainItem *eci = ec->chain.first, *next_eci = eci->next; eci; + eci = next_eci) { + LineartEdgeChainItem *eci2, *eci3, *eci4; - /* No need to care for different line types/occlusion and so on, because at this stage they - * are all the same within a chain. */ + /* Not enough point to do simplify. */ + if ((!(eci2 = eci->next)) || (!(eci3 = eci2->next))) { + next_eci = eci->next; + continue; + } - /* If p3 is within the p1-p2 segment of a width of "tolerance" */ - if (dist_to_line_segment_v2(eci3->pos, eci->pos, eci2->pos) < tolerance) { - /* And if p4 is on the extension of p1-p2 , we remove p3. */ - if ((eci4 = eci3->next) && (dist_to_line_v2(eci4->pos, eci->pos, eci2->pos) < tolerance)) { - BLI_remlink(&ec->chain, eci3); - next_eci = eci; + /* No need to care for different line types/occlusion and so on, because at this stage they + * are all the same within a chain. */ + + /* If p3 is within the p1-p2 segment of a width of "tolerance" */ + if (dist_to_line_segment_v2(eci3->pos, eci->pos, eci2->pos) < tolerance) { + float vec2[2], vec3[2], v2n[2], ratio, len2; + sub_v2_v2v2(vec2, eci2->pos, eci->pos); + sub_v2_v2v2(vec3, eci3->pos, eci->pos); + normalize_v2_v2(v2n, vec2); + ratio = dot_v2v2(v2n, vec3); + len2 = len_v2(vec2); + /* Don't remove a feature when the sharp turn stretches far behind. */ + if (ratio < len2 && ratio > -len2 * 10) { + /* And if p4 is on the extension of p1-p2 , we remove p3. */ + if ((eci4 = eci3->next) && + (dist_to_line_v2(eci4->pos, eci->pos, eci2->pos) < tolerance)) { + BLI_remlink(&ec->chain, eci3); + next_eci = eci; + continue; + } + if (!eci4) { + /* See if the last segment's direction is reversed, if so remove that. */ + if (len_v2(vec2) > len_v2(vec3)) { + BLI_remlink(&ec->chain, eci3); + } + next_eci = NULL; + continue; + } + } } + next_eci = eci->next; } + BLI_listbase_revers @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs