first version of a plugin for picking points on a mesh. alows you to label picked points as well as save the points and labels to an xml file

This commit is contained in:
Paolo Cignoni cignoni 2008-06-04 13:08:58 +00:00
parent c9be2d2afc
commit fd93cfb9e3
11 changed files with 1696 additions and 0 deletions

View File

@ -0,0 +1,24 @@
include (../../shared.pri)
HEADERS += editpickpoints.h \
pickpointsDialog.h \
pickedPoints.h \
pickPointsTemplate.h \
../../meshlab/stdpardialog.h
SOURCES += editpickpoints.cpp \
pickpointsDialog.cpp \
pickedPoints.cpp \
pickPointsTemplate.cpp \
../../meshlab/stdpardialog.cpp \
../../meshlab/filterparameter.cpp \
../../../code/lib/glew/src/glew.c
RESOURCES += editpickpoints.qrc
FORMS += pickpointsDialog.ui
TARGET = edit_pickpoints
QT += opengl
QT += xml

View File

@ -0,0 +1,243 @@
/* A class implementing Meshlab's Edit interface that is for picking points in 3D
*
*
* @author Oscar Barney
*/
#include <QtGui>
#include <GL/glew.h>
#include "editpickpoints.h"
#include <meshlab/mainwindow.h>
#include <wrap/gl/picking.h>
using namespace vcg;
EditPickPointsPlugin::EditPickPointsPlugin(){
actionList << new QAction(QIcon(":/images/pickpoints.png"), pickPointsActionName, this);
foreach(QAction *editAction, actionList)
editAction->setCheckable(true);
//initialize to false so we dont end up collection some weird point in the beginning
addPoint = false;
movePoint = false;
pickPointsDialog = 0;
}
//Constants
//name of the actions
const char* EditPickPointsPlugin::pickPointsActionName = "PickPoints";
//just returns the action list
QList<QAction *> EditPickPointsPlugin::actions() const {
return actionList;
}
const QString EditPickPointsPlugin::Info(QAction *action)
{
if( action->text() != tr(pickPointsActionName) )
assert (0);
return tr("Pick and save 3D points on the mesh");
}
const PluginInfo &EditPickPointsPlugin::Info()
{
static PluginInfo ai;
ai.Date=tr(__DATE__);
ai.Version = tr("1.0");
ai.Author = ("Oscar Barney");
return ai;
}
//called
void EditPickPointsPlugin::Decorate(QAction * /*ac*/, MeshModel &mm, GLArea *gla)
{
//qDebug() << "Decorate " << mm.fileName.c_str() << " ...";
if(gla != glArea){
qDebug() << "GLarea is different!!! ";
}
//make sure we picking points on the right meshes!
if(gla != glArea || glArea->mm() != pickPointsDialog->getCurrentMeshModel()){
//also test to see which mesh is picked currently
pickPointsDialog->setCurrentMeshModel(glArea->mm());
}
//We have to calculate the position here because it doesnt work in the mouseEvent functions for some reason
Point3f pickedPoint;
if (movePoint && Pick<Point3f>(currentMousePosition.x(),gla->height()-currentMousePosition.y(),pickedPoint)){
qDebug("Found point for move %i %i -> %f %f %f",
currentMousePosition.x(),
currentMousePosition.y(),
pickedPoint[0], pickedPoint[1], pickedPoint[2]);
//let the dialog know that this was the pointed picked incase it wants the information
pickPointsDialog->moveThisPoint(pickedPoint);
movePoint = false;
} else if(addPoint && Pick<Point3f>(currentMousePosition.x(),gla->height()-currentMousePosition.y(),pickedPoint))
{
qDebug("Found point for add %i %i -> %f %f %f",
currentMousePosition.x(),
currentMousePosition.y(),
pickedPoint[0], pickedPoint[1], pickedPoint[2]);
pickPointsDialog->addPoint(pickedPoint);
addPoint = false;
}
drawPickedPoints(pickPointsDialog->getPickedPointTreeWidgetItemVector());
}
void EditPickPointsPlugin::StartEdit(QAction * /*mode*/, MeshModel &mm, GLArea *gla )
{
qDebug() << "StartEdit Pick Points: " << mm.fileName.c_str() << " ...";
//set this so redraw can use it
glArea = gla;
//Create GUI window if we dont already have one
if(pickPointsDialog == 0)
{
pickPointsDialog = new PickPointsDialog(this, gla->window());
}
pickPointsDialog->setCurrentMeshModel(&mm);
//show the dialog
pickPointsDialog->show();
}
void EditPickPointsPlugin::EndEdit(QAction * /*mode*/, MeshModel &mm, GLArea *gla)
{
qDebug() << "EndEdit Pick Points: " << mm.fileName.c_str() << " ...";
// some cleaning at the end.
//now that were are ending tell the dialog there is no longer a model to edit
pickPointsDialog->setCurrentMeshModel(NULL);
//remove the dialog from the screen
pickPointsDialog->hide();
}
void EditPickPointsPlugin::mousePressEvent(QAction *, QMouseEvent *event, MeshModel &mm, GLArea *gla )
{
//qDebug() << "mouse press Pick Points: " << mm.fileName.c_str() << " ...";
if(Qt::LeftButton | event->buttons())
{
gla->suspendedEditor = true;
QCoreApplication::sendEvent(gla, event);
gla->suspendedEditor = false;
}
if(Qt::RightButton == event->button() &&
pickPointsDialog->getMode() == PickPointsDialog::MOVE_POINT){
currentMousePosition = event->pos();
//set flag that we need to add a new point
movePoint = true;
}
}
void EditPickPointsPlugin::mouseMoveEvent(QAction *, QMouseEvent *event, MeshModel &mm, GLArea *gla )
{
//qDebug() << "mousemove pick Points: " << mm.fileName.c_str() << " ...";
if(Qt::LeftButton | event->buttons())
{
gla->suspendedEditor = true;
QCoreApplication::sendEvent(gla, event);
gla->suspendedEditor = false;
}
if(Qt::RightButton & event->buttons() &&
pickPointsDialog->getMode() == PickPointsDialog::MOVE_POINT){
//qDebug() << "mouse move left button and move mode: ";
currentMousePosition = event->pos();
//set flag that we need to add a new point
addPoint = true;
}
}
void EditPickPointsPlugin::mouseReleaseEvent(QAction *,
QMouseEvent *event, MeshModel &mm, GLArea * gla)
{
//qDebug() << "mouseRelease Pick Points: " << mm.fileName.c_str() << " ...";
if(Qt::LeftButton | event->buttons())
{
gla->suspendedEditor = true;
QCoreApplication::sendEvent(gla, event);
gla->suspendedEditor = false;
}
//only add points for the left button
if(Qt::RightButton == event->button()){
currentMousePosition = event->pos();
//set flag that we need to add a new point
addPoint = true;
}
}
void EditPickPointsPlugin::drawPickedPoints(
std::vector<PickedPointTreeWidgetItem*> &pointVector)
{
//qDebug() << "draw picked points ";
glPushAttrib(GL_ENABLE_BIT | GL_POINT_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_LIGHTING);
//glDisable(GL_TEXTURE); //caused error but does not seem to be needed
glDepthFunc(GL_ALWAYS);
//set point attributes
glPointSize(3.0);
glColor(Color4b::Blue);
for(int i=0; i<pointVector.size(); ++i)
{
PickedPointTreeWidgetItem * item = pointVector[i];
//if the point has been set (it may not be if a template has been loaded)
if(item->isSet()){
Point3f point = item->getPoint();
glBegin(GL_POINTS);
glVertex(point);
glEnd();
assert(glArea);
glArea->renderText(point[0], point[1], point[2], QString(item->getName()) );
}
}
glPopAttrib();
glArea->update();
}
Q_EXPORT_PLUGIN(EditPickPointsPlugin)

View File

@ -0,0 +1,78 @@
/* A class implementing Meshlab's Edit interface that is for picking points in 3D
*
*
* @author Oscar Barney
*/
#ifndef EDIT_PickPoints_PLUGIN_H
#define EDIT_PickPoints_PLUGIN_H
#include <QObject>
#include <QString>
#include <QList>
#include <meshlab/meshmodel.h>
#include <meshlab/interfaces.h>
#include "pickpointsDialog.h"
class EditPickPointsPlugin : public QObject, public MeshEditInterface
{
Q_OBJECT
Q_INTERFACES(MeshEditInterface)
public:
//constructor
EditPickPointsPlugin();
//destructor
virtual ~EditPickPointsPlugin() {
//free memory for each action
foreach(QAction *editAction, actionList)
delete editAction;
//free memory used by the gui
delete pickPointsDialog;
}
virtual QList<QAction *> actions() const ;
virtual const QString 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 &, GLArea * ) ;
virtual void mouseMoveEvent(QAction *, QMouseEvent *event, MeshModel &, GLArea * ) ;
virtual void mouseReleaseEvent(QAction *, QMouseEvent *event, MeshModel &/*m*/, GLArea * );
//basically copied from void AlignPairWidget::drawPickedPoints in editalign plugin
//Draws all the picked points on the screen
void drawPickedPoints(std::vector<PickedPointTreeWidgetItem*> &pointVector);
private:
//the list of possible actions
QList <QAction *> actionList;
//constant for the name of the action for picking points
static const char* pickPointsActionName;
//the current place the mouse clicked
QPoint currentMousePosition;
//flag that tells the decorate function whether to add the latest point
bool addPoint;
//flag that tells the decorate function whether we are moving points
bool movePoint;
//the gui dialog for this plugin
PickPointsDialog *pickPointsDialog;
//we need this in order to redraw the points
GLArea *glArea;
};
#endif

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/" >
<file>images/pickpoints.png</file>
</qresource>
</RCC>

View File

@ -0,0 +1,90 @@
/* A class representing a set of point names that is used
* as a template a user can fill out to create a PickedPoints
*
*
* @author Oscar Barney
*/
#include "pickPointsTemplate.h"
#include <QtGui>
//xml stuff
#include <QtXml/QDomDocument>
#include <QtXml/QDomElement>
#include <QtXml/QDomNode>
//Define Constants
const QString PickPointsTemplate::fileExtension = ".xml";
const QString PickPointsTemplate::rootName = "PickPointsTemplate";
const QString PickPointsTemplate::pointElementName = "point";
const QString PickPointsTemplate::pointName = "name";
bool PickPointsTemplate::save(QString filename,
std::vector<QString> *pointNameVector){
QDomDocument doc(rootName);
QDomElement root = doc.createElement(rootName);
doc.appendChild(root);
//create an element for each point
for (int i = 0; i < pointNameVector->size(); ++i) {
QString name = pointNameVector->at(i);
QDomElement tag = doc.createElement(pointElementName);
tag.setAttribute(pointName, name);
//append the element to the root
root.appendChild(tag);
}
//create a file and write the data
QFile file(filename);
file.open(QIODevice::WriteOnly);
QTextStream qstream(&file);
doc.save(qstream,1);
file.close();
return true;
}
bool PickPointsTemplate::load(QString filename,
std::vector<QString> *pointNameVector){
QDomDocument doc;
pointNameVector->clear();
QFile file(filename);
QString errorMessage;
if (file.open(QIODevice::ReadOnly) && doc.setContent(&file, &errorMessage))
{
file.close();
QDomElement root = doc.documentElement();
if (root.nodeName() == rootName)
{
qDebug() << "About to read a " << rootName << " xml document";
for(QDomElement element = root.firstChildElement(pointElementName);
!element.isNull();
element = element.nextSiblingElement(pointElementName))
{
QString name = element.attribute(pointName);
qDebug() << "Reading point with name " << name;
pointNameVector->push_back(name);
}
} else {
//file is of unknown type
qDebug() << "Failed, tried to read a " << rootName << " xml document";
return false;
}
} else {
// problem opening the file
qDebug() << "problem reading from the file, setContent error: " << errorMessage;
return false;
}
return true;
}

View File

@ -0,0 +1,34 @@
/* A class representing a set of point names that is used
* as a template a user can fill out to create a PickedPoints
*
*
* @author Oscar Barney
*/
#include <QString>
#include <vector>
class PickPointsTemplate
{
public:
static bool save(QString filename, std::vector<QString> *pointNameVector);
static bool load(QString filename, std::vector<QString> *pointNameVector);
//extension of the filetype for PickPointsTemplate
static const QString fileExtension;
private:
PickPointsTemplate(){};
//root name of the xml document
static const QString rootName;
//point element's name
static const QString pointElementName;
//point's name
static const QString pointName;
};

View File

@ -0,0 +1,178 @@
/* A class representing a set of points and the format
* that we will be storing them
*
*
* @author Oscar Barney
*/
#include "pickedPoints.h"
#include <QtGui>
#include <QMap>
#include <QList>
//xml stuff
#include <QtXml/QDomDocument>
#include <QtXml/QDomElement>
#include <QtXml/QDomNode>
//Define Constants
const QString PickedPoints::fileExtension = ".xml";
const QString PickedPoints::rootName = "PickedPoints";
const QString PickedPoints::pointElementName = "point";
const QString PickedPoints::pointName = "name";
const QString PickedPoints::xCoordinate = "x";
const QString PickedPoints::yCoordinate = "y";
const QString PickedPoints::zCoordinate = "z";
PickedPoints::PickedPoints(){
pointVector = new std::vector<PickedPoint *>();
}
PickedPoints::~PickedPoints(){
delete pointVector;
}
bool PickedPoints::open(QString filename){
QDomDocument doc;
pointVector->clear();
QFile file(filename);
QString errorMessage;
if (file.open(QIODevice::ReadOnly) && doc.setContent(&file, &errorMessage))
{
file.close();
QDomElement root = doc.documentElement();
if (root.nodeName() == rootName)
{
qDebug() << "About to read a " << rootName << " xml document";
for(QDomElement element = root.firstChildElement(pointElementName);
!element.isNull();
element = element.nextSiblingElement(pointElementName))
{
QString name = element.attribute(pointName);
qDebug() << "Reading point with name " << name;
QString x = element.attribute(xCoordinate);
QString y = element.attribute(yCoordinate);
QString z = element.attribute(zCoordinate);
vcg::Point3f point(x.toFloat(), y.toFloat(), z.toFloat());
addPoint(name, point);
}
} else {
//file is of unknown type
qDebug() << "Failed, tried to read a " << rootName << " xml document";
return false;
}
} else {
// problem opening the file
qDebug() << "problem reading from the file, setContent error: " << errorMessage;
return false;
}
return true;
}
bool PickedPoints::save(QString filename){
QDomDocument doc(rootName);
QDomElement root = doc.createElement(rootName);
doc.appendChild(root);
//create an element for each point
for (int i = 0; i < pointVector->size(); ++i) {
PickedPoint *pickedPoint = pointVector->at(i);
QDomElement tag = doc.createElement(pointElementName);
tag.setAttribute(pointName, pickedPoint->name);
vcg::Point3f point = pickedPoint->point;
tag.setAttribute(xCoordinate, point[0] );
tag.setAttribute(yCoordinate, point[1] );
tag.setAttribute(zCoordinate, point[2] );
//append the element to the root
root.appendChild(tag);
}
//create a file and write the data
QFile file(filename);
file.open(QIODevice::WriteOnly);
QTextStream qstream(&file);
doc.save(qstream,1);
file.close();
return true;
}
void PickedPoints::addPoint(QString name, vcg::Point3f point){
if(NULL != pointVector){
PickedPoint *pickedPoint = new PickedPoint(name,point);
pointVector->push_back(pickedPoint);
} else
{
qDebug("NULL pointVector!");
}
}
std::vector<PickedPoint*> * PickedPoints::getPickedPointVector()
{
return pointVector;
}
std::vector<vcg::Point3f> * PickedPoints::getPoint3fVector()
{
std::vector<vcg::Point3f> *points = new std::vector<vcg::Point3f>();
for(int i = 0; i < pointVector->size(); i++)
{
points->push_back(pointVector->at(i)->point);
}
return points;
}
void PickedPoints::translatePoints(vcg::Matrix44f &translation)
{
for(int i = 0; i < pointVector->size(); i++)
{
PickedPoint* temp = pointVector->at(i);
//qDebug() << " point was x" << temp->point[0] << " y " << temp->point[1] << " z " << temp->point[2];
vcg::Point4f inputPoint(temp->point[0], temp->point[1], temp->point[2], 1);
vcg::Point4f resultPoint = translation * inputPoint;
temp->point[0] = resultPoint[0];
temp->point[1] = resultPoint[1];
temp->point[2] = resultPoint[2];
//qDebug() << " point is now x" << temp->point[0] << " y " << temp->point[1] << " z " << temp->point[2];
}
}
/*
const MeshMetaDataInterface::MetaDataType PickedPoints::getKey()
{
return MeshMetaDataInterface::PICKED_POINTS;
}
*/
QString PickedPoints::getSuggestedPickedPointsFileName(const MeshModel &meshModel){
QString outputFileName(meshModel.fileName.c_str());
//remove postfix
outputFileName.truncate(outputFileName.length()-4);
//add new postfix
outputFileName.append("_picked_points" + fileExtension);
return outputFileName;
}

View File

@ -0,0 +1,98 @@
/* A class representing a set of points and the format
* that we will be storing them
*
*
* @author Oscar Barney
*/
#ifndef PICKED_POINTS_H
#define PICKED_POINTS_H
#include <QString>
#include <QMap>
#include <meshlab/meshmodel.h>
//our points
class PickedPoint
{
public:
PickedPoint(QString _name, vcg::Point3f _point){
name = _name;
point = _point;
}
//name of point
QString name;
//tells us whether to use this or not in a calculation
//bool active;
//point
vcg::Point3f point;
};
class PickedPoints// : public MeshMetaDataInterface
{
public:
PickedPoints();
~PickedPoints();
//opens a file containing the picked points
bool open(QString filename);
//save
bool save(QString filename);
//add a point to the map
void addPoint(QString name, vcg::Point3f point);
std::vector<PickedPoint*> * getPickedPointVector();
std::vector<vcg::Point3f> * getPoint3fVector();
//translate each point using the matrix
//if the mesh moves you can then translate the points useing this function
void translatePoints(vcg::Matrix44f &translation);
//get the suggested filename for the points. will be based on the mesh's filename
static QString getSuggestedPickedPointsFileName(const MeshModel &meshModel);
//extension of the filetype for Picked Points
static const QString fileExtension;
//from MeshMetaDataInterface
//static const MetaDataType getKey();
private:
//data
std::vector<PickedPoint*> *pointVector;
//Declare Constants
//root name of the xml document
static const QString rootName;
//point element's name
static const QString pointElementName;
//point's name
static const QString pointName;
//point's x coord
static const QString xCoordinate;
//point's y coord
static const QString yCoordinate;
//points z coord
static const QString zCoordinate;
};
#endif

View File

@ -0,0 +1,547 @@
/* A class to represent the ui for the pickpoints plugin
*
* @author Oscar Barney
*/
#include <QtGui>
#include <math.h>
#include "editpickpoints.h"
#include "pickpointsDialog.h"
#include <meshlab/stdpardialog.h>
using namespace vcg;
int PickedPointTreeWidgetItem::pointCounter = 0;
PickedPointTreeWidgetItem::PickedPointTreeWidgetItem(
Point3f intputPoint) : QTreeWidgetItem(1001) {
point = intputPoint;
QString tempString;
tempString.setNum(pointCounter);
//name
setText(0, tempString);
pointCounter++;
//x
tempString.setNum(point[0]);
setText(1, tempString);
//y
tempString.setNum(point[1]);
setText(2, tempString);
//z
tempString.setNum(point[2]);
setText(3, tempString);
isPointSet = true;
}
PickedPointTreeWidgetItem::PickedPointTreeWidgetItem(QString name){
isPointSet = false;
setText(0, name);
}
void PickedPointTreeWidgetItem::setName(QString name){
setText(0, name);
}
QString PickedPointTreeWidgetItem::getName(){
return text(0);
}
void PickedPointTreeWidgetItem::setPoint(Point3f intputPoint){
point = intputPoint;
QString tempString;
//x
tempString.setNum(point[0]);
setText(1, tempString);
//y
tempString.setNum(point[1]);
setText(2, tempString);
//z
tempString.setNum(point[2]);
setText(3, tempString);
isPointSet = true;
}
vcg::Point3f PickedPointTreeWidgetItem::getPoint(){
return point;
}
void PickedPointTreeWidgetItem::clearPoint(){
point.Zero();
isPointSet = false;
//x
setText(1, "");
//y
setText(2, "");
//z
setText(3, "");
}
bool PickedPointTreeWidgetItem::isSet(){
return isPointSet;
}
PickPointsDialog::PickPointsDialog(EditPickPointsPlugin *plugin,
QWidget *parent) : QDockWidget(parent)
{
parentPlugin = plugin;
//qt standard setup step
PickPointsDialog::ui.setupUi(this);
//setup borrowed from alighnDialog.cpp
this->setWidget(ui.frame);
this->setFeatures(QDockWidget::AllDockWidgetFeatures);
this->setAllowedAreas(Qt::LeftDockWidgetArea);
QPoint p=parent->mapToGlobal(QPoint(0,0));
this->setFloating(true);
this->setGeometry(p.x()+(parent->width()-width()),p.y()+40,width(),height() );
//now stuff specific to pick points
QStringList headerNames;
headerNames << "Point Name" << "X" << "Y" << "Z";
ui.pickedPointsTreeWidget->setHeaderLabels(headerNames);
//init some variables
//set to nothing for now
itemToMove = 0;
meshModel = 0;
//start with no template
templateLoaded = false;
currentMode = ADD_POINT;
//signals and slots
connect(ui.removeHighlightedButton, SIGNAL(clicked()), this, SLOT(removeHighlightedPoint()));
connect(ui.renamePointButton, SIGNAL(clicked()), this, SLOT(renameHighlightedPoint()));
connect(ui.pickPointModeRadioButton, SIGNAL(toggled(bool)), this, SLOT(togglePickMode(bool)));
connect(ui.saveButton, SIGNAL(clicked()), this, SLOT(savePointsToFile()));
connect(ui.loadPointsButton, SIGNAL(clicked()), this, SLOT(loadPoints()));
connect(ui.clearButton, SIGNAL(clicked()), this, SLOT(clearPoints()));
connect(ui.saveTemplateButton, SIGNAL(clicked()), this, SLOT(savePointTemplate()));
connect(ui.loadTemplateButton, SIGNAL(clicked()), this, SLOT(loadPickPointsTemplate()));
connect(ui.clearTemplateButton, SIGNAL(clicked()), this, SLOT(clearPickPointsTemplate()));
connect(ui.addPointToTemplateButton, SIGNAL(clicked()), this, SLOT(addPointToTemplate()));
}
PickedPointTreeWidgetItem * PickPointsDialog::addPoint(Point3f point){
PickedPointTreeWidgetItem *widgetItem;
if(currentMode == ADD_POINT){
//if we are in template mode
if(templateLoaded){
QTreeWidgetItem *item = ui.pickedPointsTreeWidget->currentItem();
//test to see if there is actually a highlighted item
if(NULL != item){
widgetItem =
dynamic_cast<PickedPointTreeWidgetItem *>(item);
widgetItem->setPoint(point);
item = ui.pickedPointsTreeWidget->itemBelow(widgetItem);
if(NULL != item){
//set the next item to be selected
ui.pickedPointsTreeWidget->setCurrentItem(item);
}
}
} else {
widgetItem =
new PickedPointTreeWidgetItem(point);
pickedPointTreeWidgetItemVector.push_back(widgetItem);
ui.pickedPointsTreeWidget->addTopLevelItem(widgetItem);
//select the newest item
ui.pickedPointsTreeWidget->setCurrentItem(widgetItem);
}
} else if(currentMode == MOVE_POINT)
{
//test to see if there is actually a highlighted item
if(NULL != itemToMove){
itemToMove->setPoint(point);
}
}
return widgetItem;
}
void PickPointsDialog::moveThisPoint(Point3f point){
qDebug() << "point is: " << point[0] << " " << point[1] << " " << point[2];
//the item closest to the given point
PickedPointTreeWidgetItem *closestItem = 0;
//the smallest distance from the given point to one in the list
//so far....
float minDistanceSoFar = -1.0;
for(int i = 0; i < pickedPointTreeWidgetItemVector.size(); i++){
PickedPointTreeWidgetItem *item =
pickedPointTreeWidgetItemVector.at(i);
Point3f tempPoint = item->getPoint();
qDebug() << "tempPoint is: " << tempPoint[0] << " " << tempPoint[1] << " " << tempPoint[2];
float temp = sqrt(pow(point[0]-tempPoint[0],2) +
pow(point[1]-tempPoint[1],2) +
pow(point[2]-tempPoint[2],2));
qDebug() << "distance is: " << temp;
if(minDistanceSoFar < 0 || minDistanceSoFar > temp){
minDistanceSoFar = temp;
closestItem = item;
}
}
//if we found an itme
if(NULL != closestItem){
itemToMove = closestItem;
qDebug() << "Try to move: " << closestItem->getName();
}
}
void PickPointsDialog::addPoint(Point3f point, QString name){
PickedPointTreeWidgetItem *widgetItem = addPoint(point);
widgetItem->setName(name);
}
void PickPointsDialog::clearPoints(){
if(templateLoaded){
//when using templates just clear the points that were picked but not the names
for(int i = 0; i < pickedPointTreeWidgetItemVector.size(); i++){
pickedPointTreeWidgetItemVector.at(i)->clearPoint();
}
//if the size is greater than 0 set the first point to be selected
if(pickedPointTreeWidgetItemVector.size() > 0){
ui.pickedPointsTreeWidget->setCurrentItem(
pickedPointTreeWidgetItemVector.at(0));
}
} else {
clearAllPointsFromTreeWidget();
}
}
void PickPointsDialog::clearAllPointsFromTreeWidget(){
pickedPointTreeWidgetItemVector.clear();
ui.pickedPointsTreeWidget->clear();
PickedPointTreeWidgetItem::pointCounter = 0;
}
std::vector<PickedPointTreeWidgetItem*>& PickPointsDialog::getPickedPointTreeWidgetItemVector(){
return pickedPointTreeWidgetItemVector;
}
PickPointsDialog::Mode PickPointsDialog::getMode(){
return currentMode;
}
void PickPointsDialog::setCurrentMeshModel(MeshModel *newMeshModel){
qDebug() << "about to save any points we had before ";
//save any points we did have
savePointsToMetaData(getPickedPoints());
qDebug() << "done saving points about to clear ";
clearPoints();
meshModel = newMeshModel;
//dont bother with the rest if mesh model is null
if(NULL == meshModel){
return;
}
/*
//Load the points from meta data if they are there
MeshMetaDataInterface *value = meshModel->metaData.value(PickedPoints::getKey());
if(NULL != value){
PickedPoints *pickedPoints = static_cast<PickedPoints *>(value);
if(NULL != pickedPoints){
std::vector<PickedPoint*> * pickedPointVector = pickedPoints->getPickedPointVector();
qDebug() << "Found " << pickedPointVector->size() << " points so load them";
PickedPoint *point;
for(int i = 0; i < pickedPointVector->size(); i++){
point = pickedPointVector->at(i);
qDebug() << "about to add point " << i ;
addPoint(point->point, point->name);
}
qDebug() << "about to draw the ponits ";
//draw any points that may have been loaded
parentPlugin->drawPickedPoints(pickedPointTreeWidgetItemVector);
} else {
qDebug() << "problem with cast!!";
}
}*/
}
MeshModel* PickPointsDialog::getCurrentMeshModel(){
return meshModel;
}
void PickPointsDialog::removeHighlightedPoint(){
//get highlighted point
QTreeWidgetItem *item = ui.pickedPointsTreeWidget->currentItem();
//test to see if there is actually a highlighted item
if(NULL != item){
PickedPointTreeWidgetItem* pickedItem =
dynamic_cast<PickedPointTreeWidgetItem *>(item);
QString name = pickedItem->getName();
//qDebug("Remove \n");
//qDebug() << name;
std::vector<PickedPointTreeWidgetItem*>::iterator iterator;
iterator = std::find(pickedPointTreeWidgetItemVector.begin(),
pickedPointTreeWidgetItemVector.end(),
pickedItem);
//remove item from vector
pickedPointTreeWidgetItemVector.erase(iterator);
//free memory used by widget
delete pickedItem;
//redraw without deleted point
parentPlugin->drawPickedPoints(pickedPointTreeWidgetItemVector);
} else
{
qDebug("no item picked");
}
}
void PickPointsDialog::renameHighlightedPoint(){
//get highlighted point
QTreeWidgetItem *item = ui.pickedPointsTreeWidget->currentItem();
//test to see if there is actually a highlighted item
if(NULL != item){
PickedPointTreeWidgetItem* pickedItem =
dynamic_cast<PickedPointTreeWidgetItem *>(item);
QString name = pickedItem->getName();
//qDebug("Rename \n");
//qDebug() << name;
const QString newName = "newName";
FilterParameterSet parameterSet;
parameterSet.addString(newName, name, "New Name", "Enter the new name");
GenericParamDialog getNameDialog(this,&parameterSet);
//display dialog
int result = getNameDialog.exec();
if(result == QDialog::Accepted){
name = parameterSet.getString(newName);
//qDebug("New name os \n");
//qDebug() << name;
pickedItem->setName(name);
//redraw with new point name
parentPlugin->drawPickedPoints(pickedPointTreeWidgetItemVector);
}
}
}
void PickPointsDialog::togglePickMode(bool checked){
//qDebug() << "Toggle pick mode " << checked;
if(checked){
currentMode = ADD_POINT;
} else {
currentMode = MOVE_POINT;
}
}
PickedPoints * PickPointsDialog::getPickedPoints()
{
PickedPoints *pickedPoints = new PickedPoints();
//add all the points
for(int i = 0; i < pickedPointTreeWidgetItemVector.size(); i++){
PickedPointTreeWidgetItem *item =
pickedPointTreeWidgetItemVector.at(i);
pickedPoints->addPoint(item->getName(), item->getPoint() );
}
return pickedPoints;
}
void PickPointsDialog::savePointsToFile(){
PickedPoints *pickedPoints = getPickedPoints();
//save to a file if so desired and there are some points to save
if(pickedPointTreeWidgetItemVector.size() > 0){
QString suggestion(".");
if(NULL != meshModel){
suggestion = PickedPoints::getSuggestedPickedPointsFileName(*meshModel);
}
QString filename = QFileDialog::getSaveFileName(this,tr("Save File"),suggestion, "*"+PickedPoints::fileExtension);
pickedPoints->save(filename);
}
savePointsToMetaData(pickedPoints);
}
void PickPointsDialog::savePointsToMetaData(PickedPoints *pickedPoints)
{
//save the points to the metadata
if(NULL != meshModel){
//meshModel->metaData.insert(PickedPoints::getKey(), pickedPoints);
//qDebug() << "saved points";
}
}
void PickPointsDialog::loadPoints(){
//clear the points tree
clearAllPointsFromTreeWidget();
QString filename = QFileDialog::getOpenFileName(this,tr("Load File"),".", "*"+PickedPoints::fileExtension);
qDebug() << "load " << filename;
PickedPoints pickedPoints;
pickedPoints.open(filename);
std::vector<PickedPoint*> *points = pickedPoints.getPickedPointVector();
for(int i = 0; i < points->size(); i++){
PickedPoint *pickedPoint = points->at(i);
PickedPointTreeWidgetItem *item =
new PickedPointTreeWidgetItem(pickedPoint->point);
qDebug() << "name of widget " << pickedPoint->name;
item->setName(pickedPoint->name);
pickedPointTreeWidgetItemVector.push_back(item);
ui.pickedPointsTreeWidget->addTopLevelItem(item);
}
//redraw with new point name
parentPlugin->drawPickedPoints(pickedPointTreeWidgetItemVector);
}
void PickPointsDialog::savePointTemplate(){
std::vector<QString> pointNameVector;
//add all the points
for(int i = 0; i < pickedPointTreeWidgetItemVector.size(); i++){
PickedPointTreeWidgetItem *item =
pickedPointTreeWidgetItemVector.at(i);
pointNameVector.push_back(item->getName());
}
//default if for the filename to be that of the default template
QString filename = QDir::homePath() + "/.pickPointsTemplate.xml";
qDebug() << "default " << filename;
if(!ui.defaultTemplateCheckBox->isChecked())
{
filename = QFileDialog::getSaveFileName(this,tr("Save File"),".", "*"+PickPointsTemplate::fileExtension);
}
PickPointsTemplate::save(filename, &pointNameVector);
templateLoaded = true;
}
void PickPointsDialog::loadPickPointsTemplate(){
//clear the points tree
clearAllPointsFromTreeWidget();
QString filename = QFileDialog::getOpenFileName(this,tr("Load File"),".", "*"+PickPointsTemplate::fileExtension);
qDebug() << "load " << filename;
std::vector<QString> pointNameVector;
PickPointsTemplate::load(filename, &pointNameVector);
for(int i = 0; i < pointNameVector.size(); i++){
PickedPointTreeWidgetItem *widgetItem =
new PickedPointTreeWidgetItem(pointNameVector.at(i));
pickedPointTreeWidgetItemVector.push_back(widgetItem);
ui.pickedPointsTreeWidget->addTopLevelItem(widgetItem);
}
//select the first item in the list if it exists
if(pickedPointTreeWidgetItemVector.size() > 0){
ui.pickedPointsTreeWidget->setCurrentItem(pickedPointTreeWidgetItemVector.at(0));
}
templateLoaded = true;
}
void PickPointsDialog::clearPickPointsTemplate(){
templateLoaded = false;
//clear the points?
clearPoints();
}
void PickPointsDialog::addPointToTemplate(){
if(templateLoaded){
PickedPointTreeWidgetItem *widgetItem =
new PickedPointTreeWidgetItem("new point");
pickedPointTreeWidgetItemVector.push_back(widgetItem);
ui.pickedPointsTreeWidget->addTopLevelItem(widgetItem);
//select the newest item
ui.pickedPointsTreeWidget->setCurrentItem(widgetItem);
}
}

View File

@ -0,0 +1,165 @@
/* A class to represent the ui for the pickpoints plugin
*
* @author Oscar Barney
*/
#ifndef PICKPOINTS_DIALOG_H
#define PICKPOINTS_DIALOG_H
#include <QtGui>
#include <meshlab/meshmodel.h>
#include "pickedPoints.h"
#include "ui_pickpointsDialog.h"
#include "pickPointsTemplate.h"
class EditPickPointsPlugin;
class PickedPointTreeWidgetItem : public QTreeWidgetItem
{
public:
//used when a point has just been picked and
//gives it an integer name
PickedPointTreeWidgetItem(vcg::Point3f intputPoint);
//used when a pont has not been picked yet at all
//as when this tree widget item is created by loading
//a template
PickedPointTreeWidgetItem(QString name);
//set the name
void setName(QString name);
//return the name of the point
QString getName();
//change the point
void setPoint(vcg::Point3f intputPoint);
//return the Point3f
vcg::Point3f getPoint();
//clear the ponint datas
void clearPoint();
//return if the point is set
bool isSet();
//basically just so we have a unique default name for new points that are picked
static int pointCounter;
private:
//the point
vcg::Point3f point;
//tells us if the point is set
bool isPointSet;
};
class PickPointsDialog : public QDockWidget
{
Q_OBJECT
public:
PickPointsDialog(EditPickPointsPlugin *plugin,
QWidget *parent = 0);
enum Mode { ADD_POINT, MOVE_POINT };
//add a point that was just picked(could be moving a point)
PickedPointTreeWidgetItem * addPoint(vcg::Point3f point);
//we need to move the point closest to this one
void moveThisPoint(vcg::Point3f point);
//add a new point and call it something
void addPoint(vcg::Point3f point, QString name);
//return the vector
//useful if you want to draw the points
std::vector<PickedPointTreeWidgetItem*>& getPickedPointTreeWidgetItemVector();
//return the mode of this ui
PickPointsDialog::Mode getMode();
//sets the currentMesh we are working with
void setCurrentMeshModel(MeshModel *newMeshModel);
//return the current mesh model
MeshModel* getCurrentMeshModel();
private:
//get the points from the UI
PickedPoints * getPickedPoints();
//allows the ability to save to metaData only even if the ui says save to a file
void savePointsToMetaData(PickedPoints *pickedPoints);
//makes the picked point tree widget empty
void clearAllPointsFromTreeWidget();
//the current mode of the GUI
Mode currentMode;
//QT patern - the ui pointer
Ui::pickpointsDialog ui;
//a map of the tree items to the points they represent
std::vector<PickedPointTreeWidgetItem*> pickedPointTreeWidgetItemVector;
//the parrent plugin
EditPickPointsPlugin *parentPlugin;
//in MOVE_POINT Mode this holds a pointer to the item
//found on mouse button down so that on mouse button
//up it can be moved
PickedPointTreeWidgetItem *itemToMove;
//the template we have loaded
bool templateLoaded;
//we need this in order to save to the meta data and get the filename
MeshModel *meshModel;
private slots:
//remove the point highlighted in the pickedPointTree
void removeHighlightedPoint();
//rename the point highlighted in the pickedPointTree
void renameHighlightedPoint();
//move the point highlighted in the pickedPointTree
void togglePickMode(bool checked);
//save the points to a file
void savePointsToFile();
//load the points from a file
void loadPoints();
//remove all the points and start over when ui button
//is pressed
void clearPoints();
//save the point names currently listed as a template
void savePointTemplate();
//load a point template
void loadPickPointsTemplate();
//clear the loaded template if one is loaded
void clearPickPointsTemplate();
//Add a point to the loaded template. When in template
//mode the default is to now allow extra points
void addPointToTemplate();
};
#endif

View File

@ -0,0 +1,234 @@
<ui version="4.0" >
<class>pickpointsDialog</class>
<widget class="QWidget" name="pickpointsDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>463</width>
<height>525</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<widget class="QFrame" name="frame" >
<property name="geometry" >
<rect>
<x>10</x>
<y>10</y>
<width>441</width>
<height>501</height>
</rect>
</property>
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Raised</enum>
</property>
<widget class="QWidget" name="layoutWidget" >
<property name="geometry" >
<rect>
<x>20</x>
<y>370</y>
<width>411</width>
<height>30</height>
</rect>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QPushButton" name="removeHighlightedButton" >
<property name="text" >
<string>Remove Highlighted</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clearButton" >
<property name="text" >
<string>Clear All Points</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="renamePointButton" >
<property name="text" >
<string>Rename Point</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QTreeWidget" name="pickedPointsTreeWidget" >
<property name="geometry" >
<rect>
<x>10</x>
<y>70</y>
<width>421</width>
<height>291</height>
</rect>
</property>
<property name="columnCount" >
<number>4</number>
</property>
<column>
<property name="text" >
<string>1</string>
</property>
</column>
<column>
<property name="text" >
<string>2</string>
</property>
</column>
<column>
<property name="text" >
<string>3</string>
</property>
</column>
<column>
<property name="text" >
<string>4</string>
</property>
</column>
</widget>
<widget class="QGroupBox" name="groupBox" >
<property name="geometry" >
<rect>
<x>10</x>
<y>10</y>
<width>201</width>
<height>51</height>
</rect>
</property>
<property name="title" >
<string>Mode: </string>
</property>
<widget class="QRadioButton" name="pickPointModeRadioButton" >
<property name="geometry" >
<rect>
<x>10</x>
<y>20</y>
<width>131</width>
<height>23</height>
</rect>
</property>
<property name="text" >
<string>Pick Point</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
<widget class="QRadioButton" name="movePointRadioButton" >
<property name="geometry" >
<rect>
<x>100</x>
<y>20</y>
<width>91</width>
<height>23</height>
</rect>
</property>
<property name="text" >
<string>Move Point</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="layoutWidget" >
<property name="geometry" >
<rect>
<x>240</x>
<y>10</y>
<width>181</width>
<height>51</height>
</rect>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QPushButton" name="saveButton" >
<property name="text" >
<string>Save</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QPushButton" name="loadPointsButton" >
<property name="text" >
<string>Load Points From File</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="groupBox_2" >
<property name="geometry" >
<rect>
<x>10</x>
<y>430</y>
<width>421</width>
<height>61</height>
</rect>
</property>
<property name="title" >
<string>Template Controls</string>
</property>
<widget class="QWidget" name="layoutWidget" >
<property name="geometry" >
<rect>
<x>10</x>
<y>20</y>
<width>404</width>
<height>30</height>
</rect>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QPushButton" name="saveTemplateButton" >
<property name="text" >
<string>Save</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="loadTemplateButton" >
<property name="text" >
<string>Load</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clearTemplateButton" >
<property name="text" >
<string>Clear</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addPointToTemplateButton" >
<property name="text" >
<string>Add Point to Template</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QCheckBox" name="defaultTemplateCheckBox" >
<property name="geometry" >
<rect>
<x>130</x>
<y>410</y>
<width>211</width>
<height>24</height>
</rect>
</property>
<property name="text" >
<string>Save this as your default template</string>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>