Commit 5378ee7b authored by Jan Möbius's avatar Jan Möbius

Added Subdirectory

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()));
connect(toolBox_->scaleToUnitCubeUniformButton, SIGNAL(pressed()), SLOT(scaleToUnitCubeUniform()));
connect(toolBox_->scaleToUnitCubeNonUniformButton, SIGNAL(pressed()), SLOT(scaleToUnitCubeNonUniform()));
}
void PluginAlignMeshes::pluginsInitialized() {
}
void PluginAlignMeshes::scaleToUnitCubeNonUniform() {
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)
continue;
moveToMean(*tri_object);
ACG::Vec3d min(DBL_MAX);
ACG::Vec3d max(-DBL_MAX);
TriMesh& mesh = *tri_object->mesh();
for (TriMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) {
min.minimize(mesh.point(*v_it));
max.maximize(mesh.point(*v_it));
}
const ACG::Vec3d diagonal = max - min;
const double maxDiag = std::max(std::max(diagonal[0],diagonal[1]),diagonal[2]);
OpenMesh::MPropHandleT<ACG::Vec3d> origDiagonal;
if (!mesh.get_property_handle(origDiagonal, "origDiagonal"))
mesh.add_property(origDiagonal, "origDiagonal");
mesh.mproperty(origDiagonal).set_persistent(true);
mesh.property(origDiagonal) = diagonal;
for (TriMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) {
mesh.point(*v_it)[0] /= diagonal[0];
mesh.point(*v_it)[1] /= diagonal[1];
mesh.point(*v_it)[2] /= diagonal[2];
}
moveToMean(*tri_object);
emit updatedObject(tri_object->id(), UPDATE_ALL);
}
}
void PluginAlignMeshes::scaleToUnitCubeUniform() {
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)
continue;
moveToMean(*tri_object);
ACG::Vec3d min(DBL_MAX);
ACG::Vec3d max(-DBL_MAX);
TriMesh& mesh = *tri_object->mesh();
for (TriMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) {
min.minimize(mesh.point(*v_it));
max.maximize(mesh.point(*v_it));
}
const ACG::Vec3d diagonal = max - min;
const double maxDiag = std::max(std::max(diagonal[0],diagonal[1]),diagonal[2]);
OpenMesh::MPropHandleT<ACG::Vec3d> origDiagonal;
if (!mesh.get_property_handle(origDiagonal, "origDiagonal"))
mesh.add_property(origDiagonal, "origDiagonal");
mesh.mproperty(origDiagonal).set_persistent(true);
mesh.property(origDiagonal) = diagonal;
for (TriMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) {
mesh.point(*v_it)[0] /= maxDiag;
mesh.point(*v_it)[1] /= maxDiag;
mesh.point(*v_it)[2] /= maxDiag;
}
moveToMean(*tri_object);
emit updatedObject(tri_object->id(), UPDATE_ALL);
}
}
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::moveCenterOfBBToOrigin(TriMeshObject& _object) {
TriMesh& mesh = *_object.mesh();
ACG::Vec3d min(DBL_MAX);
ACG::Vec3d max(-DBL_MAX);
for (TriMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) {
min.minimize(mesh.point(*v_it));
max.maximize(mesh.point(*v_it));
}
const ACG::Vec3d diag = max - min;
const ACG::Vec3d center = min + 0.5*diag;
for (TriMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) {
mesh.point(*v_it) -= center;
}
}
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]);
}
Matrix3d covar = (data * data.transpose()) / (double)mesh.n_vertices();
JacobiSVD<Matrix3d> svd(covar, ComputeThinU | ComputeThinV);
const Matrix3d& 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]));
}
}
#if QT_VERSION < 0x050000
Q_EXPORT_PLUGIN2(pluginalignmeshes, PluginAlignMeshes)
#endif
#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)
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "org.OpenFlipper.Plugins.Plugin-AlignMeshes")
#endif
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();
void scaleToUnitCubeUniform();
void scaleToUnitCubeNonUniform();
private slots:
// BaseInterface
void initializePlugin();
void pluginsInitialized();
private:
void moveCenterOfBBToOrigin(TriMeshObject& _object);
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="1" column="0">
<widget class="QPushButton" name="scaleToUnitCubeUniformButton">
<property name="text">
<string>Scale to Unit Cube Uniformly</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="alignMeshesButton">
<property name="text">
<string>Align Meshes</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="scaleToUnitCubeNonUniformButton">
<property name="text">
<string>Scale to Unit Cube Non-Uniformly</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