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
objectadjust_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 orFalse
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. ThePyQt5
package can be used as fallback if thePySide6
package is not available.- Parameters:
scene – drawing canvas of type
QtWidgets.QGraphicsScene
, ifNone
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¶
Added 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 recordenter_entity()
,exit_entity()
andclear()
events.
- 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 theBackendProperties
as input and must return anOverride
instance.
- 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¶
Added 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 definitionMargins
- page margins definitionSettings
- configuration settingsUnits
- 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
- margins¶
page margins in page units
- 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=_not_given, *values, 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, output_layers: bool = True)¶
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 isPageAlignment.MIDDLE_CENTER
- crop_at_margins¶
crops the content at the page margins if
True
, when supported by the backend, default isFalse
- 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 ofmax_stroke_width
, e.g. 0.05 is 5% ofmax_stroke_width
- Type:
float
- fixed_stroke_width¶
Used for
LineweightPolicy.RELATIVE_FIXED
policy,fixed_stroke_width
is defined as percentage ofmax_stroke_width
, e.g. 0.15 is 15% ofmax_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
- output_layers¶
For supported backends, separate the entities into ‘layers’ in the output
- Type:
bool
SVGBackend¶
Added 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.
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¶
Added 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.
- 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)
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¶
Added 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¶
Added 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:
layout – a DXF
BaseLayout
color_mode – see
ColorMode
- class ezdxf.addons.drawing.dxf.ColorMode(value, names=_not_given, *values, 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¶
Added 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
andPlayer
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.
Added in version 1.3.0.
CustomJSONBackend¶
Added 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.
Added 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
- 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
- line_policy¶
the method to use when drawing styled lines (eg dashed, dotted etc)
- hatch_policy¶
the method to use when drawing HATCH entities
- 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¶
- custom_fg_color¶
Used for
ColorPolicy.custom
policy, custom foreground color as “#RRGGBBAA” color string (RGB+alpha)- Type:
str
- background_policy¶
- custom_bg_color¶
Used for
BackgroundPolicy.custom
policy, custom background color as “#RRGGBBAA” color string (RGB+alpha)- Type:
str
- lineweight_policy¶
- text_policy¶
- image_policy¶
the method for drawing IMAGE entities
- with_changes()¶
Returns a new frozen
Configuration
object with modified values.
BackgroundPolicy¶
- class ezdxf.addons.drawing.config.BackgroundPolicy(value, names=_not_given, *values, 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=_not_given, *values, 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=_not_given, *values, 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=_not_given, *values, 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=_not_given, *values, 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=_not_given, *values, 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=_not_given, *values, 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
toTrue
, 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=_not_given, *values, 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.
- 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 orNone
.
- filling¶
The actual
Filling
properties of the entity orNone
.
- units¶
The actual drawing units as
InsertUnits
enum.
LayerProperties¶
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
instanceexport_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.Added 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.
Added 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
finalize –
True
if thefinalize()
method of the backend should be called automaticallyfilter_func – function to filter DXf entities, the function should return
False
if a given entity should be ignoredlayout_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
draw_cad.py for a simple use of this module
cad_viewer.py for an advanced use of this module
Notes on Rendering DXF Content for additional behaviours documented during the development of this add-on.