the affine transformations now apply on the last target position set

-Rename rotate_and_translate --> rotate
-Remove the translation part of rotate_and_translate (since we can call
  the functions rotate and then translate)
-Add a function to query the current target position of a control vertex
-Update example and checks results that the result are still the same
This commit is contained in:
Sébastien Loriot 2013-09-13 23:26:29 +02:00
parent 8334ee2a72
commit 848cd324ef
4 changed files with 33 additions and 32 deletions

View File

@ -19,7 +19,5 @@
\cgalPkgDemo{Edit plugin of the Polyhedron demo,polyhedron_3.zip}
\cgalPkgShortInfoEnd
\cgalPkgDescriptionEnd
\todo change translate and rotate_and_translate to apply on the current position?
*/

View File

@ -94,13 +94,11 @@ it is better to use an individual deformation object for each connected componen
\subsection Deform_section Deformation
The deformation of the surface mesh is triggered by the displacement of the control vertices.
This is done by setting the final position of the control vertices, or setting an affine transformation
to be applied to a control vertex or a range of control vertices.
This is done by setting the target position of the control vertices (directly or by using an affine transformation
to be applied to a control vertex or a range of control vertices).
Note that the rotation and translation are always applied on the <em>original positions</em> of the control vertices. Hence,
they are not cumulative (i.e. any call to `Deform_mesh::rotate_and_translate()`, `Deform_mesh::translate()`, or `Deform_mesh::set_target_position()`
overrides the previous call). In particular, in an interactive deformation session, the user is responsible for composing the
affine transformations. The rationale for this choice is increase the numerical stability of the affine transformations.
Note that a rotation or a translation of a control vertex is always applied on its last target position set:
they are cumulative.
The deformation of the mesh happens when calling the function `Deform_mesh::deform()`. The number of optimization iterations
varies depending on whether the user choose a fixed number of iterations or a stop criteria based on the energy variation.
@ -131,7 +129,7 @@ Deformation results when running example \ref Example_1 : `deform_1.off` and `de
\cgalFigureEnd
\subsubsection Example_2 Using Affine Transformation on Range of Vertices
In this example, we use the functions `translate()` and `rotate_and_translate()` on a range of control vertices.
In this example, we use the functions `translate()` and `rotate()` on a range of control vertices.
\cgalExample{Surface_modeling/k_ring_roi_translate_rotate_example.cpp}

View File

@ -98,14 +98,10 @@ int main()
deform_mesh.preprocess();
//// DEFORM SECTION ////
deform_mesh.translate(controls_1_map.begin(), controls_1_map.end(), Eigen::Vector3d(0,0,1));
// overrides any previous call
Eigen::Quaternion<double> quad(0.92, 0, 0, -0.38);
Eigen::Vector3d vect(0, 0, 0);
deform_mesh.rotate_and_translate(controls_1_map.begin(), controls_1_map.end(), Deform_mesh::Point(0,0,0), quad, vect);
deform_mesh.rotate_and_translate(controls_2_map.begin(), controls_2_map.end(), Deform_mesh::Point(0,0,0), quad, vect);
deform_mesh.rotate(controls_1_map.begin(), controls_1_map.end(), Deform_mesh::Point(0,0,0), quad);
deform_mesh.rotate(controls_2_map.begin(), controls_2_map.end(), Deform_mesh::Point(0,0,0), quad);
deform_mesh.deform();
@ -113,6 +109,9 @@ int main()
output << mesh; // save deformed mesh
output.close();
//restore the positions of the vertices
deform_mesh.reset();
// Note that translate and rotate are not cumulative,
// they just use original positions (positions at the time of construction) of the control verticess while calculating target positions
deform_mesh.translate(controls_1_map.begin(), controls_1_map.end(), Eigen::Vector3d(0,0.30,0));

View File

@ -530,9 +530,7 @@ public:
}
/**
* Sets the target position of `vd` by applying a translation of vertex `t` to its original position
* (that is its position at the time of the functor construction or after the last call to `overwrite_original_positions()`).
* \note A call to this function cancels the last call to `rotate_and_translate()`, `translate()`, or `set_target_position()` involving `vd`.
* Updates the target position of `vd` by applying a translation of vector `t` to its last target position.
*
* @tparam Vect is a 3D vector class, `Vect::operator[](int i)` with i=0,1 or 2 returns its coordinates
*
@ -545,7 +543,7 @@ public:
region_of_solution(); // we require ros ids, so if there is any need to preprocess of region of solution -do it.
std::size_t v_id = ros_id(vd);
solution[v_id] = add_to_point(original[v_id], t);
solution[v_id] = add_to_point(solution[v_id], t);
}
/**
@ -565,15 +563,12 @@ public:
for(; begin != end; ++begin) {
std::size_t v_id = ros_id(*begin);
solution[v_id] = add_to_point(original[v_id], t);
solution[v_id] = add_to_point(solution[v_id], t);
}
}
/**
* Sets the target position of `vd` by applying a rotation around `rotation_center` defined by the quaternion `quat`, followed by a
* translation by vector `t` to its original position (that is its position at the time of the functor construction or after
* the last call to `overwrite_original_positions()`).
* \note A call to this function cancels the last call to `rotate_and_translate()`, `translate()`, or `set_target_position()` involving `vd`.
* Updates the target position of `vd` by applying a rotation around `rotation_center` defined by the quaternion `quat` to its last target position.
*
* @tparam Quaternion is a quaternion class with `Vect operator*(Quaternion, Vect)` being defined and returns the product of a quaternion with a vector
* @tparam Vect is a 3D vector class, `Vect(double x,double y, double z)` being a constructor available and `Vect::operator[](int i)` with i=0,1 or 2 returns its coordinates
@ -581,15 +576,14 @@ public:
* @param vd a control vertex
* @param rotation_center center of rotation
* @param quat rotation holder quaternion
* @param t post translation vector
*/
template <typename Quaternion, typename Vect>
void rotate_and_translate(vertex_descriptor vd, const Point& rotation_center, const Quaternion& quat, const Vect& t)
void rotate(vertex_descriptor vd, const Point& rotation_center, const Quaternion& quat)
{
region_of_solution(); // we require ros ids, so if there is any need to preprocess of region of solution -do it.
std::size_t v_id = ros_id(vd);
Vect v = quat * sub_to_vector<Vect>(original[v_id], rotation_center);
Vect v = quat * sub_to_vector<Vect>(solution[v_id], rotation_center);
const Point& rotated = add_to_point(rotation_center, v);
solution[v_id] = Point(rotated[0] + t[0], rotated[1] + t[1], rotated[2] + t[2]);
}
@ -605,23 +599,35 @@ public:
* @param end past-the-end iterator of the range of vertices
* @param rotation_center center of rotation
* @param quat rotation holder quaternion
* @param t post translation vector
*/
template <typename InputIterator, typename Quaternion, typename Vect>
void rotate_and_translate(InputIterator begin, InputIterator end, const Point& rotation_center, const Quaternion& quat, const Vect& t)
void rotate(InputIterator begin, InputIterator end, const Point& rotation_center, const Quaternion& quat)
{
region_of_solution(); // we require ros ids, so if there is any need to preprocess of region of solution -do it.
for(; begin != end; ++begin) {
std::size_t v_id = ros_id(*begin);
Vect v = quat * sub_to_vector<Vect>(original[v_id], rotation_center);
Vect v = quat * sub_to_vector<Vect>(solution[v_id], rotation_center);
const Point& rotated = add_to_point(rotation_center, v);
solution[v_id] = Point(rotated[0] + t[0], rotated[1] + t[1], rotated[2] + t[2]);
}
}
/**
* Deforms the region-of-interest according to the deformation algorithm, using the target positions of each control vertex set by using `rotate_and_translate()`, `translate()`, or `set_target_position()`.
* Returns the target position of a control vertex.
* \param vd a control vertex
* \pre `is_roi(vd)`
*/
const Point& target_position(vertex_descriptor vd)
{
region_of_solution();
CGAL_precondition( is_roi(vd) );
return solution[ ros_id(vd) ];
}
/**
* Deforms the region-of-interest according to the deformation algorithm, using the target positions of each control vertex set by using `rotate()`, `translate()`, or `set_target_position()`.
* The points associated to each vertex of the input graph that are inside the region-of-interest are updated. The initial guess for solving the
* deformation problem is using the points associated to the input graph before calling the function.
* \note Nothing happens if `preprocess()` returns `false`.
@ -856,7 +862,7 @@ private:
need_preprocess_region_of_solution = false;
std::vector<std::size_t> old_ros_id_map = ros_id_map;
std::vector<CR_matrix> old_rot_mtr = rot_mtr;
std::vector<CR_matrix> old_rot_mtr = rot_mtr;
std::vector<Point> old_solution = solution;
std::vector<Point> old_original = original;