From 5f7dfc2bb9b1cac74518c49137cafc03e53de297 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 13 Jan 2025 12:06:33 +1100 Subject: [PATCH] Test and fix for exporting small arcs to SVG. --- src/build123d/exporters.py | 13 +++++++++++++ tests/test_exporters.py | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/build123d/exporters.py b/src/build123d/exporters.py index 221e34e..810d9c9 100644 --- a/src/build123d/exporters.py +++ b/src/build123d/exporters.py @@ -36,6 +36,7 @@ from copy import copy from enum import Enum, auto from os import PathLike, fsdecode from typing import Any, TypeAlias +from warnings import warn from collections.abc import Callable, Iterable @@ -1196,6 +1197,12 @@ class ExportSVG(Export2D): def _circle_segments(self, edge: Edge, reverse: bool) -> list[PathSegment]: # pylint: disable=too-many-locals + if edge.length < 1e-6: + warn( + "Skipping arc that is too small to export safely (length < 1e-6).", + stacklevel=7, + ) + return [] curve = edge.geom_adaptor() circle = curve.Circle() radius = circle.Radius() @@ -1242,6 +1249,12 @@ class ExportSVG(Export2D): def _ellipse_segments(self, edge: Edge, reverse: bool) -> list[PathSegment]: # pylint: disable=too-many-locals + if edge.length < 1e-6: + warn( + "Skipping ellipse that is too small to export safely (length < 1e-6).", + stacklevel=7, + ) + return [] curve = edge.geom_adaptor() ellipse = curve.Ellipse() minor_radius = ellipse.MinorRadius() diff --git a/tests/test_exporters.py b/tests/test_exporters.py index a038057..f95a92e 100644 --- a/tests/test_exporters.py +++ b/tests/test_exporters.py @@ -29,6 +29,7 @@ from build123d import ( add, mirror, section, + ThreePointArc, ) from build123d.exporters import ExportSVG, ExportDXF, Drawing, LineType @@ -173,6 +174,24 @@ class ExportersTestCase(unittest.TestCase): svg.add_shape(sketch) svg.write("test-colors.svg") + def test_svg_small_arc(self): + pnts = ((0, 0), (0, 0.000001), (0.000001, 0)) + small_arc = ThreePointArc(pnts).scale(0.01) + with self.assertWarns(UserWarning): + svg_exporter = ExportSVG() + segments = svg_exporter._circle_segments(small_arc.edges()[0], False) + self.assertEqual(len(segments), 0, "Small arc should produce no segments") + + def test_svg_small_ellipse(self): + pnts = ((0, 0), (0, 0.000001), (0.000002, 0)) + small_ellipse = ThreePointArc(pnts).scale(0.01) + with self.assertWarns(UserWarning): + svg_exporter = ExportSVG() + segments = svg_exporter._ellipse_segments(small_ellipse.edges()[0], False) + self.assertEqual( + len(segments), 0, "Small ellipse should produce no segments" + ) + @pytest.mark.parametrize( "format", (Path, fsencode, fsdecode), ids=["path", "bytes", "str"]