【开发日志】2023.05 ZENO----Image Processing----CompExtractChanel & Composite

New CompExtractChanel & Composite

Test Mask Chanel RGBA

 

 

 

 

 

 

 

Test  Compositemode (Mask1mode A,Mak2mode A)

Over Under Atop Inside Outside Screen Add Subtract Multiply Divide Diff Min Max Average Xor Alpha !Alpha

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Test  Compositemode (Mask1mode A,Mak2mode R)

Over Under Atop Inside Outside Screen Add Subtract Multiply Divide Diff Min Max Average Xor Alpha !Alpha

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Test only

 

 

 

 

 

 

 

 

 

 

 

Test Two Opaque

 

 

struct Composite: INode {
    virtual void apply() override {
        auto compmode = get_input2<std::string>("Compmode");
        auto maskmode1 = get_input2<std::string>("Mask1mode");
        auto maskmode2 = get_input2<std::string>("Mask2mode");
        int w1 = 1024 ;
        int h1 = 1024 ;
        auto image1 = std::make_shared<PrimitiveObject>();
        image1->verts.resize(w1 * h1);
        image1->userData().set2("isImage", 1);
        image1->userData().set2("w", w1);
        image1->userData().set2("h", h1);
        auto image2 = std::make_shared<PrimitiveObject>();
        image2->verts.resize(w1 * h1);
        image2->userData().set2("isImage", 1);
        image2->userData().set2("w", w1);
        image2->userData().set2("h", h1);
        auto A1 = std::make_shared<PrimitiveObject>();
        A1->verts.resize(w1 * h1);
        A1->userData().set2("isImage", 1);
        A1->userData().set2("w", w1);
        A1->userData().set2("h", h1);
        A1->verts.add_attr<float>("alpha");
        for(int i = 0;i < w1 * h1;i++){
            A1->verts.attr<float>("alpha")[i] = 0.0;
        }
        std::vector<float> &alpha1 = A1->verts.attr<float>("alpha");
        auto A2 = std::make_shared<PrimitiveObject>();
        A2->verts.resize(w1 * h1);
        A2->userData().set2("isImage", 1);
        A2->userData().set2("w", w1);
        A2->userData().set2("h", h1);
        A2->verts.add_attr<float>("alpha");
        for(int i = 0;i < w1 * h1;i++){
            A2->verts.attr<float>("alpha")[i] = 0.0;
        }
        std::vector<float> &alpha2 = A2->verts.attr<float>("alpha");

        if(has_input("Background")){
            image2 = get_input2<PrimitiveObject>("Background");
            auto &ud2 = image2->userData();
            w1 = ud2.get2<int>("w");
            h1 = ud2.get2<int>("h");
            if(image2->verts.has_attr("alpha")){
                alpha2 = image2->verts.attr<float>("alpha");
            }
            else{
                image2->verts.add_attr<float>("alpha");
                for(int i = 0;i < w1 * h1;i++){
                    image2->verts.attr<float>("alpha")[i] = 1.0;
                }
                alpha2 = image2->verts.attr<float>("alpha");
            }
            if(!has_input("Foreground")){
                image1->verts.resize(image2->size());
                image1->userData().set2("w", w1);
                image1->userData().set2("h", h1);
                image1->verts.add_attr<float>("alpha");
                for(int i = 0;i < w1 * h1;i++){
                    image1->verts.attr<float>("alpha")[i] = 0.0;
                }
                alpha1 = image1->verts.attr<float>("alpha");
            }
        }
        if(has_input("Foreground")){
            image1 = get_input2<PrimitiveObject>("Foreground");
            auto &ud1 = image1->userData();
            w1 = ud1.get2<int>("w");
            h1 = ud1.get2<int>("h");
            if(image1->verts.has_attr("alpha")){
                alpha1 = image1->verts.attr<float>("alpha");
            }
            else{
                image1->verts.add_attr<float>("alpha");
                for(int i = 0;i < w1 * h1;i++){
                    image1->verts.attr<float>("alpha")[i] = 1.0;
                }
                alpha1 = image1->verts.attr<float>("alpha");
            }
            if(!has_input("Background")){
                image2->verts.resize(image1->size());
                image2->userData().set2("w", w1);
                image2->userData().set2("h", h1);
                image2->verts.add_attr<float>("alpha");
                for(int i = 0;i < w1 * h1;i++){
                    image2->verts.attr<float>("alpha")[i] = 0.0;
                }
                alpha2 = image2->verts.attr<float>("alpha");
            }
            if(has_input("Background")){
                auto &ud2 = image2->userData();
                int w2 = ud2.get2<int>("w");
                int h2 = ud2.get2<int>("h");
                if(image1->size() != image2->size() || w1 != w2 || h1 != h2){
                    image2->verts.resize(image1->size());
                    image2->userData().set2("w", w1);
                    image2->userData().set2("h", h1);
//todo: image1和image2大小不同的情况
//                    for (int i = 0; i < h1; i++) {
//                        for (int j = 0; j < w1; j++) {
//
//                        }
//                    }
                }
            }
        }
        if(has_input("Mask1")) {
            auto Mask1 = get_input2<PrimitiveObject>("Mask1");
            Mask1->verts.resize(w1 * h1);
            Mask1->userData().set2("w", w1);
            Mask1->userData().set2("h", h1);
            if(maskmode1 == "R"){
                Mask1->verts.add_attr<float>("alpha");
                for(int i = 0;i < Mask1->size();i ++){
                    Mask1->verts.attr<float>("alpha")[i] = Mask1->verts[i][0];
                }
                alpha1 = Mask1->verts.attr<float>("alpha");
            }
            if(maskmode1 == "G"){
                Mask1->verts.add_attr<float>("alpha");
                for(int i = 0;i < Mask1->size();i ++){
                    Mask1->verts.attr<float>("alpha")[i] = Mask1->verts[i][1];
                }
                alpha1 = Mask1->verts.attr<float>("alpha");
            }
            if(maskmode1 == "B"){
                Mask1->verts.add_attr<float>("alpha");
                for(int i = 0;i < Mask1->size();i ++){
                    Mask1->verts.attr<float>("alpha")[i] = Mask1->verts[i][2];
                }
                alpha1 = Mask1->verts.attr<float>("alpha");
            }
            if(maskmode1 == "A"){
                if(Mask1->verts.has_attr("alpha")){
                    alpha1 = Mask1->verts.attr<float>("alpha");
                }
                else{
                    Mask1->verts.add_attr<float>("alpha");
                    for (int i = 0; i < h1; i++) {
                        for (int j = 0; j < w1; j++) {
                            Mask1->verts.attr<float>("alpha")[i * w1 + j] = 1;
                        }
                    }
                    alpha1 = Mask1->verts.attr<float>("alpha");
                }
            }
        }
        if(has_input("Mask2")) {
            auto Mask2 = get_input2<PrimitiveObject>("Mask2");
            Mask2->verts.resize(w1 * h1);
            Mask2->userData().set2("w", w1);
            Mask2->userData().set2("h", h1);
            if(maskmode2 == "R"){
                Mask2->verts.add_attr<float>("alpha");
                for(int i = 0;i < Mask2->size();i++){
                    Mask2->verts.attr<float>("alpha")[i] = Mask2->verts[i][0];
                }
                alpha2 = Mask2->verts.attr<float>("alpha");
            }
            if(maskmode2 == "G"){
                Mask2->verts.add_attr<float>("alpha");
                for(int i = 0;i < Mask2->size();i++){
                    Mask2->verts.attr<float>("alpha")[i] = Mask2->verts[i][1];
                }
                alpha2 = Mask2->verts.attr<float>("alpha");
            }
            if(maskmode2 == "B"){
                Mask2->verts.add_attr<float>("alpha");
                for(int i = 0;i < Mask2->size();i++){
                    Mask2->verts.attr<float>("alpha")[i] = Mask2->verts[i][2];
                }
                alpha2 = Mask2->verts.attr<float>("alpha");
            }
            if(maskmode2 == "A"){
                if(Mask2->verts.has_attr("alpha")){
                    alpha2 = Mask2->verts.attr<float>("alpha");
                }
                else{
                    Mask2->verts.add_attr<float>("alpha");
                    for (int i = 0; i < h1; i++) {
                        for (int j = 0; j < w1; j++) {
                            Mask2->verts.attr<float>("alpha")[i * w1 + j] = 1;
                        }
                    }
                    alpha2 = Mask2->verts.attr<float>("alpha");
                }
            }
        }
        if(compmode == "Over") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * l1 + rgb2 * ((l1!=1 && l2!=0)? std::min((1-l1),l2) : 0);
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = ((l1!=0 || l2!=0)? zeno::max(l2,l1): 0);
                }
            }
        }
        if (compmode == "Under") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb2 * l2 + rgb1 * ((l2!=1 && l1!=0)? std::min((1-l2),l1) : 0);
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = ((l1!=0 || l2!=0)? zeno::max(l2,l1): 0);
                }
            }
        }
        if (compmode == "Atop") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * ((l1 != 0 && l2 != 0) ? l1 : 0) + rgb2 * ((l1 == 0) && (l2 != 0) ? l2 : 0);
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = (l1 !=0 && l2 !=0)? l1 : l2;
                }
            }
        }
        if (compmode == "Inside") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * ((l1 != 0) && (l2 != 0) ? l1 : 0);
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = (l1 !=0 && l2 !=0)? l1 : 0;
                }
            }
        }
        if (compmode == "Outside") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * ((l1 != 0) && (l2 == 0) ? l1 : 0);
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = (l1 != 0 && l2 == 0)? l1 : 0;
                }
            }
        }
        if(compmode == "Screen"){
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l = zeno::min(zeno::min(image1->verts[i * w1 + j][0],image1->verts[i * w1 + j][1]),image1->verts[i * w1 + j][2]);
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb2 * l2 + rgb2 * ((l1!=0 && l2!=0)? l: 0);
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = l2;
                }
            }
        }
        if (compmode == "Add") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb2 * l2 + rgb1 * l1;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Subtract") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * l1 - rgb2 * l2 ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Multiply") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * l1 * rgb2 * l2 ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Divide") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * l1 / (rgb2 * l2) ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Diff") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = abs(rgb1 * l1 - (rgb2 * l2)) ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Min") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = l1 <= l2 ? rgb1 * l1 : rgb2 * l2 ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Max") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = l1 >= l2 ? rgb1 * l1 : rgb2 * l2 ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Average") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    vec3f rgb3 = (rgb1+rgb2)/2;
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb3 * (l1+l2) ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Xor") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    vec3f rgb3 = {0, 0, 0};
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = (((l1 != 0) && (l2 != 0)) ? rgb3 : rgb1 * l1 + rgb2 * l2) ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Alpha") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    vec3f rgb3 = {1,1,1};
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    image1->verts[i * w1 + j] = rgb3 * ((l1 != 0) || (l2 != 0) ? zeno::clamp(l1 + l2, 0, 1) : 0);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "!Alpha") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    vec3f rgb3 = {1,1,1};
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    image1->verts[i * w1 + j] = rgb3 * ((l1 != 0) || (l2 != 0) ? 0 : zeno::clamp(l1 + l2, 0, 1));
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(1 - (l1 + l2), 0, 1);
                }
            }
        }
        set_output("image", image1);
    }
};

ZENDEFNODE(Composite, {
    {
        {"Foreground"},
        {"Background"},
        {"Mask1"},
        {"Mask2"},
        {"enum Over Under Atop Inside Outside Screen Add Subtract Multiply Divide Diff Min Max Average Xor Alpha !Alpha", "Compmode", "Over"},
        {"enum R G B A", "Mask1mode", "R"},
        {"enum R G B A", "Mask2mode", "R"},
    },
    {
        {"image"}
    },
    {},
    { "comp" },
});

FIXBUG

 


DEPRECATED

 

 

 

 

 

 

 

 

 

 

 

 

 

 

struct CompExtractChanel : INode {
    virtual void apply() override {
        auto image = get_input<PrimitiveObject>("image");
        auto RGB = get_input2<bool>("RGB");
        auto R = get_input2<bool>("R");
        auto G = get_input2<bool>("G");
        auto B = get_input2<bool>("B");
        auto A = get_input2<bool>("A");
        auto &ud1 = image->userData();
        int w = ud1.get2<int>("w");
        int h = ud1.get2<int>("h");
        auto image2 = std::make_shared<PrimitiveObject>();
        image2->userData().set2("isImage", 1);
        image2->userData().set2("w", w);
        image2->userData().set2("h", h);
        image2->verts.resize(image->size());

        if(RGB){
            for (auto i = 0; i < image->verts.size(); i++) {
                float R = image->verts[i][0];
                float G = image->verts[i][0];
                float B = image->verts[i][0];
                image2->verts[i][0] = R;
                image2->verts[i][1] = G;
                image2->verts[i][2] = B;
            }
        }
        if(R && !RGB) {
            for (auto i = 0; i < image->verts.size(); i++) {
                float R = image->verts[i][0];
                zeno::clamp(image2->verts[i][0] += R,0,1);
                zeno::clamp(image2->verts[i][1] += R,0,1);
                zeno::clamp(image2->verts[i][2] += R,0,1);
            }
        }
        if(G && !RGB) {
            for (auto i = 0; i < image->verts.size(); i++) {
                float G = image->verts[i][1];
                image2->verts[i][0] += G;
                image2->verts[i][1] += G;
                image2->verts[i][2] += G;
            }
        }
        if(B && !RGB) {
            for (auto i = 0; i < image->verts.size(); i++) {
                float B = image->verts[i][2];
                image2->verts[i][0] += B;
                image2->verts[i][1] += B;
                image2->verts[i][2] += B;
            }
        }
        if(A) {
            if (image->verts.has_attr("alpha")) {
                auto &Alpha = image->verts.attr<float>("alpha");
                image2->verts.add_attr<float>("alpha");
                image2->verts.attr<float>("alpha")=image->verts.attr<float>("alpha");
            }
            else{
                image2->verts.add_attr<float>("alpha");
                for(int i = 0;i < w * h;i++){
                    image2->verts.attr<float>("alpha")[i] = 1.0;
                }
            }
        }
        set_output("image", image2);
    }
};
ZENDEFNODE(CompExtractChanel, {
    {
        {"image"},
        {"bool", "RGB", "0"},
        {"bool", "R", "0"},
        {"bool", "G", "0"},
        {"bool", "B", "0"},
        {"bool", "A", "0"},
    },
    {
        {"image"}
    },
    {},
    { "comp" },
});
struct Composite: INode {
    virtual void apply() override {
        auto compmode = get_input2<std::string>("compmode");
        int w1 = 1024 ;
        int h1 = 1024 ;
        auto image1 = std::make_shared<PrimitiveObject>();
        image1->userData().set2("isImage", 1);
        image1->userData().set2("w", w1);
        image1->userData().set2("h", h1);
        auto image2 = std::make_shared<PrimitiveObject>();
        image2->userData().set2("isImage", 1);
        image2->userData().set2("w", w1);
        image2->userData().set2("h", h1);

        if(has_input("Background")){
            image2 = get_input2<PrimitiveObject>("Background");
            auto &ud2 = image2->userData();
            w1 = ud2.get2<int>("w");
            h1 = ud2.get2<int>("h");
            if(!has_input("Foreground")){
                image1->verts.resize(image2->size());
                image1->userData().set2("w", w1);
                image1->userData().set2("h", h1);
                image1->verts.add_attr<float>("alpha");
                for(int i = 0;i < w1 * h1;i++){
                    image1->verts.attr<float>("alpha")[i] = 1.0;
                }
            }
        }
        if(has_input("Foreground")){
            image1 = get_input2<PrimitiveObject>("Foreground");
            auto &ud1 = image1->userData();
            w1 = ud1.get2<int>("w");
            h1 = ud1.get2<int>("h");
            if(!has_input("Background")){
                image2->verts.resize(image1->size());
                image2->userData().set2("w", w1);
                image2->userData().set2("h", h1);
                image2->verts.add_attr<float>("alpha");
                for(int i = 0;i < w1 * h1;i++){
                    image2->verts.attr<float>("alpha")[i] = 1.0;
                }
            }
            if(has_input("Background")){
                auto &ud2 = image2->userData();
                int w2 = ud2.get2<int>("w");
                int h2 = ud2.get2<int>("h");
                if(w1 != w2 || h1 != h2 || image1->size() != image2->size()){
                    image2->verts.resize(image1->size());
                    image2->userData().set2("w", w1);
                    image2->userData().set2("h", h1);
                }
            }
        }
        auto A1 = std::make_shared<PrimitiveObject>();
        A1->verts.resize(image1->size());
        A1->verts.add_attr<float>("alpha");
        for(int i = 0;i < w1 * h1;i++){
            A1->verts.attr<float>("alpha")[i] = 1.0;
        }
        auto A2 = std::make_shared<PrimitiveObject>();
        A2->verts.resize(image2->size());
        A2->verts.add_attr<float>("alpha");
        for(int i = 0;i < w1 * h1;i++){
            A2->verts.attr<float>("alpha")[i] = 1.0;
        }
        std::vector<float> &alpha1 = A1->verts.attr<float>("alpha");
        if(image1->verts.has_attr("alpha")){
            alpha1 = image1->verts.attr<float>("alpha");
        }
        else{
            image1->verts.add_attr<float>("alpha");
        }

        if(has_input("Mask1")) {
            auto Mask1 = get_input2<PrimitiveObject>("Mask1");
            if(Mask1->verts.has_attr("alpha")){
                alpha1 = Mask1->verts.attr<float>("alpha");
            }
            else{
                Mask1->verts.add_attr<float>("alpha");
                for (int i = 0; i < h1; i++) {
                    for (int j = 0; j < w1; j++) {
                        Mask1->verts.attr<float>("alpha")[i * w1 + j] = Mask1->verts[i * w1 + j][0];
                    }
                }
                alpha1 = Mask1->verts.attr<float>("alpha");
            }
        }
        std::vector<float> &alpha2 = A2->verts.attr<float>("alpha");
        if(image2->verts.has_attr("alpha")){
            alpha2 = image2->verts.attr<float>("alpha");
        }
        else{
            image2->verts.add_attr<float>("alpha");
        }
        if(has_input("Mask2")) {
            auto Mask2 = get_input2<PrimitiveObject>("Mask2");
            if(Mask2->verts.has_attr("alpha")){
                alpha2 = Mask2->verts.attr<float>("alpha");
            }
            else{
                for (int i = 0; i < h1; i++) {
                    for (int j = 0; j < w1; j++) {
                        Mask2->verts.attr<float>("alpha")[i * w1 + j] = Mask2->verts[i * w1 + j][0];
                    }
                }
                alpha2 = Mask2->verts.attr<float>("alpha");
            }
        }

        if (compmode == "Over") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * l1 + rgb2 * ((l1!=1 && l2!=0)? std::min((1-l1),l2) : 0);
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = ((l1!=0 || l2!=0)? zeno::max(l2,l1): 0);
                }
            }
        }
        if (compmode == "Under") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb2 * l2 + rgb1 * ((l2!=1 && l1!=0)? std::min((1-l2),l1) : 0);
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = ((l1!=0 || l2!=0)? zeno::max(l2,l1): 0);
                }
            }
        }
        if (compmode == "Atop") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * ((l1 != 0 && l2 != 0) ? l1 : 0) + rgb2 * ((l1 == 0) && (l2 != 0) ? l2 : 0);
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = (l1 !=0 && l2 !=0)? l1 : l2;
                }
            }
        }
        if (compmode == "Inside") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * ((l1 != 0) && (l2 != 0) ? l1 : 0);
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = (l1 !=0 && l2 !=0)? l1 : 0;
                }
            }
        }
        if (compmode == "Outside") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * ((l1 != 0) && (l2 == 0) ? l1 : 0);
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = (l1 != 0 && l2 == 0)? l1 : 0;
                }
            }
        }
        if(compmode == "Screen"){
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l = zeno::min(zeno::min(image1->verts[i * w1 + j][0],image1->verts[i * w1 + j][1]),image1->verts[i * w1 + j][2]);
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb2 * l2 + rgb2 * ((l1!=0 && l2!=0)? l: 0);
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = l2;
                }
            }
        }
        if (compmode == "Add") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb2 * l2 + rgb1 * l1;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Subtract") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * l1 - rgb2 * l2 ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Multiply") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * l1 * rgb2 * l2 ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Divide") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb1 * l1 / (rgb2 * l2) ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Diff") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = abs(rgb1 * l1 - (rgb2 * l2)) ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Min") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = l1 <= l2 ? rgb1 * l1 : rgb2 * l2 ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Max") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = l1 >= l2 ? rgb1 * l1 : rgb2 * l2 ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Average") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    vec3f rgb3 = (rgb1+rgb2)/2;
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = rgb3 * (l1+l2) ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Xor") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    vec3f rgb3 = {0, 0, 0};
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    vec3f c = (((l1 != 0) && (l2 != 0)) ? rgb3 : rgb1 * l1 + rgb2 * l2) ;
                    image1->verts[i * w1 + j] = zeno::clamp(c, 0, 1);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "Alpha") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    vec3f rgb3 = {1,1,1};
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    image1->verts[i * w1 + j] = rgb3 * ((l1 != 0) || (l2 != 0) ? zeno::clamp(l1 + l2, 0, 1) : 0);
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(l1 + l2, 0, 1);
                }
            }
        }
        if (compmode == "!Alpha") {
            for (int i = 0; i < h1; i++) {
                for (int j = 0; j < w1; j++) {
                    vec3f rgb1 = image1->verts[i * w1 + j];
                    vec3f rgb2 = image2->verts[i * w1 + j];
                    vec3f rgb3 = {1,1,1};
                    float l1 = alpha1[i * w1 + j];
                    float l2 = alpha2[i * w1 + j];
                    image1->verts[i * w1 + j] = rgb3 * ((l1 != 0) || (l2 != 0) ? 0 : zeno::clamp(l1 + l2, 0, 1));
                    image1->verts.attr<float>("alpha")[i * w1 + j] = zeno::clamp(1 - (l1 + l2), 0, 1);
                }
            }
        }
        set_output("image", image1);
    }
};

ZENDEFNODE(Composite, {
    {
        {"Foreground"},
        {"Background"},
        {"Mask1"},
        {"Mask2"},
        {"enum Over Under Atop Inside Outside Screen Add Subtract Multiply Divide Diff Min Max Average Xor Alpha !Alpha", "compmode", "Over"},
    },
    {
        {"image"}
    },
    {},
    { "comp" },
});

猜你喜欢

转载自blog.csdn.net/Angelloveyatou/article/details/130688261