1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
# Copyright (c) 2023, Manfred Moitzi
# License: MIT License
import pytest
import math
import ezdxf
from ezdxf import transform
from ezdxf.layouts import VirtualLayout
class TestInplaceMethod:
"""The tests do not check if all possible transformations will be performed correct,
this is done by the tests for the transform() method of the entities.
"""
@pytest.fixture
def msp(self, request):
if request.param == "doc":
doc = ezdxf.new()
msp = doc.modelspace()
elif request.param == "virtual":
# The matrix() function supports virtual entities as well.
msp = VirtualLayout()
else:
return ValueError(request.param)
msp.add_point((0, 0))
msp.add_text("TEXT")
msp.add_circle((0, 0), radius=1)
return msp
@pytest.mark.parametrize("msp", ["doc", "virtual"], indirect=True)
def test_transformation_by_matrix_without_errors(self, msp):
m = transform.Matrix44.translate(1, 2, 0)
log = transform.inplace(msp, m)
assert len(log) == 0
point = msp[0]
assert point.dxf.location.isclose((1, 2, 0))
text = msp[1]
assert text.dxf.insert.isclose((1, 2, 0))
circle = msp[2]
assert circle.dxf.center.isclose((1, 2, 0))
@pytest.mark.parametrize("msp", ["doc"], indirect=True)
def test_non_uniform_transformation(self, msp):
# not supported by virtual layouts
m = transform.Matrix44.scale(1, 2, 1)
log = transform.inplace(msp, m)
assert len(log) == 0
entity = msp[2]
assert entity.dxftype() == "ELLIPSE"
def test_entities_without_transformation_support(self):
from ezdxf.entities import Layer
m = transform.Matrix44.translate(1, 0, 0)
log = transform.inplace([Layer.new()], m)
assert log[0].error == transform.Error.TRANSFORMATION_NOT_SUPPORTED
def test_acis_entities(self):
# new in v1.3.0: ACIS entities support a temporary transformation
#
# This way a temporary transformation of ACIS entities is stored by ezdxf.
# This temp. transformation has to be applied before export otherwise a warning
# will be logged.
msp = VirtualLayout()
body = msp.add_body() # ACIS entity
m = transform.Matrix44.translate(1, 2, 3)
log = transform.inplace(msp, m)
assert len(log) == 0
m2 = body.temporary_transformation().get_matrix()
v = (3, 2, 1)
assert m.transform(v).isclose(m2.transform(v))
class TestConvenientFunctions:
@pytest.fixture
def msp(self):
msp = VirtualLayout()
msp.add_point((1, 1, 1))
return msp
def test_translate(self, msp):
transform.translate(msp, offset=(1, 2))
point = msp[0]
assert point.dxf.location.isclose((2, 3, 1))
def test_scale_uniform(self, msp):
transform.scale_uniform(msp, factor=2)
point = msp[0]
assert point.dxf.location.isclose((2, 2, 2))
def test_scale(self, msp):
transform.scale(msp, sx=2, sy=3, sz=4)
point = msp[0]
assert point.dxf.location.isclose((2, 3, 4))
def test_z_rotate(self, msp):
transform.z_rotate(msp, angle=math.pi / 2)
point = msp[0]
assert point.dxf.location.isclose((-1, 1, 1))
def test_y_rotate(self, msp):
transform.y_rotate(msp, angle=math.pi / 2)
point = msp[0]
assert point.dxf.location.isclose((1, 1, -1))
def test_x_rotate(self, msp):
transform.x_rotate(msp, angle=math.pi / 2)
point = msp[0]
assert point.dxf.location.isclose((1, -1, 1))
def test_circle_non_uniform_scaling():
doc = ezdxf.new()
msp = doc.modelspace()
msp.add_circle((0, 0), radius=1)
transform.scale(msp, sx=3, sy=2, sz=1)
ellipse = msp[0]
assert ellipse.dxftype() == "ELLIPSE"
assert ellipse.dxf.center.isclose((0, 0, 0))
assert ellipse.dxf.major_axis.isclose((3, 0, 0))
assert ellipse.dxf.ratio == pytest.approx(0.6666666)
def test_polyline_non_uniform_scaling():
doc = ezdxf.new()
msp = doc.modelspace()
# semi-circle: center=(0, 0); radius=1
msp.add_lwpolyline([(-1, 0, 0, 0, 1), (1, 0)])
transform.scale(msp, sx=3, sy=2, sz=1)
ellipse = msp[0]
assert ellipse.dxftype() == "ELLIPSE"
assert ellipse.dxf.center.isclose((0, 0, 0))
assert ellipse.dxf.major_axis.isclose((3, 0, 0))
assert ellipse.dxf.ratio == pytest.approx(0.6666666)
def test_virtual_entities_do_not_support_non_uniform_scaling():
msp = VirtualLayout()
msp.add_circle((0, 0), radius=1)
log = transform.scale(msp, sx=3, sy=2, sz=1)
# does not transform the CIRCLE
circle = msp[0]
assert circle.dxftype() == "CIRCLE"
assert circle.dxf.radius == pytest.approx(1.0)
assert len(log) == 1
assert log[0].error == transform.Error.VIRTUAL_ENTITY_NOT_SUPPORTED
class TestVirtualCopies:
@pytest.fixture
def msp(self):
msp = VirtualLayout()
msp.add_circle((0, 0), radius=1)
msp.add_point((1, 1, 1))
return msp
def test_just_copy(self, msp):
log, entities = transform.copies(msp)
assert len(entities) == 2
assert all(e.is_virtual for e in entities)
def test_scale_virtual_circular_arcs_non_uniform(self, msp):
log, entities = transform.copies(msp, m=transform.Matrix44.scale(2, 3, 1))
assert len(log) == 0
assert entities[0].dxftype() == "ELLIPSE"
assert entities[1].dxftype() == "POINT"
def test_scale_virtual_polyline_with_bulge_non_uniform(self):
layout = VirtualLayout()
layout.add_lwpolyline([(-1, 0, 0, 0, 1), (1, 0)])
log, entities = transform.copies(layout, m=transform.Matrix44.scale(2, 3, 1))
assert len(log) == 0
assert len(entities) == 1
assert entities[0].dxftype() == "ELLIPSE"
class TestMLeaderNonUniformScaling:
@pytest.fixture(scope="class")
def msp(self):
from ezdxf.render import mleader
from ezdxf.math import Vec2
doc = ezdxf.new()
msp = doc.modelspace()
ml_builder = msp.add_multileader_mtext("Standard")
ml_builder.set_content("Line1\nLine2")
ml_builder.add_leader_line(mleader.ConnectionSide.right, [Vec2(40, 15)])
ml_builder.build(insert=Vec2(5, 0))
return msp
def test_transformation_will_not_be_applied_inplace(self, msp):
log = transform.scale(msp, 2, 3, 1)
assert log[0].error == transform.Error.NON_UNIFORM_SCALING_ERROR
assert msp[0].dxftype() == "MULTILEADER"
def test_mleader_will_not_copied(self, msp):
log, clones = transform.copies(msp, m=transform.Matrix44.scale(2, 3, 1))
assert log[0].error == transform.Error.NON_UNIFORM_SCALING_ERROR
assert len(clones) == 0
if __name__ == "__main__":
pytest.main([__file__])
|