/* * © Copyright 2014 – Urheberrechtshinweis * Alle Rechte vorbehalten / All Rights Reserved * * Programmcode ist urheberrechtlich geschuetzt. * Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner. * Keine Verwendung ohne explizite Genehmigung. * (vgl. § 106 ff UrhG / § 97 UrhG) */ #ifndef FLOORPLAN_3D_OBJPOOL_H #define FLOORPLAN_3D_OBJPOOL_H #include #include "../../../geo/Triangle3.h" #include #include "OBJReader.h" #include "../Obstacle3.h" // LINUX ONLY //#include //#include #include "../../../data/File.h" #include "../../../misc/Debug.h" namespace Floorplan3D { /** * load several named 3D models for quick re-use */ class OBJPool { private: static constexpr const char* name = "OBJ-Pool"; /** singleton */ OBJPool() {;} bool initDone = false; std::unordered_map cache; public: /** singleton access */ static OBJPool& get() { static OBJPool instance; return instance; } /** init with *.obj data folder */ void init(const std::string& folder) { scanFolder(folder); initDone = true; } /** init with multiple *.obj data folder */ void init(const std::initializer_list& folders) { for (const std::string& folder : folders) { try { scanFolder(folder); } catch (...) {;} } initDone = true; } /** 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: /** scan the given folder for all *.obj files */ void scanFolder(const std::string& folder) { FS::File d(folder); if (!d.exists()) { throw Exception("OBJPool: folder not found: " + folder); } for (const FS::File& f : d.listFiles()) { std::string name = f.getFilename(); if (endsWith(name, ".obj")) { //std::string name = entry.path().filename().string(); name = name.substr(0, name.length() - 4); // without extension load(f.getPath(), name); } } } 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); } } Log::add(this->name, "loaded: " + absName + " [" + std::to_string(obs.triangles.size()) + " triangles]", true); // store cache[name] = obs; } }; } #endif // FLOORPLAN_3D_OBJPOOL_H