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:
authorYimingWu <xp8110@outlook.com>2021-06-29 15:47:55 +0300
committerYimingWu <xp8110@outlook.com>2021-06-29 15:47:55 +0300
commitd1e0059eac99654624edee2a2390a3e2fdc4c7cb (patch)
tree3983e4f1b78fa3bd85e5cb16a0a010e4e3351815
parent5d5cf5308129f1632cd6e303df52dadf63026675 (diff)
LineArt: Filtering intersection lines using mask numbers
Mask value works just like transparency mask. You are able to select intersection lines inside a collection or, between collections. Reviewed By: Sebastian Parborg (zeddb) Differential Revision: https://developer.blender.org/D11309
-rw-r--r--release/scripts/startup/bl_ui/properties_collection.py7
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c31
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h9
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c134
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c73
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c3
-rw-r--r--source/blender/makesdna/DNA_collection_types.h13
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_types.h12
-rw-r--r--source/blender/makesdna/intern/dna_rename_defs.h2
-rw-r--r--source/blender/makesrna/intern/rna_collection.c13
-rw-r--r--source/blender/makesrna/intern/rna_gpencil_modifier.c20
11 files changed, 217 insertions, 100 deletions
diff --git a/release/scripts/startup/bl_ui/properties_collection.py b/release/scripts/startup/bl_ui/properties_collection.py
index 5a98e638992..27de80bb88d 100644
--- a/release/scripts/startup/bl_ui/properties_collection.py
+++ b/release/scripts/startup/bl_ui/properties_collection.py
@@ -86,6 +86,13 @@ class COLLECTION_PT_lineart_collection(CollectionButtonsPanel, Panel):
row = layout.row()
row.prop(collection, "lineart_usage")
+ layout.prop(collection, "lineart_use_intersection_mask")
+
+ row = layout.row(align=True, heading="Masks")
+ row.active = collection.lineart_use_intersection_mask
+ for i in range(0,8):
+ row.prop(collection, "lineart_intersection_mask", index=i, text=str(i), toggle=True)
+
classes = (
COLLECTION_PT_collection_flags,
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
index f205559b941..9593a1364e7 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
@@ -101,8 +101,9 @@ static void generate_strokes_actual(
lmd->use_multiple_levels ? lmd->level_end : lmd->level_start,
lmd->target_material ? BKE_gpencil_object_material_index_get(ob, lmd->target_material) : 0,
lmd->edge_types,
- lmd->material_mask_flags,
+ lmd->mask_switches,
lmd->material_mask_bits,
+ lmd->intersection_mask,
lmd->thickness,
lmd->opacity,
lmd->source_vertex_group,
@@ -462,6 +463,32 @@ static void material_mask_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(col, ptr, "use_material_mask_match", 0, IFACE_("Match All Masks"), ICON_NONE);
}
+static void intersection_panel_draw(const bContext *UNUSED(C), Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+ PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
+
+ const bool is_baked = RNA_boolean_get(ptr, "is_baked");
+ uiLayoutSetEnabled(layout, !is_baked);
+
+ uiLayoutSetPropSep(layout, true);
+
+ uiLayoutSetActive(layout, RNA_boolean_get(ptr, "use_intersection"));
+
+ uiLayout *row = uiLayoutRow(layout, true);
+ uiLayoutSetPropDecorate(row, false);
+ uiLayout *sub = uiLayoutRowWithHeading(row, true, IFACE_("Masks"));
+ char text[2] = "0";
+
+ PropertyRNA *prop = RNA_struct_find_property(ptr, "use_intersection_mask");
+ for (int i = 0; i < 8; i++, text[0]++) {
+ uiItemFullR(sub, ptr, prop, i, 0, UI_ITEM_R_TOGGLE, text, ICON_NONE);
+ }
+ uiItemL(row, "", ICON_BLANK1); /* Space for decorator. */
+
+ uiLayout *col = uiLayoutColumn(layout, true);
+ uiItemR(col, ptr, "use_intersection_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;
@@ -627,6 +654,8 @@ static void panelRegister(ARegionType *region_type)
material_mask_panel_draw,
occlusion_panel);
gpencil_modifier_subpanel_register(
+ region_type, "intersection", "Intersection", NULL, intersection_panel_draw, panel_type);
+ 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);
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index debfabae869..247b0b3f57b 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -52,8 +52,8 @@ typedef struct LineartTriangle {
/* first culled in line list to use adjacent triangle info, then go through triangle list. */
double gn[3];
- /* Material flag is removed to save space. */
unsigned char material_mask_bits;
+ unsigned char intersection_mask;
unsigned char mat_occlusion;
unsigned char flags; /* #eLineartTriangleFlags */
@@ -149,6 +149,7 @@ typedef struct LineartEdge {
/** Also for line type determination on chaining. */
unsigned char flags;
+ unsigned char intersection_mask;
/**
* Still need this entry because culled lines will not add to object
@@ -174,6 +175,7 @@ typedef struct LineartEdgeChain {
/** Chain now only contains one type of segments */
int type;
unsigned char material_mask_bits;
+ unsigned char intersection_mask;
struct Object *object_ref;
} LineartEdgeChain;
@@ -188,6 +190,7 @@ typedef struct LineartEdgeChainItem {
unsigned char line_type;
char occlusion;
unsigned char material_mask_bits;
+ unsigned char intersection_mask;
size_t index;
} LineartEdgeChainItem;
@@ -377,6 +380,7 @@ typedef struct LineartObjectInfo {
double normal[4][4];
LineartElementLinkNode *v_eln;
int usage;
+ uint8_t override_intersection_mask;
int global_i_offset;
bool free_use_mesh;
@@ -612,8 +616,9 @@ void MOD_lineart_gpencil_generate(LineartCache *cache,
int level_end,
int mat_nr,
short edge_types,
- unsigned char material_mask_flags,
+ unsigned char mask_switches,
unsigned char material_mask_bits,
+ unsigned char intersection_mask,
short thickness,
float opacity,
const char *source_vgname,
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
index a9f290eb6fa..52485648ee0 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
@@ -38,7 +38,8 @@
static LineartEdge *lineart_line_get_connected(LineartBoundingArea *ba,
LineartVert *vt,
LineartVert **new_vt,
- int match_flag)
+ int match_flag,
+ unsigned char match_isec_mask)
{
for (int i = 0; i < ba->line_count; i++) {
LineartEdge *n_e = ba->linked_lines[i];
@@ -51,6 +52,10 @@ static LineartEdge *lineart_line_get_connected(LineartBoundingArea *ba,
continue;
}
+ if (n_e->intersection_mask != match_isec_mask) {
+ continue;
+ }
+
*new_vt = LRT_OTHER_VERT(n_e, vt);
if (*new_vt) {
return n_e;
@@ -112,11 +117,11 @@ static LineartEdgeChainItem *lineart_chain_append_point(LineartRenderBuffer *rb,
/* Because the new chain point is overlapping, just replace the type and occlusion level of the
* current point. This makes it so that the line to the point after this one has the correct
* type and level. */
- LineartEdgeChainItem *old_rlci = ec->chain.last;
- old_rlci->line_type = type;
- old_rlci->occlusion = level;
- old_rlci->material_mask_bits = material_mask_bits;
- return old_rlci;
+ LineartEdgeChainItem *old_eci = ec->chain.last;
+ old_eci->line_type = type;
+ old_eci->occlusion = level;
+ old_eci->material_mask_bits = material_mask_bits;
+ return old_eci;
}
eci = lineart_mem_acquire(rb->chain_data_pool, sizeof(LineartEdgeChainItem));
@@ -194,9 +199,10 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
ec = lineart_chain_create(rb);
- /* One chain can only have one object_ref,
- * so we assign it based on the first segment we found. */
+ /* One chain can only have one object_ref and intersection_mask,
+ * so we assign them based on the first segment we found. */
ec->object_ref = e->object_ref;
+ ec->intersection_mask = e->intersection_mask;
LineartEdge *new_e;
LineartVert *new_vt;
@@ -230,7 +236,8 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
es->occlusion,
es->material_mask_bits,
e->v1_obindex);
- while (ba && (new_e = lineart_line_get_connected(ba, new_vt, &new_vt, e->flags))) {
+ while (ba && (new_e = lineart_line_get_connected(
+ ba, new_vt, &new_vt, e->flags, e->intersection_mask))) {
new_e->flags |= LRT_EDGE_FLAG_CHAIN_PICKED;
if (new_e->t1 || new_e->t2) {
@@ -360,7 +367,8 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
/* Step 3: grow right. */
ba = MOD_lineart_get_bounding_area(rb, e->v2->fbcoord[0], e->v2->fbcoord[1]);
new_vt = e->v2;
- while (ba && (new_e = lineart_line_get_connected(ba, new_vt, &new_vt, e->flags))) {
+ while (ba && (new_e = lineart_line_get_connected(
+ ba, new_vt, &new_vt, e->flags, e->intersection_mask))) {
new_e->flags |= LRT_EDGE_FLAG_CHAIN_PICKED;
if (new_e->t1 || new_e->t2) {
@@ -560,8 +568,8 @@ static void lineart_bounding_area_link_chain(LineartRenderBuffer *rb, LineartEdg
void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb)
{
- LineartEdgeChain *ec, *new_rlc;
- LineartEdgeChainItem *eci, *next_rlci;
+ LineartEdgeChain *ec, *new_ec;
+ LineartEdgeChainItem *eci, *next_eci;
ListBase swap = {0};
swap.first = rb->chains.first;
@@ -572,16 +580,16 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb)
while ((ec = BLI_pophead(&swap)) != NULL) {
ec->next = ec->prev = NULL;
BLI_addtail(&rb->chains, ec);
- LineartEdgeChainItem *first_rlci = (LineartEdgeChainItem *)ec->chain.first;
- int fixed_occ = first_rlci->occlusion;
- unsigned char fixed_mask = first_rlci->material_mask_bits;
+ LineartEdgeChainItem *first_eci = (LineartEdgeChainItem *)ec->chain.first;
+ int fixed_occ = first_eci->occlusion;
+ unsigned char fixed_mask = first_eci->material_mask_bits;
ec->level = fixed_occ;
ec->material_mask_bits = fixed_mask;
- for (eci = first_rlci->next; eci; eci = next_rlci) {
- next_rlci = eci->next;
+ for (eci = first_eci->next; eci; eci = next_eci) {
+ next_eci = eci->next;
if (eci->occlusion != fixed_occ || eci->material_mask_bits != fixed_mask) {
- if (next_rlci) {
- if (lineart_point_overlapping(next_rlci, eci->pos[0], eci->pos[1], 1e-5)) {
+ if (next_eci) {
+ if (lineart_point_overlapping(next_eci, eci->pos[0], eci->pos[1], 1e-5)) {
continue;
}
}
@@ -593,9 +601,9 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb)
/* No need to split at the last point anyway. */
break;
}
- new_rlc = lineart_chain_create(rb);
- new_rlc->chain.first = eci;
- new_rlc->chain.last = ec->chain.last;
+ new_ec = lineart_chain_create(rb);
+ new_ec->chain.first = eci;
+ new_ec->chain.last = ec->chain.last;
ec->chain.last = eci->prev;
((LineartEdgeChainItem *)ec->chain.last)->next = 0;
eci->prev = 0;
@@ -610,9 +618,10 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb)
fixed_occ,
fixed_mask,
eci->index);
- new_rlc->object_ref = ec->object_ref;
- new_rlc->type = ec->type;
- ec = new_rlc;
+ new_ec->object_ref = ec->object_ref;
+ new_ec->type = ec->type;
+ new_ec->intersection_mask = ec->intersection_mask;
+ ec = new_ec;
fixed_occ = eci->occlusion;
fixed_mask = eci->material_mask_bits;
ec->level = fixed_occ;
@@ -684,6 +693,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
LineartEdgeChainItem *eci,
int occlusion,
unsigned char material_mask_bits,
+ unsigned char isec_mask,
float dist,
float *result_new_len,
LineartBoundingArea *caller_ba)
@@ -712,7 +722,8 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
continue;
}
if (cre->ec == ec || (!cre->ec->chain.first) || (cre->ec->level != occlusion) ||
- (cre->ec->material_mask_bits != material_mask_bits)) {
+ (cre->ec->material_mask_bits != material_mask_bits) ||
+ (cre->ec->intersection_mask != isec_mask)) {
continue;
}
if (!rb->fuzzy_everything) {
@@ -748,8 +759,16 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
if (dist_to < dist && dist_to > 0) { \
LISTBASE_FOREACH (LinkData *, ld, list) { \
LineartBoundingArea *sba = (LineartBoundingArea *)ld->data; \
- adjacent_closest = lineart_chain_get_closest_cre( \
- rb, sba, ec, eci, occlusion, material_mask_bits, dist, &adjacent_new_len, ba); \
+ adjacent_closest = lineart_chain_get_closest_cre(rb, \
+ sba, \
+ ec, \
+ eci, \
+ occlusion, \
+ material_mask_bits, \
+ isec_mask, \
+ dist, \
+ &adjacent_new_len, \
+ ba); \
if (adjacent_new_len < dist) { \
dist = adjacent_new_len; \
closest_cre = adjacent_closest; \
@@ -776,13 +795,13 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
void MOD_lineart_chain_connect(LineartRenderBuffer *rb)
{
LineartEdgeChain *ec;
- LineartEdgeChainItem *rlci_l, *rlci_r;
+ LineartEdgeChainItem *eci_l, *eci_r;
LineartBoundingArea *ba_l, *ba_r;
LineartChainRegisterEntry *closest_cre_l, *closest_cre_r, *closest_cre;
float dist = rb->chaining_image_threshold;
float dist_l, dist_r;
int occlusion, reverse_main;
- unsigned char material_mask_bits;
+ unsigned char material_mask_bits, isec_mask;
ListBase swap = {0};
if (rb->chaining_image_threshold < 0.0001) {
@@ -807,15 +826,16 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb)
occlusion = ec->level;
material_mask_bits = ec->material_mask_bits;
+ isec_mask = ec->intersection_mask;
- rlci_l = ec->chain.first;
- rlci_r = ec->chain.last;
- while ((ba_l = lineart_bounding_area_get_end_point(rb, rlci_l)) &&
- (ba_r = lineart_bounding_area_get_end_point(rb, rlci_r))) {
+ eci_l = ec->chain.first;
+ 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, rlci_l, occlusion, material_mask_bits, dist, &dist_l, NULL);
+ 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, rlci_r, occlusion, material_mask_bits, dist, &dist_r, NULL);
+ rb, ba_r, ec, eci_r, occlusion, material_mask_bits, isec_mask, dist, &dist_r, NULL);
if (closest_cre_l && closest_cre_r) {
if (dist_l < dist_r) {
closest_cre = closest_cre_l;
@@ -847,8 +867,8 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb)
lineart_chain_connect(rb, ec, closest_cre->ec, reverse_main, 1);
}
BLI_remlink(&swap, closest_cre->ec);
- rlci_l = ec->chain.first;
- rlci_r = ec->chain.last;
+ eci_l = ec->chain.first;
+ eci_r = ec->chain.last;
}
ec->picked = 1;
}
@@ -876,9 +896,9 @@ float MOD_lineart_chain_compute_length(LineartEdgeChain *ec)
void MOD_lineart_chain_discard_short(LineartRenderBuffer *rb, const float threshold)
{
- LineartEdgeChain *ec, *next_rlc;
- for (ec = rb->chains.first; ec; ec = next_rlc) {
- next_rlc = ec->next;
+ LineartEdgeChain *ec, *next_ec;
+ for (ec = rb->chains.first; ec; ec = next_ec) {
+ next_ec = ec->next;
if (MOD_lineart_chain_compute_length(ec) < threshold) {
BLI_remlink(&rb->chains, ec);
}
@@ -910,8 +930,8 @@ void MOD_lineart_chain_clear_picked_flag(LineartCache *lc)
*/
void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshold_rad)
{
- LineartEdgeChain *ec, *new_rlc;
- LineartEdgeChainItem *eci, *next_rlci, *prev_rlci;
+ LineartEdgeChain *ec, *new_ec;
+ LineartEdgeChainItem *eci, *next_eci, *prev_eci;
ListBase swap = {0};
swap.first = rb->chains.first;
@@ -922,21 +942,21 @@ void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshol
while ((ec = BLI_pophead(&swap)) != NULL) {
ec->next = ec->prev = NULL;
BLI_addtail(&rb->chains, ec);
- LineartEdgeChainItem *first_rlci = (LineartEdgeChainItem *)ec->chain.first;
- for (eci = first_rlci->next; eci; eci = next_rlci) {
- next_rlci = eci->next;
- prev_rlci = eci->prev;
+ LineartEdgeChainItem *first_eci = (LineartEdgeChainItem *)ec->chain.first;
+ for (eci = first_eci->next; eci; eci = next_eci) {
+ next_eci = eci->next;
+ prev_eci = eci->prev;
float angle = M_PI;
- if (next_rlci && prev_rlci) {
- angle = angle_v2v2v2(prev_rlci->pos, eci->pos, next_rlci->pos);
+ if (next_eci && prev_eci) {
+ angle = angle_v2v2v2(prev_eci->pos, eci->pos, next_eci->pos);
}
else {
break; /* No need to split at the last point anyway. */
}
if (angle < angle_threshold_rad) {
- new_rlc = lineart_chain_create(rb);
- new_rlc->chain.first = eci;
- new_rlc->chain.last = ec->chain.last;
+ new_ec = lineart_chain_create(rb);
+ new_ec->chain.first = eci;
+ new_ec->chain.last = ec->chain.last;
ec->chain.last = eci->prev;
((LineartEdgeChainItem *)ec->chain.last)->next = 0;
eci->prev = 0;
@@ -951,11 +971,11 @@ void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshol
ec->level,
eci->material_mask_bits,
eci->index);
- new_rlc->object_ref = ec->object_ref;
- new_rlc->type = ec->type;
- new_rlc->level = ec->level;
- new_rlc->material_mask_bits = ec->material_mask_bits;
- ec = new_rlc;
+ new_ec->object_ref = ec->object_ref;
+ new_ec->type = ec->type;
+ new_ec->level = ec->level;
+ new_ec->material_mask_bits = ec->material_mask_bits;
+ ec = new_ec;
}
}
}
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index e9f398093a7..477b99d85d0 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -875,7 +875,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
* (!in0) means "when point 0 is visible".
* conditions for point 1, 2 are the same idea.
*
- * \code{.txt}
+ * \code{.txt}identify
* 1-----|-------0
* | | ---
* | |---
@@ -1807,6 +1807,8 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu
mat->lineart.mat_occlusion :
1);
+ tri->intersection_mask = obi->override_intersection_mask;
+
double gn[3];
copy_v3db_v3fl(gn, f->no);
mul_v3_mat3_m4v3_db(tri->gn, normal, gn);
@@ -1945,13 +1947,30 @@ static bool _lineart_object_not_in_source_collection(Collection *source, Object
return true;
}
+static uchar lineart_intersection_mask_check(Collection *c, Object *ob)
+{
+ LISTBASE_FOREACH (CollectionChild *, cc, &c->children) {
+ uchar result = lineart_intersection_mask_check(cc->collection, ob);
+ if (result) {
+ return result;
+ }
+ }
+
+ if (c->children.first == NULL) {
+ if (BKE_collection_has_object(c, (Object *)(ob->id.orig_id))) {
+ if (c->lineart_flags & COLLECTION_LRT_USE_INTERSECTION_MASK) {
+ return c->lineart_intersection_mask;
+ }
+ }
+ }
+ return 0;
+}
+
/**
* See if this object in such collection is used for generating line art,
* Disabling a collection for line art will doable all objects inside.
- * `_rb` is used to provide source selection info.
- * See the definition of `rb->_source_type` for details.
*/
-static int lineart_usage_check(Collection *c, Object *ob, LineartRenderBuffer *_rb)
+static int lineart_usage_check(Collection *c, Object *ob)
{
if (!c) {
@@ -1981,29 +2000,15 @@ static int lineart_usage_check(Collection *c, Object *ob, LineartRenderBuffer *_
}
return ob->lineart.usage;
}
- return OBJECT_LRT_INHERIT;
}
LISTBASE_FOREACH (CollectionChild *, cc, &c->children) {
- int result = lineart_usage_check(cc->collection, ob, _rb);
+ int result = lineart_usage_check(cc->collection, ob);
if (result > OBJECT_LRT_INHERIT) {
return result;
}
}
- /* Temp solution to speed up calculation in the modifier without cache. See the definition of
- * rb->_source_type for details. */
- if (_rb->_source_type == LRT_SOURCE_OBJECT) {
- if (ob != _rb->_source_object && ob->id.orig_id != (ID *)_rb->_source_object) {
- return OBJECT_LRT_OCCLUSION_ONLY;
- }
- }
- else if (_rb->_source_type == LRT_SOURCE_COLLECTION) {
- if (_lineart_object_not_in_source_collection(_rb->_source_collection, ob)) {
- return OBJECT_LRT_OCCLUSION_ONLY;
- }
- }
-
return OBJECT_LRT_INHERIT;
}
@@ -2123,7 +2128,9 @@ static void lineart_main_load_geometries(
DEG_OBJECT_ITER_BEGIN (depsgraph, ob, flags) {
LineartObjectInfo *obi = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartObjectInfo));
- obi->usage = lineart_usage_check(scene->master_collection, ob, rb);
+ obi->usage = lineart_usage_check(scene->master_collection, ob);
+ obi->override_intersection_mask = lineart_intersection_mask_check(scene->master_collection,
+ ob);
Mesh *use_mesh;
if (obi->usage == OBJECT_LRT_EXCLUDE) {
@@ -2841,6 +2848,7 @@ static LineartEdge *lineart_triangle_intersect(LineartRenderBuffer *rb,
BLI_addtail(&result->segments, es);
/* Don't need to OR flags right now, just a type mark. */
result->flags = LRT_EDGE_FLAG_INTERSECTION;
+ result->intersection_mask = (tri->intersection_mask | testing->intersection_mask);
lineart_prepend_edge_direct(&rb->intersection.first, result);
int r1, r2, c1, c2, row, col;
@@ -4191,8 +4199,9 @@ static void lineart_gpencil_generate(LineartCache *cache,
Object *source_object,
Collection *source_collection,
int types,
- uchar material_mask_flags,
+ uchar mask_switches,
uchar material_mask_bits,
+ uchar intersection_mask,
short thickness,
float opacity,
const char *source_vgname,
@@ -4248,8 +4257,8 @@ static void lineart_gpencil_generate(LineartCache *cache,
continue;
}
}
- if (material_mask_flags & LRT_GPENCIL_MATERIAL_MASK_ENABLE) {
- if (material_mask_flags & LRT_GPENCIL_MATERIAL_MASK_MATCH) {
+ if (mask_switches & LRT_GPENCIL_MATERIAL_MASK_ENABLE) {
+ if (mask_switches & LRT_GPENCIL_MATERIAL_MASK_MATCH) {
if (ec->material_mask_bits != material_mask_bits) {
continue;
}
@@ -4260,6 +4269,18 @@ static void lineart_gpencil_generate(LineartCache *cache,
}
}
}
+ if (types & LRT_EDGE_FLAG_INTERSECTION) {
+ if (mask_switches & LRT_GPENCIL_INTERSECTION_MATCH) {
+ if (ec->intersection_mask != intersection_mask) {
+ continue;
+ }
+ }
+ else {
+ if ((intersection_mask) && !(ec->intersection_mask & intersection_mask)) {
+ continue;
+ }
+ }
+ }
/* Preserved: If we ever do asynchronous generation, this picked flag should be set here. */
// ec->picked = 1;
@@ -4354,8 +4375,9 @@ void MOD_lineart_gpencil_generate(LineartCache *cache,
int level_end,
int mat_nr,
short edge_types,
- uchar material_mask_flags,
+ uchar mask_switches,
uchar material_mask_bits,
+ uchar intersection_mask,
short thickness,
float opacity,
const char *source_vgname,
@@ -4403,8 +4425,9 @@ void MOD_lineart_gpencil_generate(LineartCache *cache,
source_object,
source_collection,
use_types,
- material_mask_flags,
+ mask_switches,
material_mask_bits,
+ intersection_mask,
thickness,
opacity,
source_vgname,
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c
index b0ead0013d8..988c90483a6 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c
@@ -143,8 +143,9 @@ static bool bake_strokes(Object *ob,
lmd->use_multiple_levels ? lmd->level_end : lmd->level_start,
lmd->target_material ? BKE_gpencil_object_material_index_get(ob, lmd->target_material) : 0,
lmd->edge_types,
- lmd->material_mask_flags,
+ lmd->mask_switches,
lmd->material_mask_bits,
+ lmd->intersection_mask,
lmd->thickness,
lmd->opacity,
lmd->source_vertex_group,
diff --git a/source/blender/makesdna/DNA_collection_types.h b/source/blender/makesdna/DNA_collection_types.h
index aa91699ae40..1defa8b782b 100644
--- a/source/blender/makesdna/DNA_collection_types.h
+++ b/source/blender/makesdna/DNA_collection_types.h
@@ -46,9 +46,6 @@ typedef struct CollectionChild {
struct Collection *collection;
} CollectionChild;
-/**
- * \warning while the values seem to be flags, they aren't treated as flags.
- */
enum eCollectionLineArt_Usage {
COLLECTION_LRT_INCLUDE = 0,
COLLECTION_LRT_OCCLUSION_ONLY = (1 << 0),
@@ -57,6 +54,10 @@ enum eCollectionLineArt_Usage {
COLLECTION_LRT_NO_INTERSECTION = (1 << 3),
};
+enum eCollectionLineArt_Flags {
+ COLLECTION_LRT_USE_INTERSECTION_MASK = (1 << 0),
+};
+
typedef struct Collection {
ID id;
@@ -74,8 +75,10 @@ typedef struct Collection {
/* Runtime-only, always cleared on file load. */
short tag;
- /** Line Art engine specific */
- short lineart_usage;
+ short lineart_usage; /* eCollectionLineArt_Usage */
+ unsigned char lineart_flags; /* eCollectionLineArt_Flags */
+ unsigned char lineart_intersection_mask;
+ char _pad[6];
int16_t color_tag;
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h
index 0bd7e500044..40e4c65c4b8 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_types.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h
@@ -883,11 +883,14 @@ typedef enum eLineArtGPencilModifierFlags {
LRT_GPENCIL_USE_CACHE = (1 << 4),
} eLineArtGPencilModifierFlags;
-typedef enum eLineartGpencilMaterialMaskFlags {
+typedef enum eLineartGpencilMaskSwitches {
LRT_GPENCIL_MATERIAL_MASK_ENABLE = (1 << 0),
/** When set, material mask bit comparisons are done with bit wise "AND" instead of "OR". */
LRT_GPENCIL_MATERIAL_MASK_MATCH = (1 << 1),
-} eLineartGpencilMaterialMaskFlags;
+ LRT_GPENCIL_INTERSECTION_MATCH = (1 << 2),
+} eLineartGpencilMaskSwitches;
+
+struct LineartCache;
struct LineartCache;
@@ -918,8 +921,11 @@ typedef struct LineartGpencilModifierData {
float opacity;
short thickness;
- unsigned char material_mask_flags; /* eLineartGpencilMaterialMaskFlags */
+ unsigned char mask_switches; /* eLineartGpencilMaskSwitches */
unsigned char material_mask_bits;
+ unsigned char intersection_mask;
+
+ char _pad[7];
/** `0..1` range for cosine angle */
float crease_threshold;
diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h
index 57abf708f60..735be0c10bf 100644
--- a/source/blender/makesdna/intern/dna_rename_defs.h
+++ b/source/blender/makesdna/intern/dna_rename_defs.h
@@ -134,6 +134,6 @@ DNA_STRUCT_RENAME_ELEM(RigidBodyWorld, steps_per_second, substeps_per_frame)
* global_areas. See D9442. */
DNA_STRUCT_RENAME_ELEM(wmWindow, global_area_map, global_areas)
DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, line_types, edge_types)
-DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_flags, material_mask_flags)
+DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_flags, mask_switches)
DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_mask, material_mask_bits)
DNA_STRUCT_RENAME_ELEM(MaterialLineArt, transparency_mask, material_mask_bits)
diff --git a/source/blender/makesrna/intern/rna_collection.c b/source/blender/makesrna/intern/rna_collection.c
index 643503e52fa..577a3273e21 100644
--- a/source/blender/makesrna/intern/rna_collection.c
+++ b/source/blender/makesrna/intern/rna_collection.c
@@ -548,6 +548,19 @@ void RNA_def_collections(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Usage", "How to use this collection in line art");
RNA_def_property_update(prop, NC_SCENE, NULL);
+ prop = RNA_def_property(srna, "lineart_use_intersection_mask", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "lineart_flags", 1);
+ RNA_def_property_ui_text(
+ prop, "Use Intersection Masks", "Use custom intersection mask for faces in this collection");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop = RNA_def_property(srna, "lineart_intersection_mask", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "lineart_intersection_mask", 1);
+ RNA_def_property_array(prop, 8);
+ RNA_def_property_ui_text(
+ prop, "Masks", "Intersection generated by this collection will have this mask value");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
prop = RNA_def_property(srna, "color_tag", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "color_tag");
RNA_def_property_enum_funcs(
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index 24b1e66bbb5..3e6048e30c4 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -2997,15 +2997,13 @@ static void rna_def_modifier_gpencillineart(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "use_material_mask", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(
- prop, NULL, "material_mask_flags", LRT_GPENCIL_MATERIAL_MASK_ENABLE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mask_switches", LRT_GPENCIL_MATERIAL_MASK_ENABLE);
RNA_def_property_ui_text(
prop, "Use Material Mask", "Use material masks to filter out occluded strokes");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "use_material_mask_match", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(
- prop, NULL, "material_mask_flags", LRT_GPENCIL_MATERIAL_MASK_MATCH);
+ RNA_def_property_boolean_sdna(prop, NULL, "mask_switches", LRT_GPENCIL_MATERIAL_MASK_MATCH);
RNA_def_property_ui_text(
prop, "Match Masks", "Require matching all material masks instead of just one");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
@@ -3013,7 +3011,19 @@ static void rna_def_modifier_gpencillineart(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_material_mask_bits", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "material_mask_bits", 1);
RNA_def_property_array(prop, 8);
- RNA_def_property_ui_text(prop, "Mask", "");
+ RNA_def_property_ui_text(prop, "Masks", "Mask bits to match from Material Line Art settings");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "use_intersection_match", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mask_switches", LRT_GPENCIL_INTERSECTION_MATCH);
+ RNA_def_property_ui_text(
+ prop, "Match Intersection", "Require matching all intersection masks instead of just one");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "use_intersection_mask", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "intersection_mask", 1);
+ RNA_def_property_array(prop, 8);
+ RNA_def_property_ui_text(prop, "Masks", "Mask bits to match from Collection Line Art settings");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
RNA_define_lib_overridable(false);