// Copyright (c) 2021 The Foundry Visionmongers Ltd. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of Foundry nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This work is a C++ implementation compatible with version 1.2.8 of the Python-based Nuke gizmo // authored at Psyop by Jonah Friedman and Andy Jones (see https://github.com/Psyop/Cryptomatte). #ifndef ENCRYPTOMATTE_PLUGIN_H #define ENCRYPTOMATTE_PLUGIN_H #include "DDImage/MetaData.h" #include "DDImage/Hash.h" #include "DDImage/Iop.h" namespace DD { namespace Image { class Row; } } namespace NukeStudio { namespace Image { class Layer; } } namespace Foundry { namespace NukePlugins { class EncryptomattePlugin : public DD::Image::Iop { public: EncryptomattePlugin(Node* node); private: static const Description kDescription; const char* Class() const override; const char* node_help() const override; void in_channels(int input, DD::Image::ChannelSet& mask) const override; void knobs(DD::Image::Knob_Callback callback) override; const char* input_label(int input, char* buffer) const override; int knob_changed(DD::Image::Knob* k) override; void append(DD::Image::Hash& hash) override; bool updateUI(const DD::Image::OutputContext& context) override; void _validate(bool forReal) override; const DD::Image::MetaData::Bundle& _fetchMetaData(const char* searchKey) override; // TODO: Remove this once we figured out how to avoid the copies with the // Iop base class void pixel_engine(const DD::Image::Row& in, int y, int x, int r, DD::Image::ChannelMask, DD::Image::Row& out); void engine(int y, int x, int r, DD::Image::ChannelMask, DD::Image::Row &) override; // Get the standard Nuke cryptomatte sublayers from the selected // cryptomatte layer name. void setCryptomatteSublayers(); bool isMatteNameManual() const; void checkLayerInitialised(); // Returns the node name of the matte input. std::string getMatteName() const; // This method returns a data structure for the input row indexed by // the channels starting from zero. std::vector createInputRowData(const DD::Image::Row& in, int x, int r); // This method returns a data structure for the output row indexed by // the channels starting from zero. std::vector createOutputRowData(DD::Image::Row& out, int x, int r); // Baked value for the matte name knob where the user inputs the desired // matte name. std::string _matteName; // Baked value for the hidden previous matte name. This is to help // deciding whether the matte name has changed. std::string _previousMatteName; // This is used for the auto-labeling feature whether it is auto or // manual. int _matteNameTypeIndex = 0; // This is used for the merge operation feature. This could be over or // under. int _mergeOperationIndex = 0; // Holds the metadata for the current plugin instance passed downstream. DD::Image::MetaData::Bundle _meta; // Helper member variable to decide whether the layer name has changed // since the last rendering. std::string _previousCryptoLayerName; // Check whether the Encryptomatte instance owns the currently selected // layer. bool _isOwnLayer = true; // When the layer selection does not change, it means the layer has been // initialised bool _isOwnLayerInitialised = false; // Auxilliary variable, set once per rendering in validate rather than // for each row, whether the merge operation is over or under bool _isOver; // Auxilliary variable, set once per rendering in validate rather than // for each row, holding the value of the calculated hash for the // currently input matte name in the corresponding knob. float _matteId; // Baked value for the currently selected cryptomatte layer name std::string _cryptoLayerName; // The underlying cryptomatte sublayers as standard Nuke layers for the // selected main cryptomatte layer. std::vector _cryptomatteSublayers; // The depth of the cryptomatte layer. This means the number of // cryptomatte sublayers. Each sublayer can contain two objects, so the // maximum number of objects is this variable * 2 therefore. size_t _cryptoLayerDepth; }; } } #endif