diff --git a/wrap/dae/colladaformat.h b/wrap/dae/colladaformat.h index 21512c8b..9638de0b 100644 --- a/wrap/dae/colladaformat.h +++ b/wrap/dae/colladaformat.h @@ -28,6 +28,9 @@ #include #include +#include + + template struct CoordNumber{public: static unsigned int coord() { return 0; }}; @@ -762,8 +765,6 @@ namespace Tags } }; - #include - class CreatedTag : public XMLLeafTag//added { public: @@ -1155,4 +1156,4 @@ public: //} }; } //Collada -#endif \ No newline at end of file +#endif diff --git a/wrap/dae/util_dae.h b/wrap/dae/util_dae.h index 5b2e5fb6..adf7c91c 100644 --- a/wrap/dae/util_dae.h +++ b/wrap/dae/util_dae.h @@ -316,7 +316,7 @@ namespace io { } if (res.last() == "") res.removeLast(); - + // int emptyCount = res.removeAll(QString("")); // if(emptyCount>0) qDebug("- - - - - - - - valueStringList: Removed %i null strings when parsing tag %s",emptyCount,qPrintable(tag)); // for(int i =0;icN());//index of vertex normal per face. + if (mask & Mask::IOM_VERTNORMAL) + vn = vInd; //writes elements on file obj WriteFacesElement(fp,vInd,vt,vn); diff --git a/wrap/io_trimesh/import_dae.h b/wrap/io_trimesh/import_dae.h index 74e30e6e..b4c0ab2a 100644 --- a/wrap/io_trimesh/import_dae.h +++ b/wrap/io_trimesh/import_dae.h @@ -704,7 +704,7 @@ static Matrix44f getTransfMatrixFromNode(const QDomElement parentNode) QDomDocument* doc = new QDomDocument(filename); info.doc = doc; - QFile file(filename); + QFile file(filename); if (!file.open(QIODevice::ReadOnly)) return E_CANTOPEN; if (!doc->setContent(&file)) @@ -805,7 +805,7 @@ static Matrix44f getTransfMatrixFromNode(const QDomElement parentNode) bool bHasPerVertexNormal = false; bool bHasPerVertexText = false; - QDomDocument* doc = new QDomDocument(filename); + QDomDocument* doc = new QDomDocument(filename); QFile file(filename); if (!file.open(QIODevice::ReadOnly)) return false; diff --git a/wrap/io_trimesh/import_obj.h b/wrap/io_trimesh/import_obj.h index f6c6e8d6..343ace57 100644 --- a/wrap/io_trimesh/import_obj.h +++ b/wrap/io_trimesh/import_obj.h @@ -41,7 +41,7 @@ namespace vcg { namespace tri { -namespace io { +namespace io { /** This class encapsulate a filter for importing obj (Alias Wavefront) meshes. @@ -64,27 +64,29 @@ public: { public: - Info() - { - mask = 0; - cb = 0; - numTexCoords=0; - } + Info() + { + mask = 0; + cb = 0; + numTexCoords=0; + } - /// It returns a bit mask describing the field preesnt in the ply file - int mask; + /// It returns a bit mask describing the field preesnt in the ply file + 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...) - CallBackPos *cb; + /// 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...) + CallBackPos *cb; - /// number of vertices - int numVertices; - /// number of faces (the number of triangles could be - /// larger in presence of polygonal faces - int numFaces; - /// number of texture coords indexes - int numTexCoords; + /// number of vertices + int numVertices; + /// number of faces (the number of triangles could be + /// larger in presence of polygonal faces + int numFaces; + /// number of texture coords indexes + int numTexCoords; + /// number of normals + int numNormals; }; // end class @@ -99,85 +101,85 @@ public: //}; struct ObjIndexedFace { - void set(const int & num){v.resize(num);n.resize(num); t.resize(num);} - std::vector v; - std::vector n; - std::vector t; - int tInd; - bool edge[3];// useless if the face is a polygon, no need to have variable length array - Color4b c; + void set(const int & num){v.resize(num);n.resize(num); t.resize(num);} + std::vector v; + std::vector n; + std::vector t; + int tInd; + bool edge[3];// useless if the face is a polygon, no need to have variable length array + Color4b c; }; struct ObjTexCoord { - float u; - float v; + float u; + float v; }; enum OBJError { // Successfull opening - E_NOERROR = 0x000, // 0 (position of correspondig string in the array) + E_NOERROR = 0x000, // 0 (position of correspondig string in the array) - // Non Critical Errors (only odd numbers) - E_NON_CRITICAL_ERROR = 0x001, - E_MATERIAL_FILE_NOT_FOUND = 0x003, // 1 - E_MATERIAL_NOT_FOUND = 0x005, // 2 - E_TEXTURE_NOT_FOUND = 0x007, // 3 - E_VERTICES_WITH_SAME_IDX_IN_FACE = 0x009, // 4 + // Non Critical Errors (only odd numbers) + E_NON_CRITICAL_ERROR = 0x001, + E_MATERIAL_FILE_NOT_FOUND = 0x003, // 1 + E_MATERIAL_NOT_FOUND = 0x005, // 2 + E_TEXTURE_NOT_FOUND = 0x007, // 3 + E_VERTICES_WITH_SAME_IDX_IN_FACE = 0x009, // 4 - // Critical Opening Errors (only even numbers) - E_CANTOPEN = 0x00A, // 5 - E_UNESPECTEDEOF = 0x00C, // 6 - E_ABORTED = 0x00E, // 7 - E_NO_VERTEX = 0x010, // 8 - E_NO_FACE = 0x012, // 9 - E_BAD_VERTEX_STATEMENT = 0x014, // 10 - E_BAD_VERT_TEX_STATEMENT = 0x016, // 11 - E_BAD_VERT_NORMAL_STATEMENT = 0x018, // 12 - E_LESS_THAN_3VERTINFACE = 0x01A, // 13 - E_BAD_VERT_INDEX = 0x01C, // 14 - E_BAD_VERT_TEX_INDEX = 0x01E, // 15 - E_BAD_VERT_NORMAL_INDEX = 0x020 // 16 + // Critical Opening Errors (only even numbers) + E_CANTOPEN = 0x00A, // 5 + E_UNESPECTEDEOF = 0x00C, // 6 + E_ABORTED = 0x00E, // 7 + E_NO_VERTEX = 0x010, // 8 + E_NO_FACE = 0x012, // 9 + E_BAD_VERTEX_STATEMENT = 0x014, // 10 + E_BAD_VERT_TEX_STATEMENT = 0x016, // 11 + E_BAD_VERT_NORMAL_STATEMENT = 0x018, // 12 + E_LESS_THAN_3VERTINFACE = 0x01A, // 13 + E_BAD_VERT_INDEX = 0x01C, // 14 + E_BAD_VERT_TEX_INDEX = 0x01E, // 15 + E_BAD_VERT_NORMAL_INDEX = 0x020 // 16 }; // to check if a given error is critical or not. static bool ErrorCritical(int err) { - if(err<0x00A && err>=0) return false; - return true; + if(err<0x00A && err>=0) return false; + return true; } static const char* ErrorMsg(int error) { - static const char* obj_error_msg[] = - { - "No errors", // 0 + static const char* obj_error_msg[] = + { + "No errors", // 0 - "Material library file wrong or not found, a default white material is used", // 1 - "Some materials definitions were not found, a default white material is used where no material was available", // 2 - "Texture file not found", // 3 - "Identical index vertices found in the same face", // 4 + "Material library file wrong or not found, a default white material is used", // 1 + "Some materials definitions were not found, a default white material is used where no material was available", // 2 + "Texture file not found", // 3 + "Identical index vertices found in the same face", // 4 - "Can't open file", // 5 - "Premature End of file", // 6 - "File opening aborted", // 7 - "No vertex field found", // 8 - "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 - "Face with less than 3 vertices", // 13 - "Bad vertex index in face", // 14 - "Bad texture coords index in face", // 15 - "Bad vertex normal index in face" // 16 - }; + "Can't open file", // 5 + "Premature End of file", // 6 + "File opening aborted", // 7 + "No vertex field found", // 8 + "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 + "Face with less than 3 vertices", // 13 + "Bad vertex index in face", // 14 + "Bad texture coords index in face", // 15 + "Bad vertex normal index in face" // 16 + }; - // due to approximation, following line works well for either even (critical err codes) - // or odd (non critical ones) numbers - error = (int) error/2; + // due to approximation, following line works well for either even (critical err codes) + // or odd (non critical ones) numbers + error = (int) error/2; - if(error>15 || error<0) return "Unknown error"; - else return obj_error_msg[error]; + if(error>15 || error<0) return "Unknown error"; + else return obj_error_msg[error]; }; // Helper functions that checks the range of indexes @@ -185,23 +187,23 @@ public: static bool GoodObjIndex(int &index, const int maxVal) { - if (index > maxVal) return false; - if (index < 0) - { - index += maxVal+1; - if (index<0 || index > maxVal) return false; - } - return true; + if (index > maxVal) return false; + if (index < 0) + { + index += maxVal+1; + if (index<0 || index > maxVal) return false; + } + return true; } static int Open(OpenMeshType &mesh, const char *filename, int &loadmask, CallBackPos *cb=0) { - Info oi; - oi.mask=-1; - oi.cb=cb; - int ret=Open(mesh,filename,oi); - loadmask=oi.mask; - return ret; + Info oi; + oi.mask=-1; + oi.cb=cb; + int ret=Open(mesh,filename,oi); + loadmask=oi.mask; + return ret; } /*! @@ -213,173 +215,173 @@ public: */ static int Open( OpenMeshType &m, const char * filename, Info &oi) { - int result = E_NOERROR; + int result = E_NOERROR; - m.Clear(); + m.Clear(); CallBackPos *cb = oi.cb; - // if LoadMask has not been called yet, we call it here - if (oi.mask == -1) - LoadMask(filename, oi); + // if LoadMask has not been called yet, we call it here + if (oi.mask == -1) + LoadMask(filename, oi); const int inputMask = oi.mask; - Mask::ClampMask(m,oi.mask); + Mask::ClampMask(m,oi.mask); - if (oi.numVertices == 0) - return E_NO_VERTEX; + if (oi.numVertices == 0) + return E_NO_VERTEX; - // Commented out this test. You should be allowed to load point clouds. - //if (oi.numFaces == 0) - // return E_NO_FACE; + // Commented out this test. You should be allowed to load point clouds. + //if (oi.numFaces == 0) + // return E_NO_FACE; - std::ifstream stream(filename); - if (stream.fail()) - return E_CANTOPEN; + std::ifstream stream(filename); + if (stream.fail()) + return E_CANTOPEN; - std::vector materials; // materials vector - std::vector texCoords; // texture coordinates - std::vector normals; // vertex normals - std::vector indexedFaces; - std::vector< std::string > tokens; - std::string header; + std::vector materials; // materials vector + std::vector texCoords; // texture coordinates + std::vector normals; // vertex normals + std::vector indexedFaces; + std::vector< std::string > tokens; + 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 - // triangles of this face will share the same color + short currentMaterialIdx = 0; // index of current material into materials vector + 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 - materials.push_back(defaultMaterial); + Material defaultMaterial; // default material: white + materials.push_back(defaultMaterial); - int numVertices = 0; // stores the number of vertices been read till now - int numTriangles = 0; // stores the number of faces been read till now - int numTexCoords = 0; // stores the number of texture coordinates been read till now - int numVNormals = 0; // stores the number of vertex normals been read till now + int numVertices = 0; // stores the number of vertices been read till now + int numTriangles = 0; // stores the number of faces been read till now + int numTexCoords = 0; // stores the number of texture coordinates been read till now + int numVNormals = 0; // stores the number of vertex normals been read till now - int numVerticesPlusFaces = oi.numVertices + oi.numFaces; - int extraTriangles=0; - // vertices and faces allocatetion - VertexIterator vi = Allocator::AddVertices(m,oi.numVertices); - //FaceIterator fi = Allocator::AddFaces(m,oi.numFaces); + int numVerticesPlusFaces = oi.numVertices + oi.numFaces; + int extraTriangles=0; + // vertices and faces allocatetion + VertexIterator vi = Allocator::AddVertices(m,oi.numVertices); + //FaceIterator fi = Allocator::AddFaces(m,oi.numFaces); - ObjIndexedFace ff; + ObjIndexedFace ff; - while (!stream.eof()) + while (!stream.eof()) + { + tokens.clear(); + TokenizeNextLine(stream, tokens); + + unsigned int numTokens = static_cast(tokens.size()); + if (numTokens > 0) { - tokens.clear(); - TokenizeNextLine(stream, tokens); + header.clear(); + header = tokens[0]; - unsigned int numTokens = static_cast(tokens.size()); - if (numTokens > 0) + if (header.compare("v")==0) // vertex { - header.clear(); - header = tokens[0]; + if (numTokens < 4) return E_BAD_VERTEX_STATEMENT; - if (header.compare("v")==0) // vertex - { - if (numTokens < 4) return E_BAD_VERTEX_STATEMENT; + (*vi).P()[0] = (ScalarType) atof(tokens[1].c_str()); + (*vi).P()[1] = (ScalarType) atof(tokens[2].c_str()); + (*vi).P()[2] = (ScalarType) atof(tokens[3].c_str()); + ++numVertices; - (*vi).P()[0] = (ScalarType) atof(tokens[1].c_str()); - (*vi).P()[1] = (ScalarType) atof(tokens[2].c_str()); - (*vi).P()[2] = (ScalarType) atof(tokens[3].c_str()); - ++numVertices; - - // assigning vertex color - // ---------------------- + // assigning vertex color + // ---------------------- if (((oi.mask & vcg::tri::io::Mask::IOM_VERTCOLOR) != 0) && (m.HasPerVertexColor())) { - (*vi).C() = currentColor; + (*vi).C() = currentColor; } - ++vi; // move to next vertex iterator + ++vi; // move to next vertex iterator - // callback invocation, abort loading process if the call returns false - if ((cb !=NULL) && (((numTriangles + numVertices)%100)==0) && !(*cb)((100*(numTriangles + numVertices))/numVerticesPlusFaces, "Vertex Loading")) - return E_ABORTED; - } - else if (header.compare("vt")==0) // vertex texture coords - { - if (numTokens < 3) return E_BAD_VERT_TEX_STATEMENT; + // callback invocation, abort loading process if the call returns false + if ((cb !=NULL) && (((numTriangles + numVertices)%100)==0) && !(*cb)((100*(numTriangles + numVertices))/numVerticesPlusFaces, "Vertex Loading")) + return E_ABORTED; + } + else if (header.compare("vt")==0) // vertex texture coords + { + if (numTokens < 3) return E_BAD_VERT_TEX_STATEMENT; - ObjTexCoord t; - t.u = static_cast(atof(tokens[1].c_str())); - t.v = static_cast(atof(tokens[2].c_str())); - texCoords.push_back(t); + ObjTexCoord t; + t.u = static_cast(atof(tokens[1].c_str())); + t.v = static_cast(atof(tokens[2].c_str())); + texCoords.push_back(t); - numTexCoords++; - } - else if (header.compare("vn")==0) // vertex normal - { - if (numTokens != 4) return E_BAD_VERT_NORMAL_STATEMENT; + numTexCoords++; + } + else if (header.compare("vn")==0) // vertex normal + { + if (numTokens != 4) return E_BAD_VERT_NORMAL_STATEMENT; - 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()); - normals.push_back(n); + 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()); + normals.push_back(n); - numVNormals++; - } + numVNormals++; + } else if( (header.compare("f")==0) || (header.compare("q")==0) ) // face - { + { bool QuadFlag = false; // QOBJ format by Silva et al for simply storing quadrangular meshes. if(header.compare("q")==0) { QuadFlag=true; assert(numTokens == 5); } - if (numTokens < 4) return E_LESS_THAN_3VERTINFACE; - int vertexesPerFace = static_cast(tokens.size()-1); + if (numTokens < 4) return E_LESS_THAN_3VERTINFACE; + int vertexesPerFace = static_cast(tokens.size()-1); - if( (vertexesPerFace>3) && OpenMeshType::FaceType::HasPolyInfo() ){ + if( (vertexesPerFace>3) && OpenMeshType::FaceType::HasPolyInfo() ){ //_BEGIN___ if you are loading a GENERIC POLYGON mesh - ff.set(vertexesPerFace); - for(int i=0;i tmp = ff.v; - std::sort(tmp.begin(),tmp.end()); - std::unique(tmp.begin(),tmp.end()); - if(tmp.size() != ff.v.size()) - result = E_VERTICES_WITH_SAME_IDX_IN_FACE; + // verifying validity of vertex indices + std::vector tmp = ff.v; + std::sort(tmp.begin(),tmp.end()); + std::unique(tmp.begin(),tmp.end()); + if(tmp.size() != ff.v.size()) + result = E_VERTICES_WITH_SAME_IDX_IN_FACE; - for(int i=0;i > polygonVect(1); // it is a vector of polygon loops polygonVect[0].resize(vertexesPerFace); std::vector indexVVect(vertexesPerFace); @@ -430,7 +432,7 @@ public: if( (i2+1)%vertexesPerFace == i0) ff.edge[2]=false; else ff.edge[2]=true; - if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD ) + if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD ) { // verifying validity of texture coords indices for(int i=0;i<3;i++) if(!GoodObjIndex(ff.t[i],oi.numTexCoords)) return E_BAD_VERT_TEX_INDEX; @@ -460,7 +462,7 @@ public: } #else - { + { ff.set(3); for(int i=0;i<3;++i) { // remember index starts from 1 instead of 0 @@ -469,191 +471,197 @@ public: } if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD ) { - // verifying validity of texture coords indices - for(int i=0;i<3;i++) - if(!GoodObjIndex(ff.t[i],oi.numTexCoords)) - return E_BAD_VERT_TEX_INDEX; + // verifying validity of texture coords indices + for(int i=0;i<3;i++) + if(!GoodObjIndex(ff.t[i],oi.numTexCoords)) + return E_BAD_VERT_TEX_INDEX; - ff.tInd=materials[currentMaterialIdx].index; - } + ff.tInd=materials[currentMaterialIdx].index; + } - // verifying validity of vertex indices - if ((ff.v[0] == ff.v[1]) || (ff.v[0] == ff.v[2]) || (ff.v[1] == ff.v[2])) - result = E_VERTICES_WITH_SAME_IDX_IN_FACE; + // verifying validity of vertex indices + if ((ff.v[0] == ff.v[1]) || (ff.v[0] == ff.v[2]) || (ff.v[1] == ff.v[2])) + result = E_VERTICES_WITH_SAME_IDX_IN_FACE; - for(int i=0;i<3;i++) - if(!GoodObjIndex(ff.v[i],numVertices)) - return E_BAD_VERT_INDEX; + for(int i=0;i<3;i++) + if(!GoodObjIndex(ff.v[i],numVertices)) + return E_BAD_VERT_INDEX; - // assigning face normal - if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL ) + // assigning face normal + if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL ) { // verifying validity of vertex normal indices - for(int i=0;i<3;i++) - if(!GoodObjIndex(ff.n[i],numVNormals)) return E_BAD_VERT_NORMAL_INDEX; - } + for(int i=0;i<3;i++) + if(!GoodObjIndex(ff.n[i],numVNormals)) return E_BAD_VERT_NORMAL_INDEX; + } - // assigning face color - // -------------------- - if( oi.mask & vcg::tri::io::Mask::IOM_FACECOLOR) - ff.c = currentColor; + // assigning face color + // -------------------- + if( oi.mask & vcg::tri::io::Mask::IOM_FACECOLOR) + ff.c = currentColor; - // by default there are no internal edge - ff.edge[0]=ff.edge[1]=ff.edge[2]=false; - if(vertexesPerFace>3) ff.edge[2]=true; - ++numTriangles; - indexedFaces.push_back(ff); - /* - // A face polygon composed of more than three vertices is triangulated - // according to the following schema: - // v5 - // / \ - // / \ - // / \ - // v1------v4 - // |\ / - // | \ / - // | \ / - // v2---v3 - // - // As shown above, the 5 vertices polygon (v1,v2,v3,v4,v5) - // has been split into the triangles (v1,v2,v3), (v1,v3,v4) e (v1,v4,v5). - // This way vertex v1 becomes the common vertex of all newly generated - // triangles, and this may lead to the creation of very thin triangles. - */ + // by default there are no internal edge + ff.edge[0]=ff.edge[1]=ff.edge[2]=false; + if(vertexesPerFace>3) ff.edge[2]=true; + ++numTriangles; + indexedFaces.push_back(ff); + /* + // A face polygon composed of more than three vertices is triangulated + // according to the following schema: + // v5 + // / \ + // / \ + // / \ + // v1------v4 + // |\ / + // | \ / + // | \ / + // v2---v3 + // + // As shown above, the 5 vertices polygon (v1,v2,v3,v4,v5) + // has been split into the triangles (v1,v2,v3), (v1,v3,v4) e (v1,v4,v5). + // This way vertex v1 becomes the common vertex of all newly generated + // triangles, and this may lead to the creation of very thin triangles. + */ - int iVertex = 3; - while (iVertex < vertexesPerFace) // add other triangles - { + int iVertex = 3; + while (iVertex < vertexesPerFace) // add other triangles + { oi.mask |= Mask::IOM_BITPOLYGONAL; - ObjIndexedFace ffNew=ff; - int v4_index; - int vt4_index; - int vn4_index; + ObjIndexedFace ffNew=ff; + int v4_index; + int vt4_index; + int vn4_index; SplitToken(tokens[++iVertex], v4_index, vn4_index, vt4_index, inputMask); if(QuadFlag) { v4_index+=1; } - if(!GoodObjIndex(v4_index, numVertices)) - return E_BAD_VERT_INDEX; + if(!GoodObjIndex(v4_index, numVertices)) + return E_BAD_VERT_INDEX; - // assigning wedge texture coordinates - // ----------------------------------- - if( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD ) - { - // verifying validity of texture coords index - // ------------------------------------------ - if(!GoodObjIndex(vt4_index,oi.numTexCoords)) - return E_BAD_VERT_TEX_INDEX; + // assigning wedge texture coordinates + // ----------------------------------- + if( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD ) + { + // verifying validity of texture coords index + // ------------------------------------------ + if(!GoodObjIndex(vt4_index,oi.numTexCoords)) + return E_BAD_VERT_TEX_INDEX; - if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL ) - if(!GoodObjIndex(vn4_index,numVNormals)) - return E_BAD_VERT_NORMAL_INDEX; + if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL ) + if(!GoodObjIndex(vn4_index,numVNormals)) + return E_BAD_VERT_NORMAL_INDEX; - ffNew.t[1]=ff.t[2]; - ffNew.t[2]=vt4_index; - } + ffNew.t[1]=ff.t[2]; + ffNew.t[2]=vt4_index; + } - if ((ff.v[0] == v4_index) || (ff.v[2] == v4_index)) result = E_VERTICES_WITH_SAME_IDX_IN_FACE; - ffNew.v[1]=ff.v[2]; - ffNew.v[2]=v4_index; + if ((ff.v[0] == v4_index) || (ff.v[2] == v4_index)) result = E_VERTICES_WITH_SAME_IDX_IN_FACE; + ffNew.v[1]=ff.v[2]; + ffNew.v[2]=v4_index; - // assigning face normal - // --------------------- - if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL ) - { - ffNew.n[1]=ff.n[2]; - ffNew.n[2]=vn4_index; - } - // Setting internal edges: edge 1 (the opposite to vertex 0) is always an external edge. - ffNew.edge[0]=true; - ffNew.edge[1]=false; - if(iVertex < vertexesPerFace) ffNew.edge[2]=true; - else ffNew.edge[2]=false; - ++numTriangles; - ++extraTriangles; - indexedFaces.push_back(ffNew); - ff.v[2] = v4_index; - } - // callback invocation, abort loading process if the call returns false - if ((cb !=NULL)&& (((numTriangles + numVertices)%100)==0) ) - { - if (!(*cb)( (100*(numTriangles +numVertices))/ numVerticesPlusFaces, "Face Loading")) - return E_ABORTED; + // assigning face normal + // --------------------- + if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL ) + { + ffNew.n[1]=ff.n[2]; + ffNew.n[2]=vn4_index; + } + // Setting internal edges: edge 1 (the opposite to vertex 0) is always an external edge. + ffNew.edge[0]=true; + ffNew.edge[1]=false; + if(iVertex < vertexesPerFace) ffNew.edge[2]=true; + else ffNew.edge[2]=false; + ++numTriangles; + ++extraTriangles; + indexedFaces.push_back(ffNew); + ff.v[2] = v4_index; + } + // callback invocation, abort loading process if the call returns false + if ((cb !=NULL)&& (((numTriangles + numVertices)%100)==0) ) + { + if (!(*cb)( (100*(numTriangles +numVertices))/ numVerticesPlusFaces, "Face Loading")) + return E_ABORTED; } }//_END___ if you are loading a TRIMESH mesh #endif - } - else if (header.compare("mtllib")==0) // material library - { - // obtain the name of the file containing materials library - std::string materialFileName = tokens[1]; - if (!LoadMaterials( materialFileName.c_str(), materials, m.textures)) - result = E_MATERIAL_FILE_NOT_FOUND; - } - else if (header.compare("usemtl")==0) // material usage - { - std::string materialName = tokens[1]; - bool found = false; - unsigned i = 0; - while (!found && (i < materials.size())) - { - std::string currentMaterialName = materials[i].materialName; - if (currentMaterialName == materialName) - { - currentMaterialIdx = i; - Material &material = materials[currentMaterialIdx]; - Point3f diffuseColor = material.Kd; - unsigned char r = (unsigned char) (diffuseColor[0] * 255.0); - unsigned char g = (unsigned char) (diffuseColor[1] * 255.0); - unsigned char b = (unsigned char) (diffuseColor[2] * 255.0); - unsigned char alpha = (unsigned char) (material.Tr * 255.0); - currentColor= Color4b(r, g, b, alpha); - found = true; - } - ++i; } - - if (!found) - { - currentMaterialIdx = 0; - result = E_MATERIAL_NOT_FOUND; - } - } - // we simply ignore other situations - } // end for each line... - } // end while stream not eof - assert((numTriangles +numVertices) == numVerticesPlusFaces+extraTriangles); - - FaceIterator fi = Allocator::AddFaces(m,numTriangles); - //------------------------------------------------------------------------------- - - // Now the final pass to convert indexes into pointers for face to vert/norm/tex references - for(int i=0; i::AddFaces(m,numTriangles); + //------------------------------------------------------------------------------- + + // Now the final pass to convert indexes into pointers for face to vert/norm/tex references + for(int i=0; iT().u() = t.u; + m.face[i].V(j)->T().v() = t.v; + m.face[i].V(j)->T().n() = indexedFaces[i].tInd; + } + if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL ) + m.face[i].WN(j).Import(normals[indexedFaces[i].n[j]]); - if (((oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL) != 0) && (m.HasPerWedgeNormal())) - { - m.face[i].WN(j).Import(normals[indexedFaces[i].n[j]]); - } + if ( oi.mask & vcg::tri::io::Mask::IOM_VERTNORMAL ) + m.face[i].V(j)->N().Import(normals[indexedFaces[i].n[j]]); - // set faux edge flags according to internals faces + // set faux edge flags according to internals faces if (indexedFaces[i].edge[j]) { m.face[i].SetF(j); - } + } else { m.face[i].ClearF(j); @@ -667,8 +675,8 @@ public: if (((oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL) != 0) && (m.HasPerWedgeNormal())) { - // face normal is computed as an average of wedge normals - m.face[i].N().Import(m.face[i].WN(0)+m.face[i].WN(1)+m.face[i].WN(2)); + // face normal is computed as an average of wedge normals + m.face[i].N().Import(m.face[i].WN(0)+m.face[i].WN(1)+m.face[i].WN(2)); } else { @@ -676,11 +684,11 @@ public: if (m.HasPerFaceNormal()) { face::ComputeNormalizedNormal(m.face[i]); - } + } } } - return result; + return result; } // end of Open @@ -695,7 +703,7 @@ public: if(stream.eof()) return; std::string line; do - std::getline(stream, line); + std::getline(stream, line); while ((line[0] == '#' || line.length()==0) && !stream.eof()); // skip comments and empty lines if ((line[0] == '#') || (line.length() == 0)) // can be true only on last line of file @@ -709,28 +717,28 @@ public: { while (from!=length && (line[from]==' ' || line[from]=='\t' || line[from]=='\r') ) from++; - if(from!=length) - { + 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 (from2) - { - if(line[0]=='v') - { - if(line[1]==' ') oi.numVertices++; - if(line[1]=='t') oi.numTexCoords++; - if(line[1]=='n') bHasNormals = true; - } - else + { + if(line[0]=='v') + { + if(line[1]==' ') oi.numVertices++; + if(line[1]=='t') oi.numTexCoords++; + if(line[1]=='n') { + oi.numNormals ++; + bHasNormals = true; + } + } + else { if((line[0]=='f') || (line[0]=='q')) oi.numFaces++; - else + else if(line[0]=='u' && line[1]=='s') bHasPerFaceColor = true; // there is a usematerial so add per face color } + } } oi.mask = 0; if (oi.numTexCoords) - { - 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; - } - if(bHasPerFaceColor) oi.mask |= vcg::tri::io::Mask::IOM_FACECOLOR; - if (bHasNormals) oi.mask |= vcg::tri::io::Mask::IOM_WEDGNORMAL; + { + if (oi.numTexCoords==oi.numVertices) + oi.mask |= vcg::tri::io::Mask::IOM_VERTTEXCOORD; - return true; + 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; + } + if(bHasPerFaceColor) oi.mask |= vcg::tri::io::Mask::IOM_FACECOLOR; + if (bHasNormals) { + if (oi.numTexCoords==oi.numVertices) + oi.mask |= vcg::tri::io::Mask::IOM_VERTNORMAL; + else + oi.mask |= vcg::tri::io::Mask::IOM_WEDGNORMAL; + } + + return true; } static bool LoadMask(const char * filename, int &mask) { - Info oi; - bool ret=LoadMask(filename, oi); - mask= oi.mask; - return ret; + Info oi; + bool ret=LoadMask(filename, oi); + mask= oi.mask; + return ret; } static bool LoadMaterials(const char * filename, std::vector &materials, std::vector &textures) @@ -944,7 +965,7 @@ public: else first = false; //strcpy(currentMaterial.name, tokens[1].c_str()); - if(tokens.size() < 2) + if(tokens.size() < 2) return false; currentMaterial.materialName=tokens[1]; } @@ -962,7 +983,7 @@ public: float g = (float) atof(tokens[2].c_str()); float b = (float) atof(tokens[3].c_str()); - currentMaterial.Kd = Point3f(r, g, b); + currentMaterial.Kd = Point3f(r, g, b); } else if (header.compare("Ks")==0) { @@ -970,12 +991,12 @@ public: float g = (float) atof(tokens[2].c_str()); float b = (float) atof(tokens[3].c_str()); - currentMaterial.Ks = Point3f(r, g, b); + currentMaterial.Ks = Point3f(r, g, b); } else if ( (header.compare("d")==0) || - (header.compare("Tr")==0) ) // alpha + (header.compare("Tr")==0) ) // alpha { - currentMaterial.Tr = (float) atof(tokens[1].c_str()); + currentMaterial.Tr = (float) atof(tokens[1].c_str()); } else if (header.compare("Ns")==0) // shininess { @@ -984,14 +1005,14 @@ public: else if (header.compare("illum")==0) // specular illumination on/off { int illumination = atoi(tokens[1].c_str()); - //currentMaterial.bSpecular = (illumination == 2); - currentMaterial.illum = illumination; + //currentMaterial.bSpecular = (illumination == 2); + currentMaterial.illum = illumination; } else if( (header.compare("map_Kd")==0) || (header.compare("map_Ka")==0) ) // texture name { std::string textureName = tokens[1]; //strcpy(currentMaterial.textureFileName, textureName.c_str()); - currentMaterial.map_Kd=textureName; + currentMaterial.map_Kd=textureName; // adding texture name into textures vector (if not already present) // avoid adding the same name twice diff --git a/wrap/io_trimesh/import_ply.h b/wrap/io_trimesh/import_ply.h index 48c5c152..798d99f5 100644 --- a/wrap/io_trimesh/import_ply.h +++ b/wrap/io_trimesh/import_ply.h @@ -762,7 +762,7 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi ) if( pi.mask & Mask::IOM_VERTTEXCOORD ) { (*vi).T().P().X() = va.u; - (*vi).T().P().Y() = va.v; + (*vi).T().P().Y() = 1.0-va.v; // because "v" attr comes from "t" } if( pi.mask & Mask::IOM_VERTCOLOR )