diff --git a/include/Algo/Import/importObjTex.hpp b/include/Algo/Import/importObjTex.hpp index 0ff5f2f39b98edfbc70e14a0527a74d6dcc1216b..0748d35c4fc6cf065a12776b78d40eabcd4a8f28 100644 --- a/include/Algo/Import/importObjTex.hpp +++ b/include/Algo/Import/importObjTex.hpp @@ -22,7 +22,9 @@ * * *******************************************************************************/ -#include "texCoord2.h" +#include "Topology/generic/mapBrowser.h" +#include "Topology/generic/cellmarker.h" + namespace CGoGN { @@ -33,6 +35,442 @@ namespace Surface namespace Import { + +short readObjLine(std::stringstream& oss, std::vector& indices) +{ + unsigned int nb=0; + while (!oss.eof()) // lecture de tous les indices + { + int index; + oss >> index; + + indices.push_back(index); + + int slash = 0; + char sep='_'; + do + { + oss >> sep; + if (sep =='/') + ++slash; + } while ( ((sep=='/') || (sep ==' ')) && !oss.eof() ) ; + + if ((sep>='0') && (sep<='9')) + oss.seekg(-1,std::ios_base::cur); + + if (slash == 0) + { + if (indices.size()%3 == 1) + { + indices.push_back(0); + indices.push_back(0); + } + if (indices.size()%3 == 2) + { + indices.push_back(0); + } + nb++; + } + + + if (slash == 2) + { + indices.push_back(0); + } + } + return nb; +} + + +template +bool importObjTex(typename PFP::MAP& map, const std::string& filename, + std::vector& attrNames, std::vector& browsers, CellMarker& markV ) +{ + typedef typename PFP::VEC3 VEC3; + typedef Geom::Vec2f VEC2; + + attrNames.clear(); + browsers.clear(); +// parse file + // open file + std::ifstream fp(filename.c_str(), std::ios::binary); + if (!fp.good()) + { + CGoGNerr << "Unable to open file " << filename << CGoGNendl; + return false; + } + + unsigned int tagV = 0; + unsigned int tagVT = 0; + unsigned int tagVN = 0; + unsigned int tagG = 0; + unsigned int tagF = 0; + + std::string ligne; + std::string tag; + do + { + fp >> tag; + std::getline (fp, ligne); + if (tag == "v") + tagV++; + if (tag == "vn") + tagVN++; + if (tag == "vt") + tagVT++; + if (tag == "g") + tagG++; + if (tag == "f") + tagF++; + }while (!fp.eof()); + + std::cout << "Parsing OBJ"<< tagV<< std::endl; + std::cout << "Vertices:"<< tagV<< std::endl; + std::cout << "Normals:"<< tagVN<< std::endl; + std::cout << "TexCoords:"<< tagVT<< std::endl; + std::cout << "Groups:"<< tagG<< std::endl; + std::cout << "Faces:"<< tagF<< std::endl; + + + VertexAttribute positions = m_map.template getAttribute("position") ; + if (!positions.isValid()) + positions = m_map.template addAttribute("position") ; + attrNames.push_back(positions.name()) ; + + if (tagVN != 0) + { + VertexAttribute normals = m_map.template getAttribute("normal") ; + if (!normals.isValid()) + normals = m_map.template addAttribute("normal") ; + attrNames.push_back(normals.name()) ; + + AttributeHandler normalsF = m_map.template getAttribute("normalF") ; + if (!normalsF.isValid()) + normalsF = m_map.template addAttribute("normalF") ; + } + + if (tagVT != 0) + { + VertexAttribute texCoords = m_map.template getAttribute("texCoord") ; + if (!texCoords.isValid()) + texCoords = m_map.template addAttribute("texCoord") ; + attrNames.push_back(texCoords.name()) ; + + AttributeHandler texCoordsF = m_map.template getAttribute("texCoordF") ; + if (!texCoordsF.isValid()) + texCoordsF = m_map.template addAttribute("texCoordF") ; + } + + if (tagG != 0) + browsers.reserve(tagG); + + AttributeContainer& container = m_map.template getAttributeContainer() ; + + fp.close(); + fp.clear(); + fp.open(filename.c_str()); + + std::vector normalsBuffer; + std::vector texCoordsBuffer; + std::vector verticesID; + std::vector noramlsID; + std::vector texCoordsID; + + normalsBuffer.reserve(tagVN); + texCoordsBuffer.reserve(tagVT); + verticesID.reserve(tagV); // approx + noramlsID.reserve(tagV); + texCoordsID.reserve(tagV); + + std::vector localIndices; + localIndices.reserve(64*3); + FunctorInitEmb fsetemb(map); + + VertexAutoAttribute< NoMathIONameAttribute< std::vector > > vecDartsPerVertex(map, "incidents"); + VertexAutoAttribute< NoMathIONameAttribute< std::vector > > vecNormIndPerVertex(map, "incidentsN"); + VertexAutoAttribute< NoMathIONameAttribute< std::vector > > vecTCIndPerVertex(map, "incidentsTC"); + + + unsigned int i = 0; + fp >> tag; + std::getline(fp, ligne); + do + { + if (tag == std::string("v")) + { + std::stringstream oss(ligne); + + float x,y,z; + oss >> x; + oss >> y; + oss >> z; + + VEC3 pos(x,y,z); + + unsigned int id = container.insertLine(); + positions[id] = pos; + + verticesID.push_back(id); + i++; + } + + if (tag == std::string("vn")) + { + std::stringstream oss(ligne); + + VEC3 norm; + oss >> norm[0]; + oss >> norm[1]; + oss >> norm[2]; + normalsBuffer.push_back(norm); + } + + if (tag == std::string("vt")) + { + std::stringstream oss(ligne); + VEC2 tc; + oss >> tc[0]; + oss >> tc[1]; + texcoordsBuffer.push_back(tc); + } + + if (tag == std::string("g")) + { + currentBrowser = new MapBrowserLinked(map); + browsers.push_back(); + } + + if (tag == std::string("f")) + { + std::stringstream oss(ligne); + + short nbe = readObjLine(oss,localIndices); + + Dart d = map.newFace(nbe, false); + for (short j = 0; j < nbe; ++j) + { + unsigned int em = localIndices[3*j]-1; // get embedding + fsetemb.changeEmb(em) ; + map.template foreach_dart_of_orbit(d, fsetemb); + m.mark(d) ; // mark on the fly to unmark on second loop + vecDartsPerVertex[em].push_back(d); // store incident darts for fast adjacency reconstruction + vecTCIndPerVertex[em].push_back(localIndices[3*j+1]-1); + vecNormIndPerVertex[em].push_back(localIndices[3*j+2]-1); + d = map.phi1(d); + } + } + fp >> tag; + std::getline(fp, ligne); + } while (!fp.eof()); + + + + // reconstruct neighbourhood + unsigned int nbBoundaryEdges = 0; + for (Dart d = map.begin(); d != map.end(); map.next(d)) + { + if (m.isMarked(d)) + { + // darts incident to end vertex of edge + std::vector& vec = vecDartsPerVertex[map.phi1(d)]; + + unsigned int embd = map.template getEmbedding(d); + Dart good_dart = NIL; + for (typename std::vector::iterator it = vec.begin(); it != vec.end() && good_dart == NIL; ++it) + { + if (map.template getEmbedding(map.phi1(*it)) == embd) + good_dart = *it; + } + + if (good_dart != NIL) + { + map.sewFaces(d, good_dart, false); + m.unmarkOrbit(d); + } + else + { + m.unmark(d); + ++nbBoundaryEdges; + } + } + } + + TraversorV tra(map); + for (Dart d = tra.begin(); d != tra.end(); d = tra.next()) + { + std::vector& vec = vecDartsPerVertex[d]; + std::vector& vtc = vecTCIndPerVertex[d]; + std::vector& vn = vecNormIndPerVertex[d]; + + // test if normal vertex or multi-attrib vertex + unsigned int nb = vtc.size(); + bool same=true; + for (unsigned int j=1; (j> tag; +//// std::getline (fp, ligne); +//// }while (tag != std::string("v")); + +// // lecture des sommets +// std::vector verticesID; +// verticesID.reserve(102400); // on tape large (400Ko wahouuuuu !!) + +// m_texcoordsBuffer.reserve(102400); + +// m_normalsBuffer.reserve(102400); + +// unsigned int i = 0; +// do +// { +// if (tag == std::string("v")) +// { +// std::stringstream oss(ligne); + +// float x,y,z; +// oss >> x; +// oss >> y; +// oss >> z; + +// VEC3 pos(x,y,z); + +// unsigned int id = container.insertLine(); +// positions[id] = pos; + +// verticesID.push_back(id); +// i++; +// } + +// if (tag == std::string("vn")) +// { +// std::stringstream oss(ligne); + +// VEC3 norm; +// oss >> norm[0]; +// oss >> norm[1]; +// oss >> norm[2]; +// m_normalsBuffer.push_back(norm); +// } + +// if (tag == std::string("vt")) +// { +// std::stringstream oss(ligne); +// VEC2 tc; +// oss >> tc[0]; +// oss >> tc[1]; +// m_texcoordsBuffer.push_back(tc); +// } + +// fp >> tag; +// std::getline(fp, ligne); +// } while (!fp.eof()); + +// m_nbVertices = verticesID.size(); + +// // close/clear/open only way to go back to beginning of file +// fp.close(); +// fp.clear(); +// fp.open(filename.c_str()); + +// do +// { +// fp >> tag; +// std::getline (fp, ligne); +// } while (tag != std::string("f")); + +// m_nbEdges.reserve(verticesID.size()*2); +// m_emb.reserve(verticesID.size()*8); + +// std::vector table; +// table.reserve(64); // NBV cotes pour une face devrait suffire +// m_nbFaces = 0; +// do +// { +// if (tag == std::string("f")) // lecture d'une face +// { +// std::stringstream oss(ligne); +// table.clear(); +// while (!oss.eof()) // lecture de tous les indices +// { +// std::string str; +// oss >> str; + +// unsigned int ind = 0; + +//// TODO A MODIFIER POUR LIRE P/T/N ou P//N ou P/T ... + +// while ((ind 0) +// { +// long index; +// std::stringstream iss(str.substr(0, ind)); +// iss >> index; +// table.push_back(index); +// } +// } + +// unsigned int n = table.size(); +// m_nbEdges.push_back(short(n)); +// for (unsigned int j = 0; j < n; ++j) +// { +// int index = table[j] - 1; // les index commencent a 1 (boufonnerie d'obj ;) +// m_emb.push_back(verticesID[index]); +// } +// m_nbFaces++; +// } +// fp >> tag; +// std::getline(fp, ligne); +// } while (!fp.eof()); + +// fp.close (); +// return true; +} + + + + + + + + + + + template bool importObjWithTex(typename PFP::MAP& map, const std::string& filename) {