Release v0.17

By mozman, Fr 01 Oktober 2021, in category Release

attdef, attrib, drawing, dxf2code, explode, launcher, mpolygon, mtext, release, upright

Launcher

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

gear-pp

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.

Support for Config Files

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 files

For 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:

For more information read the documentation about document settings.

Store Custom Data in DXF files

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.

Support for the MPOLYGON entity

The MPOLYGON entity is supported by all internal modules and functions and the following add-ons:

upright Module

The 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:

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-on

This 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.

Configuration of the drawing Add-on

The 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

Extended MText Rendering for the drawing Add-on

Columns 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.

complex-mtext

Multi-Path Support for the ezdxf.path.Path Class

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

New Code Formatting Feature for the dxf2code Add-on

The 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')

Typed Table Factory Methods

With the addition of support for type annotations, typed factory methods were required to create resource table entries:

The 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:

Compose MText Content

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.

Create MText With Columns

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.

It is recommended to use DXF R2018 for MTEXT with columns!

DXF Entity Enhancements

Removed features

Environment variable options, these are config file only options now:

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.

Change Log

Version 0.17 - 2021-10-01

Release notes for v0.16: https://ezdxf.mozman.at/release-v0-16.html