Update branch from master after trailing whitespaces and tabs removal

This commit is contained in:
Sébastien Loriot 2020-03-26 19:16:25 +01:00
commit 35b83deffd
86 changed files with 22685 additions and 1379 deletions

View File

@ -30,28 +30,29 @@ env:
- PACKAGE='Minkowski_sum_2 Minkowski_sum_3 Modifier '
- PACKAGE='Modular_arithmetic Nef_2 Nef_3 '
- PACKAGE='Nef_S2 NewKernel_d Number_types '
- PACKAGE='OpenNL Optimal_transportation_reconstruction_2 Optimisation_basic '
- PACKAGE='Partition_2 Periodic_2_triangulation_2 Periodic_3_mesh_3 '
- PACKAGE='Periodic_3_triangulation_3 Periodic_4_hyperbolic_triangulation_2 Point_set_2 '
- PACKAGE='Point_set_3 Point_set_processing_3 Poisson_surface_reconstruction_3 '
- PACKAGE='Polygon Polygon_mesh_processing Polygonal_surface_reconstruction '
- PACKAGE='Polyhedron Polyhedron_IO Polyline_simplification_2 '
- PACKAGE='Polynomial Polytope_distance_d Principal_component_analysis '
- PACKAGE='Principal_component_analysis_LGPL Profiling_tools Property_map '
- PACKAGE='QP_solver Random_numbers Ridges_3 '
- PACKAGE='STL_Extension Scale_space_reconstruction_3 Scripts '
- PACKAGE='SearchStructures Segment_Delaunay_graph_2 Segment_Delaunay_graph_Linf_2 '
- PACKAGE='Set_movable_separability_2 Shape_detection Skin_surface_3 '
- PACKAGE='Snap_rounding_2 Solver_interface Spatial_searching '
- PACKAGE='Spatial_sorting Straight_skeleton_2 Stream_lines_2 '
- PACKAGE='Stream_support Subdivision_method_3 Surface_mesh '
- PACKAGE='Surface_mesh_approximation Surface_mesh_deformation Surface_mesh_parameterization '
- PACKAGE='Surface_mesh_segmentation Surface_mesh_shortest_path Surface_mesh_simplification '
- PACKAGE='Surface_mesh_skeletonization Surface_mesh_topology Surface_mesher '
- PACKAGE='Surface_sweep_2 TDS_2 TDS_3 '
- PACKAGE='Testsuite Three Triangulation '
- PACKAGE='Triangulation_2 Triangulation_3 Union_find '
- PACKAGE='Visibility_2 Voronoi_diagram_2 wininst '
- PACKAGE='OpenNL Optimal_bounding_box Optimal_transportation_reconstruction_2 '
- PACKAGE='Optimisation_basic Partition_2 Periodic_2_triangulation_2 '
- PACKAGE='Periodic_3_mesh_3 Periodic_3_triangulation_3 Periodic_4_hyperbolic_triangulation_2 '
- PACKAGE='Point_set_2 Point_set_3 Point_set_processing_3 '
- PACKAGE='Poisson_surface_reconstruction_3 Polygon Polygon_mesh_processing '
- PACKAGE='Polygonal_surface_reconstruction Polyhedron Polyhedron_IO '
- PACKAGE='Polyline_simplification_2 Polynomial Polytope_distance_d '
- PACKAGE='Principal_component_analysis Principal_component_analysis_LGPL Profiling_tools '
- PACKAGE='Property_map QP_solver Random_numbers '
- PACKAGE='Ridges_3 STL_Extension Scale_space_reconstruction_3 '
- PACKAGE='Scripts SearchStructures Segment_Delaunay_graph_2 '
- PACKAGE='Segment_Delaunay_graph_Linf_2 Set_movable_separability_2 Shape_detection '
- PACKAGE='Skin_surface_3 Snap_rounding_2 Solver_interface '
- PACKAGE='Spatial_searching Spatial_sorting Straight_skeleton_2 '
- PACKAGE='Stream_lines_2 Stream_support Subdivision_method_3 '
- PACKAGE='Surface_mesh Surface_mesh_approximation Surface_mesh_deformation '
- PACKAGE='Surface_mesh_parameterization Surface_mesh_segmentation Surface_mesh_shortest_path '
- PACKAGE='Surface_mesh_simplification Surface_mesh_skeletonization Surface_mesh_topology '
- PACKAGE='Surface_mesher Surface_sweep_2 TDS_2 '
- PACKAGE='TDS_3 Testsuite Three '
- PACKAGE='Triangulation Triangulation_2 Triangulation_3 '
- PACKAGE='Union_find Visibility_2 Voronoi_diagram_2 '
- PACKAGE='wininst '
compiler: clang
install:
- echo "$PWD"

View File

@ -1,138 +1,139 @@
AABB_tree
Advancing_front_surface_reconstruction
Algebraic_foundations
Algebraic_kernel_d
Algebraic_kernel_for_circles
Algebraic_kernel_for_spheres
Alpha_shapes_2
Alpha_shapes_3
Apollonius_graph_2
Arithmetic_kernel
Arrangement_on_surface_2
BGL
Barycentric_coordinates_2
Boolean_set_operations_2
Bounding_volumes
Box_intersection_d
CGAL_Core
CGAL_ImageIO
CGAL_ipelets
Cartesian_kernel
Circular_kernel_2
Circular_kernel_3
Circulator
Classification
Combinatorial_map
Cone_spanners_2
Convex_decomposition_3
Convex_hull_2
Convex_hull_3
Convex_hull_d
Distance_2
Distance_3
Envelope_2
Envelope_3
Filtered_kernel
Generalized_map
Generator
Geomview
GraphicsView
HalfedgeDS
Hash_map
Heat_method_3
Homogeneous_kernel
Hyperbolic_triangulation_2
Inscribed_areas
Installation
Interpolation
Intersections_2
Intersections_3
Interval_skip_list
Interval_support
Inventor
Jet_fitting_3
Kernel_23
Kernel_d
LEDA
Linear_cell_complex
MacOSX
Maintenance
Matrix_search
Mesh_2
Mesh_3
Mesher_level
Minkowski_sum_2
Minkowski_sum_3
Modifier
Modular_arithmetic
Nef_2
Nef_3
Nef_S2
NewKernel_d
Number_types
OpenNL
Optimal_transportation_reconstruction_2
Optimisation_basic
Partition_2
Periodic_2_triangulation_2
Periodic_3_mesh_3
Periodic_3_triangulation_3
Periodic_4_hyperbolic_triangulation_2
Point_set_2
Point_set_3
Point_set_processing_3
Poisson_surface_reconstruction_3
Polygon
Polygon_mesh_processing
Polygonal_surface_reconstruction
Polyhedron
Polyhedron_IO
Polyline_simplification_2
Polynomial
Polytope_distance_d
Principal_component_analysis
Principal_component_analysis_LGPL
Profiling_tools
Property_map
QP_solver
Random_numbers
Ridges_3
STL_Extension
Scale_space_reconstruction_3
Scripts
SearchStructures
Segment_Delaunay_graph_2
Segment_Delaunay_graph_Linf_2
Set_movable_separability_2
Shape_detection
Skin_surface_3
Snap_rounding_2
Solver_interface
Spatial_searching
Spatial_sorting
Straight_skeleton_2
Stream_lines_2
Stream_support
Subdivision_method_3
Surface_mesh
Surface_mesh_approximation
Surface_mesh_deformation
Surface_mesh_parameterization
Surface_mesh_segmentation
Surface_mesh_shortest_path
Surface_mesh_simplification
Surface_mesh_skeletonization
Surface_mesh_topology
Surface_mesher
Surface_sweep_2
TDS_2
TDS_3
Testsuite
Three
Triangulation
Triangulation_2
Triangulation_3
Union_find
Visibility_2
Voronoi_diagram_2
wininst
AABB_tree
Advancing_front_surface_reconstruction
Algebraic_foundations
Algebraic_kernel_d
Algebraic_kernel_for_circles
Algebraic_kernel_for_spheres
Alpha_shapes_2
Alpha_shapes_3
Apollonius_graph_2
Arithmetic_kernel
Arrangement_on_surface_2
BGL
Barycentric_coordinates_2
Boolean_set_operations_2
Bounding_volumes
Box_intersection_d
CGAL_Core
CGAL_ImageIO
CGAL_ipelets
Cartesian_kernel
Circular_kernel_2
Circular_kernel_3
Circulator
Classification
Combinatorial_map
Cone_spanners_2
Convex_decomposition_3
Convex_hull_2
Convex_hull_3
Convex_hull_d
Distance_2
Distance_3
Envelope_2
Envelope_3
Filtered_kernel
Generalized_map
Generator
Geomview
GraphicsView
HalfedgeDS
Hash_map
Heat_method_3
Homogeneous_kernel
Hyperbolic_triangulation_2
Inscribed_areas
Installation
Interpolation
Intersections_2
Intersections_3
Interval_skip_list
Interval_support
Inventor
Jet_fitting_3
Kernel_23
Kernel_d
LEDA
Linear_cell_complex
MacOSX
Maintenance
Matrix_search
Mesh_2
Mesh_3
Mesher_level
Minkowski_sum_2
Minkowski_sum_3
Modifier
Modular_arithmetic
Nef_2
Nef_3
Nef_S2
NewKernel_d
Number_types
OpenNL
Optimal_bounding_box
Optimal_transportation_reconstruction_2
Optimisation_basic
Partition_2
Periodic_2_triangulation_2
Periodic_3_mesh_3
Periodic_3_triangulation_3
Periodic_4_hyperbolic_triangulation_2
Point_set_2
Point_set_3
Point_set_processing_3
Poisson_surface_reconstruction_3
Polygon
Polygon_mesh_processing
Polygonal_surface_reconstruction
Polyhedron
Polyhedron_IO
Polyline_simplification_2
Polynomial
Polytope_distance_d
Principal_component_analysis
Principal_component_analysis_LGPL
Profiling_tools
Property_map
QP_solver
Random_numbers
Ridges_3
STL_Extension
Scale_space_reconstruction_3
Scripts
SearchStructures
Segment_Delaunay_graph_2
Segment_Delaunay_graph_Linf_2
Set_movable_separability_2
Shape_detection
Skin_surface_3
Snap_rounding_2
Solver_interface
Spatial_searching
Spatial_sorting
Straight_skeleton_2
Stream_lines_2
Stream_support
Subdivision_method_3
Surface_mesh
Surface_mesh_approximation
Surface_mesh_deformation
Surface_mesh_parameterization
Surface_mesh_segmentation
Surface_mesh_shortest_path
Surface_mesh_simplification
Surface_mesh_skeletonization
Surface_mesh_topology
Surface_mesher
Surface_sweep_2
TDS_2
TDS_3
Testsuite
Three
Triangulation
Triangulation_2
Triangulation_3
Union_find
Visibility_2
Voronoi_diagram_2
wininst

View File

@ -2,8 +2,8 @@
#include <CGAL/Regular_triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Regular_triangulation_2.h>
#include <CGAL/internal/boost/function_property_map.hpp>
#include <boost/property_map/function_property_map.hpp>
#include <boost/graph/kruskal_min_spanning_tree.hpp>
#include <fstream>
@ -75,7 +75,7 @@ int main(int argc,char* argv[])
std::list<edge_descriptor> mst;
boost::kruskal_minimum_spanning_tree(tr, std::back_inserter(mst),
vertex_index_map(vertex_index_pmap)
.weight_map(CGAL::internal::boost_::make_function_property_map<
.weight_map(boost::make_function_property_map<
edge_descriptor, FT, Edge_weight_functor>(Edge_weight_functor(tr))));
std::cout << "The edges of the Euclidean mimimum spanning tree:" << std::endl;

View File

@ -194,19 +194,6 @@ get_parameter(const Named_function_parameters<T, Tag, Base>& np, Query_tag tag)
return internal_np::get_parameter_impl(static_cast<const internal_np::Named_params_impl<T, Tag, Base>&>(np), tag);
}
// single parameter so that we can avoid a default construction
template <typename D>
D choose_parameter(const internal_np::Param_not_found&)
{
return D();
}
template <typename D, typename T>
const T& choose_parameter(const T& t)
{
return t;
}
// Two parameters, non-trivial default value
template <typename D>
D choose_parameter(const internal_np::Param_not_found&, const D& d)
@ -220,6 +207,19 @@ const T& choose_parameter(const T& t, const D&)
return t;
}
// single parameter so that we can avoid a default construction
template <typename D>
D choose_parameter(const internal_np::Param_not_found&)
{
return D();
}
template <typename D, typename T>
const T& choose_parameter(const T& t)
{
return t;
}
bool inline is_default_parameter(const internal_np::Param_not_found&)
{
return true;

View File

@ -222,7 +222,7 @@ typename BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
Graph, NamedParameters>::const_type \
get_initialized_##DTYPE##_index_map(const Graph& g, \
const NamedParameters& np) \
const NamedParameters& np) \
{ \
typedef BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
boost::DTYPE##_index_t, \
@ -250,7 +250,7 @@ typename BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
Graph, NamedParameters>::type \
get_initialized_##DTYPE##_index_map(Graph& g, \
const NamedParameters& np) \
const NamedParameters& np) \
{ \
typedef BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
boost::DTYPE##_index_t, \
@ -351,7 +351,7 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
typedef std::random_access_iterator_tag iterator_category;
};
};
namespace parameters
{
template <typename PointRange>

View File

@ -141,6 +141,9 @@ CGAL_add_named_parameter(max_number_of_proxies_t, max_number_of_proxies, max_num
CGAL_add_named_parameter(min_error_drop_t, min_error_drop, min_error_drop)
CGAL_add_named_parameter(number_of_relaxations_t, number_of_relaxations, number_of_relaxations)
// List of named parameters used in Optimal_bounding_box package
CGAL_add_named_parameter(use_convex_hull_t, use_convex_hull, use_convex_hull)
// meshing parameters
CGAL_add_named_parameter(subdivision_ratio_t, subdivision_ratio, subdivision_ratio)
CGAL_add_named_parameter(relative_to_chord_t, relative_to_chord, relative_to_chord)

View File

@ -41,11 +41,11 @@ void test(const NamedParameters& np)
assert(get_parameter(np, CGAL::internal_np::METIS_options).v == 800000001);
assert(get_parameter(np, CGAL::internal_np::vertex_partition_id).v == 800000002);
assert(get_parameter(np, CGAL::internal_np::face_partition_id).v == 800000003);
assert(get_parameter(np, CGAL::internal_np::vertex_to_vertex_output_iterator).v == 800000004);
assert(get_parameter(np, CGAL::internal_np::halfedge_to_halfedge_output_iterator).v == 800000005);
assert(get_parameter(np, CGAL::internal_np::face_to_face_output_iterator).v == 800000006);
assert(get_parameter(np, CGAL::internal_np::vertex_to_vertex_map).v == 800000007);
assert(get_parameter(np, CGAL::internal_np::halfedge_to_halfedge_map).v == 800000008);
assert(get_parameter(np, CGAL::internal_np::face_to_face_map).v == 800000009);
@ -86,21 +86,24 @@ void test(const NamedParameters& np)
assert(get_parameter(np, CGAL::internal_np::require_same_orientation).v == 49);
assert(get_parameter(np, CGAL::internal_np::use_bool_op_to_clip_surface).v == 50);
assert(get_parameter(np, CGAL::internal_np::face_size_map).v == 52);
assert(get_parameter(np, CGAL::internal_np::snapping_tolerance).v == 57);
assert(get_parameter(np, CGAL::internal_np::use_angle_smoothing).v == 53);
assert(get_parameter(np, CGAL::internal_np::use_area_smoothing).v == 54);
assert(get_parameter(np, CGAL::internal_np::use_Delaunay_flips).v == 55);
assert(get_parameter(np, CGAL::internal_np::use_safety_constraints).v == 56);
assert(get_parameter(np, CGAL::internal_np::area_threshold).v == 57);
assert(get_parameter(np, CGAL::internal_np::volume_threshold).v == 58);
assert(get_parameter(np, CGAL::internal_np::dry_run).v == 59);
assert(get_parameter(np, CGAL::internal_np::do_lock_mesh).v == 60);
assert(get_parameter(np, CGAL::internal_np::do_simplify_border).v == 61);
assert(get_parameter(np, CGAL::internal_np::snapping_tolerance).v == 59);
assert(get_parameter(np, CGAL::internal_np::dry_run).v == 60);
assert(get_parameter(np, CGAL::internal_np::do_lock_mesh).v == 61);
assert(get_parameter(np, CGAL::internal_np::do_simplify_border).v == 62);
// Named parameters that we use in the package 'Surface Mesh Simplification'
assert(get_parameter(np, CGAL::internal_np::get_cost_policy).v == 34);
assert(get_parameter(np, CGAL::internal_np::get_placement_policy).v == 35);
// Named parameters that we use in the package 'Optimal_bounding_box'
assert(get_parameter(np, CGAL::internal_np::use_convex_hull).v == 63);
// To-be-documented named parameters
assert(get_parameter(np, CGAL::internal_np::face_normal).v == 36);
assert(get_parameter(np, CGAL::internal_np::random_seed).v == 37);
@ -175,21 +178,24 @@ void test(const NamedParameters& np)
check_same_type<49>(get_parameter(np, CGAL::internal_np::require_same_orientation));
check_same_type<50>(get_parameter(np, CGAL::internal_np::use_bool_op_to_clip_surface));
check_same_type<52>(get_parameter(np, CGAL::internal_np::face_size_map));
check_same_type<57>(get_parameter(np, CGAL::internal_np::snapping_tolerance));
check_same_type<53>(get_parameter(np, CGAL::internal_np::use_angle_smoothing));
check_same_type<54>(get_parameter(np, CGAL::internal_np::use_area_smoothing));
check_same_type<55>(get_parameter(np, CGAL::internal_np::use_Delaunay_flips));
check_same_type<56>(get_parameter(np, CGAL::internal_np::use_safety_constraints));
check_same_type<57>(get_parameter(np, CGAL::internal_np::area_threshold));
check_same_type<58>(get_parameter(np, CGAL::internal_np::volume_threshold));
check_same_type<59>(get_parameter(np, CGAL::internal_np::dry_run));
check_same_type<60>(get_parameter(np, CGAL::internal_np::do_lock_mesh));
check_same_type<61>(get_parameter(np, CGAL::internal_np::do_simplify_border));
check_same_type<59>(get_parameter(np, CGAL::internal_np::snapping_tolerance));
check_same_type<60>(get_parameter(np, CGAL::internal_np::dry_run));
check_same_type<61>(get_parameter(np, CGAL::internal_np::do_lock_mesh));
check_same_type<62>(get_parameter(np, CGAL::internal_np::do_simplify_border));
// Named parameters that we use in the package 'Surface Mesh Simplification'
check_same_type<34>(get_parameter(np, CGAL::internal_np::get_cost_policy));
check_same_type<35>(get_parameter(np, CGAL::internal_np::get_placement_policy));
// Named parameters that we use in the package 'Optimal_bounding_box'
check_same_type<63>(get_parameter(np, CGAL::internal_np::use_convex_hull));
// To-be-documented named parameters
check_same_type<36>(get_parameter(np, CGAL::internal_np::face_normal));
check_same_type<37>(get_parameter(np, CGAL::internal_np::random_seed));
@ -203,7 +209,7 @@ void test(const NamedParameters& np)
check_same_type<42>(get_parameter(np, CGAL::internal_np::projection_functor));
check_same_type<46>(get_parameter(np, CGAL::internal_np::apply_per_connected_component));
check_same_type<47>(get_parameter(np, CGAL::internal_np::output_iterator));
// Named parameters used in the package 'Point Set Processing'
check_same_type<9000>(get_parameter(np, CGAL::internal_np::point_map));
check_same_type<9001>(get_parameter(np, CGAL::internal_np::query_point_map));
@ -307,16 +313,17 @@ int main()
.use_bool_op_to_clip_surface(A<50>(50))
.use_binary_mode(A<51>(51))
.face_size_map(A<52>(52))
.snapping_tolerance(A<57>(57))
.use_angle_smoothing(A<53>(53))
.use_area_smoothing(A<54>(54))
.use_Delaunay_flips(A<55>(55))
.use_safety_constraints(A<56>(56))
.area_threshold(A<57>(57))
.volume_threshold(A<58>(58))
.dry_run(A<59>(59))
.do_lock_mesh(A<60>(60))
.do_simplify_border(A<61>(61))
.snapping_tolerance(A<59>(59))
.dry_run(A<60>(60))
.do_lock_mesh(A<61>(61))
.do_simplify_border(A<62>(62))
.use_convex_hull(A<63>(63))
.point_map(A<9000>(9000))
.query_point_map(A<9001>(9001))
.normal_map(A<9002>(9002))

View File

@ -2,93 +2,93 @@
\ingroup PkgConvexHull2Concepts
\cgalConcept
All convex hull and extreme point algorithms provided in \cgal are
parameterized with a traits class `Traits`, which defines the
primitives (objects and predicates) that the convex hull algorithms use.
`ConvexHullTraits_2` defines the complete set of primitives required in these
functions. The specific subset of these primitives required by each function
is specified with each function.
All convex hull and extreme point algorithms provided in \cgal are
parameterized with a traits class `Traits`, which defines the
primitives (objects and predicates) that the convex hull algorithms use.
`ConvexHullTraits_2` defines the complete set of primitives required in these
functions. The specific subset of these primitives required by each function
is specified with each function.
\cgalHasModel `CGAL::Convex_hull_constructive_traits_2<R>`
\cgalHasModel `CGAL::Convex_hull_traits_2<R>`
\cgalHasModel `CGAL::Convex_hull_traits_adapter_2<R>`
\cgalHasModel `CGAL::Projection_traits_xy_3<K>`
\cgalHasModel `CGAL::Projection_traits_yz_3 <K>`
\cgalHasModel `CGAL::Projection_traits_yz_3<K>`
\cgalHasModel `CGAL::Projection_traits_xz_3<K>`
\sa `IsStronglyConvexTraits_3`
\sa `IsStronglyConvexTraits_3`
*/
class ConvexHullTraits_2 {
public:
/// \name Types
/// \name Types
/// @{
/*!
The point type on which the convex hull functions operate.
*/
typedef unspecified_type Point_2;
The point type on which the convex hull functions operate.
*/
typedef unspecified_type Point_2;
/*!
Binary predicate object type comparing `Point_2`s. Must provide
`bool operator()(Point_2 p, Point_2 q)` where `true`
is returned iff \f$ p ==_{xy} q\f$, false otherwise.
Binary predicate object type comparing `Point_2`s. Must provide
`bool operator()(Point_2 p, Point_2 q)` where `true`
is returned iff \f$ p ==_{xy} q\f$, false otherwise.
*/
typedef unspecified_type Equal_2;
*/
typedef unspecified_type Equal_2;
/*!
Binary predicate object type comparing `Point_2`s
lexicographically. Must provide
`bool operator()(Point_2 p, Point_2 q)` where `true`
is returned iff \f$ p <_{xy} q\f$.
We have \f$ p<_{xy}q\f$, iff \f$ p_x < q_x\f$ or \f$ p_x = q_x\f$ and \f$ p_y < q_y\f$,
where \f$ p_x\f$ and \f$ p_y\f$ denote \f$ x\f$ and \f$ y\f$ coordinate of point \f$ p\f$,
respectively.
Binary predicate object type comparing `Point_2`s
lexicographically. Must provide
`bool operator()(Point_2 p, Point_2 q)` where `true`
is returned iff \f$ p <_{xy} q\f$.
We have \f$ p<_{xy}q\f$, iff \f$ p_x < q_x\f$ or \f$ p_x = q_x\f$ and \f$ p_y < q_y\f$,
where \f$ p_x\f$ and \f$ p_y\f$ denote \f$ x\f$ and \f$ y\f$ coordinate of point \f$ p\f$,
respectively.
*/
typedef unspecified_type Less_xy_2;
*/
typedef unspecified_type Less_xy_2;
/*!
Same as `Less_xy_2` with the roles of \f$ x\f$ and \f$ y\f$ interchanged.
*/
typedef unspecified_type Less_yx_2;
Same as `Less_xy_2` with the roles of \f$ x\f$ and \f$ y\f$ interchanged.
*/
typedef unspecified_type Less_yx_2;
/*!
Predicate object type that must provide
`bool operator()(Point_2 p,Point_2 q,Point_2 r)`, which
returns `true` iff `r` lies to the left of the
oriented line through `p` and `q`.
*/
typedef unspecified_type Left_turn_2;
Predicate object type that must provide
`bool operator()(Point_2 p,Point_2 q,Point_2 r)`, which
returns `true` iff `r` lies to the left of the
oriented line through `p` and `q`.
*/
typedef unspecified_type Left_turn_2;
/*!
Predicate object type that must provide
`bool operator()(Point_2 p, Point_2 q,
Point_2 r,Point_2 s)`, which returns `true` iff
the signed distance from \f$ r\f$ to the line \f$ l_{pq}\f$ through \f$ p\f$ and \f$ q\f$
is smaller than the distance from \f$ s\f$ to \f$ l_{pq}\f$. It is used to
compute the point right of a line with maximum unsigned distance to
the line. The predicate must provide a total order compatible
with convexity, <I>i.e.</I>, for any line segment \f$ s\f$ one of the
endpoints
of \f$ s\f$ is the smallest point among the points on \f$ s\f$, with respect to
the order given by `Less_signed_distance_to_line_2`.
*/
typedef unspecified_type Less_signed_distance_to_line_2;
Predicate object type that must provide
`bool operator()(Point_2 p, Point_2 q,
Point_2 r,Point_2 s)`, which returns `true` iff
the signed distance from \f$ r\f$ to the line \f$ l_{pq}\f$ through \f$ p\f$ and \f$ q\f$
is smaller than the distance from \f$ s\f$ to \f$ l_{pq}\f$. It is used to
compute the point right of a line with maximum unsigned distance to
the line. The predicate must provide a total order compatible
with convexity, <I>i.e.</I>, for any line segment \f$ s\f$ one of the
endpoints
of \f$ s\f$ is the smallest point among the points on \f$ s\f$, with respect to
the order given by `Less_signed_distance_to_line_2`.
*/
typedef unspecified_type Less_signed_distance_to_line_2;
/*!
Predicate object type that must provide
`bool operator()(Point_2 e, Point_2 p,Point_2 q)`,
where `true` is returned iff a tangent at \f$ e\f$ to the point set
\f$ \{e,p,q\}\f$ hits \f$ p\f$ before \f$ q\f$ when rotated counterclockwise around
\f$ e\f$.
Ties are broken such that the point with larger distance to \f$ e\f$
is smaller!
*/
typedef unspecified_type Less_rotate_ccw_2;
Predicate object type that must provide
`bool operator()(Point_2 e, Point_2 p,Point_2 q)`,
where `true` is returned iff a tangent at \f$ e\f$ to the point set
\f$ \{e,p,q\}\f$ hits \f$ p\f$ before \f$ q\f$ when rotated counterclockwise around
\f$ e\f$.
Ties are broken such that the point with larger distance to \f$ e\f$
is smaller!
*/
typedef unspecified_type Less_rotate_ccw_2;
/*!
Predicate object type that must provide
@ -99,53 +99,53 @@ and returns `CGAL::COLLINEAR` if `r` lies on `l`.
*/
typedef unspecified_type Orientation_2;
/// @}
/// @}
/// \name Creation
/// Only a copy constructor is required.
/// \name Creation
/// Only a copy constructor is required.
/// @{
/*!
*/
ConvexHullTraits_2(ConvexHullTraits_2& t);
*/
ConvexHullTraits_2(ConvexHullTraits_2& t);
/// @}
/// @}
/// \name Operations
/// The following member functions to create instances of the above predicate
/// object types must exist.
/// \name Operations
/// The following member functions to create instances of the above predicate
/// object types must exist.
/// @{
/*!
*/
Equal_2 equal_2_object();
*/
Equal_2 equal_2_object();
/*!
*/
Less_xy_2 less_xy_2_object();
*/
Less_xy_2 less_xy_2_object();
/*!
*/
Less_yx_2 less_yx_2_object();
*/
Less_yx_2 less_yx_2_object();
/*!
*/
Less_signed_distance_to_line_2 less_signed_distance_to_line_2_object();
*/
Less_signed_distance_to_line_2 less_signed_distance_to_line_2_object();
/*!
*/
Less_rotate_ccw_2 less_rotate_ccw_2_object( );
*/
Less_rotate_ccw_2 less_rotate_ccw_2_object( );
/*!
*/
Left_turn_2 left_turn_2_object();
*/
Left_turn_2 left_turn_2_object();
/*!

View File

@ -4,7 +4,7 @@
#include <CGAL/algorithm.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/convex_hull_3.h>
#include <CGAL/convex_hull_3_to_polyhedron_3.h>
#include <CGAL/convex_hull_3_to_face_graph.h>
#include <CGAL/Delaunay_triangulation_3.h>
#include <CGAL/convex_hull_incremental_3.h>
#include <CGAL/Timer.h>
@ -36,7 +36,7 @@ void load_from_file(const char* path,std::vector<Point_3>& points)
}
while (--nbpt>0);
}
int main(int argc,char** argv)
{
std::vector<Point_3> points;
@ -68,7 +68,7 @@ int main(int argc,char** argv)
time.stop();
std::cout << "Delaunay " << time.time() << std::endl;
time.start();
CGAL::convex_hull_3_to_polyhedron_3(T,poly);
CGAL::convex_hull_3_to_face_graph(T,poly);
time.stop();
std::cout << "Delaunay+to_poly " << time.time() <<" "<< poly.size_of_vertices() << std::endl;
poly.clear();
@ -91,6 +91,6 @@ int main(int argc,char** argv)
CGAL::convex_hull_incremental_3( ek_points.begin(), ek_points.end(), poly2, false);
time.stop();
std::cout << "incremental EPEC " << time.time() <<" "<< poly2.size_of_vertices() << std::endl;
return 0;
}

View File

@ -1,29 +0,0 @@
namespace CGAL {
/*!
\ingroup PkgConvexHull3Functions
fills a polyhedron with the convex hull of a set of 3D points contained in a 3D triangulation of \cgal.
The polyhedron `P` is cleared and the convex hull of the set of 3D points is stored in `P`.
\deprecated since \cgal 4.10. Use `convex_hull_3_to_face_graph()` instead.
\attention This function does not compute the plane equations of the faces of `P`.
\attention This function works only for `CGAL::Polyhedron_3<Traits>`, and users who want
to generate a `Surface_mesh` or any other model of a `FaceGraph` may use `convex_hull_3_to_face_graph()` instead.
\pre `T.dimension()`==3.
\tparam Triangulation is a \cgal 3D triangulation.
\tparam Polyhedron is an instantiation of `CGAL::Polyhedron_3<Traits>`.
\sa `convex_hull_3()`
\sa `link_to_face_graph()`
*/
template <class Triangulation, class Polyhedron>
void convex_hull_3_to_polyhedron_3(const Triangulation& T,Polyhedron& P);
} /* namespace CGAL */

View File

@ -2,104 +2,104 @@
\ingroup PkgConvexHull3Concepts
\cgalConcept
Requirements of the traits class of the function `CGAL::convex_hull_3()`.
Requirements of the traits class of the function `CGAL::convex_hull_3()`.
\cgalHasModel `CGAL::Convex_hull_traits_3`
\cgalHasModel All models of `Kernel`
\cgalHasModel `CGAL::Convex_hull_traits_3<K>`
\cgalHasModel `CGAL::Extreme_points_traits_adapter_3<PPM, GT>`
*/
class ConvexHullTraits_3 {
public:
/// \name Types
/// \name Types
/// @{
/*!
The point type on which the convex hull algorithm operates
*/
typedef unspecified_type Point_3;
The point type on which the convex hull algorithm operates
*/
typedef unspecified_type Point_3;
/*!
a 3D plane
*/
typedef unspecified_type Plane_3;
a 3D plane
*/
typedef unspecified_type Plane_3;
/*!
a 3D segment
*/
typedef unspecified_type Segment_3;
a 3D segment
*/
typedef unspecified_type Segment_3;
/*!
a 3D triangle
*/
typedef unspecified_type Triangle_3;
a 3D triangle
*/
typedef unspecified_type Triangle_3;
/*!
Function object type that provides
`Plane_3 operator()(Point_3 p, Point_3 q, Point_3 r)`, which constructs
and returns a plane passing through `p`, `q`, and `r` and oriented
in a positive sense when seen from the positive side of the plane.
*/
typedef unspecified_type Construct_plane_3;
Function object type that provides
`Plane_3 operator()(Point_3 p, Point_3 q, Point_3 r)`, which constructs
and returns a plane passing through `p`, `q`, and `r` and oriented
in a positive sense when seen from the positive side of the plane.
*/
typedef unspecified_type Construct_plane_3;
/*!
Function object type that provides
`Segment_3 operator()(Point_3 p, Point_3 q)`, which constructs and
returns the segment with source `p` and target `q`.
*/
typedef unspecified_type Construct_segment_3;
Function object type that provides
`Segment_3 operator()(Point_3 p, Point_3 q)`, which constructs and
returns the segment with source `p` and target `q`.
*/
typedef unspecified_type Construct_segment_3;
/*!
Function object type that provides
`Triangle_3 operator()(Point_3 p, Point_3 q, Point_3 r)`, which
constructs and returns the triangle with vertices `p`, `q`, and
`r`.
*/
typedef unspecified_type Construct_triangle_3;
Function object type that provides
`Triangle_3 operator()(Point_3 p, Point_3 q, Point_3 r)`, which
constructs and returns the triangle with vertices `p`, `q`, and
`r`.
*/
typedef unspecified_type Construct_triangle_3;
/*!
Predicate object type that provides
`bool operator()(Point_3 p, Point_3 q)`, which determines
if points `p` and `q` are equal.
*/
typedef unspecified_type Equal_3;
Predicate object type that provides
`bool operator()(Point_3 p, Point_3 q)`, which determines
if points `p` and `q` are equal.
*/
typedef unspecified_type Equal_3;
/*!
Predicate object type that provides
`bool operator()(Point_3 p, Point_3 q, Point_3 r)`, which determines
if points `p`, `q` and `r` are collinear.
*/
typedef unspecified_type Collinear_3;
Predicate object type that provides
`bool operator()(Point_3 p, Point_3 q, Point_3 r)`, which determines
if points `p`, `q` and `r` are collinear.
*/
typedef unspecified_type Collinear_3;
/*!
Predicate object type that provides
`bool operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s)`, which
determines if points `p`, `q`, `r`, and `s` are coplanar.
*/
typedef unspecified_type Coplanar_3;
Predicate object type that provides
`bool operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s)`, which
determines if points `p`, `q`, `r`, and `s` are coplanar.
*/
typedef unspecified_type Coplanar_3;
/*!
Predicate object type that provides
`bool operator()(Plane_3 h, Point_3 q)`, which determines if the point
`q` is on the positive side of the halfspace `h`.
*/
typedef unspecified_type Has_on_positive_side_3;
Predicate object type that provides
`bool operator()(Plane_3 h, Point_3 q)`, which determines if the point
`q` is on the positive side of the halfspace `h`.
*/
typedef unspecified_type Has_on_positive_side_3;
/*!
Predicate object type that provides
`bool operator()(Point_3 p, Point_3 q, Point_3 r)`, which returns true iff the
distance from `q` to `p` is smaller than the distance from
`r` to `p`.
*/
typedef unspecified_type Less_distance_to_point_3;
Predicate object type that provides
`bool operator()(Point_3 p, Point_3 q, Point_3 r)`, which returns true iff the
distance from `q` to `p` is smaller than the distance from
`r` to `p`.
*/
typedef unspecified_type Less_distance_to_point_3;
/*!
Predicate object type that
provides `bool operator()(Plane_3 p, Point_3 q, Point_3 r)`, which
returns true iff the signed distance from `q` to `p` is smaller
than the signed distance from `r` to `p`
*/
typedef unspecified_type Less_signed_distance_to_plane_3;
Predicate object type that
provides `bool operator()(Plane_3 p, Point_3 q, Point_3 r)`, which
returns true iff the signed distance from `q` to `p` is smaller
than the signed distance from `r` to `p`
*/
typedef unspecified_type Less_signed_distance_to_plane_3;
/*!
A traits class providing the requirements of the template parameter `Traits` of
@ -108,7 +108,7 @@ is `Point_3`, and the 2D points considered in the algorithm are the projections
of the 3D points in the `xy`-plane.
If this type is not available, the function `CGAL::convex_hull_3()` will
automatically use `CGAL::Projection_traits_xy< CGAL::Kernel_traits<Point_3>::%Kernel >.`
Otherwise, a function must exist with the name `construct_traits_xy_3_object()` that creates an
Otherwise, a function must exist with the name `construct_traits_xy_3_object()` that creates an
instance of `Traits_xy_3`.
*/
typedef unspecified_type Traits_xy_3;
@ -125,29 +125,29 @@ typedef unspecified_type Traits_xz_3;
/// @}
/// \name Creation
/// Only a copy constructor is required.
/// \name Creation
/// Only a copy constructor is required.
/// @{
/*!
*/
ConvexHullTraits_3(ConvexHullTraits_3& ch);
*/
ConvexHullTraits_3(ConvexHullTraits_3& ch);
/// @}
/// @}
/*! \name Operations
For each of the above function and predicate object types,
`Func_obj_type`, a function must exist with the name
`func_obj_type_object` that creates an instance of the function or
predicate object type. For example:
/*! \name Operations
For each of the above function and predicate object types,
`Func_obj_type`, a function must exist with the name
`func_obj_type_object` that creates an instance of the function or
predicate object type. For example:
*/
/// @{
/*!
*/
Construct_plane_3 construct_plane_3_object();
*/
Construct_plane_3 construct_plane_3_object();
/// @}

View File

@ -42,11 +42,11 @@ namespace CGAL
Point_3 origin = Point_3(CGAL::ORIGIN))
{
typedef typename Kernel_traits<Point_3>::Kernel::Plane_3 Plane_3;
typedef typename boost::graph_traits<Polyhedron>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Polyhedron>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<Polyhedron>::vertex_descriptor vertex_descriptor;
typename boost::property_map<Polyhedron, vertex_point_t>::const_type vpm_primal = get(CGAL::vertex_point, primal);
typename boost::property_map<Polyhedron, vertex_point_t>::type vpm_dual = get(CGAL::vertex_point, dual);
// compute coordinates of extreme vertices in the dual polyhedron
@ -67,18 +67,18 @@ namespace CGAL
extreme_points[fd] = vd;
put(vpm_dual, vd, translated_extreme_p);
}
// build faces
for(vertex_descriptor vd : vertices(primal)) {
//CGAL_assertion (it->is_bivalent() == false);
std::list<vertex_descriptor> vertices;
for(face_descriptor fd : faces_around_target(halfedge(vd,primal),primal)){
vertices.push_front(extreme_points[fd]);
}
Euler::add_face(vertices,dual);
}
}
} // namespace internal
} // namespace Convex_hull_3
@ -97,7 +97,7 @@ namespace CGAL
typedef typename K::Plane_3 Plane;
Point p_origin;
if (origin) {
p_origin = boost::get(origin);
} else {
@ -142,7 +142,7 @@ namespace CGAL
boost::optional<typename Kernel_traits<typename std::iterator_traits<PlaneIterator>::value_type>::Kernel::Point_3> const& origin = boost::none) {
typedef typename Kernel_traits<typename std::iterator_traits<PlaneIterator>::value_type>::Kernel K;
typedef typename K::Point_3 Point_3;
typedef typename internal::Convex_hull_3::Default_traits_for_Chull_3<Point_3>::type Traits;
typedef typename Convex_hull_3::internal::Default_traits_for_Chull_3<Point_3>::type Traits;
halfspace_intersection_with_constructions_3(pbegin, pend, P, origin, Traits());
}

View File

@ -24,216 +24,254 @@
#include <CGAL/convex_hull_3.h>
#include <CGAL/result_of.h>
namespace CGAL {
namespace Convex_hull_3 {
namespace internal {
namespace Convex_hull_impl{
template <class F, class PointPropertyMap>
struct Forward_functor
: public F
{
PointPropertyMap vpm_;
Forward_functor(const PointPropertyMap& vpm,
const F& f) : F(f), vpm_(vpm) {}
Forward_functor(const PointPropertyMap& vpm, const F& f) : F(f), vpm_(vpm) {}
template <class Vertex>
typename cpp11::result_of<F(const Vertex&, const Vertex&)>::type
operator() (const Vertex& p, const Vertex& q) const
operator()(const Vertex& p, const Vertex& q) const
{
return static_cast<const F*>(this)->operator()(get(vpm_,p),get(vpm_,q));
return static_cast<const F*>(this)->operator()(get(vpm_, p), get(vpm_, q));
}
template <class Vertex>
typename cpp11::result_of<F(const Vertex&, const Vertex&, const Vertex&)>::type
operator() (const Vertex& p, const Vertex& q, const Vertex& r) const
operator()(const Vertex& p, const Vertex& q, const Vertex& r) const
{
return static_cast<const F*>(this)->operator()(
get(vpm_,p),
get(vpm_,q),
get(vpm_,r));
return static_cast<const F*>(this)->operator()(get(vpm_, p),
get(vpm_, q),
get(vpm_, r));
}
template <class Vertex>
typename cpp11::result_of<F(const Vertex&, const Vertex&, const Vertex&, const Vertex&)>::type
operator() (const Vertex& p, const Vertex& q, const Vertex& r, const Vertex& s) const
operator()(const Vertex& p, const Vertex& q, const Vertex& r, const Vertex& s) const
{
return static_cast<const F*>(this)->operator()(
get(vpm_,p),
get(vpm_,q),
get(vpm_,r),
get(vpm_,s));
return static_cast<const F*>(this)->operator()(get(vpm_, p),
get(vpm_, q),
get(vpm_, r),
get(vpm_, s));
}
};
}//end Convex_hull_impl
template<
class PointPropertyMap,
class Base_traits=typename internal::Convex_hull_3::Default_traits_for_Chull_3<
typename boost::property_traits<PointPropertyMap>::value_type>::type
} // namespace internal
} // namespace Convex_hull_3
template<class PointPropertyMap,
class Base_traits = typename Convex_hull_3::internal::Default_traits_for_Chull_3<
typename boost::property_traits<PointPropertyMap>::value_type>::type
>
class Extreme_points_traits_adapter_3
:public Base_traits
: public Base_traits
{
PointPropertyMap vpm_;
public:
Extreme_points_traits_adapter_3(const PointPropertyMap& vpmap, Base_traits base=Base_traits())
:Base_traits(base), vpm_(vpmap)
{}
typedef typename boost::property_traits<PointPropertyMap>::key_type Vertex;
typedef Vertex Point_3;
typedef Convex_hull_impl::Forward_functor<typename Base_traits::Equal_3, PointPropertyMap> Equal_3;
typedef Convex_hull_impl::Forward_functor<typename Base_traits::Collinear_3, PointPropertyMap> Collinear_3;
typedef Convex_hull_impl::Forward_functor<typename Base_traits::Coplanar_3, PointPropertyMap> Coplanar_3;
typedef Convex_hull_impl::Forward_functor<typename Base_traits::Less_distance_to_point_3, PointPropertyMap> Less_distance_to_point_3;
Extreme_points_traits_adapter_3(const PointPropertyMap& vpmap,
Base_traits base = Base_traits())
:
Base_traits(base), vpm_(vpmap)
{ }
typedef typename boost::property_traits<PointPropertyMap>::key_type Vertex;
typedef Vertex Point_3;
typedef Convex_hull_3::internal::Forward_functor<
typename Base_traits::Equal_3, PointPropertyMap> Equal_3;
typedef Convex_hull_3::internal::Forward_functor<
typename Base_traits::Collinear_3, PointPropertyMap> Collinear_3;
typedef Convex_hull_3::internal::Forward_functor<
typename Base_traits::Coplanar_3, PointPropertyMap> Coplanar_3;
typedef Convex_hull_3::internal::Forward_functor<
typename Base_traits::Less_distance_to_point_3, PointPropertyMap> Less_distance_to_point_3;
class Less_signed_distance_to_plane_3
:public Base_traits::Less_signed_distance_to_plane_3
: public Base_traits::Less_signed_distance_to_plane_3
{
PointPropertyMap vpm_;
const typename Base_traits::Less_signed_distance_to_plane_3& base;
public:
typedef typename Base_traits::Plane_3 Plane_3;
typedef typename Base_traits::Plane_3 Plane_3;
typedef bool result_type;
typedef bool result_type;
Less_signed_distance_to_plane_3(const PointPropertyMap& map,
const typename Base_traits::Less_signed_distance_to_plane_3& base)
: Base_traits::Less_signed_distance_to_plane_3(base), vpm_(map), base(base)
{ }
Less_signed_distance_to_plane_3(
const PointPropertyMap& map,
const typename Base_traits::Less_signed_distance_to_plane_3& base):
Base_traits::Less_signed_distance_to_plane_3(base),vpm_(map), base(base){}
bool
operator()( const Plane_3& h, const Vertex& p, const Vertex& q) const
bool operator()(const Plane_3& h, const Vertex& p, const Vertex& q) const
{
return base(h, get(vpm_,p), get(vpm_,q));
return base(h, get(vpm_, p), get(vpm_, q));
}
};
Equal_3 equal_3_object() const
{ return Equal_3(vpm_, static_cast<const Base_traits*>(this)->equal_3_object()); }
Collinear_3 collinear_3_object() const
{ return Collinear_3(vpm_, static_cast<const Base_traits*>(this)->collinear_3_object()); }
Coplanar_3 coplanar_3_object() const
{ return Coplanar_3(vpm_, static_cast<const Base_traits*>(this)->coplanar_3_object()); }
Less_distance_to_point_3 less_distance_to_point_3_object() const
{ return Less_distance_to_point_3(vpm_, static_cast<const Base_traits*>(this)->less_distance_to_point_3_object()); }
Less_signed_distance_to_plane_3 less_signed_distance_to_plane_3_object() const
{ return Less_signed_distance_to_plane_3(vpm_, static_cast<const Base_traits*>(this)->less_signed_distance_to_plane_3_object()); }
Equal_3 equal_3_object () const {return Equal_3(vpm_,static_cast<const Base_traits*>(this)->equal_3_object() );}
Collinear_3 collinear_3_object () const {return Collinear_3(vpm_,static_cast<const Base_traits*>(this)->collinear_3_object() );}
Coplanar_3 coplanar_3_object () const {return Coplanar_3(vpm_,static_cast<const Base_traits*>(this)->coplanar_3_object() );}
Less_distance_to_point_3 less_distance_to_point_3_object() const {
return Less_distance_to_point_3(vpm_,static_cast<const Base_traits*>(this)->less_distance_to_point_3_object() );}
Less_signed_distance_to_plane_3 less_signed_distance_to_plane_3_object() const {
return Less_signed_distance_to_plane_3(
vpm_,static_cast<const Base_traits*>(this)->less_signed_distance_to_plane_3_object() );
}
class Construct_plane_3:public Base_traits::Construct_plane_3
class Construct_plane_3
: public Base_traits::Construct_plane_3
{
PointPropertyMap vpm_;
const typename Base_traits::Construct_plane_3& base;
public:
Construct_plane_3(const PointPropertyMap& map, const typename Base_traits::Construct_plane_3& base):
Base_traits::Construct_plane_3(base),vpm_(map), base(base){}
typename Base_traits::Plane_3 operator()(const Vertex& p, const Vertex& q, const Vertex& r)const
Construct_plane_3(const PointPropertyMap& map,
const typename Base_traits::Construct_plane_3& base)
: Base_traits::Construct_plane_3(base), vpm_(map), base(base)
{ }
typename Base_traits::Plane_3 operator()(const Vertex& p, const Vertex& q, const Vertex& r) const
{
return base(get(vpm_,p),get(vpm_,q),get(vpm_,r));
return base(get(vpm_, p), get(vpm_, q), get(vpm_, r));
}
};
Construct_plane_3 construct_plane_3_object() const
{return Construct_plane_3(vpm_,static_cast<const Base_traits*>(this)->construct_plane_3_object());}
class Has_on_positive_side_3:public Base_traits::Has_on_positive_side_3
Construct_plane_3 construct_plane_3_object() const
{return Construct_plane_3(vpm_, static_cast<const Base_traits*>(this)->construct_plane_3_object());}
class Has_on_positive_side_3
: public Base_traits::Has_on_positive_side_3
{
PointPropertyMap vpm_;
const typename Base_traits::Has_on_positive_side_3& base;
public:
Has_on_positive_side_3(const PointPropertyMap& map,const typename Base_traits::Has_on_positive_side_3& base):
Base_traits::Has_on_positive_side_3(base),vpm_(map), base(base){}
typedef typename Base_traits::Plane_3 Plane_3;
public:
typedef bool result_type;
Has_on_positive_side_3(const PointPropertyMap& map,
const typename Base_traits::Has_on_positive_side_3& base)
: Base_traits::Has_on_positive_side_3(base), vpm_(map), base(base)
{ }
result_type
operator()( const Plane_3& pl, const Vertex& p) const
typedef typename Base_traits::Plane_3 Plane_3;
public:
typedef bool result_type;
result_type operator()( const Plane_3& pl, const Vertex& p) const
{
return base(pl, get(vpm_, p));
}
};
Has_on_positive_side_3 has_on_positive_side_3_object() const {return Has_on_positive_side_3(
vpm_,static_cast<const Base_traits*>(this)->has_on_positive_side_3_object() );}
Has_on_positive_side_3 has_on_positive_side_3_object() const
{ return Has_on_positive_side_3(vpm_, static_cast<const Base_traits*>(this)->has_on_positive_side_3_object()); }
template<class Base_proj_traits>
class Proj_traits_3:public Base_proj_traits
class Proj_traits_3
: public Base_proj_traits
{
PointPropertyMap vpm_;
typedef Base_proj_traits Btt;
public:
Proj_traits_3(const PointPropertyMap& map,const Btt& base):
Base_proj_traits(base),vpm_(map){}
typedef Point_3 Point_2;
typedef Convex_hull_impl::Forward_functor<typename Btt::Equal_2, PointPropertyMap> Equal_2;
typedef Convex_hull_impl::Forward_functor<typename Btt::Less_xy_2, PointPropertyMap> Less_xy_2;
typedef Convex_hull_impl::Forward_functor<typename Btt::Less_yx_2, PointPropertyMap> Less_yx_2;
typedef Convex_hull_impl::Forward_functor<typename Btt::Less_signed_distance_to_line_2, PointPropertyMap> Less_signed_distance_to_line_2;
typedef Convex_hull_impl::Forward_functor<typename Btt::Left_turn_2, PointPropertyMap> Left_turn_2;
class Less_rotate_ccw_2:public Btt::Less_rotate_ccw_2
public:
Proj_traits_3(const PointPropertyMap& map, const Btt& base)
: Base_proj_traits(base), vpm_(map)
{ }
typedef Point_3 Point_2;
typedef Convex_hull_3::internal::Forward_functor<
typename Btt::Equal_2, PointPropertyMap> Equal_2;
typedef Convex_hull_3::internal::Forward_functor<
typename Btt::Less_xy_2, PointPropertyMap> Less_xy_2;
typedef Convex_hull_3::internal::Forward_functor<
typename Btt::Less_yx_2, PointPropertyMap> Less_yx_2;
typedef Convex_hull_3::internal::Forward_functor<
typename Btt::Less_signed_distance_to_line_2, PointPropertyMap> Less_signed_distance_to_line_2;
typedef Convex_hull_3::internal::Forward_functor<
typename Btt::Left_turn_2, PointPropertyMap> Left_turn_2;
class Less_rotate_ccw_2
: public Btt::Less_rotate_ccw_2
{
PointPropertyMap vpm_;
const typename Btt::Less_rotate_ccw_2& base;
public:
Less_rotate_ccw_2(const PointPropertyMap& map,const typename Btt::Less_rotate_ccw_2& base):
Btt::Less_rotate_ccw_2(base),vpm_(map), base(base){}
Less_rotate_ccw_2(const PointPropertyMap& map,
const typename Btt::Less_rotate_ccw_2& base)
: Btt::Less_rotate_ccw_2(base), vpm_(map), base(base)
{ }
public:
bool operator()(Point_2 e, Point_2 p,Point_2 q) const
bool operator()(const Point_2& e, const Point_2& p, const Point_2& q) const
{
return base(get(vpm_, e), get(vpm_, p), get(vpm_, q));
}
};
Equal_2 equal_2_object () const {return Equal_2(vpm_,static_cast<const Btt*>(this)->equal_2_object() );}
Less_xy_2 less_xy_2_object ()const{return Less_xy_2(vpm_,static_cast<const Btt*>(this)->less_xy_2_object() );}
Less_yx_2 less_yx_2_object ()const{return Less_yx_2(vpm_,static_cast<const Btt*>(this)->less_yx_2_object() );}
Less_signed_distance_to_line_2 less_signed_distance_to_line_2_object ()const
{return Less_signed_distance_to_line_2(vpm_,static_cast<const Btt*>(this)->Less_signed_distance_to_line_2() );}
Less_rotate_ccw_2 less_rotate_ccw_2_object ()const
{return Less_rotate_ccw_2(vpm_,static_cast<const Btt*>(this)->less_rotate_ccw_2_object() );}
Left_turn_2 left_turn_2_object ()const{return Left_turn_2(vpm_,static_cast<const Btt*>(this)->left_turn_2_object() );}
Equal_2 equal_2_object() const
{ return Equal_2(vpm_, static_cast<const Btt*>(this)->equal_2_object()); }
Less_xy_2 less_xy_2_object() const
{ return Less_xy_2(vpm_, static_cast<const Btt*>(this)->less_xy_2_object()); }
Less_yx_2 less_yx_2_object() const
{ return Less_yx_2(vpm_, static_cast<const Btt*>(this)->less_yx_2_object()); }
Less_signed_distance_to_line_2 less_signed_distance_to_line_2_object() const
{ return Less_signed_distance_to_line_2(vpm_, static_cast<const Btt*>(this)->Less_signed_distance_to_line_2()); }
Less_rotate_ccw_2 less_rotate_ccw_2_object() const
{ return Less_rotate_ccw_2(vpm_, static_cast<const Btt*>(this)->less_rotate_ccw_2_object()); }
Left_turn_2 left_turn_2_object() const
{ return Left_turn_2(vpm_, static_cast<const Btt*>(this)->left_turn_2_object()); }
class Orientation_2:public Btt::Orientation_2
class Orientation_2
: public Btt::Orientation_2
{
PointPropertyMap vpm_;
const typename Btt::Orientation_2& base;
public:
Orientation_2(const PointPropertyMap& map,const typename Btt::Orientation_2& base):
Btt::Orientation_2(base),vpm_(map), base(base){}
typename CGAL::Orientation operator()(Point_2 e,Point_2 p, Point_2 q) const
public:
Orientation_2(const PointPropertyMap& map,
const typename Btt::Orientation_2& base)
: Btt::Orientation_2(base), vpm_(map), base(base)
{ }
typename CGAL::Orientation operator()(const Point_2& e, const Point_2& p, const Point_2& q) const
{
return base(get(vpm_, e), get(vpm_, p), get(vpm_, q));
}
};
Orientation_2 orientation_2_object ()const{return Orientation_2(vpm_,static_cast<const Btt*>(this)->orientation_2_object() );}
Orientation_2 orientation_2_object() const
{ return Orientation_2(vpm_, static_cast<const Btt*>(this)->orientation_2_object()); }
};
typedef internal::Convex_hull_3::Projection_traits<Base_traits> Base_PTraits;
typedef Proj_traits_3<typename Base_PTraits::Traits_xy_3> Traits_xy_3;
typedef Proj_traits_3<typename Base_PTraits::Traits_yz_3> Traits_yz_3;
typedef Proj_traits_3<typename Base_PTraits::Traits_xz_3> Traits_xz_3;
typedef Convex_hull_3::internal::Projection_traits<Base_traits> Base_PTraits;
typedef Proj_traits_3<typename Base_PTraits::Traits_xy_3> Traits_xy_3;
typedef Proj_traits_3<typename Base_PTraits::Traits_yz_3> Traits_yz_3;
typedef Proj_traits_3<typename Base_PTraits::Traits_xz_3> Traits_xz_3;
Traits_xy_3 construct_traits_xy_3_object()const
{return Traits_xy_3(vpm_, Base_PTraits(static_cast<const Base_traits&>(*this)).construct_traits_xy_3_object());}
Traits_yz_3 construct_traits_yz_3_object()const
{return Traits_yz_3(vpm_, Base_PTraits(static_cast<const Base_traits&>(*this)).construct_traits_yz_3_object());}
Traits_xz_3 construct_traits_xz_3_object()const
{return Traits_xz_3(vpm_, Base_PTraits(static_cast<const Base_traits&>(*this)).construct_traits_xz_3_object());}
Traits_xy_3 construct_traits_xy_3_object() const
{ return Traits_xy_3(vpm_, Base_PTraits(static_cast<const Base_traits&>(*this)).construct_traits_xy_3_object()); }
Traits_yz_3 construct_traits_yz_3_object() const
{ return Traits_yz_3(vpm_, Base_PTraits(static_cast<const Base_traits&>(*this)).construct_traits_yz_3_object()); }
Traits_xz_3 construct_traits_xz_3_object() const
{ return Traits_xz_3(vpm_, Base_PTraits(static_cast<const Base_traits&>(*this)).construct_traits_xz_3_object()); }
typename boost::property_traits<PointPropertyMap>::reference
get_point(const typename boost::property_traits<PointPropertyMap>::key_type& k) const
{
return get(vpm_, k);
}
};
template<class PointPropertyMap,class Base_traits>
Extreme_points_traits_adapter_3<PointPropertyMap, Base_traits>
make_extreme_points_traits_adapter(const PointPropertyMap& pmap, Base_traits traits = Base_traits())
make_extreme_points_traits_adapter(const PointPropertyMap& pmap,
Base_traits traits = Base_traits())
{
return Extreme_points_traits_adapter_3<PointPropertyMap, Base_traits>(pmap, traits);
}
@ -245,9 +283,6 @@ make_extreme_points_traits_adapter(const PointPropertyMap& pmap)
return Extreme_points_traits_adapter_3<PointPropertyMap>(pmap);
}
//helper function
}//end CGAL
} // namespace CGAL
#endif // CGAL_EXTREME_POINTS_TRAITS_ADAPTER_3_H

View File

@ -31,21 +31,10 @@
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Cartesian_converter.h>
#include <CGAL/Simple_cartesian.h>
#include <iostream>
#include <algorithm>
#include <utility>
#include <memory>
#include <list>
#include <vector>
#include <type_traits>
#include <boost/bind.hpp>
#include <boost/next_prior.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/graph/graph_traits.hpp>
#include <CGAL/internal/Exact_type_selector.h>
#include <CGAL/boost/graph/copy_face_graph.h>
#include <CGAL/boost/graph/Named_function_parameters.h>
#include <CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h>
#include <CGAL/boost/graph/properties_Triangulation_data_structure_2.h>
#include <CGAL/Polyhedron_3_fwd.h>
@ -54,12 +43,24 @@
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/is_iterator.h>
#include <boost/unordered_map.hpp>
#include <boost/bind.hpp>
#include <boost/next_prior.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/graph/graph_traits.hpp>
#ifndef CGAL_CH_NO_POSTCONDITIONS
#include <CGAL/convexity_check_3.h>
#endif // CGAL_CH_NO_POSTCONDITIONS
#include <algorithm>
#include <iostream>
#include <list>
#include <memory>
#include <vector>
#include <type_traits>
#include <utility>
// first some internal stuff to avoid using a true Face_graph model for extreme_points_3
namespace CGAL {
@ -67,7 +68,8 @@ namespace CGAL {
// Forward declaration
template<class VertexPointMap,class Base_traits> class Extreme_points_traits_adapter_3;
namespace internal{ namespace Convex_hull_3{
namespace Convex_hull_3 {
namespace internal {
// wrapper used as a MutableFaceGraph to extract extreme points
template <class OutputIterator>
@ -81,29 +83,30 @@ struct Output_iterator_wrapper
template <class Point_3, class OutputIterator>
void add_isolated_points(const Point_3& point,
internal::Convex_hull_3::Output_iterator_wrapper<OutputIterator>& w)
Convex_hull_3::internal::Output_iterator_wrapper<OutputIterator>& w)
{
*w.out++ = point;
}
template <class Point_3, class Polyhedron_3>
void add_isolated_points(const Point_3& point, Polyhedron_3& P)
template <class Point_3, class PolygonMesh>
void add_isolated_points(const Point_3& point, PolygonMesh& P)
{
put(get(CGAL::vertex_point, P), add_vertex(P), point);
}
template <class Point_3, class OutputIterator>
void copy_ch2_to_face_graph(const std::list<Point_3>& CH_2,
internal::Convex_hull_3::Output_iterator_wrapper<OutputIterator>& w)
Convex_hull_3::internal::Output_iterator_wrapper<OutputIterator>& w)
{
for(const Point_3& p : CH_2)
*w.out++ = p;
}
} } // internal::Convex_hull_3
} // namespace internal
} // namespace Convex_hull_3
template <class TDS, class OutputIterator>
void copy_face_graph(const TDS& tds, internal::Convex_hull_3::Output_iterator_wrapper<OutputIterator>& wrapper)
void copy_face_graph(const TDS& tds, Convex_hull_3::internal::Output_iterator_wrapper<OutputIterator>& wrapper)
{
typedef typename boost::graph_traits<TDS>::vertex_descriptor vertex_descriptor;
typename boost::property_map<TDS, boost::vertex_point_t >::const_type vpm = get(boost::vertex_point, tds);
@ -114,12 +117,12 @@ void copy_face_graph(const TDS& tds, internal::Convex_hull_3::Output_iterator_wr
}
template <class OutputIterator>
void clear(internal::Convex_hull_3::Output_iterator_wrapper<OutputIterator>&)
void clear(Convex_hull_3::internal::Output_iterator_wrapper<OutputIterator>&)
{}
template <class Point, class OutputIterator>
void make_tetrahedron(const Point& p0, const Point& p1, const Point& p2, const Point& p3,
internal::Convex_hull_3::Output_iterator_wrapper<OutputIterator>& w)
Convex_hull_3::internal::Output_iterator_wrapper<OutputIterator>& w)
{
*w.out++ = p0;
*w.out++ = p1;
@ -129,19 +132,20 @@ void make_tetrahedron(const Point& p0, const Point& p1, const Point& p2, const P
} // CGAL
namespace boost{
namespace boost {
// needed so that the regular make_tetrahedron of CGAL does not complain when tried to be instantiated
template <class OutputIterator>
struct graph_traits<CGAL::internal::Convex_hull_3::Output_iterator_wrapper<OutputIterator> >
struct graph_traits<CGAL::Convex_hull_3::internal::Output_iterator_wrapper<OutputIterator> >
{
typedef void* halfedge_descriptor;
};
}
} // namespace boost
namespace CGAL {
namespace internal{ namespace Convex_hull_3{
namespace Convex_hull_3 {
namespace internal {
//struct to select the default traits class for computing convex hull
template< class Point_3,
@ -383,7 +387,7 @@ struct Projection_traits{
typedef CGAL::Projection_traits_xy_3<K> Traits_xy_3;
typedef CGAL::Projection_traits_yz_3<K> Traits_yz_3;
typedef CGAL::Projection_traits_xz_3<K> Traits_xz_3;
Traits_xy_3 construct_traits_xy_3_object()const
{return Traits_xy_3();}
Traits_yz_3 construct_traits_yz_3_object()const
@ -407,12 +411,12 @@ struct Projection_traits<T,true>{
{return traits.construct_traits_xz_3_object();}
};
template <class Point_3, class Polyhedron_3>
void copy_ch2_to_face_graph(const std::list<Point_3>& CH_2, Polyhedron_3& P)
template <class Point_3, class PolygonMesh>
void copy_ch2_to_face_graph(const std::list<Point_3>& CH_2, PolygonMesh& P)
{
typename boost::property_map<Polyhedron_3, CGAL::vertex_point_t>::type vpm
typename boost::property_map<PolygonMesh, CGAL::vertex_point_t>::type vpm
= get(CGAL::vertex_point, P);
typedef boost::graph_traits<Polyhedron_3> Graph_traits;
typedef boost::graph_traits<PolygonMesh> Graph_traits;
typedef typename Graph_traits::vertex_descriptor vertex_descriptor;
typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor;
typedef typename Graph_traits::face_descriptor face_descriptor;
@ -435,16 +439,16 @@ void copy_ch2_to_face_graph(const std::list<Point_3>& CH_2, Polyhedron_3& P)
}
template <class InputIterator, class Point_3, class Polyhedron_3, class Traits>
template <class InputIterator, class Point_3, class PolygonMesh, class Traits>
void coplanar_3_hull(InputIterator first, InputIterator beyond,
const Point_3& p1, const Point_3& p2, const Point_3& p3,
Polyhedron_3& P, const Traits& traits )
PolygonMesh& P, const Traits& traits )
{
typedef typename internal::Convex_hull_3::Projection_traits<Traits> PTraits;
typedef typename Convex_hull_3::internal::Projection_traits<Traits> PTraits;
typedef typename PTraits::Traits_xy_3 Traits_xy_3;
typedef typename PTraits::Traits_yz_3 Traits_yz_3;
typedef typename PTraits::Traits_xz_3 Traits_xz_3;
PTraits ptraits(traits);
std::list<Point_3> CH_2;
@ -562,7 +566,7 @@ farthest_outside_point(Face_handle f, std::list<Point>& outside_set,
typedef typename std::list<Point>::iterator Outside_set_iterator;
CGAL_ch_assertion(!outside_set.empty());
typename Traits::Plane_3 plane =
typename Traits::Plane_3 plane =
traits.construct_plane_3_object()(f->vertex(0)->point(),
f->vertex(1)->point(),
f->vertex(2)->point());
@ -629,7 +633,7 @@ ch_quickhull_3_scan(TDS_2& tds,
typedef typename TDS_2::Edge Edge;
typedef typename TDS_2::Face_handle Face_handle;
typedef typename TDS_2::Vertex_handle Vertex_handle;
typedef typename Traits::Point_3 Point_3;
typedef typename Traits::Point_3 Point_3;
typedef std::list<Point_3> Outside_set;
typedef typename std::list<Point_3>::iterator Outside_set_iterator;
typedef std::map<typename TDS_2::Vertex_handle, typename TDS_2::Edge> Border_edges;
@ -758,15 +762,15 @@ void non_coplanar_quickhull_3(std::list<typename Traits::Point_3>& points,
// CGAL_ch_postcondition(is_strongly_convex_3(P, traits));
}
template <class InputIterator, class Polyhedron_3, class Traits>
template <class InputIterator, class PolygonMesh, class Traits>
void
ch_quickhull_polyhedron_3(std::list<typename Traits::Point_3>& points,
InputIterator point1_it, InputIterator point2_it,
InputIterator point3_it, Polyhedron_3& P,
const Traits& traits)
ch_quickhull_face_graph(std::list<typename Traits::Point_3>& points,
InputIterator point1_it, InputIterator point2_it, InputIterator point3_it,
PolygonMesh& P,
const Traits& traits)
{
typedef typename Traits::Point_3 Point_3;
typedef typename Traits::Plane_3 Plane_3;
typedef typename Traits::Point_3 Point_3;
typedef typename Traits::Plane_3 Plane_3;
typedef typename std::list<Point_3>::iterator P3_iterator;
typedef Triangulation_data_structure_2<
@ -848,14 +852,16 @@ ch_quickhull_polyhedron_3(std::list<typename Traits::Point_3>& points,
}
} } //namespace internal::Convex_hull_3
} // namespace internal
} // namespace Convex_hull_3
template <class InputIterator, class Traits>
void
convex_hull_3(InputIterator first, InputIterator beyond,
Object& ch_object, const Traits& traits)
Object& ch_object,
const Traits& traits)
{
typedef typename Traits::Point_3 Point_3;
typedef typename Traits::Point_3 Point_3;
typedef std::list<Point_3> Point_3_list;
typedef typename Point_3_list::iterator P3_iterator;
typedef std::pair<P3_iterator,P3_iterator> P3_iterator_pair;
@ -936,7 +942,7 @@ convex_hull_3(InputIterator first, InputIterator beyond,
}
// result will be a polyhedron
typedef typename internal::Convex_hull_3::Default_polyhedron_for_Chull_3<Traits>::type Polyhedron;
typedef typename Convex_hull_3::internal::Default_polyhedron_for_Chull_3<Traits>::type Polyhedron;
Polyhedron P;
P3_iterator minx, maxx, miny, it;
@ -948,9 +954,9 @@ convex_hull_3(InputIterator first, InputIterator beyond,
if(it->y() < miny->y()) miny = it;
}
if(! collinear(*minx, *maxx, *miny) ){
internal::Convex_hull_3::ch_quickhull_polyhedron_3(points, minx, maxx, miny, P, traits);
Convex_hull_3::internal::ch_quickhull_face_graph(points, minx, maxx, miny, P, traits);
} else {
internal::Convex_hull_3::ch_quickhull_polyhedron_3(points, point1_it, point2_it, point3_it, P, traits);
Convex_hull_3::internal::ch_quickhull_face_graph(points, point1_it, point2_it, point3_it, P, traits);
}
CGAL_assertion(num_vertices(P)>=3);
typename boost::graph_traits<Polyhedron>::vertex_iterator b,e;
@ -973,18 +979,18 @@ convex_hull_3(InputIterator first, InputIterator beyond,
template <class InputIterator>
void convex_hull_3(InputIterator first, InputIterator beyond, Object& ch_object)
void convex_hull_3(InputIterator first, InputIterator beyond,
Object& ch_object)
{
typedef typename std::iterator_traits<InputIterator>::value_type Point_3;
typedef typename internal::Convex_hull_3::Default_traits_for_Chull_3<Point_3>::type Traits;
typedef typename Convex_hull_3::internal::Default_traits_for_Chull_3<Point_3>::type Traits;
convex_hull_3(first, beyond, ch_object, Traits());
}
template <class InputIterator, class Polyhedron_3, class Traits>
template <class InputIterator, class PolygonMesh, class Traits>
void convex_hull_3(InputIterator first, InputIterator beyond,
Polyhedron_3& polyhedron, const Traits& traits)
PolygonMesh& polyhedron,
const Traits& traits)
{
typedef typename Traits::Point_3 Point_3;
typedef std::list<Point_3> Point_3_list;
@ -1009,7 +1015,7 @@ void convex_hull_3(InputIterator first, InputIterator beyond,
// if there is only one point or all points are equal
if(point2_it == points.end())
{
internal::Convex_hull_3::add_isolated_points(*point1_it, polyhedron);
Convex_hull_3::internal::add_isolated_points(*point1_it, polyhedron);
return;
}
@ -1028,39 +1034,38 @@ void convex_hull_3(InputIterator first, InputIterator beyond,
min_max_element(points.begin(), points.end(),
boost::bind(less_dist, *points.begin(), _1, _2),
boost::bind(less_dist, *points.begin(), _1, _2));
internal::Convex_hull_3::add_isolated_points(*endpoints.first, polyhedron);
internal::Convex_hull_3::add_isolated_points(*endpoints.second, polyhedron);
Convex_hull_3::internal::add_isolated_points(*endpoints.first, polyhedron);
Convex_hull_3::internal::add_isolated_points(*endpoints.second, polyhedron);
return;
}
internal::Convex_hull_3::ch_quickhull_polyhedron_3(points, point1_it, point2_it, point3_it,
Convex_hull_3::internal::ch_quickhull_face_graph(points, point1_it, point2_it, point3_it,
polyhedron, traits);
}
template <class InputIterator, class Polyhedron_3>
template <class InputIterator, class PolygonMesh>
void convex_hull_3(InputIterator first, InputIterator beyond,
Polyhedron_3& polyhedron,
typename std::enable_if<
CGAL::is_iterator<InputIterator>::value
>::type* =0) //workaround to avoid ambiguity with next overload.
PolygonMesh& polyhedron,
// workaround to avoid ambiguity with next overload.
typename std::enable_if<CGAL::is_iterator<InputIterator>::value>::type* = 0)
{
typedef typename std::iterator_traits<InputIterator>::value_type Point_3;
typedef typename internal::Convex_hull_3::Default_traits_for_Chull_3<Point_3, Polyhedron_3>::type Traits;
convex_hull_3(first, beyond, polyhedron, Traits());
typedef typename std::iterator_traits<InputIterator>::value_type Point_3;
typedef typename Convex_hull_3::internal::Default_traits_for_Chull_3<Point_3, PolygonMesh>::type Traits;
convex_hull_3(first, beyond, polyhedron, Traits());
}
template <class VertexListGraph, class PolygonMesh, class NamedParameters>
void convex_hull_3(const VertexListGraph& g,
PolygonMesh& pm,
PolygonMesh& pm,
const NamedParameters& np)
{
using CGAL::parameters::choose_parameter;
using CGAL::parameters::get_parameter;
typedef typename GetVertexPointMap<VertexListGraph, NamedParameters>::const_type Vpmap;
typedef CGAL::Property_map_to_unary_function<Vpmap> Vpmap_fct;
Vpmap vpm = CGAL::parameters::choose_parameter(
CGAL::parameters::get_parameter(np, internal_np::vertex_point),
get_const_property_map(boost::vertex_point, g));
Vpmap vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(boost::vertex_point, g));
Vpmap_fct v2p(vpm);
convex_hull_3(boost::make_transform_iterator(vertices(g).begin(), v2p),
@ -1080,7 +1085,7 @@ extreme_points_3(const InputRange& range,
OutputIterator out,
const Traits& traits)
{
internal::Convex_hull_3::Output_iterator_wrapper<OutputIterator> wrapper(out);
Convex_hull_3::internal::Output_iterator_wrapper<OutputIterator> wrapper(out);
convex_hull_3(range.begin(), range.end(), wrapper, traits);
return out;
}
@ -1091,7 +1096,7 @@ extreme_points_3(const InputRange& range, OutputIterator out)
{
typedef typename InputRange::const_iterator Iterator_type;
typedef typename std::iterator_traits<Iterator_type>::value_type Point_3;
typedef typename internal::Convex_hull_3::Default_traits_for_Chull_3<Point_3>::type Traits;
typedef typename Convex_hull_3::internal::Default_traits_for_Chull_3<Point_3>::type Traits;
return extreme_points_3(range, out, Traits());
}

View File

@ -1,37 +0,0 @@
// Copyright (c) 2011 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Sebastien Loriot
//
#ifndef CGAL_CONVEX_HULL_3_TO_POLYHEDRON_3_H
#define CGAL_CONVEX_HULL_3_TO_POLYHEDRON_3_H
#include <CGAL/license/Convex_hull_3.h>
#define CGAL_DEPRECATED_HEADER "<CGAL/convex_hull_3_to_polyhedron_3.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/convex_hull_3_to_face_graph.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/Polyhedron_3_fwd.h>
namespace CGAL {
template<class Triangulation_3,class Polyhedron_3>
CGAL_DEPRECATED void convex_hull_3_to_polyhedron_3(const Triangulation_3& T,Polyhedron_3& P){
clear(P);
link_to_face_graph(T,T.infinite_vertex(), P);
}
} //namespace CGAL
#endif //CGAL_CONVEX_HULL_3_TO_POLYHEDRON_3_H

View File

@ -19,7 +19,7 @@ typedef CGAL::Simple_cartesian<double> SCD;
typedef CGAL::Simple_homogeneous<double> SHD;
typedef CGAL::Simple_cartesian<Exact_rational> SCR;
using namespace CGAL::internal::Convex_hull_3;
using namespace CGAL::Convex_hull_3::internal;
int main()
{

View File

@ -52,7 +52,7 @@ void test_triangulated_cube(const char* fname)
std::ifstream input(fname);
SurfaceMesh mesh;
if (!input || !(input >> mesh) || mesh.is_empty()) {
std::cerr << fname << " is not a valid off file.\n";
std::cerr << fname << " is not a valid off file." << std::endl;
exit(1);
}
@ -206,9 +206,9 @@ void test_extreme_vertices(const char* fname)
std::ifstream input(fname);
Polyhedron_3 P;
if (!input || !(input >> P) || P.is_empty()) {
std::cerr << fname << " is not a valid off file.\n";
std::cerr << fname << " is not a valid off file." << std::endl;
exit(1);
}
}
/*CGAL::Extreme_points_traits_adapter_3<
boost::property_map<Polyhedron_3, CGAL::vertex_point_t>::type
,
@ -216,9 +216,9 @@ void test_extreme_vertices(const char* fname)
>
traits(get(CGAL::vertex_point, P));*/
CGAL::Convex_hull_traits_3<K, Polyhedron_3, CGAL::Tag_true> traits;
boost::property_map<Polyhedron_3, CGAL::vertex_point_t>::type pmap =
boost::property_map<Polyhedron_3, CGAL::vertex_point_t>::type pmap =
get(CGAL::vertex_point, P);
std::vector<boost::graph_traits<Polyhedron_3>::vertex_descriptor> verts;
CGAL::extreme_points_3(vertices(P), std::back_inserter(verts) ,
CGAL::make_extreme_points_traits_adapter(pmap, traits));

View File

@ -130,6 +130,7 @@
\package_listing{Box_intersection_d}
\package_listing{AABB_tree}
\package_listing{Spatial_sorting}
\package_listing{Optimal_bounding_box}
\cgalPackageSection{PartGeometricOptimization,Geometric Optimization}

View File

@ -405,6 +405,17 @@ Boissonnat}
,update = "97.08 kettner"
}
@article{ cgal:cgm-fobbo-11,
title={Fast oriented bounding box optimization on the rotation group SO (3, )},
author={Chang, Chia-Tche and Gorissen, Bastien and Melchior, Samuel},
journal={ACM Transactions on Graphics (TOG)},
volume={30},
number={5},
pages={122},
year={2011},
publisher={ACM}
}
@article{ cgal:cht-oacov-90
,author = {M. Chang and N. Huang and C. Tang}
,title = {An optimal algorithm for constructing oriented Voronoi diagrams

View File

@ -0,0 +1,54 @@
// 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_OPTIMAL_BOUNDING_BOX_H
#define CGAL_LICENSE_OPTIMAL_BOUNDING_BOX_H
#include <CGAL/config.h>
#include <CGAL/license.h>
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_COMMERCIAL_LICENSE
# if CGAL_OPTIMAL_BOUNDING_BOX_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 Optimal Bounding Box package.")
# endif
# ifdef CGAL_LICENSE_ERROR
# error "Your commercial license for CGAL does not cover this release \
of the Optimal Bounding Box package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
# endif // CGAL_OPTIMAL_BOUNDING_BOX_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
#else // no CGAL_OPTIMAL_BOUNDING_BOX_COMMERCIAL_LICENSE
# if defined(CGAL_LICENSE_WARNING)
CGAL_pragma_warning("\nThe macro CGAL_OPTIMAL_BOUNDING_BOX_COMMERCIAL_LICENSE is not defined."
"\nYou use the CGAL Optimal Bounding Box package under "
"the terms of the GPLv3+.")
# endif // CGAL_LICENSE_WARNING
# ifdef CGAL_LICENSE_ERROR
# error "The macro CGAL_OPTIMAL_BOUNDING_BOX_COMMERCIAL_LICENSE is not defined.\
You use the CGAL Optimal Bounding Box package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
#endif // no CGAL_OPTIMAL_BOUNDING_BOX_COMMERCIAL_LICENSE
#endif // CGAL_LICENSE_OPTIMAL_BOUNDING_BOX_H

View File

@ -32,6 +32,7 @@ Minkowski_sum_3 3D Minkowski Sum of Polyhedra
Nef_2 2D Boolean Operations on Nef Polygons
Nef_3 3D Boolean Operations on Nef Polyhedra
Nef_S2 2D Boolean Operations on Nef Polygons Embedded on the Sphere
Optimal_bounding_box Optimal Bounding Box
Optimal_transportation_reconstruction_2 Optimal Transportation Curve Reconstruction
Partition_2 2D Polygon Partitioning
Periodic_2_triangulation_2 2D Periodic Triangulations

View File

@ -20,7 +20,7 @@
#include <CGAL/Kernel/global_functions_2.h>
namespace CGAL {
namespace CGAL {
namespace internal {
@ -37,8 +37,8 @@ struct Projector<R,0>
typedef typename R::Compare_y_3 Compare_x_2;
typedef typename R::Compare_z_3 Compare_y_2;
typedef typename R::Equal_y_3 Equal_x_2;
typedef typename R::Equal_z_3 Equal_y_2;
typedef typename R::Equal_z_3 Equal_y_2;
static typename R::FT x(const typename R::Point_3& p) {return p.y();}
static typename R::FT y(const typename R::Point_3& p) {return p.z();}
static typename R::FT x(const typename R::Vector_3& p) {return p.y();}
@ -54,16 +54,16 @@ struct Projector<R,1>
typedef typename R::Less_x_3 Less_x_2;
typedef typename R::Less_z_3 Less_y_2;
typedef typename R::Compare_x_3 Compare_x_2;
typedef typename R::Compare_z_3 Compare_y_2;
typedef typename R::Compare_z_3 Compare_y_2;
typedef typename R::Equal_x_3 Equal_x_2;
typedef typename R::Equal_z_3 Equal_y_2;
typedef typename R::Equal_z_3 Equal_y_2;
static typename R::FT x(const typename R::Point_3& p) {return p.x();}
static typename R::FT y(const typename R::Point_3& p) {return p.z();}
static typename R::FT x(const typename R::Vector_3& p) {return p.x();}
static typename R::FT y(const typename R::Vector_3& p) {return p.z();}
static Bbox_2 bbox(const Bbox_3& bb) { return Bbox_2(bb.xmin(),bb.zmin(),bb.xmax(),bb.zmax()); }
static const int x_index=0;
static const int y_index=2;
static const int y_index=2;
};
//project onto xy
@ -73,16 +73,16 @@ struct Projector<R,2>
typedef typename R::Less_x_3 Less_x_2;
typedef typename R::Less_y_3 Less_y_2;
typedef typename R::Compare_x_3 Compare_x_2;
typedef typename R::Compare_y_3 Compare_y_2;
typedef typename R::Compare_y_3 Compare_y_2;
typedef typename R::Equal_x_3 Equal_x_2;
typedef typename R::Equal_y_3 Equal_y_2;
typedef typename R::Equal_y_3 Equal_y_2;
static typename R::FT x(const typename R::Point_3& p) {return p.x();}
static typename R::FT y(const typename R::Point_3& p) {return p.y();}
static typename R::FT x(const typename R::Vector_3& p) {return p.x();}
static typename R::FT y(const typename R::Vector_3& p) {return p.y();}
static Bbox_2 bbox(const Bbox_3& bb) { return Bbox_2(bb.xmin(),bb.ymin(),bb.xmax(),bb.ymax()); }
static const int x_index=0;
static const int y_index=1;
static const int y_index=1;
};
template <class R,int dim>
@ -90,15 +90,15 @@ class Construct_bbox_projected_2 {
public:
typedef typename R::Point_3 Point;
typedef Bbox_2 result_type;
Bbox_2 operator()(const Point& p) const { typename R::Construct_bbox_3 bb; return Projector<R, dim>::bbox(bb(p)); }
};
template <class R,int dim>
class Orientation_projected_3
class Orientation_projected_3
{
public:
typedef typename R::Point_3 Point;
typedef typename R::Point_3 Point;
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); }
@ -108,18 +108,18 @@ public:
}
CGAL::Orientation operator()(const Point& p,
const Point& q,
const Point& r) const
const Point& q,
const Point& r) const
{
return CGAL::orientation(project(p), project(q), project(r));
}
};
template <class R,int dim>
class Side_of_oriented_circle_projected_3
class Side_of_oriented_circle_projected_3
{
public:
typedef typename R::Point_3 Point;
typedef typename R::Point_3 Point;
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); }
@ -128,20 +128,20 @@ public:
{
return typename R::Point_2(x(p),y(p));
}
CGAL::Oriented_side operator() (const Point &p,
const Point &q,
const Point &r,
const Point &s) const
CGAL::Oriented_side operator() (const Point &p,
const Point &q,
const Point &r,
const Point &s) const
{
return CGAL::side_of_oriented_circle(project(p),project(q),project(r),project(s) );
}
};
template <class R,int dim>
class Side_of_bounded_circle_projected_3
class Side_of_bounded_circle_projected_3
{
public:
typedef typename R::Point_3 Point;
typedef typename R::Point_3 Point;
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); }
@ -150,17 +150,17 @@ public:
{
return typename R::Point_2(x(p),y(p));
}
CGAL::Bounded_side operator() (const Point &p,
const Point &q,
const Point &r,
const Point &s) const
CGAL::Bounded_side operator() (const Point &p,
const Point &q,
const Point &r,
const Point &s) const
{
return CGAL::side_of_bounded_circle(project(p),project(q),project(r),project(s) );
}
CGAL::Bounded_side operator() (const Point &p,
const Point &q,
const Point &r) const
CGAL::Bounded_side operator() (const Point &p,
const Point &q,
const Point &r) const
{
return CGAL::side_of_bounded_circle(project(p),project(q),project(r));
}
@ -170,8 +170,8 @@ template <class R,int dim>
class Compare_distance_projected_3
{
public:
typedef typename R::Point_3 Point_3;
typedef typename R::Point_2 Point_2;
typedef typename R::Point_3 Point_3;
typedef typename R::Point_2 Point_2;
typedef typename R::FT RT;
typename R::FT x(const Point_3 &p) const { return Projector<R,dim>::x(p); }
typename R::FT y(const Point_3 &p) const { return Projector<R,dim>::y(p); }
@ -245,9 +245,9 @@ template <class R,int dim>
class Squared_distance_projected_3
{
public:
typedef typename R::Point_3 Point_3;
typedef typename R::Point_2 Point_2;
typedef typename R::Line_3 Line_3;
typedef typename R::Point_3 Point_3;
typedef typename R::Point_2 Point_2;
typedef typename R::Line_3 Line_3;
typedef typename R::Line_2 Line_2;
typedef typename R::Segment_3 Segment_3;
typedef typename R::Segment_2 Segment_2;
@ -262,9 +262,9 @@ public:
RT operator()(const Point_3& p, const Point_3& q) const
{
Point_2 p2(project(p));
Point_2 q2(project(q));
return squared_distance(p2, q2);
Point_2 p2(project(p));
Point_2 q2(project(q));
return squared_distance(p2, q2);
}
RT operator()(const Line_3& l, const Point_3& p) const
@ -273,7 +273,7 @@ public:
Line_2 l2(project(l.point(0)), project(l.point(1)));
return squared_distance(p2, l2);
}
RT operator()(const Segment_3& s, const Point_3& p) const
{
Point_2 p2(project(p));
@ -286,13 +286,13 @@ template <class R,int dim>
class Intersect_projected_3
{
public:
typedef typename R::Point_3 Point_3;
typedef typename R::Point_3 Point_3;
typedef typename R::Segment_3 Segment_3;
typedef typename R::Point_2 Point_2;
typedef typename R::Vector_2 Vector_2;
typedef typename R::Point_2 Point_2;
typedef typename R::Vector_2 Vector_2;
typedef typename R::Segment_2 Segment_2;
typedef typename R::FT FT;
typename R::FT x(const Point_3 &p) const { return Projector<R,dim>::x(p); }
typename R::FT y(const Point_3 &p) const { return Projector<R,dim>::y(p); }
@ -313,12 +313,12 @@ public:
Point_2 s1_source = project(s1.source());
Point_2 s1_target = project(s1.target());
Point_2 s2_source = project(s2.source());
Point_2 s2_target = project(s2.target());
Point_2 s2_target = project(s2.target());
Segment_2 s1_2(s1_source, s1_target);
Segment_2 s2_2(s2_source, s2_target);
CGAL_precondition(!s1_2.is_degenerate());
CGAL_precondition(!s2_2.is_degenerate());
//compute intersection points in projected plane
//We know that none of the segment is degenerate
Object o = intersection(s1_2,s2_2);
@ -342,7 +342,7 @@ public:
src[Projector<R,dim>::x_index] = si->source().x();
src[Projector<R,dim>::y_index] = si->source().y();
tgt[Projector<R,dim>::x_index] = si->target().x();
tgt[Projector<R,dim>::y_index] = si->target().y();
tgt[Projector<R,dim>::y_index] = si->target().y();
return make_object( Segment_3( Point_3(src[0],src[1],src[2]),Point_3(tgt[0],tgt[1],tgt[2]) ) );
}
FT coords[3];
@ -353,7 +353,7 @@ public:
coords[dim] = (z1+z2) / FT(2);
coords[Projector<R,dim>::x_index] = pi->x();
coords[Projector<R,dim>::y_index] = pi->y();
Point_3 res(coords[0],coords[1],coords[2]);
CGAL_assertion(x(res)==pi->x() && y(res)==pi->y());
return make_object(res);
@ -363,18 +363,18 @@ public:
template <class R, int dim>
class Circumcenter_center_projected
{
typedef typename R::Point_3 Point_3;
typedef typename R::Point_3 Point_3;
typedef typename R::Point_2 Point_2;
typename R::FT x(const Point_3 &p) const { return Projector<R,dim>::x(p); }
typename R::FT y(const Point_3 &p) const { return Projector<R,dim>::y(p); }
Point_2 project(const Point_3& p) const
{
return Point_2(x(p),y(p));
}
Point_3 embed (const Point_2& p) const
Point_3 embed (const Point_2& p) const
{
typename R::FT coords[3];
coords[Projector<R,dim>::x_index]=p.x();
@ -382,7 +382,7 @@ class Circumcenter_center_projected
coords[dim]=typename R::FT(0);
return Point_3(coords[0],coords[1],coords[2]);
}
public:
Point_3 operator() (const Point_3& p1,const Point_3& p2) const
{
@ -398,18 +398,18 @@ public:
template <class R, int dim>
class Compute_area_projected
{
typedef typename R::Point_3 Point_3;
typedef typename R::Point_3 Point_3;
typedef typename R::Point_2 Point_2;
typename R::FT x(const Point_3 &p) const { return Projector<R,dim>::x(p); }
typename R::FT y(const Point_3 &p) const { return Projector<R,dim>::y(p); }
Point_2 project(const Point_3& p) const
{
return Point_2(x(p),y(p));
}
public:
typename R::FT operator() (const Point_3& p1,const Point_3& p2,const Point_3& p3) const
{
@ -420,18 +420,18 @@ public:
template <class R, int dim>
class Compute_squared_radius_projected
{
typedef typename R::Point_3 Point_3;
typedef typename R::Point_3 Point_3;
typedef typename R::Point_2 Point_2;
typename R::FT x(const Point_3 &p) const { return Projector<R,dim>::x(p); }
typename R::FT y(const Point_3 &p) const { return Projector<R,dim>::y(p); }
Point_2 project(const Point_3& p) const
{
return Point_2(x(p),y(p));
}
public:
typename R::FT operator() (const Point_3& p1,const Point_3& p2,const Point_3& p3) const
{
@ -521,7 +521,7 @@ public:
Weighted_point_2 project(const Weighted_point_3& wp) const
{
Point_3 p = R().construct_point_3_object()(wp);
const Point_3& p = R().construct_point_3_object()(wp);
return Weighted_point_2(Point_2(x(p), y(p)), wp.weight());
}
@ -550,7 +550,7 @@ public:
Weighted_point_2 project(const Weighted_point_3& wp) const
{
Point_3 p = R().construct_point_3_object()(wp);
const Point_3& p = R().construct_point_3_object()(wp);
return Weighted_point_2(Point_2(x(p), y(p)), wp.weight());
}
@ -577,7 +577,7 @@ public:
Weighted_point_2 project(const Weighted_point_3& wp) const
{
Point_3 p = R().construct_point_3_object()(wp);
const Point_3& p = R().construct_point_3_object()(wp);
return Weighted_point_2(Point_2(x(p), y(p)), wp.weight());
}
@ -614,7 +614,7 @@ public:
Weighted_point_2 project(const Weighted_point_3& wp) const
{
Point_3 p = R().construct_point_3_object()(wp);
const Point_3& p = R().construct_point_3_object()(wp);
return Weighted_point_2(Point_2(x(p), y(p)), wp.weight());
}
@ -659,7 +659,7 @@ public:
Weighted_point_2 project(const Weighted_point_3& wp) const
{
Point_3 p = R().construct_point_3_object()(wp);
const Point_3& p = R().construct_point_3_object()(wp);
return Weighted_point_2(Point_2(x(p), y(p)), wp.weight());
}
@ -697,7 +697,7 @@ public:
Weighted_point_2 project(const Weighted_point_3& wp) const
{
Point_3 p = R().construct_point_3_object()(wp);
const Point_3& p = R().construct_point_3_object()(wp);
return Weighted_point_2(Point_2(x(p), y(p)), wp.weight());
}
@ -739,7 +739,7 @@ public:
Weighted_point_2 project(const Weighted_point_3& wp) const
{
Point_3 p = R().construct_point_3_object()(wp);
const Point_3& p = R().construct_point_3_object()(wp);
return Weighted_point_2(Point_2(x(p), y(p)), wp.weight());
}
@ -806,7 +806,7 @@ public:
typedef Power_side_of_bounded_power_circle_projected_3<Rp,dim> Power_side_of_bounded_power_circle_2;
typedef Power_side_of_oriented_power_circle_projected_3<Rp, dim> Power_side_of_oriented_power_circle_2;
typedef Construct_bbox_projected_2<Rp,dim> Construct_bbox_2;
typedef typename Rp::Construct_point_3 Construct_point_2;
typedef typename Rp::Construct_weighted_point_3 Construct_weighted_point_2;
typedef typename Rp::Construct_segment_3 Construct_segment_2;
@ -849,7 +849,7 @@ public:
typedef bool result_type;
bool operator()(const Point_2& p, const Point_2& q) const
{
Equal_x_2 eqx;
Equal_y_2 eqy;
return eqx(p,q) & eqy(p,q);
@ -860,7 +860,7 @@ public:
typedef bool result_type;
bool operator()(const Point_2& p, const Point_2& q, const Point_2& r) const
{
Orientation_2 ori;
return ori(p,q,r) == LEFT_TURN;
}
@ -881,8 +881,8 @@ public:
typedef Circumcenter_center_projected<Rp,dim> Construct_circumcenter_2;
typedef Compute_area_projected<Rp,dim> Compute_area_2;
Construct_circumcenter_2 construct_circumcenter_2_object () const {return Construct_circumcenter_2();}
Compute_area_2 compute_area_2_object () const {return Compute_area_2();}
Compute_area_2 compute_area_2_object () const {return Compute_area_2();}
// for compatibility with previous versions
typedef Point_2 Point;
@ -891,14 +891,14 @@ public:
Projection_traits_3(){}
Projection_traits_3(
const Projection_traits_3&){}
const Projection_traits_3&){}
Projection_traits_3 &operator=(
const Projection_traits_3&){return *this;}
const Projection_traits_3&){return *this;}
typename Rp::FT x(const Point_2 &p) const { return Projector<R,dim>::x(p); }
typename Rp::FT y(const Point_2 &p) const { return Projector<R,dim>::y(p); }
Equal_2
equal_2_object() const
{ return Equal_2();}
@ -931,7 +931,7 @@ public:
{ return Compare_x_2();}
Angle_2
angle_2_object() const {
return Angle_2();
return Angle_2();
}
Compare_y_2
@ -997,7 +997,7 @@ public:
Construct_triangle_2 construct_triangle_2_object() const
{return Construct_triangle_2();}
Construct_line_2 construct_line_2_object() const
{return Construct_line_2();}

View File

@ -0,0 +1,25 @@
# Created by the script cgal_create_CMakeLists
# This is the CMake script for compiling a set of CGAL applications.
cmake_minimum_required(VERSION 3.1...3.15)
project( Optimal_bounding_box_Benchmark )
# CGAL and its components
find_package( CGAL QUIET )
if ( NOT CGAL_FOUND )
message(STATUS "This project requires the CGAL library, and will not be compiled.")
return()
endif()
# include helper file
include( ${CGAL_USE_FILE} )
find_package(Eigen3 3.1.0 REQUIRED) #(3.1.0 or greater)
if (NOT EIGEN3_FOUND)
message(STATUS "This project requires the Eigen library, and will not be compiled.")
return()
endif()
create_single_source_cgal_program("bench_obb.cpp")
CGAL_target_use_Eigen(bench_obb)

View File

@ -0,0 +1,103 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Optimal_bounding_box/oriented_bounding_box.h>
#include <CGAL/convex_hull_3.h>
#include <CGAL/subdivision_method_3.h>
#include <CGAL/Timer.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#define CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_BENCHMARK
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_3 Point_3;
typedef CGAL::Surface_mesh<Point_3> Surface_mesh;
typedef typename boost::graph_traits<Surface_mesh>::vertex_descriptor vertex_descriptor;
void bench_finding_obb(const std::string fname)
{
std::ifstream input(fname);
// import a mesh
Surface_mesh mesh;
if (!input || !(input >> mesh) || mesh.is_empty())
{
std::cerr << fname << " is not a valid off file." << std::endl;
std::exit(1);
}
CGAL::Timer timer;
std::size_t measurements = 4;
for(std::size_t t=0; t<measurements; ++t)
{
std::cout << "Iteration: " << t << std::endl;
std::cout << num_vertices(mesh) << " nv and " << num_faces(mesh) << " nf" << std::endl;
// 1) measure convex hull calculation
timer.start();
CGAL::Polyhedron_3<K> poly;
convex_hull_3(mesh, poly);
timer.stop();
std::cout << "takes : " << timer.time() << " seconds to find the convex hull\n";
std::cout << num_vertices(poly) << " vertices on the convex hull" << std::endl;
// 2) using convex hull
timer.reset();
timer.start();
std::array<Point_3, 8> obb_points1;
CGAL::oriented_bounding_box(mesh, obb_points1, CGAL::parameters::use_convex_hull(true));
timer.stop();
std::cout << "found obb using convex hull: " << timer.time() << " seconds\n";
// 3) without convex hull
timer.reset();
timer.start();
std::array<Point_3, 8> obb_points2;
CGAL::oriented_bounding_box(mesh, obb_points2, CGAL::parameters::use_convex_hull(false));
timer.stop();
std::cout << "found obb without convex hull: " << timer.time() << " seconds\n";
timer.reset();
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_BENCHMARK
Surface_mesh result_mesh1;
CGAL::make_hexahedron(obb_points1[0], obb_points1[1], obb_points1[2], obb_points1[3],
obb_points1[4], obb_points1[5], obb_points1[6], obb_points1[7],
result_mesh1);
Surface_mesh result_mesh2;
CGAL::make_hexahedron(obb_points2[0], obb_points2[1], obb_points2[2], obb_points2[3],
obb_points2[4], obb_points2[5], obb_points2[6], obb_points2[7],
result_mesh2);
std::stringstream oss1;
oss1 << "data/obb_result1_iter_" << t << std::ends;
std::ofstream out1(oss1.str().c_str());
out1 << result_mesh1;
std::stringstream oss2;
oss2 << "data/obb_result2_iter_" << t << std::ends;
std::ofstream out2(oss2.str().c_str());
out2 << result_mesh2;
CGAL::Subdivision_method_3::CatmullClark_subdivision(mesh, CGAL::parameters::number_of_iterations(1));
#endif
}
}
int main(int argc, char** argv)
{
bench_finding_obb((argc > 1) ? argv[1] : "data/elephant.off");
std::cout << "Done!" << std::endl;
return EXIT_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
/*!
\ingroup PkgOptimalBoundingBoxConcepts
\cgalConcept
The concept `OrientedBoundingBoxTraits_3` describes the requirements of the traits class
used in the function `CGAL::oriented_bounding_box()`, and in particular the need for
a 3x3 matrix type.
\cgalRefines `Kernel`
\cgalHasModel `CGAL::Oriented_bounding_box_traits_3`
*/
class OrientedBoundingBoxTraits_3
{
public:
/// The field number type; must be a model of the concept `FieldNumberType`
typedef unspecified_type FT;
/// The 3D affine transformation type; the template parameter `K` must be a model of `Kernel`
/// and be compatible with the type `Point_3`
typedef CGAL::Aff_transformation_3<K> Aff_transformation_3;
/// A 3x3 matrix type; model of the concept `SvdTraits::Matrix` and which supports
/// matrix-matrix and scalar-matrix multiplication, as well as matrix-matrix addition
typedef unspecified_type Matrix;
/// Returns the unitary matrix `Q` obtained in the QR-decomposition of the matrix `m`
Matrix get_Q(const Matrix& m) const;
};

View File

@ -0,0 +1,26 @@
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - Optimal Bounding Box"
EXTRACT_ALL = false
HIDE_UNDOC_CLASSES = true
WARN_IF_UNDOCUMENTED = true
# macros to be used inside the code
ALIASES += "cgalNamedParamsBegin=<dl class=\"params\"><dt>Named Parameters</dt><dd> <table class=\"params\">"
ALIASES += "cgalNamedParamsEnd=</table> </dd> </dl>"
ALIASES += "cgalParamBegin{1}=<tr><td class=\"paramname\">\ref OBB_\1 \"\1\"</td><td>"
ALIASES += "cgalParamEnd=</td></tr>"
#macros for NamedParameters.txt
ALIASES += "cgalNPTableBegin=<dl class=\"params\"><dt></dt><dd> <table class=\"params\">"
ALIASES += "cgalNPTableEnd=</table> </dd> </dl>"
ALIASES += "cgalNPBegin{1}=<tr><td class=\"paramname\">\1 </td><td>"
ALIASES += "cgalNPEnd=</td></tr>"
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
EXPAND_AS_DEFINED = CGAL_BGL_NP_TEMPLATE_PARAMETERS \
CGAL_BGL_NP_CLASS
EXCLUDE = ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Optimal_bounding_box/internal
EXCLUDE_SYMBOLS += experimental

View File

@ -0,0 +1,65 @@
/*!
\defgroup obb_namedparameters Named Parameters for the package Optimal Bounding Box
\ingroup PkgOptimalBoundingBoxRef
In this package, all functions optional parameters are implemented as BGL optional
named parameters (see \ref BGLNamedParameters for more information on how to use them).
Since the parameters of the various functions defined in this package are redundant,
their long descriptions are centralized below.
The sequence of named parameters should start with `CGAL::parameters::`.
`CGAL::parameters::all_default()` can be used to indicate
that default values of optional named parameters must be used.
In the following, we assume that the following types are provided as template parameters
of functions and classes. Note that, for some of these functions,
the type is more specific:
<ul>
<li>`PolygonMesh` is a model of the concept `FaceGraph`</li>.
<li>`GeomTraits` a geometric traits class in which constructions are performed and
predicates evaluated. Everywhere in this package, a \cgal `Kernel` fulfills the requirements.</li>
</ul>
The following named parameters, offered by the package \ref PkgBGL
(see \ref bgl_namedparameters), are used in this package:
\cgalNPTableBegin
\cgalNPBegin{vertex_point_map} \anchor OBB_vertex_point_map
is the property map with the points associated to the vertices of the polygon mesh `pmesh`.\n
<b>Type:</b> a class model of `ReadablePropertyMap` with
`boost::graph_traits<PolygonMesh>::%vertex_descriptor` as key type and
`GeomTraits::Point_3` as value type. \n
<b>Default:</b> \code boost::get(CGAL::vertex_point, pmesh) \endcode
\cgalNPEnd
\cgalNPBegin{point_map} \anchor OBB_point_map
is the property map containing the points associated to the elements of the point range `points`.\n
<b>Type:</b> a class model of `ReadablePropertyMap` with `PointRange::iterator::value_type` as key type
and `geom_traits::Point_3` as value type. \n
<b>Default:</b> \code CGAL::Identity_property_map<geom_traits::Point_3>\endcode
\cgalNPEnd
\cgalNPTableEnd
In addition to these named parameters, this package offers the following named parameters:
\cgalNPTableBegin
\cgalNPBegin{geom_traits} \anchor OBB_geom_traits
is the geometric traits instance in which the mesh processing operation should be performed.\n
<b>Type:</b> a Geometric traits class.\n
<b>Default:</b>
\code typename CGAL::Kernel_traits<
typename boost::property_traits<
typename boost::property_map<PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel \endcode
\cgalNPEnd
\cgalNPBegin{use_convex_hull} \anchor OBB_use_convex_hull
Parameter used in the construction of oriented bounding box to indicate whether the algorithm should
first extract the extreme points (points that are on the 3D convex hull) of the input data range
to accelerate the computation of the bounding box.
\n
<b>Type:</b> `bool` \n
<b>Default:</b> `true`
\cgalNPEnd
\cgalNPTableEnd
*/

View File

@ -0,0 +1,16 @@
namespace CGAL {
/*!
\mainpage User Manual
\anchor Chapter_Building_Optimal_Bounding_Box
\cgalAutoToc
\authors Konstantinos Katrioplas, Mael Rouxel-Labbé
\section sectionSubIntro Introduction
AABB and stuff
\section secOBB Optimal Bounding Box
*/
} /* namespace CGAL */

View File

@ -0,0 +1,53 @@
/// \defgroup PkgOptimalBoundingBoxRef Optimal Bounding Box Reference
/// \defgroup PkgOptimalBoundingBoxConcepts Concepts
/// \ingroup PkgOptimalBoundingBoxRef
/// \defgroup PkgOptimalBoundingBoxClasses Optimal Bounding Box Classes
/// \ingroup PkgOptimalBoundingBoxRef
/// \defgroup PkgOptimalBoundingBoxFunctions Optimal Bounding Box Functions
/// \ingroup PkgOptimalBoundingBoxRef
/// \defgroup PkgOptimalBoundingBox_Oriented_bounding_box Oriented Bounding Box Functions
/// \ingroup PkgOptimalBoundingBoxFunctions
/*!
\addtogroup PkgOptimalBoundingBoxRef
\cgalPkgDescriptionBegin{Optimal Bounding Box,PkgOptimalBoundingBox}
\cgalPkgPicture{optimal_bounding_box.png}
\cgalPkgSummaryBegin
\cgalPkgAuthor{Konstantinos Katrioplas, Mael Rouxel-Labbé}
\cgalPkgDesc{This package provides functions to compute tight oriented bounding boxes around a point set or a polygon mesh.}
\cgalPkgManuals{Chapter_Building_Optimal_Bounding_Box,PkgOptimalBoundingBoxRef}
\cgalPkgSummaryEnd
\cgalPkgShortInfoBegin
\cgalPkgSince{5.1}
\cgalPkgDependsOn{\ref PkgConvexHull3}
\cgalPkgBib{cgal:obb}
\cgalPkgLicense{\ref licensesGPL "GPL"}
\cgalPkgDemo{Polyhedron demo, polyhedron_3.zip}
\cgalPkgShortInfoEnd
\cgalPkgDescriptionEnd
\cgalClassifedRefPages
\cgalCRPSection{Parameters}
Optional parameters of the functions of this package are implemented as \ref BGLNamedParameters.
The page \ref obb_namedparameters describes their usage and provides a list of the parameters
that are used in this package.
\cgalCRPSection{Concepts}
- `OrientedBoundingBoxTraits_3`
\cgalCRPSection{Classes}
- `CGAL::Oriented_bounding_box_traits_3`
\cgalCRPSection{Methods}
- \link PkgOptimalBoundingBox_Oriented_bounding_box `CGAL::oriented_bounding_box()` \endlink
*/

View File

@ -0,0 +1,13 @@
Manual
Kernel_23
STL_Extension
Algebraic_foundations
Circulator
Stream_support
Polyhedron
BGL
Solver_interface
Surface_mesh
AABB_tree
Property_map

View File

@ -0,0 +1,6 @@
/*!
\example Optimal_bounding_box/obb_example.cpp
\example Optimal_bounding_box/obb_with_point_maps_example.cpp
\example Optimal_bounding_box/rotated_aabb_tree_example.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,31 @@
# Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application.
cmake_minimum_required(VERSION 3.1...3.15)
project( Optimal_bounding_box_Examples )
find_package(CGAL QUIET)
if (NOT CGAL_FOUND)
message(STATUS "This project requires the CGAL library, and will not be compiled.")
return()
endif()
include( ${CGAL_USE_FILE} )
find_package(Eigen3 3.1.0 REQUIRED) #(3.1.0 or greater)
if (NOT EIGEN3_FOUND)
message(STATUS "This project requires the Eigen library, and will not be compiled.")
return()
endif()
create_single_source_cgal_program("obb_example.cpp")
create_single_source_cgal_program("obb_with_point_maps_example.cpp")
create_single_source_cgal_program("rotated_aabb_tree_example.cpp")
foreach(target
obb_example
obb_with_point_maps_example
rotated_aabb_tree_example)
CGAL_target_use_Eigen(${target})
endforeach()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
#define CGAL_OPTIMAL_BOUNDING_BOX_DEBUG
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/optimal_bounding_box.h>
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
#include <CGAL/Polygon_mesh_processing/measure.h>
#include <CGAL/Real_timer.h>
#include <fstream>
#include <iostream>
namespace PMP = CGAL::Polygon_mesh_processing;
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_3 Point;
typedef CGAL::Surface_mesh<Point> Surface_mesh;
int main(int argc, char** argv)
{
std::ifstream input((argc > 1) ? argv[1] : "data/pig.off");
Surface_mesh sm;
if(!input || !(input >> sm) || sm.is_empty())
{
std::cerr << "Invalid input file." << std::endl;
return EXIT_FAILURE;
}
CGAL::Real_timer timer;
timer.start();
// Compute the extreme points of the mesh, and then a tightly fitted oriented bounding box
std::array<Point, 8> obb_points;
CGAL::oriented_bounding_box(sm, obb_points,
CGAL::parameters::use_convex_hull(true));
std::cout << "Elapsed time: " << timer.time() << std::endl;
// Make a mesh out of the oriented bounding box
Surface_mesh obb_sm;
CGAL::make_hexahedron(obb_points[0], obb_points[1], obb_points[2], obb_points[3],
obb_points[4], obb_points[5], obb_points[6], obb_points[7], obb_sm);
std::ofstream("obb.off") << obb_sm;
PMP::triangulate_faces(obb_sm);
std::cout << "Volume: " << PMP::volume(obb_sm) << std::endl;
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,58 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/optimal_bounding_box.h>
#include <array>
#include <fstream>
#include <iostream>
#include <map>
#include <unordered_map>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_3 Point;
typedef K::Vector_3 Vector;
typedef CGAL::Surface_mesh<Point> Surface_mesh;
typedef boost::graph_traits<Surface_mesh>::vertex_descriptor vertex_descriptor;
namespace CP = CGAL::parameters;
int main(int argc, char** argv)
{
std::ifstream input((argc > 1) ? argv[1] : "data/pig.off");
Surface_mesh sm;
if (!input || !(input >> sm) || sm.is_empty())
{
std::cerr << "Invalid input file." << std::endl;
return EXIT_FAILURE;
}
// a typical call
std::array<Point, 8> obb_points;
CGAL::oriented_bounding_box(sm, obb_points);
// one can associate positions to the vertices of the mesh without changing the mesh
std::unordered_map<vertex_descriptor, Point> translated_positions;
for(const vertex_descriptor v : vertices(sm))
translated_positions[v] = sm.point(v) + Vector(1, 2, 3);
CGAL::oriented_bounding_box(sm, obb_points,
CP::vertex_point_map(boost::make_assoc_property_map(translated_positions)));
// using a range of points
std::vector<Point> points;
for(const vertex_descriptor v : vertices(sm))
points.push_back(sm.point(v));
CGAL::oriented_bounding_box(points, obb_points);
// one can associate positions to the range without changing the range
std::map<Point, Point> scaled_positions;
for(const Point& p : points)
scaled_positions[p] = p + (p - CGAL::ORIGIN);
CGAL::oriented_bounding_box(points, obb_points,
CP::point_map(boost::make_assoc_property_map(scaled_positions)));
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,60 @@
#define CGAL_OPTIMAL_BOUNDING_BOX_DEBUG
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
#include <CGAL/optimal_bounding_box.h>
#include <boost/property_map/function_property_map.hpp>
#include <fstream>
#include <iostream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_3 Point;
typedef K::Aff_transformation_3 Aff_transformation;
typedef CGAL::Surface_mesh<Point> Surface_mesh;
typedef boost::graph_traits<Surface_mesh>::vertex_descriptor vertex_descriptor;
struct Aff_tr_fct
{
Aff_tr_fct() : m_at(nullptr), m_sm(nullptr) { }
Aff_tr_fct(const Aff_transformation& at, const Surface_mesh& sm) : m_at(&at), m_sm(&sm) { }
Point operator()(const vertex_descriptor v) const { return m_at->transform(m_sm->point(v)); }
private:
const Aff_transformation* m_at;
const Surface_mesh* m_sm;
};
int main(int argc, char** argv)
{
std::ifstream input((argc > 1) ? argv[1] : "data/pig.off");
Surface_mesh sm;
if (!input || !(input >> sm) || sm.is_empty())
{
std::cerr << "Invalid input file." << std::endl;
return EXIT_FAILURE;
}
// get the transformation that yields the optimal bounding box
Aff_transformation at;
CGAL::oriented_bounding_box(sm, at);
// functor to apply the affine transformation to a vertex of the mesh
Aff_tr_fct aff_tr_fct(at, sm);
auto aff_tr_vpm = boost::make_function_property_map<vertex_descriptor>(aff_tr_fct);
// rotated AABB tree
typedef CGAL::AABB_face_graph_triangle_primitive<Surface_mesh, decltype(aff_tr_vpm)> AABB_face_graph_primitive;
typedef CGAL::AABB_traits<K, AABB_face_graph_primitive> AABB_face_graph_traits;
CGAL::AABB_tree<AABB_face_graph_traits> tree(faces(sm).begin(), faces(sm).end(), sm, aff_tr_vpm);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,70 @@
// Copyright (c) 2018-2019 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Mael Rouxel-Labbé
//
#ifndef CGAL_OPTIMAL_BOUNDING_BOX_BOUNDING_BOX_TRAITS_H
#define CGAL_OPTIMAL_BOUNDING_BOX_BOUNDING_BOX_TRAITS_H
#include <CGAL/license/Optimal_bounding_box.h>
#include <CGAL/Aff_transformation_3.h>
#ifdef CGAL_EIGEN3_ENABLED
#include <CGAL/Eigen_matrix.h>
#include <Eigen/QR>
#endif
namespace CGAL {
#if defined(CGAL_EIGEN3_ENABLED) || defined(DOXYGEN_RUNNING)
/// \ingroup PkgOptimalBoundingBoxClasses
///
/// The class `CGAL::Oriented_bounding_box_traits_3` is a traits type
/// to be used with the overloads of the function `CGAL::oriented_bounding_box()`.
///
/// \attention This class requires the \ref thirdpartyEigen "Eigen" library.
///
/// \tparam K must be a model of `Kernel`
///
/// \cgalModels `OrientedBoundingBoxTraits_3`
///
template <typename K>
class Oriented_bounding_box_traits_3
: public K
{
public:
/// The field number type
typedef typename K::FT FT;
/// The affine transformation type
typedef typename CGAL::Aff_transformation_3<K> Aff_transformation_3;
/// The matrix type
typedef CGAL::Eigen_matrix<FT, 3, 3> Matrix;
private:
typedef typename Matrix::EigenType EigenType;
public:
/// Performs the QR-decomposition of the matrix `m` to a unitary matrix and an upper triagonal
/// and returns the unitary matrix
static Matrix get_Q(const Matrix& m)
{
Eigen::HouseholderQR<EigenType> qr(m.eigen_object());
return Matrix(EigenType(qr.householderQ()));
}
};
#endif // defined(CGAL_EIGEN3_ENABLED) || defined(DOXYGEN_RUNNING)
} // namespace CGAL
#endif // CGAL_OPTIMAL_BOUNDING_BOX_BOUNDING_BOX_TRAITS_H

View File

@ -0,0 +1,227 @@
// Copyright (c) 2018-2019 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Mael Rouxel-Labbé
// Konstantinos Katrioplas
//
#ifndef CGAL_OPTIMAL_BOUNDING_BOX_EVOLUTION_H
#define CGAL_OPTIMAL_BOUNDING_BOX_EVOLUTION_H
#include <CGAL/license/Optimal_bounding_box.h>
#include <CGAL/Optimal_bounding_box/internal/fitness_function.h>
#include <CGAL/Optimal_bounding_box/internal/helper.h>
#include <CGAL/Optimal_bounding_box/internal/nelder_mead_functions.h>
#include <CGAL/Optimal_bounding_box/internal/optimize_2.h>
#include <CGAL/Optimal_bounding_box/internal/population.h>
#include <CGAL/Random.h>
#include <CGAL/number_utils.h>
#include <algorithm>
#include <array>
#include <iostream>
#include <vector>
namespace CGAL {
namespace Optimal_bounding_box {
namespace internal {
template <typename PointRange, typename Traits>
class Evolution
{
public:
typedef typename Traits::FT FT;
typedef typename Traits::Matrix Matrix;
typedef internal::Population<Traits> Population;
typedef typename Population::Simplex Simplex;
typedef typename Population::Vertex Vertex;
Evolution(const PointRange& points,
CGAL::Random& rng,
const Traits& traits)
:
m_best_v(nullptr),
m_population(traits),
m_rng(rng),
m_points(points),
m_traits(traits)
{ }
void genetic_algorithm()
{
// This evolves an existing population
CGAL_precondition(m_population.size() != 0);
//groups 1,2 : size = floor(m/2) groups 3,4 : size = ceil(m/2).
const std::size_t m = m_population.size();
const std::size_t first_group_size = m / 2;
const std::size_t second_group_size = m - first_group_size;
std::vector<std::size_t> group1(first_group_size), group2(first_group_size);
std::vector<std::size_t> group3(second_group_size), group4(second_group_size);
int im = static_cast<int>(m);
std::generate(group1.begin(), group1.end(), [&]{ return m_rng.get_int(0, im); });
std::generate(group2.begin(), group2.end(), [&]{ return m_rng.get_int(0, im); });
std::generate(group3.begin(), group3.end(), [&]{ return m_rng.get_int(0, im); });
std::generate(group4.begin(), group4.end(), [&]{ return m_rng.get_int(0, im); });
// crossover I, pick A or B
constexpr FT lweight = 0.4, uweight = 0.6;
std::vector<Simplex> new_simplices(m);
for(std::size_t i=0; i<first_group_size; ++i)
{
Simplex offspring;
for(int j=0; j<4; ++j)
{
const FT r{m_rng.get_double()};
const FT fitnessA = m_population[group1[i]][j].fitness();
const FT fitnessB = m_population[group2[i]][j].fitness();
const FT threshold = (fitnessA < fitnessB) ? uweight : lweight;
if(r < threshold)
offspring[j] = m_population[group1[i]][j];
else
offspring[j] = m_population[group2[i]][j];
}
new_simplices[i] = std::move(offspring);
}
// crossover II, combine information from A and B
for(std::size_t i=0; i<second_group_size; ++i)
{
Simplex offspring;
for(int j=0; j<4; ++j)
{
const FT fitnessA = m_population[group3[i]][j].fitness();
const FT fitnessB = m_population[group4[i]][j].fitness();
const FT lambda = (fitnessA < fitnessB) ? uweight : lweight;
const FT rambda = FT(1) - lambda; // because the 'l' in 'lambda' stands for left
const Matrix& lm = m_population[group3[i]][j].matrix();
const Matrix& rm = m_population[group4[i]][j].matrix();
offspring[j] = Vertex{m_traits.get_Q(lambda*lm + rambda*rm), m_points, m_traits};
}
new_simplices[first_group_size + i] = std::move(offspring);
}
m_population.simplices() = std::move(new_simplices);
}
// @todo re-enable random mutations as it is -on theory- useful, but don't allow them to override
// the best (current) candidates
void evolve(const std::size_t max_generations,
const std::size_t population_size,
const std::size_t nelder_mead_iterations,
const std::size_t max_random_mutations = 0)
{
// stopping criteria prameters
FT prev_fit_value = 0;
const FT tolerance = 1e-10;
int stale = 0;
m_population.initialize(population_size, m_points, m_rng);
std::size_t gen_iter = 0;
for(;;)
{
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_PP
std::cout << "- - - - generation #" << gen_iter << "\n";
#endif
genetic_algorithm();
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_PP
std::cout << "population after genetic" << std::endl;
pop.show_population();
std::cout << std::endl;
#endif
for(std::size_t s=0; s<population_size; ++s)
nelder_mead(m_population[s], nelder_mead_iterations, m_points, m_traits);
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_PP
std::cout << "population after nelder mead: " << std::endl;
pop.show_population();
std::cout << std::endl;
#endif
// optimize the current best rotation by using the exact OBB 2D algorithm
// along the axes of the current best OBB
m_best_v = &(m_population.get_best_vertex());
Matrix& best_m = m_best_v->matrix();
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_PP
std::cout << "new best matrix: " << std::endl << best_m << std::endl;
std::cout << "fitness: " << m_best_v->fitness() << std::endl;
#endif
optimize_along_OBB_axes(best_m, m_points, m_traits);
m_best_v->fitness() = compute_fitness(best_m, m_points, m_traits);
// stopping criteria
const FT new_fit_value = m_best_v->fitness();
const FT difference = new_fit_value - prev_fit_value;
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_PP
std::cout << "post 2D optimization matrix: " << std::endl << best_m << std::endl;
std::cout << "new fit value: " << new_fit_value << std::endl;
std::cout << "difference: " << difference << std::endl;
#endif
if(CGAL::abs(difference) < tolerance * new_fit_value)
++stale;
if(stale == 5 || gen_iter++ >= max_generations)
break;
prev_fit_value = new_fit_value;
// random mutations, swap #random_mutations random simplices with a new, random simplex
if(max_random_mutations <= 0)
continue;
CGAL_warning(max_random_mutations <= population_size);
const int random_mutations = m_rng.get_int(0, static_cast<int>(max_random_mutations+1));
for(int i=0; i<random_mutations; ++i)
{
const int random_pos = m_rng.get_int(0, static_cast<int>(population_size));
m_population[random_pos] = m_population.create_simplex(m_points, m_rng);
}
}
}
const Vertex& get_best_vertex() const
{
CGAL_assertion(m_best_v != nullptr);
return *m_best_v;
}
private:
Vertex* m_best_v;
Population m_population;
CGAL::Random& m_rng;
const PointRange& m_points;
const Traits& m_traits;
};
} // namespace internal
} // namespace Optimal_bounding_box
} // namespace CGAL
#endif // CGAL_OPTIMAL_BOUNDING_BOX_EVOLUTION_H

View File

@ -0,0 +1,68 @@
// Copyright (c) 2018-2019 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Mael Rouxel-Labbé
// Konstantinos Katrioplas
//
#ifndef CGAL_OPTIMAL_BOUNDING_FITNESS_FUNCTION_H
#define CGAL_OPTIMAL_BOUNDING_FITNESS_FUNCTION_H
#include <CGAL/license/Optimal_bounding_box.h>
#include <CGAL/assertions.h>
#include <algorithm>
#include <limits>
namespace CGAL {
namespace Optimal_bounding_box {
namespace internal {
template <typename Traits, typename PointRange>
typename Traits::FT
compute_fitness(const typename Traits::Matrix& R, // rotation matrix
const PointRange& points,
const Traits& /*traits*/)
{
typedef typename Traits::FT FT;
typedef typename Traits::Point_3 Point;
CGAL_assertion(R.number_of_rows() == 3 && R.number_of_columns() == 3);
CGAL_assertion(points.size() >= 3);
FT xmin, ymin, zmin, xmax, ymax, zmax;
xmin = ymin = zmin = FT{std::numeric_limits<double>::max()};
xmax = ymax = zmax = FT{std::numeric_limits<double>::lowest()};
for(const Point& pt : points)
{
const FT x = pt.x(), y = pt.y(), z = pt.z();
const FT rx = x*R(0, 0) + y*R(0, 1) + z*R(0, 2);
const FT ry = x*R(1, 0) + y*R(1, 1) + z*R(1, 2);
const FT rz = x*R(2, 0) + y*R(2, 1) + z*R(2, 2);
xmin = (std::min)(xmin, rx);
ymin = (std::min)(ymin, ry);
zmin = (std::min)(zmin, rz);
xmax = (std::max)(xmax, rx);
ymax = (std::max)(ymax, ry);
zmax = (std::max)(zmax, rz);
}
// volume
return ((xmax - xmin) * (ymax - ymin) * (zmax - zmin));
}
} // namespace internal
} // namespace Optimal_bounding_box
} // namespace CGAL
#endif // CGAL_OPTIMAL_BOUNDING_FITNESS_FUNCTION_H

View File

@ -0,0 +1,39 @@
// Copyright (c) 2018-2019 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Konstantinos Katrioplas
// Mael Rouxel-Labbé
//
#ifndef CGAL_OPTIMAL_BOUNDING_BOX_INTERNAL_HELPER_H
#define CGAL_OPTIMAL_BOUNDING_BOX_INTERNAL_HELPER_H
#include <CGAL/license/Optimal_bounding_box.h>
namespace CGAL {
namespace Optimal_bounding_box {
namespace internal {
template <typename Matrix>
Matrix transpose(const Matrix& m)
{
Matrix tm;
tm.set(0, 0, m(0, 0)); tm.set(0, 1, m(1, 0)); tm.set(0, 2, m(2, 0));
tm.set(1, 0, m(0, 1)); tm.set(1, 1, m(1, 1)); tm.set(1, 2, m(2, 1));
tm.set(2, 0, m(0, 2)); tm.set(2, 1, m(1, 2)); tm.set(2, 2, m(2, 2));
return tm;
}
} // namespace internal
} // namespace Optimal_bounding_box
} // namespace CGAL
#endif // CGAL_OPTIMAL_BOUNDING_BOX_INTERNAL_HELPER_H

View File

@ -0,0 +1,144 @@
// Copyright (c) 2018-2019 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Mael Rouxel-Labbé
// Konstantinos Katrioplas
//
#ifndef CGAL_OPTIMAL_BOUNDING_BOX_NEALDER_MEAD_FUNCTIONS_H
#define CGAL_OPTIMAL_BOUNDING_BOX_NEALDER_MEAD_FUNCTIONS_H
#include <CGAL/license/Optimal_bounding_box.h>
#include <CGAL/Optimal_bounding_box/internal/fitness_function.h>
#include <CGAL/Optimal_bounding_box/internal/helper.h>
#include <CGAL/assertions.h>
#include <algorithm>
#include <array>
namespace CGAL {
namespace Optimal_bounding_box {
namespace internal {
template <typename Matrix>
Matrix reflection(const Matrix& S_centroid,
const Matrix& S_worst)
{
return S_centroid * transpose(S_worst) * S_centroid;
}
template <typename Matrix>
Matrix expansion(const Matrix& S_centroid,
const Matrix& S_worst,
const Matrix& S_reflection)
{
return S_centroid * transpose(S_worst) * S_reflection;
}
template <typename Matrix, typename Traits>
Matrix mean(const Matrix& m1,
const Matrix& m2,
const Traits& traits)
{
typedef typename Traits::FT FT;
constexpr FT half = FT(1) / FT(2);
const Matrix reduction = half * (m1 + m2);
return traits.get_Q(reduction);
}
template <typename Matrix, typename Traits>
const Matrix nm_centroid(const Matrix& S1,
const Matrix& S2,
const Matrix& S3,
const Traits& traits)
{
typedef typename Traits::FT FT;
constexpr FT third = FT(1) / FT(3);
const Matrix mean = third * (S1 + S2 + S3);
return traits.get_Q(mean);
}
// It's a 3D simplex with 4 rotation matrices as vertices
template <typename Simplex, typename PointRange, typename Traits>
void nelder_mead(Simplex& simplex,
const std::size_t nelder_mead_iterations,
const PointRange& points,
const Traits& traits)
{
typedef typename Simplex::value_type Vertex;
typedef typename Traits::FT FT;
typedef typename Traits::Matrix Matrix;
for(std::size_t t=0; t<nelder_mead_iterations; ++t)
{
std::sort(simplex.begin(), simplex.end(),
[](const Vertex& vi, const Vertex& vj) -> bool
{ return vi.fitness() < vj.fitness(); });
// centroid
const Matrix centroid_m = nm_centroid(simplex[0].matrix(),
simplex[1].matrix(),
simplex[2].matrix(), traits);
// find worst's vertex reflection
const Matrix& worst_m = simplex[3].matrix();
const Matrix refl_m = reflection(centroid_m, worst_m);
const FT refl_f = compute_fitness(refl_m, points, traits);
// if reflected point is better than the second worst
if(refl_f < simplex[2].fitness())
{
// if reflected point is not better than the best
if(refl_f >= simplex[0].fitness())
{
// reflection
simplex[3] = Vertex{refl_m, refl_f};
}
else
{
// expansion
const Matrix expand_m = expansion(centroid_m, worst_m, refl_m);
const FT expand_f = compute_fitness(expand_m, points, traits);
if(expand_f < refl_f)
simplex[3] = Vertex{expand_m, expand_f};
else
simplex[3] = Vertex{refl_m, refl_f};
}
}
else // reflected vertex is worse
{
const Matrix mean_m = mean(centroid_m, worst_m, traits);
const FT mean_f = compute_fitness(mean_m, points, traits);
if(mean_f <= simplex[3].fitness())
{
// contraction of worst
simplex[3] = Vertex{mean_m, mean_f};
}
else
{
// reduction: move all vertices towards the best
for(std::size_t i=1; i<4; ++i)
simplex[i] = Vertex{mean(simplex[i].matrix(), simplex[0].matrix(), traits), points, traits};
}
}
} // nelder mead iterations
}
} // namespace internal
} // namespace Optimal_bounding_box
} // namespace CGAL
#endif

View File

@ -0,0 +1,218 @@
// Copyright (c) 2020 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Mael Rouxel-Labbé
//
#ifndef CGAL_OPTIMAL_BOUNDING_BOX_INTERNAL_OPTIMIZE_2_H
#define CGAL_OPTIMAL_BOUNDING_BOX_INTERNAL_OPTIMIZE_2_H
#include <CGAL/license/Optimal_bounding_box.h>
#include <CGAL/ch_akl_toussaint.h>
#include <CGAL/min_quadrilateral_2.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/number_type_config.h>
#include <iostream>
#include <iterator>
#include <limits>
#include <utility>
#include <vector>
namespace CGAL {
namespace Optimal_bounding_box {
namespace internal {
enum PROJECTION_DIRECTION
{
ALONG_X = 0,
ALONG_Y,
ALONG_Z
};
// Now, we would like to do all of this with projection traits... Unfortunately, it's missing
// a couple of functors (Has_on_negative_side_2, for example), which are necessary in
// CGAL::Min_quadrilateral_default_traits_2. And while we know we have a generic case here,
// it's a bit tedious to get something well-defined in the generic case: for example,
// what should Has_on_negative_side_2 do if the Line_3 is orthogonal to the projection plane?
//
// So, easier to just bail out to real 2D...
template <typename Traits, typename PointRange>
std::pair<typename Traits::FT, typename Traits::FT>
compute_2D_deviation(const PointRange& points,
const PROJECTION_DIRECTION dir,
const Traits& traits)
{
typedef typename Traits::FT FT;
typedef typename Traits::Point_2 Point_2;
typedef typename Traits::Vector_2 Vector_2;
typedef typename Traits::Point_3 Point_3;
std::vector<Point_2> points_2D;
points_2D.reserve(points.size());
for(const Point_3& pt : points)
{
if(dir == ALONG_X)
points_2D.emplace_back(pt.y(), pt.z());
else if(dir == ALONG_Y)
points_2D.emplace_back(pt.x(), pt.z());
else if(dir == ALONG_Z)
points_2D.emplace_back(pt.x(), pt.y());
}
std::vector<Point_2> extreme_points;
ch_akl_toussaint(points_2D.begin(), points_2D.end(), std::back_inserter(extreme_points), traits);
CGAL::Polygon_2<Traits> pol;
CGAL::Min_quadrilateral_default_traits_2<Traits> mrt;
CGAL::min_rectangle_2(extreme_points.begin(), extreme_points.end(), std::back_inserter(pol), mrt);
if(pol.size() == 4 || !pol.is_simple() || pol.is_clockwise_oriented())
return std::make_pair(0., 0.);
// Compute the angle between the angle necessary to rotate the rectangle onto the reference frame
auto bot_pos = pol.bottom_vertex();
auto next_pos = bot_pos;
++next_pos;
if(next_pos == pol.vertices_end())
next_pos = pol.begin();
const Point_2& p = *bot_pos;
const Point_2& q = *next_pos;
const Vector_2 pq = traits.construct_vector_2_object()(p, q);
double n = sqrt(to_double(traits.compute_squared_length_2_object()(pq)));
if(n == 0.) // degenerate input, maybe? Let's just not do anything
return std::make_pair(pol.area(), 0.);
const double dot = pq.x(); // that's the scalar product of PQ with V(1, 0) (Ox)
double cosine = dot / n;
if(cosine > 1.)
cosine = 1.;
if(cosine < -1.)
cosine = -1.;
double theta = std::acos(cosine);
if(theta > 0.25 * CGAL_PI) // @todo is there a point to this
theta = 0.5 * CGAL_PI - theta;
return std::make_pair(pol.area(), FT{theta});
}
template <typename PointRange, typename Traits>
void optimize_along_OBB_axes(typename Traits::Matrix& rot,
const PointRange& points,
const Traits& traits)
{
typedef typename Traits::FT FT;
typedef typename Traits::Point_3 Point;
typedef typename Traits::Matrix Matrix;
CGAL_static_assertion((std::is_same<typename boost::range_value<PointRange>::type, Point>::value));
std::vector<Point> rotated_points;
rotated_points.size();
FT xmin, ymin, zmin, xmax, ymax, zmax;
xmin = ymin = zmin = FT{std::numeric_limits<double>::max()};
xmax = ymax = zmax = FT{std::numeric_limits<double>::lowest()};
for(const Point& pt : points)
{
const FT rx = rot(0, 0) * pt.x() + rot(0, 1) * pt.y() + rot(0, 2) * pt.z();
const FT ry = rot(1, 0) * pt.x() + rot(1, 1) * pt.y() + rot(1, 2) * pt.z();
const FT rz = rot(2, 0) * pt.x() + rot(2, 1) * pt.y() + rot(2, 2) * pt.z();
rotated_points.emplace_back(rx, ry, rz);
xmin = (std::min)(xmin, rx);
ymin = (std::min)(ymin, ry);
zmin = (std::min)(zmin, rz);
xmax = (std::max)(xmax, rx);
ymax = (std::max)(ymax, ry);
zmax = (std::max)(zmax, rz);
}
const FT lx = xmax - xmin;
const FT ly = ymax - ymin;
const FT lz = zmax - zmin;
std::array<FT, 3> angles;
std::array<FT, 3> volumes;
FT area_xy;
std::tie(area_xy, angles[0]) = compute_2D_deviation(rotated_points, ALONG_Z, traits);
volumes[0] = lz * area_xy;
FT area_xz;
std::tie(area_xz, angles[1]) = compute_2D_deviation(rotated_points, ALONG_Y, traits);
volumes[1] = ly * area_xz;
FT area_yz;
std::tie(area_yz, angles[2]) = compute_2D_deviation(rotated_points, ALONG_X, traits);
volumes[2] = lx * area_yz;
auto it = std::min_element(volumes.begin(), volumes.end());
typename std::iterator_traits<decltype(it)>::difference_type d = std::distance(volumes.begin(), it);
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG_PP
std::cout << "volumes: " << volumes[0] << " " << volumes[1] << " " << volumes[2] << std::endl;
std::cout << "angles: " << angles[0] << " " << angles[1] << " " << angles[2] << std::endl;
std::cout << "min at " << d << std::endl;
#endif
if(d == 0) // Along_Z
{
const double c = std::cos(angles[0]);
const double s = std::sin(angles[0]);
Matrix opt;
opt.set(0, 0, c); opt.set(0, 1, s); opt.set(0, 2, 0);
opt.set(1, 0, -s); opt.set(1, 1, c); opt.set(1, 2, 0);
opt.set(2, 0, 0); opt.set(2, 1, 0); opt.set(2, 2, 1);
rot = opt * rot;
}
else if(d == 1) // Along_Y
{
const double c = std::cos(angles[1]);
const double s = std::sin(angles[1]);
Matrix opt;
opt.set(0, 0, c); opt.set(0, 1, 0); opt.set(0, 2, -s);
opt.set(1, 0, 0); opt.set(1, 1, 1); opt.set(1, 2, 0);
opt.set(2, 0, s); opt.set(2, 1, 0); opt.set(2, 2, c);
rot = opt * rot;
}
else if(d == 2) // Along_X
{
const double c = std::cos(angles[2]);
const double s = std::sin(angles[2]);
Matrix opt;
opt.set(0, 0, 1); opt.set(0, 1, 0); opt.set(0, 2, 0);
opt.set(1, 0, 0); opt.set(1, 1, c); opt.set(1, 2, s);
opt.set(2, 0, 0); opt.set(2, 1, -s); opt.set(2, 2, c);
rot = opt * rot;
}
else
{
CGAL_assertion(false);
}
}
} // namespace internal
} // namespace Optimal_bounding_box
} // namespace CGAL
#endif // CGAL_OPTIMAL_BOUNDING_BOX_INTERNAL_OPTIMIZE_2_H

View File

@ -0,0 +1,168 @@
// Copyright (c) 2018-2019 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Mael Rouxel-Labbé
// Konstantinos Katrioplas
//
#ifndef CGAL_OPTIMAL_BOUNDING_BOX_POPULATION_H
#define CGAL_OPTIMAL_BOUNDING_BOX_POPULATION_H
#include <CGAL/license/Optimal_bounding_box.h>
#include <CGAL/Optimal_bounding_box/internal/fitness_function.h>
#include <CGAL/assertions.h>
#include <CGAL/Random.h>
#include <utility>
#include <vector>
namespace CGAL {
namespace Optimal_bounding_box {
namespace internal {
template<typename Traits>
struct Vertex_with_fitness
{
typedef typename Traits::FT FT;
typedef typename Traits::Matrix Matrix;
Vertex_with_fitness() { CGAL_assertion_code(m_is_val_initialized = false;) }
Vertex_with_fitness(const Matrix m, const FT v) : m_mat(std::move(m)), m_val(v)
{
CGAL_assertion_code(m_is_val_initialized = true;)
}
template <typename PointRange>
Vertex_with_fitness(const Matrix m,
const PointRange& points,
const Traits& traits)
:
m_mat(std::move(m))
{
m_val = compute_fitness(m, points, traits);
CGAL_assertion_code(m_is_val_initialized = true;)
}
Matrix& matrix() { return m_mat; }
const Matrix& matrix() const { return m_mat; }
FT& fitness() { return m_val; }
FT fitness() const { CGAL_assertion(m_is_val_initialized); return m_val; }
private:
Matrix m_mat;
FT m_val;
CGAL_assertion_code(bool m_is_val_initialized;)
};
template<typename Traits>
class Population
{
public:
typedef typename Traits::FT FT;
typedef typename Traits::Matrix Matrix;
typedef Vertex_with_fitness<Traits> Vertex;
typedef std::array<Vertex, 4> Simplex;
typedef std::vector<Simplex> Simplex_container;
public:
Population(const Traits& traits) : m_traits(traits) { }
// Access
std::size_t size() const { return m_simplices.size(); }
Simplex& operator[](const std::size_t i) { CGAL_assertion(i < m_simplices.size()); return m_simplices[i]; }
const Simplex& operator[](const std::size_t i) const { CGAL_assertion(i < m_simplices.size()); return m_simplices[i]; }
Simplex_container& simplices() { return m_simplices; }
private:
Matrix create_random_matrix(CGAL::Random& rng) const
{
Matrix m;
for(std::size_t i=0; i<3; ++i)
for(std::size_t j=0; j<3; ++j)
m.set(i, j, FT(rng.get_double()));
return m;
}
public:
template <typename PointRange>
Simplex create_simplex(const PointRange& points,
CGAL::Random& rng) const
{
Simplex s;
for(std::size_t i=0; i<4; ++i)
s[i] = Vertex{m_traits.get_Q(create_random_matrix(rng)), points, m_traits};
return s;
}
// create random population
template <typename PointRange>
void initialize(const std::size_t population_size,
const PointRange& points,
CGAL::Random& rng)
{
m_simplices.clear();
m_simplices.reserve(population_size);
for(std::size_t i=0; i<population_size; ++i)
m_simplices.emplace_back(create_simplex(points, rng));
}
Vertex& get_best_vertex()
{
std::size_t simplex_id, vertex_id;
FT best_fitness = FT{std::numeric_limits<double>::max()};
for(std::size_t i=0, ps=m_simplices.size(); i<ps; ++i)
{
for(std::size_t j=0; j<4; ++j)
{
const Vertex& vertex = m_simplices[i][j];
const FT fitness = vertex.fitness();
if(fitness < best_fitness)
{
simplex_id = i;
vertex_id = j;
best_fitness = fitness;
}
}
}
return m_simplices[simplex_id][vertex_id];
}
// Debug
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG
void show_population() const
{
std::size_t id = 0;
for(const Simplex& s : m_simplices)
{
std::cout << "Simplex: " << id++ << std::endl;
for(const Matrix& m : s)
std::cout << m << "\n\n";
std:: cout << std:: endl;
}
}
#endif
private:
std::vector<Simplex> m_simplices;
const Traits& m_traits;
};
} // namespace internal
} // namespace Optimal_bounding_box
} // namespace CGAL
#endif // CGAL_OPTIMAL_BOUNDING_BOX_POPULATION_H

View File

@ -0,0 +1,421 @@
// Copyright (c) 2018-2019 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Mael Rouxel-Labbé
//
#ifndef CGAL_OPTIMAL_BOUNDING_BOX_ORIENTED_BOUNDING_BOX_H
#define CGAL_OPTIMAL_BOUNDING_BOX_ORIENTED_BOUNDING_BOX_H
#include <CGAL/license/Optimal_bounding_box.h>
#include <CGAL/Optimal_bounding_box/internal/evolution.h>
#include <CGAL/Optimal_bounding_box/internal/population.h>
#include <CGAL/Optimal_bounding_box/Oriented_bounding_box_traits_3.h>
#include <CGAL/boost/graph/Named_function_parameters.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/assertions.h>
#include <CGAL/Bbox_3.h>
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/convex_hull_3.h>
#include <CGAL/Convex_hull_traits_3.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Iso_cuboid_3.h>
#include <CGAL/Iterator_range.h>
#include <CGAL/Kernel_traits.h>
#include <CGAL/Random.h>
#include <CGAL/Simple_cartesian.h>
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_BENCHMARKS
#include <CGAL/Real_timer.h>
#endif
#include <boost/iterator/transform_iterator.hpp>
#include <boost/range/value_type.hpp>
#include <boost/utility/enable_if.hpp>
#include <array>
#include <iostream>
#include <iterator>
#include <type_traits>
#include <vector>
#ifdef DOXYGEN_RUNNING
#define CGAL_BGL_NP_TEMPLATE_PARAMETERS NamedParameters
#define CGAL_BGL_NP_CLASS NamedParameters
#endif
namespace CGAL {
namespace Optimal_bounding_box {
namespace internal {
template <typename PointRange, typename Traits>
void construct_oriented_bounding_box(const PointRange& points,
const typename Traits::Aff_transformation_3& transformation,
const typename Traits::Aff_transformation_3& inverse_transformation,
std::array<typename Traits::Point_3, 8>& obb_points,
const Traits& traits)
{
typedef typename Traits::Point_3 Point;
// Construct the bbox of the transformed point set
CGAL::Bbox_3 bbox;
for(const Point& pt : points)
{
const Point rotated_pt = transformation.transform(pt);
bbox += traits.construct_bbox_3_object()(rotated_pt);
}
obb_points[0] = Point(bbox.xmin(), bbox.ymin(), bbox.zmin());
obb_points[1] = Point(bbox.xmax(), bbox.ymin(), bbox.zmin());
obb_points[2] = Point(bbox.xmax(), bbox.ymax(), bbox.zmin());
obb_points[3] = Point(bbox.xmin(), bbox.ymax(), bbox.zmin());
obb_points[4] = Point(bbox.xmin(), bbox.ymax(), bbox.zmax()); // see order in make_hexahedron()...
obb_points[5] = Point(bbox.xmin(), bbox.ymin(), bbox.zmax());
obb_points[6] = Point(bbox.xmax(), bbox.ymin(), bbox.zmax());
obb_points[7] = Point(bbox.xmax(), bbox.ymax(), bbox.zmax());
// Apply the inverse rotation to the rotated axis aligned bounding box
for(std::size_t i=0; i<8; ++i)
{
obb_points[i] = inverse_transformation.transform(obb_points[i]);
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG
std::cout << " OBB[" << i << "] = " << obb_points[i] << std::endl;
#endif
}
}
template <typename PointRange, typename Traits>
void compute_best_transformation(const PointRange& points,
typename Traits::Aff_transformation_3& transformation,
typename Traits::Aff_transformation_3& inverse_transformation,
CGAL::Random& rng,
const Traits& traits)
{
typedef typename Traits::Matrix Matrix;
typedef typename Traits::Aff_transformation_3 Aff_transformation_3;
CGAL_assertion(points.size() >= 3);
const std::size_t max_generations = 100;
const std::size_t population_size = 30;
const std::size_t nelder_mead_iterations = 20;
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_BENCHMARKS
CGAL::Real_timer timer;
timer.start();
#endif
Evolution<PointRange, Traits> search_solution(points, rng, traits);
search_solution.evolve(max_generations, population_size, nelder_mead_iterations);
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_BENCHMARKS
std::cout << "evolve: " << timer.time() << std::endl;
timer.reset();
#endif
const Matrix& rot = search_solution.get_best_vertex().matrix();
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_BENCHMARKS
std::cout << "get best: " << timer.time() << std::endl;
#endif
transformation = Aff_transformation_3(rot(0, 0), rot(0, 1), rot(0, 2),
rot(1, 0), rot(1, 1), rot(1, 2),
rot(2, 0), rot(2, 1), rot(2, 2));
// inverse transformation is simply the transposed since the matrix is unitary
inverse_transformation = Aff_transformation_3(rot(0, 0), rot(1, 0), rot(2, 0),
rot(0, 1), rot(1, 1), rot(2, 1),
rot(0, 2), rot(1, 2), rot(2, 2));
}
// Following two functions are overloads to dispatch depending on return type
template <typename PointRange, typename K, typename Traits>
void construct_oriented_bounding_box(const PointRange& points,
CGAL::Aff_transformation_3<K>& transformation,
CGAL::Random& rng,
const Traits& traits)
{
typename Traits::Aff_transformation_3 inverse_transformation;
compute_best_transformation(points, transformation, inverse_transformation, rng, traits);
}
template <typename PointRange, typename Array, typename Traits>
void construct_oriented_bounding_box(const PointRange& points,
Array& obb_points,
CGAL::Random& rng,
const Traits& traits,
typename boost::enable_if<
typename boost::has_range_iterator<Array>
>::type* = 0)
{
typename Traits::Aff_transformation_3 transformation, inverse_transformation;
compute_best_transformation(points, transformation, inverse_transformation, rng, traits);
construct_oriented_bounding_box(points, transformation, inverse_transformation, obb_points, traits);
}
template <typename PointRange, typename PolygonMesh, typename Traits>
void construct_oriented_bounding_box(const PointRange& points,
PolygonMesh& pm,
CGAL::Random& rng,
const Traits& traits,
typename boost::disable_if<
typename boost::has_range_iterator<PolygonMesh>
>::type* = 0)
{
typename Traits::Aff_transformation_3 transformation, inverse_transformation;
compute_best_transformation(points, transformation, inverse_transformation, rng, traits);
std::array<typename Traits::Point_3, 8> obb_points;
construct_oriented_bounding_box(points, transformation, inverse_transformation, obb_points, traits);
CGAL::make_hexahedron(obb_points[0], obb_points[1], obb_points[2], obb_points[3],
obb_points[4], obb_points[5], obb_points[6], obb_points[7], pm);
}
// Entry point, decide whether to compute the CH_3 or not
template <typename PointRange, typename Output, typename Traits>
void construct_oriented_bounding_box(const PointRange& points,
const bool use_ch,
Output& output,
CGAL::Random& rng,
const Traits& traits)
{
typedef typename Traits::Point_3 Point;
CGAL_static_assertion((std::is_same<typename boost::range_value<PointRange>::type, Point>::value));
if(use_ch) // construct the convex hull to reduce the number of points
{
std::vector<Point> ch_points;
CGAL::Convex_hull_traits_3<Traits> CH_traits;
extreme_points_3(points, std::back_inserter(ch_points), CH_traits);
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG
std::cout << ch_points.size() << " points on the convex hull" << std::endl;
#endif
return construct_oriented_bounding_box(ch_points, output, rng, traits);
}
else
{
return construct_oriented_bounding_box(points, output, rng, traits);
}
}
} // namespace internal
} // namespace Optimal_bounding_box
/// \addtogroup PkgOptimalBoundingBox_Oriented_bounding_box
///
/// The function `oriented_bounding_box` computes an approximation of the <i>optimal bounding box</i>,
/// which is defined as the rectangular box with smallest volume of all the rectangular boxes containing
/// the input points.
///
/// Internally, the algorithm uses an optimization process to compute a transformation (rotation)
/// \f$ {\mathcal R}_b\f$ such that the axis-aligned box of the rotated input point set
/// has a volume that is as small as possible given a fixed maximal number of optimization iterations.
///
/// \cgalHeading{Input}
///
/// The input can be either a range of points, or a polygon mesh.
///
/// \cgalHeading{Output}
///
/// The result of the algorithm can be retrieved as either:
/// - the best affine transformation \f${\mathcal R}_b\f$ that the algorithm has found;
/// - an array of eight points, representing the best oriented bounding box (\f${\mathcal B}_b\f$)
/// that the algorithm has constructed, which is related to \f$ {\mathcal R}_b\f$ as it is
/// the inverse transformation of the axis-aligned bounding box of the transformed point set.
/// The order of the points in the array is the same as in the function
/// \link PkgBGLHelperFct `CGAL::make_hexahedron()` \endlink,
/// which can be used to construct a mesh from these points.
///
/// Note that when returning an array of points, these points are constructed from the axis-aligned
/// bounding box and some precision loss should therefore be expected if a kernel not providing
/// exact constructions is used.
///
/// The algorithm is based on a paper by Chang, Gorissen, and Melchior \cgalCite{cgal:cgm-fobbo-11}.
/// \ingroup PkgOptimalBoundingBox_Oriented_bounding_box
///
/// The function `oriented_bounding_box` computes an approximation of the <i>optimal bounding box</i>,
/// which is defined as the rectangular box with smallest volume of all the rectangular boxes containing
/// the input points.
///
/// See \ref PkgOptimalBoundingBox_Oriented_bounding_box for more information.
///
/// \tparam PointRange a model of `Range`. The value type may not be equal to the type `%Point_3` of the traits class
/// if a point map is provided via named parameters (see below) to access points.
/// \tparam Output either the type `Aff_transformation_3` of the traits class,
/// or `std::array<Point, 8>` with `Point` being equivalent to the type `%Point_3` of the traits class,
/// or a model of `MutableFaceGraph`
/// \tparam NamedParameters a sequence of \ref obb_namedparameters "Named Parameters"
///
/// \param points the input range
/// \param out the resulting array of points or affine transformation
/// \param np an optional sequence of \ref obb_namedparameters "Named Parameters" among the ones listed below:
///
/// \cgalNamedParamsBegin
/// \cgalParamBegin{point_map}
/// a model of `ReadablePropertyMap` with value type the type `%Point_3` of the traits class.
/// If this parameter is omitted, `CGAL::Identity_property_map<%Point_3>` is used.
/// \cgalParamEnd
/// \cgalParamBegin{geom_traits}
/// a geometric traits class instance, model of the concept `OrientedBoundingBoxTraits_3`.
/// %Default is a default construction object of type `CGAL::Oriented_bounding_box_traits_3<K>`
/// where `K` is a kernel type deduced from the point type.
/// \cgalParamEnd
/// \cgalParamBegin{use_convex_hull}
/// a Boolean value to indicate whether the algorithm should first extract the so-called extreme
/// points of the data range (i.e. construct the convex hull) to reduce the input data range
/// and accelerate the algorithm. %Default is `true`.
/// \cgalParamEnd
/// \cgalNamedParamsEnd
///
template <typename PointRange,
typename Output,
typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
void oriented_bounding_box(const PointRange& points,
Output& out,
const CGAL_BGL_NP_CLASS& np
#ifndef DOXYGEN_RUNNING
, typename boost::enable_if<
typename boost::has_range_iterator<PointRange>
>::type* = 0
#endif
)
{
using CGAL::parameters::choose_parameter;
using CGAL::parameters::get_parameter;
typedef typename CGAL::GetPointMap<PointRange, CGAL_BGL_NP_CLASS>::type PointMap;
#if defined(CGAL_EIGEN3_ENABLED)
typedef typename boost::property_traits<PointMap>::value_type Point;
typedef typename CGAL::Kernel_traits<Point>::type K;
typedef Oriented_bounding_box_traits_3<K> Default_traits;
#else
typedef void Default_traits;
#endif
typedef typename internal_np::Lookup_named_param_def<internal_np::geom_traits_t,
CGAL_BGL_NP_CLASS,
Default_traits>::type Geom_traits;
CGAL_static_assertion_msg(!(std::is_same<Geom_traits, void>::value),
"You must provide a traits class or have Eigen enabled!");
Geom_traits traits = choose_parameter<Geom_traits>(get_parameter(np, internal_np::geom_traits));
PointMap point_map = choose_parameter<PointMap>(get_parameter(np, internal_np::point_map));
const bool use_ch = choose_parameter(get_parameter(np, internal_np::use_convex_hull), true);
const unsigned int seed = choose_parameter(get_parameter(np, internal_np::random_seed), -1); // undocumented
CGAL::Random fixed_seed_rng(seed);
CGAL::Random& rng = (seed == unsigned(-1)) ? CGAL::get_default_random() : fixed_seed_rng;
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG
std::cout << "Random seed: " << rng.get_seed() << std::endl;
#endif
// @todo handle those cases (or call min_rectangle_2 with a projection)
if(points.size() <= 3)
{
std::cerr << "The oriented bounding box cannot (yet) be computed for a mesh with fewer than 4 vertices!\n";
return;
}
return Optimal_bounding_box::internal::construct_oriented_bounding_box(
CGAL::make_range(
boost::make_transform_iterator(points.begin(), CGAL::Property_map_to_unary_function<PointMap>(point_map)),
boost::make_transform_iterator(points.end(), CGAL::Property_map_to_unary_function<PointMap>(point_map))),
use_ch, out, rng, traits);
}
/// \ingroup PkgOptimalBoundingBox_Oriented_bounding_box
///
/// Extracts the vertices of the mesh as a point range and calls the overload using points as input.
///
/// \tparam PolygonMesh a model of `VertexListGraph`
/// \tparam Output either the type `Aff_transformation_3` of the traits class,
/// or `std::array<Point, 8>` with `Point` being equivalent to the type `%Point_3` of the traits class,
/// or a model of `MutableFaceGraph`
/// \tparam NamedParameters a sequence of \ref obb_namedparameters "Named Parameters"
///
/// \param pmesh the input mesh
/// \param out the resulting array of points or affine transformation
/// \param np an optional sequence of \ref obb_namedparameters "Named Parameters" among the ones listed below:
///
/// \cgalNamedParamsBegin
/// \cgalParamBegin{vertex_point_map}
/// the property map with the points associated to the vertices of `pmesh`.
/// If this parameter is omitted, an internal property map for
/// `CGAL::vertex_point_t` must be available in `PolygonMesh`.
/// \cgalParamEnd
/// \cgalParamBegin{geom_traits}
/// a geometric traits class instance, model of the concept `OrientedBoundingBoxTraits_3`.
/// %Default is a default construction object of type `CGAL::Oriented_bounding_box_traits_3<K>`
/// where `K` is a kernel type deduced from the point type.
/// \cgalParamEnd
/// \cgalParamBegin{use_convex_hull}
/// a Boolean value to indicate whether the algorithm should first extract the so-called extreme
/// points of the data range (i.e. construct the convex hull) to reduce the input data range
/// and accelerate the algorithm. %Default is `true`.
/// \cgalParamEnd
/// \cgalNamedParamsEnd
///
template <typename PolygonMesh,
typename Output,
typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
void oriented_bounding_box(const PolygonMesh& pmesh,
Output& out,
const CGAL_BGL_NP_CLASS& np
#ifndef DOXYGEN_RUNNING
, typename boost::disable_if<
typename boost::has_range_iterator<PolygonMesh>
>::type* = 0
#endif
)
{
namespace PMP = CGAL::Polygon_mesh_processing;
using CGAL::parameters::choose_parameter;
using CGAL::parameters::get_parameter;
typedef typename CGAL::GetVertexPointMap<PolygonMesh, CGAL_BGL_NP_CLASS>::const_type VPM;
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(vertex_point, pmesh));
oriented_bounding_box(vertices(pmesh), out, np.point_map(vpm));
}
/// \cond SKIP_IN_MANUAL
///////////////////////////////////////////////////////////////////////////////////////////////////
/// Convenience overloads
/////////////////////////////////////////////////////////////////////////////////////////////////
template <typename Input /*range or mesh*/, typename Output /*transformation, array, or mesh*/>
void oriented_bounding_box(const Input& in, Output& out)
{
return oriented_bounding_box(in, out, CGAL::parameters::all_default());
}
/// \endcond
} // end namespace CGAL
#endif // CGAL_OPTIMAL_BOUNDING_BOX_ORIENTED_BOUNDING_BOX_H

View File

@ -0,0 +1,30 @@
// Copyright (c) 2018-2019 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Konstantinos Katrioplas
// Mael Rouxel-Labbé
//
#ifndef CGAL_OPTIMAL_BOUNDING_BOX_OBB_H
#define CGAL_OPTIMAL_BOUNDING_BOX_OBB_H
#ifndef DOXYGEN_RUNNING
#include <CGAL/license/Optimal_bounding_box.h>
#endif
/**
* \ingroup PkgOptimalBoundingBoxRef
* \file CGAL/optimal_bounding_box.h
* Convenience header file including the headers for all the classes and functions of this package.
*/
#include <CGAL/Optimal_bounding_box/Oriented_bounding_box_traits_3.h>
#include <CGAL/Optimal_bounding_box/oriented_bounding_box.h>
#endif // CGAL_OPTIMAL_BOUNDING_BOX_OBB_H

View File

@ -0,0 +1 @@
GeometryFactory (France)

View File

@ -0,0 +1,32 @@
Algebraic_foundations
Arithmetic_kernel
BGL
Bounding_volumes
Cartesian_kernel
Circulator
Convex_hull_2
Convex_hull_3
Distance_2
Distance_3
Filtered_kernel
Hash_map
Homogeneous_kernel
Installation
Intersections_2
Intersections_3
Interval_support
Kernel_23
Kernel_d
Modular_arithmetic
Number_types
Optimal_bounding_box
Optimisation_basic
Polygon
Profiling_tools
Property_map
Random_numbers
STL_Extension
Solver_interface
Stream_support
TDS_2
Triangulation_2

View File

@ -0,0 +1 @@
GPL (v3 or later)

View File

@ -0,0 +1 @@
GeometryFactory

View File

@ -0,0 +1,31 @@
# Created by the script cgal_create_CMakeLists
# This is the CMake script for compiling a set of CGAL applications.
cmake_minimum_required(VERSION 3.1...3.15)
project( Optimal_bounding_box_Tests )
find_package(CGAL QUIET)
if (NOT CGAL_FOUND)
message(STATUS "This project requires the CGAL library, and will not be compiled.")
return()
endif()
include( ${CGAL_USE_FILE} )
find_package(Eigen3 3.1.0 REQUIRED) #(3.1.0 or greater)
if (NOT EIGEN3_FOUND)
message(STATUS "This project requires the Eigen library, and will not be compiled.")
return()
endif()
create_single_source_cgal_program("test_OBB_traits.cpp")
create_single_source_cgal_program("test_nelder_mead.cpp")
create_single_source_cgal_program("test_optimization_algorithms.cpp")
foreach(target
test_OBB_traits
test_nelder_mead
test_optimization_algorithms)
CGAL_target_use_Eigen(${target})
endforeach()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,323 @@
OFF
121 200 0
0 0 0
0.10000000000000001 0 0
0.20000000000000001 0 0
0.29999999999999999 0 0
0.40000000000000002 0 0
0.5 0 0
0.59999999999999998 0 0
0.69999999999999996 0 0
0.80000000000000004 0 0
0.90000000000000002 0 0
1 0 0
0 0.10000000000000001 0.10000000000000001
0.10000000000000001 0.10000000000000001 0.10000000000000001
0.20000000000000001 0.10000000000000001 0.10000000000000001
0.29999999999999999 0.10000000000000001 0.10000000000000001
0.40000000000000002 0.10000000000000001 0.10000000000000001
0.5 0.10000000000000001 0.10000000000000001
0.59999999999999998 0.10000000000000001 0.10000000000000001
0.69999999999999996 0.10000000000000001 0.10000000000000001
0.80000000000000004 0.10000000000000001 0.10000000000000001
0.90000000000000002 0.10000000000000001 0.10000000000000001
1 0.10000000000000001 0.10000000000000001
0 0.20000000000000001 0.20000000000000001
0.10000000000000001 0.20000000000000001 0.20000000000000001
0.20000000000000001 0.20000000000000001 0.20000000000000001
0.29999999999999999 0.20000000000000001 0.20000000000000001
0.40000000000000002 0.20000000000000001 0.20000000000000001
0.5 0.20000000000000001 0.20000000000000001
0.59999999999999998 0.20000000000000001 0.20000000000000001
0.69999999999999996 0.20000000000000001 0.20000000000000001
0.80000000000000004 0.20000000000000001 0.20000000000000001
0.90000000000000002 0.20000000000000001 0.20000000000000001
1 0.20000000000000001 0.20000000000000001
0 0.29999999999999999 0.29999999999999999
0.10000000000000001 0.29999999999999999 0.29999999999999999
0.20000000000000001 0.29999999999999999 0.29999999999999999
0.29999999999999999 0.29999999999999999 0.29999999999999999
0.40000000000000002 0.29999999999999999 0.29999999999999999
0.5 0.29999999999999999 0.29999999999999999
0.59999999999999998 0.29999999999999999 0.29999999999999999
0.69999999999999996 0.29999999999999999 0.29999999999999999
0.80000000000000004 0.29999999999999999 0.29999999999999999
0.90000000000000002 0.29999999999999999 0.29999999999999999
1 0.29999999999999999 0.29999999999999999
0 0.40000000000000002 0.40000000000000002
0.10000000000000001 0.40000000000000002 0.40000000000000002
0.20000000000000001 0.40000000000000002 0.40000000000000002
0.29999999999999999 0.40000000000000002 0.40000000000000002
0.40000000000000002 0.40000000000000002 0.40000000000000002
0.5 0.40000000000000002 0.40000000000000002
0.59999999999999998 0.40000000000000002 0.40000000000000002
0.69999999999999996 0.40000000000000002 0.40000000000000002
0.80000000000000004 0.40000000000000002 0.40000000000000002
0.90000000000000002 0.40000000000000002 0.40000000000000002
1 0.40000000000000002 0.40000000000000002
0 0.5 0.5
0.10000000000000001 0.5 0.5
0.20000000000000001 0.5 0.5
0.29999999999999999 0.5 0.5
0.40000000000000002 0.5 0.5
0.5 0.5 0.5
0.59999999999999998 0.5 0.5
0.69999999999999996 0.5 0.5
0.80000000000000004 0.5 0.5
0.90000000000000002 0.5 0.5
1 0.5 0.5
0 0.59999999999999998 0.59999999999999998
0.10000000000000001 0.59999999999999998 0.59999999999999998
0.20000000000000001 0.59999999999999998 0.59999999999999998
0.29999999999999999 0.59999999999999998 0.59999999999999998
0.40000000000000002 0.59999999999999998 0.59999999999999998
0.5 0.59999999999999998 0.59999999999999998
0.59999999999999998 0.59999999999999998 0.59999999999999998
0.69999999999999996 0.59999999999999998 0.59999999999999998
0.80000000000000004 0.59999999999999998 0.59999999999999998
0.90000000000000002 0.59999999999999998 0.59999999999999998
1 0.59999999999999998 0.59999999999999998
0 0.69999999999999996 0.69999999999999996
0.10000000000000001 0.69999999999999996 0.69999999999999996
0.20000000000000001 0.69999999999999996 0.69999999999999996
0.29999999999999999 0.69999999999999996 0.69999999999999996
0.40000000000000002 0.69999999999999996 0.69999999999999996
0.5 0.69999999999999996 0.69999999999999996
0.59999999999999998 0.69999999999999996 0.69999999999999996
0.69999999999999996 0.69999999999999996 0.69999999999999996
0.80000000000000004 0.69999999999999996 0.69999999999999996
0.90000000000000002 0.69999999999999996 0.69999999999999996
1 0.69999999999999996 0.69999999999999996
0 0.80000000000000004 0.80000000000000004
0.10000000000000001 0.80000000000000004 0.80000000000000004
0.20000000000000001 0.80000000000000004 0.80000000000000004
0.29999999999999999 0.80000000000000004 0.80000000000000004
0.40000000000000002 0.80000000000000004 0.80000000000000004
0.5 0.80000000000000004 0.80000000000000004
0.59999999999999998 0.80000000000000004 0.80000000000000004
0.69999999999999996 0.80000000000000004 0.80000000000000004
0.80000000000000004 0.80000000000000004 0.80000000000000004
0.90000000000000002 0.80000000000000004 0.80000000000000004
1 0.80000000000000004 0.80000000000000004
0 0.90000000000000002 0.90000000000000002
0.10000000000000001 0.90000000000000002 0.90000000000000002
0.20000000000000001 0.90000000000000002 0.90000000000000002
0.29999999999999999 0.90000000000000002 0.90000000000000002
0.40000000000000002 0.90000000000000002 0.90000000000000002
0.5 0.90000000000000002 0.90000000000000002
0.59999999999999998 0.90000000000000002 0.90000000000000002
0.69999999999999996 0.90000000000000002 0.90000000000000002
0.80000000000000004 0.90000000000000002 0.90000000000000002
0.90000000000000002 0.90000000000000002 0.90000000000000002
1 0.90000000000000002 0.90000000000000002
0 1 1
0.10000000000000001 1 1
0.20000000000000001 1 1
0.29999999999999999 1 1
0.40000000000000002 1 1
0.5 1 1
0.59999999999999998 1 1
0.69999999999999996 1 1
0.80000000000000004 1 1
0.90000000000000002 1 1
1 1 1
3 0 1 11
3 1 12 11
3 11 12 22
3 12 23 22
3 22 23 33
3 23 34 33
3 33 34 44
3 34 45 44
3 44 45 55
3 45 56 55
3 55 56 66
3 56 67 66
3 66 67 77
3 67 78 77
3 77 78 88
3 78 89 88
3 88 89 99
3 89 100 99
3 99 100 110
3 100 111 110
3 1 2 12
3 2 13 12
3 12 13 23
3 13 24 23
3 23 24 34
3 24 35 34
3 34 35 45
3 35 46 45
3 45 46 56
3 46 57 56
3 56 57 67
3 57 68 67
3 67 68 78
3 68 79 78
3 78 79 89
3 79 90 89
3 89 90 100
3 90 101 100
3 100 101 111
3 101 112 111
3 2 3 13
3 3 14 13
3 13 14 24
3 14 25 24
3 24 25 35
3 25 36 35
3 35 36 46
3 36 47 46
3 46 47 57
3 47 58 57
3 57 58 68
3 58 69 68
3 68 69 79
3 69 80 79
3 79 80 90
3 80 91 90
3 90 91 101
3 91 102 101
3 101 102 112
3 102 113 112
3 3 4 14
3 4 15 14
3 14 15 25
3 15 26 25
3 25 26 36
3 26 37 36
3 36 37 47
3 37 48 47
3 47 48 58
3 48 59 58
3 58 59 69
3 59 70 69
3 69 70 80
3 70 81 80
3 80 81 91
3 81 92 91
3 91 92 102
3 92 103 102
3 102 103 113
3 103 114 113
3 4 5 15
3 5 16 15
3 15 16 26
3 16 27 26
3 26 27 37
3 27 38 37
3 37 38 48
3 38 49 48
3 48 49 59
3 49 60 59
3 59 60 70
3 60 71 70
3 70 71 81
3 71 82 81
3 81 82 92
3 82 93 92
3 92 93 103
3 93 104 103
3 103 104 114
3 104 115 114
3 5 6 16
3 6 17 16
3 16 17 27
3 17 28 27
3 27 28 38
3 28 39 38
3 38 39 49
3 39 50 49
3 49 50 60
3 50 61 60
3 60 61 71
3 61 72 71
3 71 72 82
3 72 83 82
3 82 83 93
3 83 94 93
3 93 94 104
3 94 105 104
3 104 105 115
3 105 116 115
3 6 7 17
3 7 18 17
3 17 18 28
3 18 29 28
3 28 29 39
3 29 40 39
3 39 40 50
3 40 51 50
3 50 51 61
3 51 62 61
3 61 62 72
3 62 73 72
3 72 73 83
3 73 84 83
3 83 84 94
3 84 95 94
3 94 95 105
3 95 106 105
3 105 106 116
3 106 117 116
3 7 8 18
3 8 19 18
3 18 19 29
3 19 30 29
3 29 30 40
3 30 41 40
3 40 41 51
3 41 52 51
3 51 52 62
3 52 63 62
3 62 63 73
3 63 74 73
3 73 74 84
3 74 85 84
3 84 85 95
3 85 96 95
3 95 96 106
3 96 107 106
3 106 107 117
3 107 118 117
3 8 9 19
3 9 20 19
3 19 20 30
3 20 31 30
3 30 31 41
3 31 42 41
3 41 42 52
3 42 53 52
3 52 53 63
3 53 64 63
3 63 64 74
3 64 75 74
3 74 75 85
3 75 86 85
3 85 86 96
3 86 97 96
3 96 97 107
3 97 108 107
3 107 108 118
3 108 119 118
3 9 10 20
3 10 21 20
3 20 21 31
3 21 32 31
3 31 32 42
3 32 43 42
3 42 43 53
3 43 54 53
3 53 54 64
3 54 65 64
3 64 65 75
3 65 76 75
3 75 76 86
3 76 87 86
3 86 87 97
3 87 98 97
3 97 98 108
3 98 109 108
3 108 109 119
3 109 120 119

View File

@ -0,0 +1,11 @@
OFF
4 4 0
-1 -0.1 0
-1 0.1 0
1 0 -0.1
1 0 0.1
3 0 1 2
3 2 3 0
3 1 3 2
3 0 3 1

View File

@ -0,0 +1,8 @@
413065776.152494 326396843.840397 326457757.911644
413065776.152494 326396843.840397 326457757.911644
413065776.152494 326396843.840397 326457757.911644
413065776.152494 326396843.840397 326457757.911644
413065776.152494 326396843.840397 326457757.911644
413065776.152494 326396843.840397 326457757.911644
413065776.152494 326396843.840397 326457757.911644

View File

@ -0,0 +1,7 @@
0 0 0
0 1 2
0 2 4
0 3 6
0 10 20
0 0.5 1

View File

@ -0,0 +1,282 @@
413065776.152494 326396843.840397 0
413057847.377906 326403660.329056 0
413052569.655378 326399341.810968 0
412964155.996695 326429557.407149 0
412960887.449993 326443760.793625 0
412939753.084117 326436727.039421 0
412939894.318992 326428463.667967 0
412947664.119328 326419882.748586 0
412970476.46515 326451966.912356 0
412968925.050862 326458160.301721 0
412963543.512664 326454495.012767 0
412985746.970294 326424302.733302 0
412983665.865636 326410836.59751 0
412996088.235308 326419469.954289 0
412998096.793163 326423084.180324 0
413003418.285576 326419809.050109 0
413002038.294065 326427600.699796 0
412945313.935335 326454359.672656 0
412943663.154485 326452834.040025 0
412952251.09554 326452986.901051 0
412950732.333508 326457757.911644 0
412943971.574173 326459149.099198 0
412934361.648126 326445041.605944 0
412936751.268924 326454822.208572 0
412964758.701994 326486192.337374 0
412966490.855253 326478259.235383 0
412973194.081713 326482046.898235 0
412950650.516328 326468707.808723 0
412957725.270744 326476103.847023 0
412950026.231257 326477412.439015 0
412988174.944206 326470661.339091 0
412986909.075808 326462858.270384 0
413000669.61306 326456348.730054 0
412966234.090172 326488146.292068 0
413023232.123734 326461197.560115 0
413023550.270655 326471002.013297 0
413016185.260894 326465438.977186 0
412987141.775588 326489693.339605 0
412982918.043107 326488237.152808 0
412985980.280763 326483135.425286 0
413001196.353514 326479715.175257 0
413008202.547705 326474962.703983 0
413003755.131316 326481400.115507 0
412929683.198695 326465491.420262 0
412920189.499339 326451860.04878 0
412931611.507502 326452533.708517 0
412992581.061321 326477132.127848 0
412989279.419663 326480089.894799 0
412935705.096519 326482202.861555 0
412925307.138482 326466637.344135 0
413076469.52736 326433412.768228 0
413075298.398716 326444763.979995 0
413065834.246237 326440647.027719 0
413009745.175265 326502212.1638 0
413001718.895276 326508920.841833 0
413002418.144751 326497753.488837 0
413060741.401393 326423820.134531 0
413060876.676061 326428728.639701 0
413058999.571918 326423687.390799 0
413025105.511534 326478606.208507 0
413037158.816855 326472407.974956 0
413026100.112628 326483530.179333 0
413079758.83472 326425207.53598 0
413076210.923893 326422944.976439 0
413078151.988242 326416248.664714 0
413053952.794291 326463144.972745 0
413055684.722689 326475529.630202 0
413045099.788495 326474825.69738 0
413062042.967186 326437063.922844 0
413066790.302583 326430817.2269 0
413004709.107113 326490135.418709 0
413005093.685865 326489983.127837 0
413098251.972367 326408565.921651 0
413098367.233587 326415127.45218 0
413097944.35044 326413442.449707 0
413070518.763323 326460355.49692 0
413066193.752266 326467461.946737 0
413087099.80728 326418237.162439 0
412932643.127595 326424163.465682 0
412947239.568275 326415586.45517 0
412929877.917135 326420120.542778 0
413010920.918128 326399072.312299 0
412915060.825449 326423803.643013 0
412963212.559984 326417484.293606 0
412974527.414159 326428576.196833 0
412992373.377627 326455620.014196 0
413010074.272151 326418465.382469 0
413011850.753162 326417002.217271 0
413014406.991439 326420203.661922 0
412977637.839421 326432544.829395 0
412986148.487405 326429359.611152 0
412995280.156846 326431026.989975 0
412990626.28213 326425374.845568 0
413032797.62091 326426191.034153 0
413029970.570148 326419936.329868 0
413044681.544615 326417464.080029 0
412999129.25698 326438072.80725 0
413007734.056563 326423851.649794 0
413016471.93654 326426364.913717 0
412968431.452864 326491828.041548 0
412958675.073533 326494006.076801 0
413012148.256747 326487804.579704 0
413016405.832048 326480671.32311 0
412975768.001435 326448708.020146 0
412979720.162501 326436886.822391 0
412982917.886679 326443564.393356 0
412988678.510158 326449487.248631 0
412985417.106869 326452678.469145 0
412971510.871442 326435116.950769 0
412983109.808175 326457244.32078 0
412957466.876904 326451325.256978 0
412959384.40943 326448781.181773 0
412966768.138142 326473363.04219 0
412971910.952526 326476870.046921 0
412963392.569735 326463111.127056 0
412924771.98365 326432849.602577 0
412917475.177804 326429370.043518 0
412911569.816167 326425718.742949 0
412924489.589924 326449937.575511 0
412956933.247292 326455774.007997 0
412955340.545694 326460219.517522 0
412977018.754996 326466258.738995 0
412970686.301222 326466481.954067 0
412978255.629151 326461355.571957 0
412939153.439846 326465339.238827 0
412923821.154719 326426918.928828 0
412975936.409656 326502806.20831 0
412963303.14509 326498679.785427 0
412969138.482087 326493922.342246 0
412956467.21651 326489106.767098 0
412959578.052441 326480365.162202 0
412977352.621415 326497109.261795 0
412941422.08486 326477143.510512 0
412936831.795868 326467205.375027 0
412961266.195768 326503954.723704 0
412958703.392685 326524881.814902 0
412953249.527674 326518460.235631 0
412935010.36184 326494112.455851 0
412931570.65415 326484602.04937 0
412985374.324569 326513222.867276 0
412978227.727596 326510871.926542 0
412984173.754694 326502503.840454 0
412985688.206537 326494576.776311 0
412978009.820415 326492658.751496 0
412993618.008235 326491281.852681 0
412997947.150272 326492521.079555 0
412976873.960635 326486185.606476 0
412981478.037092 326484421.347501 0
412980418.065914 326478321.690068 0
412979438.184438 326473334.846215 0
413010215.690383 326443409.550491 0
413008228.44707 326458894.052728 0
413035617.465636 326446767.558378 0
413027230.055638 326446990.503477 0
413030854.849802 326440245.461135 0
412979140.451061 326454242.503581 0
412985468.6174 326450604.80651 0
413015771.02389 326453064.045201 0
413021991.755036 326445142.840934 0
413008006.052746 326469763.695134 0
413048901.884808 326422501.5037 0
413045028.78386 326426372.15428 0
413005007.536883 326484301.633515 0
413002785.535959 326490180.214403 0
413014109.69202 326461894.536067 0
413017207.888265 326470063.830947 0
413045293.513014 326449673.312107 0
413044019.75301 326447988.572283 0
413047003.614678 326443105.313308 0
412999003.436139 326487344.001445 0
412996651.65689 326491134.958733 0
413012316.245006 326479912.254408 0
413012587.728747 326484153.816803 0
413016871.37429 326476971.655283 0
413019842.625853 326474794.530385 0
413039469.406178 326437529.843339 0
413041502.67459 326485107.978727 0
413036035.620497 326461314.614016 0
413031490.325583 326456799.67237 0
413020789.72965 326452093.515847 0
413020692.119972 326434154.560939 0
413029690.023638 326438011.408021 0
413043486.972873 326454746.798277 0
413033511.062177 326430679.751046 0
413067488.089213 326425961.293338 0
413083753.259443 326426175.344791 0
413067460.916052 326410232.697374 0
413068622.531383 326416317.705612 0
413061037.102135 326415163.721378 0
413071143.181797 326424762.764848 0
413060387.108431 326414188.28851 0
413060445.58895 326451275.748613 0
413036317.30909 326431883.117032 0
413045873.300553 326435644.793299 0
413048794.267495 326389319.436376 0
413030291.769546 326411368.835099 0
413024488.398109 326415338.686016 0
413021905.956926 326410737.878939 0
413027639.836779 326415641.265719 0
413017857.083999 326417952.301599 0
413029827.400431 326406821.764259 0
413001443.929946 326407150.378482 0
413036041.452869 326405791.758584 0
413033454.48341 326399656.242176 0
413018633.129927 326413338.952301 0
413045368.965357 326402337.610635 0
413048447.394379 326395169.908511 0
412986849.902761 326405367.534053 0
413065081.744554 326401671.778183 0
413092397.837156 326422086.08121 0
413095318.341189 326412788.599152 0
413093695.254875 326400330.203004 0
413099020.077932 326406314.05352 0
413093140.218869 326403110.903958 0
413056121.776141 326406403.684953 0
413089620.108842 326414007.091517 0
413089387.417624 326419721.87399 0
413093404.232693 326395001.998282 0
413085896.789345 326396361.60811 0
413085454.676931 326391470.731474 0
413074508.839395 326394470.397757 0
413068350.570434 326395560.501438 0
413070143.96055 326386445.935889 0
412918858.560132 326434979.970278 0
412955394.145789 326449536.682215 0
412971144.038673 326433652.368538 0
412965073.360409 326439051.77804 0
412970981.692447 326409503.990341 0
413014840.087809 326404397.988193 0
412994018.136075 326445298.914892 0
412990097.829467 326437133.362141 0
412965842.792609 326448792.291328 0
412961763.785867 326445852.010028 0
412947255.093497 326463668.462422 0
412939952.26946 326466492.382176 0
412943709.427436 326472618.681827 0
412952246.783422 326483371.121473 0
412944807.921928 326491083.247909 0
412940579.938471 326495813.432763 0
412945630.90436 326501939.425427 0
412938409.182245 326503335.780256 0
412951371.196888 326498868.583434 0
412949313.764109 326504296.763374 0
412945558.683443 326510754.714855 0
413008766.713556 326484732.391891 0
412990390.280433 326484843.195428 0
412995165.502732 326483367.864039 0
413016256.164946 326494798.780171 0
413017224.89391 326461129.632116 0
413029625.683716 326471350.776378 0
413025019.999494 326476200.095554 0
413048766.414482 326435871.77665 0
413051725.256746 326438529.947023 0
413052007.160945 326422036.946841 0
413058067.843268 326435775.445353 0
413083660.953967 326393424.812132 0
413083336.161107 326400813.355748 0
413066349.33981 326419281.508749 0
413068090.500382 326410610.12681 0
413074241.401196 326404770.242276 0
413081317.053152 326414171.97812 0
413073381.651167 326406897.136775 0
413095766.46998 326387248.540458 0
413097047.640536 326395426.23288 0
413098209.521961 326406637.959602 0
413089554.505615 326388294.334232 0
413074403.539056 326415367.945363 0
413040020.425247 326411046.731682 0
413045679.434506 326406659.04965 0
413039095.903129 326409071.668118 0
413031306.230818 326393733.283998 0
413052303.600823 326400659.626307 0
413081695.584061 326380509.699198 0
413077541.674433 326389883.685777 0
413082416.500748 326382824.511316 0
413073027.473224 326382906.090405 0
413088349.695199 326383000.125606 0
413094911.539918 326387536.877598 0
413092119.400999 326388985.514422 0
413093374.909798 326384034.886791 0
413096500.785907 326395520.129613 0
413094014.467295 326377700.363085 0

View File

@ -0,0 +1,12 @@
OFF
4 4 0
0 1 0
1 0 0
0 0 0
0 0 1
3 0 1 2
3 2 3 0
3 1 3 2
3 0 3 1

View File

@ -0,0 +1,9 @@
OFF
4 2 0
0 0 0
1 0 0
0 1 0
1 1 0
3 0 1 2
3 2 1 3

View File

@ -0,0 +1,110 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/optimal_bounding_box.h>
#include <CGAL/assertions.h>
#include <array>
#include <iostream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
typedef K::Point_3 Point_3;
typedef CGAL::Oriented_bounding_box_traits_3<K> Traits;
typedef Traits::Matrix Matrix;
void check_equality(const FT d1, const FT d2)
{
const FT epsilon = 1e-3;
bool ok;
if(std::is_floating_point<FT>::value)
ok = CGAL::abs(d1 - d2) < epsilon * CGAL::abs(d2);
else
ok = (d1 == d2);
if(!ok)
{
std::cout << "Error: got " << d1 << " but expected: " << d2 << std::endl;
assert(false);
}
}
void test_fitness_function(const Traits& traits)
{
std::array<Point_3, 4> points;
points[0] = Point_3(0.866802, 0.740808, 0.895304);
points[1] = Point_3(0.912651, 0.761565, 0.160330);
points[2] = Point_3(0.093661, 0.892578, 0.737412);
points[3] = Point_3(0.166461, 0.149912, 0.364944);
Matrix rotation;
rotation.set(0, 0, -0.809204);
rotation.set(0, 1, 0.124296);
rotation.set(0, 2, 0.574230);
rotation.set(1, 0, -0.574694);
rotation.set(1, 1, 0.035719);
rotation.set(1, 2, -0.817589);
rotation.set(2, 0, -0.122134);
rotation.set(2, 1, -0.991602);
rotation.set(2, 2, 0.042528);
const double fitness = CGAL::Optimal_bounding_box::internal::compute_fitness(rotation, points, traits);
check_equality(fitness, 0.58606);
}
void test_eigen_matrix_interface()
{
Matrix A;
A.set(0, 0, 0.1);
A.set(0, 1, 0.2);
A.set(0, 2, 0.3);
A.set(1, 0, 0.4);
A.set(1, 1, 0.5);
A.set(1, 2, 0.6);
A.set(2, 0, 0.7);
A.set(2, 1, 0.8);
A.set(2, 2, 0.9);
Matrix B;
B = CGAL::Optimal_bounding_box::internal::transpose(A);
Matrix S;
S = 0.5 * A;
Matrix C;
C.set(0, 0, 0.3011944);
C.set(0, 1, 0.9932761);
C.set(0, 2, 0.5483701);
C.set(1, 0, 0.5149142);
C.set(1, 1, 0.5973263);
C.set(1, 2, 0.5162336);
C.set(2, 0, 0.0039213);
C.set(2, 1, 0.0202949);
C.set(2, 2, 0.9240308);
Matrix Q = Traits::get_Q(C);
check_equality(Q(0,0), -0.504895);
check_equality(Q(0,1), 0.862834);
check_equality(Q(0,2), -0.024447);
check_equality(Q(1,0), -0.863156);
check_equality(Q(1,1), -0.504894);
check_equality(Q(1,2), 0.006687);
check_equality(Q(2,0), -0.006573);
check_equality(Q(2,1), 0.024478);
check_equality(Q(2,2), 0.999679);
}
int main(int, char**)
{
Traits traits;
test_fitness_function(traits);
test_eigen_matrix_interface();
std::cout << "Done!" << std::endl;
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,209 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/optimal_bounding_box.h>
#include <iostream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
typedef K::Point_3 Point_3;
typedef CGAL::Oriented_bounding_box_traits_3<K> Traits;
typedef Traits::Matrix Matrix;
typedef CGAL::Optimal_bounding_box::internal::Population<Traits>::Vertex Vertex;
void check_equality(const FT d1, const FT d2)
{
const FT epsilon = 1e-3;
bool ok;
if(std::is_floating_point<FT>::value)
ok = CGAL::abs(d1 - d2) < epsilon * CGAL::abs(d2);
else
ok = (d1 == d2);
if(!ok)
{
std::cout << "Error: got " << d1 << " but expected: " << d2 << std::endl;
assert(false);
}
}
void test_simplex_operations(const Traits& traits)
{
Matrix Sc;
Sc.set(0, 0, -0.809204); Sc.set(0, 1, 0.124296); Sc.set(0, 2, 0.574230);
Sc.set(1, 0, -0.574694); Sc.set(1, 1, 0.035719); Sc.set(1, 2, -0.817589);
Sc.set(2, 0, -0.122134); Sc.set(2, 1, -0.991602); Sc.set(2, 2, 0.042528);
Matrix S_worst;
S_worst.set(0, 0, -0.45070); S_worst.set(0, 1, -0.32769); S_worst.set(0, 2, -0.83035);
S_worst.set(1, 0, -0.13619); S_worst.set(1, 1, -0.89406); S_worst.set(1, 2, 0.42675);
S_worst.set(2, 0, -0.88222); S_worst.set(2, 1, 0.30543); S_worst.set(2, 2, 0.35833);
Matrix Sr = CGAL::Optimal_bounding_box::internal::reflection(Sc, S_worst);
check_equality(Sr(0,0), -0.13359);
check_equality(Sr(0,1), -0.95986);
check_equality(Sr(0,2), -0.24664);
check_equality(Sr(1,0), -0.60307);
check_equality(Sr(1,1), -0.11875);
check_equality(Sr(1,2), 0.78880);
check_equality(Sr(2,0), -0.78642);
check_equality(Sr(2,1), 0.25411);
check_equality(Sr(2,2), -0.56300);
Matrix Se = CGAL::Optimal_bounding_box::internal::expansion(Sc, S_worst, Sr);
check_equality(Se(0,0), -0.87991);
check_equality(Se(0,1), 0.36105);
check_equality(Se(0,2), -0.30888);
check_equality(Se(1,0), -0.11816);
check_equality(Se(1,1), -0.79593);
check_equality(Se(1,2), -0.59375);
check_equality(Se(2,0), -0.460215);
check_equality(Se(2,1), -0.48595);
check_equality(Se(2,2), 0.74300);
Matrix S_a;
S_a.set(0, 0, -0.277970); S_a.set(0, 1, 0.953559); S_a.set(0, 2, 0.116010);
S_a.set(1, 0, -0.567497); S_a.set(1, 1, -0.065576); S_a.set(1, 2, -0.820760);
S_a.set(2, 0, -0.775035); S_a.set(2, 1, -0.293982); S_a.set(2, 2, 0.559370);
Matrix S_b;
S_b.set(0, 0, -0.419979); S_b.set(0, 1, 0.301765); S_b.set(0, 2, -0.8558940);
S_b.set(1, 0, -0.653011); S_b.set(1, 1, -0.755415); S_b.set(1, 2, 0.054087);
S_b.set(2, 0, -0.630234); S_b.set(2, 1, 0.581624); S_b.set(2, 2, 0.514314);
Matrix S_c = CGAL::Optimal_bounding_box::internal::mean(S_a, S_b, traits);
check_equality(S_c(0,0), -0.35111);
check_equality(S_c(0,1), 0.79308);
check_equality(S_c(0,2), -0.49774);
check_equality(S_c(1,0), -0.61398);
check_equality(S_c(1,1), -0.59635);
check_equality(S_c(1,2), -0.51710);
check_equality(S_c(2,0), -0.70693);
check_equality(S_c(2,1), 0.12405);
check_equality(S_c(2,2), 0.69632);
}
void test_centroid(const Traits& traits)
{
Matrix S_a;
S_a.set(0, 0, -0.588443); S_a.set(0, 1, 0.807140); S_a.set(0, 2, -0.047542);
S_a.set(1, 0, -0.786228); S_a.set(1, 1, -0.584933); S_a.set(1, 2, -0.199246);
S_a.set(2, 0, -0.188629); S_a.set(2, 1, -0.079867); S_a.set(2, 2, 0.978795);
Matrix S_b;
S_b.set(0, 0, -0.2192721); S_b.set(0, 1, 0.2792986); S_b.set(0, 2, -0.9348326);
S_b.set(1, 0, -0.7772152); S_b.set(1, 1, -0.6292092); S_b.set(1, 2, -0.005686);
S_b.set(2, 0, -0.5897934); S_b.set(2, 1, 0.7253193); S_b.set(2, 2, 0.3550431);
Matrix S_c;
S_c.set(0, 0, -0.32657); S_c.set(0, 1, -0.60013); S_c.set(0, 2, -0.730206);
S_c.set(1, 0, -0.20022); S_c.set(1, 1, -0.71110); S_c.set(1, 2, 0.67398);
S_c.set(2, 0, -0.92372); S_c.set(2, 1, 0.36630); S_c.set(2, 2, 0.11207);
Matrix S_centroid = CGAL::Optimal_bounding_box::internal::nm_centroid(S_a, S_b, S_c, traits);
check_equality(S_centroid(0,0), -0.419979);
check_equality(S_centroid(0,1), 0.301765);
check_equality(S_centroid(0,2), -0.855894);
check_equality(S_centroid(1,0), -0.653011);
check_equality(S_centroid(1,1), -0.755415);
check_equality(S_centroid(1,2), 0.054087);
check_equality(S_centroid(2,0), -0.630234);
check_equality(S_centroid(2,1), 0.581624);
check_equality(S_centroid(2,2), 0.514314);
}
void test_nelder_mead(const Traits& traits)
{
std::array<Point_3, 4> points;
points[0] = Point_3(0.866802, 0.740808, 0.895304);
points[1] = Point_3(0.912651, 0.761565, 0.160330);
points[2] = Point_3(0.093661, 0.892578, 0.737412);
points[3] = Point_3(0.166461, 0.149912, 0.364944);
// one simplex
std::array<Vertex, 4> simplex;
Matrix v0, v1, v2, v3;
v0.set(0, 0, -0.2192721); v0.set(0, 1, 0.2792986); v0.set(0, 2, -0.9348326);
v0.set(1, 0, -0.7772152); v0.set(1, 1, -0.6292092); v0.set(1, 2, -0.0056861);
v0.set(2, 0, -0.5897934); v0.set(2, 1, 0.7253193); v0.set(2, 2, 0.3550431);
v1.set(0, 0, -0.588443); v1.set(0, 1, 0.807140); v1.set(0, 2, -0.047542);
v1.set(1, 0, -0.786228); v1.set(1, 1, -0.584933); v1.set(1, 2, -0.199246);
v1.set(2, 0, -0.188629); v1.set(2, 1, -0.079867); v1.set(2, 2, 0.978795);
v2.set(0, 0, -0.277970); v2.set(0, 1, 0.953559); v2.set(0, 2, 0.116010);
v2.set(1, 0, -0.567497); v2.set(1, 1, -0.065576); v2.set(1, 2, -0.820760);
v2.set(2, 0, -0.775035); v2.set(2, 1, -0.293982); v2.set(2, 2, 0.559370);
v3.set(0, 0, -0.32657); v3.set(0, 1, -0.60013); v3.set(0, 2, -0.73020);
v3.set(1, 0, -0.20022); v3.set(1, 1, -0.71110); v3.set(1, 2, 0.67398);
v3.set(2, 0, -0.92372); v3.set(2, 1, 0.36630); v3.set(2, 2, 0.11207);
simplex[0] = Vertex{v0, points, traits};
simplex[1] = Vertex{v1, points, traits};
simplex[2] = Vertex{v2, points, traits};
simplex[3] = Vertex{v3, points, traits};
std::size_t nm_iterations = 19;
CGAL::Optimal_bounding_box::internal::nelder_mead(simplex, nm_iterations, points, traits);
const Matrix& v0_new = simplex[0].matrix();
check_equality(v0_new(0,0), -0.288975);
check_equality(v0_new(0,1), 0.7897657);
check_equality(v0_new(0,2), -0.541076);
check_equality(v0_new(1,0), -0.9407046);
check_equality(v0_new(1,1), -0.3391466);
check_equality(v0_new(1,2), 0.0073817);
check_equality(v0_new(2,0), -0.1776743);
check_equality(v0_new(2,1), 0.5111260);
check_equality(v0_new(2,2), 0.84094);
const Matrix& v1_new = simplex[1].matrix();
check_equality(v1_new(0,0), -0.458749);
check_equality(v1_new(0,1), 0.823283);
check_equality(v1_new(0,2), -0.334296);
check_equality(v1_new(1,0), -0.885235);
check_equality(v1_new(1,1), -0.455997);
check_equality(v1_new(1,2), 0.091794);
check_equality(v1_new(2,0), -0.076866);
check_equality(v1_new(2,1), 0.338040);
check_equality(v1_new(2,2), 0.937987);
const Matrix& v2_new = simplex[2].matrix();
check_equality(v2_new(0,0), -0.346582);
check_equality(v2_new(0,1), 0.878534);
check_equality(v2_new(0,2), -0.328724);
check_equality(v2_new(1,0), -0.936885);
check_equality(v2_new(1,1), -0.341445);
check_equality(v2_new(1,2), 0.075251);
check_equality(v2_new(2,0), -0.046131);
check_equality(v2_new(2,1), 0.334057);
check_equality(v2_new(2,2), 0.941423);
const Matrix& v3_new = simplex[3].matrix();
check_equality(v3_new(0,0), -0.394713);
check_equality(v3_new(0,1), 0.791782);
check_equality(v3_new(0,2), -0.466136);
check_equality(v3_new(1,0), -0.912112);
check_equality(v3_new(1,1), -0.398788);
check_equality(v3_new(1,2), 0.094972);
check_equality(v3_new(2,0), -0.110692);
check_equality(v3_new(2,1), 0.462655);
check_equality(v3_new(2,2), 0.879601);
}
int main(int, char**)
{
Traits traits;
test_simplex_operations(traits);
test_centroid(traits);
test_nelder_mead(traits);
std::cout << "Done!" << std::endl;
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,136 @@
#define CGAL_OPTIMAL_BOUNDING_BOX_DEBUG
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/boost/graph/generators.h>
#include <CGAL/optimal_bounding_box.h>
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
#include <CGAL/Polygon_mesh_processing/measure.h>
#include <array>
#include <iostream>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
typedef K::Point_3 Point;
typedef CGAL::Polyhedron_3<K> Mesh;
typedef CGAL::Oriented_bounding_box_traits_3<K> Traits;
typedef Traits::Matrix Matrix;
bool is_equal(const FT d1, const FT d2)
{
const FT epsilon = 1e-3;
bool ok;
if(std::is_floating_point<FT>::value)
ok = CGAL::abs(d1 - d2) < std::max(epsilon * d1, epsilon);
else
ok = (d1 == d2);
if(!ok)
{
std::cout << "Error: got " << d1 << " but expected: " << d2 << std::endl;
return false;
}
return true;
}
template <typename PointRange>
void test_OBB_data(const PointRange& points,
const double expected_vol,
const bool with_convex_hull = true)
{
namespace PMP = CGAL::Polygon_mesh_processing;
// the algorithm is allowed to fail, but not too often
int failure_count = 0;
for(int i=0; i<100; ++i)
{
CGAL::Surface_mesh<Point> obb_mesh;
CGAL::oriented_bounding_box(points, obb_mesh, CGAL::parameters::use_convex_hull(with_convex_hull));
PMP::triangulate_faces(obb_mesh);
// the triangulate algorithm might fail if the algorithm manages
// to fit perfectly the box to have a true 0 volume
if(CGAL::is_triangle_mesh(obb_mesh))
{
double vol = PMP::volume(obb_mesh);
std::cout << " volume is: " << vol << ", expected: " << expected_vol << std::endl;
if(!is_equal(vol, expected_vol))
{
std::cout << "Failure!" << std::endl;
++failure_count;
}
}
}
std::cout << "failures: " << failure_count << std::endl;
assert(failure_count < 5); // 5% failure
}
void test_OBB_of_mesh(const std::string fname,
const double expected_vol)
{
std::cout << "Test: " << fname << std::endl;
std::ifstream input(fname);
Mesh mesh;
if(!input || !(input >> mesh) || mesh.is_empty())
{
std::cerr << fname << " is not a valid input file." << std::endl;
std::exit(1);
}
std::vector<Point> points;
for(const auto v : vertices(mesh))
points.push_back(v->point());
test_OBB_data(points, expected_vol);
}
void test_OBB_of_point_set(const std::string fname,
const double expected_vol)
{
std::cout << "Test: " << fname << std::endl;
std::ifstream input(fname);
if(!input)
{
std::cerr << fname << " is not a valid input file." << std::endl;
std::exit(1);
}
std::deque<Point> points;
double x, y, z;
while(input >> x >> y >> z)
points.emplace_back(x, y, z);
test_OBB_data(points, expected_vol, false /*no convex hull due to degenerate data*/);
}
int main()
{
std::cout.precision(17);
test_OBB_of_mesh("data/elephant.off", 0.294296);
test_OBB_of_mesh("data/long_tetrahedron.off", 0.04);
test_OBB_of_mesh("data/reference_tetrahedron.off", 1);
// degenerate cases
test_OBB_of_mesh("data/triangles.off", 0); // 2D data set
test_OBB_of_mesh("data/flat_mesh.off", 0); // 2D data set
test_OBB_of_point_set("data/points_2D.xyz", 0); // 2D data set
test_OBB_of_point_set("data/points_1D.xyz", 0); // 1D data set
test_OBB_of_point_set("data/points_0D.xyz", 0); // 0D data set
std::cout << "Done!" << std::endl;
return 0;
}

View File

@ -27,13 +27,13 @@
#include <CGAL/Regular_triangulation_cell_base_3.h>
#include <CGAL/enum.h>
#include <CGAL/internal/boost/function_property_map.hpp>
#include <CGAL/internal/Has_nested_type_Bare_point.h>
#include <CGAL/spatial_sort.h>
#include <CGAL/utility.h>
#include <boost/mpl/if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/property_map/function_property_map.hpp>
#include <boost/unordered_set.hpp>
#include <cstdlib>
@ -498,12 +498,12 @@ public:
// Spatial sorting can only be applied to bare points, so we need an adaptor
typedef typename Geom_traits::Construct_point_3 Construct_point_3;
typedef typename boost::result_of<const Construct_point_3(const Weighted_point&)>::type Ret;
typedef CGAL::internal::boost_::function_property_map<Construct_point_3, Weighted_point, Ret> fpmap;
typedef boost::function_property_map<Construct_point_3, Weighted_point, Ret> fpmap;
typedef CGAL::Spatial_sort_traits_adapter_3<Geom_traits, fpmap> Search_traits_3;
spatial_sort(pbegin, points.end(),
Search_traits_3(
CGAL::internal::boost_::make_function_property_map<Weighted_point, Ret, Construct_point_3>(
boost::make_function_property_map<Weighted_point, Ret, Construct_point_3>(
geom_traits().construct_point_3_object()), geom_traits()));
Cell_handle hint;

View File

@ -39,7 +39,7 @@ int main(int argc, char* argv[])
Mesh mesh;
if(!input || !(input >> mesh) || num_vertices(mesh) == 0)
{
std::cerr << filename << " is not a valid off file.\n";
std::cerr << filename << " is not a valid off file." << std::endl;
return EXIT_FAILURE;
}

View File

@ -24,7 +24,7 @@ int main(int argc, char* argv[])
Mesh mesh1;
if ( !input || !(input >> mesh1) ) {
std::cerr << filename1 << " is not a valid off file.\n";
std::cerr << filename1 << " is not a valid off file." << std::endl;
return 1;
}
input.close();
@ -34,7 +34,7 @@ int main(int argc, char* argv[])
Mesh mesh2;
if ( !input || !(input >> mesh2) ) {
std::cerr << filename2 << " is not a valid off file.\n";
std::cerr << filename2 << " is not a valid off file." << std::endl;
return 1;
}

View File

@ -4,7 +4,8 @@
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/Polygon_mesh_processing/connected_components.h>
#include <CGAL/property_map.h>
#include <CGAL/internal/boost/function_property_map.hpp>
#include <boost/property_map/function_property_map.hpp>
#include <iostream>
#include <fstream>
@ -167,7 +168,7 @@ void test_CC_with_area_size_map(Mesh sm,
std::cout << "We keep the " << 2 << " largest components" << std::endl;
std::size_t res = PMP::keep_largest_connected_components(sm, 2,
PMP::parameters::face_size_map(CGAL::internal::boost_::make_function_property_map<face_descriptor>(f))
PMP::parameters::face_size_map(boost::make_function_property_map<face_descriptor>(f))
.dry_run(true)
.output_iterator(std::back_inserter(faces_to_remove)));
@ -183,7 +184,7 @@ void test_CC_with_area_size_map(Mesh sm,
PMP::keep_largest_connected_components(sm, 2,
PMP::parameters::face_size_map(
CGAL::internal::boost_::make_function_property_map<face_descriptor>(f)));
boost::make_function_property_map<face_descriptor>(f)));
assert(vertices(sm).size() == 1459);
{
@ -199,7 +200,7 @@ void test_CC_with_area_size_map(Mesh sm,
Face_descriptor_area_functor<Mesh, Kernel> f(m, k);
PMP::keep_large_connected_components(m, 10,
CGAL::parameters::face_size_map(
CGAL::internal::boost_::make_function_property_map<face_descriptor>(f)));
boost::make_function_property_map<face_descriptor>(f)));
assert(vertices(m).size() == 3);
PMP::keep_largest_connected_components(m, 1);

View File

@ -137,7 +137,7 @@ void remove_degeneracies(const char* filename,
Mesh mesh;
if (!input || !(input >> mesh) || mesh.is_empty())
{
std::cerr << filename << " is not a valid off file.\n";
std::cerr << filename << " is not a valid off file." << std::endl;
exit(1);
}
@ -211,7 +211,7 @@ void remove_negligible_connected_components(const char* filename)
Mesh mesh, mesh_cpy;
if (!input || !(input >> mesh) || mesh.is_empty())
{
std::cerr << filename << " is not a valid off file.\n";
std::cerr << filename << " is not a valid off file." << std::endl;
exit(1);
}

View File

@ -28,13 +28,13 @@ void run(const char* filename1, const char* filename2, const char* msg)
{
TriangleMesh mesh1;
if ( !CGAL::read_off(filename1, mesh1) ) {
std::cerr << filename1 << " is not a valid off file.\n";
std::cerr << filename1 << " is not a valid off file." << std::endl;
exit(1);
}
TriangleMesh mesh2;
if ( !CGAL::read_off(filename2, mesh2) ) {
std::cerr << filename2 << " is not a valid off file.\n";
std::cerr << filename2 << " is not a valid off file." << std::endl;
exit(1);
}

View File

@ -18,7 +18,7 @@ void test_merge_duplicated_vertices_in_boundary_cycles(const char* fname,
Surface_mesh mesh;
if (!input || !(input >> mesh) || mesh.is_empty()) {
std::cerr << fname << " is not a valid off file.\n";
std::cerr << fname << " is not a valid off file." << std::endl;
exit(1);
}

View File

@ -25,7 +25,7 @@ void read_mesh(const char* fname,
std::ifstream input(fname);
if (!input || !(input >> mesh) || mesh.is_empty())
{
std::cerr << fname << " is not a valid off file.\n";
std::cerr << fname << " is not a valid off file." << std::endl;
std::exit(1);
}
}

View File

@ -24,7 +24,7 @@ void check_edge_degeneracy(const char* fname)
std::ifstream input(fname);
Surface_mesh mesh;
if (!input || !(input >> mesh) || mesh.is_empty()) {
std::cerr << fname << " is not a valid off file.\n";
std::cerr << fname << " is not a valid off file." << std::endl;
std::exit(1);
}
std::vector<edge_descriptor> all_edges(edges(mesh).begin(), edges(mesh).end());
@ -44,7 +44,7 @@ void check_triangle_face_degeneracy(const char* fname)
std::ifstream input(fname);
Surface_mesh mesh;
if (!input || !(input >> mesh) || mesh.is_empty()) {
std::cerr << fname << " is not a valid off file.\n";
std::cerr << fname << " is not a valid off file." << std::endl;
std::exit(1);
}
@ -70,7 +70,7 @@ void test_needles_and_caps(const char* fname)
std::ifstream input(fname);
Surface_mesh mesh;
if (!input || !(input >> mesh) || mesh.is_empty()) {
std::cerr << fname << " is not a valid off file.\n";
std::cerr << fname << " is not a valid off file." << std::endl;
std::exit(1);
}

View File

@ -11,14 +11,14 @@
#include <CGAL/IO/STL_writer.h>
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
#include <CGAL/internal/boost/function_property_map.hpp>
#include <QColor>
#include <QString>
#include <QStringList>
#include <QMainWindow>
#include <QInputDialog>
#include <boost/property_map/function_property_map.hpp>
#include <cstdint>
#include <fstream>
#include <iostream>
@ -90,7 +90,7 @@ load(QFileInfo fileinfo, bool& ok, bool add_to_scene){
SMesh* SM = new SMesh();
if (CGAL::Polygon_mesh_processing::is_polygon_soup_a_polygon_mesh(triangles))
{
auto pmap = CGAL::internal::boost_::make_function_property_map<std::array<double, 3>, Point_3>(
auto pmap = boost::make_function_property_map<std::array<double, 3>, Point_3>(
[](const std::array<double, 3>& a) { return Point_3(a[0], a[1], a[2]); });
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points, triangles, *SM,
CGAL::parameters::point_map(pmap),

View File

@ -17,6 +17,9 @@ target_link_libraries(clipping_box_plugin PUBLIC scene_edit_box_item scene_basi
polyhedron_demo_plugin(create_bbox_mesh_plugin Create_bbox_mesh_plugin)
target_link_libraries(create_bbox_mesh_plugin PUBLIC scene_surface_mesh_item)
polyhedron_demo_plugin(create_obb_mesh_plugin Create_obb_mesh_plugin)
target_link_libraries(create_obb_mesh_plugin PUBLIC scene_surface_mesh_item scene_selection_item scene_points_with_normal_item)
qt5_wrap_ui( volumesUI_FILES Basic_generator_widget.ui)
polyhedron_demo_plugin(basic_generator_plugin Basic_generator_plugin ${volumesUI_FILES} KEYWORDS PolygonMesh PointSetProcessing)
target_link_libraries(basic_generator_plugin PUBLIC scene_surface_mesh_item scene_points_with_normal_item scene_polylines_item)

View File

@ -0,0 +1,154 @@
#include <QtCore/qglobal.h>
#include <CGAL/Three/Scene_item.h>
#include <CGAL/Three/Scene_interface.h>
#include <QAction>
#include <QMainWindow>
#include <QMessageBox>
#include <QApplication>
#include "Scene_surface_mesh_item.h"
#include "Scene_polyhedron_selection_item.h"
#include "Scene_points_with_normal_item.h"
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include <CGAL/optimal_bounding_box.h>
using namespace CGAL::Three;
typedef Scene_surface_mesh_item Scene_facegraph_item;
class Create_obb_mesh_plugin :
public QObject,
public CGAL::Three::Polyhedron_demo_plugin_interface
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
public:
void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface*);
QList<QAction*> actions() const;
bool applicable(QAction*) const
{
if(scene->mainSelectionIndex() != -1
&& scene->item(scene->mainSelectionIndex())->isFinite())
return true;
return false;
}
protected:
void gather_mesh_points(std::vector<Point_3>& points);
void obb();
public Q_SLOTS:
void createObb()
{
QApplication::setOverrideCursor(Qt::WaitCursor);
obb();
QApplication::restoreOverrideCursor();
}
private:
Scene_interface* scene;
QMainWindow* mw;
QAction* actionObb;
}; // end Create_obb_mesh_plugin class
void Create_obb_mesh_plugin::init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface*)
{
scene = scene_interface;
mw = mainWindow;
actionObb = new QAction(tr("Create &Optimal Bbox Mesh"), mainWindow);
actionObb->setObjectName("createObbMeshAction");
connect(actionObb, SIGNAL(triggered()), this, SLOT(createObb()));
}
QList<QAction*> Create_obb_mesh_plugin::actions() const
{
return QList<QAction*>() << actionObb;
}
void Create_obb_mesh_plugin::gather_mesh_points(std::vector<Point_3>& points)
{
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Scene_facegraph_item* item = qobject_cast<Scene_facegraph_item*>(scene->item(index));
Scene_polyhedron_selection_item* selection_item =
qobject_cast<Scene_polyhedron_selection_item*>(scene->item(index));
Scene_points_with_normal_item* point_set_item =
qobject_cast<Scene_points_with_normal_item*>(scene->item(index));
if(item || selection_item)
{
typedef typename boost::property_map<FaceGraph, boost::vertex_point_t>::type PointPMap;
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
std::vector<vertex_descriptor> selected_vertices;
if(item != NULL)
{
FaceGraph& pmesh = *item->polyhedron();
selected_vertices.assign(vertices(pmesh).begin(), vertices(pmesh).end());
PointPMap pmap = get(CGAL::vertex_point, pmesh);
for(vertex_descriptor v : selected_vertices)
points.push_back(get(pmap, v));
}
else if(selection_item != NULL) // using selection of faces
{
FaceGraph& pmesh = *selection_item->polyhedron();
for(face_descriptor f : selection_item->selected_facets)
{
for(vertex_descriptor v : vertices_around_face(halfedge(f, pmesh), pmesh))
selected_vertices.push_back(v);
}
PointPMap pmap = get(CGAL::vertex_point, pmesh);
for(vertex_descriptor v : selected_vertices)
points.push_back(get(pmap, v));
}
CGAL_assertion(points.size() >= 3);
}
if(point_set_item)
{
Point_set* points_set = point_set_item->point_set();
if(points_set == NULL)
return;
std::cout << "points_set->size()= " << points_set->size() << std::endl;
for(const Point_3& p : points_set->points())
points.push_back(p);
}
}
void Create_obb_mesh_plugin::obb()
{
// gather point coordinates
std::vector<Point_3> points;
gather_mesh_points(points);
// find obb
std::array<Point_3, 8> obb_points;
CGAL::oriented_bounding_box(points, obb_points);
Scene_facegraph_item* item;
SMesh* p = new SMesh;
CGAL::make_hexahedron(obb_points[0], obb_points[1], obb_points[2], obb_points[3],
obb_points[4], obb_points[5], obb_points[6], obb_points[7], *p);
item = new Scene_facegraph_item(p);
item->setName("Optimal bbox mesh");
item->setRenderingMode(Wireframe);
scene->addItem(item);
}
#include "Create_obb_mesh_plugin.moc"

View File

@ -1,84 +0,0 @@
//
//=======================================================================
// Author: Philipp Moeller
//
// Copyright 2012, Philipp Moeller
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
//
// $URL$
// $Id$
// SPDX-License-Identifier: BSL-1.0
//
// Note: This file was copied from Boost v1.64 because it was introduced
// in a release (~v1.51) that is newer than the oldest release of Boost
// that CGAL supports.
// the property map 'function_property_map' is (currently) used
// in the packages Triangulation_2 and Triangulation_3.
#ifndef CGAL_INTERNAL_BOOST_PROPERTY_MAP_FUNCTION_PROPERTY_MAP_HPP
#define CGAL_INTERNAL_BOOST_PROPERTY_MAP_FUNCTION_PROPERTY_MAP_HPP
#include <boost/config.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/type_traits.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <utility>
namespace CGAL {
namespace internal {
namespace boost_ {
template<typename Func,
typename Key,
typename Ret = typename boost::result_of<const Func(const Key&)>::type>
class function_property_map
: public boost::put_get_helper<Ret, function_property_map<Func, Key, Ret> >
{
public:
typedef Key key_type;
typedef Ret reference;
typedef typename boost::remove_cv<typename boost::remove_reference<Ret>::type>::type value_type;
typedef typename boost::mpl::if_<
boost::mpl::and_<
boost::is_reference<Ret>,
boost::mpl::not_< boost::is_const<Ret> >
>,
boost::lvalue_property_map_tag,
boost::readable_property_map_tag>::type
category;
function_property_map(Func f = Func()) : f(f) {}
reference operator[](const Key& k) const {
return f(k);
}
private:
Func f;
};
template<typename Key, typename Func>
function_property_map<Func, Key>
make_function_property_map(const Func& f) {
return function_property_map<Func, Key>(f);
}
template<typename Key, typename Ret, typename Func>
function_property_map<Func, Key, Ret>
make_function_property_map(const Func& f) {
return function_property_map<Func, Key, Ret>(f);
}
} // boost_
} // internal
} // CGAL
#endif /* CGAL_INTERNAL_BOOST_PROPERTY_MAP_FUNCTION_PROPERTY_MAP_HPP */

View File

@ -2,7 +2,7 @@
\ingroup PkgSolverInterfaceConcepts
\cgalConcept
The concept `SvdTraits` describes the linear algebra types and algorithms needed
The concept `SvdTraits` describes the linear algebra types and algorithms needed
to solve in the least square sense a linear system with a singular value decomposition
\cgalHasModel `CGAL::Eigen_svd`
@ -28,10 +28,10 @@ public:
The matrix type, model of the concept `SvdTraits::Matrix`.
*/
typedef unspecified_type Matrix;
/// @}
/// @}
/// \name Operations
/// \name Operations
/// The concept `SvdTraits` has a linear solver using a
/// singular value decomposition algorithm.
/// @{
@ -86,6 +86,9 @@ public:
\cgalConcept
Concept of matrix type used by the concept `SvdTraits`.
\cgalRefines `DefaultConstructible`
\cgalRefines `Assignable`
\cgalHasModel `CGAL::Eigen_matrix<T>`
*/
class SvdTraits::Matrix

View File

@ -8,377 +8,84 @@
//
// Author(s) : Gael Guennebaud
#ifndef CGAL_EIGEN_MATRIX_H
#define CGAL_EIGEN_MATRIX_H
#ifndef CGAL_SOLVER_INTERFACE_EIGEN_MATRIX_H
#define CGAL_SOLVER_INTERFACE_EIGEN_MATRIX_H
#include <CGAL/basic.h> // include basic.h before testing #defines
#include <Eigen/Sparse>
#include <CGAL/Eigen_sparse_matrix.h> // for backward compatibility
#include <Eigen/Dense>
namespace CGAL {
/*!
\ingroup PkgSolverInterfaceRef
The class `Eigen_sparse_matrix` is a wrapper around `Eigen` matrix type
<a href="http://eigen.tuxfamily.org/dox/classEigen_1_1SparseMatrix.html">`Eigen::SparseMatrix`</a>
that represents general matrices, be they symmetric or not.
\cgalModels `SparseLinearAlgebraTraits_d::Matrix`
\tparam T Number type.
\sa `CGAL::Eigen_vector<T>`
\sa `CGAL::Eigen_matrix<T>`
\sa `CGAL::Eigen_sparse_symmetric_matrix<T>`
*/
template<class T>
struct Eigen_sparse_matrix
{
// Public types
public:
/// \name Types
/// @{
/// The internal matrix type from \ref thirdpartyEigen "Eigen".
typedef Eigen::SparseMatrix<T> EigenType;
typedef T NT;
/// @}
Eigen_sparse_matrix(const EigenType& et)
: m_is_already_built(true), m_matrix(et), m_is_symmetric(false)
{}
// Public operations
public:
Eigen_sparse_matrix() :
m_is_already_built(false)
{}
/// Create a square matrix initialized with zeros.
Eigen_sparse_matrix(std::size_t dim, ///< Matrix dimension.
bool is_symmetric = false) ///< Symmetric/hermitian?
:
m_is_already_built(false),
m_matrix(static_cast<int>(dim), static_cast<int>(dim))
{
CGAL_precondition(dim > 0);
m_is_symmetric = is_symmetric;
m_triplets.reserve(dim); // reserve memory for a regular 3D grid
}
/// Create a square matrix initialized with zeros.
Eigen_sparse_matrix(int dim, ///< Matrix dimension.
bool is_symmetric = false) ///< Symmetric/hermitian?
: m_is_already_built(false),
m_matrix(dim, dim)
{
CGAL_precondition(dim > 0);
m_is_symmetric = is_symmetric;
// reserve memory for a regular 3D grid
m_triplets.reserve(dim);
}
/// Create a rectangular matrix initialized with zeros.
///
/// \pre rows == columns if `is_symmetric` is true.
Eigen_sparse_matrix(std::size_t rows, ///< Number of rows.
std::size_t columns, ///< Number of columns.
bool is_symmetric = false) ///< Symmetric/hermitian?
: m_is_already_built(false),
m_matrix(static_cast<int>(rows), static_cast<int>(columns))
{
CGAL_precondition(rows > 0);
CGAL_precondition(columns > 0);
if(m_is_symmetric)
{
CGAL_precondition(rows == columns);
}
m_is_symmetric = is_symmetric;
// reserve memory for a regular 3D grid
m_triplets.reserve(rows);
}
void swap(Eigen_sparse_matrix& other)
{
std::swap(m_is_already_built, other.m_is_already_built);
std::swap(m_is_symmetric, other.m_is_symmetric);
m_matrix.swap(other.m_matrix);
m_triplets.swap(other.m_triplets);
}
/// Delete this object and the wrapped matrix.
~Eigen_sparse_matrix() { }
/// Create a rectangular matrix initialized with zeros.
///
/// \pre rows == columns if `is_symmetric` is true.
Eigen_sparse_matrix(int rows, ///< Number of rows.
int columns, ///< Number of columns.
bool is_symmetric = false) ///< Symmetric/hermitian?
: m_is_already_built(false),
m_matrix(rows,columns)
{
CGAL_precondition(rows > 0);
CGAL_precondition(columns > 0);
if(is_symmetric)
{
CGAL_precondition(rows == columns);
}
m_is_symmetric = is_symmetric;
// reserve memory for a regular 3D grid
m_triplets.reserve(rows);
}
/// Return the matrix number of rows
int row_dimension() const { return static_cast<int>(m_matrix.rows()); }
/// Return the matrix number of columns
int column_dimension() const { return static_cast<int>(m_matrix.cols()); }
/// Write access to a matrix coefficient: a_ij <- val.
///
/// Users can optimize calls to this function by setting 'new_coef' to `true`
/// if the coefficient does not already exist in the matrix.
///
/// \warning For symmetric matrices, `Eigen_sparse_matrix` only stores the lower triangle
/// and `set_coef()` does nothing if (i, j) belongs to the upper triangle.
///
/// \pre 0 <= i < row_dimension().
/// \pre 0 <= j < column_dimension().
void set_coef(std::size_t i_, std::size_t j_, T val, bool new_coef = false)
{
int i = static_cast<int>(i_);
int j = static_cast<int>(j_);
CGAL_precondition(i < row_dimension());
CGAL_precondition(j < column_dimension());
if (m_is_symmetric && (j > i))
return;
if(m_is_already_built)
{
m_matrix.coeffRef(i,j) = val;
}
else
{
if(new_coef == false)
{
assemble_matrix();
m_matrix.coeffRef(i,j) = val;
}
else
{
m_triplets.push_back(Triplet(i,j,val));
}
}
}
/// Write access to a matrix coefficient: a_ij <- a_ij + val.
///
/// \warning For symmetric matrices, Eigen_sparse_matrix only stores the lower triangle
/// `add_coef()` does nothing if (i, j) belongs to the upper triangle.
///
/// \pre 0 <= i < row_dimension().
/// \pre 0 <= j < column_dimension().
void add_coef(std::size_t i_, std::size_t j_, T val)
{
int i = static_cast<int>(i_);
int j = static_cast<int>(j_);
if(m_is_symmetric && (j > i))
return;
if(m_is_already_built){
CGAL_precondition(i < row_dimension());
CGAL_precondition(j < column_dimension());
m_matrix.coeffRef(i,j) += val;
}else{
m_triplets.push_back(Triplet(i,j,val));
}
}
/// Read access to a matrix coefficient.
///
/// \warning Complexity:
/// - O(log(n)) if the matrix is already built.
/// - O(n) if the matrix is not built.
/// `n` being the number of entries in the matrix.
///
/// \pre 0 <= i < row_dimension().
/// \pre 0 <= j < column_dimension().
NT get_coef (std::size_t i_, std::size_t j_) const
{
int i = static_cast<int>(i_);
int j = static_cast<int>(j_);
CGAL_precondition(i < row_dimension());
CGAL_precondition(j < column_dimension());
if(m_is_symmetric && j > i)
std::swap(i, j);
if (m_is_already_built)
return m_matrix.coeffRef(i,j);
else
{
NT val = 0;
for(std::size_t t=0; t<m_triplets.size(); ++t)
{
if(m_triplets[t].col() == j &&
m_triplets[t].row() == i)
val += m_triplets[t].value();
}
return val;
}
}
/// \cond SKIP_IN_MANUAL
void assemble_matrix() const
{
m_matrix.setFromTriplets(m_triplets.begin(), m_triplets.end());
m_is_already_built = true;
m_triplets.clear(); // the matrix is built and will not be rebuilt
}
/// \endcond
/// Return the internal matrix, with type `EigenType`.
const EigenType& eigen_object() const
{
if(!m_is_already_built)
assemble_matrix();
// turns the matrix into compressed mode:
// -> release some memory
// -> required for some external solvers
m_matrix.makeCompressed();
return m_matrix;
}
/// Return the internal matrix, with type `EigenType`.
EigenType& eigen_object()
{
if(!m_is_already_built)
assemble_matrix();
// turns the matrix into compressed mode:
// -> release some memory
// -> required for some external solvers
m_matrix.makeCompressed();
return m_matrix;
}
public:
/// \cond SKIP_IN_MANUAL
friend Eigen_sparse_matrix
operator*(const T& c, const Eigen_sparse_matrix& M)
{
return Eigen_sparse_matrix(c* M.eigen_object());
}
friend Eigen_sparse_matrix
operator+(const Eigen_sparse_matrix& M0, const Eigen_sparse_matrix& M1)
{
return Eigen_sparse_matrix(M0.eigen_object()+ M1.eigen_object());
}
/// \endcond
// Fields
private:
mutable bool m_is_already_built;
typedef Eigen::Triplet<T,int> Triplet;
mutable std::vector<Triplet> m_triplets;
mutable EigenType m_matrix;
// Symmetric/hermitian?
bool m_is_symmetric;
}; // Eigen_sparse_matrix
/*!
\ingroup PkgSolverInterfaceRef
The class `Eigen_sparse_symmetric_matrix` is a wrapper around `Eigen` matrix type
<a href="http://eigen.tuxfamily.org/dox/classEigen_1_1SparseMatrix.html">`Eigen::SparseMatrix` </a>
Since the matrix is symmetric, only the lower triangle part is stored.
\cgalModels `SparseLinearAlgebraTraits_d::Matrix`
\tparam T Number type.
\sa `CGAL::Eigen_vector<T>`
\sa `CGAL::Eigen_sparse_matrix<T>`
*/
template<class T>
struct Eigen_sparse_symmetric_matrix
: public Eigen_sparse_matrix<T>
{
/// Create a square *symmetric* matrix initialized with zeros.
Eigen_sparse_symmetric_matrix(int dim) ///< Matrix dimension.
: Eigen_sparse_matrix<T>(dim, true /* symmetric */)
{
}
/// Create a square *symmetric* matrix initialized with zeros.
///
/// \pre rows == columns.
Eigen_sparse_symmetric_matrix(int rows, ///< Number of rows.
int columns) ///< Number of columns.
: Eigen_sparse_matrix<T>(rows, columns, true /* symmetric */)
{
}
};
/*!
\ingroup PkgSolverInterfaceRef
The class `Eigen_matrix` is a wrapper around `Eigen` matrix type
<a href="http://eigen.tuxfamily.org/dox/classEigen_1_1Matrix.html">`Eigen::Matrix`</a>.
\cgalModels `SvdTraits::Matrix`
\cgalModels `SvdTraits::Matrix`
\tparam T Number type.
\tparam D1 Number of rows, or Dynamic
\tparam D2 Number of columns, or Dynamic
\sa `CGAL::Eigen_vector<T>`
\sa `CGAL::Eigen_sparse_matrix<T>`
\sa `CGAL::Eigen_sparse_symmetric_matrix<T>`
*/
template <class FT>
template <class FT, int D1 = ::Eigen::Dynamic, int D2 = ::Eigen::Dynamic>
struct Eigen_matrix
: public ::Eigen::Matrix<FT, ::Eigen::Dynamic, ::Eigen::Dynamic>
: public ::Eigen::Matrix<FT, D1, D2>
{
/// The internal matrix type from \ref thirdpartyEigen "Eigen".
typedef ::Eigen::Matrix<FT, ::Eigen::Dynamic, ::Eigen::Dynamic> EigenType;
typedef ::Eigen::Matrix<FT, D1, D2> EigenType;
/// Construct a matrix with `nr` rows and `nc` columns.
/// Constructs a null matrix.
Eigen_matrix() { }
/// Constructs an uninitialized matrix with `nr` rows and `nc` columns.
/// This is useful for dynamic-size matrices.
/// For fixed-size matrices, it is redundant to pass these parameters.
Eigen_matrix(std::size_t nr, std::size_t nc) : EigenType(nr, nc) { }
/// Return the matrix number of rows.
/// Constructs a matrix from an Eigen matrix.
Eigen_matrix(const EigenType& b) : EigenType(b) { }
/// Returns the matrix number of rows.
std::size_t number_of_rows() const { return this->rows(); }
/// Return the matrix number of columns.
/// Returns the matrix number of columns.
std::size_t number_of_columns() const { return this->cols(); }
/// Return the value of the matrix at position (i,j).
/// Returns the value of the matrix at position (i,j).
FT operator()( std::size_t i , std::size_t j ) const { return EigenType::operator()(i,j); }
/// Write access to a matrix coefficient: `a_ij` <- `val`.
/// Writes access to a matrix coefficient: `a_ij` <- `val`.
void set(std::size_t i, std::size_t j, FT value) { this->coeffRef(i,j) = value; }
/// Return the internal matrix, with type `EigenType`.
/// Returns the internal matrix, with type `EigenType`.
const EigenType& eigen_object() const { return static_cast<const EigenType&>(*this); }
public:
/// \cond SKIP_IN_MANUAL
friend Eigen_matrix operator*(const FT c, const Eigen_matrix& M)
{
return Eigen_matrix(c * M.eigen_object());
}
friend Eigen_matrix operator*(const Eigen_matrix& M0, const Eigen_matrix& M1)
{
return Eigen_matrix(M0.eigen_object() * M1.eigen_object());
}
friend Eigen_matrix operator+(const Eigen_matrix& M0, const Eigen_matrix& M1)
{
return Eigen_matrix(M0.eigen_object() + M1.eigen_object());
}
/// \endcond
};
} //namespace CGAL
#endif // CGAL_EIGEN_MATRIX_H
#endif // CGAL_SOLVER_INTERFACE_EIGEN_MATRIX_H

View File

@ -0,0 +1,335 @@
// Copyright (c) 2012 INRIA Bordeaux Sud-Ouest (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) : Gael Guennebaud
#ifndef CGAL_SOLVER_INTERFACE_EIGEN_SPARSE_MATRIX_H
#define CGAL_SOLVER_INTERFACE_EIGEN_SPARSE_MATRIX_H
#include <CGAL/basic.h> // include basic.h before testing #defines
#include <Eigen/Sparse>
namespace CGAL {
/*!
\ingroup PkgSolverInterfaceRef
The class `Eigen_sparse_matrix` is a wrapper around `Eigen` matrix type
<a href="http://eigen.tuxfamily.org/dox/classEigen_1_1SparseMatrix.html">`Eigen::SparseMatrix`</a>
that represents general matrices, be they symmetric or not.
\cgalModels `SparseLinearAlgebraTraits_d::Matrix`
\tparam T Number type.
\sa `CGAL::Eigen_vector<T>`
\sa `CGAL::Eigen_matrix<T>`
\sa `CGAL::Eigen_sparse_symmetric_matrix<T>`
*/
template<class T>
struct Eigen_sparse_matrix
{
// Public types
public:
/// \name Types
/// @{
/// The internal matrix type from \ref thirdpartyEigen "Eigen".
typedef Eigen::SparseMatrix<T> EigenType;
typedef T NT;
/// @}
Eigen_sparse_matrix(const EigenType& et)
: m_is_already_built(true), m_matrix(et), m_is_symmetric(false)
{}
// Public operations
public:
Eigen_sparse_matrix() : m_is_already_built(false) { }
/// Create a square matrix initialized with zeros.
Eigen_sparse_matrix(std::size_t dim, ///< Matrix dimension.
bool is_symmetric = false) ///< Symmetric/hermitian?
:
m_is_already_built(false),
m_matrix(static_cast<int>(dim), static_cast<int>(dim))
{
CGAL_precondition(dim > 0);
m_is_symmetric = is_symmetric;
m_triplets.reserve(dim); // reserve memory for a regular 3D grid
}
/// Create a square matrix initialized with zeros.
Eigen_sparse_matrix(int dim, ///< Matrix dimension.
bool is_symmetric = false) ///< Symmetric/hermitian?
: m_is_already_built(false),
m_matrix(dim, dim)
{
CGAL_precondition(dim > 0);
m_is_symmetric = is_symmetric;
// reserve memory for a regular 3D grid
m_triplets.reserve(dim);
}
/// Create a rectangular matrix initialized with zeros.
///
/// \pre rows == columns if `is_symmetric` is true.
Eigen_sparse_matrix(std::size_t rows, ///< Number of rows.
std::size_t columns, ///< Number of columns.
bool is_symmetric = false) ///< Symmetric/hermitian?
: m_is_already_built(false),
m_matrix(static_cast<int>(rows), static_cast<int>(columns))
{
CGAL_precondition(rows > 0);
CGAL_precondition(columns > 0);
if(m_is_symmetric)
{
CGAL_precondition(rows == columns);
}
m_is_symmetric = is_symmetric;
// reserve memory for a regular 3D grid
m_triplets.reserve(rows);
}
void swap(Eigen_sparse_matrix& other)
{
std::swap(m_is_already_built, other.m_is_already_built);
std::swap(m_is_symmetric, other.m_is_symmetric);
m_matrix.swap(other.m_matrix);
m_triplets.swap(other.m_triplets);
}
/// Delete this object and the wrapped matrix.
~Eigen_sparse_matrix() { }
/// Create a rectangular matrix initialized with zeros.
///
/// \pre rows == columns if `is_symmetric` is true.
Eigen_sparse_matrix(int rows, ///< Number of rows.
int columns, ///< Number of columns.
bool is_symmetric = false) ///< Symmetric/hermitian?
: m_is_already_built(false),
m_matrix(rows,columns)
{
CGAL_precondition(rows > 0);
CGAL_precondition(columns > 0);
if(is_symmetric)
{
CGAL_precondition(rows == columns);
}
m_is_symmetric = is_symmetric;
// reserve memory for a regular 3D grid
m_triplets.reserve(rows);
}
/// Return the matrix number of rows
int row_dimension() const { return static_cast<int>(m_matrix.rows()); }
/// Return the matrix number of columns
int column_dimension() const { return static_cast<int>(m_matrix.cols()); }
/// Write access to a matrix coefficient: a_ij <- val.
///
/// Users can optimize calls to this function by setting 'new_coef' to `true`
/// if the coefficient does not already exist in the matrix.
///
/// \warning For symmetric matrices, `Eigen_sparse_matrix` only stores the lower triangle
/// and `set_coef()` does nothing if (i, j) belongs to the upper triangle.
///
/// \pre 0 <= i < row_dimension().
/// \pre 0 <= j < column_dimension().
void set_coef(std::size_t i_, std::size_t j_, T val, bool new_coef = false)
{
int i = static_cast<int>(i_);
int j = static_cast<int>(j_);
CGAL_precondition(i < row_dimension());
CGAL_precondition(j < column_dimension());
if (m_is_symmetric && (j > i))
return;
if(m_is_already_built)
{
m_matrix.coeffRef(i,j) = val;
}
else
{
if(new_coef == false)
{
assemble_matrix();
m_matrix.coeffRef(i,j) = val;
}
else
{
m_triplets.push_back(Triplet(i,j,val));
}
}
}
/// Write access to a matrix coefficient: a_ij <- a_ij + val.
///
/// \warning For symmetric matrices, Eigen_sparse_matrix only stores the lower triangle
/// `add_coef()` does nothing if (i, j) belongs to the upper triangle.
///
/// \pre 0 <= i < row_dimension().
/// \pre 0 <= j < column_dimension().
void add_coef(std::size_t i_, std::size_t j_, T val)
{
int i = static_cast<int>(i_);
int j = static_cast<int>(j_);
if(m_is_symmetric && (j > i))
return;
if(m_is_already_built){
CGAL_precondition(i < row_dimension());
CGAL_precondition(j < column_dimension());
m_matrix.coeffRef(i,j) += val;
}else{
m_triplets.push_back(Triplet(i,j,val));
}
}
/// Read access to a matrix coefficient.
///
/// \warning Complexity:
/// - O(log(n)) if the matrix is already built.
/// - O(n) if the matrix is not built.
/// `n` being the number of entries in the matrix.
///
/// \pre 0 <= i < row_dimension().
/// \pre 0 <= j < column_dimension().
NT get_coef (std::size_t i_, std::size_t j_) const
{
int i = static_cast<int>(i_);
int j = static_cast<int>(j_);
CGAL_precondition(i < row_dimension());
CGAL_precondition(j < column_dimension());
if(m_is_symmetric && j > i)
std::swap(i, j);
if (m_is_already_built)
return m_matrix.coeffRef(i,j);
else
{
NT val = 0;
for(std::size_t t=0; t<m_triplets.size(); ++t)
{
if(m_triplets[t].col() == j &&
m_triplets[t].row() == i)
val += m_triplets[t].value();
}
return val;
}
}
/// \cond SKIP_IN_MANUAL
void assemble_matrix() const
{
m_matrix.setFromTriplets(m_triplets.begin(), m_triplets.end());
m_is_already_built = true;
m_triplets.clear(); // the matrix is built and will not be rebuilt
}
/// \endcond
/// Return the internal matrix, with type `EigenType`.
const EigenType& eigen_object() const
{
if(!m_is_already_built)
assemble_matrix();
// turns the matrix into compressed mode:
// -> release some memory
// -> required for some external solvers
m_matrix.makeCompressed();
return m_matrix;
}
/// Return the internal matrix, with type `EigenType`.
EigenType& eigen_object()
{
if(!m_is_already_built)
assemble_matrix();
// turns the matrix into compressed mode:
// -> release some memory
// -> required for some external solvers
m_matrix.makeCompressed();
return m_matrix;
}
public:
/// \cond SKIP_IN_MANUAL
friend Eigen_sparse_matrix
operator*(const T& c, const Eigen_sparse_matrix& M)
{
return Eigen_sparse_matrix(c* M.eigen_object());
}
friend Eigen_sparse_matrix
operator+(const Eigen_sparse_matrix& M0, const Eigen_sparse_matrix& M1)
{
return Eigen_sparse_matrix(M0.eigen_object()+ M1.eigen_object());
}
/// \endcond
// Fields
private:
mutable bool m_is_already_built;
typedef Eigen::Triplet<T,int> Triplet;
mutable std::vector<Triplet> m_triplets;
mutable EigenType m_matrix;
// Symmetric/hermitian?
bool m_is_symmetric;
}; // Eigen_sparse_matrix
/*!
\ingroup PkgSolverInterfaceRef
The class `Eigen_sparse_symmetric_matrix` is a wrapper around `Eigen` matrix type
<a href="http://eigen.tuxfamily.org/dox/classEigen_1_1SparseMatrix.html">`Eigen::SparseMatrix` </a>
Since the matrix is symmetric, only the lower triangle part is stored.
\cgalModels `SparseLinearAlgebraTraits_d::Matrix`
\tparam T Number type.
\sa `CGAL::Eigen_vector<T>`
\sa `CGAL::Eigen_sparse_matrix<T>`
*/
template<class T>
struct Eigen_sparse_symmetric_matrix
: public Eigen_sparse_matrix<T>
{
/// Create a square *symmetric* matrix initialized with zeros.
Eigen_sparse_symmetric_matrix(int dim) ///< Matrix dimension.
: Eigen_sparse_matrix<T>(dim, true /* symmetric */)
{ }
/// Create a square *symmetric* matrix initialized with zeros.
///
/// \pre rows == columns.
Eigen_sparse_symmetric_matrix(int rows, ///< Number of rows.
int columns) ///< Number of columns.
: Eigen_sparse_matrix<T>(rows, columns, true /* symmetric */)
{ }
};
} //namespace CGAL
#endif // CGAL_SOLVER_INTERFACE_EIGEN_SPARSE_MATRIX_H

View File

@ -20,7 +20,6 @@
#include <CGAL/utility.h>
#include <CGAL/Object.h>
#include <CGAL/internal/boost/function_property_map.hpp>
#include <CGAL/internal/Has_nested_type_Bare_point.h>
#include <boost/bind.hpp>
@ -34,6 +33,7 @@
#include <boost/iterator/zip_iterator.hpp>
#include <boost/mpl/and.hpp>
#include <boost/property_map/function_property_map.hpp>
#endif //CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
@ -167,7 +167,7 @@ public:
};
typedef Iterator_range<Prevent_deref<All_vertices_iterator> > All_vertex_handles;
class Finite_vertices_iterator :
public Filter_iterator<Finite_vib, Hidden_tester>
{
@ -184,7 +184,7 @@ public:
};
typedef Iterator_range<Prevent_deref<Finite_vertices_iterator> > Finite_vertex_handles;
class Hidden_vertices_iterator :
public Filter_iterator<Finite_vib, Unhidden_tester>
{
@ -201,7 +201,7 @@ public:
};
typedef Iterator_range<Prevent_deref<Hidden_vertices_iterator> > Hidden_vertex_handles;
//for backward compatibility
typedef Finite_faces_iterator Face_iterator;
typedef Finite_edges_iterator Edge_iterator;
@ -339,17 +339,17 @@ public:
All_vertices_iterator all_vertices_begin() const;
All_vertices_iterator all_vertices_end() const;
All_vertex_handles all_vertex_handles() const;
Finite_vertices_iterator finite_vertices_begin() const;
Finite_vertices_iterator finite_vertices_end() const;
Finite_vertex_handles finite_vertex_handles() const;
Vertex_handle finite_vertex() const;
Hidden_vertices_iterator hidden_vertices_begin() const;
Hidden_vertices_iterator hidden_vertices_end() const;
Hidden_vertex_handles hidden_vertex_handles() const;
// Vertex_handle file_input(std::istream& is);
// void file_output(std::ostream& os) const;
@ -414,12 +414,12 @@ public:
// spatial sorting must use bare points, so we need an adapter
typedef typename Geom_traits::Construct_point_2 Construct_point_2;
typedef typename boost::result_of<const Construct_point_2(const Weighted_point&)>::type Ret;
typedef CGAL::internal::boost_::function_property_map<Construct_point_2, Weighted_point, Ret> fpmap;
typedef boost::function_property_map<Construct_point_2, Weighted_point, Ret> fpmap;
typedef CGAL::Spatial_sort_traits_adapter_2<Geom_traits, fpmap> Search_traits_2;
spatial_sort(points.begin(), points.end(),
Search_traits_2(
CGAL::internal::boost_::make_function_property_map<Weighted_point, Ret, Construct_point_2>(
boost::make_function_property_map<Weighted_point, Ret, Construct_point_2>(
geom_traits().construct_point_2_object()), geom_traits()));
Face_handle hint;
@ -482,13 +482,13 @@ private:
typedef Index_to_Bare_point<Construct_point_2,
std::vector<Weighted_point> > Access_bare_point;
typedef typename boost::result_of<const Construct_point_2(const Weighted_point&)>::type Ret;
typedef CGAL::internal::boost_::function_property_map<Access_bare_point, std::size_t, Ret> fpmap;
typedef boost::function_property_map<Access_bare_point, std::size_t, Ret> fpmap;
typedef CGAL::Spatial_sort_traits_adapter_2<Gt, fpmap> Search_traits_2;
Access_bare_point accessor(points, geom_traits().construct_point_2_object());
spatial_sort(indices.begin(), indices.end(),
Search_traits_2(
CGAL::internal::boost_::make_function_property_map<
boost::make_function_property_map<
std::size_t, Ret, Access_bare_point>(accessor),
geom_traits()));
@ -2192,7 +2192,7 @@ all_vertices_end() const
return CGAL::filter_iterator(Base::all_vertices_end(),
Hidden_tester());
}
template < class Gt, class Tds >
typename Regular_triangulation_2<Gt,Tds>::All_vertex_handles
Regular_triangulation_2<Gt,Tds>::
@ -2200,7 +2200,7 @@ all_vertex_handles() const
{
return make_prevent_deref_range(all_vertices_begin(),all_vertices_end());
}
template < class Gt, class Tds >
typename Regular_triangulation_2<Gt,Tds>::Finite_vertices_iterator
Regular_triangulation_2<Gt,Tds>::
@ -2211,7 +2211,7 @@ finite_vertices_begin() const
Base::finite_vertices_begin());
}
template < class Gt, class Tds >
typename Regular_triangulation_2<Gt,Tds>::Vertex_handle
Regular_triangulation_2<Gt,Tds>::
@ -2238,7 +2238,7 @@ finite_vertex_handles() const
{
return make_prevent_deref_range(finite_vertices_begin(),finite_vertices_end());
}
template < class Gt, class Tds >
typename Regular_triangulation_2<Gt,Tds>::Hidden_vertices_iterator
Regular_triangulation_2<Gt,Tds>::
@ -2257,7 +2257,7 @@ hidden_vertices_end() const
return CGAL::filter_iterator(Base::finite_vertices_end(),
Unhidden_tester());
}
template < class Gt, class Tds >
typename Regular_triangulation_2<Gt,Tds>::Hidden_vertex_handles
Regular_triangulation_2<Gt,Tds>::
@ -2265,7 +2265,7 @@ hidden_vertex_handles() const
{
return make_prevent_deref_range(hidden_vertices_begin(),hidden_vertices_end());
}
template < class Gt, class Tds >
typename Regular_triangulation_2<Gt,Tds>::Vertex_handle
Regular_triangulation_2<Gt,Tds>::

View File

@ -37,7 +37,6 @@
#include <CGAL/Spatial_sort_traits_adapter_2.h>
#include <CGAL/double.h>
#include <CGAL/internal/boost/function_property_map.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/random/linear_congruential.hpp>
@ -145,7 +144,7 @@ public:
const Triangulation_2 *t;
public:
Infinite_tester() {}
Infinite_tester(const Triangulation_2 *tr) : t(tr) {}
Infinite_tester(const Triangulation_2 *tr) : t(tr) {}
bool operator()(const All_vertices_iterator & vit) const {
return t->is_infinite(vit);
@ -208,16 +207,16 @@ public:
// Range types
typedef typename Tds::Face_handles All_face_handles;
typedef typename Tds::Vertex_handles All_vertex_handles;
typedef typename Tds::Edges All_edges;
typedef Iterator_range<Prevent_deref<Finite_faces_iterator> > Finite_face_handles;
typedef Iterator_range<Prevent_deref<Finite_vertices_iterator> > Finite_vertex_handles;
typedef Iterator_range<Finite_edges_iterator> Finite_edges;
typedef Iterator_range<Point_iterator> Points;
typedef Point value_type; // to have a back_inserter
typedef const value_type& const_reference;
typedef value_type& reference;
@ -252,7 +251,7 @@ public:
_infinite_vertex = _tds.insert_first();
insert(first,last);
}
//Assignement
Triangulation_2 &operator=(const Triangulation_2 &tr);
@ -460,15 +459,15 @@ public:
Finite_faces_iterator finite_faces_begin() const;
Finite_faces_iterator finite_faces_end() const;
Finite_face_handles finite_face_handles() const;
Finite_vertices_iterator finite_vertices_begin() const;
Finite_vertices_iterator finite_vertices_end() const;
Finite_vertex_handles finite_vertex_handles() const;
Finite_edges_iterator finite_edges_begin() const;
Finite_edges_iterator finite_edges_end() const;
Finite_edges finite_edges() const;
Point_iterator points_begin() const;
Point_iterator points_end() const;
Points points() const;
@ -476,15 +475,15 @@ public:
All_faces_iterator all_faces_begin() const;
All_faces_iterator all_faces_end() const;
All_face_handles all_face_handles() const;
All_vertices_iterator all_vertices_begin() const;
All_vertices_iterator all_vertices_end() const;
All_vertex_handles all_vertex_handles() const;
All_edges_iterator all_edges_begin() const;
All_edges_iterator all_edges_end() const;
All_edges all_edges() const;
//for compatibility with previous versions
Face_iterator faces_begin() const {return finite_faces_begin();}
@ -620,7 +619,7 @@ public:
}
return os;
}
#ifndef CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
template < class InputIterator >
std::ptrdiff_t insert(InputIterator first, InputIterator last,
@ -645,7 +644,7 @@ std::ptrdiff_t insert(InputIterator first, InputIterator last,
return number_of_vertices() - n;
}
#ifndef CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
//top stands for tuple-or-pair
template <class Info>
@ -713,7 +712,7 @@ public:
}
#endif //CGAL_TRIANGULATION_2_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
bool well_oriented(Vertex_handle v) const
{
Face_circulator fc = incident_faces(v), done(fc);
@ -3236,7 +3235,7 @@ finite_edges() const
{
return Finite_edges(finite_edges_begin(), finite_edges_end());
}
template <class Gt, class Tds >
typename Triangulation_2<Gt, Tds>::Point_iterator
Triangulation_2<Gt, Tds>::
@ -3260,7 +3259,7 @@ points() const
{
return Points(points_begin(), points_end());
}
template <class Gt, class Tds >
typename Triangulation_2<Gt, Tds>::All_faces_iterator
Triangulation_2<Gt, Tds>::
@ -3275,7 +3274,7 @@ all_faces_end() const
{
return _tds.faces_end();
}
template <class Gt, class Tds >
typename Triangulation_2<Gt, Tds>::All_face_handles
Triangulation_2<Gt, Tds>::
@ -3299,7 +3298,7 @@ all_vertices_end() const
{
return _tds.vertices_end();
}
template <class Gt, class Tds >
typename Triangulation_2<Gt, Tds>::All_vertex_handles
Triangulation_2<Gt, Tds>::
@ -3331,7 +3330,7 @@ all_edges() const
{
return _tds.edges();
}
template <class Gt, class Tds >
inline
typename Triangulation_2<Gt, Tds>::Face_circulator

View File

@ -6,7 +6,7 @@
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
//
// Author(s) : Olivier Devillers <Olivivier.Devillers@sophia.inria.fr>
// Mariette Yvinec <Mariette.Yvinec@sophia.inria.fr>
@ -25,10 +25,9 @@
#include <CGAL/spatial_sort.h>
#include <CGAL/Spatial_sort_traits_adapter_2.h>
#include <CGAL/internal/boost/function_property_map.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp>
#include <boost/property_map/function_property_map.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/geometric_distribution.hpp>
#include <boost/random/variate_generator.hpp>
@ -92,10 +91,10 @@ public:
template<class InputIterator>
Triangulation_hierarchy_2(InputIterator first, InputIterator beyond,
const Geom_traits& traits = Geom_traits())
const Geom_traits& traits = Geom_traits())
: Tr_Base(traits)
{
hierarchy[0] = this;
{
hierarchy[0] = this;
for(int i=1;i<Triangulation_hierarchy_2__maxlevel;++i)
hierarchy[i] = new Tr_Base(traits);
@ -116,10 +115,10 @@ public:
// INSERT REMOVE MOVE
Vertex_handle insert(const Point &p, Face_handle start = Face_handle() );
Vertex_handle insert(const Point& p,
Locate_type lt,
Face_handle loc, int li );
Locate_type lt,
Face_handle loc, int li );
Vertex_handle push_back(const Point &p);
template < class InputIterator >
std::ptrdiff_t insert(InputIterator first, InputIterator last)
{
@ -130,12 +129,12 @@ public:
// Spatial sort can only be used with Gt::Point_2: we need an adapter
typedef typename Geom_traits::Construct_point_2 Construct_point_2;
typedef typename boost::result_of<const Construct_point_2(const Point&)>::type Ret;
typedef CGAL::internal::boost_::function_property_map<Construct_point_2, Point, Ret> fpmap;
typedef boost::function_property_map<Construct_point_2, Point, Ret> fpmap;
typedef CGAL::Spatial_sort_traits_adapter_2<Geom_traits, fpmap> Search_traits_2;
spatial_sort(points.begin(), points.end(),
Search_traits_2(
CGAL::internal::boost_::make_function_property_map<Point, Ret, Construct_point_2>(
boost::make_function_property_map<Point, Ret, Construct_point_2>(
geom_traits().construct_point_2_object()), geom_traits()));
// hints[i] is the face of the previously inserted point in level i.
@ -179,26 +178,26 @@ protected: // some internal methods
// GIVING NEW FACES
template <class OutputItFaces>
Vertex_handle insert_and_give_new_faces(const Point &p,
Vertex_handle insert_and_give_new_faces(const Point &p,
OutputItFaces fit,
Face_handle start = Face_handle() );
template <class OutputItFaces>
Vertex_handle insert_and_give_new_faces(const Point& p,
Locate_type lt,
Face_handle loc, int li,
Face_handle loc, int li,
OutputItFaces fit);
template <class OutputItFaces>
void remove_and_give_new_faces(Vertex_handle v,
void remove_and_give_new_faces(Vertex_handle v,
OutputItFaces fit);
template <class OutputItFaces>
Vertex_handle move_if_no_collision_and_give_new_faces(Vertex_handle v,
const Point &p, OutputItFaces fit);
Vertex_handle move_if_no_collision_and_give_new_faces(Vertex_handle v,
const Point &p, OutputItFaces fit);
public:
//LOCATE
Face_handle
locate(const Point& p,
@ -247,18 +246,18 @@ private:
// systematique instanciation
template <class Tag>
void add_hidden_vertices_into_map(Tag,
std::map<Vertex_handle,Vertex_handle >& V)
std::map<Vertex_handle,Vertex_handle >& V)
{
for (typename Tr_Base::Hidden_vertices_iterator
it=hierarchy[0]->hidden_vertices_begin();
it != hierarchy[0]->hidden_vertices_end(); ++it) {
for (typename Tr_Base::Hidden_vertices_iterator
it=hierarchy[0]->hidden_vertices_begin();
it != hierarchy[0]->hidden_vertices_end(); ++it) {
if (it->up() != Vertex_handle()) V[ it->up()->down() ] = it;
}
}
void add_hidden_vertices_into_map(Tag_false ,
std::map<Vertex_handle,Vertex_handle >& )
std::map<Vertex_handle,Vertex_handle >& )
{return;}
};
@ -268,8 +267,8 @@ template <class Tr_>
Triangulation_hierarchy_2<Tr_>::
Triangulation_hierarchy_2(const Geom_traits& traits)
: Tr_Base(traits)
{
hierarchy[0] = this;
{
hierarchy[0] = this;
for(int i=1;i<Triangulation_hierarchy_2__maxlevel;++i)
hierarchy[i] = new Tr_Base(traits);
}
@ -280,14 +279,14 @@ template <class Tr_>
Triangulation_hierarchy_2<Tr_>::
Triangulation_hierarchy_2(const Triangulation_hierarchy_2<Tr_> &tr)
: Tr_Base()
{
{
// create an empty triangulation to be able to delete it !
hierarchy[0] = this;
hierarchy[0] = this;
for(int i=1;i<Triangulation_hierarchy_2__maxlevel;++i)
hierarchy[i] = new Tr_Base(tr.geom_traits());
copy_triangulation(tr);
}
}
//Assignement
template <class Tr_>
@ -309,14 +308,14 @@ copy_triangulation(const Triangulation_hierarchy_2<Tr_> &tr)
for(int i=0;i<Triangulation_hierarchy_2__maxlevel;++i)
hierarchy[i]->copy_triangulation(*tr.hierarchy[i]);
}
//up and down have been copied in straightforward way
// compute a map at lower level
std::map<Vertex_handle, Vertex_handle > V;
{
for( Finite_vertices_iterator it=hierarchy[0]->finite_vertices_begin();
it != hierarchy[0]->finite_vertices_end(); ++it) {
for( Finite_vertices_iterator it=hierarchy[0]->finite_vertices_begin();
it != hierarchy[0]->finite_vertices_end(); ++it) {
if (it->up() != Vertex_handle()) V[ it->up()->down() ] = it;
}
}
@ -325,15 +324,15 @@ copy_triangulation(const Triangulation_hierarchy_2<Tr_> &tr)
{
for(int i=1;i<Triangulation_hierarchy_2__maxlevel;++i) {
for( Finite_vertices_iterator it=hierarchy[i]->finite_vertices_begin();
it != hierarchy[i]->finite_vertices_end(); ++it) {
// down pointer goes in original instead in copied triangulation
it->set_down(V[it->down()]);
// make reverse link
it->down()->set_up(it);
// I think the next line is unnecessary (my)
// make map for next level
if (it->up()!= Vertex_handle() ) V[ it->up()->down() ] = it;
for( Finite_vertices_iterator it=hierarchy[i]->finite_vertices_begin();
it != hierarchy[i]->finite_vertices_end(); ++it) {
// down pointer goes in original instead in copied triangulation
it->set_down(V[it->down()]);
// make reverse link
it->down()->set_up(it);
// I think the next line is unnecessary (my)
// make map for next level
if (it->up()!= Vertex_handle() ) V[ it->up()->down() ] = it;
}
}
}
@ -343,7 +342,7 @@ copy_triangulation(const Triangulation_hierarchy_2<Tr_> &tr)
/* void */
/* Triangulation_hierarchy_2<Tr_>:: */
/* add_hidden_vertices_into_map(Tag_false, */
/* std::map<Vertex_handle,Vertex_handle >& V) { */
/* std::map<Vertex_handle,Vertex_handle >& V) { */
/* return; */
/* } */
@ -352,10 +351,10 @@ copy_triangulation(const Triangulation_hierarchy_2<Tr_> &tr)
/* void */
/* Triangulation_hierarchy_2<Tr_>:: */
/* add_hidden_vertices_into_map(Tag_true, */
/* std::map<Vertex_handle,Vertex_handle >& V) */
/* std::map<Vertex_handle,Vertex_handle >& V) */
/* { */
/* for (typename Tr_Base::Hidden_vertices_iterator */
/* it=hierarchy[0]->hidden_vertices_begin(); */
/* it=hierarchy[0]->hidden_vertices_begin(); */
/* it != hierarchy[0]->hidden_vertices_end(); ++it) { */
/* if (it->up() != Vertex_handle()) V[ it->up()->down() ] = it; */
/* } */
@ -381,7 +380,7 @@ Triangulation_hierarchy_2<Tr_>::
~Triangulation_hierarchy_2()
{
clear();
for(int i= 1; i<Triangulation_hierarchy_2__maxlevel; ++i){
for(int i= 1; i<Triangulation_hierarchy_2__maxlevel; ++i){
delete hierarchy[i];
}
}
@ -392,7 +391,7 @@ Triangulation_hierarchy_2<Tr_>::
clear()
{
for(int i=0;i<Triangulation_hierarchy_2__maxlevel;++i)
hierarchy[i]->clear();
hierarchy[i]->clear();
}
@ -407,30 +406,30 @@ is_valid(bool verbose, int level) const
//verify correctness of triangulation at all levels
for(i=0;i<Triangulation_hierarchy_2__maxlevel;++i) {
if(verbose) // pirnt number of vertices at each level
std::cout << "number_of_vertices "
<< hierarchy[i]->number_of_vertices() << std::endl;
std::cout << "number_of_vertices "
<< hierarchy[i]->number_of_vertices() << std::endl;
result = result && hierarchy[i]->is_valid(verbose,level);
}
//verify that lower level has no down pointers
for( it = hierarchy[0]->finite_vertices_begin();
it != hierarchy[0]->finite_vertices_end(); ++it)
for( it = hierarchy[0]->finite_vertices_begin();
it != hierarchy[0]->finite_vertices_end(); ++it)
result = result && ( it->down() == Vertex_handle());
//verify that other levels have down pointer and reciprocal link is fine
for(i=1;i<Triangulation_hierarchy_2__maxlevel;++i)
for( it = hierarchy[i]->finite_vertices_begin();
it != hierarchy[i]->finite_vertices_end(); ++it)
result = result &&
( &*(it->down()->up()) == &*(it) );
for( it = hierarchy[i]->finite_vertices_begin();
it != hierarchy[i]->finite_vertices_end(); ++it)
result = result &&
( &*(it->down()->up()) == &*(it) );
//verify that levels have up pointer and reciprocal link is fine
for(i=0;i<Triangulation_hierarchy_2__maxlevel-1;++i)
for( it = hierarchy[i]->finite_vertices_begin();
it != hierarchy[i]->finite_vertices_end(); ++it)
for( it = hierarchy[i]->finite_vertices_begin();
it != hierarchy[i]->finite_vertices_end(); ++it)
result = result && ( it->up() == Vertex_handle() ||
&*it == &*(it->up())->down() );
&*it == &*(it->up())->down() );
return result;
}
template <class Tr_>
typename Triangulation_hierarchy_2<Tr_>::Vertex_handle
Triangulation_hierarchy_2<Tr_>::
@ -445,7 +444,7 @@ insert(const Point &p, Face_handle loc)
Vertex_handle vertex=hierarchy[0]->Tr_Base::insert(p,lt,positions[0],i);
Vertex_handle previous=vertex;
Vertex_handle first = vertex;
int level = 1;
while (level <= vertex_level ){
vertex=hierarchy[level]->Tr_Base::insert(p,positions[level]);
@ -462,7 +461,7 @@ typename Triangulation_hierarchy_2<Tr_>::Vertex_handle
Triangulation_hierarchy_2<Tr_>::
insert(const Point& p,
Locate_type lt,
Face_handle loc,
Face_handle loc,
int li )
{
int vertex_level = random_level();
@ -500,7 +499,7 @@ push_back(const Point &p)
}
template <class Tr_>
void
void
Triangulation_hierarchy_2<Tr_>::
remove(Vertex_handle v )
{
@ -508,7 +507,7 @@ remove(Vertex_handle v )
int l = 0 ;
while(1){
hierarchy[l++]->remove(v);
if (u == Vertex_handle()) break;
if (u == Vertex_handle()) break;
if (l >= Triangulation_hierarchy_2__maxlevel) break;
v=u; u=v->up();
}
@ -525,15 +524,15 @@ remove_and_give_new_faces(Vertex_handle v, OutputItFaces fit)
while(1){
if(l==0) hierarchy[l++]->remove_and_give_new_faces(v, fit);
else hierarchy[l++]->remove(v);
if (u == Vertex_handle()) break;
if (u == Vertex_handle()) break;
if (l >= Triangulation_hierarchy_2__maxlevel) break;
v=u; u=v->up();
}
}
}
template <class Tr_>
inline void
inline void
Triangulation_hierarchy_2<Tr_>::
remove_degree_3(Vertex_handle v )
{
@ -541,7 +540,7 @@ remove_degree_3(Vertex_handle v )
}
template <class Tr_>
inline void
inline void
Triangulation_hierarchy_2<Tr_>::
remove_first(Vertex_handle v )
{
@ -549,7 +548,7 @@ remove_first(Vertex_handle v )
}
template <class Tr_>
inline void
inline void
Triangulation_hierarchy_2<Tr_>::
remove_second(Vertex_handle v )
{
@ -565,7 +564,7 @@ move_if_no_collision(Vertex_handle v, const Point &p) {
while(1) {
Vertex_handle w = hierarchy[l++]->move_if_no_collision(v, p);
if(w != v) return w;
if (u == Vertex_handle()) break;
if (u == Vertex_handle()) break;
if (l >= Triangulation_hierarchy_2__maxlevel) break;
v=u; u=v->up();
}
@ -589,21 +588,21 @@ template <class Tr_>
template <class OutputItFaces>
typename Triangulation_hierarchy_2<Tr_>::Vertex_handle
Triangulation_hierarchy_2<Tr_>::
move_if_no_collision_and_give_new_faces(Vertex_handle v, const Point &p,
move_if_no_collision_and_give_new_faces(Vertex_handle v, const Point &p,
OutputItFaces oif)
{
Vertex_handle u=v->up(), norm = v;
int l = 0 ;
while(1){
Vertex_handle w;
if(l == 0)
w =
if(l == 0)
w =
hierarchy[l++]->move_if_no_collision_and_give_new_faces(v, p, oif);
else w = hierarchy[l++]->move_if_no_collision(v, p);
if(w != v) return w;
if (u == Vertex_handle()) break;
if (u == Vertex_handle()) break;
if (l >= Triangulation_hierarchy_2__maxlevel) break;
v=u; u=v->up();
}
@ -628,7 +627,7 @@ Triangulation_hierarchy_2<Tr_>::insert_and_give_new_faces(const Point &p,
hierarchy[0]->Tr_Base::insert_and_give_new_faces(p,lt,positions[0],i,oif);
Vertex_handle previous=vertex;
Vertex_handle first = vertex;
int level = 1;
while (level <= vertex_level ){
vertex=hierarchy[level]->Tr_Base::insert(p,positions[level]);
@ -648,7 +647,7 @@ Triangulation_hierarchy_2<Tr_>::
insert_and_give_new_faces(const Point &p,
Locate_type lt,
Face_handle loc,
int li,
int li,
OutputItFaces oif)
{
int vertex_level = random_level();
@ -713,14 +712,14 @@ locate_in_all(const Point& p,
typename Geom_traits::Construct_point_2
construct_point = geom_traits().construct_point_2_object();
// find the highest level with enough vertices that is at the same time 2D
while ( (hierarchy[--level]->number_of_vertices()
< static_cast<size_type> (Triangulation_hierarchy_2__minsize ))
|| (hierarchy[level]->dimension()<2) ){
while ( (hierarchy[--level]->number_of_vertices()
< static_cast<size_type> (Triangulation_hierarchy_2__minsize ))
|| (hierarchy[level]->dimension()<2) ){
if ( ! level) break; // do not go below 0
}
if((level>0) && (hierarchy[level]->dimension()<2)){
if((level>0) && (hierarchy[level]->dimension()<2)){
level--;
}
@ -746,10 +745,10 @@ locate_in_all(const Point& p,
}
// compare to vertex 2, but only if the triangulation is 2D, because otherwise vertex(2) is nullptr
if ( (hierarchy[level]->dimension()==2) && (! hierarchy[level]->is_infinite(position->vertex(2)))){
if ( closer( construct_point(p),
construct_point(position->vertex(2)->point()),
construct_point(nearest->point())) == SMALLER ){
nearest = position->vertex(2);
if ( closer( construct_point(p),
construct_point(position->vertex(2)->point()),
construct_point(nearest->point())) == SMALLER ){
nearest = position->vertex(2);
}
}
// go at the same vertex on level below
@ -757,7 +756,7 @@ locate_in_all(const Point& p,
position = nearest->face(); // incident face
--level;
}
pos[0]=hierarchy[0]->locate(p,lt,li,loc == Face_handle() ? position : loc); // at level 0
pos[0]=hierarchy[0]->locate(p,lt,li,loc == Face_handle() ? position : loc); // at level 0
}
template <class Tr_>

View File

@ -3,13 +3,13 @@ namespace CGAL {
/*!
\ingroup PkgTriangulation3Ref
fills the face graph `tm` with the <A HREF="https://en.wikipedia.org/wiki/Simplicial_complex#Closure.2C_star.2C_and_link">link</a> of triangulation vertex `vh`.
fills the face graph `tm` with the <A HREF="https://en.wikipedia.org/wiki/Simplicial_complex#Closure.2C_star.2C_and_link">link</a> of triangulation vertex `vh`.
\pre `T.dimension()`==3.
\tparam Triangulation must be a \cgal 3D triangulation.
\tparam TriangleMesh must be a model of the concept `MutableFaceGraph`.
\tparam Triangulation must be a \cgal 3D triangulation.
\tparam TriangleMesh must be a model of the concept `MutableFaceGraph`.
\param t the 3D triangulation
\param vh the vertex handle of the vertex
@ -18,18 +18,18 @@ fills the face graph `tm` with the <A HREF="https://en.wikipedia.org/wiki/Simpli
of the triangulation, `no_infinite_faces == true` generates a triangle mesh with a border.
Otherwise, this parameter is ignored.
\returns the vertex descriptor of the triangle mesh `tm` corresponding to the infinite vertex of `t`,
\returns the vertex descriptor of the triangle mesh `tm` corresponding to the infinite vertex of `t`,
if `vh` is on the convex hull of the triangulation, and if `no_infinite_faces == false`.
Otherwise, an arbitrary vertex descriptor of the triangle mesh `tm`.
\sa `convex_hull_3_to_polyhedron_3()`
\sa `convex_hull_3_to_face_graph()`
*/
template <class Triangulation, class TriangleMesh>
typename boost::graph_trait<FG>::vertex_descriptor
link_to_face_graph(const Triangulation& t,
typename Triangulation::Vertex_handle vh,
TriangleMesh& tm,
TriangleMesh& tm,
bool no_infinite_faces = true);
} /* namespace CGAL */

View File

@ -22,13 +22,6 @@
#include <CGAL/basic.h>
#include <set>
#include <boost/bind.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/utility/result_of.hpp>
#ifdef CGAL_LINKED_WITH_TBB
# include <CGAL/point_generators_3.h>
# include <tbb/parallel_for.h>
@ -41,7 +34,6 @@
#include <CGAL/Regular_triangulation_vertex_base_3.h>
#include <CGAL/Regular_triangulation_cell_base_3.h>
#include <CGAL/internal/Has_nested_type_Bare_point.h>
#include <CGAL/internal/boost/function_property_map.hpp>
#include <CGAL/Cartesian_converter.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
@ -63,6 +55,20 @@
#include <CGAL/point_generators_3.h>
#endif
#include <boost/bind.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/property_map/function_property_map.hpp>
#include <boost/utility/result_of.hpp>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <set>
#include <thread>
#include <utility>
#include <vector>
namespace CGAL {
/************************************************
@ -269,12 +275,12 @@ private:
// Spatial sorting can only be applied to bare points, so we need an adaptor
typedef typename Geom_traits::Construct_point_3 Construct_point_3;
typedef typename boost::result_of<const Construct_point_3(const Weighted_point&)>::type Ret;
typedef CGAL::internal::boost_::function_property_map<Construct_point_3, Weighted_point, Ret> fpmap;
typedef boost::function_property_map<Construct_point_3, Weighted_point, Ret> fpmap;
typedef CGAL::Spatial_sort_traits_adapter_3<Geom_traits, fpmap> Search_traits_3;
spatial_sort(points_on_far_sphere.begin(), points_on_far_sphere.end(),
Search_traits_3(
CGAL::internal::boost_::make_function_property_map<Weighted_point, Ret, Construct_point_3>(
boost::make_function_property_map<Weighted_point, Ret, Construct_point_3>(
geom_traits().construct_point_3_object()), geom_traits()));
typename std::vector<Weighted_point>::const_iterator it_p =
@ -341,12 +347,12 @@ public:
// kernel creates temporaries and prevent it.
typedef typename Geom_traits::Construct_point_3 Construct_point_3;
typedef typename boost::result_of<const Construct_point_3(const Weighted_point&)>::type Ret;
typedef CGAL::internal::boost_::function_property_map<Construct_point_3, Weighted_point, Ret> fpmap;
typedef boost::function_property_map<Construct_point_3, Weighted_point, Ret> fpmap;
typedef CGAL::Spatial_sort_traits_adapter_3<Geom_traits, fpmap> Search_traits_3;
spatial_sort(points.begin(), points.end(),
Search_traits_3(
CGAL::internal::boost_::make_function_property_map<Weighted_point, Ret, Construct_point_3>(
boost::make_function_property_map<Weighted_point, Ret, Construct_point_3>(
geom_traits().construct_point_3_object()), geom_traits()));
// Parallel
@ -412,7 +418,7 @@ public:
#ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
private:
//top stands for tuple-or-pair
template <class Info>
const Weighted_point& top_get_first(const std::pair<Weighted_point,Info>& pair) const { return pair.first; }
@ -425,7 +431,7 @@ private:
template <class Info>
const Info& top_get_second(const boost::tuple<Weighted_point,Info>& tuple) const { return boost::get<1>(tuple); }
// Functor to go from an index of a container of Weighted_point to
// the corresponding Bare_point
template<class Construct_bare_point, class Container>
@ -466,14 +472,14 @@ private:
typedef Index_to_Bare_point<Construct_point_3,
std::vector<Weighted_point> > Access_bare_point;
typedef typename boost::result_of<const Construct_point_3(const Weighted_point&)>::type Ret;
typedef CGAL::internal::boost_::function_property_map<Access_bare_point, std::size_t, Ret> fpmap;
typedef boost::function_property_map<Access_bare_point, std::size_t, Ret> fpmap;
typedef CGAL::Spatial_sort_traits_adapter_3<Gt, fpmap> Search_traits_3;
Access_bare_point accessor(points, geom_traits().construct_point_3_object());
spatial_sort(indices.begin(), indices.end(),
Search_traits_3(
CGAL::internal::boost_::make_function_property_map<
std::size_t, Ret, Access_bare_point>(accessor),
boost::make_function_property_map<
std::size_t, Ret, Access_bare_point>(accessor),
geom_traits()));
#ifdef CGAL_LINKED_WITH_TBB

View File

@ -47,7 +47,6 @@
#include <CGAL/function_objects.h>
#include <CGAL/Iterator_project.h>
#include <CGAL/Default.h>
#include <CGAL/internal/boost/function_property_map.hpp>
#include <CGAL/Bbox_3.h>
#include <CGAL/Spatial_lock_grid_3.h>
@ -57,6 +56,7 @@
#include <boost/random/uniform_smallint.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/mpl/if.hpp>
#include <boost/property_map/function_property_map.hpp>
#include <boost/unordered_map.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/container/small_vector.hpp>
@ -433,7 +433,7 @@ public:
typedef typename Tds::Vertex_handles All_vertex_handles;
typedef typename Tds::Facets All_facets;
typedef typename Tds::Edges All_edges;
typedef typename Tds::Simplex Simplex;
typedef typename GT::Construct_point_3 Construct_point_3;
@ -523,7 +523,7 @@ public:
typedef Iterator_range<Finite_edges_iterator> Finite_edges;
typedef Iterator_range<Finite_facets_iterator> Finite_facets;
private:
// Auxiliary iterators for convenience
// do not use default template argument to please VC++
@ -539,7 +539,7 @@ public:
typedef Iterator_range<Point_iterator> Points;
// To have a back_inserter
typedef Point value_type;
typedef const value_type& const_reference;
@ -1130,7 +1130,7 @@ public:
Hidden_points_visitor& hider,
bool *could_lock_zone = nullptr);
#ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
template < class InputIterator >
std::ptrdiff_t insert(InputIterator first, InputIterator last,
@ -1223,8 +1223,8 @@ public:
}
#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
Vertex_handle insert_in_cell(const Point& p, Cell_handle c);
Vertex_handle insert_in_facet(const Point& p, Cell_handle c, int i);
Vertex_handle insert_in_facet(const Point& p, const Facet& f) {
@ -1770,13 +1770,13 @@ public:
return CGAL::filter_iterator(cells_end(), Infinite_tester(this));
}
Finite_cell_handles finite_cell_handles() const
{
return make_prevent_deref_range(finite_cells_begin(), finite_cells_end());
return make_prevent_deref_range(finite_cells_begin(), finite_cells_end());
}
Cell_iterator cells_begin() const { return _tds.cells_begin(); }
Cell_iterator cells_end() const { return _tds.cells_end(); }
@ -1787,7 +1787,7 @@ public:
{
return _tds.cell_handles();
}
Finite_vertices_iterator finite_vertices_begin() const
{
if(number_of_vertices() <= 0)
@ -1803,9 +1803,9 @@ public:
Finite_vertex_handles finite_vertex_handles() const
{
return make_prevent_deref_range(finite_vertices_begin(), finite_vertices_end());
return make_prevent_deref_range(finite_vertices_begin(), finite_vertices_end());
}
Vertex_iterator vertices_begin() const { return _tds.vertices_begin(); }
Vertex_iterator vertices_end() const { return _tds.vertices_end(); }
@ -1816,7 +1816,7 @@ public:
{
return _tds.vertex_handles();
}
Finite_edges_iterator finite_edges_begin() const
{
if(dimension() < 1)
@ -1833,11 +1833,11 @@ public:
{
return Finite_edges(finite_edges_begin(),finite_edges_end());
}
Edge_iterator edges_begin() const { return _tds.edges_begin(); }
Edge_iterator edges_end() const { return _tds.edges_end(); }
All_edges_iterator all_edges_begin() const { return _tds.edges_begin(); }
All_edges_iterator all_edges_end() const { return _tds.edges_end(); }
@ -1845,7 +1845,7 @@ public:
{
return _tds.edges();
}
Finite_facets_iterator finite_facets_begin() const
{
if(dimension() < 2)
@ -1866,7 +1866,7 @@ public:
Facet_iterator facets_begin() const { return _tds.facets_begin(); }
Facet_iterator facets_end() const { return _tds.facets_end(); }
All_facets_iterator all_facets_begin() const { return _tds.facets_begin(); }
All_facets_iterator all_facets_end() const { return _tds.facets_end(); }
@ -1874,7 +1874,7 @@ public:
{
return _tds.facets();
}
Point_iterator points_begin() const
{
return Point_iterator(finite_vertices_begin());
@ -1888,7 +1888,7 @@ public:
{
return Points(points_begin(),points_end());
}
// cells around an edge
Cell_circulator incident_cells(const Edge& e) const
{
@ -3357,7 +3357,7 @@ side_of_facet(const Point& p,
{
// The following precondition is useless because it is written
// in side_of_facet
// CGAL_triangulation_precondition(coplanar (p,
// CGAL_triangulation_precondition(coplanar (p,
// c->vertex(0)->point,
// c->vertex(1)->point,
// c->vertex(2)->point));
@ -3384,7 +3384,7 @@ side_of_facet(const Point& p,
int inf = c->index(infinite);
// The following precondition is useless because it is written
// in side_of_facet
// CGAL_triangulation_precondition(coplanar (p,
// CGAL_triangulation_precondition(coplanar (p,
// c->neighbor(inf)->vertex(0)->point(),
// c->neighbor(inf)->vertex(1)->point(),
// c->neighbor(inf)->vertex(2)->point()));
@ -4031,9 +4031,9 @@ insert_outside_convex_hull(const Point& p, Cell_handle c)
{
case 1:
{
// // p lies in the infinite edge neighboring c
// // on the other side of li
// return insert_in_edge(p,c->neighbor(1-li),0,1);
// // p lies in the infinite edge neighboring c
// // on the other side of li
// return insert_in_edge(p,c->neighbor(1-li),0,1);
return insert_in_edge(p,c,0,1);
}
case 2:
@ -6592,12 +6592,12 @@ _remove_cluster_3D(InputIterator first, InputIterator beyond, VertexRemover& rem
// Spatial sorting can only be applied to bare points, so we need an adaptor
typedef typename Geom_traits::Construct_point_3 Construct_point_3;
typedef typename boost::result_of<const Construct_point_3(const Point&)>::type Ret;
typedef CGAL::internal::boost_::function_property_map<Construct_point_3, Point, Ret> fpmap;
typedef boost::function_property_map<Construct_point_3, Point, Ret> fpmap;
typedef CGAL::Spatial_sort_traits_adapter_3<Geom_traits, fpmap> Search_traits_3;
spatial_sort(vps.begin(), vps.end(),
Search_traits_3(
CGAL::internal::boost_::make_function_property_map<Point, Ret, Construct_point_3>(
boost::make_function_property_map<Point, Ret, Construct_point_3>(
geom_traits().construct_point_3_object()), geom_traits()));
std::size_t svps = vps.size();

View File

@ -33,8 +33,7 @@
#include <CGAL/Triangulation_hierarchy_vertex_base_3.h>
#include <CGAL/Location_policy.h>
#include <CGAL/internal/boost/function_property_map.hpp>
#include <boost/property_map/function_property_map.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/geometric_distribution.hpp>
#include <boost/random/variate_generator.hpp>
@ -169,12 +168,12 @@ public:
// Spatial sort can only be used with Geom_traits::Point_3: we need an adapter
typedef typename Geom_traits::Construct_point_3 Construct_point_3;
typedef typename boost::result_of<const Construct_point_3(const Point&)>::type Ret;
typedef CGAL::internal::boost_::function_property_map<Construct_point_3, Point, Ret> fpmap;
typedef boost::function_property_map<Construct_point_3, Point, Ret> fpmap;
typedef CGAL::Spatial_sort_traits_adapter_3<Geom_traits, fpmap> Search_traits_3;
spatial_sort(points.begin(), points.end(),
Search_traits_3(
CGAL::internal::boost_::make_function_property_map<Point, Ret, Construct_point_3>(
boost::make_function_property_map<Point, Ret, Construct_point_3>(
geom_traits().construct_point_3_object()), geom_traits()));
// hints[i] is the vertex of the previously inserted point in level i.
@ -191,7 +190,7 @@ public:
for (int level = 1; level <= vertex_level; ++level) {
v = hints[level] = hierarchy[level]->insert (*p, hints[level]);
set_up_down(v, prev);
set_up_down(v, prev);
prev = v;
}
}
@ -246,13 +245,13 @@ private:
typedef Index_to_Bare_point<Construct_point_3,
std::vector<Point> > Access_bare_point;
typedef typename boost::result_of<const Construct_point_3(const Point&)>::type Ret;
typedef CGAL::internal::boost_::function_property_map<Access_bare_point, std::size_t, Ret> fpmap;
typedef boost::function_property_map<Access_bare_point, std::size_t, Ret> fpmap;
typedef CGAL::Spatial_sort_traits_adapter_3<Geom_traits, fpmap> Search_traits_3;
Access_bare_point accessor(points, geom_traits().construct_point_3_object());
spatial_sort(indices.begin(), indices.end(),
Search_traits_3(
CGAL::internal::boost_::make_function_property_map<
boost::make_function_property_map<
std::size_t, Ret, Access_bare_point>(accessor),
geom_traits()));
@ -355,34 +354,34 @@ public: // some internal methods
// GIVING NEW FACES
template <class OutputItCells>
Vertex_handle insert_and_give_new_cells(const Point &p,
Vertex_handle insert_and_give_new_cells(const Point &p,
OutputItCells fit,
Cell_handle start = Cell_handle() );
template <class OutputItCells>
Vertex_handle insert_and_give_new_cells(const Point& p,
OutputItCells /* fit */,
Vertex_handle hint)
{
return insert_and_give_new_cells(p, hint == Vertex_handle() ?
this->infinite_cell() : hint->cell());
return insert_and_give_new_cells(p, hint == Vertex_handle() ?
this->infinite_cell() : hint->cell());
}
template <class OutputItCells>
Vertex_handle insert_and_give_new_cells(const Point& p,
Locate_type lt,
Cell_handle c, int li, int lj,
Cell_handle c, int li, int lj,
OutputItCells fit);
template <class OutputItCells>
void remove_and_give_new_cells(Vertex_handle v,
void remove_and_give_new_cells(Vertex_handle v,
OutputItCells fit);
template <class OutputItCells>
Vertex_handle move_if_no_collision_and_give_new_cells(Vertex_handle v,
Vertex_handle move_if_no_collision_and_give_new_cells(Vertex_handle v,
const Point &p, OutputItCells fit);
public:
public:
//LOCATE
@ -414,7 +413,7 @@ protected:
};
void locate(const Point& p, Locate_type& lt, int& li, int& lj,
locs pos[maxlevel], Cell_handle start = Cell_handle ()) const;
locs pos[maxlevel], Cell_handle start = Cell_handle ()) const;
int random_level();
};
@ -452,12 +451,12 @@ Triangulation_hierarchy_3(const Triangulation_hierarchy_3<Tr> &tr)
for(int j=1; j<maxlevel; ++j) {
for( Finite_vertices_iterator it = hierarchy[j]->finite_vertices_begin(),
end = hierarchy[j]->finite_vertices_end(); it != end; ++it) {
// current it->down() pointer goes in original instead in copied triangulation
set_up_down(it, V[it->down()]);
// make map for next level
if (it->up() != Vertex_handle())
V[ it->up()->down() ] = it;
end = hierarchy[j]->finite_vertices_end(); it != end; ++it) {
// current it->down() pointer goes in original instead in copied triangulation
set_up_down(it, V[it->down()]);
// make map for next level
if (it->up() != Vertex_handle())
V[ it->up()->down() ] = it;
}
}
}
@ -500,7 +499,7 @@ is_valid(bool verbose, int level) const
// verify correctness of triangulation at all levels
for(int i=0; i<maxlevel; ++i)
result = result && hierarchy[i]->is_valid(verbose, level);
result = result && hierarchy[i]->is_valid(verbose, level);
// verify that lower level has no down pointers
for( Finite_vertices_iterator it = hierarchy[0]->finite_vertices_begin(),
@ -510,15 +509,15 @@ is_valid(bool verbose, int level) const
// verify that other levels has down pointer and reciprocal link is fine
for(int j=1; j<maxlevel; ++j)
for( Finite_vertices_iterator it = hierarchy[j]->finite_vertices_begin(),
end = hierarchy[j]->finite_vertices_end(); it != end; ++it)
end = hierarchy[j]->finite_vertices_end(); it != end; ++it)
result = result && &*(it) == &*(it->down()->up());
// verify that other levels has down pointer and reciprocal link is fine
for(int k=0; k<maxlevel-1; ++k)
for( Finite_vertices_iterator it = hierarchy[k]->finite_vertices_begin(),
end = hierarchy[k]->finite_vertices_end(); it != end; ++it)
end = hierarchy[k]->finite_vertices_end(); it != end; ++it)
result = result && ( it->up() == Vertex_handle() ||
&*it == &*(it->up())->down() );
&*it == &*(it->up())->down() );
return result;
}
@ -536,10 +535,10 @@ insert(const Point &p, Cell_handle start)
locate(p, lt, i, j, positions, start);
// insert at level 0
Vertex_handle vertex = hierarchy[0]->insert(p,
positions[0].lt,
positions[0].pos,
positions[0].li,
positions[0].lj);
positions[0].lt,
positions[0].pos,
positions[0].li,
positions[0].lj);
Vertex_handle previous = vertex;
Vertex_handle first = vertex;
@ -549,10 +548,10 @@ insert(const Point &p, Cell_handle start)
vertex = hierarchy[level]->insert(p);
else
vertex = hierarchy[level]->insert(p,
positions[level].lt,
positions[level].pos,
positions[level].li,
positions[level].lj);
positions[level].lt,
positions[level].pos,
positions[level].li,
positions[level].lj);
set_up_down(vertex, previous);
previous=vertex;
level++;
@ -619,13 +618,13 @@ insert(const Point &p, Locate_type lt, Cell_handle loc, int li, int lj)
int level = 1;
while (level <= vertex_level ){
if (positions[level].pos == Cell_handle())
vertex = hierarchy[level]->insert(p);
vertex = hierarchy[level]->insert(p);
else
vertex = hierarchy[level]->insert(p,
positions[level].lt,
positions[level].pos,
positions[level].li,
positions[level].lj);
vertex = hierarchy[level]->insert(p,
positions[level].lt,
positions[level].pos,
positions[level].li,
positions[level].lj);
set_up_down(vertex, previous);
previous=vertex;
level++;
@ -638,12 +637,12 @@ template <class Tr>
template <class OutputItCells>
typename Triangulation_hierarchy_3<Tr>::Vertex_handle
Triangulation_hierarchy_3<Tr>::
insert_and_give_new_cells(const Point &p, Locate_type lt, Cell_handle loc,
insert_and_give_new_cells(const Point &p, Locate_type lt, Cell_handle loc,
int li, int lj, OutputItCells fit)
{
int vertex_level = random_level();
// insert at level 0
Vertex_handle vertex =
Vertex_handle vertex =
hierarchy[0]->insert_and_give_new_cells(p,lt,loc,li,lj,fit);
Vertex_handle previous = vertex;
Vertex_handle first = vertex;
@ -658,9 +657,9 @@ insert_and_give_new_cells(const Point &p, Locate_type lt, Cell_handle loc,
int level = 1;
while (level <= vertex_level ){
if (positions[level].pos == Cell_handle())
vertex = hierarchy[level]->insert(p);
vertex = hierarchy[level]->insert(p);
else
vertex = hierarchy[level]->insert(p,
vertex = hierarchy[level]->insert(p,
positions[level].lt,
positions[level].pos,
positions[level].li,
@ -683,7 +682,7 @@ remove(Vertex_handle v)
Vertex_handle u = v->up();
hierarchy[l]->remove(v);
if (u == Vertex_handle())
break;
break;
v = u;
}
}
@ -701,7 +700,7 @@ remove_and_give_new_cells(Vertex_handle v, OutputItCells fit)
if(l) hierarchy[l]->remove(v);
else hierarchy[l]->remove_and_give_new_cells(v, fit);
if (u == Vertex_handle())
break;
break;
v = u;
}
}
@ -711,7 +710,7 @@ typename Triangulation_hierarchy_3<Tr>::Vertex_handle
Triangulation_hierarchy_3<Tr>::
move_if_no_collision(Vertex_handle v, const Point & p)
{
CGAL_triangulation_precondition(!this->is_infinite(v));
CGAL_triangulation_precondition(!this->is_infinite(v));
if(v->point() == p) return v;
Vertex_handle ans;
for (int l = 0; l < maxlevel; ++l) {
@ -748,13 +747,13 @@ Triangulation_hierarchy_3<Tr>::
move_if_no_collision_and_give_new_cells(
Vertex_handle v, const Point & p, OutputItCells fit)
{
CGAL_triangulation_precondition(!is_infinite(v));
CGAL_triangulation_precondition(!is_infinite(v));
if(v->point() == p) return v;
Vertex_handle ans;
for (int l = 0; l < maxlevel; ++l) {
Vertex_handle u = v->up();
if(l) hierarchy[l]->move_if_no_collision(v, p);
else ans =
else ans =
hierarchy[l]->move_if_no_collision_and_give_new_cells(v, p, fit);
if(ans != v) return ans;
if (u == Vertex_handle())
@ -801,7 +800,7 @@ locate(const Point& p, Locate_type& lt, int& li, int& lj,
// find the highest level with enough vertices
while (hierarchy[--level]->number_of_vertices() < (size_type) minsize) {
if ( ! level)
break; // do not go below 0
break; // do not go below 0
}
for (int i=level+1; i<maxlevel; ++i)
@ -812,10 +811,10 @@ locate(const Point& p, Locate_type& lt, int& li, int& lj,
// locate at that level from "position"
// result is stored in "position" for the next level
pos[level].pos = position = hierarchy[level]->locate(p,
pos[level].lt,
pos[level].li,
pos[level].lj,
position);
pos[level].lt,
pos[level].li,
pos[level].lj,
position);
// find the nearest vertex.
Vertex_handle nearest = hierarchy[level]->nearest_vertex_in_cell(p, position);