LineArt: Occlusion effectiveness support
This patch adds a function where you can specify occlusion effectiveness from 0 to 255 layers per face for a given mesh material. Reviewed By: Sebastian Parborg (zeddb) Ref D11308
This commit is contained in:
parent
9c6a382f95
commit
cf21ba37ef
|
@ -291,12 +291,18 @@ class MATERIAL_PT_lineart(MaterialButtonsPanel, Panel):
|
|||
mat = context.material
|
||||
lineart = mat.lineart
|
||||
|
||||
layout.prop(lineart, "use_transparency")
|
||||
layout.prop(lineart, "use_material_mask")
|
||||
|
||||
row = layout.row(align=True, heading="Masks")
|
||||
row.active = lineart.use_transparency
|
||||
row.active = lineart.use_material_mask
|
||||
for i in range(8):
|
||||
row.prop(lineart, "use_transparency_mask", text=str(i), index=i, toggle=True)
|
||||
row.prop(lineart, "use_material_mask_bits", text=str(i), index=i, toggle=True)
|
||||
|
||||
row = layout.row(align=True, heading="Custom Occlusion")
|
||||
row.prop(lineart, "use_mat_occlusion", text="")
|
||||
sub = row.row(align=False)
|
||||
sub.active = lineart.use_mat_occlusion
|
||||
sub.prop(lineart, "mat_occlusion", slider=True, text="Levels")
|
||||
|
||||
|
||||
classes = (
|
||||
|
|
|
@ -101,8 +101,8 @@ 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->transparency_flags,
|
||||
lmd->transparency_mask,
|
||||
lmd->material_mask_flags,
|
||||
lmd->material_mask_bits,
|
||||
lmd->thickness,
|
||||
lmd->opacity,
|
||||
lmd->source_vertex_group,
|
||||
|
@ -411,7 +411,7 @@ static void occlusion_panel_draw(const bContext *UNUSED(C), Panel *panel)
|
|||
}
|
||||
}
|
||||
|
||||
static void transparency_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
|
||||
static void material_mask_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
|
||||
{
|
||||
uiLayout *layout = panel->layout;
|
||||
PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
|
||||
|
@ -419,10 +419,10 @@ static void transparency_panel_draw_header(const bContext *UNUSED(C), Panel *pan
|
|||
const bool is_baked = RNA_boolean_get(ptr, "is_baked");
|
||||
uiLayoutSetEnabled(layout, !is_baked);
|
||||
|
||||
uiItemR(layout, ptr, "use_transparency", 0, IFACE_("Transparency"), ICON_NONE);
|
||||
uiItemR(layout, ptr, "use_material_mask", 0, IFACE_("Material Mask"), ICON_NONE);
|
||||
}
|
||||
|
||||
static void transparency_panel_draw(const bContext *UNUSED(C), Panel *panel)
|
||||
static void material_mask_panel_draw(const bContext *UNUSED(C), Panel *panel)
|
||||
{
|
||||
uiLayout *layout = panel->layout;
|
||||
PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
|
||||
|
@ -432,21 +432,21 @@ static void transparency_panel_draw(const bContext *UNUSED(C), Panel *panel)
|
|||
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
|
||||
uiLayoutSetEnabled(layout, RNA_boolean_get(ptr, "use_transparency"));
|
||||
uiLayoutSetEnabled(layout, RNA_boolean_get(ptr, "use_material_mask"));
|
||||
|
||||
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_transparency_mask");
|
||||
PropertyRNA *prop = RNA_struct_find_property(ptr, "use_material_mask_bits");
|
||||
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_transparency_match", 0, IFACE_("Match All Masks"), ICON_NONE);
|
||||
uiItemR(col, ptr, "use_material_mask_match", 0, IFACE_("Match All Masks"), ICON_NONE);
|
||||
}
|
||||
|
||||
static void face_mark_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
|
||||
|
@ -606,10 +606,10 @@ static void panelRegister(ARegionType *region_type)
|
|||
PanelType *occlusion_panel = gpencil_modifier_subpanel_register(
|
||||
region_type, "occlusion", "Occlusion", NULL, occlusion_panel_draw, panel_type);
|
||||
gpencil_modifier_subpanel_register(region_type,
|
||||
"transparency",
|
||||
"material_mask",
|
||||
"",
|
||||
transparency_panel_draw_header,
|
||||
transparency_panel_draw,
|
||||
material_mask_panel_draw_header,
|
||||
material_mask_panel_draw,
|
||||
occlusion_panel);
|
||||
gpencil_modifier_subpanel_register(
|
||||
region_type, "face_mark", "", face_mark_panel_draw_header, face_mark_panel_draw, panel_type);
|
||||
|
|
|
@ -53,7 +53,8 @@ typedef struct LineartTriangle {
|
|||
double gn[3];
|
||||
|
||||
/* Material flag is removed to save space. */
|
||||
unsigned char transparency_mask;
|
||||
unsigned char material_mask_bits;
|
||||
unsigned char mat_occlusion;
|
||||
unsigned char flags; /* #eLineartTriangleFlags */
|
||||
|
||||
/**
|
||||
|
@ -101,13 +102,8 @@ typedef struct LineartEdgeSegment {
|
|||
/** Occlusion level after "at" point */
|
||||
unsigned char occlusion;
|
||||
|
||||
/**
|
||||
* For determining lines behind a glass window material.
|
||||
* the size of this variable should also be dynamically decided, 1 byte to 8 byte,
|
||||
* allows 8 to 64 materials for "transparent mask". 1 byte (8 materials) should be
|
||||
* enough for most cases.
|
||||
*/
|
||||
unsigned char transparency_mask;
|
||||
/* Used to filter line art occlusion edges */
|
||||
unsigned char material_mask_bits;
|
||||
} LineartEdgeSegment;
|
||||
|
||||
typedef struct LineartVert {
|
||||
|
@ -177,7 +173,7 @@ typedef struct LineartEdgeChain {
|
|||
|
||||
/** Chain now only contains one type of segments */
|
||||
int type;
|
||||
unsigned char transparency_mask;
|
||||
unsigned char material_mask_bits;
|
||||
|
||||
struct Object *object_ref;
|
||||
} LineartEdgeChain;
|
||||
|
@ -191,7 +187,7 @@ typedef struct LineartEdgeChainItem {
|
|||
float normal[3];
|
||||
unsigned char line_type;
|
||||
char occlusion;
|
||||
unsigned char transparency_mask;
|
||||
unsigned char material_mask_bits;
|
||||
size_t index;
|
||||
} LineartEdgeChainItem;
|
||||
|
||||
|
@ -616,8 +612,8 @@ void MOD_lineart_gpencil_generate(LineartCache *cache,
|
|||
int level_end,
|
||||
int mat_nr,
|
||||
short edge_types,
|
||||
unsigned char transparency_flags,
|
||||
unsigned char transparency_mask,
|
||||
unsigned char material_mask_flags,
|
||||
unsigned char material_mask_bits,
|
||||
short thickness,
|
||||
float opacity,
|
||||
const char *source_vgname,
|
||||
|
|
|
@ -103,7 +103,7 @@ static LineartEdgeChainItem *lineart_chain_append_point(LineartRenderBuffer *rb,
|
|||
float *normal,
|
||||
char type,
|
||||
int level,
|
||||
unsigned char transparency_mask,
|
||||
unsigned char material_mask_bits,
|
||||
size_t index)
|
||||
{
|
||||
LineartEdgeChainItem *eci;
|
||||
|
@ -115,7 +115,7 @@ static LineartEdgeChainItem *lineart_chain_append_point(LineartRenderBuffer *rb,
|
|||
LineartEdgeChainItem *old_rlci = ec->chain.last;
|
||||
old_rlci->line_type = type;
|
||||
old_rlci->occlusion = level;
|
||||
old_rlci->transparency_mask = transparency_mask;
|
||||
old_rlci->material_mask_bits = material_mask_bits;
|
||||
return old_rlci;
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ static LineartEdgeChainItem *lineart_chain_append_point(LineartRenderBuffer *rb,
|
|||
copy_v3_v3(eci->normal, normal);
|
||||
eci->line_type = type & LRT_EDGE_FLAG_ALL_TYPE;
|
||||
eci->occlusion = level;
|
||||
eci->transparency_mask = transparency_mask;
|
||||
eci->material_mask_bits = material_mask_bits;
|
||||
BLI_addtail(&ec->chain, eci);
|
||||
|
||||
return eci;
|
||||
|
@ -140,7 +140,7 @@ static LineartEdgeChainItem *lineart_chain_prepend_point(LineartRenderBuffer *rb
|
|||
float *normal,
|
||||
char type,
|
||||
int level,
|
||||
unsigned char transparency_mask,
|
||||
unsigned char material_mask_bits,
|
||||
size_t index)
|
||||
{
|
||||
LineartEdgeChainItem *eci;
|
||||
|
@ -157,7 +157,7 @@ static LineartEdgeChainItem *lineart_chain_prepend_point(LineartRenderBuffer *rb
|
|||
copy_v3_v3(eci->normal, normal);
|
||||
eci->line_type = type & LRT_EDGE_FLAG_ALL_TYPE;
|
||||
eci->occlusion = level;
|
||||
eci->transparency_mask = transparency_mask;
|
||||
eci->material_mask_bits = material_mask_bits;
|
||||
BLI_addhead(&ec->chain, eci);
|
||||
|
||||
return eci;
|
||||
|
@ -228,7 +228,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
|
|||
N,
|
||||
e->flags,
|
||||
es->occlusion,
|
||||
es->transparency_mask,
|
||||
es->material_mask_bits,
|
||||
e->v1_obindex);
|
||||
while (ba && (new_e = lineart_line_get_connected(ba, new_vt, &new_vt, e->flags))) {
|
||||
new_e->flags |= LRT_EDGE_FLAG_CHAIN_PICKED;
|
||||
|
@ -263,16 +263,16 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
|
|||
N,
|
||||
new_e->flags,
|
||||
es->occlusion,
|
||||
es->transparency_mask,
|
||||
es->material_mask_bits,
|
||||
new_e->v1_obindex);
|
||||
last_occlusion = es->occlusion;
|
||||
last_transparency = es->transparency_mask;
|
||||
last_transparency = es->material_mask_bits;
|
||||
}
|
||||
}
|
||||
else if (new_vt == new_e->v2) {
|
||||
es = new_e->segments.first;
|
||||
last_occlusion = es->occlusion;
|
||||
last_transparency = es->transparency_mask;
|
||||
last_transparency = es->material_mask_bits;
|
||||
es = es->next;
|
||||
for (; es; es = es->next) {
|
||||
double gpos[3], lpos[3];
|
||||
|
@ -291,7 +291,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
|
|||
last_transparency,
|
||||
new_e->v2_obindex);
|
||||
last_occlusion = es->occlusion;
|
||||
last_transparency = es->transparency_mask;
|
||||
last_transparency = es->material_mask_bits;
|
||||
}
|
||||
VERT_COORD_TO_FLOAT(new_e->v2);
|
||||
lineart_chain_prepend_point(rb,
|
||||
|
@ -326,7 +326,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
|
|||
* of the line. */
|
||||
es = e->segments.first;
|
||||
last_occlusion = ((LineartEdgeSegment *)es)->occlusion;
|
||||
last_transparency = ((LineartEdgeSegment *)es)->transparency_mask;
|
||||
last_transparency = ((LineartEdgeSegment *)es)->material_mask_bits;
|
||||
for (es = es->next; es; es = es->next) {
|
||||
double gpos[3], lpos[3];
|
||||
double *lfb = e->v1->fbcoord, *rfb = e->v2->fbcoord;
|
||||
|
@ -341,10 +341,10 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
|
|||
N,
|
||||
e->flags,
|
||||
es->occlusion,
|
||||
es->transparency_mask,
|
||||
es->material_mask_bits,
|
||||
e->v1_obindex);
|
||||
last_occlusion = es->occlusion;
|
||||
last_transparency = es->transparency_mask;
|
||||
last_transparency = es->material_mask_bits;
|
||||
}
|
||||
VERT_COORD_TO_FLOAT(e->v2)
|
||||
lineart_chain_append_point(rb,
|
||||
|
@ -385,10 +385,10 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
|
|||
if (new_vt == new_e->v1) {
|
||||
es = new_e->segments.last;
|
||||
last_occlusion = es->occlusion;
|
||||
last_transparency = es->transparency_mask;
|
||||
last_transparency = es->material_mask_bits;
|
||||
/* Fix leading vertex occlusion. */
|
||||
eci->occlusion = last_occlusion;
|
||||
eci->transparency_mask = last_transparency;
|
||||
eci->material_mask_bits = last_transparency;
|
||||
for (es = new_e->segments.last; es; es = es->prev) {
|
||||
double gpos[3], lpos[3];
|
||||
double *lfb = new_e->v1->fbcoord, *rfb = new_e->v2->fbcoord;
|
||||
|
@ -396,7 +396,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
|
|||
interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, es->at);
|
||||
interp_v3_v3v3_db(gpos, new_e->v1->gloc, new_e->v2->gloc, global_at);
|
||||
last_occlusion = es->prev ? es->prev->occlusion : last_occlusion;
|
||||
last_transparency = es->prev ? es->prev->transparency_mask : last_transparency;
|
||||
last_transparency = es->prev ? es->prev->material_mask_bits : last_transparency;
|
||||
POS_TO_FLOAT(lpos, gpos)
|
||||
lineart_chain_append_point(rb,
|
||||
ec,
|
||||
|
@ -412,9 +412,9 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
|
|||
else if (new_vt == new_e->v2) {
|
||||
es = new_e->segments.first;
|
||||
last_occlusion = es->occlusion;
|
||||
last_transparency = es->transparency_mask;
|
||||
last_transparency = es->material_mask_bits;
|
||||
eci->occlusion = last_occlusion;
|
||||
eci->transparency_mask = last_transparency;
|
||||
eci->material_mask_bits = last_transparency;
|
||||
es = es->next;
|
||||
for (; es; es = es->next) {
|
||||
double gpos[3], lpos[3];
|
||||
|
@ -430,10 +430,10 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
|
|||
N,
|
||||
new_e->flags,
|
||||
es->occlusion,
|
||||
es->transparency_mask,
|
||||
es->material_mask_bits,
|
||||
new_e->v2_obindex);
|
||||
last_occlusion = es->occlusion;
|
||||
last_transparency = es->transparency_mask;
|
||||
last_transparency = es->material_mask_bits;
|
||||
}
|
||||
VERT_COORD_TO_FLOAT(new_e->v2)
|
||||
lineart_chain_append_point(rb,
|
||||
|
@ -574,12 +574,12 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb)
|
|||
BLI_addtail(&rb->chains, ec);
|
||||
LineartEdgeChainItem *first_rlci = (LineartEdgeChainItem *)ec->chain.first;
|
||||
int fixed_occ = first_rlci->occlusion;
|
||||
unsigned char fixed_mask = first_rlci->transparency_mask;
|
||||
unsigned char fixed_mask = first_rlci->material_mask_bits;
|
||||
ec->level = fixed_occ;
|
||||
ec->transparency_mask = fixed_mask;
|
||||
ec->material_mask_bits = fixed_mask;
|
||||
for (eci = first_rlci->next; eci; eci = next_rlci) {
|
||||
next_rlci = eci->next;
|
||||
if (eci->occlusion != fixed_occ || eci->transparency_mask != fixed_mask) {
|
||||
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)) {
|
||||
continue;
|
||||
|
@ -589,7 +589,7 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb)
|
|||
/* Set the same occlusion level for the end vertex, so when further connection is needed
|
||||
* the backwards occlusion info is also correct. */
|
||||
eci->occlusion = fixed_occ;
|
||||
eci->transparency_mask = fixed_mask;
|
||||
eci->material_mask_bits = fixed_mask;
|
||||
/* No need to split at the last point anyway. */
|
||||
break;
|
||||
}
|
||||
|
@ -614,9 +614,9 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb)
|
|||
new_rlc->type = ec->type;
|
||||
ec = new_rlc;
|
||||
fixed_occ = eci->occlusion;
|
||||
fixed_mask = eci->transparency_mask;
|
||||
fixed_mask = eci->material_mask_bits;
|
||||
ec->level = fixed_occ;
|
||||
ec->transparency_mask = fixed_mask;
|
||||
ec->material_mask_bits = fixed_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -683,7 +683,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
|
|||
LineartEdgeChain *ec,
|
||||
LineartEdgeChainItem *eci,
|
||||
int occlusion,
|
||||
unsigned char transparency_mask,
|
||||
unsigned char material_mask_bits,
|
||||
float dist,
|
||||
float *result_new_len,
|
||||
LineartBoundingArea *caller_ba)
|
||||
|
@ -712,7 +712,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
|
|||
continue;
|
||||
}
|
||||
if (cre->ec == ec || (!cre->ec->chain.first) || (cre->ec->level != occlusion) ||
|
||||
(cre->ec->transparency_mask != transparency_mask)) {
|
||||
(cre->ec->material_mask_bits != material_mask_bits)) {
|
||||
continue;
|
||||
}
|
||||
if (!rb->fuzzy_everything) {
|
||||
|
@ -749,7 +749,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
|
|||
LISTBASE_FOREACH (LinkData *, ld, list) { \
|
||||
LineartBoundingArea *sba = (LineartBoundingArea *)ld->data; \
|
||||
adjacent_closest = lineart_chain_get_closest_cre( \
|
||||
rb, sba, ec, eci, occlusion, transparency_mask, dist, &adjacent_new_len, ba); \
|
||||
rb, sba, ec, eci, occlusion, material_mask_bits, dist, &adjacent_new_len, ba); \
|
||||
if (adjacent_new_len < dist) { \
|
||||
dist = adjacent_new_len; \
|
||||
closest_cre = adjacent_closest; \
|
||||
|
@ -782,7 +782,7 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb)
|
|||
float dist = rb->chaining_image_threshold;
|
||||
float dist_l, dist_r;
|
||||
int occlusion, reverse_main;
|
||||
unsigned char transparency_mask;
|
||||
unsigned char material_mask_bits;
|
||||
ListBase swap = {0};
|
||||
|
||||
if (rb->chaining_image_threshold < 0.0001) {
|
||||
|
@ -806,16 +806,16 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb)
|
|||
}
|
||||
|
||||
occlusion = ec->level;
|
||||
transparency_mask = ec->transparency_mask;
|
||||
material_mask_bits = ec->material_mask_bits;
|
||||
|
||||
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))) {
|
||||
closest_cre_l = lineart_chain_get_closest_cre(
|
||||
rb, ba_l, ec, rlci_l, occlusion, transparency_mask, dist, &dist_l, NULL);
|
||||
rb, ba_l, ec, rlci_l, occlusion, material_mask_bits, dist, &dist_l, NULL);
|
||||
closest_cre_r = lineart_chain_get_closest_cre(
|
||||
rb, ba_r, ec, rlci_r, occlusion, transparency_mask, dist, &dist_r, NULL);
|
||||
rb, ba_r, ec, rlci_r, occlusion, material_mask_bits, dist, &dist_r, NULL);
|
||||
if (closest_cre_l && closest_cre_r) {
|
||||
if (dist_l < dist_r) {
|
||||
closest_cre = closest_cre_l;
|
||||
|
@ -949,12 +949,12 @@ void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshol
|
|||
eci->normal,
|
||||
eci->line_type,
|
||||
ec->level,
|
||||
eci->transparency_mask,
|
||||
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->transparency_mask = ec->transparency_mask;
|
||||
new_rlc->material_mask_bits = ec->material_mask_bits;
|
||||
ec = new_rlc;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,8 +146,12 @@ static LineartEdgeSegment *lineart_give_segment(LineartRenderBuffer *rb)
|
|||
/**
|
||||
* Cuts the edge in image space and mark occlusion level for each segment.
|
||||
*/
|
||||
static void lineart_edge_cut(
|
||||
LineartRenderBuffer *rb, LineartEdge *e, double start, double end, uchar transparency_mask)
|
||||
static void lineart_edge_cut(LineartRenderBuffer *rb,
|
||||
LineartEdge *e,
|
||||
double start,
|
||||
double end,
|
||||
uchar material_mask_bits,
|
||||
uchar mat_occlusion)
|
||||
{
|
||||
LineartEdgeSegment *es, *ies, *next_es, *prev_es;
|
||||
LineartEdgeSegment *cut_start_before = 0, *cut_end_before = 0;
|
||||
|
@ -240,7 +244,7 @@ static void lineart_edge_cut(
|
|||
/* Insert cutting points for when a new cut is needed. */
|
||||
ies = cut_start_before->prev ? cut_start_before->prev : NULL;
|
||||
ns->occlusion = ies ? ies->occlusion : 0;
|
||||
ns->transparency_mask = ies->transparency_mask;
|
||||
ns->material_mask_bits = ies->material_mask_bits;
|
||||
BLI_insertlinkbefore(&e->segments, cut_start_before, ns);
|
||||
}
|
||||
/* Otherwise we already found a existing cutting point, no need to insert a new one. */
|
||||
|
@ -250,7 +254,7 @@ static void lineart_edge_cut(
|
|||
* append the new cut to the end. */
|
||||
ies = e->segments.last;
|
||||
ns->occlusion = ies->occlusion;
|
||||
ns->transparency_mask = ies->transparency_mask;
|
||||
ns->material_mask_bits = ies->material_mask_bits;
|
||||
BLI_addtail(&e->segments, ns);
|
||||
}
|
||||
if (cut_end_before) {
|
||||
|
@ -258,14 +262,14 @@ static void lineart_edge_cut(
|
|||
if (cut_end_before != ns2) {
|
||||
ies = cut_end_before->prev ? cut_end_before->prev : NULL;
|
||||
ns2->occlusion = ies ? ies->occlusion : 0;
|
||||
ns2->transparency_mask = ies ? ies->transparency_mask : 0;
|
||||
ns2->material_mask_bits = ies ? ies->material_mask_bits : 0;
|
||||
BLI_insertlinkbefore(&e->segments, cut_end_before, ns2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ies = e->segments.last;
|
||||
ns2->occlusion = ies->occlusion;
|
||||
ns2->transparency_mask = ies->transparency_mask;
|
||||
ns2->material_mask_bits = ies->material_mask_bits;
|
||||
BLI_addtail(&e->segments, ns2);
|
||||
}
|
||||
|
||||
|
@ -282,8 +286,8 @@ static void lineart_edge_cut(
|
|||
|
||||
/* Register 1 level of occlusion for all touched segments. */
|
||||
for (es = ns; es && es != ns2; es = es->next) {
|
||||
es->occlusion++;
|
||||
es->transparency_mask |= transparency_mask;
|
||||
es->occlusion += mat_occlusion;
|
||||
es->material_mask_bits |= material_mask_bits;
|
||||
}
|
||||
|
||||
/* Reduce adjacent cutting points of the same level, which saves memory. */
|
||||
|
@ -293,7 +297,7 @@ static void lineart_edge_cut(
|
|||
next_es = es->next;
|
||||
|
||||
if (prev_es && prev_es->occlusion == es->occlusion &&
|
||||
prev_es->transparency_mask == es->transparency_mask) {
|
||||
prev_es->material_mask_bits == es->material_mask_bits) {
|
||||
BLI_remlink(&e->segments, es);
|
||||
/* This puts the node back to the render buffer, if more cut happens, these unused nodes get
|
||||
* picked first. */
|
||||
|
@ -373,7 +377,11 @@ static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge *
|
|||
tri = (LineartTriangleThread *)nba->linked_triangles[i];
|
||||
/* If we are already testing the line in this thread, then don't do it. */
|
||||
if (tri->testing_e[thread_id] == e || (tri->base.flags & LRT_TRIANGLE_INTERSECTION_ONLY) ||
|
||||
lineart_occlusion_is_adjacent_intersection(e, (LineartTriangle *)tri)) {
|
||||
/* Ignore this triangle if an intersection line directly comes from it, */
|
||||
lineart_occlusion_is_adjacent_intersection(e, (LineartTriangle *)tri) ||
|
||||
/* Or if this triangle isn't effectively occluding anything nor it's providing a
|
||||
material flag. */
|
||||
((!tri->base.mat_occlusion) && (!tri->base.material_mask_bits))) {
|
||||
continue;
|
||||
}
|
||||
tri->testing_e[thread_id] = e;
|
||||
|
@ -389,7 +397,7 @@ static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge *
|
|||
rb->shift_y,
|
||||
&l,
|
||||
&r)) {
|
||||
lineart_edge_cut(rb, e, l, r, tri->base.transparency_mask);
|
||||
lineart_edge_cut(rb, e, l, r, tri->base.material_mask_bits, tri->base.mat_occlusion);
|
||||
if (e->min_occ > rb->max_occlusion_level) {
|
||||
/* No need to calculate any longer on this line because no level more than set value is
|
||||
* going to show up in the rendered result. */
|
||||
|
@ -726,7 +734,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;
|
||||
tri->material_mask_bits = orig->material_mask_bits;
|
||||
}
|
||||
|
||||
static void lineart_triangle_set_cull_flag(LineartTriangle *tri, uchar flag)
|
||||
|
@ -1782,11 +1790,15 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu
|
|||
loop = loop->next;
|
||||
tri->v[2] = &orv[BM_elem_index_get(loop->v)];
|
||||
|
||||
/* Transparency bit assignment. */
|
||||
/* Material mask bits and occlusion effectiveness assignment. */
|
||||
Material *mat = BKE_object_material_get(orig_ob, f->mat_nr + 1);
|
||||
tri->transparency_mask = ((mat && (mat->lineart.flags & LRT_MATERIAL_TRANSPARENCY_ENABLED)) ?
|
||||
mat->lineart.transparency_mask :
|
||||
0);
|
||||
tri->material_mask_bits |= ((mat && (mat->lineart.flags & LRT_MATERIAL_MASK_ENABLED)) ?
|
||||
mat->lineart.material_mask_bits :
|
||||
0);
|
||||
tri->mat_occlusion |= ((mat &&
|
||||
(mat->lineart.flags & LRT_MATERIAL_CUSTOM_OCCLUSION_EFFECTIVENESS)) ?
|
||||
mat->lineart.mat_occlusion :
|
||||
1);
|
||||
|
||||
double gn[3];
|
||||
copy_v3db_v3fl(gn, f->no);
|
||||
|
@ -4172,8 +4184,8 @@ static void lineart_gpencil_generate(LineartCache *cache,
|
|||
Object *source_object,
|
||||
Collection *source_collection,
|
||||
int types,
|
||||
uchar transparency_flags,
|
||||
uchar transparency_mask,
|
||||
uchar material_mask_flags,
|
||||
uchar material_mask_bits,
|
||||
short thickness,
|
||||
float opacity,
|
||||
const char *source_vgname,
|
||||
|
@ -4229,14 +4241,14 @@ static void lineart_gpencil_generate(LineartCache *cache,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
if (transparency_flags & LRT_GPENCIL_TRANSPARENCY_ENABLE) {
|
||||
if (transparency_flags & LRT_GPENCIL_TRANSPARENCY_MATCH) {
|
||||
if (ec->transparency_mask != transparency_mask) {
|
||||
if (material_mask_flags & LRT_GPENCIL_MATERIAL_MASK_ENABLE) {
|
||||
if (material_mask_flags & LRT_GPENCIL_MATERIAL_MASK_MATCH) {
|
||||
if (ec->material_mask_bits != material_mask_bits) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(ec->transparency_mask & transparency_mask)) {
|
||||
if (!(ec->material_mask_bits & material_mask_bits)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -4335,8 +4347,8 @@ void MOD_lineart_gpencil_generate(LineartCache *cache,
|
|||
int level_end,
|
||||
int mat_nr,
|
||||
short edge_types,
|
||||
uchar transparency_flags,
|
||||
uchar transparency_mask,
|
||||
uchar material_mask_flags,
|
||||
uchar material_mask_bits,
|
||||
short thickness,
|
||||
float opacity,
|
||||
const char *source_vgname,
|
||||
|
@ -4384,8 +4396,8 @@ void MOD_lineart_gpencil_generate(LineartCache *cache,
|
|||
source_object,
|
||||
source_collection,
|
||||
use_types,
|
||||
transparency_flags,
|
||||
transparency_mask,
|
||||
material_mask_flags,
|
||||
material_mask_bits,
|
||||
thickness,
|
||||
opacity,
|
||||
source_vgname,
|
||||
|
|
|
@ -143,8 +143,8 @@ 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->transparency_flags,
|
||||
lmd->transparency_mask,
|
||||
lmd->material_mask_flags,
|
||||
lmd->material_mask_bits,
|
||||
lmd->thickness,
|
||||
lmd->opacity,
|
||||
lmd->source_vertex_group,
|
||||
|
|
|
@ -883,11 +883,11 @@ typedef enum eLineArtGPencilModifierFlags {
|
|||
LRT_GPENCIL_USE_CACHE = (1 << 4),
|
||||
} eLineArtGPencilModifierFlags;
|
||||
|
||||
typedef enum eLineartGpencilTransparencyFlags {
|
||||
LRT_GPENCIL_TRANSPARENCY_ENABLE = (1 << 0),
|
||||
/** Set to true means using "and" instead of "or" logic on mask bits. */
|
||||
LRT_GPENCIL_TRANSPARENCY_MATCH = (1 << 1),
|
||||
} eLineartGpencilTransparencyFlags;
|
||||
typedef enum eLineartGpencilMaterialMaskFlags {
|
||||
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;
|
||||
|
||||
struct LineartCache;
|
||||
|
||||
|
@ -918,8 +918,8 @@ typedef struct LineartGpencilModifierData {
|
|||
float opacity;
|
||||
short thickness;
|
||||
|
||||
unsigned char transparency_flags; /* eLineartGpencilTransparencyFlags */
|
||||
unsigned char transparency_mask;
|
||||
unsigned char material_mask_flags; /* eLineartGpencilMaterialMaskFlags */
|
||||
unsigned char material_mask_bits;
|
||||
|
||||
/** `0..1` range for cosine angle */
|
||||
float crease_threshold;
|
||||
|
|
|
@ -146,13 +146,21 @@ typedef enum eMaterialGPencilStyle_Mode {
|
|||
} eMaterialGPencilStyle_Mode;
|
||||
|
||||
typedef struct MaterialLineArt {
|
||||
int flags; /* eMaterialLineArtFlags */
|
||||
unsigned char transparency_mask;
|
||||
unsigned char _pad[3];
|
||||
/* eMaterialLineArtFlags */
|
||||
int flags;
|
||||
|
||||
/* Used to filter line art occlusion edges */
|
||||
unsigned char material_mask_bits;
|
||||
|
||||
/** Maximum 255 levels of equavalent occlusion. */
|
||||
unsigned char mat_occlusion;
|
||||
|
||||
unsigned char _pad[2];
|
||||
} MaterialLineArt;
|
||||
|
||||
typedef enum eMaterialLineArtFlags {
|
||||
LRT_MATERIAL_TRANSPARENCY_ENABLED = (1 << 0),
|
||||
LRT_MATERIAL_MASK_ENABLED = (1 << 0),
|
||||
LRT_MATERIAL_CUSTOM_OCCLUSION_EFFECTIVENESS = (1 << 1),
|
||||
} eMaterialLineArtFlags;
|
||||
|
||||
typedef struct Material {
|
||||
|
|
|
@ -134,3 +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_mask, material_mask_bits)
|
||||
DNA_STRUCT_RENAME_ELEM(MaterialLineArt, transparency_mask, material_mask_bits)
|
||||
|
|
|
@ -2997,20 +2997,22 @@ static void rna_def_modifier_gpencillineart(BlenderRNA *brna)
|
|||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_transparency", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_flags", LRT_GPENCIL_TRANSPARENCY_ENABLE);
|
||||
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_ui_text(
|
||||
prop, "Use Transparency", "Use transparency mask from this material in line art");
|
||||
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_transparency_match", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_flags", LRT_GPENCIL_TRANSPARENCY_MATCH);
|
||||
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_ui_text(
|
||||
prop, "Match Transparency", "Require matching all transparency masks instead of just one");
|
||||
prop, "Match Masks", "Require matching all material masks instead of just one");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_transparency_mask", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1);
|
||||
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_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
|
|
@ -688,19 +688,36 @@ static void rna_def_material_lineart(BlenderRNA *brna)
|
|||
RNA_def_struct_sdna(srna, "MaterialLineArt");
|
||||
RNA_def_struct_ui_text(srna, "Material Line Art", "");
|
||||
|
||||
prop = RNA_def_property(srna, "use_transparency", PROP_BOOLEAN, PROP_NONE);
|
||||
prop = RNA_def_property(srna, "use_material_mask", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_MATERIAL_TRANSPARENCY_ENABLED);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_MATERIAL_MASK_ENABLED);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Use Transparency", "Use transparency mask from this material in line art");
|
||||
prop, "Use Material Mask", "Use material masks to filter out occluded strokes");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_transparency_mask", PROP_BOOLEAN, PROP_NONE);
|
||||
prop = RNA_def_property(srna, "use_material_mask_bits", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1);
|
||||
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_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_mat_occlusion", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_MATERIAL_CUSTOM_OCCLUSION_EFFECTIVENESS);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Custom Occlusion Effectiveness",
|
||||
"Use custom occlusion effectiveness for this material");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update");
|
||||
|
||||
prop = RNA_def_property(srna, "mat_occlusion", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_default(prop, 1);
|
||||
RNA_def_property_ui_range(prop, 0.0f, 5.0f, 1.0f, 1);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Effectiveness",
|
||||
"Faces with this material will behave as if it has set number of layers in occlusion");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update");
|
||||
}
|
||||
|
||||
void RNA_def_material(BlenderRNA *brna)
|
||||
|
|
Loading…
Reference in New Issue