Merge remote-tracking branch 'cgal/6.0.x-branch' into cgal/master

This commit is contained in:
Sébastien Loriot 2025-04-10 18:16:00 +02:00
commit c5ab9f9adc
9 changed files with 51 additions and 20 deletions

View File

@ -127,7 +127,11 @@ private:
public: public:
/*! constructs default. /*! constructs default.
*/ */
Arr_conic_traits_2() {} Arr_conic_traits_2()
: m_rat_kernel(std::make_shared<Rat_kernel>()),
m_alg_kernel(std::make_shared<Alg_kernel>()),
m_nt_traits(std::make_shared<Nt_traits>())
{}
/*! constructs from resources. /*! constructs from resources.
*/ */

View File

@ -142,10 +142,17 @@ public :
this, &Basic_generator_plugin::on_tab_changed); this, &Basic_generator_plugin::on_tab_changed);
connect(dock_widget, &GeneratorWidget::visibilityChanged, connect(dock_widget, &GeneratorWidget::visibilityChanged,
this, &Basic_generator_plugin::on_tab_changed); this, &Basic_generator_plugin::on_tab_changed);
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
connect(dock_widget->prismCheckBox, &QCheckBox::checkStateChanged,
this, &Basic_generator_plugin::on_tab_changed);
connect(dock_widget->pyramidCheckBox, &QCheckBox::checkStateChanged,
this, &Basic_generator_plugin::on_tab_changed);
#else
connect(dock_widget->prismCheckBox, &QCheckBox::stateChanged, connect(dock_widget->prismCheckBox, &QCheckBox::stateChanged,
this, &Basic_generator_plugin::on_tab_changed); this, &Basic_generator_plugin::on_tab_changed);
connect(dock_widget->pyramidCheckBox, &QCheckBox::stateChanged, connect(dock_widget->pyramidCheckBox, &QCheckBox::stateChanged,
this, &Basic_generator_plugin::on_tab_changed); this, &Basic_generator_plugin::on_tab_changed);
#endif
} }
bool applicable(QAction*) const bool applicable(QAction*) const

View File

@ -22,6 +22,7 @@ struct Custom_traits_Hausdorff
FT operator+(FT)const{return FT();} FT operator+(FT)const{return FT();}
FT operator*(FT)const{return FT();} FT operator*(FT)const{return FT();}
bool operator<=(FT)const{return false;} bool operator<=(FT)const{return false;}
bool operator==(FT)const{return false;}
bool operator>=(FT)const{return false;} bool operator>=(FT)const{return false;}
bool operator!=(FT)const{return false;} bool operator!=(FT)const{return false;}
bool operator<(FT)const{return false;} bool operator<(FT)const{return false;}

View File

@ -20,7 +20,7 @@ lot of cache misses, leading to non-optimal performance. This is the case
for example when indices are stored inside the tree, for example when indices are stored inside the tree,
or to a lesser extent when the points coordinates are stored or to a lesser extent when the points coordinates are stored
in a dynamically allocated array (e.g., `Epick_d` with dynamic in a dynamically allocated array (e.g., `Epick_d` with dynamic
dimension) &mdash; we says "to a lesser extent" because the points dimension) &mdash; we say "to a lesser extent" because the points
are re-created by the kd-tree in a cache-friendly order after its construction, are re-created by the kd-tree in a cache-friendly order after its construction,
so the coordinates are more likely to be stored in a near-optimal order on the so the coordinates are more likely to be stored in a near-optimal order on the
heap. When `EnablePointsCache` is set to `Tag_true`, the points heap. When `EnablePointsCache` is set to `Tag_true`, the points

View File

@ -127,7 +127,7 @@ which is the case for point queries.
The following two classes implement the standard The following two classes implement the standard
search strategy for orthogonal distances like the weighted Minkowski search strategy for orthogonal distances like the weighted Minkowski
distance. The second one is a specialization for incremental neighbor distance. The second one is a specialization for incremental neighbor
searching and distance browsing. Both require extendes nodes. searching and distance browsing. Both require extended nodes.
`Orthogonal_k_neighbor_search<Traits, `Orthogonal_k_neighbor_search<Traits,
OrthogonalDistance, Splitter, SpatialTree>` OrthogonalDistance, Splitter, SpatialTree>`
@ -175,9 +175,13 @@ because in general the query time will be less than using the default value.
Instead of using the default splitting rule `Sliding_midpoint` described below, Instead of using the default splitting rule `Sliding_midpoint` described below,
a user may, depending upon the data, select a user may, depending upon the data, select
one from the following splitting rules, one from the following splitting rules,
which determine how a separating hyperplane is computed. Every splitter has which determine how a separating hyperplane is computed. Some splitter have
degenerated worst cases, which may lead to a linear tree and a stack overflow. degenerated worst cases, which may lead to a linear tree and a stack overflow.
Switching the splitting rule to one of a different kind will solve the problem. Switching the splitting rule to one of a different kind will solve the problem.
The `Median_of_rectangle` and `Median_of_max_spread` are robust sliders that will
neither lead to a linear tree nor to a stack overflow. The `Median_of_rectangle`
splitter will detect if the data in a node is degenerated and applies the
`Median_of_max_spread` rule for that node to avoid a linear tree.
<DL> <DL>

View File

@ -196,7 +196,7 @@ private:
if (try_parallel_internal_node_creation (nh, c, c_low, tag)) if (try_parallel_internal_node_creation (nh, c, c_low, tag))
return; return;
if (c_low.size() > split.bucket_size()) if (c_low.size() > split.bucket_size() && !CGAL::is_zero(c_low.max_tight_spread()))
{ {
nh->lower_ch = new_internal_node(); nh->lower_ch = new_internal_node();
create_internal_node (nh->lower_ch, c_low, tag); create_internal_node (nh->lower_ch, c_low, tag);
@ -204,7 +204,7 @@ private:
else else
nh->lower_ch = create_leaf_node(c_low); nh->lower_ch = create_leaf_node(c_low);
if (c.size() > split.bucket_size()) if (c.size() > split.bucket_size() && !CGAL::is_zero(c.max_tight_spread()))
{ {
nh->upper_ch = new_internal_node(); nh->upper_ch = new_internal_node();
create_internal_node (nh->upper_ch, c, tag); create_internal_node (nh->upper_ch, c, tag);
@ -350,7 +350,7 @@ public:
Point_container c(dim_, data.begin(), data.end(),traits_); Point_container c(dim_, data.begin(), data.end(),traits_);
bbox = new Kd_tree_rectangle<FT,D>(c.bounding_box()); bbox = new Kd_tree_rectangle<FT,D>(c.bounding_box());
if (c.size() <= split.bucket_size()){ if (c.size() <= split.bucket_size() || CGAL::is_zero(c.max_tight_spread())){
tree_root = create_leaf_node(c); tree_root = create_leaf_node(c);
}else { }else {
tree_root = new_internal_node(); tree_root = new_internal_node();

View File

@ -111,11 +111,7 @@ namespace CGAL {
explicit explicit
Kd_tree_rectangle(const Kd_tree_rectangle& r) Kd_tree_rectangle(const Kd_tree_rectangle& r)
: max_span_coord_(r.max_span_coord_) : lower_(r.lower_), upper_(r.upper_), max_span_coord_(r.max_span_coord_) {}
{
lower_ = r.lower_;
upper_ = r.upper_;
}
template <class Construct_cartesian_const_iterator_d,class PointPointerIter> template <class Construct_cartesian_const_iterator_d,class PointPointerIter>
void update_from_point_pointers(PointPointerIter begin, void update_from_point_pointers(PointPointerIter begin,
@ -289,12 +285,6 @@ namespace CGAL {
std::fill(coords_, coords_ + 2*dim, FT(0)); std::fill(coords_, coords_ + 2*dim, FT(0));
} }
Kd_tree_rectangle()
: coords_(0), dim(0), max_span_coord_(-1)
{
}
explicit explicit
Kd_tree_rectangle(const Kd_tree_rectangle& r) Kd_tree_rectangle(const Kd_tree_rectangle& r)
: coords_(new FT[2*r.dim]), dim(r.dim), : coords_(new FT[2*r.dim]), dim(r.dim),

View File

@ -232,8 +232,9 @@ public:
// building the container from a sequence of Point_d* // building the container from a sequence of Point_d*
Point_container(const int d, iterator begin, iterator end,const Traits& traits_) : Point_container(const int d, iterator begin, iterator end,const Traits& traits_) :
traits(traits_),m_b(begin), m_e(end), bbox(d, begin, end,traits.construct_cartesian_const_iterator_d_object()), tbox(bbox) traits(traits_),m_b(begin), m_e(end), bbox(d, begin, end,traits.construct_cartesian_const_iterator_d_object()), tbox(d)
{ {
tbox = bbox;
built_coord = max_span_coord(); built_coord = max_span_coord();
} }
@ -419,7 +420,28 @@ public:
typename Traits::Cartesian_const_iterator_d mpit = construct_it((*(*mid))); typename Traits::Cartesian_const_iterator_d mpit = construct_it((*(*mid)));
FT val1 = *(mpit+split_coord); FT val1 = *(mpit+split_coord);
// Avoid using the low coord value as it results in an empty split
if (val1 == tbox.min_coord(split_coord)) {
iterator it = std::min_element(mid, end(), [=](const Point_d* a, const Point_d* b) -> bool {
FT a_c = *(construct_it(*a) + split_coord);
FT b_c = *(construct_it(*b) + split_coord);
if (a_c == val1)
return false;
if (b_c == val1)
return true;
return a_c < b_c;
});
return *(construct_it(**it) + split_coord);
}
mid++; mid++;
if (mid == end())
return val1;
mpit = construct_it((*(*mid))); mpit = construct_it((*(*mid)));
FT val2 = *(mpit+split_coord); FT val2 = *(mpit+split_coord);
return (val1+val2)/FT(2); return (val1+val2)/FT(2);

View File

@ -19,6 +19,7 @@
#include <CGAL/license/Spatial_searching.h> #include <CGAL/license/Spatial_searching.h>
#include <CGAL/number_utils.h>
#include <CGAL/Point_container.h> #include <CGAL/Point_container.h>
#include <CGAL/Plane_separator.h> #include <CGAL/Plane_separator.h>
@ -236,7 +237,9 @@ namespace CGAL {
void void
operator() (Separator& sep, Container& c0, Container& c1) const operator() (Separator& sep, Container& c0, Container& c1) const
{ {
sep = Separator(c0.max_span_coord(),FT(0)); if (!CGAL::is_zero(c0.tight_bounding_box().max_coord(c0.max_span_coord()) - c0.tight_bounding_box().min_coord(c0.max_span_coord())))
sep = Separator(c0.max_span_coord(),FT(0));
else sep = Separator(c0.max_tight_span_coord(), FT(0));
sep.set_cutting_value(c0.median(sep.cutting_dimension())); sep.set_cutting_value(c0.median(sep.cutting_dimension()));
c0.split(c1,sep,true); c0.split(c1,sep,true);
} }