From d262351279448fb81ddce8e932c60524e23cfecc Mon Sep 17 00:00:00 2001 From: Chris Want Date: Mon, 3 Jul 2023 18:16:19 -0600 Subject: [PATCH] SVG styling with classes didn't work out, so a quick 0.8.2 release. --- README.md | 2 +- tessagon/adaptors/svg_adaptor.py | 84 +++++++++++++++++------------- tessagon/version.py | 2 +- tests/adaptors/test_svg_adaptor.py | 78 +++++++++------------------ 4 files changed, 76 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index 01938f6..e8f0373 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Tessellate your favorite 3D surfaces (technically, 2D manifolds) with triangles, **You can find a Blender (3.6) pull request to add support for Tessagon in the "XYZ function" addon here: ** -**Check out my presentation on the creation of Tessagon as an open source Python project here: ** +**Check out my presentation on the creation of Tessagon as an open source Python project here: (or watch on [YouTube](https://www.youtube.com/watch?v=R0hG9hHs9Fw))** **A demo of using Tessagon with Inkscape Simple Scripting can be found [here](https://gist.github.com/cwant/697f0c6ce07d9e14e710f5b80ca5eece).** diff --git a/tessagon/adaptors/svg_adaptor.py b/tessagon/adaptors/svg_adaptor.py index f4cd41b..a89e593 100644 --- a/tessagon/adaptors/svg_adaptor.py +++ b/tessagon/adaptors/svg_adaptor.py @@ -21,54 +21,66 @@ def get_mesh(self): buffer = "" if self.svg_root_tag: if self.svg_root_tag is True: - buffer += '' + buffer += '\n' else: buffer += self.svg_root_tag - buffer += "" - style = self.make_style() - if style: - buffer += "".format(style) + buffer += "\n".format(self.group_style()) - for i in range(len(self.face_list)): - face = self.face_list[i] - class_string = "" - if len(self.color_list) > 0: - color = self.color_list[i] - class_string = ' class="color-{}"'.format(color) - verts = [self.vert_list[v] for v in face] - points_string = \ - ' '.join(["{},{}".format(vert[0], - vert[1]) for vert in verts]) - buffer += ''.format(points_string, - class_string) - buffer += "" - if self.svg_root_tag: - buffer += "" - return buffer - - def make_style(self): if self.style: - return self.style + buffer += "".format(self.style) - style = "" - polygon_style = "" if self.svg_fill_colors: + color_indices = self.make_color_indices() for i in range(len(self.svg_fill_colors)): - style += '.color-{} {{\n fill:{};\n}}\n'.\ - format(i, self.svg_fill_colors[i]) + if i not in color_indices: + continue + fill_color = self.svg_fill_colors[i] + faces = [self.face_list[j] for j in color_indices[i]] + buffer += self.make_color_group(faces, fill_color) + else: + for face in self.face_list: + buffer += self.make_face(face) + + buffer += "\n" + if self.svg_root_tag: + buffer += "\n" + return buffer + + def group_style(self): + style = "" if self.svg_stroke_color: - polygon_style += ' stroke:{};\n'.format(self.svg_stroke_color) + style += 'stroke:{};'.format(self.svg_stroke_color) if self.svg_stroke_width: - polygon_style += " stroke-width:{};\n".\ + style += "stroke-width:{};".\ format(self.svg_stroke_width) if self.svg_fill_color: - polygon_style += ' fill:{};\n'.format(self.svg_fill_color) + style += 'fill:{};'.format(self.svg_fill_color) + if len(style) > 0: + style = ' style="{}"'.format(style) + return style - if len(polygon_style) > 0: - style += "polygon {{\n{}}}\n".format(polygon_style) + def make_color_indices(self): + color_indices = {} + for i in range(len(self.color_list)): + color = self.color_list[i] + if color not in color_indices: + color_indices[color] = [] + color_indices[color].append(i) - if len(style) > 0: - return style + return color_indices + + def make_color_group(self, faces, fill_color): + buffer = '\n'.format(fill_color) + for face in faces: + buffer += self.make_face(face) + buffer += '\n' + + return buffer - return None + def make_face(self, face): + verts = [self.vert_list[v] for v in face] + points_string = \ + ' '.join(["{},{}".format(vert[0], + vert[1]) for vert in verts]) + return ''.format(points_string) diff --git a/tessagon/version.py b/tessagon/version.py index ef72cc0..4ca39e7 100644 --- a/tessagon/version.py +++ b/tessagon/version.py @@ -1 +1 @@ -__version__ = '0.8.1' +__version__ = '0.8.2' diff --git a/tests/adaptors/test_svg_adaptor.py b/tests/adaptors/test_svg_adaptor.py index 3832fe1..9d83aea 100644 --- a/tests/adaptors/test_svg_adaptor.py +++ b/tests/adaptors/test_svg_adaptor.py @@ -13,8 +13,7 @@ class SvgToList(HTMLParser): def __init__(self): HTMLParser.__init__(self) self.parts = [] - self.getting_style = False - self.style = "" + self.getting_data = False def handle_starttag(self, tag, attrs): self.parts.append(tag) @@ -22,13 +21,14 @@ def handle_starttag(self, tag, attrs): self.parts.append(attr[0]) self.parts.append(attr[1]) if tag == "style": - self.getting_style = True + self.getting_data = True else: - self.getting_style = False + self.getting_data = False def handle_data(self, data): - if self.getting_style: - self.style = data + # Just through the style info on the list + if self.getting_data: + self.parts.append(data) class TestSvgAdaptor: @@ -62,17 +62,13 @@ def test_get_mesh(self): parser.feed(mesh) parser.close() - print(parser.parts) assert parser.parts == ['g', 'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0', - 'class', 'color-2', 'polygon', 'points', '3.0,2.0 5.0,4.0 3.0,1.0', - 'class', 'color-0', - 'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0', - 'class', 'color-1'] + 'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0'] def test_get_mesh_root_tag(self): adaptor = SvgAdaptor(svg_root_tag=True) @@ -83,22 +79,18 @@ def test_get_mesh_root_tag(self): parser.feed(mesh) parser.close() - print(parser.parts) assert parser.parts == ['svg', 'xmlns', 'http://www.w3.org/2000/svg', 'g', 'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0', - 'class', 'color-2', 'polygon', 'points', '3.0,2.0 5.0,4.0 3.0,1.0', - 'class', 'color-0', - 'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0', - 'class', 'color-1'] + 'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0'] def test_get_mesh_style(self): - adaptor = SvgAdaptor(svg_style='whatever;') + adaptor = SvgAdaptor(svg_style='fill:#555555;') self.setup_adaptor(adaptor) mesh = adaptor.get_mesh() @@ -106,20 +98,15 @@ def test_get_mesh_style(self): parser.feed(mesh) parser.close() - print(parser.parts) assert parser.parts == ['g', 'style', + 'fill:#555555;', 'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0', - 'class', 'color-2', 'polygon', 'points', '3.0,2.0 5.0,4.0 3.0,1.0', - 'class', 'color-0', - 'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0', - 'class', 'color-1'] - - assert parser.style == 'whatever;' + 'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0'] def test_get_mesh_style_fill_color(self): adaptor = SvgAdaptor(svg_fill_color='#ffffff') @@ -130,24 +117,18 @@ def test_get_mesh_style_fill_color(self): parser.feed(mesh) parser.close() - print(parser.parts) assert parser.parts == ['g', 'style', + 'fill:#ffffff;', 'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0', - 'class', 'color-2', 'polygon', 'points', '3.0,2.0 5.0,4.0 3.0,1.0', - 'class', 'color-0', - 'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0', - 'class', 'color-1'] - - assert parser.style == \ - 'polygon {\n fill:#ffffff;\n}\n' + 'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0'] def test_get_mesh_style_fill_colors(self): - adaptor = SvgAdaptor(svg_fill_colors=['#ffffff', '#000000']) + adaptor = SvgAdaptor(svg_fill_colors=['#ffffff', '#000000', '#888888']) self.setup_adaptor(adaptor) mesh = adaptor.get_mesh() @@ -155,22 +136,22 @@ def test_get_mesh_style_fill_colors(self): parser.feed(mesh) parser.close() - print(parser.parts) assert parser.parts == ['g', - 'style', - - 'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0', - 'class', 'color-2', + 'g', + 'style', + 'fill:#ffffff;', 'polygon', 'points', '3.0,2.0 5.0,4.0 3.0,1.0', - 'class', 'color-0', + 'g', + 'style', + 'fill:#000000;', 'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0', - 'class', 'color-1'] - assert parser.style == \ - '.color-0 {\n fill:#ffffff;\n}\n'\ - '.color-1 {\n fill:#000000;\n}\n' + 'g', + 'style', + 'fill:#888888;', + 'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0'] def test_get_mesh_style_stroke(self): adaptor = SvgAdaptor(svg_stroke_color='#ffffff', @@ -182,19 +163,12 @@ def test_get_mesh_style_stroke(self): parser.feed(mesh) parser.close() - print(parser.parts) assert parser.parts == ['g', 'style', + 'stroke:#ffffff;stroke-width:1px;', 'polygon', 'points', '0.0,1.0 3.0,2.0 5.0,4.0', - 'class', 'color-2', 'polygon', 'points', '3.0,2.0 5.0,4.0 3.0,1.0', - 'class', 'color-0', - - 'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0', - 'class', 'color-1'] - assert parser.style == \ - 'polygon {\n stroke:#ffffff;\n'\ - ' stroke-width:1px;\n}\n' + 'polygon', 'points', '0.0,1.0 5.0,4.0 3.0,1.0']