[Bf-blender-cvs] [3558bb8eae7] master: LineArt: Filtering feature lines with face mask
YimingWu
noreply at git.blender.org
Fri Jun 25 12:51:41 CEST 2021
Commit: 3558bb8eae758aa7e6483d0a6fc00dc83407d4cf
Author: YimingWu
Date: Fri Jun 25 18:48:20 2021 +0800
Branches: master
https://developer.blender.org/rB3558bb8eae758aa7e6483d0a6fc00dc83407d4cf
LineArt: Filtering feature lines with face mask
User can specify filtering options inside line art modifier,
like inverting selection and including face mark region border.
Reviewed By: Sebastian Parborg (zeddb)
Differential Revision: https://developer.blender.org/D11307
===================================================================
M source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
M source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
M source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
M source/blender/makesdna/DNA_gpencil_modifier_types.h
M source/blender/makesdna/DNA_lineart_types.h
M source/blender/makesrna/intern/rna_gpencil_modifier.c
===================================================================
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
index 1f70ecb4595..b87ed9e431a 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
@@ -449,6 +449,51 @@ static void transparency_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(col, ptr, "use_transparency_match", 0, IFACE_("Match All Masks"), ICON_NONE);
}
+static void face_mark_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+ PointerRNA ob_ptr;
+ PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, &ob_ptr);
+
+ 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);
+
+ if (!use_cache || is_first) {
+ uiLayoutSetEnabled(layout, !is_baked);
+ uiItemR(layout, ptr, "use_face_mark", 0, IFACE_("Face Mark Filtering"), ICON_NONE);
+ }
+ else {
+ uiItemL(layout, IFACE_("Face Mark Filtering"), ICON_NONE);
+ }
+}
+
+static void face_mark_panel_draw(const bContext *UNUSED(C), Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+ PointerRNA ob_ptr;
+ PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, &ob_ptr);
+
+ const bool is_baked = RNA_boolean_get(ptr, "is_baked");
+ const bool use_mark = RNA_boolean_get(ptr, "use_face_mark");
+ 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);
+
+ uiLayoutSetEnabled(layout, !is_baked);
+
+ if (use_cache && !is_first) {
+ uiItemL(layout, "Cached from the first line art modifier.", ICON_INFO);
+ return;
+ }
+
+ uiLayoutSetPropSep(layout, true);
+
+ uiLayoutSetActive(layout, use_mark);
+
+ uiItemR(layout, ptr, "use_face_mark_invert", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_face_mark_boundaries", 0, NULL, ICON_NONE);
+}
+
static void chaining_panel_draw(const bContext *UNUSED(C), Panel *panel)
{
PointerRNA ob_ptr;
@@ -566,6 +611,8 @@ static void panelRegister(ARegionType *region_type)
transparency_panel_draw_header,
transparency_panel_draw,
occlusion_panel);
+ gpencil_modifier_subpanel_register(
+ region_type, "face_mark", "", face_mark_panel_draw_header, face_mark_panel_draw, panel_type);
gpencil_modifier_subpanel_register(
region_type, "chaining", "Chaining", NULL, chaining_panel_draw, panel_type);
gpencil_modifier_subpanel_register(
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index a7f4231e4aa..d78cd862383 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -299,6 +299,10 @@ typedef struct LineartRenderBuffer {
bool chain_floating_edges;
bool chain_geometry_space;
+ bool filter_face_mark;
+ bool filter_face_mark_invert;
+ bool filter_face_mark_boundaries;
+
/* Keep an copy of these data so when line art is running it's self-contained. */
bool cam_is_persp;
float cam_obmat[4][4];
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index f2d1f6776ab..ebf9bcc17e2 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -1438,34 +1438,51 @@ static LineartTriangle *lineart_triangle_from_index(LineartRenderBuffer *rb,
return (LineartTriangle *)b;
}
-static char lineart_identify_feature_line(LineartRenderBuffer *rb,
- BMEdge *e,
- LineartTriangle *rt_array,
- LineartVert *rv_array,
- float crease_threshold,
- bool no_crease,
- bool count_freestyle,
- BMesh *bm_if_freestyle)
+static uint16_t lineart_identify_feature_line(LineartRenderBuffer *rb,
+ BMEdge *e,
+ LineartTriangle *rt_array,
+ LineartVert *rv_array,
+ float crease_threshold,
+ bool no_crease,
+ bool use_freestyle_edge,
+ bool use_freestyle_face,
+ BMesh *bm_if_freestyle)
{
BMLoop *ll, *lr = NULL;
+
ll = e->l;
if (ll) {
lr = e->l->radial_next;
}
- if (!ll && !lr) {
- if (!rb->floating_as_contour) {
- return LRT_EDGE_FLAG_FLOATING;
- }
- }
-
+ FreestyleEdge *fel, *fer;
+ bool face_mark_filtered = false;
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;
+ if (use_freestyle_face && rb->filter_face_mark) {
+ fel = CustomData_bmesh_get(&bm_if_freestyle->pdata, ll->f->head.data, CD_FREESTYLE_FACE);
+ if (ll != lr && lr) {
+ fer = CustomData_bmesh_get(&bm_if_freestyle->pdata, lr->f->head.data, CD_FREESTYLE_FACE);
+ }
+ else {
+ /* Handles mesh boundary case */
+ fer = fel;
+ }
+ if (rb->filter_face_mark_boundaries ^ rb->filter_face_mark_invert) {
+ if ((fel->flag & FREESTYLE_FACE_MARK) || (fer->flag & FREESTYLE_FACE_MARK)) {
+ face_mark_filtered = true;
+ }
+ }
+ else {
+ if ((fel->flag & FREESTYLE_FACE_MARK) && (fer->flag & FREESTYLE_FACE_MARK) && (fer != fel)) {
+ face_mark_filtered = true;
+ }
+ }
+ if (rb->filter_face_mark_invert) {
+ face_mark_filtered = !face_mark_filtered;
+ }
+ if (!face_mark_filtered) {
+ return 0;
}
}
@@ -1507,11 +1524,16 @@ static char lineart_identify_feature_line(LineartRenderBuffer *rb,
edge_flag_result |= LRT_EDGE_FLAG_CREASE;
}
}
-
if (rb->use_material && (ll->f->mat_nr != lr->f->mat_nr)) {
edge_flag_result |= LRT_EDGE_FLAG_MATERIAL;
}
-
+ if (use_freestyle_edge && 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;
+ }
+ }
return edge_flag_result;
}
@@ -1628,7 +1650,8 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu
LineartEdgeSegment *o_la_s;
LineartTriangle *ort;
Object *orig_ob;
- int CanFindFreestyle = 0;
+ bool can_find_freestyle_edge = false;
+ bool can_find_freestyle_face = false;
int i;
float use_crease = 0;
@@ -1684,7 +1707,10 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE | BM_FACE);
if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) {
- CanFindFreestyle = 1;
+ can_find_freestyle_edge = 1;
+ }
+ if (CustomData_has_layer(&bm->pdata, CD_FREESTYLE_FACE)) {
+ can_find_freestyle_face = true;
}
/* If we allow duplicated edges, one edge should get added multiple times if is has been
@@ -1787,8 +1813,15 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu
e = BM_edge_at_index(bm, i);
/* Because e->head.hflag is char, so line type flags should not exceed positive 7 bits. */
- char eflag = lineart_identify_feature_line(
- rb, e, ort, orv, use_crease, orig_ob->type == OB_FONT, CanFindFreestyle, bm);
+ char eflag = lineart_identify_feature_line(rb,
+ e,
+ ort,
+ orv,
+ use_crease,
+ orig_ob->type == OB_FONT,
+ can_find_freestyle_edge,
+ can_find_freestyle_face,
+ bm);
if (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. */
@@ -3006,6 +3039,11 @@ static LineartRenderBuffer *lineart_create_render_buffer(Scene *scene,
rb->use_intersections = (edge_types & LRT_EDGE_FLAG_INTERSECTION) != 0;
rb->use_floating = (edge_types & LRT_EDGE_FLAG_FLOATING) != 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->chain_data_pool = &lc->chain_data_pool;
BLI_spin_init(&rb->lock_task);
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h
index c0768c9a077..7c0679d38a9 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_types.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h
@@ -873,6 +873,7 @@ typedef enum eLineartGpencilModifierSource {
LRT_SOURCE_SCENE = 2,
} eLineartGpencilModifierSource;
+/* This enumis for modifier internal state only. */
typedef enum eLineArtGPencilModifierFlags {
/* These two moved to eLineartMainFlags to keep consistent with flag variable purpose. */
/* LRT_GPENCIL_INVERT_SOURCE_VG
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list