From 20fa52181fc0b127b6534f8507a7482b872db8c3 Mon Sep 17 00:00:00 2001 From: Guido Ranzuglia Date: Thu, 13 Oct 2016 04:28:00 +0200 Subject: [PATCH] - fixed "if there is color both vertex/face colors are enabled even if there is just one of them" bug --- vcg/complex/algorithms/update/texture.h | 2 +- wrap/io_trimesh/import_off.h | 1409 ++++++++++++----------- 2 files changed, 708 insertions(+), 703 deletions(-) diff --git a/vcg/complex/algorithms/update/texture.h b/vcg/complex/algorithms/update/texture.h index c6f0b9b0..c454ddd1 100644 --- a/vcg/complex/algorithms/update/texture.h +++ b/vcg/complex/algorithms/update/texture.h @@ -111,7 +111,7 @@ static void WedgeTexFromVertexTex(ComputeMeshType &m) { (*fi).WT(i).U() = (*fi).V(i)->T().U(); (*fi).WT(i).V() = (*fi).V(i)->T().V(); - //(*fi).WT(i).N() = 0; + (*fi).WT(i).N() = 0; } } } diff --git a/wrap/io_trimesh/import_off.h b/wrap/io_trimesh/import_off.h index 4eb7b3ae..80e9f382 100644 --- a/wrap/io_trimesh/import_off.h +++ b/wrap/io_trimesh/import_off.h @@ -29,775 +29,780 @@ #include namespace vcg { -namespace tri { -namespace io { + namespace tri { + namespace io { -// /** \addtogroup */ -// /* @{ */ -/** - This class encapsulate a filter for importing OFF meshes. - A basic description of the OFF file format can be found at http://www.geomview.org/docs/html/geomview_41.html - */ -template -class ImporterOFF -{ -public: + // /** \addtogroup */ + // /* @{ */ + /** + This class encapsulate a filter for importing OFF meshes. + A basic description of the OFF file format can be found at http://www.geomview.org/docs/html/geomview_41.html + */ + template + class ImporterOFF + { + public: - typedef typename MESH_TYPE::VertexType VertexType; - typedef typename MESH_TYPE::VertexIterator VertexIterator; - typedef typename MESH_TYPE::VertexPointer VertexPointer; - typedef typename MESH_TYPE::FaceType FaceType; - typedef typename MESH_TYPE::FaceIterator FaceIterator; - typedef typename MESH_TYPE::FacePointer FacePointer; - typedef typename MESH_TYPE::CoordType CoordType; - typedef typename MESH_TYPE::ScalarType ScalarType; + typedef typename MESH_TYPE::VertexType VertexType; + typedef typename MESH_TYPE::VertexIterator VertexIterator; + typedef typename MESH_TYPE::VertexPointer VertexPointer; + typedef typename MESH_TYPE::FaceType FaceType; + typedef typename MESH_TYPE::FaceIterator FaceIterator; + typedef typename MESH_TYPE::FacePointer FacePointer; + typedef typename MESH_TYPE::CoordType CoordType; + typedef typename MESH_TYPE::ScalarType ScalarType; - // OFF codes - enum OFFCodes {NoError=0, CantOpen, InvalidFile, - InvalidFile_MissingOFF, - UnsupportedFormat, ErrorNotTriangularFace,ErrorHighDimension,ErrorDegenerateFace}; + // OFF codes + enum OFFCodes { + NoError = 0, CantOpen, InvalidFile, + InvalidFile_MissingOFF, + UnsupportedFormat, ErrorNotTriangularFace, ErrorHighDimension, ErrorDegenerateFace + }; - /*! - * Standard call for knowing the meaning of an error code - * \param message_code The code returned by Open - * \return The string describing the error code - */ - static const char* ErrorMsg(int message_code) - { - static const char* error_msg[] = - { - "No errors", "Can't open file", "Invalid file", - "Invalid file: OFF file should have in the first line the OFF keyword as a first token", - "Unsupported format", "Face with more than 3 vertices","File with high dimensional vertexes are not supported", "Error Degenerate Face with less than 3 vertices" }; + /*! + * Standard call for knowing the meaning of an error code + * \param message_code The code returned by Open + * \return The string describing the error code + */ + static const char* ErrorMsg(int message_code) + { + static const char* error_msg[] = + { + "No errors", "Can't open file", "Invalid file", + "Invalid file: OFF file should have in the first line the OFF keyword as a first token", + "Unsupported format", "Face with more than 3 vertices","File with high dimensional vertexes are not supported", "Error Degenerate Face with less than 3 vertices" }; - if(message_code>6 || message_code<0) - return "Unknown error"; - else - return error_msg[message_code]; - }; + if (message_code > 6 || message_code < 0) + return "Unknown error"; + else + return error_msg[message_code]; + }; - /** - * Load only the properties of the 3D objects. - * - * \param filename the name of the file to read from - * \param loadmask the mask which encodes the properties - * \return the operation result - */ - static bool LoadMask(const char *filename, int &loadmask) - { - // To obtain the loading mask all the file must be parsed - // to distinguish between per-vertex and per-face color attribute. - loadmask=0; - MESH_TYPE dummyMesh; - return (Open(dummyMesh, filename, loadmask)==NoError); - } + /** + * Load only the properties of the 3D objects. + * + * \param filename the name of the file to read from + * \param loadmask the mask which encodes the properties + * \return the operation result + */ + static bool LoadMask(const char *filename, int &loadmask) + { + // To obtain the loading mask all the file must be parsed + // to distinguish between per-vertex and per-face color attribute. + loadmask = 0; + MESH_TYPE dummyMesh; + return (Open(dummyMesh, filename, loadmask) == NoError); + } - static int Open(MESH_TYPE &mesh, const char *filename,CallBackPos *cb=0) - { - int loadmask; - return Open(mesh,filename,loadmask,cb); - } + static int Open(MESH_TYPE &mesh, const char *filename, CallBackPos *cb = 0) + { + int loadmask; + return Open(mesh, filename, loadmask, cb); + } - static int OpenMem(MESH_TYPE &mesh, const char *mem, size_t sz, int &loadmask, - CallBackPos *cb=0) - { - std::string str; - str.append(mem,sz); - std::istringstream strm(str); - return OpenStream(mesh,strm,loadmask,cb); - } + static int OpenMem(MESH_TYPE &mesh, const char *mem, size_t sz, int &loadmask, + CallBackPos *cb = 0) + { + std::string str; + str.append(mem, sz); + std::istringstream strm(str); + return OpenStream(mesh, strm, loadmask, cb); + } - /*! - * Standard call for reading a mesh. - * - * \param mesh the destination mesh - * \param filename the name of the file to read from - * \return the operation result - */ - static int Open(MESH_TYPE &mesh, const char *filename, int &loadmask, - CallBackPos *cb=0) - { - std::ifstream stream(filename); - if (stream.fail()) - return CantOpen; - return OpenStream(mesh,stream,loadmask,cb); - } + /*! + * Standard call for reading a mesh. + * + * \param mesh the destination mesh + * \param filename the name of the file to read from + * \return the operation result + */ + static int Open(MESH_TYPE &mesh, const char *filename, int &loadmask, + CallBackPos *cb = 0) + { + std::ifstream stream(filename); + if (stream.fail()) + return CantOpen; + return OpenStream(mesh, stream, loadmask, cb); + } - static int OpenStream(MESH_TYPE &mesh, std::istream &stream, int &loadmask, - CallBackPos *cb=0) - { - std::vector< std::string > tokens; - TokenizeNextLine(stream, tokens); - if(tokens.empty()) return InvalidFile_MissingOFF; + static int OpenStream(MESH_TYPE &mesh, std::istream &stream, int &loadmask, + CallBackPos *cb = 0) + { + std::vector< std::string > tokens; + TokenizeNextLine(stream, tokens); + if (tokens.empty()) return InvalidFile_MissingOFF; - bool isNormalDefined = false; - bool isColorDefined = false; - bool isTexCoordDefined = false; - int dimension = 3; - bool homogeneousComponents = false; + bool isNormalDefined = false; + bool isColorDefined = false; + bool isTexCoordDefined = false; + int dimension = 3; + bool homogeneousComponents = false; - /* - [ST][C][N][4][n]OFF # Header keyword - [Ndim] # Space dimension of vertices, present only if nOFF - NVertices NFaces NEdges # NEdges not used or checked + /* + [ST][C][N][4][n]OFF # Header keyword + [Ndim] # Space dimension of vertices, present only if nOFF + NVertices NFaces NEdges # NEdges not used or checked - x[0] y[0] z[0] # Vertices, possibly with normals, colors, and/or texture coordinates, in that order, if the prefixes N, C, ST are present. - # If 4OFF, each vertex has 4 components including a final homogeneous component. - # If nOFF, each vertex has Ndim components. - # If 4nOFF, each vertex has Ndim+1 components. - ... - x[NVertices-1] y[NVertices-1] z[NVertices-1] + x[0] y[0] z[0] # Vertices, possibly with normals, colors, and/or texture coordinates, in that order, if the prefixes N, C, ST are present. + # If 4OFF, each vertex has 4 components including a final homogeneous component. + # If nOFF, each vertex has Ndim components. + # If 4nOFF, each vertex has Ndim+1 components. + ... + x[NVertices-1] y[NVertices-1] z[NVertices-1] - # Faces - # Nv = # vertices on this face - # v[0] ... v[Nv-1]: vertex indices - # in range 0..NVertices-1 - Nv v[0] v[1] ... v[Nv-1] colorspec - ... - # colorspec continues past v[Nv-1] to end-of-line; may be 0 to 4 numbers - # nothing: default - # integer: colormap index - # 3 or 4 integers: RGB[A] values 0..255 - # 3 or 4 floats: RGB[A] values 0..1 - */ - std::string header = tokens[0]; - if (header.rfind("OFF") != std::basic_string::npos) - { // the OFF string is in the header go on parsing it. - for (int u = static_cast(header.rfind("OFF")-1); u>=0; u--) - { - if (header[u] == 'C') isColorDefined = true; - else if (header[u] == 'N') isNormalDefined = true; - else if (u>0 && header[u-1] == 'S' && header[u] == 'T') isTexCoordDefined = true; - else if (header[u] == '4') homogeneousComponents = true; - else if (header[u] == 'n') return ErrorHighDimension; - } - } - else return InvalidFile_MissingOFF; + # Faces + # Nv = # vertices on this face + # v[0] ... v[Nv-1]: vertex indices + # in range 0..NVertices-1 + Nv v[0] v[1] ... v[Nv-1] colorspec + ... + # colorspec continues past v[Nv-1] to end-of-line; may be 0 to 4 numbers + # nothing: default + # integer: colormap index + # 3 or 4 integers: RGB[A] values 0..255 + # 3 or 4 floats: RGB[A] values 0..1 + */ + std::string header = tokens[0]; + if (header.rfind("OFF") != std::basic_string::npos) + { // the OFF string is in the header go on parsing it. + for (int u = static_cast(header.rfind("OFF") - 1); u >= 0; u--) + { + if (header[u] == 'C') + isColorDefined = true; + else if (header[u] == 'N') + isNormalDefined = true; + else if (u > 0 && header[u - 1] == 'S' && header[u] == 'T') + isTexCoordDefined = true; + else if (header[u] == '4') + homogeneousComponents = true; + else if (header[u] == 'n') + return ErrorHighDimension; + } + } + else return InvalidFile_MissingOFF; - // If the file is slightly malformed and it has nvert and nface AFTER the OFF string instead of in the next line - // we manage it here... - if(tokens.size()==1) TokenizeNextLine(stream, tokens); - else tokens.erase(tokens.begin(),tokens.begin()+1); + // If the file is slightly malformed and it has nvert and nface AFTER the OFF string instead of in the next line + // we manage it here... + if (tokens.size() == 1) TokenizeNextLine(stream, tokens); + else tokens.erase(tokens.begin(), tokens.begin() + 1); - // Update loading mask - /////////////////////////////////////// + // Update loading mask + /////////////////////////////////////// - loadmask = Mask::IOM_VERTCOORD | Mask::IOM_FACEINDEX; + loadmask = Mask::IOM_VERTCOORD | Mask::IOM_FACEINDEX; - if (isNormalDefined) loadmask |= Mask::IOM_VERTNORMAL; - if (isTexCoordDefined) loadmask |= Mask::IOM_VERTTEXCOORD; - if (isColorDefined) { loadmask |= Mask::IOM_VERTCOLOR;loadmask |= Mask::IOM_FACECOLOR;} + if (isNormalDefined) loadmask |= Mask::IOM_VERTNORMAL; + if (isTexCoordDefined) loadmask |= Mask::IOM_VERTTEXCOORD; + //if (isColorDefined) { loadmask |= Mask::IOM_VERTCOLOR;loadmask |= Mask::IOM_FACECOLOR;} - //if(onlyMaskFlag) return NoError; + //if(onlyMaskFlag) return NoError; - mesh.Clear(); + mesh.Clear(); - // check on next 2 lines to detect corrupted files - if(tokens.size() < 3) - return InvalidFile; + // check on next 2 lines to detect corrupted files + if (tokens.size() < 3) + return InvalidFile; - unsigned int nVertices, nFaces, nEdges; - nVertices = atoi(tokens[0].c_str()); - nFaces = atoi(tokens[1].c_str()); - nEdges = atoi(tokens[2].c_str()); + unsigned int nVertices, nFaces, nEdges; + nVertices = atoi(tokens[0].c_str()); + nFaces = atoi(tokens[1].c_str()); + nEdges = atoi(tokens[2].c_str()); - // dimension is the space dimension of vertices => it must be three(!) - if (dimension != 3) - return UnsupportedFormat; + // dimension is the space dimension of vertices => it must be three(!) + if (dimension != 3) + return UnsupportedFormat; - if (homogeneousComponents) - return UnsupportedFormat; + if (homogeneousComponents) + return UnsupportedFormat; - // READ VERTICES - ////////////////////////////////////////////////////// + // READ VERTICES + ////////////////////////////////////////////////////// - VertexIterator v_iter = Allocator::AddVertices(mesh, nVertices); - TokenizeNextLine(stream, tokens); - size_t k = 0; // next token to read + VertexIterator v_iter = Allocator::AddVertices(mesh, nVertices); + TokenizeNextLine(stream, tokens); + size_t k = 0; // next token to read - for (unsigned int i=0; i(tokens.size()) - - static_cast(k) /* tokens already parsed */ - - 2 * (isTexCoordDefined ? 1 : 0); + // NOTE: It is assumed that colored vertex takes exactly one text line + // (otherwise it is impossible to parse color information since + // color components can vary) + if (isColorDefined) + { + // The number of color components varies from 0 to 4. + // The OFF format guaranties that there is 1 vertex per line. + int nb_color_components = static_cast(tokens.size()) + - static_cast(k) /* tokens already parsed */ + - 2 * (isTexCoordDefined ? 1 : 0); - if (nb_color_components < 0 || nb_color_components > 4) - return InvalidFile; + if (nb_color_components < 0 || nb_color_components > 4) + return InvalidFile; - // set per-vertex color attribute - if (nb_color_components > 0) - loadmask |= Mask::IOM_VERTCOLOR; + // set per-vertex color attribute + if (nb_color_components > 0) + loadmask |= Mask::IOM_VERTCOLOR; - // Store color components - if (tri::HasPerVertexColor(mesh)) - { - // Read color components + // Store color components + if (tri::HasPerVertexColor(mesh)) + { + // Read color components - if (nb_color_components == 1) - { - // read color index - (*v_iter).C().Import(ColorMap(atoi(tokens[k].c_str()))); - } - else if (nb_color_components == 3) - { - // read RGB color - if (tokens[k].find(".") == size_t(-1))// if it is a float there is a dot - { - // integers - unsigned char r = - static_cast(atoi(tokens[k].c_str())); - unsigned char g = - static_cast(atoi(tokens[k+1].c_str())); - unsigned char b = - static_cast(atoi(tokens[k+2].c_str())); + if (nb_color_components == 1) + { + // read color index + (*v_iter).C().Import(ColorMap(atoi(tokens[k].c_str()))); + } + else if (nb_color_components == 3) + { + // read RGB color + if (tokens[k].find(".") == size_t(-1))// if it is a float there is a dot + { + // integers + unsigned char r = + static_cast(atoi(tokens[k].c_str())); + unsigned char g = + static_cast(atoi(tokens[k + 1].c_str())); + unsigned char b = + static_cast(atoi(tokens[k + 2].c_str())); - vcg::Color4b color(r, g, b, 255); - (*v_iter).C().Import(color); - } - else - { - // floats - float r = static_cast(atof(tokens[k].c_str())); - float g = static_cast(atof(tokens[k+1].c_str())); - float b = static_cast(atof(tokens[k+2].c_str())); + vcg::Color4b color(r, g, b, 255); + (*v_iter).C().Import(color); + } + else + { + // floats + float r = static_cast(atof(tokens[k].c_str())); + float g = static_cast(atof(tokens[k + 1].c_str())); + float b = static_cast(atof(tokens[k + 2].c_str())); - vcg::Color4f color(r, g, b, 1.0); - (*v_iter).C().Import(color); - } - } - else if (nb_color_components == 4) - { - // read RGBA color - if (tokens[k].find(".") == size_t(-1)) - { - // integers - unsigned char r = - static_cast(atoi(tokens[k].c_str())); - unsigned char g = - static_cast(atoi(tokens[k+1].c_str())); - unsigned char b = - static_cast(atoi(tokens[k+2].c_str())); - unsigned char a = - static_cast(atoi(tokens[k+3].c_str())); + vcg::Color4f color(r, g, b, 1.0); + (*v_iter).C().Import(color); + } + } + else if (nb_color_components == 4) + { + // read RGBA color + if (tokens[k].find(".") == size_t(-1)) + { + // integers + unsigned char r = + static_cast(atoi(tokens[k].c_str())); + unsigned char g = + static_cast(atoi(tokens[k + 1].c_str())); + unsigned char b = + static_cast(atoi(tokens[k + 2].c_str())); + unsigned char a = + static_cast(atoi(tokens[k + 3].c_str())); - Color4b color(r, g, b, a); - (*v_iter).C().Import(color); - } - else - { - // floats - float r = static_cast(atof(tokens[k].c_str())); - float g = static_cast(atof(tokens[k+1].c_str())); - float b = static_cast(atof(tokens[k+2].c_str())); - float a = static_cast(atof(tokens[k+3].c_str())); + Color4b color(r, g, b, a); + (*v_iter).C().Import(color); + } + else + { + // floats + float r = static_cast(atof(tokens[k].c_str())); + float g = static_cast(atof(tokens[k + 1].c_str())); + float b = static_cast(atof(tokens[k + 2].c_str())); + float a = static_cast(atof(tokens[k + 3].c_str())); - vcg::Color4f color(r, g, b, a); - (*v_iter).C().Import(color); - } - } - } + vcg::Color4f color(r, g, b, a); + (*v_iter).C().Import(color); + } + } + } - k += nb_color_components; - } + k += nb_color_components; + } - if (isTexCoordDefined) - { - for (unsigned int j=0; j<2; j++) - { - // Go to next line when needed - if (k == tokens.size()) // if EOL - { - TokenizeNextLine(stream, tokens); - if (tokens.size() == 0) // if EOF - return InvalidFile; - k = 0; - } + if (isTexCoordDefined) + { + for (unsigned int j = 0; j < 2; j++) + { + // Go to next line when needed + if (k == tokens.size()) // if EOL + { + TokenizeNextLine(stream, tokens); + if (tokens.size() == 0) // if EOF + return InvalidFile; + k = 0; + } - std::string str = tokens[k]; - k++; + std::string str = tokens[k]; + k++; - // Store texture coordinates - if (tri::HasPerWedgeTexCoord(mesh)) - { - //...TODO... - } - } - } - } // for i=... + // Store texture coordinates + if (tri::HasPerWedgeTexCoord(mesh)) + { + //...TODO... + } + } + } + } // for i=... - // READ FACES - ////////////////////////////////////////////////////// - if(FaceType::HasPolyInfo()) - { - for (unsigned int f=0; f < nFaces; f++) - { - if(cb && (f%1000)==0) cb(50+f*50/nFaces,"Face Loading"); - TokenizeNextLine(stream, tokens); - int vert_per_face = atoi(tokens[0].c_str()); - std::vector vInd(vert_per_face); - k = 1; - for (int j=0; j < vert_per_face; j++) - { - if (k == tokens.size()) // if EOL // Go to next line when needed - { - TokenizeNextLine(stream, tokens); - if (tokens.size() == 0) return InvalidFile; // if EOF - k = 0; - } - vInd[j] = atoi(tokens[k].c_str()); - k++; - } - if(vert_per_face==3) - Allocator::AddFace(mesh, &mesh.vert[ vInd[0] ], &mesh.vert[ vInd[1] ], &mesh.vert[ vInd[2] ]); + // READ FACES + ////////////////////////////////////////////////////// + if (FaceType::HasPolyInfo()) + { + for (unsigned int f = 0; f < nFaces; f++) + { + if (cb && (f % 1000) == 0) cb(50 + f * 50 / nFaces, "Face Loading"); + TokenizeNextLine(stream, tokens); + int vert_per_face = atoi(tokens[0].c_str()); + std::vector vInd(vert_per_face); + k = 1; + for (int j = 0; j < vert_per_face; j++) + { + if (k == tokens.size()) // if EOL // Go to next line when needed + { + TokenizeNextLine(stream, tokens); + if (tokens.size() == 0) return InvalidFile; // if EOF + k = 0; + } + vInd[j] = atoi(tokens[k].c_str()); + k++; + } + if (vert_per_face == 3) + Allocator::AddFace(mesh, &mesh.vert[vInd[0]], &mesh.vert[vInd[1]], &mesh.vert[vInd[2]]); - if(vert_per_face==4) - Allocator::AddQuadFace(mesh, &mesh.vert[ vInd[0] ], &mesh.vert[ vInd[1] ], &mesh.vert[ vInd[2] ],&mesh.vert[ vInd[3] ]); + if (vert_per_face == 4) + Allocator::AddQuadFace(mesh, &mesh.vert[vInd[0]], &mesh.vert[vInd[1]], &mesh.vert[vInd[2]], &mesh.vert[vInd[3]]); - } - } - else // Standard Triangular Mesh Loading - { - Allocator::AddFaces(mesh, nFaces); - unsigned int f0=0; + } + } + else // Standard Triangular Mesh Loading + { + Allocator::AddFaces(mesh, nFaces); + unsigned int f0 = 0; - // Initial call to the QuadTriangulate with an empty vector to just reset the static set of existing diagonals - std::vector qtmp; - BitQuad::QuadTriangulate(qtmp); + // Initial call to the QuadTriangulate with an empty vector to just reset the static set of existing diagonals + std::vector qtmp; + BitQuad::QuadTriangulate(qtmp); - for (unsigned int f=0; f < nFaces; f++) - { - f0 = f; - if (stream.fail()) - return InvalidFile; + for (unsigned int f = 0; f < nFaces; f++) + { + f0 = f; + if (stream.fail()) + return InvalidFile; - if(cb && (f%1000)==0) - cb(50+f*50/nFaces,"Face Loading"); + if (cb && (f % 1000) == 0) + cb(50 + f * 50 / nFaces, "Face Loading"); - TokenizeNextLine(stream, tokens); - int vert_per_face = atoi(tokens[0].c_str()); - if(vert_per_face < 3) - return ErrorDegenerateFace; - k = 1; - if (vert_per_face == 3) - { - for (int j = 0; j < 3; j++) - { - if (k == tokens.size()) // if EOL // Go to next line when needed - { - TokenizeNextLine(stream, tokens); - if (tokens.size() == 0) return InvalidFile; // if EOF - k = 0; - } + TokenizeNextLine(stream, tokens); + int vert_per_face = atoi(tokens[0].c_str()); + if (vert_per_face < 3) + return ErrorDegenerateFace; + k = 1; + if (vert_per_face == 3) + { + for (int j = 0; j < 3; j++) + { + if (k == tokens.size()) // if EOL // Go to next line when needed + { + TokenizeNextLine(stream, tokens); + if (tokens.size() == 0) return InvalidFile; // if EOF + k = 0; + } - mesh.face[f].V(j) = &(mesh.vert[ atoi(tokens[k].c_str()) ]); - k++; - } - } - else - { - // The face must be triangulated - unsigned int trigs = vert_per_face-3; // number of extra faces to add - nFaces += trigs; - Allocator::AddFaces(mesh, trigs); - std::vector vertIndices(vert_per_face); - std::vector polygonVect(vert_per_face); // vec of polygon loops used for the triangulation of polygonal face - for (int j=0; j < vert_per_face; j++) - { - if (k == tokens.size()) // if EOL // Go to next line when needed - { - TokenizeNextLine(stream, tokens); - if (tokens.size() == 0) return InvalidFile; // if EOF - k = 0; - } - vertIndices[j] = atoi(tokens[k].c_str()); - polygonVect[j].Import (mesh.vert[ vertIndices[j] ].P()); - k++; - } - if(vert_per_face==4) - { // To well triangulate use the bitquad support function that reorders vertex for a simple fan - std::vector q(4); - for(int qqi=0;qqi<4;++qqi) - q[qqi]=& mesh.vert[vertIndices[qqi]]; - BitQuad::QuadTriangulate(q); - for(int qqi=0;qqi<4;++qqi) - vertIndices[qqi] = q[qqi]- & mesh.vert[0]; - // build a two face fan - for (int j=0; j<2; j++) - { - mesh.face[f+j].V(0) = &(mesh.vert[ vertIndices[0 ] ]); - mesh.face[f+j].V(1) = &(mesh.vert[ vertIndices[1+j] ]); - mesh.face[f+j].V(2) = &(mesh.vert[ vertIndices[2+j] ]); - if (tri::HasPerFaceFlags(mesh)) { - // tag internal polygonal edges as "faux" - if (j>0) mesh.face[f+j].SetF(0); - if (j indexTriangulatedVect; - // TessellatePlanarPolygon3(polygonVect,indexTriangulatedVect); - std::vector< std::vector > loopVect; - loopVect.push_back(polygonVect); + mesh.face[f].V(j) = &(mesh.vert[atoi(tokens[k].c_str())]); + k++; + } + } + else + { + // The face must be triangulated + unsigned int trigs = vert_per_face - 3; // number of extra faces to add + nFaces += trigs; + Allocator::AddFaces(mesh, trigs); + std::vector vertIndices(vert_per_face); + std::vector polygonVect(vert_per_face); // vec of polygon loops used for the triangulation of polygonal face + for (int j = 0; j < vert_per_face; j++) + { + if (k == tokens.size()) // if EOL // Go to next line when needed + { + TokenizeNextLine(stream, tokens); + if (tokens.size() == 0) return InvalidFile; // if EOF + k = 0; + } + vertIndices[j] = atoi(tokens[k].c_str()); + polygonVect[j].Import(mesh.vert[vertIndices[j]].P()); + k++; + } + if (vert_per_face == 4) + { // To well triangulate use the bitquad support function that reorders vertex for a simple fan + std::vector q(4); + for (int qqi = 0; qqi < 4; ++qqi) + q[qqi] = &mesh.vert[vertIndices[qqi]]; + BitQuad::QuadTriangulate(q); + for (int qqi = 0; qqi < 4; ++qqi) + vertIndices[qqi] = q[qqi] - &mesh.vert[0]; + // build a two face fan + for (int j = 0; j < 2; j++) + { + mesh.face[f + j].V(0) = &(mesh.vert[vertIndices[0]]); + mesh.face[f + j].V(1) = &(mesh.vert[vertIndices[1 + j]]); + mesh.face[f + j].V(2) = &(mesh.vert[vertIndices[2 + j]]); + if (tri::HasPerFaceFlags(mesh)) { + // tag internal polygonal edges as "faux" + if (j > 0) mesh.face[f + j].SetF(0); + if (j < vert_per_face - 3) mesh.face[f + j].SetF(2); + loadmask |= Mask::IOM_BITPOLYGONAL; + } + } + } + else // standard fan triangulation (we hope the polygon is convex...) + { + std::vector indexTriangulatedVect; + // TessellatePlanarPolygon3(polygonVect,indexTriangulatedVect); + std::vector< std::vector > loopVect; + loopVect.push_back(polygonVect); #ifdef __gl_h_ - //qDebug("OK: using opengl tessellation for a polygon of %i vertices",vertexesPerFace); - vcg::glu_tesselator::tesselate(loopVect, indexTriangulatedVect); + //qDebug("OK: using opengl tessellation for a polygon of %i vertices",vertexesPerFace); + vcg::glu_tesselator::tesselate(loopVect, indexTriangulatedVect); #else - //qDebug("Warning: using fan tessellation for a polygon of %i vertices",vertexesPerFace); - tri::io::FanTessellator(loopVect, indexTriangulatedVect); + //qDebug("Warning: using fan tessellation for a polygon of %i vertices",vertexesPerFace); + tri::io::FanTessellator(loopVect, indexTriangulatedVect); #endif - for (size_t j=0; j0); - if(isColorDefined) loadmask |= Mask::IOM_FACECOLOR; + // NOTE: It is assumed that colored face takes exactly one text line + // (otherwise it is impossible to parse color information since + // color components can vary) + size_t color_elements = tokens.size() - vert_per_face - 1; + //isColorDefined |= (color_elements>0); + //if(isColorDefined) loadmask |= Mask::IOM_FACECOLOR; - if( (color_elements>0) && tri::HasPerFaceColor(mesh) ) - { + if (color_elements > 0) + { + loadmask |= Mask::IOM_FACECOLOR; + if (tri::HasPerFaceColor(mesh)) + { + switch (color_elements) + { + case 0: + { + for (; f0 <= f; f0++) + mesh.face[f0].C().Import(vcg::Color4f(.666f, .666f, .666f, .666f)); + break; + } + case 1: + { + for (; f0 <= f; f0++) + mesh.face[f0].C().Import(ColorMap(atoi(tokens[vert_per_face + 1].c_str()))); + break; + } + case 3: + { + if (tokens[vert_per_face + 1].find('.') == std::string::npos) // if there is a float there is a dot + { + Color4b cc(Color4b::White); + cc[0] = (unsigned char)atoi(tokens[vert_per_face + 1].c_str()); + cc[1] = (unsigned char)atoi(tokens[vert_per_face + 2].c_str()); + cc[2] = (unsigned char)atoi(tokens[vert_per_face + 3].c_str()); + for (; f0 <= f; f0++) + mesh.face[f0].C() = cc; + } + else + { + float color[3]; + color[0] = (float)atof(tokens[vert_per_face + 1].c_str()); + color[1] = (float)atof(tokens[vert_per_face + 2].c_str()); + color[2] = (float)atof(tokens[vert_per_face + 3].c_str()); + for (; f0 <= f; f0++) + mesh.face[f0].C().Import(vcg::Color4f(color[0], color[1], color[2], 1.0f)); + } + break; + } + case 4: + { + if (tokens[vert_per_face + 1].find('.') == std::string::npos) // if it is a float there is a dot + { + Color4b cc; + cc[0] = (unsigned char)atoi(tokens[vert_per_face + 1].c_str()); + cc[1] = (unsigned char)atoi(tokens[vert_per_face + 2].c_str()); + cc[2] = (unsigned char)atoi(tokens[vert_per_face + 3].c_str()); + cc[3] = (unsigned char)atoi(tokens[vert_per_face + 4].c_str()); + for (; f0 <= f; f0++) + mesh.face[f0].C() = cc; + } + else + { + float color[4]; + color[0] = float(atof(tokens[vert_per_face + 1].c_str())); + color[1] = float(atof(tokens[vert_per_face + 2].c_str())); + color[2] = float(atof(tokens[vert_per_face + 3].c_str())); + color[3] = float(atof(tokens[vert_per_face + 4].c_str())); + for (; f0 <= f; f0++) + mesh.face[f0].C().Import(vcg::Color4f(color[0], color[1], color[2], color[3])); + } + break; + } + } //end switch + } + } // end if (isColorDefined) + } // end of for f=... + } + return NoError; - // set per-face color attribute - if (color_elements > 0) - loadmask |= Mask::IOM_FACECOLOR; + } // end Open - switch (color_elements) - { - case 0: - { - for ( ; f0<=f; f0++) - mesh.face[f0].C().Import(vcg::Color4f(.666f, .666f, .666f, .666f)); - break; - } - case 1: - { - for ( ; f0<=f; f0++) - mesh.face[f0].C().Import( ColorMap( atoi(tokens[vert_per_face+1].c_str()) ) ); - break; - } - case 3: - { - if (tokens[vert_per_face+1].find('.')==std::string::npos) // if there is a float there is a dot - { - Color4b cc(Color4b::White); - cc[0] = (unsigned char)atoi( tokens[vert_per_face+1].c_str() ); - cc[1] = (unsigned char)atoi( tokens[vert_per_face+2].c_str() ); - cc[2] = (unsigned char)atoi( tokens[vert_per_face+3].c_str() ); - for ( ; f0<=f; f0++) - mesh.face[f0].C()=cc; - } - else - { - float color[3]; - color[0] = (float) atof( tokens[vert_per_face+1].c_str() ); - color[1] = (float) atof( tokens[vert_per_face+2].c_str() ); - color[2] = (float) atof( tokens[vert_per_face+3].c_str() ); - for ( ; f0<=f; f0++) - mesh.face[f0].C().Import(vcg::Color4f(color[0], color[1], color[2], 1.0f)); - } - break; - } - case 4: - { - if (tokens[vert_per_face+1].find('.')==std::string::npos) // if it is a float there is a dot - { - Color4b cc; - cc[0] = (unsigned char) atoi(tokens[vert_per_face+1].c_str()); - cc[1] = (unsigned char) atoi(tokens[vert_per_face+2].c_str()); - cc[2] = (unsigned char) atoi(tokens[vert_per_face+3].c_str()); - cc[3] = (unsigned char) atoi(tokens[vert_per_face+4].c_str()); - for ( ; f0<=f; f0++) - mesh.face[f0].C()=cc; - } - else - { - float color[4]; - color[0] = float( atof(tokens[vert_per_face+1].c_str()) ); - color[1] = float( atof(tokens[vert_per_face+2].c_str()) ); - color[2] = float( atof(tokens[vert_per_face+3].c_str()) ); - color[3] = float( atof(tokens[vert_per_face+4].c_str()) ); - for ( ; f0<=f; f0++) - mesh.face[f0].C().Import(vcg::Color4f(color[0], color[1], color[2], color[3])); - } - break; - } - } //end switch - } // end if (isColorDefined) - } // end of for f=... - } - return NoError; + protected: - } // end Open + /*! + * Read the next valid line and parses it into "tokens", allowing the tokens to be read one at a time. + * \param stream The object providing the input stream + * \param tokens The "tokens" in the next line + */ + inline static void TokenizeNextLine(std::istream &stream, std::vector< std::string > &tokens) + { + std::string line; + do + std::getline(stream, line, '\n'); + while ((line[0] == '#' || line.length() == 0 || line[0] == '\r') && (!stream.eof())); -protected: + size_t from = 0; + size_t to = 0; + size_t length = line.size(); + tokens.clear(); + do + { + while (from != length && (line[from] == ' ' || line[from] == '\t' || line[from] == '\r')) + from++; + if (from != length) + { + to = from + 1; + while (to != length && (((line[to] != ' ') && (line[to] != '\t')) || (line[to] == '\r'))) + to++; + tokens.push_back(line.substr(from, to - from).c_str()); + from = to; + } + } while (from < length); + } // end Tokenize - /*! - * Read the next valid line and parses it into "tokens", allowing the tokens to be read one at a time. - * \param stream The object providing the input stream - * \param tokens The "tokens" in the next line - */ - inline static void TokenizeNextLine(std::istream &stream, std::vector< std::string > &tokens) - { - std::string line; - do - std::getline(stream, line, '\n'); - while ((line[0] == '#' || line.length()==0 || line[0]=='\r' ) && (!stream.eof())); - - size_t from = 0; - size_t to = 0; - size_t length = line.size(); - tokens.clear(); - do - { - while (from!=length && (line[from]==' ' || line[from] == '\t' || line[from] == '\r')) - from++; - if(from!=length) - { - to = from+1; - while ( to!=length && (((line[to]!=' ') && (line[to] != '\t')) || (line[to] == '\r'))) - to++; - tokens.push_back(line.substr(from, to-from).c_str()); - from = to; - } - } - while (fromcolor mapping, according to the Geomview's `cmap.fmap' file. - * \param i the color index - * \return the corresponding vcg::Color4f color - */ - static const vcg::Color4f ColorMap(int i) - { - static const float colorMap[148][4] = - { - { 1.0f, 1.0f, 1.0f, 1.0f }, - { 1.0f, 1.0f, 1.0f, 1.0f }, - { 1.0f, 1.0f, 1.0f, 1.0f }, - { 1.0f, 1.0f, 1.0f, 1.0f }, - { 1.0f, 1.0f, 1.0f, 1.0f }, - { 1.0f, 1.0f, 1.0f, 1.0f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.2f, 0.2f, 0.2f, 0.2f }, - { 0.9f, 0.9f, 0.9f, 0.9f }, - { 0.1f, 0.1f, 0.1f, 0.1f }, - { 0.1f, 0.1f, 0.1f, 0.1f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.9f, 0.9f, 0.9f, 0.9f }, - { 0.2f, 0.2f, 0.2f, 0.2f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.75f, 0.75f, 0.75f, 0.75f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.9f, 0.9f, 0.9f, 0.9f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.75f, 0.75f, 0.75f, 0.75f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.9f, 0.9f, 0.9f, 0.9f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.75f, 0.75f, 0.75f, 0.75f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.9f, 0.9f, 0.9f, 0.9f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.75f, 0.75f, 0.75f, 0.75f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 1.0f, 1.0f, 1.0f, 1.0f }, - { 1.0f, 1.0f, 1.0f, 1.0f }, - { 1.0f, 1.0f, 1.0f, 1.0f }, - { 1.0f, 1.0f, 1.0f, 1.0f }, - { 1.0f, 1.0f, 1.0f, 1.0f }, - { 1.0f, 1.0f, 1.0f, 1.0f }, - { 0.05f, 0.05f, 0.05f, 0.05f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.2f, 0.2f, 0.2f, 0.2f }, - { 0.9f, 0.9f, 0.9f, 0.9f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.1f, 0.1f, 0.1f, 0.1f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.9f, 0.9f, 0.9f, 0.9f }, - { 0.9f, 0.9f, 0.9f, 0.9f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.75f, 0.75f, 0.75f, 0.75f }, - { 0.75f, 0.75f, 0.75f, 0.75f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.9f, 0.9f, 0.9f, 0.9f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.75f, 0.75f, 0.75f, 0.75f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.9f, 0.9f, 0.9f, 0.9f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.75f, 0.75f, 0.75f, 0.75f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.7f, 0.7f, 0.7f, 0.7f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.9f, 0.9f, 0.9f, 0.9f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.75f, 0.75f, 0.75f, 0.75f }, - { 0.8f, 0.8f, 0.8f, 0.8f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.4f, 0.4f, 0.4f, 0.4f }, - { 0.8f, 0.8f, 0.8f, 0.8f } - }; - return Color4f(colorMap[i][0], colorMap[i][1], colorMap[i][2], colorMap[i][3]); - } -}; -// /*! @} */ -} //namespace io -}//namespace tri + /*! + * Provide the int->color mapping, according to the Geomview's `cmap.fmap' file. + * \param i the color index + * \return the corresponding vcg::Color4f color + */ + static const vcg::Color4f ColorMap(int i) + { + static const float colorMap[148][4] = + { + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.2f, 0.2f, 0.2f, 0.2f }, + { 0.9f, 0.9f, 0.9f, 0.9f }, + { 0.1f, 0.1f, 0.1f, 0.1f }, + { 0.1f, 0.1f, 0.1f, 0.1f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.9f, 0.9f, 0.9f, 0.9f }, + { 0.2f, 0.2f, 0.2f, 0.2f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.75f, 0.75f, 0.75f, 0.75f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.9f, 0.9f, 0.9f, 0.9f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.75f, 0.75f, 0.75f, 0.75f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.9f, 0.9f, 0.9f, 0.9f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.75f, 0.75f, 0.75f, 0.75f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.9f, 0.9f, 0.9f, 0.9f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.75f, 0.75f, 0.75f, 0.75f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 0.05f, 0.05f, 0.05f, 0.05f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.2f, 0.2f, 0.2f, 0.2f }, + { 0.9f, 0.9f, 0.9f, 0.9f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.1f, 0.1f, 0.1f, 0.1f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.9f, 0.9f, 0.9f, 0.9f }, + { 0.9f, 0.9f, 0.9f, 0.9f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.75f, 0.75f, 0.75f, 0.75f }, + { 0.75f, 0.75f, 0.75f, 0.75f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.9f, 0.9f, 0.9f, 0.9f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.75f, 0.75f, 0.75f, 0.75f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.9f, 0.9f, 0.9f, 0.9f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.75f, 0.75f, 0.75f, 0.75f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.7f, 0.7f, 0.7f, 0.7f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.9f, 0.9f, 0.9f, 0.9f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.75f, 0.75f, 0.75f, 0.75f }, + { 0.8f, 0.8f, 0.8f, 0.8f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.4f, 0.4f, 0.4f, 0.4f }, + { 0.8f, 0.8f, 0.8f, 0.8f } + }; + return Color4f(colorMap[i][0], colorMap[i][1], colorMap[i][2], colorMap[i][3]); + } + }; + // /*! @} */ + } //namespace io + }//namespace tri } // namespace vcg #endif //__VCGLIB_IMPORT_OFF