27 #ifndef SCRIBO_CORE_OBJECT_GROUPS_HH
28 # define SCRIBO_CORE_OBJECT_GROUPS_HH
34 # include <mln/util/array.hh>
36 # include <scribo/core/object_links.hh>
37 # include <scribo/core/component_set.hh>
39 # include <scribo/core/group_info.hh>
40 # include <scribo/core/internal/sort_comp_ids.hh>
41 # include <scribo/core/concept/serializable.hh>
53 template <
typename L>
class object_groups;
65 return parent(x) =
find_root(parent, parent(x));
109 bool is_valid()
const;
113 unsigned nelements()
const;
117 const group_info& group_of(
unsigned comp_id)
const;
122 const group_info& operator()(
unsigned group_id)
const;
128 void merge(
unsigned group_id_from,
unsigned group_id_to);
138 template <
typename L>
140 operator<<(std::ostream& ostr, const object_groups<L>& groups);
142 template <
typename L>
147 # ifndef MLN_INCLUDE_ONLY
154 template <
typename L>
155 object_groups_data<L>::object_groups_data()
160 template <
typename L>
161 object_groups_data<L>::object_groups_data(
const object_links<L>& links)
162 : comp_to_group_(
unsigned(links.nelements())),
163 components_(links.
components()), links_(links)
165 comp_to_group_ = links.comp_to_link();
167 unsigned ngroups = 0;
177 for_all_elements(e, comp_to_group_)
178 if (comp_to_group_(e) != e && comp_to_group_(e) != 0)
183 while (comp_to_group_(cur) != cur && !deja_vu(comp_to_group_(cur)))
185 cur = comp_to_group_(cur);
189 if (comp_to_group_(cur) != cur && deja_vu(comp_to_group_(cur)))
190 comp_to_group_(cur) = cur;
194 for_all_elements(e, comp_to_group_)
195 if (comp_to_group_(e) != 0)
199 unsigned e_root = internal::find_root(comp_to_group_, e);
201 if (! new_id(e_root))
203 new_id(e_root) = ++ngroups;
204 comp_ids.resize(comp_ids.size() + 1);
205 bboxes.resize(bboxes.size() + 1);
206 pixel_areas.resize(pixel_areas.size() + 1, 0);
209 unsigned nid = new_id(e_root);
210 comp_ids(nid).append(e);
212 bboxes(nid).take(components_(e).
bbox());
213 pixel_areas(nid) += components_(e).card();
216 group_info_.resize(1);
217 group_info_.reserve(ngroups);
220 for (
unsigned i = 1; i < new_id.nelements(); ++i)
223 unsigned id = new_id(i);
227 std::sort(comp_ids(
id).hook_std_vector_().begin(),
228 comp_ids(
id).hook_std_vector_().end(),
229 internal::sort_comp_ids<L>(components_));
231 group_idx(
id) = group_info_.size();
232 group_info_.append(group_info(group_info_.size(), comp_ids(
id), pixel_areas(
id), bboxes(
id)));
238 for (
unsigned i = 0; i < comp_to_group_.nelements(); ++i)
239 comp_to_group_(i) = group_idx(new_id(comp_to_group_(i)));
242 template <
typename L>
243 object_groups_data<L>::object_groups_data(
const object_links<L>& links,
246 components_(links.
components()), links_(links)
248 for_all_groups(g, group_info_)
249 for_all_elements(e, group_info_(g).component_ids())
250 comp_to_group_(group_info_(g).component_ids()(e)) = group_info_(g).
id();
256 template <typename L>
257 object_groups<L>::object_groups()
261 template <
typename L>
262 object_groups<L>::object_groups(
const object_links<L>& links)
264 data_ =
new data_t(links);
267 template <
typename L>
268 object_groups<L>::object_groups(
const object_links<L>& links,
271 data_ =
new data_t(links, info);
274 template <
typename L>
275 const component_set<L>&
278 return data_->components_;
281 template <
typename L>
282 const object_links<L>&
283 object_groups<L>::links()
const
285 mln_assertion(data_ != 0);
286 return data_->links_;
289 template <
typename L>
291 object_groups<L>::is_valid()
const
293 mln_assertion(data_->components_.nelements() == data_->comp_to_group_.
nelements() - 1);
294 return data_->links_.is_valid();
297 template <
typename L>
299 object_groups<L>::nelements()
const
304 template <
typename L>
308 mln_precondition(comp_id < data_->comp_to_group_.nelements());
309 mln_assertion(data_->group_info_(data_->comp_to_group_(comp_id)).
id()
310 == data_->comp_to_group_(comp_id));
311 return data_->group_info_(data_->comp_to_group_(comp_id));
314 template <
typename L>
318 mln_precondition(comp_id < data_->comp_to_group_.nelements());
319 mln_assertion(data_->group_info_(data_->comp_to_group_(comp_id)).
id()
320 == data_->comp_to_group_(comp_id));
321 return data_->group_info_(data_->comp_to_group_(comp_id));
324 template <
typename L>
326 object_groups<L>::comp_to_group()
const
328 return data_->comp_to_group_;
332 template <
typename L>
334 object_groups<L>::merge(
unsigned group_id_from,
unsigned group_id_to)
338 comp_ids = data_->group_info_(group_id_from).component_ids();
339 for_all_elements(e, comp_ids)
340 data_->comp_to_group_(comp_ids(e)) = group_id_to;
343 data_->group_info_(group_id_to).merge(data_->group_info_(group_id_from));
347 template <typename L>
349 object_groups<L>::operator()(
unsigned group_id)
const
351 mln_precondition(group_id < data_->group_info_.nelements());
352 return data_->group_info_(group_id);
356 template <
typename L>
360 mln_precondition(group_id < data_->group_info_.nelements());
361 return data_->group_info_(group_id);
365 template <
typename L>
370 object_groups<L> output;
371 output.data_ =
new data_t();
373 *(output.data_.ptr_) = *(data_.
ptr_);
377 template <
typename L>
379 operator<<(std::ostream& ostr, const object_groups<L>& groups)
381 ostr <<
"object_groups[";
383 for_all_groups(g, groups)
384 ostr << groups(g) << ", ";
386 ostr << " | comp_to_group=" << groups.comp_to_group();
394 template <typename L>
396 operator==(const object_groups<L>& lhs, const object_groups<L>& rhs)
398 if (! (lhs.components() == rhs.components()))
403 if (!( lhs.comp_to_group() == rhs.comp_to_group() && lhs.nelements() == rhs.nelements()))
409 for_all_groups(g, lhs)
410 if (! (lhs(g) == rhs(g)))
418 # endif // ! MLN_INCLUDE_ONLY
424 #endif // ! SCRIBO_CORE_OBJECT_GROUPS_HH