【开发日志】2023.05 ZENO----Image Panel----ChessBoard、Mix transparent & opaque

 

 

 

 


void ZenoImagePanel::setPrim(std::string primid) {
    primid = primid.substr(0, primid.find(":"));
    pPrimName->setText(primid.c_str());
    zenovis::Scene* scene = nullptr;
    auto mainWin = zenoApp->getMainWindow();
    ZASSERT_EXIT(mainWin);
    QVector<DisplayWidget*> wids = mainWin->viewports();
    if (!wids.isEmpty())
    {
        auto session = wids[0]->getZenoVis()->getSession();
        ZASSERT_EXIT(session);
        scene = session->get_scene();
    }
    if (!scene)
        return;

    bool found = false;
    for (auto const &[key, ptr]: scene->objectsMan->pairs()) {
        if ((key.substr(0, key.find(":"))) != primid) {
            continue;
        }
        auto &ud = ptr->userData();
        if (ud.get2<int>("isImage", 0) == 0) {
            continue;
        }
        found = true;
        if (auto obj = dynamic_cast<zeno::PrimitiveObject *>(ptr)) {
            int width = ud.get2<int>("w");
            int height = ud.get2<int>("h");
            if (image_view) {
                QImage img(width, height, QImage::Format_RGB32);
                int gridSize = 50;
                if (obj->verts.has_attr("alpha")) {
                    auto &alpha = obj->verts.attr<float>("alpha");
                    for (auto i = 0; i < obj->verts.size(); i++) {
                        int h = i / width;
                        int w = i % width;
                        auto foreground = obj->verts[i];
                        foreground = zeno::pow(foreground, 1.0f / 2.2f);
                        zeno::vec3f background;
                        if ((h / gridSize) % 2 == (w / gridSize) % 2) {
                            background = {1, 1, 1};
                        }
                        else {
                            background = {0.86, 0.86, 0.86};
                        }
                        zeno::vec3f c = zeno::mix(background, foreground, alpha[i]);

                        int r = glm::clamp(int(c[0] * 255.99), 0, 255);
                        int g = glm::clamp(int(c[1] * 255.99), 0, 255);
                        int b = glm::clamp(int(c[2] * 255.99), 0, 255);

                        img.setPixel(w, height - 1 - h, qRgb(r, g, b));
                    }
                }
                else{
                    for (auto i = 0; i < obj->verts.size(); i++) {
                        int h = i / width;
                        int w = i % width;
                        auto c = obj->verts[i];
                        c = zeno::pow(c, 1.0f / 2.2f);
                        int r = glm::clamp(int(c[0] * 255.99), 0, 255);
                        int g = glm::clamp(int(c[1] * 255.99), 0, 255);
                        int b = glm::clamp(int(c[2] * 255.99), 0, 255);

                        img.setPixel(w, height - 1 - h, qRgb(r, g, b));
                    }
                }
                image_view->setImage(img);
            }
            QString statusInfo = QString(zeno::format("width: {}, height: {}", width, height).c_str());
            pStatusBar->setText(statusInfo);
        }
    }
    if (found == false) {
        clear();
    }
}

#include "zenoimagepanel.h"
#include "PrimAttrTableModel.h"
#include "viewport/zenovis.h"
#include "zenovis/ObjectsManager.h"
#include "zeno/utils/format.h"
#include <zeno/types/UserData.h>
#include <zeno/types/PrimitiveObject.h>
#include <zenoui/comctrl/zcombobox.h>
#include "zeno/utils/log.h"
#include "zenoapplication.h"
#include "zassert.h"
#include "viewport/viewportwidget.h"
#include "zenomainwindow.h"
#include "viewport/displaywidget.h"


const float ziv_wheelZoomFactor = 1.25;

class ZenoImageView: public QGraphicsView {
public:
    QGraphicsPixmapItem *_image = nullptr;
    QGraphicsScene *scene = nullptr;
    explicit ZenoImageView(QWidget *parent) : QGraphicsView(parent) {
        scene = new QGraphicsScene;
        this->setScene(scene);

        setBackgroundBrush(QColor(37, 37, 37));

        this->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
        this->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
    }

    bool hasImage() {
        return _image != nullptr;
    }

    void clearImage() {
        if (hasImage()) {
            scene->removeItem(_image);
            _image = nullptr;
        }
    }

    void setImage(const QImage &image) {
        QPixmap pm = QPixmap::fromImage(image);
        if (hasImage()) {
            _image->setPixmap(pm);
        }
        else {
            _image = this->scene->addPixmap(pm);
        }
        setSceneRect(QRectF(pm.rect()));  // Set scene size to image size.
        updateImageView();
    }

    void updateImageView() {
        if (!hasImage()) {
            return;
        }

        fitInView(sceneRect(), Qt::AspectRatioMode::KeepAspectRatio);
    }
    void resizeEvent(QResizeEvent *event) override {
        updateImageView();
    }
};

void ZenoImagePanel::clear() {
    if (image_view) {
        image_view->clearImage();
    }
    pPrimName->clear();
    pStatusBar->clear();
}

void ZenoImagePanel::setPrim(std::string primid) {
    primid = primid.substr(0, primid.find(":"));
    pPrimName->setText(primid.c_str());
    zenovis::Scene* scene = nullptr;
    auto mainWin = zenoApp->getMainWindow();
    ZASSERT_EXIT(mainWin);
    QVector<DisplayWidget*> wids = mainWin->viewports();
    if (!wids.isEmpty())
    {
        auto session = wids[0]->getZenoVis()->getSession();
        ZASSERT_EXIT(session);
        scene = session->get_scene();
    }
    if (!scene)
        return;

    bool found = false;
    for (auto const &[key, ptr]: scene->objectsMan->pairs()) {
        if ((key.substr(0, key.find(":"))) != primid) {
            continue;
        }
        auto &ud = ptr->userData();
        if (ud.get2<int>("isImage", 0) == 0) {
            continue;
        }
        found = true;
        if (auto obj = dynamic_cast<zeno::PrimitiveObject *>(ptr)) {
            int width = ud.get2<int>("w");
            int height = ud.get2<int>("h");

            if (image_view) {
                QImage img(width, height, QImage::Format_RGB32);
                int gridSize = 50;
                std::vector<zeno::vec3f> rgb;
                if (obj->verts.has_attr("alpha")) {
                    for (int i = 0; i < height; ++i) {
                        for (int j = 0; j < width; ++j) {
                            if(obj->verts.attr<float>("alpha")[i * width + j]==0){
                                if ((i / gridSize) % 2 == (j / gridSize) % 2) {
                                    rgb.push_back(zeno::vec3f(220,220,220));
                                } else {
                                    rgb.push_back(zeno::vec3f(255, 255, 255));
//                                    img.setPixel(j, height-1-i, qRgba(255, 255, 255, 255)); // 白色格子
                                }
                            }
                            else if(obj->verts.attr<float>("alpha")[i * width + j]!=0 && obj->verts.attr<float>("alpha")[i * width + j]!=1){
                                auto a1 = obj->verts.attr<float>("alpha")[i * width + j];
                                auto c = obj->verts[i * width + j];
                                if ((i / gridSize) % 2 == (j / gridSize) % 2) {
                                    c = zeno::pow(c, 1.0f / 2.2f);
                                    rgb.push_back(zeno::vec3f(glm::clamp(int(c[0] * 255.99 * a1 + 220 * (1-a1)), 0, 255),
                                                              glm::clamp(int(c[1] * 255.99 * a1 + 220 * (1-a1)), 0, 255),
                                                              glm::clamp(int(c[2] * 255.99 * a1 + 220 * (1-a1)), 0, 255)));
                                } else {
                                    c = zeno::pow(c, 1.0f / 2.2f);
                                    rgb.push_back(zeno::vec3f(glm::clamp(int(c[0] * 255.99 * a1 + 255 * (1-a1)), 0, 255),
                                                              glm::clamp(int(c[1] * 255.99 * a1 + 255 * (1-a1)), 0, 255),
                                                              glm::clamp(int(c[2] * 255.99 * a1 + 255 * (1-a1)), 0, 255)));
                                }
                            }
                            else{
                                auto c = obj->verts[i * width + j];
                                c = zeno::pow(c, 1.0f / 2.2f);
                                rgb.push_back(zeno::vec3f(glm::clamp(int(c[0] * 255.99), 0, 255),
                                                          glm::clamp(int(c[1] * 255.99), 0, 255),
                                                          glm::clamp(int(c[2] * 255.99), 0, 255)));
                            }
                        }
                    }
                }
                else{
                    for (auto i = 0; i < obj->verts.size(); i++) {
                        auto c = obj->verts[i];
                        c = zeno::pow(c, 1.0f / 2.2f);
                        rgb.push_back(zeno::vec3f(glm::clamp(int(c[0] * 255.99), 0, 255),
                                                  glm::clamp(int(c[1] * 255.99), 0, 255),
                                                  glm::clamp(int(c[2] * 255.99), 0, 255)));
                    }
                }
                for (int i = 0; i < height; ++i) {
                    for (int j = 0; j < width; ++j) {
                        img.setPixel(j, height - 1 - i, qRgba(rgb[i * width + j][0], rgb[i * width + j][1], rgb[i * width + j][2] ,255));
                    }
                }
                image_view->setImage(img);
            }
            QString statusInfo = QString(zeno::format("width: {}, height: {}", width, height).c_str());
            pStatusBar->setText(statusInfo);
        }
    }
    if (found == false) {
        clear();
    }
}

ZenoImagePanel::ZenoImagePanel(QWidget *parent) : QWidget(parent) {
    QVBoxLayout* pMainLayout = new QVBoxLayout;
    pMainLayout->setContentsMargins(QMargins(0, 0, 0, 0));
    setLayout(pMainLayout);
    setFocusPolicy(Qt::ClickFocus);

    QPalette palette = this->palette();
    palette.setBrush(QPalette::Window, QColor(37, 37, 38));
    setPalette(palette);
    setAutoFillBackground(true);

    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);

    QHBoxLayout* pTitleLayout = new QHBoxLayout;

    QLabel* pPrim = new QLabel(tr("Prim: "));
    pPrim->setProperty("cssClass", "proppanel");
    pTitleLayout->addWidget(pPrim);

    pPrimName->setProperty("cssClass", "proppanel");
    pTitleLayout->addWidget(pPrimName);

//    ZComboBox* pMode = new ZComboBox();
//    pMode->addItem("RGB");
//    pMode->addItem("RGBA");
//    pMode->addItem("R");
//    pMode->addItem("G");
//    pMode->addItem("B");
//    pMode->setProperty("cssClass", "proppanel");
//    pTitleLayout->addWidget(pMode);

    pMainLayout->addLayout(pTitleLayout);

    image_view = new ZenoImageView(this);
    image_view->setProperty("cssClass", "proppanel");
    pMainLayout->addWidget(image_view);

    pStatusBar->setProperty("cssClass", "proppanel");
    pStatusBar->setText("PlaceHolder");


    pMainLayout->addWidget(pStatusBar);

    auto mainWin = zenoApp->getMainWindow();
    ZASSERT_EXIT(mainWin);
    QVector<DisplayWidget*> wids = mainWin->viewports();
    if (wids.isEmpty())
        return;

    Zenovis* zenovis = wids[0]->getZenoVis();
    if (!zenovis)
        return;

    connect(zenovis, &Zenovis::objectsUpdated, this, [=](int frame) {
        std::string prim_name = pPrimName->text().toStdString();
        Zenovis* zenovis = wids[0]->getZenoVis();
        ZASSERT_EXIT(zenovis);
        auto session = zenovis->getSession();
        ZASSERT_EXIT(session);
        auto scene = session->get_scene();
        ZASSERT_EXIT(scene);
        for (auto const &[key, ptr]: scene->objectsMan->pairs()) {
            if (key.find(prim_name) == 0 && key.find(zeno::format(":{}:", frame)) != std::string::npos) {
                setPrim(key);
            }
        }
    });
}

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 (auto a = 0; a < h1 * w1; a++){
//                int i = a / w1;
//                int j = a % w1;
            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" },
});

 

(220, 220, 220); // 黑色格子
(255, 255, 255); // 白色格子

#2D3239 light
#121416 dark

Color 1 (RGB): 45,50,57
Color 2 (RGB): 18,20,22

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值