/**************************************************************************** * 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. * * * ****************************************************************************/ /**************************************************************************** History $Log$ Revision 1.13 2008/04/04 14:08:15 cignoni Solved namespace ambiguities caused by the removal of a silly 'using namespace' in meshmodel.h Revision 1.12 2008/02/28 09:57:40 cignoni corrected bug: wrong selection when Tr matrix != identity Revision 1.11 2007/10/23 07:15:19 cignoni switch to selection rendering done by slot and signals Revision 1.10 2007/04/16 09:25:29 cignoni ** big change ** Added Layers managemnt. Interfaces are changing again... Revision 1.9 2007/03/20 16:23:09 cignoni Big small change in accessing mesh interface. First step toward layers Revision 1.8 2007/02/26 01:05:11 cignoni cursor added Revision 1.7 2006/11/29 00:59:18 cignoni Cleaned plugins interface; changed useless help class into a plain string Revision 1.6 2006/11/27 06:57:20 cignoni Wrong way of using the __DATE__ preprocessor symbol Revision 1.5 2006/11/07 09:22:31 cignoni Wrote correct Help strings, and added required cleardatamask Revision 1.4 2006/06/13 13:50:01 cignoni Cleaned FPS management Revision 1.3 2006/06/12 15:19:51 cignoni Correct bug in the update of the selection during dragging Revision 1.2 2006/06/07 08:48:11 cignoni Added selection modes: clean/Add (ctrl) / Sub (shift) Revision 1.1 2006/05/25 04:57:46 cignoni Major 0.7 release. A lot of things changed. Colorize interface gone away, Editing and selection start to work. Optional data really working. Clustering decimation totally rewrote. History start to work. Filters organized in classes. ****************************************************************************/ #include #include #include #include #include "meshedit.h" #include #include using namespace std; using namespace vcg; ExtraMeshEditPlugin::ExtraMeshEditPlugin() { isDragging=false; actionList << new QAction(QIcon(":/images/select_face.png"),"Select Faces in a region", this); QAction *editAction; foreach(editAction, actionList) editAction->setCheckable(true); } QList ExtraMeshEditPlugin::actions() const { return actionList; } const QString ExtraMeshEditPlugin::Info(QAction *action) { if( action->text() != tr("Select Faces in a region") ) assert (0); return tr("Interactive selection of faces inside a dragged rectangle in screen space"); } const PluginInfo &ExtraMeshEditPlugin::Info() { static PluginInfo ai; ai.Date=tr(__DATE__); ai.Version = tr("0.5"); ai.Author = ("Paolo Cignoni"); return ai; } void ExtraMeshEditPlugin::mousePressEvent (QAction *, QMouseEvent * event, MeshModel &m, GLArea * gla) { LastSel.clear(); if(event->modifiers() == Qt::ControlModifier || event->modifiers() == Qt::ShiftModifier ) { CMeshO::FaceIterator fi; for(fi=m.cm.face.begin();fi!=m.cm.face.end();++fi) if(!(*fi).IsD() && (*fi).IsS()) LastSel.push_back(&*fi); } selMode=SMClear; if(event->modifiers()==Qt::ControlModifier) selMode=SMAdd; if(event->modifiers()==Qt::ShiftModifier) selMode=SMSub; start=event->pos(); cur=start; return; } void ExtraMeshEditPlugin::mouseMoveEvent (QAction *,QMouseEvent * event, MeshModel &/*m*/, GLArea * gla) { prev=cur; cur=event->pos(); isDragging = true; // now the management of the update //static int lastMouse=0; static int lastRendering=clock(); int curT = clock(); qDebug("mouseMoveEvent: curt %i last %i",curT,lastRendering); if(gla->lastRenderingTime() < 50 || (curT - lastRendering) > 1000 ) { lastRendering=curT; gla->update(); qDebug("mouseMoveEvent: ----"); } else{ gla->makeCurrent(); glDrawBuffer(GL_FRONT); DrawXORRect(gla,true); glDrawBuffer(GL_BACK); glFlush(); } } void ExtraMeshEditPlugin::mouseReleaseEvent (QAction *,QMouseEvent * event, MeshModel &/*m*/, GLArea * gla) { gla->update(); prev=cur; cur=event->pos(); } void ExtraMeshEditPlugin::DrawXORRect(GLArea * gla, bool doubleDraw) { glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0,gla->curSiz.width(),gla->curSiz.height(),0,-1,1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glPushAttrib(GL_ENABLE_BIT); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glEnable(GL_COLOR_LOGIC_OP); glLogicOp(GL_XOR); glColor3f(1,1,1); if(doubleDraw) { glBegin(GL_LINE_LOOP); glVertex2f(start.x(),start.y()); glVertex2f(prev.x(),start.y()); glVertex2f(prev.x(),prev.y()); glVertex2f(start.x(),prev.y()); glEnd(); } glBegin(GL_LINE_LOOP); glVertex2f(start.x(),start.y()); glVertex2f(cur.x(),start.y()); glVertex2f(cur.x(),cur.y()); glVertex2f(start.x(),cur.y()); glEnd(); glDisable(GL_LOGIC_OP); // Closing 2D glPopAttrib(); glPopMatrix(); // restore modelview glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } void ExtraMeshEditPlugin::Decorate(QAction * ac, MeshModel &m, GLArea * gla) { if(isDragging) { DrawXORRect(gla,false); vector::iterator fpi; // Starting Sel vector NewSel; QPoint mid=(start+cur)/2; mid.setY(gla->curSiz.height()- mid.y()); QPoint wid=(start-cur); if(wid.x()<0) wid.setX(-wid.x()); if(wid.y()<0) wid.setY(-wid.y()); /* CMeshO::FaceIterator fi; for(fi=m.cm.face.begin(),fpi=NewSel.begin();fpi!=NewSel.end();++fi) if(!(*fi).IsD()) { if(&(*fi)!=*fpi) (*fpi)->ClearS(); else { (*fpi)->SetS(); ++fpi; } } for(;fi!=m.cm.face.end();++fi) if(!(*fi).IsD()) (*fi).ClearS(); */ CMeshO::FaceIterator fi; for(fi=m.cm.face.begin();fi!=m.cm.face.end();++fi) if(!(*fi).IsD()) (*fi).ClearS(); glPushMatrix(); glMultMatrix(m.cm.Tr); GLPickTri::PickFace(mid.x(), mid.y(), m.cm, NewSel, wid.x(), wid.y()); qDebug("Pickface: rect %i %i - %i %i",mid.x(),mid.y(),wid.x(),wid.y()); qDebug("Pickface: Got %i on %i",NewSel.size(),m.cm.face.size()); glPopMatrix(); switch(selMode) { case SMSub : for(fpi=LastSel.begin();fpi!=LastSel.end();++fpi) (*fpi)->SetS(); for(fpi=NewSel.begin();fpi!=NewSel.end();++fpi) (*fpi)->ClearS(); break; case SMAdd : for(fpi=LastSel.begin();fpi!=LastSel.end();++fpi) (*fpi)->SetS(); case SMClear : for(fpi=NewSel.begin();fpi!=NewSel.end();++fpi) (*fpi)->SetS(); break; } isDragging=false; } } void ExtraMeshEditPlugin::StartEdit(QAction * /*mode*/, MeshModel &m, GLArea *gla ) { LastSel.clear(); CMeshO::FaceIterator fi; for(fi=m.cm.face.begin();fi!=m.cm.face.end();++fi) if(!(*fi).IsD() && (*fi).IsS() ) LastSel.push_back(&*fi); gla->setCursor(QCursor(QPixmap(":/images/sel_rect.png"),1,1)); connect(this, SIGNAL(setSelectionRendering(bool)),gla,SLOT(setSelectionRendering(bool)) ); setSelectionRendering(true); } Q_EXPORT_PLUGIN(ExtraMeshEditPlugin)