diff --git a/Makefile b/Makefile index 4481ea5..4d801a2 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,18 @@ CXX := g++ CXXFLAGS := -O2 -TARGET := WFObj.o -SOURCE := WFObj.cc -LIBS := -lGL +SOURCE := WFObj.cc WFMtl.cc driver.cc +OBJS := $(SOURCE:.cc=.o) +LDFLAGS := -lGL +TARGET := driver -all: $(TARGET) driver +all: $(TARGET) -$(TARGET): $(SOURCE) $(SOURCE:.cc=.hh) - $(CXX) -c -o $@ $< $(CXXFLAGS) +$(TARGET): $(OBJS) + $(CXX) -o $@ $^ $(LDFLAGS) -driver: driver.cc $(TARGET) - $(CXX) -o $@ $< $(TARGET) $(CXXFLAGS) $(LIBS) +%.o: %.cc + $(CXX) -c -o $@ $^ $(CXXFLAGS) clean: - -rm -f *~ *.o + -rm -f *~ *.o $(TARGET) diff --git a/WFMtl.cc b/WFMtl.cc new file mode 100644 index 0000000..2c03d7a --- /dev/null +++ b/WFMtl.cc @@ -0,0 +1,134 @@ + +#include +#include +#include +#include // isspace() +#include // strlen() +#include +#include +#include +#include +#include +#include +#include "WFMtl.hh" +using namespace std; + +#define WHITESPACE " \n\r\t\v" +#define DEBUGGL + +void WFMtl::clear() +{ + m_data = map< string, vector< vector > >(); + m_currentMaterialName = ""; +} + +int WFMtl::filesize(const char * filename) +{ + struct stat st; + if (stat(filename, &st)) + return -1; + return st.st_size; +} + +bool WFMtl::load(const string & filename) +{ + clear(); + + int size = filesize(filename.c_str()); + if (size < 1) + return false; + + ifstream ifs(filename.c_str()); + if (!ifs.is_open()) + return false; + char buf[size+1]; + + string buildup; + while (ifs.good()) + { + ifs.getline(buf, size+1); + string input = trim(buf); + int sz = input.size(); + if (sz == 0 || input[0] == '#') + continue; + if (input[sz-1] == '\\') + { + input[sz-1] = ' '; + buildup = input; + continue; + } + if (buildup != "") + input = buildup + input; + buildup = ""; + processInputLine(input); + } + + /* DEBUG */ + map > >::iterator it = m_data.begin(); + while (it != m_data.end()) + { + cout << "Material '" << it->first << "':" << endl; + for (int i = 0; i < it->second.size(); i++) + { + cout << " "; + for (int j = 0; j < it->second[i].size(); j++) + { + cout << '\'' << it->second[i][j] << "' "; + } + cout << endl; + } + } + /* END DEBUG */ + + ifs.close(); + return true; +} + +string WFMtl::trim(string s) +{ + size_t lastpos = s.find_last_not_of(WHITESPACE); + if (lastpos == string::npos) + return ""; + s.erase(lastpos + 1); + s.erase(0, s.find_first_not_of(WHITESPACE)); + return s; +} + +void WFMtl::processInputLine(const std::string & input) +{ + string line = input; + vector lineParts; + for (;;) + { + string token = stripFirstToken(line); + if (token == "") + break; + lineParts.push_back(token); + } + if (lineParts.size() > 0) + { + if ( (lineParts.size() >= 2) && (lineParts[0] == "newmtl") ) + { + m_currentMaterialName = lineParts[1]; + } + else if (m_currentMaterialName != "") + { + m_data[m_currentMaterialName].push_back(lineParts); + } + } +} + +string WFMtl::stripFirstToken(string & input) +{ + size_t firstnonspace = input.find_first_not_of(WHITESPACE); + if (firstnonspace == string::npos) + return ""; + size_t spaceafter = input.find_first_of(WHITESPACE, firstnonspace); + string token = input.substr(firstnonspace, spaceafter - firstnonspace); + input.erase(0, spaceafter); + return token; +} + +void WFMtl::render() +{ +} diff --git a/WFMtl.hh b/WFMtl.hh new file mode 100644 index 0000000..41b2c32 --- /dev/null +++ b/WFMtl.hh @@ -0,0 +1,24 @@ + +#include +#include +#include +#include + +class WFMtl +{ +public: + bool load(const std::string & filename); + void render(); + +private: + /* methods */ + void clear(); + std::string trim(std::string s); + int filesize(const char * filename); + void processInputLine(const std::string & input); + std::string stripFirstToken(std::string & input); + + /* variables */ + std::map< std::string, std::vector< std::vector > > m_data; + string m_currentMaterialName; +}; diff --git a/WFObj.cc b/WFObj.cc index 7ef037a..744066b 100644 --- a/WFObj.cc +++ b/WFObj.cc @@ -15,6 +15,11 @@ using namespace std; #define WHITESPACE " \n\r\t\v" #define DEBUGGL +void WFObj::clear() +{ + m_data = std::vector< std::vector >(); +} + int WFObj::filesize(const char * filename) { struct stat st; @@ -25,6 +30,8 @@ int WFObj::filesize(const char * filename) bool WFObj::load(const string & filename) { + clear(); + int size = filesize(filename.c_str()); if (size < 1) return false; @@ -241,7 +248,7 @@ WFObj::Vertex WFObj::readVertex(const vector & parts) { int partslen = parts.size(); Vertex v; - for (int i = 1; i < partslen; i++) + for (int i = 1; i < partslen && i <= 4; i++) { sscanf(parts[i].c_str(), "%f", &v[i - 1]); } diff --git a/WFObj.hh b/WFObj.hh index 55d53da..e2cad68 100644 --- a/WFObj.hh +++ b/WFObj.hh @@ -22,6 +22,7 @@ private: }; /* methods */ + void clear(); std::string trim(std::string s); int filesize(const char * filename); void processInputLine(const std::string & input);