Drawing / Export Add-on

This add-on provides the functionality to render a DXF document to produce a rasterized or vector-graphic image which can be saved to a file or viewed interactively depending on the backend being used.

The module provides two example scripts in the folder examples/addons/drawing which can be run to save rendered images to files or view an interactive visualisation.

$ ./draw_cad.py --supported_formats
# will list the file formats supported by the matplotlib backend.
# Many formats are supported including vector graphics formats
# such as pdf and svg

$ ./draw_cad.py <my_file.dxf> --out image.png

# draw a layout other than the model space
$ ./draw_cad.py <my_file.dxf> --layout Layout1 --out image.png

# opens a GUI application to view CAD files
$ ./cad_viewer.py

See also

How-to section for the FAQ about the Drawing Add-on.

Design

The implementation of the drawing add-on is divided into a frontend and multiple backends. The frontend handles the translation of DXF features and properties into simplified structures, which are then processed by the backends.

Common Limitations to all Backends

  • rich text formatting of the MTEXT entity is close to AutoCAD but not pixel perfect

  • relative size of POINT entities cannot be replicated exactly

  • rendering of ACIS entities is not supported

  • no 3D rendering engine, therefore:

    • 3D entities are projected into the xy-plane and 3D text is not supported

    • only top view rendering of the modelspace

    • VIEWPORTS are always rendered as top view

    • no VISUALSTYLE support

  • only basic support for:

    • infinite lines (rendered as lines with a finite length)

    • OLE2FRAME entities (rendered as rectangles)

    • vertical text (will render as horizontal text)

    • rendering of additional MTEXT columns may be incorrect

MatplotlibBackend

class ezdxf.addons.drawing.matplotlib.MatplotlibBackend(ax, *, adjust_figure=True, font=FontProperties(), use_text_cache=True)

Backend which uses the Matplotlib package for image export.

Parameters:
  • ax – drawing canvas as matplotlib.pyplot.Axes object

  • adjust_figure – automatically adjust the size of the parent matplotlib.pyplot.Figure to display all content

The MatplotlibBackend is used by the Draw command of the ezdxf launcher.

Example for the usage of the Matplotlib backend:

import sys
import matplotlib.pyplot as plt
from ezdxf import recover
from ezdxf.addons.drawing import RenderContext, Frontend
from ezdxf.addons.drawing.matplotlib import MatplotlibBackend

# Safe loading procedure (requires ezdxf v0.14):
try:
    doc, auditor = recover.readfile('your.dxf')
except IOError:
    print(f'Not a DXF file or a generic I/O error.')
    sys.exit(1)
except ezdxf.DXFStructureError:
    print(f'Invalid or corrupted DXF file.')
    sys.exit(2)

# The auditor.errors attribute stores severe errors,
# which may raise exceptions when rendering.
if not auditor.has_errors:
    fig = plt.figure()
    ax = fig.add_axes([0, 0, 1, 1])
    ctx = RenderContext(doc)
    out = MatplotlibBackend(ax)
    Frontend(ctx, out).draw_layout(doc.modelspace(), finalize=True)
    fig.savefig('your.png', dpi=300)

Simplified render workflow but with less control:

from ezdxf import recover
from ezdxf.addons.drawing import matplotlib

# Exception handling left out for compactness:
doc, auditor = recover.readfile('your.dxf')
if not auditor.has_errors:
    matplotlib.qsave(doc.modelspace(), 'your.png')
ezdxf.addons.drawing.matplotlib.qsave(layout: Layout, filename: str | PathLike, *, bg: str | None = None, fg: str | None = None, dpi: int = 300, backend: str = 'agg', config: Configuration | None = None, filter_func: Callable[[DXFGraphic], bool] | None = None, size_inches: tuple[float, float] | None = None) None

Quick and simplified render export by matplotlib.

Parameters:
  • layout – modelspace or paperspace layout to export

  • filename – export filename, file extension determines the format e.g. “image.png” to save in PNG format.

  • bg – override default background color in hex format #RRGGBB or #RRGGBBAA, e.g. use bg=”#FFFFFF00” to get a transparent background and a black foreground color (ACI=7), because a white background #FFFFFF gets a black foreground color or vice versa bg=”#00000000” for a transparent (black) background and a white foreground color.

  • fg – override default foreground color in hex format #RRGGBB or #RRGGBBAA, requires also bg argument. There is no explicit foreground color in DXF defined (also not a background color), but the ACI color 7 has already a variable color value, black on a light background and white on a dark background, this argument overrides this (ACI=7) default color value.

  • dpi – image resolution (dots per inches).

  • size_inches – paper size in inch as (width, height) tuple, which also defines the size in pixels = (width * dpi) x (height * dpi). If width or height is 0.0 the value is calculated by the aspect ratio of the drawing.

  • backend – the matplotlib rendering backend to use (agg, cairo, svg etc) (see documentation for matplotlib.use() for a complete list of backends)

  • config – drawing parameters

  • filter_func – filter function which takes a DXFGraphic object as input and returns True if the entity should be drawn or False if the entity should be ignored

PyQtBackend

class ezdxf.addons.drawing.pyqt.PyQtBackend(scene=None)

Backend which uses the PySide6 package to implement an interactive viewer. The PyQt5 package can be used as fallback if the PySide6 package is not available.

Parameters:

scene – drawing canvas of type QtWidgets.QGraphicsScene, if None a new canvas will be created

The PyQtBackend is used by the View command of the ezdxf launcher.

See also

The qtviewer.py module implements the core of a simple DXF viewer and the cad_viewer.py example is a skeleton to show how to launch the CADViewer class.

Recorder

New in version 1.1.

This is a special backend which records the output of the Frontend class in compact numpy arrays and these recordings and can be played by a Player instance on one or more backends. The recorded numpy arrays support measurement of bounding boxes and transformations which is for some backends a requirement to place the DXF content on size limited pages.

class ezdxf.addons.drawing.recorder.Recorder

Records the output of the Frontend class.

The class implements the BackendInterface but does not record enter_entity(), exit_entity() and clear() events.

player() Player

Returns a Player instance with the original recordings! Make a copy of this player to protect the original recordings from being modified:

safe_player = recorder.player().copy()
class ezdxf.addons.drawing.recorder.Player

Plays the recordings of the Recorder backend on another backend.

bbox() BoundingBox2d

Returns the bounding box of all records as BoundingBox2d.

copy() Self

Returns a copy of the player with non-shared recordings.

crop_rect(p1: UVec, p2: UVec, distance: float) None

Crop recorded shapes inplace by a rectangle defined by two points.

The argument distance defines the approximation precision for paths which have to be approximated as polylines for cropping but only paths which are really get cropped are approximated, paths that are fully inside the crop box will not be approximated.

Parameters:
  • p1 – first corner of the clipping rectangle

  • p2 – second corner of the clipping rectangle

  • distance – maximum distance from the center of the curve to the center of the line segment between two approximation points to determine if a segment should be subdivided.

recordings() Iterator[tuple[DataRecord, BackendProperties]]

Yields all recordings as (DataRecord, BackendProperties) tuples.

replay(backend: BackendInterface, override: Callable[[BackendProperties], Override] | None = None) None

Replay the recording on another backend that implements the BackendInterface. The optional override function can be used to override the properties and state of data records, it gets the BackendProperties as input and must return an Override instance.

transform(m: Matrix44) None

Transforms the recordings inplace by a transformation matrix m of type Matrix44.

class ezdxf.addons.drawing.recorder.Override(properties: BackendProperties, is_visible: bool = True)

Represents the override state for a data record.

properties

original or modified BackendProperties

Type:

ezdxf.addons.drawing.properties.BackendProperties

is_visible

override visibility e.g. switch layers on/off

Type:

bool

Layout

New in version 1.1.

The Layout class builds the page layout and the matrix to transform the DXF content to page coordinates according to the layout Settings. The DXF coordinate transformation is required for PDF and HPGL/2 which expects the output coordinates in the first quadrant and SVG which has an inverted y-axis.

The Layout class uses following classes and enums for configuration:

  • Page - page definition

  • Margins - page margins definition

  • Settings - configuration settings

  • Units - enum for page units

class ezdxf.addons.drawing.layout.Page(width: float, height: float, units: Units = Units.mm, margins: Margins = (0, 0, 0, 0), max_width: float = 0.0, max_height: float = 0.0)

Page definition class

width

page width, 0 for auto-detect

Type:

float

height

page height, 0 for auto-detect

Type:

float

units

page units as enum Units

Type:

ezdxf.addons.drawing.layout.Units

margins

page margins in page units

Type:

ezdxf.addons.drawing.layout.Margins

max_width

limit width for auto-detection, 0 for unlimited

Type:

float

max_height

limit height for auto-detection, 0 for unlimited

Type:

float

property is_landscape: bool

Returns True if the page has landscape orientation.

property is_portrait: bool

Returns True if the page has portrait orientation. (square is portrait)

classmethod from_dxf_layout(layout: DXFLayout) Self

Returns the Page based on the DXF attributes stored in the LAYOUT entity. The modelspace layout often doesn’t have usable page settings!

Parameters:

layout – any paperspace layout or the modelspace layout

get_margin_rect(top_origin=True) tuple[Vec2, Vec2]

Returns the bottom-left and the top-right corner of the page margins in mm. The origin (0, 0) is the top-left corner of the page if top_origin is True or in the bottom-left corner otherwise.

to_landscape() None

Converts the page to landscape orientation.

to_portrait() None

Converts the page to portrait orientation.

class ezdxf.addons.drawing.layout.Margins(top: float, right: float, bottom: float, left: float)

Page margins definition class

top
Type:

float

left
Type:

float

bottom
Type:

float

right
Type:

float

classmethod all(margin: float) Self

Returns a page margins definition class with four equal margins.

classmethod all2(top_bottom: float, left_right: float) Self

Returns a page margins definition class with equal top-bottom and left-right margins.

scale(factor: float) Self
class ezdxf.addons.drawing.layout.PageAlignment(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Page alignment of content as enum.

TOP_LEFT
TOP_CENTER
TOP_RIGHT
MIDDLE_LEFT
MIDDLE_CENTER
MIDDLE_RIGHT
BOTTOM_LEFT
BOTTOM_CENTER
BOTTOM_RIGHT
class ezdxf.addons.drawing.layout.Settings(content_rotation: int = 0, fit_page: bool = True, scale: float = 1.0, page_alignment: PageAlignment = PageAlignment.MIDDLE_CENTER, crop_at_margins: bool = False, max_stroke_width: float = 0.001, min_stroke_width: float = 0.05, fixed_stroke_width: float = 0.15, output_coordinate_space: float = 1000000)

The Layout settings.

content_rotation

Rotate content about 0, 90, 180 or 270 degrees

Type:

int

fit_page

Scale content to fit the page.

Type:

bool

page_alignment

Supported by backends that use the Page class to define the size of the output media, default alignment is PageAlignment.MIDDLE_CENTER

Type:

ezdxf.addons.drawing.layout.PageAlignment

crop_at_margins

crops the content at the page margins if True, when supported by the backend, default is False

Type:

bool

scale

Factor to scale the DXF units of model- or paperspace, to represent 1mm in the rendered output drawing. Only uniform scaling is supported.

e.g. scale 1:100 and DXF units are meters, 1m = 1000mm corresponds 10mm in the output drawing = 10 / 1000 = 0.01;

e.g. scale 1:1; DXF units are mm = 1 / 1 = 1.0 the default value

The value is ignored if the page size is defined and the content fits the page and the value is also used to determine missing page sizes (width or height).

Type:

float

max_stroke_width

Used for LineweightPolicy.RELATIVE policy, max_stroke_width is defined as percentage of the content extents, e.g. 0.001 is 0.1% of max(page-width, page-height)

Type:

float

min_stroke_width

Used for LineweightPolicy.RELATIVE policy, min_stroke_width is defined as percentage of max_stroke_width, e.g. 0.05 is 5% of max_stroke_width

Type:

float

fixed_stroke_width

Used for LineweightPolicy.RELATIVE_FIXED policy, fixed_stroke_width is defined as percentage of max_stroke_width, e.g. 0.15 is 15% of max_stroke_width

Type:

float

output_coordinate_space

expert feature to map the DXF coordinates to the output coordinate system [0, output_coordinate_space]

Type:

float

class ezdxf.addons.drawing.layout.Units(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Page units as enum.

inch

25.4 mm

px

1/96 inch

pt

1/72 inch

mm
cm

SVGBackend

New in version 1.1.

class ezdxf.addons.drawing.svg.SVGBackend

This is a native SVG rendering backend and does not require any external packages to render SVG images other than the core dependencies. This backend support content cropping at page margins.

get_xml_root_element(page: Page, *, settings: Settings = layout.Settings(), render_box: BoundingBox2d | None = None) Element
get_string(page: Page, *, settings: Settings = layout.Settings(), render_box: BoundingBox2d | None = None, xml_declaration=True) str

Returns the XML data as unicode string.

Parameters:
  • page – page definition, see Page

  • settings – layout settings, see Settings

  • render_box – set explicit region to render, default is content bounding box

  • xml_declaration – inserts the “<?xml version=’1.0’ encoding=’utf-8’?>” string in front of the <svg> element

Usage:

from ezdxf.addons.drawing import Frontend, RenderContext
from ezdxf.addons.drawing import layout, svg

doc = ezdxf.readfile("your.dxf")
msp = doc.modelspace()
backend = svg.SVGBackend()
Frontend(RenderContext(doc), backend).draw_layout(msp)

with open("your.svg", "wt") as fp:
    fp.write(backend.get_string(layout.Page(0, 0))

PyMuPdfBackend

New in version 1.1.

class ezdxf.addons.drawing.pymupdf.PyMuPdfBackend

This backend uses the PyMuPdf package to create PDF, PNG, PPM and PBM output. This backend support content cropping at page margins.

PyMuPDF is licensed under the AGPL. Sorry, but it’s the best package for the job I’ve found so far.

Install package:

pip install pymupdf
get_pdf_bytes(page: Page, *, settings: Settings = layout.Settings(), render_box: BoundingBox2d | None = None) bytes

Returns the PDF document as bytes.

Parameters:
  • page – page definition, see Page

  • settings – layout settings, see Settings

  • render_box – set explicit region to render, default is content bounding box

get_pixmap_bytes(page: Page, *, fmt='png', settings: Settings = layout.Settings(), dpi: int = 96, alpha=False, render_box: BoundingBox2d | None = None) bytes

Returns a pixel image as bytes, supported image formats:

png

Portable Network Graphics

ppm

Portable Pixmap (no alpha channel)

pbm

Portable Bitmap (no alpha channel)

Parameters:
  • page – page definition, see Page

  • fmt – image format

  • settings – layout settings, see Settings

  • dpi – output resolution in dots per inch

  • alpha – add alpha channel (transparency)

  • render_box – set explicit region to render, default is content bounding box

Usage:

import ezdxf
from ezdxf.addons.drawing import Frontend, RenderContext
from ezdxf.addons.drawing import layout, pymupdf

doc = ezdxf.readfile("your.dxf")
msp = doc.modelspace()
backend = pymupdf.PyMuPdfBackend()
Frontend(RenderContext(doc), backend).draw_layout(msp)

with open("your.pdf", "wb") as fp:
    fp.write(backend.get_pdf_bytes(layout.Page(0, 0))

Load the output of the PyMuPdfBackend into the Image class of the Pillow package for further processing or to output additional image formats:

import io
from PIL import Image

...  # see above

# the ppm format is faster to process than png
fp = io.BytesIO(backend.get_pixmap_bytes(layout.Page(0, 0), fmt="ppm", dpi=300))
image = Image.open(fp, formats=["ppm"])

PlotterBackend

New in version 1.1.

class ezdxf.addons.drawing.hpgl2.PlotterBackend

The PlotterBackend creates HPGL/2 plot files for output on raster plotters. This backend does not need any additional packages. This backend support content cropping at page margins.

The plot files are tested by the plot file viewer ViewCompanion Standard but not on real hardware - please use with care and give feedback.

get_bytes(page: Page, *, settings: Settings = layout.Settings(), render_box: BoundingBox2d | None = None, curves=True, decimal_places: int = 1, base=64) bytes

Returns the HPGL/2 data as bytes.

Parameters:
  • page – page definition, see Page

  • settings – layout settings, see Settings

  • render_box – set explicit region to render, default is content bounding box

  • curves – use Bèzier curves for HPGL/2 output

  • decimal_places – HPGL/2 output precision, less decimal places creates smaller files but for the price of imprecise curves (text)

  • base – base for polyline encoding, 32 for 7 bit encoding or 64 for 8 bit encoding

compatible(page: Page, settings: Settings = layout.Settings()) bytes

Returns the HPGL/2 data as 7-bit encoded bytes curves as approximated polylines and coordinates are rounded to integer values. Has often the smallest file size and should be compatible to all output devices but has a low quality text rendering.

low_quality(page: Page, settings: Settings = layout.Settings()) bytes

Returns the HPGL/2 data as 8-bit encoded bytes, curves as Bézier curves and coordinates are rounded to integer values. Has a smaller file size than normal quality and the output device must support 8-bit encoding and Bèzier curves.

normal_quality(page: Page, settings: Settings = layout.Settings()) bytes

Returns the HPGL/2 data as 8-bit encoded bytes, curves as Bézier curves and coordinates are floats rounded to one decimal place. Has a smaller file size than high quality and the output device must support 8-bit encoding, Bèzier curves and fractional coordinates.

high_quality(page: Page, settings: Settings = layout.Settings()) bytes

Returns the HPGL/2 data as 8-bit encoded bytes and all curves as Bézier curves and coordinates are floats rounded to two decimal places. Has the largest file size and the output device must support 8-bit encoding, Bèzier curves and fractional coordinates.

Usage:

import ezdxf
from ezdxf.addons.drawing import Frontend, RenderContext
from ezdxf.addons.drawing import layout, hpgl2

doc = ezdxf.readfile("your.dxf")
psp = doc.paperspace("Layout1")
backend = hpgl2.PlotterBackend()
Frontend(RenderContext(doc), backend).draw_layout(psp)
page = layout.Page.from_dxf_layout(psp)

with open("your.plt", "wb") as fp:
    fp.write(backend.normal_quality(page)

You can check the output by the HPGL/2 viewer:

ezdxf hpgl your.plt

DXFBackend

New in version 1.1.

class ezdxf.addons.drawing.dxf.DXFBackend(layout: BaseLayout, color_mode: ColorMode = ColorMode.RGB)

The DXFBackend creates simple DXF files of POINT, LINE, LWPOLYLINE and HATCH entities. This backend does ot need any additional packages.

Parameters:
class ezdxf.addons.drawing.dxf.ColorMode(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

This enum is used to define the color output mode of the DXFBackend.

ACI

the color is set as AutoCAD Color Index (ACI) and assigned by layer

RGB

the color is set as RGB true color value

Render a paperspace layout into modelspace:

import ezdxf
from ezdxf.addons.drawing import Frontend, RenderContext
from ezdxf.addons.drawing import layout, dxf

doc = ezdxf.readfile("your.dxf")
layout1 = doc.paperspace("Layout1")
output_doc = ezdxf.new()
output_msp = output_doc.modelspace()

backend = dxf.DXFBackend(output_msp)
Frontend(RenderContext(doc), backend).draw_layout(layout1)

output_doc.saveas("layout1_in_modelspace.dxf")

GeoJSONBackend

New in version 1.3.0.

class ezdxf.addons.drawing.json.GeoJSONBackend(properties_maker: Callable[[str, float, str], Dict[str, Any]] = properties_maker, transform_func: Callable[[Vec2], Tuple[float, float]] = no_transform)

Creates a JSON-like output according the GeoJSON scheme. GeoJSON uses a geographic coordinate reference system, World Geodetic System 1984 EPSG:4326, and units of decimal degrees.

  • Latitude: -90 to +90 (South/North)

  • Longitude: -180 to +180 (East/West)

So most DXF files will produce invalid coordinates and it is the job of the package-user to provide a function to transfrom the input coordinates to EPSG:4326! The Recorder and Player classes can help to detect the extents of the DXF content.

Default implementation:

no_transform(location: Vec2) tuple[float, float]

Dummy transformation function. Does not apply any transformations and just returns the input coordinates.

Factory function to make a transform function from WGS84 World Mercator EPSG:3395 coordinates to WGS84 (GPS) EPSG:4326.

make_world_mercator_to_gps_function(tol: float = 1e-6) Callable[[Vec2], Tuple[float, float]]

Returns a function to transform WGS84 World Mercator EPSG:3395 location given as cartesian 2D coordinates x, y in meters into WGS84 decimal degrees as longitude and latitude EPSG:4326 as used by GPS.

Parameters:

tol – accuracy for latitude calculation

The GeoJSON format supports only straight lines so curved shapes are flattened to polylines and polygons.

The properties are handled as a foreign member feature and is therefore not defined in the GeoJSON specs. It is possible to provide a custom function to create these property objects.

Default implementation:

properties_maker(color: str, stroke_width: float, layer: str) dict[str, Any]

Returns the property dict:

{
    "color": color,
    "stroke-width": stroke_width,
    "layer": layer,
}

Returning an empty dict prevents properties in the GeoJSON output and also avoids wraping entities into “Feature” objects.

Parameters:

properties_maker – function to create a properties dict.

Class Methods

get_json_data() dict[str, Any]

Returns the result as a JSON-like data structure according the GeoJSON specs.

get_string(*, indent: int | str = 2) str

Returns the result as a JSON string.

New in version 1.3.0.

CustomJSONBackend

New in version 1.3.0.

class ezdxf.addons.drawing.json.CustomJSONBackend(orient_paths=False)

Creates a JSON-like output with a custom JSON scheme. This scheme supports curved shapes by a SVG-path like structure and coordinates are not limited in any way. This backend can be used to send geometries from a web-backend to a frontend.

The JSON scheme is documented in the source code:

https://github.com/mozman/ezdxf/blob/master/src/ezdxf/addons/drawing/json.py

Parameters:

orient_paths – orient exterior and hole paths on demand, exterior paths have counter-clockwise orientation and holes have clockwise orientation.

Class Methods

get_json_data() list[dict[str, Any]]

Returns the result as a JSON-like data structure.

get_string(*, indent: int | str = 2) str

Returns the result as a JSON string.

New in version 1.3.0.

Configuration

Additional options for the drawing add-on can be passed by the config argument of the Frontend constructor __init__(). Not every option will be supported by all backends.

Usage:

my_config = Configuration(lineweight_scaling=2)
class ezdxf.addons.drawing.config.Configuration(pdsize: int | None = None, pdmode: int | None = None, measurement: Measurement | None = None, show_defpoints: bool = False, proxy_graphic_policy: ProxyGraphicPolicy = ProxyGraphicPolicy.SHOW, line_policy: LinePolicy = LinePolicy.ACCURATE, hatch_policy: HatchPolicy = HatchPolicy.NORMAL, infinite_line_length: float = 20, lineweight_scaling: float = 1.0, min_lineweight: float | None = None, min_dash_length: float = 0.1, max_flattening_distance: float = 0.01, circle_approximation_count: int = 128, hatching_timeout: float = 30.0, min_hatch_line_distance: float = 0.0001, color_policy: ColorPolicy = ColorPolicy.COLOR, custom_fg_color: str = '#000000', background_policy: BackgroundPolicy = BackgroundPolicy.DEFAULT, custom_bg_color: str = '#ffffff', lineweight_policy: LineweightPolicy = LineweightPolicy.ABSOLUTE, text_policy: TextPolicy = TextPolicy.FILLING, image_policy: ImagePolicy = ImagePolicy.DISPLAY)

Configuration options for the drawing add-on.

pdsize

the size to draw POINT entities (in drawing units) set to None to use the $PDSIZE value from the dxf document header

0

5% of draw area height

<0

Specifies a percentage of the viewport size

>0

Specifies an absolute size

None

use the $PDMODE value from the dxf document header

Type:

int | None

pdmode

point styling mode (see POINT documentation)

see Point class documentation

Type:

int | None

measurement

whether to use metric or imperial units as enum ezdxf.enums.Measurement

0

use imperial units (in, ft, yd, …)

1

use metric units (ISO meters)

None

use the $MEASUREMENT value from the dxf document header

Type:

ezdxf.enums.Measurement | None

show_defpoints

whether to show or filter out POINT entities on the defpoints layer

Type:

bool

proxy_graphic_policy

the action to take when a proxy graphic is encountered

Type:

ezdxf.addons.drawing.config.ProxyGraphicPolicy

line_policy

the method to use when drawing styled lines (eg dashed, dotted etc)

Type:

ezdxf.addons.drawing.config.LinePolicy

hatch_policy

the method to use when drawing HATCH entities

Type:

ezdxf.addons.drawing.config.HatchPolicy

infinite_line_length

the length to use when drawing infinite lines

Type:

float

lineweight_scaling

multiplies every lineweight by this factor; set this factor to 0.0 for a constant minimum line width defined by the min_lineweight setting for all lineweights; the correct DXF lineweight often looks too thick in SVG, so setting a factor < 1 can improve the visual appearance

Type:

float

min_lineweight

the minimum line width in 1/300 inch; set to None for let the backend choose.

Type:

float | None

min_dash_length

the minimum length for a dash when drawing a styled line (default value is arbitrary)

Type:

float

max_flattening_distance

Max flattening distance in drawing units see Path.flattening documentation. The backend implementation should calculate an appropriate value, like 1 screen- or paper pixel on the output medium, but converted into drawing units. Sets Path() approximation accuracy

Type:

float

circle_approximation_count

Approximate a full circle by n segments, arcs have proportional less segments. Only used for approximation of arcs in banded polylines.

Type:

int

hatching_timeout

hatching timeout for a single entity, very dense hatching patterns can cause a very long execution time, the default timeout for a single entity is 30 seconds.

Type:

float

min_hatch_line_distance

minimum hatch line distance to render, narrower pattern lines are rendered as solid filling

Type:

float

color_policy
Type:

ezdxf.addons.drawing.config.ColorPolicy

custom_fg_color

Used for ColorPolicy.custom policy, custom foreground color as “#RRGGBBAA” color string (RGB+alpha)

Type:

str

background_policy
Type:

ezdxf.addons.drawing.config.BackgroundPolicy

custom_bg_color

Used for BackgroundPolicy.custom policy, custom background color as “#RRGGBBAA” color string (RGB+alpha)

Type:

str

lineweight_policy
Type:

ezdxf.addons.drawing.config.LineweightPolicy

text_policy
Type:

ezdxf.addons.drawing.config.TextPolicy

image_policy

the method for drawing IMAGE entities

Type:

ezdxf.addons.drawing.config.ImagePolicy

with_changes()

Returns a new frozen Configuration object with modified values.

BackgroundPolicy

class ezdxf.addons.drawing.config.BackgroundPolicy(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

This enum is used to define the background color.

DEFAULT

as resolved by the Frontend class

WHITE

white background

BLACK

black background

PAPERSPACE

default paperspace background

MODELSPACE

default modelspace background

OFF

fully transparent background

CUSTOM

custom background color by Configuration.custom_bg_color

ColorPolicy

class ezdxf.addons.drawing.config.ColorPolicy(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

This enum is used to define how to determine the line/fill color.

COLOR

as resolved by the Frontend class

COLOR_SWAP_BW

as resolved by the Frontend class but swaps black and white

COLOR_NEGATIVE

invert all colors

MONOCHROME

maps all colors to gray scale in range [0%, 100%]

MONOCHROME_DARK_BG

maps all colors to gray scale in range [30%, 100%], brightens colors for dark backgrounds

MONOCHROME_LIGHT_BG

maps all colors to gray scale in range [0%, 70%], darkens colors for light backgrounds

BLACK

maps all colors to black

WHITE

maps all colors to white

CUSTOM

maps all colors to custom color Configuration.custom_fg_color

HatchPolicy

class ezdxf.addons.drawing.config.HatchPolicy(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

The action to take when a HATCH entity is encountered

NORMAL

render pattern and solid fillings

IGNORE

do not show HATCH entities at all

SHOW_OUTLINE

show only the outline of HATCH entities

SHOW_SOLID

show HATCH entities as solid filling regardless of the pattern

ImagePolicy

class ezdxf.addons.drawing.config.ImagePolicy(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

This enum is used to define the image rendering.

DISPLAY

display images as they would appear in a regular CAD application

RECT

display images as rectangles

MISSING

images are always rendered as-if they are missing (rectangle + path text)

PROXY

images are rendered using their proxy representations (rectangle)

IGNORE

ignore images entirely

LinePolicy

class ezdxf.addons.drawing.config.LinePolicy(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

This enum is used to define how to render linetypes.

Note

Text and shapes in linetypes are not supported.

SOLID

draw all lines as solid regardless of the linetype style

ACCURATE

render styled lines as accurately as possible

APPROXIMATE

ignored since v0.18.1 - uses always ACCURATE by default

LineweightPolicy

class ezdxf.addons.drawing.config.LineweightPolicy(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

This enum is used to define how to determine the lineweight.

ABSOLUTE

in mm as resolved by the Frontend class

RELATIVE

lineweight is relative to page size

RELATIVE_FIXED

fixed lineweight relative to page size for all strokes

ProxyGraphicPolicy

class ezdxf.addons.drawing.config.ProxyGraphicPolicy(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

The action to take when an entity with a proxy graphic is encountered

Note

To get proxy graphics support proxy graphics have to be loaded: Set the global option ezdxf.options.load_proxy_graphics to True, which is the default value.

This can not prevent drawing proxy graphic inside of blocks, because this is beyond the domain of the drawing add-on!

IGNORE

do not display proxy graphics (skip_entity will be called instead)

SHOW

if the entity cannot be rendered directly (e.g. if not implemented) but a proxy is present: display the proxy

PREFER

display proxy graphics even for entities where direct rendering is available

TextPolicy

class ezdxf.addons.drawing.config.TextPolicy(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

This enum is used to define the text rendering.

FILLING

text is rendered as solid filling (default)

OUTLINE

text is rendered as outline paths

REPLACE_RECT

replace text by a rectangle

REPLACE_FILL

replace text by a filled rectangle

IGNORE

ignore text entirely

Properties

class ezdxf.addons.drawing.properties.Properties

An implementation agnostic representation of DXF entity properties like color and linetype. These properties represent the actual values after resolving all DXF specific rules like “by layer”, “by block” and so on.

color

The actual color value of the DXF entity as “#RRGGBB” or “#RRGGBBAA” string. An alpha value of “00” is opaque and “ff” is fully transparent.

rgb

RGB values extract from the color value as tuple of integers.

luminance

Perceived luminance calculated from the color value as float in the range [0.0, 1.0].

linetype_name

The actual linetype name as string like “CONTINUOUS”

linetype_pattern

The simplified DXF linetype pattern as tuple of floats, all line elements and gaps are values greater than 0.0 and 0.0 represents a point. Line or point elements do always alternate with gap elements: line-gap-line-gap-point-gap and the pattern always ends with a gap. The continuous line is an empty tuple.

linetype_scale

The scaling factor as float to apply to the linetype_pattern.

lineweight

The absolute lineweight to render in mm as float.

is_visible

Visibility flag as bool.

layer

The actual layer name the entity resides on as UPPERCASE string.

font

The FontFace used for text rendering or None.

filling

The actual Filling properties of the entity or None.

units

The actual drawing units as InsertUnits enum.

LayerProperties

class ezdxf.addons.drawing.properties.LayerProperties

Actual layer properties, inherits from class Properties.

is_visible

Modified meaning: whether entities belonging to this layer should be drawn

layer

Modified meaning: stores real layer name (mixed case)

LayoutProperties

class ezdxf.addons.drawing.properties.LayoutProperties

Actual layout properties.

name

Layout name as string

units

Layout units as InsertUnits enum.

property LayoutProperties.background_color: str

Returns the default layout background color.

property LayoutProperties.default_color: str

Returns the default layout foreground color.

property LayoutProperties.has_dark_background: bool

Returns True if the actual background-color is “dark”.

LayoutProperties.set_colors(bg: str, fg: str | None = None) None

Setup default layout colors.

Required color format “#RRGGBB” or including alpha transparency “#RRGGBBAA”.

RenderContext

class ezdxf.addons.drawing.properties.RenderContext(doc: Drawing | None = None, *, ctb: str | CTB = '', export_mode: bool = False)

The render context for the given DXF document. The RenderContext resolves the properties of DXF entities from the context they reside in to actual values like RGB colors, transparency, linewidth and so on.

A given ctb file (plot style file) overrides the default properties for all layouts, which means the plot style table stored in the layout is always ignored.

Parameters:
  • doc – DXF document

  • ctb – path to a plot style table or a ColorDependentPlotStyles instance

  • export_mode – Whether to render the document as it would look when exported (plotted) by a CAD application to a file such as pdf, or whether to render the document as it would appear inside a CAD application.

resolve_aci_color(aci: int, resolved_layer: str) str

Resolve the aci color as hex color string: “#RRGGBB”

resolve_all(entity: DXFGraphic) Properties

Resolve all properties of entity.

resolve_color(entity: DXFGraphic, *, resolved_layer: str | None = None) str

Resolve the rgb-color of entity as hex color string: “#RRGGBB” or “#RRGGBBAA”.

resolve_filling(entity: DXFGraphic) Filling | None

Resolve filling properties (SOLID, GRADIENT, PATTERN) of entity.

resolve_font(entity: DXFGraphic) FontFace | None

Resolve the text style of entity to a font name. Returns None for the default font.

resolve_layer(entity: DXFGraphic) str

Resolve the layer of entity, this is only relevant for entities inside of block references.

resolve_layer_properties(layer: Layer) LayerProperties

Resolve layer properties.

resolve_linetype(entity: DXFGraphic, *, resolved_layer: str | None = None) tuple[str, Sequence[float]]

Resolve the linetype of entity. Returns a tuple of the linetype name as upper-case string and the simplified linetype pattern as tuple of floats.

resolve_lineweight(entity: DXFGraphic, *, resolved_layer: str | None = None) float

Resolve the lineweight of entity in mm.

DXF stores the lineweight in mm times 100 (e.g. 0.13mm = 13). The smallest line weight is 0 and the biggest line weight is 211. The DXF/DWG format is limited to a fixed value table, see: ezdxf.lldxf.const.VALID_DXF_LINEWEIGHTS

CAD applications draw lineweight 0mm as an undefined small value, to prevent backends to draw nothing for lineweight 0mm the smallest return value is 0.01mm.

resolve_units() InsertUnits
resolve_visible(entity: DXFGraphic, *, resolved_layer: str | None = None) bool

Resolve the visibility state of entity. Returns True if entity is visible.

set_current_layout(layout: Layout, ctb: str | CTB = '')

Set the current layout and update layout specific properties.

Parameters:
  • layout – modelspace or a paperspace layout

  • ctb – path to a plot style table or a ColorDependentPlotStyles instance

set_layer_properties_override(func: Callable[[Sequence[LayerProperties]], None] | None = None)

The function func is called with the current layer properties as argument after resetting them, so the function can override the layer properties.

The RenderContext class can be used isolated from the drawing add-on to resolve DXF properties.

Frontend

class ezdxf.addons.drawing.frontend.Frontend(ctx: RenderContext, out: BackendInterface, config: Configuration = Configuration.defaults(), bbox_cache: ezdxf.bbox.Cache = None)

Drawing frontend for 2D backends, responsible for decomposing entities into graphic primitives and resolving entity properties.

By passing the bounding box cache of the modelspace entities can speed up paperspace rendering, because the frontend can filter entities which are not visible in the VIEWPORT. Even passing in an empty cache can speed up rendering time when multiple viewports need to be processed.

Parameters:
  • ctx – the properties relevant to rendering derived from a DXF document

  • out – the 2D backend to draw to

  • config – settings to configure the drawing frontend and backend

  • bbox_cache – bounding box cache of the modelspace entities or an empty cache which will be filled dynamically when rendering multiple viewports or None to disable bounding box caching at all

log_message(message: str)

Log given message - override to alter behavior.

skip_entity(entity: DXFEntity, msg: str) None

Called for skipped entities - override to alter behavior.

override_properties(entity: DXFGraphic, properties: Properties) None

This method can change the resolved properties of an DXF entity.

The method has access to the DXF entity attributes, the current render context and the resolved properties. It is recommended to modify only the resolved properties in this method, because the DXF entities are not copies - except for virtual entities.

Changed in version 1.3.0: This method is the first function in the stack of new property override functions. It is possible to push additional override functions onto this stack, see also push_property_override_function().

push_property_override_function(override_fn: Callable[[DXFGraphic, Properties], None]) None

The override function can change the resolved properties of an DXF entity.

The override function has access to the DXF entity attributes and the resolved properties. It is recommended to modify only the resolved properties in this function, because the DXF entities are not copies - except for virtual entities.

The override functions are called after resolving the DXF attributes of an entity and before the Frontend.draw_entity() method in the order from first to last.

New in version 1.3.0.

pop_property_override_function() None

Remove the last function from the property override stack.

Does not raise an exception if the override stack is empty.

New in version 1.3.0.

draw_layout(layout: Layout, finalize: bool = True, *, filter_func: Callable[[DXFGraphic], bool] | None = None, layout_properties: LayoutProperties | None = None) None

Draw all entities of the given layout.

Draws the entities of the layout in the default or redefined redraw-order and calls the finalize() method of the backend if requested. The default redraw order is the ascending handle order not the order the entities are stored in the layout.

The method skips invisible entities and entities for which the given filter function returns False.

Parameters:
  • layout – layout to draw of type Layout

  • finalizeTrue if the finalize() method of the backend should be called automatically

  • filter_func – function to filter DXf entities, the function should return False if a given entity should be ignored

  • layout_properties – override the default layout properties

BackendInterface

class ezdxf.addons.drawing.backend.BackendInterface

Public interface definition for 2D rendering backends.

For more information read the source code: backend.py

Backend

class ezdxf.addons.drawing.backend.Backend

Abstract base class for concrete backend implementations and implements some default features.

For more information read the source code: backend.py

Details

The rendering is performed in two stages. The frontend traverses the DXF document structure, converting each encountered entity into primitive drawing commands. These commands are fed to a backend which implements the interface: Backend.

Although the resulting images will not be pixel-perfect with AutoCAD (which was taken as the ground truth when developing this add-on) great care has been taken to achieve similar behavior in some areas:

  • The algorithm for determining color should match AutoCAD. However, the color palette is not stored in the DXF file, so the chosen colors may be different to what is expected. The RenderContext class supports passing a plot style table (CTB-file) as custom color palette but uses the same palette as AutoCAD by default.

  • Text rendering is quite accurate, text positioning, alignment and word wrapping are very faithful. Differences may occur if a different font from what was used by the CAD application but even in that case, for supported backends, measurements are taken of the font being used to match text as closely as possible.

  • Visibility determination (based on which layers are visible) should match AutoCAD

See also