Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Small internal fixes #1256

Merged
merged 26 commits into from
Jun 30, 2021
Merged
8 changes: 4 additions & 4 deletions apps/ymesh/ymesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ bool texture_brush(vector<vec3f>& positions, vector<vec2f>& texcoords,

auto scale_factor = 3.5f / params.radius;
auto max_height = gaussian_distribution(
zero3f, zero3f, 0.7f, scale_factor, params.strength, params.radius);
{0, 0, 0}, {0, 0, 0}, 0.7f, scale_factor, params.strength, params.radius);

for (auto idx : vertices) {
auto uv = texcoords[idx];
Expand Down Expand Up @@ -1032,9 +1032,9 @@ bool smooth_brush(vector<vec3f>& positions, const geodesic_solver& solver,
auto update = [&](int node, int neighbor, float new_distance) {
if (current_node == -1) current_node = node;
if (node != current_node) {
vec3f sum1 = zero3f;
float sum2 = 0.0f;
for (int i = 0; i < neighbors.size(); i++) {
auto sum1 = vec3f{0, 0, 0};
auto sum2 = 0.0f;
for (auto i = 0; i < neighbors.size(); i++) {
sum1 += positions[neighbors[i]] * weights[i];
sum2 += weights[i];
}
Expand Down
114 changes: 55 additions & 59 deletions apps/yshape/yshape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,20 @@ using namespace yocto;

// convert params
struct convert_params {
string shape = "shape.ply";
string output = "out.ply";
bool info = false;
bool smooth = false;
bool facet = false;
bool aspositions = false;
bool astriangles = false;
vec3f translate = {0, 0, 0};
vec3f rotate = {0, 0, 0};
vec3f scale = {1, 1, 1};
float scaleu = 1;
bool toedges = false;
bool tovertices = false;
string shape = "shape.ply";
string output = "out.ply";
bool info = false;
bool smooth = false;
bool facet = false;
bool aspositions = false;
bool astriangles = false;
vec3f translate = {0, 0, 0};
vec3f rotate = {0, 0, 0};
vec3f scale = {1, 1, 1};
int subdivisions = 0;
bool catmullclark = false;
bool toedges = false;
bool tovertices = false;
};

void add_options(const cli_command& cli, convert_params& params) {
Expand All @@ -63,16 +64,12 @@ void add_options(const cli_command& cli, convert_params& params) {
add_option(
cli, "aspositions", params.aspositions, "Remove all but positions.");
add_option(cli, "astriangles", params.astriangles, "Convert to triangles.");
add_option(cli, "translatex", params.translate.x, "Translate shape.");
add_option(cli, "translatey", params.translate.y, "Translate shape.");
add_option(cli, "translatez", params.translate.z, "Translate shape.");
add_option(cli, "scalex", params.scale.x, "Scale shape.");
add_option(cli, "scaley", params.scale.y, "Scale shape.");
add_option(cli, "scalez", params.scale.z, "Scale shape.");
add_option(cli, "scaleu", params.scaleu, "Scale shape.");
add_option(cli, "rotatex", params.rotate.x, "Rotate shape.");
add_option(cli, "rotatey", params.rotate.y, "Rotate shape.");
add_option(cli, "rotatez", params.rotate.z, "Rotate shape.");
add_option(cli, "translate", params.translate, "Translate shape.");
add_option(cli, "scale", params.scale, "Scale shape.");
add_option(cli, "rotate", params.rotate, "Rotate shape.");
add_option(cli, "subdivisions", params.subdivisions, "Apply subdivision.");
add_option(
cli, "catmullclark", params.catmullclark, "Catmull-Clark subdivision.");
add_option(cli, "toedges", params.toedges, "Convert shape to edges.");
add_option(
cli, "tovertices", params.tovertices, "Convert shape to vertices.");
Expand Down Expand Up @@ -106,11 +103,16 @@ void run_convert(const convert_params& params) {
for (auto& stat : stats) print_info(stat);
}

// subdivision
if (params.subdivisions > 0) {
shape = subdivide_shape(shape, params.subdivisions, params.catmullclark);
}

// transform
if (params.translate != vec3f{0, 0, 0} || params.rotate != vec3f{0, 0, 0} ||
params.scale != vec3f{1, 1, 1} || params.scaleu != 1) {
params.scale != vec3f{1, 1, 1}) {
auto translation = translation_frame(params.translate);
auto scaling = scaling_frame(params.scale * params.scaleu);
auto scaling = scaling_frame(params.scale);
auto rotation = rotation_frame({1, 0, 0}, radians(params.rotate.x)) *
rotation_frame({0, 0, 1}, radians(params.rotate.z)) *
rotation_frame({0, 1, 0}, radians(params.rotate.y));
Expand Down Expand Up @@ -169,16 +171,17 @@ void run_convert(const convert_params& params) {

// fvconvert params
struct fvconvert_params {
string shape = "shape.obj";
string output = "out.obj";
bool info = false;
bool smooth = false;
bool facet = false;
bool aspositions = false;
vec3f translate = {0, 0, 0};
vec3f rotate = {0, 0, 0};
vec3f scale = {1, 1, 1};
float scaleu = 1;
string shape = "shape.obj";
string output = "out.obj";
bool info = false;
bool smooth = false;
bool facet = false;
bool aspositions = false;
vec3f translate = {0, 0, 0};
vec3f rotate = {0, 0, 0};
vec3f scale = {1, 1, 1};
int subdivisions = 0;
bool catmullclark = false;
};

void add_options(const cli_command& cli, fvconvert_params& params) {
Expand All @@ -188,16 +191,12 @@ void add_options(const cli_command& cli, fvconvert_params& params) {
add_option(cli, "facet", params.facet, "Facet normals.");
add_option(
cli, "aspositions", params.aspositions, "Remove all but positions.");
add_option(cli, "translatex", params.translate.x, "Translate shape.");
add_option(cli, "translatey", params.translate.y, "Translate shape.");
add_option(cli, "translatez", params.translate.z, "Translate shape.");
add_option(cli, "scalex", params.scale.x, "Scale shape.");
add_option(cli, "scaley", params.scale.y, "Scale shape.");
add_option(cli, "scalez", params.scale.z, "Scale shape.");
add_option(cli, "scaleu", params.scaleu, "Scale shape.");
add_option(cli, "rotatex", params.rotate.x, "Rotate shape.");
add_option(cli, "rotatey", params.rotate.y, "Rotate shape.");
add_option(cli, "rotatez", params.rotate.z, "Rotate shape.");
add_option(cli, "translate", params.translate, "Translate shape.");
add_option(cli, "scale", params.scale, "Scale shape.");
add_option(cli, "rotate", params.rotate, "Rotate shape.");
add_option(cli, "subdivisions", params.subdivisions, "Apply subdivision.");
add_option(
cli, "catmullclark", params.catmullclark, "Catmull-Clark subdivision.");
}

// convert images
Expand All @@ -220,11 +219,16 @@ void run_fvconvert(const fvconvert_params& params) {
for (auto& stat : stats) print_info(stat);
}

// subdivision
if (params.subdivisions > 0) {
shape = subdivide_fvshape(shape, params.subdivisions, params.catmullclark);
}

// transform
if (params.translate != vec3f{0, 0, 0} || params.rotate != vec3f{0, 0, 0} ||
params.scale != vec3f{1, 1, 1} || params.scaleu != 1) {
params.scale != vec3f{1, 1, 1}) {
auto translation = translation_frame(params.translate);
auto scaling = scaling_frame(params.scale * params.scaleu);
auto scaling = scaling_frame(params.scale);
auto rotation = rotation_frame({1, 0, 0}, radians(params.rotate.x)) *
rotation_frame({0, 0, 1}, radians(params.rotate.z)) *
rotation_frame({0, 1, 0}, radians(params.rotate.y));
Expand Down Expand Up @@ -304,7 +308,6 @@ struct heightfield_params {
vec3f translate = {0, 0, 0};
vec3f rotate = {0, 0, 0};
vec3f scale = {1, 1, 1};
float scaleu = 1;
};

void add_options(const cli_command& cli, heightfield_params& params) {
Expand All @@ -313,16 +316,9 @@ void add_options(const cli_command& cli, heightfield_params& params) {
add_option(cli, "smooth", params.smooth, "Smoooth normals.");
add_option(cli, "height", params.height, "Shape height.");
add_option(cli, "info", params.info, "Print info.");
add_option(cli, "translatex", params.translate.x, "Translate shape.");
add_option(cli, "translatey", params.translate.y, "Translate shape.");
add_option(cli, "translatez", params.translate.z, "Translate shape.");
add_option(cli, "scalex", params.scale.x, "Scale shape.");
add_option(cli, "scaley", params.scale.y, "Scale shape.");
add_option(cli, "scalez", params.scale.z, "Scale shape.");
add_option(cli, "scaleu", params.scaleu, "Scale shape.");
add_option(cli, "rotatex", params.rotate.x, "Rotate shape.");
add_option(cli, "rotatey", params.rotate.y, "Rotate shape.");
add_option(cli, "rotatez", params.rotate.z, "Rotate shape.");
add_option(cli, "translate", params.translate, "Translate shape.");
add_option(cli, "scale", params.scale, "Scale shape.");
add_option(cli, "rotate", params.rotate, "Rotate shape.");
}

void run_heightfield(const heightfield_params& params) {
Expand Down Expand Up @@ -498,7 +494,7 @@ void run(const vector<string>& args) {
if (params.command == "convert") {
return run_convert(params.convert);
} else if (params.command == "fvconvert") {
return run_view(params.view);
return run_fvconvert(params.fvconvert);
} else if (params.command == "view") {
return run_view(params.view);
} else if (params.command == "heightfield") {
Expand Down
141 changes: 141 additions & 0 deletions libs/yocto/ext/tinyexr.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,11 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
const unsigned char *memory, size_t size,
const char **err);

// For Yocto/GL
extern int SaveEXRToMemory(const float *data, int width, int height, int components,
const int save_as_fp16, unsigned char **memory_out, size_t* size,
const char **err);

#ifdef __cplusplus
}
#endif
Expand Down Expand Up @@ -13789,6 +13794,142 @@ int SaveEXR(const float *data, int width, int height, int components,
return ret;
}

int SaveEXRToMemory(const float *data, int width, int height, int components,
const int save_as_fp16, unsigned char **memory_out, size_t* size, const char **err) {
if ((components == 1) || components == 3 || components == 4) {
// OK
} else {
std::stringstream ss;
ss << "Unsupported component value : " << components << std::endl;

tinyexr::SetErrorMessage(ss.str(), err);
return TINYEXR_ERROR_INVALID_ARGUMENT;
}

EXRHeader header;
InitEXRHeader(&header);

if ((width < 16) && (height < 16)) {
// No compression for small image.
header.compression_type = TINYEXR_COMPRESSIONTYPE_NONE;
} else {
header.compression_type = TINYEXR_COMPRESSIONTYPE_ZIP;
}

EXRImage image;
InitEXRImage(&image);

image.num_channels = components;

std::vector<float> images[4];

if (components == 1) {
images[0].resize(static_cast<size_t>(width * height));
memcpy(images[0].data(), data, sizeof(float) * size_t(width * height));
} else {
images[0].resize(static_cast<size_t>(width * height));
images[1].resize(static_cast<size_t>(width * height));
images[2].resize(static_cast<size_t>(width * height));
images[3].resize(static_cast<size_t>(width * height));

// Split RGB(A)RGB(A)RGB(A)... into R, G and B(and A) layers
for (size_t i = 0; i < static_cast<size_t>(width * height); i++) {
images[0][i] = data[static_cast<size_t>(components) * i + 0];
images[1][i] = data[static_cast<size_t>(components) * i + 1];
images[2][i] = data[static_cast<size_t>(components) * i + 2];
if (components == 4) {
images[3][i] = data[static_cast<size_t>(components) * i + 3];
}
}
}

float *image_ptr[4] = {0, 0, 0, 0};
if (components == 4) {
image_ptr[0] = &(images[3].at(0)); // A
image_ptr[1] = &(images[2].at(0)); // B
image_ptr[2] = &(images[1].at(0)); // G
image_ptr[3] = &(images[0].at(0)); // R
} else if (components == 3) {
image_ptr[0] = &(images[2].at(0)); // B
image_ptr[1] = &(images[1].at(0)); // G
image_ptr[2] = &(images[0].at(0)); // R
} else if (components == 1) {
image_ptr[0] = &(images[0].at(0)); // A
}

image.images = reinterpret_cast<unsigned char **>(image_ptr);
image.width = width;
image.height = height;

header.num_channels = components;
header.channels = static_cast<EXRChannelInfo *>(malloc(
sizeof(EXRChannelInfo) * static_cast<size_t>(header.num_channels)));
// Must be (A)BGR order, since most of EXR viewers expect this channel order.
if (components == 4) {
#ifdef _MSC_VER
strncpy_s(header.channels[0].name, "A", 255);
strncpy_s(header.channels[1].name, "B", 255);
strncpy_s(header.channels[2].name, "G", 255);
strncpy_s(header.channels[3].name, "R", 255);
#else
strncpy(header.channels[0].name, "A", 255);
strncpy(header.channels[1].name, "B", 255);
strncpy(header.channels[2].name, "G", 255);
strncpy(header.channels[3].name, "R", 255);
#endif
header.channels[0].name[strlen("A")] = '\0';
header.channels[1].name[strlen("B")] = '\0';
header.channels[2].name[strlen("G")] = '\0';
header.channels[3].name[strlen("R")] = '\0';
} else if (components == 3) {
#ifdef _MSC_VER
strncpy_s(header.channels[0].name, "B", 255);
strncpy_s(header.channels[1].name, "G", 255);
strncpy_s(header.channels[2].name, "R", 255);
#else
strncpy(header.channels[0].name, "B", 255);
strncpy(header.channels[1].name, "G", 255);
strncpy(header.channels[2].name, "R", 255);
#endif
header.channels[0].name[strlen("B")] = '\0';
header.channels[1].name[strlen("G")] = '\0';
header.channels[2].name[strlen("R")] = '\0';
} else {
#ifdef _MSC_VER
strncpy_s(header.channels[0].name, "A", 255);
#else
strncpy(header.channels[0].name, "A", 255);
#endif
header.channels[0].name[strlen("A")] = '\0';
}

header.pixel_types = static_cast<int *>(
malloc(sizeof(int) * static_cast<size_t>(header.num_channels)));
header.requested_pixel_types = static_cast<int *>(
malloc(sizeof(int) * static_cast<size_t>(header.num_channels)));
for (int i = 0; i < header.num_channels; i++) {
header.pixel_types[i] =
TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image

if (save_as_fp16 > 0) {
header.requested_pixel_types[i] =
TINYEXR_PIXELTYPE_HALF; // save with half(fp16) pixel format
} else {
header.requested_pixel_types[i] =
TINYEXR_PIXELTYPE_FLOAT; // save with float(fp32) pixel format(i.e.
// no precision reduction)
}
}

*size = SaveEXRImageToMemory(&image, &header, memory_out, err);

free(header.channels);
free(header.pixel_types);
free(header.requested_pixel_types);

return TINYEXR_SUCCESS;
}

#ifdef __clang__
// zero-as-null-ppinter-constant
#pragma clang diagnostic pop
Expand Down
Loading