11 #include "AlignPlugin.hh"
17 , alignMeshesButton_()
23 void AlignPlugin::slotAlignMeshes()
25 using namespace Eigen;
29 emit log(
LOGERR, tr(
"Cannot get source mesh object %1").arg(sourceId_));
35 emit log(
LOGERR, tr(
"Cannot get target mesh object %1").arg(targetId_));
41 if (!computePCA(getPoints(sourceObject), sc, spd)) {
42 emit log(
LOGERR,
"PCA of source object failed");
48 Point_container targetPoints = getPoints(targetObject);
49 if (!computePCA(targetPoints, tc, tpd)) {
50 emit log(
LOGERR,
"PCA of target object failed");
54 Affine3d t = spd.transpose() * Translation3d(-sc);
55 transformObject(sourceObject, t);
57 t = tpd.transpose() * Translation3d(-tc);
58 transformPoints(targetPoints, t);
61 if (doScaleCheckBox_->isChecked()) {
62 BBox sbbox = computeBoundingBox(getPoints(sourceObject));
63 BBox tbbox = computeBoundingBox(targetPoints);
64 t = t * Scaling((tbbox.second - tbbox.first).cwiseQuotient(sbbox.second - sbbox.first));
66 transformObject(sourceObject, t);
72 AlignPlugin::Point_container AlignPlugin::getPoints(
BaseObjectData *
object)
74 using namespace Eigen;
76 Point_container points;
81 if (mesh->is_boundary(*it)) {
82 Vector3d p = Map<const Vector3d>(mesh->
vertex(*it).data());
89 if (mesh->is_boundary(*it)) {
90 Vector3d p = Map<const Vector3d>(mesh->
vertex(*it).data());
96 points.reserve(mesh->n_vertices());
97 for (TriMesh::VertexIter it = mesh->vertices_begin(); it != mesh->vertices_end(); ++it) {
98 Vector3d p = Map<const Vector3d>(mesh->point(*it).data());
106 void AlignPlugin::transformObject(
BaseObjectData *
object, Eigen::Affine3d
const& t)
108 using namespace Eigen;
114 Vector3d ep(p[0], p[1], p[2]);
115 Vector3d tep = t * ep;
122 Vector3d ep(p[0], p[1], p[2]);
123 Vector3d tep = t * ep;
128 for (TriMesh::VertexIter it = mesh->vertices_begin(); it != mesh->vertices_end(); ++it) {
130 Vector3d ep(p[0], p[1], p[2]);
131 Vector3d tep = t * ep;
132 mesh->set_point(*it,
ACG::Vec3d(tep[0], tep[1], tep[2]));
134 mesh->update_normals();
138 void AlignPlugin::transformPoints(Point_container& points, Eigen::Affine3d
const& t)
140 for (
unsigned int i = 0; i < points.size(); ++i) {
141 points[i] = t * points[i];
145 AlignPlugin::BBox AlignPlugin::computeBoundingBox(Point_container
const& points)
147 using namespace Eigen;
149 double inf = std::numeric_limits<double>::infinity();
150 Vector3d minp = Vector3d::Constant(inf);
151 Vector3d maxp = Vector3d::Constant(-inf);
152 for (
unsigned int i = 0; i < points.size(); ++i) {
153 minp = minp.cwiseMin(points[i]);
154 maxp = maxp.cwiseMax(points[i]);
157 return BBox(minp, maxp);
160 Eigen::Vector3d AlignPlugin::computeCentroid(Point_container
const& points)
162 using namespace Eigen;
164 Vector3d centroid = Vector3d::Zero();
165 for (
unsigned int i = 0; i < points.size(); ++i) {
166 centroid += points[i];
168 if (points.size() > 0) {
169 centroid /= points.size();
174 bool AlignPlugin::computePCA(Point_container
const& points, Eigen::Vector3d& centroid, Eigen::Matrix3d& principal_directions)
176 using namespace Eigen;
178 centroid = computeCentroid(points);
180 Matrix3d cov = Matrix3d::Zero();
181 for (
unsigned int i = 0; i < points.size(); ++i) {
182 cov.noalias() += (points[i] - centroid) * (points[i] - centroid).transpose();
184 cov /= points.size() - 1;
186 SelfAdjointEigenSolver<Matrix3d> eigensolver(cov);
187 principal_directions = eigensolver.eigenvectors();
189 return eigensolver.info() == Success;
192 #if QT_VERSION < 0x050000
PolyhedralMesh * polyhedralMesh(BaseObjectData *_object)
Get an PolyhedralMesh from an object.
bool dataType(DataType _type) const
#define DATA_POLYHEDRAL_MESH
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
bool getObject(int _identifier, BSplineCurveObject *&_object)
HexahedralMesh * hexahedralMesh(BaseObjectData *_object)
Get an HexahedralMesh from an object.
const VecT & vertex(const VertexHandle &_vh) const
Get point _vh's coordinates.
void set_vertex(const VertexHandle &_vh, const VecT &_p)
Set the coordinates of point _vh.
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
#define DATA_HEXAHEDRAL_MESH