The new browse
command opens a DXF structure browser to investigate the
internals of a DXF file without interpreting the content. The functionality of
the DXF browser is similar to the DXF Pretty Printer, but without the
disadvantage of creating giant HTML files. The intended usage is debugging
invalid DXF files, which can not be loaded by ezdxf.readfile()
or the
ezdxf.recover.readfile()
functions.
C:\> ezdxf browse gear.dxf
The new command strip
removes all comment tags (999) and the THUMBNAILIMAGE
section.
The new command config
manages config files.
For more information read the launcher documentation.
Config files store global ezdxf
options in INI-files.
The default config files are loaded from the user home directory as
"~/.config/ezdxf/ezdxf.ini", and the current working directory as "./ezdxf.ini".
A custom config file can be specified by the environment variable EZDXF_CONFIG_FILE
.
Ezdxf follows the XDG Base Directory specification if the environment variable
XDG_CONFIG_HOME
is set.
For more information read the documentation about global options.
ezdxf
Meta Data in DXF filesFor debugging the ezdxf
version and date/time of creation or modification of
a DXF file is stored as meta data in DXF file itself. Ezdxf
uses standard DXF
features to store its meta data. This meta data is preserved by Autodesk products,
BricsCAD and of course ezdxf
. Other 3rd party DXF libraries may remove this
meta data.
The MetaData
object is open to store additional user data as strings:
import ezdxf
doc = ezdxf.new()
metadata = doc.ezdxf_metadata()
metadata["MyAdditionalUserData"] = "XYZ"
Keys used by ezdxf
:
CREATED_BY_EZDXF
WRITTEN_BY_EZDXF
For more information read the documentation about document settings.
New helper classes to store custom data in DXF files in a simple way.
For more information read the new tutorial about storing custom data in DXF files.
The MPOLYGON
entity is supported by all internal modules and functions and the
following add-ons:
drawing
dxf2code
geo
upright
ModuleThe upright()
and upright_all()
functions convert an inverted OCS defined
by an extrusion vector (0, 0, -1) into a 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 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)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 in the docs. 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
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:
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)
For more information read the upright documentation.
MTextExplode
Add-onThis tool is meant to explode MTEXT
entities into single line TEXT
entities
by replicating the MTEXT
layout as close as possible. This tool requires the
optional Matplotlib
package to create usable results, nonetheless it also
works without Matplotlib
, but then uses a mono-spaced replacement font for
text size measuring which leads to very inaccurate results.
Example to explode all MTEXT
entities in the DXF file "mtext.dxf":
import ezdxf
from ezdxf.addons import MTextExplode
doc = ezdxf.readfile("mtext.dxf")
msp = doc.modelspace()
# msp is the target layout for "exploded" parts of the MTEXT entity
with MTextExplode(msp) as xpl:
for mtext in msp.query("MTEXT"):
xpl.explode(mtext)
doc.saveas("xpl_mtext.dxf")
For more information read the MTextExplode documentation.
drawing
Add-onThe previous way to configure the drawing
add-on by passing an untyped dict
to the backend, has been replaced by a Configuration
dataclass, which is passed as the config
argument of the Frontend
class
initializer.
Excerpt from example file draw_cad.py
# required imports
from ezdxf.addons.drawing.config import Configuration, LinePolicy
# -x-x-x- snip
# create configuration
config = Configuration.defaults()
config = config.with_changes(
line_policy=LinePolicy.ACCURATE
if args.ltype == "ezdxf"
else config.line_policy
)
# -x-x-x- snip
# pass configuration to Frontend() class
Frontend(ctx, out, config=config).draw_layout(layout, finalize=True)
# -x-x-x- snip
drawing
Add-onColumns and inline formatting codes are now supported. Because this feature depends on the exact same font rendering as done by CAD applications, which cannot be replicated, results are close to CAD applications but are not perfect.
ezdxf.path.Path
ClassThe class ezdxf.path.Path
supports now multiple paths in one instance. This
required the new command move_to(location)
, which starts a new sub-path
at the given location
. The new property Path.has_sub_paths
is True
if
more than one path is present in an instance. The method Path.sub_paths()
yield all sub paths as single path instances, the utility function
ezdxf.path.single_paths()
does the same for an iterable of of single- or
multi-path objects.
The function ezdxf.path.to_multi_path()
builds a new multi-path object from
an iterable of single- or multi-path objects.
The converter function ezdxf.path.make_path()
supports now the HATCH
and the
MPOLYGON
entity directly and returns a multi-path instance with a sub-path
for each HATCH
boundary path. The converter function ezdxf.path.from_hatch()
still exist and returns all boundary paths of HATCH
entities as single-path
objects like in the previous versions of ezdxf
:
from ezdxf.path import make_path, from_hatch
# ...
paths = list(make_path(hatch).sub_paths())
# is the same as
paths = list(from_hatch(hatch))
dxf2code
Add-onThe method black_code_str()
returns the same code string as the
code_str()
method, but reformatted by the Black
formatting tool, if Black is installed.
import ezdxf
from ezdxf.addons.dxf2code import entities_to_code
doc = ezdxf.readfile('original.dxf')
msp = doc.modelspace()
source = entities_to_code(msp)
with open('source.py', mode='wt') as f:
f.write(source.import_str())
f.write('\n\n')
f.write(source.black_code_str())
f.write('\n')
With the addition of support for type annotations, typed factory methods were required to create resource table entries:
Drawing.layers.add()
factory method to create new layersDrawing.styles.add()
factory method to create new text stylesDrawing.linetypes.add()
factory method to create new line typesThe new recommended way to create layers, text styles or linetypes is:
import ezdxf
doc = ezdxf.new(setup=True)
doc.layers.add("MyLayer", color=2, linetype="DASHED")
doc.styles.add("Arial", font="arial.ttf")
doc.linetypes.add("DASHEDX3", [0.9, 0.8, -0.1], description="Dashed (3x) ___ ___ ___ ___ ___")
There are also new typed factory methods for all remaining resource tables, but they are not that important to library users:
Drawing.dimstyles.add()
Drawing.appids.add()
Drawing.ucs.add()
Drawing.views.add()
Drawing.viewports.add()
Drawing.block_records.add()
The MTextEditor
is a helper class to build MTEXT
content strings with
support for inline codes to change color, font or paragraph properties.
from ezdxf.tools.text import MTextEditor
e = MTextEditor("This example ").color("red").append("switches color to red.")
mtext = msp.add_mtext(str(e))
For more information see the docs
or the MTEXT
tutorial.
New factory methods to create MTEXT
entities with columns. The current
implementation works best for DXF R2018, because the content is stored as a
continuous text in a single MTEXT
entity.
For DXF versions prior to R2018 the content should be distributed across multiple
MTEXT
entities (one entity per column), which is not done by ezdxf
, but
the result is correct for advanced DXF viewers and CAD application, which
do the MTEXT
content distribution completely by itself.
BaseLayout.add_mtext_static_columns()
BaseLayout.add_mtext_dynamic_manual_height_columns()
BaseLayout.add_mtext_dynamic_auto_height_columns()
It is recommended to use DXF R2018 for MTEXT
with columns!
ezdxf.entity.MText
column support, parsing tools, composing toolsACAD_PROXY_ENTITY
entityATTRIB
and ATTDEF
entities in DXF R2018.Auditor
removes invalid DXF entities from layouts, blocks and the
OBJECTS sectionAuditor
removes invalid standalone ATTRIB
entities from layouts and
blocks.XDATA
section of a
DXF entity Environment variable options, these are config file only options now:
EZDXF_AUTO_LOAD_FONTS
EZDXF_FONT_CACHE_DIRECTORY
EZDXF_PRESERVE_PROXY_GRAPHICS
EZDXF_LOG_UNPROCESSED_TAGS
EZDXF_FILTER_INVALID_XDATA_GROUP_CODES
Removed the Vector
alias for the ezdxf.math.Vec3
class.
Removed the BaseLayout.add_attrib()
factory method to add (invalid) standalone
ATTRIB
entities
Removed the deprecated class methods from_...(entity)
from the
ezdxf.path.Path
class, use ezdxf.path.make_path(entity)
instead.
Also removed the deprecated ezdxf.path.Path
methods add_...(entity)
,
use path.add_...(path, entity)
function instead.
manylinux2010_x86_64
for Python < 3.10 and manylinux2014_x86_64
for Python >= 3.10 musllinux_2010_x86_64
for Python < 3.10 and musllinux_2014_x86_64
for Python >= 3.10manylinux_2014_aarch64
for ARM64 based Linuxmusllinux_2014_aarch64
for ARM64 based Linuxmacosx_11_0_arm64
for Apple siliconmacosx_10_9_universal2
for Apple silicon & x86MESH
entitiestransparency
argument to LayerTable.add()
BYLAYER
and BYBLOCK
for the drawing
add-onTextstyle.make_font()
returns the ezdxf font abstractiondxfattribs
argument to method Drawing.set_modelspace_vport()
ezdxf.math.split_bezier()
function to split Bezier curves of any degreeezdxf.math.intersection_line_line_3d()
ezdxf.math.intersect_poylines_2d()
ezdxf.math.intersect_poylines_3d()
ezdxf.math.quadratic_bezier_from_3p()
ezdxf.math.cubic_bezier_from_3p()
BoundingBox.contains()
, check if a bounding box contains completely
another bounding box TextEntityAlignment
enum replaces the string based alignment definitionText.get_placement()
, replaces get_pos()
Text.set_placement()
, replaces set_pos()
Text.get_align_enum()
, replaces get_align()
Text.set_align_enum()
, replaces set_align()
Text.get_pos()
will be removed in v1.0.0Text.set_pos()
will be removed in v1.0.0Text.get_align()
will be removed in v1.0.0Text.set_align()
will be removed in v1.0.0MTextEntityAlignment
to ezdxf.enums
MTextParagraphAlignment
to ezdxf.enums
MTextFlowDirection
to ezdxf.enums
MTextLineAlignment
to ezdxf.enums
MTextStroke
to ezdxf.enums
MTextLineSpacing
to ezdxf.enums
MTextBackgroundColor
to ezdxf.enums
Dimstyle.set_tolerance()
: argument align
as enum MTextLineAlignment
DimstyleOverride.set_tolerance()
: argument align
as enum MTextLineAlignment
MeshData.add_edge()
is changed to MeshData.add_edge_crease()
,
this fixes my misunderstanding of edge and crease data in the MESH
entity. Path()
and ConstructionEllipse()
drawing
add-on shows block references in ACAD_TABLE
at the
correct locationPolyface.virtual_entities()
yields correct triangle facesMESH
entity PyQt5
is still supported as fallbackDXFEntity
source_of_copy
- the immediate source of an entity copyorigin_of_copy
- the first non virtual source entity of an entity copyis_copy
- is True
if the entity is a copyPOINT
, LWPOLYLINE
, POLYLINE
, LEADER
, MLINE
, ACAD_PROXY_ENTITY
DXFEntity
has_source_block_reference
- is True
if the virtual entity was created
by a block referencesource_block_reference
- the immediate source block reference (INSERT
),
which created the virtual entity, otherwise None
ezdxf.tools.text_size
module to measure TEXT
and MTEXT
entity dimensions--ltype
arguments of the draw
command to approximate
and accurate
to be in sync with the drawing
add-on configuration.--ltype
arguments of the view
command to approximate
and accurate
to be in sync with the drawing
add-on configuration.--scale
argument of the view
commandPolylinePath.PATH_TYPE
, use PolylinePath.type
insteadEdgePath.PATH_TYPE
, use EdgePath.type
insteadXData.safe_init()
DIMSTYLE
attribute dimtxsty
browse
command MTEXT
entities with column count different than the count of
linked MTEXT
entities BaseLayout.add_mtext_static_columns()
BaseLayout.add_mtext_dynamic_manual_height_columns()
MTextExplode()
to explode MTEXT entities
into single line TEXT entities and additional LINE entities to emulate
strokes, requires the Matplotlib
packagemove_to()
command and multi-path support for the ezdxf.path.Path
class make_path()
support for the HATCH entity, returns a multi-path object make_primitive()
support for the HATCH entity text2path.make_path_from_str()
returns a multi-path object text2path.make_path_from_enity()
returns a multi-path object MPOLYGON
load/write/create supportezdxf.path.to_mpolygons()
function: Path() to MPOLYGON converterezdxf.path.render_mpolygons()
function: render MPOLYGON entities form pathsezdxf browse FILE ...
, PyQt DXF structure browserdxf2code
add-on: function black()
and method Code.black_code_str()
returns the code string formatted by Blackezdxf.upright
module to flip inverted extrusion vectors, for more
information read the docs ACAD_PROXY_ENTITY
BaseLayout.add_mtext_static_columns()
BaseLayout.add_mtext_dynamic_manual_height_columns()
MTEXT
entities for the drawing
add-onXDATA
transformation supportdrawing
add-on: replaced the backend params
argument (untyped dict)
by the new typed Configuration
object passed to the frontend class as
argument config
from_...(entity)
from Path
class,
use path.make_path(entity)
insteadPath
methods add_...(entity)
,
use path.add_...(path, entity)
function insteadexec_path
as win_exec_path
DICTIONARY
entries DICTIONARY
was not added to the OBJECTS section by calling factory.bind()
XRecord.copy()
copies content tagsRelease notes for v0.16: https://ezdxf.mozman.at/release-v0-16.html