From 841df831e89dfc4011c323203c2efb8265dc1878 Mon Sep 17 00:00:00 2001 From: YimingWu Date: Fri, 25 Jun 2021 13:15:25 +0800 Subject: LineArt: More type & related chaining improvements This patch includes: Floating edge type support, Special chaining option for floating edge, Chaining option for reducing jagged edges when floating edges are involved. Reviewed By: Sebastian Parborg (zeddb) Differential Revision: https://developer.blender.org/D11306 --- .../gpencil_modifiers/intern/MOD_gpencillineart.c | 19 ++- .../gpencil_modifiers/intern/lineart/MOD_lineart.h | 13 +- .../intern/lineart/lineart_chain.c | 7 +- .../gpencil_modifiers/intern/lineart/lineart_cpu.c | 170 +++++++++++++++------ .../intern/lineart/lineart_intern.h | 6 + 5 files changed, 159 insertions(+), 56 deletions(-) (limited to 'source/blender/gpencil_modifiers/intern') diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c index f0aae7e4498..1f70ecb4595 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c @@ -305,6 +305,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayout *col = uiLayoutColumnWithHeading(layout, true, IFACE_("Edge Types")); uiItemR(col, ptr, "use_contour", 0, IFACE_("Contour"), ICON_NONE); + uiItemR(col, ptr, "use_floating", 0, IFACE_("Floating"), ICON_NONE); uiItemR(col, ptr, "use_material", 0, IFACE_("Material Borders"), ICON_NONE); uiItemR(col, ptr, "use_edge_mark", 0, IFACE_("Edge Marks"), ICON_NONE); uiItemR(col, ptr, "use_intersection", 0, IFACE_("Intersections"), ICON_NONE); @@ -312,7 +313,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayout *sub = uiLayoutRowWithHeading(col, false, IFACE_("Crease")); uiItemR(sub, ptr, "use_crease", 0, "", ICON_NONE); uiLayout *entry = uiLayoutRow(sub, false); - uiLayoutSetActive(entry, RNA_boolean_get(ptr, "use_crease") || is_first); + uiLayoutSetEnabled(entry, RNA_boolean_get(ptr, "use_crease") || is_first); if (use_cache && !is_first) { uiItemL(entry, IFACE_("Angle Cached"), ICON_INFO); } @@ -368,6 +369,7 @@ static void options_panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(col, ptr, "use_edge_overlap", 0, IFACE_("Overlapping Edges As Contour"), ICON_NONE); uiItemR(col, ptr, "use_object_instances", 0, NULL, ICON_NONE); uiItemR(col, ptr, "use_clip_plane_boundaries", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "allow_overlap_edge_types", 0, NULL, ICON_NONE); } static void style_panel_draw(const bContext *UNUSED(C), Panel *panel) @@ -430,7 +432,7 @@ static void transparency_panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); - uiLayoutSetActive(layout, RNA_boolean_get(ptr, "use_transparency")); + uiLayoutSetEnabled(layout, RNA_boolean_get(ptr, "use_transparency")); uiLayout *row = uiLayoutRow(layout, true); uiLayoutSetPropDecorate(row, false); @@ -457,6 +459,7 @@ static void chaining_panel_draw(const bContext *UNUSED(C), Panel *panel) const bool is_baked = RNA_boolean_get(ptr, "is_baked"); const bool use_cache = RNA_boolean_get(ptr, "use_cache"); const bool is_first = BKE_gpencil_is_first_lineart_in_stack(ob_ptr.data, ptr->data); + const bool is_geom = RNA_boolean_get(ptr, "chain_geometry_space"); uiLayoutSetPropSep(layout, true); uiLayoutSetEnabled(layout, !is_baked); @@ -469,8 +472,16 @@ static void chaining_panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayout *col = uiLayoutColumnWithHeading(layout, true, IFACE_("Chain")); uiItemR(col, ptr, "use_fuzzy_intersections", 0, NULL, ICON_NONE); uiItemR(col, ptr, "use_fuzzy_all", 0, NULL, ICON_NONE); - - uiItemR(layout, ptr, "chaining_image_threshold", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "chain_floating_edges", 0, IFACE_("Floating Edges"), ICON_NONE); + uiItemR(col, ptr, "floating_as_contour", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "chain_geometry_space", 0, NULL, ICON_NONE); + + uiItemR(layout, + ptr, + "chaining_image_threshold", + 0, + is_geom ? IFACE_("Geometry Threshold") : NULL, + ICON_NONE); uiItemR(layout, ptr, "split_angle", UI_ITEM_R_SLIDER, NULL, ICON_NONE); } diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h index 72b73b4d174..a7f4231e4aa 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h +++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h @@ -189,7 +189,7 @@ typedef struct LineartEdgeChainItem { /** For restoring position to 3d space */ float gpos[3]; float normal[3]; - char line_type; + unsigned char line_type; char occlusion; unsigned char transparency_mask; size_t index; @@ -267,6 +267,7 @@ typedef struct LineartRenderBuffer { ListBase crease; ListBase material; ListBase edge_mark; + ListBase floating; ListBase chains; @@ -287,11 +288,16 @@ typedef struct LineartRenderBuffer { bool use_material; bool use_edge_marks; bool use_intersections; + bool use_floating; bool fuzzy_intersections; bool fuzzy_everything; bool allow_boundaries; bool allow_overlapping_edges; + bool allow_duplicated_types; bool remove_doubles; + bool floating_as_contour; + bool chain_floating_edges; + bool chain_geometry_space; /* Keep an copy of these data so when line art is running it's self-contained. */ bool cam_is_persp; @@ -358,11 +364,10 @@ typedef struct LineartRenderTaskInfo { ListBase crease; ListBase material; ListBase edge_mark; + ListBase floating; } LineartRenderTaskInfo; -struct BMesh; - typedef struct LineartObjectInfo { struct LineartObjectInfo *next; struct Object *original_ob; @@ -370,7 +375,7 @@ typedef struct LineartObjectInfo { double model_view_proj[4][4]; double model_view[4][4]; double normal[4][4]; - LineartElementLinkNode *v_reln; + LineartElementLinkNode *v_eln; int usage; int global_i_offset; diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c index 85a1dbb4df0..408e0081990 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c @@ -729,7 +729,8 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf } } - float new_len = len_v2v2(cre->eci->pos, eci->pos); + float new_len = rb->chain_geometry_space ? len_v3v3(cre->eci->gpos, eci->gpos) : + len_v2v2(cre->eci->pos, eci->pos); if (new_len < dist) { closest_cre = cre; dist = new_len; @@ -800,6 +801,10 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb) } BLI_addtail(&rb->chains, ec); + if (ec->type == LRT_EDGE_FLAG_FLOATING && (!rb->chain_floating_edges)) { + continue; + } + occlusion = ec->level; transparency_mask = ec->transparency_mask; diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index dffa6fce395..f2d1f6776ab 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -430,6 +430,7 @@ static int lineart_occlusion_make_task_info(LineartRenderBuffer *rb, LineartRend LRT_ASSIGN_OCCLUSION_TASK(crease); LRT_ASSIGN_OCCLUSION_TASK(material); LRT_ASSIGN_OCCLUSION_TASK(edge_mark); + LRT_ASSIGN_OCCLUSION_TASK(floating); #undef LRT_ASSIGN_OCCLUSION_TASK @@ -464,6 +465,10 @@ static void lineart_occlusion_worker(TaskPool *__restrict UNUSED(pool), LineartR for (eip = rti->edge_mark.first; eip && eip != rti->edge_mark.last; eip = eip->next) { lineart_occlusion_single_line(rb, eip, rti->thread_id); } + + for (eip = rti->floating.first; eip && eip != rti->floating.last; eip = eip->next) { + lineart_occlusion_single_line(rb, eip, rti->thread_id); + } } } @@ -486,6 +491,7 @@ static void lineart_main_occlusion_begin(LineartRenderBuffer *rb) rb->intersection.last = rb->intersection.first; rb->material.last = rb->material.first; rb->edge_mark.last = rb->edge_mark.first; + rb->floating.last = rb->floating.first; TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH); @@ -720,6 +726,7 @@ static void lineart_triangle_post(LineartTriangle *tri, LineartTriangle *orig) /* Just re-assign normal and set cull flag. */ copy_v3_v3_db(tri->gn, orig->gn); tri->flags = LRT_CULL_GENERATED; + tri->transparency_mask = orig->transparency_mask; } static void lineart_triangle_set_cull_flag(LineartTriangle *tri, uchar flag) @@ -735,6 +742,16 @@ static bool lineart_edge_match(LineartTriangle *tri, LineartEdge *e, int v1, int (tri->v[v2] == e->v1 && tri->v[v1] == e->v2)); } +static void lineart_discard_duplicated_edges(LineartEdge *old_e, int v1id, int v2id) +{ + LineartEdge *e = old_e; + e++; + while (e->v1_obindex == v1id && e->v2_obindex == v2id) { + e->flags |= LRT_EDGE_FLAG_CHAIN_PICKED; + 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. @@ -800,6 +817,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb, old_e = ta->e[e_num]; \ new_flag = old_e->flags; \ old_e->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \ + lineart_discard_duplicated_edges(old_e, old_e->v1_obindex, old_e->v2_obindex); \ INCREASE_EDGE \ e->v1 = (v1_link); \ e->v2 = (v2_link); \ @@ -820,12 +838,15 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb, #define REMOVE_TRIANGLE_EDGE \ if (ta->e[0]) { \ ta->e[0]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \ + lineart_discard_duplicated_edges(ta->e[0], ta->e[0]->v1_obindex, ta->e[0]->v2_obindex); \ } \ if (ta->e[1]) { \ ta->e[1]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \ + lineart_discard_duplicated_edges(ta->e[1], ta->e[1]->v1_obindex, ta->e[1]->v2_obindex); \ } \ if (ta->e[2]) { \ ta->e[2]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \ + lineart_discard_duplicated_edges(ta->e[2], ta->e[2]->v1_obindex, ta->e[2]->v2_obindex); \ } switch (in0 + in1 + in2) { @@ -1432,8 +1453,25 @@ static char lineart_identify_feature_line(LineartRenderBuffer *rb, lr = e->l->radial_next; } - if (ll == lr || !lr) { - return LRT_EDGE_FLAG_CONTOUR; + if (!ll && !lr) { + if (!rb->floating_as_contour) { + return LRT_EDGE_FLAG_FLOATING; + } + } + + uint16_t edge_flag_result = 0; + + if (count_freestyle && rb->use_edge_marks) { + FreestyleEdge *fe; + fe = CustomData_bmesh_get(&bm_if_freestyle->edata, e->head.data, CD_FREESTYLE_EDGE); + if (fe->flag & FREESTYLE_EDGE_MARK) { + edge_flag_result |= LRT_EDGE_FLAG_EDGE_MARK; + } + } + + /* Mesh boundary */ + if (!lr || ll == lr) { + return (edge_flag_result | LRT_EDGE_FLAG_CONTOUR); } LineartTriangle *tri1, *tri2; @@ -1449,7 +1487,6 @@ static char lineart_identify_feature_line(LineartRenderBuffer *rb, double *view_vector = vv; double dot_1 = 0, dot_2 = 0; double result; - FreestyleEdge *fe; if (rb->cam_is_persp) { sub_v3_v3v3_db(view_vector, l->gloc, rb->camera_pos); @@ -1462,24 +1499,20 @@ static char lineart_identify_feature_line(LineartRenderBuffer *rb, dot_2 = dot_v3v3_db(view_vector, tri2->gn); if ((result = dot_1 * dot_2) <= 0 && (dot_1 + dot_2)) { - return LRT_EDGE_FLAG_CONTOUR; + edge_flag_result |= LRT_EDGE_FLAG_CONTOUR; } if (rb->use_crease && (dot_v3v3_db(tri1->gn, tri2->gn) < crease_threshold)) { if (!no_crease) { - return LRT_EDGE_FLAG_CREASE; + edge_flag_result |= LRT_EDGE_FLAG_CREASE; } } - else if (rb->use_material && (ll->f->mat_nr != lr->f->mat_nr)) { - return LRT_EDGE_FLAG_MATERIAL; - } - else if (count_freestyle && rb->use_edge_marks) { - fe = CustomData_bmesh_get(&bm_if_freestyle->edata, e->head.data, CD_FREESTYLE_EDGE); - if (fe->flag & FREESTYLE_EDGE_MARK) { - return LRT_EDGE_FLAG_EDGE_MARK; - } + + if (rb->use_material && (ll->f->mat_nr != lr->f->mat_nr)) { + edge_flag_result |= LRT_EDGE_FLAG_MATERIAL; } - return 0; + + return edge_flag_result; } static void lineart_add_edge_to_list(LineartRenderBuffer *rb, LineartEdge *e) @@ -1527,6 +1560,9 @@ static void lineart_add_edge_to_list_thread(LineartObjectInfo *obi, LineartEdge case LRT_EDGE_FLAG_INTERSECTION: LRT_ASSIGN_EDGE(intersection); break; + case LRT_EDGE_FLAG_FLOATING: + LRT_ASSIGN_EDGE(floating); + break; } #undef LRT_ASSIGN_EDGE } @@ -1543,6 +1579,7 @@ static void lineart_finalize_object_edge_list(LineartRenderBuffer *rb, LineartOb LRT_OBI_TO_RB(material); LRT_OBI_TO_RB(edge_mark); LRT_OBI_TO_RB(intersection); + LRT_OBI_TO_RB(floating); #undef LRT_OBI_TO_RB } @@ -1561,6 +1598,17 @@ static void lineart_triangle_adjacent_assign(LineartTriangle *tri, } } +static int lineart_edge_type_duplication_count(char eflag) +{ + int count = 0; + /* See eLineartEdgeFlag for details. */ + for (int i = 0; i < LRT_EDGE_FLAG_FLOATING; i++) { + if (eflag & (1 << i)) { + count++; + } + } + return count; +} static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBuffer *rb) { BMesh *bm; @@ -1639,8 +1687,9 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu CanFindFreestyle = 1; } - /* Only allocate memory for verts and tris as we don't know how many lines we will generate - * yet. */ + /* 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. */ orv = lineart_mem_acquire_thread(&rb->render_data_pool, sizeof(LineartVert) * bm->totvert); ort = lineart_mem_acquire_thread(&rb->render_data_pool, bm->totface * rb->triangle_size); @@ -1653,7 +1702,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu eln->element_count = bm->totvert; eln->object_ref = orig_ob; - obi->v_reln = eln; + obi->v_eln = eln; if (orig_ob->lineart.flags & OBJECT_LRT_OWN_CREASE) { use_crease = cosf(M_PI - orig_ob->lineart.crease_threshold); @@ -1741,8 +1790,9 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu char eflag = lineart_identify_feature_line( rb, e, ort, orv, use_crease, orig_ob->type == OB_FONT, CanFindFreestyle, bm); if (eflag) { - /* Only allocate for feature lines (instead of all lines) to save memory. */ - allocate_la_e++; + /* 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. */ + allocate_la_e += rb->allow_duplicated_types ? lineart_edge_type_duplication_count(eflag) : 1; } /* Here we just use bm's flag for when loading actual lines, then we don't need to call * lineart_identify_feature_line() again, e->head.hflag deleted after loading anyway. Always @@ -1770,30 +1820,50 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu continue; } - la_e->v1 = &orv[BM_elem_index_get(e->v1)]; - la_e->v2 = &orv[BM_elem_index_get(e->v2)]; - la_e->v1_obindex = la_e->v1->index; - la_e->v2_obindex = la_e->v2->index; - if (e->l) { - int findex = BM_elem_index_get(e->l->f); - la_e->t1 = lineart_triangle_from_index(rb, ort, findex); - lineart_triangle_adjacent_assign(la_e->t1, &orta[findex], la_e); - if (e->l->radial_next && e->l->radial_next != e->l) { - findex = BM_elem_index_get(e->l->radial_next->f); - la_e->t2 = lineart_triangle_from_index(rb, ort, findex); - lineart_triangle_adjacent_assign(la_e->t2, &orta[findex], la_e); + bool edge_added = false; + + /* See eLineartEdgeFlag for details. */ + for (int flag_bit = 0; flag_bit < LRT_EDGE_FLAG_FLOATING; flag_bit++) { + char use_type = 1 << flag_bit; + if (!(use_type & e->head.hflag)) { + continue; } - } - la_e->flags = e->head.hflag; - la_e->object_ref = orig_ob; - BLI_addtail(&la_e->segments, la_s); - if (usage == OBJECT_LRT_INHERIT || usage == OBJECT_LRT_INCLUDE || - usage == OBJECT_LRT_NO_INTERSECTION) { - lineart_add_edge_to_list_thread(obi, la_e); - } - la_e++; - la_s++; + la_e->v1 = &orv[BM_elem_index_get(e->v1)]; + la_e->v2 = &orv[BM_elem_index_get(e->v2)]; + la_e->v1_obindex = la_e->v1->index; + la_e->v2_obindex = la_e->v2->index; + if (e->l) { + int findex = BM_elem_index_get(e->l->f); + la_e->t1 = lineart_triangle_from_index(rb, ort, findex); + if (!edge_added) { + lineart_triangle_adjacent_assign(la_e->t1, &orta[findex], la_e); + } + if (e->l->radial_next && e->l->radial_next != e->l) { + findex = BM_elem_index_get(e->l->radial_next->f); + la_e->t2 = lineart_triangle_from_index(rb, ort, findex); + if (!edge_added) { + lineart_triangle_adjacent_assign(la_e->t2, &orta[findex], la_e); + } + } + } + la_e->flags = use_type; + la_e->object_ref = orig_ob; + BLI_addtail(&la_e->segments, la_s); + if (usage == OBJECT_LRT_INHERIT || usage == OBJECT_LRT_INCLUDE || + usage == OBJECT_LRT_NO_INTERSECTION) { + lineart_add_edge_to_list_thread(obi, la_e); + } + + edge_added = true; + + la_e++; + la_s++; + + if (!rb->allow_duplicated_types) { + break; + } + } } /* always free bm as it's a copy from before threading */ @@ -1803,9 +1873,8 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu static void lineart_object_load_worker(TaskPool *__restrict UNUSED(pool), LineartObjectLoadTaskInfo *olti) { - LineartRenderBuffer *rb = olti->rb; for (LineartObjectInfo *obi = olti->pending; obi; obi = obi->next) { - lineart_geometry_object_load(obi, rb); + lineart_geometry_object_load(obi, olti->rb); } } @@ -1948,7 +2017,6 @@ static void lineart_main_load_geometries( { 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); @@ -2071,11 +2139,11 @@ static void lineart_main_load_geometries( for (int i = 0; i < thread_count; i++) { for (LineartObjectInfo *obi = olti[i].pending; obi; obi = obi->next) { - if (!obi->v_reln) { + if (!obi->v_eln) { continue; } - LineartVert *v = (LineartVert *)obi->v_reln->pointer; - int v_count = obi->v_reln->element_count; + LineartVert *v = (LineartVert *)obi->v_eln->pointer; + int v_count = obi->v_eln->element_count; for (int vi = 0; vi < v_count; vi++) { v[vi].index += global_i; } @@ -2823,6 +2891,7 @@ static void lineart_destroy_render_data(LineartRenderBuffer *rb) memset(&rb->intersection, 0, sizeof(ListBase)); memset(&rb->edge_mark, 0, sizeof(ListBase)); memset(&rb->material, 0, sizeof(ListBase)); + memset(&rb->floating, 0, sizeof(ListBase)); BLI_listbase_clear(&rb->chains); BLI_listbase_clear(&rb->wasted_cuts); @@ -2919,10 +2988,15 @@ static LineartRenderBuffer *lineart_create_render_buffer(Scene *scene, rb->fuzzy_everything = (lmd->calculation_flags & LRT_EVERYTHING_AS_CONTOUR) != 0; rb->allow_boundaries = (lmd->calculation_flags & LRT_ALLOW_CLIPPING_BOUNDARIES) != 0; rb->remove_doubles = (lmd->calculation_flags & LRT_REMOVE_DOUBLES) != 0; + rb->floating_as_contour = (lmd->calculation_flags & LRT_FLOATING_AS_CONTOUR) != 0; + rb->chain_floating_edges = (lmd->calculation_flags & LRT_CHAIN_FLOATING_EDGES) != 0; + rb->chain_geometry_space = (lmd->calculation_flags & LRT_CHAIN_GEOMETRY_SPACE) != 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; + rb->allow_duplicated_types = (lmd->calculation_flags & LRT_ALLOW_OVERLAP_EDGE_TYPES) != 0; + int16_t edge_types = lmd->edge_types_override; rb->use_contour = (edge_types & LRT_EDGE_FLAG_CONTOUR) != 0; @@ -2930,6 +3004,7 @@ static LineartRenderBuffer *lineart_create_render_buffer(Scene *scene, 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_floating = (edge_types & LRT_EDGE_FLAG_FLOATING) != 0; rb->chain_data_pool = &lc->chain_data_pool; @@ -4043,6 +4118,7 @@ static int UNUSED_FUNCTION(lineart_rb_edge_types)(LineartRenderBuffer *rb) 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_floating ? LRT_EDGE_FLAG_FLOATING : 0; return types; } diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h index e457d4a83a0..9d109320f09 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h @@ -98,6 +98,9 @@ void lineart_count_and_print_render_buffer_memory(struct LineartRenderBuffer *rb if (!e) { \ e = rb->intersection.first; \ } \ + if (!e) { \ + e = rb->floating.first; \ + } \ for (current_head = &rb->contour.first; e; e = next_e) { \ next_e = e->next; @@ -115,6 +118,9 @@ void lineart_count_and_print_render_buffer_memory(struct LineartRenderBuffer *rb else if (current_head == &rb->edge_mark.first) { \ current_head = &rb->intersection.first; \ } \ + else if (current_head == &rb->intersection.first) { \ + current_head = &rb->floating.first; \ + } \ else { \ break; \ } \ -- cgit v1.2.3