svg2gcode/svg/svg.py

changeset 3
a519e3ac3849
parent 2
660ce16822a9
child 12
a90b8113be25
--- a/svg2gcode/svg/svg.py	Sat Nov 07 13:33:12 2015 +0100
+++ b/svg2gcode/svg/svg.py	Sat Nov 07 13:35:32 2015 +0100
@@ -32,6 +32,7 @@
 # Regex commonly used
 number_re = r'[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?'
 unit_re = r'em|ex|px|in|cm|mm|pt|pc|%'
+point_re = r'(?:\d+(?:\.\d*)?|\.\d+),(?:\d+(?:\.\d*)?|\.\d+)'
 
 # Unit converter
 unit_convert = {
@@ -498,6 +499,72 @@
 
         return ret
 
+
+class Polygon(Transformable):
+    '''SVG <polygon>'''
+    # class Path handles the <polygon> tag
+    tag = 'polygon'
+
+    def __init__(self, elt=None):
+        Transformable.__init__(self, elt)
+        if elt is not None:
+            self.style = elt.get('style')
+            self.parse(elt.get('points'))
+
+    def parse(self, pathstr):
+        """Parse path string and build elements list"""
+
+        pathlst = re.findall(point_re, pathstr)
+
+        #pathlst.reverse()
+
+        current_pt = None
+        start_pt = None
+        while pathlst:
+            coord = pathlst.pop().split(",")
+            pt = Point(coord[0], coord[1])
+
+            if start_pt:
+                current_pt = pt
+                l = Segment(start_pt, current_pt)
+                self.items.append(l)
+                start_pt = current_pt
+            else:
+                start_pt = pt
+                self.items.append(MoveTo(pt))
+
+    def __str__(self):
+        return '\n'.join(str(x) for x in self.items)
+
+    def __repr__(self):
+        return '<Polygon ' + self.id + '>'
+
+    def segments(self, precision=0):
+        '''Return a list of segments, each segment is ended by a MoveTo.
+           A segment is a list of Points'''
+        ret = []
+        # group items separated by MoveTo
+        for moveTo, group in itertools.groupby(self.items,
+                lambda x: isinstance(x, MoveTo)):
+            # Use only non MoveTo item
+            if not moveTo:
+                # Generate segments for each relevant item
+                seg = [x.segments(precision) for x in group]
+                # Merge all segments into one
+                ret.append(list(itertools.chain.from_iterable(seg)))
+
+        return ret
+
+    def simplify(self, precision):
+        '''Simplify segment with precision:
+           Remove any point which are ~aligned'''
+        ret = []
+        for seg in self.segments(precision):
+            ret.append(simplify_segment(seg, precision))
+
+        return ret
+
+
 class Ellipse(Transformable):
     '''SVG <ellipse>'''
     # class Ellipse handles the <ellipse> tag

mercurial