Skip to content

Commit 4a63768

Browse files
committed
Completes transition to mesh agnostic implementation
1 parent ea001c0 commit 4a63768

File tree

12 files changed

+208
-632
lines changed

12 files changed

+208
-632
lines changed

CMakeLists.txt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,14 @@ include_directories("inc" ${OPENMESH_INCLUDE_DIR} ${EIGEN_INCLUDE_DIR})
2020
list(APPEND DEFORM_LINK_TARGETS ${OPENMESH_LIBRARIES})
2121

2222
add_library(deform
23-
inc/deform/mesh.h
24-
inc/deform/cotan_matrix.h
2523
inc/deform/arap.h
26-
src/arap.cpp
27-
src/cotan_matrix.cpp
24+
inc/deform/openmesh_adapter.h
2825
)
26+
set_target_properties(deform PROPERTIES LINKER_LANGUAGE CXX)
2927

3028
add_executable(deform_tests
3129
tests/catch.hpp
30+
tests/accessor.h
3231
tests/test_cotan.cpp
3332
)
3433
target_link_libraries(deform_tests deform ${DEFORM_LINK_TARGETS})

examples/deform_sphere.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111

1212
#include <deform/arap.h>
13+
#include <deform/openmesh_adapter.h>
1314
#include <string>
1415
#include <iostream>
1516

@@ -20,37 +21,38 @@ int main(int argc, char **argv) {
2021

2122
std::string pathToSource = std::string(DEFORM_ETC_DIR) + std::string("/sphere.obj");
2223

23-
deform::Mesh mesh;
24+
typedef OpenMesh::TriMesh_ArrayKernelT<> Mesh;
25+
26+
Mesh mesh;
2427
if (!OpenMesh::IO::read_mesh(mesh, pathToSource)) {
2528
std::cerr << "Failed to read mesh" << std::endl;
2629
return -1;
2730
}
2831

2932

30-
deform::Mesh::Point p = mesh.point(mesh.vertex_handle(32));
33+
Mesh::Point p = mesh.point(mesh.vertex_handle(32));
3134
double pi = -M_PI_2;
3235
double add = 0.01;
33-
deform::example::OSGViewer viewer(argc, argv, &mesh, [&p, &pi, &add](deform::Mesh *mesh, double time) {
36+
37+
deform::OpenMeshAdapter<> ma(mesh);
38+
deform::AsRigidAsPossibleDeformation< deform::OpenMeshAdapter<> > arap(ma);
39+
40+
// Set anchors
41+
Mesh::VertexHandle va = mesh.vertex_handle(37);
42+
arap.setConstraint(va.idx(), deform::convert::toEigen(mesh.point(va)));
43+
44+
deform::example::OSGViewer viewer(argc, argv, mesh, [&p, &pi, &add, &arap](Mesh &mesh, double time) {
3445

3546
pi += add;
3647
if (std::abs(pi) > M_PI_2) {
3748
add *= -1.0;
3849
pi += add;
3950
}
4051

41-
deform::OpenMeshAdapter ma(*mesh);
42-
deform::AsRigidAsPossibleDeformation2<deform::OpenMeshAdapter> arap(ma);
43-
44-
// Set anchors
45-
deform::Mesh::VertexHandle va = mesh->vertex_handle(37);
46-
arap.setConstraint(va.idx(), deform::toEigenF(mesh->point(va)));
47-
48-
deform::Mesh::VertexHandle vh = mesh->vertex_handle(32);
49-
arap.setConstraint(vh.idx(), deform::toEigenF(p + deform::Mesh::Point(0, 0, (float)(std::sin(pi)))));
52+
Mesh::VertexHandle vh = mesh.vertex_handle(32);
53+
arap.setConstraint(vh.idx(), deform::convert::toEigen(p + Mesh::Point(0, 0, (float)(std::sin(pi)))));
5054
arap.deform(3);
5155

52-
ma.vertices(arap.updatedPositions());
53-
5456
return true;
5557
});
5658
viewer.run();

examples/osg_viewer.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace deform {
2323
namespace example {
2424

2525
struct OSGViewer::data {
26-
deform::Mesh *mesh;
26+
OSGViewer::Mesh *mesh;
2727
DeformCallback dc;
2828
osg::ref_ptr<osgViewer::Viewer> viewer;
2929
osg::ref_ptr<osg::Group> root;
@@ -33,13 +33,13 @@ namespace deform {
3333
{
3434
public:
3535

36-
OSGUpdateCallback(deform::Mesh *mesh, OSGViewer::DeformCallback *dc)
36+
OSGUpdateCallback(OSGViewer::Mesh *mesh, OSGViewer::DeformCallback *dc)
3737
:_mesh(mesh), _dc(dc)
3838
{}
3939

4040
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
4141
{
42-
if ((*_dc)(_mesh, nv->getFrameStamp()->getReferenceTime())) {
42+
if ((*_dc)(*_mesh, nv->getFrameStamp()->getReferenceTime())) {
4343
_mesh->update_normals();
4444

4545
// Update vertex and normal buffer
@@ -50,10 +50,10 @@ namespace deform {
5050
osg::Vec3Array *normals = static_cast<osg::Vec3Array*>(geo->getNormalArray());
5151

5252
for (auto v = _mesh->vertices_begin(); v != _mesh->vertices_end(); ++v) {
53-
deform::Mesh::Point p = _mesh->point(*v);
53+
OSGViewer::Mesh::Point p = _mesh->point(*v);
5454
vertices->at(v->idx()) = osg::Vec3(p[0], p[1], p[2]);
5555

56-
deform::Mesh::Point n = _mesh->normal(*v);
56+
OSGViewer::Mesh::Point n = _mesh->normal(*v);
5757
normals->at(v->idx()) = osg::Vec3(n[0], n[1], n[2]);
5858
}
5959

@@ -67,14 +67,14 @@ namespace deform {
6767
}
6868

6969
private:
70-
deform::Mesh *_mesh;
70+
OSGViewer::Mesh *_mesh;
7171
OSGViewer::DeformCallback *_dc;
7272
};
7373

74-
OSGViewer::OSGViewer(int argc, char **argv, deform::Mesh *mesh, DeformCallback dc)
74+
OSGViewer::OSGViewer(int argc, char **argv, OSGViewer::Mesh &mesh, DeformCallback dc)
7575
: _data(new data())
7676
{
77-
_data->mesh = mesh;
77+
_data->mesh = &mesh;
7878
_data->mesh->request_face_normals();
7979
_data->mesh->request_vertex_normals();
8080
_data->mesh->update_normals();
@@ -117,10 +117,10 @@ namespace deform {
117117
osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array();
118118

119119
for (auto v = _data->mesh->vertices_begin(); v != _data->mesh->vertices_end(); ++v) {
120-
deform::Mesh::Point p = _data->mesh->point(*v);
120+
Mesh::Point p = _data->mesh->point(*v);
121121
vertices->push_back(osg::Vec3(p[0], p[1], p[2]));
122122

123-
deform::Mesh::Point n = _data->mesh->normal(*v);
123+
Mesh::Point n = _data->mesh->normal(*v);
124124
normals->push_back(osg::Vec3(n[0], n[1], n[2]));
125125
}
126126

@@ -132,7 +132,7 @@ namespace deform {
132132
faces->push_back(v->idx()); ++v;
133133
faces->push_back(v->idx());
134134

135-
deform::Mesh::Point p = _data->mesh->normal(*f);
135+
Mesh::Point p = _data->mesh->normal(*f);
136136
normals->push_back(osg::Vec3(p[0], p[1], p[2]));
137137
}
138138

examples/osg_viewer.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#ifndef DEFORM_OSG_VIEWER_H
1212
#define DEFORM_OSG_VIEWER_H
1313

14-
#include <deform/mesh.h>
14+
#include <deform/openmesh_adapter.h>
1515
#include <memory>
1616
#include <functional>
1717

@@ -20,9 +20,11 @@ namespace deform {
2020

2121
class OSGViewer {
2222
public:
23-
typedef std::function<bool(deform::Mesh *, double)> DeformCallback;
23+
typedef OpenMesh::TriMesh_ArrayKernelT<> Mesh;
2424

25-
OSGViewer(int argc, char **argv, deform::Mesh *mesh, DeformCallback dc);
25+
typedef std::function<bool(Mesh&, double)> DeformCallback;
26+
27+
OSGViewer(int argc, char **argv, Mesh &mesh, DeformCallback dc);
2628
OSGViewer(const OSGViewer &other) = delete;
2729
OSGViewer &operator=(const OSGViewer &other) = delete;
2830
~OSGViewer();

inc/deform/arap.h

Lines changed: 34 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,28 @@
1111
#ifndef DEFORM_ARAP_H
1212
#define DEFORM_ARAP_H
1313

14-
#include <deform/mesh.h>
15-
1614
#include <Eigen/Core>
1715
#include <Eigen/Dense>
1816
#include <Eigen/Sparse>
1917
#include <Eigen/SVD>
2018
#include <vector>
2119
#include <unordered_map>
2220

23-
#include <memory>
24-
2521
namespace deform {
2622

27-
template<class MeshAdapter>
28-
class AsRigidAsPossibleDeformation2 {
23+
template<class T> class PrivateAccessor;
24+
25+
template<class Mesh>
26+
class AsRigidAsPossibleDeformation {
2927
public:
30-
typedef typename MeshAdapter::Scalar Scalar;
28+
typedef typename Mesh::Scalar Scalar;
3129
typedef int Index;
3230
typedef typename Eigen::Matrix<Scalar, 3, 1> Point;
3331

34-
AsRigidAsPossibleDeformation2(const MeshAdapter &mesh)
35-
: _mesh(mesh), _dirty(false)
32+
AsRigidAsPossibleDeformation(Mesh &mesh)
33+
: _mesh(mesh), _dirty(true)
3634
{
37-
setupMeshTopology();
35+
initializeMeshTopology();
3836
}
3937

4038
void setConstraint(Index vidx, Eigen::Ref<const Point> loc) {
@@ -44,14 +42,16 @@ namespace deform {
4442

4543
bool deform(Index numberOfIterations) {
4644
if (_dirty) {
47-
_pprime = _mesh.vertices();
48-
_p = _pprime;
4945

46+
initializeMeshGeometry();
5047
computeCotanWeights();
5148
initializeRotations();
5249
initializeFreeVariableMapping();
5350
initializeConstraints();
5451

52+
if (_numberOfFreeVariables == _mesh.numberOfVertices())
53+
return true;
54+
5555
if (!setupLinearSystem())
5656
return false;
5757

@@ -66,6 +66,12 @@ namespace deform {
6666
// Estimate positions
6767
estimatePositions();
6868
}
69+
70+
// Update vertex locations at mesh
71+
72+
for (Index i = 0; i < _mesh.numberOfVertices(); ++i) {
73+
_mesh.vertexLocation(i, _pprime.col(i));
74+
}
6975

7076
return true;
7177
}
@@ -75,10 +81,22 @@ namespace deform {
7581
}
7682

7783
private:
84+
template<class> friend class PrivateAccessor;
7885

79-
void setupMeshTopology() {
86+
void initializeMeshTopology() {
8087

81-
_faces = _mesh.faces();
88+
_faces.resize(3, _mesh.numberOfFaces());
89+
for (Index f = 0; f < _mesh.numberOfFaces(); ++f) {
90+
_faces.col(f) = _mesh.face(f);
91+
}
92+
}
93+
94+
void initializeMeshGeometry() {
95+
_p.resize(3, _mesh.numberOfVertices());
96+
for (Index v = 0; v < _mesh.numberOfVertices(); ++v) {
97+
_p.col(v) = _mesh.vertexLocation(v);
98+
}
99+
_pprime = _p;
82100
}
83101

84102
void computeCotanWeights() {
@@ -96,6 +114,7 @@ namespace deform {
96114
auto v1 = _p.col(vids(1));
97115
auto v2 = _p.col(vids(2));
98116

117+
99118
const Scalar l0 = (v1 - v0).norm();
100119
const Scalar l1 = (v2 - v1).norm();
101120
const Scalar l2 = (v0 - v2).norm();
@@ -285,7 +304,7 @@ namespace deform {
285304
typedef Eigen::Matrix<Scalar, 3, 3> RotationMatrix;
286305
typedef Eigen::SparseMatrix<Scalar, Eigen::RowMajor> SparseMatrix;
287306

288-
const MeshAdapter &_mesh;
307+
Mesh &_mesh;
289308
Eigen::Matrix<Scalar, 3, Eigen::Dynamic> _p, _pprime;
290309
Eigen::Matrix<Index, 3, Eigen::Dynamic> _faces;
291310
SparseMatrix _edgeWeights;
@@ -301,41 +320,10 @@ namespace deform {
301320
typedef Eigen::SparseMatrix<Scalar> LMatrixType;
302321
LMatrixType _L;
303322

304-
305323
Eigen::Matrix<Scalar, 3, Eigen::Dynamic> _bFixed, _b;
306324
Eigen::SimplicialLDLT<LMatrixType> _solver;
307325

308326
};
309-
310-
311-
class AsRigidAsPossibleDeformation {
312-
public:
313-
AsRigidAsPossibleDeformation(Mesh * mesh);
314-
~AsRigidAsPossibleDeformation();
315-
AsRigidAsPossibleDeformation(const AsRigidAsPossibleDeformation &other) = delete;
316-
AsRigidAsPossibleDeformation &operator=(const AsRigidAsPossibleDeformation &other) = delete;
317-
318-
void setConstraint(Mesh::VertexHandle v, const Mesh::Point &pos);
319-
void deform(size_t nIterations);
320-
321-
private:
322-
void restorePositions();
323-
void attachMeshProperties();
324-
void releaseMeshProperties();
325-
326-
void setupFreeVariableMap();
327-
void estimateRotations();
328-
void estimatePositions();
329-
void prepareLinearSystem();
330-
331-
332-
333-
334-
335-
struct data;
336-
std::unique_ptr<data> _data;
337-
};
338-
339327
}
340328

341329
#endif

inc/deform/cotan_matrix.h

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)