Пример #1
0
class PathAccumulator(pycam.PathProcessors.BasePathProcessor):
    def __init__(self, zigzag=False, reverse=False):
        super(PathAccumulator, self).__init__()
        self.curr_path = None
        self.zigzag = zigzag
        self.scanline = None
        self.reverse = reverse

    def append(self, point):
        if self.curr_path == None:
            self.curr_path = Path()
        if self.reverse:
            self.curr_path.insert(0, point)
        else:
            self.curr_path.append(point)

    def new_direction(self, direction):
        self.scanline = 0

    def new_scanline(self):
        self.scanline += 1
        if self.curr_path:
            print "ERROR: curr_path expected to be empty"
            self.curr_path = None

    def end_scanline(self):
        if self.curr_path:
            if self.zigzag and (self.scanline % 2 == 0):
                self.curr_path.reverse()
            simplify_toolpath(self.curr_path)
            if self.reverse:
                self.paths.insert(0, self.curr_path)
            else:
                self.paths.append(self.curr_path)
            self.curr_path = None
Пример #2
0
 def copy(self):
     new_paths = []
     for path in self.paths:
         new_path = Path()
         for point in path.points:
             new_path.append(point)
         new_paths.append(new_path)
     return Toolpath(new_paths, parameters=self.get_params())
Пример #3
0
 def copy(self):
     new_paths = []
     for path in self.paths:
         new_path = Path()
         for point in path.points:
             new_path.append(point)
         new_paths.append(new_path)
     return Toolpath(new_paths, parameters=self.get_params())
Пример #4
0
 def finish(self):
     self.polygon_extractor.finish()
     paths = []
     source_paths = []
     if self.polygon_extractor.hor_path_list:
         source_paths.extend(self.polygon_extractor.hor_path_list)
     if self.polygon_extractor.ver_path_list:
         source_paths.extend(self.polygon_extractor.ver_path_list)
     for path in source_paths:
         points = path.points
         for i in range((len(points) + 1) // 2):
             new_path = Path()
             if i % 2 == 0:
                 new_path.append(points[i])
                 new_path.append(points[-i-1])
             else:
                 new_path.append(points[-i-1])
                 new_path.append(points[i])
             paths.append(new_path)
     if paths:
         for path in paths:
             simplify_toolpath(path)
             if self.reverse:
                 path.reverse()
         self.paths.extend(paths)
         self.sort_layered()
Пример #5
0
 def finish(self):
     self.polygon_extractor.finish()
     paths = []
     source_paths = []
     if self.polygon_extractor.hor_path_list:
         source_paths.extend(self.polygon_extractor.hor_path_list)
     if self.polygon_extractor.ver_path_list:
         source_paths.extend(self.polygon_extractor.ver_path_list)
     for path in source_paths:
         points = path.points
         for i in range(0, (len(points)+1)/2):
             new_path = Path()
             if i % 2 == 0:
                 new_path.append(points[i])
                 new_path.append(points[-i-1])
             else:
                 new_path.append(points[-i-1])
                 new_path.append(points[i])
             paths.append(new_path)
     if paths:
         for path in paths:
             simplify_toolpath(path)
             if self.reverse:
                 path.reverse()
         self.paths.extend(paths)
         self.sort_layered()
Пример #6
0
 def append(self, point):
     curr_path = None
     if self.curr_path == None:
         curr_path = Path()
         self.curr_path = curr_path
     else:
         curr_path = self.curr_path
         self.curr_path = None
     curr_path.append(point)
     if self.curr_path == None:
         simplify_toolpath(curr_path)
         if self.reverse:
             curr_path.reverse()
             self.paths.insert(0, curr_path)
         else:
             self.paths.append(curr_path)
Пример #7
0
 def append(self, point):
     curr_path = None
     if self.curr_path == None:
         curr_path = Path()
         self.curr_path = curr_path
     else:
         curr_path = self.curr_path
         self.curr_path = None
     curr_path.append(point)
     if self.curr_path == None:
         simplify_toolpath(curr_path)
         if self.reverse:
             curr_path.reverse()
             self.paths.insert(0, curr_path)
         else:
             self.paths.append(curr_path)
Пример #8
0
    def append(self, point):
        curr_path = None
        if self.curr_path == None:
            curr_path = Path()
            self.curr_path = curr_path
        else:
            curr_path = self.curr_path
            self.curr_path = None

        curr_path.append(point)

        if self.curr_path == None:
            if (self.scanline % 2) == 0:
                self.curr_scanline.append(curr_path)
            else:
                curr_path.reverse()
                self.curr_scanline.insert(0, curr_path)
Пример #9
0
    def append(self, point):
        curr_path = None
        if self.curr_path == None:
            curr_path = Path()
            self.curr_path = curr_path
        else:
            curr_path = self.curr_path
            self.curr_path = None

        curr_path.append(point)

        if self.curr_path == None:
            if (self.scanline % 2) == 0:
                self.curr_scanline.append(curr_path)
            else:
                curr_path.reverse()
                self.curr_scanline.insert(0, curr_path)
Пример #10
0
 def crop(self, polygons, callback=None):
     # collect all existing toolpath lines
     open_lines = []
     for path in self.toolpath:
         if path:
             for index in range(len(path.points) - 1):
                 open_lines.append(Line(path.points[index],
                         path.points[index + 1]))
     # go through all polygons and add "inner" lines (or parts thereof) to
     # the final list of remaining lines
     inner_lines = []
     for polygon in polygons:
         new_open_lines = []
         for line in open_lines:
             if callback and callback():
                 return
             inner, outer = polygon.split_line(line)
             inner_lines.extend(inner)
             new_open_lines.extend(outer)
         open_lines = new_open_lines
     # turn all "inner_lines" into toolpath movements
     new_paths = []
     current_path = Path()
     if inner_lines:
         line = inner_lines.pop(0)
         current_path.append(line.p1)
         current_path.append(line.p2)
     while inner_lines:
         if callback and callback():
             return
         end = current_path.points[-1]
         # look for the next connected point
         for line in inner_lines:
             if line.p1 == end:
                 inner_lines.remove(line)
                 current_path.append(line.p2)
                 break
         else:
             new_paths.append(current_path)
             current_path = Path()
             line = inner_lines.pop(0)
             current_path.append(line.p1)
             current_path.append(line.p2)
     if current_path.points:
         new_paths.append(current_path)
     self.toolpath = new_paths
Пример #11
0
 def crop(self, polygons, callback=None):
     # collect all existing toolpath lines
     open_lines = []
     for path in self.paths:
         if path:
             for index in range(len(path.points) - 1):
                 open_lines.append(
                     Line(path.points[index], path.points[index + 1]))
     # go through all polygons and add "inner" lines (or parts thereof) to
     # the final list of remaining lines
     inner_lines = []
     for polygon in polygons:
         new_open_lines = []
         for line in open_lines:
             if callback and callback():
                 return
             inner, outer = polygon.split_line(line)
             inner_lines.extend(inner)
             new_open_lines.extend(outer)
         open_lines = new_open_lines
     # turn all "inner_lines" into toolpath moves
     new_paths = []
     current_path = Path()
     if inner_lines:
         line = inner_lines.pop(0)
         current_path.append(line.p1)
         current_path.append(line.p2)
     while inner_lines:
         if callback and callback():
             return
         end = current_path.points[-1]
         # look for the next connected point
         for line in inner_lines:
             if line.p1 == end:
                 inner_lines.remove(line)
                 current_path.append(line.p2)
                 break
         else:
             new_paths.append(current_path)
             current_path = Path()
             line = inner_lines.pop(0)
             current_path.append(line.p1)
             current_path.append(line.p2)
     if current_path.points:
         new_paths.append(current_path)
     self.paths = new_paths
Пример #12
0
    def convert_hor_path_list(self):
        if DEBUG_POLYGONEXTRACTOR2:
            print "converting hor paths"
        hor_path_list = []
        for s in self.hor_path_list:
            allsame = True
            miny = s.points[0].y
            maxy = s.points[0].y
            for p in s.points:
                if not p.x == s.points[0].x:
                    allsame = False
                if p.y < miny:
                    miny = p.y
                if p.y > maxy:
                    maxy = p.y
            if allsame:
                if DEBUG_POLYGONEXTRACTOR2:
                    print "all same !"
                s0 = Path()
                for p in s.points:
                    if p.y == miny:
                        s0.append(p)
                hor_path_list.append(s0)
                s1 = Path()
                for p in s.points:
                    if p.y == maxy:
                        s1.append(p)
                hor_path_list.append(s1)
                continue
            prev = s.points[-1]
            p_iter = CyclicIterator(s.points)
            p = s.points[0]
            next_p = p_iter.next()
            while not ((prev.x >= p.x) and (next_p.x > p.x)):
                p = next_p
                next_p = p_iter.next()
            count = 0
            while count < len(s.points):
                s0 = Path()
                while next_p.x >= p.x:
                    s0.append(p)
                    p = next_p
                    next_p = p_iter.next()
                    count += 1
                s0.append(p)
                while (len(s0.points) > 1) \
                        and (s0.points[0].x == s0.points[1].x):
                    s0.points = s0.points[1:]
                while (len(s0.points) > 1) \
                        and (s0.points[-2].x == s0.points[-1].x):
                    s0.points = s0.points[0:-1]

                hor_path_list.append(s0)
                s1 = Path()
                while next_p.x <= p.x:
                    s1.append(p)
                    p = next_p
                    next_p = p_iter.next()
                    count += 1
                s1.append(p)
                s1.reverse()
                while (len(s1.points) > 1) \
                        and (s1.points[0].x == s1.points[1].x):
                    s1.points = s1.points[1:]
                while (len(s1.points) > 1) \
                        and (s1.points[-2].x == s1.points[-1].x):
                    s1.points = s1.points[:-1]
                hor_path_list.append(s1)
        hor_path_list.sort(cmp=lambda a, b: cmp(a.points[0].x, b.points[0].x))
        if DEBUG_POLYGONEXTRACTOR2:
            print "ver_hor_path_list = ", hor_path_list
            for s in hor_path_list:
                print "s%d =" % s.id,
                for point in s.points:
                    print point.id,
                print
        self.ver_hor_path_list = hor_path_list

        self.act_hor_path_list = []
Пример #13
0
    def process_ver_scanline(self, scanline):
        if DEBUG_POLYGONEXTRACTOR3:
            prev = None
            for p in scanline:
                if p.dir == 0:
                    self.cont.fill("red")
                else:
                    self.cont.fill("blue")
                self.cont.AddDot(p.x, p.y)
                self.cont.fill("black")
                self.cont.AddText(p.x, p.y, str(p.id))
                if prev:
                    self.cont.AddLine(prev.x, prev.y, p.x, p.y)
                prev = p

        if DEBUG_POLYGONEXTRACTOR:
            last = 0
            inside = False
            s = ""
            for point in scanline:
                next_y = point.y
                if inside:
                    s += "*" * int(next_y - last)
                else:
                    s += " " * int(next_y - last)
                last = next_y
                inside = not inside
            print s

        if DEBUG_POLYGONEXTRACTOR:
            print "active paths: ",
            for path in self.curr_path_list:
                print "%d(%g,%g)" \
                        % (path.id, path.points[-1].x, path.points[-1].y),
            print

            print "prev points: ",
            for point in self.prev_line:
                print "(%g,%g)" % (point.x, point.y),
            print

            print "active points: ",
            for point in scanline:
                print "%d(%g,%g)" % (point.id, point.x, point.y),
            print

        prev_point = Iterator(self.prev_line)
        curr_point = Iterator(scanline)
        curr_path = Iterator(self.curr_path_list)

        winding = 0
        while (prev_point.remains() > 0) or (curr_point.remains() > 0):
            if DEBUG_POLYGONEXTRACTOR:
                print "num_prev=%d, num_curr=%d" \
                        % (prev_point.remains(), curr_point.remains())
            if (prev_point.remains() == 0) and (curr_point.remains() >= 2):
                c0 = curr_point.next()
                c1 = curr_point.next()
                # new path starts
                p0 = Path()
                p0.winding = winding + 1
                if DEBUG_POLYGONEXTRACTOR:
                    print "new path %d(%g,%g)" % (p0.id, c0.x, c0.y)
                p0.append(c0)
                self.curr_path_list.append(p0)
                p1 = Path()
                p1.winding = winding
                if DEBUG_POLYGONEXTRACTOR:
                    print "new path %d(%g,%g)" % (p1.id, c1.x, c1.y)
                p1.append(c1)
                self.curr_path_list.append(p1)
                p0.top_join = p1
                p1.top_join = p0
                continue

            if (prev_point.remains() >= 2) and (curr_point.remains() == 0):
                #old path ends
                p0 = curr_path.takeNext()
                if DEBUG_POLYGONEXTRACTOR:
                    print "end path %d" % p0.id
                self.all_path_list.append(p0)
                prev_point.next()
                p1 = curr_path.takeNext()
                if DEBUG_POLYGONEXTRACTOR:
                    print "end path %d" % p1.id
                self.all_path_list.append(p1)
                prev_point.next()
                p0.bot_join = p1
                p1.bot_join = p0
                continue

            if (prev_point.remains() >= 2) and (curr_point.remains() >= 2):
                p0 = prev_point.peek(0)
                p1 = prev_point.peek(1)
                c0 = curr_point.peek(0)
                c1 = curr_point.peek(1)

                if DEBUG_POLYGONEXTRACTOR:
                    print "overlap test: p0=%g p1=%g" % (p0.x, p1.x)
                    print "overlap test: c0=%g c1=%g" % (c0.x, c1.x)

                if c1.y < p0.y:
                    # new segment is completely to the left
                    # new path starts
                    s0 = Path()
                    if DEBUG_POLYGONEXTRACTOR:
                        print "new path %d(%g,%g) w=%d" \
                                % (s0.id, c0.x, c0.y, winding + 1)
                    s0.append(c0)
                    curr_path.insert(s0)
                    s1 = Path()
                    s0.winding = winding + 1
                    s1.winding = winding
                    if DEBUG_POLYGONEXTRACTOR:
                        print "new path %d(%g,%g) w=%d" \
                                % (s1.id, c1.x, c1.y, winding)
                    s1.append(c1)
                    curr_path.insert(s1)
                    curr_point.next()
                    curr_point.next()
                    s0.top_join = s1
                    s1.top_join = s0
                elif c0.y > p1.y:
                    # new segment is completely to the right
                    # old path ends
                    s0 = curr_path.takeNext()
                    if DEBUG_POLYGONEXTRACTOR:
                        print "end path %d" % s0.id
                    self.all_path_list.append(s0)
                    prev_point.next()
                    s1 = curr_path.takeNext()
                    if DEBUG_POLYGONEXTRACTOR:
                        print "end path %d" % s1.id
                    self.all_path_list.append(s1)
                    prev_point.next()
                    s0.bot_join = s1
                    s1.bot_join = s0
                    winding = s1.winding
                else:
                    # new segment is overlapping
                    left_path = curr_path.next()
                    right_path = curr_path.peek()
                    left_point = c0
                    right_point = c1
                    winding = left_path.winding
                    curr_point.next()
                    prev_point.next()

                    overlap_p = True
                    overlap_c = True
                    while overlap_c or overlap_p:
                        overlap_p = False
                        overlap_c = False
                        # check for path joins
                        if prev_point.remains() >= 2:
                            p2 = prev_point.peek(1)
                            if DEBUG_POLYGONEXTRACTOR:
                                print "join test: p0=%g p1=%g p2=%g" \
                                        % (p0.x, p1.x, p2.x)
                                print "join test: c0=%g c1=%g" % (c0.x, c1.x)
                            if p2.y <= c1.y:
                                overlap_p = True
                                if self.policy == PolygonExtractor.CONTOUR:
                                    s0 = curr_path.takeNext()
                                    s1 = curr_path.takeNext()
                                    if curr_path.remains() >= 1:
                                        right_path = curr_path.peek()
                                    self.all_path_list.append(s0)
                                    self.all_path_list.append(s1)
                                    if DEBUG_POLYGONEXTRACTOR:
                                        print "path %d joins %d" \
                                                % (s0.id, s1.id)
                                    s0.bot_join = s1
                                    s1.bot_join = s0
                                elif self.policy == PolygonExtractor.MONOTONE:
                                    s0 = curr_path.takeNext()
                                    left_path.bot_join = s0
                                    s0.bot_join = left_path
                                    if DEBUG_POLYGONEXTRACTOR:
                                        print "path %d joins %d" \
                                                % (left_path.id, s0.id)
                                    curr_path.remove(left_path)
                                    self.all_path_list.append(left_path)
                                    self.all_path_list.append(s0)
                                    s1 = curr_path.next()
                                    left_path = s1
                                    right_path = curr_path.peek()
                                prev_point.next()
                                prev_point.next()
                                winding = s1.winding
                                p0 = p2
                                if prev_point.remains() >= 1:
                                    p1 = prev_point.peek(0)
                            else:
                                overlap_p = False

                        # check for path splits
                        if curr_point.remains()>=2:
                            c2 = curr_point.peek(1)
                            if DEBUG_POLYGONEXTRACTOR:
                                print "split test: p0=%g p1=%g" % (p0.x, p1.x)
                                print "split test: c0=%g c1=%g c2=%g" \
                                        % (c0.x, c1.x, c2.x)
                            if c2.y <= p1.y:
                                overlap_c = True
                                s0 = Path()
                                s1 = Path()
                                s0.winding = winding + 1
                                s1.winding = winding
                                s0.top_join = s1
                                s1.top_join = s0
                                if DEBUG_POLYGONEXTRACTOR:
                                    print "region split into %d and %d (w=%d)" \
                                            % (s0.id, s1.id, winding + 1)
                                curr_point.next()
                                c0 = curr_point.next()
                                if self.policy == PolygonExtractor.CONTOUR:
                                    s0.append(c1)
                                    curr_path.insert(s0)
                                    s1.append(c2)
                                    curr_path.insert(s1)
                                elif self.policy == PolygonExtractor.MONOTONE:
                                    s0.append(left_point)
                                    s1.append(c1)
                                    curr_path.insertBefore(s0)
                                    curr_path.insertBefore(s1)
                                    left_point = c2
                                if curr_point.remains() >= 1:
                                    c1 = curr_point.peek(0)
                                    right_point = c1
                            else:
                                overlap_c = False

                    if DEBUG_POLYGONEXTRACTOR:
                        print "add to path %d(%g,%g)" \
                                % (left_path.id, left_point.x, left_point.y)
                    left_path.append(left_point)
                    right_path.append(right_point)
                    if right_path == curr_path.peek():
                        curr_path.next()
                    if DEBUG_POLYGONEXTRACTOR:
                        print "add to path %d(%g,%g)" \
                                % (right_path.id, right_point.x, right_point.y)
                    winding = right_path.winding
                    prev_point.next()
                    curr_point.next()

        if DEBUG_POLYGONEXTRACTOR:
            print "active paths: ",
            for path in self.curr_path_list:
                print "%d(%g,%g,w=%d)" % (path.id, path.points[-1].x,
                        path.points[-1].y, path.winding),
            print

        self.prev_line = scanline
Пример #14
0
    def process_hor_scanline(self, scanline):
        if DEBUG_POLYGONEXTRACTOR:
            last = 0
            inside = False
            s = ""
            for point in scanline:
                next_x = point.x
                if inside:
                    s += "*" * int(next_x - last)
                else:
                    s += " " * int(next_x - last)
                last = next_x
                inside = not inside
            print s

        if DEBUG_POLYGONEXTRACTOR:
            print "active paths: ",
            for path in self.curr_path_list:
                print "%d(%g,%g)" \
                        % (path.id, path.points[-1].x, path.points[-1].y),
            print

            print "prev points: ",
            for point in self.prev_line:
                print "(%g,%g)" % (point.x, point.y),
            print

            print "active points: ",
            for point in scanline:
                print "%d(%g,%g)" % (point.id, point.x, point.y),
            print

        prev_point = Iterator(self.prev_line)
        curr_point = Iterator(scanline)
        curr_path = Iterator(self.curr_path_list)

        winding = 0
        while (prev_point.remains() > 0) or (curr_point.remains() > 0):
            if DEBUG_POLYGONEXTRACTOR:
                print "num_prev=%d, num_curr=%d" \
                        % (prev_point.remains(), curr_point.remains())
            if (prev_point.remains() == 0) and (curr_point.remains() >= 2):
                c0 = curr_point.next()
                c1 = curr_point.next()
                # new path starts
                p0 = Path()
                p0.winding = winding + 1
                if DEBUG_POLYGONEXTRACTOR:
                    print "new path %d(%g,%g)" % (p0.id, c0.x, c0.y)
                p0.append(c0)
                self.curr_path_list.append(p0)
                p1 = Path()
                p1.winding = winding
                if DEBUG_POLYGONEXTRACTOR:
                    print "new path %d(%g,%g)" % (p1.id, c1.x, c1.y)
                p1.append(c1)
                self.curr_path_list.append(p1)
                p0.top_join = p1
                p1.top_join = p0
                continue

            if (prev_point.remains() >= 2) and (curr_point.remains() == 0):
                #old path ends
                p0 = curr_path.takeNext()
                if DEBUG_POLYGONEXTRACTOR:
                    print "end path %d" % p0.id
                self.all_path_list.append(p0)
                prev_point.next()
                p1 = curr_path.takeNext()
                if DEBUG_POLYGONEXTRACTOR:
                    print "end path %d" % p1.id
                self.all_path_list.append(p1)
                prev_point.next()
                p0.bot_join = p1
                p1.bot_join = p0
                continue

            if (prev_point.remains() >= 2) and (curr_point.remains() >= 2):
                p0 = prev_point.peek(0)
                p1 = prev_point.peek(1)
                c0 = curr_point.peek(0)
                c1 = curr_point.peek(1)

                if DEBUG_POLYGONEXTRACTOR:
                    print "overlap test: p0=%g p1=%g" % (p0.x, p1.x)
                    print "overlap test: c0=%g c1=%g" % (c0.x, c1.x)

                if c1.x < p0.x:
                    # new segment is completely to the left
                    # new path starts
                    s0 = Path()
                    if DEBUG_POLYGONEXTRACTOR:
                        print "new path %d(%g,%g) w=%d" \
                                % (s0.id, c0.x, c0.y, winding + 1)
                    s0.append(c0)
                    curr_path.insert(s0)
                    s1 = Path()
                    s0.winding = winding + 1
                    s1.winding = winding
                    if DEBUG_POLYGONEXTRACTOR:
                        print "new path %d(%g,%g) w=%d" \
                                % (s1.id, c1.x, c1.y, winding)
                    s1.append(c1)
                    curr_path.insert(s1)
                    curr_point.next()
                    curr_point.next()
                    s0.top_join = s1
                    s1.top_join = s0
                elif c0.x > p1.x:
                    # new segment is completely to the right
                    # old path ends
                    s0 = curr_path.takeNext()
                    if DEBUG_POLYGONEXTRACTOR:
                        print "end path %d" % s0.id
                    self.all_path_list.append(s0)
                    prev_point.next()
                    s1 = curr_path.takeNext()
                    if DEBUG_POLYGONEXTRACTOR:
                        print "end path %d" % s1.id
                    self.all_path_list.append(s1)
                    prev_point.next()
                    s0.bot_join = s1
                    s1.bot_join = s0
                    winding = s1.winding
                else:
                    # new segment is overlapping
                    left_path = curr_path.next()
                    right_path = curr_path.peek()
                    left_point = c0
                    right_point = c1
                    winding = left_path.winding
                    curr_point.next()
                    prev_point.next()

                    overlap_p = True
                    overlap_c = True
                    while overlap_c or overlap_p:
                        overlap_p = False
                        overlap_c = False
                        # check for path joins
                        if prev_point.remains() >= 2:
                            p2 = prev_point.peek(1)
                            if DEBUG_POLYGONEXTRACTOR:
                                print "join test: p0=%g p1=%g p2=%g" \
                                        % (p0.x, p1.x, p2.x)
                                print "join test: c0=%g c1=%g" % (c0.x, c1.x)
                            if p2.x <= c1.x:
                                overlap_p = True
                                if self.policy == PolygonExtractor.CONTOUR:
                                    s0 = curr_path.takeNext()
                                    s1 = curr_path.takeNext()
                                    if curr_path.remains() >= 1:
                                        right_path = curr_path.peek()
                                    self.all_path_list.append(s0)
                                    self.all_path_list.append(s1)
                                    if DEBUG_POLYGONEXTRACTOR:
                                        print "path %d joins %d" \
                                                % (s0.id, s1.id)
                                    s0.bot_join = s1
                                    s1.bot_join = s0
                                elif self.policy == PolygonExtractor.MONOTONE:
                                    s0 = curr_path.takeNext()
                                    left_path.bot_join = s0
                                    s0.bot_join = left_path
                                    if DEBUG_POLYGONEXTRACTOR:
                                        print "path %d joins %d" \
                                                % (left_path.id, s0.id)
                                    curr_path.remove(left_path)
                                    self.all_path_list.append(left_path)
                                    self.all_path_list.append(s0)
                                    s1 = curr_path.next()
                                    left_path = s1
                                    right_path = curr_path.peek()
                                prev_point.next()
                                prev_point.next()
                                winding = s1.winding
                                p0 = p2
                                if prev_point.remains() >= 1:
                                    p1 = prev_point.peek(0)
                            else:
                                overlap_p = False

                        # check for path splits
                        if curr_point.remains() >= 2:
                            c2 = curr_point.peek(1)
                            if DEBUG_POLYGONEXTRACTOR:
                                print "split test: p0=%g p1=%g" % (p0.x, p1.x)
                                print "split test: c0=%g c1=%g c2=%g" \
                                        % (c0.x, c1.x, c2.x)
                            if c2.x <= p1.x:
                                overlap_c = True
                                s0 = Path()
                                s1 = Path()
                                s0.winding = winding + 1
                                s1.winding = winding
                                s0.top_join = s1
                                s1.top_join = s0
                                if DEBUG_POLYGONEXTRACTOR:
                                    print "region split into %d and %d (w=%d)" \
                                            % (s0.id, s1.id, winding + 1)
                                curr_point.next()
                                c0 = curr_point.next()
                                if self.policy == PolygonExtractor.CONTOUR:
                                    s0.append(c1)
                                    curr_path.insert(s0)
                                    s1.append(c2)
                                    curr_path.insert(s1)
                                elif self.policy == PolygonExtractor.MONOTONE:
                                    s0.append(left_point)
                                    s1.append(c1)
                                    curr_path.insertBefore(s0)
                                    curr_path.insertBefore(s1)
                                    left_point = c2
                                if curr_point.remains() >= 1:
                                    c1 = curr_point.peek(0)
                                    right_point = c1
                            else:
                                overlap_c = False

                    if DEBUG_POLYGONEXTRACTOR:
                        print "add to path %d(%g,%g)" \
                                % (left_path.id, left_point.x, left_point.y)
                    left_path.append(left_point)
                    right_path.append(right_point)
                    if right_path == curr_path.peek():
                        curr_path.next()
                    if DEBUG_POLYGONEXTRACTOR:
                        print "add to path %d(%g,%g)" \
                                % (right_path.id, right_point.x, right_point.y)
                    winding = right_path.winding
                    prev_point.next()
                    curr_point.next()

        if DEBUG_POLYGONEXTRACTOR:
            print "active paths: ",
            for path in self.curr_path_list:
                print "%d(%g,%g,w=%d)" % (path.id, path.points[-1].x,
                                          path.points[-1].y, path.winding),
            print

        self.prev_line = scanline
Пример #15
0
    def convert_hor_path_list(self):
        if DEBUG_POLYGONEXTRACTOR2:
            print("converting hor paths")
        hor_path_list = []
        for s in self.hor_path_list:
            allsame = True
            miny = s.points[0][1]
            maxy = s.points[0][1]
            for p in s.points:
                if not p[0] == s.points[0][0]:
                    allsame = False
                if p[1] < miny:
                    miny = p[1]
                if p[1] > maxy:
                    maxy = p[1]
            if allsame:
                if DEBUG_POLYGONEXTRACTOR2:
                    print("all same !")
                s0 = Path()
                for p in s.points:
                    if p[1] == miny:
                        s0.append(p)
                hor_path_list.append(s0)
                s1 = Path()
                for p in s.points:
                    if p[1] == maxy:
                        s1.append(p)
                hor_path_list.append(s1)
                continue
            prev = s.points[-1]
            p_iter = CyclicIterator(s.points)
            p = s.points[0]
            next_p = next(p_iter)
            while not ((prev[0] >= p[0]) and (next_p[0] > p[0])):
                p = next_p
                next_p = next(p_iter)
            count = 0
            while count < len(s.points):
                s0 = Path()
                while next_p[0] >= p[0]:
                    s0.append(p)
                    p = next_p
                    next_p = next(p_iter)
                    count += 1
                s0.append(p)
                while (len(s0.points) > 1) \
                        and (s0.points[0][0] == s0.points[1][0]):
                    s0.points = s0.points[1:]
                while (len(s0.points) > 1) \
                        and (s0.points[-2][0] == s0.points[-1][0]):
                    s0.points = s0.points[0:-1]

                hor_path_list.append(s0)
                s1 = Path()
                while next_p[0] <= p[0]:
                    s1.append(p)
                    p = next_p
                    next_p = next(p_iter)
                    count += 1
                s1.append(p)
                s1.reverse()
                while (len(s1.points) > 1) \
                        and (s1.points[0][0] == s1.points[1][0]):
                    s1.points = s1.points[1:]
                while (len(s1.points) > 1) \
                        and (s1.points[-2][0] == s1.points[-1][0]):
                    s1.points = s1.points[:-1]
                hor_path_list.append(s1)
        hor_path_list.sort(key=lambda p: p.points[0][0])
        if DEBUG_POLYGONEXTRACTOR2:
            print("ver_hor_path_list = ", hor_path_list)
            for s in hor_path_list:
                print("s%d =" % s.id),
                for point in s.points:
                    print(point.id),
                print()
        self.ver_hor_path_list = hor_path_list

        self.act_hor_path_list = []
Пример #16
0
    def process_ver_scanline(self, scanline):
        if DEBUG_POLYGONEXTRACTOR3:
            prev = None
            for p in scanline:
                if p.dir == 0:
                    self.cont.fill("red")
                else:
                    self.cont.fill("blue")
                self.cont.AddDot(p[0], p[1])
                self.cont.fill("black")
                self.cont.AddText(p[0], p[1], str(p.id))
                if prev:
                    self.cont.AddLine(prev[0], prev[1], p[0], p[1])
                prev = p

        if DEBUG_POLYGONEXTRACTOR:
            last = 0
            inside = False
            s = ""
            for point in scanline:
                next_y = point[1]
                if inside:
                    s += "*" * int(next_y - last)
                else:
                    s += " " * int(next_y - last)
                last = next_y
                inside = not inside
            print(s)

        if DEBUG_POLYGONEXTRACTOR:
            print("active paths: "),
            for path in self.curr_path_list:
                print("%d(%g,%g)" %
                      (path.id, path.points[-1][0], path.points[-1][1])),
            print()

            print("prev points: "),
            for point in self.prev_line:
                print("(%g,%g)" % (point[0], point[1])),
            print()

            print("active points: "),
            for point in scanline:
                print("%d(%g,%g)" % (point.id, point[0], point[1])),
            print()

        prev_point = Iterator(self.prev_line)
        curr_point = Iterator(scanline)
        curr_path = Iterator(self.curr_path_list)

        winding = 0
        while (prev_point.remains() > 0) or (curr_point.remains() > 0):
            if DEBUG_POLYGONEXTRACTOR:
                print("num_prev=%d, num_curr=%d" %
                      (prev_point.remains(), curr_point.remains()))
            if (prev_point.remains() == 0) and (curr_point.remains() >= 2):
                c0 = next(curr_point)
                c1 = next(curr_point)
                # new path starts
                p0 = Path()
                p0.winding = winding + 1
                if DEBUG_POLYGONEXTRACTOR:
                    print("new path %d(%g,%g)" % (p0.id, c0[0], c0[1]))
                p0.append(c0)
                self.curr_path_list.append(p0)
                p1 = Path()
                p1.winding = winding
                if DEBUG_POLYGONEXTRACTOR:
                    print("new path %d(%g,%g)" % (p1.id, c1[0], c1[1]))
                p1.append(c1)
                self.curr_path_list.append(p1)
                p0.top_join = p1
                p1.top_join = p0
                continue

            if (prev_point.remains() >= 2) and (curr_point.remains() == 0):
                # old path ends
                p0 = curr_path.takeNext()
                if DEBUG_POLYGONEXTRACTOR:
                    print("end path %d" % p0.id)
                self.all_path_list.append(p0)
                next(prev_point)
                p1 = curr_path.takeNext()
                if DEBUG_POLYGONEXTRACTOR:
                    print("end path %d" % p1.id)
                self.all_path_list.append(p1)
                next(prev_point)
                p0.bot_join = p1
                p1.bot_join = p0
                continue

            if (prev_point.remains() >= 2) and (curr_point.remains() >= 2):
                p0 = prev_point.peek(0)
                p1 = prev_point.peek(1)
                c0 = curr_point.peek(0)
                c1 = curr_point.peek(1)

                if DEBUG_POLYGONEXTRACTOR:
                    print("overlap test: p0=%g p1=%g" % (p0[0], p1[0]))
                    print("overlap test: c0=%g c1=%g" % (c0[0], c1[0]))

                if c1[1] < p0[1]:
                    # new segment is completely to the left
                    # new path starts
                    s0 = Path()
                    if DEBUG_POLYGONEXTRACTOR:
                        print("new path %d(%g,%g) w=%d" %
                              (s0.id, c0[0], c0[1], winding + 1))
                    s0.append(c0)
                    curr_path.insert(s0)
                    s1 = Path()
                    s0.winding = winding + 1
                    s1.winding = winding
                    if DEBUG_POLYGONEXTRACTOR:
                        print("new path %d(%g,%g) w=%d" %
                              (s1.id, c1[0], c1[1], winding))
                    s1.append(c1)
                    curr_path.insert(s1)
                    next(curr_point)
                    next(curr_point)
                    s0.top_join = s1
                    s1.top_join = s0
                elif c0[1] > p1[1]:
                    # new segment is completely to the right
                    # old path ends
                    s0 = curr_path.takeNext()
                    if DEBUG_POLYGONEXTRACTOR:
                        print("end path %d" % s0.id)
                    self.all_path_list.append(s0)
                    next(prev_point)
                    s1 = curr_path.takeNext()
                    if DEBUG_POLYGONEXTRACTOR:
                        print("end path %d" % s1.id)
                    self.all_path_list.append(s1)
                    next(prev_point)
                    s0.bot_join = s1
                    s1.bot_join = s0
                    winding = s1.winding
                else:
                    # new segment is overlapping
                    left_path = next(curr_path)
                    right_path = curr_path.peek()
                    left_point = c0
                    right_point = c1
                    winding = left_path.winding
                    next(curr_point)
                    next(prev_point)

                    overlap_p = True
                    overlap_c = True
                    while overlap_c or overlap_p:
                        overlap_p = False
                        overlap_c = False
                        # check for path joins
                        if prev_point.remains() >= 2:
                            p2 = prev_point.peek(1)
                            if DEBUG_POLYGONEXTRACTOR:
                                print("join test: p0=%g p1=%g p2=%g" %
                                      (p0[0], p1[0], p2[0]))
                                print("join test: c0=%g c1=%g" %
                                      (c0[0], c1[0]))
                            if p2[1] <= c1[1]:
                                overlap_p = True
                                if self.policy == PolygonExtractor.CONTOUR:
                                    s0 = curr_path.takeNext()
                                    s1 = curr_path.takeNext()
                                    if curr_path.remains() >= 1:
                                        right_path = curr_path.peek()
                                    self.all_path_list.append(s0)
                                    self.all_path_list.append(s1)
                                    if DEBUG_POLYGONEXTRACTOR:
                                        print("path %d joins %d" %
                                              (s0.id, s1.id))
                                    s0.bot_join = s1
                                    s1.bot_join = s0
                                elif self.policy == PolygonExtractor.MONOTONE:
                                    s0 = curr_path.takeNext()
                                    left_path.bot_join = s0
                                    s0.bot_join = left_path
                                    if DEBUG_POLYGONEXTRACTOR:
                                        print("path %d joins %d" %
                                              (left_path.id, s0.id))
                                    curr_path.remove(left_path)
                                    self.all_path_list.append(left_path)
                                    self.all_path_list.append(s0)
                                    s1 = next(curr_path)
                                    left_path = s1
                                    right_path = curr_path.peek()
                                next(prev_point)
                                next(prev_point)
                                winding = s1.winding
                                p0 = p2
                                if prev_point.remains() >= 1:
                                    p1 = prev_point.peek(0)
                            else:
                                overlap_p = False

                        # check for path splits
                        if curr_point.remains() >= 2:
                            c2 = curr_point.peek(1)
                            if DEBUG_POLYGONEXTRACTOR:
                                print("split test: p0=%g p1=%g" %
                                      (p0[0], p1[0]))
                                print("split test: c0=%g c1=%g c2=%g" %
                                      (c0[0], c1[0], c2[0]))
                            if c2[1] <= p1[1]:
                                overlap_c = True
                                s0 = Path()
                                s1 = Path()
                                s0.winding = winding + 1
                                s1.winding = winding
                                s0.top_join = s1
                                s1.top_join = s0
                                if DEBUG_POLYGONEXTRACTOR:
                                    print(
                                        "region split into %d and %d (w=%d)" %
                                        (s0.id, s1.id, winding + 1))
                                next(curr_point)
                                c0 = next(curr_point)
                                if self.policy == PolygonExtractor.CONTOUR:
                                    s0.append(c1)
                                    curr_path.insert(s0)
                                    s1.append(c2)
                                    curr_path.insert(s1)
                                elif self.policy == PolygonExtractor.MONOTONE:
                                    s0.append(left_point)
                                    s1.append(c1)
                                    curr_path.insertBefore(s0)
                                    curr_path.insertBefore(s1)
                                    left_point = c2
                                if curr_point.remains() >= 1:
                                    c1 = curr_point.peek(0)
                                    right_point = c1
                            else:
                                overlap_c = False

                    if DEBUG_POLYGONEXTRACTOR:
                        print("add to path %d(%g,%g)" %
                              (left_path.id, left_point[0], left_point[1]))
                    left_path.append(left_point)
                    right_path.append(right_point)
                    if right_path == curr_path.peek():
                        next(curr_path)
                    if DEBUG_POLYGONEXTRACTOR:
                        print("add to path %d(%g,%g)" %
                              (right_path.id, right_point[0], right_point[1]))
                    winding = right_path.winding
                    next(prev_point)
                    next(curr_point)

        if DEBUG_POLYGONEXTRACTOR:
            output = "active paths: "
            for path in self.curr_path_list:
                output += "%d(%g,%g,w=%d)" % (path.id, path.points[-1][0],
                                              path.points[-1][1], path.winding)
            print(output)

        self.prev_line = scanline
Пример #17
0
    def convert_hor_path_list(self):
        if DEBUG_POLYGONEXTRACTOR2:
            print "converting hor paths"
        hor_path_list = []
        for s in self.hor_path_list:
            allsame = True
            miny = s.points[0].y
            maxy = s.points[0].y
            for p in s.points:
                if not p.x == s.points[0].x:
                    allsame = False
                if p.y < miny:
                    miny = p.y
                if p.y > maxy:
                    maxy = p.y
            if allsame:
                if DEBUG_POLYGONEXTRACTOR2:
                    print "all same !"
                s0 = Path()
                for p in s.points:
                    if p.y == miny:
                        s0.append(p)
                hor_path_list.append(s0)
                s1 = Path()
                for p in s.points:
                    if p.y == maxy:
                        s1.append(p)
                hor_path_list.append(s1)
                continue
            prev = s.points[-1]
            p_iter = CyclicIterator(s.points)
            p = s.points[0]
            next_p = p_iter.next()
            while not ((prev.x >= p.x) and (next_p.x > p.x)):
                p = next_p
                next_p = p_iter.next()
            count = 0
            while count < len(s.points):
                s0 = Path()
                while next_p.x >= p.x:
                    s0.append(p)
                    p = next_p
                    next_p = p_iter.next()
                    count += 1
                s0.append(p)
                while (len(s0.points) > 1) \
                        and (s0.points[0].x == s0.points[1].x):
                    s0.points = s0.points[1:]
                while (len(s0.points) > 1) \
                        and (s0.points[-2].x == s0.points[-1].x):
                    s0.points = s0.points[0:-1]

                hor_path_list.append(s0)
                s1 = Path()
                while next_p.x <= p.x:
                    s1.append(p)
                    p = next_p
                    next_p = p_iter.next()
                    count += 1
                s1.append(p)
                s1.reverse()
                while (len(s1.points) > 1) \
                        and (s1.points[0].x == s1.points[1].x):
                    s1.points = s1.points[1:]
                while (len(s1.points) > 1) \
                        and (s1.points[-2].x == s1.points[-1].x):
                    s1.points = s1.points[:-1]
                hor_path_list.append(s1)
        hor_path_list.sort(cmp=lambda a, b: cmp(a.points[0].x, b.points[0].x))
        if DEBUG_POLYGONEXTRACTOR2:
            print "ver_hor_path_list = ", hor_path_list
            for s in hor_path_list:
                print "s%d =" % s.id,
                for point in s.points:
                    print point.id,
                print
        self.ver_hor_path_list = hor_path_list

        self.act_hor_path_list = []