mirror of https://github.com/CGAL/cgal
update usage scenario and benchmark of optimal rotations
This commit is contained in:
parent
e8e095bd95
commit
b746da91f2
|
|
@ -31,6 +31,8 @@ struct Polyhedron_deformation_data {
|
|||
Polyhedron* polyhedron_copy; // For a possible undo operation. To be written.
|
||||
std::map<Vertex_handle, Vertex_handle> t2s; // access from original mesh vertices to copied one
|
||||
bool preprocessed; // specify whether preprocessed or not
|
||||
std::map<Vertex_handle, Vector> handle_vectors; // record transform vectors of all handles,
|
||||
// only for multiple handle region scenario
|
||||
};
|
||||
|
||||
class Polyhedron_demo_edit_polyhedron_plugin :
|
||||
|
|
@ -305,14 +307,14 @@ void Polyhedron_demo_edit_polyhedron_plugin::start_deform() {
|
|||
// do deformation only when handles are selected
|
||||
if (edit_item->selected_vertices().isEmpty()) return;
|
||||
|
||||
if ( edit_item->usage_scenario() == 0 )
|
||||
//if ( edit_item->usage_scenario() == 0 )
|
||||
{
|
||||
preprocess(edit_item);
|
||||
}
|
||||
else
|
||||
/*else
|
||||
{
|
||||
complete_deform(edit_item);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -373,6 +375,7 @@ void Polyhedron_demo_edit_polyhedron_plugin::complete_deform(Scene_edit_polyhedr
|
|||
|
||||
// precomputation of Laplacian matrix
|
||||
deform->preprocess();
|
||||
data.preprocessed = true;
|
||||
deform->deform(polyhedron);
|
||||
|
||||
|
||||
|
|
@ -453,14 +456,32 @@ void Polyhedron_demo_edit_polyhedron_plugin::usage_scenario_1(Scene_edit_polyhed
|
|||
deform->roi_push(data.t2s[vh]);
|
||||
Q_FOREACH(Vertex_handle vh, edit_item->non_selected_roi())
|
||||
deform->roi_push(data.t2s[vh]);
|
||||
data.preprocessed = false;
|
||||
}
|
||||
else // moving frame: move new handles
|
||||
{
|
||||
Q_FOREACH(Vertex_handle vh, edit_item->selected_handles())
|
||||
(*deform)(data.t2s[vh], translation_last);
|
||||
//deform->assign_solution(polyhedron);
|
||||
edit_item->setSelectedVector(translation_last);
|
||||
edit_item->setSelectedHandlesMoved(true);
|
||||
if ( !data.preprocessed )
|
||||
{
|
||||
edit_item->setSelectedVector(translation_last);
|
||||
edit_item->setSelectedHandlesMoved(true);
|
||||
Q_FOREACH(Vertex_handle vh, edit_item->selected_handles())
|
||||
data.handle_vectors[vh] = translation_origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector vec = edit_item->selected_vector().second - edit_item->selected_vector().first;
|
||||
double scalar = translation_origin*vec / vec.squared_length() /3.0;
|
||||
if (scalar > 1) scalar = 1;
|
||||
if (scalar < 0) scalar = 0;
|
||||
|
||||
std::map<Vertex_handle, Vector>::iterator it = data.handle_vectors.begin();
|
||||
while ( it != data.handle_vectors.end() ) // apply scalar factor to each handle region
|
||||
{
|
||||
(*deform)( data.t2s[it->first], scalar*(it->second) );
|
||||
it++;
|
||||
}
|
||||
deform->deform(polyhedron);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -827,6 +827,16 @@ Scene_edit_polyhedron_item::selected_roi() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
std::pair<Kernel::Point_3, Kernel::Point_3>
|
||||
Scene_edit_polyhedron_item::selected_vector() const {
|
||||
std::pair<Kernel::Point_3, Kernel::Point_3> result;
|
||||
if (!d->selected_vectors.empty())
|
||||
{
|
||||
result = d->selected_vectors[0];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QList<Vertex_handle>
|
||||
Scene_edit_polyhedron_item::non_selected_roi() const {
|
||||
QList<Vertex_handle> result;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ public:
|
|||
QList<Polyhedron::Vertex_handle> non_selected_handles() const;
|
||||
QList<Polyhedron::Vertex_handle> selected_roi() const;
|
||||
QList<Polyhedron::Vertex_handle> non_selected_roi() const;
|
||||
std::pair<Kernel::Point_3, Kernel::Point_3> selected_vector() const;
|
||||
void clear_selected_roi();
|
||||
void clear_non_selected_roi();
|
||||
void clear_selected_handles();
|
||||
|
|
|
|||
|
|
@ -77,6 +77,9 @@ int main() {
|
|||
}
|
||||
}
|
||||
}
|
||||
A(0,0) = 0.030398276402182046; A(0,1) = 0.012969677925802552; A(0,2) = -0.0035929722077224779;
|
||||
A(1,0) = 0.012969677925802552; A(1,1) = 0.011464021227642014; A(1,2) = 0.0094226887152708255;
|
||||
A(2,0) = -0.0035929722077224762; A(2,1) = 0.0094226887152708255; A(2,2) = 0.032736511659156128;
|
||||
|
||||
CGAL::Timer task_timer;
|
||||
|
||||
|
|
|
|||
|
|
@ -312,7 +312,14 @@ public:
|
|||
|
||||
// initialize the rotation matrices with the same size of ROS
|
||||
rot_mtr.clear();
|
||||
rot_mtr.resize(ros.size());
|
||||
for (int i = 0; i < ros.size(); i++)
|
||||
{
|
||||
Eigen::Matrix3d r;
|
||||
r(0,0) = 1; r(0,1) = 0; r(0,2) = 0;
|
||||
r(1,0) = 0; r(1,1) = 1; r(1,2) = 0;
|
||||
r(2,0) = 0; r(2,1) = 0; r(2,2) = 1;
|
||||
rot_mtr.push_back(r);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -513,7 +520,7 @@ public:
|
|||
}
|
||||
|
||||
// The operator will be called in a real time loop from the GUI.
|
||||
// assign translation vector to handles
|
||||
// assign translation vector to all handles
|
||||
void operator()(Vector translation)
|
||||
{
|
||||
for (int idx = 0; idx < hdl.size(); idx++)
|
||||
|
|
@ -528,7 +535,7 @@ public:
|
|||
void operator()(vertex_descriptor vd, Vector translation)
|
||||
{
|
||||
int idx = boost::get(vertex_id_pmap, vd);
|
||||
solution[idx] = solution[idx] + translation;
|
||||
solution[idx] = vd->point() + translation;
|
||||
}
|
||||
|
||||
// Local step of iterations, computing optimal rotation matrices using SVD decomposition
|
||||
|
|
@ -676,7 +683,7 @@ public:
|
|||
Eigen::Vector3d w; // singular values
|
||||
Eigen::Matrix3d cov; // covariance matrix
|
||||
Eigen::Matrix3d r;
|
||||
int num_neg = 0;
|
||||
int num_svd = 0;
|
||||
|
||||
// only accumulate ros vertices
|
||||
for ( int i = 0; i < ros.size(); i++ )
|
||||
|
|
@ -707,49 +714,52 @@ public:
|
|||
}
|
||||
|
||||
// svd decomposition
|
||||
if (cov.determinant() == 0)
|
||||
{
|
||||
svd.compute( cov, Eigen::ComputeFullU | Eigen::ComputeFullV );
|
||||
u = svd.matrixU(); v = svd.matrixV(); w = svd.singularValues();
|
||||
r = v*u.transpose();
|
||||
}
|
||||
else
|
||||
if (cov.determinant()/cov.norm() > 1e-3)
|
||||
{
|
||||
polar_eigen<Eigen::Matrix3d> (cov, r);
|
||||
r = r.transpose(); // the optimal rotation matrix should be transpose of decomposition result
|
||||
}
|
||||
|
||||
// checking negative determinant of r
|
||||
if ( r.determinant() < 0 ) // back to SVD method
|
||||
{
|
||||
num_neg++;
|
||||
if (cov.determinant() != 0)
|
||||
{
|
||||
svd.compute( cov, Eigen::ComputeFullU | Eigen::ComputeFullV );
|
||||
u = svd.matrixU(); v = svd.matrixV(); w = svd.singularValues();
|
||||
}
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
int j0 = j;
|
||||
int j1 = (j+1)%3;
|
||||
int j2 = (j1+1)%3;
|
||||
if ( w[j0] <= w[j1] && w[j0] <= w[j2] ) // smallest singular value as j0
|
||||
{
|
||||
u(0, j0) = -1.0*u(0, j0);
|
||||
u(1, j0) = -1.0*u(1, j0);
|
||||
u(2, j0) = -1.0*u(2, j0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// svd.compute( cov, Eigen::ComputeFullU | Eigen::ComputeFullV );
|
||||
// u = svd.matrixU(); v = svd.matrixV(); w = svd.singularValues();
|
||||
// r = v*u.transpose();
|
||||
// num_svd++;
|
||||
//}
|
||||
//
|
||||
//// checking negative determinant of covariance matrix
|
||||
//if ( r.determinant() < 0 ) // back to SVD method
|
||||
//{
|
||||
// if (cov.determinant()/cov.norm() > 1e-3)
|
||||
// {
|
||||
// svd.compute( cov, Eigen::ComputeFullU | Eigen::ComputeFullV );
|
||||
// u = svd.matrixU(); v = svd.matrixV(); w = svd.singularValues();
|
||||
// num_svd++;
|
||||
// }
|
||||
// for (int j = 0; j < 3; j++)
|
||||
// {
|
||||
// int j0 = j;
|
||||
// int j1 = (j+1)%3;
|
||||
// int j2 = (j1+1)%3;
|
||||
// if ( w[j0] <= w[j1] && w[j0] <= w[j2] ) // smallest singular value as j0
|
||||
// {
|
||||
// u(0, j0) = -1.0*u(0, j0);
|
||||
// u(1, j0) = -1.0*u(1, j0);
|
||||
// u(2, j0) = -1.0*u(2, j0);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// re-extract rotation matrix
|
||||
r = v*u.transpose();
|
||||
}
|
||||
// // re-extract rotation matrix
|
||||
// r = v*u.transpose();
|
||||
//}
|
||||
|
||||
rot_mtr[i] = r;
|
||||
}
|
||||
|
||||
CGAL_TRACE_STREAM << num_neg << " negative rotations\n";
|
||||
double svd_percent = (double)(num_svd)/ros.size();
|
||||
CGAL_TRACE_STREAM << svd_percent*100 << "% percentage SVD decompositions;";
|
||||
CGAL_TRACE_STREAM << num_svd << " SVD decompositions\n";
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue