meshlab/src/fgt/edit_texture/edittexture.cpp
2008-05-04 20:05:01 +00:00

272 lines
6.8 KiB
C++

#include <QtGui>
#include <QString>
#include <math.h>
#include <stdlib.h>
#include <meshlab/glarea.h>
#include "edittexture.h"
#include "renderarea.h"
#include <wrap/gl/pick.h>
#include <wrap/gl/picking.h>
#include<limits>
#include <vcg/complex/trimesh/update/topology.h>
#include <vcg/complex/trimesh/update/flag.h>
using namespace vcg;
EditTexturePlugin::EditTexturePlugin()
{
isDragging = false;
widget = 0;
qFont.setFamily("Helvetica");
qFont.setPixelSize(14);
actionList << new QAction(QIcon(":/images/edit_texture.png"),"Edit UV Map", this);
QAction *editAction;
foreach(editAction, actionList) editAction->setCheckable(true);
}
EditTexturePlugin::~EditTexturePlugin()
{
if (widget != 0)
{
delete widget;
widget = 0;
}
}
QList<QAction *> EditTexturePlugin::actions() const
{
return actionList;
}
const QString EditTexturePlugin::Info(QAction *action)
{
if(action->text() != tr("Edit UV Map")) assert (0);
return tr("Edit texture coordinates of the selected area");
}
const PluginInfo &EditTexturePlugin::Info()
{
static PluginInfo ai;
ai.Date=tr(__DATE__);
ai.Version = tr("1.0.1");
ai.Author = ("Riccardo Dini");
return ai;
}
void EditTexturePlugin::mousePressEvent (QAction *, QMouseEvent * event, MeshModel &m, GLArea * gla)
{
isDragging = true;
if(event->modifiers() == Qt::ControlModifier) selMode = SMAdd;
else if(event->modifiers() == Qt::ShiftModifier) selMode = SMSub;
else selMode = SMClear;
// Change the appearance of the cursor
switch(selMode) // (in StartEdit func this doesn't work...)
{
case SMAdd: // CTRL + Mouse
gla->setCursor(QCursor(QPixmap(":/images/sel_rect_plus.png"),1,1));
break;
case SMSub: // SHIFT + Mouse
gla->setCursor(QCursor(QPixmap(":/images/sel_rect_minus.png"),1,1));
break;
case SMClear: // Mouse
gla->setCursor(QCursor(QPixmap(":/images/sel_rect.png"),1,1));
for (unsigned i = 0; i < FaceSel.size(); i++) FaceSel[i]->ClearS();
FaceSel.clear();
break;
}
if(event->modifiers() == Qt::ControlModifier || event->modifiers() == Qt::ShiftModifier )
{
CMeshO::FaceIterator fi;
for(fi = m.cm.face.begin(); fi != m.cm.face.end(); ++fi)
if(!(*fi).IsD() && (*fi).IsS()) FaceSel.push_back(&*fi);
}
start = event->pos();
cur = start;
gla->update();
return;
}
void EditTexturePlugin::mouseMoveEvent (QAction *,QMouseEvent * event, MeshModel &/*m*/, GLArea * gla)
{
prev = cur;
cur = event->pos();
int curT;
static int lastRendering;
if (isDragging)
{
// The user is selecting an area: management of the update
lastRendering = clock();
curT = clock();
if(gla->lastRenderingTime() < 50 || (curT - lastRendering) > 1000 )
{
lastRendering = curT;
gla->update();
}
else
{
gla->makeCurrent();
glDrawBuffer(GL_FRONT);
DrawXORRect(gla);
glDrawBuffer(GL_BACK);
glFlush();
}
}
}
void EditTexturePlugin::mouseReleaseEvent(QAction *,QMouseEvent * event, MeshModel &m, GLArea * gla)
{
prev = cur;
cur = event->pos();
gla->setCursor(QCursor(QPixmap(":/images/sel_rect.png"),1,1));
if (isDragging)
{
widget->SelectFromModel();
isDragging = false;
}
gla->update();
}
void EditTexturePlugin::Decorate(QAction *, MeshModel &m, GLArea *gla)
{
QPoint mid, wid;
vector<CMeshO::FacePointer> NewFaceSel;
vector<CMeshO::FacePointer>::iterator fpi;
CMeshO::FaceIterator fi;
if (isDragging)
{
DrawXORRect(gla);
mid = (start + cur)/2;
mid.setY(gla->curSiz.height() - mid.y());
wid = (start - cur);
if(wid.x()<0) wid.setX(-wid.x());
if(wid.y()<0) wid.setY(-wid.y());
for(fi = m.cm.face.begin(); fi != m.cm.face.end(); ++fi)
if(!(*fi).IsD()) (*fi).ClearS();
GLPickTri<CMeshO>::PickFace(mid.x(), mid.y(), m.cm, NewFaceSel, wid.x(), wid.y());
switch(selMode)
{
case SMSub:
for(fpi = FaceSel.begin(); fpi != FaceSel.end(); ++fpi)
(*fpi)->SetS();
for(fpi = NewFaceSel.begin(); fpi != NewFaceSel.end(); ++fpi)
(*fpi)->ClearS();
break;
case SMAdd:
for(fpi = FaceSel.begin(); fpi != FaceSel.end(); ++fpi)
(*fpi)->SetS();
case SMClear:
for(fpi = NewFaceSel.begin(); fpi != NewFaceSel.end(); ++fpi)
(*fpi)->SetS();
break;
}
}
}
void EditTexturePlugin::StartEdit(QAction * /*mode*/, MeshModel &m, GLArea *gla )
{
// Set up the model
if (!m.cm.face.IsFFAdjacencyEnabled()) m.cm.face.EnableFFAdjacency();
vcg::tri::UpdateTopology<CMeshO>::FaceFaceFromTexCoord(m.cm);
FaceSel.clear();
CMeshO::FaceIterator ff;
for(ff = m.cm.face.begin(); ff != m.cm.face.end(); ++ff)
if(!(*ff).IsD() && (*ff).IsS()) FaceSel.push_back(&*ff);
CMeshO::FaceIterator fi;
for(fi = m.cm.face.begin(); fi != m.cm.face.end(); ++fi) (*fi).ClearS();
gla->setCursor(QCursor(QPixmap(":/images/sel_rect.png"),1,1));
connect(this, SIGNAL(setSelectionRendering(bool)),gla,SLOT(setSelectionRendering(bool)));
setSelectionRendering(true);
// Create an istance of the interface
if (widget == 0)
{
widget = new TextureEditor(gla->window());
dock = new QDockWidget(gla->window());
dock->setAllowedAreas(Qt::NoDockWidgetArea);
dock->setWidget(widget);
QPoint p = gla->window()->mapToGlobal(QPoint(0,0));
dock->setGeometry(-5+p.x()+gla->window()->width()-widget->width(),p.y(),widget->width(),widget->height());
dock->setFloating(true);
QObject::connect(widget, SIGNAL(changeSelectMode(int)), this, SLOT(SelectMode(int)));
}
dock->setVisible(true);
dock->layout()->update();
widget->model = &m;
widget->area = gla;
// Initialize the texture using the intere model
InitTexture(m);
gla->update();
}
void EditTexturePlugin::EndEdit(QAction * , MeshModel &m , GLArea * )
{
// Delete the widget
for (unsigned i = 0; i < m.cm.face.size(); i++) m.cm.face[i].ClearS();
if (widget != 0)
{
delete widget;
delete dock;
widget = 0;
dock = 0;
}
}
void EditTexturePlugin::DrawXORRect(GLArea *gla)
{
// Draw the rectangle of the selection area
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);
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);
glPopAttrib();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void EditTexturePlugin::InitTexture(MeshModel &m)
{
// Get the textures name and add the tab
if (m.cm.textures.size() > 0)
{
for(unsigned i = 0; i < m.cm.textures.size(); i++)
widget->AddRenderArea(m.cm.textures[i].c_str(), &m, i);
}
else widget->AddEmptyRenderArea();
}
Q_EXPORT_PLUGIN(EditTexturePlugin)