diff --git a/projects/Alembic/ReadAlembic.cpp b/projects/Alembic/ReadAlembic.cpp index 98ca8a6639..f76e33fda2 100644 --- a/projects/Alembic/ReadAlembic.cpp +++ b/projects/Alembic/ReadAlembic.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef ZENO_WITH_PYTHON3 #include @@ -417,6 +418,62 @@ static void read_attributes2(std::shared_ptr prim, ICompoundPro } attr_from_data_vec(prim, samp.getScope(), p.getName(), data); } + else if (IC4fGeomParam::matches(p)) { + IC4fGeomParam param(arbattrs, p.getName()); + + IC4fGeomParam::Sample samp = param.getIndexedValue(iSS); + std::vector data; + data.resize(samp.getVals()->size()); + std::vector data_xyz(samp.getVals()->size()); + std::vector data_w(samp.getVals()->size()); + for (auto i = 0; i < samp.getVals()->size(); i++) { + auto v = samp.getVals()->get()[i]; + data[i] = {v[0], v[1], v[2], v[3]}; + data_xyz[i] = {v[0], v[1], v[2]}; + data_w[i] = v[3]; + } + if (!read_done) { + log_info("[alembic] C4f attr {}, len {}.", p.getName(), data.size()); + } + attr_from_data_vec(prim, samp.getScope(), p.getName(), data); + attr_from_data_vec(prim, samp.getScope(), p.getName() + "_rgb", data_xyz); + attr_from_data_vec(prim, samp.getScope(), p.getName() + "_a", data_w); + } + else { + log_info("[alembic] unknown attr {}.", p.getName()); + zeno::log_info("getExtent {} ", p.getDataType().getExtent()); + zeno::log_info("getNumBytes {} ", p.getDataType().getNumBytes()); + zeno::log_info("getPod {} ", p.getDataType().getPod()); + } + } + { + if (prim->loops.attr_keys().size() == 0) { + return; + } + if (prim->loops.attr_keys().size() == 1 && prim->loops.has_attr("uvs")) { + return; + } + if (!prim->loops.has_attr("uvs")) { + prim->loops.add_attr("uvs"); + prim->uvs.emplace_back(); + } + { + std::vector uvs(prim->loops.size()); + auto &uv_index = prim->loops.attr("uvs"); + for (auto i = 0; i < prim->loops.size(); i++) { + uvs[i] = prim->uvs[uv_index[i]]; + } + prim->uvs.values = uvs; + std::iota(uv_index.begin(), uv_index.end(), 0); + prim->loops.foreach_attr([&] (auto const &key, auto &arr) { + if (key == "uvs") { + return; + } + using T = std::decay_t; + auto &attr = prim->uvs.add_attr(key); + std::copy(arr.begin(), arr.end(), attr.begin()); + }); + } } } @@ -1358,7 +1415,7 @@ ZENDEFNODE(PrimsFilterInUserdata, { {"bool", "fuzzy", "0"}, }, { - {"out"}, + {"list", "out"}, }, {}, {"alembic"}, diff --git a/ui/zenoedit/launch/optixcmd.cpp b/ui/zenoedit/launch/optixcmd.cpp index 8bde9a3374..3a9ed37175 100644 --- a/ui/zenoedit/launch/optixcmd.cpp +++ b/ui/zenoedit/launch/optixcmd.cpp @@ -51,6 +51,7 @@ int optixcmd(const QCoreApplication& app, int port) {"video", "video", "export video"}, {"aov", "aov", "aov"}, {"exr", "exr", "exr"}, + {"mask", "mask", "mask"}, {"needDenoise", "needDenoise", "needDenoise"}, {"videoname", "videoname", "export video's name"}, {"subzsg", "subgraphzsg", "subgraph zsg file path"}, @@ -116,6 +117,8 @@ int optixcmd(const QCoreApplication& app, int port) ud.set2("output_aov", enableAOV != 0); ud.set2("output_exr", exportExr != 0); ud.set2("optix_show_background", optixShowBackground); + int enableMask = cmdParser.isSet("mask") ? cmdParser.value("mask").toInt() : 0; + ud.set2("output_mask", enableMask != 0); param.videoName = cmdParser.isSet("videoname") ? cmdParser.value("videoname") : "output.mp4"; param.subZsg = cmdParser.isSet("subzsg") ? cmdParser.value("subzsg") : ""; #else diff --git a/zenovis/xinxinoptix/optixPathTracer.cpp b/zenovis/xinxinoptix/optixPathTracer.cpp index d4251bdb72..4f4ba44181 100644 --- a/zenovis/xinxinoptix/optixPathTracer.cpp +++ b/zenovis/xinxinoptix/optixPathTracer.cpp @@ -3809,6 +3809,26 @@ static void save_exr(float3* ptr, int w, int h, std::string path) { } } } +static void save_png_data(std::string path, int w, int h, float* ptr) { + std::vector data; + data.reserve(w * h * 3); + for (auto i = 0; i < w * h * 3; i++) { + data.push_back(std::lround(ptr[i] * 255.0f)); + } + std::string native_path = zeno::create_directories_when_write_file(path); + stbi_flip_vertically_on_write(1); + stbi_write_png(native_path.c_str(), w, h, 3, data.data(),0); +} +static void save_png_color(std::string path, int w, int h, float* ptr) { + std::vector data; + data.reserve(w * h * 3); + for (auto i = 0; i < w * h * 3; i++) { + data.push_back(std::lround(pow(ptr[i], 1.0f/2.2f) * 255.0f)); + } + std::string native_path = zeno::create_directories_when_write_file(path); + stbi_flip_vertically_on_write(1); + stbi_write_png(native_path.c_str(), w, h, 3, data.data(),0); +} void optixrender(int fbo, int samples, bool denoise, bool simpleRender) { bool imageRendered = false; @@ -3849,40 +3869,44 @@ void optixrender(int fbo, int samples, bool denoise, bool simpleRender) { bool enable_output_mask = zeno::getSession().userData().get2("output_mask", false); auto exr_path = path.substr(0, path.size() - 4) + ".exr"; if (enable_output_mask) { - std::vector data; - data.reserve(w * h * 3); - float* ptr = (float *)optixgetimg_extra("mask"); - for (auto i = 0; i < w * h * 3; i++) { - data.push_back(int(ptr[i])); - } - std::string native_path = zeno::create_directories_when_write_file(path + "_mask.png"); - stbi_flip_vertically_on_write(1); - stbi_write_png(native_path.c_str(), w, h, 3, data.data(),0); + path = path.substr(0, path.size() - 4); + save_png_data(path + "_mask.png", w, h, (float*)optixgetimg_extra("mask")); } // AOV if (enable_output_aov) { - zeno::create_directories_when_write_file(exr_path); - SaveMultiLayerEXR( - { - (float*)optixgetimg_extra("color"), - (float*)optixgetimg_extra("diffuse"), - (float*)optixgetimg_extra("specular"), - (float*)optixgetimg_extra("transmit"), - (float*)optixgetimg_extra("background"), - (float*)optixgetimg_extra("mask"), - }, - w, - h, - { - "", - "diffuse.", - "specular.", - "transmit.", - "background.", - "mask.", - }, - exr_path.c_str() - ); + if (enable_output_exr) { + zeno::create_directories_when_write_file(exr_path); + SaveMultiLayerEXR( + { + (float*)optixgetimg_extra("color"), + (float*)optixgetimg_extra("diffuse"), + (float*)optixgetimg_extra("specular"), + (float*)optixgetimg_extra("transmit"), + (float*)optixgetimg_extra("background"), + (float*)optixgetimg_extra("mask"), + }, + w, + h, + { + "", + "diffuse.", + "specular.", + "transmit.", + "background.", + "mask.", + }, + exr_path.c_str() + ); + + } + else { + path = path.substr(0, path.size() - 4); + save_png_color(path + ".aov.diffuse.png", w, h, (float*)optixgetimg_extra("diffuse")); + save_png_color(path + ".aov.specular.png", w, h, (float*)optixgetimg_extra("specular")); + save_png_color(path + ".aov.transmit.png", w, h, (float*)optixgetimg_extra("transmit")); + save_png_data(path + ".aov.background.png", w, h, (float*)optixgetimg_extra("background")); + save_png_data(path + ".aov.mask.png", w, h, (float*)optixgetimg_extra("mask")); + } } else { if (enable_output_exr) {