update usage scenario and benchmark of optimal rotations

This commit is contained in:
Yin Xu 2011-08-05 14:02:14 +00:00
parent e8e095bd95
commit b746da91f2
5 changed files with 91 additions and 46 deletions

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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";
}