From e4c4a3db73ff68ed55d9bd4d086d14d574cdafc8 Mon Sep 17 00:00:00 2001 From: Martin Schultz <Martin.Schultz@RWTH-Aachen.de> Date: Wed, 14 May 2014 20:06:42 +0200 Subject: [PATCH] * changed stream operations in objloader to be pointer operations --- .../OpenGL/Data/GeometryDataLoadStoreOBJ.cc | 102 ++++++++++-------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/src/ACGL/OpenGL/Data/GeometryDataLoadStoreOBJ.cc b/src/ACGL/OpenGL/Data/GeometryDataLoadStoreOBJ.cc index a6245400..889cc4ab 100644 --- a/src/ACGL/OpenGL/Data/GeometryDataLoadStoreOBJ.cc +++ b/src/ACGL/OpenGL/Data/GeometryDataLoadStoreOBJ.cc @@ -7,6 +7,7 @@ #include <ACGL/OpenGL/Data/GeometryDataLoadStore.hh> #include <ACGL/Math/Math.hh> #include <ACGL/Utils/StringHelpers.hh> +#include <ACGL/Utils/MemoryMappedFile.hh> #include <fstream> #include <string> @@ -31,50 +32,62 @@ namespace int normal; }; - void skipLine(std::fstream& _stream) - { - _stream.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); - } - // Parses a string of space-separated numbers into a packed floating-point vector (_data) with a maximum number of _maxDimension elements - void parseVector(const std::string& _string, int _maxDimension, int& _dimension, float* _data) + void parseVector(const char* _start , const char* _end, int _maxDimension, int& _dimension, float* _data) { - std::stringstream stream(_string); - float temp; + const char* it = _start; + if (*it == ' ') + { + it++; + } + const char* end = _end; + const char* found; _dimension = 0; - while(stream >> temp && _dimension < _maxDimension) + while (_dimension < _maxDimension && it < end) { - _data[_dimension] = temp; - _dimension++; + found = std::find(it, end, ' '); + _data[_dimension++] = std::atof(it); + it = found == end ? end : found + 1; } } // Turns an index parameter string into a std::vector of IndexTuples, e.g. // "1//2 3//4 5//6" --> { IndexTuple(1, -1, 2), IndexTuple(3, -1, 4), IndexTuple(5, -1, 6) } - std::vector<IndexTuple> parseIndices(const std::string& _string) + std::vector<IndexTuple> parseIndices(const char* _start, const char* _end) { std::vector<IndexTuple> indices; - std::stringstream stream(_string); + const char* it = _start; + if (*it == ' ') //skip starting whitespace + it++; + const char* vsit; + const char* vsend; + const char* foundSlash; std::string vertexString; - while(stream >> vertexString) + std::string component; + int componentIndex; + int index; + while (it < _end) { - std::vector<std::string> componentsString = ACGL::Utils::StringHelpers::split(vertexString, '/', false); + vsit = it; + vsend = std::find(it, _end, ' '); + componentIndex = 0; IndexTuple indexTuple; - - for(int i = 0; i < std::min<int>(componentsString.size(), 3); ++i) + indices.push_back(indexTuple); + //process the string now meaning we split by / + while (vsit < vsend) { - std::string& componentString = componentsString[i]; - int index = atoi(componentString.c_str()); - - if(i == 0) indexTuple.position = index-1; - if(i == 1) indexTuple.texCoord = index-1; - if(i == 2) indexTuple.normal = index-1; + foundSlash = std::find(vsit, vsend, '/'); + index = std::atoi(vsit); + if (componentIndex == 0) indices.back().position = index - 1; + if (componentIndex == 1) indices.back().texCoord = index - 1; + if (componentIndex == 2) indices.back().normal = index - 1; + componentIndex++; + vsit = foundSlash == vsend ? vsend : foundSlash + 1; } - - indices.push_back(indexTuple); + //indices.push_back(indexTuple); + it = vsend == _end ? _end : vsend + 1; } - return indices; } } @@ -89,13 +102,14 @@ namespace OpenGL{ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _computeNormals) { SharedGeometryData data; - - std::fstream file(_filename.c_str(), std::ios_base::in); - if(!file.good()) + MemoryMappedFile mmf(_filename.c_str()); + if(mmf.errorCode()) { error() << "could not open file " << _filename << std::endl; return data; } + const char* pchBuf = mmf.data(); + const char* pchEnd = pchBuf + mmf.length(); GLenum primitiveType = GL_INVALID_ENUM; bool hasTexCoords = false; @@ -111,27 +125,30 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c std::vector<IndexTuple> indices; std::string keyword; - std::string parameters; - while(file.good()) + const char* parameters[2]; + while (pchBuf < pchEnd) { // Parse the current line + const char* pchEOL = std::find(pchBuf, pchEnd, '\n'); // If the line starts with a #, it is a comment - if(file.peek() == '#') + if (*pchBuf == '#') { - skipLine(file); + pchBuf = pchEOL + 1; continue; } // Otherwise, extract the first word and the remainder - file >> keyword; - std::getline(file, parameters); + const char* pchKey = std::find(pchBuf, pchEnd, ' '); + keyword = std::string(pchBuf, pchKey); + parameters[0] = pchKey + 1; + parameters[1] = pchEOL; if(keyword == "v") // vertex position { glm::vec4 position; int dimension; - parseVector(parameters, 4, dimension, (float*)&position); + parseVector(parameters[0], parameters[1], 4, dimension, (float*)&position); if(dimension < 4) position.w = 1.0; if(dimension < 3) @@ -146,7 +163,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c { glm::vec3 texCoord; int dimension; - parseVector(parameters, 3, dimension, (float*)&texCoord); + parseVector(parameters[0], parameters[1], 3, dimension, (float*)&texCoord); if(texCoordDimension < 0) texCoordDimension = dimension; @@ -164,7 +181,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c { glm::vec3 normal; int dimension; - parseVector(parameters, 3, dimension, (float*)&normal); + parseVector(parameters[0], parameters[1], 3, dimension, (float*)&normal); if(dimension < 3) { @@ -186,7 +203,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c return data; } - std::vector<IndexTuple> pointIndices = parseIndices(parameters); + std::vector<IndexTuple> pointIndices = parseIndices(parameters[0], parameters[1]); // points are just added in order for(size_t i = 0; i < pointIndices.size(); ++i) { @@ -203,7 +220,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c return data; } - std::vector<IndexTuple> lineIndices = parseIndices(parameters); + std::vector<IndexTuple> lineIndices = parseIndices(parameters[0], parameters[1]); // add line segments for the line strip defined by the vertices for(size_t i = 0; i < lineIndices.size() - 1; ++i) { @@ -221,7 +238,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c return data; } - std::vector<IndexTuple> faceIndices = parseIndices(parameters); + std::vector<IndexTuple> faceIndices = parseIndices(parameters[0], parameters[1]); // triangulate the polygon defined by the indices for(size_t i = 1; i < faceIndices.size() - 1; ++i) { @@ -256,6 +273,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c { warning() << "unknown OBJ keyword ignored: " << keyword << std::endl; } + pchBuf = pchEOL + 1; } if (!hasNormals && _computeNormals) { @@ -349,7 +367,7 @@ SharedGeometryData loadGeometryDataFromOBJ(const std::string& _filename, bool _c data->setStrideSize(strideSize); data->setSize(abDataElements * sizeof(GLfloat)); data->setData((GLubyte*)abData); - + std::exit(0); return data; } -- GitLab