/**************************************************************************** * MeshLab o o * * A versatile mesh processing toolbox o o * * _ O _ * * Copyright(C) 2005 \/)\/ * * Visual Computing Lab /\/| * * ISTI - Italian National Research Council | * * \ * * All rights reserved. * * * * 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. * * * * This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt) * * for more details. * * * ****************************************************************************/ #include #include #include #include "meshmodel.h" #include using namespace vcg; MeshModel *MeshDocument::getMesh(const char *name) { foreach(MeshModel *mmp, meshList) { if(mmp->shortName() == name) return mmp; } assert(0); return 0; } void MeshDocument::setCurrentMesh(unsigned int i) { assert(i < (unsigned int)meshList.size()); currentMesh=meshList.at(i); emit currentMeshChanged(i); } MeshModel *MeshDocument::addNewMesh(const char *meshName, MeshModel *newMesh) { QString newName=meshName; for(QList::iterator mmi=meshList.begin();mmi!=meshList.end();++mmi) { if((*mmi)->shortName() == newName) newName = newName+"_copy"; } if(newMesh==0) newMesh=new MeshModel(qPrintable(newName)); else newMesh->setFileName(newName); meshList.push_back(newMesh); currentMesh=meshList.back(); emit currentMeshChanged(meshList.size()-1); return newMesh; } bool MeshDocument::delMesh(MeshModel *mmToDel) { if(meshList.size()==1) return false; QMutableListIterator i(meshList); while (i.hasNext()) { MeshModel *md = i.next(); if (md==mmToDel) { i.remove(); delete mmToDel; } } if(currentMesh == mmToDel) { setCurrentMesh(0); } return true; } bool MeshModel::Render(vcg::GLW::DrawMode _dm, vcg::GLW::ColorMode _cm, vcg::GLW::TextureMode _tm) { // Needed to be defined here for splatrender as long there is no "MeshlabCore" library. using namespace vcg; glPushMatrix(); glMultMatrix(cm.Tr); if( (_cm == GLW::CMPerFace) && (!tri::HasPerFaceColor(cm)) ) _cm=GLW::CMNone; if( (_tm == GLW::TMPerWedge )&& (!tri::HasPerWedgeTexCoord(cm)) ) _tm=GLW::TMNone; if( (_tm == GLW::TMPerWedgeMulti )&& (!tri::HasPerWedgeTexCoord(cm)) ) _tm=GLW::TMNone; glw.Draw(_dm,_cm,_tm); glPopMatrix(); return true; } bool MeshModel::RenderSelectedFace() { glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT ); glEnable(GL_POLYGON_OFFSET_FILL); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); glDepthMask(GL_FALSE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; glColor4f(1.0f,0.0,0.0,.3f); glPolygonOffset(-1.0, -1); CMeshO::FaceIterator fi; glPushMatrix(); glMultMatrix(cm.Tr);glBegin(GL_TRIANGLES); cm.sfn=0; for(fi=cm.face.begin();fi!=cm.face.end();++fi) if(!(*fi).IsD() && (*fi).IsS()) { glVertex((*fi).cP(0)); glVertex((*fi).cP(1)); glVertex((*fi).cP(2)); ++cm.sfn; } glEnd(); glPopMatrix(); glPopAttrib(); return true; } bool MeshModel::RenderSelectedVert() { glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT ); glEnable(GL_POLYGON_OFFSET_FILL); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); glDepthMask(GL_FALSE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; glColor4f(1.0f,0.0,0.0,.3f); glPolygonOffset(-1.0, -1); glPointSize(2.0); glPushMatrix(); glMultMatrix(cm.Tr); glBegin(GL_POINTS); cm.svn=0; CMeshO::VertexIterator vi; for(vi=cm.vert.begin();vi!=cm.vert.end();++vi) if(!(*vi).IsD() && (*vi).IsS()) { glVertex((*vi).cP()); ++cm.svn; } glEnd(); glPopMatrix(); glPopAttrib(); return true; } int MeshModel::io2mm(int single_iobit) { switch(single_iobit) { case tri::io::Mask::IOM_NONE : return MM_NONE; case tri::io::Mask::IOM_VERTCOORD : return MM_VERTCOORD; case tri::io::Mask::IOM_VERTCOLOR : return MM_VERTCOLOR; case tri::io::Mask::IOM_VERTFLAGS : return MM_VERTFLAG; case tri::io::Mask::IOM_VERTQUALITY : return MM_VERTQUALITY; case tri::io::Mask::IOM_VERTNORMAL : return MM_VERTNORMAL; case tri::io::Mask::IOM_VERTTEXCOORD : return MM_VERTTEXCOORD; case tri::io::Mask::IOM_VERTRADIUS : return MM_VERTRADIUS; case tri::io::Mask::IOM_FACEINDEX : return MM_FACEVERT ; case tri::io::Mask::IOM_FACEFLAGS : return MM_FACEFLAG ; case tri::io::Mask::IOM_FACECOLOR : return MM_FACECOLOR ; case tri::io::Mask::IOM_FACEQUALITY : return MM_FACEQUALITY; case tri::io::Mask::IOM_FACENORMAL : return MM_FACENORMAL ; case tri::io::Mask::IOM_WEDGTEXCOORD : return MM_WEDGTEXCOORD; case tri::io::Mask::IOM_WEDGCOLOR : return MM_WEDGCOLOR; case tri::io::Mask::IOM_WEDGNORMAL : return MM_WEDGNORMAL ; case tri::io::Mask::IOM_BITPOLYGONAL : return MM_POLYGONAL ; default: assert(0); return MM_NONE; // FIXME: Returning this is not the best solution (!) break; } ; } void MeshModelState::create(int _mask, MeshModel* _m) { m=_m; changeMask=_mask; if(changeMask & MeshModel::MM_VERTCOLOR) { vertColor.resize(m->cm.vert.size()); std::vector::iterator ci; CMeshO::VertexIterator vi; for(vi = m->cm.vert.begin(), ci = vertColor.begin(); vi != m->cm.vert.end(); ++vi, ++ci) if(!(*vi).IsD()) (*ci)=(*vi).C(); } if(changeMask & MeshModel::MM_VERTCOORD) { vertCoord.resize(m->cm.vert.size()); std::vector::iterator ci; CMeshO::VertexIterator vi; for(vi = m->cm.vert.begin(), ci = vertCoord.begin(); vi != m->cm.vert.end(); ++vi, ++ci) if(!(*vi).IsD()) (*ci)=(*vi).P(); } if(changeMask & MeshModel::MM_VERTNORMAL) { vertNormal.resize(m->cm.vert.size()); std::vector::iterator ci; CMeshO::VertexIterator vi; for(vi = m->cm.vert.begin(), ci = vertNormal.begin(); vi != m->cm.vert.end(); ++vi, ++ci) if(!(*vi).IsD()) (*ci)=(*vi).N(); } if(changeMask & MeshModel::MM_FACEFLAGSELECT) { faceSelection.resize(m->cm.face.size()); std::vector::iterator ci; CMeshO::FaceIterator fi; for(fi = m->cm.face.begin(), ci = faceSelection.begin(); fi != m->cm.face.end(); ++fi, ++ci) if(!(*fi).IsD()) (*ci) = (*fi).IsS(); } if(changeMask & MeshModel::MM_TRANSFMATRIX) Tr = m->cm.Tr; } bool MeshModelState::apply(MeshModel *_m) { if(_m != m) return false; if(changeMask & MeshModel::MM_VERTCOLOR) { if(vertColor.size() != m->cm.vert.size()) return false; std::vector::iterator ci; CMeshO::VertexIterator vi; for(vi = m->cm.vert.begin(), ci = vertColor.begin(); vi != m->cm.vert.end(); ++vi, ++ci) if(!(*vi).IsD()) (*vi).C()=(*ci); } if(changeMask & MeshModel::MM_VERTCOORD) { if(vertCoord.size() != m->cm.vert.size()) return false; std::vector::iterator ci; CMeshO::VertexIterator vi; for(vi = m->cm.vert.begin(), ci = vertCoord.begin(); vi != m->cm.vert.end(); ++vi, ++ci) if(!(*vi).IsD()) (*vi).P()=(*ci); } if(changeMask & MeshModel::MM_VERTNORMAL) { if(vertNormal.size() != m->cm.vert.size()) return false; std::vector::iterator ci; CMeshO::VertexIterator vi; for(vi = m->cm.vert.begin(), ci=vertNormal.begin(); vi != m->cm.vert.end(); ++vi, ++ci) if(!(*vi).IsD()) (*vi).N()=(*ci); //now reset the face normals vcg::tri::UpdateNormals::PerFaceNormalized(m->cm); } if(changeMask & MeshModel::MM_FACEFLAGSELECT) { if(faceSelection.size() != m->cm.face.size()) return false; std::vector::iterator ci; CMeshO::FaceIterator fi; for(fi = m->cm.face.begin(), ci = faceSelection.begin(); fi != m->cm.face.end(); ++fi, ++ci) { if((*ci)) (*fi).SetS(); else (*fi).ClearS(); } } if(changeMask & MeshModel::MM_TRANSFMATRIX) m->cm.Tr=Tr; return true; } const QString MeshModel::shortName() const { return QFileInfo(fullPathFileName).fileName(); }