From d164880064e0386427c4d18514c03101ee330512 Mon Sep 17 00:00:00 2001 From: mozman Date: Tue, 19 Mar 2024 17:53:07 +0100 Subject: [PATCH] add test for polygon orientation to revcloud.add_entity() --- examples/revcloud.py | 8 ++++++++ src/ezdxf/revcloud.py | 18 +++++++++++++++--- tests/test_05_tools/test_544_revcloud.py | 5 +++-- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/examples/revcloud.py b/examples/revcloud.py index 6780ce2a4..6fd76b582 100644 --- a/examples/revcloud.py +++ b/examples/revcloud.py @@ -39,7 +39,15 @@ def revcloud_entity(): revcloud.add_entity(msp, [(0, 0), (1, 0), (1, 1), (0, 1)], segment_length=0.1) doc.saveas(CWD / "revcloud-entity.dxf") +def revcloud_reverse_entity(): + doc = ezdxf.new() + msp = doc.modelspace() + + revcloud.add_entity(msp, [(0, 0), (0, 1), (1, 1), (1, 0)], segment_length=0.1) + doc.saveas(CWD / "revcloud-reverse-entity.dxf") + if __name__ == "__main__": revcloud_manually() revcloud_entity() + revcloud_reverse_entity() diff --git a/src/ezdxf/revcloud.py b/src/ezdxf/revcloud.py index 3942ac9b9..b4e6f6357 100644 --- a/src/ezdxf/revcloud.py +++ b/src/ezdxf/revcloud.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Sequence, TYPE_CHECKING, Iterable, Any import math -from ezdxf.math import UVec, Vec2 +from ezdxf.math import UVec, Vec2, has_clockwise_orientation from ezdxf.entities import LWPolyline, DXFEntity if TYPE_CHECKING: @@ -83,8 +83,19 @@ def add_entity( dxfattribs: additional DXF attributes """ + _vertices: list[Vec2] = Vec2.list(vertices) + if len(_vertices) < 3: + raise ValueError("3 or more points required.") + if not _vertices[0].isclose(_vertices[-1]): + _vertices.append(_vertices[0]) + if len(_vertices) < 4: + raise ValueError("3 or more points required.") + bulge = REQUIRED_BULGE + if has_clockwise_orientation(_vertices): + bulge = -bulge + end_width = segment_length * 0.1 if calligraphy else 0.0 - lw_points = points(vertices, segment_length, end_width=end_width) + lw_points = points(vertices, segment_length, bulge=bulge, end_width=end_width) lwp = layout.add_lwpolyline(lw_points, close=True, dxfattribs=dxfattribs) lwp.set_xdata(REVCLOUD_PROPS, [(1070, 0), (1040, segment_length)]) doc = layout.doc @@ -103,5 +114,6 @@ def is_revcloud(entity: DXFEntity) -> bool: if not lwpolyline.has_xdata(REVCLOUD_PROPS): return False return all( - abs(p[0] - REQUIRED_BULGE) < 0.02 for p in lwpolyline.get_points(format="b") + abs(REQUIRED_BULGE- abs(p[0])) < 0.02 + for p in lwpolyline.get_points(format="b") ) diff --git a/tests/test_05_tools/test_544_revcloud.py b/tests/test_05_tools/test_544_revcloud.py index f96d193ab..64997c3d6 100644 --- a/tests/test_05_tools/test_544_revcloud.py +++ b/tests/test_05_tools/test_544_revcloud.py @@ -28,13 +28,14 @@ def test_too_small_segment_length_raises_exception(): def test_add_entity(): doc = ezdxf.new() msp = doc.modelspace() + # counter-clockwise oriented revision cloud: lwp = revcloud.add_entity(msp, [(0, 0), (1, 0), (1, 1), (0, 1)], 0.1) assert doc.appids.has_entry(revcloud.REVCLOUD_PROPS) assert revcloud.is_revcloud(lwp) is True - # adding a second revision cloud should be ok: - lwp = revcloud.add_entity(msp, [(0, 0), (1, 0), (1, 1), (0, 1)], 0.1) + # clockwise oriented revision cloud: + lwp = revcloud.add_entity(msp, [(0, 0), (0, 1), (1, 1), (1, 0)], 0.1) assert revcloud.is_revcloud(lwp) is True