diff --git a/BGL/include/CGAL/boost/parameter.h b/BGL/include/CGAL/boost/parameter.h index d4f213919d2..496a7b46ac6 100644 --- a/BGL/include/CGAL/boost/parameter.h +++ b/BGL/include/CGAL/boost/parameter.h @@ -110,6 +110,7 @@ BOOST_PARAMETER_NAME( (pointer_to_stop_atomic_boolean, tag ) pointer_to_stop_ato BOOST_PARAMETER_NAME( (function, tag ) function_) BOOST_PARAMETER_NAME( (bounding_object, tag ) bounding_object_) BOOST_PARAMETER_NAME( (relative_error_bound, tag ) relative_error_bound_) +BOOST_PARAMETER_NAME( (weights, tag) weights_) BOOST_PARAMETER_NAME( (p_rng, tag ) p_rng_) BOOST_PARAMETER_NAME( (null_subdomain_index, tag ) null_subdomain_index_) BOOST_PARAMETER_NAME( (construct_surface_patch_index, tag ) construct_surface_patch_index_) diff --git a/CGAL_ImageIO/include/CGAL/Image_3.h b/CGAL_ImageIO/include/CGAL/Image_3.h index 90242dc48d7..2c0965f9289 100644 --- a/CGAL_ImageIO/include/CGAL/Image_3.h +++ b/CGAL_ImageIO/include/CGAL/Image_3.h @@ -157,6 +157,11 @@ public: return ::evaluate(image(),i,j,k); } + bool is_valid() const + { + return image_ptr.get() != nullptr; + } + public: bool read(const char* file) diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image.cpp index 70d26c890f1..d12fed5b42d 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -35,38 +34,28 @@ using namespace CGAL::parameters; using Word_type = unsigned char; using Subdomain_index = int; -using Wrapper = CGAL::Mesh_3::Image_plus_weights_to_labeled_function_wrapper< - CGAL::Image_3, K, Word_type, - unsigned char, // Weights_type, - Subdomain_index>; - int main(int argc, char* argv[]) { - /// [Loads images] + /// [Loads image] const char* fname = (argc > 1) ? argv[1] : "data/liver.inr.gz"; - const float sigma = (argc > 2) ? atof(argv[2]) : 1.f; CGAL::Image_3 image; if(!image.read(fname)){ std::cerr << "Error: Cannot read file " << fname << std::endl; return EXIT_FAILURE; } - /// [Loads images] + /// [Loads image] /// [Generate weights] - CGAL::Image_3 weights = + const float sigma = (argc > 2) ? atof(argv[2]) : 1.f; + CGAL::Image_3 img_weights = CGAL::Mesh_3::generate_weights(image, sigma, (unsigned char)(1)); /// [Generate weights] /// [Domain creation] - Mesh_domain domain = argc > 2 - ? Mesh_domain(Wrapper(image, weights), - CGAL::Mesh_3::internal::compute_bounding_box(image), - relative_error_bound = 1e-6) - : Mesh_domain::create_labeled_image_mesh_domain( - image, // null_subdomain_index - // = [](auto) { return true; - // }, - relative_error_bound = 1e-6); + Mesh_domain domain + = Mesh_domain::create_labeled_image_mesh_domain(image, + weights = img_weights, + relative_error_bound = 1e-6); /// [Domain creation] // Mesh criteria diff --git a/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h b/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h index 0dceef7f282..d5dd4c0550b 100644 --- a/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h @@ -39,6 +39,8 @@ // support for `CGAL::Image_3` #include #include +#include +#include // support for implicit functions #include @@ -418,6 +420,7 @@ public: (optional (relative_error_bound_, (const FT&), FT(1e-3)) + (weights_, (const CGAL::Image_3&), CGAL::Image_3()) (value_outside_, *, 0) (p_rng_, (CGAL::Random*), (CGAL::Random*)(0)) (image_values_to_subdomain_indices_, *, @@ -429,18 +432,37 @@ public: ) { namespace p = CGAL::parameters; - return Labeled_mesh_domain_3 - (create_labeled_image_wrapper + if (weights_.is_valid()) + { + return Labeled_mesh_domain_3 + (create_weighted_labeled_image_wrapper (image_, + weights_, image_values_to_subdomain_indices_, value_outside_), - Mesh_3::internal::compute_bounding_box(image_), - p::relative_error_bound = relative_error_bound_, - p::p_rng = p_rng_, - p::null_subdomain_index = - create_null_subdomain_index(null_subdomain_index_), - p::construct_surface_patch_index = - create_construct_surface_patch_index(construct_surface_patch_index_)); + Mesh_3::internal::compute_bounding_box(image_), + p::relative_error_bound = relative_error_bound_, + p::p_rng = p_rng_, + p::null_subdomain_index = + create_null_subdomain_index(null_subdomain_index_), + p::construct_surface_patch_index = + create_construct_surface_patch_index(construct_surface_patch_index_)); + } + else + { + return Labeled_mesh_domain_3 + (create_labeled_image_wrapper + (image_, + image_values_to_subdomain_indices_, + value_outside_), + Mesh_3::internal::compute_bounding_box(image_), + p::relative_error_bound = relative_error_bound_, + p::p_rng = p_rng_, + p::null_subdomain_index = + create_null_subdomain_index(null_subdomain_index_), + p::construct_surface_patch_index = + create_construct_surface_patch_index(construct_surface_patch_index_)); + } } BOOST_PARAMETER_MEMBER_FUNCTION( @@ -866,6 +888,32 @@ protected: transform_fct(value_outside)); } + template + static + Function + create_weighted_labeled_image_wrapper_with_know_word_type + (const CGAL::Image_3& image, + const CGAL::Image_3& weights, + const Functor& image_values_to_subdomain_indices, + const FT& value_outside) + { + using Mesh_3::internal::Create_labeled_image_values_to_subdomain_indices; + typedef Create_labeled_image_values_to_subdomain_indices C_i_v_t_s_i; + typedef typename C_i_v_t_s_i::type Image_values_to_subdomain_indices; + Image_values_to_subdomain_indices transform_fct = + C_i_v_t_s_i()(image_values_to_subdomain_indices); + + typedef Mesh_3::Image_plus_weights_to_labeled_function_wrapper< + Image_word_type, + unsigned char, // Weights_type, + Subdomain_index> Wrapper; + return Wrapper(image, + weights, + transform_fct, + transform_fct(value_outside)); + } + template static Function @@ -885,6 +933,27 @@ protected: return Function(); } + template + static + Function + create_weighted_labeled_image_wrapper(const CGAL::Image_3& image, + const CGAL::Image_3& weights, + const Functor& image_values_to_subdomain_indices, + const FT& value_outside) + { + CGAL_IMAGE_IO_CASE(image.image(), + return create_weighted_labeled_image_wrapper_with_know_word_type + (image, + weights, + image_values_to_subdomain_indices, + value_outside); + ); + CGAL_error_msg("This place should never be reached, because it would mean " + "the image word type is a type that is not handled by " + "CGAL_ImageIO."); + return Function(); + } + static Construct_surface_patch_index create_construct_surface_patch_index(const Null_functor&) { diff --git a/Mesh_3/include/CGAL/Mesh_3/Image_plus_weights_to_labeled_function_wrapper.h b/Mesh_3/include/CGAL/Mesh_3/Image_plus_weights_to_labeled_function_wrapper.h index 775da605e76..a0c1a5c64ae 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Image_plus_weights_to_labeled_function_wrapper.h +++ b/Mesh_3/include/CGAL/Mesh_3/Image_plus_weights_to_labeled_function_wrapper.h @@ -72,26 +72,25 @@ namespace Mesh_3 { * Wraps a pair of images into a labeled function which takes his values into * N. Uses weighted trilinear interpolation. */ -template + typename Image_values_to_labels = std::function > class Image_plus_weights_to_labeled_function_wrapper { public: + // Types typedef Return_type return_type; typedef Image_word_type word_type; - typedef typename BGT::Point_3 Point_3; + typedef CGAL::Image_3 Image_; /// Constructor Image_plus_weights_to_labeled_function_wrapper (const Image_& image, const Image_& weights_image, - const Transform& transform = Transform(), + Image_values_to_labels transform = Identity(), const Return_type value_outside = 0) : r_im_(image) , r_weights_im_(weights_image) @@ -111,9 +110,9 @@ public: * @param p the input point * @return the label at point \c p */ - return_type operator()(const Point_3& p, const bool = true) const + template + return_type operator()(const Point_3& p) const { - return transform( r_im_.template labellized_trilinear_interpolation( CGAL::to_double(p.x()), @@ -127,7 +126,7 @@ private: /// Labeled image to wrap const Image_& r_im_; const Image_& r_weights_im_; - const Transform transform; + const Image_values_to_labels transform; const Return_type value_outside; CGAL::ImageIO::Weighted_indicator_factory indicator_factory;