diff --git a/src/meshlabplugins/edit_pickpoints/edit_pickpoints.pro b/src/meshlabplugins/edit_pickpoints/edit_pickpoints.pro new file mode 100755 index 000000000..ecd1a5eba --- /dev/null +++ b/src/meshlabplugins/edit_pickpoints/edit_pickpoints.pro @@ -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 diff --git a/src/meshlabplugins/edit_pickpoints/editpickpoints.cpp b/src/meshlabplugins/edit_pickpoints/editpickpoints.cpp new file mode 100644 index 000000000..f63143dea --- /dev/null +++ b/src/meshlabplugins/edit_pickpoints/editpickpoints.cpp @@ -0,0 +1,243 @@ +/* A class implementing Meshlab's Edit interface that is for picking points in 3D + * + * + * @author Oscar Barney + */ + +#include + +#include + +#include "editpickpoints.h" +#include + +#include + +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 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(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(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 &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; iisSet()){ + 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) diff --git a/src/meshlabplugins/edit_pickpoints/editpickpoints.h b/src/meshlabplugins/edit_pickpoints/editpickpoints.h new file mode 100644 index 000000000..754e676b9 --- /dev/null +++ b/src/meshlabplugins/edit_pickpoints/editpickpoints.h @@ -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 +#include +#include + +#include +#include + +#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 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 &pointVector); + +private: + //the list of possible actions + QList 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 diff --git a/src/meshlabplugins/edit_pickpoints/editpickpoints.qrc b/src/meshlabplugins/edit_pickpoints/editpickpoints.qrc new file mode 100644 index 000000000..27c90831d --- /dev/null +++ b/src/meshlabplugins/edit_pickpoints/editpickpoints.qrc @@ -0,0 +1,5 @@ + + + images/pickpoints.png + + \ No newline at end of file diff --git a/src/meshlabplugins/edit_pickpoints/pickPointsTemplate.cpp b/src/meshlabplugins/edit_pickpoints/pickPointsTemplate.cpp new file mode 100644 index 000000000..2cf08015e --- /dev/null +++ b/src/meshlabplugins/edit_pickpoints/pickPointsTemplate.cpp @@ -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 +//xml stuff +#include +#include +#include + + +//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 *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 *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; +} \ No newline at end of file diff --git a/src/meshlabplugins/edit_pickpoints/pickPointsTemplate.h b/src/meshlabplugins/edit_pickpoints/pickPointsTemplate.h new file mode 100644 index 000000000..63da30f59 --- /dev/null +++ b/src/meshlabplugins/edit_pickpoints/pickPointsTemplate.h @@ -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 +#include + +class PickPointsTemplate +{ +public: + + static bool save(QString filename, std::vector *pointNameVector); + + static bool load(QString filename, std::vector *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; + +}; diff --git a/src/meshlabplugins/edit_pickpoints/pickedPoints.cpp b/src/meshlabplugins/edit_pickpoints/pickedPoints.cpp new file mode 100644 index 000000000..1a95d83c8 --- /dev/null +++ b/src/meshlabplugins/edit_pickpoints/pickedPoints.cpp @@ -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 +#include +#include + +//xml stuff +#include +#include +#include + +//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(); +} + +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 * PickedPoints::getPickedPointVector() +{ + return pointVector; +} + +std::vector * PickedPoints::getPoint3fVector() +{ + std::vector *points = new std::vector(); + + 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; +} + diff --git a/src/meshlabplugins/edit_pickpoints/pickedPoints.h b/src/meshlabplugins/edit_pickpoints/pickedPoints.h new file mode 100644 index 000000000..039d31d11 --- /dev/null +++ b/src/meshlabplugins/edit_pickpoints/pickedPoints.h @@ -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 +#include + +#include + +//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 * getPickedPointVector(); + + std::vector * 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 *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 diff --git a/src/meshlabplugins/edit_pickpoints/pickpointsDialog.cpp b/src/meshlabplugins/edit_pickpoints/pickpointsDialog.cpp new file mode 100644 index 000000000..847810d53 --- /dev/null +++ b/src/meshlabplugins/edit_pickpoints/pickpointsDialog.cpp @@ -0,0 +1,547 @@ +/* A class to represent the ui for the pickpoints plugin + * + * @author Oscar Barney + */ + +#include + +#include + +#include "editpickpoints.h" +#include "pickpointsDialog.h" + +#include + +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(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& 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(value); + + if(NULL != pickedPoints){ + + + std::vector * 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(item); + + QString name = pickedItem->getName(); + //qDebug("Remove \n"); + //qDebug() << name; + + std::vector::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(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,¶meterSet); + + //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 *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 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 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); + } +} diff --git a/src/meshlabplugins/edit_pickpoints/pickpointsDialog.h b/src/meshlabplugins/edit_pickpoints/pickpointsDialog.h new file mode 100644 index 000000000..f07a8b002 --- /dev/null +++ b/src/meshlabplugins/edit_pickpoints/pickpointsDialog.h @@ -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 + +#include + +#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& 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 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 diff --git a/src/meshlabplugins/edit_pickpoints/pickpointsDialog.ui b/src/meshlabplugins/edit_pickpoints/pickpointsDialog.ui new file mode 100644 index 000000000..d4fee4ea4 --- /dev/null +++ b/src/meshlabplugins/edit_pickpoints/pickpointsDialog.ui @@ -0,0 +1,234 @@ + + pickpointsDialog + + + + 0 + 0 + 463 + 525 + + + + Form + + + + + 10 + 10 + 441 + 501 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 20 + 370 + 411 + 30 + + + + + + + Remove Highlighted + + + + + + + Clear All Points + + + + + + + Rename Point + + + + + + + + + 10 + 70 + 421 + 291 + + + + 4 + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + + + 10 + 10 + 201 + 51 + + + + Mode: + + + + + 10 + 20 + 131 + 23 + + + + Pick Point + + + true + + + + + + 100 + 20 + 91 + 23 + + + + Move Point + + + + + + + 240 + 10 + 181 + 51 + + + + + + + Save + + + + + + + Load Points From File + + + + + + + + + 10 + 430 + 421 + 61 + + + + Template Controls + + + + + 10 + 20 + 404 + 30 + + + + + + + Save + + + + + + + Load + + + + + + + Clear + + + + + + + Add Point to Template + + + + + + + + + + 130 + 410 + 211 + 24 + + + + Save this as your default template + + + + + + +