diff options
Diffstat (limited to 'lib/elements/satin_column.py')
| -rw-r--r-- | lib/elements/satin_column.py | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/lib/elements/satin_column.py b/lib/elements/satin_column.py index 25f50e13..a63ca403 100644 --- a/lib/elements/satin_column.py +++ b/lib/elements/satin_column.py @@ -280,7 +280,7 @@ class SatinColumn(EmbroideryElement): def reverse_rails(self): return self.get_param('reverse_rails', 'automatic') - def _get_rails_to_reverse(self, rails): + def _get_rails_to_reverse(self): choice = self.reverse_rails if choice == 'first': @@ -290,6 +290,7 @@ class SatinColumn(EmbroideryElement): elif choice == 'both': return True, True elif choice == 'automatic': + rails = [shgeo.LineString(self.flatten_subpath(rail)) for rail in self.rails] if len(rails) == 2: # Sample ten points along the rails. Compare the distance # between corresponding points on both rails with and without @@ -314,7 +315,7 @@ class SatinColumn(EmbroideryElement): # reverse the second rail return False, True - return None + return False, False @property @param( @@ -508,7 +509,7 @@ class SatinColumn(EmbroideryElement): """The rails, as LineStrings.""" paths = [shgeo.LineString(self.flatten_subpath(rail)) for rail in self.rails] - rails_to_reverse = self._get_rails_to_reverse(paths) + rails_to_reverse = self._get_rails_to_reverse() if paths and rails_to_reverse is not None: for i, reverse in enumerate(rails_to_reverse): if reverse: @@ -537,14 +538,19 @@ class SatinColumn(EmbroideryElement): else: return [subpath for i, subpath in enumerate(self.csp) if i not in self.rail_indices] + @cache def _synthesize_rungs(self): rung_endpoints = [] # check for unequal length of rails equal_length = len(self.rails[0]) == len(self.rails[1]) - for rail in self.rails: + rails_to_reverse = self._get_rails_to_reverse() + for i, rail in enumerate(self.rails): points = self.strip_control_points(rail) + if rails_to_reverse[i]: + points = points[::-1] + if len(points) > 2 or not equal_length: # Don't bother putting rungs at the start and end. points = points[1:-1] @@ -744,6 +750,9 @@ class SatinColumn(EmbroideryElement): Returns two new SatinColumn instances: the part before and the part after the split point. All parameters are copied over to the new SatinColumn instances. + + The returned SatinColumns will not be in the SVG document and will have + their transforms applied. """ cut_points = self._find_cut_points(split_point) @@ -856,6 +865,43 @@ class SatinColumn(EmbroideryElement): return SatinColumn(node) + def merge(self, satin): + """Merge this satin with another satin + + This method expects that the provided satin continues on directly after + this one, as would be the case, for example, if the two satins were the + result of the split() method. + + Returns a new SatinColumn instance that combines the rails and rungs of + this satin and the provided satin. A rung is added at the end of this + satin. + + The returned SatinColumn will not be in the SVG document and will have + its transforms applied. + """ + rails = [self.flatten_subpath(rail) for rail in self.rails] + other_rails = [satin.flatten_subpath(rail) for rail in satin.rails] + + if len(rails) != 2 or len(other_rails) != 2: + # weird non-satin things, give up and don't merge + return self + + # remove first node of each other rail before merging (avoid duplicated nodes) + rails[0].extend(other_rails[0][1:]) + rails[1].extend(other_rails[1][1:]) + + rungs = [self.flatten_subpath(rung) for rung in self.rungs] + other_rungs = [satin.flatten_subpath(rung) for rung in satin.rungs] + + # add a rung in between the two satins and extend it just a litte to ensure it is crossing the rails + new_rung = shgeo.LineString([other_rails[0][0], other_rails[1][0]]) + rungs.append(list(shaffinity.scale(new_rung, 1.2, 1.2).coords)) + + # add on the other satin's rungs + rungs.extend(other_rungs) + + return self._csp_to_satin(point_lists_to_csp(rails + rungs)) + @property @cache def center_line(self): |
