Compositor: Turn Mask options into inputs
This patch turns the options of the Mask node into inputs. Reference #137223. Pull Request: https://projects.blender.org/blender/blender/pulls/137479
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 23
|
||||
#define BLENDER_FILE_SUBVERSION 24
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
||||
@@ -680,6 +680,19 @@ static void write_compositor_legacy_properties(bNodeTree &node_tree)
|
||||
property = input->default_value_typed<bNodeSocketValueBoolean>()->value;
|
||||
};
|
||||
|
||||
auto write_input_to_property_bool_int16_flag = [&](const char *identifier,
|
||||
int16_t &property,
|
||||
const int flag,
|
||||
const bool negative = false) {
|
||||
const bNodeSocket *input = blender::bke::node_find_socket(*node, SOCK_IN, identifier);
|
||||
if (bool(input->default_value_typed<bNodeSocketValueBoolean>()->value) != negative) {
|
||||
property |= flag;
|
||||
}
|
||||
else {
|
||||
property &= ~flag;
|
||||
}
|
||||
};
|
||||
|
||||
auto write_input_to_property_int = [&](const char *identifier, int &property) {
|
||||
const bNodeSocket *input = blender::bke::node_find_socket(*node, SOCK_IN, identifier);
|
||||
property = input->default_value_typed<bNodeSocketValueInt>()->value;
|
||||
@@ -713,6 +726,18 @@ static void write_compositor_legacy_properties(bNodeTree &node_tree)
|
||||
write_input_to_property_int16("Start Frame", node->custom1);
|
||||
write_input_to_property_int16("End Frame", node->custom2);
|
||||
}
|
||||
|
||||
if (node->type_legacy == CMP_NODE_MASK) {
|
||||
NodeMask *storage = static_cast<NodeMask *>(node->storage);
|
||||
write_input_to_property_int("Size X", storage->size_x);
|
||||
write_input_to_property_int("Size Y", storage->size_y);
|
||||
write_input_to_property_bool_int16_flag(
|
||||
"Feather", node->custom1, CMP_NODE_MASK_FLAG_NO_FEATHER, true);
|
||||
write_input_to_property_bool_int16_flag(
|
||||
"Motion Blur", node->custom1, CMP_NODE_MASK_FLAG_MOTION_BLUR);
|
||||
write_input_to_property_int16("Motion Blur Samples", node->custom2);
|
||||
write_input_to_property_float("Motion Blur Shutter", node->custom3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1932,6 +1932,97 @@ static void do_version_time_curve_node_options_to_inputs_animation(bNodeTree *no
|
||||
});
|
||||
}
|
||||
|
||||
/* The options were converted into inputs. */
|
||||
static void do_version_mask_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
|
||||
{
|
||||
NodeMask *storage = static_cast<NodeMask *>(node->storage);
|
||||
if (!storage) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!blender::bke::node_find_socket(*node, SOCK_IN, "Size X")) {
|
||||
bNodeSocket *input = blender::bke::node_add_static_socket(
|
||||
*node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Size X", "Size X");
|
||||
input->default_value_typed<bNodeSocketValueInt>()->value = storage->size_x;
|
||||
}
|
||||
|
||||
if (!blender::bke::node_find_socket(*node, SOCK_IN, "Size Y")) {
|
||||
bNodeSocket *input = blender::bke::node_add_static_socket(
|
||||
*node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Size Y", "Size Y");
|
||||
input->default_value_typed<bNodeSocketValueInt>()->value = storage->size_y;
|
||||
}
|
||||
|
||||
if (!blender::bke::node_find_socket(*node, SOCK_IN, "Feather")) {
|
||||
bNodeSocket *input = blender::bke::node_add_static_socket(
|
||||
*node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Feather", "Feather");
|
||||
input->default_value_typed<bNodeSocketValueBoolean>()->value = !(
|
||||
node->custom1 & CMP_NODE_MASK_FLAG_NO_FEATHER);
|
||||
}
|
||||
|
||||
if (!blender::bke::node_find_socket(*node, SOCK_IN, "Motion Blur")) {
|
||||
bNodeSocket *input = blender::bke::node_add_static_socket(
|
||||
*node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Motion Blur", "Motion Blur");
|
||||
input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(
|
||||
node->custom1 & CMP_NODE_MASK_FLAG_MOTION_BLUR);
|
||||
}
|
||||
|
||||
if (!blender::bke::node_find_socket(*node, SOCK_IN, "Motion Blur Samples")) {
|
||||
bNodeSocket *input = blender::bke::node_add_static_socket(
|
||||
*node_tree, *node, SOCK_IN, SOCK_INT, PROP_NONE, "Motion Blur Samples", "Samples");
|
||||
input->default_value_typed<bNodeSocketValueInt>()->value = node->custom2;
|
||||
}
|
||||
|
||||
if (!blender::bke::node_find_socket(*node, SOCK_IN, "Motion Blur Shutter")) {
|
||||
bNodeSocket *input = blender::bke::node_add_static_socket(
|
||||
*node_tree, *node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Motion Blur Shutter", "Shutter");
|
||||
input->default_value_typed<bNodeSocketValueFloat>()->value = node->custom3;
|
||||
}
|
||||
}
|
||||
|
||||
/* The options were converted into inputs. */
|
||||
static void do_version_mask_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
|
||||
{
|
||||
/* Compute the RNA path of the node. */
|
||||
char escaped_node_name[sizeof(node->name) * 2 + 1];
|
||||
BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
|
||||
const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
|
||||
|
||||
BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
|
||||
/* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
|
||||
* path. */
|
||||
if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
|
||||
* values of the FCurves frames when needed. */
|
||||
char *old_rna_path = fcurve->rna_path;
|
||||
if (BLI_str_endswith(fcurve->rna_path, "size_x")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[0].default_value");
|
||||
}
|
||||
else if (BLI_str_endswith(fcurve->rna_path, "size_y")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[1].default_value");
|
||||
}
|
||||
else if (BLI_str_endswith(fcurve->rna_path, "use_feather")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
|
||||
}
|
||||
else if (BLI_str_endswith(fcurve->rna_path, "use_motion_blur")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
|
||||
}
|
||||
else if (BLI_str_endswith(fcurve->rna_path, "motion_blur_samples")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[4].default_value");
|
||||
}
|
||||
else if (BLI_str_endswith(fcurve->rna_path, "motion_blur_shutter")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[5].default_value");
|
||||
}
|
||||
|
||||
/* The RNA path was changed, free the old path. */
|
||||
if (fcurve->rna_path != old_rna_path) {
|
||||
MEM_freeN(old_rna_path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void do_version_viewer_shortcut(bNodeTree *node_tree)
|
||||
{
|
||||
LISTBASE_FOREACH_MUTABLE (bNode *, node, &node_tree->nodes) {
|
||||
@@ -2399,6 +2490,19 @@ void do_versions_after_linking_400(FileData *fd, Main *bmain)
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 24)) {
|
||||
FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
|
||||
if (node_tree->type == NTREE_COMPOSIT) {
|
||||
LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
|
||||
if (node->type_legacy == CMP_NODE_MASK) {
|
||||
do_version_mask_node_options_to_inputs_animation(node_tree, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.
|
||||
@@ -6984,6 +7088,19 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 24)) {
|
||||
FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
|
||||
if (node_tree->type == NTREE_COMPOSIT) {
|
||||
LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
|
||||
if (node->type_legacy == CMP_NODE_MASK) {
|
||||
do_version_mask_node_options_to_inputs(node_tree, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
/* Always run this versioning (keep at the bottom of the function). Meshes are written with the
|
||||
* legacy format which always needs to be converted to the new format on file load. To be moved
|
||||
* to a subversion check in 5.0. */
|
||||
|
||||
@@ -1321,7 +1321,8 @@ typedef struct NodeDilateErode {
|
||||
} NodeDilateErode;
|
||||
|
||||
typedef struct NodeMask {
|
||||
int size_x, size_y;
|
||||
int size_x DNA_DEPRECATED;
|
||||
int size_y DNA_DEPRECATED;
|
||||
} NodeMask;
|
||||
|
||||
typedef struct NodeSetAlpha {
|
||||
|
||||
@@ -3850,6 +3850,14 @@ static const char node_input_color_shift[] = "Color Shift";
|
||||
static const char node_input_start_frame[] = "Start Frame";
|
||||
static const char node_input_end_frame[] = "End Frame";
|
||||
|
||||
/* Mask node. */
|
||||
static const char node_input_size_x[] = "Size X";
|
||||
static const char node_input_size_y[] = "Size Y";
|
||||
static const char node_input_feather[] = "Feather";
|
||||
static const char node_input_motion_blur[] = "Motion Blur";
|
||||
static const char node_input_motion_blur_samples[] = "Motion Blur Samples";
|
||||
static const char node_input_motion_blur_shutter[] = "Motion Blur Shutter";
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* White Balance Node.
|
||||
*/
|
||||
@@ -8843,23 +8851,36 @@ static void def_cmp_mask(BlenderRNA * /*brna*/, StructRNA *srna)
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update_relations");
|
||||
|
||||
prop = RNA_def_property(srna, "use_feather", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_negative_sdna(prop, nullptr, "custom1", CMP_NODE_MASK_FLAG_NO_FEATHER);
|
||||
RNA_def_property_boolean_funcs(prop,
|
||||
"rna_node_property_to_input_getter<bool, node_input_feather>",
|
||||
"rna_node_property_to_input_setter<bool, node_input_feather>");
|
||||
RNA_def_property_ui_text(prop, "Feather", "Use feather information from the mask");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_motion_blur", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "custom1", CMP_NODE_MASK_FLAG_MOTION_BLUR);
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop,
|
||||
"rna_node_property_to_input_getter<bool, node_input_motion_blur>",
|
||||
"rna_node_property_to_input_setter<bool, node_input_motion_blur>");
|
||||
RNA_def_property_ui_text(prop, "Motion Blur", "Use multi-sampled motion blur of the mask");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, nullptr, "custom2");
|
||||
RNA_def_property_int_funcs(
|
||||
prop,
|
||||
"rna_node_property_to_input_getter<int, node_input_motion_blur_samples>",
|
||||
"rna_node_property_to_input_setter<int, node_input_motion_blur_samples>",
|
||||
nullptr);
|
||||
RNA_def_property_range(prop, 1, CMP_NODE_MASK_MBLUR_SAMPLES_MAX);
|
||||
RNA_def_property_ui_text(prop, "Samples", "Number of motion blur samples");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, nullptr, "custom3");
|
||||
RNA_def_property_float_funcs(
|
||||
prop,
|
||||
"rna_node_property_to_input_getter<float, node_input_motion_blur_shutter>",
|
||||
"rna_node_property_to_input_setter<float, node_input_motion_blur_shutter>",
|
||||
nullptr);
|
||||
RNA_def_property_range(prop, 0.0, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Shutter", "Exposure for motion blur as a factor of FPS");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
@@ -8871,14 +8892,20 @@ static void def_cmp_mask(BlenderRNA * /*brna*/, StructRNA *srna)
|
||||
prop, "Size Source", "Where to get the mask size from for aspect/size information");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
RNA_def_struct_sdna_from(srna, "NodeMask", "storage");
|
||||
|
||||
prop = RNA_def_property(srna, "size_x", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_funcs(prop,
|
||||
"rna_node_property_to_input_getter<int, node_input_size_x>",
|
||||
"rna_node_property_to_input_setter<int, node_input_size_x>",
|
||||
nullptr);
|
||||
RNA_def_property_range(prop, 1.0f, 10000.0f);
|
||||
RNA_def_property_ui_text(prop, "X", "");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "size_y", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_funcs(prop,
|
||||
"rna_node_property_to_input_getter<int, node_input_size_y>",
|
||||
"rna_node_property_to_input_setter<int, node_input_size_y>",
|
||||
nullptr);
|
||||
RNA_def_property_range(prop, 1.0f, 10000.0f);
|
||||
RNA_def_property_ui_text(prop, "Y", "");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* \ingroup cmpnodes
|
||||
*/
|
||||
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_string_utf8.h"
|
||||
|
||||
#include "DNA_mask_types.h"
|
||||
@@ -22,21 +23,59 @@
|
||||
|
||||
namespace blender::nodes::node_composite_mask_cc {
|
||||
|
||||
NODE_STORAGE_FUNCS(NodeMask)
|
||||
|
||||
static void cmp_node_mask_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.use_custom_socket_order();
|
||||
|
||||
b.add_output<decl::Float>("Mask");
|
||||
|
||||
b.add_layout([](uiLayout *layout, bContext *C, PointerRNA *ptr) {
|
||||
uiTemplateID(layout, C, ptr, "mask", nullptr, nullptr, nullptr);
|
||||
uiItemR(layout, ptr, "size_source", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
|
||||
});
|
||||
|
||||
b.add_input<decl::Int>("Size X")
|
||||
.default_value(256)
|
||||
.min(1)
|
||||
.description("The resolution of the mask along the X direction")
|
||||
.compositor_expects_single_value();
|
||||
b.add_input<decl::Int>("Size Y")
|
||||
.default_value(256)
|
||||
.min(1)
|
||||
.description("The resolution of the mask along the Y direction")
|
||||
.compositor_expects_single_value();
|
||||
b.add_input<decl::Bool>("Feather")
|
||||
.default_value(true)
|
||||
.description("Use feather information from the mask")
|
||||
.compositor_expects_single_value();
|
||||
|
||||
PanelDeclarationBuilder &motion_blur_panel = b.add_panel("Motion Blur").default_closed(true);
|
||||
motion_blur_panel.add_input<decl::Bool>("Motion Blur")
|
||||
.default_value(false)
|
||||
.panel_toggle()
|
||||
.description("Use multi-sampled motion blur of the mask")
|
||||
.compositor_expects_single_value();
|
||||
motion_blur_panel.add_input<decl::Int>("Samples", "Motion Blur Samples")
|
||||
.default_value(16)
|
||||
.min(1)
|
||||
.max(64)
|
||||
.description("Number of motion blur samples")
|
||||
.compositor_expects_single_value();
|
||||
motion_blur_panel.add_input<decl::Float>("Shutter", "Motion Blur Shutter")
|
||||
.default_value(0.5f)
|
||||
.subtype(PROP_FACTOR)
|
||||
.min(0.0f)
|
||||
.max(1.0f)
|
||||
.description("Exposure for motion blur as a factor of FPS")
|
||||
.compositor_expects_single_value();
|
||||
}
|
||||
|
||||
static void node_composit_init_mask(bNodeTree * /*ntree*/, bNode *node)
|
||||
{
|
||||
/* All members are deprecated and needn't be set, but the data is still allocated for forward
|
||||
* compatibility. */
|
||||
NodeMask *data = MEM_callocN<NodeMask>(__func__);
|
||||
data->size_x = data->size_y = 256;
|
||||
node->storage = data;
|
||||
|
||||
node->custom2 = 16; /* samples */
|
||||
node->custom3 = 0.5f; /* shutter */
|
||||
}
|
||||
|
||||
static void node_mask_label(const bNodeTree * /*ntree*/,
|
||||
@@ -47,27 +86,14 @@ static void node_mask_label(const bNodeTree * /*ntree*/,
|
||||
BLI_strncpy_utf8(label, node->id ? node->id->name + 2 : IFACE_("Mask"), label_maxncpy);
|
||||
}
|
||||
|
||||
static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *ptr)
|
||||
static void node_update(bNodeTree *ntree, bNode *node)
|
||||
{
|
||||
bNode *node = (bNode *)ptr->data;
|
||||
|
||||
uiTemplateID(layout, C, ptr, "mask", nullptr, nullptr, nullptr);
|
||||
uiItemR(layout, ptr, "use_feather", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
|
||||
|
||||
uiItemR(layout, ptr, "size_source", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
|
||||
|
||||
if (node->custom1 & (CMP_NODE_MASK_FLAG_SIZE_FIXED | CMP_NODE_MASK_FLAG_SIZE_FIXED_SCENE)) {
|
||||
uiItemR(layout, ptr, "size_x", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
|
||||
uiItemR(layout, ptr, "size_y", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
|
||||
}
|
||||
|
||||
uiItemR(layout, ptr, "use_motion_blur", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
|
||||
if (node->custom1 & CMP_NODE_MASK_FLAG_MOTION_BLUR) {
|
||||
uiItemR(
|
||||
layout, ptr, "motion_blur_samples", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
|
||||
uiItemR(
|
||||
layout, ptr, "motion_blur_shutter", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
|
||||
}
|
||||
const bool is_size_needed = node->custom1 & (CMP_NODE_MASK_FLAG_SIZE_FIXED |
|
||||
CMP_NODE_MASK_FLAG_SIZE_FIXED_SCENE);
|
||||
bNodeSocket *size_x_input = bke::node_find_socket(*node, SOCK_IN, "Size X");
|
||||
bNodeSocket *size_y_input = bke::node_find_socket(*node, SOCK_IN, "Size Y");
|
||||
blender::bke::node_set_socket_availability(*ntree, *size_x_input, is_size_needed);
|
||||
blender::bke::node_set_socket_availability(*ntree, *size_y_input, is_size_needed);
|
||||
}
|
||||
|
||||
using namespace blender::compositor;
|
||||
@@ -78,89 +104,97 @@ class MaskOperation : public NodeOperation {
|
||||
|
||||
void execute() override
|
||||
{
|
||||
Result &output_mask = get_result("Mask");
|
||||
if (!get_mask() || (!is_fixed_size() && !context().is_valid_compositing_region())) {
|
||||
Result &output_mask = this->get_result("Mask");
|
||||
if (!this->get_mask() ||
|
||||
(!this->is_fixed_size() && !this->context().is_valid_compositing_region()))
|
||||
{
|
||||
output_mask.allocate_invalid();
|
||||
return;
|
||||
}
|
||||
|
||||
const Domain domain = compute_domain();
|
||||
Result &cached_mask = context().cache_manager().cached_masks.get(context(),
|
||||
get_mask(),
|
||||
domain.size,
|
||||
get_aspect_ratio(),
|
||||
get_use_feather(),
|
||||
get_motion_blur_samples(),
|
||||
get_motion_blur_shutter());
|
||||
Result &cached_mask = context().cache_manager().cached_masks.get(
|
||||
this->context(),
|
||||
this->get_mask(),
|
||||
domain.size,
|
||||
this->get_aspect_ratio(),
|
||||
this->get_use_feather(),
|
||||
this->get_motion_blur_samples(),
|
||||
this->get_motion_blur_shutter());
|
||||
|
||||
output_mask.wrap_external(cached_mask);
|
||||
}
|
||||
|
||||
Domain compute_domain() override
|
||||
{
|
||||
return Domain(compute_size());
|
||||
return Domain(this->compute_size());
|
||||
}
|
||||
|
||||
int2 compute_size()
|
||||
{
|
||||
if (get_flags() & CMP_NODE_MASK_FLAG_SIZE_FIXED) {
|
||||
return get_size();
|
||||
if (this->get_flags() & CMP_NODE_MASK_FLAG_SIZE_FIXED) {
|
||||
return this->get_size();
|
||||
}
|
||||
|
||||
if (get_flags() & CMP_NODE_MASK_FLAG_SIZE_FIXED_SCENE) {
|
||||
return get_size() * context().get_render_percentage();
|
||||
if (this->get_flags() & CMP_NODE_MASK_FLAG_SIZE_FIXED_SCENE) {
|
||||
return this->get_size() * this->context().get_render_percentage();
|
||||
}
|
||||
|
||||
return context().get_compositing_region_size();
|
||||
return this->context().get_compositing_region_size();
|
||||
}
|
||||
|
||||
int2 get_size()
|
||||
{
|
||||
return int2(node_storage(bnode()).size_x, node_storage(bnode()).size_y);
|
||||
return int2(math::max(1, this->get_input("Size X").get_single_value_default(256)),
|
||||
math::max(1, this->get_input("Size Y").get_single_value_default(256)));
|
||||
}
|
||||
|
||||
float get_aspect_ratio()
|
||||
{
|
||||
if (is_fixed_size()) {
|
||||
if (this->is_fixed_size()) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
return context().get_render_data().yasp / context().get_render_data().xasp;
|
||||
return this->context().get_render_data().yasp / this->context().get_render_data().xasp;
|
||||
}
|
||||
|
||||
bool is_fixed_size()
|
||||
{
|
||||
return get_flags() & (CMP_NODE_MASK_FLAG_SIZE_FIXED | CMP_NODE_MASK_FLAG_SIZE_FIXED_SCENE);
|
||||
return this->get_flags() &
|
||||
(CMP_NODE_MASK_FLAG_SIZE_FIXED | CMP_NODE_MASK_FLAG_SIZE_FIXED_SCENE);
|
||||
}
|
||||
|
||||
bool get_use_feather()
|
||||
{
|
||||
return !bool(get_flags() & CMP_NODE_MASK_FLAG_NO_FEATHER);
|
||||
return this->get_input("Feather").get_single_value_default(true);
|
||||
}
|
||||
|
||||
int get_motion_blur_samples()
|
||||
{
|
||||
return use_motion_blur() ? bnode().custom2 : 1;
|
||||
const int samples = math::clamp(
|
||||
this->get_input("Motion Blur Samples").get_single_value_default(16), 1, 64);
|
||||
return this->use_motion_blur() ? samples : 1;
|
||||
}
|
||||
|
||||
float get_motion_blur_shutter()
|
||||
{
|
||||
return bnode().custom3;
|
||||
return math::clamp(
|
||||
this->get_input("Motion Blur Shutter").get_single_value_default(0.5f), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
bool use_motion_blur()
|
||||
{
|
||||
return get_flags() & CMP_NODE_MASK_FLAG_MOTION_BLUR;
|
||||
return this->get_input("Motion Blur").get_single_value_default(false);
|
||||
}
|
||||
|
||||
CMPNodeMaskFlags get_flags()
|
||||
{
|
||||
return static_cast<CMPNodeMaskFlags>(bnode().custom1);
|
||||
return static_cast<CMPNodeMaskFlags>(this->bnode().custom1);
|
||||
}
|
||||
|
||||
Mask *get_mask()
|
||||
{
|
||||
return reinterpret_cast<Mask *>(bnode().id);
|
||||
return reinterpret_cast<Mask *>(this->bnode().id);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -183,7 +217,7 @@ void register_node_type_cmp_mask()
|
||||
ntype.enum_name_legacy = "MASK";
|
||||
ntype.nclass = NODE_CLASS_INPUT;
|
||||
ntype.declare = file_ns::cmp_node_mask_declare;
|
||||
ntype.draw_buttons = file_ns::node_composit_buts_mask;
|
||||
ntype.updatefunc = file_ns::node_update;
|
||||
ntype.initfunc = file_ns::node_composit_init_mask;
|
||||
ntype.labelfunc = file_ns::node_mask_label;
|
||||
ntype.get_compositor_operation = file_ns::get_compositor_operation;
|
||||
|
||||
Reference in New Issue
Block a user