Test and fix for exporting small arcs to SVG.

This commit is contained in:
Anthony 2025-01-13 12:06:33 +11:00
parent 18f591d0a2
commit 5f7dfc2bb9
2 changed files with 32 additions and 0 deletions

View file

@ -36,6 +36,7 @@ from copy import copy
from enum import Enum, auto from enum import Enum, auto
from os import PathLike, fsdecode from os import PathLike, fsdecode
from typing import Any, TypeAlias from typing import Any, TypeAlias
from warnings import warn
from collections.abc import Callable, Iterable from collections.abc import Callable, Iterable
@ -1196,6 +1197,12 @@ class ExportSVG(Export2D):
def _circle_segments(self, edge: Edge, reverse: bool) -> list[PathSegment]: def _circle_segments(self, edge: Edge, reverse: bool) -> list[PathSegment]:
# pylint: disable=too-many-locals # 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() curve = edge.geom_adaptor()
circle = curve.Circle() circle = curve.Circle()
radius = circle.Radius() radius = circle.Radius()
@ -1242,6 +1249,12 @@ class ExportSVG(Export2D):
def _ellipse_segments(self, edge: Edge, reverse: bool) -> list[PathSegment]: def _ellipse_segments(self, edge: Edge, reverse: bool) -> list[PathSegment]:
# pylint: disable=too-many-locals # 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() curve = edge.geom_adaptor()
ellipse = curve.Ellipse() ellipse = curve.Ellipse()
minor_radius = ellipse.MinorRadius() minor_radius = ellipse.MinorRadius()

View file

@ -29,6 +29,7 @@ from build123d import (
add, add,
mirror, mirror,
section, section,
ThreePointArc,
) )
from build123d.exporters import ExportSVG, ExportDXF, Drawing, LineType from build123d.exporters import ExportSVG, ExportDXF, Drawing, LineType
@ -173,6 +174,24 @@ class ExportersTestCase(unittest.TestCase):
svg.add_shape(sketch) svg.add_shape(sketch)
svg.write("test-colors.svg") 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( @pytest.mark.parametrize(
"format", (Path, fsencode, fsdecode), ids=["path", "bytes", "str"] "format", (Path, fsencode, fsdecode), ids=["path", "bytes", "str"]