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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/quadriflow/src/loader.cpp')
-rw-r--r--extern/quadriflow/src/loader.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/extern/quadriflow/src/loader.cpp b/extern/quadriflow/src/loader.cpp
new file mode 100644
index 00000000000..aa27066e6e4
--- /dev/null
+++ b/extern/quadriflow/src/loader.cpp
@@ -0,0 +1,159 @@
+//
+// loader.cpp
+// Loop
+//
+// Created by Jingwei on 10/22/17.
+// Copyright © 2017 Jingwei. All rights reserved.
+//
+
+#include "loader.hpp"
+
+#include <fstream>
+#include <unordered_map>
+
+namespace qflow {
+
+inline std::vector<std::string> &str_tokenize(const std::string &s, char delim, std::vector<std::string> &elems, bool include_empty = false) {
+ std::stringstream ss(s);
+ std::string item;
+ while (std::getline(ss, item, delim))
+ if (!item.empty() || include_empty)
+ elems.push_back(item);
+ return elems;
+}
+
+inline std::vector<std::string> str_tokenize(const std::string &s, char delim, bool include_empty) {
+ std::vector<std::string> elems;
+ str_tokenize(s, delim, elems, include_empty);
+ return elems;
+}
+
+inline uint32_t str_to_uint32_t(const std::string &str) {
+ char *end_ptr = nullptr;
+ uint32_t result = (uint32_t)strtoul(str.c_str(), &end_ptr, 10);
+ if (*end_ptr != '\0')
+ throw std::runtime_error("Could not parse unsigned integer \"" + str + "\"");
+ return result;
+}
+
+void load(const char* filename, MatrixXd& V, MatrixXi& F)
+{
+ /// Vertex indices used by the OBJ format
+ struct obj_vertex {
+ uint32_t p = (uint32_t)-1;
+ uint32_t n = (uint32_t)-1;
+ uint32_t uv = (uint32_t)-1;
+
+ inline obj_vertex() { }
+
+ inline obj_vertex(const std::string &string) {
+ std::vector<std::string> tokens = str_tokenize(string, '/', true);
+
+ if (tokens.size() < 1 || tokens.size() > 3)
+ throw std::runtime_error("Invalid vertex data: \"" + string + "\"");
+
+ p = str_to_uint32_t(tokens[0]);
+
+#if 0
+ if (tokens.size() >= 2 && !tokens[1].empty())
+ uv = str_to_uint32_t(tokens[1]);
+
+ if (tokens.size() >= 3 && !tokens[2].empty())
+ n = str_to_uint32_t(tokens[2]);
+#endif
+ }
+
+ inline bool operator==(const obj_vertex &v) const {
+ return v.p == p && v.n == n && v.uv == uv;
+ }
+ };
+
+ /// Hash function for obj_vertex
+ struct obj_vertexHash : std::unary_function<obj_vertex, size_t> {
+ std::size_t operator()(const obj_vertex &v) const {
+ size_t hash = std::hash<uint32_t>()(v.p);
+ hash = hash * 37 + std::hash<uint32_t>()(v.uv);
+ hash = hash * 37 + std::hash<uint32_t>()(v.n);
+ return hash;
+ }
+ };
+
+ typedef std::unordered_map<obj_vertex, uint32_t, obj_vertexHash> VertexMap;
+
+ std::ifstream is(filename);
+
+ std::vector<Vector3d> positions;
+ //std::vector<Vector2d> texcoords;
+ //std::vector<Vector3d> normals;
+ std::vector<uint32_t> indices;
+ std::vector<obj_vertex> vertices;
+ VertexMap vertexMap;
+
+ std::string line_str;
+ while (std::getline(is, line_str)) {
+ std::istringstream line(line_str);
+
+ std::string prefix;
+ line >> prefix;
+
+ if (prefix == "v") {
+ Vector3d p;
+ line >> p.x() >> p.y() >> p.z();
+ positions.push_back(p);
+ }
+ else if (prefix == "vt") {
+ /*
+ Vector2d tc;
+ line >> tc.x() >> tc.y();
+ texcoords.push_back(tc);
+ */
+ }
+ else if (prefix == "vn") {
+ /*
+ Vector3d n;
+ line >> n.x() >> n.y() >> n.z();
+ normals.push_back(n);
+ */
+ }
+ else if (prefix == "f") {
+ std::string v1, v2, v3, v4;
+ line >> v1 >> v2 >> v3 >> v4;
+ obj_vertex tri[6];
+ int nVertices = 3;
+
+ tri[0] = obj_vertex(v1);
+ tri[1] = obj_vertex(v2);
+ tri[2] = obj_vertex(v3);
+
+ if (!v4.empty()) {
+ /* This is a quad, split into two triangles */
+ tri[3] = obj_vertex(v4);
+ tri[4] = tri[0];
+ tri[5] = tri[2];
+ nVertices = 6;
+ }
+ /* Convert to an indexed vertex list */
+ for (int i = 0; i<nVertices; ++i) {
+ const obj_vertex &v = tri[i];
+ VertexMap::const_iterator it = vertexMap.find(v);
+ if (it == vertexMap.end()) {
+ vertexMap[v] = (uint32_t)vertices.size();
+ indices.push_back((uint32_t)vertices.size());
+ vertices.push_back(v);
+ }
+ else {
+ indices.push_back(it->second);
+ }
+ }
+ }
+ }
+
+ F.resize(3, indices.size() / 3);
+ memcpy(F.data(), indices.data(), sizeof(uint32_t)*indices.size());
+
+ V.resize(3, vertices.size());
+ for (uint32_t i = 0; i<vertices.size(); ++i)
+ V.col(i) = positions.at(vertices[i].p - 1);
+}
+
+} // namespace qflow