mirror of https://github.com/CGAL/cgal
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:
parent
8334ee2a72
commit
848cd324ef
|
|
@ -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?
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue