kopia lustrzana https://github.com/inkstitch/inkstitch
				
				
				
			pick closest starting point
							rodzic
							
								
									b16f7de2fc
								
							
						
					
					
						commit
						e48a0f6556
					
				
							
								
								
									
										107
									
								
								embroider.py
								
								
								
								
							
							
						
						
									
										107
									
								
								embroider.py
								
								
								
								
							| 
						 | 
					@ -311,7 +311,7 @@ class Fill(EmbroideryElement):
 | 
				
			||||||
        if shgeo.LineString(segment1).distance(shgeo.LineString(segment1)) > self.row_spacing * 1.1:
 | 
					        if shgeo.LineString(segment1).distance(shgeo.LineString(segment1)) > self.row_spacing * 1.1:
 | 
				
			||||||
            return False
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        quad = make_quadrilateral(segment1, segment2)
 | 
					        quad = self.make_quadrilateral(segment1, segment2)
 | 
				
			||||||
        quad_area = quad.area
 | 
					        quad_area = quad.area
 | 
				
			||||||
        intersection_area = self.shape.intersection(quad).area
 | 
					        intersection_area = self.shape.intersection(quad).area
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -448,14 +448,16 @@ class Fill(EmbroideryElement):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AutoFill(Fill):
 | 
					class AutoFill(Fill):
 | 
				
			||||||
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        super(AutoFill, self).__init__(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.outline = self.shape.boundary[0]
 | 
				
			||||||
 | 
					        self.outline_length = self.outline.length
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def flip(self):
 | 
					    def flip(self):
 | 
				
			||||||
        return False
 | 
					        return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def outline(self):
 | 
					 | 
				
			||||||
        return self.shape.boundary[0]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def running_stitch_length(self):
 | 
					    def running_stitch_length(self):
 | 
				
			||||||
        return self.get_float_param("running_stitch_length_mm")    
 | 
					        return self.get_float_param("running_stitch_length_mm")    
 | 
				
			||||||
| 
						 | 
					@ -469,51 +471,82 @@ class AutoFill(Fill):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def perimeter_distance(self, p1, p2):
 | 
				
			||||||
 | 
					        # how far around the perimeter (and in what direction) do I need to go
 | 
				
			||||||
 | 
					        # to get from p1 to p2?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        p1_projection = self.outline.project(shgeo.Point(p1))
 | 
				
			||||||
 | 
					        p2_projection = self.outline.project(shgeo.Point(p2))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        distance = p2_projection - p1_projection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if abs(distance) > self.outline_length / 2.0:
 | 
				
			||||||
 | 
					            # if we'd have to go more than halfway around, it's faster to go
 | 
				
			||||||
 | 
					            # the other way
 | 
				
			||||||
 | 
					            if distance < 0:
 | 
				
			||||||
 | 
					                return distance + self.outline_length
 | 
				
			||||||
 | 
					            elif distance > 0:
 | 
				
			||||||
 | 
					                return distance - self.outline_length
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                # this ought not happen, but just for completeness, return 0 if
 | 
				
			||||||
 | 
					                # p1 and p0 are the same point
 | 
				
			||||||
 | 
					                return 0
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return distance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def connect_points(self, p1, p2):
 | 
				
			||||||
 | 
					        patch = Patch(color=self.color)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pos = self.outline.project(shgeo.Point(p1))
 | 
				
			||||||
 | 
					        distance = self.perimeter_distance(p1, p2)
 | 
				
			||||||
 | 
					        stitches = abs(int(distance / self.running_stitch_length))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        direction = distance / abs(distance)
 | 
				
			||||||
 | 
					        stitch = self.running_stitch_length * direction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for i in xrange(stitches):
 | 
				
			||||||
 | 
					           pos = (pos + stitch) % self.outline_length
 | 
				
			||||||
 | 
					           
 | 
				
			||||||
 | 
					           patch.add_stitch(PyEmb.Point(*self.outline.interpolate(pos).coords[0]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return patch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_corner_points(self, section):
 | 
					    def get_corner_points(self, section):
 | 
				
			||||||
        return section[0][0], section[0][-1], section[-1][0], section[-1][-1]
 | 
					        return section[0][0], section[0][-1], section[-1][0], section[-1][-1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def connect_points(self, p1, p2):
 | 
					    def nearest_corner(self, section, point):
 | 
				
			||||||
        p1 = shgeo.Point(p1)
 | 
					        return min(self.get_corner_points(section),
 | 
				
			||||||
        p2 = shgeo.Point(p2)
 | 
					                   key=lambda corner: abs(self.perimeter_distance(point, corner)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        patch = Patch(color=self.color)
 | 
					    def find_nearest_section(self, sections, point):
 | 
				
			||||||
 | 
					        sections_with_nearest_corner = [(i, self.nearest_corner(section, point))
 | 
				
			||||||
 | 
					                                    for i, section in enumerate(sections)]
 | 
				
			||||||
 | 
					        return min(sections_with_nearest_corner,
 | 
				
			||||||
 | 
					                   key=lambda(section, corner): abs(self.perimeter_distance(point, corner)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        outline = self.outline
 | 
					    def section_from_corner(self, section, start_corner):
 | 
				
			||||||
        outline_length = outline.length
 | 
					        if start_corner not in section[0]:
 | 
				
			||||||
        start = outline.project(p1)
 | 
					            section = list(reversed(section))
 | 
				
			||||||
        stitch_length = self.running_stitch_length
 | 
					 | 
				
			||||||
        stitches = int(outline.length / stitch_length)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # TODO: tidy this code up, make pull_runs split more aggressively to
 | 
					        if section[0][0] != start_corner:
 | 
				
			||||||
        # completely avoid discontiguous sections, find the shorter direction
 | 
					            section = [list(reversed(row)) for row in section]
 | 
				
			||||||
        # around the shape to the destination
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for i in xrange(stitches):
 | 
					        return self.section_to_patch(section)
 | 
				
			||||||
            next_point = outline.interpolate((start + i * stitch_length) % outline_length)
 | 
					 | 
				
			||||||
            patch.add_stitch(PyEmb.Point(next_point.x, next_point.y))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if next_point.distance(p2) <= stitch_length:
 | 
					 | 
				
			||||||
                break
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return patch
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def to_patches(self):
 | 
					    def to_patches(self):
 | 
				
			||||||
        rows_of_segments = self.intersect_region_with_grating()
 | 
					        rows_of_segments = self.intersect_region_with_grating()
 | 
				
			||||||
        sections = self.pull_runs(rows_of_segments)
 | 
					        sections = self.pull_runs(rows_of_segments)
 | 
				
			||||||
        # to do: perhaps travel to the sections in a more intelligent manner, by
 | 
					 | 
				
			||||||
        # finding the next nearest corner point?
 | 
					 | 
				
			||||||
        #corner_points = [self.get_corner_points(section) for section in sections]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        print >> dbg, "autofill"
 | 
					        patches = []        
 | 
				
			||||||
 | 
					        while sections:
 | 
				
			||||||
 | 
					            if patches:
 | 
				
			||||||
 | 
					                last_stitch = patches[-1].stitches[-1]
 | 
				
			||||||
 | 
					                section_index, start_corner = self.find_nearest_section(sections, last_stitch)
 | 
				
			||||||
 | 
					                patches.append(self.connect_points(last_stitch, start_corner))
 | 
				
			||||||
 | 
					                patches.append(self.section_from_corner(sections.pop(section_index), start_corner))
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                patches.append(self.section_to_patch(sections.pop(0)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        patches = []
 | 
					 | 
				
			||||||
        last_section = None
 | 
					 | 
				
			||||||
        for section in sections:
 | 
					 | 
				
			||||||
            if last_section:
 | 
					 | 
				
			||||||
                patches.append(self.connect_points(patches[-1].stitches[-1], section[0][0]))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            patches.append(self.section_to_patch(section))
 | 
					 | 
				
			||||||
            last_section = section
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return patches
 | 
					        return patches
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Ładowanie…
	
		Reference in New Issue