diff --git a/wrap/io_trimesh/import_obj.h b/wrap/io_trimesh/import_obj.h index e418a873..859464d4 100644 --- a/wrap/io_trimesh/import_obj.h +++ b/wrap/io_trimesh/import_obj.h @@ -8,7 +8,7 @@ * \ * * All rights reserved. * * * -* This program is free software; you can redistribute it and/or modify * +* This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * @@ -44,7 +44,7 @@ namespace vcg { namespace tri { namespace io { - /** + /** This class encapsulate a filter for importing obj (Alias Wavefront) meshes. Warning: this code assume little endian (PC) architecture!!! */ @@ -74,7 +74,7 @@ namespace vcg { } /// It returns a bit mask describing the field preesnt in the ply file - int mask; + int mask; /// a Simple callback that can be used for long obj parsing. // it returns the current position, and formats a string with a description of what th efunction is doing (loading vertexes, faces...) @@ -82,7 +82,7 @@ namespace vcg { /// number of vertices int numVertices; - /// number of faces (the number of triangles could be + /// number of faces (the number of triangles could be /// larger in presence of polygonal faces int numFaces; /// number of texture coords indexes @@ -102,7 +102,7 @@ namespace vcg { // short attr; // material index //}; struct ObjIndexedFace - { + { void set(const int & num){v.resize(num);n.resize(num); t.resize(num);} std::vector v; std::vector n; @@ -146,7 +146,7 @@ namespace vcg { // to check if a given error is critical or not. static bool ErrorCritical(int err) - { + { if(err<0x00A && err>=0) return false; return true; } @@ -169,7 +169,7 @@ namespace vcg { "No face field found", // 9 "Vertex statement with less than 3 coords", // 10 "Texture coords statement with less than 2 coords", // 11 - "Vertex normal statement with less than 3 coords", // 12 + "Vertex normal statement with less than 3 coords", // 12 "Face with less than 3 vertices", // 13 "Bad vertex index in face", // 14 "Bad texture coords index in face", // 15 @@ -184,7 +184,7 @@ namespace vcg { else return obj_error_msg[error]; }; - // Helper functions that checks the range of indexes + // Helper functions that checks the range of indexes // putting them in the correct range if less than zero (as in the obj style) static bool GoodObjIndex(int &index, const int maxVal) @@ -248,7 +248,7 @@ namespace vcg { std::string header; short currentMaterialIdx = 0; // index of current material into materials vector - Color4b currentColor=Color4b::LightGray; // we declare this outside code block since other + Color4b currentColor=Color4b::LightGray; // we declare this outside code block since other // triangles of this face will share the same color Material defaultMaterial; // default material: white @@ -265,7 +265,7 @@ namespace vcg { VertexIterator vi = vcg::tri::Allocator::AddVertices(m,oi.numVertices); //FaceIterator fi = Allocator::AddFaces(m,oi.numFaces); std::vector vertexColorVector; - ObjIndexedFace ff; + ObjIndexedFace ff; const char *loadingStr = "Loading"; while (!stream.eof()) { @@ -337,7 +337,7 @@ namespace vcg { CoordType n; n[0] = (ScalarType) atof(tokens[1].c_str()); n[1] = (ScalarType) atof(tokens[2].c_str()); - n[2] = (ScalarType) atof(tokens[3].c_str()); + n[2] = (ScalarType) atof(tokens[3].c_str()); normals.push_back(n); numVNormals++; @@ -416,6 +416,8 @@ namespace vcg { GoodObjIndex(indexTVect[pi],oi.numTexCoords); polygonVect[0][pi].Import(m.vert[indexVVect[pi]].cP()); } + if(vertexesPerFace>3) + oi.mask |= Mask::IOM_BITPOLYGONAL; if(vertexesPerFace<5) InternalFanTessellator(polygonVect, indexTriangulatedVect); @@ -463,7 +465,7 @@ namespace vcg { { // verifying validity of texture coords indices bool invalid = false; for(int i=0;i<3;i++) - if(!GoodObjIndex(ff.t[i],oi.numTexCoords)) + if(!GoodObjIndex(ff.t[i],oi.numTexCoords)) { //return E_BAD_VERT_TEX_INDEX; invalid = true; @@ -882,7 +884,7 @@ namespace vcg { lineCount++; std::getline(stream, line); totRead+=line.size(); - if(oi.cb && (lineCount%1000)==0) + if(oi.cb && (lineCount%1000)==0) (*oi.cb)( (int)(100.0*(float(totRead))/float(length)), "Loading mask..."); if(line.size()>2) { @@ -908,17 +910,17 @@ namespace vcg { } } oi.mask = 0; - if (oi.numTexCoords) + if (oi.numTexCoords) { if (oi.numTexCoords==oi.numVertices) oi.mask |= vcg::tri::io::Mask::IOM_VERTTEXCOORD; oi.mask |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD; // Usually if you have tex coords you also have materials - oi.mask |= vcg::tri::io::Mask::IOM_FACECOLOR; + oi.mask |= vcg::tri::io::Mask::IOM_FACECOLOR; } - if(bHasPerFaceColor) oi.mask |= vcg::tri::io::Mask::IOM_FACECOLOR; - if(bHasPerVertexColor) oi.mask |= vcg::tri::io::Mask::IOM_VERTCOLOR; + if(bHasPerFaceColor) oi.mask |= vcg::tri::io::Mask::IOM_FACECOLOR; + if(bHasPerVertexColor) oi.mask |= vcg::tri::io::Mask::IOM_VERTCOLOR; if (bHasNormals) { if (oi.numNormals == oi.numVertices) oi.mask |= vcg::tri::io::Mask::IOM_VERTNORMAL; @@ -975,7 +977,7 @@ namespace vcg { first = false; //strcpy(currentMaterial.name, tokens[1].c_str()); if(tokens.size() < 2) - return false; + return false; currentMaterial.materialName=tokens[1]; } else if (header.compare("Ka")==0) @@ -1015,7 +1017,7 @@ namespace vcg { return false; currentMaterial.Tr = (float) atof(tokens[1].c_str()); } - else if (header.compare("Ns")==0) // shininess + else if (header.compare("Ns")==0) // shininess { if (tokens.size() < 2) return false; diff --git a/wrap/io_trimesh/import_off.h b/wrap/io_trimesh/import_off.h index 39360770..55296293 100644 --- a/wrap/io_trimesh/import_off.h +++ b/wrap/io_trimesh/import_off.h @@ -8,7 +8,7 @@ * \ * * All rights reserved. * * * -* This program is free software; you can redistribute it and/or modify * +* This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * @@ -37,7 +37,7 @@ namespace vcg { // /** \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 */ @@ -58,7 +58,7 @@ namespace vcg // OFF codes enum OFFCodes {NoError=0, CantOpen, InvalidFile, InvalidFile_MissingOFF, - UnsupportedFormat, ErrorNotTriangularFace,ErrorHighDimension,ErrorDegenerateFace}; + UnsupportedFormat, ErrorNotTriangularFace,ErrorHighDimension,ErrorDegenerateFace}; /*! * Standard call for knowing the meaning of an error code @@ -71,9 +71,9 @@ namespace vcg { "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" }; + "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) + if(message_code>6 || message_code<0) return "Unknown error"; else return error_msg[message_code]; @@ -90,9 +90,9 @@ namespace vcg { // To obtain the loading mask all the file must be parsed // to distinguish between per-vertex and per-face color attribute. - loadmask=0; + loadmask=0; MESH_TYPE dummyMesh; - return (Open(dummyMesh, filename, loadmask)==NoError); + return (Open(dummyMesh, filename, loadmask)==NoError); } static int Open(MESH_TYPE &mesh, const char *filename,CallBackPos *cb=0) @@ -109,7 +109,7 @@ namespace vcg * \return the operation result */ static int Open(MESH_TYPE &mesh, const char *filename, int &loadmask, - CallBackPos *cb=0) + CallBackPos *cb=0) { std::ifstream stream(filename); if (stream.fail()) @@ -129,14 +129,14 @@ namespace vcg [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] - + # Faces # Nv = # vertices on this face # v[0] ... v[Nv-1]: vertex indices @@ -147,7 +147,7 @@ namespace vcg # nothing: default # integer: colormap index # 3 or 4 integers: RGB[A] values 0..255 - # 3 or 4 floats: RGB[A] values 0..1 + # 3 or 4 floats: RGB[A] values 0..1 */ std::string header = tokens[0]; if (header.rfind("OFF") != std::basic_string::npos) @@ -163,11 +163,11 @@ namespace vcg } 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 + // 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 /////////////////////////////////////// @@ -178,11 +178,11 @@ namespace vcg if (isColorDefined) { loadmask |= Mask::IOM_VERTCOLOR;loadmask |= Mask::IOM_FACECOLOR;} - //if(onlyMaskFlag) return NoError; - - + //if(onlyMaskFlag) return NoError; + + mesh.Clear(); - + // check on next 2 lines to detect corrupted files if(tokens.size() < 3) return InvalidFile; @@ -208,7 +208,7 @@ namespace vcg for (unsigned int i=0; i(atoi(tokens[k].c_str())); - unsigned char g = + unsigned char g = static_cast(atoi(tokens[k+1].c_str())); - unsigned char b = + 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())); @@ -307,13 +307,13 @@ namespace vcg { // read RGBA color if (tokens[k].find(".") == size_t(-1)) - { + { // integers - unsigned char r = + unsigned char r = static_cast(atoi(tokens[k].c_str())); - unsigned char g = + unsigned char g = static_cast(atoi(tokens[k+1].c_str())); - unsigned char b = + unsigned char b = static_cast(atoi(tokens[k+2].c_str())); unsigned char a = static_cast(atoi(tokens[k+3].c_str())); @@ -322,7 +322,7 @@ namespace vcg (*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())); @@ -410,7 +410,7 @@ namespace vcg 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 + 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 @@ -420,7 +420,7 @@ namespace vcg k = 0; } vertIndices[j] = atoi(tokens[k].c_str()); - polygonVect[j].Import (mesh.vert[ vertIndices[j] ].P()); + polygonVect[j].Import (mesh.vert[ vertIndices[j] ].P()); k++; } if(vert_per_face==4) @@ -449,7 +449,7 @@ namespace vcg { std::vector indexTriangulatedVect; // TessellatePlanarPolygon3(polygonVect,indexTriangulatedVect); - std::vector< std::vector > loopVect; + std::vector< std::vector > loopVect; loopVect.push_back(polygonVect); #ifdef __gl_h_ //qDebug("OK: using opengl tessellation for a polygon of %i vertices",vertexesPerFace); @@ -463,6 +463,14 @@ namespace vcg mesh.face[f+j/3].V(0) = &(mesh.vert[ vertIndices[ indexTriangulatedVect[j+0] ] ]); mesh.face[f+j/3].V(1) = &(mesh.vert[ vertIndices[ indexTriangulatedVect[j+1] ] ]); mesh.face[f+j/3].V(2) = &(mesh.vert[ vertIndices[ indexTriangulatedVect[j+2] ] ]); + // To correctly set Faux edges we have to clear the faux bit for all the edges that do not correspond to consecutive vertices + // Consecutivity is in the space of the index of the polygon. + for(int qq=0;qq<3;++qq) + { + if( (indexTriangulatedVect[j+qq]+1)%indexTriangulatedVect.size() == indexTriangulatedVect[j+(qq+1)%3]) + mesh.face[f+j/3].ClearF(qq); + else mesh.face[f+j/3].SetF(qq); + } } } f+=trigs; @@ -471,11 +479,11 @@ namespace vcg // 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; + 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) && tri::HasPerFaceColor(mesh) ) { @@ -551,21 +559,21 @@ namespace vcg } // end Open - protected: - + protected: + /*! * 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::ifstream &stream, std::vector< std::string > &tokens) + inline static void TokenizeNextLine(std::ifstream &stream, std::vector< std::string > &tokens) { std::string line; do std::getline(stream, line, '\n'); while (line[0] == '#' || line.length()==0 || line[0]=='\r'); - size_t from = 0; + size_t from = 0; size_t to = 0; size_t length = line.size(); tokens.clear(); @@ -590,9 +598,9 @@ namespace vcg * \param i the color index * \return the corresponding vcg::Color4f color */ - static const vcg::Color4f ColorMap(int i) + static const vcg::Color4f ColorMap(int i) { - static const float colorMap[148][4] = + static const float colorMap[148][4] = { { 1.0f, 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f },