将数据写入选定的掩码

Write data to selected mask

我尝试写入选定的掩码,但它不起作用。

class IdMaskV1 : public Iop
{
public:

    IdMaskV1(Node* node) : Iop(node),
        aaIndexFile(0)
    {
        mChannelSet = Mask_RGBA;
    }

    ~IdMaskV1() {}

    //int maximum_inputs() const { return 1; }
    //int minimum_inputs() const { return 1; }

    virtual void knobs(Knob_Callback);
    void _validate(bool);
    void in_channels(int input_number, ChannelSet& channels) const;
    void _request(int x, int y, int r, int t, ChannelMask channels, int count);
    void engine(int y, int x, int r, ChannelMask channels, Row& outRow);


    const char* Class() const { return CLASS; }
    const char* node_help() const { return HELP; }

private:
    static const Iop::Description description;
    static const char* const CLASS;
    static const char* const HELP;
    ChannelSet mChannelSet;
};


static Iop* IdMaskV1Create(Node* node)
{
    return new IdMaskV1(node);
}

const Iop::Description IdMaskV1::description(CLASS, "Examples/IdMaskV1", IdMaskV1Create);
const char* const IdMaskV1::CLASS = "IdMaskV1";
const char* const IdMaskV1::HELP = "Example Plugin";

void IdMaskV1::_validate(bool for_real)
{
    copy_info();
    set_out_channels(mChannelSet);
    info_.turn_on(mChannelSet);
}

void IdMaskV1::in_channels(int input_number, ChannelSet& channels) const
{
    /*
    // Must turn on the other color channels if any color channels are requested:
    foreach(z, channels) {
        if (colourIndex(z) <= 3) { // it is red, green, or blue
            if (!(mChannelSet & z)) { // save some time if we already turned this on
                mChannelSet.addBrothers(z, 3); // add all three to the "done" set
            }
        }
    }*/
    //channels += mChannelSet; // add the colors to the channels we need
}

void IdMaskV1::_request(int x, int y, int r, int t, ChannelMask channels, int count)
{
    input(0)->request(x, y, r, t, ChannelMask(channels), count);
}


void IdMaskV1::engine(int y, int x, int r, ChannelMask channels, Row& outRow)
{

    ChannelMask mask(channels);

    if (aborted()) {
        std::cerr << "Aborted!";
        return;
    }

    Row inputRow(x, r);
    inputRow.get(input0(), y, x, r, mask);

    foreach(channel, mask) {
        Channel ch = brother(channel, colourIndex(channel));
        mChannelSet += ch;
    }

    for (int curX = x; curX < r; curX++) {

        foreach(channel, mChannelSet) {
            float value = 0;

                        // some process. In RGB i write 0.f, to A i write mask;

            outRow.writable(channel)[curX] = value;
        }
    }
}


void IdMaskV1::knobs(Knob_Callback f)
{
    ...
    ChannelMask_knob(f, &mChannelSet, 1, "channels");
}

对于我创建的进程 'other.test'。在旋钮中,我选择了通道 rgba(或自定义:'test')和自定义掩码:'other.test'

我在 'other.test' 中等待结果,但我在 rgba 中看到了结果 | rgba.alpha |答:\

更新

新尝试:

#include "DDImage/Iop.h"
#include "DDImage/Row.h"
#include "DDImage/Knobs.h"
#include "DDImage/Tile.h"

using namespace DD::Image;
using namespace std;

class IdMaskV1 : public Iop
{
public:

    IdMaskV1(Node* node) : Iop(node)
    {

    }

    ~IdMaskV1() {}

    virtual void knobs(Knob_Callback);
    void _validate(bool);
    void _request(int x, int y, int r, int t, ChannelMask channels, int count);
    void engine(int y, int x, int r, ChannelMask channels, Row& outRow);

    const char* Class() const { return CLASS; }
    const char* node_help() const { return HELP; }

private:
    static const Iop::Description description;
    static const char* const CLASS;
    static const char* const HELP;
    Channel mMaskChan;
};


static Iop* IdMaskV1Create(Node* node)
{
    return new IdMaskV1(node);
}

const Iop::Description IdMaskV1::description(CLASS, "Examples/IdMaskV1", IdMaskV1Create);
const char* const IdMaskV1::CLASS = "IdMaskV1";
const char* const IdMaskV1::HELP = "Example Plugin";

void IdMaskV1::_validate(bool for_real)
{
    copy_info();
    set_out_channels(mMaskChan);
    info_.turn_on(mMaskChan);
}

void IdMaskV1::_request(int x, int y, int r, int t, ChannelMask channels, int count)
{
    input(0)->request(x, y, r, t, channels, count);
}


void IdMaskV1::engine(int y, int x, int r, ChannelMask channels, Row& outRow)
{
    if (aborted()) {
        std::cerr << "Aborted!";
        return;
    }
    ChannelSet unchanged(channels);

    if (unchanged & mMaskChan) {
        unchanged -= mMaskChan;

        static float value = 0.1678f;

        float* out = outRow.writable(mMaskChan) + x;
        const float* END = outRow[mMaskChan] + r;
        while (out < END)
            *out++ = value;
    }

    if (unchanged)
        input0().get(y, x, r, unchanged, outRow);
}

void IdMaskV1::knobs(Knob_Callback f)
{
    Channel_knob(f, &mMaskChan, 1, "channels");
}

不起作用:\

来自 Nuke 的画面:

通常,如果您想对用户指定的所有频道执行相同的操作,您会使用 ChannelSet_knob(或它的变体)。但是,确定旋钮 ChannelSet 中的给定通道是否实际上是旋钮上的掩码下拉列表中指定的通道可能很棘手,因为其他一些通道可以被禁用。

因此,如果要将特定数据写入特定通道,使用Channel_knob会简单得多,并且只在内部呈现和操作单个通道。

在这种情况下,engine() 实现可能如下所示:

void IdMaskV1::engine(int y, int x, int r, ChannelMask channels, Row& outRow)
{
    ChannelSet unchanged(channels);

    // mMaskChan is a `Channel`, and is the private knob storage for a `Channel_knob`
    if (unchanged & mMaskChan) {
        unchanged -= mMaskChan;

        static float value = 0.1678f;  // Whatever value or data you want

        float* OUT = outRow.writable(mMaskChan) + x;
        const float* END = outRow[mMaskChan] + r;
        while (OUT < END)
            *OUT++ = value;
    }

    if (unchanged)
        input0().get(y, x, r, unchanged, outRow);
}

您还需要修改 _validate 方法以在 mMaskChan 上调用 set_out_channelsinfo_.turn_on 而不是 mChannelSet

希望对您有所帮助。