mirror of https://github.com/CGAL/cgal
Merge pull request #1699 from sloriot/SMSeg-match_concepts
Update code to match documented concepts
This commit is contained in:
commit
cfc0ac01c3
|
|
@ -84,7 +84,8 @@ public:
|
||||||
std::map<face_descriptor, std::size_t> neighbors;
|
std::map<face_descriptor, std::size_t> neighbors;
|
||||||
NeighborSelector()(mesh,*facet_it, window_size,
|
NeighborSelector()(mesh,*facet_it, window_size,
|
||||||
neighbors); // gather neighbors in the window
|
neighbors); // gather neighbors in the window
|
||||||
double current_sdf_value = values[*facet_it];
|
|
||||||
|
double current_sdf_value = get(values, *facet_it);
|
||||||
|
|
||||||
double range_parameter_actual;
|
double range_parameter_actual;
|
||||||
if(!range_parameter) {
|
if(!range_parameter) {
|
||||||
|
|
@ -92,7 +93,7 @@ public:
|
||||||
double deviation = 0.0;
|
double deviation = 0.0;
|
||||||
for(typename std::map<face_descriptor, std::size_t>::iterator it =
|
for(typename std::map<face_descriptor, std::size_t>::iterator it =
|
||||||
neighbors.begin(); it != neighbors.end(); ++it) {
|
neighbors.begin(); it != neighbors.end(); ++it) {
|
||||||
deviation += std::pow(values[it->first] - current_sdf_value, 2);
|
deviation += std::pow(get(values, it->first) - current_sdf_value, 2);
|
||||||
}
|
}
|
||||||
deviation = std::sqrt(deviation / neighbors.size());
|
deviation = std::sqrt(deviation / neighbors.size());
|
||||||
if(deviation == 0.0) {
|
if(deviation == 0.0) {
|
||||||
|
|
@ -112,12 +113,12 @@ public:
|
||||||
neighbors.begin(); it != neighbors.end(); ++it) {
|
neighbors.begin(); it != neighbors.end(); ++it) {
|
||||||
double spatial_weight = gaussian_function(static_cast<double>(it->second),
|
double spatial_weight = gaussian_function(static_cast<double>(it->second),
|
||||||
spatial_parameter_actual);
|
spatial_parameter_actual);
|
||||||
double range_weight = gaussian_function(values[it->first] - current_sdf_value,
|
double range_weight = gaussian_function(get(values, it->first) - current_sdf_value,
|
||||||
range_parameter_actual);
|
range_parameter_actual);
|
||||||
// we can use just spatial_weight for Gaussian filtering
|
// we can use just spatial_weight for Gaussian filtering
|
||||||
double weight = spatial_weight * range_weight;
|
double weight = spatial_weight * range_weight;
|
||||||
|
|
||||||
total_sdf_value += values[it->first] * weight;
|
total_sdf_value += get(values, it->first) * weight;
|
||||||
total_weight += weight;
|
total_weight += weight;
|
||||||
}
|
}
|
||||||
smoothed_values.push_back(total_sdf_value / total_weight);
|
smoothed_values.push_back(total_sdf_value / total_weight);
|
||||||
|
|
@ -127,7 +128,7 @@ public:
|
||||||
for(boost::tie(facet_it,fend) = faces(mesh);
|
for(boost::tie(facet_it,fend) = faces(mesh);
|
||||||
facet_it != fend;
|
facet_it != fend;
|
||||||
++facet_it, ++smoothed_value_it) {
|
++facet_it, ++smoothed_value_it) {
|
||||||
values[*facet_it] = *smoothed_value_it;
|
put(values, *facet_it, *smoothed_value_it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -204,9 +204,9 @@ public:
|
||||||
cone_angle, true, disk_samples);
|
cone_angle, true, disk_samples);
|
||||||
|
|
||||||
if(sdf_value) {
|
if(sdf_value) {
|
||||||
sdf_values[*facet_begin] = *sdf_value;
|
put(sdf_values, *facet_begin, *sdf_value);
|
||||||
} else {
|
} else {
|
||||||
sdf_values[*facet_begin] = -1.0;
|
put(sdf_values, *facet_begin, -1.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ public:
|
||||||
face_iterator facet_it, fend;
|
face_iterator facet_it, fend;
|
||||||
for(boost::tie(facet_it,fend) = faces(mesh);
|
for(boost::tie(facet_it,fend) = faces(mesh);
|
||||||
facet_it != fend; ++facet_it) {
|
facet_it != fend; ++facet_it) {
|
||||||
double sdf_value = sdf_values[*facet_it];
|
double sdf_value = get(sdf_values, *facet_it);
|
||||||
CGAL_assertion(sdf_value == -1 || sdf_value >= 0); // validity check
|
CGAL_assertion(sdf_value == -1 || sdf_value >= 0); // validity check
|
||||||
if(sdf_value != -1.0) {
|
if(sdf_value != -1.0) {
|
||||||
min_sdf = (std::min)(sdf_value, min_sdf);
|
min_sdf = (std::min)(sdf_value, min_sdf);
|
||||||
|
|
@ -95,7 +95,7 @@ public:
|
||||||
std::size_t nb_valid_neighbors = 0;
|
std::size_t nb_valid_neighbors = 0;
|
||||||
do {
|
do {
|
||||||
if(!(face(opposite(*facet_circulator,mesh),mesh) == boost::graph_traits<Polyhedron>::null_face())) {
|
if(!(face(opposite(*facet_circulator,mesh),mesh) == boost::graph_traits<Polyhedron>::null_face())) {
|
||||||
double neighbor_sdf = sdf_values[face(opposite(*facet_circulator,mesh),mesh)];
|
double neighbor_sdf = get(sdf_values, face(opposite(*facet_circulator,mesh),mesh));
|
||||||
if(neighbor_sdf != -1) {
|
if(neighbor_sdf != -1) {
|
||||||
total_neighbor_sdf += neighbor_sdf;
|
total_neighbor_sdf += neighbor_sdf;
|
||||||
++nb_valid_neighbors;
|
++nb_valid_neighbors;
|
||||||
|
|
@ -107,7 +107,7 @@ public:
|
||||||
still_missing_facets.push_back(*facet_it);
|
still_missing_facets.push_back(*facet_it);
|
||||||
} else {
|
} else {
|
||||||
sdf_value = total_neighbor_sdf / nb_valid_neighbors;
|
sdf_value = total_neighbor_sdf / nb_valid_neighbors;
|
||||||
sdf_values[*facet_it] = sdf_value;
|
put(sdf_values, *facet_it, sdf_value);
|
||||||
// trying to update min_sdf is pointless, since it is interpolated one of the neighbors sdf will be smaller than it
|
// trying to update min_sdf is pointless, since it is interpolated one of the neighbors sdf will be smaller than it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -116,7 +116,7 @@ public:
|
||||||
for(typename std::vector<face_descriptor>::iterator it =
|
for(typename std::vector<face_descriptor>::iterator it =
|
||||||
still_missing_facets.begin();
|
still_missing_facets.begin();
|
||||||
it != still_missing_facets.end(); ++it) {
|
it != still_missing_facets.end(); ++it) {
|
||||||
sdf_values[*it] = min_sdf;
|
put(sdf_values, *it, min_sdf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,7 +128,7 @@ public:
|
||||||
face_iterator facet_it, fend;
|
face_iterator facet_it, fend;
|
||||||
for(boost::tie(facet_it,fend) = faces(mesh);
|
for(boost::tie(facet_it,fend) = faces(mesh);
|
||||||
facet_it != fend; ++facet_it) {
|
facet_it != fend; ++facet_it) {
|
||||||
double sdf_value = sdf_values[*facet_it];
|
double sdf_value = get(sdf_values, *facet_it);
|
||||||
max_sdf = (std::max)(sdf_value, max_sdf);
|
max_sdf = (std::max)(sdf_value, max_sdf);
|
||||||
min_sdf = (std::min)(sdf_value, min_sdf);
|
min_sdf = (std::min)(sdf_value, min_sdf);
|
||||||
}
|
}
|
||||||
|
|
@ -154,7 +154,7 @@ public:
|
||||||
face_iterator facet_it, fend;
|
face_iterator facet_it, fend;
|
||||||
for(boost::tie(facet_it,fend) = faces(mesh);
|
for(boost::tie(facet_it,fend) = faces(mesh);
|
||||||
facet_it != fend; ++facet_it) {
|
facet_it != fend; ++facet_it) {
|
||||||
sdf_values[*facet_it] = (sdf_values[*facet_it] - min_sdf) / max_min_dif;
|
put(sdf_values, *facet_it, (get(sdf_values, *facet_it) - min_sdf) / max_min_dif);
|
||||||
}
|
}
|
||||||
return std::make_pair(min_sdf, max_sdf);
|
return std::make_pair(min_sdf, max_sdf);
|
||||||
}
|
}
|
||||||
|
|
@ -295,7 +295,7 @@ public:
|
||||||
for(boost::tie(facet_it,fend) = faces(mesh);
|
for(boost::tie(facet_it,fend) = faces(mesh);
|
||||||
facet_it != fend;
|
facet_it != fend;
|
||||||
++facet_it, ++label_it) {
|
++facet_it, ++label_it) {
|
||||||
segment_pmap[*facet_it] = *label_it; // fill with cluster-ids
|
put(segment_pmap, *facet_it, *label_it); // fill with cluster-ids
|
||||||
}
|
}
|
||||||
if(clusters_to_segments) {
|
if(clusters_to_segments) {
|
||||||
// assign a segment id for each facet
|
// assign a segment id for each facet
|
||||||
|
|
@ -351,7 +351,7 @@ private:
|
||||||
face_iterator facet_it, fend;
|
face_iterator facet_it, fend;
|
||||||
for(boost::tie(facet_it,fend) = faces(mesh);
|
for(boost::tie(facet_it,fend) = faces(mesh);
|
||||||
facet_it != fend; ++facet_it) {
|
facet_it != fend; ++facet_it) {
|
||||||
double log_normalized = log(sdf_values[*facet_it] * CGAL_NORMALIZATION_ALPHA +
|
double log_normalized = log(get(sdf_values, *facet_it) * CGAL_NORMALIZATION_ALPHA +
|
||||||
1) / log(CGAL_NORMALIZATION_ALPHA + 1);
|
1) / log(CGAL_NORMALIZATION_ALPHA + 1);
|
||||||
normalized_sdf_values.push_back(log_normalized);
|
normalized_sdf_values.push_back(log_normalized);
|
||||||
}
|
}
|
||||||
|
|
@ -458,7 +458,7 @@ private:
|
||||||
face_iterator facet_it, fend;
|
face_iterator facet_it, fend;
|
||||||
for(boost::tie(facet_it,fend) = faces(mesh);
|
for(boost::tie(facet_it,fend) = faces(mesh);
|
||||||
facet_it != fend; ++facet_it) {
|
facet_it != fend; ++facet_it) {
|
||||||
if(segments[*facet_it] <
|
if(get(segments, *facet_it) <
|
||||||
number_of_clusters) { // not visited by depth_first_traversal
|
number_of_clusters) { // not visited by depth_first_traversal
|
||||||
double average_sdf_value = breadth_first_traversal(*facet_it, segment_id,
|
double average_sdf_value = breadth_first_traversal(*facet_it, segment_id,
|
||||||
sdf_values, segments);
|
sdf_values, segments);
|
||||||
|
|
@ -485,8 +485,8 @@ private:
|
||||||
// . Then place its sorted index to pmap
|
// . Then place its sorted index to pmap
|
||||||
for(boost::tie(facet_it,fend) = faces(mesh);
|
for(boost::tie(facet_it,fend) = faces(mesh);
|
||||||
facet_it != fend; ++facet_it) {
|
facet_it != fend; ++facet_it) {
|
||||||
std::size_t segment_id = segments[*facet_it] - number_of_clusters;
|
std::size_t segment_id = get(segments, *facet_it) - number_of_clusters;
|
||||||
segments[*facet_it] = segment_id_to_sorted_id_map[segment_id];
|
put(segments, *facet_it, segment_id_to_sorted_id_map[segment_id]);
|
||||||
}
|
}
|
||||||
return segment_id - number_of_clusters;
|
return segment_id - number_of_clusters;
|
||||||
}
|
}
|
||||||
|
|
@ -507,10 +507,10 @@ private:
|
||||||
std::queue<face_descriptor> facet_queue;
|
std::queue<face_descriptor> facet_queue;
|
||||||
facet_queue.push(root);
|
facet_queue.push(root);
|
||||||
|
|
||||||
std::size_t prev_segment_id = segments[root];
|
std::size_t prev_segment_id = get(segments, root);
|
||||||
segments[root] = segment_id;
|
put(segments, root, segment_id);
|
||||||
|
|
||||||
double total_sdf_value = sdf_values[root];
|
double total_sdf_value = get(sdf_values, root);
|
||||||
std::size_t visited_facet_count = 1;
|
std::size_t visited_facet_count = 1;
|
||||||
|
|
||||||
while(!facet_queue.empty()) {
|
while(!facet_queue.empty()) {
|
||||||
|
|
@ -522,11 +522,11 @@ private:
|
||||||
continue; // no facet to traversal
|
continue; // no facet to traversal
|
||||||
}
|
}
|
||||||
face_descriptor neighbor = face(opposite(*facet_circulator,mesh),mesh);
|
face_descriptor neighbor = face(opposite(*facet_circulator,mesh),mesh);
|
||||||
if(prev_segment_id == segments[neighbor]) {
|
if(prev_segment_id == get(segments, neighbor)) {
|
||||||
segments[neighbor] = segment_id;
|
put(segments, neighbor, segment_id);
|
||||||
facet_queue.push(neighbor);
|
facet_queue.push(neighbor);
|
||||||
|
|
||||||
total_sdf_value += sdf_values[neighbor];
|
total_sdf_value += get(sdf_values, neighbor);
|
||||||
++visited_facet_count;
|
++visited_facet_count;
|
||||||
}
|
}
|
||||||
} while( ++facet_circulator != done);
|
} while( ++facet_circulator != done);
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
* @brief The API which contains free template functions for SDF computation and mesh segmentation.
|
* @brief The API which contains free template functions for SDF computation and mesh segmentation.
|
||||||
*/
|
*/
|
||||||
#include <CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h>
|
#include <CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h>
|
||||||
|
#include <CGAL/boost/graph/helpers.h>
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <CGAL/Kernel/global_functions_3.h>
|
#include <CGAL/Kernel/global_functions_3.h>
|
||||||
|
|
||||||
|
|
@ -65,7 +66,7 @@ sdf_values( const TriangleMesh& triangle_mesh,
|
||||||
* It is possible to compute raw SDF values (without post-processing). In such a case,
|
* It is possible to compute raw SDF values (without post-processing). In such a case,
|
||||||
* -1 is used to indicate when no SDF value could be computed for a facet.
|
* -1 is used to indicate when no SDF value could be computed for a facet.
|
||||||
*
|
*
|
||||||
* @pre @a triangle_mesh.is_pure_triangle()
|
* @pre `is_triangle_mesh(triangle_mesh)`
|
||||||
*
|
*
|
||||||
* @tparam TriangleMesh a model of `FaceListGraph`
|
* @tparam TriangleMesh a model of `FaceListGraph`
|
||||||
* @tparam SDFPropertyMap a `ReadWritePropertyMap` with `boost::graph_traits<TriangleMesh>::%face_descriptor` as key and `double` as value type
|
* @tparam SDFPropertyMap a `ReadWritePropertyMap` with `boost::graph_traits<TriangleMesh>::%face_descriptor` as key and `double` as value type
|
||||||
|
|
@ -80,7 +81,7 @@ sdf_values( const TriangleMesh& triangle_mesh,
|
||||||
* @param traits traits class
|
* @param traits traits class
|
||||||
* @param ppmap point property map. An overload is provided with `get(boost::vertex_point,triangle_mesh)` as default.
|
* @param ppmap point property map. An overload is provided with `get(boost::vertex_point,triangle_mesh)` as default.
|
||||||
*
|
*
|
||||||
* @return minimum and maximum raw SDF values if @a postprocess is `true`, otherwise minimum and maximum SDF values (before linear normalization)
|
* @return minimum and maximum raw SDF values if `postprocess` is `true`, otherwise minimum and maximum SDF values (before linear normalization)
|
||||||
*/
|
*/
|
||||||
template <class TriangleMesh, class SDFPropertyMap, class PointPropertyMap
|
template <class TriangleMesh, class SDFPropertyMap, class PointPropertyMap
|
||||||
#ifdef DOXYGEN_RUNNING
|
#ifdef DOXYGEN_RUNNING
|
||||||
|
|
@ -118,7 +119,7 @@ sdf_values( const TriangleMesh& triangle_mesh,
|
||||||
*
|
*
|
||||||
* See the section \ref Surface_mesh_segmentationPostprocessing for more details.
|
* See the section \ref Surface_mesh_segmentationPostprocessing for more details.
|
||||||
*
|
*
|
||||||
* @pre @a triangle_mesh.is_pure_triangle()
|
* @pre `is_triangle_mesh(triangle_mesh)`
|
||||||
* @pre Raw values should be greater or equal to 0. -1 indicates when no value could be computed
|
* @pre Raw values should be greater or equal to 0. -1 indicates when no value could be computed
|
||||||
*
|
*
|
||||||
* @tparam TriangleMesh a model of `FaceListGraph`
|
* @tparam TriangleMesh a model of `FaceListGraph`
|
||||||
|
|
@ -134,7 +135,7 @@ std::pair<double, double>
|
||||||
sdf_values_postprocessing(const TriangleMesh& triangle_mesh,
|
sdf_values_postprocessing(const TriangleMesh& triangle_mesh,
|
||||||
SDFPropertyMap sdf_values_map)
|
SDFPropertyMap sdf_values_map)
|
||||||
{
|
{
|
||||||
CGAL_precondition(triangle_mesh.is_pure_triangle());
|
CGAL_precondition(is_triangle_mesh(triangle_mesh));
|
||||||
return internal::Postprocess_sdf_values<TriangleMesh>().postprocess(triangle_mesh,
|
return internal::Postprocess_sdf_values<TriangleMesh>().postprocess(triangle_mesh,
|
||||||
sdf_values_map);
|
sdf_values_map);
|
||||||
}
|
}
|
||||||
|
|
@ -156,8 +157,8 @@ sdf_values_postprocessing(const TriangleMesh& triangle_mesh,
|
||||||
* \note There is no direct relation between the parameter `number_of_clusters`
|
* \note There is no direct relation between the parameter `number_of_clusters`
|
||||||
* and the final number of segments after segmentation. However, setting a large number of clusters will result in a detailed segmentation of the mesh with a large number of segments.
|
* and the final number of segments after segmentation. However, setting a large number of clusters will result in a detailed segmentation of the mesh with a large number of segments.
|
||||||
*
|
*
|
||||||
* @pre @a triangle_mesh.is_pure_triangle()
|
* @pre `is_triangle_mesh(triangle_mesh)`
|
||||||
* @pre @a number_of_clusters > 0
|
* @pre `number_of_clusters > 0`
|
||||||
*
|
*
|
||||||
* @tparam TriangleMesh a model of `FaceListGraph`
|
* @tparam TriangleMesh a model of `FaceListGraph`
|
||||||
* @tparam SDFPropertyMap a `ReadablePropertyMap` with `boost::graph_traits<TriangleMesh>::%face_descriptor` as key and `double` as value type
|
* @tparam SDFPropertyMap a `ReadablePropertyMap` with `boost::graph_traits<TriangleMesh>::%face_descriptor` as key and `double` as value type
|
||||||
|
|
@ -253,8 +254,8 @@ segmentation_via_sdf_values(const TriangleMesh& triangle_mesh,
|
||||||
* it is more efficient to first compute the SDF values using `CGAL::sdf_values()` and use them in different calls to
|
* it is more efficient to first compute the SDF values using `CGAL::sdf_values()` and use them in different calls to
|
||||||
* `CGAL::segmentation_from_sdf_values()`.
|
* `CGAL::segmentation_from_sdf_values()`.
|
||||||
*
|
*
|
||||||
* @pre @a triangle_mesh.is_pure_triangle()
|
* @pre `is_triangle_mesh(triangle_mesh)`
|
||||||
* @pre @a number_of_clusters > 0
|
* @pre `number_of_clusters > 0`
|
||||||
*
|
*
|
||||||
* @tparam TriangleMesh a model of `FaceListGraph`
|
* @tparam TriangleMesh a model of `FaceListGraph`
|
||||||
* @tparam SegmentPropertyMap a `ReadWritePropertyMap` with `boost::graph_traits<TriangleMesh>::%face_descriptor` as key and `std::size_t` as value type
|
* @tparam SegmentPropertyMap a `ReadWritePropertyMap` with `boost::graph_traits<TriangleMesh>::%face_descriptor` as key and `std::size_t` as value type
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue