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/MTLReader.h
k-a-z-u ae3b95cb0e added sanity check to csv
refactoring for wifi models
adjusted obj/mtl parsing
2018-06-26 11:58:36 +02:00

131 lines
3.0 KiB
C++

#ifndef MTLREADER_H
#define MTLREADER_H
#include <vector>
#include <unordered_map>
#include <string>
#include <fstream>
#include "../../../geo/Point2.h"
#include "../../../geo/Point3.h"
/**
* prase .mtl files
*/
class MTLReader {
public:
struct Material {
std::string textureFile = "";
Point3 diffuse = Point3(1,1,1);
float alpha = 1.0;
};
Material* cur = nullptr;
std::unordered_map<std::string, Material> map;
/** ctor. use readXYZ() */
MTLReader() {
;
}
/** read .obj from the given file */
void readFile(const std::string& file) {
std::ifstream is(file);
std::string line;
while(getline(is, line)) {parseLine(line);}
is.close();
}
/** read obj from the given data string (.obj file contents) */
void readData(const std::string& data) {
std::stringstream is(data);
std::string line;
while(getline(is, line)) {parseLine(line);}
}
/** get the given material */
const Material& getMaterial(const std::string& mat) const {
const auto& it = map.find(mat);
if (it == map.end()) {throw Exception("material not available");}
return it->second;
}
private:
template<typename Out>
void split(const std::string &s, char delim, Out result) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
*(result++) = item;
}
}
void replaceAll(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
size_t end_pos = start_pos + from.length();
str.replace(start_pos, end_pos, to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
}
/** remove empty strings from the vector */
std::vector<std::string> nonEmpty(const std::vector<std::string>& src) {
std::vector<std::string> res;
for (const std::string& s : src) {
if (!s.empty()) {res.push_back(s);}
}
return res;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, std::back_inserter(elems));
return elems;
}
/** parse one line of the .obj file */
void parseLine(std::string line) {
if (line.length() < 2) {return;}
// remove leading "#"
while (line[0] == ' ' || line[0] == '\t') {
line.erase(line.begin());
}
// remove other linebreaks
replaceAll(line, "\r", "");
const std::vector<std::string> tokens = nonEmpty(split(line, ' '));
const std::string token = tokens.front();
if ("newmtl" == token) {
const std::string id = tokens[1];
map[id] = Material();
cur = &map[id];
} else if ("map_Ka" == token) {
const std::string texFile = tokens[1];
cur->textureFile = texFile;
} else if ("map_Kd" == token) {
const std::string texFile = tokens[1];
cur->textureFile = texFile;
} else if ("Kd" == token) {
cur->diffuse.x = std::stof(tokens[1]);
cur->diffuse.y = std::stof(tokens[2]);
cur->diffuse.z = std::stof(tokens[3]);
} else if ("d" == token) {
cur->alpha = std::stof(tokens[1]);
}
}
};
#endif // MTLREADER_H