diff --git a/docs/ToDo.txt b/docs/ToDo.txt new file mode 100644 index 000000000..c408f5ae8 --- /dev/null +++ b/docs/ToDo.txt @@ -0,0 +1,45 @@ +25/5/06 +o clustering nel filtro in input epoch. +o install doc e attempt. + +24/5/06 + +o Uniformare i nomi degli slot nel main window +o Measuring Tool +o risistemare Recent file stuff...(bug in apertura cambio dir?) +o snapshot con fbo invece che con il rendering nel backbuffer. +o Ambient Occlusion +o Clustering dialog diag percentage <1 non va +o esc che ritorna all'ultimo modo di selezione. +x selection ico che stanno accese // DONE 24/5 +x selection drawing abilitato subito // DONE 24/5 +o filtro geodesic quality + +23/5/06 + +o scrivere doc di sample di fiultri +x aggiornare i filtri epoch // DONE 25/5 +o aggiungere un filtro in ingresso per aln + +22/5/06 + +o Mapping Colore Qualita Implementare e Debuggare +o Default colore e curvatura +o Colore nel clustering +x Face Selection Tool // DONE 24/5 + - Feature // DONE 24/5 + - Icon // DONE 24/5 +x Face Selection Drawing // DONE 24/5 + - Func // DONE 23/5 + - Ico e slot // DONE 24/5 +o Global Options, for each plugins +o Animation Spinning e interopolation +o Ripulire glarea + - Snapshot + - FPS + - Log + - Paint +o ScriptDialog +o Generic dialog option +o Clustering con bound e selezione. +o Dialogo shaders che galleggia un po' troppo diff --git a/src/meshlab/filterscript.h b/src/meshlab/filterscript.h new file mode 100644 index 000000000..8ac94a1e6 --- /dev/null +++ b/src/meshlab/filterscript.h @@ -0,0 +1,20 @@ +#ifndef FILTERSCRIPT_H +#define FILTERSCRIPT_H + +#include +#include + +#include "meshmodel.h" +//#include "glarea.h" + +class FilterScript +{ +public: + bool Open(QString filename); + bool Save(QString filename); + + QList< QPair< QAction *, FilterParameter> > actionList; + typedef QList< QPair >::iterator iterator; +}; + +#endif diff --git a/src/meshlab/glarea.cpp b/src/meshlab/glarea.cpp index 15613f89c..54ba11f0f 100644 --- a/src/meshlab/glarea.cpp +++ b/src/meshlab/glarea.cpp @@ -24,6 +24,10 @@ History $Log$ +Revision 1.100 2006/05/25 04:57:45 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. + Revision 1.99 2006/03/01 10:08:01 ponchio WHEEL_DELTA -> WHEEL_STEP as WHEEL_DELTA is already defined somewhere. @@ -72,8 +76,10 @@ GLArea::GLArea(QWidget *parent) animMode=AnimNone; iRenderer=0; //Shader support iDecoratorsList=0; - currentTime=0; - lastTime=0; + iEdit=0; + currentEditor=0; + //currentTime=0; + //lastTime=0; deltaTime=0; cfps=0; hasToPick=false; @@ -86,11 +92,10 @@ GLArea::GLArea(QWidget *parent) currentSharder = NULL; lastFilterRef = NULL; mm = NULL; - time.start(); currLogLevel = -1; // Projection Matrix starting settings - objDist = 3.f; + //objDist = 3.f; fov = 60; clipRatioFar = 1; clipRatioNear = 1; @@ -132,6 +137,10 @@ void GLArea::initializeGL() trackball_light.center=Point3f(0, 0, 0); trackball_light.radius= 1; + GLenum err = glewInit(); + if (err != GLEW_OK ) { + assert(0); + } } @@ -218,7 +227,10 @@ void GLArea::myGluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GL void GLArea::paintGL() { - lastTime=time.elapsed(); + QTime time; + time.start(); + + //int lastTime=time.elapsed(); initTexture(); glClearColor(1.0,1.0,1.0,0.0); //vannini: alpha was 1.0 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -304,7 +316,7 @@ void GLArea::paintGL() glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - myGluPerspective(fov, (GLdouble) currentWidth / (GLdouble) currentHeight, nearPlane, farPlane); + myGluPerspective(fov, (GLdouble) curSiz.width() / (GLdouble) curSiz.height(), nearPlane, farPlane); glMatrixMode(GL_MODELVIEW); } @@ -316,21 +328,32 @@ void GLArea::paintGL() glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); } - if(iRenderer && currentSharder) { + if(rm.backFaceCull) glEnable(GL_CULL_FACE); + else glDisable(GL_CULL_FACE); + + if(iRenderer && currentSharder) { glPushAttrib(GL_ALL_ATTRIB_BITS); iRenderer->Render(currentSharder, *mm, rm, this); } mm->Render(rm.drawMode,rm.colorMode,rm.textureMode); + if(iEdit){ + iEdit->Decorate(currentEditor,*mm,this); + } + if(iRenderer) { glPopAttrib(); glUseProgramObjectARB(0); } + // Draw the selection + if(rm.selectedFaces) + mm->RenderSelectedFaces(); + if(iDecoratorsList){ pair p; - foreach(p,*iDecoratorsList){p.second->Decorate(p.first,*mm,rm,this);} + foreach(p,*iDecoratorsList){p.second->Decorate(p.first,*mm,rm,this,qFont);} } // ...and take a snapshot @@ -378,7 +401,7 @@ void GLArea::paintGL() glBlendFunc(GL_ONE,GL_SRC_ALPHA); cs.lColor.V(3) = 128; // set half alpha value glColor(cs.lColor); - float h = -0.80f;//vcg::math::Min(-0.8f,-.08f*qFont.pointSize());//((.03f * currentHeight) - (currentHeight>>1)) / (float)currentHeight; + float h = -0.80f;//vcg::math::Min(-0.8f,-.08f*qFont.pointSize());//((.03f * curSiz.height()) - (curSiz.height()>>1)) / (float)curSiz.height(); glBegin(GL_TRIANGLE_STRIP); glVertex2f(-1.f,h); glVertex2f(-1.f,-1.f); @@ -393,16 +416,17 @@ void GLArea::paintGL() glColor4f(1,1,1,1); if(logVisible) { - renderText(20,currentHeight - 5 * (qFont.pointSizeF()+(currentHeight/225.f)),tr("LOG MESSAGES"),qFont); - log.glDraw(this,currLogLevel,3,qFont.pointSizeF()+(currentHeight/225.f),qFont); + renderText(20,curSiz.height() - 5 * (qFont.pointSizeF()+(curSiz.height()/225.f)),tr("LOG MESSAGES"),qFont); + log.glDraw(this,currLogLevel,3,qFont.pointSizeF()+(curSiz.height()/225.f),qFont); } // Second the MESH INFO (numVert,NumFaces,....) displayMeshInfo(); // Third the ENV INFO (Fps,ClippingPlanes,....) - currentTime=time.elapsed(); - deltaTime=currentTime-lastTime; + //int currentTime=time.elapsed(); + //deltaTime=currentTime-lastTime; + deltaTime=time.elapsed(); updateFps(); displayEnvInfo(); @@ -421,35 +445,35 @@ void GLArea::paintGL() void GLArea::displayMeshInfo() { - float fontSpacingV = qFont.pointSizeF()+(currentHeight/225.f); - float startPos= currentHeight-(fontSpacingV/3); + float fontSpacingV = qFont.pointSizeF()+(curSiz.height()/225.f); + float startPos= curSiz.height()-(fontSpacingV/3); - renderText(currentWidth*.5f,startPos-5*fontSpacingV,tr("MESH INFO"),qFont); + renderText(curSiz.width()*.5f,startPos-5*fontSpacingV,tr("MESH INFO"),qFont); - renderText(currentWidth*.5f,startPos-3*fontSpacingV,tr("Vertices: %1").arg(mm->cm.vert.size()),qFont); - renderText(currentWidth*.5f,startPos-2*fontSpacingV,tr("Faces: %1").arg(mm->cm.face.size()),qFont); - renderText(currentWidth*.5f,startPos- fontSpacingV,GetMeshInfoString(mm->mask),qFont); + renderText(curSiz.width()*.5f,startPos-3*fontSpacingV,tr("Vertices: %1").arg(mm->cm.vert.size()),qFont); + renderText(curSiz.width()*.5f,startPos-2*fontSpacingV,tr("Faces: %1").arg(mm->cm.face.size()),qFont); + renderText(curSiz.width()*.5f,startPos- fontSpacingV,GetMeshInfoString(mm->mask),qFont); } void GLArea::displayEnvInfo() { - float fontSpacingV = qFont.pointSizeF()+(currentHeight/225.f); - float startPos = currentHeight-(fontSpacingV/3); + float fontSpacingV = qFont.pointSizeF()+(curSiz.height()/225.f); + float startPos = curSiz.height()-(fontSpacingV/3); QString strNear=QString("Nplane: %1 ").arg(nearPlane,2,'f',1); QString strFar=QString("Fplane: %1").arg(farPlane,2,'f',1); - QString strViewer=QString("Viewer: %1 ").arg(objDist,2,'f',1); + //QString strViewer=QString("Viewer: %1 ").arg(objDist,2,'f',1); - renderText(currentWidth-currentWidth*.25f,startPos-5*fontSpacingV,tr("ENV INFO"),qFont); + renderText(curSiz.width()-curSiz.width()*.25f,startPos-5*fontSpacingV,tr("ENV INFO"),qFont); - renderText(currentWidth-currentWidth*.25f,startPos-3*fontSpacingV,strViewer+strNear+strFar,qFont); - renderText(currentWidth-currentWidth*.25f,startPos-2*fontSpacingV,QString("FOV: ")+QString::number((int)fov,10),qFont); + //renderText(curSiz.width()-curSiz.width()*.25f,startPos-3*fontSpacingV,strViewer+strNear+strFar,qFont); + renderText(curSiz.width()-curSiz.width()*.25f,startPos-2*fontSpacingV,QString("FOV: ")+QString::number((int)fov,10),qFont); if ((cfps>0) && (cfps<200)) { QString strInfo=QString("FPS: %1").arg(cfps,7,'f',1); - renderText(currentWidth-currentWidth*.25f,startPos-fontSpacingV,strInfo,qFont); + renderText(curSiz.width()-curSiz.width()*.25f,startPos-fontSpacingV,strInfo,qFont); } } @@ -462,8 +486,8 @@ void GLArea::resizeGL(int _width, int _height) //gluPerspective(fov, float(_width)/float(_height), nearPlane, farPlane); //glMatrixMode(GL_MODELVIEW); glViewport(0,0, _width, _height); - currentWidth=_width; - currentHeight=_height; + curSiz.setWidth(_width); + curSiz.setHeight(_height); // Set font size depending on window size (min = 1, max = 9) qFont.setPointSizeF(vcg::math::Clamp(-3 + sqrtf(_width*_width + _height*_height) * .01f,1,9)); @@ -486,8 +510,8 @@ void GLArea::displayHelp() glEnd(); - float fontSpacingV = (currentHeight*.01f)+3; - float hPosition = currentWidth*.1f; + float fontSpacingV = (curSiz.height()*.01f)+3; + float hPosition = curSiz.width()*.1f; glColor(Color4b::White); qFont.setBold(true);renderText(2+hPosition-(qFont.pointSize()*9),1.5*fontSpacingV,QString("MeshLab Quick Help"),qFont);qFont.setBold(false); renderText(2,3*fontSpacingV,QString("Drag:"),qFont); renderText(hPosition,3*fontSpacingV,QString("Rotate"),qFont); @@ -573,14 +597,17 @@ void GLArea::keyReleaseEvent ( QKeyEvent * e ) void GLArea::mousePressEvent(QMouseEvent*e) { e->accept(); - if ((e->modifiers() & Qt::ShiftModifier) && (e->modifiers() & Qt::ControlModifier) && - (e->button()==Qt::LeftButton) ) - activeDefaultTrackball=false; - else activeDefaultTrackball=true; - - if (isDefaultTrackBall()) - trackball.MouseDown(e->x(),height()-e->y(), QT2VCG(e->button(), e->modifiers() ) ); - else trackball_light.MouseDown(e->x(),height()-e->y(), QT2VCG(e->button(), Qt::NoModifier ) ); + if(iEdit) iEdit->mousePressEvent(currentEditor,e,*mm,this); + else { + if ((e->modifiers() & Qt::ShiftModifier) && (e->modifiers() & Qt::ControlModifier) && + (e->button()==Qt::LeftButton) ) + activeDefaultTrackball=false; + else activeDefaultTrackball=true; + + if (isDefaultTrackBall()) + trackball.MouseDown(e->x(),height()-e->y(), QT2VCG(e->button(), e->modifiers() ) ); + else trackball_light.MouseDown(e->x(),height()-e->y(), QT2VCG(e->button(), Qt::NoModifier ) ); + } update(); } @@ -588,17 +615,23 @@ void GLArea::mouseMoveEvent(QMouseEvent*e) { if(e->buttons() | Qt::LeftButton) { - if (isDefaultTrackBall()) trackball.MouseMove(e->x(),height()-e->y()); - else trackball_light.MouseMove(e->x(),height()-e->y()); - update(); + if(iEdit) iEdit->mouseMoveEvent(currentEditor,e,*mm,this); + else { + if (isDefaultTrackBall()) trackball.MouseMove(e->x(),height()-e->y()); + else trackball_light.MouseMove(e->x(),height()-e->y()); + update(); + } } } void GLArea::mouseReleaseEvent(QMouseEvent*e) { activeDefaultTrackball=true; - if (isDefaultTrackBall()) trackball.MouseUp(e->x(),height()-e->y(), QT2VCG(e->button(), e->modifiers() ) ); - else trackball_light.MouseUp(e->x(),height()-e->y(), QT2VCG(e->button(),e->modifiers()) ); + if(iEdit) iEdit->mouseReleaseEvent(currentEditor,e,*mm,this); + else { + if (isDefaultTrackBall()) trackball.MouseUp(e->x(),height()-e->y(), QT2VCG(e->button(), e->modifiers() ) ); + else trackball_light.MouseUp(e->x(),height()-e->y(), QT2VCG(e->button(),e->modifiers()) ); + } update(); } @@ -693,12 +726,16 @@ void GLArea::setLightMode(bool state,LightingModel lmode) void GLArea::setBackFaceCulling(bool enabled) { - if(enabled) glEnable(GL_CULL_FACE); - else glDisable(GL_CULL_FACE); rm.backFaceCull = enabled; updateGL(); } +void GLArea::setSelectionRendering(bool enabled) +{ + rm.selectedFaces = enabled; + updateGL(); +} + void GLArea::setLightModel() { static GLfloat standard_light[]={1.f,1.f,1.f,1.f}; @@ -739,13 +776,13 @@ void GLArea::setSnapshotSetting(const SnapshotSetting & s) void GLArea::setView() { - GLfloat fAspect = (GLfloat)currentWidth/ currentHeight; + GLfloat fAspect = (GLfloat)curSiz.width()/ curSiz.height(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Si deve mettere la camera ad una distanza che inquadri la sfera unitaria bene. float ratio = 1.75f; - objDist = ratio / tanf(vcg::math::ToRad(fov*.5f)); + float objDist = ratio / tanf(vcg::math::ToRad(fov*.5f)); nearPlane = objDist - 2.f*clipRatioNear; farPlane = objDist + 2.f*clipRatioFar; diff --git a/src/meshlab/glarea.h b/src/meshlab/glarea.h index bf66d80e2..88f53fec3 100644 --- a/src/meshlab/glarea.h +++ b/src/meshlab/glarea.h @@ -24,6 +24,10 @@ History $Log$ +Revision 1.57 2006/05/25 04:57:45 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. + Revision 1.56 2006/02/16 10:09:34 cignoni Removed unnecessary stuff (modifiers) @@ -63,43 +67,14 @@ Revision 1.51 2006/01/25 03:57:15 glvertex #include #include "GLLogStream.h" - #include "meshmodel.h" #include "interfaces.h" +#include "filterscript.h" #define SSHOT_BYTES_PER_PIXEL 4 enum LightingModel{LDOUBLE,LFANCY}; -class RenderMode -{ -public: - vcg::GLW::DrawMode drawMode; - vcg::GLW::ColorMode colorMode; - vcg::GLW::TextureMode textureMode; - - bool lighting; - bool backFaceCull; - bool doubleSideLighting; - bool fancyLighting; - bool castShadow; - vcg::Point3f lightDir; - - - RenderMode() - { - drawMode = GLW::DMSmooth; - colorMode = GLW::CMNone; - textureMode = GLW::TMNone; - - lighting = true; - backFaceCull = false; - doubleSideLighting = false; - fancyLighting = false; - castShadow = false; - } -}; - class ColorSetting { @@ -147,9 +122,9 @@ public: vcg::Trackball trackball_light; GLLogStream log; short currLogLevel; + FilterScript filterHistory; - int currentWidth; - int currentHeight; + QSize curSiz; QSize minimumSizeHint() const; QSize sizeHint() const; QFont getFont() {return qFont;} @@ -182,6 +157,7 @@ public: bool isDefaultTrackBall() {return activeDefaultTrackball;} void setBackFaceCulling(bool enabled); + void setSelectionRendering(bool enabled); void setCustomSetting(const ColorSetting & s); void setSnapshotSetting(const SnapshotSetting & s); void setDrawMode(vcg::GLW::DrawMode mode); @@ -198,7 +174,9 @@ public: void setRenderer(MeshRenderInterface *rend, QAction *shader){ iRenderer = rend; currentSharder = shader;} MeshRenderInterface * getRenderer() { return iRenderer; } - void setEdit(MeshEditInterface *edit){ iEdit = edit; } + void setEdit(MeshEditInterface *edit, QAction *editor){ iEdit = edit; currentEditor=editor;} + QAction * getEditAction() { return currentEditor; } + void endEdit(){ iEdit = 0; currentEditor=0;}/// void closeEvent(QCloseEvent *event); @@ -220,6 +198,7 @@ protected: void mouseDoubleClickEvent ( QMouseEvent * event ) ; void wheelEvent(QWheelEvent*e); + bool drawSelection; private: void pasteTile(); void myGluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); @@ -240,21 +219,21 @@ private: // Editing support MeshEditInterface *iEdit; + QAction *currentEditor; RenderMode rm; ColorSetting cs; - float cfps; float fov; - float objDist; + //float objDist; float clipRatioFar; float clipRatioNear; float nearPlane; float farPlane; - QTime time; - int deltaTime; - int lastTime; - int currentTime; +public: + int deltaTime; +private: float fpsVector[10]; + float cfps; QString fileName; diff --git a/src/meshlab/images/icons.xar b/src/meshlab/images/icons.xar index 659770d44..8e520b42e 100644 Binary files a/src/meshlab/images/icons.xar and b/src/meshlab/images/icons.xar differ diff --git a/src/meshlab/interfaces.h b/src/meshlab/interfaces.h index 457000a92..01a514782 100644 --- a/src/meshlab/interfaces.h +++ b/src/meshlab/interfaces.h @@ -23,6 +23,10 @@ /**************************************************************************** History $Log$ +Revision 1.42 2006/05/25 04:57:45 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. + Revision 1.41 2006/04/18 06:57:34 zifnab1974 syntax errors for gcc 3.4.5 resolved @@ -147,13 +151,17 @@ Added copyright info #ifndef MESHLAB_INTERFACES_H #define MESHLAB_INTERFACES_H +#include +#include +#include +#include class QWidget; +class QGLWidget; class QIcon; class QString; +class QVariant; class QMouseEvent; -//class QList; -class QAction; class MeshModel; class RenderMode; class GLArea; @@ -210,19 +218,106 @@ public: QWidget *parent= 0)=0 ; // prima istanza il dialogo di opzioni viene sempre. }; + + +class FilterParameter +{ +public: + + FilterParameter(){} + + inline bool getBool(QString name) { + QMap::iterator ii=paramMap.find(name); + assert(ii!=paramMap.end()); + assert(ii.value().type()==QVariant::Bool); + return ii.value().toBool(); + } + + inline int getInt(QString name) { + QMap::iterator ii=paramMap.find(name); + if(ii==paramMap.end()) assert(0); + assert(ii.value().type()==QVariant::Int); + return float(ii.value().toInt()); + } + + inline float getFloat(QString name) { + QMap::iterator ii=paramMap.find(name); + if(ii==paramMap.end()) assert(0); + assert(ii.value().type()==QVariant::Double); + return float(ii.value().toDouble()); + } + + inline Matrix44f getMatrix44(QString name) { + QMap::iterator ii=paramMap.find(name); + if(ii==paramMap.end()) assert(0); + assert(ii.value().type()==QVariant::List); + Matrix44f matrix; + QList matrixVals = ii.value().toList(); + assert(matrixVals.size()==16); + for(int i=0;i<16;++i) + matrix.V()[i]=matrixVals[i].toDouble(); + + return matrix; + } + + inline void addFloat(QString name,float val){ paramMap.insert(name, QVariant( double(val)) ); } + inline void addInt (QString name,float val){ paramMap.insert(name, QVariant( int(val)) ); } + inline void addBool (QString name,bool val) { paramMap.insert(name, QVariant( val ) ); } + + inline void addMatrix44(QString name,Matrix44f val) { + QList matrixVals; + for(int i=0;i<16;++i) + matrixVals.append(val.V()[i]); + paramMap.insert(name, QVariant(matrixVals) ); + } + + inline void clear() { paramMap.clear(); } +private: + // The data is just a list of Parameters + QMap paramMap; +}; + class MeshFilterInterface { public: - enum FilterClass { Generic, Selection, Cleaning, Subdivision} ; - + typedef int FilterType; + enum FilterClass { Generic, Selection, Cleaning, Remeshing, FaceColoring, VertexColoring} ; virtual ~MeshFilterInterface() {} - virtual QList actions() const = 0; - virtual const ActionInfo &Info(QAction *)=0; + virtual const ActionInfo &Info(QAction *)=0; + + // The filterclass describe in which submenu each filter should be placed virtual const FilterClass getClass(QAction *) {return MeshFilterInterface::Generic;}; + + // This function invokes a dialog and get back the parameters + virtual bool getParameters(QAction *, QWidget * /*parent*/, MeshModel &/*m*/, FilterParameter & /*par*/) {return true;}; + + // The filters can require some additional + virtual const int getRequirements(QAction *){return MeshModel::MM_NONE;} + + // The main function that apply the selected filter + virtual bool applyFilter(QAction * /*filter*/, MeshModel &/*m*/, FilterParameter & /*parent*/, vcg::CallBackPos * /*cb*/) = 0; + virtual const PluginInfo &Info()=0; - virtual void setLog(GLLogStream* )=0; - virtual bool applyFilter(QAction * /*filter*/, MeshModel &/*m*/, QWidget * /*parent*/, vcg::CallBackPos * /*cb*/) = 0; + void setLog(GLLogStream *log) { this->log = log ; } + + virtual const QString ST(FilterType filter)=0; + + virtual const FilterType ID(QAction *a) + { + foreach( FilterType tt, types()) + if( a->text() == this->ST(tt) ) return tt; + assert(0); + return 0; + } + virtual QList actions() const { return actionList;} + virtual QList &types() { return typeList;} + +protected: + QList actionList; + QList typeList; + GLLogStream *log; }; + /* Serve per customizzare totalmente il processo di rendering Viene invocata al posto del rendering standard della mesh. @@ -237,27 +332,14 @@ class MeshRenderInterface public: virtual ~MeshRenderInterface() {} - virtual void Init(QAction * /*mode*/, MeshModel &/*m*/, RenderMode &/*rm*/, GLArea * /*parent*/){}; - virtual void Render(QAction * /*mode*/, MeshModel &/*m*/, RenderMode &/*rm*/, GLArea * /*parent*/) = 0; + virtual void Init(QAction * /*mode*/, MeshModel &/*m*/, RenderMode &/*rm*/, QGLWidget * /*parent*/){}; + virtual void Render(QAction * /*mode*/, MeshModel &/*m*/, RenderMode &/*rm*/, QGLWidget * /*parent*/) = 0; virtual void Finalize(QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/){}; virtual bool isSupported() = 0; virtual const PluginInfo &Info()=0; virtual QList actions() const = 0; }; -class MeshColorizeInterface -{ -public: - virtual const ActionInfo &Info(QAction *)=0; - virtual const PluginInfo &Info()=0; - virtual void setLog(GLLogStream* )=0; - virtual void Compute(QAction * /*mode*/, MeshModel &/*m*/, RenderMode &/*rm*/, GLArea * /*parent*/){}; - virtual void Show(QAction * /*mode*/, bool /*show*/, MeshModel &/*m*/, GLArea * /*parent*/) {}; - virtual void Finalize(QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/){}; - virtual QList actions() const = 0; -}; - - class MeshDecorateInterface { @@ -268,7 +350,7 @@ public: virtual const PluginInfo &Info()=0; virtual void Init(QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/){}; - virtual void Decorate(QAction * /*mode*/, MeshModel &/*m*/, RenderMode &/*rm*/, GLArea * /*parent*/) = 0; + virtual void Decorate(QAction * /*mode*/, MeshModel &/*m*/, RenderMode &/*rm*/, QGLWidget * /*parent*/,QFont qf) = 0; virtual void Finalize(QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/){}; virtual QList actions() const = 0; }; @@ -283,9 +365,9 @@ public: virtual const PluginInfo &Info()=0; virtual void StartEdit(QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/){}; - virtual void Edit(QAction * /*mode*/, MeshModel &/*m*/, RenderMode &/*rm*/, GLArea * /*parent*/) = 0; + //virtual void Edit(QAction * /*mode*/, MeshModel &/*m*/, RenderMode &/*rm*/, GLArea * /*parent*/) = 0; virtual void EndEdit(QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/){}; - virtual void Decorate(QAction * /*mode*/, MeshModel &/*m*/, RenderMode &/*rm*/, GLArea * /*parent*/) = 0; + virtual void Decorate(QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/) = 0; virtual void mousePressEvent (QAction *, QMouseEvent *event, MeshModel &/*m*/, GLArea * )=0; virtual void mouseMoveEvent (QAction *,QMouseEvent *event, MeshModel &/*m*/, GLArea * )=0; virtual void mouseReleaseEvent (QAction *,QMouseEvent *event, MeshModel &/*m*/, GLArea * )=0; @@ -296,7 +378,6 @@ public: Q_DECLARE_INTERFACE(MeshIOInterface, "vcg.meshlab.MeshIOInterface/1.0") Q_DECLARE_INTERFACE(MeshFilterInterface, "vcg.meshlab.MeshFilterInterface/1.0") Q_DECLARE_INTERFACE(MeshRenderInterface, "vcg.meshlab.MeshRenderInterface/1.0") -Q_DECLARE_INTERFACE(MeshColorizeInterface, "vcg.meshlab.MeshColorizeInterface/1.0") Q_DECLARE_INTERFACE(MeshDecorateInterface, "vcg.meshlab.MeshDecorateInterface/1.0") Q_DECLARE_INTERFACE(MeshEditInterface, "vcg.meshlab.MeshEditInterface/1.0") diff --git a/src/meshlab/mainwindow.h b/src/meshlab/mainwindow.h index 23635412e..43973cb41 100644 --- a/src/meshlab/mainwindow.h +++ b/src/meshlab/mainwindow.h @@ -23,6 +23,10 @@ /**************************************************************************** History $Log$ +Revision 1.63 2006/05/25 04:57:45 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. + Revision 1.62 2006/04/12 15:12:18 cignoni Added Filter classes (cleaning, meshing etc) @@ -77,7 +81,7 @@ class MainWindow : public QMainWindow public: MainWindow(); static bool QCallBack(const int pos, const char * str); - const QString appName() const {return tr("MeshLab v0.6"); } + const QString appName() const {return tr("MeshLab v0.7"); } // MaskObj maskobj; public slots: @@ -87,13 +91,19 @@ public slots: private slots: //////////// Slot Menu File ////////////////////// + void openFilterScript(QString fileName=QString()); + void saveFilterScript(QString fileName=QString()); void reload(); void openRecentFile(); bool saveAs(); - bool saveSnapshot(); + bool saveSnapshot(); + ///////////Slot Menu Edit //////////////////////// + void applyEditMode(); + void endEditMode(); ///////////Slot Menu Filter //////////////////////// void applyFilter(); void applyLastFilter(); + void runFilterScript(); /////////// Slot Menu Render ///////////////////// void renderBbox(); void renderPoint(); @@ -109,8 +119,8 @@ private slots: void setColorMode(QAction *qa); void applyRenderMode(); void applyColorMode(); - void applyEditMode(); void toggleBackFaceCulling(); + void toggleSelectionRendering(); void applyDecorateMode(); ///////////Slot Menu View //////////////////////// void fullScreen(); @@ -153,16 +163,19 @@ private: QStringList pluginFileNames; std::vector meshIOPlugins; QByteArray toolbarState; //stato delle toolbar e dockwidgets + QMap filterMap; // a map to retrieve an action from a name. Used for playing filter scripts. //////// ToolBars /////////////// QToolBar *mainToolBar; QToolBar *renderToolBar; + QToolBar *editToolBar; ///////// Menus /////////////// QMenu *fileMenu; QMenu *filterMenu; QMenu *filterMenuSelect; QMenu *filterMenuClean; + QMenu *filterMenuRemeshing; QMenu *editMenu; //Render Menu and SubMenu //// QMenu *shadersMenu; @@ -183,14 +196,19 @@ private: //////////// Actions Menu File /////////////////////// QAction *openAct; + QAction *openFilterScriptAct; + QAction *saveFilterScriptAct; QAction *closeAct; QAction *reloadAct; QAction *saveAsAct; QAction *saveSnapshotAct; QAction *lastFilterAct; + QAction *runFilterScriptAct; QAction *recentFileActs[MAXRECENTFILES]; QAction *separatorAct; QAction *exitAct; + /////////// Actions Menu Edit ///////////////////// + QAction *endEditModeAct; /////////// Actions Menu Render ///////////////////// QActionGroup *renderModeGroupAct; QAction *renderBboxAct; @@ -205,6 +223,7 @@ private: QAction *setFancyLightingAct; QAction *setLightAct; QAction *backFaceCullAct; + QAction *setSelectionRenderingAct; QActionGroup *colorModeGroupAct; QAction *colorModeNoneAct; diff --git a/src/meshlab/mainwindow_Init.cpp b/src/meshlab/mainwindow_Init.cpp index a06285c3a..16ff4473b 100644 --- a/src/meshlab/mainwindow_Init.cpp +++ b/src/meshlab/mainwindow_Init.cpp @@ -24,6 +24,10 @@ History $Log$ +Revision 1.53 2006/05/25 04:57:45 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. + Revision 1.52 2006/04/18 06:57:34 zifnab1974 syntax errors for gcc 3.4.5 resolved @@ -104,7 +108,17 @@ void MainWindow::createActions() openAct->setShortcut(Qt::CTRL+Qt::Key_O); connect(openAct, SIGNAL(triggered()), this, SLOT(open())); - closeAct = new QAction(tr("&Close"), this); + openFilterScriptAct = new QAction(QIcon(":/images/open.png"),tr("&Open Filter Script..."), this); + openFilterScriptAct->setShortcutContext(Qt::ApplicationShortcut); + openFilterScriptAct->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_O); + connect(openFilterScriptAct, SIGNAL(triggered()), this, SLOT(openFilterScript())); + + saveFilterScriptAct = new QAction(QIcon(":/images/save.png"),tr("&Save Filter Script..."), this); + saveFilterScriptAct->setShortcutContext(Qt::ApplicationShortcut); + saveFilterScriptAct->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_S); + connect(saveFilterScriptAct, SIGNAL(triggered()), this, SLOT(saveFilterScript())); + + closeAct = new QAction(tr("&Close"), this); closeAct->setShortcutContext(Qt::ApplicationShortcut); closeAct->setShortcut(Qt::CTRL+Qt::Key_C); connect(closeAct, SIGNAL(triggered()),workspace, SLOT(closeActiveWindow())); @@ -191,7 +205,13 @@ void MainWindow::createActions() backFaceCullAct->setShortcutContext(Qt::ApplicationShortcut); backFaceCullAct->setShortcut(Qt::CTRL+Qt::Key_K); connect(backFaceCullAct, SIGNAL(triggered()), this, SLOT(toggleBackFaceCulling())); - + + setSelectionRenderingAct = new QAction(QIcon(":/images/selected.png"),tr("Selected Face Rendering"),this); + setSelectionRenderingAct->setCheckable(true); + setSelectionRenderingAct->setShortcutContext(Qt::ApplicationShortcut); + setSelectionRenderingAct->setShortcut(Qt::CTRL+Qt::Key_S); + connect(setSelectionRenderingAct, SIGNAL(triggered()), this, SLOT(toggleSelectionRendering())); + //////////////Action Menu View //////////////////////////////////////////////////////////////////////////// fullScreenAct = new QAction (tr("&FullScreen"), this); fullScreenAct->setCheckable(true); @@ -226,6 +246,12 @@ void MainWindow::createActions() resetTrackBallAct->setShortcut(Qt::CTRL+Qt::Key_H); connect(resetTrackBallAct, SIGNAL(triggered()), this, SLOT(resetTrackBall())); + endEditModeAct = new QAction (QIcon(":/images/no_edit.png"),tr("Not editing"), this); + endEditModeAct->setShortcut(Qt::Key_Escape); + endEditModeAct->setCheckable(true); + endEditModeAct->setChecked(true); + connect(endEditModeAct, SIGNAL(triggered()), this, SLOT(endEditMode())); + //////////////Action Menu Windows ///////////////////////////////////////////////////////////////////////// windowsTileAct = new QAction(tr("&Tile"), this); connect(windowsTileAct, SIGNAL(triggered()), workspace, SLOT(tile())); @@ -246,6 +272,10 @@ void MainWindow::createActions() lastFilterAct->setEnabled(false); connect(lastFilterAct, SIGNAL(triggered()), this, SLOT(applyLastFilter())); + runFilterScriptAct = new QAction(tr("Run current filter script"),this); + runFilterScriptAct->setEnabled(false); + connect(runFilterScriptAct, SIGNAL(triggered()), this, SLOT(runFilterScript())); + //////////////Action Menu Preferences ///////////////////////////////////////////////////////////////////// setCustomizeAct = new QAction(tr("&Options..."),this); connect(setCustomizeAct, SIGNAL(triggered()), this, SLOT(setCustomize())); @@ -268,10 +298,15 @@ void MainWindow::createToolBars() mainToolBar->addAction(saveSnapshotAct); renderToolBar = addToolBar(tr("Render")); - renderToolBar->setIconSize(QSize(32,32)); + //renderToolBar->setIconSize(QSize(32,32)); renderToolBar->addActions(renderModeGroupAct->actions()); renderToolBar->addAction(renderModeTextureAct); renderToolBar->addAction(setLightAct); + renderToolBar->addAction(setSelectionRenderingAct); + + editToolBar = addToolBar(tr("Edit")); + editToolBar->addAction(endEditModeAct); + } @@ -283,6 +318,8 @@ void MainWindow::createMenus() fileMenu->addAction(closeAct); fileMenu->addAction(reloadAct); fileMenu->addAction(saveAsAct); + fileMenu->addAction(openFilterScriptAct); + fileMenu->addAction(saveFilterScriptAct); fileMenu->addSeparator(); @@ -296,13 +333,16 @@ void MainWindow::createMenus() //////////////////// Menu Edit ////////////////////////////////////////////////////////////////////////// editMenu = menuBar()->addMenu(tr("&Edit")); + editMenu->addAction(endEditModeAct); //////////////////// Menu Filter ////////////////////////////////////////////////////////////////////////// filterMenu = menuBar()->addMenu(tr("Fi<ers")); filterMenu->addAction(lastFilterAct); filterMenu->addSeparator(); filterMenuSelect = filterMenu->addMenu(tr("Select")); - filterMenuClean = filterMenu->addMenu(tr("Clean")); + filterMenuClean = filterMenu->addMenu(tr("Clean")); + filterMenuRemeshing = filterMenu->addMenu(tr("Remeshing")); + //////////////////// Menu Render ////////////////////////////////////////////////////////////////////////// @@ -312,6 +352,7 @@ void MainWindow::createMenus() renderModeMenu->addAction(backFaceCullAct); renderModeMenu->addActions(renderModeGroupAct->actions()); renderModeMenu->addAction(renderModeTextureAct); + renderModeMenu->addAction(setSelectionRenderingAct); lightingModeMenu=renderMenu->addMenu(tr("&Lighting")); lightingModeMenu->addAction(setLightAct); @@ -397,23 +438,27 @@ void MainWindow::loadPlugins() QObject *plugin = loader.instance(); if (plugin) { - MeshColorizeInterface *iColor = qobject_cast(plugin); - if (iColor) - addToMenu(iColor->actions(), colorModeMenu, SLOT(applyColorMode())); - + //MeshColorizeInterface *iColor = qobject_cast(plugin); + MeshFilterInterface *iFilter = qobject_cast(plugin); if (iFilter) { QAction *filterAction; foreach(filterAction, iFilter->actions()) { + filterMap[filterAction->text()]=filterAction; connect(filterAction,SIGNAL(triggered()),this,SLOT(applyFilter())); - switch(iFilter->getClass(filterAction)) + switch(iFilter->getClass(filterAction)) { + case MeshFilterInterface::FaceColoring : + case MeshFilterInterface::VertexColoring : + colorModeMenu->addAction(filterAction); break; case MeshFilterInterface::Selection : filterMenuSelect->addAction(filterAction); break; case MeshFilterInterface::Cleaning : filterMenuClean->addAction(filterAction); break; + case MeshFilterInterface::Remeshing : + filterMenuRemeshing->addAction(filterAction); break; case MeshFilterInterface::Generic : default: filterMenu->addAction(filterAction); break; @@ -435,9 +480,15 @@ void MainWindow::loadPlugins() addToMenu(iRender->actions(), shadersMenu, SLOT(applyRenderMode())); MeshEditInterface *iEdit = qobject_cast(plugin); + QAction *editAction; if (iEdit) - addToMenu(iEdit->actions(), editMenu, SLOT(applyEditMode())); - + foreach(editAction, iEdit->actions()) + { + editMenu->addAction(editAction); + if(!editAction->icon().isNull()) + editToolBar->addAction(editAction); + connect(editAction,SIGNAL(triggered()),this,SLOT(applyEditMode())); + } pluginFileNames += fileName; } } diff --git a/src/meshlab/mainwindow_RunTime.cpp b/src/meshlab/mainwindow_RunTime.cpp index 30fec2578..a858131c4 100644 --- a/src/meshlab/mainwindow_RunTime.cpp +++ b/src/meshlab/mainwindow_RunTime.cpp @@ -24,6 +24,10 @@ History $Log$ +Revision 1.94 2006/05/25 04:57:45 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. + Revision 1.93 2006/03/07 10:47:50 cignoni Better mask management during io @@ -144,34 +148,20 @@ void MainWindow::updateMenus() if(active){ const RenderMode &rm=GLA()->getCurrentRenderMode(); switch (rm.drawMode) { - case GLW::DMBox: - renderBboxAct->setChecked(true); - break; - case GLW::DMPoints: - renderModePointsAct->setChecked(true); - break; - case GLW::DMWire: - renderModeWireAct->setChecked(true); - break; - case GLW::DMFlat: - renderModeFlatAct->setChecked(true); - break; - case GLW::DMSmooth: - renderModeSmoothAct->setChecked(true); - break; - case GLW::DMFlatWire: - renderModeFlatLinesAct->setChecked(true); - break; - case GLW::DMHidden: - renderModeHiddenLinesAct->setChecked(true); - break; + case GLW::DMBox: renderBboxAct->setChecked(true); break; + case GLW::DMPoints: renderModePointsAct->setChecked(true); break; + case GLW::DMWire: renderModeWireAct->setChecked(true); break; + case GLW::DMFlat: renderModeFlatAct->setChecked(true); break; + case GLW::DMSmooth: renderModeSmoothAct->setChecked(true); break; + case GLW::DMFlatWire: renderModeFlatLinesAct->setChecked(true); break; + case GLW::DMHidden: renderModeHiddenLinesAct->setChecked(true); break; } switch (rm.colorMode) { - case GLW::CMNone: colorModeNoneAct->setChecked(true); break; - case GLW::CMPerVert: colorModePerVertexAct->setChecked(true); break; - case GLW::CMPerFace: colorModePerFaceAct->setChecked(true); break; + case GLW::CMNone: colorModeNoneAct->setChecked(true); break; + case GLW::CMPerVert: colorModePerVertexAct->setChecked(true); break; + case GLW::CMPerFace: colorModePerFaceAct->setChecked(true); break; } lastFilterAct->setEnabled(false); @@ -186,6 +176,13 @@ void MainWindow::updateMenus() } + if(GLA()->getEditAction()) + { + endEditModeAct->setChecked(false); + GLA()->getEditAction()->setChecked(true); + } + else endEditModeAct->setChecked(true); + showLogAct->setChecked(GLA()->isLogVisible()); showInfoPaneAct->setChecked(GLA()->isInfoAreaVisible()); showTrackBallAct->setChecked(GLA()->isTrackBallVisible()); @@ -198,6 +195,7 @@ void MainWindow::updateMenus() setFancyLightingAct->setChecked(rm.fancyLighting); setDoubleLightingAct->setChecked(rm.doubleSideLighting); + setSelectionRenderingAct->setChecked(rm.selectedFaces); foreach (QAction *a,TotalDecoratorsList){a->setChecked(false);} if(GLA()->iDecoratorsList){ @@ -209,34 +207,86 @@ void MainWindow::updateMenus() void MainWindow::applyLastFilter() { - GLA()->getLastAppliedFilter()->activate(QAction::Trigger); + GLA()->getLastAppliedFilter()->activate(QAction::Trigger); } +void MainWindow::runFilterScript() +{ + FilterScript::iterator ii; + for(ii= GLA()->filterHistory.actionList.begin();ii!= GLA()->filterHistory.actionList.end();++ii) + { + MeshFilterInterface *iFilter = qobject_cast( (*ii).first->parent()); + iFilter->applyFilter( (*ii).first, *(GLA()->mm), (*ii).second, QCallBack ); + GLA()->log.Log(GLLogStream::Info,"Re-Applied filter %s",qPrintable((*ii).first->text())); + } +} +// ///////////////////////////////////////////////// +// The Very Important Procedure of applying a filter +// ///////////////////////////////////////////////// + void MainWindow::applyFilter() { QAction *action = qobject_cast(sender()); MeshFilterInterface *iFilter = qobject_cast(action->parent()); - qb->show(); - iFilter->setLog(&(GLA()->log)); + + // (1) Ask for filter requirements (eg a filter can need topology, border flags etc) + // and statisfy them + int req=iFilter->getRequirements(action); + GLA()->mm->updateDataMask(req); + + + // (2) Ask for filter parameters (e.g. user defined threshold that could require a widget) + FilterParameter par; + iFilter->getParameters(action, GLA(),*(GLA()->mm), par); + - // Log if filter applied succesfully - if(iFilter->applyFilter(action,*(GLA()->mm ),GLA(),QCallBack)) + // (3) save the current filter and its parameters in the history + GLA()->filterHistory.actionList.append(qMakePair(action,par)); + + qDebug("Filter History size %i",GLA()->filterHistory.actionList.size()); + qDebug("Filter History Last entry %s",qPrintable (GLA()->filterHistory.actionList.front().first->text())); + + qb->show(); + iFilter->setLog(&(GLA()->log)); + // (4) Apply the Filter + bool ret=iFilter->applyFilter(action, *(GLA()->mm), par, QCallBack); + + // (5) Apply post filter actions (e.g. recompute non updated stuff if needed) + + if(ret) { - GLA()->log.Log(GLLogStream::Info,"Applied filter %s",action->text().toLocal8Bit().constData()); + GLA()->log.Log(GLLogStream::Info,"Applied filter %s",qPrintable(action->text())); GLA()->setWindowModified(true); GLA()->setLastAppliedFilter(action); lastFilterAct->setText(QString("Apply filter ") + action->text()); lastFilterAct->setEnabled(true); } - qb->reset(); -} + // at the end for filters that change the color set the appropriate color mode + if(iFilter->getClass(action)==MeshFilterInterface::FaceColoring ) + GLA()->setColorMode(vcg::GLW::CMPerFace); + if(iFilter->getClass(action)==MeshFilterInterface::VertexColoring ) + GLA()->setColorMode(vcg::GLW::CMPerVert); + if(iFilter->getClass(action)==MeshFilterInterface::Selection ) + GLA()->setSelectionRendering(true); + + qb->reset(); + updateMenus(); +} +void MainWindow::endEditMode() +{ + GLA()->getEditAction()->setChecked(false); + GLA()->endEdit(); +} void MainWindow::applyEditMode() { QAction *action = qobject_cast(sender()); MeshEditInterface *iEdit = qobject_cast(action->parent()); - GLA()->setEdit(iEdit); - GLA()->log.Log(GLLogStream::Info,"Started Mode %s",action->text().toLocal8Bit().constData()); + GLA()->setEdit(iEdit,action); + iEdit->StartEdit(action,*(GLA()->mm),GLA()); + GLA()->log.Log(GLLogStream::Info,"Started Mode %s",qPrintable (action->text())); + GLA()->setSelectionRendering(true); + updateMenus(); } void MainWindow::applyRenderMode() @@ -255,7 +305,7 @@ void MainWindow::applyRenderMode() if(iRenderTemp->isSupported()) { GLA()->setRenderer(iRenderTemp,action); - GLA()->log.Log(GLLogStream::Info,"%s",action->text().toLocal8Bit().constData()); // Prints out action name + GLA()->log.Log(GLLogStream::Info,"%s",qPrintable(action->text())); // Prints out action name } else { @@ -269,9 +319,9 @@ void MainWindow::applyRenderMode() void MainWindow::applyColorMode() { QAction *action = qobject_cast(sender()); - MeshColorizeInterface *iColorTemp = qobject_cast(action->parent()); + MeshFilterInterface *iColorTemp = qobject_cast(action->parent()); iColorTemp->setLog(&(GLA()->log)); - iColorTemp->Compute(action,*(GLA()->mm ),GLA()->getCurrentRenderMode(), GLA()); + //iColorTemp->Compute(action,*(GLA()->mm ),GLA()->getCurrentRenderMode(), GLA()); GLA()->log.Log(GLLogStream::Info,"Applied colorize %s",action->text().toLocal8Bit().constData()); updateMenus(); } @@ -338,10 +388,15 @@ void MainWindow::setFancyLighting() void MainWindow::toggleBackFaceCulling() { RenderMode &rm = GLA()->getCurrentRenderMode(); - GLA()->setBackFaceCulling(!rm.backFaceCull); } +void MainWindow::toggleSelectionRendering() +{ + RenderMode &rm = GLA()->getCurrentRenderMode(); + GLA()->setSelectionRendering(!rm.selectedFaces); +} + enum TypeIO{IMPORT,EXPORT}; void MainWindow::LoadKnownFilters(QStringList &filters, QHash &allKnownFormats, int type) @@ -392,6 +447,26 @@ void MainWindow::LoadKnownFilters(QStringList &filters, QHash &all filters.push_front(allKnownFormatsFilter); } +void MainWindow::openFilterScript(QString fileName) +{ + if (fileName.isEmpty()) + fileName = QFileDialog::getOpenFileName(this,tr("Open Filter Script File"),".", "*.mls"); + + if (fileName.isEmpty()) return; + + +} + +void MainWindow::saveFilterScript(QString fileName) +{ + if (fileName.isEmpty()) + fileName = QFileDialog::getOpenFileName(this,tr("Open Filter Script File"),".", "*.mls"); + + if (fileName.isEmpty()) return; +} + + + void MainWindow::open(QString fileName) { // Opening files in a transparent form (IO plugins contribution is hidden to user) @@ -434,24 +509,22 @@ void MainWindow::open(QString fileName) gla=new GLArea(workspace); gla->mm=mm; gla->mm->mask = mask; // store mask into model structure - + gla->setFileName(fileName); gla->setWindowTitle(QFileInfo(fileName).fileName()+tr("[*]")); gla->showInfoArea(true); workspace->addWindow(gla); if(workspace->isVisible()) gla->showMaximized(); setCurrentFile(fileName); + + if( mask & vcg::tri::io::Mask::IOM_FACECOLOR) + gla->setColorMode(GLW::CMPerFace); if( mask & vcg::tri::io::Mask::IOM_VERTCOLOR) { gla->mm->storeVertexColor(); gla->setColorMode(GLW::CMPerVert); } - else if( mask & vcg::tri::io::Mask::IOM_FACECOLOR) - gla->setColorMode(GLW::CMPerFace); - else - gla->setColorMode(GLW::CMNone); - updateMenus(); - renderModeTextureAct->setChecked(false); + renderModeTextureAct->setChecked(false); renderModeTextureAct->setEnabled(false); if(!GLA()->mm->cm.textures.empty()) { @@ -460,10 +533,10 @@ void MainWindow::open(QString fileName) GLA()->setTextureMode(GLW::TMPerWedgeMulti); } vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(mm->cm); + updateMenus(); } - //qb->hide(); - qb->reset(); + qb->reset(); } void MainWindow::openRecentFile() diff --git a/src/meshlab/meshlab.pro b/src/meshlab/meshlab.pro index 4740853c9..dcb73db86 100644 --- a/src/meshlab/meshlab.pro +++ b/src/meshlab/meshlab.pro @@ -15,14 +15,13 @@ SOURCES = main.cpp \ mainwindow_Init.cpp \ mainwindow_RunTime.cpp\ meshmodel.cpp \ - GLLogStream.cpp \ + GLLogStream.cpp \ glarea.cpp \ plugindialog.cpp \ customDialog.cpp \ saveSnapshotDialog.cpp \ savemaskexporter.cpp \ changetexturename.cpp \ - ../../../sf/wrap/ply/plylib.cpp\ ../../../sf/wrap/gui/trackball.cpp\ ../../../sf/wrap/gui/trackmode.cpp \ ../../../code/lib/glew/src/glew.c diff --git a/src/meshlab/meshlab.qrc b/src/meshlab/meshlab.qrc index 5fef16eab..bdefd2c6c 100644 --- a/src/meshlab/meshlab.qrc +++ b/src/meshlab/meshlab.qrc @@ -1,21 +1,23 @@ - images/bbox.png images/backlines.png + images/bbox.png + images/eye_256_splash.png images/flat.png images/flatlines.png images/info.png images/lightoff.png images/lighton.png + images/logo.png images/open.png images/points.png + images/reload.png images/save.png + images/selected.png images/smooth.png - images/wire.png + images/snapshot.png images/textures.png - images/logo.png - images/eye_256_splash.png - images/snapshot.png - images/reload.png + images/wire.png + images/no_edit.png diff --git a/src/meshlab/meshmodel.cpp b/src/meshlab/meshmodel.cpp index 51389a8a6..ce7c9a170 100644 --- a/src/meshlab/meshmodel.cpp +++ b/src/meshlab/meshmodel.cpp @@ -23,6 +23,10 @@ /**************************************************************************** History $Log$ +Revision 1.23 2006/05/25 04:57:45 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. + Revision 1.22 2006/01/17 23:45:12 cignoni Removed useless open function @@ -32,45 +36,6 @@ update ply::PlyMask -> io::Mask Revision 1.20 2005/12/22 21:05:43 cignoni Removed Optional Face Normal and added some initalization after opening -Revision 1.19 2005/12/09 18:16:12 fmazzant -added generic obj save with plugin arch. - -Revision 1.18 2005/12/09 00:26:25 buzzelli -io importing mechanism adapted in order to be fully transparent towards the user - -Revision 1.17 2005/12/07 00:56:40 fmazzant -added support for exporter generic obj file (level base) - -Revision 1.16 2005/12/06 16:27:43 fmazzant -added obj file in generic open dialog - -Revision 1.15 2005/12/04 00:22:46 cignoni -Switched from progresBar widget to progressbar dialog - -Revision 1.14 2005/12/02 00:54:13 cignoni -Added TextureMode in render - -Revision 1.13 2005/11/25 11:55:59 alemochi -Added function to Enable/Disable lighting (work in progress) - -Revision 1.12 2005/11/24 01:45:28 cignoni -commented line 62. dangerous unuseful debug line. - -Revision 1.11 2005/11/24 01:38:36 cignoni -Added new plugins intefaces, tested with shownormal render mode - -Revision 1.10 2005/11/23 00:04:03 cignoni -added hint for better hiddenline - -Revision 1.9 2005/11/22 11:40:14 glvertex -Now using a single method to compute normals (PerVertePerFace instead PerVertex then PerFace) - -Revision 1.8 2005/11/21 22:09:35 cignoni -added missing enablenormal - -Revision 1.7 2005/11/21 12:12:54 cignoni -Added copyright info - ****************************************************************************/ #include "meshmodel.h" @@ -79,8 +44,32 @@ Added copyright info bool MeshModel::Render(GLW::DrawMode dm, GLW::ColorMode cm, GLW::TextureMode tm) { - glw.SetHintParamf(GLW::HNPZTwist,0.0005f); // glColor3f(.8f,.8f,.8f); glw.Draw(dm,cm,tm); return true; } + +bool MeshModel::RenderSelectedFaces() +{ + 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; + glBegin(GL_TRIANGLES); + 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)); + } + glEnd(); + glPopAttrib(); + return true; +} diff --git a/src/meshlab/meshmodel.h b/src/meshlab/meshmodel.h index 64f1b536a..f7536d34e 100644 --- a/src/meshlab/meshmodel.h +++ b/src/meshlab/meshmodel.h @@ -23,6 +23,10 @@ /**************************************************************************** History $Log$ +Revision 1.21 2006/05/25 04:57:45 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. + Revision 1.20 2006/02/13 14:20:13 cignoni Removed glew.h @@ -53,6 +57,8 @@ Made FFAdj optional and added store and restore color functions #include #include #include +#include +#include #include #include @@ -65,13 +71,29 @@ class CEdge; // dummy prototype never used class CFaceO; class CVertexO; -// Opt stuff +//Vert Mem Occupancy --- 36 --- -class CVertexO : public VertexSimp2< CVertexO, CEdge, CFaceO, vert::Coord3f, vert::Color4b, vert::Normal3f, vert::Qualityf, vert::BitFlags >{ -public: - Color4b origC; +class CVertexO : public VertexSimp2< CVertexO, CEdge, CFaceO, + vert::Coord3f, /* 12b */ + vert::BitFlags, /* 4b */ + vert::Normal3f, /* 12b */ + vert::Qualityf, /* 4b */ + vert::Color4b /* 4b */ + >{ }; -class CFaceO : public FaceSimp2< CVertexO, CEdge, CFaceO, face::InfoOcf, face::Color4b, face::FFAdjOcf, face::WedgeTexturefOcf, face::VertexRef, face::BitFlags, face::Normal3f, face::Mark > {}; + +//Face Mem Occupancy --- 32 --- + +class CFaceO : public FaceSimp2< CVertexO, CEdge, CFaceO, + face::InfoOcf, /* 4b */ + face::VertexRef, /*12b */ + face::BitFlags, /* 4b */ + face::Normal3f, /*12b */ + face::MarkOcf, /* 0b */ + face::Color4bOcf, /* 0b */ + face::FFAdjOcf, /* 0b */ + face::WedgeTexturefOcf /* 0b */ + > {}; class CMeshO : public vcg::tri::TriMesh< vector, face::vector_ocf > {}; /* @@ -85,27 +107,129 @@ class MeshModel : public tri::io::Mask { public: + enum FilterReq { MM_NONE = 0x0000, + MM_BORDERFLAG = 0x0001, + MM_FACETOPO = 0x0002, + MM_WEDGTEXCOORD = 0x0004, + MM_FACECOLOR = 0x0008, + MM_FACEMARK = 0x0010, + MM_ALL = 0xffff} ; + + CMeshO cm; GlTrimesh glw; + vector originalVertexColor; + + // Bitmask denoting what fields are currently kept updated in mesh + int currentDataMask; + // Bitmask denoting what fields are loaded/saved + int mask; + MeshModel() { +// size_t faceSize=sizeof(CFaceO); +// size_t vertSize=sizeof(CVertexO); + glw.m=&cm; - cm.face.EnableWedgeTex(); - cm.face.EnableFFAdjacency(); + currentDataMask=MM_NONE; mask= IOM_VERTCOORD | IOM_FACEINDEX | IOM_FLAGS; } bool Render(GLW::DrawMode dm, GLW::ColorMode cm, GLW::TextureMode tm); + bool RenderSelectedFaces(); + inline void storeVertexColor() { + originalVertexColor.resize(cm.vert.size()); + vector::iterator ci; CMeshO::VertexIterator vi; - for(vi=cm.vert.begin();vi!=cm.vert.end();++vi) (*vi).origC=(*vi).C(); + for(vi=cm.vert.begin(),ci=originalVertexColor.begin();vi!=cm.vert.end();++vi,++ci) + (*ci)=(*vi).C(); } inline void restoreVertexColor() { + vector::iterator ci; CMeshO::VertexIterator vi; - for(vi=cm.vert.begin();vi!=cm.vert.end();++vi) (*vi).C()=(*vi).origC; + for(vi=cm.vert.begin(),ci=originalVertexColor.begin();vi!=cm.vert.end();++vi,++ci) + (*vi).C()=(*ci); } - int mask; +// FUNZIONE equivalente alla updatedatamask ma solo che prende in ingresso mask da filetype. + void Enable(int openingFileMask) + { + if( openingFileMask & IOM_WEDGTEXCOORD ) updateDataMask(MM_WEDGTEXCOORD); + if( openingFileMask & IOM_FACECOLOR ) updateDataMask(MM_FACECOLOR); + } + + // Ogni filtro dichiara + // 1) di che cosa ha bisogno + // 2) che cosa sa aggiornare (di solito quello di cui ha bisogno) + // 3) quello che ha cambiato (vertici topologia colore) + + // il framework si preoccupa + // 1) prima di invocare il filtro di preparare quel che serve + // 2) dopo il filtro di aggiornare quello che non ha aggiornato il filtro + + // Enable optional fields that could be needed + void updateDataMask(int neededDataMask) + { + if( ( (neededDataMask & MM_FACETOPO)!=0) && (currentDataMask& MM_FACETOPO)==0) + { + cm.face.EnableFFAdjacency(); + currentDataMask |= MM_FACETOPO; + tri::UpdateTopology::FaceFace(cm); + } + if( ( (neededDataMask & MM_BORDERFLAG)!=0) && (currentDataMask& MM_BORDERFLAG)==0) + { + if(currentDataMask& MM_FACETOPO) tri::UpdateFlags::FaceBorderFromFF(cm); + else tri::UpdateFlags::FaceBorderFromNone(cm); + currentDataMask |= MM_BORDERFLAG; + } + if( ( (neededDataMask & MM_WEDGTEXCOORD)!=0) && (currentDataMask& MM_WEDGTEXCOORD)==0) + { + cm.face.EnableWedgeTex(); + currentDataMask |= MM_WEDGTEXCOORD; + } + if( ( (neededDataMask & MM_FACECOLOR)!=0) && (currentDataMask& MM_FACECOLOR)==0) + { + cm.face.EnableColor(); + currentDataMask |= MM_FACECOLOR; + } + if( ( (neededDataMask & MM_FACEMARK)!=0) && (currentDataMask& MM_FACEMARK)==0) + { + cm.face.EnableMark(); + currentDataMask |= MM_FACEMARK; + } + } +}; + +class RenderMode +{ +public: + vcg::GLW::DrawMode drawMode; + vcg::GLW::ColorMode colorMode; + vcg::GLW::TextureMode textureMode; + + bool lighting; + bool backFaceCull; + bool doubleSideLighting; + bool fancyLighting; + bool castShadow; + bool selectedFaces; + vcg::Point3f lightDir; + + + RenderMode() + { + drawMode = GLW::DMFlat; + colorMode = GLW::CMNone; + textureMode = GLW::TMNone; + + lighting = true; + backFaceCull = false; + doubleSideLighting = false; + fancyLighting = false; + castShadow = false; + selectedFaces=false; + } }; #endif \ No newline at end of file diff --git a/src/meshlab/plugindialog.cpp b/src/meshlab/plugindialog.cpp index 798343218..b003332aa 100644 --- a/src/meshlab/plugindialog.cpp +++ b/src/meshlab/plugindialog.cpp @@ -23,6 +23,10 @@ /**************************************************************************** History $Log$ +Revision 1.12 2006/05/25 04:57:45 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. + Revision 1.11 2006/02/15 23:09:06 fmazzant added the part of MeshIO credits @@ -155,12 +159,6 @@ void PluginDialog::populateTreeWidget(const QString &path,const QStringList &fil foreach(QAction *a,iDecorate->actions()){Templist.push_back(a->text());} addItems(pluginItem,Templist); } - MeshColorizeInterface *iColorize = qobject_cast(plugin); - if (iColorize){ - QStringList Templist; - foreach(QAction *a,iColorize->actions()){Templist.push_back(a->text());} - addItems(pluginItem,Templist); - } MeshFilterInterface *iFilter = qobject_cast(plugin); if (iFilter){ QStringList Templist; @@ -233,13 +231,6 @@ void PluginDialog::displayInfo(QTreeWidgetItem* item,int ncolumn) else foreach(QAction *a,iDecorate->actions()) if (actionName==a->text()) labelInfo->setText(iDecorate->Info(a).Help); } - MeshColorizeInterface *iColorize = qobject_cast(plugin); - if (iColorize) - { - if (item->parent()==NULL) labelInfo->setText(QString("Author: ")+iColorize->Info().Author+QString(" Date: ")+iColorize->Info().Date+QString(" Version: ")+iColorize->Info().Version); - else foreach(QAction *a,iColorize->actions()) - if (actionName==a->text()) labelInfo->setText(iColorize->Info(a).Help); - } MeshFilterInterface *iFilter = qobject_cast(plugin); if (iFilter) { diff --git a/src/meshlab/ui/GenericELDialog.ui b/src/meshlab/ui/GenericELDialog.ui index feed93f7e..cb39e1b4e 100644 --- a/src/meshlab/ui/GenericELDialog.ui +++ b/src/meshlab/ui/GenericELDialog.ui @@ -57,7 +57,7 @@ - <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><pre style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:Courier New,courier;">Percentile</span></pre></body></html> + Percentile @@ -97,7 +97,7 @@ - <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#000000;">Diagonal percentage</span></p></body></html> + Diagonal Percentage @@ -119,6 +119,9 @@ 100 + + 0.2 + diff --git a/src/meshlabplugins/meshcolorize/curvature.h b/src/meshlabplugins/meshcolorize/curvature.h index bcb838077..abbce7364 100644 --- a/src/meshlabplugins/meshcolorize/curvature.h +++ b/src/meshlabplugins/meshcolorize/curvature.h @@ -23,6 +23,10 @@ /**************************************************************************** History $Log$ +Revision 1.9 2006/05/25 04:57:45 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. + Revision 1.8 2006/02/04 09:41:44 vannini Better handling of curvature computation for border vertex Plugin info updated @@ -89,8 +93,12 @@ namespace vcg class Frange { public: - float min; - float max; + Frange(){} + Frange(pair minmax):minV(minmax.first),maxV(minmax.second){} + Frange(float _min,float _max):minV(_min),maxV(_max){} + + float minV; + float maxV; }; template class Curvature @@ -208,18 +216,21 @@ namespace vcg } public: + // REQUIREMENTS: + // FF Topology + // Face Border flags + // Vertex Border flags + // in case of doubts before calling it: + // vcg::tri::UpdateTopology::FaceFace((*ms)); + // vcg::tri::UpdateFlags::FaceBorderFromFF((*ms)); + // vcg::tri::UpdateFlags::VertexBorderFromFace((*ms)); + Curvature(MESH_TYPE &mt):ms(&mt) { TDCurvPtr = new SimpleTempData((*ms).vert); (*TDCurvPtr).Start(CurvData()); TDAreaPtr = new SimpleTempData((*ms).vert); (*TDAreaPtr).Start(AreaData()); - - vcg::tri::UpdateTopology::FaceFace((*ms)); - vcg::tri::UpdateFlags::FaceBorderFromFF((*ms)); - vcg::tri::UpdateFlags::VertexBorderFromFace((*ms)); - //vcg::tri::UpdateColor::VertexBorderFlag((*ms)); - ComputeHK(); } @@ -268,49 +279,6 @@ namespace vcg } } - Frange minMaxQ() - { - VertexIterator vi; - Frange r; - r.min=std::numeric_limits::max(); - r.max=-std::numeric_limits::max(); - - for(vi=(*ms).vert.begin(); vi!=(*ms).vert.end(); ++vi) if(!(*vi).IsD() /*&& !(*vi).IsB()*/) - { - if ((*vi).Q() < r.min) r.min = (*vi).Q(); - if ((*vi).Q() > r.max) r.max = (*vi).Q(); - } - - return r; - - } - - Frange histoPercentile(Frange Q, float histo_frac=DEFAULT_HISTO_FRAC, int histo_range=DEFAULT_HISTO_RANGE) - { - VertexIterator vi; - vcg::Histogram histo; - - histo.SetRange(Q.min, Q.max, histo_range); - - for(vi=(*ms).vert.begin(); vi!=(*ms).vert.end(); ++vi) if(!(*vi).IsD() /*&& !(*vi).IsB()*/) - histo.Add((*vi).Q()); - - Q.min = histo.Percentile(histo_frac); - Q.max = histo.Percentile(1.0f - histo_frac); - - return Q; - } - - - void ColorizeByEqualizedQuality(Frange P) - { - VertexIterator vi; - - for(vi=(*ms).vert.begin(); vi!=(*ms).vert.end(); ++vi) if(!(*vi).IsD() /*&& !(*vi).IsB()*/) - (*vi).C().ColorRamp(P.min, P.max, (*vi).Q()); - - } - }; } #endif // CURVATURE_H \ No newline at end of file diff --git a/src/meshlabplugins/meshcolorize/meshcolorize.cpp b/src/meshlabplugins/meshcolorize/meshcolorize.cpp index 39ebf69a2..f67cefaf6 100644 --- a/src/meshlabplugins/meshcolorize/meshcolorize.cpp +++ b/src/meshlabplugins/meshcolorize/meshcolorize.cpp @@ -23,6 +23,10 @@ /**************************************************************************** History $Log$ +Revision 1.25 2006/05/25 04:57:45 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. + Revision 1.24 2006/02/04 09:41:44 vannini Better handling of curvature computation for border vertex Plugin info updated @@ -102,6 +106,7 @@ Added copyright info #include #include #include +#include #include #include "meshcolorize.h" #include "color_manifold.h" @@ -111,40 +116,36 @@ Added copyright info using namespace vcg; ExtraMeshColorizePlugin::ExtraMeshColorizePlugin() { - actionList << new QAction(ST(CP_EQUALIZE), this); - actionList << new QAction(ST(CP_GAUSSIAN), this); - actionList << new QAction(ST(CP_MEAN), this); - actionList << new QAction(ST(CP_RMS), this); - actionList << new QAction(ST(CP_ABSOLUTE), this); - actionList << new QAction(ST(CP_SELFINTERSECT), this); - actionList << new QAction(ST(CP_BORDER), this); - actionList << new QAction(ST(CP_COLORNM), this); - actionList << new QAction(ST(CP_SMOOTH), this); - actionList << new QAction(ST(CP_RESTORE_ORIGINAL), this); + typeList << + CP_MAP_QUALITY_INTO_COLOR << + CP_GAUSSIAN << + CP_MEAN << + CP_RMS << + CP_ABSOLUTE << + CP_SELFINTERSECT << + CP_BORDER << + CP_COLOR_NON_MANIFOLD << + CP_SMOOTH << + CP_RESTORE_ORIGINAL; + + FilterType tt; + foreach(tt , types()) + actionList << new QAction(ST(tt), this); } -const QString ExtraMeshColorizePlugin::ST(ColorizeType c) { + +const QString ExtraMeshColorizePlugin::ST(FilterType c) { switch(c) { - case CP_EQUALIZE: - return QString("Colorize by Quality"); - case CP_GAUSSIAN: - return QString("Gaussian Curvature (equalized)"); - case CP_MEAN: - return QString("Mean Curvature (equalized)"); - case CP_RMS: - return QString("Root mean square Curvature (equalized)"); - case CP_ABSOLUTE: - return QString("Absolute Curvature (equalized)"); - case CP_SELFINTERSECT: - return QString("Self Intersections"); - case CP_BORDER: - return QString("Border"); - case CP_COLORNM: - return QString("Color non Manifold"); - case CP_SMOOTH: - return QString("Smooth Color"); - case CP_RESTORE_ORIGINAL: - return QString("Restore Color"); + case CP_MAP_QUALITY_INTO_COLOR: return QString("Colorize by Quality"); + case CP_GAUSSIAN: return QString("Gaussian Curvature (equalized)"); + case CP_MEAN: return QString("Mean Curvature (equalized)"); + case CP_RMS: return QString("Root mean square Curvature (equalized)"); + case CP_ABSOLUTE: return QString("Absolute Curvature (equalized)"); + case CP_SELFINTERSECT: return QString("Self Intersections"); + case CP_BORDER: return QString("Border"); + case CP_COLOR_NON_MANIFOLD: return QString("Color non Manifold"); + case CP_SMOOTH: return QString("Smooth Color"); + case CP_RESTORE_ORIGINAL: return QString("Restore Color"); default: assert(0); } return QString("error!"); @@ -152,58 +153,28 @@ const QString ExtraMeshColorizePlugin::ST(ColorizeType c) { const ActionInfo &ExtraMeshColorizePlugin::Info(QAction *action) { static ActionInfo ai; - - if( action->text() == ST(CP_EQUALIZE) ) + switch(ID(action)) { - ai.Help = tr("Colorize vertex and faces depending on quality field (manually equalized)."); - ai.ShortHelp = tr("Colorize by quality"); - } - if( action->text() == ST(CP_GAUSSIAN) ) - { - ai.Help = tr("Colorize vertex and faces depending on equalized gaussian curvature."); - ai.ShortHelp = tr("Colorize by gaussian curvature"); - } - if( action->text() == ST(CP_MEAN) ) - { - ai.Help = tr("Colorize vertex and faces depending on equalized mean curvature."); - ai.ShortHelp = tr("Colorize by mean curvature"); - } - if( action->text() == ST(CP_RMS) ) - { - ai.Help = tr("Colorize vertex and faces depending on equalized root mean square curvature."); - ai.ShortHelp = tr("Colorize by root mean square curvature"); - } - if( action->text() == ST(CP_ABSOLUTE) ) - { - ai.Help = tr("Colorize vertex and faces depending on equalize absolute curvature."); - ai.ShortHelp = tr("Colorize by absolute curvature"); - } - if( action->text() == ST(CP_SELFINTERSECT) ) - { - ai.Help = tr("Colorize only self intersecting faces."); - ai.ShortHelp = tr("Colorize only self intersecting faces"); - } - - if( action->text() == ST(CP_BORDER) ) - { - ai.Help = tr("Colorize only border edges."); - ai.ShortHelp = tr("Colorize only border edges"); - } - - if( action->text() == ST(CP_COLORNM) ) - { - ai.Help = tr("Colorize only non manifold edges."); - ai.ShortHelp = tr("Colorize only non manifold edges"); - } - if( action->text() == ST(CP_SMOOTH) ) - { - ai.Help = tr("Apply laplacian smooth for colors."); - ai.ShortHelp = tr("Laplacian smooth for colors"); - } - if( action->text() == ST(CP_RESTORE_ORIGINAL) ) - { - ai.Help = tr("Restore original per vertex color."); - ai.ShortHelp = tr("Restore original per vertex color"); + case CP_MAP_QUALITY_INTO_COLOR : ai.Help = tr("Colorize vertex and faces depending on quality field (manually equalized)."); + ai.ShortHelp = tr("Colorize by quality");break; + case CP_GAUSSIAN : ai.Help = tr("Colorize vertex and faces depending on equalized gaussian curvature."); + ai.ShortHelp = tr("Colorize by gaussian curvature");break; + case CP_MEAN : ai.Help = tr("Colorize vertex and faces depending on equalized mean curvature."); + ai.ShortHelp = tr("Colorize by mean curvature");break; + case CP_RMS : ai.Help = tr("Colorize vertex and faces depending on equalized root mean square curvature."); + ai.ShortHelp = tr("Colorize by root mean square curvature");break; + case CP_ABSOLUTE : ai.Help = tr("Colorize vertex and faces depending on equalize absolute curvature."); + ai.ShortHelp = tr("Colorize by absolute curvature");break; + case CP_SELFINTERSECT: ai.Help = tr("Colorize only self intersecting faces."); + ai.ShortHelp = tr("Colorize only self intersecting faces");break; + case CP_BORDER : ai.Help = tr("Colorize only border edges."); + ai.ShortHelp = tr("Colorize only border edges");break; + case CP_COLOR_NON_MANIFOLD: ai.Help = tr("Colorize only non manifold edges."); + ai.ShortHelp = tr("Colorize only non manifold edges");break; + case CP_SMOOTH : ai.Help = tr("Apply laplacian smooth for colors."); + ai.ShortHelp = tr("Laplacian smooth for colors");break; + case CP_RESTORE_ORIGINAL : ai.Help = tr("Restore original per vertex color."); + ai.ShortHelp = tr("Restore original per vertex color"); break; } return ai; } @@ -216,80 +187,88 @@ const PluginInfo &ExtraMeshColorizePlugin::Info() return ai; } -QList ExtraMeshColorizePlugin::actions() const { - return actionList; -} -void ExtraMeshColorizePlugin::Compute(QAction * mode, MeshModel &m, RenderMode &rm, GLArea *parent){ - if(mode->text() == ST(CP_EQUALIZE)) - { - Curvature c(m.cm); - - Frange mmmq = c.minMaxQ(); - eqSettings.meshMinQ = mmmq.min; - eqSettings.meshMaxQ = mmmq.max; - Frange hmmq=c.histoPercentile(mmmq, 1.0f / (float) eqSettings.percentile, eqSettings.range); - eqSettings.histoMinQ = hmmq.min; - eqSettings.histoMaxQ = hmmq.max; +const int ExtraMeshColorizePlugin::getRequirements(QAction *action) +{ + switch(ID(action)) + { + case CP_GAUSSIAN: + case CP_MEAN: + case CP_RMS: + case CP_ABSOLUTE: return MeshModel::MM_FACETOPO | MeshModel::MM_BORDERFLAG; + case CP_SELFINTERSECT: return MeshModel::MM_FACEMARK | MeshModel::MM_FACETOPO | MeshModel::MM_FACECOLOR; + case CP_BORDER: return MeshModel::MM_BORDERFLAG; + case CP_COLOR_NON_MANIFOLD: return MeshModel::MM_FACETOPO; + case CP_SMOOTH: + case CP_RESTORE_ORIGINAL: + case CP_MAP_QUALITY_INTO_COLOR: return 0; + default: assert(0); + } + return 0; +} + + +bool ExtraMeshColorizePlugin::getParameters(QAction *action, QWidget *parent, MeshModel &m,FilterParameter &par) +{ + par.clear(); + switch(ID(action)) + { + case CP_MAP_QUALITY_INTO_COLOR : + Histogramf H; + tri::Stat::ComputePerVertexQualityHistogram(m.cm,H); + + Frange mmmq(tri::Stat::ComputePerVertexQualityMinMax(m.cm)); + eqSettings.meshMinQ = mmmq.minV; + eqSettings.meshMaxQ = mmmq.maxV; + + eqSettings.histoMinQ = H.Percentile(eqSettings.percentile/100); + eqSettings.histoMaxQ = H.Percentile(1.0f-eqSettings.percentile/100); EqualizerDialog eqdialog(parent); eqdialog.setValues(eqSettings); + if (eqdialog.exec()!=QDialog::Accepted) - return; + return false; + Frange FinalRange; eqSettings=eqdialog.getValues(); - if (eqSettings.useManual) - { - Frange manual; - manual.min=eqSettings.manualMinQ; - manual.max=eqSettings.manualMaxQ; - c.ColorizeByEqualizedQuality(manual); - }else{ - c.ColorizeByEqualizedQuality(c.histoPercentile(mmmq, 1.0f / (float) eqSettings.percentile, eqSettings.range)); - } + if (eqSettings.useManual) + FinalRange = Frange(eqSettings.manualMinQ,eqSettings.manualMaxQ); + else + { + FinalRange.minV=H.Percentile(eqSettings.percentile); + FinalRange.maxV=H.Percentile(1.0f-eqSettings.percentile); + } + + par.addFloat("RangeMin",FinalRange.minV); + par.addFloat("RangeMax",FinalRange.maxV); + } +} +bool ExtraMeshColorizePlugin::applyFilter(QAction *filter, MeshModel &m, FilterParameter & par, vcg::CallBackPos *cb) +{ + switch(ID(filter)) { + case CP_MAP_QUALITY_INTO_COLOR : + { +// Curvature c(m.cm); + break; + } + case CP_GAUSSIAN: + case CP_MEAN: + case CP_RMS: + case CP_ABSOLUTE: + { + Curvature c(m.cm); + switch (ID(filter)){ + case CP_GAUSSIAN: c.MapGaussianCurvatureIntoQuality(); break; + case CP_MEAN: c.MapMeanCurvatureIntoQuality(); break; + case CP_RMS: c.MapRMSCurvatureIntoQuality(); break; + case CP_ABSOLUTE: c.MapAbsoluteCurvatureIntoQuality(); break; + } - rm.colorMode = GLW::CMPerVert; - - return; + tri::UpdateColor::VertexQuality(m.cm,-.1,.1); + break; } - - if(mode->text() == ST(CP_GAUSSIAN)) - { - Curvature c(m.cm); - c.MapGaussianCurvatureIntoQuality(); - c.ColorizeByEqualizedQuality(c.histoPercentile(c.minMaxQ(), 1.0f / (float) eqSettings.percentile, eqSettings.range)); - rm.colorMode = GLW::CMPerVert; - return; - } - - if(mode->text() == ST(CP_MEAN)) - { - Curvature c(m.cm); - c.MapMeanCurvatureIntoQuality(); - c.ColorizeByEqualizedQuality(c.histoPercentile(c.minMaxQ(), 1.0f / (float) eqSettings.percentile, eqSettings.range)); - rm.colorMode = GLW::CMPerVert; - return; - } - - if(mode->text() == ST(CP_RMS)) - { - Curvature c(m.cm); - c.MapRMSCurvatureIntoQuality(); - c.ColorizeByEqualizedQuality(c.histoPercentile(c.minMaxQ(), 1.0f / (float) eqSettings.percentile, eqSettings.range)); - rm.colorMode = GLW::CMPerVert; - return; - } - - if(mode->text() == ST(CP_ABSOLUTE)) - { - Curvature c(m.cm); - c.MapAbsoluteCurvatureIntoQuality(); - c.ColorizeByEqualizedQuality(c.histoPercentile(c.minMaxQ(), 1.0f / (float) eqSettings.percentile, eqSettings.range)); - rm.colorMode = GLW::CMPerVert; - return; - } - - if(mode->text() == ST(CP_SELFINTERSECT)) + case CP_SELFINTERSECT: { vector IntersFace; tri::Clean::SelfIntersections(m.cm,IntersFace); @@ -298,38 +277,45 @@ void ExtraMeshColorizePlugin::Compute(QAction * mode, MeshModel &m, RenderMode & for(fpi=IntersFace.begin();fpi!=IntersFace.end();++fpi) (*fpi)->C()=Color4b::Red; - rm.colorMode = GLW::CMPerFace; - return; + break; } - if(mode->text() == ST(CP_BORDER)) - { - vcg::tri::UpdateTopology::FaceFace(m.cm); - vcg::tri::UpdateFlags::FaceBorderFromFF(m.cm); - vcg::tri::UpdateFlags::VertexBorderFromFace (m.cm); - vcg::tri::UpdateColor::VertexBorderFlag(m.cm); - rm.colorMode = GLW::CMPerVert; - return; - } - - if(mode->text() == ST(CP_COLORNM)) - { - vcg::tri::UpdateTopology::FaceFace(m.cm); + case CP_BORDER: + vcg::tri::UpdateColor::VertexBorderFlag(m.cm); + break; + case CP_COLOR_NON_MANIFOLD: ColorManifold(m.cm); - rm.colorMode = GLW::CMPerVert; - } - - if(mode->text() == ST(CP_RESTORE_ORIGINAL)) - { + break; + case CP_RESTORE_ORIGINAL: m.restoreVertexColor(); - rm.colorMode = GLW::CMPerVert; - } - - if(mode->text() == ST(CP_SMOOTH)) - { + break; + case CP_SMOOTH: LaplacianSmoothColor(m.cm,1); - rm.colorMode = GLW::CMPerVert; + break; + } + return true; +} + +const MeshFilterInterface::FilterClass ExtraMeshColorizePlugin::getClass(QAction *a) +{ + switch(ID(a)) + { + case CP_BORDER: + case CP_COLOR_NON_MANIFOLD: + case CP_SMOOTH: + case CP_RESTORE_ORIGINAL: + case CP_MAP_QUALITY_INTO_COLOR: + case CP_GAUSSIAN: + case CP_MEAN: + case CP_RMS: + case CP_ABSOLUTE: + return MeshFilterInterface::VertexColoring; + case CP_SELFINTERSECT: + return MeshFilterInterface::FaceColoring; + default: assert(0); + return MeshFilterInterface::Generic; } } + Q_EXPORT_PLUGIN(ExtraMeshColorizePlugin) diff --git a/src/meshlabplugins/meshcolorize/meshcolorize.h b/src/meshlabplugins/meshcolorize/meshcolorize.h index 590a2165b..6df71c982 100644 --- a/src/meshlabplugins/meshcolorize/meshcolorize.h +++ b/src/meshlabplugins/meshcolorize/meshcolorize.h @@ -23,6 +23,10 @@ /**************************************************************************** History $Log$ +Revision 1.19 2006/05/25 04:57:45 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. + Revision 1.18 2006/02/01 16:23:09 vannini Added "smooth color" filter @@ -35,21 +39,6 @@ added colorize equalizer dialog and "Colorize by Quality" filter some small bugfixes removed color_curvature.h in favour of curvature.h - -Revision 1.15 2006/01/20 18:17:07 vannini -added Restore Color - -Revision 1.14 2006/01/20 16:25:39 vannini -Added Absolute Curvature colorize - -Revision 1.13 2006/01/20 14:46:44 vannini -Code refactoring -Added RMS Curvature colorize - -Revision 1.12 2006/01/13 16:24:16 vannini -Moved gaussian and mean curvature functions into color_curvature.h - - ****************************************************************************/ #ifndef EXTRACOLORIZEPLUGIN_H @@ -70,30 +59,41 @@ Moved gaussian and mean curvature functions into color_curvature.h #include #include "equalizerDialog.h" -class ExtraMeshColorizePlugin : public QObject, public MeshColorizeInterface +class ExtraMeshColorizePlugin : public QObject, public MeshFilterInterface { Q_OBJECT - Q_INTERFACES(MeshColorizeInterface) + Q_INTERFACES(MeshFilterInterface) public: - enum ColorizeType {CP_EQUALIZE,CP_GAUSSIAN,CP_MEAN,CP_RMS,CP_ABSOLUTE,CP_SELFINTERSECT,CP_BORDER,CP_COLORNM,CP_SMOOTH,CP_RESTORE_ORIGINAL}; - const QString ST(ColorizeType c); + enum { + CP_MAP_QUALITY_INTO_COLOR, + CP_GAUSSIAN, + CP_MEAN, + CP_RMS, + CP_ABSOLUTE, + CP_SELFINTERSECT, + CP_BORDER, + CP_COLOR_NON_MANIFOLD, + CP_SMOOTH, + CP_RESTORE_ORIGINAL + }; + + ExtraMeshColorizePlugin(); - - virtual const ActionInfo &Info(QAction *); - virtual const PluginInfo &Info(); - virtual QList actions() const; - - void Compute(QAction * mode, MeshModel &m, RenderMode &rm, GLArea *parent); - void setLog(GLLogStream *log) { this->log = log ; } - -protected: - GLLogStream *log; - QList actionList; - EqualizerSettings eqSettings; + ~ExtraMeshColorizePlugin(){}; + + virtual const QString ST(FilterType filter); + virtual const ActionInfo &Info(QAction *); + virtual const PluginInfo &Info(); + virtual const FilterClass getClass(QAction *); + virtual bool getParameters(QAction *, QWidget *, MeshModel &m, FilterParameter &par); + virtual const int getRequirements(QAction *); + virtual bool applyFilter(QAction *filter, MeshModel &m, FilterParameter & /*parent*/, vcg::CallBackPos * cb) ; +protected: + EqualizerSettings eqSettings; }; #endif diff --git a/src/meshlabplugins/meshdecorate/meshdecorate.cpp b/src/meshlabplugins/meshdecorate/meshdecorate.cpp index d51979dc6..0e81a5bbe 100644 --- a/src/meshlabplugins/meshdecorate/meshdecorate.cpp +++ b/src/meshlabplugins/meshdecorate/meshdecorate.cpp @@ -23,6 +23,10 @@ /**************************************************************************** History $Log$ +Revision 1.36 2006/05/25 04:57:45 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. + Revision 1.35 2006/04/20 16:58:51 cignoni Disambiguated (hopefully for the last time) max(float/double) issue. @@ -78,9 +82,8 @@ Some changes in DrawAxis in order to compile under gcc #include #include #include - #include "meshdecorate.h" -#include +#include #include using namespace vcg; @@ -137,7 +140,7 @@ const QString ExtraMeshDecoratePlugin::ST(int id) const return QString("error!"); } -void ExtraMeshDecoratePlugin::Decorate(QAction *a, MeshModel &m, RenderMode &/*rm*/, GLArea *gla) +void ExtraMeshDecoratePlugin::Decorate(QAction *a, MeshModel &m, RenderMode &/*rm*/, QGLWidget *gla, QFont qf) { if(a->text() == ST(DP_SHOW_NORMALS)) { @@ -150,20 +153,21 @@ void ExtraMeshDecoratePlugin::Decorate(QAction *a, MeshModel &m, RenderMode &/*r glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glBegin(GL_LINES); glColor4f(.4f,.4f,1.f,.6f); - for(vi=m.cm.vert.begin();vi!=m.cm.vert.end();++vi) - { - glVertex((*vi).P()); - glVertex((*vi).P()+(*vi).N()*LineLen); - } + for(vi=m.cm.vert.begin();vi!=m.cm.vert.end();++vi) + if(!(*vi).IsD()) + { + glVertex((*vi).P()); + glVertex((*vi).P()+(*vi).N()*LineLen); + } glEnd(); glPopAttrib(); } if(a->text() == ST(DP_SHOW_BOX_CORNERS)) DrawBBoxCorner(m); - if(a->text() == ST(DP_SHOW_AXIS)) DrawAxis(m,gla); - if(a->text() == ST(DP_SHOW_QUOTED_BOX)) DrawQuotedBox(m,gla); + if(a->text() == ST(DP_SHOW_AXIS)) DrawAxis(m,gla,qf); + if(a->text() == ST(DP_SHOW_QUOTED_BOX)) DrawQuotedBox(m,gla,qf); } -void ExtraMeshDecoratePlugin::DrawQuotedBox(MeshModel &m,GLArea *gla) +void ExtraMeshDecoratePlugin::DrawQuotedBox(MeshModel &m,QGLWidget *gla,QFont qf) { glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POINT_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_COLOR_BUFFER_BIT ); glDisable(GL_LIGHTING); @@ -198,21 +202,21 @@ void ExtraMeshDecoratePlugin::DrawQuotedBox(MeshModel &m,GLArea *gla) glPushMatrix(); glScalef(1,s,s); glTranslatef(0,c[1]/s-c[1],c[2]/s-c[2]); - drawQuotedLine(p1,p2,b.min[0],b.max[0],calcSlope(p1,p2,b.DimX(),LabelSpacing,mm,mp,vp),gla); // Draws x axis + drawQuotedLine(p1,p2,b.min[0],b.max[0],calcSlope(p1,p2,b.DimX(),LabelSpacing,mm,mp,vp),gla,qf); // Draws x axis glPopMatrix(); chooseY(b,mm,mp,vp,p1,p2); // Selects y axis candidate glPushMatrix(); glScalef(s,1,s); glTranslatef(c[0]/s-c[0],0,c[2]/s-c[2]); - drawQuotedLine(p1,p2,b.min[1],b.max[1],calcSlope(p1,p2,b.DimY(),LabelSpacing,mm,mp,vp),gla); // Draws y axis + drawQuotedLine(p1,p2,b.min[1],b.max[1],calcSlope(p1,p2,b.DimY(),LabelSpacing,mm,mp,vp),gla,qf); // Draws y axis glPopMatrix(); chooseZ(b,mm,mp,vp,p1,p2); // Selects z axis candidate glPushMatrix(); glScalef(s,s,1); glTranslatef(c[0]/s-c[0],c[1]/s-c[1],0); - drawQuotedLine(p2,p1,b.min[2],b.max[2],calcSlope(p1,p2,b.DimZ(),LabelSpacing,mm,mp,vp),gla); // Draws z axis + drawQuotedLine(p2,p1,b.min[2],b.max[2],calcSlope(p1,p2,b.DimZ(),LabelSpacing,mm,mp,vp),gla,qf); // Draws z axis glPopMatrix(); glPopAttrib(); @@ -365,7 +369,7 @@ void ExtraMeshDecoratePlugin::drawTickedLine(const Point3d &a,const Point3d &b, } -void ExtraMeshDecoratePlugin::drawQuotedLine(const Point3d &a,const Point3d &b, float aVal, float bVal, float tickDist,GLArea *gla) +void ExtraMeshDecoratePlugin::drawQuotedLine(const Point3d &a,const Point3d &b, float aVal, float bVal, float tickDist,QGLWidget *gla, QFont qf) { qDebug("drawQuotedLine %f",tickDist); @@ -391,7 +395,7 @@ void ExtraMeshDecoratePlugin::drawQuotedLine(const Point3d &a,const Point3d &b, int neededZeros=ceil(max(0.0,-log10(double(tickDist)))); for(i=firstTick;irenderText(Zero[0]+i*v[0],Zero[1]+i*v[1],Zero[2]+i*v[2],tr("%1").arg(i,3+neededZeros,'f',neededZeros),gla->getFont()); + gla->renderText(Zero[0]+i*v[0],Zero[1]+i*v[1],Zero[2]+i*v[2],tr("%1").arg(i,3+neededZeros,'f',neededZeros),qf); glPointSize(1); glBegin(GL_POINTS); @@ -413,7 +417,6 @@ void ExtraMeshDecoratePlugin::drawQuotedLine(const Point3d &a,const Point3d &b, glPopAttrib(); // bold font at beginning and at the end - QFont qf = gla->getFont(); qf.setBold(true); gla->renderText(a[0],a[1],a[2],tr("%1").arg(aVal,3+neededZeros,'f',neededZeros+2 ),qf); gla->renderText(b[0],b[1],b[2],tr("%1").arg(bVal,3+neededZeros,'f',neededZeros+2 ),qf); @@ -475,8 +478,8 @@ void ExtraMeshDecoratePlugin::DrawBBoxCorner(MeshModel &m) glPopAttrib(); } - -void ExtraMeshDecoratePlugin::DrawAxis(MeshModel &m,GLArea* gla) + +void ExtraMeshDecoratePlugin::DrawAxis(MeshModel &m,QGLWidget* gla,QFont qf) { float hw=m.cm.bbox.Diag()/2.0; glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POINT_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_COLOR_BUFFER_BIT ); @@ -523,11 +526,11 @@ void ExtraMeshDecoratePlugin::DrawAxis(MeshModel &m,GLArea* gla) glTranslate(c); glRotatef(-90,0,1,0); glScalef(sf,sf,sf); Add_Ons::Cone(10,3,1,true); glPopMatrix(); - QFont f(gla->getFont()); - f.setBold(true); - glColor(Color4b::Red); gla->renderText(hw+(sf*3),0,0,QString("X"),f); - glColor(Color4b::Green); gla->renderText(0,hw+(sf*3),0,QString("Y"),f); - glColor(Color4b::Blue); gla->renderText(0,0,hw+(sf*3),QString("Z"),f); + //QFont f(gla->getFont()); + qf.setBold(true); + glColor(Color4b::Red); gla->renderText(hw+(sf*3),0,0,QString("X"),qf); + glColor(Color4b::Green); gla->renderText(0,hw+(sf*3),0,QString("Y"),qf); + glColor(Color4b::Blue); gla->renderText(0,0,hw+(sf*3),QString("Z"),qf); glPopAttrib(); } diff --git a/src/meshlabplugins/meshdecorate/meshdecorate.h b/src/meshlabplugins/meshdecorate/meshdecorate.h index 470bb19fb..9106763f2 100644 --- a/src/meshlabplugins/meshdecorate/meshdecorate.h +++ b/src/meshlabplugins/meshdecorate/meshdecorate.h @@ -23,6 +23,10 @@ /**************************************************************************** History $Log$ +Revision 1.16 2006/05/25 04:57:45 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. + Revision 1.15 2006/02/22 12:24:41 cignoni Restructured Quoted Box. @@ -66,7 +70,7 @@ Starting quoted box (simply draws xyz axes) #include #include -#include "../../meshlab/mainwindow.h" +//#include "../../meshlab/mainwindow.h" class ExtraMeshDecoratePlugin : public QObject, public MeshDecorateInterface { @@ -92,7 +96,7 @@ private: float calcSlope(const Point3d &a,const Point3d &b,float dim,int spacing,double *mm,double *mp,int *vp); void drawTickedLine(const Point3d &p1,const Point3d &p2,float dim,float tickDist); - void drawQuotedLine(const Point3d &a,const Point3d &b,float aVal, float bVal,float tickDist,GLArea *gla); + void drawQuotedLine(const Point3d &a,const Point3d &b,float aVal, float bVal,float tickDist,QGLWidget *gla, QFont qf); void chooseX(Box3f &box,double *modelview,double *projection,int *viewport,Point3d &x1,Point3d &x2); @@ -121,10 +125,10 @@ public: QList actions () const {return actionList;} void DrawBBoxCorner(MeshModel &m); - void DrawAxis(MeshModel &m,GLArea* gla); - void DrawQuotedBox(MeshModel &m,GLArea *gla); + void DrawAxis(MeshModel &m,QGLWidget* gla, QFont qf); + void DrawQuotedBox(MeshModel &m,QGLWidget *gla, QFont qf); - virtual void Decorate(QAction *a, MeshModel &m, RenderMode &rm, GLArea *gla); + virtual void Decorate(QAction *a, MeshModel &m, RenderMode &rm, QGLWidget *gla,QFont qf); }; diff --git a/src/meshlabplugins/meshedit/images/select_face.png b/src/meshlabplugins/meshedit/images/select_face.png new file mode 100644 index 000000000..a4681476e Binary files /dev/null and b/src/meshlabplugins/meshedit/images/select_face.png differ diff --git a/src/meshlabplugins/meshedit/meshedit.cpp b/src/meshlabplugins/meshedit/meshedit.cpp new file mode 100644 index 000000000..643ea8ff2 --- /dev/null +++ b/src/meshlabplugins/meshedit/meshedit.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** + * 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.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 +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 ActionInfo &ExtraMeshEditPlugin::Info(QAction *action) + { + static ActionInfo ai; + + if( action->text() == tr("Invert Selection") ) + { + ai.Help = tr("Apply Loop's Subdivision Surface algorithm, it is an approximate method"); + ai.ShortHelp = tr("Apply Loop's Subdivision Surface algorithm"); + } + return ai; + } + + 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) + { + 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=0; + int curT = clock(); + if(gla->deltaTime < 50 ) gla->update(); + 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; + 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(); + + + 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()); + + for(fpi=NewSel.begin();fpi!=NewSel.end();++fpi) + (*fpi)->SetS(); + + isDragging=false; + } + + } + +void ExtraMeshEditPlugin::StartEdit(QAction * /*mode*/, MeshModel &m, GLArea * /*parent*/) +{ + 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); + +} + + + +Q_EXPORT_PLUGIN(ExtraMeshEditPlugin) diff --git a/src/meshlabplugins/meshedit/meshedit.h b/src/meshlabplugins/meshedit/meshedit.h new file mode 100644 index 000000000..de966b931 --- /dev/null +++ b/src/meshlabplugins/meshedit/meshedit.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2005-2005 Trolltech AS. All rights reserved. +** +** This file is part of the example classes of the Qt Toolkit. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef EDITPLUGIN_H +#define EDITPLUGIN_H + +#include +#include +#include + +#include +#include + +class ExtraMeshEditPlugin : public QObject, public MeshEditInterface +{ + Q_OBJECT + Q_INTERFACES(MeshEditInterface) + + QList actionList; + +public: + ExtraMeshEditPlugin(); + + virtual ~ExtraMeshEditPlugin() {} + + virtual const ActionInfo &Info(QAction *); + virtual const PluginInfo &Info(); + + virtual void StartEdit(QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/); + virtual void EndEdit(QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/){}; + virtual void Decorate(QAction * /*mode*/, MeshModel &/*m*/, GLArea * /*parent*/); + virtual void mousePressEvent (QAction *, QMouseEvent *event, MeshModel &/*m*/, GLArea * ); + virtual void mouseMoveEvent (QAction *,QMouseEvent *event, MeshModel &/*m*/, GLArea * ); + virtual void mouseReleaseEvent (QAction *,QMouseEvent *event, MeshModel &/*m*/, GLArea * ); +// virtual void wheelEvent (QAction *QWheelEvent*e, MeshModel &/*m*/, GLArea * ); + virtual QList actions() const ; + QPoint start; + QPoint cur; + QPoint prev; + bool isDragging; + vector LastSel; + +private: + void DrawXORRect(GLArea * gla, bool doubleDraw); +}; + +#endif diff --git a/src/meshlabplugins/meshedit/meshedit.pro b/src/meshlabplugins/meshedit/meshedit.pro new file mode 100644 index 000000000..4d2b202be --- /dev/null +++ b/src/meshlabplugins/meshedit/meshedit.pro @@ -0,0 +1,31 @@ +TEMPLATE = lib +CONFIG += plugin +INCLUDEPATH += ../.. ../../../../sf ../../../../code/lib/glew/include +HEADERS = meshedit.h +SOURCES = meshedit.cpp ../../../../code/lib/glew/src/glew.c +TARGET = meshedit +DESTDIR = ../../meshlab/plugins +DEFINES += GLEW_STATIC +QT += opengl +RESOURCES = meshlab.qrc + +# the following line is needed to avoid mismatch between +# the awful min/max macros of windows and the limits max +win32:DEFINES += NOMINMAX + +unix{ + QMAKE_CC = gcc-3.3 + QMAKE_CXX = g++-3.3 + QMAKE_LINK = gcc-3.3 + CONFIG += warn_off debug_and_release +} + +contains(TEMPLATE,lib) { + CONFIG(debug, debug|release) { + unix:TARGET = $$member(TARGET, 0)_debug + else:TARGET = $$member(TARGET, 0)d + } +} + + + diff --git a/src/meshlabplugins/meshedit/meshlab.qrc b/src/meshlabplugins/meshedit/meshlab.qrc new file mode 100644 index 000000000..b58759f17 --- /dev/null +++ b/src/meshlabplugins/meshedit/meshlab.qrc @@ -0,0 +1,5 @@ + + + images/select_face.png + + diff --git a/src/meshlabplugins/meshfilter/invert_faces.h b/src/meshlabplugins/meshfilter/invert_faces.h index 5487c9329..1a3c11d7e 100644 --- a/src/meshlabplugins/meshfilter/invert_faces.h +++ b/src/meshlabplugins/meshfilter/invert_faces.h @@ -24,6 +24,10 @@ /* * $Log$ + * Revision 1.4 2006/05/25 04:57:45 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. + * * Revision 1.3 2006/05/06 17:05:18 mariolatronico * - Added license and history * - On invert face also swap the texture coordinates if the @@ -51,21 +55,15 @@ namespace vcg{ typename MESH_TYPE::FaceIterator fi; for (fi = m.face.begin(); fi != m.face.end(); ++fi) - { - + { swap((*fi).V1(0), (*fi).V2(0)); // swap also texture coordinates - if (MESH_TYPE::HasPerWedgeTexture()) { + if (HasPerWedgeTexture(m)) { swap((*fi).WT(0),(*fi).WT(1)); - swap((*fi).WT(1),(*fi).WT(2)); - swap((*fi).WT(2),(*fi).WT(0)); - + // swap((*fi).WT(1),(*fi).WT(2)); + // swap((*fi).WT(2),(*fi).WT(0)); } } - vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(m); - vcg::tri::UpdateTopology::FaceFace(m); - vcg::tri::UpdateTopology::VertexFace(m); - } } // end of namespace diff --git a/src/meshlabplugins/meshfilter/meshfilter.cpp b/src/meshlabplugins/meshfilter/meshfilter.cpp index 6aaa4544a..5e5610d9e 100644 --- a/src/meshlabplugins/meshfilter/meshfilter.cpp +++ b/src/meshlabplugins/meshfilter/meshfilter.cpp @@ -22,6 +22,10 @@ /**************************************************************************** History $Log$ +Revision 1.61 2006/05/25 04:57:45 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. + Revision 1.60 2006/04/18 06:57:35 zifnab1974 syntax errors for gcc 3.4.5 resolved @@ -77,15 +81,16 @@ added scale to unit box, move obj center. Rotate around object and origin are no #include #include "refine_loop.h" #include "meshfilter.h" -#include "detacher.h" #include +#include #include +#include #include #include #include -#include #include "invert_faces.h" -#include "decimator.h" +//#include "decimator.h" + #include "../../meshlab/GLLogStream.h" #include "../../meshlab/LogStream.h" @@ -97,14 +102,14 @@ ExtraMeshFilterPlugin::ExtraMeshFilterPlugin() FP_BUTTERFLY_SS<< FP_REMOVE_UNREFERENCED_VERTEX<< FP_REMOVE_DUPLICATED_VERTEX<< - FP_REMOVE_NULL_FACES<< + FP_REMOVE_FACES_BY_AREA<< + FP_REMOVE_FACES_BY_EDGE<< FP_LAPLACIAN_SMOOTH<< FP_DECIMATOR<< FP_MIDPOINT<< FP_REORIENT << FP_INVERT_FACES<< - FP_TRANSFORM<< - FP_REMOVE_SMALL_FACES ; + FP_TRANSFORM; FilterType tt; @@ -129,24 +134,19 @@ const ExtraMeshFilterPlugin::FilterClass ExtraMeshFilterPlugin::getClass(QAction { case FP_REMOVE_UNREFERENCED_VERTEX : case FP_REMOVE_DUPLICATED_VERTEX : - case FP_REMOVE_NULL_FACES : - case FP_REMOVE_SMALL_FACES : + case FP_REMOVE_FACES_BY_AREA: + case FP_REMOVE_FACES_BY_EDGE : return MeshFilterInterface::Cleaning; + case FP_BUTTERFLY_SS : + case FP_LOOP_SS : + case FP_MIDPOINT : + return MeshFilterInterface::Remeshing; default : return MeshFilterInterface::Generic; } } -const ExtraMeshFilterPlugin::FilterType ExtraMeshFilterPlugin::ID(QAction *a) -{ - foreach( FilterType tt, types()) - if( a->text() == ST(tt) ) return tt; - assert(0); - return FP_LOOP_SS; -} - - const QString ExtraMeshFilterPlugin::ST(FilterType filter) { switch(filter) @@ -155,12 +155,12 @@ const QString ExtraMeshFilterPlugin::ST(FilterType filter) case FP_BUTTERFLY_SS : return QString("Butterfly Subdivision Surfaces"); case FP_REMOVE_UNREFERENCED_VERTEX : return QString("Remove Unreferenced Vertex"); case FP_REMOVE_DUPLICATED_VERTEX : return QString("Remove Duplicated Vertex"); - case FP_REMOVE_NULL_FACES : return QString("Remove Null Faces"); - case FP_REMOVE_SMALL_FACES: return QString("Remove faces wrt size"); + case FP_REMOVE_FACES_BY_AREA : return QString("Remove Zero Area Faces"); + case FP_REMOVE_FACES_BY_EDGE : return QString("Remove Faces with edges longer than..."); case FP_LAPLACIAN_SMOOTH : return QString("Laplacian Smooth"); case FP_DECIMATOR : return QString("Clustering decimation"); case FP_MIDPOINT : return QString("Midpoint Subdivision Surfaces"); - case FP_REORIENT : return QString("Re-oriented"); + case FP_REORIENT : return QString("Re-orient"); case FP_INVERT_FACES: return QString("Invert Faces"); case FP_TRANSFORM: return QString("Apply Transform"); @@ -181,10 +181,6 @@ ExtraMeshFilterPlugin::~ExtraMeshFilterPlugin() { } } -QList ExtraMeshFilterPlugin::actions() const { - return actionList; -} - const ActionInfo &ExtraMeshFilterPlugin::Info(QAction *action) { static ActionInfo ai; @@ -198,6 +194,10 @@ const ActionInfo &ExtraMeshFilterPlugin::Info(QAction *action) ai.Help = tr("Apply Butterfly Subdivision Surface algorithm. It is an interpolated method, defined on arbitrary triangular meshes. The scheme is known to be C1 but not C2 on regular meshes"); ai.ShortHelp = tr("Apply Butterfly Subdivision Surface algorithm"); break; + case FP_MIDPOINT : + ai.Help = tr("Splits every edge in two"); + ai.ShortHelp = tr("Apply Midpoint's Subdivision Surface algorithm"); + break; case FP_REMOVE_UNREFERENCED_VERTEX : ai.Help = tr("Check for every vertex on the mesh if it is referenced by a face and removes it"); ai.ShortHelp = tr("Remove Unreferenced Vertexes"); @@ -206,10 +206,14 @@ const ActionInfo &ExtraMeshFilterPlugin::Info(QAction *action) ai.Help = tr("Check for every vertex on the mesh if there are two vertices with same coordinates and removes it"); ai.ShortHelp = tr("Remove Duplicated Vertexes"); break; - case FP_REMOVE_NULL_FACES : + case FP_REMOVE_FACES_BY_AREA : ai.Help = tr("Removes faces with area equal to zero"); ai.ShortHelp = tr("Remove Null Faces"); break; + case FP_REMOVE_FACES_BY_EDGE : + ai.Help = tr("Remove from the mesh all triangles whose have an edge with lenght greater or equal than a threshold"); + ai.ShortHelp = tr("Remove triangle with edge greater than a threshold"); + break; case FP_LAPLACIAN_SMOOTH : ai.Help = tr("For each vertex it calculates the average position with nearest vertex"); ai.ShortHelp = tr("Smooth the mesh surface"); @@ -218,10 +222,6 @@ const ActionInfo &ExtraMeshFilterPlugin::Info(QAction *action) ai.Help = tr("Collapse vertices by creating a three dimensional grid enveloping the mesh and discretizes them based on the cells of this grid"); ai.ShortHelp = tr("Simplify the surface eliminating triangle"); break; - case FP_MIDPOINT : - ai.Help = tr("Splits every edge in two"); - ai.ShortHelp = tr("Apply Midpoint's Subdivision Surface algorithm"); - break; case FP_REORIENT : ai.Help = tr("Re-oriented the adjacencies of the face of the mesh"); ai.ShortHelp = tr("Re-oriented the face"); @@ -234,15 +234,12 @@ const ActionInfo &ExtraMeshFilterPlugin::Info(QAction *action) ai.Help = tr("Apply transformation, you can rotate, translate or scale the mesh"); ai.ShortHelp = tr("Apply Transform"); break; - case FP_REMOVE_SMALL_FACES : - ai.Help = tr("Remove from the mesh all triangles whose have an edge with lenght greater or equal than a threshold"); - ai.ShortHelp = tr("Remove triangle with edge greater than a threshold"); - break; } return ai; } - const PluginInfo &ExtraMeshFilterPlugin::Info() + +const PluginInfo &ExtraMeshFilterPlugin::Info() { static PluginInfo ai; ai.Date=tr("__DATE__"); @@ -251,101 +248,117 @@ const ActionInfo &ExtraMeshFilterPlugin::Info(QAction *action) return ai; } - -bool ExtraMeshFilterPlugin::applyFilter(QAction *filter, MeshModel &m, QWidget *parent, vcg::CallBackPos *cb) +const int ExtraMeshFilterPlugin::getRequirements(QAction *action) { - double threshold = 0.0; - bool selected = false; + switch(ID(action)) + { + case FP_LOOP_SS : + case FP_BUTTERFLY_SS : + case FP_MIDPOINT : return MeshModel::MM_FACETOPO | MeshModel::MM_BORDERFLAG; + case FP_LAPLACIAN_SMOOTH: return MeshModel::MM_BORDERFLAG; + case FP_REORIENT: return MeshModel::MM_FACETOPO; + case FP_REMOVE_UNREFERENCED_VERTEX: + case FP_REMOVE_DUPLICATED_VERTEX: + case FP_REMOVE_FACES_BY_AREA: + case FP_REMOVE_FACES_BY_EDGE: + case FP_DECIMATOR: + case FP_TRANSFORM: + case FP_INVERT_FACES: return 0; + default: assert(0); + } + return 0; +} - if( filter->text().contains(tr("Subdivision Surface")) ) { +bool ExtraMeshFilterPlugin::getParameters(QAction *action, QWidget *, MeshModel &m,FilterParameter &par) +{ + par.clear(); + switch(ID(action)) + { + case FP_LOOP_SS : + case FP_BUTTERFLY_SS : + case FP_MIDPOINT : + case FP_REMOVE_FACES_BY_EDGE: + case FP_DECIMATOR: + { + Histogram histo; + genericELD->setHistogram(&histo); + genericELD->setDiagonale(m.cm.bbox.Diag()); + int continueValue = genericELD->exec(); - vcg::tri::UpdateTopology::FaceFace(m.cm); + //int continueValue = refineDialog->exec(); + if (continueValue == QDialog::Rejected) return false; // don't continue, user pressed Cancel + float threshold = genericELD->getThreshold(); // threshold for refinying + // qDebug( "%f", threshold ); + bool selected = genericELD->getSelected(); // refine only selected faces + par.addBool("Selected",selected); + par.addFloat("Threshold",threshold); + break; + } + case FP_TRANSFORM: + { + transformDialog->setMesh(&m.cm); + int continueValue = transformDialog->exec(); + if (continueValue == QDialog::Rejected) + return false; + Matrix44f matrix = transformDialog->getTransformation(); + par.addMatrix44("Transform",matrix); + break; + } + case FP_REMOVE_FACES_BY_AREA: + case FP_REMOVE_UNREFERENCED_VERTEX: + case FP_REMOVE_DUPLICATED_VERTEX: + case FP_REORIENT: + case FP_INVERT_FACES: + case FP_LAPLACIAN_SMOOTH: + return true; // no parameters + default :assert(0); + } + return true; +} + +bool ExtraMeshFilterPlugin::applyFilter(QAction *filter, MeshModel &m, FilterParameter & par, vcg::CallBackPos *cb) +{ + if( getClass(filter)==Remeshing) + { + if ( ! vcg::tri::Clean::IsTwoManifoldFace(m.cm) ) { + QMessageBox::warning(0, QString("Can't continue"), QString("Mesh faces not 2 manifold")); // text + return false; // can't continue, mesh can't be processed + } - if ( ! vcg::tri::Clean::IsTwoManifoldFace(m.cm) ) { - QMessageBox::warning(parent, // parent - QString("Can't continue"), // caption - QString("Mesh faces not 2 manifold")); // text - return false; // can't continue, mesh can't be processed - } - if(!m.cm.face.IsWedgeTexEnabled()) m.cm.face.EnableWedgeTex(); - vcg::tri::UpdateTopology::FaceFace(m.cm); - vcg::tri::UpdateFlags::FaceBorderFromFF(m.cm); - vcg::tri::UpdateNormals::PerVertexNormalized(m.cm); - vcg::tri::UpdateBounding::Box(m.cm); + bool selected=par.getBool("Selected"); + float threshold = par.getFloat("Threshold"); - float diagonale = m.cm.bbox.Diag(); - Histogram *histo= new Histogram(); - histo->SetRange( 0, diagonale, 10000); - CMeshO::FaceIterator fi; - for(fi = m.cm.face.begin(); fi != m.cm.face.end(); ++fi) - { - if(!(*fi).IsD()) - { - if( !(*fi).V(0)->IsS() && !(*fi).V(1)->IsS() ) - { - histo->Add(Distance((*fi).V(0)->P(),(*fi).V(1)->P())); - (*fi).V(0)->SetS(); - (*fi).V(1)->SetS(); - } - if( !(*fi).V(1)->IsS() && !(*fi).V(2)->IsS()) - { - histo->Add(Distance((*fi).V(1)->P(),(*fi).V(2)->P())); - (*fi).V(2)->SetS(); - (*fi).V(1)->SetS(); - } - if( !(*fi).V(2)->IsS() && !(*fi).V(0)->IsS()) - { - histo->Add(Distance((*fi).V(2)->P(),(*fi).V(0)->P())); - (*fi).V(0)->SetS(); - (*fi).V(2)->SetS(); - } - } - } - CMeshO::VertexIterator vi; - for(vi = m.cm.vert.begin(); vi != m.cm.vert.end(); ++vi) - (*vi).ClearS(); - genericELD->setHistogram(histo); - genericELD->setDiagonale(diagonale); - int continueValue = genericELD->exec(); - //int continueValue = refineDialog->exec(); - if (continueValue == QDialog::Rejected) - return false; // don't continue, user pressed Cancel - threshold = genericELD->getThreshold(); // threshold for refinying - // qDebug( "%f", threshold ); - bool selected = genericELD->getSelected(); // refine only selected faces + switch(ID(filter)) { + case FP_LOOP_SS : + RefineOddEvenE, EvenPointLoop > + (m.cm, OddPointLoop(), EvenPointLoop(), threshold, selected, cb); + break; + case FP_BUTTERFLY_SS : + Refine > + (m.cm, MidPointButterfly(), threshold, selected, cb); + break; + case FP_MIDPOINT : + Refine > + (m.cm, MidPoint(), threshold, selected, cb); + } + } + if (ID(filter) == FP_REMOVE_FACES_BY_EDGE ) { + bool selected = par.getBool("Selected"); + float threshold = par.getFloat("Threshold"); + if(selected) tri::Clean::RemoveFaceOutOfRangeEdgeSel(m.cm,0,threshold ); + else tri::Clean::RemoveFaceOutOfRangeEdgeSel(m.cm,0,threshold ); } - if(filter->text() == ST(FP_LOOP_SS) ) + if(filter->text() == ST(FP_REMOVE_FACES_BY_AREA) ) { - vcg::RefineOddEvenE, vcg::EvenPointLoop > - (m.cm, OddPointLoop(), EvenPointLoop(),threshold, selected, cb); - - vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(m.cm); + int nullFaces=tri::Clean::RemoveFaceOutOfRangeArea(m.cm,0); + if (log) log->Log(GLLogStream::Info, "Removed %d null faces", nullFaces); } - if(filter->text() == ST(FP_BUTTERFLY_SS) ) - { - vcg::Refine > - (m.cm,vcg::MidPointButterfly(),threshold, selected, cb); - - vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(m.cm); - } - - if(filter->text() == ST(FP_MIDPOINT) ) - { - vcg::Refine > - (m.cm,vcg::MidPoint(),threshold, selected, cb); - - vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(m.cm); - } - - if(filter->text() == ST(FP_REMOVE_UNREFERENCED_VERTEX) ) + if(filter->text() == ST(FP_REMOVE_UNREFERENCED_VERTEX) ) { int delvert=tri::Clean::RemoveUnreferencedVertex(m.cm); - if (log) - log->Log(GLLogStream::Info, "Removed %d unreferenced vertices",delvert); - if (delvert != 0) - vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(m.cm); + if (log) log->Log(GLLogStream::Info, "Removed %d unreferenced vertices",delvert); } if(filter->text() == ST(FP_REMOVE_DUPLICATED_VERTEX) ) @@ -357,23 +370,12 @@ bool ExtraMeshFilterPlugin::applyFilter(QAction *filter, MeshModel &m, QWidget * vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(m.cm); } - if(filter->text() == ST(FP_REMOVE_NULL_FACES) ) - { - int nullFaces=tri::Clean::RemoveZeroAreaFace(m.cm); - if (log) - log->Log(GLLogStream::Info, "Removed %d null faces", nullFaces); - if (nullFaces != 0) - vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(m.cm); - } - if(filter->text() == ST(FP_REORIENT) ) { bool oriented; bool orientable; - vcg::tri::UpdateTopology::FaceFace(m.cm); tri::Clean::IsOrientedMesh(m.cm, oriented,orientable); vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(m.cm); - } if(filter->text() == ST(FP_LAPLACIAN_SMOOTH)) @@ -382,40 +384,25 @@ bool ExtraMeshFilterPlugin::applyFilter(QAction *filter, MeshModel &m, QWidget * vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(m.cm); } - if(filter->text() == ST(FP_DECIMATOR)) { - float diagonale = m.cm.bbox.Diag(); - - decimatorDialog->setBboxEdge(m.cm.bbox.min,m.cm.bbox.max); - //decimatorDialog->setDiagonale(diagonale); - - int continueValue = decimatorDialog->exec(); - - if (continueValue == QDialog::Rejected) - return false; // don't continue, user pressed Cancel - int Xstep = decimatorDialog->getXStep(); - int Ystep = decimatorDialog->getYStep(); - int Zstep = decimatorDialog->getZStep(); - vcg::tri::UpdateTopology::FaceFace(m.cm); - int delvert = Decimator(m.cm,Xstep,Ystep,Zstep); - if (log) - log->Log(GLLogStream::Info, "Removed %d vertices", delvert); + bool selected = par.getBool("Selected"); + float threshold = par.getFloat("Threshold"); + vcg::tri::Clustering > Grid; + Grid.Init(m.cm.bbox,100000,threshold); + Grid.Add(m.cm); + Grid.Extract(m.cm); vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(m.cm); } if (filter->text() == ST(FP_INVERT_FACES) ) { - InvertFaces(m.cm); } if (filter->text() == ST(FP_TRANSFORM) ) { - transformDialog->setMesh(&m.cm); - int continueValue = transformDialog->exec(); - if (continueValue == QDialog::Rejected) - return false; - Matrix44f matrix = transformDialog->getTransformation(); - if (log) { + Matrix44f matrix= par.getMatrix44("Transform"); + + if (log) { log->Log(GLLogStream::Info, transformDialog->getLog().toAscii().data()); } @@ -424,49 +411,6 @@ bool ExtraMeshFilterPlugin::applyFilter(QAction *filter, MeshModel &m, QWidget * vcg::tri::UpdateBounding::Box(m.cm); } - if (filter->text() == ST(FP_REMOVE_SMALL_FACES) ) { - float diagonale = m.cm.bbox.Diag(); - Histogram *histo= new Histogram(); - histo->SetRange( 0, diagonale, 10000); - CMeshO::FaceIterator fi; - for(fi = m.cm.face.begin(); fi != m.cm.face.end(); ++fi) - { - if(!(*fi).IsD()) - { - if( !(*fi).V(0)->IsS() && !(*fi).V(1)->IsS() ) - { - histo->Add(Distance((*fi).V(0)->P(),(*fi).V(1)->P())); - (*fi).V(0)->SetS(); - (*fi).V(1)->SetS(); - } - if( !(*fi).V(1)->IsS() && !(*fi).V(2)->IsS()) - { - histo->Add(Distance((*fi).V(1)->P(),(*fi).V(2)->P())); - (*fi).V(2)->SetS(); - (*fi).V(1)->SetS(); - } - if( !(*fi).V(2)->IsS() && !(*fi).V(0)->IsS()) - { - histo->Add(Distance((*fi).V(2)->P(),(*fi).V(0)->P())); - (*fi).V(0)->SetS(); - (*fi).V(2)->SetS(); - } - } - } - CMeshO::VertexIterator vi; - for(vi = m.cm.vert.begin(); vi != m.cm.vert.end(); ++vi) - (*vi).ClearS(); - genericELD->setHistogram(histo); - genericELD->setDiagonale(diagonale); - int continueValue = genericELD->exec(); - - if (continueValue == QDialog::Rejected) - return false; // don't continue, user pressed Cancel - double threshold = genericELD->getThreshold(); // threshold for refinying - selected = genericELD->getSelected(); - Detacher(m.cm, threshold,selected); - vcg::tri::UpdateTopology::FaceFace(m.cm); - } return true; } diff --git a/src/meshlabplugins/meshfilter/meshfilter.h b/src/meshlabplugins/meshfilter/meshfilter.h index 761e2174d..d391cd4ff 100644 --- a/src/meshlabplugins/meshfilter/meshfilter.h +++ b/src/meshlabplugins/meshfilter/meshfilter.h @@ -1,25 +1,32 @@ /**************************************************************************** -** -** Copyright (C) 2005-2005 Trolltech AS. All rights reserved. -** -** This file is part of the example classes of the Qt Toolkit. -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software. -** -** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for -** information about Qt Commercial License Agreements. -** -** Contact info@trolltech.com if any conditions of this licensing are -** not clear to you. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** +* 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.29 2006/05/25 04:57:45 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. + Revision 1.28 2006/04/12 15:12:18 cignoni Added Filter classes (cleaning, meshing etc) @@ -41,8 +48,7 @@ changed spinbox to QEdgeLength widget Revision 1.22 2006/01/31 14:40:40 mariolatronico removed unused variable ActionInfo *ai, added Log history -*/ - +****************************************************************************/ #ifndef EXTRAFILTERSPLUGIN_H #define EXTRAFILTERSPLUGIN_H @@ -68,37 +74,35 @@ class ExtraMeshFilterPlugin : public QObject, public MeshFilterInterface - FP -> Filter Plugin - name of the plugin separated by _ */ - enum FilterType { FP_LOOP_SS, - FP_BUTTERFLY_SS, - FP_REMOVE_UNREFERENCED_VERTEX, - FP_REMOVE_DUPLICATED_VERTEX, - FP_REMOVE_NULL_FACES, - FP_LAPLACIAN_SMOOTH, - FP_DECIMATOR, - FP_MIDPOINT, - FP_REORIENT , - FP_INVERT_FACES, - FP_TRANSFORM, - FP_REMOVE_SMALL_FACES } ; - - const QString ST(FilterType filter); - const FilterType ID(QAction *a); - - virtual QList &types() { return typeList;} + enum { FP_LOOP_SS, + FP_BUTTERFLY_SS, + FP_REMOVE_UNREFERENCED_VERTEX, + FP_REMOVE_DUPLICATED_VERTEX, + FP_REMOVE_FACES_BY_AREA, + FP_REMOVE_FACES_BY_EDGE, + FP_LAPLACIAN_SMOOTH, + FP_DECIMATOR, + FP_MIDPOINT, + FP_REORIENT , + FP_INVERT_FACES, + FP_TRANSFORM + } ; + + ExtraMeshFilterPlugin(); ~ExtraMeshFilterPlugin(); - virtual const ActionInfo &Info(QAction *); + virtual const QString ST(FilterType filter); + virtual const ActionInfo &Info(QAction *); virtual const PluginInfo &Info(); virtual const FilterClass getClass(QAction *); + virtual bool getParameters(QAction *, QWidget *, MeshModel &m, FilterParameter &par); + virtual const int getRequirements(QAction *); - virtual QList actions() const; - bool applyFilter(QAction *filter, MeshModel &m, QWidget *parent, vcg::CallBackPos * cb) ; - void setLog(GLLogStream *log) { this->log = log ; } + + virtual bool applyFilter(QAction *filter, MeshModel &m, FilterParameter & /*parent*/, vcg::CallBackPos * cb) ; protected: - GLLogStream *log; - QList actionList; - QList typeList; + // RefineDialog *refineDialog; DecimatorDialog *decimatorDialog; diff --git a/src/meshlabplugins/meshfilter/meshfilter.pro b/src/meshlabplugins/meshfilter/meshfilter.pro index df65bfcd4..a2a0a85b2 100644 --- a/src/meshlabplugins/meshfilter/meshfilter.pro +++ b/src/meshlabplugins/meshfilter/meshfilter.pro @@ -2,11 +2,11 @@ TEMPLATE = lib CONFIG += plugin INCLUDEPATH += ../.. ../../../../sf ../../../../code/lib/glew/include HEADERS = transformDialog.h \ -decimatorDialog.h \ -detacher.h \ -../../meshlab/GenericELDialog.h \ -../../meshlab/interfaces.h \ -meshfilter.h + decimatorDialog.h \ + clean.h \ + ../../meshlab/GenericELDialog.h \ + ../../meshlab/interfaces.h \ + meshfilter.h SOURCES = transformDialog.cpp \ meshfilter.cpp \ diff --git a/src/meshlabplugins/meshio/meshio.cpp b/src/meshlabplugins/meshio/meshio.cpp index 81aabbfe0..1e522540d 100644 --- a/src/meshlabplugins/meshio/meshio.cpp +++ b/src/meshlabplugins/meshio/meshio.cpp @@ -24,6 +24,10 @@ History $Log$ + Revision 1.85 2006/05/25 04:57:45 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. + Revision 1.84 2006/03/29 10:05:33 cignoni Added missing include export.obj @@ -114,13 +118,8 @@ bool ExtraMeshIOPlugin::open(const QString &formatName, QString &fileName, MeshM oi.cb = cb; if (!vcg::tri::io::ImporterOBJ::LoadMask(filename.c_str(), oi)) return false; - - if(oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) - { - qDebug("Has Wedge Text Coords\n"); - m.cm.face.EnableWedgeTex(); - } - + m.Enable(oi.mask); + int result = vcg::tri::io::ImporterOBJ::Open(m.cm, filename.c_str(), oi); if (result != vcg::tri::io::ImporterOBJ::E_NOERROR) { @@ -141,16 +140,7 @@ bool ExtraMeshIOPlugin::open(const QString &formatName, QString &fileName, MeshM else if (formatName.toUpper() == tr("PLY")) { vcg::tri::io::ImporterPLY::LoadMask(filename.c_str(), mask); - - if(mask&MeshModel::IOM_VERTQUALITY) qDebug("Has Vertex Quality\n"); - if(mask&MeshModel::IOM_FACEQUALITY) qDebug("Has Face Quality\n"); - if(mask&MeshModel::IOM_FACECOLOR) qDebug("Has Face Color\n"); - if(mask&MeshModel::IOM_VERTCOLOR) qDebug("Has Vertex Color\n"); - if(mask&MeshModel::IOM_WEDGTEXCOORD) - { - qDebug("Has Wedge Text Coords\n"); - m.cm.face.EnableWedgeTex(); - } + m.Enable(mask); int result = vcg::tri::io::ImporterPLY::Open(m.cm, filename.c_str(), mask, cb); if (result != ::vcg::ply::E_NOERROR) @@ -191,12 +181,7 @@ bool ExtraMeshIOPlugin::open(const QString &formatName, QString &fileName, MeshM info.cb = cb; Lib3dsFile *file = NULL; vcg::tri::io::Importer3DS::LoadMask(filename.c_str(), file, info); - - if(info.mask & MeshModel::IOM_WEDGTEXCOORD) - { - qDebug("Has Wedge Text Coords\n"); - m.cm.face.EnableWedgeTex(); - } + m.Enable(info.mask); int result = vcg::tri::io::Importer3DS::Open(m.cm, filename.c_str(), file, info); if (result != vcg::tri::io::Importer3DS::E_NOERROR) diff --git a/src/meshlabplugins/meshio/meshio.pro b/src/meshlabplugins/meshio/meshio.pro index 93f02e67b..31e203f0f 100644 --- a/src/meshlabplugins/meshio/meshio.pro +++ b/src/meshlabplugins/meshio/meshio.pro @@ -15,7 +15,7 @@ SOURCES = meshio.cpp \ TARGET = meshio DESTDIR = ../../meshlab/plugins -#win32:LIBS += ../../../../code/lib/lib3ds-1.2.0/lib3ds-120s.lib +win32-msvc.net:LIBS += ../../../../code/lib/lib3ds-1.2.0/lib3ds-120s.lib win32-g++:LIBS += ../../../../code/lib/lib3ds-1.2.0/lib3ds/lib3ds.a diff --git a/src/meshlabplugins/meshlabplugins.pro b/src/meshlabplugins/meshlabplugins.pro index 430612333..664d526ab 100644 --- a/src/meshlabplugins/meshlabplugins.pro +++ b/src/meshlabplugins/meshlabplugins.pro @@ -3,4 +3,6 @@ SUBDIRS = meshfilter \ meshrender \ meshio \ meshcolorize \ - meshdecorate \ No newline at end of file + meshdecorate \ + meshedit \ + meshselect \ No newline at end of file diff --git a/src/meshlabplugins/meshrender/meshrender.cpp b/src/meshlabplugins/meshrender/meshrender.cpp index fd3cf7784..883cc838b 100644 --- a/src/meshlabplugins/meshrender/meshrender.cpp +++ b/src/meshlabplugins/meshrender/meshrender.cpp @@ -23,6 +23,10 @@ /**************************************************************************** History $Log$ +Revision 1.17 2006/05/25 04:57:45 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. + Revision 1.16 2006/03/08 17:26:13 ggangemi added texture tab @@ -69,6 +73,7 @@ Added copyright info #include #include "meshrender.h" +#include using namespace vcg; @@ -259,10 +264,10 @@ void MeshShaderRenderPlugin::initActionList() { } } -void MeshShaderRenderPlugin::Init(QAction *a, MeshModel &m, RenderMode &rm, GLArea *gla) +void MeshShaderRenderPlugin::Init(QAction *a, MeshModel &m, RenderMode &rm, QGLWidget *gla) { if (sDialog) sDialog->close(); - + gla->makeCurrent(); GLenum err = glewInit(); if (GLEW_OK == err) { if (GLEW_ARB_vertex_program && GLEW_ARB_fragment_program) { @@ -359,7 +364,7 @@ void MeshShaderRenderPlugin::Init(QAction *a, MeshModel &m, RenderMode &rm, GLAr } -void MeshShaderRenderPlugin::Render(QAction *a, MeshModel &m, RenderMode &rm, GLArea *gla) +void MeshShaderRenderPlugin::Render(QAction *a, MeshModel &m, RenderMode &rm, QGLWidget * /* gla */) { if (shaders.find(a->text()) != shaders.end()) { ShaderInfo si = shaders[a->text()]; diff --git a/src/meshlabplugins/meshrender/meshrender.h b/src/meshlabplugins/meshrender/meshrender.h index 7e367a941..376e7fde1 100644 --- a/src/meshlabplugins/meshrender/meshrender.h +++ b/src/meshlabplugins/meshrender/meshrender.h @@ -23,6 +23,10 @@ /**************************************************************************** History $Log$ +Revision 1.18 2006/05/25 04:57:45 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. + Revision 1.17 2006/02/27 05:02:01 ggangemi Added texture support @@ -126,8 +130,8 @@ public: virtual const PluginInfo &Info(); virtual bool isSupported() {return supported;} - virtual void Init(QAction *a, MeshModel &m, RenderMode &rm, GLArea *gla); - virtual void Render(QAction *a, MeshModel &m, RenderMode &rm, GLArea *gla); + virtual void Init(QAction *a, MeshModel &m, RenderMode &rm, QGLWidget *gla); + virtual void Render(QAction *a, MeshModel &m, RenderMode &rm, QGLWidget *gla); }; diff --git a/src/meshlabplugins/meshrender/shaderDialog.cpp b/src/meshlabplugins/meshrender/shaderDialog.cpp index 221a99a0c..ba0f0afa1 100644 --- a/src/meshlabplugins/meshrender/shaderDialog.cpp +++ b/src/meshlabplugins/meshrender/shaderDialog.cpp @@ -1,11 +1,13 @@ #include "shaderDialog.h" #include - +#include +#include +#include #define DECFACTOR 100000.0f -ShaderDialog::ShaderDialog(ShaderInfo *sInfo, GLArea* gla, RenderMode &rm, QWidget *parent) +ShaderDialog::ShaderDialog(ShaderInfo *sInfo, QGLWidget* gla, RenderMode &rm, QWidget *parent) : QDialog(parent) { ui.setupUi(this); diff --git a/src/meshlabplugins/meshrender/shaderDialog.h b/src/meshlabplugins/meshrender/shaderDialog.h index 5b9a55016..668138435 100644 --- a/src/meshlabplugins/meshrender/shaderDialog.h +++ b/src/meshlabplugins/meshrender/shaderDialog.h @@ -11,20 +11,23 @@ #include #include #include +#include +#include + #include "shaderStructs.h" #include "ui_shaderDialog.h" -#include +//#include class ShaderDialog : public QDialog { Q_OBJECT public: - ShaderDialog(ShaderInfo *sInfo, GLArea* gla, RenderMode &rm, QWidget *parent = 0); + ShaderDialog(ShaderInfo *sInfo, QGLWidget* gla, RenderMode &rm, QWidget *parent = 0); ~ShaderDialog(); private: - GLArea* glarea; + QGLWidget* glarea; RenderMode * rendMode; ShaderInfo * shaderInfo; QSignalMapper *colorSignalMapper; diff --git a/src/meshlabplugins/meshselect/meshselect.cpp b/src/meshlabplugins/meshselect/meshselect.cpp new file mode 100644 index 000000000..53c437521 --- /dev/null +++ b/src/meshlabplugins/meshselect/meshselect.cpp @@ -0,0 +1,129 @@ +/**************************************************************************** + * 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.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 "meshselect.h" + +using namespace vcg; + +const QString SelectionFilterPlugin::ST(FilterType filter) +{ + switch(filter) + { + case FP_SELECT_ALL : return QString("Select All"); + case FP_SELECT_NONE : return QString("Select None"); + case FP_SELECT_INVERT : return QString("Invert Selection"); + case FP_SELECT_DELETE : return QString("Delete Selected Faces"); + } + return QString("Unknown filter"); +} + +SelectionFilterPlugin::SelectionFilterPlugin() +{ + typeList << + FP_SELECT_ALL << + FP_SELECT_NONE << + FP_SELECT_DELETE << + FP_SELECT_INVERT; + + FilterType tt; + + foreach(tt , types()) + actionList << new QAction(ST(tt), this); +} +SelectionFilterPlugin::~SelectionFilterPlugin() +{ + for (int i = 0; i < actionList.count() ; i++ ) { + delete actionList.at(i); + } +} + + +bool SelectionFilterPlugin::applyFilter(QAction *action, MeshModel &m, FilterParameter & par, vcg::CallBackPos * cb) +{ + par.clear(); + CMeshO::FaceIterator fi; + switch(ID(action)) + { + case FP_SELECT_DELETE : + for(fi=m.cm.face.begin();fi!=m.cm.face.end();++fi) + if(!(*fi).IsD() && (*fi).IsS() ) + { + (*fi).SetD(); + --m.cm.fn; + } + break; + case FP_SELECT_ALL : + for(fi=m.cm.face.begin();fi!=m.cm.face.end();++fi) + if(!(*fi).IsD()) (*fi).SetS(); + break; + case FP_SELECT_NONE : + for(fi=m.cm.face.begin();fi!=m.cm.face.end();++fi) + if(!(*fi).IsD()) (*fi).ClearS(); + break; + case FP_SELECT_INVERT : + for(fi=m.cm.face.begin();fi!=m.cm.face.end();++fi) + if(!(*fi).IsD()) + { + if((*fi).IsS()) (*fi).ClearS(); + else (*fi).SetS(); + } + break; + default: assert(0); + } + return true; +} + + const ActionInfo &SelectionFilterPlugin::Info(QAction *action) + { + static ActionInfo ai; + + if( action->text() == tr("Loop Subdivision Surface") ) + { + ai.Help = tr("Apply Loop's Subdivision Surface algorithm, it is an approximate method"); + ai.ShortHelp = tr("Apply Loop's Subdivision Surface algorithm"); + } + return ai; + } + + const PluginInfo &SelectionFilterPlugin::Info() +{ + static PluginInfo ai; + ai.Date=tr("__DATE__"); + ai.Version = tr("0.5"); + ai.Author = ("Paolo Cignoni"); + return ai; + } + +Q_EXPORT_PLUGIN(SelectionFilterPlugin) diff --git a/src/meshlabplugins/meshselect/meshselect.h b/src/meshlabplugins/meshselect/meshselect.h new file mode 100644 index 000000000..cf18bc086 --- /dev/null +++ b/src/meshlabplugins/meshselect/meshselect.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2005-2005 Trolltech AS. All rights reserved. +** +** This file is part of the example classes of the Qt Toolkit. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef EDITPLUGIN_H +#define EDITPLUGIN_H + +#include +#include +#include + +#include +#include + + +class SelectionFilterPlugin : public QObject, public MeshFilterInterface +{ + Q_OBJECT + Q_INTERFACES(MeshFilterInterface) + + public: + /* naming convention : + - FP -> Filter Plugin + - name of the plugin separated by _ + */ + enum { FP_SELECT_ALL, FP_SELECT_NONE, FP_SELECT_INVERT, FP_SELECT_DELETE} ; + + SelectionFilterPlugin(); + ~SelectionFilterPlugin(); + virtual const ActionInfo &Info(QAction *); + virtual const PluginInfo &Info(); + + virtual const QString ST(FilterType filter); + virtual const FilterClass getClass(QAction *) {return FilterClass::Selection;}; + virtual bool getParameters(QAction *, QWidget *, MeshModel &m, FilterParameter &par){return true;}; + virtual const int getRequirements(QAction *){return 0;}; + virtual bool applyFilter(QAction *filter, MeshModel &m, FilterParameter & /*parent*/, vcg::CallBackPos * cb) ; + +protected: + + ActionInfo *ai; + +}; + +#endif diff --git a/src/meshlabplugins/meshselect/meshselect.pro b/src/meshlabplugins/meshselect/meshselect.pro new file mode 100644 index 000000000..91f056f97 --- /dev/null +++ b/src/meshlabplugins/meshselect/meshselect.pro @@ -0,0 +1,27 @@ +TEMPLATE = lib +CONFIG += plugin +INCLUDEPATH += ../.. ../../../../sf ../../../../code/lib/glew/include +HEADERS = meshselect.h +SOURCES = meshselect.cpp +TARGET = meshselect +DESTDIR = ../../meshlab/plugins +# the following line is needed to avoid mismatch between +# the awful min/max macros of windows and the limits max +win32:DEFINES += NOMINMAX + +unix{ + QMAKE_CC = gcc-3.3 + QMAKE_CXX = g++-3.3 + QMAKE_LINK = gcc-3.3 + CONFIG += warn_off debug_and_release +} + +contains(TEMPLATE,lib) { + CONFIG(debug, debug|release) { + unix:TARGET = $$member(TARGET, 0)_debug + else:TARGET = $$member(TARGET, 0)d + } +} + + +