diff --git a/.gitignore b/.gitignore
index c6f90d2c446..0e72878b613 100644
--- a/.gitignore
+++ b/.gitignore
@@ -131,8 +131,6 @@ CGAL_ImageIO/examples/CGALimageIO/convert_raw_image_to_inr
CGAL_ImageIO/examples/CGALimageIO/makefile
CGAL_ImageIO/examples/CGALimageIO/test_imageio
CGAL_ImageIO/src/CGAL_ImageIO/Makefile
-CGAL_ImageIO/test/CGAL_ImageIO/Makefile
-CGAL_ImageIO/test/CGAL_ImageIO/test_trilinear_interpolation
Circular_kernel_3/demo/Circular_kernel_3/Circular_kernel_3_demo
Circular_kernel_3/demo/Circular_kernel_3/Makefile
Circular_kernel_3/test/Circular_kernel_3/cgal_test_with_cmake
@@ -384,6 +382,7 @@ Mesh_3/applications/stat_mesh
Mesh_3/applications/test_off
Mesh_3/demo/Mesh_3/Makefile
Mesh_3/demo/Mesh_3/Mesh_3
+Mesh_3/demo/Mesh_3/build*
Mesh_3/demo/Mesh_3/out.mesh
Mesh_3/doxygen
Mesh_3/examples/Mesh_3/*.cgal
@@ -483,6 +482,54 @@ Mesh_3/test/Mesh_3/test_robust_weighted_circumcenter
/Mesh_3/test/Mesh_3/test_mesh_3_implicit_vector_to_labeled_function_wrapper
/Mesh_3/test/Mesh_3/test_mesh_3_labeled_mesh_domain_3
/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image
+Min_annulus_d/*.aux
+Min_annulus_d/*.bbl
+Min_annulus_d/*.blg
+Min_annulus_d/*.dvi
+Min_annulus_d/*.idx
+Min_annulus_d/*.ilg
+Min_annulus_d/*.ind
+Min_annulus_d/*.log
+Min_annulus_d/*.mxp
+Min_annulus_d/*.toc
+Min_annulus_d/.dep
+Min_annulus_d/.obj
+Min_annulus_d/.tmp
+Min_annulus_d/Makefile
+Min_annulus_d/bin
+Min_annulus_d/doc_ps
+Min_circle_2/*.aux
+Min_circle_2/*.bbl
+Min_circle_2/*.blg
+Min_circle_2/*.dvi
+Min_circle_2/*.idx
+Min_circle_2/*.ilg
+Min_circle_2/*.ind
+Min_circle_2/*.log
+Min_circle_2/*.mxp
+Min_circle_2/*.toc
+Min_circle_2/.dep
+Min_circle_2/.obj
+Min_circle_2/.tmp
+Min_circle_2/Makefile
+Min_circle_2/bin
+Min_circle_2/doc_ps
+Min_ellipse_2/*.aux
+Min_ellipse_2/*.bbl
+Min_ellipse_2/*.blg
+Min_ellipse_2/*.dvi
+Min_ellipse_2/*.idx
+Min_ellipse_2/*.ilg
+Min_ellipse_2/*.ind
+Min_ellipse_2/*.log
+Min_ellipse_2/*.mxp
+Min_ellipse_2/*.toc
+Min_ellipse_2/.dep
+Min_ellipse_2/.obj
+Min_ellipse_2/.tmp
+Min_ellipse_2/Makefile
+Min_ellipse_2/bin
+Min_ellipse_2/doc_ps
Minkowski_sum_3/test/Minkowski_sum_3/CMakeLists.txt
Minkowski_sum_3/test/Minkowski_sum_3/cgal_test_with_cmake
Nef_2/test/Nef_2/CMakeLists.txt
diff --git a/CGAL_ImageIO/include/CGAL/Image_3.h b/CGAL_ImageIO/include/CGAL/Image_3.h
index f77e5e6ca3c..34133fc176a 100644
--- a/CGAL_ImageIO/include/CGAL/Image_3.h
+++ b/CGAL_ImageIO/include/CGAL/Image_3.h
@@ -234,7 +234,8 @@ Image_3::trilinear_interpolation(const Coord_type& x,
Image_transform transform) const
{
// Check on double/float coordinates, because (int)-0.1 gives 0
- if ( x < 0 || y < 0 || z < 0 ) return value_outside;
+ if ( x < 0 || y < 0 || z < 0 )
+ return Target_word_type(value_outside);
const Coord_type lx = x / image()->vx;
const Coord_type ly = y / image()->vy;
@@ -251,7 +252,7 @@ Image_3::trilinear_interpolation(const Coord_type& x,
ly >= dimy-1 ||
lx >= dimx-1)
{
- return transform(value_outside);
+ return Target_word_type(transform(value_outside));
}
// images are indexed by (z,y,x)
@@ -290,17 +291,17 @@ Image_3::trilinear_interpolation(const Coord_type& x,
Image_word_type* ptr = (Image_word_type*)image()->data;
ptr += i1 * dimxy + j1 * dimx + k1;
- const Target_word_type a = transform(*ptr);
- const Target_word_type e = transform(*(ptr+1));
+ const Target_word_type a = Target_word_type(transform(*ptr));
+ const Target_word_type e = Target_word_type(transform(*(ptr+1)));
ptr += dimxy; // i2 * dimxy + j1 * dimx + k1;
- const Target_word_type b = transform(*ptr);
- const Target_word_type f = transform(*(ptr+1));
+ const Target_word_type b = Target_word_type(transform(*ptr));
+ const Target_word_type f = Target_word_type(transform(*(ptr+1)));
ptr += dimx; // i2 * dimxy + j2 * dimx + k1
- const Target_word_type c = transform(*ptr);
- const Target_word_type g = transform(*(ptr+1));
+ const Target_word_type c = Target_word_type(transform(*ptr));
+ const Target_word_type g = Target_word_type(transform(*(ptr+1)));
ptr -= dimxy; // i1 * dimxy + j2 * dimx + k1
- const Target_word_type d = transform(*ptr);
- const Target_word_type h = transform(*(ptr+1));
+ const Target_word_type d = Target_word_type(transform(*ptr));
+ const Target_word_type h = Target_word_type(transform(*(ptr+1)));
// const Target_word_type a = ((Image_word_type*)image()->data)[i1 * dimxy + j1 * dimx + k1];
@@ -312,7 +313,7 @@ Image_3::trilinear_interpolation(const Coord_type& x,
// const Target_word_type g = ((Image_word_type*)image()->data)[i2 * dimxy + j2 * dimx + k2];
// const Target_word_type h = ((Image_word_type*)image()->data)[i1 * dimxy + j2 * dimx + k2];
-// const Target_word_type outside = transform(value_outside);
+// const Target_word_type outside = Target_word_type(transform(value_outside);
// if(x < 0.f ||
// y < 0.f ||
diff --git a/Installation/changes.html b/Installation/changes.html
index 90f5fbd74f4..dbd6c1af3fe 100644
--- a/Installation/changes.html
+++ b/Installation/changes.html
@@ -160,6 +160,10 @@ and src/ directories).
+
3D Mesh Generation
+
+ - Add support of 3D gray level images as input for the tetrahedral mesh generation.
+
Polygon Mesh Processing
diff --git a/Mesh_3/doc/Mesh_3/CGAL/Gray_image_mesh_domain_3.h b/Mesh_3/doc/Mesh_3/CGAL/Gray_image_mesh_domain_3.h
new file mode 100644
index 00000000000..3dfabf18aec
--- /dev/null
+++ b/Mesh_3/doc/Mesh_3/CGAL/Gray_image_mesh_domain_3.h
@@ -0,0 +1,74 @@
+namespace CGAL {
+
+/*!
+\ingroup PkgMesh_3Domains
+
+The class `Gray_image_mesh_domain_3` implements a domain described by a 3D
+gray image. A 3D gray image is a grid of voxels,
+where each voxel is associated with a gray level value.
+This class is a model of the concept `MeshDomain_3`.
+The domain to be discretized is the union of voxels that lie inside a surface
+described by an isolevel value, called \a isovalue.
+
+This class includes a member function that provides, by interpolation,
+a gray level value at any query point.
+An intersection between a segment and bounding
+surfaces is detected when both segment endpoints are associated with gray level
+values which are on both sides of the isovalue.
+The intersection is then constructed by bisection.
+The bisection stops when the query segment is shorter than a given error bound
+`e`. This error bound is given by `e=d`\f$ \times\f$`bound` where `d` is the
+length of the diagonal of the bounding box (in world coordinates) and
+`bound` is the argument passed to the constructor of `Labeled_image_mesh_domain_3`.
+
+
+\tparam Image is the type of the input image.
+This parameter must be a model of the concept
+`LabeledImage_3`.
+
+\tparam BGT is a geometric traits class which provides
+the basic operations to implement
+intersection tests and intersection computations
+through a bisection method. This parameter must be instantiated
+with a model of the concept `BisectionGeometricTraits_3`.
+
+\tparam Image_word_type is the data type encoded in the `Image`
+input file
+
+
+\cgalModels `MeshDomain_3`
+
+\sa `BisectionGeometricTraits_3`
+\sa `CGAL::make_mesh_3()`.
+
+*/
+template
+class Gray_image_mesh_domain_3
+{
+public:
+
+/// \name Creation
+/// @{
+
+/*!
+Construction from an image.
+@param image the input image
+@param iso_value the isovalue, inside `image`,
+ of the surface describing the boundary of the object to be meshed
+@param value_outside the value attached to voxels outside of the domain
+ to be meshed
+@param error_bound is relative to the size of the image.
+*/
+ Gray_image_mesh_domain_3(
+ const Image& image,
+ const Image_word_type iso_value,
+ const Image_word_type value_outside =
+ std::numeric_limits::max(),
+ const BGT::FT& error_bound = BGT::FT(1e-3));
+
+/// @}
+
+}; /* end Labeled_image_mesh_domain_3 */
+} /* end namespace CGAL */
diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt
index 98d807b2410..71fed5ae5e6 100644
--- a/Mesh_3/doc/Mesh_3/PackageDescription.txt
+++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt
@@ -98,6 +98,7 @@ and their associated classes:
- `CGAL::Polyhedral_mesh_domain_3`
- `CGAL::Polyhedral_mesh_domain_with_features_3`
- `CGAL::Labeled_image_mesh_domain_3`
+- `CGAL::Gray_image_mesh_domain_3`
- `CGAL::Mesh_domain_with_polyline_features_3`
- `CGAL::Mesh_polyhedron_3`
- `CGAL::Triangle_accessor_3,K>`
diff --git a/Mesh_3/examples/Mesh_3/CMakeLists.txt b/Mesh_3/examples/Mesh_3/CMakeLists.txt
index f1dd4198064..57585206126 100644
--- a/Mesh_3/examples/Mesh_3/CMakeLists.txt
+++ b/Mesh_3/examples/Mesh_3/CMakeLists.txt
@@ -66,6 +66,7 @@ if ( CGAL_FOUND )
create_single_source_cgal_program( "mesh_optimization_example.cpp" )
create_single_source_cgal_program( "mesh_optimization_lloyd_example.cpp" )
create_single_source_cgal_program( "mesh_3D_image.cpp" )
+ create_single_source_cgal_program( "mesh_3D_gray_image.cpp" )
create_single_source_cgal_program( "mesh_3D_image_variable_size.cpp" )
else()
message( STATUS "NOTICE: The examples mesh_3D_image.cpp, mesh_3D_image_variable_size.cpp, mesh_optimization_example.cpp and mesh_optimization_lloyd_example.cpp need CGAL_ImageIO to be configured with ZLIB support, and will not be compiled." )
diff --git a/Mesh_3/examples/Mesh_3/data/skull_2.9.inr b/Mesh_3/examples/Mesh_3/data/skull_2.9.inr
new file mode 100644
index 00000000000..d8dc23e59d9
Binary files /dev/null and b/Mesh_3/examples/Mesh_3/data/skull_2.9.inr differ
diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp
new file mode 100644
index 00000000000..c7b61315113
--- /dev/null
+++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp
@@ -0,0 +1,75 @@
+// Copyright (c) 2012 GeometryFactory (France).
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org).
+// You can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// Licensees holding a valid commercial license may use this file in
+// accordance with the commercial license agreement provided with the software.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $URL$
+// $Id$
+//
+//
+// Author(s) : Laurent Rineau
+//
+//******************************************************************************
+// File Description :
+//***************************************************************************
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+typedef float Image_word_type;
+
+// Domain
+typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
+typedef CGAL::Gray_image_mesh_domain_3 > > Mesh_domain;
+
+// Triangulation
+typedef CGAL::Mesh_triangulation_3::type Tr;
+typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3;
+
+// Criteria
+typedef CGAL::Mesh_criteria_3
Mesh_criteria;
+
+// To avoid verbose function and named parameters call
+using namespace CGAL::parameters;
+
+int main()
+{
+ // Loads image
+ CGAL::Image_3 image;
+ if(!image.read("data/skull_2.9.inr")) return 1;
+
+ // Domain
+ Mesh_domain domain(image, std::bind1st(std::less(), 2.9f), 0.f);
+
+ // Mesh criteria
+ Mesh_criteria criteria(facet_angle=30, facet_size=6, facet_distance=2,
+ cell_radius_edge_ratio=3, cell_size=8);
+
+ // Meshing
+ C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria);
+
+ // Output
+ std::ofstream medit_file("out.mesh");
+ c3t3.output_to_medit(medit_file);
+
+ return 0;
+}
diff --git a/Mesh_3/include/CGAL/Gray_image_mesh_domain_3.h b/Mesh_3/include/CGAL/Gray_image_mesh_domain_3.h
new file mode 100644
index 00000000000..574f888be65
--- /dev/null
+++ b/Mesh_3/include/CGAL/Gray_image_mesh_domain_3.h
@@ -0,0 +1,121 @@
+// Copyright (c) 2009 INRIA Sophia-Antipolis (France).
+// Copyright (c) 2012 GeometryFactory Sarl (France).
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org).
+// You can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// Licensees holding a valid commercial license may use this file in
+// accordance with the commercial license agreement provided with the software.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $URL$
+// $Id$
+//
+//
+// Author(s) : Stephane Tayeb, Laurent Rineau
+//
+
+#ifndef CGAL_GRAY_IMAGE_MESH_DOMAIN_3_H
+#define CGAL_GRAY_IMAGE_MESH_DOMAIN_3_H
+
+#include
+#include
+#include
+
+#include
+#include
+
+namespace CGAL {
+
+/**
+ * @class Gray_image_mesh_domain_3
+ *
+ *
+ */
+template >,
+ typename Subdomain_index = int>
+class Gray_image_mesh_domain_3
+ : public Labeled_mesh_domain_3<
+ Mesh_3::Image_to_labeled_function_wrapper ,
+ BGT>
+{
+public:
+ typedef Mesh_3::Image_to_labeled_function_wrapper Wrapper;
+
+ typedef Labeled_mesh_domain_3 Base;
+
+ typedef typename Base::Sphere_3 Sphere_3;
+ typedef typename Base::FT FT;
+ typedef BGT Geom_traits;
+ typedef CGAL::Bbox_3 Bbox_3;
+
+ /// Constructor
+ Gray_image_mesh_domain_3(const Image& image,
+ const Image_word_type iso_value,
+ const Image_word_type value_outside =
+ (std::numeric_limits::max)(),
+ const FT& error_bound = FT(1e-3),
+ CGAL::Random* p_rng = NULL)
+ : Base(Wrapper(image,
+ Transform(std::less(), iso_value),
+ value_outside),
+ compute_bounding_box(image),
+ error_bound,
+ p_rng)
+ {}
+
+ Gray_image_mesh_domain_3(const Image& image,
+ const Transform& transform,
+ const Image_word_type value_outside =
+ (std::numeric_limits::max)(),
+ const FT& error_bound = FT(1e-3),
+ CGAL::Random* p_rng = NULL)
+ : Base(Wrapper(image, transform, value_outside),
+ compute_bounding_box(image),
+ error_bound,
+ p_rng)
+ {}
+
+ /// Destructor
+ virtual ~Gray_image_mesh_domain_3() {}
+
+
+private:
+ /// Returns a box enclosing image \c im
+ Bbox_3 compute_bounding_box(const Image& im) const
+ {
+ return Bbox_3(-1,-1,-1,
+ im.xdim()*im.vx()+1, im.ydim()*im.vy()+1, im.zdim()*im.vz()+1);
+ }
+
+private:
+ // Disabled copy constructor & assignment operator
+ typedef Gray_image_mesh_domain_3 Self;
+ Gray_image_mesh_domain_3(const Self& src);
+ Self& operator=(const Self& src);
+
+}; // end class Gray_image_mesh_domain_3
+
+
+
+} // end namespace CGAL
+
+
+
+#endif // CGAL_GRAY_IMAGE_MESH_DOMAIN_3_H
diff --git a/Mesh_3/include/CGAL/IO/File_medit.h b/Mesh_3/include/CGAL/IO/File_medit.h
index 929346e327f..452fe542041 100644
--- a/Mesh_3/include/CGAL/IO/File_medit.h
+++ b/Mesh_3/include/CGAL/IO/File_medit.h
@@ -795,11 +795,11 @@ output_to_medit(std::ostream& os,
{
V[vit] = inum++;
Point_3 p = vit->point();
- os << CGAL::to_double(p.x()) << " "
- << CGAL::to_double(p.y()) << " "
- << CGAL::to_double(p.z()) << " "
+ os << CGAL::to_double(p.x()) << ' '
+ << CGAL::to_double(p.y()) << ' '
+ << CGAL::to_double(p.z()) << ' '
<< get(vertex_pmap, vit)
- << '\n';
+ << '\n';
}
//-------------------------------------------------------
@@ -822,7 +822,7 @@ output_to_medit(std::ostream& os,
if (i != fit->second)
{
const Vertex_handle& vh = (*fit).first->vertex(i);
- os << V[vh] << " ";
+ os << V[vh] << ' ';
}
}
os << get(facet_pmap, *fit) << '\n';
@@ -835,7 +835,7 @@ output_to_medit(std::ostream& os,
if (i != fit->second)
{
const Vertex_handle& vh = (*fit).first->vertex(i);
- os << V[vh] << " ";
+ os << V[vh] << ' ';
}
}
os << get(facet_twice_pmap, *fit) << '\n';
@@ -853,7 +853,7 @@ output_to_medit(std::ostream& os,
++cit )
{
for (int i=0; i<4; i++)
- os << V[cit->vertex(i)] << " ";
+ os << V[cit->vertex(i)] << ' ';
os << get(cell_pmap, cit) << '\n';
}
diff --git a/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h b/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h
index 62eefd5afe6..19513ebad7c 100644
--- a/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h
+++ b/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h
@@ -42,7 +42,11 @@ namespace CGAL {
*/
template >
+ typename Image_word_type = unsigned char,
+ typename Subdomain_index = int,
+ class Wrapper = Mesh_3::Image_to_labeled_function_wrapper >
class Labeled_image_mesh_domain_3
: public Labeled_mesh_domain_3
{
diff --git a/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h b/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h
index be3288e1920..1e8863de3f9 100644
--- a/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h
+++ b/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h
@@ -3026,6 +3026,9 @@ move_point_topo_change(const Vertex_handle& old_vertex,
std::back_inserter(insertion_conflict_boundary),
std::inserter(removal_conflict_cells, removal_conflict_cells.end()),
could_lock_zone);
+ if (insertion_conflict_cells.empty())
+ return old_vertex;//new_position coincides with an existing vertex (not old_vertex)
+ //and old_vertex should not be removed of the nb_vertices will change
reset_circumcenter_cache(removal_conflict_cells);
reset_sliver_cache(removal_conflict_cells);
reset_circumcenter_cache(insertion_conflict_cells);
diff --git a/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h b/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h
index c200376f8df..9f26118da66 100644
--- a/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h
+++ b/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h
@@ -27,9 +27,9 @@
#ifndef CGAL_MESH_3_IMAGE_TO_LABELED_FUNCTION_WRAPPER_H
#define CGAL_MESH_3_IMAGE_TO_LABELED_FUNCTION_WRAPPER_H
-
-
#include
+#include
+
namespace CGAL {
@@ -46,6 +46,8 @@ template,
+ bool labeled_image = true,
bool use_trilinear_interpolation=true>
class Image_to_labeled_function_wrapper
{
@@ -56,8 +58,13 @@ public:
typedef typename BGT::Point_3 Point_3;
/// Constructor
- Image_to_labeled_function_wrapper(const Image_& image)
- : r_im_(image) {}
+ Image_to_labeled_function_wrapper(const Image_& image,
+ const Transform& transform = Transform(),
+ const Image_word_type value_outside = 0)
+ : r_im_(image)
+ , transform(transform)
+ , value_outside(value_outside)
+ {}
// Default copy constructor and assignment operator are ok
@@ -73,12 +80,23 @@ public:
{
if ( use_trilinear_interpolation )
{
- return static_cast(
+ if ( labeled_image )
+ {
+ return static_cast(transform(
r_im_.labellized_trilinear_interpolation(
CGAL::to_double(p.x()),
CGAL::to_double(p.y()),
CGAL::to_double(p.z()),
- word_type(0)));
+ value_outside)));
+ } else {
+ return static_cast(transform(
+ static_cast(
+ r_im_.template trilinear_interpolation(
+ CGAL::to_double(p.x()),
+ CGAL::to_double(p.y()),
+ CGAL::to_double(p.z()),
+ value_outside))));
+ }
}
else
{
@@ -101,13 +119,16 @@ public:
}
const word_type* data = static_cast(r_im_.data());
- return data[ pz*dimy*dimx + py*dimx + px ];
+ return static_cast(transform(
+ data[pz*dimy*dimx + py*dimx + px]));
}
}
private:
/// Labeled image to wrap
const Image_& r_im_;
+ const Transform transform;
+ const Image_word_type value_outside;
}; // end class Image_to_labeled_function_wrapper
diff --git a/Mesh_3/include/CGAL/Mesh_3/global_parameters.h b/Mesh_3/include/CGAL/Mesh_3/global_parameters.h
index fcb93bf19d1..e3fce732319 100644
--- a/Mesh_3/include/CGAL/Mesh_3/global_parameters.h
+++ b/Mesh_3/include/CGAL/Mesh_3/global_parameters.h
@@ -86,6 +86,7 @@ BOOST_PARAMETER_NAME( (dump_after_refine_prefix, tag ) dump_after_refine_prefix_
BOOST_PARAMETER_NAME( (dump_after_glob_opt_prefix, tag ) dump_after_glob_opt_prefix_)
BOOST_PARAMETER_NAME( (dump_after_perturb_prefix, tag ) dump_after_perturb_prefix_)
BOOST_PARAMETER_NAME( (dump_after_exude_prefix, tag ) dump_after_exude_prefix_)
+BOOST_PARAMETER_NAME( (number_of_initial_points, tag) number_of_initial_points_)
CGAL_PRAGMA_DIAG_POP
} // end namespace parameters
diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h
index de9d6490331..8a2fadb6b46 100644
--- a/Mesh_3/include/CGAL/make_mesh_3.h
+++ b/Mesh_3/include/CGAL/make_mesh_3.h
@@ -135,7 +135,8 @@ namespace Mesh_3 {
template < typename C3T3, typename MeshDomain, typename MeshCriteria >
void
-init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&)
+init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&,
+ const int nb_initial_points)
{
typedef typename MeshDomain::Point_3 Point_3;
typedef typename MeshDomain::Index Index;
@@ -145,7 +146,11 @@ init_c3t3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria&)
// Mesh initialization : get some points and add them to the mesh
Initial_points_vector initial_points;
- domain.construct_initial_points_object()(std::back_inserter(initial_points));
+ if (nb_initial_points > 0)
+ domain.construct_initial_points_object()(std::back_inserter(initial_points),
+ nb_initial_points);
+ else //use default number of points
+ domain.construct_initial_points_object()(std::back_inserter(initial_points));
// Insert points and set their index and dimension
for ( Ipv_iterator it = initial_points.begin() ;
@@ -211,7 +216,8 @@ struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures >
void operator()(C3T3& c3t3,
const MD& domain,
const MC& criteria,
- bool with_features)
+ bool with_features,
+ const int nb_initial_points = -1)
{
if ( with_features )
{
@@ -219,7 +225,7 @@ struct C3t3_initializer < C3T3, MD, MC, false, HasFeatures >
<< " without features !" << std::endl;
}
- init_c3t3(c3t3,domain,criteria);
+ init_c3t3(c3t3,domain,criteria,nb_initial_points);
}
};
@@ -231,10 +237,11 @@ struct C3t3_initializer < C3T3, MD, MC, true, HasFeatures >
void operator()(C3T3& c3t3,
const MD& domain,
const MC& criteria,
- bool with_features)
+ bool with_features,
+ const int nb_initial_points = -1)
{
C3t3_initializer < C3T3, MD, MC, true, typename MD::Has_features >()
- (c3t3,domain,criteria,with_features);
+ (c3t3,domain,criteria,with_features,nb_initial_points);
}
};
@@ -247,10 +254,11 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_true >
void operator()(C3T3& c3t3,
const MD& domain,
const MC& criteria,
- bool with_features)
+ bool with_features,
+ const int nb_initial_points = -1)
{
if ( with_features ) { init_c3t3_with_features(c3t3,domain,criteria); }
- else { init_c3t3(c3t3,domain,criteria); }
+ else { init_c3t3(c3t3,domain,criteria,nb_initial_points); }
}
};
@@ -263,7 +271,8 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false >
void operator()(C3T3& c3t3,
const MD& domain,
const MC& criteria,
- bool with_features)
+ bool with_features,
+ const int nb_initial_points = -1)
{
if ( with_features )
{
@@ -271,7 +280,7 @@ struct C3t3_initializer < C3T3, MD, MC, true, CGAL::Tag_false >
<< " without features !" << std::endl;
}
- init_c3t3(c3t3,domain,criteria);
+ init_c3t3(c3t3,domain,criteria,nb_initial_points);
}
};
@@ -412,15 +421,17 @@ void make_mesh_3_impl(C3T3& c3t3,
MeshDomain,
MeshCriteria,
internal::Mesh_3::has_Has_features::value > () (c3t3,
- domain,
- criteria,
- with_features);
-
+ domain,
+ criteria,
+ with_features,
+ mesh_options.number_of_initial_points);
+
// If c3t3 initialization is not sufficient (may happen if there is only
// a planar curve as feature for example), add some surface points
if ( c3t3.triangulation().dimension() != 3 )
{
- internal::Mesh_3::init_c3t3(c3t3, domain, criteria);
+ internal::Mesh_3::init_c3t3(c3t3, domain, criteria,
+ mesh_options.number_of_initial_points);
}
CGAL_assertion( c3t3.triangulation().dimension() == 3 );
diff --git a/Mesh_3/include/CGAL/refine_mesh_3.h b/Mesh_3/include/CGAL/refine_mesh_3.h
index 17c63c9c449..24fd93fce29 100644
--- a/Mesh_3/include/CGAL/refine_mesh_3.h
+++ b/Mesh_3/include/CGAL/refine_mesh_3.h
@@ -177,6 +177,7 @@ namespace parameters {
, dump_after_glob_opt_prefix()
, dump_after_perturb_prefix()
, dump_after_exude_prefix()
+ , number_of_initial_points()
{}
std::string dump_after_init_prefix;
@@ -185,6 +186,7 @@ namespace parameters {
std::string dump_after_glob_opt_prefix;
std::string dump_after_perturb_prefix;
std::string dump_after_exude_prefix;
+ int number_of_initial_points;
}; // end struct Mesh_3_options
@@ -289,6 +291,7 @@ namespace parameters {
(dump_after_glob_opt_prefix_, (std::string), "" )
(dump_after_perturb_prefix_, (std::string), "" )
(dump_after_exude_prefix_, (std::string), "" )
+ (number_of_initial_points_, (int), -1)
)
)
{
@@ -300,7 +303,8 @@ namespace parameters {
options.dump_after_glob_opt_prefix=dump_after_glob_opt_prefix_;
options.dump_after_perturb_prefix=dump_after_perturb_prefix_;
options.dump_after_exude_prefix=dump_after_exude_prefix_;
-
+ options.number_of_initial_points=number_of_initial_points_;
+
return options;
}
diff --git a/Mesh_3/test/Mesh_3/CMakeLists.txt b/Mesh_3/test/Mesh_3/CMakeLists.txt
index 7cf30f717fc..47a766b7d45 100644
--- a/Mesh_3/test/Mesh_3/CMakeLists.txt
+++ b/Mesh_3/test/Mesh_3/CMakeLists.txt
@@ -39,6 +39,7 @@ if ( CGAL_FOUND )
create_single_source_cgal_program( "test_mesh_criteria_creation.cpp" )
if(CGAL_ImageIO_USE_ZLIB)
create_single_source_cgal_program( "test_meshing_3D_image.cpp" )
+ create_single_source_cgal_program( "test_meshing_3D_gray_image.cpp" )
else()
message(STATUS "test_meshing_3D_image requires the ZLIB library, and will not be compiled.")
endif()
diff --git a/Mesh_3/test/Mesh_3/data/skull_2.9.inr b/Mesh_3/test/Mesh_3/data/skull_2.9.inr
new file mode 100644
index 00000000000..d8dc23e59d9
Binary files /dev/null and b/Mesh_3/test/Mesh_3/data/skull_2.9.inr differ
diff --git a/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp b/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp
new file mode 100644
index 00000000000..2658e3be79d
--- /dev/null
+++ b/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp
@@ -0,0 +1,109 @@
+// Copyright (c) 2015 GeometryFactory (France).
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org).
+// You can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// Licensees holding a valid commercial license may use this file in
+// accordance with the commercial license agreement provided with the software.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $URL$
+// $Id$
+//
+//
+// Author(s) : Laurent Rineau, Jane Tournois
+//
+//******************************************************************************
+// File Description :
+//***************************************************************************
+
+#include "test_meshing_utilities.h"
+#include
+#include
+#include
+
+#include
+
+// To avoid verbose function and named parameters call
+using namespace CGAL::parameters;
+
+template
+struct Image_tester : public Tester
+{
+public:
+ void image() const
+ {
+ typedef float Image_word_type;
+ typedef CGAL::Image_3 Image;
+ typedef CGAL::Gray_image_mesh_domain_3<
+ Image,
+ K_e_i,
+ Image_word_type,
+ std::binder1st< std::less > > Mesh_domain;
+
+ typedef typename CGAL::Mesh_triangulation_3<
+ Mesh_domain,
+ CGAL::Kernel_traits::Kernel,
+ Concurrency_tag>::type Tr;
+ typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3;
+ typedef CGAL::Mesh_criteria_3
Mesh_criteria;
+
+ CGAL_USE_TYPE(typename Mesh_domain::Surface_patch_index);
+
+ //-------------------------------------------------------
+ // Data generation
+ //-------------------------------------------------------
+ Image image;
+ if (!image.read("data/skull_2.9.inr"))
+ {
+ std::cout << "Image reading error. Exit test.\n";
+ return;
+ }
+
+ std::cout << "\tSeed is\t"
+ << CGAL::default_random.get_seed() << std::endl;
+
+ // Domain
+ Mesh_domain domain(image,
+ std::bind1st(std::less(), 2.9f),//transform
+ 0.f, //value_outside
+ 1e-3, //error_bound
+ &CGAL::default_random);//random generator for determinism
+
+ // Mesh criteria
+ Mesh_criteria criteria(facet_angle = 30,
+ facet_size = 6,
+ facet_distance = 2,
+ cell_radius_edge_ratio = 3,
+ cell_size = 8);
+
+ // Mesh generation
+ C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria,
+ mesh_3_options(number_of_initial_points = 30));
+
+ // Verify
+ this->verify_c3t3_volume(c3t3, 1236086 * 0.95, 1236086 * 1.05);
+ this->verify(c3t3, domain, criteria, Bissection_tag());
+ }
+};
+
+
+int main()
+{
+ Image_tester<> test_epic;
+ std::cerr << "Mesh generation from a 3D image:\n";
+ test_epic.image();
+
+#ifdef CGAL_LINKED_WITH_TBB
+ Image_tester test_epic_p;
+ std::cerr << "Parallel mesh generation from a 3D image:\n";
+ test_epic_p.image();
+#endif
+
+ return EXIT_SUCCESS;
+}