#ifndef OBJPOOL_H #define OBJPOOL_H #include #include "../../../geo/Triangle3.h" #include #include "OBJReader.h" #include "Obstacle3.h" // LINUX ONLY //#include //#include #include namespace Ray3D { /** * load several named 3D models for quick re-use */ class OBJPool { private: /** singleton */ OBJPool() {;} bool initDone = false; std::unordered_map cache; public: /** singleton access */ static OBJPool& get() { static OBJPool instance; return instance; } /** data folder */ void init(const std::string& folder) { initDone = true; // LINUX ONLY! //DIR* d = opendir(folder.c_str()); //if (!d) {throw Exception("OBJPool: folder not found: " + folder);} std::experimental::filesystem::path d(folder); if (!std::experimental::filesystem::exists(d)) { throw Exception("OBJPool: folder not found: " + folder); } //struct dirent *dir; //while ((dir = readdir(d)) != NULL) { for (std::experimental::filesystem::directory_entry entry : std::experimental::filesystem::directory_iterator(d)) { //const std::string absFile = folder + "/" + dir->d_name; const std::string absFile = entry.path().native(); if (endsWith(absFile, ".obj")) { //std::string name = std::string(dir->d_name); std::string name = entry.path().filename(); name = name.substr(0, name.length() - 4); // without extension load(absFile, name); } } //closedir(d); } /** get all triangles for the given object (if known) */ const Obstacle3D& getObject(const std::string& name) { // ensure the cache is initialized if (!initDone) { throw Exception("OBJPool: not initialized. call init(folder) first"); } static Obstacle3D empty; // find the entry const auto& it = cache.find(name); if (it == cache.end()) {return empty;} return it->second; } private: inline bool endsWith(std::string const & value, std::string const & ending) { if (ending.size() > value.size()) return false; return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); } /** load the given .obj file into the cache */ void load(const std::string& absName, const std::string& name) { OBJReader reader; reader.readFile(absName); //reader.readFile("/mnt/vm/paper/diss/code/IndoorMap/res/mdl/" + file + ".obj"); // todo // create triangles Obstacle3D obs; for (const OBJReader::Object& obj : reader.getData().objects) { for (const OBJReader::Face& face : obj.faces) { const Triangle3 tria(face.vnt[0].vertex, face.vnt[1].vertex, face.vnt[2].vertex); obs.triangles.push_back(tria); } } // store cache[name] = obs; } }; } #endif // OBJPOOL_H