diff --git a/.travis.yml b/.travis.yml index 11c3e4b..e661c06 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: python python: - - "2.7" - "3.6" - "3.9" script: diff --git a/pyembroidery/GenericWriter.py b/pyembroidery/GenericWriter.py new file mode 100644 index 0000000..c539bfc --- /dev/null +++ b/pyembroidery/GenericWriter.py @@ -0,0 +1,577 @@ +import pyembroidery +from pyembroidery import ( + CONTINGENCY_SEQUIN_UTILIZE, + decode_embroidery_command, + STITCH, + COLOR_CHANGE, + NEEDLE_SET, + TRIM, + JUMP, + SEQUIN_MODE, + SEQUIN_EJECT, + STOP, + SLOW, + FAST, + END, + get_common_name_dictionary, + COMMAND_MASK, +) +from pyembroidery.WriteHelper import write_string_utf8 + +WRITES_SPEEDS = True +SEQUIN_CONTINGENCY = CONTINGENCY_SEQUIN_UTILIZE + + +def write(pattern, f, settings=None): + writer = GenericWriter(pattern, f, settings) + writer.write() + + +class GenericWriter: + """ + Generic Writer will write generic data fit to a formatted set of strings. + + Blocks are established by the first segment. + Colors are established by the first segment or the first segment after a color change or by a needle_set. + Documents are established by the first segment, or the first segment after an end. + + Segment is the default for any-command. Specific commands override segment. + + stitch is the default stitch. + stitch_first overrides stitch for the first stitch in a block. + stitch_last overrides stitch for the last stitch in a block. + + trims and jumps occurring before a color change belong to the previous color. + trims and jumps occurring after a color change belong to the next color. + + Missing segments are treated as if they never existed. Value properties will differ if segments are excluded. + """ + + def __init__(self, pattern, f, settings): + self.pattern = pattern + self.f = f + self.settings = settings + self.metadata_entry = settings.get("metadata_entry", None) + self.thread_entry = settings.get("thread_entry", None) + self.pattern_start = settings.get("pattern_start", None) + self.pattern_end = settings.get("pattern_end", None) + self.document_start = settings.get("document_start", None) + self.document_end = settings.get("document_end", None) + self.color_start = settings.get("color_start", None) + self.color_end = settings.get("color_end", None) + self.color_join = settings.get("color_join", None) + self.block_start = settings.get("block_start", None) + self.block_end = settings.get("block_end", None) + self.block_join = settings.get("block_join", None) + self.segment_start = settings.get("segment_start", None) + self.segment = settings.get("segment", None) + self.segment_end = settings.get("segment_end", None) + self.segment_join = settings.get("segment_join", None) + self.stitch_first = settings.get("stitch_first", None) + self.stitch_last = settings.get("stitch_last", None) + self.stitch = settings.get("stitch", None) + self.stop = settings.get("stop", None) + self.jump = settings.get("jump", None) + self.trim = settings.get("trim", None) + self.needle_set = settings.get("needle_set", None) + self.color_change = settings.get("color_change", None) + self.sequin = settings.get("sequin", None) + self.sequin_mode = settings.get("sequin_mode", None) + self.slow = settings.get("slow", None) + self.fast = settings.get("fast", None) + self.end = settings.get("end", None) + + self.format_dictionary = {} + self.pattern_established = False + self.document_established = False + self.color_established = False + self.block_established = False + self.document_index = -1 + self.thread = None + self.thread_index = -1 + self.stitch_index = -1 + self.color_index = -1 + self.block_index = -1 + self.dx = 0 + self.dy = 0 + self.xx = 0 + self.yy = 0 + self.last_x = 0 + self.last_y = 0 + self.z = 0.0 + self.z_increment = settings.get("stitch_z_travel", 10.0) + self.command_index = 0 + + self.current_stitch = None + self.x = None + self.y = None + self.command = None + self.cmd = None + self.thread = None + self.needle = None + self.order = None + self.cmd_str = None + + self.block_closing = False + self.color_closing = False + self.document_closing = False + + self.block_opening = False + self.color_opening = False + self.document_opening = False + + def write_opens(self): + if self.document_opening: + self.document_opening = False + if self.document_start is not None: + write_string_utf8(self.f, self.document_start.format_map(self.format_dictionary)) + if self.color_opening: + self.color_opening = False + if self.color_join is not None and self.color_index != 0: + write_string_utf8(self.f, self.color_join.format_map(self.format_dictionary)) + if self.color_start is not None: + write_string_utf8(self.f, self.color_start.format_map(self.format_dictionary)) + if self.block_opening: + self.block_opening = False + if self.block_join is not None and self.block_index != 0: + write_string_utf8(self.f, self.block_join.format_map(self.format_dictionary)) + if self.block_start is not None: + write_string_utf8(self.f, self.block_start.format_map(self.format_dictionary)) + + def write_closes(self): + if self.block_closing: + self.block_closing = False + if self.block_end is not None: + write_string_utf8(self.f, self.block_end.format_map(self.format_dictionary)) + if self.color_closing: + self.color_closing = False + if self.color_end is not None: + write_string_utf8(self.f, self.color_end.format_map(self.format_dictionary)) + if self.document_closing: + self.document_closing = False + if self.document_end is not None: + write_string_utf8(self.f, self.document_end.format_map(self.format_dictionary)) + + def get_write_segment(self, cmd): + # SEQUIN_MODE + if cmd == SEQUIN_MODE and self.sequin_mode is not None: + return self.sequin_mode + + # SEQUIN + if cmd == SEQUIN_EJECT and self.sequin is not None: + return self.sequin + + # STITCH + if cmd == STITCH and self.stitch is not None: + return self.stitch + + # TRIM + if cmd == TRIM and self.trim is not None: + return self.trim + + # JUMP + if cmd == JUMP and self.jump is not None: + return self.jump + + # COLOR CHANGE + if cmd == COLOR_CHANGE and self.color_change is not None: + return self.color_change + + # NEEDLE SET + if cmd == NEEDLE_SET and self.needle_set is not None: + return self.needle_set + + # STOP COMMAND + if cmd == STOP and self.stop is not None: + return self.stop + + # SLOW COMMAND + if cmd == SLOW and self.slow is not None: + return self.slow + + # FAST COMMAND + if cmd == FAST and self.fast is not None: + return self.fast + + # END COMMAND + if cmd == END and self.end is not None: + return self.end + + # GENERIC SEGMENT + return self.segment + + def set_document_statistics(self): + pattern = self.pattern + self.format_dictionary.update(pattern.extras) + + bounds = pattern.bounds() # convert to mm. + width = bounds[2] - bounds[0] + height = bounds[3] - bounds[1] + + stitch_counts = {} + for s in pattern.stitches: + command = s[2] & COMMAND_MASK + if command in stitch_counts: + stitch_counts[command] += 1 + else: + stitch_counts[command] = 1 + + names = get_common_name_dictionary() + for name in names: + value = names[name].lower() + self.format_dictionary[value + "_count"] = stitch_counts.get(name,0) + self.format_dictionary.update( + { + "stitch_total": pattern.count_stitches(), + "thread_total": pattern.count_threads(), + "extents_left": bounds[0], + "extends_top": bounds[1], + "extends_right": bounds[2], + "extends_bottom": bounds[3], + "extends_width": width, + "extends_height": height, + "extents_left_mm": bounds[0] / 10.0, + "extends_top_mm": bounds[1] / 10.0, + "extends_right_mm": bounds[2] / 10.0, + "extends_bottom_mm": bounds[3] / 10.0, + "extends_width_mm": width / 10.0, + "extends_height_mm": height / 10.0, + } + ) + + def update_positions(self, x, y, cmd): + self.dx = x - self.last_x + self.dy = y - self.last_y + idx = int(round(x - self.xx)) + idy = int(round(y - self.yy)) + self.xx += idx + self.yy += idy + self.format_dictionary.update( + { + "x": x, + "y": y, + "z": self.z, + "_x": -x, + "_y": -y, + "dx": self.dx, + "dy": self.dy, + "idx": idx, + "idy": idy, + "_idx": -idx, + "_idy": -idy, + "ix": self.xx, + "iy": self.yy, + "_ix": -self.xx, + "_iy": -self.yy, + "last_x": self.last_x, + "last_y": self.last_y, + "_last_x": -self.last_x, + "_last_y": -self.last_y, + } + ) + if cmd == STITCH: + self.z += self.z_increment + self.last_x = x + self.last_y = y + + def update_command(self): + try: + self.current_stitch = self.pattern.stitches[self.command_index] + + self.x, self.y, self.command = self.current_stitch + self.cmd, self.thread, self.needle, self.order = decode_embroidery_command( + self.command + ) + self.cmd_str = pyembroidery.get_common_name_dictionary()[self.cmd] + except IndexError: + self.current_stitch = None + self.x = None + self.y = None + self.command = None + self.cmd = None + self.thread = None + self.needle = None + self.order = None + self.cmd_str = None + self.format_dictionary.update( + { + "index": self.command_index, + "command": self.command, + "cmd_str": self.cmd_str, + "cmd": self.cmd, + "cmd_thread": self.thread, + "cmd_needle": self.needle, + "cmd_order": self.order, + } + ) + + def open_pattern(self): + if not self.pattern_established: + self.pattern_established = True + if self.pattern_start is not None: + write_string_utf8( + self.f, self.pattern_start.format_map(self.format_dictionary) + ) + + def open_document(self): + # DOCUMENT START + if not self.document_established: + self.document_established = True + self.document_index += 1 + self.document_opening = True + self.color_index = 0 + + self.format_dictionary.update( + { + "document_index": self.document_index, + "document_index1": self.document_index + 1, + "color_index": self.color_index, + "color_index1": self.color_index + 1, + "block_index": self.block_index, + "block_index1": self.block_index + 1, + } + ) + + def open_color(self): + # COLOR START + if not self.color_established: + self.color_established = True + self.thread_index += 1 + self.color_opening = True + + self.thread = self.pattern.get_thread_or_filler(self.thread_index) + self.block_index = 0 + self.color_index += 1 + self.format_dictionary.update( + { + "document_index": self.document_index, + "document_index1": self.document_index + 1, + "color_index": self.color_index, + "color_index1": self.color_index + 1, + "block_index": self.block_index, + "block_index1": self.block_index + 1, + } + ) + + def open_block(self): + # BLOCK START + if not self.block_established: + self.block_established = True + self.block_index += 1 + self.block_opening = True + self.format_dictionary.update( + { + "document_index": self.document_index, + "document_index1": self.document_index + 1, + "color_index": self.color_index, + "color_index1": self.color_index + 1, + "block_index": self.block_index, + "block_index1": self.block_index + 1, + } + ) + + def write_segment(self, segment): + # SEGMENT + if self.segment_start is not None: + write_string_utf8(self.f, self.segment_start.format_map(self.format_dictionary)) + + write_string_utf8(self.f, segment.format_map(self.format_dictionary)) + + # SEGMENT JOIN + if self.segment_join is not None: + write_string_utf8(self.f, self.segment_join.format_map(self.format_dictionary)) + + # SEGMENT_END + if self.segment_end is not None: + write_string_utf8(self.f, self.segment_end.format_map(self.format_dictionary)) + + def close_pattern(self): + if self.pattern_established: + self.pattern_established = False + if self.pattern_end is not None: + write_string_utf8( + self.f, self.pattern_end.format_map(self.format_dictionary) + ) + + def close_document(self): + # DOCUMENT END + if self.document_established: + self.document_established = False + self.document_closing = True + + def close_color(self): + # COLOR END + if self.color_established: + self.color_established = False + self.color_closing = True + + def close_block(self): + # BLOCK END + if self.block_established: + self.block_established = False + self.block_closing = True + + def write(self): + pattern = self.pattern + f = self.f + settings = self.settings + + if settings is None: + return + + # DOCUMENT STATISTICS + self.set_document_statistics() + + self.open_pattern() + if self.metadata_entry is not None: + for i, key in enumerate(pattern.extras): + value = pattern.extras[key] + self.format_dictionary.update({ + "metadata_index": i, + "metadata_key": str(key), + "metadata_value": str(value), + }) + write_string_utf8( + self.f, self.metadata_entry.format_map(self.format_dictionary) + ) + + if self.thread_entry is not None: + for i, thread in enumerate(pattern.threadlist): + self.format_dictionary.update({ + "thread_index": i, + "thread_color": thread.hex_color(), + "thread_description": thread.description, + "thread_brand": thread.brand, + "thread_catalog_number": thread.catalog_number, + "thread_chart": thread.chart, + "thread_details": thread.details, + "thread_weight": thread.weight, + "thread_red": thread.get_red(), + "thread_green": thread.get_green(), + "thread_blue": thread.get_blue(), + }) + write_string_utf8( + self.f, self.thread_entry.format_map(self.format_dictionary) + ) + for self.command_index in range(0, len(pattern.stitches)): + self.update_command() + write_segment = self.get_write_segment(self.cmd) + + # MAIN CODE, there is something to write. + if write_segment is not None: + self.update_positions(self.x, self.y, self.cmd) + if self.cmd == SEQUIN_MODE: + self.open_document() + self.open_color() + self.open_block() + + # SEQUIN + if self.cmd == SEQUIN_EJECT: + self.open_document() + self.open_color() + self.open_block() + + # STITCH + if self.cmd == STITCH: + self.open_document() + self.open_color() + self.open_block() + + # TRIM + if self.cmd == TRIM: + self.open_document() + self.open_color() + + # JUMP + if self.cmd == JUMP: + self.open_document() + self.open_color() + self.open_block() + + # COLOR CHANGE + if self.cmd == COLOR_CHANGE: + self.open_document() + + # NEEDLE SET + if self.cmd == NEEDLE_SET: + self.open_document() + self.open_color() + + # STOP COMMAND + if self.cmd == STOP: + self.open_document() + self.open_color() + self.open_block() + + # SLOW COMMAND + if self.cmd == SLOW: + self.open_document() + self.open_color() + self.open_block() + + # FAST COMMAND + if self.cmd == FAST: + self.open_document() + self.open_color() + self.open_block() + + # END COMMAND + if self.cmd == END: + self.open_document() + self.open_color() + self.open_block() + + self.write_opens() + self.write_segment(write_segment) + + if self.cmd == SEQUIN_MODE: + pass + + # SEQUIN + if self.cmd == SEQUIN_EJECT: + pass + + # STITCH + if self.cmd == STITCH: + pass + + # TRIM + if self.cmd == TRIM: + self.close_block() + + # JUMP + if self.cmd == JUMP: + pass + + # COLOR CHANGE + if self.cmd == COLOR_CHANGE: + self.close_block() + self.close_color() + + # NEEDLE SET + if self.cmd == NEEDLE_SET: + pass + + # STOP COMMAND + if self.cmd == STOP: + pass + + # SLOW COMMAND + if self.cmd == SLOW: + pass + + # FAST COMMAND + if self.cmd == FAST: + pass + + # END COMMAND + if self.cmd == END: + self.close_block() + self.close_color() + self.close_document() + self.write_closes() + + self.close_block() + self.close_color() + self.close_document() + self.close_pattern() diff --git a/setup.py b/setup.py index fb630cd..8875f62 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="pyembroidery", - version="1.4.33", + version="1.4.34", author="Tatarize", author_email="tatarize@gmail.com", description="Embroidery IO library", diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/test_catalog.py b/test/test_catalog.py index 14a5be7..9e0272e 100644 --- a/test/test_catalog.py +++ b/test/test_catalog.py @@ -1,7 +1,7 @@ from __future__ import print_function import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestDataCatalog(unittest.TestCase): diff --git a/test/test_color_fileformats.py b/test/test_color_fileformats.py index 8f8d62e..5332541 100644 --- a/test/test_color_fileformats.py +++ b/test/test_color_fileformats.py @@ -2,7 +2,7 @@ import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestColorFormats(unittest.TestCase): diff --git a/test/test_convert_csv.py b/test/test_convert_csv.py index 7f88f73..e612990 100644 --- a/test/test_convert_csv.py +++ b/test/test_convert_csv.py @@ -2,7 +2,7 @@ import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestConverts(unittest.TestCase): diff --git a/test/test_convert_dst.py b/test/test_convert_dst.py index bcf42bc..77d08c7 100644 --- a/test/test_convert_dst.py +++ b/test/test_convert_dst.py @@ -2,7 +2,7 @@ import unittest from pyembroidery import * -from pattern_for_tests import * +from test.pattern_for_tests import * class TestConverts(unittest.TestCase): diff --git a/test/test_convert_exp.py b/test/test_convert_exp.py index c5e4d76..395b1bd 100644 --- a/test/test_convert_exp.py +++ b/test/test_convert_exp.py @@ -2,7 +2,7 @@ import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestConverts(unittest.TestCase): diff --git a/test/test_convert_gcode.py b/test/test_convert_gcode.py index 8600e35..48cab67 100644 --- a/test/test_convert_gcode.py +++ b/test/test_convert_gcode.py @@ -2,7 +2,7 @@ import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestConverts(unittest.TestCase): diff --git a/test/test_convert_jef.py b/test/test_convert_jef.py index b9d3420..20895c6 100644 --- a/test/test_convert_jef.py +++ b/test/test_convert_jef.py @@ -2,7 +2,7 @@ import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestConverts(unittest.TestCase): diff --git a/test/test_convert_pec.py b/test/test_convert_pec.py index 6ed3c5f..646f6d0 100644 --- a/test/test_convert_pec.py +++ b/test/test_convert_pec.py @@ -2,7 +2,7 @@ import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestConverts(unittest.TestCase): diff --git a/test/test_convert_pes.py b/test/test_convert_pes.py index 46ef91f..fc2b8ab 100644 --- a/test/test_convert_pes.py +++ b/test/test_convert_pes.py @@ -2,7 +2,7 @@ import unittest from pyembroidery import * -from pattern_for_tests import * +from test.pattern_for_tests import * class TestConverts(unittest.TestCase): diff --git a/test/test_convert_u01.py b/test/test_convert_u01.py index 706bbc8..f1b21a5 100644 --- a/test/test_convert_u01.py +++ b/test/test_convert_u01.py @@ -2,7 +2,7 @@ import unittest from pyembroidery import * -from pattern_for_tests import * +from test.pattern_for_tests import * class TestConverts(unittest.TestCase): diff --git a/test/test_convert_vp3.py b/test/test_convert_vp3.py index 6322a5c..a92760e 100644 --- a/test/test_convert_vp3.py +++ b/test/test_convert_vp3.py @@ -2,7 +2,7 @@ import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestConverts(unittest.TestCase): diff --git a/test/test_convert_xxx.py b/test/test_convert_xxx.py index d60cb98..73d9d6a 100644 --- a/test/test_convert_xxx.py +++ b/test/test_convert_xxx.py @@ -2,7 +2,7 @@ import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestConverts(unittest.TestCase): diff --git a/test/test_datapreservation.py b/test/test_datapreservation.py index 0a7a90d..4c44400 100644 --- a/test/test_datapreservation.py +++ b/test/test_datapreservation.py @@ -1,7 +1,7 @@ from __future__ import print_function import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestDataPreservation(unittest.TestCase): diff --git a/test/test_embpattern.py b/test/test_embpattern.py index ee31600..52d0d5c 100644 --- a/test/test_embpattern.py +++ b/test/test_embpattern.py @@ -2,7 +2,7 @@ import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestEmbpattern(unittest.TestCase): diff --git a/test/test_encoder.py b/test/test_encoder.py index 6cce6a0..05b51e3 100644 --- a/test/test_encoder.py +++ b/test/test_encoder.py @@ -2,7 +2,7 @@ import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestEmbpattern(unittest.TestCase): diff --git a/test/test_generic.py b/test/test_generic.py new file mode 100644 index 0000000..d9b3b01 --- /dev/null +++ b/test/test_generic.py @@ -0,0 +1,78 @@ +from __future__ import print_function + +import unittest + +from test.pattern_for_tests import * +from pyembroidery import GenericWriter + + +class TestConverts(unittest.TestCase): + def test_generic_write_stitch(self): + file1 = "convert.dst" + file2 = "convert.txt" + self.addCleanup(os.remove, file1) + self.addCleanup(os.remove, file2) + pattern = get_fractal_pattern() + pattern.write(file1) + + pattern = EmbPattern(file1) + + EmbPattern.write_embroidery( + GenericWriter, + pattern, + file2, + { + "segment_start": "\t\t", + "segment_end": "\n", + "segment": "{cmd_str} {x},{y}", + "stitch": "Stitch: {x},{y}", + "jump": "Jump {x},{y}", + "trim": "Trim: {x},{y}", + "color_change": "Color-Change: {x},{y}", + "block_start": "\t{{\n", + "block_end": "\t}}\n", + "color_start": "[\n", + "color_end": "]\n", + }, + ) + print("write generic: ", file1) + + def test_generic_write_gcode(self): + gcode_writer_dict = { + "scale": (-0.1, -0.1), + "pattern_start": "(STITCH_COUNT: {stitch_total})\n" + "(THREAD_COUNT: {color_change_count})\n" + "(EXTENTS_LEFT: {extents_left:.3f})\n" + "(EXTENTS_TOP: {extends_top:.3f})\n" + "(EXTENTS_RIGHT: {extends_right:.3f})\n" + "(EXTENTS_BOTTOM: {extends_bottom:.3f})\n" + "(EXTENTS_WIDTH: {extends_width:.3f})\n" + "(EXTENTS_HEIGHT: {extends_height:.3f})\n" + "(COMMAND_STITCH: {stitch_count})\n" + "(COMMAND_COLOR_CHANGE: {color_change_count})\n" + "(COMMAND_TRIM: {trim_count})\n" + "(COMMAND_STOP: {stop_count})\n" + "(COMMAND_END: {end_count})\n", + "metadata_entry": "({metadata_key}: {metadata_value})\n", + "thread_entry": "(Thread{thread_index}: {thread_color} {thread_description} {thread_brand} {thread_catalog_number})\n", + "stitch": "G00 X{x:.3f} Y{y:.3f}\nG00 Z{z:.1f}\n", + "color_change": "M00\n", + "stop": "M00\n", + "end": "M30\n", + } + file1 = "file-gcode.gcode" + file2 = "file-generic.gcode" + pattern = get_fractal_pattern() + pattern.fix_color_count() + EmbPattern.write_embroidery( + GenericWriter, + pattern, + file2, + gcode_writer_dict, + ) + pattern.write(file1) + f1 = open(file1, "rb").read() + f2 = open(file2, "rb").read() + self.assertEqual(f1, f2) + self.addCleanup(os.remove, file1) + self.addCleanup(os.remove, file2) diff --git a/test/test_interpolate.py b/test/test_interpolate.py index 4296982..5462b49 100644 --- a/test/test_interpolate.py +++ b/test/test_interpolate.py @@ -3,7 +3,7 @@ import unittest from pyembroidery import * -from pattern_for_tests import * +from test.pattern_for_tests import * class TestInterpolate(unittest.TestCase): diff --git a/test/test_json.py b/test/test_json.py index 8ce2735..28e8646 100644 --- a/test/test_json.py +++ b/test/test_json.py @@ -2,7 +2,7 @@ import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestJson(unittest.TestCase): diff --git a/test/test_overloads.py b/test/test_overloads.py index 3e7ef24..526f801 100644 --- a/test/test_overloads.py +++ b/test/test_overloads.py @@ -2,7 +2,7 @@ import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * class TestOverloads(unittest.TestCase): diff --git a/test/test_trims_dst_jef.py b/test/test_trims_dst_jef.py index b5a6f12..5fd3579 100644 --- a/test/test_trims_dst_jef.py +++ b/test/test_trims_dst_jef.py @@ -3,7 +3,7 @@ import unittest from pyembroidery import * -from pattern_for_tests import * +from test.pattern_for_tests import * class TestTrims(unittest.TestCase): diff --git a/test/test_writes.py b/test/test_writes.py index cbf69ff..5b7f11f 100644 --- a/test/test_writes.py +++ b/test/test_writes.py @@ -2,7 +2,7 @@ import unittest -from pattern_for_tests import * +from test.pattern_for_tests import * from pyembroidery import *