add SRE_ARAP in the user manual

This commit is contained in:
Sébastien Loriot 2016-06-21 21:36:45 +02:00
parent 55fffdd915
commit a653b5cc40
10 changed files with 2633 additions and 6 deletions

View File

@ -151968,3 +151968,11 @@ pages = {179--189}
year={2007},
organization={Wiley Online Library}
}
@article{levismooth,
title={Smooth Rotation Enhanced As-Rigid-As-Possible Mesh Animation},
author={Levi, Zohar and Gotsman, Craig},
journal={IEEE Transactions on Visualization \& Computer Graphics},
publisher={IEEE},
year={2015}
}

View File

@ -35,9 +35,10 @@ The ROI features the green vertices (the unconstrained vertices) and the red ver
the coordinates of the unconstrained vertices being updated by the deformation algorithm.
\cgalFigureEnd
In this package, two algorithms are implemented:
- The <em>As-Rigid-As-Possible</em> (<em>ARAP</em>) method described in \cgalCite{Sorkine2007AsRigidAs};
- The <em>Spokes and Rims</em> method \cgalCite{Chao2010SimpleGeomModel}.
In this package, three algorithms are implemented:
- The <em>As-Rigid-As-Possible</em> (<em>ARAP</em>) method \cgalCite{Sorkine2007AsRigidAs};
- The <em>Spokes and Rims</em> method \cgalCite{Chao2010SimpleGeomModel};
- The <em>Smoothed %Rotation Enhanced As-Rigid-As-Possible</em> method \cgalCite{levismooth}
Given an edge weighting scheme, both methods iteratively minimize an energy function and produce a different surface mesh at each step until convergence is reached.
@ -46,16 +47,21 @@ convergence while the <em>ARAP</em> method requires the edge weights to be posit
the results obtained using the <em>Spokes and Rims</em> method are more dependent on the discretization
of the deformed surface (See \cgalFigureRef{Arap_spokes_comparison}).
The <em>Smoothed %Rotation Enhanced As-Rigid-As-Possible</em> method adds a bending term to the ARAP energy that penalizes rotation difference between neighboring elements. In the current implementation a 1-ring type element is used while in general it is possible to use a triangle type element.
More details on these algorithms are provided in section \ref SMD_Overview.
\cgalFigureBegin{Arap_spokes_comparison, arap_spokes_comparison.png}
Comparison between the As-Rigid-As-Possible and the Spokes and Rims deformation methods.
A comparison between the As-Rigid-As-Possible and the Spokes and Rims deformation methods.
On the surface mesh of a square with spikes depicted on the left, the ROI consists of the green vertices. The control vertices are the red ones.
We translate the control vertices along the normal to the plane and observe the result produced by
the As-Rigid-As-Possible (center) and the Spokes and Rims (right) methods from the same view point. The
latter method provides unconditional convergence does not produce a symmetric result.
\cgalFigureEnd
\cgalFigureBegin{Arap_spokes_comparison, sr_arap_comparison.png}
A comparison on a 5261 vertices cactus model (left) between the As-Rigid-As-Possible (middle) and the Smoothed %Rotation Enhanced As-Rigid-As-Possible (right).
\cgalFigureEnd
\section SMD_API User Interface Description
@ -132,10 +138,10 @@ which will also require a new preprocessing step).
This behavior is illustrated in \ref SModelingVideo_1 "Video 1".
\subsection Surface_mesh_deformation_arap_or_spokes_and_rims As-Rigid-As-Possible and Spokes-and-Rims Deformation Techniques
Two deformation techniques are provided by this package. This section summarizes from the user point of view what is
Three deformation techniques are provided by this package. This section summarizes from the user point of view what is
explained in details in the section \ref SMD_Overview.
The As-Rigid-As-Possible deformation technique requires the use of a positive weighting scheme to guarantee
The As-Rigid-As-Possible deformation techniques require the use of a positive weighting scheme to guarantee
the correct minimization of the energy. When using the default cotangent weighting scheme, this means that
the input surface mesh must be <em>clean</em>. That is, that for all edges in the surface mesh
the sum of the angles opposite to the edge in the incident triangles is less that \f$ \pi \f$.
@ -198,6 +204,11 @@ Another example is given in the manual page of the concept `::SurfaceMeshDeforma
\cgalExample{Surface_mesh_deformation/custom_weight_for_edges_example.cpp}
\subsubsection SModelingExample_5 Using the Smoothed Rotation Enhanced As-Rigid-As-Possible
In this example, a survey \cgalCite{Botsch2008OnLinearVariational} model is loaded, alpha that determines the influence of the bending term is set, and the deformation method is set to `SRE_ARAP`.
\cgalExample{Surface_mesh_deformation/deform_mesh_for_botsch08_format_sre_arap.cpp}
\section SMD_Demo How to Use the Demo
A plugin for the polyhedron demo is available to test the algorithm. The following video tutorials explain how to use it.
@ -490,9 +501,28 @@ However, this method is more dependent on the discretization of the deformed sur
The implementation in this package uses the cotangent weights by default (negative values included) as proposed in \cgalCite{Chao2010SimpleGeomModel}.
\subsection SMD_Overview_SRE_ARAP Smoothed Rotation Enhanced As-Rigid-As Possible (SR_ARAP) Deformation
Using 1-ring elements, SR-ARAP adds a bending element to Eq. \f$\eqref{eq:arap_energy}\f$:
\f[
\begin{equation}
\sum_{\mathbf{v}_i \in M}
\sum_{\mathbf{v}_j \in N(\mathbf{v}_i)} w_{ij}
\left\| (\mathbf{v}'_i - \mathbf{v}'_j) - \mathbf{R}_i(\mathbf{v}_i - \mathbf{v}_j) \right\|^2 + \alpha A \left\| \mathbf{R}_i - \mathbf{R}_j \right\|^2_F
\label{eq:sre_arap_energy}
\end{equation}
\f]
where
- \f$\alpha=0.02\f$ is a weighting coefficient.
- \f$A\f$ is the surface area for scaling invariance.
Only the local step is influenced by the added term, and the optimal rotation now takes into account the rotation of neighbors.
\section SMD_History Design and Implementation History
An initial version of this package has been implemented during the 2011 Google Summer of Code by Yin Xu under the guidance of Olga Sorkine and Andreas Fabri.
Ilker O. Yaz took over the finalization of the package with the help of Sébastien Loriot for the documentation and the API.
In 2016, Zohar Levi and Sébastien Loriot extended the package to support Smoothed Rotation Enhanced ARAP.
The authors are grateful to Gaël Guennebaud for his great help on using the Eigen library and for providing the code to compute
the closest rotation.
*/

View File

@ -3,4 +3,5 @@
\example Surface_mesh_deformation/k_ring_roi_translate_rotate_example.cpp
\example Surface_mesh_deformation/deform_polyhedron_with_custom_pmap_example.cpp
\example Surface_mesh_deformation/custom_weight_for_edges_example.cpp
\example Surface_mesh_deformation/deform_mesh_for_botsch08_format_sre_arap.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View File

@ -27,6 +27,7 @@ if ( CGAL_FOUND )
create_single_source_cgal_program( "deform_polyhedron_with_custom_pmap_example.cpp" )
create_single_source_cgal_program( "k_ring_roi_translate_rotate_example.cpp" )
create_single_source_cgal_program( "k_ring_roi_translate_rotate_Surface_mesh.cpp" )
create_single_source_cgal_program( "deform_mesh_for_botsch08_format_sre_arap.cpp" )
find_package( OpenMesh QUIET )
if ( OpenMesh_FOUND )

View File

@ -0,0 +1,5 @@
# 4x4 handle transformation matrix
0.999641 0.021031 0.016579 -0.019322
-0.022776 0.342021 0.939416 -0.134331
0.014087 -0.939457 0.342378 0.821073
0.000000 0.000000 0.000000 1.000000

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,622 @@
# per vertex status: 0=fixed, 1=deformable-region, 2=handle
# 620 vertices
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
2
1
1
1
1
1
1
1
1
2
1
1
1
1
1
1
1
1
2
2
1
1
1
1
1
1
1
1
1
1
1
1
2
2
2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
2
1
1
1
1
1
1
1
1
1
2
2
2
1
1
1
1
1
1
1
1
1
2
2
1
1
2
2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
2
1
1
1
1
1
1
1
2
2
2
1
1
1
1
1
1
1
1
1
1
1
2
2
2
2
1
1
1
1
2
2
1
1
2
2
2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
1
1
1
1
2
2
1
1
2
2
2
1
1
1
1
1
1
1
2
2
2
2
1
1
1
1
2
2
1
1
2
2
2
1
1
1
1
1
1
1
1
1
1
1
1
2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
1
1
1
1
1
1
1
1
0
0
1
1
1
1
1
1
1
1
1
1
0
0
0
0
0
1
1
1
1
1
1
1
0
1
1
1
0
0
0
0
0
1
1
1
1
1
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
1
0
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
1
1
1
1
1
1
1
1
2
2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
1
1
2
2
2
1
1
2
2
1
1
1
1
1
1
1
1
1
1
1
2
1
1
1
1
1
2
2
2
2
1
1
1
1
1
1
1
1
1
1
1
1
2
1
2
1
1
1
2
2
2
2
2
2
2
1
1
1
1
1
1
1
2
2
1
2
1
1
1
2
1
1
1
1
1
1
1
1
1
1
2
2
2
1
1
1
1
2
2
1
1
1
1
2
1
1
1
1
1
1
2
2
1
1
1
1
1
1
1
2
2
1
1
1
1
1
1
1
1
1
2
1
1
1
1
1
2
2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
1
1
1
1
1
1
1
1
0
0
1
1
1
0
0
1
1
1
1
1
0
0
1
1
0
0
0
1
1
1
0
0
0
0
1
1
1
0
0
0
0
0
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0

View File

@ -0,0 +1 @@
data/cactus.off data/cactus.sel data/cactus.def

View File

@ -0,0 +1,101 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Polyhedron_items_with_id_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
// HalfedgeGraph adapters for Polyhedron_3
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include <CGAL/boost/graph/properties_Polyhedron_3.h>
#include <boost/foreach.hpp>
#include <CGAL/Surface_mesh_deformation.h>
#include <fstream>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef CGAL::Polyhedron_3<Kernel, CGAL::Polyhedron_items_with_id_3> Polyhedron;
typedef boost::graph_traits<Polyhedron>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Polyhedron>::vertex_iterator vertex_iterator;
typedef CGAL::Surface_mesh_deformation<Polyhedron,CGAL::Default, CGAL::Default, CGAL::SRE_ARAP> Surface_mesh_deformation;
int main(int argc,char** argv)
{
if ( argc!=4){
std::cerr <<"Usage " << argv[0] << " input.off input.sel input.def\n";
return 1;
}
Polyhedron mesh;
std::ifstream input(argv[1]);
if ( !input || !(input >> mesh) || mesh.empty() ) {
std::cerr<< argv[1] << " is not a valid off file" << std::endl;
return 1;
}
input.close();
// Init the indices of the halfedges and the vertices.
set_halfedgeds_items_id(mesh);
// Create a deformation object
Surface_mesh_deformation deform_mesh(mesh);
// Changing alpha value
deform_mesh.set_sre_arap_alpha(0.02);
// Definition of the region of interest (use the whole mesh)
vertex_iterator vb,ve;
boost::tie(vb, ve) = boost::vertices(mesh);
//the selection is set by a file
input.open(argv[2]);
std::string line;
std::vector<vertex_descriptor> control_vertices;
while(getline(input, line))
{
if (line[0]=='#') continue;
if (line[0]=='1') deform_mesh.insert_roi_vertex(*vb);
if (line[0]=='2') {
deform_mesh.insert_control_vertex(*vb);
control_vertices.push_back(*vb);
}
++vb;
if (vb==ve) break;
}
input.close();
std::cout << "Using " << control_vertices.size() << " control vertices\n";
// The definition of the ROI and the control vertices is done, call preprocess
bool is_matrix_factorization_OK = deform_mesh.preprocess();
if(!is_matrix_factorization_OK){
std::cerr << "Error in preprocessing, check documentation of preprocess()" << std::endl;
return 1;
}
//define the transformation
input.open(argv[3]);
double m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, hw, sink;
getline(input, line); // skip first comment line
input >> m00 >> m01 >> m02 >> m03;
input >> m10 >> m11 >> m12 >> m13;
input >> m20 >> m21 >> m22 >> m23;
input >> sink >> sink >> sink >> hw;
std::cout << "Setting target positions\n";
Kernel::Aff_transformation_3 aff(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23);
BOOST_FOREACH(vertex_descriptor vd, control_vertices)
{
Surface_mesh_deformation::Point pos = vd->point().transform(aff);
deform_mesh.set_target_position(vd, pos);
}
// Call the function deform() with one-time parameters:
std::cout << "Deforming the mesh\n";
deform_mesh.deform(1000, 1e-4);
// Save the deformed mesh into a file
std::ofstream output("deform_res.off");
output << mesh;
output.close();
}