27 #ifndef MLN_MORPHO_TREE_IMPL_COMPUTE_PARENT_DUAL_HQUEUE_HH
28 # define MLN_MORPHO_TREE_IMPL_COMPUTE_PARENT_DUAL_HQUEUE_HH
47 # include <mln/data/sort_psites.hh>
48 # include <mln/data/fill.hh>
50 # include <mln/geom/nsites.hh>
51 # include <mln/geom/translate.hh>
53 # include <mln/morpho/tree/data.hh>
55 # include <mln/util/hqueues.hh>
56 # include <mln/util/ord.hh>
58 # include <mln/value/value_array.hh>
59 # include <mln/value/set.hh>
61 # include <mln/util/timer.hh>
83 template <
typename I,
typename N>
93 # ifndef MLN_INCLUDE_ONLY
98 template <
typename I,
typename N,
class E>
99 struct shared_flood_args
101 typedef mln_psite(I) P;
102 typedef mln_value(I) V;
108 mln_ch_value(I, P)& parent;
111 util::hqueues<P, V>& hqueues;
115 mln_ch_value(I,
bool) deja_vu;
118 shared_flood_args(const I& f_,
121 mln_ch_value(I, P)& parent_,
122 util::hqueues<mln_psite(I), V>& hqueues_,
130 is_node_at_level (false),
131 vset (hqueues.vset())
138 template <
typename I>
141 compute_histo(
const I& f,
const I& m, mln_value(I)& hmin, mln_psite(I)& pmin)
154 for (
unsigned i = 0; i < hm.
nvalues(); ++i)
158 mln_piter(I)
p(m.domain());
159 for (
p.start(); m(
p) != hmin;
p.next())
161 mln_assertion(
p.is_valid());
170 template <typename I>
178 mln_psite(I) operator() (const mln_psite(I)& p)
const
184 const mln_psite(I)::
delta dp_;
192 template <
typename I,
typename N,
typename E>
194 flood(internal::shared_flood_args<I, N, E>& args,
const unsigned h_idx)
196 mln_assertion(args.is_node_at_level[h_idx]);
198 while (!args.hqueues[h_idx].empty())
200 mln_psite(I) p = args.hqueues[h_idx].pop_front();
201 unsigned p_idx = args.vset.index_of(args.f(p));
205 mln_psite(I) pext = args.extend(p);
206 args.parent(pext) = args.node_at_level[h_idx];
209 args.parent(p) = args.node_at_level[h_idx];
212 if (!args.is_node_at_level[p_idx])
214 args.is_node_at_level[p_idx] =
true;
215 args.node_at_level[p_idx] =
p;
222 if (!args.f.domain().has(args.node_at_level[p_idx]) ||
225 args.parent(args.node_at_level[p_idx]) =
p;
226 args.node_at_level[p_idx] =
p;
229 args.parent(p) = args.node_at_level[p_idx];
234 mln_niter(N) n(args.nbh, p);
236 if (args.f.domain().has(n) && !args.deja_vu(n))
238 unsigned mn = args.vset.index_of(args.m(n));
239 unsigned fn = args.vset.index_of(args.f(n));
240 args.hqueues[mn].push(n);
241 args.deja_vu(n) =
true;
243 mln_psite(I) ext = args.extend(n);
246 mln_psite(I) node = (fn == mn) ? n : ext;
247 if (!args.is_node_at_level[mn])
249 args.is_node_at_level[mn] =
true;
250 args.node_at_level[mn] = node;
255 mn = flood(args, mn);
260 args.is_node_at_level[h_idx] =
false;
262 while (c > 0 && !args.is_node_at_level[c])
265 mln_psite(I) x = args.node_at_level[h_idx];
267 args.parent(x) = args.node_at_level[c];
274 template <typename I, typename N>
276 data< I, p_array<mln_psite(I)> >
277 dual_hqueue(const Image<I>& f_,
279 const Neighborhood<N>& neibh_)
281 mln_trace(
"mln::morpho::tree::impl::dual_hqueue");
283 const I& f =
exact(f_);
284 const I& m =
exact(m_);
285 const N& nbh =
exact(neibh_);
287 typedef mln_psite(I) P;
288 typedef p_array<mln_psite(I)> S;
296 const
histo::array<mln_value(I)>
histo = internal::compute_histo(f, m, hmin, pmin);
297 util::hqueues<P, mln_value(I)> hqueues(
histo);
299 mln_psite(I)::
delta dp(literal::zero);
300 mln_domain(I) d_ext = f.domain();
301 mln_domain(I) d = f.domain();
304 dp[0] = d.pmax()[0] - d.pmin()[0] + 1;
310 mln_concrete(I) fext;
311 mln_ch_value(I, P) parent;
312 p_array<mln_psite(I)> s;
315 fext = geom::
translate(m, dp.to_vec(), f, d);
317 s.reserve(geom::
nsites(fext));
320 internal::extend<I> extend(dp);
321 internal::shared_flood_args< I, N, internal::extend<I> >
322 args(f, m, nbh, parent, hqueues, extend);
324 unsigned r = args.vset.index_of(hmin);
325 args.deja_vu(pmin) = true;
326 args.hqueues[r].push(pmin);
327 args.node_at_level[r] = (f(pmin) == hmin) ? pmin : extend(pmin);
328 args.is_node_at_level[r] = true;
335 if (args.is_node_at_level[i])
337 parent(args.node_at_level[r]) = args.node_at_level[i];
342 parent(args.node_at_level[r]) = args.node_at_level[r];
346 mln_ch_value(I,
bool) deja_vu(d_ext);
349 p_array<mln_psite(I)> s_f = mln::
data::sort_psites_increasing(f);
350 mln_fwd_piter(S) p(s_f);
361 mln_assertion(!(d_ext.has(q) && fext(p) == fext(q) && d_ext.has(parent(q)) && q != parent(q)));
363 while (d_ext.has(q) && !deja_vu(q) && (fext(q) != fext(parent(q)) || q == parent(q)))
371 if (d_ext.has(q) && fext(q) == fext(parent(q)) && q != parent(q))
373 q = (parent(x) = parent(q));
374 mln_assertion(f.domain().has(q));
377 if (fext(q) == fext(parent(q)))
378 parent(x) = parent(q);
382 mln_assertion((q = parent(p)) == parent(q) || fext(q) != fext(parent(q)));
395 # endif // ! MLN_INCLUDE_ONLY
403 #endif // !MLN_MORPHO_TREE_COMPUTE_PARENT_DUAL_HQUEUE_HH