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/wifi/estimate/ray3/OBJPool.h

119 lines
2.7 KiB
C++

#ifndef OBJPOOL_H
#define 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 <experimental/filesystem>
namespace Ray3D {
/**
* load several named 3D models for quick re-use
*/
class OBJPool {
private:
/** singleton */
OBJPool() {;}
bool initDone = false;
std::unordered_map<std::string, Obstacle3D> 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().string();
if (endsWith(absFile, ".obj")) {
//std::string name = std::string(dir->d_name);
std::string name = entry.path().filename().string();
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