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: | ||||
|             return False | ||||
| 
 | ||||
|         quad = make_quadrilateral(segment1, segment2) | ||||
|         quad = self.make_quadrilateral(segment1, segment2) | ||||
|         quad_area = quad.area | ||||
|         intersection_area = self.shape.intersection(quad).area | ||||
| 
 | ||||
|  | @ -448,14 +448,16 @@ class Fill(EmbroideryElement): | |||
| 
 | ||||
| 
 | ||||
| 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 | ||||
|     def flip(self): | ||||
|         return False | ||||
| 
 | ||||
|     @property | ||||
|     def outline(self): | ||||
|         return self.shape.boundary[0] | ||||
| 
 | ||||
|     @property | ||||
|     def running_stitch_length(self): | ||||
|         return self.get_float_param("running_stitch_length_mm")     | ||||
|  | @ -469,51 +471,82 @@ class AutoFill(Fill): | |||
| 
 | ||||
|         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): | ||||
|         return section[0][0], section[0][-1], section[-1][0], section[-1][-1] | ||||
| 
 | ||||
|     def connect_points(self, p1, p2): | ||||
|         p1 = shgeo.Point(p1) | ||||
|         p2 = shgeo.Point(p2) | ||||
|     def nearest_corner(self, section, point): | ||||
|         return min(self.get_corner_points(section), | ||||
|                    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 | ||||
|         outline_length = outline.length | ||||
|         start = outline.project(p1) | ||||
|         stitch_length = self.running_stitch_length | ||||
|         stitches = int(outline.length / stitch_length) | ||||
|     def section_from_corner(self, section, start_corner): | ||||
|         if start_corner not in section[0]: | ||||
|             section = list(reversed(section)) | ||||
| 
 | ||||
|         # TODO: tidy this code up, make pull_runs split more aggressively to | ||||
|         # completely avoid discontiguous sections, find the shorter direction | ||||
|         # around the shape to the destination | ||||
|         if section[0][0] != start_corner: | ||||
|             section = [list(reversed(row)) for row in section] | ||||
| 
 | ||||
|         for i in xrange(stitches): | ||||
|             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 | ||||
|         return self.section_to_patch(section) | ||||
| 
 | ||||
|     def to_patches(self): | ||||
|         rows_of_segments = self.intersect_region_with_grating() | ||||
|         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 | ||||
| 
 | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Lex Neva
						Lex Neva