mirror of https://github.com/CGAL/cgal
Merge remote-tracking branch 'origin/master' into Region_growing-revision-danston
This commit is contained in:
commit
930278ec50
|
|
@ -6,7 +6,7 @@ jobs:
|
|||
cmake-testsuite:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: install dependencies
|
||||
|
|
@ -15,7 +15,7 @@ jobs:
|
|||
run: |
|
||||
set -e
|
||||
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:
|
||||
|
||||
|
|
@ -29,4 +29,4 @@ jobs:
|
|||
run: |
|
||||
set -e
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ namespace CGAL
|
|||
typedef boost::readable_property_map_tag category;
|
||||
|
||||
inline friend
|
||||
reference
|
||||
get(Tet_from_cell_iterator_proprety_map<GeomTraits, Iterator>, key_type it)
|
||||
value_type
|
||||
get(Tet_from_cell_iterator_proprety_map<GeomTraits, Iterator>, key_type it)
|
||||
{
|
||||
typename GeomTraits::Construct_point_3 point;
|
||||
return value_type(point(it->vertex(0)->point()),
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ point.
|
|||
\cgalRefines `ArrangementBasicTraits_2`
|
||||
|
||||
\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_non_caching_segment_traits_2<Kernel>`
|
||||
\cgalHasModel `CGAL::Arr_segment_traits_2<Kernel>`
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
* \cgalRefines `ArrangementBasicTraits_2`
|
||||
*
|
||||
* \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_non_caching_segment_traits_2<Kernel>`
|
||||
* \cgalHasModel `CGAL::Arr_segment_traits_2<Kernel>`
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
* `ArrangementConstructXMonotoneCurveTraits_2`
|
||||
*
|
||||
* \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_non_caching_segment_traits_2<Kernel>`
|
||||
* \cgalHasModel `CGAL::Arr_segment_traits_2<Kernel>`
|
||||
|
|
|
|||
|
|
@ -58,8 +58,11 @@ int main() {
|
|||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
x1 = theRandom.get_int(random_min,random_max);
|
||||
y1 = theRandom.get_int(random_min,random_max);
|
||||
do{
|
||||
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 =
|
||||
Circle_2( Point_2(x1,y1), x1*x1 + y1*y1);
|
||||
ac.push_back(v);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
// A property map that reads/writes the information to/from the extended
|
||||
// face.
|
||||
template <typename Arrangement, class Type> class Extended_face_property_map {
|
||||
template <typename Arrangement, class Type>
|
||||
class Extended_face_property_map {
|
||||
public:
|
||||
typedef typename Arrangement::Face_handle Face_handle;
|
||||
|
||||
|
|
@ -32,8 +33,7 @@ public:
|
|||
{ return key->data(); }
|
||||
|
||||
// The put function is required by the property map concept.
|
||||
friend void put(const Extended_face_property_map&,
|
||||
key_type key, value_type val)
|
||||
friend void put(const Extended_face_property_map&, key_type key, value_type val)
|
||||
{ key->set_data(val); }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ struct Dual_vertex_index_pmap{
|
|||
typedef typename boost::graph_traits<G>::face_descriptor key_type;
|
||||
typedef typename Property_map::value_type value_type;
|
||||
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)
|
||||
: 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 Property_map::value_type value_type;
|
||||
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)
|
||||
: m_pmap( get(boost::vertex_index, g) )
|
||||
|
|
|
|||
|
|
@ -727,7 +727,7 @@ struct Graph_with_descriptor_with_graph_property_map {
|
|||
template <typename Descriptor>
|
||||
friend
|
||||
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(d.graph == gpm.graph);
|
||||
|
|
@ -747,9 +747,9 @@ struct Graph_with_descriptor_with_graph_property_map<Graph, PM, boost::lvalue_pr
|
|||
Graph* graph;
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -12,11 +12,14 @@
|
|||
#ifndef 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>
|
||||
#endif
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#define CGAL_BGL_NP_TEMPLATE_PARAMETERS T, typename Tag, typename 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
|
||||
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) );
|
||||
#endif
|
||||
return get_parameter_impl(static_cast<const typename Base::base&>(np), tag);
|
||||
}
|
||||
|
||||
|
|
@ -359,6 +364,7 @@ bool is_default_parameter(const T&)
|
|||
|
||||
} //namespace CGAL
|
||||
|
||||
#ifndef CGAL_NO_STATIC_ASSERTION_TESTS
|
||||
// code added to avoid silent runtime issues in non-updated code
|
||||
namespace boost
|
||||
{
|
||||
|
|
@ -368,5 +374,6 @@ namespace boost
|
|||
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
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ struct Alpha_expansion_old_API_wrapper_graph
|
|||
: 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;
|
||||
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]);
|
||||
return out;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef CGAL::Pointer_property_map<double>::const_type Edge_cost_map;
|
||||
|
|
|
|||
|
|
@ -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 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:
|
||||
|
|
@ -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 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&) { }
|
||||
};
|
||||
|
||||
|
|
@ -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 DummyPlaneIndexMap Self;
|
||||
friend reference get(const Self&, const key_type&) { return -1; }
|
||||
friend value_type get(const Self&, const key_type&) { return -1; }
|
||||
};
|
||||
|
||||
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 DummyConstrainedMap Self;
|
||||
friend reference get(const Self&, const key_type&) { return false; }
|
||||
friend value_type get(const Self&, const key_type&) { return false; }
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ CGAL_add_named_parameter(pca_plane_t, pca_plane, pca_plane)
|
|||
|
||||
// tetrahedral remeshing parameters
|
||||
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(smooth_constrained_edges_t, smooth_constrained_edges, smooth_constrained_edges)
|
||||
|
||||
|
|
|
|||
|
|
@ -105,14 +105,15 @@ struct Index_accessor
|
|||
|
||||
template<typename Handle>
|
||||
struct Edge_index_accessor
|
||||
: boost::put_get_helper< std::size_t, Edge_index_accessor<Handle> >
|
||||
{
|
||||
typedef boost::readable_property_map_tag category;
|
||||
typedef std::size_t reference;
|
||||
typedef std::size_t value_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,
|
||||
|
|
@ -135,7 +136,7 @@ struct 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 ConstReference reference;
|
||||
typedef ConstReference reference;
|
||||
typedef ValueType value_type;
|
||||
typedef Handle key_type;
|
||||
|
||||
|
|
@ -160,10 +161,11 @@ struct Is_writable_property_map<PropertyMap, boost::writable_property_map_tag> :
|
|||
template <typename PropertyMap>
|
||||
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,
|
||||
// but boost::lvalue_property_map_tag is defined as:
|
||||
// 'lvalue_property_map_tag' is annoying, because the property map is allowed to be non-mutable,
|
||||
// but boost::lvalue_property_map_tag is always defined as:
|
||||
// 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
|
||||
// a non-const reference doesn't mean that 'put(map, key, val)' exists, which is what a writable
|
||||
|
|
|
|||
|
|
@ -37,11 +37,10 @@ public:
|
|||
OpenMesh::HPropHandleT<Value>,
|
||||
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 Value value_type;
|
||||
|
||||
typedef value_type& reference;
|
||||
|
||||
OM_pmap()
|
||||
|
|
@ -66,19 +65,19 @@ public:
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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());
|
||||
return pm.mesh->property(pm.h,eh);
|
||||
|
|
@ -133,7 +132,6 @@ public:
|
|||
|
||||
template <typename OpenMesh>
|
||||
class OM_edge_weight_pmap
|
||||
: public boost::put_get_helper<typename OpenMesh::Scalar , OM_edge_weight_pmap<OpenMesh> >
|
||||
{
|
||||
public:
|
||||
typedef boost::readable_property_map_tag category;
|
||||
|
|
@ -150,17 +148,19 @@ public:
|
|||
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:
|
||||
const OpenMesh& sm_;
|
||||
};
|
||||
|
||||
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:
|
||||
typedef boost::readable_property_map_tag category;
|
||||
typedef unsigned int value_type;
|
||||
typedef unsigned int reference;
|
||||
typedef unsigned int value_type;
|
||||
typedef unsigned int reference;
|
||||
typedef VEF key_type;
|
||||
|
||||
OM_index_pmap()
|
||||
|
|
@ -170,18 +170,21 @@ public:
|
|||
{
|
||||
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>
|
||||
class OM_point_pmap //: public boost::put_get_helper<bool, OM_point_pmap<OpenMesh> >
|
||||
class OM_point_pmap
|
||||
{
|
||||
public:
|
||||
typedef boost::read_write_property_map_tag category;
|
||||
#if defined(CGAL_USE_OM_POINTS)
|
||||
typedef boost::lvalue_property_map_tag category;
|
||||
typedef typename OpenMesh::Point value_type;
|
||||
typedef const typename OpenMesh::Point& reference;
|
||||
#else
|
||||
typedef boost::read_write_property_map_tag category;
|
||||
typedef P value_type;
|
||||
typedef P reference;
|
||||
#endif
|
||||
|
|
@ -199,7 +202,7 @@ public:
|
|||
: sm_(pm.sm_)
|
||||
{}
|
||||
|
||||
value_type operator[](key_type v)
|
||||
reference operator[](key_type v)
|
||||
{
|
||||
#if defined(CGAL_USE_OM_POINTS)
|
||||
return sm_->point(v);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ struct Triangle_from_face_descriptor_map{
|
|||
|
||||
//get function for property map
|
||||
inline friend
|
||||
reference
|
||||
value_type
|
||||
get(const Triangle_from_face_descriptor_map<TriangleMesh,VertexPointMap>& pmap,
|
||||
key_type f)
|
||||
{
|
||||
|
|
@ -66,7 +66,7 @@ struct Triangle_from_face_descriptor_map{
|
|||
}
|
||||
|
||||
inline friend
|
||||
reference
|
||||
value_type
|
||||
get(const Triangle_from_face_descriptor_map<TriangleMesh,VertexPointMap>& pmap,
|
||||
const std::pair<key_type, const TriangleMesh*>& f)
|
||||
{
|
||||
|
|
@ -111,7 +111,7 @@ struct Segment_from_edge_descriptor_map{
|
|||
|
||||
//get function for property map
|
||||
inline friend
|
||||
reference
|
||||
value_type
|
||||
get(const Segment_from_edge_descriptor_map<PolygonMesh,VertexPointMap>& pmap,
|
||||
key_type h)
|
||||
{
|
||||
|
|
@ -120,7 +120,7 @@ struct Segment_from_edge_descriptor_map{
|
|||
}
|
||||
|
||||
inline friend
|
||||
reference
|
||||
value_type
|
||||
get(const Segment_from_edge_descriptor_map<PolygonMesh,VertexPointMap>& pmap,
|
||||
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::property_traits< VertexPointMap >::value_type value_type;
|
||||
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
|
||||
inline friend
|
||||
|
|
@ -196,6 +196,7 @@ struct Source_point_from_edge_descriptor_map{
|
|||
typedef typename boost::property_traits< VertexPointMap >::reference reference;
|
||||
typedef typename boost::graph_traits<PolygonMesh>::edge_descriptor key_type;
|
||||
typedef boost::readable_property_map_tag category;
|
||||
|
||||
//data
|
||||
typename boost::remove_const<PolygonMesh>::type* m_pm;
|
||||
VertexPointMap m_vpm;
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ struct Regularization_graph
|
|||
typedef vertex_descriptor key_type;
|
||||
typedef std::size_t value_type;
|
||||
typedef std::size_t& reference;
|
||||
typedef boost::lvalue_property_map_tag category;
|
||||
typedef boost::read_write_property_map_tag category;
|
||||
|
||||
Regularization_graph* rg;
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ struct Regularization_graph
|
|||
: 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;
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ struct Regularization_graph
|
|||
Edge_cost_map (const Regularization_graph* 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 etarget = target(ed, pmap.rg->fg);
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ BOOST_PARAMETER_NAME( (pointer_to_stop_atomic_boolean, tag ) pointer_to_stop_ato
|
|||
BOOST_PARAMETER_NAME( (function, tag ) function_)
|
||||
BOOST_PARAMETER_NAME( (bounding_object, tag ) bounding_object_)
|
||||
BOOST_PARAMETER_NAME( (relative_error_bound, tag ) relative_error_bound_)
|
||||
BOOST_PARAMETER_NAME( (weights, tag) weights_)
|
||||
BOOST_PARAMETER_NAME( (p_rng, tag ) p_rng_)
|
||||
BOOST_PARAMETER_NAME( (null_subdomain_index, tag ) null_subdomain_index_)
|
||||
BOOST_PARAMETER_NAME( (construct_surface_patch_index, tag ) construct_surface_patch_index_)
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ test_graph_range(const std::vector<Graph>& graphs)
|
|||
typedef SM::Point Point_3;
|
||||
|
||||
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 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 edge_descriptor key_type;
|
||||
|
||||
|
||||
Constraint()
|
||||
:g_(NULL)
|
||||
{}
|
||||
|
|
@ -406,9 +405,12 @@ struct Constraint : public boost::put_get_helper<bool,Constraint<Mesh, VertexPoi
|
|||
return false;
|
||||
}
|
||||
|
||||
friend inline value_type get(const Constraint& m, const key_type k) { return m[k]; }
|
||||
|
||||
const Mesh* g_;
|
||||
VertexPointPMap vppmap;
|
||||
};
|
||||
|
||||
template<class Mesh, class FCCMAP, class Adapter>
|
||||
void test_mesh(Adapter fga)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ struct Non_mutable_property_map
|
|||
{
|
||||
typedef Key key_type;
|
||||
typedef Value value_type;
|
||||
typedef value_type reference;
|
||||
typedef const value_type& reference;
|
||||
typedef boost::readable_property_map_tag category;
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@ struct RW_property_map
|
|||
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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -6,6 +6,14 @@
|
|||
/// The namespace containing concepts specific to 2D Boolean Set Operations.
|
||||
namespace ArrDirectionalTraits {}
|
||||
|
||||
/*!
|
||||
\code
|
||||
#include <CGAL/draw_polygon_set_2.h>
|
||||
\endcode
|
||||
*/
|
||||
/// \defgroup PkgDrawPolygonSet2 Draw a 2D Polygon Set
|
||||
/// \ingroup PkgBooleanSetOperations2Ref
|
||||
|
||||
/*!
|
||||
\addtogroup PkgBooleanSetOperations2Ref
|
||||
\todo check generated documentation
|
||||
|
|
@ -62,4 +70,7 @@ containment predicates.
|
|||
- \link boolean_oriented_side `CGAL::oriented_side()` \endlink
|
||||
- \link boolean_connect_holes `CGAL::connect_holes()` \endlink
|
||||
|
||||
\cgalCRPSection{Draw a Polygon_set_2}
|
||||
- \link PkgDrawPolygonSet2 CGAL::draw<PS>() \endlink
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
\example Boolean_set_operations_2/conic_traits_adapter.cpp
|
||||
\example Boolean_set_operations_2/connect_polygon.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/sequence.cpp
|
||||
\example Boolean_set_operations_2/set_union.cpp
|
||||
|
|
|
|||
|
|
@ -4,9 +4,7 @@
|
|||
cmake_minimum_required(VERSION 3.1...3.20)
|
||||
project(Boolean_set_operations_2_Examples)
|
||||
|
||||
find_package(CGAL REQUIRED COMPONENTS Core)
|
||||
|
||||
include(${CGAL_USE_FILE})
|
||||
find_package(CGAL REQUIRED COMPONENTS Core OPTIONAL_COMPONENTS Qt5)
|
||||
|
||||
# create a target per cppfile
|
||||
file(
|
||||
|
|
@ -16,3 +14,12 @@ file(
|
|||
foreach(cppfile ${cppfiles})
|
||||
create_single_source_cgal_program("${cppfile}")
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -8,6 +8,7 @@ Circulator
|
|||
Distance_2
|
||||
Distance_3
|
||||
Filtered_kernel
|
||||
GraphicsView
|
||||
HalfedgeDS
|
||||
Hash_map
|
||||
Homogeneous_kernel
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include <limits>
|
||||
#include <set>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
|
|
@ -102,7 +103,7 @@ public:
|
|||
// 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);
|
||||
}
|
||||
|
|
@ -146,9 +147,9 @@ public:
|
|||
double vy() const { return image_ptr->vy; }
|
||||
double vz() const { return image_ptr->vz; }
|
||||
|
||||
double tx() const { return image_ptr->tx; }
|
||||
double ty() const { return image_ptr->ty; }
|
||||
double tz() const { return image_ptr->tz; }
|
||||
float tx() const { return image_ptr->tx; }
|
||||
float ty() const { return image_ptr->ty; }
|
||||
float tz() const { return image_ptr->tz; }
|
||||
|
||||
float value(const std::size_t i,
|
||||
const std::size_t j,
|
||||
|
|
@ -157,6 +158,11 @@ public:
|
|||
return ::evaluate(image(),i,j,k);
|
||||
}
|
||||
|
||||
bool is_valid() const
|
||||
{
|
||||
return image_ptr.get() != nullptr;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
bool read(const char* file)
|
||||
|
|
@ -164,6 +170,11 @@ public:
|
|||
return private_read(::_readImage(file));
|
||||
}
|
||||
|
||||
bool read(const std::string& file)
|
||||
{
|
||||
return read(file.c_str());
|
||||
}
|
||||
|
||||
bool read_raw(const char* file,
|
||||
const unsigned int rx,
|
||||
const unsigned int ry,
|
||||
|
|
|
|||
|
|
@ -191,28 +191,12 @@ int main() {
|
|||
image.set_data(nullptr); // trick to avoid ~Image_3 segfault.
|
||||
|
||||
|
||||
const char* filenames[] = {
|
||||
"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"
|
||||
};
|
||||
const std::string filename = CGAL::data_file_path("images/skull_2.9.inr");
|
||||
|
||||
std::size_t file_index = 0;
|
||||
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";
|
||||
std::cerr << "Opening file " << filename << "...\n";
|
||||
|
||||
CGAL::Image_3 image2;
|
||||
const bool result = image2.read(filenames[file_index]);
|
||||
const bool result = image2.read(filename);
|
||||
assert(result);
|
||||
|
||||
std::cerr << "Image info:"
|
||||
|
|
|
|||
|
|
@ -4380,6 +4380,8 @@ namespace CartesianKernelFunctors {
|
|||
typedef typename K::Circle_2 Circle_2;
|
||||
typedef typename K::Line_2 Line_2;
|
||||
typedef typename K::Triangle_2 Triangle_2;
|
||||
typedef typename K::Segment_2 Segment_2;
|
||||
typedef typename K::FT FT;
|
||||
public:
|
||||
typedef typename K::Oriented_side result_type;
|
||||
|
||||
|
|
@ -4416,6 +4418,30 @@ namespace CartesianKernelFunctors {
|
|||
? result_type(ON_ORIENTED_BOUNDARY)
|
||||
: 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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#endif // CGAL_PREDICATES_KERNEL_FTC2_H
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ public:
|
|||
public:
|
||||
using argument_type = std::size_t;
|
||||
using result_type = typename boost::property_traits<ItemMap>::reference;
|
||||
using category = boost::readable_property_map_tag;
|
||||
|
||||
const ItemRange* m_range;
|
||||
ItemMap m_item_map;
|
||||
|
|
|
|||
|
|
@ -67,10 +67,12 @@ class Point_set_neighborhood
|
|||
using value_type = typename boost::property_traits<PointMap>::value_type;
|
||||
using reference = typename boost::property_traits<PointMap>::reference;
|
||||
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 (const PointRange *input, PointMap point_map)
|
||||
: input (input), point_map (point_map) { }
|
||||
|
||||
friend reference get (const My_point_property_map& ppmap, key_type i)
|
||||
{ return get(ppmap.point_map, *(ppmap.input->begin()+std::size_t(i))); }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public:
|
|||
: m_mesh (mesh), m_vpm (vpm) { }
|
||||
|
||||
/// \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;
|
||||
|
||||
|
|
@ -139,7 +139,7 @@ public:
|
|||
: m_mesh (mesh), m_vpm (vpm) { }
|
||||
|
||||
/// \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;
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -3256,6 +3256,12 @@ pages = "207--221"
|
|||
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
|
||||
% ----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -356,6 +356,7 @@ div.summary
|
|||
text-align: left;
|
||||
outline: none;
|
||||
font: 14px Roboto,sans-serif;
|
||||
user-select: auto;
|
||||
}
|
||||
|
||||
.active, .collapsible:hover {
|
||||
|
|
|
|||
|
|
@ -356,6 +356,7 @@ div.summary
|
|||
text-align: left;
|
||||
outline: none;
|
||||
font: 14px Roboto,sans-serif;
|
||||
user-select: auto;
|
||||
}
|
||||
|
||||
.active, .collapsible:hover {
|
||||
|
|
|
|||
|
|
@ -356,6 +356,7 @@ div.summary
|
|||
text-align: left;
|
||||
outline: none;
|
||||
font: 14px Roboto,sans-serif;
|
||||
user-select: auto;
|
||||
}
|
||||
|
||||
.active, .collapsible:hover {
|
||||
|
|
|
|||
|
|
@ -347,6 +347,7 @@ div.summary
|
|||
text-align: left;
|
||||
outline: none;
|
||||
font: 14px Roboto,sans-serif;
|
||||
user-select: auto;
|
||||
}
|
||||
|
||||
.active, .collapsible:hover {
|
||||
|
|
|
|||
|
|
@ -356,6 +356,7 @@ div.summary
|
|||
text-align: left;
|
||||
outline: none;
|
||||
font: 14px Roboto,sans-serif;
|
||||
user-select: auto;
|
||||
}
|
||||
|
||||
.active, .collapsible:hover {
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ class Do_intersect_3
|
|||
typedef typename K_base::Ray_3 Ray_3;
|
||||
typedef typename K_base::Segment_3 Segment_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::Do_intersect_3 Base;
|
||||
|
||||
|
|
@ -126,7 +127,46 @@ public:
|
|||
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
|
||||
operator()(const Bbox_3& b, const Ray_3 &r) const
|
||||
|
|
@ -169,6 +209,396 @@ public:
|
|||
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
|
||||
operator()(const Bbox_3& b, const Sphere_3 &s) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ generate_point() {
|
|||
this->d_item = creator( T( this->d_range), T(d));
|
||||
break;
|
||||
default:
|
||||
CGAL_assume(false);
|
||||
CGAL_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,27 +133,29 @@ namespace boost {
|
|||
public:
|
||||
typedef KeyType key_type;
|
||||
typedef ValueType value_type;
|
||||
typedef const value_type& reference;
|
||||
typedef value_type& reference;
|
||||
typedef lvalue_property_map_tag category;
|
||||
|
||||
associative_property_map() : m_c(0) { }
|
||||
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];
|
||||
}
|
||||
|
||||
friend
|
||||
const value_type&
|
||||
get(const associative_property_map<C>& uhm, const key_type& key)
|
||||
{
|
||||
return uhm[key];
|
||||
}
|
||||
friend
|
||||
reference
|
||||
get(const associative_property_map<C>& uhm, const key_type& key)
|
||||
{
|
||||
return uhm[key];
|
||||
}
|
||||
|
||||
friend
|
||||
void
|
||||
put(associative_property_map<C>& uhm, const key_type& key, const value_type& val)
|
||||
{
|
||||
uhm[key] = val;
|
||||
}
|
||||
friend
|
||||
void
|
||||
put(associative_property_map<C>& uhm, const key_type& key, const value_type& val)
|
||||
{
|
||||
uhm[key] = val;
|
||||
}
|
||||
|
||||
private:
|
||||
C* m_c;
|
||||
|
|
|
|||
|
|
@ -856,7 +856,7 @@ Aff_transformation_repH2<R>::homogeneous(int i, int j) const
|
|||
case 0: return a;
|
||||
case 1: return b;
|
||||
case 2: return c;
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 1: switch (j)
|
||||
|
|
@ -864,7 +864,7 @@ Aff_transformation_repH2<R>::homogeneous(int i, int j) const
|
|||
case 0: return d;
|
||||
case 1: return e;
|
||||
case 2: return f;
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 2: switch (j)
|
||||
|
|
@ -872,10 +872,10 @@ Aff_transformation_repH2<R>::homogeneous(int i, int j) const
|
|||
case 0: return RT(0);
|
||||
case 1: return RT(0);
|
||||
case 2: return g;
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
}
|
||||
CGAL_assume(false);
|
||||
CGAL_unreachable();
|
||||
return RT(0);
|
||||
}
|
||||
|
||||
|
|
@ -900,7 +900,7 @@ Translation_repH2<R>::homogeneous(int i, int j) const
|
|||
case 0: return _tv.hw();
|
||||
case 1: return RT(0);
|
||||
case 2: return _tv.hx();
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 1: switch (j)
|
||||
|
|
@ -908,7 +908,7 @@ Translation_repH2<R>::homogeneous(int i, int j) const
|
|||
case 0: return RT(0);
|
||||
case 1: return _tv.hw();
|
||||
case 2: return _tv.hy();
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 2: switch (j)
|
||||
|
|
@ -916,10 +916,10 @@ Translation_repH2<R>::homogeneous(int i, int j) const
|
|||
case 0: return RT(0);
|
||||
case 1: return RT(0);
|
||||
case 2: return _tv.hw();
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
}
|
||||
CGAL_assume(false);
|
||||
CGAL_unreachable();
|
||||
return RT(0);
|
||||
}
|
||||
|
||||
|
|
@ -935,7 +935,7 @@ Translation_repH2<R>::cartesian(int i, int j) const
|
|||
case 0: return FT(1);
|
||||
case 1: return FT(0);
|
||||
case 2: return _tv.x();
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 1: switch (j)
|
||||
|
|
@ -943,7 +943,7 @@ Translation_repH2<R>::cartesian(int i, int j) const
|
|||
case 0: return FT(0);
|
||||
case 1: return FT(1);
|
||||
case 2: return _tv.y();
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 2: switch (j)
|
||||
|
|
@ -951,10 +951,10 @@ Translation_repH2<R>::cartesian(int i, int j) const
|
|||
case 0: return FT(0);
|
||||
case 1: return FT(0);
|
||||
case 2: return FT(1);
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
}
|
||||
CGAL_assume(false);
|
||||
CGAL_unreachable();
|
||||
return FT(0);
|
||||
}
|
||||
|
||||
|
|
@ -971,7 +971,7 @@ homogeneous(int i, int j) const
|
|||
case 0: return _cos;
|
||||
case 1: return - _sin;
|
||||
case 2: return RT(0);
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 1: switch (j)
|
||||
|
|
@ -979,7 +979,7 @@ homogeneous(int i, int j) const
|
|||
case 0: return _sin;
|
||||
case 1: return _cos;
|
||||
case 2: return RT(0);
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 2: switch (j)
|
||||
|
|
@ -987,10 +987,10 @@ homogeneous(int i, int j) const
|
|||
case 0: return RT(0);
|
||||
case 1: return RT(0);
|
||||
case 2: return _den;
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
}
|
||||
CGAL_assume(false);
|
||||
CGAL_unreachable();
|
||||
return RT(0);
|
||||
}
|
||||
|
||||
|
|
@ -1007,7 +1007,7 @@ cartesian(int i, int j) const
|
|||
case 0: return FT(_cos) / FT(_den);
|
||||
case 1: return - FT(_sin) / FT(_den);
|
||||
case 2: return FT(0);
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 1: switch (j)
|
||||
|
|
@ -1015,7 +1015,7 @@ cartesian(int i, int j) const
|
|||
case 0: return FT(_sin) / FT(_den);
|
||||
case 1: return FT(_cos) / FT(_den);
|
||||
case 2: return FT(0);
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 2: switch (j)
|
||||
|
|
@ -1023,10 +1023,10 @@ cartesian(int i, int j) const
|
|||
case 0: return FT(0);
|
||||
case 1: return FT(0);
|
||||
case 2: return FT(1);
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
}
|
||||
CGAL_assume(false);
|
||||
CGAL_unreachable();
|
||||
return FT(0);
|
||||
}
|
||||
|
||||
|
|
@ -1043,7 +1043,7 @@ homogeneous(int i, int j) const
|
|||
case 0: return _sf_num;
|
||||
case 1: return RT(0);
|
||||
case 2: return RT(0);
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 1: switch (j)
|
||||
|
|
@ -1051,7 +1051,7 @@ homogeneous(int i, int j) const
|
|||
case 0: return RT(0);
|
||||
case 1: return _sf_num;
|
||||
case 2: return RT(0);
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 2: switch (j)
|
||||
|
|
@ -1059,10 +1059,10 @@ homogeneous(int i, int j) const
|
|||
case 0: return RT(0);
|
||||
case 1: return RT(0);
|
||||
case 2: return _sf_den;
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
}
|
||||
CGAL_assume(false);
|
||||
CGAL_unreachable();
|
||||
return RT(0);
|
||||
}
|
||||
|
||||
|
|
@ -1079,7 +1079,7 @@ cartesian(int i, int j) const
|
|||
case 0: return FT(_sf_num) / FT(_sf_den);
|
||||
case 1: return FT(0);
|
||||
case 2: return FT(0);
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 1: switch (j)
|
||||
|
|
@ -1087,7 +1087,7 @@ cartesian(int i, int j) const
|
|||
case 0: return FT(0);
|
||||
case 1: return FT(_sf_num) / FT(_sf_den);
|
||||
case 2: return FT(0);
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 2: switch (j)
|
||||
|
|
@ -1095,10 +1095,10 @@ cartesian(int i, int j) const
|
|||
case 0: return FT(0);
|
||||
case 1: return FT(0);
|
||||
case 2: return FT(1);
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
}
|
||||
CGAL_assume(false);
|
||||
CGAL_unreachable();
|
||||
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 1: return l.a()*l.b()*mRT2;
|
||||
case 2: return l.a()*l.c()*mRT2;
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 1: switch (j)
|
||||
|
|
@ -1124,7 +1124,7 @@ homogeneous(int i, int j) const
|
|||
case 0: return l.a()*l.b()*mRT2;
|
||||
case 1: return l.a()*l.a() - l.b()*l.b();
|
||||
case 2: return l.b()*l.c()*mRT2;
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 2: switch (j)
|
||||
|
|
@ -1132,10 +1132,10 @@ homogeneous(int i, int j) const
|
|||
case 0: return RT(0);
|
||||
case 1: return RT(0);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -1153,7 +1153,7 @@ cartesian(int i, int j) const
|
|||
case 0: return FT( l.b()-l.a() ) / FT( l.a()+l.b());
|
||||
case 1: return FT( homogeneous(0,1)) / de;
|
||||
case 2: return FT( homogeneous(0,2)) / de;
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 1: switch (j)
|
||||
|
|
@ -1161,7 +1161,7 @@ cartesian(int i, int j) const
|
|||
case 0: return FT( homogeneous(1,0)) / de;
|
||||
case 1: return FT( l.a()-l.b() ) / FT( l.a()+l.b());
|
||||
case 2: return FT( homogeneous(1,2)) / de;
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 2: switch (j)
|
||||
|
|
@ -1169,10 +1169,10 @@ cartesian(int i, int j) const
|
|||
case 0: return FT(0);
|
||||
case 1: return FT(0);
|
||||
case 2: return FT(1);
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
}
|
||||
CGAL_assume(false);
|
||||
CGAL_unreachable();
|
||||
return FT(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -706,7 +706,7 @@ homogeneous(int i, int j) const
|
|||
case 1: return t01;
|
||||
case 2: return t02;
|
||||
case 3: return t03;
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 1: switch (j)
|
||||
|
|
@ -715,7 +715,7 @@ homogeneous(int i, int j) const
|
|||
case 1: return t11;
|
||||
case 2: return t12;
|
||||
case 3: return t13;
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 2: switch (j)
|
||||
|
|
@ -724,7 +724,7 @@ homogeneous(int i, int j) const
|
|||
case 1: return t21;
|
||||
case 2: return t22;
|
||||
case 3: return t23;
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 3: switch (j)
|
||||
|
|
@ -733,10 +733,10 @@ homogeneous(int i, int j) const
|
|||
case 1: return RT0;
|
||||
case 2: return RT0;
|
||||
case 3: return t33;
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
}
|
||||
CGAL_assume(false);
|
||||
CGAL_unreachable();
|
||||
return RT0;
|
||||
}
|
||||
|
||||
|
|
@ -864,7 +864,7 @@ Translation_repH3<R>::homogeneous(int i, int j) const
|
|||
case 1: return RT0;
|
||||
case 2: return RT0;
|
||||
case 3: return tv.hx();
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 1: switch (j)
|
||||
|
|
@ -873,7 +873,7 @@ Translation_repH3<R>::homogeneous(int i, int j) const
|
|||
case 1: return tv.hw();
|
||||
case 2: return RT0;
|
||||
case 3: return tv.hy();
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 2: switch (j)
|
||||
|
|
@ -882,7 +882,7 @@ Translation_repH3<R>::homogeneous(int i, int j) const
|
|||
case 1: return RT0;
|
||||
case 2: return tv.hw();
|
||||
case 3: return tv.hz();
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
break;
|
||||
case 3: switch (j)
|
||||
|
|
@ -891,10 +891,10 @@ Translation_repH3<R>::homogeneous(int i, int j) const
|
|||
case 1: return RT0;
|
||||
case 2: return RT0;
|
||||
case 3: return tv.hw();
|
||||
default: CGAL_assume(false);
|
||||
default: CGAL_unreachable();
|
||||
}
|
||||
}
|
||||
CGAL_assume(false);
|
||||
CGAL_unreachable();
|
||||
return RT0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4683,6 +4683,7 @@ namespace HomogeneousKernelFunctors {
|
|||
typedef typename K::Circle_2 Circle_2;
|
||||
typedef typename K::Line_2 Line_2;
|
||||
typedef typename K::Triangle_2 Triangle_2;
|
||||
typedef typename K::Segment_2 Segment_2;
|
||||
public:
|
||||
typedef typename K::Oriented_side result_type;
|
||||
|
||||
|
|
@ -4722,6 +4723,41 @@ namespace HomogeneousKernelFunctors {
|
|||
? ON_ORIENTED_BOUNDARY
|
||||
: -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,15 @@ Release History
|
|||
-----------
|
||||
|
||||
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)
|
||||
|
||||
|
|
@ -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.
|
||||
|
||||
- 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)
|
||||
|
||||
- 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.
|
||||
|
||||
|
||||
|
||||
### [Point Set Processing](https://doc.cgal.org/5.4/Manual/packages.html#PkgPointSetProcessing3)
|
||||
|
||||
- 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))
|
||||
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)
|
||||
-----------
|
||||
|
|
|
|||
|
|
@ -200,11 +200,21 @@ endif()
|
|||
set(CGAL_DATA_DIR "@CGAL_DATA_DIR@")
|
||||
|
||||
if(NOT TARGET CGAL::Data)
|
||||
add_library(CGAL::Data INTERFACE IMPORTED)
|
||||
add_library(CGAL::Data INTERFACE IMPORTED GLOBAL)
|
||||
if ( NOT "${CGAL_DATA_DIR}" STREQUAL "" )
|
||||
set_target_properties(CGAL::Data PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS "CGAL_DATA_DIR=\"${CGAL_DATA_DIR}\"")
|
||||
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")
|
||||
|
|
|
|||
|
|
@ -184,11 +184,21 @@ endif()
|
|||
set(CGAL_DATA_DIR "@CGAL_DATA_DIR@")
|
||||
|
||||
if(NOT TARGET CGAL::Data)
|
||||
add_library(CGAL::Data INTERFACE IMPORTED)
|
||||
add_library(CGAL::Data INTERFACE IMPORTED GLOBAL)
|
||||
if ( NOT "${CGAL_DATA_DIR}" STREQUAL "" )
|
||||
set_target_properties(CGAL::Data PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS "CGAL_DATA_DIR=\"${CGAL_DATA_DIR}\"")
|
||||
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")
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
@ -41,7 +41,7 @@ set(list_of_whitelisted_headers_txt [=[
|
|||
CGAL/IO/Triangulation_geomview_ostream_3.h
|
||||
CGAL/IO/Triangulation_geomview_ostream_2.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})
|
||||
|
|
|
|||
|
|
@ -369,15 +369,17 @@ using std::max;
|
|||
# define CGAL_NO_UNIQUE_ADDRESS
|
||||
#endif
|
||||
|
||||
// Macro CGAL_ASSUME
|
||||
// Macro CGAL_ASSUME and CGAL_UNREACHABLE
|
||||
// Call a builtin of the compiler to pass a hint to the compiler
|
||||
#if __has_builtin(__builtin_unreachable) || (CGAL_GCC_VERSION > 0 && !__STRICT_ANSI__)
|
||||
// From g++ 4.5, there exists a __builtin_unreachable()
|
||||
// Also in LLVM/clang
|
||||
# define CGAL_ASSUME(EX) if(!(EX)) { __builtin_unreachable(); }
|
||||
# define CGAL_UNREACHABLE() __builtin_unreachable()
|
||||
#elif defined(_MSC_VER)
|
||||
// MSVC has __assume
|
||||
# define CGAL_ASSUME(EX) __assume(EX)
|
||||
# define CGAL_UNREACHABLE() __assume(0)
|
||||
#endif
|
||||
// If CGAL_ASSUME is not defined, then CGAL_assume and CGAL_assume_code are
|
||||
// defined differently, in <CGAL/assertions.h>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -97,4 +97,3 @@ Triangulation dD Triangulations
|
|||
Visibility_2 2D Visibility Computation
|
||||
Voronoi_diagram_2 2D Voronoi Diagram Adaptor
|
||||
Tetrahedral_remeshing Tetrahedral Remeshing
|
||||
Weights Weights
|
||||
|
|
|
|||
|
|
@ -77,11 +77,11 @@ if (NOT CGAL_DATA_DIR)
|
|||
if(DEFINED ENV{CGAL_DATA_DIR})
|
||||
set(CGAL_DATA_DIR $ENV{CGAL_DATA_DIR})
|
||||
else()
|
||||
if (EXISTS "${CGAL_ROOT}/data")
|
||||
set(CGAL_DATA_DIR "${CGAL_ROOT}/data")
|
||||
if (EXISTS "${CGAL_ROOT}/Data/data")
|
||||
set(CGAL_DATA_DIR "${CGAL_ROOT}/Data/data")
|
||||
else()
|
||||
if (EXISTS "${CGAL_ROOT}/Data/data")
|
||||
set(CGAL_DATA_DIR "${CGAL_ROOT}/Data/data")
|
||||
if (EXISTS "${CGAL_ROOT}/data")
|
||||
set(CGAL_DATA_DIR "${CGAL_ROOT}/data")
|
||||
else()
|
||||
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()")
|
||||
|
|
@ -91,7 +91,7 @@ if (NOT CGAL_DATA_DIR)
|
|||
endif()
|
||||
|
||||
if(NOT TARGET CGAL::Data)
|
||||
add_library(CGAL::Data INTERFACE IMPORTED)
|
||||
add_library(CGAL::Data INTERFACE IMPORTED GLOBAL)
|
||||
if ( NOT "${CGAL_DATA_DIR}" STREQUAL "" )
|
||||
set_target_properties(CGAL::Data PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS "CGAL_DATA_DIR=\"${CGAL_DATA_DIR}\"")
|
||||
|
|
@ -164,6 +164,16 @@ foreach(cgal_lib ${CGAL_LIBRARIES})
|
|||
endif()
|
||||
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)
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ endif()
|
|||
find_package(TBB QUIET)
|
||||
include(CGAL_TBB_support)
|
||||
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)
|
||||
endif()
|
||||
|
||||
|
|
|
|||
|
|
@ -50,8 +50,13 @@ struct Value_function
|
|||
|
||||
template <typename V, typename G>
|
||||
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 std::pair<G, bool> result_type;
|
||||
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ Segment_2_Line_2_pair<K>::intersection_type() const
|
|||
_result = SEGMENT;
|
||||
break;
|
||||
default:
|
||||
CGAL_assume(false);
|
||||
CGAL_unreachable();
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,48 +34,267 @@ namespace Intersections {
|
|||
|
||||
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>
|
||||
inline bool
|
||||
inline S2S2_inter_info
|
||||
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>
|
||||
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)
|
||||
S2S2_inter_info
|
||||
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,
|
||||
int /* i1 */, int i2, int i3, int /* i4 */,
|
||||
const K& k, bool extra_test)
|
||||
{
|
||||
switch (make_certain(k.orientation_2_object()(p1,p2,p3))) {
|
||||
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:
|
||||
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:
|
||||
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);
|
||||
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>
|
||||
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)
|
||||
S2S2_inter_info
|
||||
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,
|
||||
int /* i1 */, int /* i2 */, int i3, int i4,
|
||||
const K& k, bool extra_test)
|
||||
{
|
||||
switch (make_certain(k.orientation_2_object()(p1,p2,p3))) {
|
||||
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:
|
||||
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:
|
||||
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);
|
||||
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 K& k)
|
||||
{
|
||||
typename K::Point_2 const & A1 = seg1.source();
|
||||
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;
|
||||
return do_intersect_with_info(seg1, seg2, k, false).inter;
|
||||
}
|
||||
|
||||
|
||||
template <class K>
|
||||
class Segment_2_Segment_2_pair {
|
||||
public:
|
||||
|
|
@ -294,110 +330,52 @@ template <class K>
|
|||
typename Segment_2_Segment_2_pair<K>::Intersection_results
|
||||
Segment_2_Segment_2_pair<K>::intersection_type() const
|
||||
{
|
||||
typename K::Construct_vector_2 construct_vector;
|
||||
if (_result!=UNKNOWN)
|
||||
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;
|
||||
return _result;
|
||||
}
|
||||
typename K::Line_2 const &l1 = _seg1->supporting_line();
|
||||
typename K::Line_2 const &l2 = _seg2->supporting_line();
|
||||
Line_2_Line_2_pair<K> linepair(&l1, &l2);
|
||||
switch ( linepair.intersection_type()) {
|
||||
case Line_2_Line_2_pair<K>::NO_INTERSECTION:
|
||||
default:
|
||||
_result = NO_INTERSECTION;
|
||||
break;
|
||||
case Line_2_Line_2_pair<K>::POINT:
|
||||
_intersection_point = linepair.intersection_point();
|
||||
_result = POINT;
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// check if intersection is a segment
|
||||
if (inter_info.dim==1)
|
||||
{
|
||||
_result=SEGMENT;
|
||||
_intersection_point = (inter_info.pt_ids[0]>1)
|
||||
? _seg2->point(inter_info.pt_ids[0]-2)
|
||||
: _seg1->point(inter_info.pt_ids[0]);
|
||||
_other_point = inter_info.pt_ids[1]>1
|
||||
? _seg2->point(inter_info.pt_ids[1]-2)
|
||||
: _seg1->point(inter_info.pt_ids[1]);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(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)));
|
||||
|
||||
// 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()
|
||||
|
|
|
|||
|
|
@ -16,12 +16,15 @@
|
|||
|
||||
// Fast Triangle-Cuboid intersection test, following Tomas Akenine-Moeller description.
|
||||
// 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/Bbox_3.h>
|
||||
#include <CGAL/Uncertain.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
|
||||
namespace CGAL {
|
||||
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,
|
||||
// use get_min_max without the AXE template parameter
|
||||
// available in _plane_is_cuboid_do_intersect.h
|
||||
template <class K, class Box3, int AXE>
|
||||
template <class FT, class Box3, int AXE>
|
||||
inline
|
||||
void get_min_max(const typename K::FT& px,
|
||||
const typename K::FT& py,
|
||||
const typename K::FT& pz,
|
||||
void get_min_max(const FT& px,
|
||||
const FT& py,
|
||||
const FT& pz,
|
||||
const Box3& c,
|
||||
typename K::Point_3& p_min,
|
||||
typename K::Point_3& p_max)
|
||||
std::array<FT, 3>& p_min,
|
||||
std::array<FT, 3>& p_max)
|
||||
{
|
||||
CGAL_USE(px);
|
||||
CGAL_USE(py);
|
||||
CGAL_USE(pz);
|
||||
|
||||
if(AXE == 0 || px > 0) {
|
||||
if(AXE == 1 || py > 0) {
|
||||
if(AXE == 2 || pz > 0) {
|
||||
p_min = typename K::Point_3(c.xmin(), c.ymin(),c.zmin());
|
||||
p_max = typename K::Point_3(c.xmax(), c.ymax(),c.zmax());
|
||||
p_min = CGAL::make_array<FT>(c.xmin(), c.ymin(),c.zmin());
|
||||
p_max = CGAL::make_array<FT>(c.xmax(), c.ymax(),c.zmax());
|
||||
}
|
||||
else {
|
||||
p_min = typename K::Point_3(c.xmin(), c.ymin(),c.zmax());
|
||||
p_max = typename K::Point_3(c.xmax(), c.ymax(),c.zmin());
|
||||
p_min = CGAL::make_array<FT>(c.xmin(), c.ymin(),c.zmax());
|
||||
p_max = CGAL::make_array<FT>(c.xmax(), c.ymax(),c.zmin());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(AXE == 2 || pz > 0) {
|
||||
p_min = typename K::Point_3(c.xmin(), c.ymax(),c.zmin());
|
||||
p_max = typename K::Point_3(c.xmax(), c.ymin(),c.zmax());
|
||||
p_min = CGAL::make_array<FT>(c.xmin(), c.ymax(),c.zmin());
|
||||
p_max = CGAL::make_array<FT>(c.xmax(), c.ymin(),c.zmax());
|
||||
}
|
||||
else {
|
||||
p_min = typename K::Point_3(c.xmin(), c.ymax(),c.zmax());
|
||||
p_max = typename K::Point_3(c.xmax(), c.ymin(),c.zmin());
|
||||
p_min = CGAL::make_array<FT>(c.xmin(), c.ymax(),c.zmax());
|
||||
p_max = CGAL::make_array<FT>(c.xmax(), c.ymin(),c.zmin());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(AXE == 1 || py > 0) {
|
||||
if(AXE == 2 || pz > 0) {
|
||||
p_min = typename K::Point_3(c.xmax(), c.ymin(),c.zmin());
|
||||
p_max = typename K::Point_3(c.xmin(), c.ymax(),c.zmax());
|
||||
p_min = CGAL::make_array<FT>(c.xmax(), c.ymin(),c.zmin());
|
||||
p_max = CGAL::make_array<FT>(c.xmin(), c.ymax(),c.zmax());
|
||||
}
|
||||
else {
|
||||
p_min = typename K::Point_3(c.xmax(), c.ymin(),c.zmax());
|
||||
p_max = typename K::Point_3(c.xmin(), c.ymax(),c.zmin());
|
||||
p_min = CGAL::make_array<FT>(c.xmax(), c.ymin(),c.zmax());
|
||||
p_max = CGAL::make_array<FT>(c.xmin(), c.ymax(),c.zmin());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(AXE == 2 || pz > 0) {
|
||||
p_min = typename K::Point_3(c.xmax(), c.ymax(),c.zmin());
|
||||
p_max = typename K::Point_3(c.xmin(), c.ymin(),c.zmax());
|
||||
p_min = CGAL::make_array<FT>(c.xmax(), c.ymax(),c.zmin());
|
||||
p_max = CGAL::make_array<FT>(c.xmin(), c.ymin(),c.zmax());
|
||||
}
|
||||
else {
|
||||
p_min = typename K::Point_3(c.xmax(), c.ymax(),c.zmax());
|
||||
p_max = typename K::Point_3(c.xmin(), c.ymin(),c.zmin());
|
||||
p_min = CGAL::make_array<FT>(c.xmax(), c.ymax(),c.zmax());
|
||||
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
|
||||
typename K::FT
|
||||
do_axis_intersect_aux(const typename K::FT& alpha,
|
||||
const typename K::FT& beta,
|
||||
const typename K::Vector_3* sides)
|
||||
Uncertain<Sign>
|
||||
do_axis_intersect_aux_A0(const FT& alpha,
|
||||
const FT& beta,
|
||||
const std::array<std::array<FT,3>, 3>& sides,
|
||||
Fct do_axis_intersect_aux_impl)
|
||||
{
|
||||
switch ( AXE )
|
||||
{
|
||||
case 0:
|
||||
return -sides[SIDE].z()*alpha + sides[SIDE].y()*beta;
|
||||
case 1:
|
||||
return sides[SIDE].z()*alpha - sides[SIDE].x()*beta;
|
||||
case 2:
|
||||
return -sides[SIDE].y()*alpha + sides[SIDE].x()*beta;
|
||||
default:
|
||||
CGAL_error();
|
||||
return typename K::FT(0);
|
||||
}
|
||||
return do_axis_intersect_aux_impl(alpha, beta, sides[SIDE][2], sides[SIDE][1]);
|
||||
}
|
||||
|
||||
template <class FT, int SIDE, class Fct>
|
||||
inline
|
||||
Uncertain<Sign>
|
||||
do_axis_intersect_aux_A1(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(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
|
||||
//of the orthonormal frame. return -1 otherwise
|
||||
template <class K>
|
||||
template <class FT>
|
||||
inline
|
||||
int
|
||||
collinear_axis(typename K::Vector_3 side)
|
||||
collinear_axis(const std::array<FT,3>& side)
|
||||
{
|
||||
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))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <class K, class Box3, int AXE, int SIDE>
|
||||
template <class FT, class Box3, int AXE, int SIDE, class Fct>
|
||||
inline
|
||||
Uncertain<bool> do_axis_intersect(const typename K::Triangle_3& triangle,
|
||||
const typename K::Vector_3* sides,
|
||||
const Box3& bbox)
|
||||
Uncertain<bool> do_axis_intersect(const std::array<std::array<FT, 3>, 3>& triangle,
|
||||
const std::array<std::array<FT, 3>, 3>& sides,
|
||||
const Box3& bbox,
|
||||
Fct do_axis_intersect_aux_impl)
|
||||
{
|
||||
const typename K::Point_3* j = & triangle.vertex(SIDE);
|
||||
const typename K::Point_3* k = & triangle.vertex((SIDE+2)%3);
|
||||
const std::array<FT, 3>& j = triangle[SIDE];
|
||||
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;
|
||||
get_min_max<K,Box3, AXE>(AXE==0? 0: AXE==1? sides[SIDE].z(): -sides[SIDE].y(),
|
||||
AXE==0? -sides[SIDE].z(): AXE==1? 0: sides[SIDE].x(),
|
||||
AXE==0? sides[SIDE].y(): AXE==1? -sides[SIDE].x():
|
||||
typename K::FT(0), bbox, p_min, p_max);
|
||||
std::array<FT, 3> p_min, p_max;
|
||||
get_min_max<FT, Box3, AXE>(AXE==0? 0: AXE==1? sides[SIDE][2]: -sides[SIDE][1],
|
||||
AXE==0? -sides[SIDE][2]: AXE==1? 0: sides[SIDE][0],
|
||||
AXE==0? sides[SIDE][1]: AXE==1? -sides[SIDE][0]:
|
||||
FT(0), bbox, p_min, p_max);
|
||||
|
||||
switch ( AXE )
|
||||
switch(AXE)
|
||||
{
|
||||
case 0: {
|
||||
case 0:
|
||||
{
|
||||
// t_max >= t_min
|
||||
Uncertain<bool> b = do_axis_intersect_aux<K,AXE,SIDE>(k->y()-j->y(), k->z()-j->z(), sides) >= 0;
|
||||
if (is_indeterminate(b))
|
||||
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))
|
||||
return b;
|
||||
if(b) std::swap(j,k);
|
||||
return CGAL_AND((do_axis_intersect_aux<K,AXE,SIDE>(p_min.y()-j->y(), p_min.z()-j->z(), sides) <= 0),
|
||||
(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) );
|
||||
if(b)
|
||||
std::swap(j_ptr, k_ptr);
|
||||
|
||||
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
|
||||
Uncertain<bool> b = do_axis_intersect_aux<K,AXE,SIDE>(k->x()-j->x(), k->y()-j->y(), sides) >= 0;
|
||||
if ( is_indeterminate(b))
|
||||
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))
|
||||
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.y()-j->y(), sides) <= 0),
|
||||
(do_axis_intersect_aux<K,AXE,SIDE>(p_max.x()-k->x(), p_max.y()-k->y(), sides) >= 0) );
|
||||
if(b)
|
||||
std::swap(j_ptr, k_ptr);
|
||||
|
||||
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:
|
||||
// Should not happen
|
||||
case 2:
|
||||
{
|
||||
// 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();
|
||||
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>
|
||||
bool do_intersect_bbox_or_iso_cuboid(const typename K::Triangle_3& a_triangle,
|
||||
const Box3& a_bbox,
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
typename K::Vector_3 sides[3];
|
||||
sides[0] = a_triangle[1] - a_triangle[0];
|
||||
sides[1] = a_triangle[2] - a_triangle[1];
|
||||
sides[2] = a_triangle[0] - a_triangle[2];
|
||||
int forbidden_axis=-1;
|
||||
int forbidden_size=-1;
|
||||
//determine whether one vector is collinear with an axis
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
typedef typename K::FT FT;
|
||||
auto do_axis_intersect_aux_impl = [](const FT& alpha,
|
||||
const FT& beta,
|
||||
const FT& c_alpha,
|
||||
const FT& c_beta) -> Uncertain<Sign>
|
||||
{
|
||||
return CGAL::sign(- c_alpha * alpha + c_beta * beta);
|
||||
};
|
||||
|
||||
#if 0
|
||||
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());
|
||||
std::array< std::array<FT, 3>, 3> triangle =
|
||||
{{
|
||||
{ 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);
|
||||
typename K::Vector_3 v = m - CGAL::ORIGIN;
|
||||
|
||||
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
|
||||
// exception will be thrown in case the output is indeterminate
|
||||
return do_intersect_bbox_or_iso_cuboid_impl<FT>(triangle, a_bbox, do_axis_intersect_aux_impl);
|
||||
}
|
||||
|
||||
template <class K>
|
||||
|
|
|
|||
|
|
@ -68,12 +68,12 @@ public:
|
|||
|
||||
template <class TPoly>
|
||||
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:
|
||||
|
||||
//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::Traits::Vector_3 value_type;
|
||||
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:
|
||||
//read_write or lvalue
|
||||
//typedef boost::read_write_property_map_tag category;
|
||||
typedef boost::lvalue_property_map_tag category;
|
||||
typedef typename TPoly::Halfedge key_type;
|
||||
typedef typename TPoly::Traits::FT value_type;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ provides exact predicates.
|
|||
\cgalModels `DelaunayTriangulationTraits_2`
|
||||
\cgalModels `ConstrainedTriangulationTraits_2`
|
||||
\cgalModels `PolygonTraits_2`
|
||||
\cgalModels `ConformingDelaunayTriangulationTraits_2`
|
||||
|
||||
\sa `CGAL::Projection_traits_xy_3`
|
||||
\sa `CGAL::Projection_traits_xz_3`
|
||||
|
|
|
|||
|
|
@ -9258,6 +9258,16 @@ public:
|
|||
Oriented_side operator()(const Kernel::Triangle_2&t,
|
||||
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 */
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
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_y_2 Compare_y_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 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;
|
||||
|
|
@ -1014,6 +1050,10 @@ public:
|
|||
orientation_2_object() const
|
||||
{ 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_object() const
|
||||
{return Side_of_oriented_circle_2();}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ namespace CGAL {
|
|||
/*!
|
||||
\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.
|
||||
\param alcc the linear cell complex to draw.
|
||||
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
||||
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}
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -15,10 +15,6 @@ endif()
|
|||
|
||||
find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt5)
|
||||
|
||||
if(CGAL_Qt5_FOUND)
|
||||
add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS)
|
||||
endif()
|
||||
|
||||
# For Gprof.
|
||||
# ADD_DEFINITIONS("-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")
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ namespace CGAL {
|
|||
|
||||
template<typename LCC, typename FT>
|
||||
struct Wrap_squared_lcc
|
||||
: boost::put_get_helper< double, Wrap_squared_lcc<LCC, FT> >
|
||||
{
|
||||
typedef typename boost::graph_traits<LCC>::edge_descriptor Handle;
|
||||
typedef FT value_type;
|
||||
|
|
@ -54,12 +53,19 @@ struct Wrap_squared_lcc
|
|||
{}
|
||||
|
||||
template<typename E>
|
||||
FT operator[](const E& e) const
|
||||
value_type operator[](const E& e) const
|
||||
{
|
||||
return approximate_sqrt(CGAL::squared_distance
|
||||
(m_lcc.point(e.first_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:
|
||||
const LCC& m_lcc;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -92,6 +92,17 @@ points `p`, `q`, `r` (`q` being the vertex of the angle).
|
|||
*/
|
||||
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;
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -242,25 +242,9 @@ private:
|
|||
bool segment_hides_circumcenter(const Segment& seg,
|
||||
const Triangle& tr)
|
||||
{
|
||||
Point a = seg.source();
|
||||
Point b = seg.target();
|
||||
double dX = b.x() - a.x();
|
||||
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);
|
||||
typename Geom_traits::Oriented_side_2 os
|
||||
= m_cdt.geom_traits().oriented_side_2_object();
|
||||
return (os(seg, tr) != CGAL::ON_POSITIVE_SIDE);
|
||||
}
|
||||
|
||||
// tags with their sights, with respect to the Edge constraint,
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ private:
|
|||
sum += CGAL::sqrt(*it);
|
||||
|
||||
#ifdef CGAL_MESH_2_OPTIMIZER_VERBOSE
|
||||
sum_moves_ = sum/big_moves_.size();
|
||||
sum_moves_ = sum/FT(big_moves_.size());
|
||||
#endif
|
||||
|
||||
return ( sum/FT(big_moves_.size()) < convergence_ratio_ );
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ private:
|
|||
typename Tr::Edge_circulator end = ec;
|
||||
|
||||
FT sum_len(0.);
|
||||
FT nb = 0.;
|
||||
unsigned int nb = 0;
|
||||
do
|
||||
{
|
||||
Edge e = *ec;
|
||||
|
|
@ -187,7 +187,7 @@ private:
|
|||
while(++ec != end);
|
||||
// nb == 0 could happen if there is an isolated point.
|
||||
if( 0 != nb )
|
||||
return sum_len/nb;
|
||||
return sum_len/FT(nb);
|
||||
else
|
||||
// Use outside faces to compute size of point
|
||||
return 1.;//todo
|
||||
|
|
|
|||
|
|
@ -233,6 +233,12 @@ The parameters are optional unless otherwise specified.
|
|||
<li> <b>`parameters::image` (mandatory)</b> the input 3D image. Must
|
||||
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
|
||||
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
|
||||
|
||||
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>
|
||||
static
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ ALIASES += "cgalDescribePolylineType=A polyline is defined as a sequence of poin
|
|||
|
||||
INPUT += \
|
||||
${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"
|
||||
HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/implicit_domain_3.jpg \
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
\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
|
||||
|
||||
The example \ref Mesh_3/mesh_3D_image_with_custom_initialization.cpp is a modification
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ and their associated classes:
|
|||
- `CGAL::lloyd_optimize_mesh_3()`
|
||||
- `CGAL::odt_optimize_mesh_3()`
|
||||
- `CGAL::facets_in_complex_3_to_triangle_mesh()`
|
||||
- `CGAL::Mesh_3::generate_label_weights()`
|
||||
|
||||
\cgalCRPSection{CGAL::parameters Functions}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
\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_custom_initialization.cpp
|
||||
\example Mesh_3/mesh_3D_weighted_image.cpp
|
||||
\example Mesh_3/random_labeled_image.h
|
||||
\example CGAL/Mesh_3/initialize_triangulation_from_gray_image.h
|
||||
\example CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 115 KiB |
|
|
@ -161,10 +161,21 @@ if(TARGET CGAL::CGAL_ImageIO)
|
|||
create_single_source_cgal_program("mesh_3D_image_variable_size.cpp")
|
||||
target_link_libraries(mesh_3D_image_variable_size
|
||||
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()
|
||||
message(
|
||||
STATUS
|
||||
"NOTICE: The examples mesh_3D_image.cpp, mesh_3D_image_variable_size.cpp, mesh_optimization_example.cpp and mesh_optimization_lloyd_example.cpp need CGAL_ImageIO to be configured with ZLIB support, and will not be compiled."
|
||||
"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()
|
||||
|
||||
|
|
@ -179,6 +190,7 @@ if(CGAL_ACTIVATE_CONCURRENT_MESH_3 AND TARGET CGAL::TBB_support)
|
|||
foreach(
|
||||
target
|
||||
mesh_3D_image
|
||||
mesh_3D_weighted_image
|
||||
mesh_3D_image_variable_size
|
||||
mesh_3D_image_with_custom_initialization
|
||||
mesh_3D_gray_image_with_custom_initialization
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -28,7 +28,7 @@ using namespace CGAL::parameters;
|
|||
|
||||
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
|
||||
CGAL::Image_3 image;
|
||||
if(!image.read(fname)){
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ struct Image_to_multiple_iso_level_sets {
|
|||
|
||||
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
|
||||
CGAL::Image_3 image;
|
||||
if(!image.read(fname)){
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ using namespace CGAL::parameters;
|
|||
|
||||
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]
|
||||
CGAL::Image_3 image;
|
||||
if (!image.read(fname)) {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ using namespace CGAL::parameters;
|
|||
int main(int argc, char* argv[])
|
||||
{
|
||||
/// [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;
|
||||
if(!image.read(fname)){
|
||||
std::cerr << "Error: Cannot read file " << fname << std::endl;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ using namespace CGAL::parameters;
|
|||
|
||||
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
|
||||
CGAL::Image_3 image;
|
||||
if(!image.read(fname)){
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ using namespace CGAL::parameters;
|
|||
// not documented.
|
||||
bool add_1D_features(const CGAL::Image_3& image,
|
||||
Mesh_domain& domain,
|
||||
const char* lines_fname)
|
||||
const std::string lines_fname)
|
||||
{
|
||||
typedef K::Point_3 Point_3;
|
||||
typedef unsigned char Word_type;
|
||||
|
|
@ -72,7 +72,7 @@ bool add_1D_features(const CGAL::Image_3& image,
|
|||
|
||||
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
|
||||
CGAL::Image_3 image;
|
||||
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);
|
||||
|
||||
/// 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)) {
|
||||
return EXIT_FAILURE;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ using namespace CGAL::parameters;
|
|||
|
||||
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
|
||||
CGAL::Image_3 image;
|
||||
if(!image.read(fname)){
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue