Code Modified to remove use of C++11 features.

Tested compilation with VS2012, clang++ 3.4 and g++.
This commit is contained in:
E J Burns
2014-04-29 13:15:22 +01:00
parent 08ff49d2d0
commit b89a46c417
3 changed files with 105 additions and 81 deletions

91
test.cc
View File

@@ -3,12 +3,9 @@
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cassert> #include <cassert>
#include <cstddef>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <functional>
#include <memory>
static void PrintInfo(const std::vector<tinyobj::shape_t>& shapes) static void PrintInfo(const std::vector<tinyobj::shape_t>& shapes)
{ {
@@ -45,8 +42,8 @@ static void PrintInfo(const std::vector<tinyobj::shape_t>& shapes)
printf(" material.map_Kd = %s\n", shapes[i].material.diffuse_texname.c_str()); printf(" material.map_Kd = %s\n", shapes[i].material.diffuse_texname.c_str());
printf(" material.map_Ks = %s\n", shapes[i].material.specular_texname.c_str()); printf(" material.map_Ks = %s\n", shapes[i].material.specular_texname.c_str());
printf(" material.map_Ns = %s\n", shapes[i].material.normal_texname.c_str()); printf(" material.map_Ns = %s\n", shapes[i].material.normal_texname.c_str());
auto it = shapes[i].material.unknown_parameter.begin(); std::map<std::string, std::string>::const_iterator it(shapes[i].material.unknown_parameter.begin());
auto itEnd = shapes[i].material.unknown_parameter.end(); std::map<std::string, std::string>::const_iterator itEnd(shapes[i].material.unknown_parameter.end());
for (; it != itEnd; it++) { for (; it != itEnd; it++) {
printf(" material.%s = %s\n", it->first.c_str(), it->second.c_str()); printf(" material.%s = %s\n", it->first.c_str(), it->second.c_str());
} }
@@ -113,48 +110,54 @@ TestStreamLoadObj()
"usemtl white\n" "usemtl white\n"
"f 2 6 7 3\n" "f 2 6 7 3\n"
"# 6 elements"; "# 6 elements";
auto getMatFileIStreamFunc =
[](const std::string& matId)
{
if (matId == "cube.mtl") {
std::unique_ptr<std::stringstream> matStream(
new std::stringstream(
"newmtl white\n"
"Ka 0 0 0\n"
"Kd 1 1 1\n"
"Ks 0 0 0\n"
"\n"
"newmtl red\n"
"Ka 0 0 0\n"
"Kd 1 0 0\n"
"Ks 0 0 0\n"
"\n"
"newmtl green\n"
"Ka 0 0 0\n"
"Kd 0 1 0\n"
"Ks 0 0 0\n"
"\n"
"newmtl blue\n"
"Ka 0 0 0\n"
"Kd 0 0 1\n"
"Ks 0 0 0\n"
"\n"
"newmtl light\n"
"Ka 20 20 20\n"
"Kd 1 1 1\n"
"Ks 0 0 0"));
return matStream; std::string matStream(
} "newmtl white\n"
"Ka 0 0 0\n"
"Kd 1 1 1\n"
"Ks 0 0 0\n"
"\n"
"newmtl red\n"
"Ka 0 0 0\n"
"Kd 1 0 0\n"
"Ks 0 0 0\n"
"\n"
"newmtl green\n"
"Ka 0 0 0\n"
"Kd 0 1 0\n"
"Ks 0 0 0\n"
"\n"
"newmtl blue\n"
"Ka 0 0 0\n"
"Kd 0 0 1\n"
"Ks 0 0 0\n"
"\n"
"newmtl light\n"
"Ka 20 20 20\n"
"Kd 1 1 1\n"
"Ks 0 0 0");
std::unique_ptr<std::stringstream> emptyUP( nullptr ); using namespace tinyobj;
return emptyUP; class MaterialStringStreamReader:
}; public MaterialReader
{
public:
MaterialStringStreamReader(const std::string& matSStream): m_matSStream(matSStream) {}
virtual ~MaterialStringStreamReader() {}
virtual std::string operator() (
const std::string& matId,
std::map<std::string, material_t>& matMap)
{
return LoadMtl(matMap, m_matSStream);
}
private:
std::stringstream m_matSStream;
};
MaterialStringStreamReader matSSReader(matStream);
std::vector<tinyobj::shape_t> shapes; std::vector<tinyobj::shape_t> shapes;
std::string err = tinyobj::LoadObj(shapes, objStream, getMatFileIStreamFunc); std::string err = tinyobj::LoadObj(shapes, objStream, matSSReader);
if (!err.empty()) { if (!err.empty()) {
std::cerr << err << std::endl; std::cerr << err << std::endl;

View File

@@ -478,6 +478,22 @@ std::string LoadMtl (
return err.str(); return err.str();
} }
std::string MaterialFileReader::operator() (
const std::string& matId,
std::map<std::string, material_t>& matMap)
{
std::string filepath;
if (!m_mtlBasePath.empty()) {
filepath = std::string(m_mtlBasePath) + matId;
} else {
filepath = matId;
}
std::ifstream matIStream(filepath.c_str());
return LoadMtl(matMap, matIStream);
}
std::string std::string
LoadObj( LoadObj(
std::vector<shape_t>& shapes, std::vector<shape_t>& shapes,
@@ -495,28 +511,19 @@ LoadObj(
return err.str(); return err.str();
} }
auto getMatFileIStreamFunc = std::string basePath;
[&](const std::string& matId) if (mtl_basepath) {
{ basePath = mtl_basepath;
std::string filepath; }
MaterialFileReader matFileReader( basePath );
if (mtl_basepath) {
filepath = std::string(mtl_basepath) + matId;
} else {
filepath = matId;
}
std::unique_ptr<std::ifstream> ifs( new std::ifstream(filepath.c_str()) );
return ifs;
};
return LoadObj(shapes, ifs, getMatFileIStreamFunc); return LoadObj(shapes, ifs, matFileReader);
} }
std::string LoadObj( std::string LoadObj(
std::vector<shape_t>& shapes, std::vector<shape_t>& shapes,
std::istream& inStream, std::istream& inStream,
GetMtlIStreamFn getMatFn) MaterialReader& readMatFn)
{ {
std::stringstream err; std::stringstream err;
@@ -633,19 +640,11 @@ std::string LoadObj(
char namebuf[4096]; char namebuf[4096];
token += 7; token += 7;
sscanf(token, "%s", namebuf); sscanf(token, "%s", namebuf);
if (!getMatFn) {
err << "Could not read material, no callable function target.";
return err.str();
}
std::unique_ptr<std::istream> matIStream = getMatFn(namebuf); std::string err_mtl = readMatFn(namebuf, material_map);
if (matIStream) { if (!err_mtl.empty()) {
std::string err_mtl = LoadMtl(material_map, *matIStream); faceGroup.clear(); // for safety
if (!err_mtl.empty()) { return err_mtl;
faceGroup.clear(); // for safety
return err_mtl;
}
} }
continue; continue;

View File

@@ -9,8 +9,6 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
#include <functional>
#include <memory>
namespace tinyobj { namespace tinyobj {
@@ -51,12 +49,30 @@ typedef struct
mesh_t mesh; mesh_t mesh;
} shape_t; } shape_t;
/// typedef for a function that returns a pointer to an istream for class MaterialReader
/// the material identified by the const std::string& {
typedef std::function< public:
std::unique_ptr<std::istream>( MaterialReader(){}
const std::string&) virtual ~MaterialReader(){}
> GetMtlIStreamFn;
virtual std::string operator() (
const std::string& matId,
std::map<std::string, material_t>& matMap) = 0;
};
class MaterialFileReader:
public MaterialReader
{
public:
MaterialFileReader(const std::string& mtl_basepath): m_mtlBasePath(mtl_basepath) {}
virtual ~MaterialFileReader() {}
virtual std::string operator() (
const std::string& matId,
std::map<std::string, material_t>& matMap);
private:
std::string m_mtlBasePath;
};
/// Loads .obj from a file. /// Loads .obj from a file.
/// 'shapes' will be filled with parsed shape data /// 'shapes' will be filled with parsed shape data
@@ -74,7 +90,13 @@ std::string LoadObj(
std::string LoadObj( std::string LoadObj(
std::vector<shape_t>& shapes, // [output] std::vector<shape_t>& shapes, // [output]
std::istream& inStream, std::istream& inStream,
GetMtlIStreamFn getMatFn); MaterialReader& readMatFn);
/// Loads materials into std::map
/// Returns an empty string if successful
std::string LoadMtl (
std::map<std::string, material_t>& material_map,
std::istream& inStream);
}; };
#endif // _TINY_OBJ_LOADER_H #endif // _TINY_OBJ_LOADER_H