// 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 CRYPTOMATTE_PLUGIN_H #define CRYPTOMATTE_PLUGIN_H #include "CryptomatteUtils.h" #include "DDImage/Knobs.h" #include "DDImage/PixelIop.h" #include namespace Foundry { namespace NukePlugins { class CryptomattePlugin : public DD::Image::PixelIop { public: CryptomattePlugin(Node* node); 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; int knob_changed(DD::Image::Knob* k) override; bool updateUI(const DD::Image::OutputContext& context) override; protected: void _validate(bool forReal) override; void pixel_engine(const DD::Image::Row& in, int y, int x, int r, DD::Image::ChannelMask channels, DD::Image::Row& out) override; private: // Enumerates possible modes of Matte List selection by the user. enum MatteSelectionMode { eSelectByTopCoverage = 0, eUnselectByTopCoverage }; // Helper struct that contains Cryptomatte objects, fetched from the metadata, // the index of currently selected object, and the flag that determines whether the UI // is up to date in regards to fetched objects. struct CryptomatteContext { std::vector objects; size_t selectedIndex = 0; bool uiUpToDate = false; }; // Updates the Matte List with mattes, picked by associated IDs in the area of interest (user-selected bbox). void updateMatteListBySelectionArea(const DD::Image::Box& selectionArea, MatteSelectionMode selectionMode); // Fetches available Cryptomatte objects from the metadata and determines the index // of selected object as well as whether the UI is up to date in regards to fetched objects. CryptomatteContext loadCryptomatteContext() const; void saveLastSelectedCryptoLayerName(const CryptomatteContext& objectsAndState) const; // Updates manifest source knob and sidecar filepath knob in regards to the state of selected Cryptomatte Object. void updateManifestSourceKnobs(const std::vector& cryptomatteObjects); // Populates Cryptomatte Layers menu in regards to the state of selected Cryptomatte Object. void updateCryptoLayerChoiceKnob(const CryptomatteContext& objectsAndState); // Enables sidecar filepath knob, if the source of Manifest is sidecar file; otherwise disables it. void updateSidecarFilenameKnobEnabled(); // Add obsolete knobs for backward compatibility & error handling when loading a Cryptomatte gizmo. void addObsoleteKnobs(DD::Image::Knob_Callback f) const; // Loads the manifest from the selected source. Cryptomatte::Manifest getManifestFromSelectedSource(const Cryptomatte::CryptomatteObject& cryptomatte); // Gets the value of Manifest Source Modified Knob. bool getManifestSourceModified() const; // Gets the value of Manifest Source Modified Knob. void setManifestSourceModified(bool value); // Knob names static const char* kCryptoLayerChoiceKnob; static const char* kManifestSourceKnob; static const char* kSidecarFilepathKnob; static const char* kPreviewEnabled; static const char* kPickerAddKnob; static const char* kPickerRemoveKnob; static const char* kMatteListKnob; static const char* kClearKnob; static const char* kMatteOutputKnob; static const char* kUnpremultiply; static const char* kRemoveChannelsKnob; static const char* kManifestSourceModifiedKnob; static const char* kLastSelectedCryptoLayerNameKnob; // Knob values bool _previewEnabled = true; float _pickerAddValue[8]{}; float _pickerRemoveValue[8]{}; // User-selected Matte List string const char* _matteList = nullptr; // Index of user-selected cryptomatte that persists // in a collection of available cryptomattes int _selectedCryptomatteIndex = 0; // Menu items of the Cryptomatte Layers enumeration knob DD::Image::ENUM_LABELS _cryptoLayersMenu = nullptr; // Index of manifest source: 0 - embedded; 1 - sidecar. int _manifestSourceIndex = 0; // Path to the sidecar manifest file. const char* _sidecarFilePath = nullptr; // Determines if the output must be unpremultiplied by the input alpha bool _unpremultiplyEnabled = false; // User-selected Matte Out Channel DD::Image::Channel _matteOutChannel = DD::Image::Chan_Alpha; // Determines if all the channels except for RGB // and the Matte Output channel should be removed. bool _removeChannels = false; // Determines if the manifest source was modified by the user. bool _manifestSourceModified = false; // Preserves the name of last user-selected cryptomatte. std::string _lastSelectedCryptoLayerName; // Dynamic values, updated by each _validate() call // Cryptomatte IDs, resolved from the user-selected Matte List std::set _resolvedIDs; // User-selected cryptomatte object Cryptomatte::CryptomatteObject _selectedCryptomatte; }; } } #endif