This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Indoor/floorplan/3D/objects/OBJPool.h
2018-10-25 11:50:12 +02:00

146 lines
3.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* © 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 <vector>
#include "../../../geo/Triangle3.h"
#include <unordered_map>
#include "OBJReader.h"
#include "../Obstacle3.h"
// LINUX ONLY
//#include <dirent.h>
//#include <stdio.h>
#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<std::string, Obstacle3D> 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<std::string>& 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