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)!
|