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:
authorJeroen Bakker <jeroen@blender.org>2021-03-16 09:37:30 +0300
committerJeroen Bakker <jeroen@blender.org>2021-03-16 09:43:17 +0300
commitd49e7b82da67885aac5933e094ee217ff777ac03 (patch)
tree6ef994837bc165e76bd17aacb1f5296033f31c09 /source/blender/makesrna/intern/rna_nodetree.c
parent269536d47ec5684a1c6018353120559be0ba2961 (diff)
Compositor: Redesign Cryptomatte node for better usability
In the current implementation, cryptomatte passes are connected to the node and elements are picked by using the eyedropper tool on a special pick channel. This design has two disadvantages - both connecting all passes individually and always having to switch to the picker channel are tedious. With the new design, the user selects the RenderLayer or Image from which the Cryptomatte layers are directly loaded (the type of pass is determined by an enum). This allows the node to automatically detect all relevant passes. Then, when using the eyedropper tool, the operator looks up the selected coordinates from the picked Image, Node backdrop or Clip and reads the picked object directly from the Renderlayer/Image, therefore allowing to pick in any context (e.g. by clicking on the Combined pass in the Image Viewer). The sampled color is looked up in the metadata and the actual name is stored in the cryptomatte node. This also allows to remove a hash by just removing the name from the matte id. Technically there is some loss of flexibility because the Cryptomatte pass inputs can no longer be connected to other nodes, but since any compositing done on them is likely to break the Cryptomatte system anyways, this isn't really a concern in practise. In the future, this would also allow to automatically translate values to names by looking up the value in the associated metadata of the input, or to get a better visualization of overlapping areas in the Pick output since we could blend colors now that the output doesn't have to contain the exact value. Idea + Original patch: Lucas Stockner Reviewed By: Brecht van Lommel Differential Revision: https://developer.blender.org/D3959
Diffstat (limited to 'source/blender/makesrna/intern/rna_nodetree.c')
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c215
1 files changed, 209 insertions, 6 deletions
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 622460979e7..35c319c2f79 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -398,6 +398,12 @@ static const EnumPropertyItem prop_shader_output_target_items[] = {
{0, NULL, 0, NULL, NULL},
};
+static const EnumPropertyItem node_cryptomatte_layer_name_items[] = {
+ {0, "CryptoObject", 0, "Object", "Use Object layer"},
+ {1, "CryptoMaterial", 0, "Material", "Use Material layer"},
+ {2, "CryptoAsset", 0, "Asset", "Use Asset layer"},
+ {0, NULL, 0, NULL, NULL}};
+
#endif
#define ITEM_ATTRIBUTE \
@@ -3444,6 +3450,10 @@ static void rna_Node_image_layer_update(Main *bmain, Scene *scene, PointerRNA *p
Image *ima = (Image *)node->id;
ImageUser *iuser = node->storage;
+ if (node->type == CMP_NODE_CRYPTOMATTE && node->custom1 != CMP_CRYPTOMATTE_SRC_IMAGE) {
+ return;
+ }
+
BKE_image_multilayer_index(ima->rr, iuser);
BKE_image_signal(bmain, ima, iuser, IMA_SIGNAL_SRC_CHANGE);
@@ -3490,6 +3500,10 @@ static const EnumPropertyItem *rna_Node_image_layer_itemf(bContext *UNUSED(C),
const EnumPropertyItem *item = NULL;
RenderLayer *rl;
+ if (node->type == CMP_NODE_CRYPTOMATTE && node->custom1 != CMP_CRYPTOMATTE_SRC_IMAGE) {
+ return DummyRNA_NULL_items;
+ }
+
if (ima == NULL || ima->rr == NULL) {
*r_free = false;
return DummyRNA_NULL_items;
@@ -3508,8 +3522,12 @@ static bool rna_Node_image_has_layers_get(PointerRNA *ptr)
bNode *node = (bNode *)ptr->data;
Image *ima = (Image *)node->id;
+ if (node->type == CMP_NODE_CRYPTOMATTE && node->custom1 != CMP_CRYPTOMATTE_SRC_IMAGE) {
+ return false;
+ }
+
if (!ima || !(ima->rr)) {
- return 0;
+ return false;
}
return RE_layers_have_name(ima->rr);
@@ -3520,8 +3538,12 @@ static bool rna_Node_image_has_views_get(PointerRNA *ptr)
bNode *node = (bNode *)ptr->data;
Image *ima = (Image *)node->id;
+ if (node->type == CMP_NODE_CRYPTOMATTE && node->custom1 != CMP_CRYPTOMATTE_SRC_IMAGE) {
+ return false;
+ }
+
if (!ima || !(ima->rr)) {
- return 0;
+ return false;
}
return BLI_listbase_count_at_most(&ima->rr->views, 2) > 1;
@@ -3566,6 +3588,10 @@ static const EnumPropertyItem *rna_Node_image_view_itemf(bContext *UNUSED(C),
const EnumPropertyItem *item = NULL;
RenderView *rv;
+ if (node->type == CMP_NODE_CRYPTOMATTE && node->custom1 != CMP_CRYPTOMATTE_SRC_IMAGE) {
+ return DummyRNA_NULL_items;
+ }
+
if (ima == NULL || ima->rr == NULL) {
*r_free = false;
return DummyRNA_NULL_items;
@@ -3722,6 +3748,115 @@ static void rna_NodeColorBalance_update_cdl(Main *bmain, Scene *scene, PointerRN
rna_Node_update(bmain, scene, ptr);
}
+static void rna_NodeCryptomatte_source_set(PointerRNA *ptr, int value)
+{
+ bNode *node = (bNode *)ptr->data;
+ if (node->id && node->custom1 != value) {
+ id_us_min((ID *)node->id);
+ node->id = NULL;
+ }
+ node->custom1 = value;
+}
+
+static int rna_NodeCryptomatte_layer_name_get(PointerRNA *ptr)
+{
+ int index = 0;
+ bNode *node = (bNode *)ptr->data;
+ NodeCryptomatte *storage = node->storage;
+ LISTBASE_FOREACH_INDEX (CryptomatteLayer *, layer, &storage->runtime.layers, index) {
+ if (STREQLEN(storage->layer_name, layer->name, sizeof(storage->layer_name))) {
+ return index;
+ }
+ }
+ return 0;
+}
+
+static void rna_NodeCryptomatte_layer_name_set(PointerRNA *ptr, int new_value)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeCryptomatte *storage = node->storage;
+
+ CryptomatteLayer *layer = BLI_findlink(&storage->runtime.layers, new_value);
+ if (layer) {
+ STRNCPY(storage->layer_name, layer->name);
+ }
+}
+
+static const EnumPropertyItem *rna_NodeCryptomatte_layer_name_itemf(bContext *UNUSED(C),
+ PointerRNA *ptr,
+ PropertyRNA *UNUSED(prop),
+ bool *r_free)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeCryptomatte *storage = node->storage;
+ EnumPropertyItem *item = NULL;
+ EnumPropertyItem template = {0, "", 0, "", ""};
+ int totitem = 0;
+
+ ntreeCompositCryptomatteUpdateLayerNames(node);
+ int layer_index;
+ LISTBASE_FOREACH_INDEX (CryptomatteLayer *, layer, &storage->runtime.layers, layer_index) {
+ template.value = layer_index;
+ template.identifier = layer->name;
+ template.name = layer->name;
+ RNA_enum_item_add(&item, &totitem, &template);
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
+static PointerRNA rna_NodeCryptomatte_scene_get(PointerRNA *ptr)
+{
+ bNode *node = (bNode *)ptr->data;
+
+ Scene *scene = (node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER) ? (Scene *)node->id : NULL;
+ return rna_pointer_inherit_refine(ptr, &RNA_Scene, scene);
+}
+
+static void rna_NodeCryptomatte_scene_set(PointerRNA *ptr,
+ PointerRNA value,
+ struct ReportList *reports)
+{
+ bNode *node = (bNode *)ptr->data;
+
+ if (node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER) {
+ rna_Node_scene_set(ptr, value, reports);
+ }
+}
+
+static PointerRNA rna_NodeCryptomatte_image_get(PointerRNA *ptr)
+{
+ bNode *node = (bNode *)ptr->data;
+
+ Image *image = (node->custom1 == CMP_CRYPTOMATTE_SRC_IMAGE) ? (Image *)node->id : NULL;
+ return rna_pointer_inherit_refine(ptr, &RNA_Image, image);
+}
+
+static void rna_NodeCryptomatte_image_set(PointerRNA *ptr,
+ PointerRNA value,
+ struct ReportList *UNUSED(reports))
+{
+ bNode *node = (bNode *)ptr->data;
+
+ if (node->custom1 == CMP_CRYPTOMATTE_SRC_IMAGE) {
+ if (node->id)
+ id_us_min((ID *)node->id);
+ if (value.data)
+ id_us_plus((ID *)value.data);
+
+ node->id = value.data;
+ }
+}
+
+static bool rna_NodeCryptomatte_image_poll(PointerRNA *UNUSED(ptr), PointerRNA value)
+{
+ Image *image = (Image *)value.owner_id;
+ return image->type == IMA_TYPE_MULTILAYER;
+}
+
static void rna_NodeCryptomatte_matte_get(PointerRNA *ptr, char *value)
{
bNode *node = (bNode *)ptr->data;
@@ -3750,13 +3885,13 @@ static void rna_NodeCryptomatte_matte_set(PointerRNA *ptr, const char *value)
static void rna_NodeCryptomatte_update_add(Main *bmain, Scene *scene, PointerRNA *ptr)
{
- ntreeCompositCryptomatteSyncFromAdd((bNodeTree *)ptr->owner_id, ptr->data);
+ ntreeCompositCryptomatteSyncFromAdd(ptr->data);
rna_Node_update(bmain, scene, ptr);
}
static void rna_NodeCryptomatte_update_remove(Main *bmain, Scene *scene, PointerRNA *ptr)
{
- ntreeCompositCryptomatteSyncFromRemove((bNodeTree *)ptr->owner_id, ptr->data);
+ ntreeCompositCryptomatteSyncFromRemove(ptr->data);
rna_Node_update(bmain, scene, ptr);
}
@@ -8409,12 +8544,11 @@ static void def_cmp_cryptomatte_entry(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop);
}
-static void def_cmp_cryptomatte(StructRNA *srna)
+static void def_cmp_cryptomatte_common(StructRNA *srna)
{
PropertyRNA *prop;
static float default_1[3] = {1.0f, 1.0f, 1.0f};
- RNA_def_struct_sdna_from(srna, "NodeCryptomatte", "storage");
prop = RNA_def_property(srna, "matte_id", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop,
"rna_NodeCryptomatte_matte_get",
@@ -8425,6 +8559,7 @@ static void def_cmp_cryptomatte(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "add", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_float_sdna(prop, NULL, "runtime.add");
RNA_def_property_float_array_default(prop, default_1);
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_text(
@@ -8432,6 +8567,7 @@ static void def_cmp_cryptomatte(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeCryptomatte_update_add");
prop = RNA_def_property(srna, "remove", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_float_sdna(prop, NULL, "runtime.remove");
RNA_def_property_float_array_default(prop, default_1);
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_text(
@@ -8441,6 +8577,73 @@ static void def_cmp_cryptomatte(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeCryptomatte_update_remove");
}
+static void def_cmp_cryptomatte_legacy(StructRNA *srna)
+{
+ RNA_def_struct_sdna_from(srna, "NodeCryptomatte", "storage");
+ def_cmp_cryptomatte_common(srna);
+}
+
+static void def_cmp_cryptomatte(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ static const EnumPropertyItem cryptomatte_source_items[] = {
+ {CMP_CRYPTOMATTE_SRC_RENDER, "RENDER", 0, "Render", "Use Cryptomatte passes from a render"},
+ {CMP_CRYPTOMATTE_SRC_IMAGE, "IMAGE", 0, "Image", "Use Cryptomatte passes from an image"},
+ {0, NULL, 0, NULL, NULL}};
+
+ prop = RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, cryptomatte_source_items);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_NodeCryptomatte_source_set", NULL);
+ RNA_def_property_ui_text(prop, "Source", "Where the Cryptomatte passes are loaded from");
+
+ prop = RNA_def_property(srna, "scene", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_funcs(
+ prop, "rna_NodeCryptomatte_scene_get", "rna_NodeCryptomatte_scene_set", NULL, NULL);
+ RNA_def_property_struct_type(prop, "Scene");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
+ RNA_def_property_ui_text(prop, "Scene", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_funcs(prop,
+ "rna_NodeCryptomatte_image_get",
+ "rna_NodeCryptomatte_image_set",
+ NULL,
+ "rna_NodeCryptomatte_image_poll");
+ RNA_def_property_struct_type(prop, "Image");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Image", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ RNA_def_struct_sdna_from(srna, "NodeCryptomatte", "storage");
+ def_cmp_cryptomatte_common(srna);
+
+ prop = RNA_def_property(srna, "layer_name", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, node_cryptomatte_layer_name_items);
+ RNA_def_property_enum_funcs(prop,
+ "rna_NodeCryptomatte_layer_name_get",
+ "rna_NodeCryptomatte_layer_name_set",
+ "rna_NodeCryptomatte_layer_name_itemf");
+ RNA_def_property_ui_text(prop, "Cryptomatte Layer", "What Cryptomatte layer is used");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "entries", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "entries", NULL);
+ RNA_def_property_struct_type(prop, "CryptomatteEntry");
+ RNA_def_property_ui_text(prop, "Mattes", "");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ /* Included here instead of defining image_user as a property of the node,
+ * see def_cmp_image for details.
+ * As mentioned in DNA_node_types.h, iuser is the first member of the Cryptomatte
+ * storage type, so we can cast node->storage to ImageUser.
+ * That is required since we can't define the properties from storage->iuser directly... */
+ RNA_def_struct_sdna_from(srna, "ImageUser", "storage");
+ def_node_image_user(srna);
+}
+
static void def_cmp_denoise(StructRNA *srna)
{
PropertyRNA *prop;