Skip to content

Instantly share code, notes, and snippets.

@OlegJakushkin
Last active August 3, 2017 18:22
Show Gist options
  • Save OlegJakushkin/f16c3dde15bb46ecbf1a71f2a014fc9e to your computer and use it in GitHub Desktop.
Save OlegJakushkin/f16c3dde15bb46ecbf1a71f2a014fc9e to your computer and use it in GitHub Desktop.
#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