26 #ifndef MLN_MORPHO_TREE_IMPL_COMPUTE_PARENT_DUAL_HQUEUE_HH
27 # define MLN_MORPHO_TREE_IMPL_COMPUTE_PARENT_DUAL_HQUEUE_HH
46 # include <mln/data/sort_psites.hh>
47 # include <mln/data/fill.hh>
49 # include <mln/geom/nsites.hh>
50 # include <mln/geom/translate.hh>
52 # include <mln/morpho/tree/data.hh>
54 # include <mln/util/hqueues.hh>
55 # include <mln/util/ord.hh>
57 # include <mln/value/value_array.hh>
58 # include <mln/value/set.hh>
60 # include <mln/util/timer.hh>
82 template <
typename I,
typename N>
85 dual_hqueue(
const Image<I>& f,
87 const Neighborhood<N>& nbh);
92 # ifndef MLN_INCLUDE_ONLY
97 template <
typename I,
typename N,
class E>
98 struct shared_flood_args
100 typedef mln_psite(I) P;
101 typedef mln_value(I) V;
102 typedef p_array<P> S;
107 mln_ch_value(I, P)& parent;
110 util::hqueues<P, V>& hqueues;
112 value::value_array<V,
bool> is_node_at_level;
113 value::value_array<V, P> node_at_level;
114 mln_ch_value(I,
bool) deja_vu;
115 const value::set<V>& vset;
117 shared_flood_args(const I& f_,
120 mln_ch_value(I, P)& parent_,
121 util::hqueues<mln_psite(I), V>& hqueues_,
129 is_node_at_level (false),
130 vset (hqueues.vset())
137 template <
typename I>
139 histo::array<mln_value(I)>
140 compute_histo(
const I& f,
const I& m, mln_value(I)& hmin, mln_psite(I)& pmin)
153 for (
unsigned i = 0; i < hm.nvalues(); ++i)
157 mln_piter(I) p(m.domain());
158 for (p.start(); m(p) != hmin; p.next())
160 mln_assertion(p.is_valid());
169 template <typename I>
172 extend(
const mln_psite(I)::delta& dp)
177 mln_psite(I) operator() (const mln_psite(I)& p)
const
183 const mln_psite(I)::
delta dp_;
191 template <
typename I,
typename N,
typename E>
193 flood(internal::shared_flood_args<I, N, E>& args,
const unsigned h_idx)
195 mln_assertion(args.is_node_at_level[h_idx]);
197 while (!args.hqueues[h_idx].empty())
199 mln_psite(I) p = args.hqueues[h_idx].pop_front();
200 unsigned p_idx = args.vset.index_of(args.f(p));
204 mln_psite(I) pext = args.extend(p);
205 args.parent(pext) = args.node_at_level[h_idx];
208 args.parent(p) = args.node_at_level[h_idx];
211 if (!args.is_node_at_level[p_idx])
213 args.is_node_at_level[p_idx] =
true;
214 args.node_at_level[p_idx] = p;
221 if (!args.f.domain().has(args.node_at_level[p_idx]) ||
224 args.parent(args.node_at_level[p_idx]) = p;
225 args.node_at_level[p_idx] = p;
228 args.parent(p) = args.node_at_level[p_idx];
233 mln_niter(N) n(args.nbh, p);
235 if (args.f.domain().has(n) && !args.deja_vu(n))
237 unsigned mn = args.vset.index_of(args.m(n));
238 unsigned fn = args.vset.index_of(args.f(n));
239 args.hqueues[mn].push(n);
240 args.deja_vu(n) =
true;
242 mln_psite(I) ext = args.extend(n);
245 mln_psite(I) node = (fn == mn) ? n : ext;
246 if (!args.is_node_at_level[mn])
248 args.is_node_at_level[mn] =
true;
249 args.node_at_level[mn] = node;
254 mn = flood(args, mn);
259 args.is_node_at_level[h_idx] =
false;
261 while (c > 0 && !args.is_node_at_level[c])
264 mln_psite(I) x = args.node_at_level[h_idx];
266 args.parent(x) = args.node_at_level[c];
273 template <typename I, typename N>
275 data< I, p_array<mln_psite(I)> >
276 dual_hqueue(const Image<I>& f_,
278 const Neighborhood<N>& neibh_)
280 trace::entering(
"mln::morpho::tree::impl::dual_hqueue");
282 const I& f = exact(f_);
283 const I& m = exact(m_);
284 const N& nbh = exact(neibh_);
286 typedef mln_psite(I) P;
287 typedef p_array<mln_psite(I)> S;
295 const histo::array<mln_value(I)> histo = internal::compute_histo(f, m, hmin, pmin);
296 util::hqueues<P, mln_value(I)> hqueues(histo);
298 mln_psite(I)::delta dp(literal::zero);
299 mln_domain(I) d_ext = f.domain();
300 mln_domain(I) d = f.domain();
303 dp[0] = d.pmax()[0] - d.pmin()[0] + 1;
309 mln_concrete(I) fext;
310 mln_ch_value(I, P) parent;
311 p_array<mln_psite(I)> s;
314 fext = geom::translate(m, dp.to_vec(), f, d);
315 initialize(parent, fext);
316 s.reserve(geom::nsites(fext));
319 internal::extend<I> extend(dp);
320 internal::shared_flood_args< I, N, internal::extend<I> >
321 args(f, m, nbh, parent, hqueues, extend);
323 unsigned r = args.vset.index_of(hmin);
324 args.deja_vu(pmin) = true;
325 args.hqueues[r].push(pmin);
326 args.node_at_level[r] = (f(pmin) == hmin) ? pmin : extend(pmin);
327 args.is_node_at_level[r] = true;
334 if (args.is_node_at_level[i])
336 parent(args.node_at_level[r]) = args.node_at_level[i];
341 parent(args.node_at_level[r]) = args.node_at_level[r];
345 mln_ch_value(I,
bool) deja_vu(d_ext);
346 mln::
data::fill(deja_vu, false);
348 p_array<mln_psite(I)> s_f = mln::
data::sort_psites_increasing(f);
349 mln_fwd_piter(S) p(s_f);
360 mln_assertion(!(d_ext.has(q) && fext(p) == fext(q) && d_ext.has(parent(q)) && q != parent(q)));
362 while (d_ext.has(q) && !deja_vu(q) && (fext(q) != fext(parent(q)) || q == parent(q)))
370 if (d_ext.has(q) && fext(q) == fext(parent(q)) && q != parent(q))
372 q = (parent(x) = parent(q));
373 mln_assertion(f.domain().has(q));
376 if (fext(q) == fext(parent(q)))
377 parent(x) = parent(q);
381 mln_assertion((q = parent(p)) == parent(q) || fext(q) != fext(parent(q)));
386 std::cout <<
"Construction de l'arbre en " << tm <<
" s." << std::endl;
390 trace::exiting(
"mln::morpho::tree::impl::dual_hqueue");
397 # endif // ! MLN_INCLUDE_ONLY
405 #endif // !MLN_MORPHO_TREE_COMPUTE_PARENT_DUAL_HQUEUE_HH