Last active
August 3, 2017 18:22
-
-
Save OlegJakushkin/f16c3dde15bb46ecbf1a71f2a014fc9e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <OpenMesh/Core/IO/MeshIO.hh> | |
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh> | |
#include <CGAL/Polyhedron_3.h> | |
#include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h> | |
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h> | |
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> | |
#include <CGAL/mesh_segmentation.h> | |
#include <CGAL/Polygon_mesh_processing/connected_components.h> | |
#include <CGAL/internal/corefinement/connected_components.h> | |
#include <CGAL/boost/graph/copy_face_graph.h> | |
#include <iostream> | |
#include <unordered_set> | |
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; | |
typedef CGAL::Polyhedron_3<Kernel> Polyhedron; | |
typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> Surface_mesh; | |
int main() | |
{ | |
using namespace std; | |
Surface_mesh mesh_in, mesh_out; | |
Polyhedron mesh; | |
string path; | |
cout << "input Mesh path with '/' in it \n (e.g C:/dev/CGAL-4.10/examples/Surface_mesh_segmentation/data/cactus.off)?" << std::endl; | |
cin >> path; | |
OpenMesh::IO::read_mesh(mesh_in, path); | |
CGAL::copy_face_graph(mesh_in, mesh); | |
// create a property-map for SDF values | |
typedef std::map<Polyhedron::Facet_const_handle, double> Facet_double_map; | |
Facet_double_map internal_sdf_map; | |
boost::associative_property_map<Facet_double_map> sdf_property_map(internal_sdf_map); | |
// compute SDF values using default parameters for number of rays, and cone angle | |
CGAL::sdf_values(mesh, sdf_property_map); | |
// create a property-map for segment-ids | |
typedef std::map<Polyhedron::Facet_const_handle, std::size_t> Facet_int_map; | |
Facet_int_map internal_segment_map; | |
boost::associative_property_map<Facet_int_map> segment_property_map(internal_segment_map); | |
//Soft Clustering | |
// segment the mesh using default parameters for number of levels, and smoothing lambda | |
// Any other scalar values can be used instead of using SDF values computed using the CGAL function | |
std::size_t number_of_segments = CGAL::segmentation_from_sdf_values(mesh, sdf_property_map, segment_property_map); | |
const std::size_t number_of_clusters = 9; // use 4 clusters in soft clustering | |
const double smoothing_lambda = 0.3; // importance of surface features, suggested to be in-between [0,1] | |
// Note that we can use the same SDF values (sdf_property_map) over and over again for segmentation. | |
// This feature is relevant for segmenting the mesh several times with different parameters. | |
Facet_int_map internal_segment_mapBig; | |
boost::associative_property_map<Facet_int_map> segment_property_mapBig(internal_segment_mapBig); | |
//Hard Clustering | |
CGAL::segmentation_from_sdf_values( | |
mesh, sdf_property_map, segment_property_mapBig, number_of_clusters, smoothing_lambda); | |
std::cout << "Number of segments: " << number_of_segments << std::endl; | |
// Aggregate cluster segment-ids into set | |
std::unordered_set<std::string> pain; | |
for (Polyhedron::Facet_const_iterator facet_it = mesh.facets_begin(); | |
facet_it != mesh.facets_end(); ++facet_it) { | |
pain.insert(std::to_string(segment_property_mapBig[facet_it])); | |
} | |
int j = 0; | |
int i = 0; | |
std::cout << "CLUSTERED OUT: " << pain.size() << std::endl; | |
//Save each cluster individually | |
for (auto cluster : pain) { | |
++j; | |
std::cout << "started: " << i << std::endl; | |
const auto filter = [&](const Polyhedron::Halfedge_const_iterator& h) { | |
auto result = false; | |
auto current_id = std::to_string(segment_property_mapBig[h->facet()]); | |
if (cluster == current_id) { | |
result = !result; | |
} | |
return result; | |
}; | |
std::size_t num_component; | |
CGAL::Counting_output_iterator output_it(&num_component); | |
std::vector<Polyhedron> v; | |
//Filter all connected mesh segments from this cluster | |
CGAL::internal::corefinement::extract_connected_components(mesh, filter, std::back_inserter(v)); | |
std::cout << "extracted! " << v.size() << std::endl; | |
//Save segments bigger than 1 face | |
for (auto p : v) { | |
if (p.size_of_facets() > 3) { | |
Surface_mesh mesh_out; | |
CGAL::copy_face_graph(p, mesh_out); | |
auto name = "data/" + std::to_string(j) + "_part_" + std::to_string(++i) + ".obj"; | |
if (!OpenMesh::IO::write_mesh(mesh_out, name)) | |
{ | |
std::cout << "write error on " << name << std::endl; | |
} | |
} | |
} | |
} | |
std::cout << std::endl; | |
std::cin.get(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment