mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-15 17:14:39 +00:00
318 lines
12 KiB
C++
318 lines
12 KiB
C++
/****************************************************************************
|
|
* 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: meshedit.cpp,v $
|
|
****************************************************************************/
|
|
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include <meshlab/glarea.h>
|
|
#include "sampleedit.h"
|
|
#include <wrap/gl/pick.h>
|
|
#include <wrap/qt/gl_label.h>
|
|
#include <wrap/qt/device_to_logical.h>
|
|
|
|
using namespace std;
|
|
using namespace vcg;
|
|
|
|
SampleEditPlugin::SampleEditPlugin()
|
|
{
|
|
qFont.setFamily("Helvetica");
|
|
qFont.setPixelSize(12);
|
|
|
|
haveToPick = false;
|
|
pickmode = 0; // 0 face 1 vertex
|
|
curFacePtr = 0;
|
|
curVertPtr = 0;
|
|
pIndex = 0;
|
|
}
|
|
|
|
const QString SampleEditPlugin::Info()
|
|
{
|
|
return tr("Return detailed info about a picked face or vertex of the model.");
|
|
}
|
|
|
|
void SampleEditPlugin::mouseReleaseEvent(QMouseEvent * event, MeshModel &/*m*/, GLArea * gla)
|
|
{
|
|
gla->update();
|
|
const Point2f loc = QTLogicalToOpenGL(gla, event->pos());
|
|
curGL = QPoint(int(loc.X()), int(loc.Y()));
|
|
haveToPick = true;
|
|
curFacePtr = 0;
|
|
curVertPtr = 0;
|
|
pIndex = 0;
|
|
}
|
|
|
|
void SampleEditPlugin::Decorate(MeshModel &m, GLArea * gla, QPainter *p)
|
|
{
|
|
// first of all, the picking
|
|
if (haveToPick)
|
|
{
|
|
glPushMatrix();
|
|
glMultMatrix(m.cm.Tr);
|
|
|
|
if (pickmode == 0)
|
|
{
|
|
NewFaceSel.clear();
|
|
GLPickTri<CMeshO>::PickVisibleFace(curGL.x(), curGL.y(), m.cm, NewFaceSel);
|
|
if (NewFaceSel.size() > 0)
|
|
{
|
|
curFacePtr = NewFaceSel[pIndex];
|
|
}
|
|
haveToPick = false;
|
|
}
|
|
else if (pickmode == 1)
|
|
{
|
|
NewVertSel.clear();
|
|
GLPickTri<CMeshO>::PickVert(curGL.x(), curGL.y(), m.cm, NewVertSel,15,15);
|
|
if (NewVertSel.size() > 0)
|
|
{
|
|
curVertPtr = NewVertSel[pIndex];
|
|
}
|
|
haveToPick = false;
|
|
}
|
|
|
|
glPopMatrix();
|
|
}
|
|
|
|
// then, the status
|
|
QString line1 = "";
|
|
QString line2 = "";
|
|
QString line3 = "";
|
|
|
|
if (pickmode == 0)
|
|
line1 = "Face Picking - T for vertex<br>";
|
|
else if (pickmode == 1)
|
|
line1 = "Vertex Picking - T for face<br>";
|
|
|
|
if ((curFacePtr != 0) || (curVertPtr != 0))
|
|
{
|
|
if (pickmode == 0)
|
|
{
|
|
line2 = QString("FACE# %1<br>").arg(QString::number(tri::Index(m.cm, curFacePtr)));
|
|
if (NewFaceSel.size() > 1)
|
|
line3 = "Q to cycle selected faces<br>";
|
|
line3 += "P to log the details of the face";
|
|
}
|
|
else if (pickmode == 1)
|
|
{
|
|
line2 = QString("VERTEX# %1<br>").arg(QString::number(tri::Index(m.cm, curVertPtr)));
|
|
if (NewVertSel.size() > 1)
|
|
line3 = "Q to cycle selected vertices<br>";
|
|
line3 += "P to log the details of the vertex";
|
|
}
|
|
}
|
|
|
|
this->RealTimeLog("Geometry Info", m.shortName(),
|
|
"%s %s %s", line1.toStdString().c_str(), line2.toStdString().c_str(), line3.toStdString().c_str());
|
|
|
|
// finally, the actual decoration
|
|
if (curFacePtr)
|
|
{
|
|
glPushMatrix();
|
|
glMultMatrix(m.cm.Tr);
|
|
glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_LINE_BIT | GL_DEPTH_BUFFER_BIT);
|
|
glLineWidth(2.0f);
|
|
glDepthFunc(GL_ALWAYS);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDepthMask(GL_FALSE);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
glColor(vcg::Color4b(vcg::Color4b::DarkRed));
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex(curFacePtr->P(0));
|
|
glVertex(curFacePtr->P(1));
|
|
glVertex(curFacePtr->P(2));
|
|
glEnd();
|
|
|
|
glDepthMask(GL_TRUE);
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDepthFunc(GL_LESS);
|
|
glColor(vcg::Color4b(vcg::Color4b::Red));
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex(curFacePtr->P(0));
|
|
glVertex(curFacePtr->P(1));
|
|
glVertex(curFacePtr->P(2));
|
|
glEnd();
|
|
|
|
drawFace(curFacePtr, m, gla, p);
|
|
|
|
glPopAttrib();
|
|
glPopMatrix();
|
|
}
|
|
|
|
if (curVertPtr)
|
|
{
|
|
glPushMatrix();
|
|
glMultMatrix(m.cm.Tr);
|
|
glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_POINT_BIT | GL_DEPTH_BUFFER_BIT);
|
|
glPointSize(6.0f);
|
|
glDepthFunc(GL_ALWAYS);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDepthMask(GL_FALSE);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
glColor(vcg::Color4b(vcg::Color4b::DarkBlue));
|
|
glBegin(GL_POINTS);
|
|
glVertex(curVertPtr->P());
|
|
glEnd();
|
|
|
|
glDepthMask(GL_TRUE);
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDepthFunc(GL_LESS);
|
|
glColor(vcg::Color4b(vcg::Color4b::Blue));
|
|
glBegin(GL_POINTS);
|
|
glVertex(curVertPtr->P());
|
|
glEnd();
|
|
|
|
drawVert(curVertPtr, m, gla, p);
|
|
|
|
glPopAttrib();
|
|
glPopMatrix();
|
|
}
|
|
}
|
|
|
|
void SampleEditPlugin::drawFace(CMeshO::FacePointer fp, MeshModel &m, GLArea *gla, QPainter *p)
|
|
{
|
|
QString buf = QString("f#%1 - v#(%2 %3 %4)").arg(QString::number(tri::Index(m.cm, fp))).arg(QString::number(tri::Index(m.cm, fp->V(0)))).arg(QString::number(tri::Index(m.cm, fp->V(1)))).arg(QString::number(tri::Index(m.cm, fp->V(2))));
|
|
if (m.hasDataMask(MeshModel::MM_FACECOLOR))
|
|
buf += QString(" - color(%1 %2 %3 %4)").arg(QString::number(fp->C()[0])).arg(QString::number(fp->C()[1])).arg(QString::number(fp->C()[2])).arg(QString::number(fp->C()[3]));
|
|
Point3m c = Barycenter(*fp);
|
|
vcg::glLabel::render(p, c, buf);
|
|
for (int i = 0; i<3; ++i)
|
|
{
|
|
QString buf;
|
|
buf =QString("fv%1:v#%2 - pos[%3 %4 %5]").arg(QString::number(i)).arg(QString::number(fp->V(i) - &m.cm.vert[0])).arg(QString::number(fp->P(i)[0])).arg(QString::number(fp->P(i)[1])).arg(QString::number(fp->P(i)[2]));
|
|
if( m.hasDataMask(MeshModel::MM_VERTQUALITY) )
|
|
buf +=QString(" - Q(%1)").arg(QString::number(fp->V(i)->Q()));
|
|
if (m.hasDataMask(MeshModel::MM_VERTCOLOR))
|
|
buf += QString(" - color(%1 %2 %3 %4)").arg(QString::number(fp->V(i)->C()[0])).arg(QString::number(fp->V(i)->C()[1])).arg(QString::number(fp->V(i)->C()[2])).arg(QString::number(fp->V(i)->C()[3]));
|
|
if( m.hasDataMask(MeshModel::MM_WEDGTEXCOORD) )
|
|
buf +=QString(" - [W]uv(%1 %2) id:%3").arg(QString::number(fp->WT(i).U())).arg(QString::number(fp->WT(i).V())).arg(QString::number(fp->WT(i).N()));
|
|
if( m.hasDataMask(MeshModel::MM_VERTTEXCOORD) )
|
|
buf +=QString(" - [V]uv(%1 %2) id:%3").arg(QString::number(fp->V(i)->T().U())).arg(QString::number(fp->V(i)->T().V())).arg(QString::number(fp->V(i)->T().N()));
|
|
|
|
vcg::glLabel::render(p,fp->V(i)->P(),buf);
|
|
}
|
|
}
|
|
|
|
void SampleEditPlugin::drawVert(CMeshO::VertexPointer vp, MeshModel &m, GLArea *gla, QPainter *p)
|
|
{
|
|
QString buf;
|
|
buf = QString("v#%1 - pos[%2 %3 %4]").arg(QString::number(vp - &m.cm.vert[0])).arg(QString::number(vp->P()[0])).arg(QString::number(vp->P()[1])).arg(QString::number(vp->P()[2]));
|
|
if (m.hasDataMask(MeshModel::MM_VERTQUALITY))
|
|
buf += QString(" - Q(%1)").arg(QString::number(vp->Q()));
|
|
if (m.hasDataMask(MeshModel::MM_VERTCOLOR))
|
|
buf += QString(" - color(%1 %2 %3 %4)").arg(QString::number(vp->C()[0])).arg(QString::number(vp->C()[1])).arg(QString::number(vp->C()[2])).arg(QString::number(vp->C()[3]));
|
|
if (m.hasDataMask(MeshModel::MM_VERTTEXCOORD))
|
|
buf += QString(" - [V]uv(%1 %2) id:%3").arg(QString::number(vp->T().U())).arg(QString::number(vp->T().V())).arg(QString::number(vp->T().N()));
|
|
|
|
vcg::glLabel::render(p, vp->P(), buf);
|
|
}
|
|
|
|
void SampleEditPlugin::keyReleaseEvent(QKeyEvent *e, MeshModel &m, GLArea *gla)
|
|
{
|
|
if (e->key() == Qt::Key_T) // toggle pick mode
|
|
{
|
|
pickmode = (pickmode + 1) % 2;
|
|
curFacePtr = 0;
|
|
curVertPtr = 0;
|
|
pIndex = 0;
|
|
gla->update();
|
|
}
|
|
|
|
if ((e->key() == Qt::Key_Q) && ((curFacePtr != 0) || (curVertPtr != 0))) // tab to next selected mode
|
|
{
|
|
if (pickmode == 0)
|
|
{
|
|
pIndex = (pIndex + 1) % NewFaceSel.size();
|
|
curFacePtr = NewFaceSel[pIndex];
|
|
}
|
|
else if (pickmode == 1)
|
|
{
|
|
pIndex = (pIndex + 1) % NewVertSel.size();
|
|
curVertPtr = NewVertSel[pIndex];
|
|
}
|
|
gla->update();
|
|
}
|
|
|
|
if ((e->key() == Qt::Key_P) && ((curFacePtr != 0) || (curVertPtr != 0))) // tab to next selected mode
|
|
{
|
|
// print on log
|
|
if (pickmode == 0)
|
|
{
|
|
this->Log(GLLogStream::FILTER, "------");
|
|
this->Log(GLLogStream::FILTER, "face# %i : vert# (%i %i %i)", tri::Index(m.cm, curFacePtr), tri::Index(m.cm, curFacePtr->V(0)), tri::Index(m.cm, curFacePtr->V(1)), tri::Index(m.cm, curFacePtr->V(2)));
|
|
if (m.hasDataMask(MeshModel::MM_FACECOLOR))
|
|
this->Log(GLLogStream::FILTER, "face color (%i %i %i %i)", curFacePtr->C()[0], curFacePtr->C()[1], curFacePtr->C()[2], curFacePtr->C()[3]);
|
|
for (int i = 0; i < 3; ++i)
|
|
{
|
|
this->Log(GLLogStream::FILTER, "face vert %i : vert# %i", i, tri::Index(m.cm, curFacePtr->V(i)));
|
|
this->Log(GLLogStream::FILTER, "position [%f %f %f]", curFacePtr->V(i)->P()[0], curFacePtr->V(i)->P()[1], curFacePtr->V(i)->P()[2]);
|
|
this->Log(GLLogStream::FILTER, "normal [%f %f %f]", curFacePtr->V(i)->N()[0], curFacePtr->V(i)->N()[1], curFacePtr->V(i)->N()[2]);
|
|
if (m.hasDataMask(MeshModel::MM_VERTQUALITY))
|
|
this->Log(GLLogStream::FILTER, "quality %f", curFacePtr->V(i)->Q());
|
|
if (m.hasDataMask(MeshModel::MM_VERTCOLOR))
|
|
this->Log(GLLogStream::FILTER, "color (%f %f %f %f)", curFacePtr->V(i)->C()[0], curFacePtr->V(i)->C()[1], curFacePtr->V(i)->C()[2], curFacePtr->V(i)->C()[3]);
|
|
if (m.hasDataMask(MeshModel::MM_WEDGTEXCOORD))
|
|
this->Log(GLLogStream::FILTER, "wedge UV (%f %f) texID %i)", curFacePtr->WT(i).U(), curFacePtr->WT(i).V(), curFacePtr->WT(i).N());
|
|
if (m.hasDataMask(MeshModel::MM_VERTTEXCOORD))
|
|
this->Log(GLLogStream::FILTER, "vertex UV (%f %f) texID %i)", curFacePtr->V(i)->T().U(), curFacePtr->V(i)->T().U(), curFacePtr->V(i)->T().N());
|
|
}
|
|
this->Log(GLLogStream::FILTER, "------");
|
|
}
|
|
else if (pickmode == 1)
|
|
{
|
|
this->Log(GLLogStream::FILTER, "------");
|
|
this->Log(GLLogStream::FILTER, "vertex# %i", tri::Index(m.cm, curVertPtr));
|
|
this->Log(GLLogStream::FILTER, "position [%f %f %f]", curVertPtr->P()[0], curVertPtr->P()[1], curVertPtr->P()[2]);
|
|
this->Log(GLLogStream::FILTER, "normal [%f %f %f]", curVertPtr->N()[0], curVertPtr->N()[1], curVertPtr->N()[2]);
|
|
if (m.hasDataMask(MeshModel::MM_VERTQUALITY))
|
|
this->Log(GLLogStream::FILTER, "quality %f", curVertPtr->Q());
|
|
if (m.hasDataMask(MeshModel::MM_VERTCOLOR))
|
|
this->Log(GLLogStream::FILTER, "color (%f %f %f %f)", curVertPtr->C()[0], curVertPtr->C()[1], curVertPtr->C()[2], curVertPtr->C()[3]);
|
|
if (m.hasDataMask(MeshModel::MM_VERTTEXCOORD))
|
|
this->Log(GLLogStream::FILTER, "vertex UV (%f %f) texID %i)", curVertPtr->T().U(), curVertPtr->T().U(), curVertPtr->T().N());
|
|
this->Log(GLLogStream::FILTER, "------");
|
|
}
|
|
gla->update();
|
|
}
|
|
}
|
|
|
|
bool SampleEditPlugin::StartEdit(MeshModel &/*m*/, GLArea * gla, MLSceneGLSharedDataContext* /*cont*/)
|
|
{
|
|
gla->setCursor(QCursor(QPixmap(":/images/cur_info.png"),1,1));
|
|
connect(this, SIGNAL(suspendEditToggle()), gla, SLOT(suspendEditToggle()));
|
|
return true;
|
|
}
|
|
|
|
void SampleEditPlugin::EndEdit(MeshModel &/*m*/, GLArea * /*parent*/, MLSceneGLSharedDataContext* /*cont*/)
|
|
{
|
|
haveToPick = false;
|
|
pickmode = 0; // 0 face 1 vertex
|
|
curFacePtr = 0;
|
|
curVertPtr = 0;
|
|
pIndex = 0;
|
|
}
|