Fix #36755, EXR Layers are not fully updated on scene load or image refresh.
authorLukas Toenne <lukas.toenne@googlemail.com>
Thu, 19 Sep 2013 08:21:55 +0000 (08:21 +0000)
committerLukas Toenne <lukas.toenne@googlemail.com>
Thu, 19 Sep 2013 08:21:55 +0000 (08:21 +0000)
After discussion with Brecht decided that automatically updating the sockets of the node based on externally modified data (removed EXR file passes) is not desirable behavior. But at least making sure
the correct passes are assigned to the output sockets of the Image node is possible. Now the passes are matched by name instead of using the faulty index stored in the socket data, which is more
reliable. Still may break if changing pass names externally, but an image reload is highly recommended anyway and will fix that.

source/blender/compositor/nodes/COM_ImageNode.cpp
source/blender/compositor/nodes/COM_ImageNode.h
source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
source/blender/compositor/operations/COM_MultilayerImageOperation.h

index c3aaf8358fee50305d84f707bf8f720003bc3b5b..6e4bff460d1188cd07445955d37da4cb71a32bab 100644 (file)
@@ -38,19 +38,19 @@ ImageNode::ImageNode(bNode *editorNode) : Node(editorNode)
        /* pass */
 
 }
-NodeOperation *ImageNode::doMultilayerCheck(ExecutionSystem *system, RenderLayer *rl, Image *image, ImageUser *user, int framenumber, int outputsocketIndex, int pass, DataType datatype)
+NodeOperation *ImageNode::doMultilayerCheck(ExecutionSystem *system, RenderLayer *rl, Image *image, ImageUser *user, int framenumber, int outputsocketIndex, int passindex, DataType datatype)
 {
        OutputSocket *outputSocket = this->getOutputSocket(outputsocketIndex);
        MultilayerBaseOperation *operation = NULL;
        switch (datatype) {
                case COM_DT_VALUE:
-                       operation = new MultilayerValueOperation(pass);
+                       operation = new MultilayerValueOperation(passindex);
                        break;
                case COM_DT_VECTOR:
-                       operation = new MultilayerVectorOperation(pass);
+                       operation = new MultilayerVectorOperation(passindex);
                        break;
                case COM_DT_COLOR:
-                       operation = new MultilayerColorOperation(pass);
+                       operation = new MultilayerColorOperation(passindex);
                        break;
                default:
                        break;
@@ -93,10 +93,19 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
                                        socket = this->getOutputSocket(index);
                                        if (socket->isConnected() || index == 0) {
                                                bNodeSocket *bnodeSocket = socket->getbNodeSocket();
-                                               NodeImageLayer *storage = (NodeImageLayer *)bnodeSocket->storage;
-                                               int passindex = storage->pass_index;
-                                               
+                                               /* Passes in the file can differ from passes stored in sockets (#36755).
+                                                * Look up the correct file pass using the socket identifier instead.
+                                                */
+                                               #if 0
+                                               NodeImageLayer *storage = (NodeImageLayer *)bnodeSocket->storage;*/
+                                               int passindex = storage->pass_index;*/
                                                RenderPass *rpass = (RenderPass *)BLI_findlink(&rl->passes, passindex);
+                                               #endif
+                                               int passindex;
+                                               RenderPass *rpass;
+                                               for (rpass = (RenderPass *)rl->passes.first, passindex = 0; rpass; rpass = rpass->next, ++passindex)
+                                                       if (STREQ(rpass->name, bnodeSocket->identifier))
+                                                               break;
                                                if (rpass) {
                                                        imageuser->pass = passindex;
                                                        switch (rpass->channels) {
index 49006efbed57cfe6c945595538fe554405e9658b..12b4da6c8b35ff12918087367c705993591f72fb 100644 (file)
@@ -35,7 +35,7 @@ extern "C" {
  */
 class ImageNode : public Node {
 private:
-       NodeOperation *doMultilayerCheck(ExecutionSystem *system, RenderLayer *rl, Image *image, ImageUser *user, int framenumber, int outputsocketIndex, int pass, DataType datatype);
+       NodeOperation *doMultilayerCheck(ExecutionSystem *system, RenderLayer *rl, Image *image, ImageUser *user, int framenumber, int outputsocketIndex, int passindex, DataType datatype);
 public:
        ImageNode(bNode *editorNode);
        void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
index 1a2a1e778338c15cb028e9d6330f7fc651b52d80..e2a95b2e33b3b0ee93b8bfaa1ce77ceb4e72524b 100644 (file)
@@ -27,16 +27,15 @@ extern "C" {
        #include "IMB_imbuf_types.h"
 }
 
-MultilayerBaseOperation::MultilayerBaseOperation(int pass) : BaseImageOperation()
+MultilayerBaseOperation::MultilayerBaseOperation(int passindex) : BaseImageOperation()
 {
-       this->m_passId = pass;
+       this->m_passId = passindex;
 }
 ImBuf *MultilayerBaseOperation::getImBuf()
 {
-       RenderPass *rpass;
-       rpass = (RenderPass *)BLI_findlink(&this->m_renderlayer->passes, this->m_passId);
+       RenderPass *rpass = (RenderPass *)BLI_findlink(&this->m_renderlayer->passes, this->m_passId);
        if (rpass) {
-               this->m_imageUser->pass = this->m_passId;
+               this->m_imageUser->pass = m_passId;
                BKE_image_multilayer_index(this->m_image->rr, this->m_imageUser);
                return BaseImageOperation::getImBuf();
        }
index 3c498e962b5f37b1ddab4b2c7b58df4c4c8ae2f4..065bcc7da1e882e5f3665332448685f220e81798 100644 (file)
@@ -37,13 +37,13 @@ public:
        /**
         * Constructor
         */
-       MultilayerBaseOperation(int pass);
+       MultilayerBaseOperation(int passindex);
        void setRenderLayer(RenderLayer *renderlayer) { this->m_renderlayer = renderlayer; }
 };
 
 class MultilayerColorOperation : public MultilayerBaseOperation {
 public:
-       MultilayerColorOperation(int pass) : MultilayerBaseOperation(pass) {
+       MultilayerColorOperation(int passindex) : MultilayerBaseOperation(passindex) {
                this->addOutputSocket(COM_DT_COLOR);
        }
        void executePixel(float output[4], float x, float y, PixelSampler sampler);
@@ -51,7 +51,7 @@ public:
 
 class MultilayerValueOperation : public MultilayerBaseOperation {
 public:
-       MultilayerValueOperation(int pass) : MultilayerBaseOperation(pass) {
+       MultilayerValueOperation(int passindex) : MultilayerBaseOperation(passindex) {
                this->addOutputSocket(COM_DT_VALUE);
        }
        void executePixel(float output[4], float x, float y, PixelSampler sampler);
@@ -59,7 +59,7 @@ public:
 
 class MultilayerVectorOperation : public MultilayerBaseOperation {
 public:
-       MultilayerVectorOperation(int pass) : MultilayerBaseOperation(pass) {
+       MultilayerVectorOperation(int passindex) : MultilayerBaseOperation(passindex) {
                this->addOutputSocket(COM_DT_VECTOR);
        }
        void executePixel(float output[4], float x, float y, PixelSampler sampler);