From de15c7891c841cf570438a43f7762c8ca9852783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 3 Jul 2014 12:10:48 +0200 Subject: [PATCH] add cactus deformation session test with OpenMesh+CGAL point --- .../test/Surface_modeling/CMakeLists.txt | 9 ++ .../Cactus_deformation_session_OpenMesh.cpp | 116 ++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 Surface_modeling/test/Surface_modeling/Cactus_deformation_session_OpenMesh.cpp diff --git a/Surface_modeling/test/Surface_modeling/CMakeLists.txt b/Surface_modeling/test/Surface_modeling/CMakeLists.txt index 27450c6dc43..62e19c4a735 100644 --- a/Surface_modeling/test/Surface_modeling/CMakeLists.txt +++ b/Surface_modeling/test/Surface_modeling/CMakeLists.txt @@ -28,6 +28,15 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "Cactus_deformation_session.cpp" ) create_single_source_cgal_program( "Cactus_performance_test.cpp" ) create_single_source_cgal_program( "Symmetry_test.cpp" ) + + find_package( OpenMesh QUIET ) + if ( OpenMesh_FOUND ) + include( UseOpenMesh ) + create_single_source_cgal_program( "Cactus_deformation_session_OpenMesh.cpp" ) + target_link_libraries( Cactus_deformation_session_OpenMesh ${OPENMESH_LIBRARIES} ) + else() + message(STATUS "Example that use OpenMesh will not be compiled.") + endif() else() message(STATUS "NOTICE: These tests require the Eigen library, version 3.2 or later and will not be compiled.") endif() diff --git a/Surface_modeling/test/Surface_modeling/Cactus_deformation_session_OpenMesh.cpp b/Surface_modeling/test/Surface_modeling/Cactus_deformation_session_OpenMesh.cpp new file mode 100644 index 00000000000..26293d41fb3 --- /dev/null +++ b/Surface_modeling/test/Surface_modeling/Cactus_deformation_session_OpenMesh.cpp @@ -0,0 +1,116 @@ +#include "Surface_modeling_test_commons.h" +#include +#include + +#include +#include + +// HalfedgeGraph adapters +//~ #define CGAL_USE_OM_POINTS // use OpenMesh point type +#include +#include + +#include + +#include + +#include +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef OpenMesh::PolyMesh_ArrayKernelT Mesh; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; + +typedef CGAL::Deform_mesh Deform_mesh_arap; +typedef CGAL::Deform_mesh Deform_mesh_spoke; +const double squared_threshold = 0.001; // alert if average difs between precomputed and deformed mesh models is above threshold + +void compare_mesh(const Mesh& mesh_1, const Mesh& mesh_2) +{ + vertex_iterator it_1,end_1, it_2, end_2; + CGAL::cpp11::tie(it_1, end_1) = vertices(mesh_1); + CGAL::cpp11::tie(it_2, end_2) = vertices(mesh_2); + boost::property_map::type + ppmap_1 = get(boost::vertex_point, mesh_1), ppmap_2 = get(boost::vertex_point, mesh_2); + Kernel::Vector_3 total_dif(0,0,0); + for( ; it_1 != end_1; ++it_1 , ++it_2) + { + total_dif = total_dif + (get(ppmap_1, *it_1) - get(ppmap_2, *it_2)); + } + double average_mesh_dif = (total_dif / num_vertices(mesh_1)).squared_length(); + + std::cerr << "Average mesh difference: " << average_mesh_dif << std::endl; + + assert( average_mesh_dif < squared_threshold); +} + +// read deformation session saved as a handle differences +template +void read_handle_difs_and_deform(DeformMesh& deform_mesh, InputIterator begin, InputIterator end) +{ + typedef CGAL::Simple_cartesian::Vector_3 Vector; + + if(!deform_mesh.preprocess()) { + std::cerr << "Error: preprocess() failed!" << std::endl; + assert(false); + } + + std::ifstream dif_stream("data/cactus_handle_differences.txt"); + std::vector dif_vector; + double x, y, z; + while(dif_stream >> x >> y >> z) + { dif_vector.push_back(Vector(x, y, z)); } + + CGAL::Timer timer; + + //the original behavior of translate was to overwrite the previous + //translation. Now that it is cumulative, we need to substract the + //previous translation vector to mimic the overwrite + Vector previous(0,0,0); + for(std::size_t i = 0; i < dif_vector.size(); ++i) + { + timer.start(); + deform_mesh.translate(begin, end, dif_vector[i]-previous); + deform_mesh.deform(); + timer.stop(); + previous=dif_vector[i]; + + // read pre-deformed cactus + std::stringstream predeformed_cactus_file; + predeformed_cactus_file << "data/cactus_deformed/cactus_deformed_" << i << ".off"; + Mesh predeformed_cactus; + + OpenMesh::IO::read_mesh(predeformed_cactus, predeformed_cactus_file.str().c_str()); + compare_mesh(predeformed_cactus, deform_mesh.halfedge_graph()); + + // for saving deformation + //std::ofstream(predeformed_cactus_file) << deform_mesh.halfedge_graph(); + //std::cerr << predeformed_cactus_file << std::endl; + } + std::cerr << "Deformation performance (with default number_of_iteration and tolerance) " << std::endl + << dif_vector.size() << " translation: " << timer.time() << std::endl; +} + +int main() +{ + Mesh mesh_1; + OpenMesh::IO::read_mesh(mesh_1, "data/cactus.off"); + Mesh mesh_2 = mesh_1; + + Deform_mesh_arap deform_mesh_arap(mesh_1); + Deform_mesh_spoke deform_mesh_spoke(mesh_2); + // For original arap + std::vector hg_1 = + read_rois(deform_mesh_arap, "data/cactus_roi.txt", "data/cactus_handle.txt"); + + read_handle_difs_and_deform(deform_mesh_arap, hg_1.begin(), hg_1.end()); + std::cerr << "ORIGINAL ARAP Success!" << std::endl; + // For spokes rims + std::vector hg_2 = + read_rois(deform_mesh_spoke, "data/cactus_roi.txt", "data/cactus_handle.txt"); + + read_handle_difs_and_deform(deform_mesh_spoke, hg_2.begin(), hg_2.end()); + std::cerr << "SPOKES AND RIMS ARAP Success!" << std::endl; + std::cerr << "All done!" << std::endl; +} +