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

Mesh loading of STL and triangles only #1113

Merged
merged 1 commit into from
Dec 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions apps/ymeshproc/ymeshproc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ using namespace yocto;

// Shape presets used ofr testing.
bool make_mesh_preset(vector<vec3i>& triangles, vector<vec3f>& positions,
vector<vec3f>& normals, vector<vec2f>& texcoords, vector<vec3f>& colors,
vector<vec3f>& normals, vector<vec2f>& texcoords, vector<vec4f>& colors,
const string& type, string& error) {
auto set_quads = [&](quads_shape&& shape) {
triangles = quads_to_triangles(shape.quads);
Expand Down Expand Up @@ -157,7 +157,7 @@ int main(int argc, const char* argv[]) {
auto positions = vector<vec3f>{};
auto normals = vector<vec3f>{};
auto texcoords = vector<vec2f>{};
auto colors = vector<vec3f>{};
auto colors = vector<vec4f>{};
auto triangles = vector<vec3i>{};
auto lines = vector<vec2i>{}; // for line output

Expand Down Expand Up @@ -231,10 +231,10 @@ int main(int argc, const char* argv[]) {
if (tags[i] == 1) triangles[i] = {-1, -1, -1};
}
} else {
colors = vector<vec3f>(positions.size());
colors = vector<vec4f>(positions.size());
for (int i = 0; i < colors.size(); ++i) {
auto c = sinf(geodesic_scale * field[i]);
colors[i] = vec3f{c, c, c};
colors[i] = vec4f{c, c, c, 1};
}
// distance_to_color(shape.colors, field, geodesic_scale);
}
Expand Down
2 changes: 1 addition & 1 deletion apps/ymeshtest/ymeshtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ int main(int argc, const char* argv[]) {
auto positions = vector<vec3f>{};
auto normals = vector<vec3f>{};
auto texcoords = vector<vec2f>{};
auto colors = vector<vec3f>{};
auto colors = vector<vec4f>{};
auto triangles = vector<vec3i>{};

// stats, progress
Expand Down
185 changes: 140 additions & 45 deletions libs/yocto/yocto_mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2633,10 +2633,21 @@ mesh_point eval_path_point(const geodesic_path& path,
// -----------------------------------------------------------------------------
namespace yocto {

// Convert quads to triangles
static vector<vec3i> quads_to_triangles(const vector<vec4i>& quads) {
auto triangles = vector<vec3i>{};
triangles.reserve(quads.size() * 2);
for (auto& q : quads) {
triangles.push_back({q.x, q.y, q.w});
if (q.z != q.w) triangles.push_back({q.z, q.w, q.y});
}
return triangles;
}

// Load ply mesh
bool load_mesh(const string& filename, vector<vec3i>& triangles,
vector<vec3f>& positions, vector<vec3f>& normals, vector<vec2f>& texcoords,
vector<vec3f>& colors, string& error, bool flip_texcoord) {
vector<vec4f>& colors, string& error, bool flip_texcoord) {
auto format_error = [filename, &error]() {
error = filename + ": unknown format";
return false;
Expand All @@ -2658,41 +2669,30 @@ bool load_mesh(const string& filename, vector<vec3i>& triangles,
auto ply_guard = std::make_unique<ply_model>();
auto ply = ply_guard.get();
if (!load_ply(filename, ply, error)) return false;

// gets vertex
get_positions(ply, positions);
get_normals(ply, normals);
get_texcoords(ply, texcoords, flip_texcoord);
get_colors(ply, colors);

// get faces
get_triangles(ply, triangles);

if (positions.empty()) return shape_error();
return true;
} else if (ext == ".obj" || ext == ".OBJ") {
// load obj
auto obj_guard = std::make_unique<obj_scene>();
auto obj = obj_guard.get();
if (!load_obj(filename, obj, error, true)) return false;

// get shape
if (obj->shapes.empty()) return shape_error();
if (obj->shapes.size() > 1) return shape_error();
auto shape = obj->shapes.front();
if (shape->points.empty() && shape->lines.empty() && shape->faces.empty())
return shape_error();

if (shape->faces.empty()) return shape_error();
// decide what to do and get properties
auto materials = vector<string>{};
auto ematerials = vector<int>{};
if (!shape->faces.empty()) {
get_triangles(shape, triangles, positions, normals, texcoords, materials,
ematerials, flip_texcoord);
} else {
return shape_error();
}

get_triangles(shape, triangles, positions, normals, texcoords, materials,
ematerials, flip_texcoord);
if (positions.empty()) return shape_error();
return true;
} else {
Expand All @@ -2703,7 +2703,7 @@ bool load_mesh(const string& filename, vector<vec3i>& triangles,
// Save ply mesh
bool save_mesh(const string& filename, const vector<vec3i>& triangles,
const vector<vec3f>& positions, const vector<vec3f>& normals,
const vector<vec2f>& texcoords, const vector<vec3f>& colors, string& error,
const vector<vec2f>& texcoords, const vector<vec4f>& colors, string& error,
bool ascii, bool flip_texcoord) {
auto format_error = [filename, &error]() {
error = filename + ": unknown format";
Expand All @@ -2730,15 +2730,126 @@ bool save_mesh(const string& filename, const vector<vec3i>& triangles,
auto obj_guard = std::make_unique<obj_scene>();
auto obj = obj_guard.get();
auto oshape = add_shape(obj);
if (!triangles.empty()) {
set_triangles(
oshape, triangles, positions, normals, texcoords, {}, flip_texcoord);
} else {
if (triangles.empty()) return shape_error();
set_triangles(
oshape, triangles, positions, normals, texcoords, {}, flip_texcoord);
if (!save_obj(filename, obj, error)) return false;
return true;
} else if (ext == ".stl" || ext == ".STL") {
auto stl_guard = std::make_unique<stl_model>();
auto stl = stl_guard.get();
if (triangles.empty()) return shape_error();
add_triangles(stl, triangles, positions, {});
if (!save_stl(filename, stl, error)) return false;
return true;
} else {
return format_error();
}
}

// Load ply mesh
bool load_mesh(const string& filename, vector<vec3i>& triangles,
vector<vec3f>& positions, string& error) {
auto format_error = [filename, &error]() {
error = filename + ": unknown format";
return false;
};
auto shape_error = [filename, &error]() {
error = filename + ": empty shape";
return false;
};

triangles = {};
positions = {};

auto ext = path_extension(filename);
if (ext == ".ply" || ext == ".PLY") {
// open ply
auto ply_guard = std::make_unique<ply_model>();
auto ply = ply_guard.get();
if (!load_ply(filename, ply, error)) return false;
get_positions(ply, positions);
get_triangles(ply, triangles);
if (positions.empty()) return shape_error();
return true;
} else if (ext == ".obj" || ext == ".OBJ") {
// load obj
auto obj_guard = std::make_unique<obj_scene>();
auto obj = obj_guard.get();
if (!load_obj(filename, obj, error, true)) return false;
// get shape
if (obj->shapes.empty()) return shape_error();
if (obj->shapes.size() > 1) return shape_error();
auto shape = obj->shapes.front();
if (shape->faces.empty()) return shape_error();
// decide what to do and get properties
auto materials = vector<string>{};
auto ematerials = vector<int>{};
auto quadspos = vector<vec4i>{};
auto quadsnorm = vector<vec4i>{};
auto quadstexcoord = vector<vec4i>{};
auto normals = vector<vec3f>{};
auto texcoords = vector<vec2f>{};
get_fvquads(shape, quadspos, quadsnorm, quadstexcoord, positions, normals,
texcoords, materials, ematerials);
triangles = quads_to_triangles(quadspos);
if (positions.empty()) return shape_error();
return true;
} else if (ext == ".stl" || ext == ".STL") {
// open ply
auto stl_guard = std::make_unique<stl_model>();
auto stl = stl_guard.get();
if (!load_stl(filename, stl, error)) return false;
if (stl->shapes.empty()) return shape_error();
if (stl->shapes.size() > 1) return shape_error();
auto fnormals = vector<vec3f>{};
if (!get_triangles(stl, 0, triangles, positions, fnormals))
return shape_error();
}
if (positions.empty()) return shape_error();
return true;
} else {
return format_error();
}
}

// Save ply mesh
bool save_mesh(const string& filename, const vector<vec3i>& triangles,
const vector<vec3f>& positions, string& error, bool ascii) {
auto format_error = [filename, &error]() {
error = filename + ": unknown format";
return false;
};
auto shape_error = [filename, &error]() {
error = filename + ": empty shape";
return false;
};

auto ext = path_extension(filename);
if (ext == ".ply" || ext == ".PLY") {
// create ply
auto ply_guard = std::make_unique<ply_model>();
auto ply = ply_guard.get();
if (triangles.empty()) return shape_error();
add_positions(ply, positions);
add_triangles(ply, triangles);
if (!save_ply(filename, ply, error)) return false;
return true;
} else if (ext == ".obj" || ext == ".OBJ") {
auto obj_guard = std::make_unique<obj_scene>();
auto obj = obj_guard.get();
auto oshape = add_shape(obj);
if (triangles.empty()) return shape_error();
set_triangles(oshape, triangles, positions, {}, {}, {});
auto err = ""s;
if (!save_obj(filename, obj, error)) return false;
return true;
} else if (ext == ".stl" || ext == ".STL") {
auto stl_guard = std::make_unique<stl_model>();
auto stl = stl_guard.get();
if (triangles.empty()) return shape_error();
add_triangles(stl, triangles, positions, {});
if (!save_stl(filename, stl, error)) return false;
return true;
} else {
return format_error();
}
Expand All @@ -2747,7 +2858,7 @@ bool save_mesh(const string& filename, const vector<vec3i>& triangles,
// Load ply mesh
bool load_lines(const string& filename, vector<vec2i>& lines,
vector<vec3f>& positions, vector<vec3f>& normals, vector<vec2f>& texcoords,
vector<vec3f>& colors, string& error, bool flip_texcoord) {
vector<vec4f>& colors, string& error, bool flip_texcoord) {
auto format_error = [filename, &error]() {
error = filename + ": unknown format";
return false;
Expand All @@ -2769,41 +2880,30 @@ bool load_lines(const string& filename, vector<vec2i>& lines,
auto ply_guard = std::make_unique<ply_model>();
auto ply = ply_guard.get();
if (!load_ply(filename, ply, error)) return false;

// gets vertex
get_positions(ply, positions);
get_normals(ply, normals);
get_texcoords(ply, texcoords, flip_texcoord);
get_colors(ply, colors);

// get faces
get_lines(ply, lines);

if (positions.empty()) return shape_error();
return true;
} else if (ext == ".obj" || ext == ".OBJ") {
// load obj
auto obj_guard = std::make_unique<obj_scene>();
auto obj = obj_guard.get();
if (!load_obj(filename, obj, error, true)) return false;

// get shape
if (obj->shapes.empty()) return shape_error();
if (obj->shapes.size() > 1) return shape_error();
auto shape = obj->shapes.front();
if (shape->points.empty() && shape->lines.empty() && shape->faces.empty())
return shape_error();

if (shape->lines.empty()) return shape_error();
// decide what to do and get properties
auto materials = vector<string>{};
auto ematerials = vector<int>{};
if (!shape->faces.empty()) {
get_lines(shape, lines, positions, normals, texcoords, materials,
ematerials, flip_texcoord);
} else {
return shape_error();
}

get_lines(shape, lines, positions, normals, texcoords, materials,
ematerials, flip_texcoord);
if (positions.empty()) return shape_error();
return true;
} else {
Expand All @@ -2814,7 +2914,7 @@ bool load_lines(const string& filename, vector<vec2i>& lines,
// Save ply mesh
bool save_lines(const string& filename, const vector<vec2i>& lines,
const vector<vec3f>& positions, const vector<vec3f>& normals,
const vector<vec2f>& texcoords, const vector<vec3f>& colors, string& error,
const vector<vec2f>& texcoords, const vector<vec4f>& colors, string& error,
bool ascii, bool flip_texcoord) {
auto format_error = [filename, &error]() {
error = filename + ": unknown format";
Expand All @@ -2841,13 +2941,8 @@ bool save_lines(const string& filename, const vector<vec2i>& lines,
auto obj_guard = std::make_unique<obj_scene>();
auto obj = obj_guard.get();
auto oshape = add_shape(obj);
if (!lines.empty()) {
set_lines(
oshape, lines, positions, normals, texcoords, {}, flip_texcoord);
} else {
return shape_error();
}
auto err = ""s;
if (lines.empty()) return shape_error();
set_lines(oshape, lines, positions, normals, texcoords, {}, flip_texcoord);
if (!save_obj(filename, obj, error)) return false;
return true;
} else {
Expand All @@ -2864,7 +2959,7 @@ namespace yocto {

vector<string> mesh_stats(const vector<vec3i>& triangles,
const vector<vec3f>& positions, const vector<vec3f>& normals,
const vector<vec2f>& texcoords, const vector<vec3f>& colors, bool verbose) {
const vector<vec2f>& texcoords, const vector<vec4f>& colors, bool verbose) {
auto format = [](auto num) {
auto str = std::to_string(num);
while (str.size() < 13) str = " " + str;
Expand Down
16 changes: 11 additions & 5 deletions libs/yocto/yocto_mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,21 +391,27 @@ namespace yocto {
// Load/save a shape as indexed meshes
bool load_mesh(const string& filename, vector<vec3i>& triangles,
vector<vec3f>& positions, vector<vec3f>& normals, vector<vec2f>& texcoords,
vector<vec3f>& colors, string& error, bool flip_texcoords = true);
vector<vec4f>& colors, string& error, bool flip_texcoords = true);
bool save_mesh(const string& filename, const vector<vec3i>& triangles,
const vector<vec3f>& positions, const vector<vec3f>& normals,
const vector<vec2f>& texcoords, const vector<vec3f>& colors, string& error,
const vector<vec2f>& texcoords, const vector<vec4f>& colors, string& error,
bool ascii = false, bool flip_texcoords = true);

// Load/save a set of lines
bool load_lines(const string& filename, vector<vec2i>& lines,
vector<vec3f>& positions, vector<vec3f>& normals, vector<vec2f>& texcoords,
vector<vec3f>& colors, string& error, bool flip_texcoords = true);
vector<vec4f>& colors, string& error, bool flip_texcoords = true);
bool save_lines(const string& filename, const vector<vec2i>& lines,
const vector<vec3f>& positions, const vector<vec3f>& normals,
const vector<vec2f>& texcoords, const vector<vec3f>& colors, string& error,
const vector<vec2f>& texcoords, const vector<vec4f>& colors, string& error,
bool ascii = false, bool flip_texcoords = true);

// Load/save a shape as indexed meshes
bool load_mesh(const string& filename, vector<vec3i>& triangles,
vector<vec3f>& positions, string& error);
bool save_mesh(const string& filename, const vector<vec3i>& triangles,
const vector<vec3f>& positions, string& error, bool ascii = false);

} // namespace yocto

// -----------------------------------------------------------------------------
Expand All @@ -416,7 +422,7 @@ namespace yocto {
// Get mesh statistics for printing
vector<string> mesh_stats(const vector<vec3i>& triangles,
const vector<vec3f>& positions, const vector<vec3f>& normals,
const vector<vec2f>& texcoords, const vector<vec3f>& colors,
const vector<vec2f>& texcoords, const vector<vec4f>& colors,
bool verbose = false);

} // namespace yocto
Expand Down