From c3b842dc46599c0044ec7d43236be9c6ef33579a Mon Sep 17 00:00:00 2001 From: iyaz Date: Tue, 16 Apr 2013 20:58:40 +0300 Subject: [PATCH] Using diagonal of AABB box to convert rays to segments --- .../SDF_calculation.h | 74 +++++++++++++------ .../Surface_mesh_segmentation.h | 5 +- 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/SDF_calculation.h b/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/SDF_calculation.h index a427b0ea9a6..e03e4383ed4 100644 --- a/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/SDF_calculation.h +++ b/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/SDF_calculation.h @@ -96,29 +96,43 @@ private: Tree tree; + double max_diagonal; + bool use_diagonal; public: /** * Construct AABB tree with a mesh. * @param mesh `CGAL Polyhedron` on which AABB tree constructed * @param build_kd_tree requirement on internal kd-tree (it is only required if find_closest_with_AABB_distance is planned to use) + * @param use_diagonal if true: calculates diagonal of AABB tree and cast segments instead of rays using diagonal length * @param traits trait object */ SDF_calculation(const Polyhedron& mesh, bool build_kd_tree = false, - GeomTraits traits = GeomTraits()) - : traits(traits), - angle_functor(traits.angle_3_object()), - scale_functor(traits.construct_scaled_vector_3_object()), - sum_functor(traits.construct_sum_of_vectors_3_object()), - normal_functor(traits.construct_normal_3_object()), - unit_normal_functor(traits.construct_unit_normal_3_object()), - translated_point_functor(traits.construct_translated_point_3_object()), - centroid_functor(traits.construct_centroid_3_object()) { + bool use_diagonal = true, GeomTraits traits = GeomTraits()) + : + use_diagonal(use_diagonal), + traits(traits), + angle_functor(traits.angle_3_object()), + scale_functor(traits.construct_scaled_vector_3_object()), + sum_functor(traits.construct_sum_of_vectors_3_object()), + normal_functor(traits.construct_normal_3_object()), + unit_normal_functor(traits.construct_unit_normal_3_object()), + translated_point_functor(traits.construct_translated_point_3_object()), + centroid_functor(traits.construct_centroid_3_object()) { tree.insert(mesh.facets_begin(), mesh.facets_end()); tree.build(); if(build_kd_tree) { tree.accelerate_distance_queries(); } + + if(use_diagonal) { + CGAL::Bbox_3 bbox = tree.bbox(); + max_diagonal = + std::sqrt( + CGAL::squared_distanceC3( bbox.xmin(), bbox.ymin(), bbox.zmin(), bbox.xmax(), + bbox.ymax(), bbox.zmax() ) + ); + } } /** @@ -259,8 +273,8 @@ public: Plane plane(center, normal); Vector v1 = plane.base1(), v2 = plane.base2(); - v1 = scale_functor(v1, static_cast(1.0 / CGAL::sqrt(v1.squared_length()))); - v2 = scale_functor(v2, static_cast(1.0 / CGAL::sqrt(v2.squared_length()))); + v1 = scale_functor(v1, FT(1.0 / CGAL::sqrt(v1.squared_length()))); + v2 = scale_functor(v2, FT(1.0 / CGAL::sqrt(v2.squared_length()))); std::vector > ray_distances; ray_distances.reserve(disk_samples.size()); @@ -268,7 +282,7 @@ public: const FT normal_multiplier( cos(cone_angle / 2.0) ); const FT disk_multiplier ( sin(cone_angle / 2.0) ); - Vector scaled_normal = scale_functor(normal, normal_multiplier); + const Vector& scaled_normal = scale_functor(normal, normal_multiplier); for(Disk_samples_list::const_iterator sample_it = disk_samples.begin(); sample_it != disk_samples.end(); ++sample_it) { @@ -277,20 +291,38 @@ public: Primitive_id closest_id; Vector disk_vector = sum_functor( - scale_functor(v1, static_cast(disk_multiplier * sample_it->get<0>())), - scale_functor(v2, static_cast(disk_multiplier * sample_it->get<1>())) ); + scale_functor(v1, FT(disk_multiplier * sample_it->get<0>())), + scale_functor(v2, FT(disk_multiplier * sample_it->get<1>())) ); Vector ray_direction = sum_functor(scaled_normal, disk_vector); - Ray ray(center, ray_direction); + if(use_diagonal) { + FT max_distance( max_diagonal / std::sqrt(ray_direction.squared_length())); + const Vector& scaled_direction = scale_functor(ray_direction, max_distance); + const Vector& target_vector = sum_functor( Vector(Point(ORIGIN), center), + scaled_direction); + const Point& target_point = translated_point_functor(Point(ORIGIN), + target_vector); + Segment segment(center, target_point); - if(traits.is_degenerate_3_object()(ray)) { - CGAL_warning(false && - "A degenerate ray is constructed. Most probable reason is using CGAL_PI as cone_angle parameter and also picking center of disk as a sample."); + if(traits.is_degenerate_3_object()(segment)) { + CGAL_warning(false && + "A degenerate segment is constructed. Most probable reason is using CGAL_PI as cone_angle parameter and also picking center of disk as a sample."); + } + + boost::tie(is_intersected, intersection_is_acute, min_distance, closest_id) + = cast_and_return_minimum(segment, skip, accept_if_acute); + } else { + Ray ray(center, ray_direction); + + if(traits.is_degenerate_3_object()(ray)) { + CGAL_warning(false && + "A degenerate ray is constructed. Most probable reason is using CGAL_PI as cone_angle parameter and also picking center of disk as a sample."); + } + + boost::tie(is_intersected, intersection_is_acute, min_distance, closest_id) + = cast_and_return_minimum(ray, skip, accept_if_acute); } - boost::tie(is_intersected, intersection_is_acute, min_distance, closest_id) - = cast_and_return_minimum(ray, skip, accept_if_acute); - if(!intersection_is_acute) { continue; } diff --git a/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h b/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h index 783646b7d40..6b0ee2a6965 100644 --- a/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h +++ b/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h @@ -96,8 +96,9 @@ public: calculate_sdf_values(double cone_angle, int number_of_rays, SDFPropertyMap sdf_pmap) { // calculate sdf values - SDF_calculation_class(mesh, traits).calculate_sdf_values(cone_angle, - number_of_rays, sdf_pmap); + SDF_calculation_class sdf_calculator(mesh, false, true, traits); + sdf_calculator.calculate_sdf_values(mesh.facets_begin(), mesh.facets_end(), + cone_angle, number_of_rays, sdf_pmap); // apply post-processing steps check_zero_sdf_values(sdf_pmap); Filter()(mesh, get_window_size(), sdf_pmap);