mask object blending and alpha options
This commit is contained in:
@@ -591,6 +591,13 @@ class CLIP_PT_mask_objects(Panel):
|
||||
active = mask.objects.active
|
||||
if active:
|
||||
layout.prop(active, "name")
|
||||
|
||||
# blending
|
||||
row = layout.row(align=True)
|
||||
row.prop(active, "alpha")
|
||||
row.prop(active, "invert", text="", icon='IMAGE_ALPHA')
|
||||
|
||||
layout.prop(active, "blend")
|
||||
|
||||
|
||||
class CLIP_PT_active_mask_spline(Panel):
|
||||
|
||||
@@ -1729,13 +1729,57 @@ void BKE_mask_object_shape_changed_remove(MaskObject *maskobj, int index, int co
|
||||
}
|
||||
}
|
||||
|
||||
/* local functions */
|
||||
static void invert_vn_vn(float *array, const int size)
|
||||
{
|
||||
float *arr = array + (size - 1);
|
||||
int i = size;
|
||||
while (i--) {
|
||||
*(arr) = 1.0f - *(arr);
|
||||
arr--;
|
||||
}
|
||||
}
|
||||
|
||||
static void m_invert_vn_vn(float *array, const float f, const int size)
|
||||
{
|
||||
float *arr = array + (size - 1);
|
||||
int i = size;
|
||||
while (i--) {
|
||||
*(arr) = 1.0f - (*(arr) * f);
|
||||
arr--;
|
||||
}
|
||||
}
|
||||
|
||||
static void clamp_vn_vn(float *array, const int size)
|
||||
{
|
||||
float *arr = array + (size - 1);
|
||||
|
||||
int i = size;
|
||||
while (i--) {
|
||||
if (*arr < 0.0f) *arr = 0.0f;
|
||||
else if (*arr > 1.0f) *arr = 1.0f;
|
||||
arr--;
|
||||
}
|
||||
}
|
||||
|
||||
/* rasterization */
|
||||
void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer)
|
||||
{
|
||||
MaskObject *maskobj;
|
||||
|
||||
/* temp blending buffer */
|
||||
const int buffer_size = width * height;
|
||||
float *buffer_tmp = MEM_mallocN(sizeof(float) * buffer_size, __func__);
|
||||
|
||||
for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) {
|
||||
MaskSpline *spline;
|
||||
float alpha;
|
||||
|
||||
if (maskobj->restrictflag & MASK_RESTRICT_RENDER) {
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(buffer_tmp, 0, sizeof(float) * buffer_size);
|
||||
|
||||
for (spline = maskobj->splines.first; spline; spline = spline->next) {
|
||||
float (*diff_points)[2];
|
||||
@@ -1774,17 +1818,67 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer)
|
||||
}
|
||||
|
||||
if (tot_diff_point) {
|
||||
PLX_raskterize((float (*)[2])diff_points, tot_diff_point, buffer, width, height);
|
||||
PLX_raskterize((float (*)[2])diff_points, tot_diff_point,
|
||||
buffer_tmp, width, height);
|
||||
|
||||
if (tot_diff_feather_points) {
|
||||
PLX_raskterize_feather((float (*)[2])diff_points, tot_diff_point,
|
||||
(float (*)[2])diff_feather_points, tot_diff_feather_points,
|
||||
buffer, width, height);
|
||||
MEM_freeN(diff_feather_points);
|
||||
buffer_tmp, width, height);
|
||||
}
|
||||
|
||||
MEM_freeN(diff_points);
|
||||
if (tot_diff_point) {
|
||||
MEM_freeN(diff_points);
|
||||
}
|
||||
if (tot_diff_feather_points) {
|
||||
MEM_freeN(diff_feather_points);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* blend with original */
|
||||
if (maskobj->blend_flag & MASK_BLENDFLAG_INVERT) {
|
||||
/* apply alpha multiply before inverting */
|
||||
if (maskobj->alpha != 1.0f) {
|
||||
m_invert_vn_vn(buffer_tmp, maskobj->alpha, buffer_size);
|
||||
}
|
||||
else {
|
||||
invert_vn_vn(buffer_tmp, buffer_size);
|
||||
}
|
||||
|
||||
alpha = 1.0f;
|
||||
}
|
||||
else {
|
||||
alpha = maskobj->alpha;
|
||||
}
|
||||
|
||||
switch (maskobj->blend) {
|
||||
case MASK_BLEND_SUBTRACT:
|
||||
{
|
||||
if (alpha == 1.0f) {
|
||||
sub_vn_vn(buffer, buffer_tmp, buffer_size);
|
||||
}
|
||||
else {
|
||||
msub_vn_vn(buffer, buffer_tmp, alpha, buffer_size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MASK_BLEND_ADD:
|
||||
default:
|
||||
{
|
||||
if (alpha == 1.0f) {
|
||||
add_vn_vn(buffer, buffer_tmp, buffer_size);
|
||||
}
|
||||
else {
|
||||
madd_vn_vn(buffer, buffer_tmp, alpha, buffer_size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* clamp at the end */
|
||||
clamp_vn_vn(buffer, buffer_size);
|
||||
}
|
||||
|
||||
MEM_freeN(buffer_tmp);
|
||||
}
|
||||
|
||||
@@ -2251,6 +2251,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
|
||||
// uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE); // enable when used
|
||||
uiItemR(row, itemptr, "hide", 0, "", 0);
|
||||
uiItemR(row, itemptr, "hide_select", 0, "", 0);
|
||||
uiItemR(row, itemptr, "hide_render", 0, "", 0);
|
||||
|
||||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
}
|
||||
|
||||
@@ -108,10 +108,14 @@ typedef struct MaskObject {
|
||||
struct MaskSpline *act_spline; /* active spline */
|
||||
struct MaskSplinePoint *act_point; /* active point */
|
||||
|
||||
/* blending options */
|
||||
float alpha;
|
||||
char blend;
|
||||
char blend_flag;
|
||||
|
||||
//char flag; /* not used yet */
|
||||
char restrictflag; /* matching 'Object' flag of the same name - eventually use in the outliner */
|
||||
char pad[3];
|
||||
char pad[1];
|
||||
} MaskObject;
|
||||
|
||||
/* MaskParent->flag */
|
||||
@@ -144,4 +148,16 @@ enum {
|
||||
MASK_DT_WHITE
|
||||
};
|
||||
|
||||
/* maskobj->blend */
|
||||
enum {
|
||||
MASK_BLEND_ADD = 0,
|
||||
MASK_BLEND_SUBTRACT = 1
|
||||
};
|
||||
|
||||
/* maskobj->blend_flag */
|
||||
enum {
|
||||
MASK_BLENDFLAG_INVERT = (1 << 0)
|
||||
};
|
||||
|
||||
|
||||
#endif // __DNA_MASK_TYPES_H__
|
||||
|
||||
@@ -126,6 +126,11 @@ static void rna_Mask_object_active_index_range(PointerRNA *ptr, int *min, int *m
|
||||
*softmax = *max;
|
||||
}
|
||||
|
||||
static char *rna_MaskObject_path(PointerRNA *ptr)
|
||||
{
|
||||
return BLI_sprintfN("objects[\"%s\"]", ((MaskObject *)ptr->data)->name);
|
||||
}
|
||||
|
||||
static PointerRNA rna_Mask_object_active_get(PointerRNA *ptr)
|
||||
{
|
||||
Mask *mask = (Mask *)ptr->id.data;
|
||||
@@ -483,7 +488,8 @@ static void rna_def_maskSpline(BlenderRNA *brna)
|
||||
static EnumPropertyItem spline_interpolation_items[] = {
|
||||
{MASK_SPLINE_INTERP_LINEAR, "LINEAR", 0, "Linear", ""},
|
||||
{MASK_SPLINE_INTERP_EASE, "EASE", 0, "Ease", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
@@ -510,6 +516,12 @@ static void rna_def_maskSpline(BlenderRNA *brna)
|
||||
|
||||
static void rna_def_mask_object(BlenderRNA *brna)
|
||||
{
|
||||
static EnumPropertyItem maskobj_blend_mode_items[] = {
|
||||
{MASK_BLEND_ADD, "ADD", 0, "Add", ""},
|
||||
{MASK_BLEND_SUBTRACT, "SUBTRACT", 0, "Subtract", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
@@ -518,6 +530,7 @@ static void rna_def_mask_object(BlenderRNA *brna)
|
||||
|
||||
srna = RNA_def_struct(brna, "MaskObject", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Mask Object", "Single object used for masking pixels");
|
||||
RNA_def_struct_path_func(srna, "rna_MaskObject_path");
|
||||
|
||||
/* name */
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
@@ -551,14 +564,28 @@ static void rna_def_mask_object(BlenderRNA *brna)
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", MASK_RESTRICT_RENDER);
|
||||
RNA_def_property_ui_text(prop, "Restrict Render", "Restrict renderability");
|
||||
RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1);
|
||||
RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL);
|
||||
RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL);
|
||||
|
||||
/* render settings */
|
||||
prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "alpha");
|
||||
RNA_def_property_range(prop, 0.0, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Opacity", "Render Opacity");
|
||||
RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL);
|
||||
RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL);
|
||||
|
||||
/* weight interpolation */
|
||||
prop = RNA_def_property(srna, "blend", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "blend");
|
||||
RNA_def_property_enum_items(prop, maskobj_blend_mode_items);
|
||||
RNA_def_property_ui_text(prop, "Blend", "Method of blending mask objects");
|
||||
RNA_def_property_update(prop, 0, "rna_Mask_update_data");
|
||||
RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "blend_flag", MASK_BLENDFLAG_INVERT);
|
||||
RNA_def_property_ui_text(prop, "Restrict View", "Restrict visibility in the viewport");
|
||||
RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL);
|
||||
|
||||
}
|
||||
|
||||
static void rna_def_maskobjects(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
@@ -616,6 +643,9 @@ static void rna_def_mask(BlenderRNA *brna)
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_int_funcs(prop, "rna_Mask_object_active_index_get", "rna_Mask_object_active_index_set", "rna_Mask_object_active_index_range");
|
||||
RNA_def_property_ui_text(prop, "Active Shape Index", "Index of active object in list of all mask's objects");
|
||||
|
||||
/* pointers */
|
||||
rna_def_animdata_common(srna);
|
||||
}
|
||||
|
||||
void RNA_def_mask(BlenderRNA *brna)
|
||||
|
||||
Reference in New Issue
Block a user