[Bf-blender-cvs] [4ef8e143dd2] compositor-cryptomatte-workflow: Compositor: Redesign Cryptomatte node for better usability

Jeroen Bakker noreply at git.blender.org
Tue Feb 16 09:47:20 CET 2021


Commit: 4ef8e143dd2d84e3d0bf04dfcc8f8629ec7bbf88
Author: Jeroen Bakker
Date:   Mon Feb 15 10:02:14 2021 +0100
Branches: compositor-cryptomatte-workflow
https://developer.blender.org/rB4ef8e143dd2d84e3d0bf04dfcc8f8629ec7bbf88

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).

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.

{F9502764}

Differential Revision: https://developer.blender.org/D3959

===================================================================

M	source/blender/blenkernel/BKE_cryptomatte.h
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/cryptomatte.cc
M	source/blender/blenkernel/intern/node.cc
M	source/blender/blenkernel/intern/scene.c
M	source/blender/blenloader/intern/versioning_290.c
M	source/blender/compositor/nodes/COM_CryptomatteNode.cpp
M	source/blender/draw/engines/eevee/eevee_cryptomatte.c
M	source/blender/draw/engines/eevee/eevee_engine.c
M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/engines/eevee/eevee_render.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/draw/engines/gpencil/gpencil_render.c
M	source/blender/draw/engines/workbench/workbench_private.h
M	source/blender/draw/engines/workbench/workbench_render.c
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager.c
M	source/blender/editors/include/ED_clip.h
M	source/blender/editors/include/ED_image.h
M	source/blender/editors/include/ED_node.h
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/CMakeLists.txt
M	source/blender/editors/interface/interface_eyedropper_color.c
M	source/blender/editors/interface/interface_templates.c
M	source/blender/editors/space_clip/clip_editor.c
M	source/blender/editors/space_image/image_ops.c
M	source/blender/editors/space_node/drawnode.c
M	source/blender/editors/space_node/node_edit.c
M	source/blender/editors/space_node/node_intern.h
M	source/blender/editors/space_node/node_ops.c
M	source/blender/editors/space_node/node_view.c
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/composite/nodes/node_composite_cryptomatte.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_cryptomatte.h b/source/blender/blenkernel/BKE_cryptomatte.h
index eb2de96a745..27982593388 100644
--- a/source/blender/blenkernel/BKE_cryptomatte.h
+++ b/source/blender/blenkernel/BKE_cryptomatte.h
@@ -49,6 +49,7 @@ uint32_t BKE_cryptomatte_material_hash(struct CryptomatteSession *session,
 uint32_t BKE_cryptomatte_asset_hash(struct CryptomatteSession *session,
                                     const struct Object *object);
 float BKE_cryptomatte_hash_to_float(uint32_t cryptomatte_hash);
+struct ID *BKE_cryptomatte_find_id(const struct Main *bmain, const float encoded_hash);
 
 char *BKE_cryptomatte_entries_to_matte_id(struct NodeCryptomatte *node_storage);
 void BKE_cryptomatte_matte_id_to_entries(const struct Main *bmain,
@@ -63,4 +64,4 @@ void BKE_cryptomatte_store_metadata(struct CryptomatteSession *session,
 
 #ifdef __cplusplus
 }
-#endif
+#endif
\ No newline at end of file
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 7984bbc980a..b450481ba21 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1237,6 +1237,15 @@ void ntreeGPUMaterialNodes(struct bNodeTree *localtree,
 #define CMP_TRACKPOS_RELATIVE_FRAME 2
 #define CMP_TRACKPOS_ABSOLUTE_FRAME 3
 
+/* cryptomatte source */
+#define CMP_CRYPTOMATTE_SRC_RENDER 0
+#define CMP_CRYPTOMATTE_SRC_IMAGE 1
+
+/* cryptomatte type */
+#define CMP_CRYPTOMATTE_TYPE_OBJECT 0
+#define CMP_CRYPTOMATTE_TYPE_MATERIAL 1
+#define CMP_CRYPTOMATTE_TYPE_ASSET 2
+
 /* API */
 void ntreeCompositExecTree(struct Scene *scene,
                            struct bNodeTree *ntree,
@@ -1279,10 +1288,8 @@ void ntreeCompositOutputFileUniqueLayer(struct ListBase *list,
 void ntreeCompositColorBalanceSyncFromLGG(bNodeTree *ntree, bNode *node);
 void ntreeCompositColorBalanceSyncFromCDL(bNodeTree *ntree, bNode *node);
 
-void ntreeCompositCryptomatteSyncFromAdd(bNodeTree *ntree, bNode *node);
-void ntreeCompositCryptomatteSyncFromRemove(bNodeTree *ntree, bNode *node);
-struct bNodeSocket *ntreeCompositCryptomatteAddSocket(struct bNodeTree *ntree, struct bNode *node);
-int ntreeCompositCryptomatteRemoveSocket(struct bNodeTree *ntree, struct bNode *node);
+void ntreeCompositCryptomatteSyncFromAdd(struct Main *bmain, bNodeTree *ntree, bNode *node);
+void ntreeCompositCryptomatteSyncFromRemove(struct Main *bmain, bNodeTree *ntree, bNode *node);
 
 /** \} */
 
diff --git a/source/blender/blenkernel/intern/cryptomatte.cc b/source/blender/blenkernel/intern/cryptomatte.cc
index db83547fe36..15d7434952e 100644
--- a/source/blender/blenkernel/intern/cryptomatte.cc
+++ b/source/blender/blenkernel/intern/cryptomatte.cc
@@ -212,7 +212,7 @@ static ID *cryptomatte_find_id(const ListBase *ids, const float encoded_hash)
 }
 
 /* Find an ID in the given main that matches the given encoded float. */
-static struct ID *BKE_cryptomatte_find_id(const Main *bmain, const float encoded_hash)
+struct ID *BKE_cryptomatte_find_id(const Main *bmain, const float encoded_hash)
 {
   ID *result;
   result = cryptomatte_find_id(&bmain->objects, encoded_hash);
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index e34afd1ce17..147eb714c88 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -858,7 +858,8 @@ void ntreeBlendReadExpand(BlendExpander *expander, bNodeTree *ntree)
   }
 
   LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
-    if (node->id && node->type != CMP_NODE_R_LAYERS) {
+    if (node->id && !(node->type == CMP_NODE_R_LAYERS) &&
+        !(node->type == CMP_NODE_CRYPTOMATTE && node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER)) {
       BLO_expand(expander, node->id);
     }
 
@@ -4936,12 +4937,23 @@ void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, const int layer
 {
   BLI_assert(layer_index != -1);
   LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+    /* Check whether this node references layers. */
+    short *node_index = NULL;
     if (node->type == CMP_NODE_R_LAYERS && (Scene *)node->id == scene) {
-      if (node->custom1 == layer_index) {
-        node->custom1 = 0;
+      node_index = &node->custom1;
+    }
+    else if (node->type == CMP_NODE_CRYPTOMATTE && node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER &&
+             (Scene *)node->id == scene) {
+      node_index = &node->custom2;
+    }
+
+    /* If it does, ensure that it remains valid. */
+    if (node_index) {
+      if (*node_index == layer_index) {
+        *node_index = 0;
       }
-      else if (node->custom1 > layer_index) {
-        node->custom1--;
+      else if (*node_index > layer_index) {
+        *node_index -= 1;
       }
     }
   }
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 25951fa3e6f..95dfccb6b52 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1379,9 +1379,10 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
 /* patch for missing scene IDs, can't be in do-versions */
 static void composite_patch(bNodeTree *ntree, Scene *scene)
 {
-
   LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
-    if (node->id == NULL && node->type == CMP_NODE_R_LAYERS) {
+    if (node->id == NULL &&
+        ((node->type == CMP_NODE_R_LAYERS) ||
+         (node->type == CMP_NODE_CRYPTOMATTE && node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER))) {
       node->id = &scene->id;
     }
   }
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index b8ca2f17fd2..28986d4704c 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -325,6 +325,18 @@ static void seq_convert_transform_crop_lb_2(const Scene *scene,
   }
 }
 
+static void compositor_convert_cryptomatte_node(Main *bmain, bNode *node)
+{
+  NodeCryptomatte *storage = (NodeCryptomatte *)node->storage;
+
+  char *matte_id = storage->matte_id;
+  if (matte_id == NULL || strlen(storage->matte_id) == 0) {
+    return;
+  }
+  BKE_cryptomatte_matte_id_to_entries(bmain, storage, storage->matte_id);
+  MEM_SAFE_FREE(storage->matte_id);
+}
+
 void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
 {
   if (!MAIN_VERSION_ATLEAST(bmain, 290, 1)) {
@@ -599,6 +611,19 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
    */
   {
     /* Keep this block, even when empty. */
+
+    /* Convert `NodeCryptomatte->storage->matte_id` to `NodeCryptomatte->storage->entries` */
+    if (!DNA_struct_find(fd->filesdna, "CryptomatteEntry")) {
+      LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+        if (scene->nodetree) {
+          LISTBASE_FOREACH (bNode *, node, &scene->nodetree->nodes) {
+            if (node->type == CMP_NODE_CRYPTOMATTE) {
+              compositor_convert_cryptomatte_node(bmain, node);
+            }
+          }
+        }
+      }
+    }
   }
 }
 
diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp
index 27ef98af8f3..1eea6447947 100644
--- a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp
+++ b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp
@@ -17,15 +17,17 @@
  */
 
 #include "COM_CryptomatteNode.h"
-#include "COM_ConvertOperation.h"
-#include "COM_CryptomatteOperation.h"
-
+#include "BKE_node.h"
 #include "BLI_assert.h"
 #include "BLI_hash_mm3.h"
 #include "BLI_listbase.h"
 #include "BLI_string.h"
-
+#include "COM_ConvertOperation.h"
+#include "COM_CryptomatteOperation.h"
+#include "COM_MultilayerImageOperation.h"
+#include "COM_RenderLayersProg.h"
 #include "COM_SetAlphaMultiplyOperation.h"
+#include "COM_SetColorOperation.h"
 #include <iterator>
 
 CryptomatteNode::CryptomatteNode(bNode *editorNode) : Node(editorNode)
@@ -34,7 +36,7 @@ CryptomatteNode::CryptomatteNode(bNode *editorNode) : Node(editorNode)
 }
 
 void CryptomatteNode::convertToOperations(NodeConverter &converter,
-                                          const CompositorContext & /*context*/) const
+                                          const CompositorContext &context) const
 {
   NodeInput *inputSocketImage = this->getInputSocket(0);
   NodeOutput *outputSocketImage = this->getOutputSocket(0);
@@ -44,17 +46,116 @@ void CryptomatteNode::convertToOperations(NodeConverter &converter,
   bNode *node = this->getbNode();
   NodeCryptomatte *cryptoMatteSettings = (NodeCryptomatte *)node->storage;
 
-  CryptomatteOperation *operation = new CryptomatteOperation(getNumberOfInputSockets() - 1);
-  if (cryptoMatteSettings) {
-    LISTBASE_FOREACH (CryptomatteEntry *, cryptomatte_entry, &cryptoMatteSettings->entries) {
-      operation->addObjectIndex(cryptomatte_entry->encoded_hash);
+  const char *prefix = "";
+  switch (cryptoMatteSettings->type) {
+    case CMP_CRYPTOMATTE_TYPE_OBJECT:
+      prefix = "CryptoObject";
+      break;
+    case CMP_CRYPTOMATTE_TYPE_MATERIAL:
+      prefix = "CryptoMaterial";
+      break;
+    case CMP_CRYPTOMATTE_TYPE_ASSET:
+      prefix = "CryptoAsset";
+      break;
+    default:
+      BLI_assert(false);
+      break;
+  }
+
+  vector<NodeOperation *> input_operations;
+  if (node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER) {
+    Scene *scene = (Scene *)node->id;
+    BLI_assert(GS(scene->id.name) == ID_SCE);
+    Render *re = (scene) ? RE_GetSceneRender(scene) : NULL;
+
+    if (re) {
+      const short layerId = node->custom2;
+      RenderResult *rr = RE_AcquireResultRead(re);
+      if (rr) {
+        ViewLayer *view_layer = (ViewLayer *)BLI_findlink(&scene->view_layers, layerId);
+        if (view_layer) {
+          RenderLayer *rl = RE_GetRenderLayer(rr, view_layer->name);
+          if (rl) {
+            LISTBASE_FOREACH (RenderPass *, rpass, &rl->passes) {
+              if (STRPREFIX(rpass->name, prefix)) {
+                RenderLayersProg *op = new RenderLayersProg(
+                    rpass->name, COM_DT_COLOR, rpass->channels);
+                op->setScene(scene);
+                op->setLayerId(layerId);
+                op->setRenderData(context.getRenderData(

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list