49 const base_node *min, *max;
52 struct box_index_id_compare {
53 bool operator()(
const box_index *plhs,
const box_index *prhs)
const {
54 return plhs->id < prhs->id;
58 struct box_index_topology_compare {
59 const scalar_type EPS;
60 bool is_less(
const base_node &lhs,
const base_node &rhs)
const {
61 GMM_ASSERT2(lhs.size() == rhs.size(),
"size mismatch");
62 for (
size_type i = 0; i < lhs.size(); ++i)
63 if (gmm::abs(lhs[i] - rhs[i]) > EPS) {
64 return lhs[i] < rhs[i];
69 box_index_topology_compare(scalar_type EPS_) : EPS{EPS_} {}
71 bool operator()(
const box_index &lhs,
const box_index &rhs)
const {
72 if (EPS == scalar_type(0))
73 return lhs.id < rhs.id;
75 return is_less(*lhs.min, *rhs.min) ||
76 (!is_less(*rhs.min, *lhs.min) && is_less(*lhs.max, *rhs.max));
80 struct rtree_elt_base {
81 enum { RECTS_PER_LEAF=8 };
83 bool isleaf()
const {
return isleaf_; }
85 rtree_elt_base(
bool leaf,
const base_node& rmin_,
const base_node& rmax_)
86 : isleaf_(leaf), rmin(rmin_), rmax(rmax_) {}
87 virtual ~rtree_elt_base() {}
100 using box_cont = std::set<box_index,box_index_topology_compare> ;
101 using pbox_cont = std::vector<const box_index*>;
102 using pbox_set = std::set<const box_index *, box_index_id_compare>;
104 rtree(scalar_type EPS = 0);
110 size_type nb_boxes()
const {
return boxes.size(); }
114 pbox_set& boxlst)
const;
116 pbox_set& boxlst)
const;
118 pbox_set& boxlst)
const;
119 void find_boxes_at_point(
const base_node& P, pbox_set& boxlst)
const;
120 void find_line_intersecting_boxes(
const base_node& org,
122 pbox_set& boxlst)
const;
123 void find_line_intersecting_boxes(
const base_node& org,
127 pbox_set& boxlst)
const;
130 std::vector<size_type>& idvec) {
132 find_intersecting_boxes(bmin, bmax, bs);
133 pbox_set_to_idvec(bs, idvec);
136 std::vector<size_type>& idvec) {
138 find_containing_boxes(bmin, bmax, bs);
139 pbox_set_to_idvec(bs, idvec);
141 void find_contained_boxes(
const base_node& bmin,
143 std::vector<size_type>& idvec) {
145 find_contained_boxes(bmin, bmax, bs);
146 pbox_set_to_idvec(bs, idvec);
148 void find_boxes_at_point(
const base_node& P,
149 std::vector<size_type>& idvec)
const
150 { pbox_set bs; find_boxes_at_point(P, bs); pbox_set_to_idvec(bs, idvec); }
151 void find_line_intersecting_boxes(
const base_node& org,
153 std::vector<size_type>& idvec) {
155 find_line_intersecting_boxes(org, dirv, bs);
156 pbox_set_to_idvec(bs, idvec);
158 void find_line_intersecting_boxes(
const base_node& org,
162 std::vector<size_type>& idvec) {
164 find_line_intersecting_boxes(org, dirv, bmin, bmax, bs);
165 pbox_set_to_idvec(bs, idvec);
171 void pbox_set_to_idvec(pbox_set bs, std::vector<size_type>& idvec)
const {
172 idvec.reserve(bs.size()); idvec.resize(0);
173 for (pbox_set::const_iterator it=bs.begin(); it != bs.end(); ++it)
174 idvec.push_back((*it)->id);
177 const scalar_type EPS;
180 std::unique_ptr<rtree_elt_base> root;
182 getfem::lock_factory locks_;