Merge remote-tracking branch 'origin/master' into Region_growing-revision-danston

This commit is contained in:
Dmitry Anisimov 2021-11-16 14:57:16 +01:00
commit 930278ec50
252 changed files with 3001 additions and 1347 deletions

View File

@ -6,7 +6,7 @@ jobs:
cmake-testsuite: cmake-testsuite:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2.0.0 - uses: actions/checkout@v2.0.0
- name: install dependencies - name: install dependencies
@ -15,7 +15,7 @@ jobs:
run: | run: |
set -e set -e
mkdir build && cd build && CXX=clang++ cmake -DWITH_examples=ON -DWITH_tests=ON -DWITH_demos=ON -DBUILD_TESTING=ON .. mkdir build && cd build && CXX=clang++ cmake -DWITH_examples=ON -DWITH_tests=ON -DWITH_demos=ON -DBUILD_TESTING=ON ..
ctest -L CGAL_cmake_testsuite ctest -L Installation -j $(getconf _NPROCESSORS_ONLN)
cmake-testsuite-with-qt5: cmake-testsuite-with-qt5:
@ -29,4 +29,4 @@ jobs:
run: | run: |
set -e set -e
mkdir build && cd build && CXX=clang++ cmake -DWITH_examples=ON -DWITH_tests=ON -DWITH_demos=ON -DBUILD_TESTING=ON .. mkdir build && cd build && CXX=clang++ cmake -DWITH_examples=ON -DWITH_tests=ON -DWITH_demos=ON -DBUILD_TESTING=ON ..
ctest -L CGAL_cmake_testsuite ctest -L Installation -j $(getconf _NPROCESSORS_ONLN)

View File

@ -58,8 +58,8 @@ namespace CGAL
typedef boost::readable_property_map_tag category; typedef boost::readable_property_map_tag category;
inline friend inline friend
reference value_type
get(Tet_from_cell_iterator_proprety_map<GeomTraits, Iterator>, key_type it) get(Tet_from_cell_iterator_proprety_map<GeomTraits, Iterator>, key_type it)
{ {
typename GeomTraits::Construct_point_3 point; typename GeomTraits::Construct_point_3 point;
return value_type(point(it->vertex(0)->point()), return value_type(point(it->vertex(0)->point()),

View File

@ -9,7 +9,7 @@ point.
\cgalRefines `ArrangementBasicTraits_2` \cgalRefines `ArrangementBasicTraits_2`
\cgalHasModel `CGAL::Arr_conic_traits_2<RatKernel,AlgKernel,NtTraits>` \cgalHasModel `CGAL::Arr_conic_traits_2<RatKernel,AlgKernel,NtTraits>`
\cond \cgalHasModel `CGAL::Arr_geodesic_arc_on_sphere_traits_2` \endcond \cgalHasModel `CGAL::Arr_geodesic_arc_on_sphere_traits_2`
\cgalHasModel `CGAL::Arr_linear_traits_2<Kernel>` \cgalHasModel `CGAL::Arr_linear_traits_2<Kernel>`
\cgalHasModel `CGAL::Arr_non_caching_segment_traits_2<Kernel>` \cgalHasModel `CGAL::Arr_non_caching_segment_traits_2<Kernel>`
\cgalHasModel `CGAL::Arr_segment_traits_2<Kernel>` \cgalHasModel `CGAL::Arr_segment_traits_2<Kernel>`

View File

@ -8,7 +8,7 @@
* \cgalRefines `ArrangementBasicTraits_2` * \cgalRefines `ArrangementBasicTraits_2`
* *
* \cgalHasModel `CGAL::Arr_conic_traits_2<RatKernel,AlgKernel,NtTraits>` * \cgalHasModel `CGAL::Arr_conic_traits_2<RatKernel,AlgKernel,NtTraits>`
* \cond \cgalHasModel `CGAL::Arr_geodesic_arc_on_sphere_traits_2` \endcond * \cgalHasModel `CGAL::Arr_geodesic_arc_on_sphere_traits_2`
* \cgalHasModel `CGAL::Arr_linear_traits_2<Kernel>` * \cgalHasModel `CGAL::Arr_linear_traits_2<Kernel>`
* \cgalHasModel `CGAL::Arr_non_caching_segment_traits_2<Kernel>` * \cgalHasModel `CGAL::Arr_non_caching_segment_traits_2<Kernel>`
* \cgalHasModel `CGAL::Arr_segment_traits_2<Kernel>` * \cgalHasModel `CGAL::Arr_segment_traits_2<Kernel>`

View File

@ -13,7 +13,7 @@
* `ArrangementConstructXMonotoneCurveTraits_2` * `ArrangementConstructXMonotoneCurveTraits_2`
* *
* \cgalHasModel `CGAL::Arr_conic_traits_2<RatKernel,AlgKernel,NtTraits>` * \cgalHasModel `CGAL::Arr_conic_traits_2<RatKernel,AlgKernel,NtTraits>`
* \cond \cgalHasModel `CGAL::Arr_geodesic_arc_on_sphere_traits_2` \endcond * \cgalHasModel `CGAL::Arr_geodesic_arc_on_sphere_traits_2`
* \cgalHasModel `CGAL::Arr_linear_traits_2<Kernel>` * \cgalHasModel `CGAL::Arr_linear_traits_2<Kernel>`
* \cgalHasModel `CGAL::Arr_non_caching_segment_traits_2<Kernel>` * \cgalHasModel `CGAL::Arr_non_caching_segment_traits_2<Kernel>`
* \cgalHasModel `CGAL::Arr_segment_traits_2<Kernel>` * \cgalHasModel `CGAL::Arr_segment_traits_2<Kernel>`

View File

@ -58,8 +58,11 @@ int main() {
} }
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
x1 = theRandom.get_int(random_min,random_max); do{
y1 = theRandom.get_int(random_min,random_max); x1 = theRandom.get_int(random_min,random_max);
y1 = theRandom.get_int(random_min,random_max);
}
while(x1==0 && y1==0);
boost::variant< Circular_arc_2, Line_arc_2 > v = boost::variant< Circular_arc_2, Line_arc_2 > v =
Circle_2( Point_2(x1,y1), x1*x1 + y1*y1); Circle_2( Point_2(x1,y1), x1*x1 + y1*y1);
ac.push_back(v); ac.push_back(v);

View File

@ -17,7 +17,8 @@
// A property map that reads/writes the information to/from the extended // A property map that reads/writes the information to/from the extended
// face. // face.
template <typename Arrangement, class Type> class Extended_face_property_map { template <typename Arrangement, class Type>
class Extended_face_property_map {
public: public:
typedef typename Arrangement::Face_handle Face_handle; typedef typename Arrangement::Face_handle Face_handle;
@ -32,8 +33,7 @@ public:
{ return key->data(); } { return key->data(); }
// The put function is required by the property map concept. // The put function is required by the property map concept.
friend void put(const Extended_face_property_map&, friend void put(const Extended_face_property_map&, key_type key, value_type val)
key_type key, value_type val)
{ key->set_data(val); } { key->set_data(val); }
}; };

View File

@ -42,7 +42,7 @@ public:
} }
}; };
double get(Edge_length_func edge_length, Arrangement_2::Halfedge_handle e) double get(const Edge_length_func& edge_length, Arrangement_2::Halfedge_handle e)
{ {
return edge_length(e); return edge_length(e);
} }

View File

@ -128,7 +128,7 @@ struct Dual_vertex_index_pmap{
typedef typename boost::graph_traits<G>::face_descriptor key_type; typedef typename boost::graph_traits<G>::face_descriptor key_type;
typedef typename Property_map::value_type value_type; typedef typename Property_map::value_type value_type;
typedef typename Property_map::reference reference; typedef typename Property_map::reference reference;
typedef typename Property_map::category category; typedef boost::readable_property_map_tag category;
Dual_vertex_index_pmap(const G& g) Dual_vertex_index_pmap(const G& g)
: m_pmap( get(boost::face_index, g) ) : m_pmap( get(boost::face_index, g) )
@ -147,7 +147,7 @@ struct Dual_face_index_pmap{
typedef typename boost::graph_traits<G>::vertex_descriptor key_type; typedef typename boost::graph_traits<G>::vertex_descriptor key_type;
typedef typename Property_map::value_type value_type; typedef typename Property_map::value_type value_type;
typedef typename Property_map::reference reference; typedef typename Property_map::reference reference;
typedef typename Property_map::category category; typedef boost::readable_property_map_tag category;
Dual_face_index_pmap(const G& g) Dual_face_index_pmap(const G& g)
: m_pmap( get(boost::vertex_index, g) ) : m_pmap( get(boost::vertex_index, g) )

View File

@ -727,7 +727,7 @@ struct Graph_with_descriptor_with_graph_property_map {
template <typename Descriptor> template <typename Descriptor>
friend friend
void void
put(const Graph_with_descriptor_with_graph_property_map<Graph,PM>& gpm, const Descriptor& d, const value_type& v) put(const Graph_with_descriptor_with_graph_property_map<Graph,PM>& gpm, const Descriptor& d, const value_type& v)
{ {
CGAL_assertion(gpm.graph!=nullptr); CGAL_assertion(gpm.graph!=nullptr);
CGAL_assertion(d.graph == gpm.graph); CGAL_assertion(d.graph == gpm.graph);
@ -747,9 +747,9 @@ struct Graph_with_descriptor_with_graph_property_map<Graph, PM, boost::lvalue_pr
Graph* graph; Graph* graph;
PM pm; PM pm;
value_type& operator[](key_type& k) const reference operator[](key_type& k) const
{ {
return get(*this, k); return get(*this, k);
} }
Graph_with_descriptor_with_graph_property_map() Graph_with_descriptor_with_graph_property_map()

View File

@ -12,11 +12,14 @@
#ifndef CGAL_BOOST_GRAPH_NAMED_FUNCTION_PARAMS_H #ifndef CGAL_BOOST_GRAPH_NAMED_FUNCTION_PARAMS_H
#define CGAL_BOOST_GRAPH_NAMED_FUNCTION_PARAMS_H #define CGAL_BOOST_GRAPH_NAMED_FUNCTION_PARAMS_H
#ifndef CGAL_NO_STATIC_ASSERTION_TESTS
#include <CGAL/basic.h> #include <CGAL/basic.h>
#endif
#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_same.hpp>
#include <boost/mpl/if.hpp> #include <boost/mpl/if.hpp>
#include <type_traits> #include <type_traits>
#include <utility>
#define CGAL_BGL_NP_TEMPLATE_PARAMETERS T, typename Tag, typename Base #define CGAL_BGL_NP_TEMPLATE_PARAMETERS T, typename Tag, typename Base
#define CGAL_BGL_NP_CLASS CGAL::Named_function_parameters<T,Tag,Base> #define CGAL_BGL_NP_CLASS CGAL::Named_function_parameters<T,Tag,Base>
@ -154,7 +157,9 @@ template <typename T, typename Tag, typename Base, typename Query_tag>
typename Get_param<Named_params_impl<T, Tag, Base>, Query_tag>::type typename Get_param<Named_params_impl<T, Tag, Base>, Query_tag>::type
get_parameter_impl(const Named_params_impl<T, Tag, Base>& np, Query_tag tag) get_parameter_impl(const Named_params_impl<T, Tag, Base>& np, Query_tag tag)
{ {
#ifndef CGAL_NO_STATIC_ASSERTION_TEST
CGAL_static_assertion( (!boost::is_same<Query_tag, Tag>::value) ); CGAL_static_assertion( (!boost::is_same<Query_tag, Tag>::value) );
#endif
return get_parameter_impl(static_cast<const typename Base::base&>(np), tag); return get_parameter_impl(static_cast<const typename Base::base&>(np), tag);
} }
@ -359,6 +364,7 @@ bool is_default_parameter(const T&)
} //namespace CGAL } //namespace CGAL
#ifndef CGAL_NO_STATIC_ASSERTION_TESTS
// code added to avoid silent runtime issues in non-updated code // code added to avoid silent runtime issues in non-updated code
namespace boost namespace boost
{ {
@ -368,5 +374,6 @@ namespace boost
CGAL_static_assertion(B && "You must use CGAL::parameters::get_parameter instead of boost::get_param"); CGAL_static_assertion(B && "You must use CGAL::parameters::get_parameter instead of boost::get_param");
} }
} }
#endif
#endif // CGAL_BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP #endif // CGAL_BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP

View File

@ -68,7 +68,7 @@ struct Alpha_expansion_old_API_wrapper_graph
: cost_matrix (cost_matrix) : cost_matrix (cost_matrix)
{ } { }
friend reference get (const Vertex_label_cost_map& pmap, key_type idx) friend value_type get (const Vertex_label_cost_map& pmap, key_type idx)
{ {
std::vector<double> out; std::vector<double> out;
out.reserve (pmap.cost_matrix->size()); out.reserve (pmap.cost_matrix->size());
@ -76,7 +76,6 @@ struct Alpha_expansion_old_API_wrapper_graph
out.push_back ((*pmap.cost_matrix)[i][idx]); out.push_back ((*pmap.cost_matrix)[i][idx]);
return out; return out;
} }
}; };
typedef CGAL::Pointer_property_map<double>::const_type Edge_cost_map; typedef CGAL::Pointer_property_map<double>::const_type Edge_cost_map;

View File

@ -291,7 +291,7 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
typedef boost::readable_property_map_tag category; typedef boost::readable_property_map_tag category;
typedef DummyNormalPmap Self; typedef DummyNormalPmap Self;
friend reference get(const Self&, const key_type&) { return CGAL::NULL_VECTOR; } friend value_type get(const Self&, const key_type&) { return CGAL::NULL_VECTOR; }
}; };
public: public:
@ -422,7 +422,7 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
typedef boost::read_write_property_map_tag category; typedef boost::read_write_property_map_tag category;
typedef DummyNormalMap Self; typedef DummyNormalMap Self;
friend reference get(const Self&, const key_type&) { return CGAL::NULL_VECTOR; } friend value_type get(const Self&, const key_type&) { return CGAL::NULL_VECTOR; }
friend void put(const Self&, const key_type&, const value_type&) { } friend void put(const Self&, const key_type&, const value_type&) { }
}; };
@ -466,7 +466,7 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
typedef boost::readable_property_map_tag category; typedef boost::readable_property_map_tag category;
typedef DummyPlaneIndexMap Self; typedef DummyPlaneIndexMap Self;
friend reference get(const Self&, const key_type&) { return -1; } friend value_type get(const Self&, const key_type&) { return -1; }
}; };
public: public:
@ -489,7 +489,7 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
typedef boost::readable_property_map_tag category; typedef boost::readable_property_map_tag category;
typedef DummyConstrainedMap Self; typedef DummyConstrainedMap Self;
friend reference get(const Self&, const key_type&) { return false; } friend value_type get(const Self&, const key_type&) { return false; }
}; };
public: public:

View File

@ -201,7 +201,7 @@ CGAL_add_named_parameter(pca_plane_t, pca_plane, pca_plane)
// tetrahedral remeshing parameters // tetrahedral remeshing parameters
CGAL_add_named_parameter(remesh_boundaries_t, remesh_boundaries, remesh_boundaries) CGAL_add_named_parameter(remesh_boundaries_t, remesh_boundaries, remesh_boundaries)
CGAL_add_named_parameter(cell_selector_t, cell_selector, cell_selector) CGAL_add_named_parameter(cell_selector_t, cell_selector, cell_is_selected_map)
CGAL_add_named_parameter(facet_is_constrained_t, facet_is_constrained, facet_is_constrained_map) CGAL_add_named_parameter(facet_is_constrained_t, facet_is_constrained, facet_is_constrained_map)
CGAL_add_named_parameter(smooth_constrained_edges_t, smooth_constrained_edges, smooth_constrained_edges) CGAL_add_named_parameter(smooth_constrained_edges_t, smooth_constrained_edges, smooth_constrained_edges)

View File

@ -105,14 +105,15 @@ struct Index_accessor
template<typename Handle> template<typename Handle>
struct Edge_index_accessor struct Edge_index_accessor
: boost::put_get_helper< std::size_t, Edge_index_accessor<Handle> >
{ {
typedef boost::readable_property_map_tag category; typedef boost::readable_property_map_tag category;
typedef std::size_t reference; typedef std::size_t reference;
typedef std::size_t value_type; typedef std::size_t value_type;
typedef Handle key_type; typedef Handle key_type;
reference operator[](Handle h) const { return h.id(); } value_type operator[](Handle h) const { return h.id(); }
friend inline value_type get(const Edge_index_accessor& m, const key_type k) { return m[k]; }
}; };
template<typename Handle, typename ValueType, typename Reference, template<typename Handle, typename ValueType, typename Reference,
@ -135,7 +136,7 @@ struct Point_accessor<Handle, ValueType, ConstReference, true>
: boost::put_get_helper< ConstReference, Point_accessor<Handle, ValueType, ConstReference, true> > : boost::put_get_helper< ConstReference, Point_accessor<Handle, ValueType, ConstReference, true> >
{ {
typedef boost::lvalue_property_map_tag category; typedef boost::lvalue_property_map_tag category;
typedef ConstReference reference; typedef ConstReference reference;
typedef ValueType value_type; typedef ValueType value_type;
typedef Handle key_type; typedef Handle key_type;
@ -160,10 +161,11 @@ struct Is_writable_property_map<PropertyMap, boost::writable_property_map_tag> :
template <typename PropertyMap> template <typename PropertyMap>
struct Is_writable_property_map<PropertyMap, boost::read_write_property_map_tag> : CGAL::Tag_true { }; struct Is_writable_property_map<PropertyMap, boost::read_write_property_map_tag> : CGAL::Tag_true { };
// 'lvalue_pmap_tag' is annoying, because the property map is allowed to be non-mutable, // 'lvalue_property_map_tag' is annoying, because the property map is allowed to be non-mutable,
// but boost::lvalue_property_map_tag is defined as: // but boost::lvalue_property_map_tag is always defined as:
// struct lvalue_property_map_tag : public read_write_property_map_tag // struct lvalue_property_map_tag : public read_write_property_map_tag
// so we can't just check that 'writable_property_map_tag' is a base of the lvalue tag. // whereas it should sometimes only be
// struct lvalue_property_map_tag : public readable_property_map_tag.
// //
// This checks if the reference is non-const, which is not completely correct: map[key] returning // This checks if the reference is non-const, which is not completely correct: map[key] returning
// a non-const reference doesn't mean that 'put(map, key, val)' exists, which is what a writable // a non-const reference doesn't mean that 'put(map, key, val)' exists, which is what a writable

View File

@ -37,11 +37,10 @@ public:
OpenMesh::HPropHandleT<Value>, OpenMesh::HPropHandleT<Value>,
OpenMesh::EPropHandleT<Value> >::type>::type>::type H; OpenMesh::EPropHandleT<Value> >::type>::type>::type H;
typedef boost::read_write_property_map_tag category; typedef boost::lvalue_property_map_tag category;
typedef Descriptor key_type; typedef Descriptor key_type;
typedef Value value_type; typedef Value value_type;
typedef value_type& reference; typedef value_type& reference;
OM_pmap() OM_pmap()
@ -66,19 +65,19 @@ public:
} }
inline friend reference get(const OM_pmap<Mesh,Descriptor,Value>& pm, inline friend reference get(const OM_pmap<Mesh,Descriptor,Value>& pm,
typename boost::graph_traits<Mesh>::face_descriptor k) typename boost::graph_traits<Mesh>::face_descriptor k)
{ {
return pm.mesh->property(pm.h,k); return pm.mesh->property(pm.h,k);
} }
inline friend reference get(const OM_pmap<Mesh,Descriptor,Value>& pm, inline friend reference get(const OM_pmap<Mesh,Descriptor,Value>& pm,
typename boost::graph_traits<Mesh>::halfedge_descriptor k) typename boost::graph_traits<Mesh>::halfedge_descriptor k)
{ {
return pm.mesh->property(pm.h,k); return pm.mesh->property(pm.h,k);
} }
inline friend reference get(const OM_pmap<Mesh,Descriptor,Value>& pm, inline friend reference get(const OM_pmap<Mesh,Descriptor,Value>& pm,
typename boost::graph_traits<Mesh>::edge_descriptor k) typename boost::graph_traits<Mesh>::edge_descriptor k)
{ {
typename Mesh::EdgeHandle eh(k.idx()); typename Mesh::EdgeHandle eh(k.idx());
return pm.mesh->property(pm.h,eh); return pm.mesh->property(pm.h,eh);
@ -133,7 +132,6 @@ public:
template <typename OpenMesh> template <typename OpenMesh>
class OM_edge_weight_pmap class OM_edge_weight_pmap
: public boost::put_get_helper<typename OpenMesh::Scalar , OM_edge_weight_pmap<OpenMesh> >
{ {
public: public:
typedef boost::readable_property_map_tag category; typedef boost::readable_property_map_tag category;
@ -150,17 +148,19 @@ public:
return sm_.calc_edge_length(e.halfedge()); return sm_.calc_edge_length(e.halfedge());
} }
friend inline value_type get(const OM_edge_weight_pmap& m, const key_type& k) { return m[k]; }
private: private:
const OpenMesh& sm_; const OpenMesh& sm_;
}; };
template <typename K, typename VEF> template <typename K, typename VEF>
class OM_index_pmap : public boost::put_get_helper<unsigned int, OM_index_pmap<K,VEF> > class OM_index_pmap
{ {
public: public:
typedef boost::readable_property_map_tag category; typedef boost::readable_property_map_tag category;
typedef unsigned int value_type; typedef unsigned int value_type;
typedef unsigned int reference; typedef unsigned int reference;
typedef VEF key_type; typedef VEF key_type;
OM_index_pmap() OM_index_pmap()
@ -170,18 +170,21 @@ public:
{ {
return vd.idx(); return vd.idx();
} }
friend inline value_type get(const OM_index_pmap& m, const key_type& k) { return m[k]; }
}; };
template<typename OpenMesh, typename P> template<typename OpenMesh, typename P>
class OM_point_pmap //: public boost::put_get_helper<bool, OM_point_pmap<OpenMesh> > class OM_point_pmap
{ {
public: public:
typedef boost::read_write_property_map_tag category;
#if defined(CGAL_USE_OM_POINTS) #if defined(CGAL_USE_OM_POINTS)
typedef boost::lvalue_property_map_tag category;
typedef typename OpenMesh::Point value_type; typedef typename OpenMesh::Point value_type;
typedef const typename OpenMesh::Point& reference; typedef const typename OpenMesh::Point& reference;
#else #else
typedef boost::read_write_property_map_tag category;
typedef P value_type; typedef P value_type;
typedef P reference; typedef P reference;
#endif #endif
@ -199,7 +202,7 @@ public:
: sm_(pm.sm_) : sm_(pm.sm_)
{} {}
value_type operator[](key_type v) reference operator[](key_type v)
{ {
#if defined(CGAL_USE_OM_POINTS) #if defined(CGAL_USE_OM_POINTS)
return sm_->point(v); return sm_->point(v);

View File

@ -53,7 +53,7 @@ struct Triangle_from_face_descriptor_map{
//get function for property map //get function for property map
inline friend inline friend
reference value_type
get(const Triangle_from_face_descriptor_map<TriangleMesh,VertexPointMap>& pmap, get(const Triangle_from_face_descriptor_map<TriangleMesh,VertexPointMap>& pmap,
key_type f) key_type f)
{ {
@ -66,7 +66,7 @@ struct Triangle_from_face_descriptor_map{
} }
inline friend inline friend
reference value_type
get(const Triangle_from_face_descriptor_map<TriangleMesh,VertexPointMap>& pmap, get(const Triangle_from_face_descriptor_map<TriangleMesh,VertexPointMap>& pmap,
const std::pair<key_type, const TriangleMesh*>& f) const std::pair<key_type, const TriangleMesh*>& f)
{ {
@ -111,7 +111,7 @@ struct Segment_from_edge_descriptor_map{
//get function for property map //get function for property map
inline friend inline friend
reference value_type
get(const Segment_from_edge_descriptor_map<PolygonMesh,VertexPointMap>& pmap, get(const Segment_from_edge_descriptor_map<PolygonMesh,VertexPointMap>& pmap,
key_type h) key_type h)
{ {
@ -120,7 +120,7 @@ struct Segment_from_edge_descriptor_map{
} }
inline friend inline friend
reference value_type
get(const Segment_from_edge_descriptor_map<PolygonMesh,VertexPointMap>& pmap, get(const Segment_from_edge_descriptor_map<PolygonMesh,VertexPointMap>& pmap,
const std::pair<key_type, const PolygonMesh*>& h) const std::pair<key_type, const PolygonMesh*>& h)
{ {
@ -154,7 +154,7 @@ struct One_point_from_face_descriptor_map{
typedef typename boost::graph_traits<PolygonMesh>::face_descriptor key_type; typedef typename boost::graph_traits<PolygonMesh>::face_descriptor key_type;
typedef typename boost::property_traits< VertexPointMap >::value_type value_type; typedef typename boost::property_traits< VertexPointMap >::value_type value_type;
typedef typename boost::property_traits< VertexPointMap >::reference reference; typedef typename boost::property_traits< VertexPointMap >::reference reference;
typedef boost::lvalue_property_map_tag category; typedef boost::readable_property_map_tag category;
//get function for property map //get function for property map
inline friend inline friend
@ -196,6 +196,7 @@ struct Source_point_from_edge_descriptor_map{
typedef typename boost::property_traits< VertexPointMap >::reference reference; typedef typename boost::property_traits< VertexPointMap >::reference reference;
typedef typename boost::graph_traits<PolygonMesh>::edge_descriptor key_type; typedef typename boost::graph_traits<PolygonMesh>::edge_descriptor key_type;
typedef boost::readable_property_map_tag category; typedef boost::readable_property_map_tag category;
//data //data
typename boost::remove_const<PolygonMesh>::type* m_pm; typename boost::remove_const<PolygonMesh>::type* m_pm;
VertexPointMap m_vpm; VertexPointMap m_vpm;

View File

@ -102,7 +102,7 @@ struct Regularization_graph
typedef vertex_descriptor key_type; typedef vertex_descriptor key_type;
typedef std::size_t value_type; typedef std::size_t value_type;
typedef std::size_t& reference; typedef std::size_t& reference;
typedef boost::lvalue_property_map_tag category; typedef boost::read_write_property_map_tag category;
Regularization_graph* rg; Regularization_graph* rg;
@ -132,7 +132,7 @@ struct Regularization_graph
: rg (rg) : rg (rg)
{ } { }
friend reference get (const Vertex_label_probability_map& pmap, key_type fd) friend value_type get (const Vertex_label_probability_map& pmap, key_type fd)
{ {
double value = (1. - pmap.rg->weight) * pmap.rg->area (fd) / pmap.rg->total_area; double value = (1. - pmap.rg->weight) * pmap.rg->area (fd) / pmap.rg->total_area;
@ -167,7 +167,7 @@ struct Regularization_graph
Edge_cost_map (const Regularization_graph* rg) Edge_cost_map (const Regularization_graph* rg)
: rg (rg) { } : rg (rg) { }
friend reference get (const Edge_cost_map& pmap, key_type ed) friend value_type get (const Edge_cost_map& pmap, key_type ed)
{ {
fg_vertex_descriptor esource = source(ed, pmap.rg->fg); fg_vertex_descriptor esource = source(ed, pmap.rg->fg);
fg_vertex_descriptor etarget = target(ed, pmap.rg->fg); fg_vertex_descriptor etarget = target(ed, pmap.rg->fg);

View File

@ -110,6 +110,7 @@ BOOST_PARAMETER_NAME( (pointer_to_stop_atomic_boolean, tag ) pointer_to_stop_ato
BOOST_PARAMETER_NAME( (function, tag ) function_) BOOST_PARAMETER_NAME( (function, tag ) function_)
BOOST_PARAMETER_NAME( (bounding_object, tag ) bounding_object_) BOOST_PARAMETER_NAME( (bounding_object, tag ) bounding_object_)
BOOST_PARAMETER_NAME( (relative_error_bound, tag ) relative_error_bound_) BOOST_PARAMETER_NAME( (relative_error_bound, tag ) relative_error_bound_)
BOOST_PARAMETER_NAME( (weights, tag) weights_)
BOOST_PARAMETER_NAME( (p_rng, tag ) p_rng_) BOOST_PARAMETER_NAME( (p_rng, tag ) p_rng_)
BOOST_PARAMETER_NAME( (null_subdomain_index, tag ) null_subdomain_index_) BOOST_PARAMETER_NAME( (null_subdomain_index, tag ) null_subdomain_index_)
BOOST_PARAMETER_NAME( (construct_surface_patch_index, tag ) construct_surface_patch_index_) BOOST_PARAMETER_NAME( (construct_surface_patch_index, tag ) construct_surface_patch_index_)

View File

@ -355,7 +355,7 @@ test_graph_range(const std::vector<Graph>& graphs)
typedef SM::Point Point_3; typedef SM::Point Point_3;
template<class Mesh, typename VertexPointPMap> template<class Mesh, typename VertexPointPMap>
struct Constraint : public boost::put_get_helper<bool,Constraint<Mesh, VertexPointPMap> > struct Constraint
{ {
typedef typename boost::graph_traits<Mesh>::edge_descriptor edge_descriptor; typedef typename boost::graph_traits<Mesh>::edge_descriptor edge_descriptor;
typedef boost::readable_property_map_tag category; typedef boost::readable_property_map_tag category;
@ -363,7 +363,6 @@ struct Constraint : public boost::put_get_helper<bool,Constraint<Mesh, VertexPoi
typedef bool reference; typedef bool reference;
typedef edge_descriptor key_type; typedef edge_descriptor key_type;
Constraint() Constraint()
:g_(NULL) :g_(NULL)
{} {}
@ -406,9 +405,12 @@ struct Constraint : public boost::put_get_helper<bool,Constraint<Mesh, VertexPoi
return false; return false;
} }
friend inline value_type get(const Constraint& m, const key_type k) { return m[k]; }
const Mesh* g_; const Mesh* g_;
VertexPointPMap vppmap; VertexPointPMap vppmap;
}; };
template<class Mesh, class FCCMAP, class Adapter> template<class Mesh, class FCCMAP, class Adapter>
void test_mesh(Adapter fga) void test_mesh(Adapter fga)
{ {

View File

@ -13,12 +13,12 @@ struct Non_mutable_property_map
{ {
typedef Key key_type; typedef Key key_type;
typedef Value value_type; typedef Value value_type;
typedef value_type reference; typedef const value_type& reference;
typedef boost::readable_property_map_tag category; typedef boost::readable_property_map_tag category;
Non_mutable_property_map(const Container& c) : m_c(c) { } Non_mutable_property_map(const Container& c) : m_c(c) { }
friend reference get(const Non_mutable_property_map<Key, Value, Container>& pmap, key_type k) friend reference get(const Non_mutable_property_map<Key, Value, Container>& pmap, const key_type& k)
{ {
return pmap.m_c.at(k); return pmap.m_c.at(k);
} }
@ -42,7 +42,7 @@ struct RW_property_map
pmap.m_c[k] = val; pmap.m_c[k] = val;
} }
friend reference get(RW_property_map<Key, Value, Container>& pmap, const key_type& k) friend reference get(const RW_property_map<Key, Value, Container>& pmap, const key_type& k)
{ {
return pmap.m_c[k]; return pmap.m_c[k];
} }

View File

@ -0,0 +1,15 @@
namespace CGAL {
/*!
\ingroup PkgDrawPolygonSet2
opens a new window and draws `aps`, an instance of the `CGAL::Polygon_set_2` class. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires `CGAL_Qt5`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is defined.
Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt5` and add the definition `CGAL_USE_BASIC_VIEWER`.
\tparam PS an instance of the `CGAL::Polygon_set_2` class.
\param aps the polygon set to draw.
*/
template<class PS>
void draw(const PS& aps);
} /* end namespace CGAL */

View File

@ -6,6 +6,14 @@
/// The namespace containing concepts specific to 2D Boolean Set Operations. /// The namespace containing concepts specific to 2D Boolean Set Operations.
namespace ArrDirectionalTraits {} namespace ArrDirectionalTraits {}
/*!
\code
#include <CGAL/draw_polygon_set_2.h>
\endcode
*/
/// \defgroup PkgDrawPolygonSet2 Draw a 2D Polygon Set
/// \ingroup PkgBooleanSetOperations2Ref
/*! /*!
\addtogroup PkgBooleanSetOperations2Ref \addtogroup PkgBooleanSetOperations2Ref
\todo check generated documentation \todo check generated documentation
@ -62,4 +70,7 @@ containment predicates.
- \link boolean_oriented_side `CGAL::oriented_side()` \endlink - \link boolean_oriented_side `CGAL::oriented_side()` \endlink
- \link boolean_connect_holes `CGAL::connect_holes()` \endlink - \link boolean_connect_holes `CGAL::connect_holes()` \endlink
\cgalCRPSection{Draw a Polygon_set_2}
- \link PkgDrawPolygonSet2 CGAL::draw<PS>() \endlink
*/ */

View File

@ -5,6 +5,7 @@
\example Boolean_set_operations_2/conic_traits_adapter.cpp \example Boolean_set_operations_2/conic_traits_adapter.cpp
\example Boolean_set_operations_2/connect_polygon.cpp \example Boolean_set_operations_2/connect_polygon.cpp
\example Boolean_set_operations_2/do_intersect.cpp \example Boolean_set_operations_2/do_intersect.cpp
\example Boolean_set_operations_2/draw_polygon_set.cpp
\example Boolean_set_operations_2/dxf_union.cpp \example Boolean_set_operations_2/dxf_union.cpp
\example Boolean_set_operations_2/sequence.cpp \example Boolean_set_operations_2/sequence.cpp
\example Boolean_set_operations_2/set_union.cpp \example Boolean_set_operations_2/set_union.cpp

View File

@ -4,9 +4,7 @@
cmake_minimum_required(VERSION 3.1...3.20) cmake_minimum_required(VERSION 3.1...3.20)
project(Boolean_set_operations_2_Examples) project(Boolean_set_operations_2_Examples)
find_package(CGAL REQUIRED COMPONENTS Core) find_package(CGAL REQUIRED COMPONENTS Core OPTIONAL_COMPONENTS Qt5)
include(${CGAL_USE_FILE})
# create a target per cppfile # create a target per cppfile
file( file(
@ -16,3 +14,12 @@ file(
foreach(cppfile ${cppfiles}) foreach(cppfile ${cppfiles})
create_single_source_cgal_program("${cppfile}") create_single_source_cgal_program("${cppfile}")
endforeach() endforeach()
if(CGAL_Qt5_FOUND)
target_link_libraries(draw_polygon_set PUBLIC CGAL::CGAL_Basic_viewer)
else()
message(
STATUS
"NOTICE: The example draw_polygon_set requires Qt and drawing will be disabled."
)
endif()

View File

@ -0,0 +1,47 @@
/*! \file draw_polygon_set.cpp
* Drawing a polygon set.
*/
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Polygon_with_holes_2.h>
#include <CGAL/Polygon_set_2.h>
#include <CGAL/draw_polygon_set_2.h>
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
typedef CGAL::Polygon_2<K> Polygon_2;
typedef CGAL::Polygon_with_holes_2<K> Polygon_with_holes_2;
typedef CGAL::Polygon_set_2<K> Polygon_set_2;
typedef CGAL::Point_2<K> Point_2;
Polygon_2 rectangle(int l)
{
// Create a rectangle with given side length.
Polygon_2 P;
P.push_back(Point_2(-l,-l));
P.push_back(Point_2(l,-l));
P.push_back(Point_2(l,l));
P.push_back(Point_2(-l,l));
return P;
}
int main()
{
// Create a large rectangle A, with a hole and a smaller rectangle
// B inside A's hole.
Polygon_with_holes_2 A(rectangle(3));
Polygon_2 H(rectangle(2));
H.reverse_orientation();
A.add_hole(H);
Polygon_2 B(rectangle(1));
// Add them to a polygon set and draw it.
Polygon_set_2 S;
S.insert(A);
S.insert(B);
CGAL::draw(S);
return 0;
}

View File

@ -0,0 +1,94 @@
// Copyright (c) 1997
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
#ifndef CGAL_DRAW_POLYGON_SET_2_H
#define CGAL_DRAW_POLYGON_SET_2_H
#include <CGAL/draw_polygon_with_holes_2.h>
#ifdef DOXYGEN_RUNNING
namespace CGAL {
/*!
\ingroup PkgDrawPolygonSet2
opens a new window and draws `aps`, an instance of the `CGAL::Polygon_set_2` class. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires `CGAL_Qt5`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is defined.
Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt5` and add the definition `CGAL_USE_BASIC_VIEWER`.
\tparam PS an instance of the `CGAL::Polygon_set_2` class.
\param aps the polygon set to draw.
*/
template<class PS>
void draw(const PS& aps);
} /* namespace CGAL */
#endif
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Polygon_set_2.h>
namespace CGAL
{
template<class PS2>
class SimplePolygonSet2ViewerQt :
public SimplePolygonWithHoles2ViewerQt<typename PS2::Polygon_with_holes_2>
{
typedef SimplePolygonWithHoles2ViewerQt<typename PS2::Polygon_with_holes_2> Base;
public:
SimplePolygonSet2ViewerQt(QWidget* parent, const PS2& aps2,
const char* title="Basic Polygon_set_2 Viewer") :
Base(parent, title)
{
std::vector<typename PS2::Polygon_with_holes_2> polygons;
aps2.polygons_with_holes(std::back_inserter(polygons));
for (typename PS2::Polygon_with_holes_2& P: polygons) {
Base::compute_elements(P);
}
}
};
// Specialization of draw function.
template<class T, class C>
void draw(const CGAL::Polygon_set_2<T, C>& aps2,
const char* title="Polygon_set_2 Basic Viewer")
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
if (!cgal_test_suite)
{
CGAL::Qt::init_ogl_context(4,3);
int argc=1;
const char* argv[2]={"t2_viewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimplePolygonSet2ViewerQt<CGAL::Polygon_set_2<T, C> >
mainwindow(app.activeWindow(), aps2, title);
mainwindow.show();
app.exec();
}
}
} // End namespace CGAL
#endif // CGAL_USE_BASIC_VIEWER
#endif // CGAL_DRAW_POLYGON_SET_2_H

View File

@ -8,6 +8,7 @@ Circulator
Distance_2 Distance_2
Distance_3 Distance_3
Filtered_kernel Filtered_kernel
GraphicsView
HalfedgeDS HalfedgeDS
Hash_map Hash_map
Homogeneous_kernel Homogeneous_kernel

View File

@ -28,6 +28,7 @@
#include <limits> #include <limits>
#include <set> #include <set>
#include <cstdlib> #include <cstdlib>
#include <string>
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
# pragma warning(push) # pragma warning(push)
@ -102,7 +103,7 @@ public:
// std::cerr << "Image_3::copy_constructor\n"; // std::cerr << "Image_3::copy_constructor\n";
} }
Image_3(_image* im, Own own_the_data = OWN_THE_DATA) explicit Image_3(_image* im, Own own_the_data = OWN_THE_DATA)
{ {
private_read(im, own_the_data); private_read(im, own_the_data);
} }
@ -146,9 +147,9 @@ public:
double vy() const { return image_ptr->vy; } double vy() const { return image_ptr->vy; }
double vz() const { return image_ptr->vz; } double vz() const { return image_ptr->vz; }
double tx() const { return image_ptr->tx; } float tx() const { return image_ptr->tx; }
double ty() const { return image_ptr->ty; } float ty() const { return image_ptr->ty; }
double tz() const { return image_ptr->tz; } float tz() const { return image_ptr->tz; }
float value(const std::size_t i, float value(const std::size_t i,
const std::size_t j, const std::size_t j,
@ -157,6 +158,11 @@ public:
return ::evaluate(image(),i,j,k); return ::evaluate(image(),i,j,k);
} }
bool is_valid() const
{
return image_ptr.get() != nullptr;
}
public: public:
bool read(const char* file) bool read(const char* file)
@ -164,6 +170,11 @@ public:
return private_read(::_readImage(file)); return private_read(::_readImage(file));
} }
bool read(const std::string& file)
{
return read(file.c_str());
}
bool read_raw(const char* file, bool read_raw(const char* file,
const unsigned int rx, const unsigned int rx,
const unsigned int ry, const unsigned int ry,

View File

@ -191,28 +191,12 @@ int main() {
image.set_data(nullptr); // trick to avoid ~Image_3 segfault. image.set_data(nullptr); // trick to avoid ~Image_3 segfault.
const char* filenames[] = { const std::string filename = CGAL::data_file_path("images/skull_2.9.inr");
"data/skull_2.9.inr",
"../../examples/Surface_mesher/data/skull_2.9.inr",
"../../../Surface_mesher/examples/Surface_mesher/data/skull_2.9.inr",
"../Surface_mesher_Examples/data/skull_2.9.inr"
};
std::size_t file_index = 0; std::cerr << "Opening file " << filename << "...\n";
for( ; file_index < sizeof(filenames); ++file_index)
{
std::ifstream image_file(filenames[file_index], std::ios_base::binary | std::ios_base::in );
if(image_file) {
break;
}
}
assert(file_index < sizeof(filenames) );
std::cerr << "Opening file " << filenames[file_index] << "...\n";
CGAL::Image_3 image2; CGAL::Image_3 image2;
const bool result = image2.read(filenames[file_index]); const bool result = image2.read(filename);
assert(result); assert(result);
std::cerr << "Image info:" std::cerr << "Image info:"

View File

@ -4380,6 +4380,8 @@ namespace CartesianKernelFunctors {
typedef typename K::Circle_2 Circle_2; typedef typename K::Circle_2 Circle_2;
typedef typename K::Line_2 Line_2; typedef typename K::Line_2 Line_2;
typedef typename K::Triangle_2 Triangle_2; typedef typename K::Triangle_2 Triangle_2;
typedef typename K::Segment_2 Segment_2;
typedef typename K::FT FT;
public: public:
typedef typename K::Oriented_side result_type; typedef typename K::Oriented_side result_type;
@ -4416,6 +4418,30 @@ namespace CartesianKernelFunctors {
? result_type(ON_ORIENTED_BOUNDARY) ? result_type(ON_ORIENTED_BOUNDARY)
: opposite(ot); : opposite(ot);
} }
result_type
operator()(const Segment_2& s, const Triangle_2& t) const
{
typename K::Construct_source_2 source;
typename K::Construct_target_2 target;
const Point_2& a = source(s);
const Point_2& b = target(s);
CGAL_assertion(a != b);
typename K::Construct_vertex_2 vertex;
const Point_2& p0 = vertex(t, 0);
const Point_2& p1 = vertex(t, 1);
const Point_2& p2 = vertex(t, 2);
CGAL_assertion(p0 != p1 && p1 != p2 && p2 != p0);
return circumcenter_oriented_side_of_oriented_segmentC2(
a.x(), a.y(),
b.x(), b.y(),
p0.x(), p0.y(),
p1.x(), p1.y(),
p2.x(), p2.y()
);
}
}; };
template <typename K> template <typename K>

View File

@ -708,6 +708,28 @@ power_side_of_oriented_power_circleC2(const FT &px, const FT &py, const FT &pwt,
return cmpy * sign_of_determinant(dpy, dpz, dqy, dqz); return cmpy * sign_of_determinant(dpy, dpz, dqy, dqz);
} }
template <class FT>
Oriented_side
circumcenter_oriented_side_of_oriented_segmentC2(const FT& ax, const FT& ay,
const FT& bx, const FT& by,
const FT& p0x, const FT& p0y,
const FT& p1x, const FT& p1y,
const FT& p2x, const FT& p2y)
{
const FT dX = bx - ax;
const FT dY = by - ay;
const FT R0 = p0x * p0x + p0y * p0y;
const FT R1 = p1x * p1x + p1y * p1y;
const FT R2 = p2x * p2x + p2y * p2y;
const FT denominator = (p1x - p0x) * (p2y - p0y) +
(p0x - p2x) * (p1y - p0y);
const FT det = 2 * denominator * (ax * dY - ay * dX)
- (R2 - R1) * (p0x * dX + p0y * dY)
- (R0 - R2) * (p1x * dX + p1y * dY)
- (R1 - R0) * (p2x * dX + p2y * dY);
return CGAL::sign(det);
}
} //namespace CGAL } //namespace CGAL
#endif // CGAL_PREDICATES_KERNEL_FTC2_H #endif // CGAL_PREDICATES_KERNEL_FTC2_H

View File

@ -66,7 +66,6 @@ public:
public: public:
using argument_type = std::size_t; using argument_type = std::size_t;
using result_type = typename boost::property_traits<ItemMap>::reference; using result_type = typename boost::property_traits<ItemMap>::reference;
using category = boost::readable_property_map_tag;
const ItemRange* m_range; const ItemRange* m_range;
ItemMap m_item_map; ItemMap m_item_map;

View File

@ -67,10 +67,12 @@ class Point_set_neighborhood
using value_type = typename boost::property_traits<PointMap>::value_type; using value_type = typename boost::property_traits<PointMap>::value_type;
using reference = typename boost::property_traits<PointMap>::reference; using reference = typename boost::property_traits<PointMap>::reference;
using key_type = std::uint32_t; using key_type = std::uint32_t;
using category = typename boost::property_traits<PointMap>::category; using category = boost::readable_property_map_tag;
My_point_property_map () { } My_point_property_map () { }
My_point_property_map (const PointRange *input, PointMap point_map) My_point_property_map (const PointRange *input, PointMap point_map)
: input (input), point_map (point_map) { } : input (input), point_map (point_map) { }
friend reference get (const My_point_property_map& ppmap, key_type i) friend reference get (const My_point_property_map& ppmap, key_type i)
{ return get(ppmap.point_map, *(ppmap.input->begin()+std::size_t(i))); } { return get(ppmap.point_map, *(ppmap.input->begin()+std::size_t(i))); }
}; };

View File

@ -67,7 +67,7 @@ public:
: m_mesh (mesh), m_vpm (vpm) { } : m_mesh (mesh), m_vpm (vpm) { }
/// \cond SKIP_IN_MANUAL /// \cond SKIP_IN_MANUAL
inline friend reference get (const Face_descriptor_to_center_of_mass_map& map, key_type f) inline friend value_type get (const Face_descriptor_to_center_of_mass_map& map, key_type f)
{ {
std::vector<Point_3> points; std::vector<Point_3> points;
@ -139,7 +139,7 @@ public:
: m_mesh (mesh), m_vpm (vpm) { } : m_mesh (mesh), m_vpm (vpm) { }
/// \cond SKIP_IN_MANUAL /// \cond SKIP_IN_MANUAL
inline friend reference get (const Face_descriptor_to_face_descriptor_with_bbox_map& map, key_type f) inline friend value_type get (const Face_descriptor_to_face_descriptor_with_bbox_map& map, key_type f)
{ {
CGAL::Bbox_3 bbox; CGAL::Bbox_3 bbox;

Binary file not shown.

View File

@ -0,0 +1,13 @@
namespace CGAL{
/// returns the full path of a data file from \cgal.
/// The data files are located in the `data` directory of a \cgal release
/// or in the directory `Data/data` from a git branch checkout.
/// That function uses as prefix the environment variable `CGAL_DATA_DIR` if set, and
/// the value of the macro `CGAL_DATA_DIR` otherwise.
/// When using `cmake` and a standard \cgal setup, linking the target using that function
/// with the target `CGAL::Data` will automatically set the macro `CGAL_DATA_DIR`
/// pointing to the data directory of the \cgal version used.
/// The function will attempt to open the file at the returned location
/// and will print a warning message via `std::cerr` if the file could not be opened.
std::string data_file_path(const std::string& filename);
}

View File

@ -3256,6 +3256,12 @@ pages = "207--221"
publisher = {ACM} publisher = {ACM}
} }
@article{stalling1998weighted,
title={Weighted labels for 3D image segmentation},
author={Stalling, Detlev and Z{\"o}ckler, Malte and Sander, Oliver and Hege, Hans-Christian},
year={1998}
}
% ---------------------------------------------------------------------------- % ----------------------------------------------------------------------------
% END OF BIBFILE % END OF BIBFILE
% ---------------------------------------------------------------------------- % ----------------------------------------------------------------------------

View File

@ -356,6 +356,7 @@ div.summary
text-align: left; text-align: left;
outline: none; outline: none;
font: 14px Roboto,sans-serif; font: 14px Roboto,sans-serif;
user-select: auto;
} }
.active, .collapsible:hover { .active, .collapsible:hover {

View File

@ -356,6 +356,7 @@ div.summary
text-align: left; text-align: left;
outline: none; outline: none;
font: 14px Roboto,sans-serif; font: 14px Roboto,sans-serif;
user-select: auto;
} }
.active, .collapsible:hover { .active, .collapsible:hover {

View File

@ -356,6 +356,7 @@ div.summary
text-align: left; text-align: left;
outline: none; outline: none;
font: 14px Roboto,sans-serif; font: 14px Roboto,sans-serif;
user-select: auto;
} }
.active, .collapsible:hover { .active, .collapsible:hover {

View File

@ -347,6 +347,7 @@ div.summary
text-align: left; text-align: left;
outline: none; outline: none;
font: 14px Roboto,sans-serif; font: 14px Roboto,sans-serif;
user-select: auto;
} }
.active, .collapsible:hover { .active, .collapsible:hover {

View File

@ -356,6 +356,7 @@ div.summary
text-align: left; text-align: left;
outline: none; outline: none;
font: 14px Roboto,sans-serif; font: 14px Roboto,sans-serif;
user-select: auto;
} }
.active, .collapsible:hover { .active, .collapsible:hover {

View File

@ -43,6 +43,7 @@ class Do_intersect_3
typedef typename K_base::Ray_3 Ray_3; typedef typename K_base::Ray_3 Ray_3;
typedef typename K_base::Segment_3 Segment_3; typedef typename K_base::Segment_3 Segment_3;
typedef typename K_base::Triangle_3 Triangle_3; typedef typename K_base::Triangle_3 Triangle_3;
typedef typename K_base::Tetrahedron_3 Tetrahedron_3;
typedef typename K_base::Sphere_3 Sphere_3; typedef typename K_base::Sphere_3 Sphere_3;
typedef typename K_base::Do_intersect_3 Base; typedef typename K_base::Do_intersect_3 Base;
@ -126,7 +127,46 @@ public:
return Base::operator()(s,b); return Base::operator()(s,b);
} }
result_type
operator()(const Bbox_3& b, const Tetrahedron_3 &t) const
{
return this->operator()(t, b);
}
result_type
operator()(const Tetrahedron_3 &t, const Bbox_3& b) const
{
CGAL_BRANCH_PROFILER_3(std::string("semi-static failures/attempts/calls to : ") +
std::string(CGAL_PRETTY_FUNCTION), tmp);
Get_approx<Point_3> get_approx;
double px, py, pz;
for(int i = 0; i < 4; ++i)
{
const Point_3& p = t[i];
if (fit_in_double(get_approx(p).x(), px) && fit_in_double(get_approx(p).y(), py) &&
fit_in_double(get_approx(p).z(), pz) )
{
CGAL_BRANCH_PROFILER_BRANCH_1(tmp);
if( (px >= b.xmin() && px <= b.xmax()) &&
(py >= b.ymin() && py <= b.ymax()) &&
(pz >= b.zmin() && pz <= b.zmax()) )
{
return true;
}
CGAL_BRANCH_PROFILER_BRANCH_2(tmp);
}
else
{
return Base::operator()(t,b);
}
}
return Base::operator()(t,b);
}
result_type result_type
operator()(const Bbox_3& b, const Ray_3 &r) const operator()(const Bbox_3& b, const Ray_3 &r) const
@ -169,6 +209,396 @@ public:
return Base::operator()(r,b); return Base::operator()(r,b);
} }
result_type
operator()(const Bbox_3& b, const Triangle_3 &t) const
{
return this->operator()(t, b);
}
Uncertain<Sign> sign_of_minor(double px, double py, double qx, double qy, double rx, double ry) const
{
CGAL_BRANCH_PROFILER_3("certain / uncertain / calls to : sign_of_minor", tmp);
double qx_px = (qx - px);
double ry_py = (ry - py);
double rx_px = (rx - px);
double qy_py = (qy - py);
Sign int_tmp_result;
double double_tmp_result;
double eps;
double_tmp_result = ((qx_px * ry_py) - (rx_px * qy_py));
double max1 = CGAL::abs(qx_px);
if( (max1 < CGAL::abs(rx_px)) )
{
max1 = CGAL::abs(rx_px);
}
double max2 = CGAL::abs(ry_py);
if( (max2 < CGAL::abs(qy_py)) )
{
max2 = CGAL::abs(qy_py);
}
double lower_bound_1;
double upper_bound_1;
lower_bound_1 = max1;
upper_bound_1 = max1;
if( (max2 < lower_bound_1) )
{
lower_bound_1 = max2;
}
else
{
if( (max2 > upper_bound_1) )
{
upper_bound_1 = max2;
}
}
if( (lower_bound_1 < 5.00368081960964746551e-147) )
{
CGAL_BRANCH_PROFILER_BRANCH_1(tmp);
return Uncertain<Sign>::indeterminate();
}
else
{
if( (upper_bound_1 > 1.67597599124282389316e+153) )
{
CGAL_BRANCH_PROFILER_BRANCH_1(tmp);
return Uncertain<Sign>::indeterminate();
}
eps = (8.88720573725927976811e-16 * (max1 * max2));
if( (double_tmp_result > eps) )
{
int_tmp_result = POSITIVE;
}
else
{
if( (double_tmp_result < -eps) )
{
int_tmp_result = NEGATIVE;
}
else
{
CGAL_BRANCH_PROFILER_BRANCH_1(tmp);
return Uncertain<Sign>::indeterminate();
}
}
}
CGAL_BRANCH_PROFILER_BRANCH_2(tmp);
return int_tmp_result;
};
bool get_cross_product_sign(const std::array< std::array<double, 3>, 3 >& pts, std::array<Sign, 3>& signs) const
{
CGAL_BRANCH_PROFILER_3("determinate / indeterminate / calls to : get_cross_product_sign", tmp);
Uncertain<Sign> s = sign_of_minor(pts[0][1], pts[0][2], pts[1][1], pts[1][2], pts[2][1], pts[2][2]);
if (is_indeterminate(s)){
CGAL_BRANCH_PROFILER_BRANCH_1(tmp);
return false;
}
signs[0]=make_certain(s);
s = sign_of_minor(pts[0][2], pts[0][0], pts[1][2], pts[1][0], pts[2][2], pts[2][0]);
if (is_indeterminate(s)){
CGAL_BRANCH_PROFILER_BRANCH_1(tmp);
return false;
}
signs[1]=make_certain(s);
s = sign_of_minor(pts[0][0], pts[0][1], pts[1][0], pts[1][1], pts[2][0], pts[2][1]);
if (is_indeterminate(s)){
CGAL_BRANCH_PROFILER_BRANCH_1(tmp);
return false;
}
signs[2]=make_certain(s);
CGAL_BRANCH_PROFILER_BRANCH_2(tmp);
return true;
}
// adaptation of the do-intersect code of Plane_3/Bbox_3 when we don't know the plane equation exactly
bool do_intersect_supporting_plane_bbox(const Triangle_3& t, const std::array< std::array<double, 3>, 3>& pts, const Bbox_3& bbox) const
{
// copy of the static filter of Orientation_3 skipping the fit_in_double + using Uncertain as result type
auto statically_filtered_orientation_3 =
[](const std::array< std::array<double, 3>, 3>& pts, double x, double y, double z)
-> Uncertain<Orientation>
{
CGAL_BRANCH_PROFILER(std::string("Plane-BBox_3 semi-static Orientation_3 calls to/failures : ") +
std::string(CGAL_PRETTY_FUNCTION), tmp);
double pqx = pts[1][0] - pts[0][0];
double pqy = pts[1][1] - pts[0][1];
double pqz = pts[1][2] - pts[0][2];
double prx = pts[2][0] - pts[0][0];
double pry = pts[2][1] - pts[0][1];
double prz = pts[2][2] - pts[0][2];
double psx = x - pts[0][0];
double psy = y - pts[0][1];
double psz = z - pts[0][2];
// CGAL::abs uses fabs on platforms where it is faster than (a<0)?-a:a
// Then semi-static filter.
double maxx = CGAL::abs(pqx);
double maxy = CGAL::abs(pqy);
double maxz = CGAL::abs(pqz);
double aprx = CGAL::abs(prx);
double apsx = CGAL::abs(psx);
double apry = CGAL::abs(pry);
double apsy = CGAL::abs(psy);
double aprz = CGAL::abs(prz);
double apsz = CGAL::abs(psz);
#ifdef CGAL_USE_SSE2_MAX
CGAL::Max<double> mmax;
maxx = mmax(maxx, aprx, apsx);
maxy = mmax(maxy, apry, apsy);
maxz = mmax(maxz, aprz, apsz);
#else
if (maxx < aprx) maxx = aprx;
if (maxx < apsx) maxx = apsx;
if (maxy < apry) maxy = apry;
if (maxy < apsy) maxy = apsy;
if (maxz < aprz) maxz = aprz;
if (maxz < apsz) maxz = apsz;
#endif
double det = CGAL::determinant(pqx, pqy, pqz,
prx, pry, prz,
psx, psy, psz);
double eps = 5.1107127829973299e-15 * maxx * maxy * maxz;
#ifdef CGAL_USE_SSE2_MAX
#if 0
CGAL::Min<double> mmin;
double tmp = mmin(maxx, maxy, maxz);
maxz = mmax(maxx, maxy, maxz);
maxx = tmp;
#else
sse2minmax(maxx,maxy,maxz);
// maxy can contain ANY element
#endif
#else
// Sort maxx < maxy < maxz.
if (maxx > maxz)
std::swap(maxx, maxz);
if (maxy > maxz)
std::swap(maxy, maxz);
else if (maxy < maxx)
std::swap(maxx, maxy);
#endif
// Protect against underflow in the computation of eps.
if (maxx < 1e-97) /* cbrt(min_double/eps) */ {
if (maxx == 0)
return ZERO;
}
// Protect against overflow in the computation of det.
else if (maxz < 1e102) /* cbrt(max_double [hadamard]/4) */ {
if (det > eps) return POSITIVE;
if (det < -eps) return NEGATIVE;
}
CGAL_BRANCH_PROFILER_BRANCH(tmp);
return Uncertain<Orientation>::indeterminate();
};
auto orientation =
[statically_filtered_orientation_3]
(const Triangle_3& t, const std::array< std::array<double, 3>, 3>& pts, double x, double y, double z)
-> Orientation
{
Uncertain<Orientation> res = statically_filtered_orientation_3(pts, x, y, z);
if (!is_indeterminate(res)) return make_certain(res);
typename K_base::Orientation_3 orient = K_base().orientation_3_object(); // skip the static filter and directly call the base
return orient(t[0], t[1], t[2], Point_3(x,y,z));
};
std::array<Sign, 3> signs;
bool OK = get_cross_product_sign(pts, signs);
if (OK)
{
// extract extreme directions (copy of the code of get_min_max from Bbox_3_Plane_3_do_intersect.h)
std::array<double, 3> p_min, p_max;
if(signs[0] == POSITIVE) {
if(signs[1] == POSITIVE) {
if(signs[2] == POSITIVE) {
p_min = {bbox.xmin(), bbox.ymin(),bbox.zmin()};
p_max = {bbox.xmax(), bbox.ymax(),bbox.zmax()};
} else {
p_min = {bbox.xmin(), bbox.ymin(),bbox.zmax()};
p_max = {bbox.xmax(), bbox.ymax(),bbox.zmin()};
}
} else {
if(signs[2]==POSITIVE) {
p_min = {bbox.xmin(), bbox.ymax(),bbox.zmin()};
p_max = {bbox.xmax(), bbox.ymin(),bbox.zmax()};
} else {
p_min = {bbox.xmin(), bbox.ymax(),bbox.zmax()};
p_max = {bbox.xmax(), bbox.ymin(),bbox.zmin()};
}
}
}
else{
if(signs[1]==POSITIVE) {
if(signs[2]==POSITIVE) {
p_min = {bbox.xmax(), bbox.ymin(),bbox.zmin()};
p_max = {bbox.xmin(), bbox.ymax(),bbox.zmax()};
}
else{
p_min = {bbox.xmax(), bbox.ymin(),bbox.zmax()};
p_max = {bbox.xmin(), bbox.ymax(),bbox.zmin()};
}
}
else {
if(signs[2]==POSITIVE) {
p_min = {bbox.xmax(), bbox.ymax(),bbox.zmin()};
p_max = {bbox.xmin(), bbox.ymin(),bbox.zmax()};
}
else {
p_min = {bbox.xmax(), bbox.ymax(),bbox.zmax()};
p_max = {bbox.xmin(), bbox.ymin(),bbox.zmin()};
}
}
}
return ! (orientation(t, pts, p_max[0], p_max[1], p_max[2]) == ON_NEGATIVE_SIDE ||
orientation(t, pts, p_min[0], p_min[1], p_min[2]) == ON_POSITIVE_SIDE);
}
CGAL::Orientation side = orientation(t, pts, bbox.xmin(), bbox.ymin(),bbox.zmin());
if(side == COPLANAR) return true;
CGAL::Oriented_side s = orientation(t, pts, bbox.xmax(), bbox.ymax(),bbox.zmax());
if(s != side) return true;
s = orientation(t, pts, bbox.xmin(), bbox.ymin(),bbox.zmax());
if(s != side) return true;
s = orientation(t, pts, bbox.xmax(), bbox.ymax(),bbox.zmin());
if(s != side) return true;
s = orientation(t, pts, bbox.xmin(), bbox.ymax(),bbox.zmin());
if(s != side) return true;
s = orientation(t, pts, bbox.xmax(), bbox.ymin(),bbox.zmax());
if(s != side) return true;
s = orientation(t, pts, bbox.xmin(), bbox.ymax(),bbox.zmax());
if(s != side) return true;
s = orientation(t, pts, bbox.xmax(), bbox.ymin(),bbox.zmin());
if(s != side) return true;
return false;
};
result_type
operator()(const Triangle_3 &t, const Bbox_3& b) const
{
CGAL_BRANCH_PROFILER_3(std::string("semi-static failures/attempts/calls to : ") +
std::string(CGAL_PRETTY_FUNCTION), tmp);
// check if at least one triangle point is inside the bbox
Get_approx<Point_3> get_approx;
std::array< std::array<double, 3>, 3> pts;
for (int i=0; i<3; ++i)
{
const Point_3& p = t[i];
if (fit_in_double(get_approx(p).x(), pts[i][0]) && fit_in_double(get_approx(p).y(), pts[i][1]) &&
fit_in_double(get_approx(p).z(), pts[i][2]) )
{
CGAL_BRANCH_PROFILER_BRANCH_1(tmp);
if( (pts[i][0] >= b.xmin() && pts[i][0] <= b.xmax()) &&
(pts[i][1] >= b.ymin() && pts[i][1] <= b.ymax()) &&
(pts[i][2] >= b.zmin() && pts[i][2] <= b.zmax()) )
{
return true;
}
CGAL_BRANCH_PROFILER_BRANCH_2(tmp);
}
else
{
return Base::operator()(t,b);
}
}
// copy of the regular code with do_axis_intersect_aux_impl statically filtered
auto do_axis_intersect_aux_impl = [](double alpha, double beta, double c_alpha, double c_beta) -> Uncertain<Sign>
{
CGAL_BRANCH_PROFILER_3("certain / uncertain / calls to : axis_inter", tmp2);
Sign int_tmp_result;
double double_tmp_result;
double eps;
double_tmp_result = ((-c_alpha * alpha) + (c_beta * beta));
double max1 = CGAL::abs(c_alpha);
if( (max1 < CGAL::abs(c_beta)) )
{
max1 = CGAL::abs(c_beta);
}
double max2 = CGAL::abs(alpha);
if( (max2 < CGAL::abs(beta)) )
{
max2 = CGAL::abs(beta);
}
double lower_bound_1;
double upper_bound_1;
lower_bound_1 = max1;
upper_bound_1 = max1;
if( (max2 < lower_bound_1) )
{
lower_bound_1 = max2;
}
else
{
if( (max2 > upper_bound_1) )
{
upper_bound_1 = max2;
}
}
if( (lower_bound_1 < 5.00368081960964746551e-147) )
{
CGAL_BRANCH_PROFILER_BRANCH_1(tmp2);
return Uncertain<Sign>::indeterminate();
}
else
{
if( (upper_bound_1 > 1.67597599124282389316e+153) )
{
CGAL_BRANCH_PROFILER_BRANCH_1(tmp2);
return Uncertain<Sign>::indeterminate();
}
eps = (8.88720573725927976811e-16 * (max1 * max2));
if( (double_tmp_result > eps) )
{
int_tmp_result = POSITIVE;
}
else
{
if( (double_tmp_result < -eps) )
{
int_tmp_result = NEGATIVE;
}
else
{
CGAL_BRANCH_PROFILER_BRANCH_1(tmp2);
return Uncertain<Sign>::indeterminate();
}
}
}
CGAL_BRANCH_PROFILER_BRANCH_2(tmp2);
return int_tmp_result;
};
if ( !do_intersect_supporting_plane_bbox(t, pts, b) )
return false;
Uncertain<bool> res = Intersections::internal::do_intersect_bbox_or_iso_cuboid_impl<double>(pts, b, do_axis_intersect_aux_impl);
if ( !is_indeterminate(res) )
return make_certain(res);
return Base::operator()(t,b);
}
result_type result_type
operator()(const Bbox_3& b, const Sphere_3 &s) const operator()(const Bbox_3& b, const Sphere_3 &s) const
{ {

View File

@ -186,7 +186,7 @@ generate_point() {
this->d_item = creator( T( this->d_range), T(d)); this->d_item = creator( T( this->d_range), T(d));
break; break;
default: default:
CGAL_assume(false); CGAL_unreachable();
} }
} }

View File

@ -133,27 +133,29 @@ namespace boost {
public: public:
typedef KeyType key_type; typedef KeyType key_type;
typedef ValueType value_type; typedef ValueType value_type;
typedef const value_type& reference; typedef value_type& reference;
typedef lvalue_property_map_tag category; typedef lvalue_property_map_tag category;
associative_property_map() : m_c(0) { } associative_property_map() : m_c(0) { }
associative_property_map(C& c) : m_c(&c) { } associative_property_map(C& c) : m_c(&c) { }
value_type& operator[](const key_type& k) const {
reference operator[](const key_type& k) const {
return (*m_c)[k]; return (*m_c)[k];
} }
friend friend
const value_type& reference
get(const associative_property_map<C>& uhm, const key_type& key) get(const associative_property_map<C>& uhm, const key_type& key)
{ {
return uhm[key]; return uhm[key];
} }
friend friend
void void
put(associative_property_map<C>& uhm, const key_type& key, const value_type& val) put(associative_property_map<C>& uhm, const key_type& key, const value_type& val)
{ {
uhm[key] = val; uhm[key] = val;
} }
private: private:
C* m_c; C* m_c;

View File

@ -856,7 +856,7 @@ Aff_transformation_repH2<R>::homogeneous(int i, int j) const
case 0: return a; case 0: return a;
case 1: return b; case 1: return b;
case 2: return c; case 2: return c;
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 1: switch (j) case 1: switch (j)
@ -864,7 +864,7 @@ Aff_transformation_repH2<R>::homogeneous(int i, int j) const
case 0: return d; case 0: return d;
case 1: return e; case 1: return e;
case 2: return f; case 2: return f;
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 2: switch (j) case 2: switch (j)
@ -872,10 +872,10 @@ Aff_transformation_repH2<R>::homogeneous(int i, int j) const
case 0: return RT(0); case 0: return RT(0);
case 1: return RT(0); case 1: return RT(0);
case 2: return g; case 2: return g;
default: CGAL_assume(false); default: CGAL_unreachable();
} }
} }
CGAL_assume(false); CGAL_unreachable();
return RT(0); return RT(0);
} }
@ -900,7 +900,7 @@ Translation_repH2<R>::homogeneous(int i, int j) const
case 0: return _tv.hw(); case 0: return _tv.hw();
case 1: return RT(0); case 1: return RT(0);
case 2: return _tv.hx(); case 2: return _tv.hx();
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 1: switch (j) case 1: switch (j)
@ -908,7 +908,7 @@ Translation_repH2<R>::homogeneous(int i, int j) const
case 0: return RT(0); case 0: return RT(0);
case 1: return _tv.hw(); case 1: return _tv.hw();
case 2: return _tv.hy(); case 2: return _tv.hy();
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 2: switch (j) case 2: switch (j)
@ -916,10 +916,10 @@ Translation_repH2<R>::homogeneous(int i, int j) const
case 0: return RT(0); case 0: return RT(0);
case 1: return RT(0); case 1: return RT(0);
case 2: return _tv.hw(); case 2: return _tv.hw();
default: CGAL_assume(false); default: CGAL_unreachable();
} }
} }
CGAL_assume(false); CGAL_unreachable();
return RT(0); return RT(0);
} }
@ -935,7 +935,7 @@ Translation_repH2<R>::cartesian(int i, int j) const
case 0: return FT(1); case 0: return FT(1);
case 1: return FT(0); case 1: return FT(0);
case 2: return _tv.x(); case 2: return _tv.x();
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 1: switch (j) case 1: switch (j)
@ -943,7 +943,7 @@ Translation_repH2<R>::cartesian(int i, int j) const
case 0: return FT(0); case 0: return FT(0);
case 1: return FT(1); case 1: return FT(1);
case 2: return _tv.y(); case 2: return _tv.y();
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 2: switch (j) case 2: switch (j)
@ -951,10 +951,10 @@ Translation_repH2<R>::cartesian(int i, int j) const
case 0: return FT(0); case 0: return FT(0);
case 1: return FT(0); case 1: return FT(0);
case 2: return FT(1); case 2: return FT(1);
default: CGAL_assume(false); default: CGAL_unreachable();
} }
} }
CGAL_assume(false); CGAL_unreachable();
return FT(0); return FT(0);
} }
@ -971,7 +971,7 @@ homogeneous(int i, int j) const
case 0: return _cos; case 0: return _cos;
case 1: return - _sin; case 1: return - _sin;
case 2: return RT(0); case 2: return RT(0);
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 1: switch (j) case 1: switch (j)
@ -979,7 +979,7 @@ homogeneous(int i, int j) const
case 0: return _sin; case 0: return _sin;
case 1: return _cos; case 1: return _cos;
case 2: return RT(0); case 2: return RT(0);
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 2: switch (j) case 2: switch (j)
@ -987,10 +987,10 @@ homogeneous(int i, int j) const
case 0: return RT(0); case 0: return RT(0);
case 1: return RT(0); case 1: return RT(0);
case 2: return _den; case 2: return _den;
default: CGAL_assume(false); default: CGAL_unreachable();
} }
} }
CGAL_assume(false); CGAL_unreachable();
return RT(0); return RT(0);
} }
@ -1007,7 +1007,7 @@ cartesian(int i, int j) const
case 0: return FT(_cos) / FT(_den); case 0: return FT(_cos) / FT(_den);
case 1: return - FT(_sin) / FT(_den); case 1: return - FT(_sin) / FT(_den);
case 2: return FT(0); case 2: return FT(0);
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 1: switch (j) case 1: switch (j)
@ -1015,7 +1015,7 @@ cartesian(int i, int j) const
case 0: return FT(_sin) / FT(_den); case 0: return FT(_sin) / FT(_den);
case 1: return FT(_cos) / FT(_den); case 1: return FT(_cos) / FT(_den);
case 2: return FT(0); case 2: return FT(0);
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 2: switch (j) case 2: switch (j)
@ -1023,10 +1023,10 @@ cartesian(int i, int j) const
case 0: return FT(0); case 0: return FT(0);
case 1: return FT(0); case 1: return FT(0);
case 2: return FT(1); case 2: return FT(1);
default: CGAL_assume(false); default: CGAL_unreachable();
} }
} }
CGAL_assume(false); CGAL_unreachable();
return FT(0); return FT(0);
} }
@ -1043,7 +1043,7 @@ homogeneous(int i, int j) const
case 0: return _sf_num; case 0: return _sf_num;
case 1: return RT(0); case 1: return RT(0);
case 2: return RT(0); case 2: return RT(0);
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 1: switch (j) case 1: switch (j)
@ -1051,7 +1051,7 @@ homogeneous(int i, int j) const
case 0: return RT(0); case 0: return RT(0);
case 1: return _sf_num; case 1: return _sf_num;
case 2: return RT(0); case 2: return RT(0);
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 2: switch (j) case 2: switch (j)
@ -1059,10 +1059,10 @@ homogeneous(int i, int j) const
case 0: return RT(0); case 0: return RT(0);
case 1: return RT(0); case 1: return RT(0);
case 2: return _sf_den; case 2: return _sf_den;
default: CGAL_assume(false); default: CGAL_unreachable();
} }
} }
CGAL_assume(false); CGAL_unreachable();
return RT(0); return RT(0);
} }
@ -1079,7 +1079,7 @@ cartesian(int i, int j) const
case 0: return FT(_sf_num) / FT(_sf_den); case 0: return FT(_sf_num) / FT(_sf_den);
case 1: return FT(0); case 1: return FT(0);
case 2: return FT(0); case 2: return FT(0);
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 1: switch (j) case 1: switch (j)
@ -1087,7 +1087,7 @@ cartesian(int i, int j) const
case 0: return FT(0); case 0: return FT(0);
case 1: return FT(_sf_num) / FT(_sf_den); case 1: return FT(_sf_num) / FT(_sf_den);
case 2: return FT(0); case 2: return FT(0);
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 2: switch (j) case 2: switch (j)
@ -1095,10 +1095,10 @@ cartesian(int i, int j) const
case 0: return FT(0); case 0: return FT(0);
case 1: return FT(0); case 1: return FT(0);
case 2: return FT(1); case 2: return FT(1);
default: CGAL_assume(false); default: CGAL_unreachable();
} }
} }
CGAL_assume(false); CGAL_unreachable();
return FT(0); return FT(0);
} }
@ -1116,7 +1116,7 @@ homogeneous(int i, int j) const
case 0: return l.b()*l.b() - l.a()*l.a(); case 0: return l.b()*l.b() - l.a()*l.a();
case 1: return l.a()*l.b()*mRT2; case 1: return l.a()*l.b()*mRT2;
case 2: return l.a()*l.c()*mRT2; case 2: return l.a()*l.c()*mRT2;
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 1: switch (j) case 1: switch (j)
@ -1124,7 +1124,7 @@ homogeneous(int i, int j) const
case 0: return l.a()*l.b()*mRT2; case 0: return l.a()*l.b()*mRT2;
case 1: return l.a()*l.a() - l.b()*l.b(); case 1: return l.a()*l.a() - l.b()*l.b();
case 2: return l.b()*l.c()*mRT2; case 2: return l.b()*l.c()*mRT2;
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 2: switch (j) case 2: switch (j)
@ -1132,10 +1132,10 @@ homogeneous(int i, int j) const
case 0: return RT(0); case 0: return RT(0);
case 1: return RT(0); case 1: return RT(0);
case 2: return l.a()*l.a() + l.b()*l.b(); case 2: return l.a()*l.a() + l.b()*l.b();
default: CGAL_assume(false); default: CGAL_unreachable();
} }
} }
CGAL_assume(false); CGAL_unreachable();
return RT(0); return RT(0);
} }
@ -1153,7 +1153,7 @@ cartesian(int i, int j) const
case 0: return FT( l.b()-l.a() ) / FT( l.a()+l.b()); case 0: return FT( l.b()-l.a() ) / FT( l.a()+l.b());
case 1: return FT( homogeneous(0,1)) / de; case 1: return FT( homogeneous(0,1)) / de;
case 2: return FT( homogeneous(0,2)) / de; case 2: return FT( homogeneous(0,2)) / de;
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 1: switch (j) case 1: switch (j)
@ -1161,7 +1161,7 @@ cartesian(int i, int j) const
case 0: return FT( homogeneous(1,0)) / de; case 0: return FT( homogeneous(1,0)) / de;
case 1: return FT( l.a()-l.b() ) / FT( l.a()+l.b()); case 1: return FT( l.a()-l.b() ) / FT( l.a()+l.b());
case 2: return FT( homogeneous(1,2)) / de; case 2: return FT( homogeneous(1,2)) / de;
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 2: switch (j) case 2: switch (j)
@ -1169,10 +1169,10 @@ cartesian(int i, int j) const
case 0: return FT(0); case 0: return FT(0);
case 1: return FT(0); case 1: return FT(0);
case 2: return FT(1); case 2: return FT(1);
default: CGAL_assume(false); default: CGAL_unreachable();
} }
} }
CGAL_assume(false); CGAL_unreachable();
return FT(0); return FT(0);
} }

View File

@ -706,7 +706,7 @@ homogeneous(int i, int j) const
case 1: return t01; case 1: return t01;
case 2: return t02; case 2: return t02;
case 3: return t03; case 3: return t03;
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 1: switch (j) case 1: switch (j)
@ -715,7 +715,7 @@ homogeneous(int i, int j) const
case 1: return t11; case 1: return t11;
case 2: return t12; case 2: return t12;
case 3: return t13; case 3: return t13;
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 2: switch (j) case 2: switch (j)
@ -724,7 +724,7 @@ homogeneous(int i, int j) const
case 1: return t21; case 1: return t21;
case 2: return t22; case 2: return t22;
case 3: return t23; case 3: return t23;
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 3: switch (j) case 3: switch (j)
@ -733,10 +733,10 @@ homogeneous(int i, int j) const
case 1: return RT0; case 1: return RT0;
case 2: return RT0; case 2: return RT0;
case 3: return t33; case 3: return t33;
default: CGAL_assume(false); default: CGAL_unreachable();
} }
} }
CGAL_assume(false); CGAL_unreachable();
return RT0; return RT0;
} }
@ -864,7 +864,7 @@ Translation_repH3<R>::homogeneous(int i, int j) const
case 1: return RT0; case 1: return RT0;
case 2: return RT0; case 2: return RT0;
case 3: return tv.hx(); case 3: return tv.hx();
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 1: switch (j) case 1: switch (j)
@ -873,7 +873,7 @@ Translation_repH3<R>::homogeneous(int i, int j) const
case 1: return tv.hw(); case 1: return tv.hw();
case 2: return RT0; case 2: return RT0;
case 3: return tv.hy(); case 3: return tv.hy();
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 2: switch (j) case 2: switch (j)
@ -882,7 +882,7 @@ Translation_repH3<R>::homogeneous(int i, int j) const
case 1: return RT0; case 1: return RT0;
case 2: return tv.hw(); case 2: return tv.hw();
case 3: return tv.hz(); case 3: return tv.hz();
default: CGAL_assume(false); default: CGAL_unreachable();
} }
break; break;
case 3: switch (j) case 3: switch (j)
@ -891,10 +891,10 @@ Translation_repH3<R>::homogeneous(int i, int j) const
case 1: return RT0; case 1: return RT0;
case 2: return RT0; case 2: return RT0;
case 3: return tv.hw(); case 3: return tv.hw();
default: CGAL_assume(false); default: CGAL_unreachable();
} }
} }
CGAL_assume(false); CGAL_unreachable();
return RT0; return RT0;
} }

View File

@ -4683,6 +4683,7 @@ namespace HomogeneousKernelFunctors {
typedef typename K::Circle_2 Circle_2; typedef typename K::Circle_2 Circle_2;
typedef typename K::Line_2 Line_2; typedef typename K::Line_2 Line_2;
typedef typename K::Triangle_2 Triangle_2; typedef typename K::Triangle_2 Triangle_2;
typedef typename K::Segment_2 Segment_2;
public: public:
typedef typename K::Oriented_side result_type; typedef typename K::Oriented_side result_type;
@ -4722,6 +4723,41 @@ namespace HomogeneousKernelFunctors {
? ON_ORIENTED_BOUNDARY ? ON_ORIENTED_BOUNDARY
: -ot; : -ot;
} }
result_type
operator()(const Segment_2& s, const Triangle_2& t) const
{
typename K::Construct_source_2 source;
typename K::Construct_target_2 target;
typename K::Construct_vertex_2 vertex;
typename K::Construct_circumcenter_2 circumcenter;
typename K::Orientation_2 orientation;
const Point_2& a = source(s);
const Point_2& b = target(s);
CGAL_assertion(a != b);
const Point_2& p0 = vertex(t, 0);
const Point_2& p1 = vertex(t, 1);
const Point_2& p2 = vertex(t, 2);
CGAL_assertion(p0 != p1 && p1 != p2 && p2 != p0);
const Point_2 cc = circumcenter(t);
CGAL::Orientation o_abc = orientation(a, b, cc);
if (o_abc == CGAL::COLLINEAR)
return CGAL::ON_ORIENTED_BOUNDARY;
CGAL::Orientation o_abt = orientation(a, b, p0);
if (o_abt == CGAL::COLLINEAR)
o_abt = orientation(a, b, p1);
if (o_abt == CGAL::COLLINEAR)
o_abt = orientation(a, b, p2);
CGAL_assertion(o_abt != CGAL::COLLINEAR);
if (o_abc == o_abt) return CGAL::ON_POSITIVE_SIDE;
else return CGAL::ON_NEGATIVE_SIDE;
}
}; };

View File

@ -4,6 +4,15 @@ Release History
----------- -----------
Release date: December 2021 Release date: December 2021
### General changes
- Added the cmake target `CGAL::CGAL_Basic_viewer` to ease the compilation of programs using
the basic viewer based function `CGAL::draw`. This target will define the macro and link with
`CGAL_Qt5` target when linked with it.
### [General changes](https://doc.cgal.org/5.4/Manual/general_intro.html)
- The kernel providing exact constructions and exact predicates (`Exact_predicates_exact_constructions_kernel`)
has been made thread-safe. See changes in 2D and 3D Linear Geometry Kernel
for more details.
### [Weights](https://doc.cgal.org/5.4/Manual/packages.html#PkgWeights) (new package) ### [Weights](https://doc.cgal.org/5.4/Manual/packages.html#PkgWeights) (new package)
@ -41,6 +50,14 @@ Release date: December 2021
- Added documentation for the class `Projection_traits_3`, which enables the use of 2D algorithms on the projections of 3D data onto an arbitrary plane. - Added documentation for the class `Projection_traits_3`, which enables the use of 2D algorithms on the projections of 3D data onto an arbitrary plane.
- Most operations on `Exact_predicates_exact_constructions_kernel` objects are now thread-safe
if `CGAL::Exact_rational` is `mpq_class` (from `GMPXX`), `boost::multiprecision::mpq_rational` or
`CGAL::Quotient<CGAL::MP_Float>`. The objects are not atomic though, so the usual restrictions
on avoiding race conditions apply. For users who do not use threads, this can be disabled with `CGAL_HAS_NO_THREADS`.
### [dD Kernel](https://doc.cgal.org/5.4/Manual/packages.html#PkgKernelD)
- Most operations on `Epeck_d` objects are now thread-safe, see 2D and 3D Linear Geometry Kernel for details.
### [Polygon Mesh Processing](https://doc.cgal.org/5.4/Manual/packages.html#PkgPolygonMeshProcessing) ### [Polygon Mesh Processing](https://doc.cgal.org/5.4/Manual/packages.html#PkgPolygonMeshProcessing)
- Added the function `CGAL::Polygon_mesh_processing::match_faces()`, which, given two polygon meshes, - Added the function `CGAL::Polygon_mesh_processing::match_faces()`, which, given two polygon meshes,
@ -89,7 +106,6 @@ Release date: December 2021
- A new geometry traits , namely, `Arr_geodesic_arc_on_sphere_traits_2`, is introduced. It handles arcs of great circles embedded on the unit sphere. - A new geometry traits , namely, `Arr_geodesic_arc_on_sphere_traits_2`, is introduced. It handles arcs of great circles embedded on the unit sphere.
### [Point Set Processing](https://doc.cgal.org/5.4/Manual/packages.html#PkgPointSetProcessing3) ### [Point Set Processing](https://doc.cgal.org/5.4/Manual/packages.html#PkgPointSetProcessing3)
- Added support for `libpointmatcher::GenericDescriptorOutlierFilter` - Added support for `libpointmatcher::GenericDescriptorOutlierFilter`
@ -126,6 +142,11 @@ Release date: December 2021
and [`oriented_side`](https://doc.cgal.org/5.4/Boolean_set_operations_2/group__boolean__oriented__side.html)) and [`oriented_side`](https://doc.cgal.org/5.4/Boolean_set_operations_2/group__boolean__oriented__side.html))
to control whether to use `Arr_polyline_traits_2` as default traits. It is the new default as it provides better performances in general. to control whether to use `Arr_polyline_traits_2` as default traits. It is the new default as it provides better performances in general.
### [3D Mesh Generation](https://doc.cgal.org/latest/Manual/packages.html#PkgMesh3)
- Added support of weighted images for an improved quality of meshes generated from labeled images,
along with a function `CGAL::Mesh_3::generate_label_weights()` to generate the weights.
[Release 5.3](https://github.com/CGAL/cgal/releases/tag/v5.3) [Release 5.3](https://github.com/CGAL/cgal/releases/tag/v5.3)
----------- -----------

View File

@ -200,11 +200,21 @@ endif()
set(CGAL_DATA_DIR "@CGAL_DATA_DIR@") set(CGAL_DATA_DIR "@CGAL_DATA_DIR@")
if(NOT TARGET CGAL::Data) if(NOT TARGET CGAL::Data)
add_library(CGAL::Data INTERFACE IMPORTED) add_library(CGAL::Data INTERFACE IMPORTED GLOBAL)
if ( NOT "${CGAL_DATA_DIR}" STREQUAL "" ) if ( NOT "${CGAL_DATA_DIR}" STREQUAL "" )
set_target_properties(CGAL::Data PROPERTIES set_target_properties(CGAL::Data PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "CGAL_DATA_DIR=\"${CGAL_DATA_DIR}\"") INTERFACE_COMPILE_DEFINITIONS "CGAL_DATA_DIR=\"${CGAL_DATA_DIR}\"")
endif() endif()
endif() endif()
#
# Define a specific target for basic viewer
#
if (NOT TARGET CGAL::CGAL_Basic_viewer)
add_library(CGAL::CGAL_Basic_viewer INTERFACE IMPORTED GLOBAL)
set_target_properties(CGAL::CGAL_Basic_viewer PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "CGAL_USE_BASIC_VIEWER;QT_NO_KEYWORDS"
INTERFACE_LINK_LIBRARIES CGAL::CGAL_Qt5)
endif()
include("${CGAL_MODULES_DIR}/CGAL_enable_end_of_configuration_hook.cmake") include("${CGAL_MODULES_DIR}/CGAL_enable_end_of_configuration_hook.cmake")

View File

@ -184,11 +184,21 @@ endif()
set(CGAL_DATA_DIR "@CGAL_DATA_DIR@") set(CGAL_DATA_DIR "@CGAL_DATA_DIR@")
if(NOT TARGET CGAL::Data) if(NOT TARGET CGAL::Data)
add_library(CGAL::Data INTERFACE IMPORTED) add_library(CGAL::Data INTERFACE IMPORTED GLOBAL)
if ( NOT "${CGAL_DATA_DIR}" STREQUAL "" ) if ( NOT "${CGAL_DATA_DIR}" STREQUAL "" )
set_target_properties(CGAL::Data PROPERTIES set_target_properties(CGAL::Data PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "CGAL_DATA_DIR=\"${CGAL_DATA_DIR}\"") INTERFACE_COMPILE_DEFINITIONS "CGAL_DATA_DIR=\"${CGAL_DATA_DIR}\"")
endif() endif()
endif() endif()
#
# Define a specific target for basic viewer
#
if (NOT TARGET CGAL::CGAL_Basic_viewer)
add_library(CGAL::CGAL_Basic_viewer INTERFACE IMPORTED GLOBAL)
set_target_properties(CGAL::CGAL_Basic_viewer PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "CGAL_USE_BASIC_VIEWER;QT_NO_KEYWORDS"
INTERFACE_LINK_LIBRARIES CGAL::CGAL_Qt5)
endif()
include("${CGAL_MODULES_DIR}/CGAL_enable_end_of_configuration_hook.cmake") include("${CGAL_MODULES_DIR}/CGAL_enable_end_of_configuration_hook.cmake")

View File

@ -0,0 +1,7 @@
if(ITK_FOUND AND NOT TARGET CGAL::ITK_support)
add_library(CGAL::ITK_support INTERFACE IMPORTED)
set_target_properties(CGAL::ITK_support PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "CGAL_USE_ITK"
INTERFACE_INCLUDE_DIRECTORIES "${ITK_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${ITK_LIBRARIES}")
endif()

View File

@ -41,7 +41,7 @@ set(list_of_whitelisted_headers_txt [=[
CGAL/IO/Triangulation_geomview_ostream_3.h CGAL/IO/Triangulation_geomview_ostream_3.h
CGAL/IO/Triangulation_geomview_ostream_2.h CGAL/IO/Triangulation_geomview_ostream_2.h
CGAL/IO/Polyhedron_geomview_ostream.h CGAL/IO/Polyhedron_geomview_ostream.h
CGAL/Mesh_3/generate_label_weights.h
]=]) ]=])
separate_arguments(list_of_whitelisted_headers UNIX_COMMAND ${list_of_whitelisted_headers_txt}) separate_arguments(list_of_whitelisted_headers UNIX_COMMAND ${list_of_whitelisted_headers_txt})

View File

@ -369,15 +369,17 @@ using std::max;
# define CGAL_NO_UNIQUE_ADDRESS # define CGAL_NO_UNIQUE_ADDRESS
#endif #endif
// Macro CGAL_ASSUME // Macro CGAL_ASSUME and CGAL_UNREACHABLE
// Call a builtin of the compiler to pass a hint to the compiler // Call a builtin of the compiler to pass a hint to the compiler
#if __has_builtin(__builtin_unreachable) || (CGAL_GCC_VERSION > 0 && !__STRICT_ANSI__) #if __has_builtin(__builtin_unreachable) || (CGAL_GCC_VERSION > 0 && !__STRICT_ANSI__)
// From g++ 4.5, there exists a __builtin_unreachable() // From g++ 4.5, there exists a __builtin_unreachable()
// Also in LLVM/clang // Also in LLVM/clang
# define CGAL_ASSUME(EX) if(!(EX)) { __builtin_unreachable(); } # define CGAL_ASSUME(EX) if(!(EX)) { __builtin_unreachable(); }
# define CGAL_UNREACHABLE() __builtin_unreachable()
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
// MSVC has __assume // MSVC has __assume
# define CGAL_ASSUME(EX) __assume(EX) # define CGAL_ASSUME(EX) __assume(EX)
# define CGAL_UNREACHABLE() __assume(0)
#endif #endif
// If CGAL_ASSUME is not defined, then CGAL_assume and CGAL_assume_code are // If CGAL_ASSUME is not defined, then CGAL_assume and CGAL_assume_code are
// defined differently, in <CGAL/assertions.h> // defined differently, in <CGAL/assertions.h>

View File

@ -1,54 +0,0 @@
// Copyright (c) 2016 GeometryFactory SARL (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Andreas Fabri
//
// Warning: this file is generated, see include/CGAL/licence/README.md
#ifndef CGAL_LICENSE_WEIGHTS_H
#define CGAL_LICENSE_WEIGHTS_H
#include <CGAL/config.h>
#include <CGAL/license.h>
#ifdef CGAL_WEIGHTS_COMMERCIAL_LICENSE
# if CGAL_WEIGHTS_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
# if defined(CGAL_LICENSE_WARNING)
CGAL_pragma_warning("Your commercial license for CGAL does not cover "
"this release of the Weights package.")
# endif
# ifdef CGAL_LICENSE_ERROR
# error "Your commercial license for CGAL does not cover this release \
of the Weights package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
# endif // CGAL_WEIGHTS_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
#else // no CGAL_WEIGHTS_COMMERCIAL_LICENSE
# if defined(CGAL_LICENSE_WARNING)
CGAL_pragma_warning("\nThe macro CGAL_WEIGHTS_COMMERCIAL_LICENSE is not defined."
"\nYou use the CGAL Weights package under "
"the terms of the GPLv3+.")
# endif // CGAL_LICENSE_WARNING
# ifdef CGAL_LICENSE_ERROR
# error "The macro CGAL_WEIGHTS_COMMERCIAL_LICENSE is not defined.\
You use the CGAL Weights package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
#endif // no CGAL_WEIGHTS_COMMERCIAL_LICENSE
#endif // CGAL_LICENSE_WEIGHTS_H

View File

@ -97,4 +97,3 @@ Triangulation dD Triangulations
Visibility_2 2D Visibility Computation Visibility_2 2D Visibility Computation
Voronoi_diagram_2 2D Voronoi Diagram Adaptor Voronoi_diagram_2 2D Voronoi Diagram Adaptor
Tetrahedral_remeshing Tetrahedral Remeshing Tetrahedral_remeshing Tetrahedral Remeshing
Weights Weights

View File

@ -77,11 +77,11 @@ if (NOT CGAL_DATA_DIR)
if(DEFINED ENV{CGAL_DATA_DIR}) if(DEFINED ENV{CGAL_DATA_DIR})
set(CGAL_DATA_DIR $ENV{CGAL_DATA_DIR}) set(CGAL_DATA_DIR $ENV{CGAL_DATA_DIR})
else() else()
if (EXISTS "${CGAL_ROOT}/data") if (EXISTS "${CGAL_ROOT}/Data/data")
set(CGAL_DATA_DIR "${CGAL_ROOT}/data") set(CGAL_DATA_DIR "${CGAL_ROOT}/Data/data")
else() else()
if (EXISTS "${CGAL_ROOT}/Data/data") if (EXISTS "${CGAL_ROOT}/data")
set(CGAL_DATA_DIR "${CGAL_ROOT}/Data/data") set(CGAL_DATA_DIR "${CGAL_ROOT}/data")
else() else()
message("CGAL_ROOT = ${CGAL_ROOT}") message("CGAL_ROOT = ${CGAL_ROOT}")
message(WARNING "CGAL_DATA_DIR cannot be deduced, set the variable CGAL_DATA_DIR to set the default value of CGAL::data_file_path()") message(WARNING "CGAL_DATA_DIR cannot be deduced, set the variable CGAL_DATA_DIR to set the default value of CGAL::data_file_path()")
@ -91,7 +91,7 @@ if (NOT CGAL_DATA_DIR)
endif() endif()
if(NOT TARGET CGAL::Data) if(NOT TARGET CGAL::Data)
add_library(CGAL::Data INTERFACE IMPORTED) add_library(CGAL::Data INTERFACE IMPORTED GLOBAL)
if ( NOT "${CGAL_DATA_DIR}" STREQUAL "" ) if ( NOT "${CGAL_DATA_DIR}" STREQUAL "" )
set_target_properties(CGAL::Data PROPERTIES set_target_properties(CGAL::Data PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "CGAL_DATA_DIR=\"${CGAL_DATA_DIR}\"") INTERFACE_COMPILE_DEFINITIONS "CGAL_DATA_DIR=\"${CGAL_DATA_DIR}\"")
@ -164,6 +164,16 @@ foreach(cgal_lib ${CGAL_LIBRARIES})
endif() endif()
endforeach() endforeach()
#
# Define a specific target for basic viewer
#
if (NOT TARGET CGAL::CGAL_Basic_viewer)
add_library(CGAL::CGAL_Basic_viewer INTERFACE IMPORTED GLOBAL)
set_target_properties(CGAL::CGAL_Basic_viewer PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "CGAL_USE_BASIC_VIEWER;QT_NO_KEYWORDS"
INTERFACE_LINK_LIBRARIES CGAL::CGAL_Qt5)
endif()
include(${CGAL_CONFIG_DIR}/CGALConfigVersion.cmake) include(${CGAL_CONFIG_DIR}/CGALConfigVersion.cmake)
# #

View File

@ -50,7 +50,7 @@ endif()
find_package(TBB QUIET) find_package(TBB QUIET)
include(CGAL_TBB_support) include(CGAL_TBB_support)
create_single_source_cgal_program("test_TBB.cpp") create_single_source_cgal_program("test_TBB.cpp")
if(TARGET CGAl::TBB_support) if(TARGET CGAL::TBB_support)
target_link_libraries(test_TBB PUBLIC CGAL::TBB_support) target_link_libraries(test_TBB PUBLIC CGAL::TBB_support)
endif() endif()

View File

@ -50,8 +50,13 @@ struct Value_function
template <typename V, typename G> template <typename V, typename G>
struct Gradient_function struct Gradient_function
: public std::iterator<std::output_iterator_tag, void, void, void, void>
{ {
typedef void value_type;
typedef void Distance;
typedef void Pointer;
typedef void Reference;
typedef std::output_iterator_tag category;
typedef V argument_type; typedef V argument_type;
typedef std::pair<G, bool> result_type; typedef std::pair<G, bool> result_type;

View File

@ -125,7 +125,7 @@ Segment_2_Line_2_pair<K>::intersection_type() const
_result = SEGMENT; _result = SEGMENT;
break; break;
default: default:
CGAL_assume(false); CGAL_unreachable();
} }
return _result; return _result;
} }

View File

@ -34,48 +34,267 @@ namespace Intersections {
namespace internal { namespace internal {
// struct used to report the combinaric of the intersection
// of 2 2D segments.
// More information could be gathered if exposed in do_intersect.
// See comments with DI_MORE_INFO_TAG
struct S2S2_inter_info
{
bool inter = false;
bool dim = 0;
std::array<int, 2> pt_ids = {-1,-1};
S2S2_inter_info(bool inter)
: inter(inter)
{}
// intersection is an input endpoint
S2S2_inter_info(int id)
: inter(true)
{
pt_ids[0]=id;
}
// intersection is a segment
S2S2_inter_info(int id1,int id2)
: inter(true)
, dim(1)
{
pt_ids[0]=id1;
pt_ids[1]=id2;
}
};
template <class K> template <class K>
inline bool inline S2S2_inter_info
do_intersect(const typename K::Segment_2 &seg1, const typename K::Segment_2 &seg2); do_intersect(const typename K::Segment_2 &seg1, const typename K::Segment_2 &seg2);
// lexicographic order of points p1 < p3 < p2 < p4, with segments (p1,p2) and (p3,p4)
template <class K> template <class K>
bool seg_seg_do_intersect_crossing( S2S2_inter_info
const typename K::Point_2 &p1, const typename K::Point_2 &p2, seg_seg_do_intersect_crossing(
const typename K::Point_2 &p3, const typename K::Point_2 &p4, const typename K::Point_2& p1, const typename K::Point_2& p2,
const K& k) const typename K::Point_2& p3, const typename K::Point_2& p4,
int /* i1 */, int i2, int i3, int /* i4 */,
const K& k, bool extra_test)
{ {
switch (make_certain(k.orientation_2_object()(p1,p2,p3))) { switch (make_certain(k.orientation_2_object()(p1,p2,p3))) {
case LEFT_TURN: case LEFT_TURN:
return ! (k.orientation_2_object()(p3,p4,p2) == RIGHT_TURN); // right_turn(p3,p4,p2); {
switch (k.orientation_2_object()(p3,p4,p2))
{
case COLLINEAR:
return S2S2_inter_info(i2);
case RIGHT_TURN:
return S2S2_inter_info(false);
case LEFT_TURN:
return S2S2_inter_info(true);
default:
CGAL_unreachable();
}
}
case RIGHT_TURN: case RIGHT_TURN:
return ! (k.orientation_2_object()(p3,p4,p2) == LEFT_TURN); //left_turn(p3,p4,p2); {
switch (k.orientation_2_object()(p3,p4,p2))
{
case COLLINEAR:
return S2S2_inter_info(i2);
case RIGHT_TURN:
return S2S2_inter_info(true);
case LEFT_TURN:
return S2S2_inter_info(false);
default:
CGAL_unreachable();
}
}
case COLLINEAR: case COLLINEAR:
return true; if (extra_test && k.collinear_2_object()(p3,p4,p2))
return S2S2_inter_info(i3, i2);
return S2S2_inter_info(i3);
default:
CGAL_unreachable();
} }
CGAL_kernel_assertion(false); CGAL_kernel_assertion(false);
return false; return S2S2_inter_info(false);
}
// used internally by Arr_segment_traits_2template <class K>
template <class K>
bool
seg_seg_do_intersect_crossing(
const typename K::Point_2& p1, const typename K::Point_2& p2,
const typename K::Point_2& p3, const typename K::Point_2& p4,
const K& k)
{
return seg_seg_do_intersect_crossing(p1,p2,p3,p4,0,0,0,0,k,false).inter;
} }
// lexicographic order of points p1 < p3 < p4 < p2, with segments (p1,p2) and (p3,p4)
template <class K> template <class K>
bool seg_seg_do_intersect_contained( S2S2_inter_info
const typename K::Point_2 &p1, const typename K::Point_2 &p2, seg_seg_do_intersect_contained(
const typename K::Point_2 &p3, const typename K::Point_2 &p4, const typename K::Point_2& p1, const typename K::Point_2& p2,
const K& k) const typename K::Point_2& p3, const typename K::Point_2& p4,
int /* i1 */, int /* i2 */, int i3, int i4,
const K& k, bool extra_test)
{ {
switch (make_certain(k.orientation_2_object()(p1,p2,p3))) { switch (make_certain(k.orientation_2_object()(p1,p2,p3))) {
case LEFT_TURN: case LEFT_TURN:
return ! (k.orientation_2_object()(p1,p2,p4) == LEFT_TURN); // left_turn(p1,p2,p4); {
switch (k.orientation_2_object()(p1,p2,p4))
{
case COLLINEAR:
return S2S2_inter_info(i4);
case RIGHT_TURN:
return S2S2_inter_info(true);
case LEFT_TURN:
return S2S2_inter_info(false);
default:
CGAL_unreachable();
}
}
case RIGHT_TURN: case RIGHT_TURN:
return ! (k.orientation_2_object()(p1,p2,p4) == RIGHT_TURN); // right_turn(p1,p2,p4); {
switch (k.orientation_2_object()(p1,p2,p4))
{
case COLLINEAR:
return S2S2_inter_info(i4);
case RIGHT_TURN:
return S2S2_inter_info(false);
case LEFT_TURN:
return S2S2_inter_info(true);
default:
CGAL_unreachable();
}
}
case COLLINEAR: case COLLINEAR:
return true; if (extra_test && k.collinear_2_object()(p3,p4,p2))
return S2S2_inter_info(i3, i4);
return S2S2_inter_info(i3);
default:
CGAL_unreachable();
} }
CGAL_kernel_assertion(false); CGAL_kernel_assertion(false);
return false; return S2S2_inter_info(false);
}
// used internally by Arr_segment_traits_2
template <class K>
bool
seg_seg_do_intersect_contained(
const typename K::Point_2& p1, const typename K::Point_2& p2,
const typename K::Point_2& p3, const typename K::Point_2& p4,
const K& k)
{
return seg_seg_do_intersect_contained(p1,p2,p3,p4,0,0,0,0,k,false).inter;
}
template <class K>
S2S2_inter_info
do_intersect_with_info(const typename K::Segment_2 &seg1,
const typename K::Segment_2 &seg2,
const K& k, bool extra_test)
{
typename K::Less_xy_2 less_xy;
bool seg1_is_left_to_right = less_xy(seg1.source(),seg1.target());
bool seg2_is_left_to_right = less_xy(seg2.source(),seg2.target());
int A1_id = seg1_is_left_to_right ? 0 : 1;
int A2_id = seg1_is_left_to_right ? 1 : 0;
int B1_id = seg2_is_left_to_right ? 0 : 1;
int B2_id = seg2_is_left_to_right ? 1 : 0;
typename K::Point_2 const & A1 = seg1.point(A1_id);
typename K::Point_2 const & A2 = seg1.point(A2_id);
typename K::Point_2 const & B1 = seg2.point(B1_id);
typename K::Point_2 const & B2 = seg2.point(B2_id);
typename K::Compare_xy_2 compare_xy;
// first try to filter using the bbox of the segments
if (less_xy(A2,B1)
|| less_xy(B2,A1))
return S2S2_inter_info(false);
switch(make_certain(compare_xy(A1,B1))) {
case SMALLER:
switch(make_certain(compare_xy(A2,B1))) {
case SMALLER:
return S2S2_inter_info(false);
case EQUAL:
return S2S2_inter_info(A2_id); // DI_MORE_INFO_TAG: A2==B1 but only A2 is reported
case LARGER:
switch(make_certain(compare_xy(A2,B2))) {
case SMALLER:
return seg_seg_do_intersect_crossing(A1,A2,B1,B2, A1_id,A2_id,B1_id+2,B2_id+2, k, extra_test);
case EQUAL:
// A1 < B1 < B2 = A1
if (extra_test && k.collinear_2_object()(A1, A2, B1))
return S2S2_inter_info(B1_id+2, B2_id+2); // DI_MORE_INFO_TAG: A2==B2 but only B2 is reported
return S2S2_inter_info(A2_id); // DI_MORE_INFO_TAG: A2==B2 but only A2 is reported
case LARGER:
return seg_seg_do_intersect_contained(A1,A2,B1,B2, A1_id,A2_id,B1_id+2,B2_id+2, k, extra_test);
default:
CGAL_unreachable();
}
default:
CGAL_unreachable();
}
case EQUAL:
if (extra_test)
{
switch(make_certain(compare_xy(A2,B2))) {
case SMALLER:
// A1 = B1 < A2 < B2
if (k.collinear_2_object()(A1,A2,B2))
return S2S2_inter_info(A1_id, A2_id); // DI_MORE_INFO_TAG: A1==B1 but only A1 is reported
break;
case EQUAL:
// A1 = B1 < A2 = B2
return S2S2_inter_info(A1_id, A2_id); // DI_MORE_INFO_TAG: A1==B1 and A2==B2 but only A1 and A2 are reported
case LARGER:
// A1 = B1 < B2 < A2
if (k.collinear_2_object()(A1,A2,B2))
return S2S2_inter_info(B1_id+2, B2_id+2); // DI_MORE_INFO_TAG: A1==B1 but only B1 is reported
break;
default:
CGAL_unreachable();
}
}
return S2S2_inter_info(A1_id); // DI_MORE_INFO_TAG: A1==B1 but only A1 is reported
case LARGER:
switch(make_certain(compare_xy(B2,A1))) {
case SMALLER:
return S2S2_inter_info(false);
case EQUAL:
return S2S2_inter_info(A1_id); // DI_MORE_INFO_TAG: A1==B2 but only A1 is reported
case LARGER:
switch(make_certain(compare_xy(B2,A2))) {
case SMALLER:
return seg_seg_do_intersect_crossing(B1,B2,A1,A2, B1_id+2,B2_id+2,A1_id,A2_id, k, extra_test);
case EQUAL:
// B1 < A1 < A2 = B2
if (extra_test && k.collinear_2_object()(B1, A1, B2))
return S2S2_inter_info(A1_id, A2_id); // DI_MORE_INFO_TAG: A2==B2 but only A2 is reported
return S2S2_inter_info(A2_id); // DI_MORE_INFO_TAG: A2==B2 but only A2 is reported
case LARGER:
return seg_seg_do_intersect_contained(B1,B2,A1,A2, B1_id+2,B2_id+2,A1_id,A2_id, k, extra_test);
default:
CGAL_unreachable();
}
default:
CGAL_unreachable();
}
default:
CGAL_unreachable();
}
CGAL_kernel_assertion(false);
return S2S2_inter_info(false);
} }
@ -85,192 +304,9 @@ do_intersect(const typename K::Segment_2 &seg1,
const typename K::Segment_2 &seg2, const typename K::Segment_2 &seg2,
const K& k) const K& k)
{ {
typename K::Point_2 const & A1 = seg1.source(); return do_intersect_with_info(seg1, seg2, k, false).inter;
typename K::Point_2 const & A2 = seg1.target();
typename K::Point_2 const & B1 = seg2.source();
typename K::Point_2 const & B2 = seg2.target();
typename K::Less_xy_2 less_xy;
typename K::Compare_xy_2 compare_xy;
if (less_xy(A1,A2)) {
if (less_xy(B1,B2)) {
if (less_xy(A2,B1)
|| less_xy(B2,A1))
return false;
} else {
if (less_xy(A2,B2)
|| less_xy(B1,A1))
return false;
}
} else {
if (less_xy(B1,B2)) {
if (less_xy(A1,B1)
|| less_xy(B2,A2))
return false;
} else {
if (less_xy(A1,B2)
|| less_xy(B1,A2))
return false;
}
}
if (less_xy(A1,A2)) {
if (less_xy(B1,B2)) {
switch(make_certain(compare_xy(A1,B1))) {
case SMALLER:
switch(make_certain(compare_xy(A2,B1))) {
case SMALLER:
return false;
case EQUAL:
return true;
default: // LARGER
switch(make_certain(compare_xy(A2,B2))) {
case SMALLER:
return seg_seg_do_intersect_crossing(A1,A2,B1,B2, k);
case EQUAL:
return true;
default: // LARGER
return seg_seg_do_intersect_contained(A1,A2,B1,B2, k);
}
}
case EQUAL:
return true;
default: // LARGER
switch(make_certain(compare_xy(B2,A1))) {
case SMALLER:
return false;
case EQUAL:
return true;
default: // LARGER
switch(make_certain(compare_xy(B2,A2))) {
case SMALLER:
return seg_seg_do_intersect_crossing(B1,B2,A1,A2, k);
case EQUAL:
return true;
default: // LARGER
return seg_seg_do_intersect_contained(B1,B2,A1,A2, k);
}
}
}
} else {
switch(make_certain(compare_xy(A1,B2))) {
case SMALLER:
switch(make_certain(compare_xy(A2,B2))) {
case SMALLER:
return false;
case EQUAL:
return true;
default: // LARGER
switch(make_certain(compare_xy(A2,B1))) {
case SMALLER:
return seg_seg_do_intersect_crossing(A1,A2,B2,B1, k);
case EQUAL:
return true;
default: // LARGER
return seg_seg_do_intersect_contained(A1,A2,B2,B1, k);
}
}
case EQUAL:
return true;
default: // LARGER
switch(make_certain(compare_xy(B1,A1))) {
case SMALLER:
return false;
case EQUAL:
return true;
default: // LARGER
switch(make_certain(compare_xy(B1,A2))) {
case SMALLER:
return seg_seg_do_intersect_crossing(B2,B1,A1,A2, k);
case EQUAL:
return true;
default: // LARGER
return seg_seg_do_intersect_contained(B2,B1,A1,A2, k);
}
}
}
}
} else {
if (less_xy(B1,B2)) {
switch(make_certain(compare_xy(A2,B1))) {
case SMALLER:
switch(make_certain(compare_xy(A1,B1))) {
case SMALLER:
return false;
case EQUAL:
return true;
default: // LARGER
switch(make_certain(compare_xy(A1,B2))) {
case SMALLER:
return seg_seg_do_intersect_crossing(A2,A1,B1,B2, k);
case EQUAL:
return true;
default: // LARGER
return seg_seg_do_intersect_contained(A2,A1,B1,B2, k);
}
}
case EQUAL:
return true;
default: // LARGER
switch(make_certain(compare_xy(B2,A2))) {
case SMALLER:
return false;
case EQUAL:
return true;
default: // LARGER
switch(make_certain(compare_xy(B2,A1))) {
case SMALLER:
return seg_seg_do_intersect_crossing(B1,B2,A2,A1, k);
case EQUAL:
return true;
default: // LARGER
return seg_seg_do_intersect_contained(B1,B2,A2,A1, k);
}
}
}
} else {
switch(make_certain(compare_xy(A2,B2))) {
case SMALLER:
switch(make_certain(compare_xy(A1,B2))) {
case SMALLER:
return false;
case EQUAL:
return true;
default: // LARGER
switch(make_certain(compare_xy(A1,B1))) {
case SMALLER:
return seg_seg_do_intersect_crossing(A2,A1,B2,B1, k);
case EQUAL:
return true;
default: // LARGER
return seg_seg_do_intersect_contained(A2,A1,B2,B1, k);
}
}
case EQUAL:
return true;
default: // LARGER
switch(make_certain(compare_xy(B1,A2))) {
case SMALLER:
return false;
case EQUAL:
return true;
default: // LARGER
switch(make_certain(compare_xy(B1,A1))) {
case SMALLER:
return seg_seg_do_intersect_crossing(B2,B1,A2,A1, k);
case EQUAL:
return true;
default: // LARGER
return seg_seg_do_intersect_contained(B2,B1,A2,A1, k);
}
}
}
}
}
CGAL_kernel_assertion(false);
return false;
} }
template <class K> template <class K>
class Segment_2_Segment_2_pair { class Segment_2_Segment_2_pair {
public: public:
@ -294,110 +330,52 @@ template <class K>
typename Segment_2_Segment_2_pair<K>::Intersection_results typename Segment_2_Segment_2_pair<K>::Intersection_results
Segment_2_Segment_2_pair<K>::intersection_type() const Segment_2_Segment_2_pair<K>::intersection_type() const
{ {
typename K::Construct_vector_2 construct_vector;
if (_result!=UNKNOWN) if (_result!=UNKNOWN)
return _result; return _result;
if (!internal::do_intersect(*_seg1, *_seg2, K())) {
S2S2_inter_info inter_info = do_intersect_with_info(*_seg1, *_seg2, K(), true);
if (!inter_info.inter) {
_result = NO_INTERSECTION; _result = NO_INTERSECTION;
return _result; return _result;
} }
typename K::Line_2 const &l1 = _seg1->supporting_line();
typename K::Line_2 const &l2 = _seg2->supporting_line(); // check if intersection is a segment
Line_2_Line_2_pair<K> linepair(&l1, &l2); if (inter_info.dim==1)
switch ( linepair.intersection_type()) { {
case Line_2_Line_2_pair<K>::NO_INTERSECTION: _result=SEGMENT;
default: _intersection_point = (inter_info.pt_ids[0]>1)
_result = NO_INTERSECTION; ? _seg2->point(inter_info.pt_ids[0]-2)
break; : _seg1->point(inter_info.pt_ids[0]);
case Line_2_Line_2_pair<K>::POINT: _other_point = inter_info.pt_ids[1]>1
_intersection_point = linepair.intersection_point(); ? _seg2->point(inter_info.pt_ids[1]-2)
_result = POINT; : _seg1->point(inter_info.pt_ids[1]);
break; return _result;
case Line_2_Line_2_pair<K>::LINE:
{
//typedef typename K::RT RT;
typename K::Point_2 const &start1 = _seg1->source();
typename K::Point_2 const &end1 = _seg1->target();
typename K::Point_2 const &start2 = _seg2->source();
typename K::Point_2 const &end2 = _seg2->target();
typename K::Vector_2 diff1 = construct_vector(start1, end1);
typename K::Point_2 const *minpt;
typename K::Point_2 const *maxpt;
if (CGAL_NTS abs(diff1.x()) > CGAL_NTS abs(diff1.y())) {
if (start1.x() < end1.x()) {
minpt = &start1;
maxpt = &end1;
} else {
minpt = &end1;
maxpt = &start1;
}
if (start2.x() < end2.x()) {
if (start2.x() > minpt->x()) {
minpt = &start2;
}
if (end2.x() < maxpt->x()) {
maxpt = &end2;
}
} else {
if (end2.x() > minpt->x()) {
minpt = &end2;
}
if (start2.x() < maxpt->x()) {
maxpt = &start2;
}
}
if (maxpt->x() < minpt->x()) {
_result = NO_INTERSECTION;
return _result;
}
if (maxpt->x() == minpt->x()) {
_intersection_point = *minpt;
_result = POINT;
return _result;
}
_intersection_point = *minpt;
_other_point = *maxpt;
_result = SEGMENT;
return _result;
} else {
if (start1.y() < end1.y()) {
minpt = &start1;
maxpt = &end1;
} else {
minpt = &end1;
maxpt = &start1;
}
if (start2.y() < end2.y()) {
if (start2.y() > minpt->y()) {
minpt = &start2;
}
if (end2.y() < maxpt->y()) {
maxpt = &end2;
}
} else {
if (end2.y() > minpt->y()) {
minpt = &end2;
}
if (start2.y() < maxpt->y()) {
maxpt = &start2;
}
}
if (maxpt->y() < minpt->y()) {
_result = NO_INTERSECTION;
return _result;
}
if (maxpt->y() == minpt->y()) {
_intersection_point = *minpt;
_result = POINT;
return _result;
}
_intersection_point = *minpt;
_other_point = *maxpt;
_result = SEGMENT;
return _result;
}
}
} }
// starting from here we know that the intersection is a point
_result = POINT;
// check if intersection is an input endpoint
if (inter_info.pt_ids[0]>=0)
{
_intersection_point = (inter_info.pt_ids[0]>1)
? _seg2->point(inter_info.pt_ids[0]-2)
: _seg1->point(inter_info.pt_ids[0]);
return _result;
}
// segments intersect in their interiors
typename K::FT s1_dx = _seg1->point(0).x() - _seg1->point(1).x(),
s1_dy = _seg1->point(0).y() - _seg1->point(1).y(),
s2_dx = _seg2->point(1).x() - _seg2->point(0).x(),
s2_dy = _seg2->point(1).y() - _seg2->point(0).y(),
lx = _seg2->point(1).x() - _seg1->point(1).x(),
ly = _seg2->point(1).y() - _seg1->point(1).y();
typename K::FT alpha = (lx*s2_dy-ly*s2_dx)/(s1_dx*s2_dy-s1_dy*s2_dx);
_intersection_point = K().construct_barycenter_2_object()(_seg1->point(0), alpha, _seg1->point(1));
return _result; return _result;
} }

View File

@ -431,6 +431,56 @@ struct Test
check_intersection (S(p( 0, 0), p( 10, 0)), S(p( 1, 0), p( 8, 0)), S(P( 1, 0), P( 8, 0))); check_intersection (S(p( 0, 0), p( 10, 0)), S(p( 1, 0), p( 8, 0)), S(P( 1, 0), P( 8, 0)));
check_intersection (S(p(68, 106), p(192, 106)), S(p(150, 106), p(255, 106)), S(P(150, 106), P(192, 106))); check_intersection (S(p(68, 106), p(192, 106)), S(p(150, 106), p(255, 106)), S(P(150, 106), P(192, 106)));
check_intersection (S(p( 1, 10), p( 1, 2)), S(p( 1, 7), p( 1, 3)), S(P( 1, 3), P( 1, 7))); check_intersection (S(p( 1, 10), p( 1, 2)), S(p( 1, 7), p( 1, 3)), S(P( 1, 3), P( 1, 7)));
// exact point intersection
check_intersection (S(p( 3, 0), p( 3, 10)), S(p( 3, 3), p( 5, 10)), p( 3, 3));
check_intersection (S(p( 3, 0), p( 3, 10)), S(p( 5, 10), p( 3, 3)), p( 3, 3));
check_intersection (S(p( 3, 0), p( 3, 10)), S(p( 3, 3), p( -5, 10)), p( 3, 3));
check_intersection (S(p( 3, 0), p( 3, 10)), S(p( -5, 10), p( 3, 3)), p( 3, 3));
check_intersection (S(p( 0, 0), p( 44, 44)), S(p( 44, 44), p( 55, 55)), p( 44, 44));
check_intersection (S(p( 0, 0), p( 44, 44)), S(p( 55, 55), p( 44, 44)), p( 44, 44));
check_intersection (S(p( 44, 44), p( 0, 0)), S(p( 44, 44), p( 55, 55)), p( 44, 44));
check_intersection (S(p( 44, 44), p( 0, 0)), S(p( 55, 55), p( 44, 44)), p( 44, 44));
check_intersection (S(p( 0, 0), p( -44, -44)), S(p( -44, -44), p( -55, -55)), p( -44, -44));
check_intersection (S(p( 0, 0), p( -44, -44)), S(p( -55, -55), p( -44, -44)), p( -44, -44));
check_intersection (S(p( -44, -44), p( 0, 0)), S(p( -44, -44), p( -55, -55)), p( -44, -44));
check_intersection (S(p( -44, -44), p( 0, 0)), S(p( -55, -55), p( -44, -44)), p( -44, -44));
// more segment intersection (containment)
check_intersection (S(p(0,0), p(4,4)), S(p(1,1), p(2,2)), S(p(1,1), p(2,2)));
check_intersection (S(p(0,0), p(4,4)), S(p(2,2), p(1,1)), S(p(1,1), p(2,2)));
check_intersection (S(p(4,4), p(0,0)), S(p(1,1), p(2,2)), S(p(1,1), p(2,2)));
check_intersection (S(p(4,4), p(0,0)), S(p(2,2), p(1,1)), S(p(1,1), p(2,2)));
// more segment intersection (overlap)
check_intersection (S(p( 0,0), p( 2,2)), S(p(1,1), p(4,4)), S(p(1,1), p(2,2)));
check_intersection (S(p( 0,0), p( 2,2)), S(p(4,4), p(1,1)), S(p(1,1), p(2,2)));
check_intersection (S(p( 2,2), p( 0,0)), S(p(1,1), p(4,4)), S(p(1,1), p(2,2)));
check_intersection (S(p( 2,2), p( 0,0)), S(p(4,4), p(1,1)), S(p(1,1), p(2,2)));
check_intersection (S(p( 0,0), p( -2,-2)), S(p(-1,-1), p(-4,-4)), S(p(-2,-2),p(-1,-1)));
check_intersection (S(p( 0,0), p( -2,-2)), S(p(-4,-4), p(-1,-1)), S(p(-2,-2),p(-1,-1)));
check_intersection (S(p( -2,-2), p( 0,0)), S(p(-1,-1), p(-4,-4)), S(p(-2,-2),p(-1,-1)));
check_intersection (S(p( -2,-2), p( 0,0)), S(p(-4,-4), p(-1,-1)), S(p(-2,-2),p(-1,-1)));
// more segment intersection (one common point)
check_intersection (S(p( 0,0), p( 2,2)), S(p(1,1), p(2,2)), S(p(1,1), p(2,2)));
check_intersection (S(p( 0,0), p( 2,2)), S(p(2,2), p(1,1)), S(p(1,1), p(2,2)));
check_intersection (S(p( 2,2), p( 0,0)), S(p(1,1), p(2,2)), S(p(1,1), p(2,2)));
check_intersection (S(p( 2,2), p( 0,0)), S(p(2,2), p(1,1)), S(p(1,1), p(2,2)));
check_intersection (S(p( 0,0), p( -2,-2)), S(p(-1,-1), p(-2,-2)), S(p(-2,-2),p(-1,-1)));
check_intersection (S(p( 0,0), p( -2,-2)), S(p(-2,-2), p(-1,-1)), S(p(-2,-2),p(-1,-1)));
check_intersection (S(p( -2,-2), p( 0,0)), S(p(-1,-1), p(-2,-2)), S(p(-2,-2),p(-1,-1)));
check_intersection (S(p( -2,-2), p( 0,0)), S(p(-2,-2), p(-1,-1)), S(p(-2,-2),p(-1,-1)));
// more segment intersection (two identical points)
check_intersection (S(p( 1,1), p( 2,2)), S(p(1,1), p(2,2)), S(p(1,1), p(2,2)));
check_intersection (S(p( 1,1), p( 2,2)), S(p(2,2), p(1,1)), S(p(1,1), p(2,2)));
check_intersection (S(p( 2,2), p( 1,1)), S(p(1,1), p(2,2)), S(p(1,1), p(2,2)));
check_intersection (S(p( 2,2), p( 1,1)), S(p(2,2), p(1,1)), S(p(1,1), p(2,2)));
check_intersection (S(p( -1,-1), p( -2,-2)), S(p(-1,-1), p(-2,-2)), S(p(-2,-2),p(-1,-1)));
check_intersection (S(p( -1,-1), p( -2,-2)), S(p(-2,-2), p(-1,-1)), S(p(-2,-2),p(-1,-1)));
check_intersection (S(p( -2,-2), p( -1,-1)), S(p(-1,-1), p(-2,-2)), S(p(-2,-2),p(-1,-1)));
check_intersection (S(p( -2,-2), p( -1,-1)), S(p(-2,-2), p(-1,-1)), S(p(-2,-2),p(-1,-1)));
} }
void R_R() void R_R()

View File

@ -16,12 +16,15 @@
// Fast Triangle-Cuboid intersection test, following Tomas Akenine-Moeller description. // Fast Triangle-Cuboid intersection test, following Tomas Akenine-Moeller description.
// The code looks slightly different from his code because we avoid the translation at // The code looks slightly different from his code because we avoid the translation at
// a minimal cost (and we use C++;). // a minimal cost (and we use C++ ;).
#include <CGAL/Triangle_3.h>
#include <CGAL/Bbox_3.h>
#include <CGAL/Uncertain.h>
#include <CGAL/Intersections_3/internal/Bbox_3_Plane_3_do_intersect.h> #include <CGAL/Intersections_3/internal/Bbox_3_Plane_3_do_intersect.h>
#include <CGAL/Bbox_3.h> #include <CGAL/number_utils.h>
#include <CGAL/Uncertain.h>
namespace CGAL { namespace CGAL {
namespace Intersections { namespace Intersections {
@ -77,93 +80,101 @@ bool do_bbox_intersect(const typename K::Triangle_3& triangle,
// if you do not know it, or if it does not exist, // if you do not know it, or if it does not exist,
// use get_min_max without the AXE template parameter // use get_min_max without the AXE template parameter
// available in _plane_is_cuboid_do_intersect.h // available in _plane_is_cuboid_do_intersect.h
template <class K, class Box3, int AXE> template <class FT, class Box3, int AXE>
inline inline
void get_min_max(const typename K::FT& px, void get_min_max(const FT& px,
const typename K::FT& py, const FT& py,
const typename K::FT& pz, const FT& pz,
const Box3& c, const Box3& c,
typename K::Point_3& p_min, std::array<FT, 3>& p_min,
typename K::Point_3& p_max) std::array<FT, 3>& p_max)
{ {
CGAL_USE(px);
CGAL_USE(py);
CGAL_USE(pz);
if(AXE == 0 || px > 0) { if(AXE == 0 || px > 0) {
if(AXE == 1 || py > 0) { if(AXE == 1 || py > 0) {
if(AXE == 2 || pz > 0) { if(AXE == 2 || pz > 0) {
p_min = typename K::Point_3(c.xmin(), c.ymin(),c.zmin()); p_min = CGAL::make_array<FT>(c.xmin(), c.ymin(),c.zmin());
p_max = typename K::Point_3(c.xmax(), c.ymax(),c.zmax()); p_max = CGAL::make_array<FT>(c.xmax(), c.ymax(),c.zmax());
} }
else { else {
p_min = typename K::Point_3(c.xmin(), c.ymin(),c.zmax()); p_min = CGAL::make_array<FT>(c.xmin(), c.ymin(),c.zmax());
p_max = typename K::Point_3(c.xmax(), c.ymax(),c.zmin()); p_max = CGAL::make_array<FT>(c.xmax(), c.ymax(),c.zmin());
} }
} }
else { else {
if(AXE == 2 || pz > 0) { if(AXE == 2 || pz > 0) {
p_min = typename K::Point_3(c.xmin(), c.ymax(),c.zmin()); p_min = CGAL::make_array<FT>(c.xmin(), c.ymax(),c.zmin());
p_max = typename K::Point_3(c.xmax(), c.ymin(),c.zmax()); p_max = CGAL::make_array<FT>(c.xmax(), c.ymin(),c.zmax());
} }
else { else {
p_min = typename K::Point_3(c.xmin(), c.ymax(),c.zmax()); p_min = CGAL::make_array<FT>(c.xmin(), c.ymax(),c.zmax());
p_max = typename K::Point_3(c.xmax(), c.ymin(),c.zmin()); p_max = CGAL::make_array<FT>(c.xmax(), c.ymin(),c.zmin());
} }
} }
} }
else { else {
if(AXE == 1 || py > 0) { if(AXE == 1 || py > 0) {
if(AXE == 2 || pz > 0) { if(AXE == 2 || pz > 0) {
p_min = typename K::Point_3(c.xmax(), c.ymin(),c.zmin()); p_min = CGAL::make_array<FT>(c.xmax(), c.ymin(),c.zmin());
p_max = typename K::Point_3(c.xmin(), c.ymax(),c.zmax()); p_max = CGAL::make_array<FT>(c.xmin(), c.ymax(),c.zmax());
} }
else { else {
p_min = typename K::Point_3(c.xmax(), c.ymin(),c.zmax()); p_min = CGAL::make_array<FT>(c.xmax(), c.ymin(),c.zmax());
p_max = typename K::Point_3(c.xmin(), c.ymax(),c.zmin()); p_max = CGAL::make_array<FT>(c.xmin(), c.ymax(),c.zmin());
} }
} }
else { else {
if(AXE == 2 || pz > 0) { if(AXE == 2 || pz > 0) {
p_min = typename K::Point_3(c.xmax(), c.ymax(),c.zmin()); p_min = CGAL::make_array<FT>(c.xmax(), c.ymax(),c.zmin());
p_max = typename K::Point_3(c.xmin(), c.ymin(),c.zmax()); p_max = CGAL::make_array<FT>(c.xmin(), c.ymin(),c.zmax());
} }
else { else {
p_min = typename K::Point_3(c.xmax(), c.ymax(),c.zmax()); p_min = CGAL::make_array<FT>(c.xmax(), c.ymax(),c.zmax());
p_max = typename K::Point_3(c.xmin(), c.ymin(),c.zmin()); p_max = CGAL::make_array<FT>(c.xmin(), c.ymin(),c.zmin());
} }
} }
} }
} }
template <class K, int AXE, int SIDE> template <class FT, int SIDE, class Fct>
inline inline
typename K::FT Uncertain<Sign>
do_axis_intersect_aux(const typename K::FT& alpha, do_axis_intersect_aux_A0(const FT& alpha,
const typename K::FT& beta, const FT& beta,
const typename K::Vector_3* sides) const std::array<std::array<FT,3>, 3>& sides,
Fct do_axis_intersect_aux_impl)
{ {
switch ( AXE ) return do_axis_intersect_aux_impl(alpha, beta, sides[SIDE][2], sides[SIDE][1]);
{ }
case 0:
return -sides[SIDE].z()*alpha + sides[SIDE].y()*beta; template <class FT, int SIDE, class Fct>
case 1: inline
return sides[SIDE].z()*alpha - sides[SIDE].x()*beta; Uncertain<Sign>
case 2: do_axis_intersect_aux_A1(const FT& alpha,
return -sides[SIDE].y()*alpha + sides[SIDE].x()*beta; const FT& beta,
default: const std::array<std::array<FT,3>, 3>& sides,
CGAL_error(); Fct do_axis_intersect_aux_impl)
return typename K::FT(0); {
} return do_axis_intersect_aux_impl(beta, alpha, sides[SIDE][0], sides[SIDE][2]);
}
template <class FT, int SIDE, class Fct>
inline
Uncertain<Sign>
do_axis_intersect_aux_A2(const FT& alpha,
const FT& beta,
const std::array<std::array<FT,3>, 3>& sides,
Fct do_axis_intersect_aux_impl)
{
return do_axis_intersect_aux_impl(alpha, beta, sides[SIDE][1], sides[SIDE][0]);
} }
//given a vector checks whether it is collinear to a base vector //given a vector checks whether it is collinear to a base vector
//of the orthonormal frame. return -1 otherwise //of the orthonormal frame. return -1 otherwise
template <class K> template <class FT>
inline inline
int int
collinear_axis(typename K::Vector_3 side) collinear_axis(const std::array<FT,3>& side)
{ {
if(certainly(side[0] == 0)) if(certainly(side[0] == 0))
{ {
@ -177,201 +188,243 @@ collinear_axis(typename K::Vector_3 side)
if(certainly(side[1] == 0) && certainly(side[2] == 0)) if(certainly(side[1] == 0) && certainly(side[2] == 0))
return 0; return 0;
} }
return -1; return -1;
} }
template <class K, class Box3, int AXE, int SIDE> template <class FT, class Box3, int AXE, int SIDE, class Fct>
inline inline
Uncertain<bool> do_axis_intersect(const typename K::Triangle_3& triangle, Uncertain<bool> do_axis_intersect(const std::array<std::array<FT, 3>, 3>& triangle,
const typename K::Vector_3* sides, const std::array<std::array<FT, 3>, 3>& sides,
const Box3& bbox) const Box3& bbox,
Fct do_axis_intersect_aux_impl)
{ {
const typename K::Point_3* j = & triangle.vertex(SIDE); const std::array<FT, 3>& j = triangle[SIDE];
const typename K::Point_3* k = & triangle.vertex((SIDE+2)%3); const std::array<FT, 3>& k = triangle[(SIDE+2)%3];
const std::array<FT, 3>* j_ptr = &j;
const std::array<FT, 3>* k_ptr = &k;
typename K::Point_3 p_min, p_max; std::array<FT, 3> p_min, p_max;
get_min_max<K,Box3, AXE>(AXE==0? 0: AXE==1? sides[SIDE].z(): -sides[SIDE].y(), get_min_max<FT, Box3, AXE>(AXE==0? 0: AXE==1? sides[SIDE][2]: -sides[SIDE][1],
AXE==0? -sides[SIDE].z(): AXE==1? 0: sides[SIDE].x(), AXE==0? -sides[SIDE][2]: AXE==1? 0: sides[SIDE][0],
AXE==0? sides[SIDE].y(): AXE==1? -sides[SIDE].x(): AXE==0? sides[SIDE][1]: AXE==1? -sides[SIDE][0]:
typename K::FT(0), bbox, p_min, p_max); FT(0), bbox, p_min, p_max);
switch ( AXE ) switch(AXE)
{ {
case 0: { case 0:
{
// t_max >= t_min // t_max >= t_min
Uncertain<bool> b = do_axis_intersect_aux<K,AXE,SIDE>(k->y()-j->y(), k->z()-j->z(), sides) >= 0; Uncertain<bool> b = do_axis_intersect_aux_A0<FT,SIDE>(k[1]-j[1], k[2]-j[2], sides, do_axis_intersect_aux_impl) != NEGATIVE;
if (is_indeterminate(b)) if(is_indeterminate(b))
return b; return b;
if(b) std::swap(j,k); if(b)
return CGAL_AND((do_axis_intersect_aux<K,AXE,SIDE>(p_min.y()-j->y(), p_min.z()-j->z(), sides) <= 0), std::swap(j_ptr, k_ptr);
(do_axis_intersect_aux<K,AXE,SIDE>(p_max.y()-k->y(), p_max.z()-k->z(), sides) >= 0) );
}
case 1: {
// t_max >= t_min
Uncertain<bool> b = do_axis_intersect_aux<K,AXE,SIDE>(k->x()-j->x(), k->z()-j->z(), sides) >= 0;
if (is_indeterminate(b))
return b;
if(b) std::swap(j,k);
return CGAL_AND((do_axis_intersect_aux<K,AXE,SIDE>(p_min.x()-j->x(), p_min.z()-j->z(), sides) <= 0),
(do_axis_intersect_aux<K,AXE,SIDE>(p_max.x()-k->x(), p_max.z()-k->z(), sides) >= 0) );
return CGAL_AND((do_axis_intersect_aux_A0<FT,SIDE>(p_min[1]-(*j_ptr)[1], p_min[2]-(*j_ptr)[2],
sides, do_axis_intersect_aux_impl) != POSITIVE),
(do_axis_intersect_aux_A0<FT,SIDE>(p_max[1]-(*k_ptr)[1], p_max[2]-(*k_ptr)[2],
sides, do_axis_intersect_aux_impl) != NEGATIVE) );
} }
case 2: { case 1:
{
// t_max >= t_min // t_max >= t_min
Uncertain<bool> b = do_axis_intersect_aux<K,AXE,SIDE>(k->x()-j->x(), k->y()-j->y(), sides) >= 0; Uncertain<bool> b = do_axis_intersect_aux_A1<FT,SIDE>(k[0]-j[0], k[2]-j[2], sides, do_axis_intersect_aux_impl) != NEGATIVE;
if ( is_indeterminate(b)) if(is_indeterminate(b))
return b; return b;
if(b) std::swap(j,k); if(b)
return CGAL_AND((do_axis_intersect_aux<K,AXE,SIDE>(p_min.x()-j->x(), p_min.y()-j->y(), sides) <= 0), std::swap(j_ptr, k_ptr);
(do_axis_intersect_aux<K,AXE,SIDE>(p_max.x()-k->x(), p_max.y()-k->y(), sides) >= 0) );
return CGAL_AND((do_axis_intersect_aux_A1<FT,SIDE>(p_min[0]-(*j_ptr)[0], p_min[2]-(*j_ptr)[2],
sides, do_axis_intersect_aux_impl) != POSITIVE),
(do_axis_intersect_aux_A1<FT,SIDE>(p_max[0]-(*k_ptr)[0], p_max[2]-(*k_ptr)[2],
sides, do_axis_intersect_aux_impl) != NEGATIVE) );
} }
default: case 2:
// Should not happen {
// t_max >= t_min
Uncertain<bool> b = do_axis_intersect_aux_A2<FT,SIDE>(k[0]-j[0], k[1]-j[1], sides, do_axis_intersect_aux_impl) != NEGATIVE;
if(is_indeterminate(b))
return b;
if(b)
std::swap(j_ptr, k_ptr);
return CGAL_AND((do_axis_intersect_aux_A2<FT,SIDE>(p_min[0]-(*j_ptr)[0], p_min[1]-(*j_ptr)[1],
sides, do_axis_intersect_aux_impl) != POSITIVE),
(do_axis_intersect_aux_A2<FT,SIDE>(p_max[0]-(*k_ptr)[0], p_max[1]-(*k_ptr)[1],
sides, do_axis_intersect_aux_impl) != NEGATIVE) );
}
default: // Should not happen
CGAL_error(); CGAL_error();
return make_uncertain(false); return make_uncertain(false);
} }
} }
template <class FT, class Box3, class Fct>
Uncertain<bool>
do_intersect_bbox_or_iso_cuboid_impl(const std::array< std::array<FT, 3>, 3>& triangle,
const Box3& bbox,
Fct do_axis_intersect_aux_impl)
{
std::array< std::array<FT, 3>, 3> sides =
{{
{triangle[1][0] - triangle[0][0], triangle[1][1] - triangle[0][1], triangle[1][2] - triangle[0][2]},
{triangle[2][0] - triangle[1][0], triangle[2][1] - triangle[1][1], triangle[2][2] - triangle[1][2]},
{triangle[0][0] - triangle[2][0], triangle[0][1] - triangle[2][1], triangle[0][2] - triangle[2][2]}
}};
int forbidden_axis = -1;
int forbidden_size = -1;
//determine whether one vector is collinear with an axis
int tmp = collinear_axis<FT>(sides[0]);
if(tmp != -1)
{
forbidden_axis = tmp;
forbidden_size = 0;
}
else
{
tmp = collinear_axis<FT>(sides[1]);
if(tmp != -1)
{
forbidden_axis = tmp;
forbidden_size = 1;
}
else
{
tmp = collinear_axis<FT>(sides[2]);
if(tmp != -1)
{
forbidden_axis = tmp;
forbidden_size = 2;
}
}
}
// Create a "certainly true"
Uncertain<bool> ind_or_true = make_uncertain(true);
if(forbidden_axis != 0)
{
if(forbidden_size != 0)
{
Uncertain<bool> b = do_axis_intersect<FT,Box3,0,0>(triangle, sides, bbox, do_axis_intersect_aux_impl);
if(is_indeterminate(b))
ind_or_true = b;
else if(!b)
return false;
}
if(forbidden_size != 1)
{
Uncertain<bool> b = do_axis_intersect<FT,Box3,0,1>(triangle, sides, bbox, do_axis_intersect_aux_impl);
if(is_indeterminate(b))
ind_or_true = b;
else if(!b)
return false;
}
if(forbidden_size != 2)
{
Uncertain<bool> b = do_axis_intersect<FT,Box3,0,2>(triangle, sides, bbox, do_axis_intersect_aux_impl);
if(is_indeterminate(b))
ind_or_true = b;
else if(!b)
return false;
}
}
if(forbidden_axis != 1)
{
if(forbidden_size != 0)
{
Uncertain<bool> b = do_axis_intersect<FT,Box3,1,0>(triangle, sides, bbox, do_axis_intersect_aux_impl);
if(is_indeterminate(b))
ind_or_true = b;
else if(!b)
return false;
}
if(forbidden_size != 1)
{
Uncertain<bool> b = do_axis_intersect<FT,Box3,1,1>(triangle, sides, bbox, do_axis_intersect_aux_impl);
if(is_indeterminate(b))
ind_or_true = b;
else if(!b)
return false;
}
if(forbidden_size != 2)
{
Uncertain<bool> b = do_axis_intersect<FT,Box3,1,2>(triangle, sides, bbox, do_axis_intersect_aux_impl);
if(is_indeterminate(b))
ind_or_true = b;
else if(!b)
return false;
}
}
if(forbidden_axis != 2)
{
if(forbidden_size != 0)
{
Uncertain<bool> b = do_axis_intersect<FT,Box3,2,0>(triangle, sides, bbox, do_axis_intersect_aux_impl);
if(is_indeterminate(b))
ind_or_true = b;
else if(!b)
return false;
}
if(forbidden_size != 1)
{
Uncertain<bool> b = do_axis_intersect<FT,Box3,2,1>(triangle, sides, bbox, do_axis_intersect_aux_impl);
if(is_indeterminate(b))
ind_or_true = b;
else if(!b)
return false;
}
if(forbidden_size != 2)
{
Uncertain<bool> b = do_axis_intersect<FT,Box3,2,2>(triangle, sides, bbox, do_axis_intersect_aux_impl);
if(is_indeterminate(b))
ind_or_true = b;
else if(!b)
return false;
}
}
return ind_or_true;
}
template <class K, class Box3> template <class K, class Box3>
bool do_intersect_bbox_or_iso_cuboid(const typename K::Triangle_3& a_triangle, bool do_intersect_bbox_or_iso_cuboid(const typename K::Triangle_3& a_triangle,
const Box3& a_bbox, const Box3& a_bbox,
const K& k) const K& k)
{ {
if(certainly_not(do_bbox_intersect<K>(a_triangle, a_bbox)))
if(certainly_not( do_bbox_intersect<K>(a_triangle, a_bbox) ))
return false; return false;
if(certainly_not( do_intersect(a_triangle.supporting_plane(), a_bbox, k) )) if(certainly_not(do_intersect(a_triangle.supporting_plane(), a_bbox, k)))
return false; return false;
typename K::Vector_3 sides[3]; typedef typename K::FT FT;
sides[0] = a_triangle[1] - a_triangle[0]; auto do_axis_intersect_aux_impl = [](const FT& alpha,
sides[1] = a_triangle[2] - a_triangle[1]; const FT& beta,
sides[2] = a_triangle[0] - a_triangle[2]; const FT& c_alpha,
int forbidden_axis=-1; const FT& c_beta) -> Uncertain<Sign>
int forbidden_size=-1; {
//determine whether one vector is collinear with an axis return CGAL::sign(- c_alpha * alpha + c_beta * beta);
int tmp=collinear_axis<K>(sides[0]); };
if ( tmp!= -1){
forbidden_axis=tmp;
forbidden_size=0;
}
else{
tmp=collinear_axis<K>(sides[1]);
if ( tmp!= -1){
forbidden_axis=tmp;
forbidden_size=1;
}
else{
tmp=collinear_axis<K>(sides[2]);
if ( tmp!= -1){
forbidden_axis=tmp;
forbidden_size=2;
}
}
}
#if 0 std::array< std::array<FT, 3>, 3> triangle =
typename K::Point_3 p(a_bbox.xmin(), a_bbox.ymin(), a_bbox.zmin()); {{
typename K::Point_3 q(a_bbox.xmax(), a_bbox.ymax(), a_bbox.zmax()); { a_triangle[0][0], a_triangle[0][1], a_triangle[0][2] },
{ a_triangle[1][0], a_triangle[1][1], a_triangle[1][2] },
{ a_triangle[2][0], a_triangle[2][1], a_triangle[2][2] }
}};
typename K::Point_3 m = CGAL::midpoint(p,q); // exception will be thrown in case the output is indeterminate
typename K::Vector_3 v = m - CGAL::ORIGIN; return do_intersect_bbox_or_iso_cuboid_impl<FT>(triangle, a_bbox, do_axis_intersect_aux_impl);
typename K::Triangle_3 triangle(a_triangle[0]-v, a_triangle[1]-v, a_triangle[2]-v);
Box3 bbox( (p-v).bbox() + (q-v).bbox());
#else
const typename K::Triangle_3& triangle = a_triangle;
const Box3& bbox = a_bbox;
#endif
// Create a "certainly true"
Uncertain<bool> ind_or_true = make_uncertain(true);
if (forbidden_axis!=0){
if (forbidden_size!=0){
Uncertain<bool> b = do_axis_intersect<K,Box3,0,0>(triangle, sides, bbox);
if(is_indeterminate(b)){
ind_or_true = b;
} else if(! b){
return false;
}
}
if (forbidden_size!=1){
Uncertain<bool> b = do_axis_intersect<K,Box3,0,1>(triangle, sides, bbox);
if(is_indeterminate(b)){
ind_or_true = b;
} else if(! b){
return false;
}
}
if (forbidden_size!=2){
Uncertain<bool> b = do_axis_intersect<K,Box3,0,2>(triangle, sides, bbox);
if(is_indeterminate(b)){
ind_or_true = b;
} else if(! b){
return false;
}
}
}
if (forbidden_axis!=1){
if (forbidden_size!=0){
Uncertain<bool> b = do_axis_intersect<K,Box3,1,0>(triangle, sides, bbox);
if(is_indeterminate(b)){
ind_or_true = b;
} else if(! b){
return false;
}
}
if (forbidden_size!=1){
Uncertain<bool> b = do_axis_intersect<K,Box3,1,1>(triangle, sides, bbox);
if(is_indeterminate(b)){
ind_or_true = b;
} else if(! b){
return false;
}
}
if (forbidden_size!=2){
Uncertain<bool> b = do_axis_intersect<K,Box3,1,2>(triangle, sides, bbox);
if(is_indeterminate(b)){
ind_or_true = b;
} else if(! b){
return false;
}
}
}
if (forbidden_axis!=2){
if (forbidden_size!=0){
Uncertain<bool> b = do_axis_intersect<K,Box3,2,0>(triangle, sides, bbox);
if(is_indeterminate(b)){
ind_or_true = b;
} else if(! b){
return false;
}
}
if (forbidden_size!=1){
Uncertain<bool> b = do_axis_intersect<K,Box3,2,1>(triangle, sides, bbox);
if(is_indeterminate(b)){
ind_or_true = b;
} else if(! b){
return false;
}
}
if (forbidden_size!=2){
Uncertain<bool> b = do_axis_intersect<K,Box3,2,2>(triangle, sides, bbox);
if(is_indeterminate(b)){
ind_or_true = b;
} else if(! b){
return false;
}
}
}
return ind_or_true; // throws exception in case it is indeterminate
} }
template <class K> template <class K>

View File

@ -68,12 +68,12 @@ public:
template <class TPoly> template <class TPoly>
class Facet_PM : class Facet_PM :
public boost::put_get_helper<typename TPoly::Traits::Vector_3, Facet_PM<TPoly> > public boost::put_get_helper<typename TPoly::Traits::Vector_3&, Facet_PM<TPoly> >
{ {
public: public:
//read_write //read_write
typedef boost::read_write_property_map_tag category; typedef boost::lvalue_property_map_tag category;
typedef typename TPoly::Facet key_type; typedef typename TPoly::Facet key_type;
typedef typename TPoly::Traits::Vector_3 value_type; typedef typename TPoly::Traits::Vector_3 value_type;
typedef typename TPoly::Traits::Vector_3& reference; typedef typename TPoly::Traits::Vector_3& reference;
@ -121,8 +121,6 @@ class HEdge_PM :
public boost::put_get_helper<typename TPoly::Traits::FT&, HEdge_PM<TPoly> >//double public boost::put_get_helper<typename TPoly::Traits::FT&, HEdge_PM<TPoly> >//double
{ {
public: public:
//read_write or lvalue
//typedef boost::read_write_property_map_tag category;
typedef boost::lvalue_property_map_tag category; typedef boost::lvalue_property_map_tag category;
typedef typename TPoly::Halfedge key_type; typedef typename TPoly::Halfedge key_type;
typedef typename TPoly::Traits::FT value_type; typedef typename TPoly::Traits::FT value_type;

View File

@ -19,6 +19,7 @@ provides exact predicates.
\cgalModels `DelaunayTriangulationTraits_2` \cgalModels `DelaunayTriangulationTraits_2`
\cgalModels `ConstrainedTriangulationTraits_2` \cgalModels `ConstrainedTriangulationTraits_2`
\cgalModels `PolygonTraits_2` \cgalModels `PolygonTraits_2`
\cgalModels `ConformingDelaunayTriangulationTraits_2`
\sa `CGAL::Projection_traits_xy_3` \sa `CGAL::Projection_traits_xy_3`
\sa `CGAL::Projection_traits_xz_3` \sa `CGAL::Projection_traits_xz_3`

View File

@ -9258,6 +9258,16 @@ public:
Oriented_side operator()(const Kernel::Triangle_2&t, Oriented_side operator()(const Kernel::Triangle_2&t,
const Kernel::Point_2&p); const Kernel::Point_2&p);
/*!
* returns \ref CGAL::ON_ORIENTED_BOUNDARY,
* \ref CGAL::ON_NEGATIVE_SIDE, or the constant \ref CGAL::ON_POSITIVE_SIDE,
* depending on the position of the circumcenter of `t` relative
* to the oriented supporting line of `s`. The orientation of the
* supporting line is the same as the orientation of `s`.
*/
Oriented_side operator()(const Kernel::Segment_2& s,
const Kernel::Triangle_2& t);
/// @} /// @}
}; /* end Kernel::OrientedSide_2 */ }; /* end Kernel::OrientedSide_2 */

View File

@ -115,6 +115,41 @@ public:
} }
}; };
template <class R, int dim>
class Oriented_side_projected_3
{
public:
typedef typename R::Segment_2 Segment_2;
typedef typename R::Triangle_2 Triangle_2;
typedef typename R::Point_3 Point;
typedef typename R::Segment_3 Segment_3;
typedef typename R::Triangle_3 Triangle_3;
typename R::FT x(const Point& p) const { return Projector<R, dim>::x(p); }
typename R::FT y(const Point& p) const { return Projector<R, dim>::y(p); }
typename R::Point_2 project(const Point& p) const
{
return typename R::Point_2(x(p), y(p));
}
Triangle_2 project(const Triangle_3& t) const
{
typename R::Construct_vertex_3 v;
return Triangle_2(project(v(t, 0)), project(v(t, 1)), project(v(t, 2)));
}
Segment_2 project(const Segment_3& s) const
{
typename R::Construct_source_3 source;
typename R::Construct_target_3 target;
return Segment_2(project(source(s)), project(target(s)));
}
CGAL::Oriented_side operator()(const Segment_3& s, const Triangle_3& t) const
{
return typename R::Oriented_side_2()(project(s), project(t));
}
};
template <class R,int dim> template <class R,int dim>
class Side_of_oriented_circle_projected_3 class Side_of_oriented_circle_projected_3
{ {
@ -854,6 +889,7 @@ public:
typedef typename Projector<R,dim>::Compare_x_2 Compare_x_2; typedef typename Projector<R,dim>::Compare_x_2 Compare_x_2;
typedef typename Projector<R,dim>::Compare_y_2 Compare_y_2; typedef typename Projector<R,dim>::Compare_y_2 Compare_y_2;
typedef Orientation_projected_3<Rp,dim> Orientation_2; typedef Orientation_projected_3<Rp,dim> Orientation_2;
typedef Oriented_side_projected_3<Rp,dim> Oriented_side_2;
typedef Angle_projected_3<Rp,dim> Angle_2; typedef Angle_projected_3<Rp,dim> Angle_2;
typedef Side_of_oriented_circle_projected_3<Rp,dim> Side_of_oriented_circle_2; typedef Side_of_oriented_circle_projected_3<Rp,dim> Side_of_oriented_circle_2;
typedef Less_signed_distance_to_line_projected_3<Rp,dim> Less_signed_distance_to_line_2; typedef Less_signed_distance_to_line_projected_3<Rp,dim> Less_signed_distance_to_line_2;
@ -1014,6 +1050,10 @@ public:
orientation_2_object() const orientation_2_object() const
{ return Orientation_2();} { return Orientation_2();}
Oriented_side_2
oriented_side_2_object() const
{ return Oriented_side_2();}
Side_of_oriented_circle_2 Side_of_oriented_circle_2
side_of_oriented_circle_2_object() const side_of_oriented_circle_2_object() const
{return Side_of_oriented_circle_2();} {return Side_of_oriented_circle_2();}

View File

@ -3,7 +3,8 @@ namespace CGAL {
/*! /*!
\ingroup PkgDrawLinearCellComplex \ingroup PkgDrawLinearCellComplex
opens a new window and draws `alcc`, a model of the `LinearCellComplex` concept. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. opens a new window and draws `alcc`, a model of the `LinearCellComplex` concept. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires `CGAL_Qt5`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is defined.
Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt5` and add the definition `CGAL_USE_BASIC_VIEWER`.
\tparam LCC a model of the `LinearCellComplex` concept. \tparam LCC a model of the `LinearCellComplex` concept.
\param alcc the linear cell complex to draw. \param alcc the linear cell complex to draw.

View File

@ -257,7 +257,8 @@ A linear cell complex can be visualized by calling the \link PkgDrawLinearCellCo
\cgalExample{Linear_cell_complex/draw_linear_cell_complex.cpp} \cgalExample{Linear_cell_complex/draw_linear_cell_complex.cpp}
This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. This function requires `CGAL_Qt5`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is defined.
Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt5` and add the definition `CGAL_USE_BASIC_VIEWER`.
\cgalFigureBegin{fig_draw_lcc,draw_lcc.png} \cgalFigureBegin{fig_draw_lcc,draw_lcc.png}
Result of the run of the draw_linear_cell_complex program. A window shows two 3D cubes and allows to navigate through the 3D scene. Result of the run of the draw_linear_cell_complex program. A window shows two 3D cubes and allows to navigate through the 3D scene.

View File

@ -15,10 +15,6 @@ endif()
find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt5) find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt5)
if(CGAL_Qt5_FOUND)
add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS)
endif()
# For Gprof. # For Gprof.
# ADD_DEFINITIONS("-pg") # ADD_DEFINITIONS("-pg")
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg") # set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
@ -41,5 +37,5 @@ create_single_source_cgal_program("voronoi_3.cpp")
create_single_source_cgal_program("draw_linear_cell_complex.cpp") create_single_source_cgal_program("draw_linear_cell_complex.cpp")
if(CGAL_Qt5_FOUND) if(CGAL_Qt5_FOUND)
target_link_libraries(draw_linear_cell_complex PUBLIC CGAL::CGAL_Qt5) target_link_libraries(draw_linear_cell_complex PUBLIC CGAL::CGAL_Basic_viewer)
endif() endif()

View File

@ -42,7 +42,6 @@ namespace CGAL {
template<typename LCC, typename FT> template<typename LCC, typename FT>
struct Wrap_squared_lcc struct Wrap_squared_lcc
: boost::put_get_helper< double, Wrap_squared_lcc<LCC, FT> >
{ {
typedef typename boost::graph_traits<LCC>::edge_descriptor Handle; typedef typename boost::graph_traits<LCC>::edge_descriptor Handle;
typedef FT value_type; typedef FT value_type;
@ -54,12 +53,19 @@ struct Wrap_squared_lcc
{} {}
template<typename E> template<typename E>
FT operator[](const E& e) const value_type operator[](const E& e) const
{ {
return approximate_sqrt(CGAL::squared_distance return approximate_sqrt(CGAL::squared_distance
(m_lcc.point(e.first_halfedge()), (m_lcc.point(e.first_halfedge()),
m_lcc.point(e.second_halfedge()))); m_lcc.point(e.second_halfedge())));
} }
friend inline
value_type get(const Wrap_squared_lcc& m, const key_type& k)
{
return m[k];
}
private: private:
const LCC& m_lcc; const LCC& m_lcc;
}; };

View File

@ -92,6 +92,17 @@ points `p`, `q`, `r` (`q` being the vertex of the angle).
*/ */
typedef unspecified_type Angle_2; typedef unspecified_type Angle_2;
/*!
Predicate object. Must provide the operator
`CGAL::Oriented_side operator()(Segment_2 s, Triangle_2 t)` that
returns \ref ON_ORIENTED_BOUNDARY, \ref ON_NEGATIVE_SIDE,
or \ref ON_POSITIVE_SIDE,
depending on the position of the circumcenter of `t` relative
to the oriented supporting line of `s`. The orientation of the
supporting line is the same as the orientation of `s`.
*/
typedef unspecified_type Oriented_side_2;
/// @} /// @}

View File

@ -242,25 +242,9 @@ private:
bool segment_hides_circumcenter(const Segment& seg, bool segment_hides_circumcenter(const Segment& seg,
const Triangle& tr) const Triangle& tr)
{ {
Point a = seg.source(); typename Geom_traits::Oriented_side_2 os
Point b = seg.target(); = m_cdt.geom_traits().oriented_side_2_object();
double dX = b.x() - a.x(); return (os(seg, tr) != CGAL::ON_POSITIVE_SIDE);
double dY = b.y() - a.y();
const Point& p0 = tr[0];
const Point& p1 = tr[1];
const Point& p2 = tr[2];
double R0 = p0.x()*p0.x() + p0.y()*p0.y();
double R1 = p1.x()*p1.x() + p1.y()*p1.y();
double R2 = p2.x()*p2.x() + p2.y()*p2.y();
double denominator = (p1.x()-p0.x())*(p2.y()-p0.y()) +
(p0.x()-p2.x())*(p1.y()-p0.y());
double det = 2*denominator * (a.x()*dY - a.y()*dX)
- (R2-R1) * (p0.x()*dX + p0.y()*dY)
- (R0-R2) * (p1.x()*dX + p1.y()*dY)
- (R1-R0) * (p2.x()*dX + p2.y()*dY);
return (det <= 0);
} }
// tags with their sights, with respect to the Edge constraint, // tags with their sights, with respect to the Edge constraint,

View File

@ -352,7 +352,7 @@ private:
sum += CGAL::sqrt(*it); sum += CGAL::sqrt(*it);
#ifdef CGAL_MESH_2_OPTIMIZER_VERBOSE #ifdef CGAL_MESH_2_OPTIMIZER_VERBOSE
sum_moves_ = sum/big_moves_.size(); sum_moves_ = sum/FT(big_moves_.size());
#endif #endif
return ( sum/FT(big_moves_.size()) < convergence_ratio_ ); return ( sum/FT(big_moves_.size()) < convergence_ratio_ );

View File

@ -169,7 +169,7 @@ private:
typename Tr::Edge_circulator end = ec; typename Tr::Edge_circulator end = ec;
FT sum_len(0.); FT sum_len(0.);
FT nb = 0.; unsigned int nb = 0;
do do
{ {
Edge e = *ec; Edge e = *ec;
@ -187,7 +187,7 @@ private:
while(++ec != end); while(++ec != end);
// nb == 0 could happen if there is an isolated point. // nb == 0 could happen if there is an isolated point.
if( 0 != nb ) if( 0 != nb )
return sum_len/nb; return sum_len/FT(nb);
else else
// Use outside faces to compute size of point // Use outside faces to compute size of point
return 1.;//todo return 1.;//todo

View File

@ -233,6 +233,12 @@ The parameters are optional unless otherwise specified.
<li> <b>`parameters::image` (mandatory)</b> the input 3D image. Must <li> <b>`parameters::image` (mandatory)</b> the input 3D image. Must
be a `CGAL::Image_3` object. be a `CGAL::Image_3` object.
<li> <b>`parameters::weights`</b> an input 3D image that provides
weights associated to each voxel (the word type is `unsigned char`,
and the voxels values are integers between 0 and 255).
The weights image can be generated with `CGAL::Mesh_3::generate_label_weights()`.
Its dimensions must be the same as the dimensions of `parameters::image`.
<li><b>`parameter::value_outside`</b> the value attached to voxels <li><b>`parameter::value_outside`</b> the value attached to voxels
outside of the domain to be meshed. Its default value is `0`. outside of the domain to be meshed. Its default value is `0`.
@ -246,6 +252,11 @@ From the example (\ref Mesh_3/mesh_3D_image.cpp):
\snippet Mesh_3/mesh_3D_image.cpp Domain creation \snippet Mesh_3/mesh_3D_image.cpp Domain creation
From the example (\ref Mesh_3/mesh_3D_weighted_image.cpp),
where the labeled image is used with a precomputed 3D image of weights :
\snippet Mesh_3/mesh_3D_weighted_image.cpp Domain creation
*/ */
template <typename ... A_i> template <typename ... A_i>
static static

View File

@ -5,7 +5,8 @@ ALIASES += "cgalDescribePolylineType=A polyline is defined as a sequence of poin
INPUT += \ INPUT += \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Polyhedral_complex_mesh_domain_3.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Polyhedral_complex_mesh_domain_3.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_domain_with_polyline_features_3.h ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_domain_with_polyline_features_3.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Mesh_3/generate_label_weights.h
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 3D Mesh Generation" PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 3D Mesh Generation"
HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/implicit_domain_3.jpg \ HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/implicit_domain_3.jpg \

View File

@ -706,6 +706,24 @@ The resulting mesh is shown in \cgalFigureRef{figureliver_3d_image_mesh}.
Cut view of a 3D mesh produced from a segmented liver image. Code from subsection \ref Mesh_3_subsection_examples_3d_image generates this file. Cut view of a 3D mesh produced from a segmented liver image. Code from subsection \ref Mesh_3_subsection_examples_3d_image generates this file.
\cgalFigureEnd \cgalFigureEnd
\subsubsection Mesh_3DomainsFrom3DImagesWithWeights Domains From Segmented 3D Images, with Weights
When a segmented image is given as input, the generated mesh surface sometimes sticks too closely
to the voxels surface, causing an aliasing effect.
A solution to generate a smooth and accurate output surface was described by Stalling et al in
\cgalCite{stalling1998weighted}. It consists in generating a second input image, made
of integer coefficients called *weights*, and use those weights to define smoother domain boundaries.
The 3D image of weights can be generated using `CGAL::Mesh_3::generate_weights()` as shown in
the following example.
\cgalExample{Mesh_3/mesh_3D_weighted_image.cpp}
\cgalFigureBegin{figure_weightedImage, weighted_images.jpg}
Surface of the output mesh generated with a very small `facet_distance`
without the weights (left, 25563 vertices) and with the weights (right, 19936 vertices).
\cgalFigureEnd
\subsubsection Mesh_3DomainsFrom3DImagesWithCustomInitialization Domains From 3D Images, with a Custom Initialization \subsubsection Mesh_3DomainsFrom3DImagesWithCustomInitialization Domains From 3D Images, with a Custom Initialization
The example \ref Mesh_3/mesh_3D_image_with_custom_initialization.cpp is a modification The example \ref Mesh_3/mesh_3D_image_with_custom_initialization.cpp is a modification

View File

@ -115,6 +115,7 @@ and their associated classes:
- `CGAL::lloyd_optimize_mesh_3()` - `CGAL::lloyd_optimize_mesh_3()`
- `CGAL::odt_optimize_mesh_3()` - `CGAL::odt_optimize_mesh_3()`
- `CGAL::facets_in_complex_3_to_triangle_mesh()` - `CGAL::facets_in_complex_3_to_triangle_mesh()`
- `CGAL::Mesh_3::generate_label_weights()`
\cgalCRPSection{CGAL::parameters Functions} \cgalCRPSection{CGAL::parameters Functions}

View File

@ -4,6 +4,7 @@
\example Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp \example Mesh_3/mesh_3D_gray_image_with_custom_initialization.cpp
\example Mesh_3/mesh_3D_image_with_features.cpp \example Mesh_3/mesh_3D_image_with_features.cpp
\example Mesh_3/mesh_3D_image_with_custom_initialization.cpp \example Mesh_3/mesh_3D_image_with_custom_initialization.cpp
\example Mesh_3/mesh_3D_weighted_image.cpp
\example Mesh_3/random_labeled_image.h \example Mesh_3/random_labeled_image.h
\example CGAL/Mesh_3/initialize_triangulation_from_gray_image.h \example CGAL/Mesh_3/initialize_triangulation_from_gray_image.h
\example CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h \example CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

View File

@ -161,10 +161,21 @@ if(TARGET CGAL::CGAL_ImageIO)
create_single_source_cgal_program("mesh_3D_image_variable_size.cpp") create_single_source_cgal_program("mesh_3D_image_variable_size.cpp")
target_link_libraries(mesh_3D_image_variable_size target_link_libraries(mesh_3D_image_variable_size
PUBLIC CGAL::Eigen3_support) PUBLIC CGAL::Eigen3_support)
find_package(ITK QUIET COMPONENTS ITKCommon ITKThresholding ITKSmoothing ITKImageIntensity)
if(ITK_FOUND)
include(CGAL_ITK_support)
create_single_source_cgal_program("mesh_3D_weighted_image.cpp")
target_link_libraries(mesh_3D_weighted_image
PUBLIC CGAL::Eigen3_support CGAL::ITK_support)
else(ITK_FOUND)
message(STATUS "NOTICE: The examples that need ITK will not be compiled.")
endif(ITK_FOUND)
else() else()
message( message(
STATUS 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." "NOTICE: The examples mesh_3D_image.cpp, mesh_3D_weighted_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."
) )
endif() endif()
@ -179,6 +190,7 @@ if(CGAL_ACTIVATE_CONCURRENT_MESH_3 AND TARGET CGAL::TBB_support)
foreach( foreach(
target target
mesh_3D_image mesh_3D_image
mesh_3D_weighted_image
mesh_3D_image_variable_size mesh_3D_image_variable_size
mesh_3D_image_with_custom_initialization mesh_3D_image_with_custom_initialization
mesh_3D_gray_image_with_custom_initialization mesh_3D_gray_image_with_custom_initialization

View File

@ -28,7 +28,7 @@ using namespace CGAL::parameters;
int main(int argc, char*argv[]) int main(int argc, char*argv[])
{ {
const char* fname = (argc>1)?argv[1]:"data/skull_2.9.inr"; const std::string fname = (argc>1)?argv[1]:CGAL::data_file_path("images/skull_2.9.inr");
// Load image // Load image
CGAL::Image_3 image; CGAL::Image_3 image;
if(!image.read(fname)){ if(!image.read(fname)){

View File

@ -42,7 +42,7 @@ struct Image_to_multiple_iso_level_sets {
int main(int argc, char*argv[]) int main(int argc, char*argv[])
{ {
const char* fname = (argc>1)?argv[1]:"data/skull_2.9.inr"; const std::string fname = (argc>1)?argv[1]:CGAL::data_file_path("images/skull_2.9.inr");
// Load image // Load image
CGAL::Image_3 image; CGAL::Image_3 image;
if(!image.read(fname)){ if(!image.read(fname)){

View File

@ -37,7 +37,7 @@ using namespace CGAL::parameters;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
const char* fname = (argc > 1) ? argv[1] : "data/skull_2.9.inr"; const std::string fname = (argc > 1) ? argv[1] : CGAL::data_file_path("images/skull_2.9.inr");
/// [Load image] /// [Load image]
CGAL::Image_3 image; CGAL::Image_3 image;
if (!image.read(fname)) { if (!image.read(fname)) {

View File

@ -32,7 +32,7 @@ using namespace CGAL::parameters;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
/// [Loads image] /// [Loads image]
const char* fname = (argc>1)?argv[1]:"data/liver.inr.gz"; const std::string fname = (argc>1)?argv[1]:CGAL::data_file_path("images/liver.inr.gz");
CGAL::Image_3 image; CGAL::Image_3 image;
if(!image.read(fname)){ if(!image.read(fname)){
std::cerr << "Error: Cannot read file " << fname << std::endl; std::cerr << "Error: Cannot read file " << fname << std::endl;

View File

@ -36,7 +36,7 @@ using namespace CGAL::parameters;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
const char* fname = (argc>1)?argv[1]:"data/liver.inr.gz"; const std::string fname = (argc>1)?argv[1]:CGAL::data_file_path("images/liver.inr.gz");
// Loads image // Loads image
CGAL::Image_3 image; CGAL::Image_3 image;
if(!image.read(fname)){ if(!image.read(fname)){

View File

@ -44,7 +44,7 @@ using namespace CGAL::parameters;
// not documented. // not documented.
bool add_1D_features(const CGAL::Image_3& image, bool add_1D_features(const CGAL::Image_3& image,
Mesh_domain& domain, Mesh_domain& domain,
const char* lines_fname) const std::string lines_fname)
{ {
typedef K::Point_3 Point_3; typedef K::Point_3 Point_3;
typedef unsigned char Word_type; typedef unsigned char Word_type;
@ -72,7 +72,7 @@ bool add_1D_features(const CGAL::Image_3& image,
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
const char* fname = (argc>1)?argv[1]:"data/420.inr"; const std::string fname = (argc>1)?argv[1]:CGAL::data_file_path("images/420.inr");
// Loads image // Loads image
CGAL::Image_3 image; CGAL::Image_3 image;
if(!image.read(fname)){ if(!image.read(fname)){
@ -84,7 +84,7 @@ int main(int argc, char* argv[])
Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image);
/// Declare 1D-features, see above [Call add_1D_features] /// Declare 1D-features, see above [Call add_1D_features]
const char* lines_fname = (argc>2)?argv[2]:"data/420.polylines.txt"; const std::string lines_fname = (argc>2)?argv[2]:CGAL::data_file_path("images/420.polylines.txt");
if(!add_1D_features(image, domain, lines_fname)) { if(!add_1D_features(image, domain, lines_fname)) {
return EXIT_FAILURE; return EXIT_FAILURE;

View File

@ -0,0 +1,67 @@
#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/Mesh_3/generate_label_weights.h>
#include <CGAL/make_mesh_3.h>
#include <CGAL/Image_3.h>
#include <CGAL/IO/File_binary_mesh_3.h>
#include <CGAL/tags.h>
// Domain
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
using Mesh_domain = CGAL::Labeled_mesh_domain_3<K>;
// Triangulation
using Tr = CGAL::Mesh_triangulation_3<Mesh_domain,
CGAL::Default,
CGAL::Parallel_if_available_tag>::type;
using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3<Tr>;
// Criteria
using Mesh_criteria = CGAL::Mesh_criteria_3<Tr>;
// To avoid verbose function and named parameters call
using namespace CGAL::parameters;
int main(int argc, char* argv[])
{
/// [Loads image]
const std::string fname = (argc > 1) ? argv[1] : CGAL::data_file_path("images/liver.inr.gz");
CGAL::Image_3 image;
if(!image.read(fname)){
std::cerr << "Error: Cannot read file " << fname << std::endl;
return EXIT_FAILURE;
}
/// [Loads image]
/// [Domain creation]
const float sigma = 10.f;
CGAL::Image_3 img_weights =
CGAL::Mesh_3::generate_label_weights(image, sigma);
Mesh_domain domain
= Mesh_domain::create_labeled_image_mesh_domain(image,
weights = img_weights,
relative_error_bound = 1e-6);
/// [Domain creation]
// Mesh criteria
Mesh_criteria criteria(facet_angle=30, facet_size=6, facet_distance=0.5,
cell_radius_edge_ratio=3, cell_size=8);
/// [Meshing]
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria);
/// [Meshing]
// Output
std::ofstream medit_file("out.mesh");
c3t3.output_to_medit(medit_file);
std::ofstream bin_file("out.binary.cgal", std::ios_base::binary);
CGAL::IO::save_binary_file(bin_file, c3t3);
return 0;
}

View File

@ -31,7 +31,7 @@ using namespace CGAL::parameters;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
const char* fname = (argc>1)?argv[1]:"data/liver.inr.gz"; const std::string fname = (argc>1)?argv[1]:CGAL::data_file_path("images/liver.inr.gz");
// Domain // Domain
CGAL::Image_3 image; CGAL::Image_3 image;
if(!image.read(fname)){ if(!image.read(fname)){

Some files were not shown because too many files have changed in this diff Show More