Merge remote-tracking branch 'cgal/master' into Iterative_authalic_parameterization

This commit is contained in:
Mael Rouxel-Labbé 2020-07-22 14:25:03 +02:00
commit c5ab12f840
46 changed files with 44514 additions and 203 deletions

View File

@ -189,7 +189,7 @@ example illustrates this for two polyhedral surfaces.
\subsection aabb_tree_examples_7 Trees of Custom Primitives \subsection aabb_tree_examples_7 Trees of Custom Primitives
The AABB tree example folder contains three examples of trees The AABB tree example folder contains three examples of trees
constructed with customize primitives. In \ref AABB_tree/AABB_custom_example.cpp "AABB_custom_example.cpp" constructed with custom primitives. In \ref AABB_tree/AABB_custom_example.cpp "AABB_custom_example.cpp"
the primitive contains triangles which are defined by three pointers the primitive contains triangles which are defined by three pointers
to custom points. In \ref AABB_tree/AABB_custom_triangle_soup_example.cpp "AABB_custom_triangle_soup_example.cpp" all input to custom points. In \ref AABB_tree/AABB_custom_triangle_soup_example.cpp "AABB_custom_triangle_soup_example.cpp" all input
triangles are stored into a single array so as to form a triangle triangles are stored into a single array so as to form a triangle

View File

@ -112,7 +112,7 @@ public:
/*! /*!
Id type: Id type:
- `boost::graph_traits<FaceGraph>::%face_descriptor` if `OneFaceGraphPerTree` is `CGAL::Tag_true` - `boost::graph_traits<FaceGraph>::%face_descriptor` if `OneFaceGraphPerTree` is `CGAL::Tag_true`
- `std::pair<boost::graph_traits<FaceGraph>::%face_descriptor, FaceGraph>` if `OneFaceGraphPerTree` is `CGAL::Tag_false` - `std::pair<boost::graph_traits<FaceGraph>::%face_descriptor, const FaceGraph*>` if `OneFaceGraphPerTree` is `CGAL::Tag_false`
*/ */
unspecified_type Id; unspecified_type Id;

View File

@ -125,8 +125,8 @@ public:
typedef Kernel_traits<Point>::Kernel::Segment_3 Datum; typedef Kernel_traits<Point>::Kernel::Segment_3 Datum;
/*! /*!
Id type: Id type:
- `boost::graph_traits<HalfedgeGraph>::%edge_descriptor if `OneHalfedgeGraphPerTree` is `Tag_true` - `boost::graph_traits<HalfedgeGraph>::%edge_descriptor` if `OneHalfedgeGraphPerTree` is `Tag_true`
- `std::pair<boost::graph_traits<HalfedgeGraph>::edge_descriptor, HalfedgeGraph>` if `OneHalfedgeGraphPerTree` is `Tag_false` - `std::pair<boost::graph_traits<HalfedgeGraph>::%edge_descriptor, const HalfedgeGraph*>` if `OneHalfedgeGraphPerTree` is `Tag_false`
*/ */
unspecified_type Id; unspecified_type Id;
/// @} /// @}
@ -202,4 +202,3 @@ public:
#include <CGAL/enable_warnings.h> #include <CGAL/enable_warnings.h>
#endif // CGAL_AABB_HALFEDGE_GRAPH_SEGMENT_PRIMITIVE_H #endif // CGAL_AABB_HALFEDGE_GRAPH_SEGMENT_PRIMITIVE_H

View File

@ -171,9 +171,11 @@ class AABB_tree;
/// \sa `AABBPrimitiveWithSharedData` /// \sa `AABBPrimitiveWithSharedData`
template<typename GeomTraits, typename AABBPrimitive, typename BboxMap = Default> template<typename GeomTraits, typename AABBPrimitive, typename BboxMap = Default>
class AABB_traits: class AABB_traits
public internal::AABB_tree::AABB_traits_base<AABBPrimitive>, #ifndef DOXYGEN_RUNNING
: public internal::AABB_tree::AABB_traits_base<AABBPrimitive>,
public internal::AABB_tree::AABB_traits_base_2<GeomTraits> public internal::AABB_tree::AABB_traits_base_2<GeomTraits>
#endif
{ {
typedef typename CGAL::Object Object; typedef typename CGAL::Object Object;
public: public:

View File

@ -56,7 +56,7 @@ or <A HREF="https://msdn.microsoft.com/en-us/library/1fe2x6kt(v=vs.140).aspx">`h
The \stl comes with the compiler, and as such no installation is required. The \stl comes with the compiler, and as such no installation is required.
\subsection thirdpartyBoost Boost \subsection thirdpartyBoost Boost
<b>Version 1.58 or later</b> <b>Version 1.62 or later</b>
The \sc{Boost} libraries are a set of portable C++ source libraries. The \sc{Boost} libraries are a set of portable C++ source libraries.
Most of \sc{Boost} libraries are header-only, but a few of them need to be compiled or Most of \sc{Boost} libraries are header-only, but a few of them need to be compiled or

View File

@ -382,8 +382,6 @@ include(${CGAL_MODULES_DIR}/CGAL_Macros.cmake)
include(${CGAL_MODULES_DIR}/CGAL_enable_end_of_configuration_hook.cmake) include(${CGAL_MODULES_DIR}/CGAL_enable_end_of_configuration_hook.cmake)
cgal_setup_module_path() cgal_setup_module_path()
message( STATUS "CGAL_REFERENCE_CACHE_DIR=${CGAL_REFERENCE_CACHE_DIR}" )
if ( RUNNING_CGAL_AUTO_TEST ) if ( RUNNING_CGAL_AUTO_TEST )
message(STATUS "Operating system:") message(STATUS "Operating system:")
execute_process(COMMAND uname -a execute_process(COMMAND uname -a
@ -392,41 +390,6 @@ if ( RUNNING_CGAL_AUTO_TEST )
ERROR_VARIABLE uname_a) ERROR_VARIABLE uname_a)
message(STATUS "${uname_a}") message(STATUS "${uname_a}")
CGAL_display_compiler_version() CGAL_display_compiler_version()
if ( NOT "${CGAL_REFERENCE_CACHE_DIR}" STREQUAL "" )
if ( EXISTS ${CGAL_REFERENCE_CACHE_DIR} )
if ( EXISTS ${CGAL_REFERENCE_CACHE_DIR}/CMakeCache.txt )
message( STATUS "Loading reference cache from ${CGAL_REFERENCE_CACHE_DIR}" )
load_cache( ${CGAL_REFERENCE_CACHE_DIR}
EXCLUDE CGAL_Core_LIBRARY
CGAL_CORE_PACKAGE_DIR
WITH_CGAL_Core
CGAL_INSTALLATION_PACKAGE_DIR
CGAL_MAINTENANCE_PACKAGE_DIR
CGAL_PDB_BINARY_DIR
CGAL_PDB_SOURCE_DIR
CGAL_BINARY_DIR
CGAL_SOURCE_DIR)
# message("List of cache variables:")
## The following lines removes nasty loaded cache values. We do not
## want that the current build tree depends on binaries that were
## build in the reference build tree.
get_property(cache_variables DIRECTORY PROPERTY CACHE_VARIABLES)
foreach(var ${cache_variables})
# get_property(var_value CACHE ${var} PROPERTY VALUE)
# get_property(type CACHE ${var} PROPERTY TYPE)
string(REGEX MATCH "^CGAL(_.*_(DEPENDS|BINARY_DIR)|_.*LIBRARY)$" var_name_matches ${var})
if(var_name_matches)
unset(${var} CACHE)
# else()
# message("${var}:${var_type}=${var_value}")
endif()
endforeach()
endif()
endif()
endif()
endif() endif()
include(CGAL_Common) include(CGAL_Common)

View File

@ -16,6 +16,9 @@ if(NOT POLICY CMP0064)
# Add a fake function to avoid CMake errors # Add a fake function to avoid CMake errors
function(cgal_add_compilation_test) function(cgal_add_compilation_test)
endfunction() endfunction()
# Add a fake function to avoid CMake errors
function(cgal_setup_test_properties)
endfunction()
# Then return, to exit the file # Then return, to exit the file
return() return()
@ -213,7 +216,7 @@ function(cgal_setup_test_properties test_name)
PROPERTY PROPERTY
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/__exec_test_dir) WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/__exec_test_dir)
endif() endif()
set_property(TEST "${test_name}" set_property(TEST "${test_name}"
APPEND PROPERTY FIXTURES_REQUIRED "${PROJECT_NAME}") APPEND PROPERTY FIXTURES_REQUIRED "${PROJECT_NAME}")
if(exe_name) if(exe_name)

View File

@ -1,4 +1,5 @@
find_package( GMP QUIET ) find_package( GMP QUIET )
find_package( MPFR QUIET )
if( GMP_FOUND AND MPFR_FOUND ) if( GMP_FOUND AND MPFR_FOUND )

View File

@ -36,8 +36,9 @@
# define WIN64 # define WIN64
#endif #endif
#ifdef BOOST_MSVC #ifdef _MSC_VER
#define _SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING 1 #define _SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING 1
#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING 1
#endif #endif
#ifdef CGAL_INCLUDE_WINDOWS_DOT_H #ifdef CGAL_INCLUDE_WINDOWS_DOT_H
@ -296,6 +297,10 @@
#if __cplusplus >= 201402L || _MSVC_LANG >= 201402L #if __cplusplus >= 201402L || _MSVC_LANG >= 201402L
# define CGAL_CXX14 1 # define CGAL_CXX14 1
#endif #endif
// Same for C++17
#if __cplusplus >= 201703L || _MSVC_LANG >= 201703L
# define CGAL_CXX17 1
#endif
#if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) || BOOST_VERSION < 105000 #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) || BOOST_VERSION < 105000
#define CGAL_CFG_NO_STD_HASH 1 #define CGAL_CFG_NO_STD_HASH 1
@ -559,7 +564,7 @@ using std::max;
#define CGAL_NORETURN [[noreturn]] #define CGAL_NORETURN [[noreturn]]
// Macro to specify [[no_unique_address]] if supported // Macro to specify [[no_unique_address]] if supported
#if __has_cpp_attribute(no_unique_address) #if CGAL_CXX11 && __has_cpp_attribute(no_unique_address)
# define CGAL_NO_UNIQUE_ADDRESS [[no_unique_address]] # define CGAL_NO_UNIQUE_ADDRESS [[no_unique_address]]
#else #else
# define CGAL_NO_UNIQUE_ADDRESS # define CGAL_NO_UNIQUE_ADDRESS

View File

@ -161,23 +161,40 @@ do_intersect(const typename K::Tetrahedron_3 &tet,
} }
template <class K> template <class K>
inline inline typename K::Boolean do_intersect(const typename K::Tetrahedron_3 &tet,
typename K::Boolean const CGAL::Bbox_3 &bb, const K &k) {
do_intersect(const typename K::Tetrahedron_3 &tet, // Swap arguments.
const CGAL::Bbox_3 &bb, return do_intersect(bb, tet, k);
const K & k)
{
return do_intersect_tetrahedron_bounded(bb, tet, typename K::Point_3(bb.xmin(), bb.ymin(), bb.zmin()), k);
} }
template <class K> // BBox_3 specific code since it is ok for BBox_3 to degenerate.
inline template <class K>
typename K::Boolean inline typename K::Boolean do_intersect(const CGAL::Bbox_3 &aabb,
do_intersect(const CGAL::Bbox_3 &bb, const typename K::Tetrahedron_3 &tet,
const typename K::Tetrahedron_3 &tet, const K &k) {
const K & k) typename K::Construct_triangle_3 tr = k.construct_triangle_3_object();
{ typename K::Boolean result = false;
return do_intersect_tetrahedron_bounded(bb, tet, typename K::Point_3(bb.xmin(), bb.ymin(), bb.zmin()), k); typename K::Boolean b = false;
b = do_intersect(aabb, tr(tet[0], tet[1], tet[2]), k);
if (certainly(b)) return b;
if (is_indeterminate(b)) result = b;
b = do_intersect(aabb, tr(tet[1], tet[2], tet[3]), k);
if (certainly(b)) return b;
if (is_indeterminate(b)) result = b;
b = do_intersect(aabb, tr(tet[2], tet[3], tet[0]), k);
if (certainly(b)) return b;
if (is_indeterminate(b)) result = b;
b = do_intersect(aabb, tr(tet[3], tet[0], tet[1]), k);
if (certainly(b)) return b;
if (is_indeterminate(b)) result = b;
b = k.has_on_bounded_side_3_object()(
tet, k.construct_point_3_object()(aabb.xmin(), aabb.ymin(), aabb.zmin()));
if (certainly(b)) return b;
if (is_indeterminate(b)) result = b;
return result;
} }
} // namespace internal } // namespace internal

View File

@ -29,7 +29,7 @@ LC_CTYPE=en_US.UTF-8
# from branch 5.0 # from branch 5.0
0 21 * * Sat cd $HOME/CGAL/create_internal_release-5.0-branch && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/CGAL-5.0-branch.git --public --do-it || echo ERROR 0 21 * * Sat cd $HOME/CGAL/create_internal_release-5.0-branch && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/CGAL-5.0-branch.git --public --do-it || echo ERROR
# from branch 4.14 # from branch 4.14
0 21 * * Fri cd $HOME/CGAL/create_internal_release-4.14-branch && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/CGAL-4.14-branch.git --public --do-it || echo ERROR 0 21 * * Fri cd $HOME/CGAL/create_internal_release-4.14-branch && /usr/bin/time scl enable rh-git29 -- $HOME/bin/create_release $HOME/CGAL/branches/CGAL-4.14-branch.git $HOME/CGAL/branches/empty-dir --public --do-it || echo ERROR
## Older stuff ## Older stuff
# from branch 4.13 # from branch 4.13

View File

@ -69,7 +69,7 @@ sub reformat_results($)
if (/LEDAWIN_VERSION = '([^']+)'/) { if (/LEDAWIN_VERSION = '([^']+)'/) {
$LEDA_VERSION="$LEDA_VERSION+win"; $LEDA_VERSION="$LEDA_VERSION+win";
} }
if (/^COMPILER_VERSION = '([^']+)'/) { if (/COMPILER_VERSION = '([^']+)'/) {
$COMPILER = $1; $COMPILER = $1;
} }
if (/^TESTER_NAME\s+(.*)$/) { if (/^TESTER_NAME\s+(.*)$/) {

View File

@ -133,23 +133,26 @@ else()
message( STATUS "NOTICE: Some examples need the CGAL_ImageIO library, and will not be compiled." ) message( STATUS "NOTICE: Some examples need the CGAL_ImageIO library, and will not be compiled." )
endif() endif()
if(CGAL_ACTIVATE_CONCURRENT_MESH_3 AND TARGET CGAL::TBB_support AND TARGET ${target}) if(CGAL_ACTIVATE_CONCURRENT_MESH_3 AND TARGET CGAL::TBB_support)
foreach(target foreach(target
mesh_3D_image_with_features
mesh_3D_image mesh_3D_image
mesh_polyhedral_domain mesh_3D_image_variable_size
mesh_3D_image_with_custom_initialization mesh_3D_image_with_custom_initialization
mesh_two_implicit_spheres_with_balls mesh_3D_image_with_features
mesh_optimization_lloyd_example
mesh_optimization_example
mesh_implicit_sphere mesh_implicit_sphere
mesh_polyhedral_complex_sm
mesh_implicit_sphere_variable_size mesh_implicit_sphere_variable_size
mesh_polyhedral_domain_sm mesh_optimization_example
mesh_polyhedral_domain_with_lipschitz_sizing mesh_optimization_lloyd_example
mesh_polyhedral_complex mesh_polyhedral_complex
mesh_polyhedral_complex_sm
mesh_polyhedral_domain
mesh_polyhedral_domain_sm
mesh_polyhedral_domain_with_features mesh_polyhedral_domain_with_features
mesh_3D_image_variable_size) mesh_polyhedral_domain_with_features_sm
target_link_libraries(${target} PUBLIC CGAL::TBB_support) mesh_polyhedral_domain_with_lipschitz_sizing
mesh_two_implicit_spheres_with_balls)
if(TARGET ${target})
target_link_libraries(${target} PUBLIC CGAL::TBB_support)
endif()
endforeach() endforeach()
endif() endif()

View File

@ -1572,10 +1572,17 @@ private:
Cell_vector c3t3_cells(const Cell_vector& cells) const Cell_vector c3t3_cells(const Cell_vector& cells) const
{ {
Cell_vector c3t3_cells; Cell_vector c3t3_cells;
#ifdef CGAL_CXX17
std::remove_copy_if(cells.begin(),
cells.end(),
std::back_inserter(c3t3_cells),
std::not_fn(Is_in_c3t3<Cell_handle>(c3t3_)));
#else
std::remove_copy_if(cells.begin(), std::remove_copy_if(cells.begin(),
cells.end(), cells.end(),
std::back_inserter(c3t3_cells), std::back_inserter(c3t3_cells),
std::not1(Is_in_c3t3<Cell_handle>(c3t3_)) ); std::not1(Is_in_c3t3<Cell_handle>(c3t3_)) );
#endif
return c3t3_cells; return c3t3_cells;
} }

View File

@ -1155,6 +1155,7 @@ insert_balls(const Vertex_handle& vp,
// n = 2(d-sq) / (sp+sq) // n = 2(d-sq) / (sp+sq)
// ======================= // =======================
const FT d_signF = static_cast<FT>(d_sign);
int n = static_cast<int>(std::floor(FT(2)*(d-sq) / (sp+sq))+.5); int n = static_cast<int>(std::floor(FT(2)*(d-sq) / (sp+sq))+.5);
// if( minimal_weight_ != 0 && n == 0 ) return; // if( minimal_weight_ != 0 && n == 0 ) return;
@ -1180,7 +1181,7 @@ insert_balls(const Vertex_handle& vp,
const Bare_point new_point = const Bare_point new_point =
domain_.construct_point_on_curve(cp(vp_wp), domain_.construct_point_on_curve(cp(vp_wp),
curve_index, curve_index,
d_sign * d / 2); d_signF * d / 2);
const int dim = 1; // new_point is on edge const int dim = 1; // new_point is on edge
const Index index = domain_.index_from_curve_index(curve_index); const Index index = domain_.index_from_curve_index(curve_index);
const FT point_weight = CGAL::square(size_(new_point, dim, index)); const FT point_weight = CGAL::square(size_(new_point, dim, index));
@ -1230,7 +1231,6 @@ insert_balls(const Vertex_handle& vp,
FT norm_step_size = dleft_frac * step_size; FT norm_step_size = dleft_frac * step_size;
// Initial distance // Initial distance
FT d_signF = static_cast<FT>(d_sign);
FT pt_dist = d_signF * norm_step_size; FT pt_dist = d_signF * norm_step_size;
Vertex_handle prev = vp; Vertex_handle prev = vp;
const Bare_point& p = cp(c3t3_.triangulation().point(vp)); const Bare_point& p = cp(c3t3_.triangulation().point(vp));

View File

@ -105,13 +105,14 @@ bool build_finite_cells(Tr& tr,
const std::vector<typename Tr::Vertex_handle>& vertex_handle_vector, const std::vector<typename Tr::Vertex_handle>& vertex_handle_vector,
boost::unordered_map<std::array<typename Tr::Vertex_handle, 3>, boost::unordered_map<std::array<typename Tr::Vertex_handle, 3>,
std::vector<std::pair<typename Tr::Cell_handle, int> > >& incident_cells_map, std::vector<std::pair<typename Tr::Cell_handle, int> > >& incident_cells_map,
const std::map<std::array<int,3>, int>& border_facets, const std::map<std::array<int,3>, typename Tr::Cell::Surface_patch_index>& border_facets,
const bool verbose) const bool verbose)
{ {
typedef std::array<int, 5> Tet_with_ref; // 4 ids + 1 reference typedef std::array<int, 5> Tet_with_ref; // 4 ids + 1 reference
typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Vertex_handle Vertex_handle;
typedef typename Tr::Cell_handle Cell_handle; typedef typename Tr::Cell_handle Cell_handle;
typedef typename Tr::Cell::Surface_patch_index Surface_patch_index;
CGAL_assertion_code( CGAL_assertion_code(
typename Tr::Geom_traits::Construct_point_3 cp = typename Tr::Geom_traits::Construct_point_3 cp =
@ -171,7 +172,8 @@ bool build_finite_cells(Tr& tr,
++k; ++k;
} while(f[0] != n0); } while(f[0] != n0);
typename std::map<std::array<int,3>, int>::const_iterator it = border_facets.find(f); typename std::map<std::array<int,3>, Surface_patch_index>::const_iterator
it = border_facets.find(f);
if(it != border_facets.end()) if(it != border_facets.end())
{ {
c->set_surface_patch_index(j, it->second); c->set_surface_patch_index(j, it->second);
@ -186,7 +188,7 @@ bool build_finite_cells(Tr& tr,
if(it != border_facets.end()) if(it != border_facets.end())
c->set_surface_patch_index(j, it->second); c->set_surface_patch_index(j, it->second);
else else
c->set_surface_patch_index(j, 0); c->set_surface_patch_index(j, Surface_patch_index());
} }
} }
} }
@ -259,6 +261,8 @@ bool build_infinite_cells(Tr& tr,
// the only finite facet // the only finite facet
it->second.push_back(std::make_pair(opp_c, 0)); it->second.push_back(std::make_pair(opp_c, 0));
CGAL_assertion(it->second.size() == 2); CGAL_assertion(it->second.size() == 2);
opp_c->set_surface_patch_index(0, c->surface_patch_index(i));
} }
#ifdef CGAL_TET_SOUP_TO_C3T3_DEBUG #ifdef CGAL_TET_SOUP_TO_C3T3_DEBUG
@ -322,7 +326,7 @@ template<class Tr, bool c3t3_loader_failed>
bool build_triangulation(Tr& tr, bool build_triangulation(Tr& tr,
const std::vector<typename Tr::Point>& points, const std::vector<typename Tr::Point>& points,
const std::vector<std::array<int,5> >& finite_cells, const std::vector<std::array<int,5> >& finite_cells,
const std::map<std::array<int,3>, int>& border_facets, const std::map<std::array<int,3>, typename Tr::Cell::Surface_patch_index>& border_facets,
std::vector<typename Tr::Vertex_handle>& vertex_handle_vector, std::vector<typename Tr::Vertex_handle>& vertex_handle_vector,
const bool verbose = false) const bool verbose = false)
{ {
@ -389,7 +393,7 @@ bool build_triangulation_from_file(std::istream& is,
std::vector<Tet_with_ref> finite_cells; std::vector<Tet_with_ref> finite_cells;
std::vector<Point_3> points; std::vector<Point_3> points;
std::map<Facet, int> border_facets; std::map<Facet, typename Tr::Cell::Surface_patch_index> border_facets;
// grab the vertices // grab the vertices
int dim; int dim;
@ -420,7 +424,8 @@ bool build_triangulation_from_file(std::istream& is,
is >> nf; is >> nf;
for(int i=0; i<nf; ++i) for(int i=0; i<nf; ++i)
{ {
int n1, n2, n3, surface_patch_id; int n1, n2, n3;
typename Tr::Cell::Surface_patch_index surface_patch_id;
is >> n1 >> n2 >> n3 >> surface_patch_id; is >> n1 >> n2 >> n3 >> surface_patch_id;
Facet facet; Facet facet;
facet[0] = n1 - 1; facet[0] = n1 - 1;

View File

@ -113,6 +113,7 @@ template <class Circulator>
class Construct_circulator_2 class Construct_circulator_2
{ {
public: public:
typedef Circulator result_type;
Circulator operator()(Circulator p1) const { return p1; } Circulator operator()(Circulator p1) const { return p1; }
}; };

View File

@ -40,6 +40,14 @@ public:
using Base::operator(); using Base::operator();
template<typename F>
struct result : Base::template result<F> {};
template<typename F>
struct result<F(Point_3)> {
typedef const Point_3& type;
};
const Point_3& operator()(const Point_3& p) const { return p; } const Point_3& operator()(const Point_3& p) const { return p; }
}; };

View File

@ -49,6 +49,14 @@ public:
using Base::operator(); // for K::Weighted_point_3 to Point_3 using Base::operator(); // for K::Weighted_point_3 to Point_3
template<typename F>
struct result : Base::template result<F> {};
template<typename F>
struct result<F(Weighted_point_3)> {
typedef Point_3 type;
};
Point_3 operator()(const Weighted_point_3& wp) const { Point_3 operator()(const Weighted_point_3& wp) const {
return std::make_pair(operator()(wp.first), wp.second /* offset */); return std::make_pair(operator()(wp.first), wp.second /* offset */);
} }

View File

@ -112,7 +112,7 @@ public:
template <typename OutputIterator> template <typename OutputIterator>
void get_iterators (const Point& query, unsigned int k, FT neighbor_radius, void get_iterators (const Point& query, unsigned int k, FT neighbor_radius,
OutputIterator output, bool fallback_k_if_sphere_empty = true) const OutputIterator output, unsigned int fallback_k_if_sphere_empty = 3) const
{ {
if (neighbor_radius != FT(0)) if (neighbor_radius != FT(0))
{ {
@ -142,11 +142,10 @@ public:
catch (const Maximum_points_reached_exception&) catch (const Maximum_points_reached_exception&)
{ } { }
// Fallback, if less than 3 points are return, search for the 3 // Fallback, if not enough points are return, search for the knn
// first points // first points
if (fallback_k_if_sphere_empty && nb < 3) if (nb < fallback_k_if_sphere_empty)
k = 3; k = fallback_k_if_sphere_empty;
// Else, no need to search for K nearest neighbors
else else
k = 0; k = 0;
} }
@ -173,14 +172,14 @@ public:
template <typename OutputIterator> template <typename OutputIterator>
void get_points (const Point& query, unsigned int k, FT neighbor_radius, void get_points (const Point& query, unsigned int k, FT neighbor_radius,
OutputIterator output) const OutputIterator output, unsigned int fallback_k_if_sphere_empty = 3) const
{ {
return get_iterators(query, k, neighbor_radius, return get_iterators(query, k, neighbor_radius,
boost::make_function_output_iterator boost::make_function_output_iterator
([&](const input_iterator& it) ([&](const input_iterator& it)
{ {
*(output ++) = get (m_point_map, *it); *(output ++) = get (m_point_map, *it);
})); }), fallback_k_if_sphere_empty);
} }
}; };

View File

@ -209,7 +209,7 @@ std::size_t cluster_point_set (PointRange& points,
neighbors.clear(); neighbors.clear();
neighbor_query.get_iterators (get (point_map, p), 0, neighbor_radius, neighbor_query.get_iterators (get (point_map, p), 0, neighbor_radius,
std::back_inserter (neighbors), false); std::back_inserter (neighbors), 0);
for (const iterator& it : neighbors) for (const iterator& it : neighbors)
{ {

View File

@ -70,7 +70,10 @@ jet_estimate_normal(const typename NeighborQuery::Point_3& query, ///< point to
typedef typename Monge_jet_fitting::Monge_form Monge_form; typedef typename Monge_jet_fitting::Monge_form Monge_form;
std::vector<Point> points; std::vector<Point> points;
neighbor_query.get_points (query, k, neighbor_radius, std::back_inserter(points));
// query using as fallback minimum requires nb points for jet fitting (d+1)*(d+2)/2
neighbor_query.get_points (query, k, neighbor_radius, std::back_inserter(points),
(degree_fitting + 1) * (degree_fitting + 2) / 2);
// performs jet fitting // performs jet fitting
Monge_jet_fitting monge_fit; Monge_jet_fitting monge_fit;

View File

@ -75,7 +75,10 @@ jet_smooth_point(
typedef typename Monge_jet_fitting::Monge_form Monge_form; typedef typename Monge_jet_fitting::Monge_form Monge_form;
std::vector<Point> points; std::vector<Point> points;
neighbor_query.get_points (query, k, neighbor_radius, std::back_inserter(points));
// query using as fallback minimum requires nb points for jet fitting (d+1)*(d+2)/2
neighbor_query.get_points (query, k, neighbor_radius, std::back_inserter(points),
(degree_fitting + 1) * (degree_fitting + 2) / 2);
// performs jet fitting // performs jet fitting
Monge_jet_fitting monge_fit; Monge_jet_fitting monge_fit;

View File

@ -490,13 +490,7 @@ build_cgal_on_host()
CGAL_BINARY_DIR="${CGAL_BINARY_DIR_BASE}/${PLATFORM}" CGAL_BINARY_DIR="${CGAL_BINARY_DIR_BASE}/${PLATFORM}"
if [ -d "${REFERENCE_PLATFORMS_DIR}/${PLATFORM}" ] ; then log "${ACTUAL_LOGFILE}" "Building cgal libs on host ${HOST} and platform ${PLATFORM}\nUnder ${CGAL_BINARY_DIR}\n"
CGAL_REFERENCE_CACHE_DIR="${REFERENCE_PLATFORMS_DIR}/${PLATFORM}"
else
CGAL_REFERENCE_CACHE_DIR=""
fi
log "${ACTUAL_LOGFILE}" "Building cgal libs on host ${HOST} and platform ${PLATFORM}\nUnder ${CGAL_BINARY_DIR}\nUsing reference cache directory ${CGAL_REFERENCE_CACHE_DIR}"
if [ -f "${CGAL_BINARY_DIR}/localbuildscript" ] ; then if [ -f "${CGAL_BINARY_DIR}/localbuildscript" ] ; then
log "${ACTUAL_LOGFILE}" "WARNING! Already built on platform ${PLATFORM}." log "${ACTUAL_LOGFILE}" "WARNING! Already built on platform ${PLATFORM}."
@ -514,19 +508,12 @@ if [ -z "\$CMAKE_GENERATOR" ]; then
CMAKE_GENERATOR='${CMAKE_GENERATOR}'; CMAKE_GENERATOR='${CMAKE_GENERATOR}';
fi fi
MAKE_CMD='${MAKE_CMD}'; MAKE_CMD='${MAKE_CMD}';
if [ -n "${IS_CYGWIN}" ]; then
CGAL_REFERENCE_CACHE_DIR=\$( cygpath -w '${CGAL_REFERENCE_CACHE_DIR}' );
else
CGAL_REFERENCE_CACHE_DIR='${CGAL_REFERENCE_CACHE_DIR}';\
fi
export CMAKE_GENERATOR; export CMAKE_GENERATOR;
export MAKE_CMD; export MAKE_CMD;
export CGAL_BINARY_DIR; export CGAL_BINARY_DIR;
export CGAL_REFERENCE_CACHE_DIR;
cd '${CGAL_BINARY_DIR}'; cd '${CGAL_BINARY_DIR}';
cmake \${INIT_FILE:+"-C\${INIT_FILE}"} '${CMAKE_GENERATOR}' -DRUNNING_CGAL_AUTO_TEST=TRUE \\ cmake \${INIT_FILE:+"-C\${INIT_FILE}"} '${CMAKE_GENERATOR}' -DRUNNING_CGAL_AUTO_TEST=TRUE \\
-DCGAL_REFERENCE_CACHE_DIR="\$CGAL_REFERENCE_CACHE_DIR" \\
VERBOSE=1 \\ VERBOSE=1 \\
../../..; ../../..;
${MAKE_CMD} VERBOSE=ON -k -fMakefile ; ${MAKE_CMD} VERBOSE=ON -k -fMakefile ;

View File

@ -56,5 +56,6 @@ while preserving the input geometric curve and surface features.
\cgalCRPSection{Function Templates} \cgalCRPSection{Function Templates}
- `CGAL::tetrahedral_isotropic_remeshing()` - `CGAL::tetrahedral_isotropic_remeshing()`
- `CGAL::convert_to_triangulation_3()`
*/ */

View File

@ -39,17 +39,18 @@ The tetrahedral remeshing algorithm improves the quality of dihedral angles,
while targeting the user-defined uniform sizing field and preserving the while targeting the user-defined uniform sizing field and preserving the
topology of the feature complex, as highlighted by Figure \cgalFigureRef{Remesh_liver}. topology of the feature complex, as highlighted by Figure \cgalFigureRef{Remesh_liver}.
\cgalFigureBegin{Remesh_liver, tetrahedral_remeshing_before_after.png}
Tetrahedral mesh, improved by the uniform tetrahedral remeshing algorithm.
(Left) Before remeshing, dihedral angles were in the interval [0.7; 178.9].
(Right) After remeshing and keeping the same density,
dihedral angles are the interval [12,7; 157.7].
\cgalFigureEnd
Experimental evidence shows that a higher number of remeshing iterations Experimental evidence shows that a higher number of remeshing iterations
leads to a mesh with a improved fidelity to the sizing criterion, leads to a mesh with a improved fidelity to the sizing criterion,
and higher quality dihedral angles. and higher quality dihedral angles.
\cgalFigureBegin{Remesh_liver, tetrahedral_remeshing_before_after.png}
Tetrahedral mesh, modified by our uniform tetrahedral remeshing method.
(Left) Before remeshing, dihedral angles were in the interval [1.3; 177.8].
(Right) After remeshing and keeping the same density,
dihedral angles are in the interval [12,7; 157.7].
\cgalFigureEnd
\section secTetRemeshingAPI API \section secTetRemeshingAPI API
The tetrahedral remeshing algorithm is implemented as a single free function The tetrahedral remeshing algorithm is implemented as a single free function
@ -97,5 +98,17 @@ setting the named parameter `remesh_boundaries` to `false`.
\cgalExample{Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp } \cgalExample{Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp }
\subsection ssecEx4 Tetrahedral Remeshing After Mesh Generation
The tetrahedral remeshing algorithm is designed as a post-processing for
mesh generation algorithms. The API allows to generate a tetrahedral mesh
with `Mesh_3`, the tetrahedral mesh generation package, and
further improve it with the tetrahedral remeshing algorithm.
This example shows how to use tetrahedral mesh generation and remeshing in sequence,
from a polyhedral domain with features.
\cgalExample{Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features.cpp}
*/ */
} /* namespace CGAL */ } /* namespace CGAL */

View File

@ -3,5 +3,5 @@
\example Tetrahedral_remeshing/tetrahedral_remeshing_example.cpp \example Tetrahedral_remeshing/tetrahedral_remeshing_example.cpp
\example Tetrahedral_remeshing/tetrahedral_remeshing_of_one_subdomain.cpp \example Tetrahedral_remeshing/tetrahedral_remeshing_of_one_subdomain.cpp
\example Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp \example Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp
\example Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features.cpp
*/ */

View File

@ -19,9 +19,15 @@ if ( NOT Boost_FOUND )
return() return()
endif() endif()
# Use Eigen for Mesh_3
find_package(Eigen3 3.1.0 REQUIRED) #(3.1.0 or greater)
include(CGAL_Eigen_support)
# Creating entries for all C++ files with "main" routine # Creating entries for all C++ files with "main" routine
# ########################################################## # ##########################################################
create_single_source_cgal_program( "tetrahedral_remeshing_example.cpp" ) create_single_source_cgal_program( "tetrahedral_remeshing_example.cpp" )
create_single_source_cgal_program( "tetrahedral_remeshing_with_features.cpp") create_single_source_cgal_program( "tetrahedral_remeshing_with_features.cpp")
create_single_source_cgal_program( "tetrahedral_remeshing_of_one_subdomain.cpp") create_single_source_cgal_program( "tetrahedral_remeshing_of_one_subdomain.cpp")
create_single_source_cgal_program( "mesh_and_remesh_polyhedral_domain_with_features.cpp" )
target_link_libraries(mesh_and_remesh_polyhedral_domain_with_features PUBLIC CGAL::Eigen_support)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,75 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Mesh_triangulation_3.h>
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
#include <CGAL/Mesh_criteria_3.h>
#include <CGAL/Polyhedral_mesh_domain_with_features_3.h>
#include <CGAL/make_mesh_3.h>
#include <CGAL/tetrahedral_remeshing.h>
// Domain
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Mesh_polyhedron_3<K>::type Polyhedron;
typedef CGAL::Polyhedral_mesh_domain_with_features_3<K> Mesh_domain;
// Triangulation for Meshing
typedef CGAL::Mesh_triangulation_3<Mesh_domain, CGAL::Default, CGAL::Default>::type Tr;
typedef CGAL::Mesh_complex_3_in_triangulation_3<
Tr, Mesh_domain::Corner_index, Mesh_domain::Curve_index> C3t3;
// Criteria
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
// Triangulation for Remeshing
typedef CGAL::Triangulation_3<typename Tr::Geom_traits,
typename Tr::Triangulation_data_structure> Triangulation_3;
// To avoid verbose function and named parameters call
using namespace CGAL::parameters;
int main(int argc, char* argv[])
{
const char* fname = (argc > 1) ? argv[1] : "data/fandisk.off";
std::ifstream input(fname);
Polyhedron polyhedron;
input >> polyhedron;
if (input.fail()) {
std::cerr << "Error: Cannot read file " << fname << std::endl;
return EXIT_FAILURE;
}
if (!CGAL::is_triangle_mesh(polyhedron)) {
std::cerr << "Input geometry is not triangulated." << std::endl;
return EXIT_FAILURE;
}
// Create domain
Mesh_domain domain(polyhedron);
// Get sharp features
domain.detect_features();
// Mesh criteria
Mesh_criteria criteria(edge_size = 0.025,
facet_angle = 25, facet_size = 0.05, facet_distance = 0.005,
cell_radius_edge_ratio = 3, cell_size = 0.05);
// Mesh generation
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria);
Triangulation_3 tr = CGAL::convert_to_triangulation_3(std::move(c3t3));
//note we use the move semantic, with std::move(c3t3),
// to avoid a copy of the triangulation by the function
// `CGAL::convert_to_triangulation_3()`
// After the call to this function, c3t3 is an empty and valid C3t3.
//It is possible to use : CGAL::convert_to_triangulation_3(c3t3),
// Then the triangulation is copied and duplicated, and c3t3 remains as is.
const double target_edge_length = 0.1;//coarsen the mesh
CGAL::tetrahedral_isotropic_remeshing(tr, target_edge_length,
CGAL::parameters::number_of_iterations(3));
return EXIT_SUCCESS;
}

View File

@ -14,7 +14,6 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Tetrahedral_remeshing::Remeshing_triangulation_3<K> Remeshing_triangulation; typedef CGAL::Tetrahedral_remeshing::Remeshing_triangulation_3<K> Remeshing_triangulation;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
const double target_edge_length = (argc > 1) ? atof(argv[1]) : 0.1; const double target_edge_length = (argc > 1) ? atof(argv[1]) : 0.1;

View File

@ -79,9 +79,7 @@ int main(int argc, char* argv[])
boost::unordered_set<std::pair<Vertex_handle, Vertex_handle> > constraints; boost::unordered_set<std::pair<Vertex_handle, Vertex_handle> > constraints;
CGAL::Tetrahedral_remeshing::generate_input_cube(nbv, t3, constraints); CGAL::Tetrahedral_remeshing::generate_input_cube(nbv, t3, constraints);
make_constraints_from_cube_edges(t3, constraints); make_constraints_from_cube_edges(t3, constraints);
CGAL_assertion(t3.is_valid()); CGAL_assertion(t3.is_valid());
CGAL::tetrahedral_isotropic_remeshing(t3, target_edge_length, CGAL::tetrahedral_isotropic_remeshing(t3, target_edge_length,

View File

@ -54,12 +54,13 @@ class CollapseTriangulation
typedef typename C3t3::Cell_handle Cell_handle; typedef typename C3t3::Cell_handle Cell_handle;
typedef typename C3t3::Vertex_handle Vertex_handle; typedef typename C3t3::Vertex_handle Vertex_handle;
typedef typename C3t3::Subdomain_index Subdomain_index; typedef typename C3t3::Subdomain_index Subdomain_index;
typedef typename C3t3::Surface_patch_index Surface_patch_index;
typedef typename C3t3::Triangulation::Point Point_3; typedef typename C3t3::Triangulation::Point Point_3;
typedef typename C3t3::Triangulation::Geom_traits::Vector_3 Vector_3; typedef typename C3t3::Triangulation::Geom_traits::Vector_3 Vector_3;
public: public:
CollapseTriangulation(C3t3& c3t3, CollapseTriangulation(const Edge& e,
const Edge& e, const std::unordered_set<Cell_handle>& cells_to_insert,
Collapse_type _collapse_type) Collapse_type _collapse_type)
: collapse_type(_collapse_type) : collapse_type(_collapse_type)
, v0_init(e.first->vertex(e.second)) , v0_init(e.first->vertex(e.second))
@ -68,14 +69,6 @@ public:
typedef std::array<int, 3> Facet; // 3 = id typedef std::array<int, 3> Facet; // 3 = id
typedef std::array<int, 5> Tet_with_ref; // first 4 = id, fifth = reference typedef std::array<int, 5> Tet_with_ref; // first 4 = id, fifth = reference
std::unordered_set<Cell_handle> cells_to_insert;
c3t3.triangulation().finite_incident_cells(v0_init,
std::inserter(cells_to_insert, cells_to_insert.end()));
c3t3.triangulation().finite_incident_cells(v1_init,
std::inserter(cells_to_insert, cells_to_insert.end()));
make_cells_set_manifold(c3t3, cells_to_insert);
std::unordered_set<Vertex_handle> vertices_to_insert; std::unordered_set<Vertex_handle> vertices_to_insert;
for (Cell_handle ch : cells_to_insert) for (Cell_handle ch : cells_to_insert)
{ {
@ -115,7 +108,7 @@ public:
// finished // finished
std::vector<Vertex_handle> new_vertices; std::vector<Vertex_handle> new_vertices;
std::map<Facet, int> border_facets; std::map<Facet, typename C3t3::Surface_patch_index> border_facets;
if (CGAL::build_triangulation<Tr, false>(triangulation, if (CGAL::build_triangulation<Tr, false>(triangulation,
points, finite_cells, border_facets, points, finite_cells, border_facets,
new_vertices, false/*verbose*/)) new_vertices, false/*verbose*/))
@ -144,58 +137,6 @@ public:
#endif #endif
} }
void make_cells_set_manifold(const C3t3& c3t3,
std::unordered_set<Cell_handle>& cells)
{
typedef Vertex_handle Vh;
typedef std::array<Vh, 3> FV;
typedef std::pair<Vh, Vh> EV;
boost::unordered_map<FV, int> facets;
for (Cell_handle c : cells)
{
for (int i = 0; i < 4; ++i)
{
const FV fvi = make_vertex_array(c->vertex((i + 1) % 4),
c->vertex((i + 2) % 4),
c->vertex((i + 3) % 4));
typename boost::unordered_map<FV, int>::iterator fit = facets.find(fvi);
if(fit == facets.end())
facets.insert(std::make_pair(fvi, 1));
else
fit->second++;
}
}
boost::unordered_map<EV, int> edges;
for (const std::pair<FV, int>& fvv : facets)
{
if(fvv.second != 1)
continue;
for (int i = 0; i < 3; ++i)
{
const EV evi = make_vertex_pair(fvv.first[i], fvv.first[(i + 1) % 3]);
typename boost::unordered_map<EV, int>::iterator eit = edges.find(evi);
if (eit == edges.end())
edges.insert(std::make_pair(evi, 1));
else
eit->second++;
}
}
for (const std::pair<EV, int>& evv : edges)
{
if (evv.second != 2)
{
c3t3.triangulation().finite_incident_cells(evv.first.first,
std::inserter(cells, cells.begin()));
c3t3.triangulation().finite_incident_cells(evv.first.second,
std::inserter(cells, cells.begin()));
}
}
}
Result_type collapse() Result_type collapse()
{ {
if (not_an_edge) if (not_an_edge)
@ -1038,6 +979,55 @@ typename C3t3::Vertex_handle collapse(typename C3t3::Edge& edge,
return vh; return vh;
} }
template<typename C3t3>
bool is_cells_set_manifold(const C3t3&,
std::unordered_set<typename C3t3::Cell_handle>& cells)
{
typedef typename C3t3::Cell_handle Cell_handle;
typedef typename C3t3::Vertex_handle Vh;
typedef std::array<Vh, 3> FV;
typedef std::pair<Vh, Vh> EV;
boost::unordered_map<FV, int> facets;
for (Cell_handle c : cells)
{
for (int i = 0; i < 4; ++i)
{
const FV fvi = make_vertex_array(c->vertex((i + 1) % 4),
c->vertex((i + 2) % 4),
c->vertex((i + 3) % 4));
typename boost::unordered_map<FV, int>::iterator fit = facets.find(fvi);
if (fit == facets.end())
facets.insert(std::make_pair(fvi, 1));
else
fit->second++;
}
}
boost::unordered_map<EV, int> edges;
for (const std::pair<FV, int>& fvv : facets)
{
if (fvv.second != 1)
continue;
for (int i = 0; i < 3; ++i)
{
const EV evi = make_vertex_pair(fvv.first[i], fvv.first[(i + 1) % 3]);
typename boost::unordered_map<EV, int>::iterator eit = edges.find(evi);
if (eit == edges.end())
edges.insert(std::make_pair(evi, 1));
else
eit->second++;
}
}
for (const std::pair<EV, int>& evv : edges)
if (evv.second != 2)
return false;
return true;
}
template<typename C3t3, typename CellSelector, typename Visitor> template<typename C3t3, typename CellSelector, typename Visitor>
typename C3t3::Vertex_handle collapse_edge(typename C3t3::Edge& edge, typename C3t3::Vertex_handle collapse_edge(typename C3t3::Edge& edge,
C3t3& c3t3, C3t3& c3t3,
@ -1049,6 +1039,7 @@ typename C3t3::Vertex_handle collapse_edge(typename C3t3::Edge& edge,
typedef typename C3t3::Triangulation Tr; typedef typename C3t3::Triangulation Tr;
typedef typename Tr::Point Point; typedef typename Tr::Point Point;
typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Vertex_handle Vertex_handle;
typedef typename Tr::Cell_handle Cell_handle;
const Vertex_handle v0 = edge.first->vertex(edge.second); const Vertex_handle v0 = edge.first->vertex(edge.second);
const Vertex_handle v1 = edge.first->vertex(edge.third); const Vertex_handle v1 = edge.first->vertex(edge.third);
@ -1121,7 +1112,19 @@ typename C3t3::Vertex_handle collapse_edge(typename C3t3::Edge& edge,
CGAL_assertion(c3t3.triangulation().is_edge(edge.first->vertex(edge.second), CGAL_assertion(c3t3.triangulation().is_edge(edge.first->vertex(edge.second),
edge.first->vertex(edge.third), dc, di, dj)); edge.first->vertex(edge.third), dc, di, dj));
CollapseTriangulation<C3t3> local_tri(c3t3, edge, collapse_type); Vertex_handle v0_init = edge.first->vertex(edge.second);
Vertex_handle v1_init = edge.first->vertex(edge.third);
std::unordered_set<Cell_handle> cells_to_insert;
c3t3.triangulation().finite_incident_cells(v0_init,
std::inserter(cells_to_insert, cells_to_insert.end()));
c3t3.triangulation().finite_incident_cells(v1_init,
std::inserter(cells_to_insert, cells_to_insert.end()));
if(!is_cells_set_manifold(c3t3, cells_to_insert))
return Vertex_handle();
CollapseTriangulation<C3t3> local_tri(edge, cells_to_insert, collapse_type);
Result_type res = local_tri.collapse(); Result_type res = local_tri.collapse();
if (res == VALID) if (res == VALID)

View File

@ -53,7 +53,7 @@ typename C3t3::Vertex_handle split_edge(const typename C3t3::Edge& e,
(point(v1->point()), point(v2->point())); (point(v1->point()), point(v2->point()));
//backup subdomain info of incident cells before making changes //backup subdomain info of incident cells before making changes
short dimension = (c3t3.is_in_complex(e)) ? 1 : 3; short dimension = (std::max)((std::max)(1, c3t3.in_dimension(v1)), c3t3.in_dimension(v2));
boost::unordered_map<Facet, Subdomain_index> cells_info; boost::unordered_map<Facet, Subdomain_index> cells_info;
boost::unordered_map<Facet, std::pair<Vertex_handle, Surface_patch_index> > facets_info; boost::unordered_map<Facet, std::pair<Vertex_handle, Surface_patch_index> > facets_info;
@ -110,11 +110,6 @@ typename C3t3::Vertex_handle split_edge(const typename C3t3::Edge& e,
// surface data for facets of the cells to be split // surface data for facets of the cells to be split
const int findex = CGAL::Triangulation_utils_3::next_around_edge(index_v1, index_v2); const int findex = CGAL::Triangulation_utils_3::next_around_edge(index_v1, index_v2);
if (c3t3.is_in_complex(c, findex))
{
if (dimension == 3)
dimension = 2;
}
Surface_patch_index patch = c3t3.surface_patch_index(c, findex); Surface_patch_index patch = c3t3.surface_patch_index(c, findex);
Vertex_handle opp_vertex = c->vertex(findex); Vertex_handle opp_vertex = c->vertex(findex);
facets_info.insert(std::make_pair(opp_facet1, facets_info.insert(std::make_pair(opp_facet1,
@ -179,6 +174,8 @@ typename C3t3::Vertex_handle split_edge(const typename C3t3::Edge& e,
// will have its patch tagged from the other side, if needed // will have its patch tagged from the other side, if needed
} }
set_index(new_v, c3t3);
return new_v; return new_v;
} }

View File

@ -30,6 +30,7 @@
#include <CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h> #include <CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h>
#include <CGAL/Tetrahedral_remeshing/internal/compute_c3t3_statistics.h> #include <CGAL/Tetrahedral_remeshing/internal/compute_c3t3_statistics.h>
#include <boost/optional.hpp>
namespace CGAL namespace CGAL
{ {
@ -103,6 +104,8 @@ class Adaptive_remesher
typedef typename C3t3::Vertex_handle Vertex_handle; typedef typename C3t3::Vertex_handle Vertex_handle;
typedef typename C3t3::Subdomain_index Subdomain_index; typedef typename C3t3::Subdomain_index Subdomain_index;
typedef typename C3t3::Surface_patch_index Surface_patch_index; typedef typename C3t3::Surface_patch_index Surface_patch_index;
typedef typename C3t3::Curve_index Curve_index;
typedef typename C3t3::Corner_index Corner_index;
typedef Tetrahedral_remeshing_smoother<C3t3> Smoother; typedef Tetrahedral_remeshing_smoother<C3t3> Smoother;
@ -141,6 +144,8 @@ public:
#ifdef CGAL_DUMP_REMESHING_STEPS #ifdef CGAL_DUMP_REMESHING_STEPS
CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "00-init"); CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "00-init");
CGAL::Tetrahedral_remeshing::debug::dump_facets_in_complex(m_c3t3,
"00-facets_in_complex_after_init.off");
#endif #endif
} }
@ -167,6 +172,8 @@ public:
#ifdef CGAL_DUMP_REMESHING_STEPS #ifdef CGAL_DUMP_REMESHING_STEPS
CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "00-init"); CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "00-init");
CGAL::Tetrahedral_remeshing::debug::dump_facets_in_complex(m_c3t3,
"00-facets_in_complex_after_init.off");
#endif #endif
} }
@ -184,8 +191,14 @@ public:
split_long_edges(m_c3t3, emax, m_protect_boundaries, split_long_edges(m_c3t3, emax, m_protect_boundaries,
m_cell_selector, m_visitor); m_cell_selector, m_visitor);
#ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG
CGAL_assertion(tr().tds().is_valid(true)); CGAL_assertion(tr().tds().is_valid(true));
CGAL_assertion(debug::are_cell_orientations_valid(tr())); CGAL_assertion(debug::are_cell_orientations_valid(tr()));
CGAL::Tetrahedral_remeshing::debug::dump_facets_in_complex(m_c3t3,
"1-facets_in_complex_after_split.off");
CGAL::Tetrahedral_remeshing::debug::dump_vertices_by_dimension(
m_c3t3.triangulation(), "1-c3t3_vertices_after_split");
#endif
#ifdef CGAL_DUMP_REMESHING_STEPS #ifdef CGAL_DUMP_REMESHING_STEPS
CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "1-split"); CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "1-split");
#endif #endif
@ -201,8 +214,12 @@ public:
collapse_short_edges(m_c3t3, emin, emax, m_protect_boundaries, collapse_short_edges(m_c3t3, emin, emax, m_protect_boundaries,
m_cell_selector, m_visitor); m_cell_selector, m_visitor);
#ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG
CGAL_assertion(tr().tds().is_valid(true)); CGAL_assertion(tr().tds().is_valid(true));
CGAL_assertion(debug::are_cell_orientations_valid(tr())); CGAL_assertion(debug::are_cell_orientations_valid(tr()));
CGAL::Tetrahedral_remeshing::debug::dump_vertices_by_dimension(
m_c3t3.triangulation(), "2-c3t3_vertices_after_collapse");
#endif
#ifdef CGAL_DUMP_REMESHING_STEPS #ifdef CGAL_DUMP_REMESHING_STEPS
CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "2-collapse"); CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "2-collapse");
#endif #endif
@ -213,8 +230,12 @@ public:
flip_edges(m_c3t3, m_protect_boundaries, flip_edges(m_c3t3, m_protect_boundaries,
m_cell_selector, m_visitor); m_cell_selector, m_visitor);
#ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG
CGAL_assertion(tr().tds().is_valid(true)); CGAL_assertion(tr().tds().is_valid(true));
CGAL_assertion(debug::are_cell_orientations_valid(tr())); CGAL_assertion(debug::are_cell_orientations_valid(tr()));
CGAL::Tetrahedral_remeshing::debug::dump_vertices_by_dimension(
m_c3t3.triangulation(), "3-c3t3_vertices_after_flip");
#endif
#ifdef CGAL_DUMP_REMESHING_STEPS #ifdef CGAL_DUMP_REMESHING_STEPS
CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "3-flip"); CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "3-flip");
#endif #endif
@ -224,8 +245,12 @@ public:
{ {
m_vertex_smoother.smooth_vertices(m_c3t3, m_protect_boundaries, m_cell_selector); m_vertex_smoother.smooth_vertices(m_c3t3, m_protect_boundaries, m_cell_selector);
#ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG
CGAL_assertion(tr().tds().is_valid(true)); CGAL_assertion(tr().tds().is_valid(true));
CGAL_assertion(debug::are_cell_orientations_valid(tr())); CGAL_assertion(debug::are_cell_orientations_valid(tr()));
CGAL::Tetrahedral_remeshing::debug::dump_vertices_by_dimension(
m_c3t3.triangulation(), "4-c3t3_vertices_after_smooth");
#endif
#ifdef CGAL_DUMP_REMESHING_STEPS #ifdef CGAL_DUMP_REMESHING_STEPS
CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "4-smooth"); CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "4-smooth");
#endif #endif
@ -294,31 +319,33 @@ public:
} }
} }
#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE
std::cout << "Peelable cells : " << peelable_cells.size() << std::endl;
#endif
for (auto c_i : peelable_cells) for (auto c_i : peelable_cells)
{ {
Cell_handle c = c_i.first; Cell_handle c = c_i.first;
std::array<bool, 4> f_on_surface = c_i.second; std::array<bool, 4> f_on_surface = c_i.second;
bool found = false; boost::optional<Surface_patch_index> patch;
Surface_patch_index patch;
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
{ {
if (f_on_surface[i]) if (f_on_surface[i])
{ {
Surface_patch_index spi = m_c3t3.surface_patch_index(c, i); Surface_patch_index spi = m_c3t3.surface_patch_index(c, i);
if (found && patch != spi) if (patch != boost::none && patch != spi)
{ {
found = false; patch = boost::none;
break; break;
} }
else else
{ {
found = true;
patch = spi; patch = spi;
} }
} }
} }
if(!found) if(patch == boost::none)
continue; continue;
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
@ -326,16 +353,17 @@ public:
if(f_on_surface[i]) if(f_on_surface[i])
m_c3t3.remove_from_complex(c, i); m_c3t3.remove_from_complex(c, i);
else else
m_c3t3.add_to_complex(c, i, patch); m_c3t3.add_to_complex(c, i, patch.get());
} }
m_c3t3.remove_from_complex(c); m_c3t3.remove_from_complex(c);
++nb_slivers_peel; ++nb_slivers_peel;
} }
#ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG
CGAL_assertion(tr().tds().is_valid(true)); CGAL_assertion(tr().tds().is_valid(true));
CGAL_assertion(debug::are_cell_orientations_valid(tr())); CGAL_assertion(debug::are_cell_orientations_valid(tr()));
#endif
#ifdef CGAL_DUMP_REMESHING_STEPS #ifdef CGAL_DUMP_REMESHING_STEPS
CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "99-postprocess"); CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "99-postprocess");
#endif #endif
@ -359,6 +387,7 @@ private:
const FacetIsConstrainedMap& fcmap) const FacetIsConstrainedMap& fcmap)
{ {
#ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG #ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG
debug_c3t3();
std::size_t nbc = 0; std::size_t nbc = 0;
std::size_t nbf = 0; std::size_t nbf = 0;
std::size_t nbe = 0; std::size_t nbe = 0;
@ -466,7 +495,7 @@ private:
#endif #endif
//tag vertices //tag vertices
unsigned int corner_id = 0; Corner_index corner_id = 0;
for (Vertex_handle vit : tr().finite_vertex_handles()) for (Vertex_handle vit : tr().finite_vertex_handles())
{ {
if ( vit->in_dimension() == 0 if ( vit->in_dimension() == 0
@ -478,12 +507,17 @@ private:
if (vit->in_dimension() == -1 || vit->in_dimension() > 0) if (vit->in_dimension() == -1 || vit->in_dimension() > 0)
vit->set_dimension(0); vit->set_dimension(0);
vit->set_index(corner_id);
#ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG #ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG
++nbv; ++nbv;
#endif #endif
} }
} }
for (Vertex_handle v : tr().finite_vertex_handles())
set_index(v, m_c3t3);
#ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG #ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG
std::cout << "C3t3 ready :" << std::endl; std::cout << "C3t3 ready :" << std::endl;
std::cout << "\t cells = " << nbc << std::endl; std::cout << "\t cells = " << nbc << std::endl;
@ -508,6 +542,14 @@ private:
} }
return true; return true;
} }
void debug_c3t3()
{
for (typename Tr::Facet f : tr().finite_facets())
{
typename Tr::Facet mf = tr().mirror_facet(f);
CGAL_assertion(m_c3t3.is_in_complex(f) == m_c3t3.is_in_complex(mf));
}
}
template<typename PatchIndex> template<typename PatchIndex>
void set_surface_patch_index_to_default(const Subdomain_index&, void set_surface_patch_index_to_default(const Subdomain_index&,

View File

@ -307,6 +307,28 @@ typename C3t3::Surface_patch_index surface_patch_index(const typename C3t3::Vert
return Surface_patch_index(); return Surface_patch_index();
} }
template<typename C3t3>
void set_index(typename C3t3::Vertex_handle v, const C3t3& c3t3)
{
switch (v->in_dimension())
{
case 3:
v->set_index(v->cell()->subdomain_index());
break;
case 2:
v->set_index(surface_patch_index(v, c3t3));
break;
case 1:
v->set_index(typename C3t3::Curve_index(1));
break;
case 0:
v->set_index(boost::get<typename C3t3::Corner_index>(v->index()));
break;
default:
CGAL_assertion(false);
}
}
template<typename C3t3> template<typename C3t3>
bool is_edge_in_complex(const typename C3t3::Vertex_handle& v0, bool is_edge_in_complex(const typename C3t3::Vertex_handle& v0,
const typename C3t3::Vertex_handle& v1, const typename C3t3::Vertex_handle& v1,

View File

@ -252,10 +252,54 @@ void tetrahedral_isotropic_remeshing(
CGAL::parameters::all_default()); CGAL::parameters::all_default());
} }
/*!
* \ingroup PkgTetrahedralRemeshingRef
* converts the triangulation contained in the input to a `Triangulation_3`.
*
* This function should be used to generate a valid triangulation
* for tetrahedral remeshing, when the input triangulation is generated with the
* tetrahedral mesh generation package.
*
* @tparam Tr is the underlying triangulation for `Mesh_complex_3_in_triangulation_3`.
* It can be instantiated with any 3D regular triangulation of CGAL provided
* that its vertex and cell base classes are models of the concepts
* `MeshVertexBase_3` (refined by `RemeshingCellBase_3`)
* and `MeshCellBase_3` (refined by `RemeshingVertexBase_3`), respectively.
* @tparam CornerIndex is the type of the indices for feature corners.
* If `c3t3` has been generated using `CGAL::make_mesh_3()`, it must match
* the `Corner_index` type of the model of the `MeshDomainWithFeatures_3` concept used for mesh generation.
* @tparam CurveIndex is the type of the indices for feature curves.
* If `c3t3` has been generated using `CGAL::make_mesh_3()`, it must match
* the `Curve_index` type of the model of the `MeshDomainWithFeatures_3` concept used for mesh generation.
*
* @param c3t3 the complex containing the triangulation to be remeshed.
*/
template<typename Tr,
typename CornerIndex,
typename CurveIndex>
CGAL::Triangulation_3<typename Tr::Geom_traits,
typename Tr::Triangulation_data_structure>
convert_to_triangulation_3(
CGAL::Mesh_complex_3_in_triangulation_3<Tr, CornerIndex, CurveIndex> c3t3)
{
using GT = typename Tr::Geom_traits;
using TDS = typename Tr::Triangulation_data_structure;
CGAL::Triangulation_3<GT, TDS> tr;
tr.swap(c3t3.triangulation());
return tr;
}
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
/////// MESH_COMPLEX_3_IN_TRIANGULATION_3 ///////// /////// MESH_COMPLEX_3_IN_TRIANGULATION_3 /////////
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
///////
////// Warning with using this version :
////// the triangulation after remeshing is not regular anymore
////// the empty-sphere property is not respected
///////
template<typename Tr, template<typename Tr,
typename CornerIndex, typename CurveIndex, typename CornerIndex, typename CurveIndex,
typename NamedParameters> typename NamedParameters>

View File

@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.1...3.14)
project( Tetrahedral_remeshing_Tests ) project( Tetrahedral_remeshing_Tests )
# CGAL and its components # CGAL and its components
find_package( CGAL REQUIRED ) find_package(CGAL COMPONENTS ImageIO)
if ( NOT CGAL_FOUND ) if ( NOT CGAL_FOUND )
message(STATUS "This project requires the CGAL library, and will not be compiled.") message(STATUS "This project requires the CGAL library, and will not be compiled.")
return() return()
@ -19,10 +19,26 @@ if ( NOT Boost_FOUND )
return() return()
endif() endif()
# Creating entries for all C++ files with "main" routine # Creating entries for all C++ files with "main" routine
# ########################################################## # ##########################################################
create_single_source_cgal_program( "test_tetrahedral_remeshing.cpp" ) create_single_source_cgal_program( "test_tetrahedral_remeshing.cpp" )
create_single_source_cgal_program( "test_tetrahedral_remeshing_with_features.cpp") create_single_source_cgal_program( "test_tetrahedral_remeshing_with_features.cpp")
create_single_source_cgal_program( "test_tetrahedral_remeshing_of_one_subdomain.cpp") create_single_source_cgal_program( "test_tetrahedral_remeshing_of_one_subdomain.cpp")
create_single_source_cgal_program( "test_tetrahedral_remeshing_io.cpp") create_single_source_cgal_program( "test_tetrahedral_remeshing_io.cpp")
create_single_source_cgal_program( "test_tetrahedral_remeshing_from_mesh_file.cpp")
# Tests using Mesh_3 require Eigen
find_package(Eigen3 3.1.0 REQUIRED) #(3.1.0 or greater)
include(CGAL_Eigen_support)
if (NOT TARGET CGAL::Eigen_support)
message(STATUS "This project requires the Eigen library, and will not be compiled.")
return()
endif()
create_single_source_cgal_program("test_mesh_and_remesh_polyhedral_domain_with_features.cpp")
target_link_libraries(test_mesh_and_remesh_polyhedral_domain_with_features PUBLIC CGAL::Eigen_support)
if( CGAL_ImageIO_USE_ZLIB )
create_single_source_cgal_program( "test_mesh_and_remesh_image.cpp")
target_link_libraries(test_mesh_and_remesh_image PUBLIC CGAL::Eigen_support)
endif()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,72 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Mesh_triangulation_3.h>
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
#include <CGAL/Mesh_criteria_3.h>
#include <CGAL/Labeled_mesh_domain_3.h>
#include <CGAL/make_mesh_3.h>
#include <CGAL/Image_3.h>
#include <CGAL/tetrahedral_remeshing.h>
// Domain
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Image_3 Image;
typedef CGAL::Labeled_mesh_domain_3<K> Mesh_domain;
// Triangulation
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Mesh Criteria
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
typedef Mesh_criteria::Facet_criteria Facet_criteria;
typedef Mesh_criteria::Cell_criteria Cell_criteria;
typedef CGAL::Triangulation_3<typename Tr::Geom_traits,
typename Tr::Triangulation_data_structure> T3;
using namespace CGAL::parameters;
int main()
{
const char* filename = "data/liver.inr.gz";
CGAL::Image_3 image;
if (!image.read(filename)) {
std::cerr << "Error: Cannot read file " << filename << std::endl;
return EXIT_FAILURE;
}
Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image, 1e-9);
// Mesh criteria
Facet_criteria facet_criteria(25, 20, 2); // angle, size, approximation
Cell_criteria cell_criteria(3, 20); // radius-edge ratio, size
Mesh_criteria criteria(facet_criteria, cell_criteria);
// Meshing
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria, no_exude(), no_perturb());
std::cout << "Meshing done." << std::endl;
//Remeshing : extract triangulation
T3 t3 = CGAL::convert_to_triangulation_3(c3t3);
//Remeshing : coarsen
double target_edge_length = 15.;
CGAL::tetrahedral_isotropic_remeshing(t3, target_edge_length,
CGAL::parameters::number_of_iterations(2));
std::cout << "Remeshing 1 done." << std::endl;
//Remeshing : refine
target_edge_length = 20.;
CGAL::tetrahedral_isotropic_remeshing(t3, target_edge_length,
CGAL::parameters::number_of_iterations(2).remesh_boundaries(false));
std::cout << "Remeshing 2 done." << std::endl;
return 0;
}

View File

@ -0,0 +1,81 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Mesh_triangulation_3.h>
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
#include <CGAL/Mesh_criteria_3.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polyhedral_mesh_domain_with_features_3.h>
#include <CGAL/make_mesh_3.h>
#include <CGAL/tetrahedral_remeshing.h>
// Domain
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Surface_mesh<K::Point_3> Polyhedron;
typedef CGAL::Polyhedral_mesh_domain_with_features_3<K, Polyhedron> Mesh_domain;
#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Parallel_tag Concurrency_tag;
#else
typedef CGAL::Sequential_tag Concurrency_tag;
#endif
// Triangulation
typedef CGAL::Mesh_triangulation_3<Mesh_domain, CGAL::Default, Concurrency_tag>::type Tr;
typedef CGAL::Mesh_complex_3_in_triangulation_3<
Tr, Mesh_domain::Corner_index, Mesh_domain::Curve_index> C3t3;
// Criteria
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
// To avoid verbose function and named parameters call
using namespace CGAL::parameters;
int main(int argc, char* argv[])
{
const char* fname = (argc > 1) ? argv[1] : "data/fandisk.off";
std::ifstream input(fname);
Polyhedron polyhedron;
input >> polyhedron;
if (input.fail()) {
std::cerr << "Error: Cannot read file " << fname << std::endl;
return EXIT_FAILURE;
}
if (!CGAL::is_triangle_mesh(polyhedron)) {
std::cerr << "Input geometry is not triangulated." << std::endl;
return EXIT_FAILURE;
}
// Create domain
Mesh_domain domain(polyhedron);
// Get sharp features
domain.detect_features();
// Mesh criteria
Mesh_criteria criteria(edge_size = 0.025,
facet_angle = 25, facet_size = 0.05, facet_distance = 0.005,
cell_radius_edge_ratio = 3, cell_size = 0.05);
// Mesh generation
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria);
auto t3 = CGAL::convert_to_triangulation_3(std::move(c3t3));
double target_edge_length = 0.1;//coarsen the mesh
CGAL::tetrahedral_isotropic_remeshing(t3, target_edge_length,
CGAL::parameters::number_of_iterations(3).remesh_boundaries(false));
assert(t3.is_valid());
target_edge_length = 0.04;//re-refine the mesh
CGAL::tetrahedral_isotropic_remeshing(t3, target_edge_length,
CGAL::parameters::number_of_iterations(1));//remesh_boundaries(true)
assert(t3.is_valid());
return EXIT_SUCCESS;
}

View File

@ -1,6 +1,6 @@
#define CGAL_TETRAHEDRAL_REMESHING_VERBOSE #define CGAL_TETRAHEDRAL_REMESHING_VERBOSE
#define CGAL_DUMP_REMESHING_STEPS //#define CGAL_DUMP_REMESHING_STEPS
#define CGAL_TETRAHEDRAL_REMESHING_DEBUG //#define CGAL_TETRAHEDRAL_REMESHING_DEBUG
//#define CGAL_TETRAHEDRAL_REMESHING_GENERATE_INPUT_FILES //#define CGAL_TETRAHEDRAL_REMESHING_GENERATE_INPUT_FILES
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>

View File

@ -0,0 +1,32 @@
//#define CGAL_TETRAHEDRAL_REMESHING_DEBUG
//#define CGAL_TETRAHEDRAL_REMESHING_VERBOSE
//#define CGAL_DUMP_REMESHING_STEPS
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Tetrahedral_remeshing/Remeshing_triangulation_3.h>
#include <CGAL/tetrahedral_remeshing.h>
#include <iostream>
#include <fstream>
#include <CGAL/Mesh_3/tet_soup_to_c3t3.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Tetrahedral_remeshing::Remeshing_triangulation_3<K> Remeshing_triangulation;
int main(int argc, char* argv[])
{
const double target_edge_length = (argc > 1) ? atof(argv[1]) : 0.1;
Remeshing_triangulation tr;
std::ifstream in("data/sphere.mesh");
if (CGAL::build_triangulation_from_file<Remeshing_triangulation, true>(in, tr))
std::cout << "build triangulation ok" << std::endl;
CGAL::tetrahedral_isotropic_remeshing(tr, target_edge_length);
return EXIT_SUCCESS;
}

View File

@ -567,7 +567,7 @@ protected:
public: public:
template<typename P> // Point or Point_3 template<typename P> // Point or Point_3
typename boost::result_of<const Construct_point_3(const P&)>::type typename boost::result_of<Construct_point_3(P)>::type
construct_point(const P& p) const construct_point(const P& p) const
{ {
return geom_traits().construct_point_3_object()(p); return geom_traits().construct_point_3_object()(p);