mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-19 11:04:39 +00:00
An edit plugin to select parts of a point cloud in a reasonable way.
It is based on a knn-graph, built on the mesh, where we search for near points. It takes two parameters, a maximum distance of hop (between two adjacent points in the graph) and a maximum distance from the selected point. Both of them are chosen via mouse (actually via keyboard).
This commit is contained in:
parent
64e1e7020a
commit
fd90fd27db
202
src/fgt/edit_point/connectedComponent.h
Normal file
202
src/fgt/edit_point/connectedComponent.h
Normal file
@ -0,0 +1,202 @@
|
||||
#ifndef CONNECTEDCOMPONENT_H
|
||||
#define CONNECTEDCOMPONENT_H
|
||||
|
||||
#include "knnGraph.h"
|
||||
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
|
||||
#include <vcg/complex/complex.h>
|
||||
#include <vcg/complex/allocate.h>
|
||||
#include <vcg/complex/algorithms/update/flag.h>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace vcg;
|
||||
|
||||
template <typename _MyMeshType, typename _MyVertexType>
|
||||
class ComponentFinder {
|
||||
public:
|
||||
static std::vector<_MyVertexType*> &FindComponent(_MyMeshType& m, _MyVertexType& v, int numOfNeighbours, int numOfHop);
|
||||
static std::vector<_MyVertexType*> &FindComponent(_MyMeshType& m, _MyVertexType& v, int numOfNeighbours, float dim, float maxHopDist, vector<_MyVertexType*> &borderVect, vector<_MyVertexType*> ¬ReachableVect);
|
||||
|
||||
static void DeletePerVertexAttribute(_MyMeshType& m);
|
||||
|
||||
static void Dijkstra(_MyMeshType& m, _MyVertexType& v, int numOfNeighbours, float maxHopDist, vector<_MyVertexType*> ¬ReachableVect);
|
||||
};
|
||||
|
||||
|
||||
/** This function returns a vector which stores pointers to the vertex of the connected component with
|
||||
* center v and max distance (in number of edges) 'numOfHop' from v.
|
||||
* It uses the knnGraph with k = numOfNeighbours to find the component.
|
||||
* In order to compute the connected component it is used a Depth-Limited search
|
||||
**/
|
||||
template <typename _MyMeshType, typename _MyVertexType>
|
||||
std::vector<_MyVertexType*> &ComponentFinder<_MyMeshType, _MyVertexType>::FindComponent(_MyMeshType& m, _MyVertexType& v, int numOfNeighbours, int numOfHop) {
|
||||
vector<_MyVertexType*> *resultVect = new vector<_MyVertexType*>();
|
||||
stack<_MyVertexType*> DFSStack;
|
||||
stack<int> levelStack;
|
||||
|
||||
tri::UpdateFlags<_MyMeshType>::VertexClearV(m);
|
||||
|
||||
KNNTree<_MyMeshType, _MyVertexType>::MakeKNNTree(m, numOfNeighbours);
|
||||
|
||||
typename _MyMeshType::template PerVertexAttributeHandle<vector<_MyVertexType*>* > neighboursVect = vcg::tri::Allocator<_MyMeshType>::template GetPerVertexAttribute<vector<_MyVertexType*>* >(m,"KNNGraph");
|
||||
typename vector<_MyVertexType*>::iterator it;
|
||||
int actualLevel;
|
||||
|
||||
DFSStack.push(&v);
|
||||
levelStack.push(0);
|
||||
v.SetV();
|
||||
resultVect->push_back(&v);
|
||||
|
||||
|
||||
// The Depth-Limited Search
|
||||
_MyVertexType* element;
|
||||
while (!DFSStack.empty()) {
|
||||
element = DFSStack.top();
|
||||
actualLevel = levelStack.top();
|
||||
DFSStack.pop();
|
||||
levelStack.pop();
|
||||
|
||||
if (actualLevel < numOfHop) {
|
||||
for (it = neighboursVect[element]->begin(); it != neighboursVect[element]->end(); it++) {
|
||||
if (!((*it)->IsV())) {
|
||||
DFSStack.push(*it);
|
||||
levelStack.push(actualLevel + 1);
|
||||
(*it)->SetV();
|
||||
resultVect->push_back(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KNNTree<_MyMeshType, _MyVertexType>::DeleteKNNTree(m);
|
||||
|
||||
return *resultVect;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename _MyMeshType, typename _MyVertexType>
|
||||
class Compare {
|
||||
private:
|
||||
typename _MyMeshType::template PerVertexAttributeHandle<float> *distFromCenter;
|
||||
|
||||
public:
|
||||
Compare(typename _MyMeshType::template PerVertexAttributeHandle<float> *distFromCenter) {
|
||||
this->distFromCenter = distFromCenter;
|
||||
}
|
||||
|
||||
bool operator() (const _MyVertexType* lhs, const _MyVertexType* rhs) const {
|
||||
return (*distFromCenter)[*lhs] > (*distFromCenter)[*rhs];
|
||||
}
|
||||
};
|
||||
|
||||
/** This function returns a vector which stores pointers to the vertex of the connected component with
|
||||
* center v and max distance 'dim' from v.
|
||||
* It uses the knnGraph with k = numOfNeighbours to find the component.
|
||||
* In order to compute the connected component it is used a Shortest Path algorithm where maxHopDist is the
|
||||
* maximum distance we want between two vertex (with the Shortest Path we also compute the geodesic distance)
|
||||
**/
|
||||
template <typename _MyMeshType, typename _MyVertexType>
|
||||
std::vector<_MyVertexType*> &ComponentFinder<_MyMeshType, _MyVertexType>::FindComponent(_MyMeshType& m, _MyVertexType& v, int numOfNeighbours, float dim, float maxHopDist, vector<_MyVertexType*> &borderVect, vector<_MyVertexType*> ¬ReachableVect) {
|
||||
vector<_MyVertexType*> *resultVect = new vector<_MyVertexType*>();
|
||||
|
||||
tri::UpdateFlags<_MyMeshType>::VertexClearV(m);
|
||||
|
||||
bool hasDistParam = vcg::tri::HasPerVertexAttribute(m, "DistParam");
|
||||
|
||||
typename _MyMeshType::template PerVertexAttributeHandle<float> distFromCenter;
|
||||
|
||||
if (hasDistParam) distFromCenter = vcg::tri::Allocator<_MyMeshType>::template GetPerVertexAttribute<float>(m, std::string("DistParam"));
|
||||
else return *resultVect;
|
||||
|
||||
for (typename _MyMeshType::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); vi++) {
|
||||
if (distFromCenter[vi] < dim) resultVect->push_back(&*vi);
|
||||
}
|
||||
|
||||
typename vector<_MyVertexType*>::iterator it;
|
||||
for (it = notReachableVect.begin(); it != notReachableVect.end(); it++) {
|
||||
if (distFromCenter[*it] < dim) borderVect.push_back(*it);
|
||||
}
|
||||
|
||||
return *resultVect;
|
||||
}
|
||||
|
||||
|
||||
template <typename _MyMeshType, typename _MyVertexType>
|
||||
void ComponentFinder<_MyMeshType, _MyVertexType>::Dijkstra(_MyMeshType& m, _MyVertexType& v, int numOfNeighbours, float maxHopDist, vector<_MyVertexType*> ¬ReachableVect) {
|
||||
bool hasKNNGraph = vcg::tri::HasPerVertexAttribute(m, "KNNGraph");
|
||||
bool hasDistParam = vcg::tri::HasPerVertexAttribute(m, "DistParam");
|
||||
|
||||
notReachableVect.clear();
|
||||
|
||||
typename _MyMeshType::template PerVertexAttributeHandle<float> distFromCenter;
|
||||
if (!hasDistParam) {
|
||||
distFromCenter = vcg::tri::Allocator<_MyMeshType>::template AddPerVertexAttribute<float>(m, std::string("DistParam"));
|
||||
}
|
||||
else distFromCenter = vcg::tri::Allocator<_MyMeshType>::template GetPerVertexAttribute<float>(m, std::string("DistParam"));
|
||||
|
||||
if (!hasKNNGraph) {
|
||||
KNNTree<_MyMeshType, _MyVertexType>::MakeKNNTree(m, numOfNeighbours);
|
||||
}
|
||||
|
||||
typename _MyMeshType::template PerVertexAttributeHandle<vector<_MyVertexType*>* > neighboursVect = vcg::tri::Allocator<_MyMeshType>::template GetPerVertexAttribute<vector<_MyVertexType*>* >(m,"KNNGraph");
|
||||
|
||||
|
||||
typename vector<_MyVertexType*>::iterator it;
|
||||
|
||||
typedef priority_queue<_MyVertexType*, vector<_MyVertexType*>, Compare<_MyMeshType, _MyVertexType> > VertPriorityQueue;
|
||||
Compare<_MyMeshType, _MyVertexType> Comparator(&distFromCenter);
|
||||
VertPriorityQueue prQueue (Comparator);
|
||||
|
||||
for (typename _MyMeshType::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); vi++)
|
||||
distFromCenter[vi] = numeric_limits<float>::max();
|
||||
|
||||
distFromCenter[v] = 0.f;
|
||||
|
||||
tri::UpdateFlags<_MyMeshType>::VertexClearV(m);
|
||||
|
||||
prQueue.push(&v);
|
||||
v.SetV();
|
||||
|
||||
float distance;
|
||||
_MyVertexType* element;
|
||||
|
||||
|
||||
while (!prQueue.empty()) {
|
||||
element = prQueue.top();
|
||||
prQueue.pop();
|
||||
|
||||
for (it = neighboursVect[element]->begin(); it != neighboursVect[element]->end(); it++) {
|
||||
distance = vcg::Distance((*it)->P(), element->P());
|
||||
|
||||
if (distFromCenter[*element] + distance < distFromCenter[*it]) distFromCenter[*it] = distFromCenter[*element] + distance;
|
||||
if (!((*it)->IsV()) && distance <= maxHopDist) {
|
||||
prQueue.push(*it);
|
||||
(*it)->SetV();
|
||||
}
|
||||
else if (distance > maxHopDist) notReachableVect.push_back(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename _MyMeshType, typename _MyVertexType>
|
||||
void ComponentFinder<_MyMeshType, _MyVertexType>::DeletePerVertexAttribute(_MyMeshType& m) {
|
||||
KNNTree<_MyMeshType, _MyVertexType>::DeleteKNNTree(m);
|
||||
|
||||
bool hasDistParam = vcg::tri::HasPerVertexAttribute(m, "DistParam");
|
||||
if (hasDistParam) {
|
||||
vcg::tri::Allocator<_MyMeshType>::DeletePerVertexAttribute(m, "DistParam");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // CONNECTEDCOMPONENT_H
|
||||
179
src/fgt/edit_point/edit_point.cpp
Normal file
179
src/fgt/edit_point/edit_point.cpp
Normal file
@ -0,0 +1,179 @@
|
||||
/****************************************************************************
|
||||
* 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. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtGui>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <meshlab/glarea.h>
|
||||
#include "edit_point.h"
|
||||
#include <wrap/gl/pick.h>
|
||||
#include <wrap/qt/gl_label.h>
|
||||
|
||||
#include "connectedComponent.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace vcg;
|
||||
|
||||
EditPointPlugin::EditPointPlugin() {}
|
||||
|
||||
const QString EditPointPlugin::Info() {
|
||||
return tr("Select a region of the mesh");
|
||||
}
|
||||
|
||||
void EditPointPlugin::Decorate(MeshModel &m, GLArea * gla, QPainter *p)
|
||||
{
|
||||
if(haveToPick)
|
||||
{
|
||||
glPushMatrix();
|
||||
glMultMatrix(m.cm.Tr);
|
||||
vector<CMeshO::VertexPointer> NewSel;
|
||||
GLPickTri<CMeshO>::PickVert(cur.x(), gla->height() - cur.y(), m.cm, NewSel);
|
||||
if(NewSel.size() > 0) {
|
||||
startingVertex = NewSel.front();
|
||||
|
||||
ComponentFinder<CMeshO, CVertexO>::Dijkstra(m.cm, *startingVertex, 6, this->maxHop, this->NotReachableVector);
|
||||
ComponentVector.push_back(startingVertex);
|
||||
}
|
||||
|
||||
haveToPick = false;
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
if (startingVertex != NULL) {
|
||||
glPushMatrix();
|
||||
glMultMatrix(m.cm.Tr);
|
||||
|
||||
glPushAttrib(GL_ENABLE_BIT );
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthRange (0.0, 0.9999);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glPointSize(6.f);
|
||||
|
||||
glBegin(GL_POINTS);
|
||||
glColor4f(1,0,0,.6f);
|
||||
|
||||
for(vector<CMeshO::VertexPointer>::iterator vi = ComponentVector.begin(); vi != ComponentVector.end(); ++vi)
|
||||
{
|
||||
glVertex((*vi)->cP());
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_POINTS);
|
||||
glColor4f(1,1,0,.6f);
|
||||
|
||||
for(vector<CMeshO::VertexPointer>::iterator vi = BorderVector.begin(); vi != BorderVector.end(); ++vi)
|
||||
{
|
||||
glVertex((*vi)->cP());
|
||||
}
|
||||
|
||||
glEnd();
|
||||
glPopAttrib();
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
bool EditPointPlugin::StartEdit(MeshModel &m, GLArea *gla ) {
|
||||
BorderVector = std::vector<CVertexO*>();
|
||||
NotReachableVector = std::vector<CVertexO*>();
|
||||
this->maxHop = m.cm.bbox.Diag() / 100.0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditPointPlugin::EndEdit(MeshModel &m, GLArea *gla) {
|
||||
ComponentFinder<CMeshO, CVertexO>::DeletePerVertexAttribute(m.cm);
|
||||
}
|
||||
|
||||
|
||||
void EditPointPlugin::mousePressEvent(QMouseEvent *ev, MeshModel &m, GLArea *gla ) {
|
||||
startingVertex = NULL;
|
||||
|
||||
cur = ev->pos();
|
||||
haveToPick = true;
|
||||
|
||||
this->isMousePressed = true;
|
||||
this->dist = 0.0;
|
||||
this->startingClick = vcg::Point2f(ev->x(), ev->y());
|
||||
|
||||
BorderVector.clear();
|
||||
ComponentVector.clear();
|
||||
}
|
||||
|
||||
void EditPointPlugin::mouseMoveEvent(QMouseEvent *ev, MeshModel &m, GLArea *gla ) {
|
||||
if (this->isMousePressed && startingVertex != NULL) {
|
||||
float distFromCenter = math::Sqrt((startingClick.X() - ev->x())*(startingClick.X() - ev->x()) + (startingClick.Y() - ev->y()) * (startingClick.Y() - ev->y()));
|
||||
|
||||
float perim = 2 * m.cm.bbox.DimX() + 2 * m.cm.bbox.DimY();
|
||||
perim = (perim < 2 * m.cm.bbox.DimY() + 2 * m.cm.bbox.DimZ()) ? 2 * m.cm.bbox.DimY() + 2 * m.cm.bbox.DimZ() : perim;
|
||||
perim = (perim < 2 * m.cm.bbox.DimX() + 2 * m.cm.bbox.DimZ()) ? 2 * m.cm.bbox.DimX() + 2 * m.cm.bbox.DimZ() : perim;
|
||||
|
||||
this->dist = (perim * distFromCenter) / gla->width();
|
||||
|
||||
BorderVector.clear();
|
||||
ComponentVector = ComponentFinder<CMeshO, CVertexO>::FindComponent(m.cm, *startingVertex, 6, this->dist, this->maxHop, BorderVector, NotReachableVector);
|
||||
}
|
||||
}
|
||||
|
||||
void EditPointPlugin::mouseReleaseEvent(QMouseEvent *ev, MeshModel &m, GLArea *gla) {
|
||||
gla->update();
|
||||
}
|
||||
|
||||
void EditPointPlugin::keyPressEvent(QKeyEvent *ev, MeshModel &m, GLArea *gla) {
|
||||
bool hopDistModified = false;
|
||||
int keyPressed = ev->key();
|
||||
|
||||
if (startingVertex != NULL) {
|
||||
switch (keyPressed) {
|
||||
case Qt::Key_A:
|
||||
this->maxHop *= 1.2;
|
||||
|
||||
hopDistModified = true;
|
||||
|
||||
break;
|
||||
|
||||
case Qt::Key_Z:
|
||||
this->maxHop /= 1.2;
|
||||
|
||||
hopDistModified = true;
|
||||
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hopDistModified) {
|
||||
ComponentFinder<CMeshO, CVertexO>::Dijkstra(m.cm, *startingVertex, 6, this->maxHop, this->NotReachableVector);
|
||||
|
||||
BorderVector.clear();
|
||||
ComponentVector = ComponentFinder<CMeshO, CVertexO>::FindComponent(m.cm, *startingVertex, 6, this->dist, this->maxHop, BorderVector, NotReachableVector);
|
||||
}
|
||||
|
||||
gla->update();
|
||||
return;
|
||||
}
|
||||
67
src/fgt/edit_point/edit_point.h
Normal file
67
src/fgt/edit_point/edit_point.h
Normal file
@ -0,0 +1,67 @@
|
||||
/****************************************************************************
|
||||
* 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. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef EDITPOINTPLUGIN_H
|
||||
#define EDITPOINTPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#include <common/interfaces.h>
|
||||
|
||||
class EditPointPlugin : public QObject, public MeshEditInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(MeshEditInterface)
|
||||
|
||||
public:
|
||||
EditPointPlugin();
|
||||
virtual ~EditPointPlugin() {}
|
||||
|
||||
static const QString Info();
|
||||
|
||||
bool StartEdit(MeshModel &/*m*/, GLArea * /*parent*/);
|
||||
void EndEdit(MeshModel &/*m*/, GLArea * /*parent*/);
|
||||
void Decorate(MeshModel &/*m*/, GLArea * /*parent*/, QPainter *p);
|
||||
void mousePressEvent(QMouseEvent *, MeshModel &, GLArea * );
|
||||
void mouseMoveEvent(QMouseEvent *, MeshModel &, GLArea * );
|
||||
void mouseReleaseEvent(QMouseEvent *, MeshModel &/*m*/, GLArea * );
|
||||
void keyPressEvent(QKeyEvent *, MeshModel &/*m*/, GLArea *);
|
||||
|
||||
|
||||
private:
|
||||
bool isMousePressed;
|
||||
bool haveToPick;
|
||||
|
||||
CMeshO::VertexPointer startingVertex;
|
||||
vcg::Point2f startingClick;
|
||||
|
||||
float dist;
|
||||
float maxHop;
|
||||
|
||||
std::vector<CMeshO::VertexPointer> ComponentVector;
|
||||
std::vector<CMeshO::VertexPointer> BorderVector;
|
||||
std::vector<CMeshO::VertexPointer> NotReachableVector;
|
||||
|
||||
QPoint cur;
|
||||
};
|
||||
|
||||
#endif
|
||||
23
src/fgt/edit_point/edit_point.pro
Normal file
23
src/fgt/edit_point/edit_point.pro
Normal file
@ -0,0 +1,23 @@
|
||||
include (../../shared.pri)
|
||||
|
||||
|
||||
HEADERS = \
|
||||
edit_point.h \
|
||||
edit_point_factory.h \
|
||||
connectedComponent.h \
|
||||
knnGraph.h
|
||||
|
||||
SOURCES = \
|
||||
edit_point.cpp \
|
||||
edit_point_factory.cpp \
|
||||
|
||||
|
||||
TARGET = edit_point
|
||||
|
||||
QT += opengl
|
||||
|
||||
#RESOURCES = sampleedit.qrc
|
||||
|
||||
|
||||
|
||||
|
||||
57
src/fgt/edit_point/edit_point_factory.cpp
Normal file
57
src/fgt/edit_point/edit_point_factory.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
* MeshLab o o *
|
||||
* A versatile mesh processing toolbox o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2005-2008 \/)\/ *
|
||||
* 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. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "edit_point_factory.h"
|
||||
#include "edit_point.h"
|
||||
|
||||
PointEditFactory::PointEditFactory()
|
||||
{
|
||||
editPoint = new QAction(QIcon(":/images/icon_info.png"),"Point", this);
|
||||
|
||||
actionList << editPoint;
|
||||
|
||||
foreach(QAction *editAction, actionList)
|
||||
editAction->setCheckable(true);
|
||||
}
|
||||
|
||||
//gets a list of actions available from this plugin
|
||||
QList<QAction *> PointEditFactory::actions() const
|
||||
{
|
||||
return actionList;
|
||||
}
|
||||
|
||||
//get the edit tool for the given action
|
||||
MeshEditInterface* PointEditFactory::getMeshEditInterface(QAction *action)
|
||||
{
|
||||
if(action == editPoint)
|
||||
{
|
||||
return new EditPointPlugin();
|
||||
} else assert(0); //should never be asked for an action that isn't here
|
||||
}
|
||||
|
||||
QString PointEditFactory::getEditToolDescription(QAction *)
|
||||
{
|
||||
return EditPointPlugin::Info();
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN(PointEditFactory)
|
||||
55
src/fgt/edit_point/edit_point_factory.h
Normal file
55
src/fgt/edit_point/edit_point_factory.h
Normal file
@ -0,0 +1,55 @@
|
||||
/****************************************************************************
|
||||
* MeshLab o o *
|
||||
* A versatile mesh processing toolbox o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2005-2008 \/)\/ *
|
||||
* 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. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef EditPointFactoryPLUGIN_H
|
||||
#define EditPointFactoryPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#include <common/interfaces.h>
|
||||
|
||||
class PointEditFactory : public QObject, public MeshEditInterfaceFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(MeshEditInterfaceFactory)
|
||||
|
||||
public:
|
||||
PointEditFactory();
|
||||
virtual ~PointEditFactory() { delete editPoint; }
|
||||
|
||||
//gets a list of actions available from this plugin
|
||||
virtual QList<QAction *> actions() const;
|
||||
|
||||
//get the edit tool for the given action
|
||||
virtual MeshEditInterface* getMeshEditInterface(QAction *);
|
||||
|
||||
//get the description for the given action
|
||||
virtual QString getEditToolDescription(QAction *);
|
||||
|
||||
private:
|
||||
QList <QAction *> actionList;
|
||||
|
||||
QAction *editPoint;
|
||||
};
|
||||
|
||||
#endif
|
||||
88
src/fgt/edit_point/knnGraph.h
Normal file
88
src/fgt/edit_point/knnGraph.h
Normal file
@ -0,0 +1,88 @@
|
||||
#ifndef KNNGRAPH_H
|
||||
#define KNNGRAPH_H
|
||||
|
||||
#include <Vector>
|
||||
|
||||
#include <vcg/complex/complex.h>
|
||||
#include <vcg/complex/allocate.h>
|
||||
|
||||
#include <vcg/space/index/kdtree/kdtree.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace vcg;
|
||||
|
||||
template <typename _MyMeshType, typename _MyVertexType>
|
||||
class KNNTree {
|
||||
public:
|
||||
static void MakeKNNTree(_MyMeshType& m, int numOfNeighbours);
|
||||
static void DeleteKNNTree(_MyMeshType& m);
|
||||
};
|
||||
|
||||
/**
|
||||
* Static function to create and fill the PerVertexAttribute KNNGraph, which stores the k-nearest
|
||||
* neighbours via vertex pointers
|
||||
*/
|
||||
template <typename _MyMeshType, typename _MyVertexType>
|
||||
void KNNTree<_MyMeshType, _MyVertexType>::MakeKNNTree(_MyMeshType& m, int numOfNeighbours) {
|
||||
//we search k+1 neighbours in order to exclude the queryPoint from the returned heap
|
||||
int neighboursVectSize = numOfNeighbours + 1;
|
||||
|
||||
int neighbours; //number of neighbours found (no more than neighboursVectSize)
|
||||
|
||||
//we have to use the indices of the vertices, and they MUST be continuous
|
||||
tri::Allocator<_MyMeshType>::CompactVertexVector(m);
|
||||
|
||||
//the PerVertexAttribute handles is create and each of the vector capacity set to the maximum possible
|
||||
typename _MyMeshType::template PerVertexAttributeHandle<vector<_MyVertexType*>* > kNeighboursVect;
|
||||
kNeighboursVect = vcg::tri::Allocator<_MyMeshType>::template AddPerVertexAttribute<vector<_MyVertexType*>* >(m, std::string("KNNGraph"));
|
||||
for (typename _MyMeshType::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); vi++) {
|
||||
kNeighboursVect[vi] = new vector<_MyVertexType*>();
|
||||
kNeighboursVect[vi]->reserve(neighboursVectSize);
|
||||
}
|
||||
|
||||
//we create and fill the DataWrapper we need to pass the points to the KdTree
|
||||
vector<typename _MyMeshType::CoordType> input(m.vn);
|
||||
int i = 0;
|
||||
for (typename _MyMeshType::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); vi++, ++i) {
|
||||
input[i] = vi->cP();
|
||||
}
|
||||
ConstDataWrapper<typename _MyMeshType::CoordType> DW(&(input[0]), input.size());
|
||||
|
||||
KdTree<float> tree(DW);
|
||||
|
||||
tree.setMaxNofNeighbors(neighboursVectSize);
|
||||
|
||||
//For each vertex we insert the k-nearest neighbours in the associated vector.
|
||||
//If the number of the found vertices is less than the required we exclude the point with
|
||||
//the highest value (inserted by the doQueryK function of the vcg library). Moreover
|
||||
//we have to exclude the queryPoint!
|
||||
int neightId = -1;
|
||||
for (int j = 0; j < m.vn; j++) {
|
||||
tree.doQueryK(m.vert[j].cP());
|
||||
|
||||
neighbours = tree.getNofFoundNeighbors();
|
||||
for (int i = 0; i < neighbours; i++) {
|
||||
neightId = tree.getNeighborId(i);
|
||||
if (neightId < m.vn && (neightId != j))
|
||||
kNeighboursVect[m.vert[j]]->push_back(&(m.vert[neightId]));
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static function which removes the KNNGraph PerVertex attribute
|
||||
*/
|
||||
template <typename _MyMeshType, typename _MyVertexType>
|
||||
void KNNTree<_MyMeshType, _MyVertexType>::DeleteKNNTree(_MyMeshType& m) {
|
||||
bool hasKNNGraph = tri::HasPerVertexAttribute(m, "KNNGraph");
|
||||
|
||||
if (hasKNNGraph) {
|
||||
vcg::tri::Allocator<_MyMeshType>::DeletePerVertexAttribute(m, "KNNGraph");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif // KNNGRAPH_H
|
||||
Loading…
x
Reference in New Issue
Block a user