diff --git a/Surface_modeling/doc/Surface_modeling/PackageDescription.txt b/Surface_modeling/doc/Surface_modeling/PackageDescription.txt
index 837b98b44d7..ba870f072b3 100644
--- a/Surface_modeling/doc/Surface_modeling/PackageDescription.txt
+++ b/Surface_modeling/doc/Surface_modeling/PackageDescription.txt
@@ -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?
*/
diff --git a/Surface_modeling/doc/Surface_modeling/Surface_modeling.txt b/Surface_modeling/doc/Surface_modeling/Surface_modeling.txt
index 5ad50a16428..9d3bdb7a5f0 100644
--- a/Surface_modeling/doc/Surface_modeling/Surface_modeling.txt
+++ b/Surface_modeling/doc/Surface_modeling/Surface_modeling.txt
@@ -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 original positions 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}
diff --git a/Surface_modeling/examples/Surface_modeling/k_ring_roi_translate_rotate_example.cpp b/Surface_modeling/examples/Surface_modeling/k_ring_roi_translate_rotate_example.cpp
index d67d96d7339..e5509ad3a7a 100644
--- a/Surface_modeling/examples/Surface_modeling/k_ring_roi_translate_rotate_example.cpp
+++ b/Surface_modeling/examples/Surface_modeling/k_ring_roi_translate_rotate_example.cpp
@@ -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 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));
diff --git a/Surface_modeling/include/CGAL/Deform_mesh.h b/Surface_modeling/include/CGAL/Deform_mesh.h
index e4539d03b13..0c100910a3f 100644
--- a/Surface_modeling/include/CGAL/Deform_mesh.h
+++ b/Surface_modeling/include/CGAL/Deform_mesh.h
@@ -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
- 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(original[v_id], rotation_center);
+ Vect v = quat * sub_to_vector(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
- 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(original[v_id], rotation_center);
+ Vect v = quat * sub_to_vector(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 old_ros_id_map = ros_id_map;
- std::vector old_rot_mtr = rot_mtr;
+ std::vector old_rot_mtr = rot_mtr;
std::vector old_solution = solution;
std::vector old_original = original;