From b746da91f2885f30dddb4d8e9c5770533db34ce4 Mon Sep 17 00:00:00 2001 From: Yin Xu Date: Fri, 5 Aug 2011 14:02:14 +0000 Subject: [PATCH] update usage scenario and benchmark of optimal rotations --- ...Polyhedron_demo_edit_polyhedron_plugin.cpp | 37 ++++++-- .../Polyhedron/Scene_edit_polyhedron_item.cpp | 10 +++ .../Polyhedron/Scene_edit_polyhedron_item.h | 1 + .../optimal_rotation_polar_eigen.cpp | 3 + .../include/CGAL/Deform_mesh_BGL.h | 86 +++++++++++-------- 5 files changed, 91 insertions(+), 46 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp index 4c09f2461e8..8b7be3df94f 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp @@ -31,6 +31,8 @@ struct Polyhedron_deformation_data { Polyhedron* polyhedron_copy; // For a possible undo operation. To be written. std::map t2s; // access from original mesh vertices to copied one bool preprocessed; // specify whether preprocessed or not + std::map 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::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); + } } } diff --git a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp index 4e9f5a68811..bc514b46d7b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp @@ -827,6 +827,16 @@ Scene_edit_polyhedron_item::selected_roi() const { return result; } +std::pair +Scene_edit_polyhedron_item::selected_vector() const { + std::pair result; + if (!d->selected_vectors.empty()) + { + result = d->selected_vectors[0]; + } + return result; +} + QList Scene_edit_polyhedron_item::non_selected_roi() const { QList result; diff --git a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h index 6d5ba0f114e..7fd0c489b4d 100644 --- a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h @@ -71,6 +71,7 @@ public: QList non_selected_handles() const; QList selected_roi() const; QList non_selected_roi() const; + std::pair selected_vector() const; void clear_selected_roi(); void clear_non_selected_roi(); void clear_selected_handles(); diff --git a/Surface_modeling/benchmark/Surface_modeling/optimal_rotation/optimal_rotation_polar_eigen.cpp b/Surface_modeling/benchmark/Surface_modeling/optimal_rotation/optimal_rotation_polar_eigen.cpp index 7cd93d4c7de..99bdd0ba3a4 100644 --- a/Surface_modeling/benchmark/Surface_modeling/optimal_rotation/optimal_rotation_polar_eigen.cpp +++ b/Surface_modeling/benchmark/Surface_modeling/optimal_rotation/optimal_rotation_polar_eigen.cpp @@ -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; diff --git a/Surface_modeling/include/CGAL/Deform_mesh_BGL.h b/Surface_modeling/include/CGAL/Deform_mesh_BGL.h index 7e71515197e..04871427a0e 100644 --- a/Surface_modeling/include/CGAL/Deform_mesh_BGL.h +++ b/Surface_modeling/include/CGAL/Deform_mesh_BGL.h @@ -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 (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"; }