File: upright.rst

package info (click to toggle)
ezdxf 1.4.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 104,528 kB
  • sloc: python: 182,341; makefile: 116; lisp: 20; ansic: 4
file content (160 lines) | stat: -rw-r--r-- 4,866 bytes parent folder | download
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
Upright
=======

.. module:: ezdxf.upright

The functions in this module can help to convert an inverted :ref:`OCS` defined
by an extrusion vector (0, 0, -1) into a :ref:`WCS` aligned OCS defined by
an extrusion vector (0, 0, 1).

This simplifies 2D entity processing for `ezdxf` users and creates DXF
output for 3rd party DXF libraries which ignore the existence of the :ref:`OCS`.

Supported DXF entities:

- CIRCLE
- ARC
- ELLIPSE (WCS entity, flips only the extrusion vector)
- SOLID
- TRACE
- LWPOLYLINE
- POLYLINE (only 2D entities)
- HATCH
- MPOLYGON
- INSERT (block references)

.. warning::

    The WCS representation of OCS entities with flipped extrusion vector
    is not 100% identical to the source entity, curve orientation and vertex order
    may change, see `additional explanation`_ below.
    A mirrored text represented by an extrusion vector (0, 0, -1)
    cannot represented by an extrusion vector (0, 0, 1), therefore this CANNOT
    work for text entities or entities including text:
    TEXT, ATTRIB, ATTDEF, MTEXT, DIMENSION, LEADER, MLEADER

Usage
-----

The functions can be applied to any DXF entity without expecting errors or
exceptions if the DXF entity is not supported or the extrusion vector differs
from (0, 0, -1). This also means you can apply the functions multiple times to
the same entities without any problems. A common case would be to upright all
entities of the model space:

.. code-block:: Python

    import ezdxf
    from ezdxf.upright import upright_all

    doc = ezdxf.readfile("your.dxf")
    msp = doc.modelspace()
    upright_all(msp)
    # doing it again is no problem but also has no further effects
    upright_all(msp)

Another use case is exploding block references (INSERT) which may include
reflections (= scaling by negative factors) that can lead to inverted
extrusion vectors.

.. code-block:: Python

    for block_ref in msp.query("INSERT"):
        entities = block_ref.explode()  # -> EntityQuery object
        upright_all(entities)

Functions
---------

.. autofunction:: upright

.. autofunction:: upright_all


Additional Explanation
----------------------

This example shows why the entities with an inverted OCS, extrusion vector is
(0, 0, -1), are not exact the same as with an WCS aligned OCS, extrusion vector
is (0, 0, 1).

.. note::

    The ARC entity represents the curve **always** in counter-clockwise
    orientation around the extrusion vector.

.. code-block:: Python

    import ezdxf
    from ezdxf.upright import upright
    from ezdxf.math import Matrix44

    doc = ezdxf.new()
    msp = doc.modelspace()

    arc = msp.add_arc(
        (5, 0),
        radius=5,
        start_angle=-90,
        end_angle=90,
        dxfattribs={"color": ezdxf.const.RED},
    )
    # draw lines to the start- and end point of the ARC
    msp.add_line((0, 0), arc.start_point, dxfattribs={"color": ezdxf.const.GREEN})
    msp.add_line((0, 0), arc.end_point, dxfattribs={"color": ezdxf.const.BLUE})

    # copy arc
    mirrored_arc = arc.copy()
    msp.add_entity(mirrored_arc)

    # mirror copy
    mirrored_arc.transform(Matrix44.scale(-1, 1, 1))

    # This creates an inverted extrusion vector:
    assert mirrored_arc.dxf.extrusion.isclose((0, 0, -1))

    # draw lines to the start- and end point of the mirrored ARC
    msp.add_line((0, 0), mirrored_arc.start_point, dxfattribs={"color": ezdxf.const.GREEN})
    msp.add_line((0, 0), mirrored_arc.end_point, dxfattribs={"color": ezdxf.const.BLUE})

Result without applying the :func:`upright` function - true mirroring:

.. image:: gfx/upright_arc_0.png
    :align: center
    :width: 600px

.. code-block:: Python

    ...

    # This creates an inverted extrusion vector:
    assert mirrored_arc.dxf.extrusion.isclose((0, 0, -1))

    start_point_inv = mirrored_arc.start_point
    end_point_inv = mirrored_arc.end_point

    upright(mirrored_arc)
    # OCS is aligned with WCS:
    assert mirrored_arc.dxf.extrusion.isclose((0, 0, 1))

    # start- and end points are swapped after applying upright()
    assert mirrored_arc.start_point.isclose(end_point_inv)
    assert mirrored_arc.end_point.isclose(start_point_inv)

    # draw lines to the start- and end point of the mirrored ARC
    msp.add_line((0, 0), mirrored_arc.start_point, dxfattribs={"color": ezdxf.const.GREEN})
    msp.add_line((0, 0), mirrored_arc.end_point, dxfattribs={"color": ezdxf.const.BLUE})

Result after applying the :func:`upright` function - false mirroring:

.. image:: gfx/upright_arc_1.png
    :align: center
    :width: 600px

To avoid this issue the ARC entity would have to represent the curve in clockwise
orientation around the extrusion vector (0, 0, 1), which is not possible!

.. note::

    The shape of the mirrored arcs is the same for both extrusion vectors, but
    the start- and the end points are swapped (reversed vertex order)!