Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2018-09-19 12:02:24 +0300
committerbubnikv <bubnikv@gmail.com>2018-09-19 12:02:24 +0300
commit0558b53493a77bae44831cf87bb0f59359828ef5 (patch)
treec3e8dbdf7d91a051c12d9ebbf7606d41047fea96 /src/libslic3r/Format/OBJ.cpp
parent3ddaccb6410478ad02d8c0e02d6d8e6eb1785b9f (diff)
WIP: Moved sources int src/, separated most of the source code from Perl.
The XS was left only for the unit / integration tests, and it links libslic3r only. No wxWidgets are allowed to be used from Perl starting from now.
Diffstat (limited to 'src/libslic3r/Format/OBJ.cpp')
-rw-r--r--src/libslic3r/Format/OBJ.cpp118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/libslic3r/Format/OBJ.cpp b/src/libslic3r/Format/OBJ.cpp
new file mode 100644
index 000000000..ee5756083
--- /dev/null
+++ b/src/libslic3r/Format/OBJ.cpp
@@ -0,0 +1,118 @@
+#include "../libslic3r.h"
+#include "../Model.hpp"
+#include "../TriangleMesh.hpp"
+
+#include "OBJ.hpp"
+#include "objparser.hpp"
+
+#include <string>
+
+#ifdef _WIN32
+#define DIR_SEPARATOR '\\'
+#else
+#define DIR_SEPARATOR '/'
+#endif
+
+namespace Slic3r {
+
+bool load_obj(const char *path, Model *model, const char *object_name_in)
+{
+ // Parse the OBJ file.
+ ObjParser::ObjData data;
+ if (! ObjParser::objparse(path, data)) {
+// die "Failed to parse $file\n" if !-e $path;
+ return false;
+ }
+
+ // Count the faces and verify, that all faces are triangular.
+ size_t num_faces = 0;
+ size_t num_quads = 0;
+ for (size_t i = 0; i < data.vertices.size(); ) {
+ size_t j = i;
+ for (; j < data.vertices.size() && data.vertices[j].coordIdx != -1; ++ j) ;
+ if (i == j)
+ continue;
+ size_t face_vertices = j - i;
+ if (face_vertices != 3 && face_vertices != 4) {
+ // Non-triangular and non-quad faces are not supported as of now.
+ return false;
+ }
+ if (face_vertices == 4)
+ ++ num_quads;
+ ++ num_faces;
+ i = j + 1;
+ }
+
+ // Convert ObjData into STL.
+ TriangleMesh mesh;
+ stl_file &stl = mesh.stl;
+ stl.stats.type = inmemory;
+ stl.stats.number_of_facets = int(num_faces + num_quads);
+ stl.stats.original_num_facets = int(num_faces + num_quads);
+ // stl_allocate clears all the allocated data to zero, all normals are set to zeros as well.
+ stl_allocate(&stl);
+ size_t i_face = 0;
+ for (size_t i = 0; i < data.vertices.size(); ++ i) {
+ if (data.vertices[i].coordIdx == -1)
+ continue;
+ stl_facet &facet = stl.facet_start[i_face ++];
+ size_t num_normals = 0;
+ stl_normal normal(stl_normal::Zero());
+ for (unsigned int v = 0; v < 3; ++ v) {
+ const ObjParser::ObjVertex &vertex = data.vertices[i++];
+ memcpy(facet.vertex[v].data(), &data.coordinates[vertex.coordIdx*4], 3 * sizeof(float));
+ if (vertex.normalIdx != -1) {
+ normal(0) += data.normals[vertex.normalIdx*3];
+ normal(1) += data.normals[vertex.normalIdx*3+1];
+ normal(2) += data.normals[vertex.normalIdx*3+2];
+ ++ num_normals;
+ }
+ }
+ if (data.vertices[i].coordIdx != -1) {
+ // This is a quad. Produce the other triangle.
+ stl_facet &facet2 = stl.facet_start[i_face++];
+ facet2.vertex[0] = facet.vertex[0];
+ facet2.vertex[1] = facet.vertex[2];
+ const ObjParser::ObjVertex &vertex = data.vertices[i++];
+ memcpy(facet2.vertex[2].data(), &data.coordinates[vertex.coordIdx * 4], 3 * sizeof(float));
+ if (vertex.normalIdx != -1) {
+ normal(0) += data.normals[vertex.normalIdx*3];
+ normal(1) += data.normals[vertex.normalIdx*3+1];
+ normal(2) += data.normals[vertex.normalIdx*3+2];
+ ++ num_normals;
+ }
+ if (num_normals == 4) {
+ // Normalize an average normal of a quad.
+ float len = facet.normal.norm();
+ if (len > EPSILON) {
+ normal /= len;
+ facet.normal = normal;
+ facet2.normal = normal;
+ }
+ }
+ } else if (num_normals == 3) {
+ // Normalize an average normal of a triangle.
+ float len = facet.normal.norm();
+ if (len > EPSILON)
+ facet.normal = normal / len;
+ }
+ }
+ stl_get_size(&stl);
+ mesh.repair();
+ if (mesh.facets_count() == 0) {
+ // die "This STL file couldn't be read because it's empty.\n"
+ return false;
+ }
+
+ std::string object_name;
+ if (object_name_in == nullptr) {
+ const char *last_slash = strrchr(path, DIR_SEPARATOR);
+ object_name.assign((last_slash == nullptr) ? path : last_slash + 1);
+ } else
+ object_name.assign(object_name_in);
+
+ model->add_object(object_name.c_str(), path, std::move(mesh));
+ return true;
+}
+
+}; // namespace Slic3r