Commit 50104514 authored by Isaak Lim's avatar Isaak Lim

added the AlignMeshes plugin, which uses PCA to align target meshes...

added the AlignMeshes plugin, which uses PCA to align target meshes consistently as good as possible

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/MachineLearning/Plugin-AlignMeshes@18251 383ad7c9-94d9-4d36-a494-682f7c89f535
parents
include (plugin)
openflipper_plugin(DIRS Widgets DEPS OpenMesh EIGEN3)
#include "PluginAlignMeshes.hh"
#include <Eigen/Dense>
PluginAlignMeshes::PluginAlignMeshes() :
toolBox_(0) {
}
PluginAlignMeshes::~PluginAlignMeshes() {
}
void PluginAlignMeshes::initializePlugin() {
toolBox_ = new AlignMeshesToolbox();
emit addToolbox("Align Meshes", toolBox_);
connect(toolBox_->alignMeshesButton, SIGNAL(pressed()), SLOT(alignMeshes()));
}
void PluginAlignMeshes::pluginsInitialized() {
}
void PluginAlignMeshes::alignMeshes() {
for (PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS, DATA_TRIANGLE_MESH); o_it
!= PluginFunctions::objectsEnd(); ++o_it) {
TriMeshObject* tri_object = PluginFunctions::triMeshObject(*o_it);
if (tri_object != NULL) {
moveToMean(*tri_object);
rotate(*tri_object);
emit updatedObject(tri_object->id(), UPDATE_ALL);
}
}
}
void PluginAlignMeshes::moveToMean(TriMeshObject& _object) {
TriMesh& mesh = *_object.mesh();
ACG::Vec3d mean(0.0);
for (TriMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) {
mean += mesh.point(*v_it);
}
mean /= (double)mesh.n_vertices();
for (TriMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) {
mesh.set_point(*v_it, mesh.point(*v_it) - mean);
}
}
void PluginAlignMeshes::rotate(TriMeshObject& _object) {
using namespace Eigen;
TriMesh& mesh = *_object.mesh();
Matrix3Xd data = Matrix3Xd::Zero(3, mesh.n_vertices());
size_t i(0);
for (TriMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it, ++i) {
const ACG::Vec3d tmp = mesh.point(*v_it);
data.col(i) = Vector3d(tmp[0], tmp[1], tmp[2]);
}
MatrixXd covar = (data * data.transpose()) / (double)mesh.n_vertices();
JacobiSVD<MatrixXd> svd(covar, ComputeThinU | ComputeThinV);
const MatrixXd& u = svd.matrixU();
Eigen::Vector3d v0 = u.col(0);
Eigen::Vector3d v1 = u.col(1);
Eigen::Vector3d v2 = v0.cross(v1);
v0.normalize();
v1.normalize();
v2.normalize();
Matrix3d trans;
trans.col(0) = v0;
trans.col(1) = v1;
trans.col(2) = v2;
Matrix3d invTrans = trans.inverse();
ACG::Matrix4x4d mat;
mat.identity();
for (i = 0; i < 3; ++i) {
for (size_t j = 0; j < 3; ++j) {
mat(i,j) = invTrans(i,j);
}
}
for (TriMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it, ++i) {
const ACG::Vec4d tmp(mesh.point(*v_it)[0], mesh.point(*v_it)[1], mesh.point(*v_it)[2], 1.0);
const ACG::Vec4d res = mat * tmp;
mesh.set_point(*v_it, ACG::Vec3d(res[0], res[1],res[2]));
}
}
Q_EXPORT_PLUGIN2(pluginalignmeshes, PluginAlignMeshes)
#ifndef PLUGINALIGNMESHES_HH
#define PLUGINALIGNMESHES_HH
#include <QtGui>
#include <OpenFlipper/BasePlugin/BaseInterface.hh>
#include <OpenFlipper/BasePlugin/LoggingInterface.hh>
#include <OpenFlipper/BasePlugin/ToolboxInterface.hh>
#include <OpenFlipper/common/Types.hh>
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
#include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
#include <ObjectTypes/PolyMesh/PolyMesh.hh>
#include "Widgets/AlignMeshesToolbox.hh"
class PluginAlignMeshes :
public QObject,
BaseInterface,
LoggingInterface,
ToolboxInterface {
Q_OBJECT
Q_INTERFACES(BaseInterface)
Q_INTERFACES(ToolboxInterface)
Q_INTERFACES(LoggingInterface)
public:
PluginAlignMeshes();
~PluginAlignMeshes();
// BaseInterface
QString name() { return QString("PluginAlignMeshes"); }
QString description() { return tr("Aligns meshes"); }
signals:
// BaseInterface
void updateView();
void updatedObject(int, const UpdateType);
void nodeVisibilityChanged(int _identifier);
void setSlotDescription(QString _slotName, QString _slotDescription,
QStringList _parameters, QStringList _descriptions);
// LoggingInterface
void log(Logtype _type, QString _message);
void log(QString _message);
// ToolboxInterface
void addToolbox(QString _name, QWidget* _widget);
public slots:
// BaseInterface
QString version() { return QString("1.0"); }
void alignMeshes();
private slots:
// BaseInterface
void initializePlugin();
void pluginsInitialized();
private:
void moveToMean(TriMeshObject& _object);
void rotate(TriMeshObject& _object);
private:
AlignMeshesToolbox* toolBox_;
};
#endif // PLUGINALIGNMESHES_HH
#include "AlignMeshesToolbox.hh"
AlignMeshesToolbox::AlignMeshesToolbox(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
}
#ifndef ALIGN_MESHES_TOOLBOX_HH
#define ALIGN_MESHES_TOOLBOX_HH
#include "ui_AlignMeshesToolbox.hh"
#include <QtGui>
class AlignMeshesToolbox : public QWidget, public Ui::AlignMeshesToolbox
{
Q_OBJECT
public:
AlignMeshesToolbox(QWidget *parent = 0);
};
#endif // ALIGN_MESHES_TOOLBOX_HH
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AlignMeshesToolbox</class>
<widget class="QWidget" name="AlignMeshesToolbox">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>385</width>
<height>118</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QPushButton" name="alignMeshesButton">
<property name="text">
<string>Align Meshes</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment