$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r60640 - sandbox/geometry/boost/geometry/algorithms
From: barend.gehrels_at_[hidden]
Date: 2010-03-16 06:59:26
Author: barendgehrels
Date: 2010-03-16 06:59:25 EDT (Tue, 16 Mar 2010)
New Revision: 60640
URL: http://svn.boost.org/trac/boost/changeset/60640
Log:
Updated monotonic sections, splitted sectionalize_range to sectionalize_part to be able to create sections on-the-fly 
Text files modified: 
   sandbox/geometry/boost/geometry/algorithms/sectionalize.hpp |   111 +++++++++++++++++++++++++++------------ 
   1 files changed, 76 insertions(+), 35 deletions(-)
Modified: sandbox/geometry/boost/geometry/algorithms/sectionalize.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/sectionalize.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/sectionalize.hpp	2010-03-16 06:59:25 EDT (Tue, 16 Mar 2010)
@@ -74,7 +74,6 @@
     bool duplicate;
     int non_duplicate_index;
 
-
     inline section()
         : id(-1)
         , ring_index(-99)
@@ -110,7 +109,8 @@
 
 
 #ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace sectionalize {
+namespace detail { namespace sectionalize 
+{
 
 template <typename Segment, std::size_t Dimension, std::size_t DimensionCount>
 struct get_direction_loop
@@ -247,7 +247,7 @@
     }
 };
 
-
+/// @brief Helper class to create sections of a part of a range, on the fly
 template
 <
     typename Range,
@@ -256,61 +256,59 @@
     std::size_t DimensionCount,
     std::size_t MaxCount
 >
-struct sectionalize_range
+struct sectionalize_part
 {
-    static inline void apply(Range const& range, Sections& sections,
+    typedef geometry::segment<Point const> segment_type;
+    typedef typename boost::range_value<Sections>::type section_type;
+    typedef typename boost::range_iterator<Range const>::type iterator_type;
+
+    static inline void apply(Sections& sections, section_type& section,
+                std::size_t& index, int& ndi, 
+                Range const& range, 
                 int ring_index = -1, int multi_index = -1)
     {
-        typedef segment<const Point> segment_type;
 
         std::size_t const n = boost::size(range);
-        if (n == 0)
+        if (n <= index + 1)
         {
-            // Zero points, no section
+            // Zero points, or only one point
+            // -> no section can be generated
             return;
         }
 
-        if (n == 1)
+        if (index == 0)
         {
-            // Line with one point ==> no sections
-            return;
+            ndi = 0;
         }
 
-        int i = 0;
-        int ndi = 0; // non duplicate index
-
-        typedef typename boost::range_value<Sections>::type sections_range_type;
-        sections_range_type section;
-
-        typedef typename boost::range_const_iterator<Range>::type iterator_type;
         iterator_type it = boost::begin(range);
+        it += index;
 
         for(iterator_type previous = it++;
             it != boost::end(range);
-            previous = it++, i++)
+            previous = it++, index++)
         {
-            segment_type s(*previous, *it);
+            segment_type segment(*previous, *it);
 
             int direction_classes[DimensionCount] = {0};
             get_direction_loop
                 <
                     segment_type, 0, DimensionCount
-                >::apply(s, direction_classes);
+                >::apply(segment, direction_classes);
 
             // if "dir" == 0 for all point-dimensions, it is duplicate.
             // Those sections might be omitted, if wished, lateron
-            bool check_duplicate = true; //?
             bool duplicate = false;
 
-            if (check_duplicate && direction_classes[0] == 0)
+            if (direction_classes[0] == 0)
             {
-                // Recheck because all dimensions should be checked,
-                // not only first one,
-                // Note that DimensionCount might be < dimension<P>::value
+                // Recheck because ALL dimensions should be checked,
+                // not only first one.
+                // (DimensionCount might be < dimension<P>::value)
                 if (check_duplicate_loop
                     <
                         segment_type, 0, geometry::dimension<Point>::type::value
-                    >::apply(s)
+                    >::apply(segment)
                     )
                 {
                     duplicate = true;
@@ -336,12 +334,12 @@
                 )
             {
                 sections.push_back(section);
-                section = sections_range_type();
+                section = section_type();
             }
 
             if (section.count == 0)
             {
-                section.begin_index = i;
+                section.begin_index = index;
                 section.ring_index = ring_index;
                 section.multi_index = multi_index;
                 section.duplicate = duplicate;
@@ -356,14 +354,59 @@
             }
 
             geometry::combine(section.bounding_box, *it);
-            section.end_index = i + 1;
+            section.end_index = index + 1;
             section.count++;
             if (! duplicate)
             {
                 ndi++;
             }
         }
+    }
+};
+
 
+template
+<
+    typename Range,
+    typename Point,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize_range
+{
+    static inline void apply(Range const& range, Sections& sections,
+                int ring_index = -1, int multi_index = -1)
+    {
+        typedef segment<const Point> segment_type;
+
+        std::size_t const n = boost::size(range);
+        if (n == 0)
+        {
+            // Zero points, no section
+            return;
+        }
+
+        if (n == 1)
+        {
+            // Line with one point ==> no sections
+            return;
+        }
+
+        std::size_t index = 0;
+        int ndi = 0; // non duplicate index
+
+        typedef typename boost::range_value<Sections>::type section_type;
+        section_type section;
+
+        sectionalize_part
+            <
+                Range, Point, Sections,
+                DimensionCount, MaxCount
+            >::apply(sections, section, index, ndi, 
+                        range, ring_index, multi_index);
+
+        // Add last section if applicable
         if (section.count > 0)
         {
             sections.push_back(section);
@@ -390,9 +433,9 @@
                 ring_type, point_type, Sections, DimensionCount, MaxCount
             > sectionalizer_type;
 
-        typedef typename boost::range_const_iterator
+        typedef typename boost::range_iterator
             <
-            typename interior_type<Polygon>::type
+                typename interior_type<Polygon>::type const
             >::type iterator_type;
 
         sectionalizer_type::apply(exterior_ring(poly), sections, -1, multi_index);
@@ -583,9 +626,7 @@
 }
 
 
-
-
-
 }} // namespace boost::geometry
 
+
 #endif // BOOST_GEOMETRY_ALGORITHMS_SECTIONALIZE_HPP