【开发日志】2023.03.04 ZENO----SimpleGeometry----CreateSphere_EndlessDaydream的博客-CSDN博客CreateSpherehttps://blog.csdn.net/Angelloveyatou/article/details/129178914(4条消息) 【开发日志】2023.04 ZENO----Composite----CompNormalMap_EndlessDaydream的博客-CSDN博客https://blog.csdn.net/Angelloveyatou/article/details/130319455
Deprecated
struct CreateSphere : zeno::INode {
virtual void apply() override {
auto prim = std::make_shared<zeno::PrimitiveObject>();
auto position = get_input2<zeno::vec3f>("position");
auto scale = get_input2<zeno::vec3f>("scaleSize");
auto rows = get_input2<int>("rows");
auto columns = get_input2<int>("columns");
auto radius = get_input2<float>("radius");
auto quad = get_input2<bool>("quads");
if (rows < 2) {
rows = 2;
}
if (columns < 3) {
columns = 3;
}
std::vector<zeno::vec3f> verts = {};
std::vector<zeno::vec2i> poly = {};
std::vector<int> loops = {};
std::vector<zeno::vec2f> uvs = {};
std::vector<zeno::vec3f> nors = {};
verts.push_back (vec3f(0,1,0));
for (auto row = 1; row < rows; row++) {
float v = (float)row / (float)rows;
float theta = M_PI * v;
for (auto column = 0; column < columns; column++) {
float u = (float)column / (float)columns;
float phi = M_PI * 2 * u;
float x = sin(theta) * cos(phi);
float y = cos(theta);
float z = -sin(theta) * sin(phi);
verts.push_back(vec3f(x,y,z));
}
}
verts.push_back (vec3f(0,-1,0));
{
//head
for (auto column = 0; column < columns; column++) {
if (column == columns - 1) {
loops.push_back(0);
loops.push_back(columns);
loops.push_back(1);
poly.push_back(vec2i(column * 3, 3));
} else {
loops.push_back(0);
loops.push_back(column + 1);
loops.push_back(column + 2);
poly.push_back(vec2i(column * 3, 3));
}
}
//body
for (auto row = 1; row < rows - 1; row++) {
for (auto column = 0; column < columns; column++) {
if (column == columns - 1) {
loops.push_back((row - 1) * columns + 1);
loops.push_back((row - 1) * columns + columns);
loops.push_back(row * columns + columns);
loops.push_back(row * columns + 1);
poly.push_back(vec2i(columns * 3 + (row - 1) * columns * 4 + column * 4, 4));
} else {
loops.push_back((row - 1) * columns + column + 2);
loops.push_back((row - 1) * columns + column + 1);
loops.push_back(row * columns + column + 1);
loops.push_back(row * columns + column + 2);
poly.push_back(vec2i(loops.size() - 4, 4));
}
}
}
//tail
for (auto column = 0; column < columns; column++) {
if (column == columns - 1) {
loops.push_back((rows - 2) * columns + 1);
loops.push_back((rows - 2) * columns + column + 1);
loops.push_back((rows - 1) * columns + 1);
poly.push_back(vec2i(columns * 3 + (rows - 2) * columns * 4 + column * 3, 3));
} else {
loops.push_back((rows - 2) * columns + column + 2);
loops.push_back((rows - 2) * columns + column + 1);
loops.push_back((rows - 1) * columns + 1);
poly.push_back(vec2i(loops.size() - 3, 3));
}
}
}
for(int column = 0;column < columns;column++){
uvs.push_back({(column+0.5f)/columns, 1.0f, 0.0f});
}
for(int row = 1;row < rows;row++){
for(int column = 0;column < columns+1;column++){
uvs.push_back({(column+0.0f)/columns,1.0f-(row+0.0f)/rows,0.0f});
}
}
for(int column = 0;column < columns;column++){
uvs.push_back({(column+0.5f)/columns, 0.0f, 0.0f});
}
auto& loops_uv = prim->loops.add_attr<int>("uvs");
loops_uv.resize(0);
for(int column = 0;column < columns;column++){
loops_uv.push_back(column);
loops_uv.push_back(columns+column);
loops_uv.push_back(columns+column+1);
}
for(int row = 1;row < rows-1;row++){
for(int column = 0;column < columns;column++){
loops_uv.push_back(columns+(columns+1)*(row-1)+column+1);
loops_uv.push_back(columns+(columns+1)*(row-1)+column);
loops_uv.push_back(columns+(columns+1)*row+column);
loops_uv.push_back(columns+(columns+1)*row+column+1);
}
}
for(int column = 0;column < columns;column++){
loops_uv.push_back(columns+(columns+1)*(rows-2)+column+1);
loops_uv.push_back(columns+(columns+1)*(rows-2)+column);
loops_uv.push_back(columns+(columns+1)*(rows-1)+column);
}
nors.resize(verts.size());
for(int i = 0; i < verts.size(); i++){
auto n = verts[i];
auto p = verts[i];
auto rotate = get_input2<zeno::vec3f>("rotate");
glm::mat4 transform = glm::mat4 (1.0);
transform = glm::translate(transform, glm::vec3(position[0], position[1], position[2]));
transform = glm::rotate(transform, glm::radians(rotate[0]), glm::vec3(1, 0, 0));
transform = glm::rotate(transform, glm::radians(rotate[1]), glm::vec3(0, 1, 0));
transform = glm::rotate(transform, glm::radians(rotate[2]), glm::vec3(0, 0, 1));
transform = glm::scale(transform, glm::vec3(scale[0],scale[1],scale[2]) * radius);
auto gp = transform * glm::vec4(p[0], p[1], p[2], 1);
verts[i] = zeno::vec3f(gp.x, gp.y, gp.z);
auto n_transform = glm::transpose(glm::inverse(transform));
auto gn = n_transform * glm::vec4 (n[0], n[1], n[2], 0);
nors[i] = zeno::vec3f (gn.x, gn.y, gn.z);
}
prim->verts.resize(verts.size());
for (auto i = 0; i < verts.size(); i++) {
prim->verts[i] = verts[i];
}
prim->polys.resize(poly.size());
for (auto i = 0; i < poly.size(); i++) {
prim->polys[i] = poly[i];
}
prim->loops.resize(loops.size());
for (auto i = 0; i < loops.size(); i++) {
prim->loops[i] = loops[i];
}
prim->uvs.resize(uvs.size());
for (auto i = 0; i < uvs.size(); i++) {
prim->uvs[i] = uvs[i];
}
auto &nors2 = prim->verts.add_attr<zeno::vec3f>("nrm");
for (auto i = 0; i < nors.size(); i++) {
nors2[i] = nors[i];
}
if (!get_input2<bool>("hasNormal")){
prim->verts.attrs.erase("nrm");
}
if (!get_input2<bool>("hasVertUV")){
prim->uvs.clear();
prim->loops.erase_attr("uvs");
}
if (get_input2<bool>("isFlipFace")){
for (auto i = 0; i < prim->polys.size(); i++) {
auto [base, cnt] = prim->polys[i];
for (int j = 0; j < (cnt / 2); j++) {
std::swap(prim->loops[base + j], prim->loops[base + cnt - 1 - j]);
if (prim->loops.has_attr("uvs")) {
std::swap(prim->loops.attr<int>("uvs")[base + j], prim->loops.attr<int>("uvs")[base + cnt - 1 - j]);
}
}
}
}
if(!quad){
primTriangulate(prim.get());
}
set_output("prim",std::move(prim));
}
};
ZENDEFNODE(CreateSphere, {
{
{"vec3f", "position", "0, 0, 0"},
{"vec3f", "scaleSize", "1, 1, 1"},
{"float", "radius", "1"},
ROTATE_PARM
NORMUV_PARM
{"int", "rows", "12"},
{"int", "columns", "24"},
{"bool", "quads", "0"},
},
{"prim"},
{},
{"create"},
});
struct PrimitiveDuplicate : zeno::INode {
virtual void apply() override {
auto mesh = get_input<PrimitiveObject>("meshPrim");
auto pars = get_input<PrimitiveObject>("particlesPrim");
auto outm = std::make_shared<PrimitiveObject>();
outm->resize(pars->size() * mesh->size());
float uniScale = has_input("uniScale") ?
get_input<NumericObject>("uniScale")->get<float>() : 1.0f;
auto scaleByAttr = get_param<std::string>("scaleByAttr");
auto const &parspos = pars->attr<vec3f>("pos");
auto const &meshpos = mesh->attr<vec3f>("pos");
auto &outmpos = outm->add_attr<vec3f>("pos");
if (scaleByAttr.size()) {
auto const &scaleAttr = pars->attr<float>(scaleByAttr);
#pragma omp parallel for
for(int i = 0; i < parspos.size(); i++) {
for (int j = 0; j < meshpos.size(); j++) {
auto scale = uniScale * scaleAttr[i];
outmpos[i * meshpos.size() + j] = parspos[i] + scale * meshpos[j];
}
}
} else {
#pragma omp parallel for
for(int i = 0; i < parspos.size(); i++) {
for (int j = 0; j < meshpos.size(); j++) {
auto scale = uniScale;
outmpos[i * meshpos.size() + j] = parspos[i] + scale * meshpos[j];
}
}
}
if (get_param<bool>("attrFromMesh")) {
mesh->verts.foreach_attr([&] (auto const &key, auto const &attr) {
using T = std::decay_t<decltype(attr[0])>;
auto &outattr = outm->add_attr<T>(key);
#pragma omp parallel for
for(int i = 0; i < pars->size(); i++) {
for (int j = 0; j < attr.size(); j++) {
outattr[i * attr.size() + j] = attr[j];
}
}
});
}
if (get_param<bool>("attrFromParticles")) {
pars->verts.foreach_attr([&] (auto const &key, auto const &attr) {
using T = std::decay_t<decltype(attr[0])>;
auto &outattr = outm->add_attr<T>(key);
#pragma omp parallel for
for (int i = 0; i < attr.size(); i++) {
for (int j = 0; j < mesh->size(); j++) {
outattr[i * mesh->size() + j] = attr[i];
}
}
});
}
outm->points.resize(pars->size() * mesh->points.size());
#pragma omp parallel for
for(int i = 0; i < pars->size(); i++) {
for (int j = 0; j < mesh->points.size(); j++) {
outm->points[i * mesh->points.size() + j]
= mesh->points[j] + i * meshpos.size();
}
}
outm->lines.resize(pars->size() * mesh->lines.size());
#pragma omp parallel for
for(int i = 0; i < pars->size(); i++) {
for (int j = 0; j < mesh->lines.size(); j++) {
outm->lines[i * mesh->lines.size() + j]
= mesh->lines[j] + i * meshpos.size();
}
}
outm->tris.resize(pars->size() * mesh->tris.size());
#pragma omp parallel for
for(int i = 0; i < pars->size(); i++) {
for (int j = 0; j < mesh->tris.size(); j++) {
outm->tris[i * mesh->tris.size() + j]
= mesh->tris[j] + i * meshpos.size();
}
}
outm->quads.resize(pars->size() * mesh->quads.size());
#pragma omp parallel for
for(int i = 0; i < pars->size(); i++) {
for (int j = 0; j < mesh->quads.size(); j++) {
outm->quads[i * mesh->quads.size() + j]
= mesh->quads[j] + i * meshpos.size();
}
}
set_output("outPrim", std::move(outm));
}
};
ZENDEFNODE(PrimitiveDuplicate, {
{
"meshPrim",
"particlesPrim",
{"float", "uniScale", "1.0"},
}, {
"outPrim",
}, {
{"bool", "attrFromMesh", "1"},
{"bool", "attrFromParticles", "1"},
{"string", "scaleByAttr", ""},
}, {
"deprecated",
}});
}
void primSampleTexture(
std::shared_ptr<PrimitiveObject> prim,
const std::string &srcChannel,
const std::string &uvSource,
const std::string &dstChannel,
std::shared_ptr<PrimitiveObject> img,
const std::string &wrap,
const std::string &filter,
vec3f borderColor,
float remapMin,
float remapMax
) {
if (!img->userData().has("isImage")) throw zeno::Exception("not an image");
using ColorT = float;
const ColorT *data = (float *)img->verts.data();
auto &clr = prim->add_attr<zeno::vec3f>(dstChannel);
auto w = img->userData().get2<int>("w");
auto h = img->userData().get2<int>("h");
std::function<zeno::vec3f(vec3f, const ColorT*, int, int, int, vec3f)> queryColor;
if (filter == "nearest") {
if (wrap == "REPEAT") {
queryColor = [=](vec3f uv, const ColorT *data, int w, int h, int n, vec3f _clr) -> vec3f {
uv = (uv - remapMin) / (remapMax - remapMin);
auto iuv = uvRepeat(uv, w, h);
return queryColorInner(iuv, data, w, n);
};
} else if (wrap == "CLAMP_TO_EDGE") {
queryColor = [=](vec3f uv, const ColorT *data, int w, int h, int n, vec3f _clr) -> vec3f {
uv = (uv - remapMin) / (remapMax - remapMin);
auto iuv = uvClampToEdge(uv, w, h);
return queryColorInner(iuv, data, w, n);
};
} else if (wrap == "CLAMP_TO_BORDER") {
queryColor = [=](vec3f uv, const ColorT *data, int w, int h, int n, vec3f clr) -> vec3f {
uv = (uv - remapMin) / (remapMax - remapMin);
if (uv[0] < 0 || uv[0] > 1 || uv[1] < 0 || uv[1] > 1) {
return clr;
}
auto iuv = uvClampToEdge(uv, w, h);
return queryColorInner(iuv, data, w, n);
};
} else {
zeno::log_error("wrap type error");
throw std::runtime_error("wrap type error");
}
}
else {
queryColor = [=](vec3f uv, const ColorT *data, int w, int h, int n, vec3f _clr) -> vec3f {
uv = (uv - remapMin) / (remapMax - remapMin);
float u, v;
auto iuv = uvClampToEdge(uv, w, h, u, v);
auto c00 = queryColorInner(iuv, data, w, n, h);
auto c01 = queryColorInner(iuv + vec2i(1, 0), data, w, n, h);
auto c10 = queryColorInner(iuv + vec2i(0, 1), data, w, n, h);
auto c11 = queryColorInner(iuv + vec2i(1, 1), data, w, n, h);
auto a = zeno::mix(c00, c01, u);
auto b = zeno::mix(c10, c11, u);
auto c = zeno::mix(a, b, v);
return c;
};
}
if (uvSource == "vertex") {
auto &uv = prim->attr<zeno::vec3f>(srcChannel);
#pragma omp parallel for
for (auto i = 0; i < uv.size(); i++) {
clr[i] = queryColor(uv[i], data, w, h, 3, borderColor);
}
}
else if (uvSource == "tris") {
auto uv0 = prim->tris.attr<vec3f>("uv0");
auto uv1 = prim->tris.attr<vec3f>("uv1");
auto uv2 = prim->tris.attr<vec3f>("uv2");
#pragma omp parallel for
for (auto i = 0; i < prim->tris.size(); i++) {
auto tri = prim->tris[i];
clr[tri[0]] = queryColor(uv0[i], data, w, h, 3, borderColor);
clr[tri[1]] = queryColor(uv1[i], data, w, h, 3, borderColor);
clr[tri[2]] = queryColor(uv2[i], data, w, h, 3, borderColor);
}
}
else if (uvSource == "loopsuv") {
auto &loopsuv = prim->loops.attr<int>("uvs");
#pragma omp parallel for
for (auto i = 0; i < prim->loops.size(); i++) {
auto uv = prim->uvs[loopsuv[i]];
int index = prim->loops[i];
clr[index] = queryColor({uv[0], uv[1], 0}, data, w, h, 3, borderColor);
}
}
else {
zeno::log_error("unknown uvSource");
throw std::runtime_error("unknown uvSource");
}
}
void primSampleTexture(
std::shared_ptr<PrimitiveObject> prim,
const std::string &srcChannel,
const std::string &uvSource,
const std::string &dstChannel,
std::shared_ptr<PrimitiveObject> img,
const std::string &wrap,
vec3f borderColor,
float remapMin,
float remapMax
) {
return primSampleTexture(prim, srcChannel, uvSource, dstChannel, img, wrap, "nearest", borderColor, remapMin, remapMax);;
}
struct PrimSample2D : zeno::INode {
virtual void apply() override {
auto prim = get_input<PrimitiveObject>("prim");
auto srcChannel = get_input2<std::string>("uvChannel");
auto srcSource = get_input2<std::string>("uvSource");
auto dstChannel = get_input2<std::string>("targetChannel");
auto image = get_input2<PrimitiveObject>("image");
auto wrap = get_input2<std::string>("wrap");
auto filter = get_input2<std::string>("filter");
auto borderColor = get_input2<vec3f>("borderColor");
auto remapMin = get_input2<float>("remapMin");
auto remapMax = get_input2<float>("remapMax");
primSampleTexture(prim, srcChannel, srcSource, dstChannel, image, wrap, filter, borderColor, remapMin, remapMax);
set_output("outPrim", std::move(prim));
}
};
ZENDEFNODE(PrimSample2D, {
{
{"PrimitiveObject", "prim"},
{"PrimitiveObject", "image"},
{"string", "uvChannel", "uv"},
{"enum vertex tris loopsuv", "uvSource", "vertex"},
{"string", "targetChannel", "clr"},
{"float", "remapMin", "0"},
{"float", "remapMax", "1"},
{"enum REPEAT CLAMP_TO_EDGE CLAMP_TO_BORDER", "wrap", "REPEAT"},
{"enum nearest linear", "filter", "nearest"},
{"vec3f", "borderColor", "0,0,0"},
},
{
{"PrimitiveObject", "outPrim"}
},
{},
{"primitive"},
});