* filter/all.hh: Add new includes. * filter/object_links_non_aligned.hh, * filter/object_links_non_h_aligned.hh, * filter/object_links_non_v_aligned.hh: New filters. * src/text/grouping/group_from_double_link_filter_non_aligned.cc: New example. * headers.mk, * tests/unit_test/unit-tests.mk: Regen. --- scribo/ChangeLog | 16 ++ scribo/filter/all.hh | 3 + scribo/filter/object_links_non_aligned.hh | 136 ++++++++++++++++ scribo/filter/object_links_non_h_aligned.hh | 109 +++++++++++++ scribo/filter/object_links_non_v_aligned.hh | 122 +++++++++++++++ scribo/headers.mk | 18 +- .../group_from_double_link_filter_non_aligned.cc | 165 ++++++++++++++++++++ scribo/tests/unit_test/unit-tests.mk | 36 ++-- 8 files changed, 578 insertions(+), 27 deletions(-) create mode 100644 scribo/filter/object_links_non_aligned.hh create mode 100644 scribo/filter/object_links_non_h_aligned.hh create mode 100644 scribo/filter/object_links_non_v_aligned.hh create mode 100644 scribo/src/text/grouping/group_from_double_link_filter_non_aligned.cc diff --git a/scribo/ChangeLog b/scribo/ChangeLog index a7cd378..69af059 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,5 +1,21 @@ 2009-08-25 Guillaume Lazzara <lazzara@lrde.epita.fr> + Add new filters. + + * filter/all.hh: Add new includes. + + * filter/object_links_non_aligned.hh, + * filter/object_links_non_h_aligned.hh, + * filter/object_links_non_v_aligned.hh: New filters. + + * src/text/grouping/group_from_double_link_filter_non_aligned.cc: + New example. + + * headers.mk, + * tests/unit_test/unit-tests.mk: Regen. + +2009-08-25 Guillaume Lazzara <lazzara@lrde.epita.fr> + Rename filters. * filter/all.hh: Update includes. diff --git a/scribo/filter/all.hh b/scribo/filter/all.hh index 0b5bc11..f9ef9ce 100644 --- a/scribo/filter/all.hh +++ b/scribo/filter/all.hh @@ -42,6 +42,9 @@ namespace scribo } // end of namespace scribo # include <scribo/filter/object_groups_small.hh> +# include <scribo/filter/object_links_non_aligned.hh> +# include <scribo/filter/object_links_non_h_aligned.hh> +# include <scribo/filter/object_links_non_v_aligned.hh> # include <scribo/filter/objects_large.hh> # include <scribo/filter/objects_small.hh> # include <scribo/filter/objects_thick.hh> diff --git a/scribo/filter/object_links_non_aligned.hh b/scribo/filter/object_links_non_aligned.hh new file mode 100644 index 0000000..46a425e --- /dev/null +++ b/scribo/filter/object_links_non_aligned.hh @@ -0,0 +1,136 @@ +// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef SCRIBO_FILTER_OBJECT_LINKS_NON_ALIGNED_HH +# define SCRIBO_FILTER_OBJECT_LINKS_NON_ALIGNED_HH + +/// \file +/// +/// Invalidate links between two non aligned objects. + + +# include <mln/util/array.hh> + +# include <scribo/core/macros.hh> +# include <scribo/core/object_links.hh> +# include <scribo/core/object_image.hh> + +namespace scribo +{ + + namespace filter + { + + using namespace mln; + + /*! \brief Invalidate links between two non aligned objects. + Alignment is based on object bounding boxes. + + \param[in] objects An object image. + \param[in] links Object links information. + \param[in] dim Choose the dimension on which applying the + filter. + \param[in] max_delta Maximum delta. + + + Exemple with dim == 1 (horizontal filter): + + \verbatim + v + ------ ~ ~ ~ + | | |\ + ------ ~ ~ ~ |~ ~ | ~ ~ ~ \ + | | | | ^ \ + | x------------x | => delta, must be < to max_delta + | | | | v / + ------ ~ ~ ~ |~ ~ | ~ ~ ~ / + object1 | | |/ + ------ ~ ~ ~ + object2 ^ + + \endverbatim + + */ + template <typename L> + object_links<L> + object_links_non_aligned(const object_image(L)& objects, + const object_links<L>& links, + unsigned dim, + unsigned max_delta); + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename L> + object_links<L> + object_links_non_aligned(const object_image(L)& objects, + const object_links<L>& links, + unsigned dim, + unsigned max_delta) + { + trace::entering("scribo::filter::object_links_non_aligned"); + + mln_precondition(objects.is_valid()); + + + typedef typename object_image(L)::bbox_t bbox_t; + const mln::util::array<bbox_t>& bboxes = objects.bboxes(); + object_links<L> output(links); + + for_all_components(i, objects.bboxes()) + { + + unsigned + lnbh = bboxes(links[i]).pmax()[dim] - bboxes(links[i]).pmin()[dim], + lcurrent = bboxes(i).pmax()[dim] - bboxes(i).pmin()[dim], + hmin = i, + hmax = links[i]; + + if (lnbh < lcurrent) + { + hmin = links[i]; + hmax = i; + } + + if ((bboxes[hmin].pmin()[dim] - (float)bboxes[hmax].pmin()[dim]) > max_delta + || (bboxes[hmin].pmax()[dim] - (float) bboxes[hmax].pmax()[dim]) > max_delta) + output[i] = i; + } + + trace::exiting("scribo::filter::object_links_non_aligned"); + return output; + } + + +# endif // ! MLN_INCLUDE_ONLY + + + } // end of namespace scribo::filter + +} // end of namespace scribo + + +#endif // ! SCRIBO_FILTER_OBJECT_LINKS_NON_ALIGNED_HH diff --git a/scribo/filter/object_links_non_h_aligned.hh b/scribo/filter/object_links_non_h_aligned.hh new file mode 100644 index 0000000..cae84a9 --- /dev/null +++ b/scribo/filter/object_links_non_h_aligned.hh @@ -0,0 +1,109 @@ +// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef SCRIBO_FILTER_OBJECT_LINKS_NON_H_ALIGNED_HH +# define SCRIBO_FILTER_OBJECT_LINKS_NON_H_ALIGNED_HH + +/// \file +/// +/// Invalidate links between two non horizontaly aligned objects. + + +# include <mln/util/array.hh> + +# include <scribo/core/object_links.hh> +# include <scribo/core/object_image.hh> +# include <scribo/filter/object_links_non_aligned.hh> + +namespace scribo +{ + + namespace filter + { + + using namespace mln; + + + /*! \brief Invalidate links between two non horizontaly aligned objects. + Alignment is based on object bounding boxes. + + \param[in] objects An object image. + \param[in] links Object links information. + \param[in] max_delta Maximum delta. + + \result Filtered object links data. + + \verbatim + v + ------ ~ ~ ~ + | | |\ + ------ ~ ~ ~ |~ ~ | ~ ~ ~ \ + | | | | ^ \ + | x- - - - - --x | => delta, must be < to max_delta + | | | | v / + ------ ~ ~ ~ |~ ~ | ~ ~ ~ / + object1 | | |/ + ------ ~ ~ ~ + object2 ^ + + \endverbatim + + + */ + template <typename L> + object_links<L> + object_links_non_h_aligned(const object_image(L)& objects, + const object_links<L>& links, + float ratio); + +# ifndef MLN_INCLUDE_ONLY + + + template <typename L> + object_links<L> + object_links_non_h_aligned(const object_image(L)& objects, + const object_links<L>& links, + float ratio) + { + trace::entering("scribo::filter::object_links_non_h_aligned"); + + mln_precondition(objects.is_valid()); + + object_links<L> + output = object_links_non_aligned(objects, links, 1, ratio); + + trace::exiting("scribo::filter::object_links_non_h_aligned"); + return output; + } + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace scribo::filter + +} // end of namespace scribo + + +#endif // ! SCRIBO_FILTER_OBJECT_LINKS_NON_H_ALIGNED_HH diff --git a/scribo/filter/object_links_non_v_aligned.hh b/scribo/filter/object_links_non_v_aligned.hh new file mode 100644 index 0000000..bd2aeee --- /dev/null +++ b/scribo/filter/object_links_non_v_aligned.hh @@ -0,0 +1,122 @@ +// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#ifndef SCRIBO_FILTER_OBJECT_LINKS_NON_V_ALIGNED_HH +# define SCRIBO_FILTER_OBJECT_LINKS_NON_V_ALIGNED_HH + +/// \file +/// +/// Invalidate links between two non verticaly aligned objects. + + +# include <mln/util/array.hh> + +# include <scribo/core/object_links.hh> +# include <scribo/core/object_image.hh> +# include <scribo/filter/object_links_non_aligned.hh> + +namespace scribo +{ + + namespace filter + { + + using namespace mln; + + /*! \brief Invalidate links between two non verticaly aligned objects. + Alignment is based on object bounding boxes. + + \param[in] objects An object image. + \param[in] links Object links information. + \param[in] max_delta Maximum delta. + + + \verbatim + + delta (must be < to max_delta) + /\ + / \ + / \ + >:-:<>:-:< + : : + : : + : ---:-- + | | + : | x: | object1 + | | | + : --|:-- + + : |: + + : |: + -- --- + | || + | | + | || + | x| object2 + | | + | | + | | + ------ + + \endverbatim + + */ + template <typename L> + object_links<L> + object_links_non_v_aligned(const object_image(L)& objects, + const object_links<L>& links, + float ratio); + +# ifndef MLN_INCLUDE_ONLY + + + template <typename L> + object_links<L> + object_links_non_v_aligned(const object_image(L)& objects, + const object_links<L>& links, + float ratio) + { + trace::entering("scribo::object_links::object_links_non_v_aligned"); + + mln_precondition(objects.is_valid()); + + object_links<L> + output = object_links_non_aligned(objects, links, 0, ratio); + + trace::exiting("scribo::filter::object_links_non_v_aligned"); + return output; + } + + +# endif // ! MLN_INCLUDE_ONLY + + + } // end of namespace scribo::filter + +} // end of namespace scribo + + +#endif // ! SCRIBO_FILTER_OBJECT_LINKS_NON_V_ALIGNED_HH diff --git a/scribo/headers.mk b/scribo/headers.mk index c266c78..8ca14cf 100644 --- a/scribo/headers.mk +++ b/scribo/headers.mk @@ -21,12 +21,15 @@ nobase_scribo_HEADERS = \ ./draw/bounding_box_links.hh \ ./draw/bounding_boxes.hh \ ./filter/all.hh \ -./filter/large_objects.hh \ -./filter/small_object_groups.hh \ -./filter/small_objects.hh \ -./filter/thick_objects.hh \ -./filter/thin_objects.hh \ -./fun/v2b/small_objects_filter.hh \ +./filter/object_groups_small.hh \ +./filter/object_links_non_aligned.hh \ +./filter/object_links_non_h_aligned.hh \ +./filter/object_links_non_v_aligned.hh \ +./filter/objects_large.hh \ +./filter/objects_small.hh \ +./filter/objects_thick.hh \ +./filter/objects_thin.hh \ +./fun/v2b/objects_small_filter.hh \ ./make/all.hh \ ./make/debug_filename.hh \ ./make/influence_zone_graph.hh \ @@ -51,9 +54,6 @@ nobase_scribo_HEADERS = \ ./primitive/extract/objects.hh \ ./primitive/group/all.hh \ ./primitive/group/apply.hh \ -./primitive/group/filter_non_aligned.hh \ -./primitive/group/filter_non_h_aligned.hh \ -./primitive/group/filter_non_v_aligned.hh \ ./primitive/group/from_double_link.hh \ ./primitive/group/from_graph.hh \ ./primitive/group/from_single_link.hh \ diff --git a/scribo/src/text/grouping/group_from_double_link_filter_non_aligned.cc b/scribo/src/text/grouping/group_from_double_link_filter_non_aligned.cc new file mode 100644 index 0000000..fce389e --- /dev/null +++ b/scribo/src/text/grouping/group_from_double_link_filter_non_aligned.cc @@ -0,0 +1,165 @@ +// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +#include <iostream> + +#include <mln/core/image/image2d.hh> +#include <mln/labeling/colorize.hh> +#include <mln/debug/println.hh> +#include <mln/util/array.hh> +#include <mln/literal/colors.hh> +#include <mln/io/pbm/load.hh> +#include <mln/core/alias/neighb2d.hh> +#include <mln/value/label_16.hh> + +#include <scribo/core/object_image.hh> + +#include <scribo/primitive/extract/objects.hh> +#include <scribo/primitive/link/with_single_left_link.hh> +#include <scribo/primitive/link/with_single_right_link.hh> +#include <scribo/debug/save_linked_bboxes_image.hh> +#include <scribo/primitive/group/from_double_link.hh> +#include <scribo/primitive/group/from_single_link.hh> +#include <scribo/primitive/link/merge_double_link.hh> +#include <scribo/primitive/group/apply.hh> +#include <scribo/filter/objects_small.hh> + +#include <scribo/filter/object_links_non_h_aligned.hh> + +#include <scribo/debug/save_bboxes_image.hh> +#include <scribo/make/debug_filename.hh> + + +#include <scribo/debug/usage.hh> + +const char *args_desc[][2] = +{ + { "input.pbm", "A binary image. 'True' for objects, 'False'\ +for the background." }, + { "hlmax", "Maximum distance between two grouped objects while browsing on the left." }, + { "hrmax", "Maximum distance between two grouped objects while browsing on the right." }, + { "hdelta_max", "Maximum horizontal distance between top/bottom corner of two grouped bboxes." }, + { "prefix", "Output names prefix" }, + {0, 0} +}; + +int main(int argc, char *argv[]) +{ + using namespace scribo; + using namespace mln; + + if (argc != 6) + return scribo::debug::usage(argv, + "Group potential text objects using a double validation link.", + "input.pbm hlmax hrmax hdelta_max prefix", + args_desc, + "Several images showing the process."); + + + scribo::make::internal::debug_filename_prefix = argv[5]; + + image2d<bool> input; + io::pbm::load(input, argv[1]); + + value::label_16 nbboxes; + typedef image2d<value::label_16> L; + typedef object_image(L) text_t; + + text_t text = primitive::extract::objects(input, c8(), nbboxes); + + text = filter::objects_small(text, 4); + + object_links<L> left_link + = primitive::link::with_single_left_link(text, atoi(argv[2])); + object_links<L> right_link + = primitive::link::with_single_right_link(text, atoi(argv[3])); + + std::cout << "BEFORE - nbboxes = " << nbboxes << std::endl; + +// scribo::debug::save_linked_textbboxes_image(input, +// text, left_link, +// literal::red, literal::cyan, +// scribo::make::debug_filename("left_linked.ppm")); +// scribo::debug::save_linked_textbboxes_image(input, +// text, right_link, +// literal::red, literal::cyan, +// scribo::make::debug_filename("right_linked.ppm")); + + scribo::debug::save_linked_bboxes_image(input, + text, left_link, right_link, + literal::red, literal::cyan, literal::yellow, + literal::green, + scribo::make::debug_filename("links.ppm")); + + // With validation. + object_links<L> double_link + = primitive::link::merge_double_link(text, + left_link, + right_link); + + + text_t + grouped_text = primitive::group::apply(text, double_link); + std::cout << "AFTER double grouping - nbboxes = " + << grouped_text.bboxes().nelements() << std::endl; + + + io::ppm::save(mln::labeling::colorize(value::rgb8(), + grouped_text, + grouped_text.nlabels()), + scribo::make::debug_filename("label_color.ppm")); + + + scribo::debug::save_bboxes_image(input, grouped_text.bboxes(), + literal::red, + scribo::make::debug_filename("bboxes.ppm")); + + + + // Filter non-correctly aligned grouped objects. + + object_links<L> filtered_links + = filter::object_links_non_h_aligned(text, double_link, atoi(argv[4])); + + + text_t aligned_grouped_text + = primitive::group::apply(text, filtered_links); + + + std::cout << "AFTER filtering - Links may have been canceled - nbboxes = " + << aligned_grouped_text.bboxes().nelements() << std::endl; + + + io::ppm::save(mln::labeling::colorize(value::rgb8(), + aligned_grouped_text, + aligned_grouped_text.nlabels()), + scribo::make::debug_filename("label_color-filtered.ppm")); + + + scribo::debug::save_bboxes_image(input, aligned_grouped_text.bboxes(), + literal::red, + scribo::make::debug_filename("bboxes-filtered.ppm")); + +} diff --git a/scribo/tests/unit_test/unit-tests.mk b/scribo/tests/unit_test/unit-tests.mk index 237581f..89c72d9 100644 --- a/scribo/tests/unit_test/unit-tests.mk +++ b/scribo/tests/unit_test/unit-tests.mk @@ -20,12 +20,15 @@ scribo_draw_all \ scribo_draw_bounding_box_links \ scribo_draw_bounding_boxes \ scribo_filter_all \ -scribo_filter_large_objects \ -scribo_filter_small_object_groups \ -scribo_filter_small_objects \ -scribo_filter_thick_objects \ -scribo_filter_thin_objects \ -scribo_fun_v2b_small_objects_filter \ +scribo_filter_object_groups_small \ +scribo_filter_object_links_non_aligned \ +scribo_filter_object_links_non_h_aligned \ +scribo_filter_object_links_non_v_aligned \ +scribo_filter_objects_large \ +scribo_filter_objects_small \ +scribo_filter_objects_thick \ +scribo_filter_objects_thin \ +scribo_fun_v2b_objects_small_filter \ scribo_make_all \ scribo_make_debug_filename \ scribo_make_influence_zone_graph \ @@ -50,9 +53,6 @@ scribo_primitive_extract_lines_v_thick \ scribo_primitive_extract_objects \ scribo_primitive_group_all \ scribo_primitive_group_apply \ -scribo_primitive_group_filter_non_aligned \ -scribo_primitive_group_filter_non_h_aligned \ -scribo_primitive_group_filter_non_v_aligned \ scribo_primitive_group_from_double_link \ scribo_primitive_group_from_graph \ scribo_primitive_group_from_single_link \ @@ -114,12 +114,15 @@ scribo_draw_all_SOURCES = scribo_draw_all.cc scribo_draw_bounding_box_links_SOURCES = scribo_draw_bounding_box_links.cc scribo_draw_bounding_boxes_SOURCES = scribo_draw_bounding_boxes.cc scribo_filter_all_SOURCES = scribo_filter_all.cc -scribo_filter_large_objects_SOURCES = scribo_filter_large_objects.cc -scribo_filter_small_object_groups_SOURCES = scribo_filter_small_object_groups.cc -scribo_filter_small_objects_SOURCES = scribo_filter_small_objects.cc -scribo_filter_thick_objects_SOURCES = scribo_filter_thick_objects.cc -scribo_filter_thin_objects_SOURCES = scribo_filter_thin_objects.cc -scribo_fun_v2b_small_objects_filter_SOURCES = scribo_fun_v2b_small_objects_filter.cc +scribo_filter_object_groups_small_SOURCES = scribo_filter_object_groups_small.cc +scribo_filter_object_links_non_aligned_SOURCES = scribo_filter_object_links_non_aligned.cc +scribo_filter_object_links_non_h_aligned_SOURCES = scribo_filter_object_links_non_h_aligned.cc +scribo_filter_object_links_non_v_aligned_SOURCES = scribo_filter_object_links_non_v_aligned.cc +scribo_filter_objects_large_SOURCES = scribo_filter_objects_large.cc +scribo_filter_objects_small_SOURCES = scribo_filter_objects_small.cc +scribo_filter_objects_thick_SOURCES = scribo_filter_objects_thick.cc +scribo_filter_objects_thin_SOURCES = scribo_filter_objects_thin.cc +scribo_fun_v2b_objects_small_filter_SOURCES = scribo_fun_v2b_objects_small_filter.cc scribo_make_all_SOURCES = scribo_make_all.cc scribo_make_debug_filename_SOURCES = scribo_make_debug_filename.cc scribo_make_influence_zone_graph_SOURCES = scribo_make_influence_zone_graph.cc @@ -144,9 +147,6 @@ scribo_primitive_extract_lines_v_thick_SOURCES = scribo_primitive_extract_lines_ scribo_primitive_extract_objects_SOURCES = scribo_primitive_extract_objects.cc scribo_primitive_group_all_SOURCES = scribo_primitive_group_all.cc scribo_primitive_group_apply_SOURCES = scribo_primitive_group_apply.cc -scribo_primitive_group_filter_non_aligned_SOURCES = scribo_primitive_group_filter_non_aligned.cc -scribo_primitive_group_filter_non_h_aligned_SOURCES = scribo_primitive_group_filter_non_h_aligned.cc -scribo_primitive_group_filter_non_v_aligned_SOURCES = scribo_primitive_group_filter_non_v_aligned.cc scribo_primitive_group_from_double_link_SOURCES = scribo_primitive_group_from_double_link.cc scribo_primitive_group_from_graph_SOURCES = scribo_primitive_group_from_graph.cc scribo_primitive_group_from_single_link_SOURCES = scribo_primitive_group_from_single_link.cc -- 1.5.6.5