From 8fc0e08356fb336f212323bd93c2fa1b6dd5f2ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 16 Feb 2024 12:01:30 +0100 Subject: [PATCH] Fix Isosurfacing_3's Image_3 IO: ref to 'grid' in 'values' must be stable --- .../CGAL/Isosurfacing_3/Cartesian_grid_3.h | 70 ++++++++++++++----- .../include/CGAL/Isosurfacing_3/IO/Image_3.h | 54 ++++++-------- .../Interpolated_discrete_values_3.h | 1 + ...ogically_correct_marching_cubes_functors.h | 1 - .../Isosurfacing_3/interpolation_schemes_3.h | 2 +- 5 files changed, 76 insertions(+), 52 deletions(-) diff --git a/Isosurfacing_3/include/CGAL/Isosurfacing_3/Cartesian_grid_3.h b/Isosurfacing_3/include/CGAL/Isosurfacing_3/Cartesian_grid_3.h index bfb13e426ea..c1a8ee484f9 100644 --- a/Isosurfacing_3/include/CGAL/Isosurfacing_3/Cartesian_grid_3.h +++ b/Isosurfacing_3/include/CGAL/Isosurfacing_3/Cartesian_grid_3.h @@ -89,7 +89,39 @@ private: Geom_traits m_gt; +private: + void compute_spacing() + { + auto x_coord = m_gt.compute_x_3_object(); + auto y_coord = m_gt.compute_y_3_object(); + auto z_coord = m_gt.compute_z_3_object(); + auto vertex = m_gt.construct_vertex_3_object(); + + // calculate grid spacing + const Point_3& min_p = vertex(m_bbox, 0); + const Point_3& max_p = vertex(m_bbox, 7); + const FT x_span = x_coord(max_p) - x_coord(min_p); + const FT y_span = y_coord(max_p) - y_coord(min_p); + const FT z_span = z_coord(max_p) - z_coord(min_p); + + const FT d_x = x_span / (m_sizes[0] - 1); + const FT d_y = y_span / (m_sizes[1] - 1); + const FT d_z = z_span / (m_sizes[2] - 1); + + m_spacing = make_array(d_x, d_y, d_z); + } + public: + /*! + * \brief Default constructor + */ + Cartesian_grid_3() + : m_bbox{Point_3{0, 0, 0}, Point_3{0, 0, 0}}, + m_sizes{2, 2, 2}, + m_spacing{0, 0, 0}, + m_gt{Geom_traits()} + { } + /** * \brief creates a %Cartesian grid with `xdim * ydim * zdim` grid vertices. * @@ -112,22 +144,7 @@ public: m_sizes{xdim, ydim, zdim}, m_gt{gt} { - auto x_coord = m_gt.compute_x_3_object(); - auto y_coord = m_gt.compute_y_3_object(); - auto z_coord = m_gt.compute_z_3_object(); - auto vertex = m_gt.construct_vertex_3_object(); - - // calculate grid spacing - const Point_3& min_p = vertex(bbox, 0); - const Point_3& max_p = vertex(bbox, 7); - const FT x_span = x_coord(max_p) - x_coord(min_p); - const FT y_span = y_coord(max_p) - y_coord(min_p); - const FT z_span = z_coord(max_p) - z_coord(min_p); - - const FT d_x = x_span / (xdim - 1); - const FT d_y = y_span / (ydim - 1); - const FT d_z = z_span / (zdim - 1); - m_spacing = make_array(d_x, d_y, d_z); + compute_spacing(); } /** @@ -221,6 +238,15 @@ public: */ const Iso_cuboid_3& bbox() const { return m_bbox; } + /** + * sets the bounding box of the %Cartesian grid and recomputes the spacing. + */ + void set_bbox(const Iso_cuboid_3& bbox) + { + m_bbox = bbox; + compute_spacing(); + } + /** * \return the spacing of the %Cartesian grid, that is a vector whose coordinates are * the grid steps in the `x`, `y`, and `z` directions, respectively @@ -242,6 +268,16 @@ public: */ std::size_t zdim() const { return m_sizes[2]; } + /** + * sets the number of grid vertices in the `x`, `y`, and `z` directions, respectively, + * and recomputes the spacing. + */ + void set_sizes(const std::size_t xdim, const std::size_t ydim, const std::size_t zdim) + { + m_sizes = {xdim, ydim, zdim}; + compute_spacing(); + } + public: /** * \brief gets the canonical index of a grid cell given its indices. @@ -251,8 +287,6 @@ public: const std::size_t k) const { CGAL_precondition(i < m_sizes[0] && j < m_sizes[1] && k < m_sizes[2]); - - // convert (i, j, k) into a linear index, e.g. to access the scalar values / gradient vectors return (k * m_sizes[1] + j) * m_sizes[0] + i; } diff --git a/Isosurfacing_3/include/CGAL/Isosurfacing_3/IO/Image_3.h b/Isosurfacing_3/include/CGAL/Isosurfacing_3/IO/Image_3.h index f1bc964004d..946c0b9aa1f 100644 --- a/Isosurfacing_3/include/CGAL/Isosurfacing_3/IO/Image_3.h +++ b/Isosurfacing_3/include/CGAL/Isosurfacing_3/IO/Image_3.h @@ -32,59 +32,49 @@ namespace IO { * The dimensions and bounding box are read from the image. The values stored * in the image must be of type `Geom_traits::FT` or implicitly convertible to it. * - * \tparam K must be a model of `IsosurfacingTraits_3` + * \tparam Grid must be `CGAL::Cartesian_grid_3` whose `GeomTraits` is a model of `IsosurfacingTraits_3` + * \tparam Values must be `CGAL::Interpolated_discrete_values_3` * * \param image the image providing the data - * \param k the traits + * \param grid the grid + * \tparam values the values */ -template -std::pair, - Interpolated_discrete_values_3 > > -read_Image_3(const CGAL::Image_3& image, - const K& k = K()) +template +bool read_Image_3(const CGAL::Image_3& image, + Grid& grid, + Values& values) { - using Grid = Cartesian_grid_3; - using Values = Interpolated_discrete_values_3; + using Geom_traits = typename Grid::Geom_traits; + using FT = typename Geom_traits::FT; + using Point_3 = typename Geom_traits::Point_3; + using Iso_cuboid_3 = typename Geom_traits::Iso_cuboid_3; - using FT = typename K::FT; - using Point_3 = typename K::Point_3; - using Iso_cuboid_3 = typename K::Iso_cuboid_3; - - auto point = k.construct_point_3_object(); - auto iso_cuboid = k.construct_iso_cuboid_3_object(); - - Iso_cuboid_3 bbox; + auto point = grid.geom_traits().construct_point_3_object(); + auto iso_cuboid = grid.geom_traits().construct_iso_cuboid_3_object(); // compute bounding box const FT max_x = image.tx() + (image.xdim() - 1) * image.vx(); const FT max_y = image.ty() + (image.ydim() - 1) * image.vy(); const FT max_z = image.tz() + (image.zdim() - 1) * image.vz(); - bbox = iso_cuboid(point(image.tx(), image.ty(), image.tz()), - point(max_x, max_y, max_z)); + Iso_cuboid_3 bbox = iso_cuboid(point(image.tx(), image.ty(), image.tz()), + point(max_x, max_y, max_z)); // get spacing // std::array spacing = make_array(image.vx(), image.vy(), image.vz()); // get sizes - std::array sizes; - sizes[0] = image.xdim(); - sizes[1] = image.ydim(); - sizes[2] = image.zdim(); - - Grid grid { bbox, sizes[0], sizes[1], sizes[2], k }; - - Values values { grid }; + grid.set_bbox(bbox); + grid.set_sizes(image.xdim(), image.ydim(), image.zdim()); // copy values - for(std::size_t x=0; x