/******************************************************************************* * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * version 0.1 * * Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg * * * * This library is free software; you can redistribute it and/or modify it * * under the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation; either version 2.1 of the License, or (at your * * option) any later version. * * * * This library is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * * for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this library; if not, write to the Free Software Foundation, * * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * * * Web site: http://cgogn.unistra.fr/ * * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ #include "Topology/generic/attributeHandler.h" #include "Topology/generic/autoAttributeHandler.h" #include "Container/fakeAttribute.h" #include #include namespace CGoGN { namespace Algo { namespace Surface { namespace Import { template OBJModel::OBJModel(typename PFP::MAP& map): m_map(map), m_maxTextureSize(2048), m_tagV(0),m_tagVT(0),m_tagVN(0),m_tagG(0),m_tagF(0), m_specialVertices(map),m_dirtyEdges(map) { } template OBJModel::~OBJModel() { for (std::vector::iterator it = m_materials.begin(); it != m_materials.end(); ++it) delete *it; } template inline void OBJModel::setMaxTextureSize(unsigned int mts) { m_maxTextureSize = mts; } template inline typename PFP::VEC3 OBJModel::getPosition(Dart d) { return m_positions[d]; } template inline typename PFP::VEC3 OBJModel::getNormal(Dart d) { if (m_specialVertices.isMarked(d)) return m_normalsF[d]; return m_normals[d]; } template inline Geom::Vec2f OBJModel::getTexCoord(Dart d) { if (m_specialVertices.isMarked(d)) return m_texCoordsF[d]; return m_texCoords[d]; } template void OBJModel::setPositionAttribute(VertexAttribute position) { m_positions = position; } template void OBJModel::setNormalAttribute(VertexAttribute normal) { m_normals = normal; } template void OBJModel::setTexCoordAttribute(VertexAttributetexcoord) { m_texCoords = texcoord; } template void OBJModel::readMaterials(const std::string& filename) { m_materials.reserve(m_materialNames.size()); if (!filename.empty()) { m_matFileName = filename; } // open file std::ifstream fp(m_matFileName.c_str()); if (!fp.good()) { CGoGNerr << "Unable to open file " << m_matFileName << CGoGNendl; return ; } MaterialOBJ* currentMat = NULL; m_materials.resize(m_materialNames.size(),NULL); std::string ligne; do { std::getline (fp, ligne); std::stringstream oss(ligne); std::string tag; oss >> tag; if (tag == "newmtl") { std::string name; oss >> name ; std::map::iterator it = m_materialNames.find(name); if (it == m_materialNames.end()) { CGoGNerr << "Skipping material "<< name << CGoGNendl; do { fp >> tag; }while (!fp.eof() && (tag == "new mtl")); } else { CGoGNout << "Reading material "<< name << CGoGNendl; currentMat = new MaterialOBJ(); m_materials[it->second] = currentMat; currentMat->name = name; } } else if (currentMat != NULL) { if (tag == "Ka") { oss >> currentMat->ambiantColor[0]; oss >> currentMat->ambiantColor[1]; oss >> currentMat->ambiantColor[2]; } if (tag == "Kd") { oss >> currentMat->diffuseColor[0]; oss >> currentMat->diffuseColor[1]; oss >> currentMat->diffuseColor[2]; } if (tag == "Ks") { oss >> currentMat->specularColor[0]; oss >> currentMat->specularColor[1]; oss >> currentMat->specularColor[2]; } if (tag == "Ns") { oss >> currentMat->shininess; } if (tag == "Tf") { oss >> currentMat->transparentFilter[0]; oss >> currentMat->transparentFilter[1]; oss >> currentMat->transparentFilter[2]; } if ((tag == "illum")) { oss >> currentMat->illuminationModel; } if ((tag == "Tr") || (tag == "d")) { oss >> currentMat->transparency; } if (tag == "map_Kd") // diffuse texture { if (currentMat->textureDiffuse == NULL) { currentMat->textureDiffuse = new Utils::Texture<2,Geom::Vec3uc>(GL_UNSIGNED_BYTE); std::string buff; getline (oss, buff); std::string tname = buff.substr(buff.find_first_not_of(' ')); if (tname[tname.length()-1] == '\r') tname = tname.substr(0,tname.length()-1); currentMat->textureDiffuse->load(m_matPath+tname); CGoGNout << "Loading texture "<< m_matPath+tname << " -> "<textureDiffuse <textureDiffuse->scaleNearest( currentMat->textureDiffuse->newMaxSize(m_maxTextureSize)); currentMat->textureDiffuse->setFiltering(GL_LINEAR); currentMat->textureDiffuse->setWrapping(GL_REPEAT); currentMat->textureDiffuse->update(); } } if (tag == "map_Ka") // ambiant texture { // CGoGNerr << tag << " not yet supported in OBJ material reading" << CGoGNendl; if (currentMat->textureDiffuse == NULL) { currentMat->textureDiffuse = new Utils::Texture<2,Geom::Vec3uc>(GL_UNSIGNED_BYTE); std::string buff; getline (oss, buff); std::string tname = buff.substr(buff.find_first_not_of(' ')); if (tname[tname.length()-1] == '\r') tname = tname.substr(0,tname.length()-1); currentMat->textureDiffuse->load(m_matPath+tname); CGoGNout << "Loading texture "<< m_matPath+tname << " -> "<textureDiffuse <textureDiffuse->scaleNearest( currentMat->textureDiffuse->newMaxSize(m_maxTextureSize)); currentMat->textureDiffuse->setFiltering(GL_LINEAR); currentMat->textureDiffuse->setWrapping(GL_REPEAT); currentMat->textureDiffuse->update(); } } if (tag == "map_d") // opacity texture { CGoGNerr << tag << " not yet supported in OBJ material reading" << CGoGNendl; } if ((tag == "map_bump") || (tag == "bump")) { CGoGNerr << tag << " not yet supported in OBJ material reading" << CGoGNendl; } tag=""; } }while (!fp.eof()); for (std::vector::iterator it = m_materials.begin(); it != m_materials.end(); ++it) { if (*it == NULL) CGoGNerr << "Warning missing material in .mtl"<< CGoGNendl; } } template unsigned int OBJModel::getMaterialIndex(const std::string& name) const { std::map::iterator it = m_materialNames.find(name); if (it != m_materialNames.end()) return it->second; return 0xffffffff; } //template //bool OBJModel::generateBrowsers(std::vector& browsers) //{ // browsers.clear(); // if (m_groupNames.empty()) // return false; // ContainerBrowserLinked* MBLptr = new ContainerBrowserLinked(m_map,DART); // browsers.push_back(MBLptr); // for (unsigned int i = 1; i(browsers[g]); // mb->pushBack(d.index); // } // return true; //} template short OBJModel::readObjLine(std::stringstream& oss, std::vector& indices) { indices.clear(); 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 unsigned int OBJModel::createSimpleVBO_P(Utils::VBO* positionVBO) { TraversorF traf(m_map); std::vector posBuff; posBuff.reserve(16384); unsigned int nbtris = 0; for (Dart d=traf.begin(); d!= traf.end(); d = traf.next()) { Dart e = m_map.phi1(d); Dart f = m_map.phi1(e); do { posBuff.push_back(m_positions[d]); posBuff.push_back(m_positions[e]); posBuff.push_back(m_positions[f]); e=f; f = m_map.phi1(e); nbtris++; }while (f!=d); } positionVBO->setDataSize(3); positionVBO->allocate(posBuff.size()); Geom::Vec3f* ptrPos = reinterpret_cast(positionVBO->lockPtr()); memcpy(ptrPos,&posBuff[0],posBuff.size()*sizeof(Geom::Vec3f)); positionVBO->releasePtr(); return 3*nbtris; } template unsigned int OBJModel::createSimpleVBO_PT(Utils::VBO* positionVBO, Utils::VBO* texcoordVBO) { TraversorF traf(m_map); std::vector posBuff; std::vector TCBuff; posBuff.reserve(16384); TCBuff.reserve(16384); unsigned int nbtris = 0; for (Dart d=traf.begin(); d!= traf.end(); d = traf.next()) { Dart e = m_map.phi1(d); Dart f = m_map.phi1(e); do { posBuff.push_back(m_positions[d]); if (m_specialVertices.isMarked(d)) TCBuff.push_back(m_texCoordsF[d]); else TCBuff.push_back(m_texCoords[d]); posBuff.push_back(m_positions[e]); if (m_specialVertices.isMarked(e)) TCBuff.push_back(m_texCoordsF[e]); else TCBuff.push_back(m_texCoords[e]); posBuff.push_back(m_positions[f]); if (m_specialVertices.isMarked(f)) TCBuff.push_back(m_texCoordsF[f]); else TCBuff.push_back(m_texCoords[f]); e=f; f = m_map.phi1(e); nbtris++; }while (f!=d); } positionVBO->setDataSize(3); positionVBO->allocate(posBuff.size()); Geom::Vec3f* ptrPos = reinterpret_cast(positionVBO->lockPtr()); memcpy(ptrPos,&posBuff[0],posBuff.size()*sizeof(Geom::Vec3f)); positionVBO->releasePtr(); texcoordVBO->setDataSize(2); texcoordVBO->allocate(TCBuff.size()); Geom::Vec2f* ptrTC = reinterpret_cast(texcoordVBO->lockPtr()); memcpy(ptrTC,&TCBuff[0],TCBuff.size()*sizeof(Geom::Vec2f)); texcoordVBO->releasePtr(); return 3*nbtris; } template unsigned int OBJModel::createSimpleVBO_PN(Utils::VBO* positionVBO, Utils::VBO* normalVBO ) { TraversorF traf(m_map); std::vector posBuff; std::vector normalBuff; posBuff.reserve(16384); normalBuff.reserve(16384); unsigned int nbtris = 0; for (Dart d=traf.begin(); d!= traf.end(); d = traf.next()) { Dart e = m_map.phi1(d); Dart f = m_map.phi1(e); do { posBuff.push_back(m_positions[d]); if (m_specialVertices.isMarked(d)) { normalBuff.push_back(m_normalsF[d]); } else { normalBuff.push_back(m_normals[d]); } posBuff.push_back(m_positions[e]); if (m_specialVertices.isMarked(e)) { normalBuff.push_back(m_normalsF[e]); } else { normalBuff.push_back(m_normals[e]); } posBuff.push_back(m_positions[f]); if (m_specialVertices.isMarked(f)) { normalBuff.push_back(m_normalsF[f]); } else { normalBuff.push_back(m_normals[f]); } e=f; f = m_map.phi1(e); nbtris++; }while (f!=d); } positionVBO->setDataSize(3); positionVBO->allocate(posBuff.size()); Geom::Vec3f* ptrPos = reinterpret_cast(positionVBO->lockPtr()); memcpy(ptrPos,&posBuff[0],posBuff.size()*sizeof(Geom::Vec3f)); positionVBO->releasePtr(); normalVBO->setDataSize(3); normalVBO->allocate(normalBuff.size()); Geom::Vec3f* ptrNormal = reinterpret_cast(normalVBO->lockPtr()); memcpy(ptrNormal, &normalBuff[0], normalBuff.size()*sizeof(Geom::Vec3f)); normalVBO->releasePtr(); return 3*nbtris; } template unsigned int OBJModel::createSimpleVBO_PTN(Utils::VBO* positionVBO, Utils::VBO* texcoordVBO, Utils::VBO* normalVBO ) { if (!m_normals.isValid()) { CGoGNerr << "no normal attribute "<< CGoGNendl; return 0; } if (!m_texCoords.isValid()) { CGoGNerr << "no tex coords attribute "<< CGoGNendl; return 0; } TraversorF traf(m_map); std::vector posBuff; std::vector TCBuff; std::vector normalBuff; posBuff.reserve(16384); TCBuff.reserve(16384); normalBuff.reserve(16384); unsigned int nbtris = 0; for (Dart d=traf.begin(); d!= traf.end(); d = traf.next()) { Dart e = m_map.phi1(d); Dart f = m_map.phi1(e); do { posBuff.push_back(m_positions[d]); if (m_specialVertices.isMarked(d)) { if (hasTexCoords()) TCBuff.push_back(m_texCoordsF[d]); else TCBuff.push_back(m_texCoords[d]); if (hasNormals()) normalBuff.push_back(m_normalsF[d]); else normalBuff.push_back(m_normals[d]); } else { TCBuff.push_back(m_texCoords[d]); normalBuff.push_back(m_normals[d]); } posBuff.push_back(m_positions[e]); if (m_specialVertices.isMarked(e)) { if (hasTexCoords()) TCBuff.push_back(m_texCoordsF[e]); else TCBuff.push_back(m_texCoords[e]); if (hasNormals()) normalBuff.push_back(m_normalsF[e]); else normalBuff.push_back(m_normals[e]); } else { TCBuff.push_back(m_texCoords[e]); normalBuff.push_back(m_normals[e]); } posBuff.push_back(m_positions[f]); if (m_specialVertices.isMarked(f)) { if (hasTexCoords()) TCBuff.push_back(m_texCoordsF[f]); else TCBuff.push_back(m_texCoords[f]); if (hasNormals()) normalBuff.push_back(m_normalsF[f]); else normalBuff.push_back(m_normals[f]); } else { TCBuff.push_back(m_texCoords[f]); normalBuff.push_back(m_normals[f]); } e=f; f = m_map.phi1(e); nbtris++; }while (f!=d); } positionVBO->setDataSize(3); positionVBO->allocate(posBuff.size()); Geom::Vec3f* ptrPos = reinterpret_cast(positionVBO->lockPtr()); memcpy(ptrPos,&posBuff[0],posBuff.size()*sizeof(Geom::Vec3f)); positionVBO->releasePtr(); texcoordVBO->setDataSize(2); texcoordVBO->allocate(TCBuff.size()); Geom::Vec2f* ptrTC = reinterpret_cast(texcoordVBO->lockPtr()); memcpy(ptrTC,&TCBuff[0],TCBuff.size()*sizeof(Geom::Vec2f)); texcoordVBO->releasePtr(); normalVBO->setDataSize(3); normalVBO->allocate(normalBuff.size()); Geom::Vec3f* ptrNormal = reinterpret_cast(normalVBO->lockPtr()); memcpy(ptrNormal, &normalBuff[0], normalBuff.size()*sizeof(Geom::Vec3f)); normalVBO->releasePtr(); return 3*nbtris; } template bool OBJModel::createGroupMatVBO_P(Utils::VBO* positionVBO) { m_beginIndices.clear(); m_nbIndices.clear(); std::vector posBuff; posBuff.reserve(16384); std::vector< std::vector > group_faces(m_materialNames.size()); TraversorF traf(m_map); for (Dart d=traf.begin(); d!= traf.end(); d = traf.next()) { unsigned int g = m_attMat[d]; group_faces[g].push_back(d); } unsigned int firstIndex = 0; unsigned int sz = group_faces.size(); m_beginIndices.resize(sz); m_nbIndices.resize(sz); m_groupIdx.resize(sz); for (unsigned int g=0; g& traf = group_faces[g]; if (m_tagG != 0) m_groupIdx[g] = m_groups[traf.front()]; else m_groupIdx[g]=0; for (std::vector::iterator id=traf.begin(); id!= traf.end(); ++id) { Dart d = *id; Dart e = m_map.phi1(d); Dart f = m_map.phi1(e); do { posBuff.push_back(m_positions[d]); posBuff.push_back(m_positions[e]); posBuff.push_back(m_positions[f]); e=f; f = m_map.phi1(e); nbtris++; }while (f!=d); } m_beginIndices[g] = firstIndex; m_nbIndices[g] = 3*nbtris; firstIndex += 3*nbtris; } positionVBO->setDataSize(3); positionVBO->allocate(posBuff.size()); Geom::Vec3f* ptrPos = reinterpret_cast(positionVBO->lockPtr()); memcpy(ptrPos,&posBuff[0],posBuff.size()*sizeof(Geom::Vec3f)); positionVBO->releasePtr(); updateGroups(); return true; } template bool OBJModel::createGroupMatVBO_PT(Utils::VBO* positionVBO, Utils::VBO* texcoordVBO) { m_beginIndices.clear(); m_nbIndices.clear(); std::vector posBuff; std::vector TCBuff; posBuff.reserve(16384); TCBuff.reserve(16384); std::vector< std::vector > group_faces(m_materialNames.size()); TraversorF traf(m_map); for (Dart d=traf.begin(); d!= traf.end(); d = traf.next()) { unsigned int g = m_attMat[d]; group_faces[g].push_back(d); } unsigned int firstIndex = 0; unsigned int sz = group_faces.size(); m_beginIndices.resize(sz); m_nbIndices.resize(sz); m_groupIdx.resize(sz); for (unsigned int g=0; g& traf = group_faces[g]; if (m_tagG != 0) m_groupIdx[g] = m_groups[traf.front()]; else m_groupIdx[g]=0; for (std::vector::iterator id=traf.begin(); id!= traf.end(); ++id) { Dart d = *id; Dart e = m_map.phi1(d); Dart f = m_map.phi1(e); do { posBuff.push_back(m_positions[d]); if (m_specialVertices.isMarked(d)) TCBuff.push_back(m_texCoordsF[d]); else TCBuff.push_back(m_texCoords[d]); posBuff.push_back(m_positions[e]); if (m_specialVertices.isMarked(e)) TCBuff.push_back(m_texCoordsF[e]); else TCBuff.push_back(m_texCoords[e]); posBuff.push_back(m_positions[f]); if (m_specialVertices.isMarked(f)) TCBuff.push_back(m_texCoordsF[f]); else TCBuff.push_back(m_texCoords[f]); e=f; f = m_map.phi1(e); nbtris++; }while (f!=d); } m_beginIndices[g] = firstIndex; m_nbIndices[g] = 3*nbtris; firstIndex += 3*nbtris; } positionVBO->setDataSize(3); positionVBO->allocate(posBuff.size()); Geom::Vec3f* ptrPos = reinterpret_cast(positionVBO->lockPtr()); memcpy(ptrPos,&posBuff[0],posBuff.size()*sizeof(Geom::Vec3f)); positionVBO->releasePtr(); texcoordVBO->setDataSize(2); texcoordVBO->allocate(TCBuff.size()); Geom::Vec2f* ptrTC = reinterpret_cast(texcoordVBO->lockPtr()); memcpy(ptrTC,&TCBuff[0],TCBuff.size()*sizeof(Geom::Vec2f)); texcoordVBO->releasePtr(); updateGroups(); return true; } template bool OBJModel::createGroupMatVBO_PN(Utils::VBO* positionVBO, Utils::VBO* normalVBO) { m_beginIndices.clear(); m_nbIndices.clear(); std::vector posBuff; std::vector normalBuff; posBuff.reserve(16384); normalBuff.reserve(16384); std::vector< std::vector > group_faces(m_materialNames.size()); TraversorF traf(m_map); for (Dart d=traf.begin(); d!= traf.end(); d = traf.next()) { unsigned int g = m_attMat[d]; group_faces[g].push_back(d); } unsigned int firstIndex = 0; unsigned int sz = group_faces.size(); m_beginIndices.resize(sz); m_nbIndices.resize(sz); m_groupIdx.resize(sz); for (unsigned int g=0; g& traf = group_faces[g]; if (m_tagG != 0) m_groupIdx[g] = m_groups[traf.front()]; else m_groupIdx[g]=0; for (std::vector::iterator id=traf.begin(); id!= traf.end(); ++id) { Dart d = *id; Dart e = m_map.phi1(d); Dart f = m_map.phi1(e); do { posBuff.push_back(m_positions[d]); if (m_specialVertices.isMarked(d)) { normalBuff.push_back(m_normalsF[d]); } else { normalBuff.push_back(m_normals[d]); } posBuff.push_back(m_positions[e]); if (m_specialVertices.isMarked(e)) { normalBuff.push_back(m_normalsF[e]); } else { normalBuff.push_back(m_normals[e]); } posBuff.push_back(m_positions[f]); if (m_specialVertices.isMarked(f)) { normalBuff.push_back(m_normalsF[f]); } else { normalBuff.push_back(m_normals[f]); } e=f; f = m_map.phi1(e); nbtris++; }while (f!=d); } m_beginIndices[g] = firstIndex; m_nbIndices[g] = 3*nbtris; firstIndex += 3*nbtris; } positionVBO->setDataSize(3); positionVBO->allocate(posBuff.size()); Geom::Vec3f* ptrPos = reinterpret_cast(positionVBO->lockPtr()); memcpy(ptrPos,&posBuff[0],posBuff.size()*sizeof(Geom::Vec3f)); positionVBO->releasePtr(); normalVBO->setDataSize(3); normalVBO->allocate(normalBuff.size()); Geom::Vec3f* ptrNormal = reinterpret_cast(normalVBO->lockPtr()); memcpy(ptrNormal, &normalBuff[0], normalBuff.size()*sizeof(Geom::Vec3f)); normalVBO->releasePtr(); updateGroups(); return true; } template bool OBJModel::createGroupMatVBO_PTN( Utils::VBO* positionVBO, Utils::VBO* texcoordVBO, Utils::VBO* normalVBO) { m_beginIndices.clear(); m_nbIndices.clear(); if (!m_normals.isValid()) { CGoGNerr << "no normal attribute "<< CGoGNendl; return false; } if (!m_texCoords.isValid()) { CGoGNerr << "no tex coords attribute "<< CGoGNendl; return false; } std::vector posBuff; std::vector TCBuff; std::vector normalBuff; posBuff.reserve(16384); TCBuff.reserve(16384); normalBuff.reserve(16384); std::vector< std::vector > group_faces(m_materialNames.size()); TraversorF traf(m_map); for (Dart d=traf.begin(); d!= traf.end(); d = traf.next()) { unsigned int g = m_attMat[d]; group_faces[g].push_back(d); } unsigned int firstIndex = 0; unsigned int sz = group_faces.size(); m_beginIndices.resize(sz); m_nbIndices.resize(sz); m_groupIdx.resize(sz); for (unsigned int g=0; g& traf = group_faces[g]; if (m_tagG != 0) m_groupIdx[g] = m_groups[traf.front()]; else m_groupIdx[g]=0; for (std::vector::iterator id=traf.begin(); id!= traf.end(); ++id) { Dart d = *id; Dart e = m_map.phi1(d); Dart f = m_map.phi1(e); do { posBuff.push_back(m_positions[d]); // if (m_specialVertices.isMarked(d)) { if (hasTexCoords()) TCBuff.push_back(m_texCoordsF[d]); else TCBuff.push_back(m_texCoords[d]); if (hasNormals()) normalBuff.push_back(m_normalsF[d]); else normalBuff.push_back(m_normals[d]); } // else // { // TCBuff.push_back(m_texCoords[d]); // normalBuff.push_back(m_normals[d]); // } posBuff.push_back(m_positions[e]); // if (m_specialVertices.isMarked(e)) { if (hasTexCoords()) TCBuff.push_back(m_texCoordsF[e]); else TCBuff.push_back(m_texCoords[e]); if (hasNormals()) normalBuff.push_back(m_normalsF[e]); else normalBuff.push_back(m_normals[e]); } // else // { // TCBuff.push_back(m_texCoords[e]); // normalBuff.push_back(m_normals[e]); // } posBuff.push_back(m_positions[f]); // if (m_specialVertices.isMarked(f)) { if (hasTexCoords()) TCBuff.push_back(m_texCoordsF[f]); else TCBuff.push_back(m_texCoords[f]); if (hasNormals()) normalBuff.push_back(m_normalsF[f]); else normalBuff.push_back(m_normals[f]); } // else // { // TCBuff.push_back(m_texCoords[f]); // normalBuff.push_back(m_normals[f]); // } e=f; f = m_map.phi1(e); nbtris++; }while (f!=d); } m_beginIndices[g] = firstIndex; m_nbIndices[g] = 3*nbtris; firstIndex += 3*nbtris; } positionVBO->setDataSize(3); positionVBO->allocate(posBuff.size()); Geom::Vec3f* ptrPos = reinterpret_cast(positionVBO->lockPtr()); memcpy(ptrPos,&posBuff[0],posBuff.size()*sizeof(Geom::Vec3f)); positionVBO->releasePtr(); texcoordVBO->setDataSize(2); texcoordVBO->allocate(TCBuff.size()); Geom::Vec2f* ptrTC = reinterpret_cast(texcoordVBO->lockPtr()); memcpy(ptrTC,&TCBuff[0],TCBuff.size()*sizeof(Geom::Vec2f)); texcoordVBO->releasePtr(); normalVBO->setDataSize(3); normalVBO->allocate(normalBuff.size()); Geom::Vec3f* ptrNormal = reinterpret_cast(normalVBO->lockPtr()); memcpy(ptrNormal, &normalBuff[0], normalBuff.size()*sizeof(Geom::Vec3f)); normalVBO->releasePtr(); updateGroups(posBuff); return true; } template void OBJModel::updateGroups(const std::vector& pos) { unsigned int sz = m_beginIndices.size(); unsigned int i=0; do { m_objGroups.push_back(i); m_groupBBs.resize(m_objGroups.size()); Geom::BoundingBox& bb = m_groupBBs.back(); unsigned int grp = m_groupIdx[i]; while ((i bool OBJModel::import( const std::string& filename, std::vector& attrNames) { typedef typename PFP::VEC3 VEC3; typedef Geom::Vec2f VEC2; attrNames.clear(); // open file std::ifstream fp(filename.c_str()/*, std::ios::binary*/); if (!fp.good()) { CGoGNerr << "Unable to open file " << filename << CGoGNendl; return false; } std::string ligne; std::string tag; do { std::getline (fp, ligne); std::stringstream oss(ligne); oss >> tag; if (tag == "v") m_tagV++; if (tag == "vn") m_tagVN++; if (tag == "vt") m_tagVT++; if ((tag == "g") || (tag == "o")) m_tagG++; if (tag == "f") m_tagF++; if (tag == "mtllib") { unsigned found = filename.find_last_of("/\\"); std::string mtfn; oss >> mtfn; m_matPath = filename.substr(0,found) + "/"; m_matFileName = m_matPath + mtfn; } tag.clear(); }while (!fp.eof()); m_positions = m_map.template getAttribute("position") ; if (!m_positions.isValid()) m_positions = m_map.template addAttribute("position") ; attrNames.push_back(m_positions.name()) ; m_texCoords = m_map.template getAttribute("texCoord") ; if (!m_texCoords.isValid()) m_texCoords = m_map.template addAttribute("texCoord") ; attrNames.push_back(m_texCoords.name()) ; if (m_tagVT != 0) { m_texCoordsF = m_map.template getAttribute("texCoordF") ; if (!m_texCoordsF.isValid()) m_texCoordsF = m_map.template addAttribute("texCoordF") ; } m_normals = m_map.template getAttribute("normal") ; if (!m_normals.isValid()) m_normals = m_map.template addAttribute("normal") ; attrNames.push_back(m_normals.name()) ; if (m_tagVN != 0) { m_normalsF = m_map.template getAttribute("normalF") ; if (!m_normalsF.isValid()) m_normalsF = m_map.template addAttribute("normalF") ; } // if (m_tagG != 0) always use group even if not in the file { m_groups = m_map.template getAttribute("groups") ; if (!m_groups.isValid()) m_groups = m_map.template addAttribute("groups") ; attrNames.push_back(m_groups.name()) ; } m_attMat = m_map.template getAttribute("material") ; if (!m_attMat.isValid()) m_attMat = m_map.template addAttribute("material") ; attrNames.push_back(m_attMat.name()) ; AttributeContainer& container = m_map.template getAttributeContainer() ; fp.close(); fp.clear(); fp.open(filename.c_str()); std::vector normalsBuffer; normalsBuffer.reserve(m_tagVN); std::vector texCoordsBuffer; texCoordsBuffer.reserve(m_tagVT); std::vector verticesID; verticesID.reserve(m_tagV); std::vector normalsID; normalsID.reserve(m_tagV); std::vector texCoordsID; texCoordsID.reserve(m_tagV); std::vector localIndices; localIndices.reserve(64*3); FunctorInitEmb fsetemb(m_map); VertexAutoAttribute< NoTypeNameAttribute< std::vector > > vecDartsPerVertex(m_map, "incidents"); VertexAutoAttribute< NoTypeNameAttribute< std::vector > > vecNormIndPerVertex(m_map, "incidentsN"); VertexAutoAttribute< NoTypeNameAttribute< std::vector > > vecTCIndPerVertex(m_map, "incidentsTC"); unsigned int currentGroup = 0; unsigned int currentMat = 0; unsigned int nextMat = 0; DartMarkerNoUnmark mk(m_map) ; 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(); m_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("usemtl")) { std::stringstream oss(ligne); std::string matName; oss >> matName; std::map::iterator it = m_materialNames.find(matName); if (it==m_materialNames.end()) { m_materialNames.insert(std::pair(matName,nextMat)); currentMat = nextMat++; std::cout << "New Material Name = "<< matName << " index = "<< currentMat << std::endl; } else { currentMat = it->second; std::cout << "Using Material Name = "<< matName << " index = "<< currentMat << std::endl; } } if ( (tag == std::string("g")) && (tag == std::string("g")) ) { m_groupNames.push_back(ligne); currentGroup++; } if (tag == std::string("f")) { std::stringstream oss(ligne); short nbe = readObjLine(oss,localIndices); Dart d = m_map.newFace(nbe, false); if (m_tagG!=0) m_groups[d] = currentGroup; m_attMat[d] = currentMat; for (short j = 0; j < nbe; ++j) { unsigned int em = localIndices[3*j]-1; // get embedding fsetemb.changeEmb(em) ; m_map.template foreach_dart_of_orbit(d, fsetemb); mk.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 = m_map.phi1(d); } } fp >> tag; std::getline(fp, ligne); } while (!fp.eof()); fp.close (); // reconstruct neighbourhood unsigned int nbBoundaryEdges = 0; for (Dart d = m_map.begin(); d != m_map.end(); m_map.next(d)) { if (mk.isMarked(d)) { // darts incident to end vertex of edge std::vector& vec = vecDartsPerVertex[m_map.phi1(d)]; unsigned int embd = m_map.template getEmbedding(d); Dart good_dart = NIL; for (typename std::vector::iterator it = vec.begin(); it != vec.end() && good_dart == NIL; ++it) { if (m_map.template getEmbedding(m_map.phi1(*it)) == embd) good_dart = *it; } if (good_dart != NIL) { if (good_dart == m_map.phi2(good_dart) && (d == m_map.phi2(d))) m_map.sewFaces(d, good_dart, false); else m_dirtyEdges.mark(d); mk.unmarkOrbit(d); } else { mk.unmark(d); m_dirtyEdges.mark(d); ++nbBoundaryEdges; } } } // A SIMPLIFIER ??? TraversorV tra(m_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