EZDXF(1) | ezdxf | EZDXF(1) |
ezdxf - ezdxf Documentation [image]
Welcome! This is the documentation for ezdxf release 0.14.2, last updated Nov 27, 2020.
https://ezdxf.mozman.at/
Documentation of development version at https://ezdxf.mozman.at/docs
Documentation of latest release at http://ezdxf.readthedocs.io/
Source Code: http://github.com/mozman/ezdxf.git
Issue Tracker at GitHub: http://github.com/mozman/ezdxf/issues
Please post questions at the forum or stack overflow to make answers available to other users as well.
ezdxf is a Python interface to the DXF (drawing interchange file) format developed by Autodesk, it allows developers to read and modify existing DXF drawings or create new DXF drawings.
The main objective in the development of ezdxf was to hide complex DXF details from the programmer but still support most capabilities of the DXF format. Nevertheless, a basic understanding of the DXF format is required, also to understand which tasks and goals are possible to accomplish by using the the DXF format.
Not all DXF features are supported yet, but additional features will be added in the future gradually.
ezdxf is also a replacement for my dxfwrite and my dxfgrabber packages but with different APIs, for more information see also: faq001
ezdxf requires at least Python 3.6 and will be tested with the latest stable CPython 3 version and the latest stable release of pypy3 during development.
ezdxf is written in pure Python and requires only pyparser as additional library beside the Python Standard Library. pytest is required to run the unit- and integration tests. Data to run the stress and audit test can not be provided, because I don’t have the rights for publishing this DXF files.
ezdxf is OS independent and runs on all platforms which provide an appropriate Python interpreter (>=3.6).
Version | AutoCAD Release |
AC1009 | AutoCAD R12 |
AC1012 | AutoCAD R13 -> R2000 |
AC1014 | AutoCAD R14 -> R2000 |
AC1015 | AutoCAD R2000 |
AC1018 | AutoCAD R2004 |
AC1021 | AutoCAD R2007 |
AC1024 | AutoCAD R2010 |
AC1027 | AutoCAD R2013 |
AC1032 | AutoCAD R2018 |
ezdxf reads also older DXF versions but saves it as DXF R12.
The DXF format allows third-party applications to embed application-specific information. ezdxf manages DXF data in a structure-preserving form, but for the price of large memory requirement. Because of this, processing of DXF information of third-party applications is possible and will retained on rewriting.
ezdxf is licensed under the very liberal MIT-License.
This section shows the intended usage of the ezdxf package. This is just a brief overview for new ezdxf users, follow the provided links for more detailed information.
First import the package:
import ezdxf
ezdxf supports loading ASCII and binary DXF files from a file:
doc = ezdxf.readfile(filename)
or from a zip-file:
doc = ezdxf.readzip(zipfilename[, filename])
Which loads the DXF file filename from the zip-file zipfilename or the first DXF file in the zip-file if filename is absent.
It is also possible to read a DXF file from a stream by the ezdxf.read() function, but this is a more advanced feature, because this requires detection of the file encoding in advance.
This works well with DXF files from trusted sources like AutoCAD or BricsCAD, for loading DXF files with minor or major flaws look at the ezdxf.recover module.
SEE ALSO:
Save the DXF document with a new name:
doc.saveas('new_name.dxf')
or with the same name as loaded:
doc.save()
SEE ALSO:
Create new file for the latest supported DXF version:
doc = ezdxf.new()
Create a new DXF file for a specific DXF version, e.g for DXF R12:
doc = ezdxf.new('R12')
To setup some basic DXF resources use the setup argument:
doc = ezdxf.new(setup=True)
SEE ALSO:
Layouts are containers for DXF entities like LINE or CIRCLE. The most important layout is the modelspace labeled as “Model” in CAD applications which represents the “world” work space. Paperspace layouts represents plottable sheets which contains often the framing and the tile block of a drawing and VIEWPORT entities as scaled and clipped “windows” into the modelspace.
The modelspace is always present and can not be deleted. The active paperspace is also always present in a new DXF document but can be deleted, in that case another paperspace layout gets the new active paperspace, but you can not delete the last paperspace layout.
Getting the modelspace of a DXF document:
msp = doc.modelspace()
Getting a paperspace layout by the name as shown in the tab of a CAD application:
psp = doc.layout('Layout1')
A block is just another kind of entity space, which can be inserted multiple times into other layouts and blocks by the INSERT entity also called block references, this is a very powerful and important concept of the DXF format.
Getting a block layout by the block name:
blk = doc.blocks.get('NAME')
All these layouts have factory functions to create graphical DXF entities for their entity space, for more information about creating entities see section: Create new DXF Entities
The block definitions of a DXF document are managed by the BlocksSection object:
my_block = doc.blocks.new('MyBlock')
SEE ALSO:
As said in the Layouts and Blocks section, all graphical DXF entities are stored in layouts, all these layouts can be iterated and support the index operator e.g. layout[-1] returns the last entity.
The main difference between iteration and index access is, that iteration filters destroyed entities, but the the index operator returns also destroyed entities until these entities are purged by layout.purge() more about this topic in section: Delete Entities.
There are two advanced query methods: query() and groupby().
Get all lines of layer 'MyLayer':
lines = msp.query('LINE[layer=="MyLayer"]')
This returns an EntityQuery container, which also provides the same query() and groupby() methods.
Get all lines categorized by a DXF attribute like color:
all_lines_by_color = msp.query('LINE').groupby('color') lines_with_color_1 = all_lines_by_color.get(1, [])
The groupby() method returns a regular Python dict with colors as key and a regular Python list of entities as values (not an EntityQuery container).
SEE ALSO:
Each DXF entity has a dxf namespace attribute, which stores the named DXF attributes, some DXF attributes are only indirect available like the vertices in the LWPOLYLINE entity. More information about the DXF attributes of each entity can found in the documentation of the ezdxf.entities module.
Get some basic DXF attributes:
layer = entity.dxf.layer # default is '0' color = entity.dxf.color # default is 256 = BYLAYER
Most DXF attributes have a default value, which will be returned if the DXF attribute is not present, for DXF attributes without a default value you can check in the attribute really exist:
entity.dxf.hasattr('true_color')
or use the get() method and a default value:
entity.dxf.get('true_color', 0)
SEE ALSO:
The factory functions for creating new graphical DXF entities are located in the BaseLayout class. This means this factory function are available for all entity containers:
The usage is simple:
msp = doc.modelspace() msp.add_line((0, 0), (1, 0), dxfattribs={'layer': 'MyLayer'})
A few important or required DXF attributes are explicit method arguments, most additional and optional DXF attributes are gives as a regular Python dict object. The supported DXF attributes can be found in the documentation of the ezdxf.entities module.
WARNING:
A block reference is just another DXF entity called INSERT, but the term “Block Reference” is a better choice and so the Insert entity is created by the factory function: add_blockref():
msp.add_blockref('MyBlock')
SEE ALSO:
A layer is not an entity container, a layer is just another DXF attribute stored in the entity and this entity can inherit some properties from this Layer object. Layer objects are stored in the layer table which is available as attribute doc.layers.
You can create your own layers:
my_layer = doc.layer.new('MyLayer')
The layer object also controls the visibility of entities which references this layer, the on/off state of the layer is unfortunately stored as positive or negative color value which make the raw DXF attribute of layers useless, to change the color of a layer use the property Layer.color
my_layer.color = 1
To change the state of a layer use the provided methods of the Layer object, like on(), off(), freeze() or thaw():
my_layer.off()
SEE ALSO:
The safest way to delete entities is to delete the entity from the layout containing that entity:
line = msp.add_line((0, 0), (1, 0)) msp.delete_entity(line)
This removes the entity immediately from the layout and destroys the entity. The property is_alive returns False for a destroyed entity and all Python attributes are deleted, so line.dxf.color will raise an AttributeError exception, because line does not have a dxf attribute anymore.
The current version of ezdxf also supports also destruction of entities by calling method destroy() manually:
line.destroy()
Manually destroyed entities are not removed immediately from entities containers like Modelspace or EntityQuery, but iterating such a container will filter destroyed entities automatically, so a for e in msp: ... loop will never yield destroyed entities. The index operator and the len() function do not filter deleted entities, to avoid getting deleted entities call the purge() method of the container manually to remove deleted entities.
The Basic Concepts section teach the intended meaning of DXF attributes and structures without teaching the application of this information or the specific implementation by ezdxf, if you are looking for more information about the ezdxf internals look at the Reference section or if you want to learn how to use ezdxf go to the Tutorials section and for the solution of specific problems go to the Howto section.
The color attribute represents an ACI (AutoCAD Color Index). AutoCAD and many other CAD application provides a default color table, but pen table would be the more correct term. Each ACI entry defines the color value, the line weight and some other attributes to use for the pen. This pen table can be edited by the user or loaded from an CTB or STB file. ezdxf provides functions to create (new()) or modify (ezdxf.acadctb.load()) plot styles files.
DXF R12 and prior are not good in preserving the layout of a drawing, because of the lack of a standard color table defined by the DXF reference and missing DXF structures to define these color tables in the DXF file. So if a CAD user redefined an ACI and do not provide a CTB or STB file, you have no ability to determine which color or lineweight was used. This is better in later DXF versions by providing additional DXF attributes like lineweight and true_color.
SEE ALSO:
Every object has a layer as one of its properties. You may be familiar with layers - independent drawing spaces that stack on top of each other to create an overall image - from using drawing programs. Most CAD programs use layers as the primary organizing principle for all the objects that you draw. You use layers to organize objects into logical groups of things that belong together; for example, walls, furniture, and text notes usually belong on three separate layers, for a couple of reasons:
Create a layer table entry Layer by Drawing.layers.new(), assign the layer properties such as color and linetype. Then assign those layers to other DXF entities by setting the DXF attribute layer to the layer name as string.
It is possible to use layers without a layer definition but not recommend, just use a layer name without a layer definition, the layer has the default linetype 'Continuous' and the default color is 7.
The advantage of assigning a linetype and a color to a layer is that entities on this layer can inherit this properties by using 'BYLAYER' as linetype string and 256 as color, both values are default values for new entities.
SEE ALSO:
The linetype defines the pattern of a line. The linetype of an entity can be specified by the DXF attribute linetype, this can be an explicit named linetype or the entity can inherit its line type from the assigned layer by setting linetype to 'BYLAYER', which is also the default value. CONTINUOUS is the default line type for layers with unspecified line type.
ezdxf creates several standard linetypes, if the argument setup is True at calling new(), this simple line types are supported by all DXF versions:
doc = ezdxf.new('R2007', setup=True)
In DXF R13 Autodesk introduced complex linetypes, containing TEXT or SHAPES in linetypes. ezdxf v0.8.4 and later supports complex linetypes.
SEE ALSO:
Global linetype scaling can be changed by setting the header variable doc.header['$LTSCALE'] = 2, which stretches the line pattern by factor 2.
To change the linetype scaling for single entities set scaling factor by DXF attribute ltscale, which is supported since DXF version R2000.
AutoLISP Reference to Coordinate Systems provided by Autodesk.
To brush up you knowledge about vectors, watch the YouTube tutorials of 3Blue1Brown about Linear Algebra.
World coordinate system - the reference coordinate system. All other coordinate systems are defined relative to the WCS, which never changes. Values measured relative to the WCS are stable across changes to other coordinate systems.
User coordinate system - the working coordinate system defined by the user to make drawing tasks easier. All points passed to AutoCAD commands, including those returned from AutoLISP routines and external functions, are points in the current UCS. As far as I know, all coordinates stored in DXF files are always WCS or OCS never UCS.
User defined coordinate systems are not just helpful for interactive CAD, therefore ezdxf provides a converter class UCS to translate coordinates from UCS into WCS and vice versa, but always remember: store only WCS or OCS coordinates in DXF files, because there is no method to determine which UCS was active or used to create UCS coordinates.
SEE ALSO:
Object coordinate system - coordinates relative to the object itself. These points are usually converted into the WCS, current UCS, or current DCS, according to the intended use of the object. Conversely, points must be translated into an OCS before they are written to the database. This is also known as the entity coordinate system.
Because ezdxf is just an interface to DXF, it does not automatically convert OCS into WCS, this is the domain of the user/application. And further more, the main goal of OCS is to place 2D elements in 3D space, this maybe was useful in the early years of CAD, I think nowadays this is an not often used feature, but I am not an AutoCAD user.
OCS differ from WCS only if extrusion != (0, 0, 1), convert OCS into WCS:
# circle is an DXF entity with extrusion != (0, 0, 1) ocs = circle.ocs() wcs_center = ocs.to_wcs(circle.dxf.center)
SEE ALSO:
Display coordinate system - the coordinate system into which objects are transformed before they are displayed. The origin of the DCS is the point stored in the AutoCAD system variable TARGET, and its z-axis is the viewing direction. In other words, a viewport is always a plan view of its DCS. These coordinates can be used to determine where something will be displayed to the AutoCAD user.
The points associated with each entity are expressed in terms of the entity’s own object coordinate system (OCS). The OCS was referred to as ECS in previous releases of AutoCAD.
With OCS, the only additional information needed to describe the entity’s position in 3D space is the 3D vector describing the z-axis of the OCS, and the elevation value.
For a given z-axis (or extrusion) direction, there are an infinite number of coordinate systems, defined by translating the origin in 3D space and by rotating the x- and y-axis around the z-axis. However, for the same z-axis direction, there is only one OCS. It has the following properties:
These entities do not lie in a particular plane. All points are expressed in world coordinates. Of these entities, only lines and points can be extruded. Their extrusion direction can differ from the world z-axis.
These entities are planar in nature. All points are expressed in object coordinates. All of these entities can be extruded. Their extrusion direction can differ from the world z-axis.
Some of a Dimension’s points are expressed in WCS and some in OCS.
Elevation group code 38:
Exists only in output from versions prior to R11. Otherwise, Z coordinates are supplied as part of each of the entity’s defining points.
The arbitrary axis algorithm is used by AutoCAD internally to implement the arbitrary but consistent generation of object coordinate systems for all entities that use object coordinates.
Given a unit-length vector to be used as the z-axis of a coordinate system, the arbitrary axis algorithm generates a corresponding x-axis for the coordinate system. The y-axis follows by application of the right-hand rule.
We are looking for the arbitrary x- and y-axis to go with the normal Az (the arbitrary z-axis). They will be called Ax and Ay (using Vector):
Az = Vector(entity.dxf.extrusion).normalize() # normal (extrusion) vector # Extrusion vector normalization should not be necessary, but don't rely on any DXF content if (abs(Az.x) < 1/64.) and (abs(Az.y) < 1/64.):
Ax = Vector(0, 1, 0).cross(Az).normalize() # the cross-product operator else:
Ax = Vector(0, 0, 1).cross(Az).normalize() # the cross-product operator Ay = Az.cross(Ax).normalize()
def wcs_to_ocs(point):
px, py, pz = Vector(point) # point in WCS
x = px * Ax.x + py * Ax.y + pz * Ax.z
y = px * Ay.x + py * Ay.y + pz * Ay.z
z = px * Az.x + py * Az.y + pz * Az.z
return Vector(x, y, z)
Wx = wcs_to_ocs((1, 0, 0)) Wy = wcs_to_ocs((0, 1, 0)) Wz = wcs_to_ocs((0, 0, 1)) def ocs_to_wcs(point):
px, py, pz = Vector(point) # point in OCS
x = px * Wx.x + py * Wx.y + pz * Wx.z
y = px * Wy.x + py * Wy.y + pz * Wy.z
z = px * Wz.x + py * Wz.y + pz * Wz.z
return Vector(x, y, z)
In this tutorial I show you how to get data from an existing DXF drawing.
Loading the DXF file:
import sys import ezdxf try:
doc = ezdxf.readfile("your_dxf_file.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)
This works well with DXF files from trusted sources like AutoCAD or BricsCAD, for loading DXF files with minor or major flaws look at the ezdxf.recover module.
SEE ALSO:
I use the term layout as synonym for an arbitrary entity space which can contain DXF entities like LINE, CIRCLE, TEXT and so on. Every DXF entity can only reside in exact one layout.
There are three different layout types:
A DXF drawing consist of exact one modelspace and at least of one paperspace. DXF R12 has only one unnamed paperspace the later DXF versions support more than one paperspace and each paperspace has a name.
Iterate over all DXF entities in modelspace. Although this is a possible way to retrieve DXF entities, I would like to point out that entity queries are the better way.
# iterate over all entities in modelspace msp = doc.modelspace() for e in msp:
if e.dxftype() == 'LINE':
print_entity(e) # entity query for all LINE entities in modelspace for e in msp.query('LINE'):
print_entity(e) def print_entity(e):
print("LINE on layer: %s\n" % e.dxf.layer)
print("start point: %s\n" % e.dxf.start)
print("end point: %s\n" % e.dxf.end)
All layout objects supports the standard Python iterator protocol and the in operator.
Check the type of an DXF entity by e.dxftype(). The DXF type is always uppercase. All DXF attributes of an entity are grouped in the namespace attribute dxf:
e.dxf.layer # layer of the entity as string e.dxf.color # color of the entity as integer
See Common graphical DXF attributes
If a DXF attribute is not set (a valid DXF attribute has no value), a DXFValueError will be raised. To avoid this use the get_dxf_attrib() method with a default value:
# If DXF attribute 'paperspace' does not exist, the entity defaults # to modelspace: p = e.get_dxf_attrib('paperspace', 0)
An unsupported DXF attribute raises an DXFAttributeError.
paperspace = doc.layout('layout0')
Retrieves the paperspace named layout0, the usage of the Layout object is the same as of the modelspace object. DXF R12 provides only one paperspace, therefore the paperspace name in the method call doc.layout('layout0') is ignored or can be left off. For the later DXF versions you get a list of the names of the available layouts by layout_names().
ezdxf provides a flexible query language for DXF entities. All layout types have a query() method to start an entity query or use the ezdxf.query.new() function.
The query string is the combination of two queries, first the required entity query and second the optional attribute query, enclosed in square brackets: 'EntityQuery[AttributeQuery]'
The entity query is a whitespace separated list of DXF entity names or the special name *. Where * means all DXF entities, all other DXF names have to be uppercase. The * search can exclude entity types by adding the entity name with a presceding ! (e.g. * !LINE, search all entities except lines).
The attribute query is used to select DXF entities by its DXF attributes. The attribute query is an addition to the entity query and matches only if the entity already match the entity query. The attribute query is a boolean expression, supported operators: and, or, !.
SEE ALSO:
Get all LINE entities from the modelspace:
msp = doc.modelspace() lines = msp.query('LINE')
The result container EntityQuery also provides the query() method, get all LINE entities at layer construction:
construction_lines = lines.query('*[layer=="construction"]')
The * is a wildcard for all DXF types, in this case you could also use LINE instead of *, * works here because lines just contains entities of DXF type LINE.
All together as one query:
lines = msp.query('LINE[layer=="construction"]')
The ENTITIES section also supports the query() method:
lines_and_circles = doc.entities.query('LINE CIRCLE[layer=="construction"]')
Get all modelspace entities at layer construction, but excluding entities with linetype DASHED:
not_dashed_entities = msp.query('*[layer=="construction" and linetype!="DASHED"]')
Search and group entities by a user defined criteria. As example let’s group all entities from modelspace by layer, the result will be a dict with layer names as dict-key and a list of all entities from modelspace matching this layer as dict-value. Usage as dedicated function call:
from ezdxf.groupby import groupby group = groupby(entities=msp, dxfattrib='layer')
The entities argument can be any container or generator which yields DXFEntity or inherited objects. Shorter and simpler to use as method of BaseLayout (modelspace, paperspace layouts, blocks) and query results as EntityQuery objects:
group = msp.groupby(dxfattrib='layer') for layer, entities in group.items():
print(f'Layer "{layer}" contains following entities:')
for entity in entities:
print(' {}'.format(str(entity)))
print('-'*40)
The previous example shows how to group entities by a single DXF attribute, but it is also possible to group entities by a custom key, to do so create a custom key function, which accepts a DXF entity as argument and returns a hashable value as dict-key or None to exclude the entity. The following example shows how to group entities by layer and color, so each result entry has a tuple (layer, color) as key and a list of entities with matching DXF attributes:
def layer_and_color_key(entity):
# return None to exclude entities from result container
if entity.dxf.layer == '0': # exclude entities from default layer '0'
return None
else:
return entity.dxf.layer, entity.dxf.color group = msp.groupby(key=layer_and_color_key) for key, entities in group.items():
print(f'Grouping criteria "{key}" matches following entities:')
for entity in entities:
print(' {}'.format(str(entity)))
print('-'*40)
To exclude entities from the result container the key function should return None. The groupby() function catches DXFAttributeError exceptions while processing entities and excludes this entities from the result container. So there is no need to worry about DXF entities which do not support certain attributes, they will be excluded automatically.
SEE ALSO:
r12writer - create simple DXF R12 drawings with a restricted entities set: LINE, CIRCLE, ARC, TEXT, POINT, SOLID, 3DFACE and POLYLINE. Advantage of the r12writer is the speed and the low memory footprint, all entities are written direct to the file/stream without building a drawing data structure in memory.
SEE ALSO:
Create a new DXF drawing with ezdxf.new() to use all available DXF entities:
import ezdxf doc = ezdxf.new('R2010') # create a new DXF R2010 drawing, official DXF version name: 'AC1024' msp = doc.modelspace() # add new entities to the modelspace msp.add_line((0, 0), (10, 0)) # add a LINE entity doc.saveas('line.dxf')
New entities are always added to layouts, a layout can be the modelspace, a paperspace layout or a block layout.
SEE ALSO:
If you are not familiar with the concept of layers, please read this first: layer_concept
import ezdxf doc = ezdxf.new(setup=True) # setup required line types msp = doc.modelspace() doc.layers.new(name='MyLines', dxfattribs={'linetype': 'DASHED', 'color': 7})
The advantage of assigning a linetype and a color to a layer is that entities on this layer can inherit this properties by using 'BYLAYER' as linetype string and 256 as color, both values are default values for new entities so you can left off this assignments:
msp.add_line((0, 0), (10, 0), dxfattribs={'layer': 'MyLines'})
The new created line will be drawn with color 7 and linetype 'DASHED'.
Get the layer definition object:
my_lines = doc.layers.get('MyLines')
Check the state of the layer:
my_lines.is_off() # True if layer is off my_lines.is_on() # True if layer is on my_lines.is_locked() # True if layer is locked layer_name = my_lines.dxf.name # get the layer name
Change the state of the layer:
# switch layer off, entities at this layer will not shown in CAD applications/viewers my_lines.off() # lock layer, entities at this layer are not editable in CAD applications my_lines.lock()
Get/set default color of a layer by property Layer.color, because the DXF attribute Layer.dxf.color is misused for switching the layer on and off, layer is off if the color value is negative.
Changing the default layer values:
my_lines.dxf.linetype = 'DOTTED' my_lines.color = 13 # preserves on/off state of layer
SEE ALSO:
The layers object supports some standard Python protocols:
# iteration for layer in doc.layers:
if layer.dxf.name != '0':
layer.off() # switch all layers off except layer '0' # check for existing layer definition if 'MyLines' in doc.layers:
layer = doc.layers.get('MyLines') layer_count = len(doc.layers) # total count of layer definitions
Delete a layer definition:
doc.layers.remove('MyLines')
This just deletes the layer definition, all DXF entities with the DXF attribute layer set to 'MyLines' are still there, but if they inherit color and/or linetype from the layer definition they will be drawn now with linetype 'Continuous' and color 1.
Blocks are collections of DXF entities which can be placed multiply times as block references in different layouts and other block definitions. The block reference (Insert) can be rotated, scaled, placed in 3D by OCS and arranged in a grid like manner, each Insert entity can have individual attributes (Attrib) attached.
Blocks are managed as BlockLayout by a BlocksSection object, every drawing has only one blocks section stored in the attribute: Drawing.blocks.
import ezdxf import random # needed for random placing points def get_random_point():
"""Returns random x, y coordinates."""
x = random.randint(-100, 100)
y = random.randint(-100, 100)
return x, y # Create a new drawing in the DXF format of AutoCAD 2010 doc = ezdxf.new('R2010') # Create a block with the name 'FLAG' flag = doc.blocks.new(name='FLAG') # Add DXF entities to the block 'FLAG'. # The default base point (= insertion point) of the block is (0, 0). flag.add_lwpolyline([(0, 0), (0, 5), (4, 3), (0, 3)]) # the flag symbol as 2D polyline flag.add_circle((0, 0), .4, dxfattribs={'color': 2}) # mark the base point with a circle
A block reference is a DXF Insert entity and can be placed in any layout: Modelspace, any Paperspace or BlockLayout (which enables nested block references). Every block reference can be scaled and rotated individually.
Lets insert some random flags into the modelspace:
# Get the modelspace of the drawing. msp = doc.modelspace() # Get 50 random placing points. placing_points = [get_random_point() for _ in range(50)] for point in placing_points:
# Every flag has a different scaling and a rotation of -15 deg.
random_scale = 0.5 + random.random() * 2.0
# Add a block reference to the block named 'FLAG' at the coordinates 'point'.
msp.add_blockref('FLAG', point, dxfattribs={
'xscale': random_scale,
'yscale': random_scale,
'rotation': -15
}) # Save the drawing. doc.saveas("blockref_tutorial.dxf")
Query all block references of block FLAG:
for flag_ref in msp.query('INSERT[name=="FLAG"]'):
print(str(flag_ref))
An attribute (Attrib) is a text annotation attached to a block reference with an associated tag. Attributes are often used to add information to blocks which can be evaluated and exported by CAD programs. An attribute can be visible or hidden. The simple way to use attributes is just to add an attribute to a block reference by Insert.add_attrib(), but the attribute is geometrically not related to the block reference, so you have to calculate the insertion point, rotation and scaling of the attribute by yourself.
The second way to use attributes in block references is a two step process, first step is to create an attribute definition (template) in the block definition, the second step is adding the block reference by Layout.add_blockref() and attach and fill attribute automatically by the add_auto_attribs() method to the block reference. The advantage of this method is that all attributes are placed relative to the block base point with the same rotation and scaling as the block, but has the disadvantage that non uniform scaling is not handled very well. The method Layout.add_auto_blockref() handles non uniform scaling better by wrapping the block reference and its attributes into an anonymous block and let the CAD application do the transformation work which will create correct graphical representations at least by AutoCAD and BricsCAD. This method has the disadvantage of a more complex evaluation of attached attributes
Using attribute definitions (Attdef):
# Define some attributes for the block 'FLAG', placed relative # to the base point, (0, 0) in this case. flag.add_attdef('NAME', (0.5, -0.5), dxfattribs={'height': 0.5, 'color': 3}) flag.add_attdef('XPOS', (0.5, -1.0), dxfattribs={'height': 0.25, 'color': 4}) flag.add_attdef('YPOS', (0.5, -1.5), dxfattribs={'height': 0.25, 'color': 4}) # Get another 50 random placing points. placing_points = [get_random_point() for _ in range(50)] for number, point in enumerate(placing_points):
# values is a dict with the attribute tag as item-key and
# the attribute text content as item-value.
values = {
'NAME': "P(%d)" % (number + 1),
'XPOS': "x = %.3f" % point[0],
'YPOS': "y = %.3f" % point[1]
}
# Every flag has a different scaling and a rotation of +15 deg.
random_scale = 0.5 + random.random() * 2.0
blockref = msp.add_blockref('FLAG', point, dxfattribs={
'rotation': 15
}).set_scale(random_scale)
blockref.add_auto_attribs(values) # Save the drawing. doc.saveas("auto_blockref_tutorial.dxf")
See the howto: howto_get_attribs
As mentioned above evaluation of block references wrapped into anonymous blocks is complex:
# Collect all anonymous block references starting with '*U' anonymous_block_refs = modelspace.query('INSERT[name ? "^\*U.+"]') # Collect real references to 'FLAG' flag_refs = [] for block_ref in anonymous_block_refs:
# Get the block layout of the anonymous block
block = doc.blocks.get(block_ref.dxf.name)
# Find all block references to 'FLAG' in the anonymous block
flag_refs.extend(block.query('INSERT[name=="FLAG"]')) # Evaluation example: collect all flag names. flag_numbers = [flag.get_attrib_text('NAME') for flag in flag_refs if flag.has_attrib('NAME')] print(flag_numbers)
New in version 0.12.
This is an advanced and still experimental feature and because ezdxf is still not a CAD application, the results may no be perfect. Non uniform scaling lead to incorrect results for text entities (TEXT, MTEXT, ATTRIB) and some other entities like HATCH with arc or ellipse path segments.
By default the “exploded” entities are added to the same layout as the block reference is located.
for flag_ref in msp.query('INSERT[name=="FLAG"]'):
flag_ref.explode()
New in version 0.12.
If you just want to examine the entities of a block reference use the virtual_entities() method. This methods yields “virtual” entities with attributes identical to “exploded” entities but they are not stored in the entity database, have no handle and are not assigned to any layout.
for flag_ref in msp.query('INSERT[name=="FLAG"]'):
for entity in flag_ref.virtual_entities():
if entity.dxftype() == 'LWPOLYLINE':
print(f'Found {str(entity)}.')
The LWPolyline is defined as a single graphic entity, which differs from the old-style Polyline entity, which is defined as a group of sub-entities. LWPolyline display faster (in AutoCAD) and consume less disk space, it is a planar element, therefore all points in OCS as (x, y) tuples (LWPolyline.dxf.elevation is the z-axis value).
Create a simple polyline:
import ezdxf doc = ezdxf.new('R2000') msp = doc.modelspace() points = [(0, 0), (3, 0), (6, 3), (6, 6)] msp.add_lwpolyline(points) doc.saveas("lwpolyline1.dxf")
Append multiple points to a polyline:
doc = ezdxf.readfile("lwpolyline1.dxf") msp = doc.modelspace() line = msp.query('LWPOLYLINE')[0] # take first LWPolyline line.append_points([(8, 7), (10, 7)]) doc.saveas("lwpolyline2.dxf")
Getting points always returns a 5-tuple (x, y, start_width, ent_width, bulge), start_width, end_width and bulge is 0 if not present:
first_point = line[0] x, y, start_width, end_width, bulge = first_point
Use context manager to edit polyline points, this method was introduced because accessing single points was very slow, but since ezdxf v0.8.9, direct access by index operator [] is very fast and using the context manager is not required anymore. Advantage of the context manager is the ability to use a user defined point format:
doc = ezdxf.readfile("lwpolyline2.dxf") msp = doc.modelspace() line = msp.query('LWPOLYLINE').first # take first LWPolyline, 'first' was introduced with v0.10 with line.points('xyseb') as points:
# points is a standard python list
# existing points are 5-tuples, but new points can be
# set as (x, y, [start_width, [end_width, [bulge]]]) tuple
# set start_width, end_width to 0 to be ignored (x, y, 0, 0, bulge).
del points[-2:] # delete last 2 points
points.extend([(4, 7), (0, 7)]) # adding 2 other points
# the same as one command
# points[-2:] = [(4, 7), (0, 7)] doc.saveas("lwpolyline3.dxf")
Each line segment can have a different start- and end-width, if omitted start- and end-width is 0:
doc = ezdxf.new('R2000') msp = doc.modelspace() # point format = (x, y, [start_width, [end_width, [bulge]]]) # set start_width, end_width to 0 to be ignored (x, y, 0, 0, bulge). points = [(0, 0, .1, .15), (3, 0, .2, .25), (6, 3, .3, .35), (6, 6)] msp.add_lwpolyline(points) doc.saveas("lwpolyline4.dxf")
The first point carries the start- and end-width of the first segment, the second point of the second segment and so on, the start- and end-width value of the last point is used for the closing segment if polyline is closed else the values are ignored. Start- and end-width only works if the DXF attribute dxf.const_width is unset, to be sure delete it:
del line.dxf.const_width # no exception will be raised if const_width is already unset
LWPolyline can also have curved elements, they are defined by the bulge value:
doc = ezdxf.new('R2000') msp = doc.modelspace() # point format = (x, y, [start_width, [end_width, [bulge]]]) # set start_width, end_width to 0 to be ignored (x, y, 0, 0, bulge). points = [(0, 0, 0, .05), (3, 0, .1, .2, -.5), (6, 0, .1, .05), (9, 0)] msp.add_lwpolyline(points) doc.saveas("lwpolyline5.dxf")
The curved segment is drawn from the point which defines the bulge value to the following point, the curved segment is always aa arc, The bulge value defines the ratio of the arc sagitta (segment height h) to half line segment length (point distance), a bulge value of 1 defines a semicircle. bulge > 0 the curve is on the right side of the vertex connection line, bulge < 0 the curve is on the left side.
ezdxf v0.8.9 supports a user defined points format, default is xyseb:
msp.add_lwpolyline([(0, 0, 0), (10, 0, 1), (20, 0, 0)], format='xyb') msp.add_lwpolyline([(0, 10, 0), (10, 10, .5), (20, 10, 0)], format='xyb')
Add a simple one line text entity by factory function add_text().
import ezdxf # TEXT is a basic entity and is supported by every DXF version. # Argument setup=True for adding standard linetypes and text styles. doc = ezdxf.new('R12', setup=True) msp = doc.modelspace() # use set_pos() for proper TEXT alignment: # The relations between DXF attributes 'halign', 'valign', # 'insert' and 'align_point' are tricky. msp.add_text("A Simple Text").set_pos((2, 3), align='MIDDLE_RIGHT') # Using a text style msp.add_text("Text Style Example: Liberation Serif",
dxfattribs={
'style': 'LiberationSerif',
'height': 0.35}
).set_pos((2, 6), align='LEFT') doc.saveas("simple_text.dxf")
Valid text alignments for argument align in Text.set_pos():
Vert/Horiz | Left | Center | Right |
Top | TOP_LEFT | TOP_CENTER | TOP_RIGHT |
Middle | MIDDLE_LEFT | MIDDLE_CENTER | MIDDLE_RIGHT |
Bottom | BOTTOM_LEFT | BOTTOM_CENTER | BOTTOM_RIGHT |
Baseline | LEFT | CENTER | RIGHT |
Special alignments are ALIGNED and FIT, they require a second alignment point, the text is justified with the vertical alignment Baseline on the virtual line between these two points.
Alignment | Description |
ALIGNED | Text is stretched or compressed to fit exactly between p1 and p2 and the text height is also adjusted to preserve height/width ratio. |
FIT | Text is stretched or compressed to fit exactly between p1 and p2 but only the text width is adjusted, the text height is fixed by the height attribute. |
MIDDLE | also a special adjustment, but the result is the same as for MIDDLE_CENTER. |
Setup some standard text styles and linetypes by argument setup=True:
doc = ezdxf.new('R12', setup=True)
Replaced all proprietary font declarations in setup_styles() (ARIAL, ARIAL_NARROW, ISOCPEUR and TIMES) by open source fonts, this is also the style name (e.g. {'style': 'OpenSans-Italic'}): [image]
Creating a new text style is simple:
doc.styles.new('myStandard', dxfattribs={'font' : 'OpenSans-Regular.ttf'})
But getting the correct font name is often not that simple, especially on Windows. This shows the required steps to get the font name for Open Sans:
The style name has to be unique in the DXF document, else ezdxf will raise an DXFTableEntryError exception. To replace an existing entry, delete the existing entry by doc.styles.remove(name), and add the replacement entry.
It is possible to place the 2D Text entity into 3D space by using the OCS, for further information see: tut_ocs.
The MText entity is a multi line entity with extended formatting possibilities and requires at least DXF version R2000, to use all features (e.g. background fill) DXF R2007 is required.
Prolog code:
import ezdxf doc = ezdxf.new('R2007', setup=True) msp = doc.modelspace() lorem_ipsum = """ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. """
The MText entity can be added to any layout (modelspace, paperspace or block) by the add_mtext() function.
# store MText entity for additional manipulations mtext = msp.add_mtext(lorem_ipsum, dxfattribs={'style': 'OpenSans'})
This adds a MText entity with text style 'OpenSans'. The MText content can be accessed by the text attribute, this attribute can be edited like any Python string:
mtext.text += 'Append additional text to the MText entity.' # even shorter with __iadd__() support: mtext += 'Append additional text to the MText entity.'
IMPORTANT:
The location of the MText entity is defined by the MText.dxf.insert and the MText.dxf.attachment_point attributes. The attachment_point defines the text alignment relative to the insert location, default value is 1.
Attachment point constants defined in ezdxf.lldxf.const:
MText.dxf.attachment_point | Value |
MTEXT_TOP_LEFT | 1 |
MTEXT_TOP_CENTER | 2 |
MTEXT_TOP_RIGHT | 3 |
MTEXT_MIDDLE_LEFT | 4 |
MTEXT_MIDDLE_CENTER | 5 |
MTEXT_MIDDLE_RIGHT | 6 |
MTEXT_BOTTOM_LEFT | 7 |
MTEXT_BOTTOM_CENTER | 8 |
MTEXT_BOTTOM_RIGHT | 9 |
The MText entity has a method for setting insert, attachment_point and rotation attributes by one call: set_location()
The character height is defined by the DXF attribute MText.dxf.char_height in drawing units, which has also consequences for the line spacing of the MText entity:
mtext.dxf.char_height = 0.5
The character height can be changed inline, see also MText formatting and mtext_inline_codes.
The MText.dxf.rotation attribute defines the text rotation as angle between the x-axis and the horizontal direction of the text in degrees. The MText.dxf.text_direction attribute defines the horizontal direction of MText as vector in WCS or OCS, if an OCS is defined. Both attributes can be present at the same entity, in this case the MText.dxf.text_direction attribute has the higher priority.
The MText entity has two methods to get/set rotation: get_rotation() returns the rotation angle in degrees independent from definition as angle or direction, and set_rotation() set the rotation attribute and removes the text_direction attribute if present.
The wrapping border limits the text width and forces a line break for text beyond this border. Without attribute dxf.width (or setting 0) the lines are wrapped only at the regular line endings \P or \n, setting the reference column width forces additional line wrappings at the given width. The text height can not be limited, the text always occupies as much space as needed.
mtext.dxf.width = 60
MText supports inline formatting by special codes: mtext_inline_codes
mtext.text = "{\\C1red text} - {\\C3green text} - {\\C5blue text}"
MText also supports stacked text:
# the space ' ' in front of 'Lower' anr the ';' behind 'Lower' are necessary # combined with vertical center alignment mtext.text = "\\A1\\SUpper^ Lower; - \\SUpper/ Lower;} - \\SUpper# Lower;"
Available helper function for text formatting:
The MText entity can have a background filling:
Because of the complex dependencies ezdxf provides a method to set all required DXF attributes at once:
mtext.set_bg_color(2, scale=1.5)
The parameter scale determines how much border there is around the text, the value is based on the text height, and should be in the range of 1 - 5, where 1 fits exact the MText entity. [image]
Background information about B-spline at Wikipedia.
Splines can be defined by fit points only, this means the curve goes through all given fit points. AutoCAD and BricsCAD generates required control points and knot values by itself, if only fit points are present.
Create a simple spline:
doc = ezdxf.new('R2000') fit_points = [(0, 0, 0), (750, 500, 0), (1750, 500, 0), (2250, 1250, 0)] msp = doc.modelspace() spline = msp.add_spline(fit_points)
Append a fit point to a spline:
# fit_points, control_points, knots and weights are list-like containers: spline.fit_points.append((2250, 2500, 0))
You can set additional control points, but if they do not fit the auto-generated AutoCAD values, they will be ignored and don’t mess around with knot values.
Solve problems of incorrect values after editing a spline generated by AutoCAD:
doc = ezdxf.readfile("AutoCAD_generated.dxf") msp = doc.modelspace() spline = msp.query('SPLINE').first # fit_points, control_points, knots and weights are list-like objects: spline.fit_points.append((2250, 2500, 0))
As far as I have tested, this approach works without complaints from AutoCAD, but for the case of problems remove invalid data:
# current control points do not match spline defined by fit points spline.control_points = [] # count of knots is not correct: # count of knots = count of control points + degree + 1 spline.knots = [] # same for weights, count of weights == count of control points spline.weights = []
To create splines from fit points is the easiest way to create splines, but this method is also the least accurate, because a spline is defined by control points and knot values, which are generated for the case of a definition by fit points, and the worst fact is that for every given set of fit points exist an infinite number of possible splines as solution.
AutoCAD (and BricsCAD also) uses an proprietary algorithm to generate control points and knot values from fit points, which differs from the well documented Global Curve Interpolation. Therefore splines generated from fit points by ezdxf do not match splines generated by AutoCAD (BricsCAD).
To ensure the same spline geometry for all CAD applications, the spline has to be defined by control points. The method add_spline_control_frame() adds a spline trough fit points by calculating the control points by the Global Curve Interpolation algorithm. There is also a low level function ezdxf.math.global_bspline_interpolation() which calculates the control points from fit points.
msp.add_spline_control_frame(fit_points, method='uniform', dxfattribs={'color': 1}) msp.add_spline_control_frame(fit_points, method='chord', dxfattribs={'color': 3}) msp.add_spline_control_frame(fit_points, method='centripetal', dxfattribs={'color': 5})
Add and open (clamped) spline defined by control points with the method add_open_spline(). If no knot values are given, an open uniform knot vector will be generated. A clamped B-spline starts at the first control point and ends at the last control point.
control_points = [(0, 0, 0), (1250, 1560, 0), (3130, 610, 0), (2250, 1250, 0)] msp.add_open_spline(control_points)
A closed spline is continuous closed curve.
msp.add_closed_spline(control_points)
Rational B-splines have a weight for every control point, which can raise or lower the influence of the control point, default weight = 1, to lower the influence set a weight < 1 to raise the influence set a weight > 1. The count of weights has to be always equal to the count of control points.
Example to raise the influence of the first control point:
msp.add_closed_rational_spline(control_points, weights=[3, 1, 1, 1])
Check if spline is a closed curve or close/open spline, for a closed spline the last point is connected to the first point:
if spline.closed:
# this spline is closed
pass # close spline spline.closed = True # open spline spline.closed = False
Set start- and end tangent for splines defined by fit points:
spline.dxf.start_tangent = (0, 1, 0) # in y-axis spline.dxf.end_tangent = (1, 0, 0) # in x-axis
Get data count as stored in DXF file:
count = spline.dxf.n_fit_points count = spline.dxf.n_control_points count = spline.dxf.n_knots
Get data count of real existing data:
count = spline.fit_point_count count = spline.control_point_count count = spline.knot_count
coming soon …
Create a cube mesh by direct access to base data structures:
import ezdxf # 8 corner vertices cube_vertices = [
(0, 0, 0),
(1, 0, 0),
(1, 1, 0),
(0, 1, 0),
(0, 0, 1),
(1, 0, 1),
(1, 1, 1),
(0, 1, 1), ] # 6 cube faces cube_faces = [
[0, 1, 2, 3],
[4, 5, 6, 7],
[0, 1, 5, 4],
[1, 2, 6, 5],
[3, 2, 6, 7],
[0, 3, 7, 4] ] doc = ezdxf.new('R2000') # MESH requires DXF R2000 or later msp = doc.modelspace() mesh = msp.add_mesh() mesh.dxf.subdivision_levels = 0 # do not subdivide cube, 0 is the default value with mesh.edit_data() as mesh_data:
mesh_data.vertices = cube_vertices
mesh_data.faces = cube_faces doc.saveas("cube_mesh_1.dxf")
Create a cube mesh by method calls:
import ezdxf # 8 corner vertices p = [
(0, 0, 0),
(1, 0, 0),
(1, 1, 0),
(0, 1, 0),
(0, 0, 1),
(1, 0, 1),
(1, 1, 1),
(0, 1, 1), ] doc = ezdxf.new('R2000') # MESH requires DXF R2000 or later msp = doc.modelspace() mesh = msp.add_mesh() with mesh.edit_data() as mesh_data:
mesh_data.add_face([p[0], p[1], p[2], p[3]])
mesh_data.add_face([p[4], p[5], p[6], p[7]])
mesh_data.add_face([p[0], p[1], p[5], p[4]])
mesh_data.add_face([p[1], p[2], p[6], p[5]])
mesh_data.add_face([p[3], p[2], p[6], p[7]])
mesh_data.add_face([p[0], p[3], p[7], p[4]])
mesh_data.optimize() # optional, minimizes vertex count doc.saveas("cube_mesh_2.dxf")
The simplest form of the Hatch entity has one polyline path with only straight lines as boundary path:
import ezdxf doc = ezdxf.new('R2000') # hatch requires the DXF R2000 (AC1015) format or later msp = doc.modelspace() # adding entities to the model space hatch = msp.add_hatch(color=2) # by default a solid fill hatch with fill color=7 (white/black) # every boundary path is always a 2D element # vertex format for the polyline path is: (x, y[, bulge]) # there are no bulge values in this example hatch.paths.add_polyline_path([(0, 0), (10, 0), (10, 10), (0, 10)], is_closed=1) doc.saveas("solid_hatch_polyline_path.dxf")
But like all polyline entities the polyline path can also have bulge values:
import ezdxf doc = ezdxf.new('R2000') # hatch requires the DXF R2000 (AC1015) format or later msp = doc.modelspace() # adding entities to the model space hatch = msp.add_hatch(color=2) # by default a solid fill hatch with fill color=7 (white/black) # every boundary path is always a 2D element # vertex format for the polyline path is: (x, y[, bulge]) # bulge value 1 = an arc with diameter=10 (= distance to next vertex * bulge value) # bulge value > 0 ... arc is right of line # bulge value < 0 ... arc is left of line hatch.paths.add_polyline_path([(0, 0, 1), (10, 0), (10, 10, -0.5), (0, 10)], is_closed=1) doc.saveas("solid_hatch_polyline_path_with_bulge.dxf")
The most flexible way to define a boundary path is the edge path. An edge path consist of a number of edges and each edge can be one of the following elements:
Create a solid hatch with an edge path (ellipse) as boundary path:
import ezdxf doc = ezdxf.new('R2000') # hatch requires the DXF R2000 (AC1015) format or later msp = doc.modelspace() # adding entities to the model space # important: major axis >= minor axis (ratio <= 1.) # minor axis length = major axis length * ratio msp.add_ellipse((0, 0), major_axis=(0, 10), ratio=0.5) # by default a solid fill hatch with fill color=7 (white/black) hatch = msp.add_hatch(color=2) # every boundary path is always a 2D element edge_path = hatch.paths.add_edge_path() # each edge path can contain line arc, ellipse and spline elements # important: major axis >= minor axis (ratio <= 1.) edge_path.add_ellipse((0, 0), major_axis=(0, 10), ratio=0.5) doc.saveas("solid_hatch_ellipse.dxf")
The DXF atribute hatch_style defines the island detection style:
0 | nested - altering filled and unfilled areas |
1 | outer - area between external and outermost path is filled |
2 | ignore - external path is filled |
hatch = msp.add_hatch(color=1, dxfattribs={
'hatch_style': 0,
# 0 = nested
# 1 = outer
# 2 = ignore }) # The first path has to set flag: 1 = external # flag const.BOUNDARY_PATH_POLYLINE is added (OR) automatically hatch.paths.add_polyline_path([(0, 0), (10, 0), (10, 10), (0, 10)], is_closed=1, flags=1)
This is also the result for all 4 paths and hatch_style set to 2 (ignore). [image]
# The second path has to set flag: 16 = outermost hatch.paths.add_polyline_path([(1, 1), (9, 1), (9, 9), (1, 9)], is_closed=1, flags=16)
This is also the result for all 4 paths and hatch_style set to 1 (outer). [image]
# The third path has to set flag: 0 = default hatch.paths.add_polyline_path([(2, 2), (8, 2), (8, 8), (2, 8)], is_closed=1, flags=0)
# The forth path has to set flag: 0 = default, and so on hatch.paths.add_polyline_path([(3, 3), (7, 3), (7, 7), (3, 7)], is_closed=1, flags=0)
The expected result of combinations of various hatch_style values and paths flags, or the handling of overlapping paths is not documented by the DXF reference, so don’t ask me, ask Autodesk or just try it by yourself and post your experience in the forum.
hatch = msp.add_hatch(color=1) # 1. polyline path hatch.paths.add_polyline_path([
(240, 210, 0),
(0, 210, 0),
(0, 0, 0.),
(240, 0, 0), ],
is_closed=1,
flags=1, ) # 2. edge path edge_path = hatch.paths.add_edge_path(flags=16) edge_path.add_spline(
control_points=[
(126.658105895725, 177.0823706957212),
(141.5497003747484, 187.8907860433995),
(205.8997365206943, 154.7946313459515),
(113.0168862297068, 117.8189380884978),
(202.9816918983783, 63.17222935389572),
(157.363511042264, 26.4621294342132),
(144.8204003260554, 28.4383294369643)
],
knot_values=[
0.0, 0.0, 0.0, 0.0, 55.20174685732758, 98.33239645153571,
175.1126541251052, 213.2061566683142, 213.2061566683142,
213.2061566683142, 213.2061566683142
], ) edge_path.add_arc(
center=(152.6378550678883, 128.3209356351659),
radius=100.1880612627354,
start_angle=94.4752130054052,
end_angle=177.1345242028005, ) edge_path.add_line(
(52.57506282464041, 123.3124200796114),
(126.658105895725, 177.0823706957212) )
[image]
A HATCH entity can be associative to a base geometry, which means if the base geometry is edited in a CAD application the HATCH get the same modification. Because ezdxf is not a CAD application, this association is not maintained nor verified by ezdxf, so if you modify the base geometry afterwards the geometry of the boundary path is not updated and no verification is done to check if the associated geometry matches the boundary path, this opens many possibilities to create invalid DXF files: USE WITH CARE.
This example associates a LWPOLYLINE entity to the hatch created from the LWPOLYLINE vertices:
# Create base geometry lwpolyline = msp.add_lwpolyline(
[(0, 0, 0), (10, 0, .5), (10, 10, 0), (0, 10, 0)],
format='xyb',
dxfattribs={'closed': True}, ) hatch = msp.add_hatch(color=1) path = hatch.paths.add_polyline_path(
# get path vertices from associated LWPOLYLINE entity
lwpolyline.get_points(format='xyb'),
# get closed state also from associated LWPOLYLINE entity
is_closed=lwpolyline.closed, ) # Set association between boundary path and LWPOLYLINE hatch.associate(path, [lwpolyline])
An EdgePath needs associations to all geometry entities forming the boundary path.
Use predefined hatch pattern by name:
hatch.set_pattern_fill('ANSI31', scale=0.5)
TODO
TODO
Insert a raster image into a DXF drawing, the raster image is NOT embedded into the DXF file:
import ezdxf doc = ezdxf.new('AC1015') # image requires the DXF R2000 format or later my_image_def = doc.add_image_def(filename='mycat.jpg', size_in_pixel=(640, 360)) # The IMAGEDEF entity is like a block definition, it just defines the image msp = doc.modelspace() # add first image msp.add_image(insert=(2, 1), size_in_units=(6.4, 3.6), image_def=my_image_def, rotation=0) # The IMAGE entity is like the INSERT entity, it creates an image reference, # and there can be multiple references to the same picture in a drawing. msp.add_image(insert=(4, 5), size_in_units=(3.2, 1.8), image_def=my_image_def, rotation=30) # get existing image definitions, Important: IMAGEDEFs resides in the objects section image_defs = doc.objects.query('IMAGEDEF') # get all image defs in drawing doc.saveas("dxf_with_cat.dxf")
Insert a PDF, DWF, DWFx or DGN file as drawing underlay, the underlay file is NOT embedded into the DXF file:
import ezdxf doc = ezdxf.new('AC1015') # underlay requires the DXF R2000 format or later my_underlay_def = doc.add_underlay_def(filename='my_underlay.pdf', name='1') # The (PDF)DEFINITION entity is like a block definition, it just defines the underlay # 'name' is misleading, because it defines the page/sheet to be displayed # PDF: name is the page number to display # DGN: name='default' ??? # DWF: ???? msp = doc.modelspace() # add first underlay msp.add_underlay(my_underlay_def, insert=(2, 1, 0), scale=0.05) # The (PDF)UNDERLAY entity is like the INSERT entity, it creates an underlay reference, # and there can be multiple references to the same underlay in a drawing. msp.add_underlay(my_underlay_def, insert=(4, 5, 0), scale=.5, rotation=30) # get existing underlay definitions, Important: UNDERLAYDEFs resides in the objects section pdf_defs = doc.objects.query('PDFDEFINITION') # get all pdf underlay defs in drawing doc.saveas("dxf_with_underlay.dxf")
Simple line type example: [image]
You can define your own line types. A DXF linetype definition consists of name, description and elements:
elements = [total_pattern_length, elem1, elem2, ...]
Create a new linetype definition:
import ezdxf from ezdxf.tools.standards import linetypes # some predefined line types doc = ezdxf.new() msp = modelspace() my_line_types = [
("DOTTED", "Dotted . . . . . . . . . . . . . . . .", [0.2, 0.0, -0.2]),
("DOTTEDX2", "Dotted (2x) . . . . . . . . ", [0.4, 0.0, -0.4]),
("DOTTED2", "Dotted (.5) . . . . . . . . . . . . . . . . . . . ", [0.1, 0.0, -0.1]), ] for name, desc, pattern in my_line_types:
if name not in doc.linetypes:
doc.linetypes.new(name=name, dxfattribs={'description': desc, 'pattern': pattern})
Setup some predefined linetypes:
for name, desc, pattern in linetypes():
if name not in doc.linetypes:
doc.linetypes.new(name=name, dxfattribs={'description': desc, 'pattern': pattern})
The linetypes object supports some standard Python protocols:
# iteration print('available line types:') for linetype in doc.linetypes:
print('{}: {}'.format(linetype.dxf.name, linetype.dxf.description)) # check for existing line type if 'DOTTED' in doc.linetypes:
pass count = len(doc.linetypes) # total count of linetypes
WARNING:
You can delete a linetype:
doc.layers.remove('DASHED')
This just deletes the linetype definition, all DXF entity with the DXF attribute linetype set to DASHED still refers to linetype DASHED and AutoCAD will not open DXF files with undefined line types.
In DXF R13 Autodesk introduced complex line types, containing TEXT or SHAPES in line types. ezdxf v0.8.4 and later supports complex line types.
Complex line type example with text: [image]
Complex line type example with shapes: [image]
For simplicity the pattern string for complex line types is mostly the same string as the pattern definition strings in AutoCAD .lin files.
Example for complex line type TEXT:
doc = ezdxf.new('R2018') # DXF R13 or later is required doc.linetypes.new('GASLEITUNG2', dxfattribs={
'description': 'Gasleitung2 ----GAS----GAS----GAS----GAS----GAS----GAS--',
'length': 1, # required for complex line types
# line type definition in acadlt.lin:
'pattern': 'A,.5,-.2,["GAS",STANDARD,S=.1,U=0.0,X=-0.1,Y=-.05],-.25', })
The pattern always starts with an A, the following float values have the same meaning as for simple line types, a value > 0 is a line, a value < 0 is a gap, and a 0 is a point, the [ starts the complex part of the line pattern. A following text in quotes defines a TEXT type, a following text without quotes defines a SHAPE type, in .lin files the shape type is a shape name, but ezdxf can not translate this name into the required shape file index, so YOU have to translate this name into the shape file index (e.g. saving the file with AutoCAD as DXF and searching for the line type definition, see also DXF Internals: ltype_table_internals).
The second parameter is the text style for a TEXT type and the shape file name for the SHAPE type, the shape file has to be in the same directory as the DXF file. The following parameters in the scheme of S=1.0 are:
The parameters are case insensitive. ] ends the complex part of the line pattern.
The fine tuning of this parameters is still a try an error process for me, for TEXT the scaling factor (STANDARD text style) sets the text height (S=.1 the text is .1 units in height), by shifting in y direction by half of the scaling factor, the center of the text is on the line. For the x direction it seems to be a good practice to place a gap in front of the text and after the text, find x shifting value and gap sizes by try and error. The overall length is at least the sum of all line and gap definitions (absolute values).
Example for complex line type SHAPE:
doc.linetypes.new('GRENZE2', dxfattribs={
'description': 'Grenze eckig ----[]-----[]----[]-----[]----[]--',
'length': 1.45, # required for complex line types
# line type definition in acadlt.lin:
# A,.25,-.1,[BOX,ltypeshp.shx,x=-.1,s=.1],-.1,1
# replacing BOX by shape index 132 (got index from an AutoCAD file),
# ezdxf can't get shape index from ltypeshp.shx
'pattern': 'A,.25,-.1,[132,ltypeshp.shx,x=-.1,s=.1],-.1,1', })
Complex line types with shapes only work if the associated shape file (ltypeshp.shx) and the DXF file are in the same directory.
For OCS/UCS usage is a basic understanding of vectors required, for a brush up, watch the YouTube tutorials of 3Blue1Brown about Linear Algebra.
Second read the Coordinate Systems introduction please.
For WCS there is not much to say as, it is what it is: the main world coordinate system, and a drawing unit can have any real world unit you want. Autodesk added some mechanism to define a scale for dimension and text entities, but because I am not an AutoCAD user, I am not familiar with it, and further more I think this is more an AutoCAD topic than a DXF topic.
The OCS is used to place planar 2D entities in 3D space. ALL points of a planar entity lay in the same plane, this is also true if the plane is located in 3D space by an OCS. There are three basic DXF attributes that gives a 2D entity its spatial form.
The extrusion vector defines the OCS, it is a normal vector to the base plane of a planar entity. This base plane is always located in the origin of the WCS. But there are some entities like Ellipse, which have an extrusion vector, but do not establish an OCS. For this entities the extrusion vector defines only the extrusion direction and thickness defines the extrusion distance, but all other points in WCS.
The elevation value defines the z-axis value for all points of a planar entity, this is an OCS value, and defines the distance of the entity plane from the base plane.
This value exists only in output from DXF versions prior to R11 as separated DXF attribute (group code 38). In DXF R12 and later, the elevation value is supplied as z-axis value of each point. But as always in DXF, this simple rule does not apply to all entities: LWPolyline and Hatch have an DXF attribute elevation, where the z-axis of this point is the elevation height and the x-axis = y-axis = 0.
Defines the extrusion distance for an entity.
NOTE:
This edition shows the hard way to accomplish the transformations by low level operations.
The colors for axis follow the AutoCAD standard:
import ezdxf from ezdxf.math import OCS doc = ezdxf.new('R2010') msp = doc.modelspace() # For this example the OCS is rotated around x-axis about 45 degree # OCS z-axis: x=0, y=1, z=1 # extrusion vector must not normalized here ocs = OCS((0, 1, 1)) msp.add_circle(
# You can place the 2D circle in 3D space
# but you have to convert WCS into OCS
center=ocs.from_wcs((0, 2, 2)),
# center in OCS: (0.0, 0.0, 2.82842712474619)
radius=1,
dxfattribs={
# here the extrusion vector should be normalized,
# which is granted by using the ocs.uz
'extrusion': ocs.uz,
'color': 1,
}) # mark center point of circle in WCS msp.add_point((0, 2, 2), dxfattribs={'color': 1})
The following image shows the 2D circle in 3D space in AutoCAD Left and Front view. The blue line shows the OCS z-axis (extrusion direction), elevation is the distance from the origin to the center of the circle in this case 2.828, and you see that the x- and y-axis of OCS and WCS are not aligned. [image: circle in ocs as side view] [image] [image: circle in ocs as front view] [image]
For simplicity of calculation I use the UCS class in this example to place a 2D pentagon in 3D space.
# The center of the pentagon should be (0, 2, 2), and the shape is # rotated around x-axis about 45 degree, to accomplish this I use an # UCS with z-axis (0, 1, 1) and an x-axis parallel to WCS x-axis. ucs = UCS(
origin=(0, 2, 2), # center of pentagon
ux=(1, 0, 0), # x-axis parallel to WCS x-axis
uz=(0, 1, 1), # z-axis ) # calculating corner points in local (UCS) coordinates points = [Vector.from_deg_angle((360 / 5) * n) for n in range(5)] # converting UCS into OCS coordinates ocs_points = list(ucs.points_to_ocs(points)) # LWPOLYLINE accepts only 2D points and has an separated DXF attribute elevation. # All points have the same z-axis (elevation) in OCS! elevation = ocs_points[0].z msp.add_lwpolyline(
points=ocs_points,
format='xy', # ignore z-axis
dxfattribs={
'elevation': elevation,
'extrusion': ucs.uz,
'closed': True,
'color': 1,
})
The following image shows the 2D pentagon in 3D space in AutoCAD Left, Front and Top view. The three lines from the center of the pentagon show the UCS, the three colored lines in the origin show the OCS the white lines in the origin show the WCS.
The z-axis of the UCS and the OCS show the same direction (extrusion direction), and the x-axis of the UCS and the WCS show the same direction. The elevation is the distance from the origin to the center of the pentagon and all points of the pentagon have the same elevation, and you see that the y- axis of UCS, OCS and WCS are not aligned. [image: pentagon in ucs as side view] [image] [image: pentagon in ucs as front view] [image]
It is much simpler to use a 3D Polyline to create the 3D pentagon. The UCS class is handy for this example and all kind of 3D operations.
# Using an UCS simplifies 3D operations, but UCS definition can happen later # calculating corner points in local (UCS) coordinates without Vector class angle = math.radians(360 / 5) corners_ucs = [(math.cos(angle * n), math.sin(angle * n), 0) for n in range(5)] # let's do some transformations tmatrix = Matrix44.chain( # creating a transformation matrix
Matrix44.z_rotate(math.radians(15)), # 1. rotation around z-axis
Matrix44.translate(0, .333, .333), # 2. translation ) transformed_corners_ucs = tmatrix.transform_vertices(corners_ucs) # transform UCS into WCS ucs = UCS(
origin=(0, 2, 2), # center of pentagon
ux=(1, 0, 0), # x-axis parallel to WCS x-axis
uz=(0, 1, 1), # z-axis ) corners_wcs = list(ucs.points_to_wcs(transformed_corners_ucs)) msp.add_polyline3d(
points=corners_wcs,
dxfattribs={
'closed': True,
'color': 1,
}) # add lines from center to corners center_wcs = ucs.to_wcs((0, .333, .333)) for corner in corners_wcs:
msp.add_line(center_wcs, corner, dxfattribs={'color': 1})
The problem by placing text in 3D space is the text rotation, which is always counter clockwise around the OCS z-axis, and 0 degree is in direction of the positive OCS x-axis, and the OCS x-axis is calculated by the Arbitrary Axis Algorithm.
Calculate the OCS rotation angle by converting the TEXT rotation angle (in UCS or WCS) into a vector or begin with text direction as vector, transform this direction vector into OCS and convert the OCS vector back into an angle in the OCS xy-plane (see example), this procedure is available as UCS.to_ocs_angle_deg() or UCS.to_ocs_angle_rad().
AutoCAD supports thickness for the TEXT entity only for .shx fonts and not for true type fonts.
# Thickness for text works only with shx fonts not with true type fonts doc.styles.new('TXT', dxfattribs={'font': 'romans.shx'}) ucs = UCS(origin=(0, 2, 2), ux=(1, 0, 0), uz=(0, 1, 1)) # calculation of text direction as angle in OCS: # convert text rotation in degree into a vector in UCS text_direction = Vector.from_deg_angle(-45) # transform vector into OCS and get angle of vector in xy-plane rotation = ucs.to_ocs(text_direction).angle_deg text = msp.add_text(
text="TEXT",
dxfattribs={
# text rotation angle in degrees in OCS
'rotation': rotation,
'extrusion': ucs.uz,
'thickness': .333,
'color': 1,
'style': 'TXT',
}) # set text position in OCS text.set_pos(ucs.to_ocs((0, 0, 0)), align='MIDDLE_CENTER')
HINT:
Here we have the same problem as for placing text, you need the start and end angle of the arc in degrees in OCS, and this example also shows a shortcut for calculating the OCS angles.
ucs = UCS(origin=(0, 2, 2), ux=(1, 0, 0), uz=(0, 1, 1)) msp.add_arc(
center=ucs.to_ocs((0, 0)),
radius=1,
start_angle=ucs.to_ocs_angle_deg(45),
end_angle=ucs.to_ocs_angle_deg(270),
dxfattribs={
'extrusion': ucs.uz,
'color': 1,
}) center = ucs.to_wcs((0, 0)) msp.add_line(
start=center,
end=ucs.to_wcs(Vector.from_deg_angle(45)),
dxfattribs={'color': 1}, ) msp.add_line(
start=center,
end=ucs.to_wcs(Vector.from_deg_angle(270)),
dxfattribs={'color': 1}, )
Despite the fact that block references (Insert) can contain true 3D entities like Line or Mesh, the Insert entity uses the same placing principe as Text or Arc shown in the previous chapters.
Simple placing by OCS and rotation about the z-axis, can be achieved the same way as for generic 2D entity types. The DXF attribute Insert.dxf.rotation rotates a block reference around the block z-axis, which is located in the Block.dxf.base_point. To rotate the block reference around the WCS x-axis, a transformation of the block z-axis into the WCS x-axis is required by rotating the block z-axis 90 degree counter clockwise around y-axis by using an UCS:
This is just an excerpt of the important parts, see the whole code of insert.py at github.
# rotate UCS around an arbitrary axis: def ucs_rotation(ucs: UCS, axis: Vector, angle: float):
# new in ezdxf v0.11: UCS.rotate(axis, angle)
t = Matrix44.axis_rotate(axis, math.radians(angle))
ux, uy, uz = t.transform_vertices([ucs.ux, ucs.uy, ucs.uz])
return UCS(origin=ucs.origin, ux=ux, uy=uy, uz=uz) doc = ezdxf.new('R2010', setup=True) blk = doc.blocks.new('CSYS') setup_csys(blk) msp = doc.modelspace() ucs = ucs_rotation(UCS(), axis=Y_AXIS, angle=90) # transform insert location to OCS insert = ucs.to_ocs((0, 0, 0)) # rotation angle about the z-axis (= WCS x-axis) rotation = ucs.to_ocs_angle_deg(15) msp.add_blockref('CSYS', insert, dxfattribs={
'extrusion': ucs.uz,
'rotation': rotation, })
To rotate a block reference around another axis than the block z-axis, you have to find the rotated z-axis (extrusion vector) of the rotated block reference, following example rotates the block reference around the block x-axis by 15 degrees:
# t is a transformation matrix to rotate 15 degree around the x-axis t = Matrix44.axis_rotate(axis=X_AXIS, angle=math.radians(15)) # transform block z-axis into new UCS z-axis (= extrusion vector) uz = Vector(t.transform(Z_AXIS)) # create new UCS at the insertion point, because we are rotating around the x-axis, # ux is the same as the WCS x-axis and uz is the rotated z-axis. ucs = UCS(origin=(1, 2, 0), ux=X_AXIS, uz=uz) # transform insert location to OCS, block base_point=(0, 0, 0) insert = ucs.to_ocs((0, 0, 0)) # for this case a rotation around the z-axis is not required rotation = 0 blockref = msp.add_blockref('CSYS', insert, dxfattribs={
'extrusion': ucs.uz,
'rotation': rotation, })
The next example shows how to translate a block references with an already established OCS:
# translate a block references with an established OCS translation = Vector(-3, -1, 1) # get established OCS ocs = blockref.ocs() # get insert location in WCS actual_wcs_location = ocs.to_wcs(blockref.dxf.insert) # translate location new_wcs_location = actual_wcs_location + translation # convert WCS location to OCS location blockref.dxf.insert = ocs.from_wcs(new_wcs_location)
Setting a new insert location is the same procedure without adding a translation vector, just transform the new insert location into the OCS. [image] [image]
The next operation is to rotate a block reference with an established OCS, rotation axis is the block y-axis, rotation angle is -90 degrees. First transform block y-axis (rotation axis) and block z-axis (extrusion vector) from OCS into WCS:
# rotate a block references with an established OCS around the block y-axis about 90 degree ocs = blockref.ocs() # convert block y-axis (= rotation axis) into WCS vector rotation_axis = ocs.to_wcs((0, 1, 0)) # convert local z-axis (=extrusion vector) into WCS vector local_z_axis = ocs.to_wcs((0, 0, 1))
Build transformation matrix and transform extrusion vector and build new UCS:
# build transformation matrix t = Matrix44.axis_rotate(axis=rotation_axis, angle=math.radians(-90)) uz = t.transform(local_z_axis) uy = rotation_axis # the block reference origin stays at the same location, no rotation needed wcs_insert = ocs.to_wcs(blockref.dxf.insert) # build new UCS to convert WCS locations and angles into OCS ucs = UCS(origin=wcs_insert, uy=uy, uz=uz)
Set new OCS attributes, we also have to set the rotation attribute even though we do not rotate the block reference around the local z-axis, the new block x-axis (0 deg) differs from OCS x-axis and has to be adjusted:
# set new OCS blockref.dxf.extrusion = ucs.uz # set new insert blockref.dxf.insert = ucs.to_ocs((0, 0, 0)) # set new rotation: we do not rotate the block reference around the local z-axis, # but the new block x-axis (0 deg) differs from OCS x-axis and has to be adjusted blockref.dxf.rotation = ucs.to_ocs_angle_deg(0)
And here is the point, where my math knowledge ends, for more advanced CAD operation you have to look elsewhere.
With ezdxf v0.11 a new feature for entity transformation was introduced, which makes working with OCS/UCS much easier, this is a new edition of the older tut_ocs. For the basic information read the old tutorial please. In ezdxf v0.13 the transform_to_wcs() interface was replaced by the general transformation interface: transform().
For this tutorial we don’t have to worry about the OCS and the extrusion vector, this is done automatically by the transform() method of each DXF entity.
To recreate the situation of the old tutorial instantiate a new UCS and rotate it around the local x-axis. Use UCS coordinates to place the 2D CIRCLE in 3D space, and transform the UCS coordinates to the WCS.
import math import ezdxf from ezdxf.math import UCS doc = ezdxf.new('R2010') msp = doc.modelspace() ucs = UCS() # New default UCS # All rotation angles in radians, and rotation # methods always return a new UCS. ucs = ucs.rotate_local_x(math.radians(-45)) circle = msp.add_circle(
# Use UCS coordinates to place the 2d circle in 3d space
center=(0, 0, 2),
radius=1,
dxfattribs={'color': 1} ) circle.transform(ucs.matrix) # mark center point of circle in WCS msp.add_point((0, 0, 2), dxfattribs={'color': 1}).transform(ucs.matrix)
Simplified LWPOLYLINE example:
# The center of the pentagon should be (0, 2, 2), and the shape is # rotated around x-axis about -45 degree ucs = UCS(origin=(0, 2, 2)).rotate_local_x(math.radians(-45)) msp.add_lwpolyline(
# calculating corner points in UCS coordinates
points=(Vector.from_deg_angle((360 / 5) * n) for n in range(5)),
format='xy', # ignore z-axis
dxfattribs={
'closed': True,
'color': 1,
} ).transform(ucs.matrix)
The 2D pentagon in 3D space in BricsCAD Left and Front view. [image: pentagon in ucs as side view] [image] [image: pentagon in ucs as front view] [image]
Simplified POLYLINE example: Using a first UCS to transform the POLYLINE and a second UCS to place the POLYLINE in 3D space.
# using an UCS simplifies 3D operations, but UCS definition can happen later # calculating corner points in local (UCS) coordinates without Vector class angle = math.radians(360 / 5) corners_ucs = [(math.cos(angle * n), math.sin(angle * n), 0) for n in range(5)] # let's do some transformations by UCS transformation_ucs = UCS().rotate_local_z(math.radians(15)) # 1. rotation around z-axis transformation_ucs.shift((0, .333, .333)) # 2. translation (inplace) corners_ucs = list(transformation_ucs.points_to_wcs(corners_ucs)) location_ucs = UCS(origin=(0, 2, 2)).rotate_local_x(math.radians(-45)) msp.add_polyline3d(
points=corners_ucs,
dxfattribs={
'closed': True,
'color': 1,
} ).transform(location_ucs.matrix) # Add lines from the center of the POLYLINE to the corners center_ucs = transformation_ucs.to_wcs((0, 0, 0)) for corner in corners_ucs:
msp.add_line(
center_ucs, corner, dxfattribs={'color': 1}
).transform(location_ucs.matrix)
The problem with the text rotation in the old tutorial disappears (or better it is hidden in transform()) with the new UCS based transformation method:
AutoCAD supports thickness for the TEXT entity only for .shx fonts and not for true type fonts.
# thickness for text works only with shx fonts not with true type fonts doc.styles.new('TXT', dxfattribs={'font': 'romans.shx'}) ucs = UCS(origin=(0, 2, 2)).rotate_local_x(math.radians(-45)) text = msp.add_text(
text="TEXT",
dxfattribs={
# text rotation angle in degrees in UCS
'rotation': -45,
'thickness': .333,
'color': 1,
'style': 'TXT',
} ) # set text position in UCS text.set_pos((0, 0, 0), align='MIDDLE_CENTER') text.transform(ucs.matrix)
Same as for the text example, OCS angle transformation can be ignored:
ucs = UCS(origin=(0, 2, 2)).rotate_local_x(math.radians(-45)) CENTER = (0, 0) START_ANGLE = 45 END_ANGLE = 270 msp.add_arc(
center=CENTER,
radius=1,
start_angle=START_ANGLE,
end_angle=END_ANGLE,
dxfattribs={'color': 6}, ).transform(ucs.matrix) msp.add_line(
start=CENTER,
end=Vector.from_deg_angle(START_ANGLE),
dxfattribs={'color': 6}, ).transform(ucs.matrix) msp.add_line(
start=CENTER,
end=Vector.from_deg_angle(END_ANGLE),
dxfattribs={'color': 6}, ).transform(ucs.matrix)
Despite the fact that block references (INSERT) can contain true 3D entities like LINE or MESH, the INSERT entity uses the same placing principe as TEXT or ARC shown in the previous chapters.
To rotate the block reference 15 degrees around the WCS x-axis, we place the block reference in the origin of the UCS, and rotate the UCS 90 degrees around its local y-axis, to align the UCS z-axis with the WCS x-axis:
This is just an excerpt of the important parts, see the whole code of insert.py at github.
doc = ezdxf.new('R2010', setup=True) blk = doc.blocks.new('CSYS') setup_csys(blk) msp = doc.modelspace() ucs = UCS().rotate_local_y(angle=math.radians(90)) msp.add_blockref(
'CSYS',
insert=(0, 0),
# rotation around the block z-axis (= WCS x-axis)
dxfattribs={'rotation': 15}, ).transform(ucs.matrix)
A more simple approach is to ignore the rotate attribute at all and just rotate the UCS. To rotate a block reference around any axis rather than the block z-axis, rotate the UCS into the desired position. Following example rotates the block reference around the block x-axis by 15 degrees:
ucs = UCS(origin=(1, 2, 0)).rotate_local_x(math.radians(15)) blockref = msp.add_blockref('CSYS', insert=(0, 0, 0)) blockref.transform(ucs.matrix)
The next example shows how to translate a block references with an already established OCS:
# New UCS at the translated location, axis aligned to the WCS ucs = UCS((-3, -1, 1)) # Transform an already placed block reference, including # the transformation of the established OCS. blockref.transform(ucs.matrix)
The next operation is to rotate a block reference with an established OCS, rotation axis is the block y-axis, rotation angle is -90 degrees. The idea is to create an UCS in the origin of the already placed block reference, UCS axis aligned to the block axis and resetting the block reference parameters for a new WCS transformation.
# Get UCS at the block reference insert location, UCS axis aligned # to the block axis. ucs = blockref.ucs() # Rotate UCS around the local y-axis. ucs = ucs.rotate_local_y(math.radians(-90))
Reset block reference parameters, this places the block reference in the UCS origin and aligns the block axis to the UCS axis, now we do a new transformation from UCS to WCS:
# Reset block reference parameters to place block reference in # UCS origin, without any rotation and OCS. blockref.reset_transformation() # Transform block reference from UCS to WCS blockref.transform(ucs.matrix)
The Dimension entity is the generic entity for all dimension types, but unfortunately AutoCAD is not willing to show a dimension line defined only by this dimension entity, it also needs an anonymous block which contains the dimension line shape constructed by basic DXF entities like LINE and TEXT entities, this representation is called the dimension line rendering in this documentation, beside the fact this is not a real graphical rendering. BricsCAD is a much more friendly CAD application, which do show the dimension entity without the graphical rendering as block, which was very useful for testing, because there is no documentation how to apply all the dimension style variables (more than 80). This seems to be the reason why dimension lines are rendered so differently by many CAD application.
Don’t expect to get the same rendering results by ezdxf as you get from AutoCAD, ezdxf tries to be as close to the results rendered by BricsCAD, but it was not possible to implement all the various combinations of dimension style parameters.
Text rendering is another problem, because ezdxf has no real rendering engine. Some font properties, like the real text width, are not available to ezdxf and may also vary slightly for different CAD applications. The text properties in ezdxf are based on the default monospaced standard font, but for TrueType fonts the space around the text is much bigger than needed.
Not all DIMENSION and DIMSTYLE features are supported by all DXF versions, especially DXF R12 does not support many features, but in this case the required rendering of dimension lines is an advantage, because if the application just shows the rendered block, all features which can be used in DXF R12 are displayed like linetypes, but they disappear if the dimension line is edited in the application. ezdxf writes only the supported DIMVARS of the used DXF version to avoid invalid DXF files. So it is not that critical to know all the supported features of a DXF version, except for limits and tolerances, ezdxf uses the advanced features of MTEXT to create limits and tolerances and therefore they are not supported (displayed) in DXF R12 files.
SEE ALSO:
import ezdxf # Argument setup=True setups the default dimension styles doc = ezdxf.new('R2010', setup=True) # Add new dimension entities to the modelspace msp = doc.modelspace() # Add a LINE entity, not required msp.add_line((0, 0), (3, 0)) # Add a horizontal dimension, default dimension style is 'EZDXF' dim = msp.add_linear_dim(base=(3, 2), p1=(0, 0), p2=(3, 0)) # Necessary second step, to create the BLOCK entity with the dimension geometry. # Additional processing of the dimension line could happen between adding and # rendering call. dim.render() doc.saveas('dim_linear_horiz.dxf')
[image]
The example above creates a horizontal Dimension entity, the default dimension style 'EZDXF' and is defined as 1 drawing unit is 1m in reality, the drawing scale 1:100 and the length factor is 100, which creates a measurement text in cm.
The base point defines the location of the dimension line, ezdxf accepts any point on the dimension line, the point p1 defines the start point of the first extension line, which also defines the first measurement point and the point p2 defines the start point of the second extension line, which also defines the second measurement point.
The return value dim is not a dimension entity, instead a DimStyleOverride object is returned, the dimension entity is stored as dim.dimension.
Argument angle defines the angle of the dimension line in relation to the x-axis of the WCS or UCS, measurement is the distance between first and second measurement point in direction of angle.
# assignment to dim is not necessary, if no additional processing happens msp.add_linear_dim(base=(3, 2), p1=(0, 0), p2=(3, 0), angle=-30).render() doc.saveas('dim_linear_rotated.dxf')
For a vertical dimension set argument angle to 90 degree, but in this example the vertical distance would be 0.
An aligned dimension line is parallel to the line defined by the definition points p1 and p2. The placement of the dimension line is defined by the argument distance, which is the distance between the definition line and the dimension line. The distance of the dimension line is orthogonal to the base line in counter clockwise orientation.
msp.add_line((0, 2), (3, 0)) dim = msp.add_aligned_dim(p1=(0, 2), p2=(3, 0), distance=1) doc.saveas('dim_linear_aligned.dxf')
Many dimension styling options are defined by the associated DimStyle entity. But often you wanna change just a few settings without creating a new dimension style, therefore the DXF format has a protocol to store this changed settings in the dimension entity itself. This protocol is supported by ezdxf and every factory function which creates dimension entities supports the override argument. This override argument is a simple Python dictionary (e.g. override = {'dimtad': 4}, place measurement text below dimension line).
The overriding protocol is managed by the DimStyleOverride object, which is returned by the most dimension factory functions.
The “default” location of the measurement text depends on various DimStyle parameters and is applied if no user defined text location is defined.
“Horizontal direction” means in direction of the dimension line and “vertical direction” means perpendicular to the dimension line direction.
The “horizontal” location of the measurement text is defined by dimjust:
0 | Center of dimension line |
1 | Left side of the dimension line, near first extension line |
2 | Right side of the dimension line, near second extension line |
3 | Over first extension line |
4 | Over second extension line |
msp.add_linear_dim(base=(3, 2), p1=(0, 0), p2=(3, 0), override={'dimjust': 1}).render()
The “vertical” location of the measurement text relative to the dimension line is defined by dimtad:
0 | Center, it is possible to adjust the vertical location by dimtvp |
1 | Above |
2 | Outside, handled like Above by ezdxf |
3 | JIS, handled like Above by ezdxf |
4 | Below |
msp.add_linear_dim(base=(3, 2), p1=(0, 0), p2=(3, 0), override={'dimtad': 4}).render()
The distance between text and dimension line is defined by dimgap.
The DimStyleOverride object has a method set_text_align() to set the default text location in an easy way, this is also the reason for the 2 step creation process of dimension entities:
dim = msp.add_linear_dim(base=(3, 2), p1=(0, 0), p2=(3, 0)) dim.set_text_align(halign='left', valign='center') dim.render()
halign | 'left', 'right', 'center', 'above1', 'above2' |
valign | 'above', 'center', 'below' |
Run function example_for_all_text_placings_R2007() in the example script dimension_linear.py to create a DXF file with all text placings supported by ezdxf.
Beside the default location, it is possible to locate the measurement text freely.
The user defined text location can be set by the argument location in most dimension factory functions and always references the midpoint of the measurement text:
msp.add_linear_dim(base=(3, 2), p1=(3, 0), p2=(6, 0), location=(4, 4)).render()
The location is relative to origin of the active coordinate system or WCS if no UCS is defined in the render() method, the user defined location can also be set by user_location_override().
The method set_location() has additional features for linear dimensions. Argument leader = True adds a simple leader from the measurement text to the center of the dimension line and argument relative = True places the measurement text relative to the center of the dimension line.
dim = msp.add_linear_dim(base=(3, 2), p1=(3, 0), p2=(6, 0)) dim.set_location(location=(-1, 1), leader=True, relative=True) dim.render()
The method shift_text() shifts the measurement text away from the default text location. Shifting directions are aligned to the text direction, which is the direction of the dimension line in most cases, dh (for delta horizontal) shifts the text parallel to the text direction, dv (for delta vertical) shifts the text perpendicular to the text direction. This method does not support leaders.
dim = msp.add_linear_dim(base=(3, 2), p1=(3, 0), p2=(6, 0)) dim.shift_text(dh=1, dv=1) dim.render()
DIMVAR | Description |
dimtxsty | Specifies the text style of the dimension as Textstyle name. |
dimtxt | Text height in drawing units. |
dimclrt | Measurement text color as ACI. |
msp.add_linear_dim(
base=(3, 2), p1=(3, 0), p2=(6, 0),
override={
'dimtxsty': 'Standard',
'dimtxt': 0.35,
'dimclrt': 1,
}).render()
[image]
Background fillings are supported since DXF R2007, and ezdxf uses the MTEXT entity to implement this feature, so setting background filling in DXF R12 has no effect.
Set dimtfill to 1 to use the canvas color as background filling or set dimtfill to 2 to use dimtfillclr as background filling, color value as ACI. Set dimtfill to 0 to disable background filling.
DIMVAR | Description |
dimtfill | Enables background filling if bigger than 0 |
dimtfillclr | Fill color as ACI, if dimtfill is 2 |
dimtfill | Description |
0 | disabled |
1 | canvas color |
2 | color defined by dimtfillclr |
msp.add_linear_dim(
base=(3, 2), p1=(3, 0), p2=(6, 0),
override={
'dimtfill': 2,
'dimtfillclr': 1,
}).render()
To set this values the ezdxf.entities.DimStyle.set_text_format() and ezdxf.entities.DimStyleOverride.set_text_format() methods are very recommended.
Measurement text overriding is stored in the Dimension entity, the content of to DXF attribute text represents the override value as string. Special values are one space ' ' to just suppress the measurement text, an empty string '' or '<>' to get the regular measurement.
All factory functions have an explicit text argument, which always replaces the text value in the dxfattribs dict.
msp.add_linear_dim(base=(3, 2), p1=(3, 0), p2=(6, 0), text='>1m').render()
The dimension line color is defined by the DIMVAR dimclrd as ACI, dimclrd also defines the color of the arrows. The linetype is defined by dimltype but requires DXF R2007 for full support by CAD Applications and the line weight is defined by dimlwd (DXF R2000), see also the lineweight reference for valid values. The dimdle is the extension of the dimension line beyond the extension lines, this dimension line extension is not supported for all arrows.
DIMVAR | Description |
dimclrd | dimension line and arrows color as ACI |
dimltype | linetype of dimension line |
dimlwd | line weight of dimension line |
dimdle | extension of dimension line in drawing units |
msp.add_linear_dim(
base=(3, 2), p1=(3, 0), p2=(6, 0),
override={
'dimclrd': 1, # red
'dimdle': 0.25,
'dimltype': 'DASHED2',
'dimlwd': 35, # 0.35mm line weight
}).render()
[image]
DimStyleOverride() method:
dim = msp.add_linear_dim(base=(3, 2), p1=(3, 0), p2=(6, 0)) dim.set_dimline_format(color=1, linetype='DASHED2', lineweight=35, extension=0.25) dim.render()
The extension line color is defined by the DIMVAR dimclre as ACI. The linetype for first and second extension line is defined by dimltex1 and dimltex2 but requires DXF R2007 for full support by CAD Applications and the line weight is defined by dimlwe (DXF R2000), see also the lineweight reference for valid values.
The dimexe is the extension of the extension line beyond the dimension line, and dimexo defines the offset of the extension line from the measurement point.
DIMVAR | Description |
dimclre | extension line color as ACI |
dimltex1 | linetype of first extension line |
dimltex2 | linetype of second extension line |
dimlwe | line weight of extension line |
dimexe | extension beyond dimension line in drawing units |
dimexo | offset of extension line from measurement point |
dimfxlon | set to 1 to enable fixed length extension line |
dimfxl | length of fixed length extension line in drawing units |
dimse1 | suppress first extension line if 1 |
dimse2 | suppress second extension line if 1 |
msp.add_linear_dim(
base=(3, 2), p1=(3, 0), p2=(6, 0),
override={
'dimclre': 1, # red
'dimltex1': 'DASHED2',
'dimltex2': 'CENTER2',
'dimlwe': 35, # 0.35mm line weight
'dimexe': 0.3, # length above dimension line
'dimexo': 0.1, # offset from measurement point
}).render()
DimStyleOverride() methods:
dim = msp.add_linear_dim(base=(3, 2), p1=(3, 0), p2=(6, 0)) dim.set_extline_format(color=1, lineweight=35, extension=0.3, offset=0.1) dim.set_extline1(linetype='DASHED2') dim.set_extline2(linetype='CENTER2') dim.render()
Fixed length extension lines are supported in DXF R2007+, set dimfxlon to 1 and dimfxl defines the length of the extension line starting at the dimension line.
msp.add_linear_dim(
base=(3, 2), p1=(3, 0), p2=(6, 0),
override={
'dimfxlon': 1, # fixed length extension lines
'dimexe': 0.2, # length above dimension line
'dimfxl': 0.4, # length below dimension line
}).render()
DimStyleOverride() method:
dim = msp.add_linear_dim(base=(3, 2), p1=(3, 0), p2=(6, 0)) dim.set_extline_format(extension=0.2, fixed_length=0.4) dim.render()
To suppress extension lines set dimse1 = 1 to suppress the first extension line and dimse2 = 1 to suppress the second extension line.
msp.add_linear_dim(
base=(3, 2), p1=(3, 0), p2=(6, 0),
override={
'dimse1': 1, # suppress first extension line
'dimse2': 1, # suppress second extension line
'dimblk': ezdxf.ARROWS.closed_filled, # arrows just looks better
}).render()
DimStyleOverride() methods:
dim = msp.add_linear_dim(base=(3, 2), p1=(3, 0), p2=(6, 0)) dim.set_arrows(blk=ezdxf.ARROWS.closed_filled) dim.set_extline1(disable=True) dim.set_extline2(disable=True) dim.render()
“Arrows” mark then beginning and the end of a dimension line, and most of them do not look like arrows.
DXF distinguish between the simple tick and arrows as blocks.
Using the simple tick by setting tick size dimtsz != 0 also disables arrow blocks as side effect:
dim = msp.add_linear_dim(base=(3, 2), p1=(3, 0), p2=(6, 0)) dim.set_tick(size=0.25) dim.render()
ezdxf uses the "ARCHTICK" block at double size to render the tick (AutoCAD and BricsCad just draw a simple line), so there is no advantage of using the tick instead of an arrow.
Using arrows:
dim = msp.add_linear_dim(base=(3, 2), p1=(3, 0), p2=(6, 0)) dim.set_arrow(blk="OPEN_30", size=0.25) dim.render()
DIMVAR | Description |
dimtsz | tick size in drawing units, set to 0 to use arrows |
dimblk | set both arrow block names at once |
dimblk1 | first arrow block name |
dimblk2 | second arrow block name |
dimasz | arrow size in drawing units |
msp.add_linear_dim(
base=(3, 2), p1=(3, 0), p2=(6, 0),
override={
'dimtsz': 0, # set tick size to 0 to enable arrow usage
'dimasz': 0.25, # arrow size in drawing units
'dimblk': "OPEN_30", # arrow block name
}).render()
Dimension line extension (dimdle) works only for a few arrow blocks and the simple tick:
[image]
The arrow names are stored as attributes in the ezdxf.ARROWS object.
closed_filled | "" (empty string) |
dot | "DOT" |
dot_small | "DOTSMALL" |
dot_blank | "DOTBLANK" |
origin_indicator | "ORIGIN" |
origin_indicator_2 | "ORIGIN2" |
open | "OPEN" |
right_angle | "OPEN90" |
open_30 | "OPEN30" |
closed | "CLOSED" |
dot_smallblank | "SMALL" |
none | "NONE" |
oblique | "OBLIQUE" |
box_filled | "BOXFILLED" |
box | "BOXBLANK" |
closed_blank | "CLOSEDBLANK" |
datum_triangle_filled | "DATUMFILLED" |
datum_triangle | "DATUMBLANK" |
integral | "INTEGRAL" |
architectural_tick | "ARCHTICK" |
ez_arrow | "EZ_ARROW" |
ez_arrow_blank | "EZ_ARROW_BLANK" |
ez_arrow_filled | "EZ_ARROW_FILLED" |
The tolerances ans limits features are implemented by using the MText entity, therefore DXF R2000+ is required to use these features. It is not possible to use both tolerances and limits at the same time.
Geometrical tolerances are shown as additional text appended to the measurement text. It is recommend to use set_tolerance() method in DimStyleOverride or DimStyle.
The attribute dimtp defines the upper tolerance value, dimtm defines the lower tolerance value if present, else the lower tolerance value is the same as the upper tolerance value. Tolerance values are shown as given!
Same upper and lower tolerance value:
dim = msp.add_linear_dim(base=(0, 3), p1=(3, 0), p2=(6.5, 0)) dim.set_tolerance(.1, hfactor=.4, align="top", dec=2) dim.render()
Different upper and lower tolerance values:
dim = msp.add_linear_dim(base=(0, 3), p1=(3, 0), p2=(6.5, 0)) dim.set_tolerance(upper=.1, lower=.15, hfactor=.4, align="middle", dec=2) dim.render()
The attribute dimtfac specifies a scale factor for the text height of limits and tolerance values relative to the dimension text height, as set by dimtxt. For example, if dimtfac is set to 1.0, the text height of fractions and tolerances is the same height as the dimension text. If dimtxt is set to 0.75, the text height of limits and tolerances is three-quarters the size of dimension text.
Vertical justification for tolerances is specified by dimtolj:
dimtolj | Description |
0 | Align with bottom line of dimension text |
1 | Align vertical centered to dimension text |
2 | Align with top line of dimension text |
DIMVAR | Description |
dimtol | set to 1 to enable tolerances |
dimtp | set the maximum (or upper) tolerance limit for dimension text |
dimtm | set the minimum (or lower) tolerance limit for dimension text |
dimtfac | specifies a scale factor for the text height of limits and tolerance values relative to the dimension text height, as set by dimtxt. |
dimtzin | 4 to suppress leading zeros, 8 to suppress trailing zeros or 12 to suppress both, like dimzin for dimension text, see also Text Formatting |
dimtolj | set the vertical justification for tolerance values relative to the nominal dimension text. |
dimtdec | set the number of decimal places to display in tolerance values |
The geometrical limits are shown as upper and lower measurement limit and replaces the usual measurement text. It is recommend to use set_limits() method in DimStyleOverride or DimStyle.
For limits the tolerance values are drawing units scaled by measurement factor dimlfac, the upper limit is scaled measurement value + dimtp and the lower limit is scaled measurement value - dimtm.
The attributes dimtfac, dimtzin and dimtdec have the same meaning for limits as for tolerances.
dim = msp.add_linear_dim(base=(0, 3), p1=(3, 0), p2=(6.5, 0)) dim.set_limits(upper=.1, lower=.15, hfactor=.4, dec=2) dim.render()
DIMVAR | Description |
dimlim | set to 1 to enable limits |
Alternative units are not supported.
Please read the tut_linear_dimension before, if you haven’t.
import ezdxf # DXF R2010 drawing, official DXF version name: 'AC1024', # setup=True setups the default dimension styles doc = ezdxf.new('R2010', setup=True) msp = doc.modelspace() # add new dimension entities to the modelspace msp.add_circle((0, 0), radius=3) # add a CIRCLE entity, not required # add default radius dimension, measurement text is located outside dim = msp.add_radius_dim(center=(0, 0), radius=3, angle=45, dimstyle='EZ_RADIUS') # necessary second step, to create the BLOCK entity with the dimension geometry. dim.render() doc.saveas('radius_dimension.dxf')
The example above creates a 45 degrees slanted radius Dimension entity, the default dimension style 'EZ_RADIUS' is defined as 1 drawing unit is 1m in reality, drawing scale 1:100 and the length factor is 100, which creates a measurement text in cm, the default location for the measurement text is outside of the circle.
The center point defines the the center of the circle but there doesn’t have to exist a circle entity, radius defines the circle radius, which is also the measurement, and angle defines the slope of the dimension line, it is also possible to define the circle by a measurement point mpoint on the circle.
The return value dim is not a dimension entity, instead a DimStyleOverride object is returned, the dimension entity is stored as dim.dimension.
There are different predefined DIMSTYLES to achieve various text placing locations.
DIMSTYLE 'EZ_RADIUS' settings are: 1 drawing unit is 1m, scale 1:100, length_factor is 100 which creates measurement text in cm, and a closed filled arrow with size 0.25 is used.
NOTE:
SEE ALSO:
'EZ_RADIUS' default settings for to place text outside:
tmove | 1 to keep dim line with text, this is the best setting for text outside to preserve appearance of the DIMENSION entity, if editing afterwards in BricsCAD or AutoCAD. |
dimtad | 1 to place text vertical above the dimension line |
dim = msp.add_radius_dim(center=(0, 0), radius=2.5, angle=45,
dimstyle='EZ_RADIUS'
) dim.render() # required, but not shown in the following examples
[image]
To force text outside horizontal set dimtoh to 1:
dim = msp.add_radius_dim(center=(0, 0), radius=2.5, angle=45,
dimstyle='EZ_RADIUS',
override={'dimtoh': 1}
)
DIMSTYLE 'EZ_RADIUS_INSIDE' can be used to place the dimension text inside the circle at a default location. Default DIMSTYLE settings are: 1 drawing unit is 1m, scale 1:100, length_factor is 100 which creates measurement text in cm, and a closed filled arrow with size 0.25 is used.
'EZ_RADIUS_INSIDE' default settings:
tmove | 0 to keep dim line with text, this is the best setting for text inside to preserve appearance of the DIMENSION entity, if editing afterwards in BricsCAD or AutoCAD. |
dimtix | 1 to force text inside |
dimatfit | 0 to force text inside, required by BricsCAD and AutoCAD |
dimtad | 0 to center text vertical, BricsCAD and AutoCAD always create vertical centered text, ezdxf let you choose the vertical placement (above, below, center), but editing the DIMENSION in BricsCAD or AutoCAD will reset text to center placement. |
dim = msp.add_radius_dim(center=(0, 0), radius=2.5, angle=45,
dimstyle='EZ_RADIUS_INSIDE'
)
To force text inside horizontal set dimtih to 1:
dim = msp.add_radius_dim(center=(0, 0), radius=2.5, angle=45,
dimstyle='EZ_RADIUS_INSIDE',
override={'dimtih': 1}
)
Beside the default location it is always possible to override the text location by a user defined location. This location also determines the angle of the dimension line and overrides the argument angle. For user defined locations it is not necessary to force text inside (dimtix=1), because the location of the text is explicit given, therefore the DIMSTYLE 'EZ_RADIUS' can be used for all this examples.
User defined location outside of the circle:
dim = msp.add_radius_dim(center=(0, 0), radius=2.5, location=(4, 4),
dimstyle='EZ_RADIUS'
)
User defined location outside of the circle and forced horizontal text:
dim = msp.add_radius_dim(center=(0, 0), radius=2.5, location=(4, 4),
dimstyle='EZ_RADIUS',
override={'dimtoh': 1}
)
User defined location inside of the circle:
dim = msp.add_radius_dim(center=(0, 0), radius=2.5, location=(1, 1),
dimstyle='EZ_RADIUS'
)
User defined location inside of the circle and forced horizontal text:
dim = msp.add_radius_dim(center=(0, 0), radius=2.5, location=(1, 1),
dimstyle='EZ_RADIUS',
override={'dimtih': 1},
)
Center mark/lines are controlled by dimcen, default value is 0 for predefined dimstyles 'EZ_RADIUS' and 'EZ_RADIUS_INSIDE' :
0 | Center mark is off |
>0 | Create center mark of given size |
<0 | Create center lines |
dim = msp.add_radius_dim(center=(0, 0), radius=2.5, angle=45,
dimstyle='EZ_RADIUS',
override={'dimcen': 0.25},
)
[image]
See Linear Dimension Tutorial: tut_overriding_measurement_text
See Linear Dimension Tutorial: tut_measurement_text_formatting_and_styling
Please read the tut_radius_dimension before, if you haven’t.
This is a repetition of the radius tutorial, just with diameter dimensions.
import ezdxf # setup=True setups the default dimension styles doc = ezdxf.new('R2010', setup=True) msp = doc.modelspace() # add new dimension entities to the modelspace msp.add_circle((0, 0), radius=3) # add a CIRCLE entity, not required # add default diameter dimension, measurement text is located outside dim = msp.add_diameter_dim(center=(0, 0), radius=3, angle=45, dimstyle='EZ_RADIUS') dim.render() doc.saveas('diameter_dimension.dxf')
The example above creates a 45 degrees slanted diameter Dimension entity, the default dimension style 'EZ_RADIUS' (same as for radius dimensions) is defined as 1 drawing unit is 1m in reality, drawing scale 1:100 and the length factor is 100, which creates a measurement text in cm, the default location for the measurement text is outside of the circle.
The center point defines the the center of the circle but there doesn’t have to exist a circle entity, radius defines the circle radius and angle defines the slope of the dimension line, it is also possible to define the circle by a measurement point mpoint on the circle.
The return value dim is not a dimension entity, instead a DimStyleOverride object is returned, the dimension entity is stored as dim.dimension.
There are different predefined DIMSTYLES to achieve various text placing locations.
DIMSTYLE 'EZ_RADIUS' settings are: 1 drawing unit is 1m, scale 1:100, length_factor is 100 which creates measurement text in cm, and a closed filled arrow with size 0.25 is used.
NOTE:
SEE ALSO:
'EZ_RADIUS' default settings for to place text outside:
tmove | 1 to keep dim line with text, this is the best setting for text outside to preserve appearance of the DIMENSION entity, if editing afterwards in BricsCAD or AutoCAD. |
dimtad | 1 to place text vertical above the dimension line |
dim = msp.add_diameter_dim(center=(0, 0), radius=2.5, angle=45,
dimstyle='EZ_RADIUS') dim.render() # required, but not shown in the following examples
[image]
To force text outside horizontal set dimtoh to 1:
dim = msp.add_diameter_dim(center=(0, 0), radius=2.5, angle=45,
dimstyle='EZ_RADIUS',
override={'dimtoh': 1}
)
DIMSTYLE 'EZ_RADIUS_INSIDE' can be used to place the dimension text inside the circle at a default location. Default DIMSTYLE settings are: 1 drawing unit is 1m, scale 1:100, length_factor is 100 which creates measurement text in cm, and a closed filled arrow with size 0.25 is used.
'EZ_RADIUS_INSIDE' default settings:
tmove | 0 to keep dim line with text, this is the best setting for text inside to preserve appearance of the DIMENSION entity, if editing afterwards in BricsCAD or AutoCAD. |
dimtix | 1 to force text inside |
dimatfit | 0 to force text inside, required by BricsCAD and AutoCAD |
dimtad | 0 to center text vertical, BricsCAD and AutoCAD always create vertical centered text, ezdxf let you choose the vertical placement (above, below, center), but editing the DIMENSION in BricsCAD or AutoCAD will reset text to center placement. |
dim = msp.add_diameter_dim(center=(0, 0), radius=2.5, angle=45,
dimstyle='EZ_RADIUS_INSIDE'
)
To force text inside horizontal set dimtih to 1:
dim = msp.add_diameter_dim(center=(0, 0), radius=2.5, angle=45,
dimstyle='EZ_RADIUS_INSIDE',
override={'dimtih': 1}
)
Beside the default location it is always possible to override the text location by a user defined location. This location also determines the angle of the dimension line and overrides the argument angle. For user defined locations it is not necessary to force text inside (dimtix=1), because the location of the text is explicit given, therefore the DIMSTYLE 'EZ_RADIUS' can be used for all this examples.
User defined location outside of the circle:
dim = msp.add_diameter_dim(center=(0, 0), radius=2.5, location=(4, 4),
dimstyle='EZ_RADIUS'
)
User defined location outside of the circle and forced horizontal text:
dim = msp.add_diameter_dim(center=(0, 0), radius=2.5, location=(4, 4),
dimstyle='EZ_RADIUS',
override={'dimtoh': 1}
)
User defined location inside of the circle:
dim = msp.add_diameter_dim(center=(0, 0), radius=2.5, location=(1, 1),
dimstyle='EZ_RADIUS'
)
User defined location inside of the circle and forced horizontal text:
dim = msp.add_diameter_dim(center=(0, 0), radius=2.5, location=(1, 1),
dimstyle='EZ_RADIUS',
override={'dimtih': 1},
)
See Radius Dimension Tutorial: tut_center_mark
See Linear Dimension Tutorial: tut_overriding_measurement_text
See Linear Dimension Tutorial: tut_measurement_text_formatting_and_styling
The DXF Reference is online available at Autodesk.
Quoted from the original DXF 12 Reference which is not available on the web:
new() can create drawings for following DXF versions:
Version | AutoCAD Release |
AC1009 | AutoCAD R12 |
AC1015 | AutoCAD R2000 |
AC1018 | AutoCAD R2004 |
AC1021 | AutoCAD R2007 |
AC1024 | AutoCAD R2010 |
AC1027 | AutoCAD R2013 |
AC1032 | AutoCAD R2018 |
setup default styles, False for no setup, True to setup everything or a list of topics as strings, e.g. [“linetypes”, “styles”] to setup only some topics:
Topic | Description |
linetypes | setup line types |
styles | setup text styles |
dimstyles | setup default ezdxf dimension styles |
visualstyles | setup 25 standard visual styles |
Open DXF drawings from file system or text stream, byte stream usage is not supported.
DXF files prior to R2007 requires file encoding defined by header variable $DWGCODEPAGE, DXF R2007 and later requires an UTF-8 encoding.
ezdxf supports reading of files for following DXF versions:
Version | Release | Encoding | Remarks |
< AC1009 | $DWGCODEPAGE | pre AutoCAD R12 upgraded to AC1009 | |
AC1009 | R12 | $DWGCODEPAGE | AutoCAD R12 |
AC1012 | R13 | $DWGCODEPAGE | AutoCAD R13 upgraded to AC1015 |
AC1014 | R14 | $DWGCODEPAGE | AutoCAD R14 upgraded to AC1015 |
AC1015 | R2000 | $DWGCODEPAGE | AutoCAD R2000 |
AC1018 | R2004 | $DWGCODEPAGE | AutoCAD R2004 |
AC1021 | R2007 | UTF-8 | AutoCAD R2007 |
AC1024 | R2010 | UTF-8 | AutoCAD R2010 |
AC1027 | R2013 | UTF-8 | AutoCAD R2013 |
AC1032 | R2018 | UTF-8 | AutoCAD R2018 |
This is the preferred method to load existing ASCII or Binary DXF files, the required text encoding will be detected automatically and decoding errors will be ignored.
Override encoding detection by setting argument encoding to the estimated encoding. (use Python encoding names like in the open() function).
If this function struggles to load the DXF document and raises a DXFStructureError exception, try the ezdxf.recover.readfile() function to load this corrupt DXF document.
specify decoding error handler
Deprecated since version v0.14: argument legacy_mode, use module ezdxf.recover to load DXF documents with structural flaws.
Since DXF version R2007 (AC1021) file encoding is always “utf-8”, use the helper function dxf_stream_info() to detect the required text encoding for prior DXF versions. To preserve possible binary data in use errors='surrogateescape' as error handler for the import stream.
If this function struggles to load the DXF document and raises a DXFStructureError exception, try the ezdxf.recover.read() function to load this corrupt DXF document.
Deprecated since version v0.14: argument legacy_mode, use module ezdxf.recover to load DXF documents with structural flaws.
specify decoding error handler
specify decoding error handler
HINT:
Save the DXF document to the file system by Drawing methods save() or saveas(). Write the DXF document to a text stream with write(), the text stream requires at least a write() method. Get required output encoding for text streams by property Drawing.output_encoding
The HeaderSection stores meta data like modelspace extensions, user name or saving time and current application settings, like actual layer, text style or dimension style settings. These settings are not necessary to process DXF data and therefore many of this settings are not maintained by ezdxf automatically.
$ACADVER | DXF version |
$TDCREATE | date/time at creating the drawing |
$FINGERPRINTGUID | every drawing gets a GUID |
$TDUPDATE | actual date/time at saving |
$HANDSEED | next available handle as hex string |
$DWGCODEPAGE | encoding setting |
$VERSIONGUID | every saved version gets a new GUID |
SEE ALSO:
For supported DXF versions see dwgmanagement
see also: dxf file encoding
supported | encodings |
'cp874' | Thai |
'cp932' | Japanese |
'gbk' | UnifiedChinese |
'cp949' | Korean |
'cp950' | TradChinese |
'cp1250' | CentralEurope |
'cp1251' | Cyrillic |
'cp1252' | WesternEurope |
'cp1253' | Greek |
'cp1254' | Turkish |
'cp1255' | Hebrew |
'cp1256' | Arabic |
'cp1257' | Baltic |
'cp1258' | Vietnam |
New in version 0.11.
requires DXF R13 or later
Reference to the layers table, where you can create, get and remove layers, see also Table and Layer
Reference to the styles table, see also Style.
Reference to the dimstyles table, see also DimStyle.
Reference to the linetypes table, see also Linetype.
Reference to the views table, see also View.
Reference to the viewports table, see also Viewport.
Reference to the ucs table, see also UCS.
Reference to the appids table, see also AppID.
If writing to a StringIO stream, use Drawing.encode() to encode the result string from StringIO.get_value():
binary = doc.encode(stream.get_value())
SEE ALSO:
SEE ALSO:
Add an ImageDef entity to the drawing (objects section). filename is the image file name as relative or absolute path and size_in_pixel is the image size in pixel as (x, y) tuple. To avoid dependencies to external packages, ezdxf can not determine the image size by itself. Returns a ImageDef entity which is needed to create an image reference. name is the internal image name, if set to None, name is auto-generated.
Absolute image paths works best for AutoCAD but not really good, you have to update external references manually in AutoCAD, which is not possible in TrueView. If the drawing units differ from 1 meter, you also have to use: set_raster_variables().
SEE ALSO:
units for inserting images. This defines the real world unit for one drawing unit for the purpose of inserting and scaling images with an associated resolution.
mm | Millimeter |
cm | Centimeter |
m | Meter (ezdxf default) |
km | Kilometer |
in | Inch |
ft | Foot |
yd | Yard |
mi | Mile |
SEE ALSO:
If you are messing around with internal structures, call this method before saving to be sure to export valid DXF documents, but be aware this is a long running task.
Returns: True if no errors occurred
New in version v0.14.
This module provides functions to “recover” ASCII DXF documents with structural flaws, which prevents the regular ezdxf.read() and ezdxf.readfile() functions to load the document.
The read() and readfile() functions will repair as much flaws as possible and run the required audit process automatically afterwards and return the result of this audit process:
import sys import ezdxf from ezdxf import recover try:
doc, auditor = recover.readfile("messy.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) # DXF file can still have unrecoverable errors, but this is maybe just # a problem when saving the recovered DXF file. if auditor.has_errors:
auditor.print_error_report()
This efforts cost some time, loading the DXF document with ezdxf.read() or ezdxf.readfile() will be faster.
WARNING:
Writing such files back with ezdxf may create invalid DXF files, or at least some information will be lost - handle with care!
To avoid this problem use recover.readfile(filename, errors='strict') which raises an UnicodeDecodeError exception for such binary data. Catch the exception and handle this DXF files as unrecoverable.
Mostly DXF files from AutoCAD or BricsCAD (e.g. for In-house solutions):
try:
doc = ezdxf.readfile(name) 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: {name}.')
sys.exit(2)
DXF files have only minor flaws, like undefined resources:
try:
doc = ezdxf.readfile(name) 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: {name}.')
sys.exit(2) auditor = doc.audit() if auditor.has_errors:
auditor.print_error_report()
From trusted and untrusted sources but with good hopes, the worst case works like a cache miss, you pay for the first try and pay the extra fee for the recover mode:
try: # Fast path:
doc = ezdxf.readfile(name) except IOError:
print(f'Not a DXF file or a generic I/O error.')
sys.exit(1) # Catch all DXF errors: except ezdxf.DXFError:
try: # Slow path including fixing low level structures:
doc, auditor = recover.readfile(name)
except ezdxf.DXFStructureError:
print(f'Invalid or corrupted DXF file: {name}.')
sys.exit(2) # DXF file can still have unrecoverable errors, but this is maybe # just a problem when saving the recovered DXF file. if auditor.has_errors:
print(f'Found unrecoverable errors in DXF file: {name}.')
auditor.print_error_report()
Untrusted sources and expecting many invalid or corrupted DXF files, you always pay an extra fee for the recover mode:
try: # Slow path including fixing low level structures:
doc, auditor = recover.readfile(name) 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: {name}.')
sys.exit(2) # DXF file can still have unrecoverable errors, but this is maybe # just a problem when saving the recovered DXF file. if auditor.has_errors:
print(f'Found unrecoverable errors in DXF file: {name}.')
auditor.print_error_report()
If files contain binary data which can not be decoded by the document encoding, it is maybe the best to ignore this files, this works in normal and recover mode:
try:
doc, auditor = recover.readfile(name, errors='strict') 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: {name}.')
sys.exit(2) except UnicodeDecodeError:
print(f'Decoding error in DXF file: {name}.')
sys.exit(3)
Sometimes ignoring decoding errors can recover DXF files or at least you can detect where the decoding errors occur:
try:
doc, auditor = recover.readfile(name, errors='ignore') 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: {name}.')
sys.exit(2) if auditor.has_errors:
auditor.print_report()
The error messages with code AuditError.DECODING_ERROR shows the approximate line number of the decoding error: “Fixed unicode decoding error near line: xxx.”
HINT:
specify decoding error handler
specify decoding error handler
The drawing settings are stored in the HEADER section, which is accessible by the header attribute of the Drawing object. See the online documentation from Autodesk for available header variables.
SEE ALSO:
The CLASSES section in DXF files holds the information for application-defined classes whose instances appear in Layout objects. As usual package user there is no need to bother about CLASSES.
SEE ALSO:
Storage key is the (name, cpp_class_name) tuple, because there are some classes with the same name but different cpp_class_names.
0 | No operations allowed (0) |
1 | Erase allowed (0x1) |
2 | Transform allowed (0x2) |
4 | Color change allowed (0x4) |
8 | Layer change allowed (0x8) |
16 | Linetype change allowed (0x10) |
32 | Linetype scale change allowed (0x20) |
64 | Visibility change allowed (0x40) |
128 | Cloning allowed (0x80) |
256 | Lineweight change allowed (0x100) |
512 | Plot Style Name change allowed (0x200) |
895 | All operations except cloning allowed (0x37F) |
1023 | All operations allowed (0x3FF) |
1024 | Disables proxy warning dialog (0x400) |
32768 | R13 format proxy (0x8000) |
The TABLES section is the home of all TABLE objects of a DXF document.
SEE ALSO:
The BLOCKS section is the home all block definitions (BlockLayout) of a DXF document.
SEE ALSO:
type_char | Anonymous Block Type |
'U' | '*U###' anonymous BLOCK |
'E' | '*E###' anonymous non-uniformly scaled BLOCK |
'X' | '*X###' anonymous HATCH graphic |
'D' | '*D###' anonymous DIMENSION graphic |
'A' | '*A###' anonymous GROUP |
'T' | '*T###' anonymous block for ACAD_TABLE content |
WARNING:
Changed in version 0.14: removed unsafe mode
WARNING:
The ENTITIES section is the home of all Modelspace and active Paperspace layout entities. This is a real section in the DXF file, for ezdxf the EntitySection is just a proxy for modelspace and the active paperspace linked together.
SEE ALSO:
The OBJECTS section is the home of all none graphical objects of a DXF document. The OBJECTS section is accessible by Drawing.objects.
Convenience methods of the Drawing object to create required structures in the OBJECTS section:
SEE ALSO:
The underlying data structure for storing DXF objects is organized like a standard Python list, therefore index can be any valid list indexing or slicing term, like a single index objects[-1] to get the last entity, or an index slice objects[:10] to get the first 10 or less objects as List[DXFObject].
The GEODATA entity requires DXF version R2010+. The DXF Reference does not document if other layouts than model space supports geo referencing, so getting/setting geo data may only make sense for the model space layout, but it is also available in paper space layouts.
Add an ImageDef entity to the drawing (objects section). filename is the image file name as relative or absolute path and size_in_pixel is the image size in pixel as (x, y) tuple. To avoid dependencies to external packages, ezdxf can not determine the image size by itself. Returns a ImageDef entity which is needed to create an image reference. name is the internal image name, if set to None, name is auto-generated.
Absolute image paths works best for AutoCAD but not really good, you have to update external references manually in AutoCAD, which is not possible in TrueView. If the drawing units differ from 1 meter, you also have to use: set_raster_variables().
units for inserting images. This defines the real world unit for one drawing unit for the purpose of inserting and scaling images with an associated resolution.
mm | Millimeter |
cm | Centimeter |
m | Meter (ezdxf default) |
km | Kilometer |
in | Inch |
ft | Foot |
yd | Yard |
mi | Mile |
(internal API), public interface set_raster_variables()
(internal API), public interface set_wipeout_variables()
Collection of Layer objects.
Generic table class of Table.
Collection of Linetype objects.
Collection of Textstyle objects.
A .shx shape file table entry has no name, so you have to search by the font attribute.
Generic table class of Table.
Collection of DimStyle objects.
Generic table class of Table.
Collection of AppID objects.
Generic table class of Table.
Collection of UCSTable objects.
Generic table class of Table.
Collection of View objects.
The name of the actual displayed viewport configuration is '*ACTIVE'.
Duplication of table entries is not supported: duplicate_entry() raises NotImplementedError
Generic table class of Table.
Collection of BlockRecord objects.
LAYER (DXF Reference) definition, defines attribute values for entities on this layer for their attributes set to BYLAYER.
Subclass of | ezdxf.entities.DXFEntity |
DXF type | 'LAYER' |
Factory function | Drawing.layers.new() |
SEE ALSO:
1 | Layer is frozen; otherwise layer is thawed; use is_frozen(), freeze() and thaw() |
2 | Layer is frozen by default in new viewports |
4 | Layer is locked; use is_locked(), lock(), unlock() |
16 | If set, table entry is externally dependent on an xref |
32 | If both this bit and bit 16 are set, the externally dependent xref has been successfully resolved |
64 | If set, the table entry was referenced by at least one entity in the drawing the last time the drawing was edited. (This flag is for the benefit of AutoCAD commands. It can be ignored by most programs that read DXF files and need not be set by programs that write DXF files) |
(requires DXF R2004)
1 | plot layer (default value) |
0 | don’t plot layer |
ezdxf.lldxf.const.LINEWEIGHT_DEFAULT for using global default line weight.
(requires DXF R13)
(requires DXF R13)
(requires DXF R13)
layer.rgb = (30, 40, 50) r, g, b = layer.rgb
This is the recommend method to get/set RGB values, when ever possible do not use the DXF low level attribute dxf.true_color.
New in version 0.10.
New in version 0.10.
New in version 0.10.
New in version 0.10.
WARNING:
Defines a text style (DXF Reference), can be used by entities: Text, Attrib and Attdef.
Subclass of | ezdxf.entities.DXFEntity |
DXF type | 'STYLE' |
Factory function | Drawing.styles.new() |
SEE ALSO:
1 | If set, this entry describes a shape |
4 | Vertical text |
16 | If set, table entry is externally dependent on an xref |
32 | If both this bit and bit 16 are set, the externally dependent xref has been successfully resolved |
64 | If set, the table entry was referenced by at least one entity in the drawing the last time the drawing was edited. (This flag is only for the benefit of AutoCAD)commands. It can be ignored by most programs that read DXF files and need not be set by programs that write DXF files) |
2 | text is backward (mirrored in X) |
4 | text is upside down (mirrored in Y) |
Defines a linetype (DXF Reference).
Subclass of | ezdxf.entities.DXFEntity |
DXF type | 'LTYPE' |
Factory function | Drawing.linetypes.new() |
SEE ALSO:
DXF Internals: ltype_table_internals
[image] [image]
DIMSTYLE (DXF Reference) defines the appearance of Dimension entities. Each of this dimension variables starting with dim... can be overridden for any Dimension entity individually.
Subclass of | ezdxf.entities.DXFEntity |
DXF type | 'DIMSTYLE' |
Factory function | Drawing.dimstyles.new() |
16 | If set, table entry is externally dependent on an xref |
32 | If both this bit and bit 16 are set, the externally dependent xref has been successfully resolved |
64 | If set, the table entry was referenced by at least one entity in the drawing the last time the drawing was edited. (This flag is only for the benefit of AutoCAD) |
Rounds all dimensioning distances to the specified value, for instance, if DIMRND is set to 0.25, all distances round to the nearest 0.25 unit. If you set DIMRND to 1.0, all distances round to the nearest integer.
0 | center |
1 | above |
2 | outside, handled like above by ezdxf |
3 | JIS, handled like above by ezdxf |
4 | below |
Values 0-3 affect feet-and-inch dimensions only.
0 | Suppresses zero feet and precisely zero inches |
1 | Includes zero feet and precisely zero inches |
2 | Includes zero feet and suppresses zero inches |
3 | Includes zero inches and suppresses zero feet |
4 | Suppresses leading zeros in decimal dimensions (for example, 0.5000 becomes .5000) |
8 | Suppresses trailing zeros in decimal dimensions (for example, 12.5000 becomes 12.5) |
12 | Suppresses both leading and trailing zeros (for example, 0.5000 becomes .5) |
0 | Displays all leading and trailing zeros |
1 | Suppresses leading zeros in decimal dimensions (for example, 0.5000 becomes .5000) |
2 | Suppresses trailing zeros in decimal dimensions (for example, 12.5000 becomes 12.5) |
3 | Suppresses leading and trailing zeros (for example, 0.5000 becomes .5) |
0 | Moves the dimension line with dimension text |
1 | Adds a leader when dimension text is moved |
2 | Allows text to be moved freely without a leader |
0 | Center of dimension line |
1 | Left side of the dimension line, near first extension line |
2 | Right side of the dimension line, near second extension line |
3 | Over first extension line |
4 | Over second extension line |
0 | Align with bottom line of dimension text |
1 | Align vertical centered to dimension text |
2 | Align with top line of dimension text |
The viewport table (DXF Reference) stores the modelspace viewport configurations. So this entries just modelspace viewports, not paperspace viewports, for paperspace viewports see the Viewport entity.
Subclass of | ezdxf.entities.DXFEntity |
DXF type | 'VPORT' |
Factory function | Drawing.viewports.new() |
SEE ALSO:
Defines a viewport configurations for the modelspace.
16 | If set, table entry is externally dependent on an xref |
32 | If both this bit and bit 16 are set, the externally dependent xref has been successfully resolved |
64 | If set, the table entry was referenced by at least one entity in the drawing the last time the drawing was edited. (This flag is only for the benefit of AutoCAD) |
The View table (DXF Reference) stores named views of the model or paperspace layouts. This stored views makes parts of the drawing or some view points of the model in a CAD applications more accessible. This views have no influence to the drawing content or to the generated output by exporting PDFs or plotting on paper sheets, they are just for the convenience of CAD application users.
Subclass of | ezdxf.entities.DXFEntity |
DXF type | 'VIEW' |
Factory function | Drawing.views.new() |
SEE ALSO:
1 | If set, this is a paper space view |
16 | If set, table entry is externally dependent on an xref |
32 | If both this bit and bit 16 are set, the externally dependent xref has been successfully resolved |
64 | If set, the table entry was referenced by at least one entity in the drawing the last time the drawing was edited. (This flag is only for the benefit of AutoCAD) |
0 | 2D Optimized (classic 2D) |
1 | Wireframe |
2 | Hidden line |
3 | Flat shaded |
4 | Gouraud shaded |
5 | Flat shaded with wireframe |
6 | Gouraud shaded with wireframe |
0 | UCS is not orthographic |
1 | Top |
2 | Bottom |
3 | Front |
4 | Back |
5 | Left |
6 | Right |
Defines an APPID (DXF Reference). These table entries maintain a set of names for all registered applications.
Subclass of | ezdxf.entities.DXFEntity |
DXF type | 'APPID' |
Factory function | Drawing.appids.new() |
16 | If set, table entry is externally dependent on an xref |
32 | If both this bit and bit 16 are set, the externally dependent xref has been successfully resolved |
64 | If set, the table entry was referenced by at least one entity in the drawing the last time the drawing was edited. (This flag is only for the benefit of AutoCAD) |
Defines an named or unnamed user coordinate system (DXF Reference) for usage in CAD applications. This UCS table entry does not interact with ezdxf in any way, to do coordinate transformations by ezdxf use the ezdxf.math.UCS class.
Subclass of | ezdxf.entities.DXFEntity |
DXF type | 'UCS' |
Factory function | Drawing.ucs.new() |
SEE ALSO:
16 | If set, table entry is externally dependent on an xref |
32 | If both this bit and bit 16 are set, the externally dependent xref has been successfully resolved |
64 | If set, the table entry was referenced by at least one entity in the drawing the last time the drawing was edited. (This flag is only for the benefit of AutoCAD) |
BLOCK_RECORD (DXF Reference) is the core management structure for BlockLayout and Layout. This is an internal DXF structure managed by ezdxf, package users don’t have to care about it.
Subclass of | ezdxf.entities.DXFEntity |
DXF type | 'BLOCK_RECORD' |
Factory function | Drawing.block_records.new() |
0 | Unitless |
1 | Inches |
2 | Feet |
3 | Miles |
4 | Millimeters |
5 | Centimeters |
6 | Meters |
7 | Kilometers |
8 | Microinches |
9 | Mils |
10 | Yards |
11 | Angstroms |
12 | Nanometers |
13 | Microns |
14 | Decimeters |
15 | Decameters |
16 | Hectometers |
17 | Gigameters |
18 | Astronomical units |
19 | Light years |
20 | Parsecs |
21 | US Survey Feet |
22 | US Survey Inch |
23 | US Survey Yard |
24 | US Survey Mile |
Do not change this structures, this is just an information for experienced developers!
The BLOCK_RECORD is the owner of all the entities in a layout and stores them in an EntitySpace object (BlockRecord.entity_space). For each layout exist a BLOCK definition in the BLOCKS section, a reference to the Block entity is stored in BlockRecord.block.
Modelspace and Paperspace layouts require an additional DXFLayout object in the OBJECTS section.
SEE ALSO:
A block definition (BlockLayout) is a collection of DXF entities, which can be placed multiply times at different layouts or other blocks as references to the block definition.
SEE ALSO:
BLOCK (DXF Reference) entity is embedded into the BlockLayout object. The BLOCK entity is accessible by the BlockLayout.block attribute.
Subclass of | ezdxf.entities.DXFEntity |
DXF type | 'BLOCK' |
Factory function | Drawing.blocks.new() (returns a BlockLayout) |
SEE ALSO:
Insertion location referenced by the Insert entity to place the block reference and also the center of rotation and scaling.
1 | Anonymous block generated by hatching, associative dimensioning, other internal operations, or an application |
2 | Block has non-constant attribute definitions (this bit is not set if the block has any attribute definitions that are constant, or has no attribute definitions at all) |
4 | Block is an external reference (xref) |
8 | Block is an xref overlay |
16 | Block is externally dependent |
32 | This is a resolved external reference, or dependent of an external reference (ignored on input) |
64 | This definition is a referenced external reference (ignored on input) |
ENDBLK entity is embedded into the BlockLayout object. The ENDBLK entity is accessible by the BlockLayout.endblk attribute.
Subclass of | ezdxf.entities.DXFEntity |
DXF type | 'ENDBLK' |
Block reference (DXF Reference) with maybe attached attributes (Attrib).
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'INSERT' |
Factory function | ezdxf.layouts.BaseLayout.add_blockref() |
Inherited DXF attributes | Common graphical DXF attributes |
SEE ALSO:
WARNING:
TODO: influence of layer, linetype, color DXF attributes to block entities
Not all CAD applications support non-uniform scaling (e.g. LibreCAD).
Not all CAD applications support non-uniform scaling (e.g. LibreCAD).
New in version 0.12.
New in version 0.14.
Example for appending an attribute to an INSERT entity with none standard alignment:
e.add_attrib('EXAMPLETAG', 'example text').set_pos(
(3, 7), align='MIDDLE_CENTER' )
This method avoids the wrapper block of the add_auto_blockref() method, but the visual results may not match the results of CAD applications, especially for non uniform scaling. If the visual result is very important to you, use the add_auto_blockref() method.
Unlike the transformation matrix m, the INSERT entity can not represent a non orthogonal target coordinate system, for this case an InsertTransformationError will be raised.
New in version 0.13.
New in version 0.13.
This entities are not stored in the entity database, have no handle and are not assigned to any layout. It is possible to convert this entities into regular drawing entities by adding the entities to the entities database and a layout of the same DXF document as the block reference:
doc.entitydb.add(entity) msp = doc.modelspace() msp.add_entity(entity)
This method does not resolve the MINSERT attributes, only the sub-entities of the base INSERT will be returned. To resolve MINSERT entities check if multi insert processing is required, that’s the case if property Insert.mcount > 1, use the Insert.multi_insert() method to resolve the MINSERT entity into single INSERT entities.
WARNING:
Changed in version 0.13: deprecated non_uniform_scaling argument
New in version 0.14.
Transforms the block entities into the required WCS location by applying the block reference attributes insert, extrusion, rotation and the scaling values xscale, yscale and zscale.
Attached ATTRIB entities are converted to TEXT entities, this is the behavior of the BURST command of the AutoCAD Express Tools.
Returns an EntityQuery container with all “exploded” DXF entities.
WARNING:
Changed in version 0.13: deprecated non_uniform_scaling argument
The ATTRIB (DXF Reference) entity represents a text value associated with a tag. In most cases an ATTRIB is appended to an Insert entity, but it can also appear as standalone entity.
Subclass of | ezdxf.entities.Text |
DXF type | 'ATTRIB' |
Factory function | ezdxf.layouts.BaseLayout.add_attrib() (stand alone entity) |
Factory function | Insert.add_attrib() (attached to Insert) |
Inherited DXF attributes | Common graphical DXF attributes |
SEE ALSO:
WARNING:
The ATTDEF (DXF Reference) entity is a template in a BlockLayout, which will be used to create an attached Attrib entity for an Insert entity.
Subclass of | ezdxf.entities.Text |
DXF type | 'ATTDEF' |
Factory function | ezdxf.layouts.BaseLayout.add_attdef() |
Inherited DXF attributes | Common graphical DXF attributes |
SEE ALSO:
WARNING:
The layout manager is unique to each DXF drawing, access the layout manager as layouts attribute of the Drawing object.
A Layout represents and manages DXF entities, there are three different layout objects:
WARNING:
A layout owns all entities residing in their entity space, this means the dxf.owner attribute of any DXFGraphic in this layout is the dxf.handle of the layout, and deleting an entity from a layout is the end of life of this entity, because it is also deleted from the EntityDB. But it is possible to just unlink an entity from a layout, so it can be assigned to another layout, use the move_to_layout() method to move entities between layouts.
The underlying data structure for storing entities is organized like a standard Python list, therefore index can be any valid list indexing or slicing term, like a single index layout[-1] to get the last entity, or an index slice layout[:10] to get the first 10 or less entities as List[DXFGraphic].
Not all DXF types are supported and every dependency or resource reference from another DXF document will be removed except attribute layer will be preserved but only with default attributes like color 7 and linetype CONTINUOUS because the layer attribute doesn’t need a layer table entry.
If the entity is part of another DXF document, it will be unlinked from this document and its entity database if argument copy is False, else the entity will be copied. Unassigned entities like from DXF iterators will just be added.
Supported DXF types:
The Attrib entities are placed relative to the insert point, which is equal to the block base point.
This method wraps the INSERT and all the ATTRIB entities into an anonymous block, which produces the best visual results, especially for non uniform scaled block references, because the transformation and scaling is done by the CAD application. But this makes evaluation of block references with attributes more complicated, if you prefer INSERT and ATTRIB entities without a wrapper block use the add_blockref_with_attribs() method.
Set position and alignment by the idiom:
layout.add_attdef('NAME').set_pos((2, 3), align='MIDDLE_CENTER')
New in version 0.11: user defined point format
The LWPolyline is defined as a single DXF entity and needs less disk space than a Polyline entity. (requires DXF R2000)
Format codes:
AutoCAD creates a spline through fit points by a proprietary algorithm. ezdxf can not reproduce the control point calculation. See also: tut_spline.
Open uniform B-splines start and end at your first and last control point.
Closed uniform B-splines is a closed curve start and end at the first control point.
weights has to be an iterable of floats, which defines the influence of the associated control point to the shape of the B-spline, therefore for each control point is one weight value required.
Open rational uniform B-splines start and end at the first and last control point.
weights has to be an iterable of floats, which defines the influence of the associated control point to the shape of the B-spline, therefore for each control point is one weight value required.
Closed rational uniform B-splines start and end at the first control point.
This method creates only a 2D entity in the xy-plane of the layout, the z-axis of the input vertices are ignored.
This method returns a DimStyleOverride object - to create the necessary dimension geometry, you have to call render() manually, this two step process allows additional processing steps on the Dimension entity between creation and rendering.
NOTE:
Returns: DimStyleOverride
This method sets many design decisions by itself, the necessary geometry will be generated automatically, no required nor possible render() call. This method is easy to use but you get what you get.
NOTE:
This method returns a DimStyleOverride object, to create the necessary dimension geometry, you have to call DimStyleOverride.render() manually, this two step process allows additional processing steps on the Dimension entity between creation and rendering.
NOTE:
Returns: DimStyleOverride
If an UCS is used for dimension line rendering, all point definitions in UCS coordinates, translation into WCS and OCS is done by the rendering function. Extrusion vector is defined by UCS or (0, 0, 1) by default.
This method returns a DimStyleOverride object - to create the necessary dimension geometry, you have to call render() manually, this two step process allows additional processing steps on the Dimension entity between creation and rendering.
Following render types are supported:
Placing the dimension text at a user defined location, overrides the mpoint and the angle argument, but requires a given radius argument. The location argument does not define the exact text location, instead it defines the dimension line starting at center and the measurement text midpoint projected on this dimension line going through location, if text is aligned to the dimension line. If text is horizontal, location is the kink point of the dimension line from radial to horizontal direction.
NOTE:
Returns: DimStyleOverride
Returns: DimStyleOverride
Returns: DimStyleOverride
If an UCS is used for dimension line rendering, all point definitions in UCS coordinates, translation into WCS and OCS is done by the rendering function. Extrusion vector is defined by UCS or (0, 0, 1) by default.
This method returns a DimStyleOverride object - to create the necessary dimension geometry, you have to call render() manually, this two step process allows additional processing steps on the Dimension entity between creation and rendering.
NOTE:
Returns: DimStyleOverride
(not implemented yet!)
Returns: DimStyleOverride
Leader shares its styling infrastructure with Dimension.
By default a Leader without any annotation is created. For creating more fancy leaders and annotations see documentation provided by Autodesk or Demystifying DXF: LEADER and MULTILEADER implementation notes .
This enables direct access to the underlying LAYOUT entity, e.g. Layout.dxf.layout_flags
0 | last screen display |
1 | drawing extents |
2 | drawing limits |
3 | view specific (defined by Layout.dxf.plot_view_name) |
4 | window specific (defined by Layout.set_plot_window_limits()) |
5 | layout information (default) |
To change redraw order associate a different sort handle to entities, this redefines the order in which the entities are regenerated. handles can be a dict of entity_handle and sort_handle as (k, v) pairs, or an iterable of (entity_handle, sort_handle) tuples.
The sort_handle doesn’t have to be unique, some or all entities can share the same sort handle and a sort handle can be an existing handle.
The “0” handle can be used, but this sort_handle will be drawn as latest (on top of all other entities) and not as first as expected.
The modelspace contains the “real” world representation of the drawing subjects in real world units.
The GEODATA entity requires DXF R2010. The DXF reference does not document if other layouts than the modelspace supports geo referencing, so I assume getting/setting geo data may only make sense for the modelspace.
Paperspace layouts are used to create different drawing sheets of the modelspace subjects for printing or PDF export.
Reset paper limits, extends and viewports.
int | Rotation |
0 | no rotation |
1 | 90 degrees counter-clockwise |
2 | upside-down |
3 | 90 degrees clockwise |
plot origin = lower left corner of printable area + plot origin offset
Block layouts are reusable sets of graphical entities, which can be referenced by multiple Insert entities. Each reference can be placed, scaled and rotated individually and can have it’s own set of DXF Attrib entities attached.
A group is just a bunch of DXF entities tied together. All entities of a group has to be on the same layout (modelspace or any paper layout but not block). Groups can be named or unnamed, but in reality an unnamed groups has just a special name like “*Annnn”. The name of a group has to be unique in the drawing. Groups are organized in the main group table, which is stored as attribute groups in the Drawing object.
Group entities have to be in modelspace or any paperspace layout but not in a block definition!
with group.edit_data() as data:
# add new entities to a group
data.append(modelspace.add_line((0, 0), (3, 0)))
# remove last entity from a group
data.pop()
Invalid handles are: deleted entities, not all entities in the same layout or entities in a block layout.
Each Drawing has one group table, which is accessible by the attribute groups.
WARNING:
Common base class for all DXF entities and objects.
WARNING:
# set attribute value entity.dxf.layer = 'MyLayer' # get attribute value linetype = entity.dxf.linetype # delete attribute del entity.dxf.linetype
Raises DXFAttributeError if key is not an supported DXF attribute.
layer = entity.get_dxf_attrib("layer") # same as layer = entity.dxf.layer
Raises DXFAttributeError if key is not an supported DXF attribute.
entity.set_dxf_attrib("layer", "MyLayer") # same as entity.dxf.layer = "MyLayer"
Raises DXFAttributeError if key is not an supported DXF attribute.
Raises DXFAttributeError if key is not an supported DXF attribute.
Changed in version 0.12: added drop argument
Common base class for all graphical DXF entities.
This entities resides in entity spaces like Modelspace, any Paperspace or BlockLayout.
Subclass of | ezdxf.entities.DXFEntity |
WARNING:
entity.rgb = (30, 40, 50) r, g, b = entity.rgb
This is the recommend method to get/set RGB values, when ever possible do not use the DXF low level attribute dxf.true_color.
This attribute requires DXF R2004 or later, returns 0 for prior DXF versions and raises DXFAttributeError for setting transparency in older DXF versions.
It is more efficient to call the unlink_entity() method of the associated layout, especially if you have to unlink more than one entity.
New in version 0.13.
New in version 0.12.
New in version 0.12.
New in version 0.12.
New in version 0.12.
New in version 0.13.
Basic implementation uses the transform() interface, subclasses may have faster implementations.
New in version 0.13.
New in version 0.13.
New in version 0.13.
New in version 0.13.
New in version 0.13.
New in version 0.13.
New in version 0.13.
Constants defined in ezdxf.lldxf.const
0 | BYBLOCK |
256 | BYLAYER |
257 | BYOBJECT |
Constants defined in ezdxf.lldxf.const
-1 | LINEWEIGHT_BYLAYER |
-2 | LINEWEIGHT_BYBLOCK |
-3 | LINEWEIGHT_DEFAULT |
Valid DXF lineweights stored in VALID_DXF_LINEWEIGHTS: 0, 5, 9, 13, 15, 18, 20, 25, 30, 35, 40, 50, 53, 60, 70, 80, 90, 100, 106, 120, 140, 158, 200, 211
(requires DXF R2004)
0 | casts and receives shadows |
1 | casts shadows |
2 | receives shadows |
3 | ignores shadows |
(requires DXF R2007)
A 3DFACE (DXF Reference) is real 3D solid filled triangle or quadrilateral. Access vertices by name (entity.dxf.vtx0 = (1.7, 2.3)) or by index (entity[0] = (1.7, 2.3)).
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | '3DFACE' |
Factory function | ezdxf.layouts.BaseLayout.add_3dface() |
Inherited DXF attributes | Common graphical DXF attributes |
WARNING:
1 | first edge is invisible |
2 | second edge is invisible |
4 | third edge is invisible |
8 | fourth edge is invisible |
Combine values by adding them, e.g. 1+4 = first and third edge is invisible.
New in version 0.13.
3DSOLID (DXF Reference) created by an ACIS based geometry kernel provided by the Spatial Corp.
ezdxf will never interpret ACIS source code, don’t ask me for this feature.
Subclass of | ezdxf.entities.Body |
DXF type | '3DSOLID' |
Factory function | ezdxf.layouts.BaseLayout.add_3dsolid() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
WARNING:
ARC (DXF Reference) center at location dxf.center and radius of dxf.radius from dxf.start_angle to dxf.end_angle. ARC goes always from dxf.start_angle to dxf.end_angle in counter clockwise orientation around the dxf.extrusion vector, which is (0, 0, 1) by default and the usual case for 2D arcs.
Subclass of | ezdxf.entities.Circle |
DXF type | 'ARC' |
Factory function | ezdxf.layouts.BaseLayout.add_arc() |
Inherited DXF attributes | Common graphical DXF attributes |
WARNING:
New in version 0.11.
New in version 0.11.
All angles are normalized in the range from [0, 360).
Raises NonUniformScalingError() for non uniform scaling.
New in version 0.13.
Adds the new ELLIPSE entity to the entity database and to the same layout as the source entity.
New in version 0.13.
Adds the new SPLINE entity to the entity database and to the same layout as the source entity.
New in version 0.13.
New in version 0.14.
New in version 0.14.
BODY (DXF Reference) created by an ACIS based geometry kernel provided by the Spatial Corp.
ezdxf will never interpret ACIS source code, don’t ask me for this feature.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'BODY' |
Factory function | ezdxf.layouts.BaseLayout.add_body() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
WARNING:
CIRCLE (DXF Reference) center at location dxf.center and radius of dxf.radius.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'CIRCLE' |
Factory function | ezdxf.layouts.BaseLayout.add_circle() |
Inherited DXF attributes | Common graphical DXF attributes |
WARNING:
New in version 0.11.
Raises NonUniformScalingError() for non uniform scaling.
New in version 0.13.
New in version 0.13.
Adds the new ELLIPSE entity to the entity database and to the same layout as the source entity.
New in version 0.13.
Adds the new SPLINE entity to the entity database and to the same layout as the source entity.
New in version 0.13.
The DIMENSION entity (DXF Reference) represents several types of dimensions in many orientations and alignments. The basic types of dimensioning are linear, radial, angular, ordinate, and arc length.
For more information about dimensions see the online help from AutoDesk: About the Types of Dimensions
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'DIMENSION' |
factory function | see table below |
Inherited DXF attributes | Common graphical DXF attributes |
Linear and Rotated Dimension (DXF) | add_linear_dim() |
Aligned Dimension (DXF) | add_aligned_dim() |
Angular Dimension (DXF) | add_angular_dim() (not implemented) |
Angular 3P Dimension (DXF) | add_angular_3p_dim() (not implemented) |
Diameter Dimension (DXF) | add_diameter_dim() |
Radius Dimension (DXF) | add_radius_dim() |
Ordinate Dimension (DXF) | add_ordinate_dim() (not implemented) |
WARNING:
For AutoCAD this graphical representation is mandatory, else AutoCAD will not open the DXF drawing. BricsCAD will render the DIMENSION entity by itself, if the graphical representation is not present, but uses the BLOCK instead of rendering, if it is present.
0 | Linear and Rotated Dimension (DXF) |
1 | Aligned Dimension (DXF) |
2 | Angular Dimension (DXF) |
3 | Diameter Dimension (DXF) |
4 | Radius Dimension (DXF) |
5 | Angular 3P Dimension (DXF) |
6 | Ordinate Dimension (DXF) |
8 | subclass ezdxf.entities.ArcDimension introduced in DXF R2004 |
32 | Indicates that graphical representation geometry is referenced by this dimension only. (always set in DXF R13 and later) |
64 | Ordinate type. This is a bit value (bit 7) used only with integer value 6. If set, ordinate is X-type; if not set, ordinate is Y-type |
128 | This is a bit value (bit 8) added to the other dimtype values if the dimension text has been positioned at a user-defined location rather than at the default location |
Linear and rotated dimension: dxf.defpoint specifies the dimension line location.
Arc and angular dimension: dxf.defpoint and dxfdefpoint4 specify the endpoints of the line used to determine the second extension line.
Linear and rotated dimension: The dxf.defpoint2 specifies the start point of the first extension line.
Arc and angular dimension: The dxf.defpoint2 and dxf.defpoint3 specify the endpoints of the line used to determine the first extension line.
Linear and rotated dimension: The dxf.defpoint3 specifies the start point of the second extension line.
Arc and angular dimension: The dxf.defpoint2 and dxf.defpoint3 specify the endpoints of the line used to determine the first extension line.
Arc and angular dimension: dxf.defpoint and dxf.defpoint4 specify the endpoints of the line used to determine the second extension line.
This value is used by CAD application (Baseline and Continue) and ignored by ezdxf.
1 | Top left |
2 | Top center |
3 | Top right |
4 | Middle left |
5 | Middle center |
6 | Middle right |
7 | Bottom left |
8 | Bottom center |
9 | Bottom right |
1 | At least (taller characters will override) |
2 | Exact (taller characters will not override) |
Percentage of default (3-on-5) line spacing to be applied. Valid values range from 0.25 to 4.00.
If empty string or '<>', the dimension measurement is drawn as the text, if ' ' (one blank space), the text is suppressed. Anything else is drawn as the text.
When added to the rotation dxf.angle of the linear dimension, it gives the angle of the extension lines.
This attribute determines the orientation of dimension text and lines for horizontal, vertical, and rotated linear dimensions. This value is the negative of the angle in the OCS xy-plane between the dimension line and the OCS x-axis.
Raises NonUniformScalingError() for non uniform scaling.
New in version 0.13.
This entities are located at the original positions, but are not stored in the entity database, have no handle and are not assigned to any layout.
Returns an EntityQuery container with all DXF primitives.
All of the DimStyle attributes can be overridden for each Dimension entity individually.
The DimStyleOverride class manages all the complex dependencies between DimStyle and Dimension, the different features of all DXF versions and the rendering process to create the Dimension picture as BLOCK, which is required for AutoCAD.
Returns default value for attributes not supported by DXF R12. This is a hack to use the same algorithm to render DXF R2000 and DXF R12 DIMENSION entities. But the DXF R2000 attributes are not stored in the DXF R12 file! Does not catch invalid attributes names! Look into debug log for ignored DIMSTYLE attributes.
For a friendly CAD applications like BricsCAD you can discard the dimension line rendering, because it is done automatically by BricsCAD, if no dimension rendering BLOCK is available and it is likely to get better results as by ezdxf.
AutoCAD does not render DIMENSION entities automatically, so I rate AutoCAD as an unfriendly CAD application.
The ARC_DIMENSION entity was introduced in DXF R2004 and is not documented in the DXF reference.
Subclass of | ezdxf.entities.Dimension |
DXF type | 'ARC_DIMENSION' |
factory function | add_arc_dim() (not implemented) |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2004 ('AC1018') |
WARNING:
ELLIPSE (DXF Reference) with center point at location dxf.center and a major axis dxf.major_axis as vector. dxf.ratio is the ratio of minor axis to major axis. dxf.start_param and dxf.end_param defines the starting- and the end point of the ellipse, a full ellipse goes from 0 to 2*pi. The ellipse goes from starting- to end param in counter clockwise direction.
dxf.extrusion is supported, but does not establish an OCS, but creates an 3D entity by extruding the base ellipse in direction of the dxf.extrusion vector.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'ELLIPSE' |
factory function | add_ellipse() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
New in version 0.11.
New in version 0.11.
New in version 0.12.
New in version 0.13.
New in version 0.13.
All params are normalized in the range from [0, 2pi).
New in version 0.13.
New in version 0.13.
Adds the new SPLINE entity to the entity database and to the same layout as the source entity.
New in version 0.13.
The new SPLINE entity has no owner, no handle, is not stored in the entity database nor assigned to any layout!
New in version 0.13.
The HATCH entity (DXF Reference) fills an enclosed area defined by one or more boundary paths with a hatch pattern, solid fill, or gradient fill.
All points in OCS as (x, y) tuples (Hatch.dxf.elevation is the z-axis value).
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'HATCH' |
Factory function | ezdxf.layouts.BaseLayout.add_hatch() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
SEE ALSO:
Boundary paths helper classes
Path manager: BoundaryPaths
Pattern and gradient helper classes
1 | solid fill, better use: Hatch.set_solid_fill() |
0 | pattern fill, better use: Hatch.set_pattern_fill() |
1 | associative hatch |
0 | not associative hatch |
Associations not handled by ezdxf, you have to set the handles to the associated DXF entities by yourself.
0 | normal |
1 | outer |
2 | ignore |
(search AutoCAD help for more information)
0 | user |
1 | predefined |
2 | custom |
usage:
color = hatch.bgcolor # get background color as (r, g, b) tuple hatch.bgcolor = (10, 20, 30) # set background color del hatch.bgcolor # delete background color
Changed in version 0.13: added angle argument
Starts always from the original base scaling, set_pattern_scale(1) reset the pattern scaling to the original appearance as defined by the pattern designer, but only if the the pattern attribute dxf.pattern_scale represents the actual scaling, it is not possible to recreate the original pattern scaling from the pattern definition itself.
New in version 0.13.
Starts always from the original base rotation 0, set_pattern_angle(0) reset the pattern rotation to the original appearance as defined by the pattern designer, but only if the the pattern attribute dxf.pattern_angle represents the actual rotation, it is not possible to recreate the original rotation from the pattern definition itself.
New in version 0.13.
Valid gradient type names are:
New in version 0.13.
A HATCH entity can be associative to a base geometry, this association is not maintained nor verified by ezdxf, so if you modify the base geometry the geometry of the boundary path is not updated and no verification is done to check if the associated geometry matches the boundary path, this opens many possibilities to create invalid DXF files: USE WITH CARE!
New in version 0.13.
0 | default |
1 | external |
2 | polyline, will be set by ezdxf |
16 | outermost |
My interpretation of the path_type_flags, see also tut_hatch:
If there are troubles with AutoCAD, maybe the hatch entity has the Hatch.dxf.pixel_size attribute set - delete it del hatch.dxf.pixel_size and maybe the problem is solved. ezdxf does not use the Hatch.dxf.pixel_size attribute, but it can occur in DXF files created by other applications.
0 | default |
1 | external |
16 | outermost |
see PolylinePath.path_type_flags
WARNING:
Be careful, this changes the base pattern definition, maybe better use Hatch.set_pattern_scale() or Hatch.set_pattern_angle().
New in version 0.13.
SEE ALSO:
Add a raster IMAGE (DXF Reference) to the DXF file, the file itself is not embedded into the DXF file, it is always a separated file. The IMAGE entity is like a block reference, you can use it multiple times to add the image on different locations with different scales and rotations. But therefore you need a also a IMAGEDEF entity, see ImageDef. ezdxf creates only images in the xy-plan, you can place images in the 3D space too, but then you have to set the Image.dxf.u_pixel and the Image.dxf.v_pixel vectors by yourself.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'IMAGE' |
Factory function | ezdxf.layouts.BaseLayout.add_image() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
WARNING:
Image.dxf.flags | Value | Description |
Image.SHOW_IMAGE | 1 | Show image |
Image.SHOW_WHEN_NOT_ALIGNED | 2 | Show image when not aligned with screen |
Image.USE_CLIPPING_BOUNDARY | 4 | Use clipping boundary |
Image.USE_TRANSPARENCY | 8 | Transparency is on |
0 | clipping off |
1 | clipping on |
1 | Rectangular |
2 | Polygonal |
0 | Outside |
1 | Inside |
New in version 0.14.
New in version 0.13.
The LEADER entity (DXF Reference) represents an arrow, made up of one or more vertices (or spline fit points) and an arrowhead. The label or other content to which the Leader is attached is stored as a separate entity, and is not part of the Leader itself.
Leader shares its styling infrastructure with Dimension.
By default a Leader without any annotation is created. For creating more fancy leaders and annotations see documentation provided by Autodesk or Demystifying DXF: LEADER and MULTILEADER implementation notes .
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'LEADER' |
Factory function | ezdxf.layouts.BaseLayout.add_leader() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
0 | Disabled |
1 | Enabled |
0 | Straight line segments |
1 | Spline |
0 | Created with text annotation |
1 | Created with tolerance annotation |
2 | Created with block reference annotation |
3 | Created without any annotation (default) |
0 | Hookline (or end of tangent for a splined leader) is the opposite direction from the horizontal vector |
1 | Hookline (or end of tangent for a splined leader) is the same direction as horizontal vector (see has_hook_line) |
0 | No hookline |
1 | Has a hookline |
New in version 0.13.
This entities are located at the original positions, but are not stored in the entity database, have no handle and are not assigned to any layout.
New in version 0.14.
Returns an EntityQuery container with all DXF parts.
New in version 0.14.
LINE (DXF Reference) entity is a 3D line from Line.dxf.start to Line.dxf.end.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'LINE' |
Factory function | ezdxf.layouts.BaseLayout.add_line() |
Inherited DXF Attributes | Common graphical DXF attributes |
WARNING:
New in version 0.13.
New in version 0.13.
The LWPOLYLINE entity (DXF Reference) is defined as a single graphic entity, which differs from the old-style Polyline entity, which is defined as a group of sub-entities. LWPolyline display faster (in AutoCAD) and consume less disk space, it is a planar element, therefore all points in OCS as (x, y) tuples (LWPolyline.dxf.elevation is the z-axis value).
Changed in version 0.8.9: LWPolyline stores point data as packed data (array.array).
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'LWPOLYLINE' |
factory function | add_lwpolyline() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
Bulge value
The bulge value is used to create arc shaped line segments for Polyline and LWPolyline entities. The bulge value defines the ratio of the arc sagitta (versine) to half line segment length, a bulge value of 1 defines a semicircle.
The sign of the bulge value defines the side of the bulge:
Start- and end width
The start width and end width values defines the width in drawing units for the following line segment. To use the default width value for a line segment set value to 0.
Width and bulge values at last point
The width and bulge values of the last point has only a meaning if the polyline is closed, and they apply to the last line segment from the last to the first point.
SEE ALSO:
Code | Point Component |
x | x-coordinate |
y | y-coordinate |
s | start width |
e | end width |
b | bulge value |
v | (x, y [, z]) as tuple |
dxf.flags | Value | Description |
LWPOLYLINE_CLOSED | 1 | polyline is closed |
LWPOLYLINE_PLINEGEN | 128 | ??? |
New in version 0.14.
All coordinates in OCS.
All coordinates in OCS.
All coordinates in OCS.
All coordinates in OCS.
All coordinates in OCS.
All points in OCS as (x, y) tuples (dxf.elevation is the z-axis value).
All coordinates in OCS.
All coordinates in OCS.
New in version 0.13.
This entities are located at the original positions, but are not stored in the entity database, have no handle and are not assigned to any layout.
Returns an EntityQuery container with all DXF parts.
The MESH entity (DXF Reference) is a 3D mesh similar to the Polyface entity.
All vertices in WCS as (x, y, z) tuples
Changed in version 0.8.9: Mesh stores vertices, edges, faces and creases as packed data.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'MESH' |
Factory function | ezdxf.layouts.BaseLayout.add_mesh() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
SEE ALSO:
Despite that vertices, edge and faces since ezdxf v0.8.9 are accessible as packed data types, the usage of MeshData by context manager edit_data() is still recommended.
New in version 0.13.
Each face consist of a list of vertex indices (= index in vertices).
Each edge consist of exact two vertex indices (= index in vertices).
The MTEXT entity (DXF Reference) fits a multiline text in a specified width but can extend vertically to an indefinite length. You can format individual words or characters within the MText.
SEE ALSO:
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'MTEXT' |
Factory function | ezdxf.layouts.BaseLayout.add_mtext() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
MText.dxf.attachment_point | Value |
MTEXT_TOP_LEFT | 1 |
MTEXT_TOP_CENTER | 2 |
MTEXT_TOP_RIGHT | 3 |
MTEXT_MIDDLE_LEFT | 4 |
MTEXT_MIDDLE_CENTER | 5 |
MTEXT_MIDDLE_RIGHT | 6 |
MTEXT_BOTTOM_LEFT | 7 |
MTEXT_BOTTOM_CENTER | 8 |
MTEXT_BOTTOM_RIGHT | 9 |
MText.dxf.flow_direction | Value | Description |
MTEXT_LEFT_TO_RIGHT | 1 | left to right |
MTEXT_TOP_TO_BOTTOM | 3 | top to bottom |
MTEXT_BY_STYLE | 5 | by style (the flow direction is inherited from the associated text style) |
Constants defined in ezdxf.lldxf.const:
MText.dxf.line_spacing_style | Value | Description |
MTEXT_AT_LEAST | 1 | taller characters will override |
MTEXT_EXACT | 2 | taller characters will not override |
MText.dxf.bg_fill | Value | Description |
MTEXT_BG_OFF | 0 | no background color |
MTEXT_BG_COLOR | 1 | use specified color |
MTEXT_BG_WINDOW_COLOR | 2 | use window color (?) |
MTEXT_BG_CANVAS_COLOR | 3 | use canvas background color |
Requires: bg_fill, bg_fill_color else AutoCAD complains
Better use set_bg_color()
Better use set_bg_color()
Better use set_bg_color()
Better use set_bg_color()
Line endings \n will be replaced by the MTEXT line endings \P at DXF export, but not vice versa \P by \n at DXF file loading.
Use special color name canvas, to set background color to canvas background color.
"^": vertical stacked without divider line, e.g. \SA^B:
A
B "/": vertical stacked with divider line, e.g. \SX/Y:
X
-
Y "#": diagonal stacked, with slanting divider line, e.g. \S1#4:
1/4
New in version 0.11.1.
New in version 0.13.
Code | Description |
\L | Start underline |
\l | Stop underline |
\O | Start overstrike |
\o | Stop overstrike |
\K | Start strike-through |
\k | Stop strike-through |
\P | New paragraph (new line) |
\pxi | Control codes for bullets, numbered paragraphs and columns |
\X | Paragraph wrap on the dimension line (only in dimensions) |
\Q | Slanting (obliquing) text by angle - e.g. \Q30; |
\H | Text height - e.g. \H3x; |
\W | Text width - e.g. \W0.8x; |
\F | Font selection e.g. \Fgdt;o - GDT-tolerance |
\S | Stacking, fractions e.g. \SA^B or \SX/Y or \S1#4 |
\A | Alignment 0.0 • 2 \A0; = bottom • 2 \A1; = center • 2 \A2; = top 168u |
\C | Color change 0.0 • 2 \C1; = red • 2 \C2; = yellow • 2 \C3; = green • 2 \C4; = cyan • 2 \C5; = blue • 2 \C6; = magenta • 2 \C7; = white 168u |
\T | Tracking, char.spacing - e.g. \T2; |
\~ | Non-wrapping space, hard space |
{} | Braces - define the text area influenced by the code, codes and braces can be nested up to 8 levels deep |
\ | Escape character - e.g. \{ = “{“ |
Constant | Description |
UNDERLINE_START | start underline text (b += b.UNDERLINE_START) |
UNDERLINE_STOP | stop underline text (b += b.UNDERLINE_STOP) |
UNDERLINE | underline text (b += b.UNDERLINE % "Text") |
OVERSTRIKE_START | start overstrike |
OVERSTRIKE_STOP | stop overstrike |
OVERSTRIKE | overstrike text |
STRIKE_START | start strike trough |
STRIKE_STOP | stop strike trough |
STRIKE | strike trough text |
GROUP_START | start of group |
GROUP_END | end of group |
GROUP | group text |
NEW_LINE | start in new line (b += "Text" + b.NEW_LINE) |
NBSP | none breaking space (b += "Python" + b.NBSP + "3.4") |
POINT (DXF Reference) at location dxf.point.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'POINT' |
Factory function | ezdxf.layouts.BaseLayout.add_point() |
Inherited DXF attributes | Common graphical DXF attributes |
WARNING:
New in version 0.13.
New in version 0.13.
The POLYLINE entity (POLYLINE DXF Reference) is very complex, it’s used to build 2D/3D polylines, 3D meshes and 3D polyfaces. For every type exists a different wrapper class but they all have the same dxftype of 'POLYLINE'. Detect POLYLINE type by Polyline.get_mode().
POLYLINE types returned by Polyline.get_mode():
For 2D entities all vertices in OCS.
For 3D entities all vertices in WCS.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'POLYLINE' |
2D factory function | ezdxf.layouts.BaseLayout.add_polyline2d() |
3D factory function | ezdxf.layouts.BaseLayout.add_polyline3d() |
Inherited DXF attributes | Common graphical DXF attributes |
WARNING:
# delete first and second vertex del polyline.vertices[:2]
Polyline.dxf.flags | Value | Description |
POLYLINE_CLOSED | 1 | This is a closed Polyline (or a polygon mesh closed in the M direction) |
POLYLINE_MESH_CLOSED_M_DIRECTION | 1 | equals POLYLINE_CLOSED |
POLYLINE_CURVE_FIT_VERTICES_ADDED | 2 | Curve-fit vertices have been added |
POLYLINE_SPLINE_FIT_VERTICES_ADDED | 4 | Spline-fit vertices have been added |
POLYLINE_3D_POLYLINE | 8 | This is a 3D Polyline |
POLYLINE_3D_POLYMESH | 16 | This is a 3D polygon mesh |
POLYLINE_MESH_CLOSED_N_DIRECTION | 32 | The polygon mesh is closed in the N direction |
POLYLINE_POLYFACE_MESH | 64 | This Polyline is a polyface mesh |
POLYLINE_GENERATE_LINETYPE_PATTERN | 128 | The linetype pattern is generated continuously around the vertices of this Polyline |
Constants for smooth_type defined in ezdxf.lldxf.const:
Polyline.dxf.smooth_type | Value | Description |
POLYMESH_NO_SMOOTH | 0 | no smooth surface fitted |
POLYMESH_QUADRATIC_BSPLINE | 5 | quadratic B-spline surface |
POLYMESH_CUBIC_BSPLINE | 6 | cubic B-spline surface |
POLYMESH_BEZIER_SURFACE | 8 | Bezier surface |
New in version 0.14.
New in version 0.13.
This entities are located at the original positions, but are not stored in the entity database, have no handle and are not assigned to any layout.
New in version 0.12.
New in version 0.12.
A VERTEX (VERTEX DXF Reference) represents a polyline/mesh vertex.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'VERTEX' |
Factory function | Polyline.append_vertex() |
Factory function | Polyline.extend() |
Factory function | Polyline.insert_vertices() |
Inherited DXF Attributes | Common graphical DXF attributes |
The bulge value is used to create arc shaped line segments.
Vertex.dxf.flags | Value | Description |
VTX_EXTRA_VERTEX_CREATED | 1 | Extra vertex created by curve-fitting |
VTX_CURVE_FIT_TANGENT | 2 | curve-fit tangent defined for this vertex. A curve-fit tangent direction of 0 may be omitted from the DXF output, but is significant if this bit is set. |
VTX_SPLINE_VERTEX_CREATED | 8 | spline vertex created by spline-fitting |
VTX_SPLINE_FRAME_CONTROL_POINT | 16 | spline frame control point |
VTX_3D_POLYLINE_VERTEX | 32 | 3D polyline vertex |
VTX_3D_POLYGON_MESH_VERTEX | 64 | 3D polygon mesh |
VTX_3D_POLYFACE_MESH_VERTEX | 128 | polyface mesh vertex |
Format codes:
New in version 0.14.
Subclass of | ezdxf.entities.Polyline |
DXF type | 'POLYLINE' |
Factory function | ezdxf.layouts.BaseLayout.add_polymesh() |
Inherited DXF Attributes | Common graphical DXF attributes |
Set vertex location: cache[row, col] = (x, y, z)
Get vertex location: x, y, z = cache[row, col]
Subclass of | ezdxf.entities.Polyline |
DXF type | 'POLYLINE' |
Factory function | ezdxf.layouts.BaseLayout.add_polyface() |
Inherited DXF Attributes | Common graphical DXF attributes |
SEE ALSO:
RAY entity (DXF Reference) starts at Ray.dxf.point and continues to infinity (construction line).
Subclass of | ezdxf.entities.XLine |
DXF type | 'RAY' |
Factory function | ezdxf.layouts.BaseLayout.add_ray() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
Start point as (3D Point in WCS)
Unit direction vector as (3D Point in WCS)
New in version 0.13.
New in version 0.13.
REGION (DXF Reference) created by an ACIS based geometry kernel provided by the Spatial Corp.
ezdxf will never interpret ACIS source code, don’t ask me for this feature.
Subclass of | ezdxf.entities.Body |
DXF type | 'REGION' |
Factory function | ezdxf.layouts.BaseLayout.add_region() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
WARNING:
SHAPES (DXF Reference) are objects that are used like block references, each SHAPE reference can be scaled and rotated individually. The SHAPE definitions are stored in external shape files (*.SHX), and ezdxf can not create this shape files.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'SHAPE' |
Factory function | ezdxf.layouts.BaseLayout.add_shape() |
Inherited DXF attributes | Common graphical DXF attributes |
WARNING:
New in version 0.13.
SOLID (DXF Reference) is a filled triangle or quadrilateral. Access vertices by name (entity.dxf.vtx0 = (1.7, 2.3)) or by index (entity[0] = (1.7, 2.3)).
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'SOLID' |
Factory function | ezdxf.layouts.BaseLayout.add_solid() |
Inherited DXF attributes | Common graphical DXF attributes |
WARNING:
New in version 0.13.
SPLINE curve (DXF Reference), all coordinates have to be 3D coordinates even the spline is only a 2D planar curve.
The spline curve is defined by control points, knot values and weights. The control points establish the spline, the various types of knot vector determines the shape of the curve and the weights of rational splines define how strong a control point influences the shape.
To create a Spline curve you just need a bunch of fit points - knot values and weights are optional (tested with AutoCAD 2010). If you add additional data, be sure that you know what you do.
SEE ALSO:
Since ezdxf v0.8.9 Spline stores fit- and control points, knots and weights as packed data (array.array).
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'SPLINE' |
Factory function | see table below |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
Basic spline entity | add_spline() |
Spline control frame from fit points | add_spline_control_frame() |
Open uniform spline | add_open_spline() |
Closed uniform spline | add_closed_spline() |
Open rational uniform spline | add_rational_spline() |
Closed rational uniform spline | add_closed_rational_spline() |
dxf.flags | Value | Description |
CLOSED_SPLINE | 1 | Spline is closed |
PERIODIC_SPLINE | 2 | |
RATIONAL_SPLINE | 4 | |
PLANAR_SPLINE | 8 | |
LINEAR_SPLINE | 16 | planar bit is also set |
New in version 0.13.
New in version 0.13.
New in version 0.13.
The new SPLINE entity has no owner, no handle, is not stored in the entity database nor assigned to any layout!
New in version 0.13.
SURFACE (DXF Reference) created by an ACIS based geometry kernel provided by the Spatial Corp.
ezdxf will never interpret ACIS source code, don’t ask me for this feature.
Subclass of | ezdxf.entities.Body |
DXF type | 'SURFACE' |
Factory function | ezdxf.layouts.BaseLayout.add_surface() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
WARNING:
(DXF Reference)
Subclass of | ezdxf.entities.Surface |
DXF type | 'EXTRUDEDSURFACE' |
Factory function | ezdxf.layouts.BaseLayout.add_extruded_surface() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2007 ('AC1021') |
0 | No alignment |
1 | Align sweep entity to path |
2 | Translate sweep entity to path |
3 | Translate path to sweep entity |
(DXF Reference)
Subclass of | ezdxf.entities.Surface |
DXF type | 'LOFTEDSURFACE' |
Factory function | ezdxf.layouts.BaseLayout.add_lofted_surface() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2007 ('AC1021') |
(DXF Reference)
Subclass of | ezdxf.entities.Surface |
DXF type | 'REVOLVEDSURFACE' |
Factory function | ezdxf.layouts.BaseLayout.add_revolved_surface() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2007 ('AC1021') |
(DXF Reference)
Subclass of | ezdxf.entities.Surface |
DXF type | 'SWEPTSURFACE' |
Factory function | ezdxf.layouts.BaseLayout.add_swept_surface() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2007 ('AC1021') |
One line TEXT entity (DXF Reference). Text.dxf.height in drawing units and defaults to 1, but it also depends on the font rendering of the CAD application. Text.dxf.width is a scaling factor, but the DXF reference does not define the base value to scale, in practice the Text.dxf.height is the base value, the effective text width depends on the font defined by Text.dxf.style and the font rendering of the CAD application, especially for proportional fonts, text width calculation is nearly impossible without knowlegde of the used CAD application and their font rendering behavior. This is one reason why the DXF and also DWG file format are not reliable for exchanging exact text layout, they are just reliable for exchanging exact geometry.
SEE ALSO:
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'TEXT' |
Factory function | ezdxf.layouts.BaseLayout.add_text() |
Inherited DXF attributes | Common graphical DXF attributes |
WARNING:
second alignment point of text (2D/3D Point in OCS), if the justification is anything other than 'LEFT', the second alignment point specify also the first alignment point: (or just the second alignment point for 'ALIGN' and 'FIT')
0 | Left |
2 | Right |
3 | Aligned (if vertical alignment = 0) |
4 | Middle (if vertical alignment = 0) |
5 | Fit (if vertical alignment = 0) |
0 | Baseline |
1 | Bottom |
2 | Middle |
3 | Top |
2 | text is backward (mirrored in X) |
4 | text is upside down (mirrored in Y) |
Vertical | Left | Center | Right |
Top | TOP_LEFT | TOP_CENTER | TOP_RIGHT |
Middle | MIDDLE_LEFT | MIDDLE_CENTER | MIDDLE_RIGHT |
Bottom | BOTTOM_LEFT | BOTTOM_CENTER | BOTTOM_RIGHT |
Baseline | LEFT | CENTER | RIGHT |
Alignments 'ALIGNED' and 'FIT' are special, they require a second alignment point, text is aligned on the virtual line between these two points and has vertical alignment Baseline.
New in version 0.13.
New in version 0.13.
New in version 0.13.
TRACE entity (DXF Reference) is solid filled triangle or quadrilateral. Access vertices by name (entity.dxf.vtx0 = (1.7, 2.3)) or by index (entity[0] = (1.7, 2.3)). I don’t know the difference between SOLID and TRACE.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'TRACE' |
Factory function | ezdxf.layouts.BaseLayout.add_trace() |
Inherited DXF attributes | Common graphical DXF attributes |
WARNING:
New in version 0.13.
UNDERLAY entity (DXF Reference) links an underlay file to the DXF file, the file itself is not embedded into the DXF file, it is always a separated file. The (PDF)UNDERLAY entity is like a block reference, you can use it multiple times to add the underlay on different locations with different scales and rotations. But therefore you need a also a (PDF)DEFINITION entity, see UnderlayDefinition.
The DXF standard supports three different file formats: PDF, DWF (DWFx) and DGN. An Underlay can be clipped by a rectangle or a polygon path. The clipping coordinates are 2D OCS coordinates in drawing units but without scaling.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | internal base class |
Factory function | ezdxf.layouts.BaseLayout.add_underlay() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
dxf.flags | Value | Description |
UNDERLAY_CLIPPING | 1 | clipping is on/off |
UNDERLAY_ON | 2 | underlay is on/off |
UNDERLAY_MONOCHROME | 4 | Monochrome |
UNDERLAY_ADJUST_FOR_BACKGROUND | 8 | Adjust for background |
Two vertices describe a rectangle (lower left and upper right corner), more than two vertices is a polygon as clipping path.
Subclass of | ezdxf.entities.Underlay |
DXF type | 'PDFUNDERLAY' |
Factory function | ezdxf.layouts.BaseLayout.add_underlay() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
Subclass of | ezdxf.entities.Underlay |
DXF type | 'DWFUNDERLAY' |
Factory function | ezdxf.layouts.BaseLayout.add_underlay() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
Subclass of | ezdxf.entities.Underlay |
DXF type | 'DGNUNDERLAY' |
Factory function | ezdxf.layouts.BaseLayout.add_underlay() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
The VIEWPORT (DXF Reference) entity is a window from a paperspace layout to the modelspace.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'VIEWPORT' |
Factory function | ezdxf.layouts.Paperspace.add_viewport() |
Inherited DXF attributes | Common graphical DXF attributes |
WARNING:
-1 | On, but is fully off screen, or is one of the viewports that is not active because the $MAXACTVP count is currently being exceeded. |
0 | Off |
>0 | On and active. The value indicates the order of stacking for the viewports, where 1 is the active viewport, 2 is the next, and so forth |
1 (0x1) | Enables perspective mode |
2 (0x2) | Enables front clipping |
4 (0x4) | Enables back clipping |
8 (0x8) | Enables UCS follow |
16 (0x10) | Enables front clip not at eye |
32 (0x20) | Enables UCS icon visibility |
64 (0x40) | Enables UCS icon at origin |
128 (0x80) | Enables fast zoom |
256 (0x100) | Enables snap mode |
512 (0x200) | Enables grid mode |
1024 (0x400) | Enables isometric snap style |
2048 (0x800) | Enables hide plot mode |
4096 (0x1000) | kIsoPairTop. If set and kIsoPairRight is not set, then isopair top is enabled. If both kIsoPairTop and kIsoPairRight are set, then isopair left is enabled |
8192 (0x2000) | kIsoPairRight. If set and kIsoPairTop is not set, then isopair right is enabled |
16384 (0x4000) | Enables viewport zoom locking |
32768 (0x8000) | Currently always enabled |
65536 (0x10000) | Enables non-rectangular clipping |
131072 (0x20000) | Turns the viewport off |
262144 (0x40000) | Enables the display of the grid beyond the drawing limits |
524288 (0x80000) | Enable adaptive grid display |
1048576 (0x100000) | Enables subdivision of the grid below the set grid spacing when the grid display is adaptive |
2097152 (0x200000) | Enables grid follows workplane switching |
0 | 2D Optimized (classic 2D) |
1 | Wireframe |
2 | Hidden line |
3 | Flat shaded |
4 | Gouraud shaded |
5 | Flat shaded with wireframe |
6 | Gouraud shaded with wireframe |
0 | not orthographic |
1 | Top |
2 | Bottom |
3 | Front |
4 | Back |
5 | Left |
6 | Right |
0 | As Displayed |
1 | Wireframe |
2 | Hidden |
3 | Rendered |
0 | One distant light |
1 | Two distant lights |
THE WIPEOUT (DXF Reference) entity is a polygonal area that masks underlying objects with the current background color. The WIPEOUT entity is based on the IMAGE entity, but usage does not require any knowledge about the IMAGE entity.
The handles to the support entities ImageDef and ImageDefReactor are always “0”, both are not needed by the WIPEOUT entity.
Subclass of | ezdxf.entities.Image |
DXF type | 'WIPEOUT' |
Factory function | ezdxf.layouts.BaseLayout.add_wipeout() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
WARNING:
XLINE entity (DXF Reference) is a construction line that extents to infinity in both directions.
Subclass of | ezdxf.entities.DXFGraphic |
DXF type | 'XLINE' |
Factory function | ezdxf.layouts.BaseLayout.add_xline() |
Inherited DXF attributes | Common graphical DXF attributes |
Required DXF version | DXF R2000 ('AC1015') |
Location point of line as (3D Point in WCS)
Unit direction vector as (3D Point in WCS)
New in version 0.13.
New in version 0.13.
Common base class for all non-graphical DXF objects.
The DICTIONARY is a general storage entity.
AutoCAD maintains items such as MLINE_STYLES and GROUP definitions as objects in dictionaries. Other applications are free to create and use their own dictionaries as they see fit. The prefix 'ACAD_' is reserved for use by AutoCAD applications.
Dictionary entries are (key, DXFEntity) pairs. At loading time the value could be a str, because at this time not all objects are already stored in the EntityDB, and have to be acquired later.
Subclass of | ezdxf.entities.DXFObject |
DXF type | 'DICTIONARY' |
Factory function | ezdxf.sections.objects.ObjectsSection.add_dictionary() |
WARNING:
0 | not applicable |
1 | keep existing |
2 | use clone |
3 | <xref>$0$<name> |
4 | $0$<name> |
5 | Unmangle name |
Subclass of | ezdxf.entities.Dictionary |
DXF type | 'ACDBDICTIONARYWDFLT' |
Factory function | ezdxf.sections.objects.ObjectsSection.add_dictionary_with_default() |
Subclass of | ezdxf.entities.DXFObject |
DXF type | 'DICTIONARYVAR' |
Factory function | ezdxf.entities.Dictionary.add_dict_var() |
The GEODATA entity is associated to the Modelspace object.
Subclass of | ezdxf.entities.DXFObject |
DXF type | 'GEODATA' |
Factory function | ezdxf.layouts.Modelspace.new_geodata() |
Required DXF version | R2010 ('AC1024') |
SEE ALSO:
WARNING:
1 | R2009 |
2 | R2010 |
0 | unknown |
1 | local grid |
2 | projected grid |
3 | geographic (latitude/longitude) |
Changed in version 0.10: renamed from dxf.block_record
1 | none |
2 | user specified scale factor |
3 | grid scale at reference point |
4 | prismoidal |
IMAGEDEF entity defines an image file, which can be placed by the Image entity.
Subclass of | ezdxf.entities.DXFObject |
DXF type | 'IMAGEDEF' |
Factory function (1) | ezdxf.document.Drawing.add_image_def() |
Factory function (2) | ezdxf.sections.objects.ObjectsSection.add_image_def() |
WARNING:
0 | No units |
2 | Centimeters |
5 | Inch |
Default = 0
LAYOUT entity is part of a modelspace or paperspace layout definitions.
Subclass of | ezdxf.entities.PlotSettings |
DXF type | 'LAYOUT' |
Factory function | internal data structure, use Layouts to manage layout objects. |
TODO
The ACDBPLACEHOLDER object for internal usage.
Subclass of | ezdxf.entities.DXFObject |
DXF type | 'ACDBPLACEHOLDER' |
Factory function | ezdxf.sections.objects.ObjectsSection.add_placeholder() |
WARNING:
All PLOTSETTINGS attributes are part of the DXFLayout entity, I don’t know if this entity also appears as standalone entity.
Subclass of | ezdxf.entities.DXFObject |
DXF type | 'PLOTSETTINGS' |
Factory function | internal data structure |
TODO
SUN entity defines properties of the sun.
Subclass of | ezdxf.entities.DXFObject |
DXF type | 'SUN' |
Factory function | creating a new SUN entity is not supported |
0 | Sun do not cast shadows |
1 | Sun do cast shadows |
UnderlayDefinition (DXF Reference) defines an underlay file, which can be placed by the Underlay entity.
Subclass of | ezdxf.entities.DXFObject |
DXF type | internal base class |
Factory function (1) | ezdxf.document.Drawing.add_underlay_def() |
Factory function (2) | ezdxf.sections.objects.ObjectsSection.add_underlay_def() |
'pdf' | PDF page number |
'dgn' | always 'default' |
'dwf' | ? |
WARNING:
Subclass of | ezdxf.entities.UnderlayDefinition |
DXF type | 'PDFDEFINITION' |
Factory function (1) | ezdxf.document.Drawing.add_underlay_def() |
Factory function (2) | ezdxf.sections.objects.ObjectsSection.add_underlay_def() |
Subclass of | ezdxf.entities.UnderlayDefinition |
DXF type | 'DWFDEFINITION' |
Factory function (1) | ezdxf.document.Drawing.add_underlay_def() |
Factory function (2) | ezdxf.sections.objects.ObjectsSection.add_underlay_def() |
Subclass of | ezdxf.entities.UnderlayDefinition |
DXF type | 'DGNDEFINITION' |
Factory function (1) | ezdxf.document.Drawing.add_underlay_def() |
Factory function (2) | ezdxf.sections.objects.ObjectsSection.add_underlay_def() |
Important class for storing application defined data in DXF files.
XRECORD objects are used to store and manage arbitrary data. They are composed of DXF group codes ranging from 1 through 369. This object is similar in concept to XDATA but is not limited by size or order.
To reference a XRECORD by an DXF entity, store the handle of the XRECORD in the XDATA section, application defined data or the ExtensionDict of the DXF entity.
Subclass of | ezdxf.entities.DXFObject |
DXF type | 'XRECORD' |
Factory function | ezdxf.sections.objects.ObjectsSection.add_xrecord() |
WARNING:
0 | not applicable |
1 | keep existing |
2 | use clone |
3 | <xref>$0$<name> |
4 | $0$<name> |
5 | Unmangle name |
SEE ALSO:
QueryString := EntityQuery ("[" AttribQuery "]" "i"?)*
The query string is the combination of two queries, first the required entity query and second the optional attribute query, enclosed in square brackets, append 'i' after the closing square bracket to ignore case for strings.
The entity query is a whitespace separated list of DXF entity names or the special name '*'. Where '*' means all DXF entities, exclude some entity types by appending their names with a preceding ! (e.g. all entities except LINE = '* !LINE'). All DXF names have to be uppercase.
The optional attribute query is a boolean expression, supported operators are:
Attribute selection is a term: “name comparator value”, where name is a DXF entity attribute in lowercase, value is a integer, float or double quoted string, valid comparators are:
The EntityQuery class is the return type of all query() methods. EntityQuery contains all DXF entities of the source collection, which matches one name of the entity query AND the whole attribute query. If a DXF entity does not have or support a required attribute, the corresponding attribute search term is False.
examples:
raises: ParseException (pyparsing.py)
SEE ALSO:
def group_key(entity: DXFEntity):
return entity.dxf.layer, entity.dxf.color
For not suitable DXF entities return None to exclude this entity, in this case it’s not required, because groupby() catches DXFAttributeError exceptions to exclude entities, which do not provide layer and/or color attributes, automatically.
Result dict for dxfattrib = 'layer' may look like this:
{
'0': [ ... list of entities ],
'ExampleLayer1': [ ... ],
'ExampleLayer2': [ ... ],
... }
Result dict for key = group_key, which returns a (layer, color) tuple, may look like this:
{
('0', 1): [ ... list of entities ],
('0', 3): [ ... ],
('0', 7): [ ... ],
('ExampleLayer1', 1): [ ... ],
('ExampleLayer1', 2): [ ... ],
('ExampleLayer1', 5): [ ... ],
('ExampleLayer2', 7): [ ... ],
... }
All entity containers (modelspace, paperspace layouts and blocks) and the EntityQuery object have a dedicated groupby() method.
Utility functions and classes located in module ezdxf.math.
order = degree + 1
order = degree + 1
Relationship:
“p” is the degree of the B-spline, text-book notation.
0 | remove fraction |
0.1 | round next to x.1, x.2, … x.0 |
0.25 | round next to x.25, x.50, x.75 or x.00 |
0.5 | round next to x.5 or x.0 |
1.0 | round to a multiple of 1: remove fraction |
2.0 | round to a multiple of 2: xxx2, xxx4, xxx6 … |
5.0 | round to a multiple of 5: xxx5 or xxx0 |
10.0 | round to a multiple of 10: xx10, xx20, … |
Returns num evenly spaced samples, calculated over the interval [start, stop]. The endpoint of the interval can optionally be excluded.
New in version 0.12.3.
SEE ALSO:
Based on Bulge Center by Lee Mac.
Based on Bulge Radius by Lee Mac
Based on Bulge to Arc by Lee Mac.
Based on 3-Points to Bulge by Lee Mac.
New in version 0.14.
New in version 0.14.
New in version 0.11.
Source: Wikipedia
Given conjugated diameter d1 is the vector from center C to point P and the given conjugated diameter d2 is the vector from center C to point Q. Center of ellipse is always (0, 0, 0). This algorithm works for 2D/3D vectors.
WARNING:
New in version 0.11.
source = [(0, 0), (3, 0), (3, 3), (0, 3)] result = list(offset_vertices_2d(source, offset=0.5, closed=True))
[image]
Example for a closed collinear shape, which creates 2 additional vertices and the first one has an unexpected location:
source = [(0, 0), (0, 1), (0, 2), (0, 3)] result = list(offset_vertices_2d(source, offset=0.5, closed=True))
New in version 0.11.
New in version 0.11.
New in version 0.11.
New in version 0.12.
New in version 0.11.
Available tangent estimation methods:
Available estimation methods:
There exist infinite numerical correct solution for this setup, but some facts are known:
The last missing parameter is the start- and end tangents estimation method used by BricsCAD, if these tangents are stored in the DXF file provide them as argument tangents as 2-tuple (start, end) and the interpolated control vertices will match the BricsCAD calculation, except for floating point imprecision.
New in version 0.13.
It is possible to constraint the curve by tangents, by start- and end tangent if only two tangents are given or by one tangent for each fit point.
If tangents are given, they represent 1st derivatives and and should be scaled if they are unit vectors, if only start- and end tangents given the function estimate_end_tangent_magnitude() helps with an educated guess, if all tangents are given, scaling by chord length is a reasonable choice (Piegl & Tiller).
Source: Piegl & Tiller: “The NURBS Book” - chapter 9.3.4
Available tangent estimation methods:
or pass pre-calculated tangents, which overrides tangent estimation.
New in version 0.13.
New in version 0.13.
New in version 0.13.
New in version 0.13.
New in version 0.13.
If x- and y-axis are None: ux = (1, 0, 0), uy = (0, 1, 0), uz = (0, 0, 1).
Unit vectors don’t have to be normalized, normalization is done at initialization, this is also the reason why scaling gets lost by copying or rotating.
New in version 0.11.
The OCS is defined by the z-axis of the UCS.
The OCS is defined by the z-axis of the UCS.
New in version 0.14.
New in version 0.11.
New in version 0.11.
New in version 0.11.
New in version 0.11.
New in version 0.11.
New in version 0.11.
The utility functions for constructing transformations and transforming vectors and points assumes that vectors are stored as row vectors, meaning when multiplied, transformations are applied left to right (e.g. vAB transforms v by A then by B).
Matrix44 initialization:
Assumes that both matrices have a right column of (0, 0, 0, 1). This is True for matrices composed of rotations, translations and scales. fast_mul is approximately 25% quicker than the *= operator.
v1 = Vector(1, 2, 3) v2 = v1 v2.z = 7 # this is not possible, raises AttributeError v2 = Vector(v2.x, v2.y, 7) # this creates a new Vector() object assert v1.z == 3 # and v1 remains unchanged
Vector initialization:
Addition, subtraction, scalar multiplication and scalar division left and right handed are supported:
v = Vector(1, 2, 3) v + (1, 2, 3) == Vector(2, 4, 6) (1, 2, 3) + v == Vector(2, 4, 6) v - (1, 2, 3) == Vector(0, 0, 0) (1, 2, 3) - v == Vector(0, 0, 0) v * 3 == Vector(3, 6, 9) 3 * v == Vector(3, 6, 9) Vector(3, 6, 9) / 3 == Vector(1, 2, 3) -Vector(1, 2, 3) == (-1, -2, -3)
Comparison between vectors and vectors or tuples is supported:
Vector(1, 2, 3) < Vector (2, 2, 2) (1, 2, 3) < tuple(Vector(2, 2, 2)) # conversion necessary Vector(1, 2, 3) == (1, 2, 3) bool(Vector(1, 2, 3)) is True bool(Vector(0, 0, 0)) is False
Vec2 initialization accepts float-tuples (x, y[, z]), two floats or any object providing x and y attributes like Vec2 and Vector objects.
Vec2 implements a subset of Vector.
New in version 0.11.
If colinear is True, a colinear point is also left of the line.
tuple size | Description |
0 | no intersection |
1 | ray is a tangent to circle |
2 | ray intersects with the circle |
tuple size | Description |
0 | no intersection |
1 | circle touches the other circle at one point |
2 | circle intersects with the other circle |
ConstructionArc represents a 2D arc in the xy-plane, use an UCS to place arc in 3D space, see method add_to_layout().
Implements the 2D transformation tools: translate(), scale_uniform() and rotate_z()
All angles are normalized in the range from [0, 360).
The parameter center_is_left defines if the center of the arc is left or right of the line from start_point to end_point. Parameter ccw = False swaps start- and end point, which also inverts the meaning of center_is_left.
Supports 3D arcs by using an UCS. An ConstructionArc is always defined in the xy-plane, but by using an arbitrary UCS, the arc can be placed in 3D space, automatically OCS transformation included.
OCS elevation is stored in center.z.
All params are normalized in the range from [0, 2pi).
The vertex don’t has to be exact on the ellipse curve or in the range from start- to end param or even in the ellipse plane. Param is calculated from the intersection point of the ray projected on the ellipse plane from the center of the ellipse through the vertex.
WARNING:
Entity ELLIPSE has always a ratio in range from 1e-6 to 1.
Arc and Circle parameters defined in OCS.
list size | Description |
0 | no intersection |
1 | line touches box at one corner |
2 | line intersects with box |
New in version 0.11.
New in version 0.13.
e.g. n=1 returns point and 1st derivative.
e.g. n=1 returns point and 1st derivative.
This is the preferred method to represent the most common non-rational B-splines of 3rd degree by cubic Bézier curves, which are often supported by render backends.
1. approximation by level: an educated guess, the first level of approximation segments is based on the count of control points and their distribution along the B-spline, every additional level is a subdivision of the previous level. E.g. a B-Spline of 8 control points has 7 segments at the first level, 14 at the 2nd level and 28 at the 3rd level, a level >= 3 is recommended.
This is a general implementation which works with any count of definition points greater than 2, but it is a simple and slow implementation. For more performance look at the specialized Bezier4P class.
Objects are immutable.
New in version 0.14.
Special behavior:
New in version 0.14.
This is a parametric curve, which always starts at the origin = (0, 0).
Changed in version 0.10: renamed from circle_midpoint
Generates segments+1 vertices as Vector objects.
Internally used for matrix inverse calculation.
New in version 0.13.
HINT:
New in version 0.13.
Reference implementation for error checking.
New in version 0.13.
Reference implementation for error checking.
New in version 0.13.
Note: a0 is not used but has to be present, cn-1 is also not used and must not be present.
If an ZeroDivisionError exception occurs, the equation system can possibly be solved by BandedMatrixLU(A, 1, 1).solve_vector(B)
diagonal matrix [[a0..an-1], [b0..bn-1], [c0..cn-1]]
[[b0, c0, 0, 0, ...], [a1, b1, c1, 0, ...], [0, a2, b2, c2, ...], ... ]
New in version 0.13.
Note: a0 is not used but has to be present, cn-1 is also not used and must not be present.
If an ZeroDivisionError exception occurs, the equation system can possibly be solved by BandedMatrixLU(A, 1, 1).solve_vector(B)
diagonal matrix [[a0..an-1], [b0..bn-1], [c0..cn-1]]
[[b0, c0, 0, 0, ...], [a1, b1, c1, 0, ...], [0, a2, b2, c2, ...], ... ]
New in version 0.13.
The matrix can be frozen by function freeze_matrix() or method Matrix.freeze(), than the data is stored in immutable tuples.
Initialization:
New in version 0.13.
An index of 0 specifies the main diagonal, negative values specifies diagonals below the main diagonal and positive values specifies diagonals above the main diagonal.
e.g. given a 4x4 matrix: index 0 is [00, 11, 22, 33], index -1 is [10, 21, 32] and index +1 is [01, 12, 23]
An index of 0 specifies the main diagonal, negative values specifies diagonals below the main diagonal and positive values specifies diagonals above the main diagonal.
e.g. given a 4x4 matrix: index 0 is [00, 11, 22, 33], index -1 is [10, 21, 32] and index +1 is [01, 12, 23]
This algorithm is a little bit faster than the Gauss-Elimination algorithm using CPython and much faster when using pypy.
The LUDecomposition.matrix attribute gives access to the matrix data as list of rows like in the Matrix class, and the LUDecomposition.index attribute gives access to the swapped row indices.
New in version 0.13.
Global options stored in ezdxf.options
The DXF format uses a special form of unicode encoding: “\U+xxxx”.
To avoid a speed penalty such encoded characters are not decoded automatically by the regular loading function:func:ezdxf.readfile, only the recover module does the decoding automatically, because this loading mode is already slow.
This kind of encoding is most likely used only in older DXF versions, because since DXF R2007 the whole DXF file is encoded in utf8 and a special unicode encoding is not necessary.
The ezdxf.has_dxf_unicode() and ezdxf.decode_dxf_unicode() are new support functions to decode unicode characters “\U+xxxx” manually.
New in version 0.14.
Some handy tool functions used internally by ezdxf.
Tools to reorder DXF entities by handle or a special sort handle mapping.
Such reorder mappings are stored only in layouts as Modelspace, Paperspace or BlockLayout, and can be retrieved by the method get_redraw_order().
Each entry in the handle mapping replaces the actual entity handle, where the “0” handle has a special meaning, this handle always shows up at last in ascending ordering.
The sort handle doesn’t have to be the entity handle, every entity handle in mapping will be replaced by the given sort handle, mapping is an iterable of 2-tuples (entity_handle, sort_handle) or a dict (entity_handle, sort_handle). Entities with equal sort handles show up in source entities order.
The sort handle doesn’t have to be the entity handle, every entity handle in mapping will be replaced by the given sort handle, mapping is an iterable of 2-tuples (entity_handle, sort_handle) or a dict (entity_handle, sort_handle). Entities with equal sort handles show up in reversed source entities order.
The Howto section show how to accomplish specific tasks with ezdxf in a straight forward way without teaching basics or internals, if you are looking for more information about the ezdxf internals look at the Reference section or if you want to learn how to use ezdxf go to the Tutorials section or to the Basic Concepts section.
General preconditions:
import sys import ezdxf try:
doc = ezdxf.readfile("your_dxf_file.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) msp = doc.modelspace()
This works well with DXF files from trusted sources like AutoCAD or BricsCAD, for loading DXF files with minor or major flaws look at the ezdxf.recover module.
If you know the files you will process have most likely minor or major flaws, use the ezdxf.recover module:
import sys from ezdxf import recover try: # low level structure repair:
doc, auditor = recover.readfile(name) 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: {name}.')
sys.exit(2) # DXF file can still have unrecoverable errors, but this is maybe # just a problem when saving the recovered DXF file. if auditor.has_errors:
print(f'Found unrecoverable errors in DXF file: {name}.')
auditor.print_error_report()
For more loading scenarios follow the link: ezdxf.recover
ezdxf has an interface to get and set HEADER variables:
doc.header['VarName'] = value value = doc.header['VarName']
SEE ALSO:
Use this HEADER variables to setup the default units for CAD applications opening the DXF file. This settings are not relevant for ezdxf API calls, which are unitless for length values and coordinates and decimal degrees for angles (in most cases).
Sets drawing units:
$MEASUREMENT controls whether the current drawing uses imperial or metric hatch pattern and linetype files:
doc.header['$MEASUREMENT'] = 1
0 | English |
1 | Metric |
$LUNITS sets the linear units format for creating objects:
doc.header['$LUNITS'] = 2
1 | Scientific |
2 | Decimal (default) |
3 | Engineering |
4 | Architectural |
5 | Fractional |
$AUNITS set units format for angles:
doc.header['$AUNITS'] = 0
0 | Decimal degrees |
1 | Degrees/minutes/seconds |
2 | Grad |
3 | Radians |
$INSUNITS set default drawing units for AutoCAD DesignCenter blocks:
doc.header['$INSUNITS'] = 6
0 | Unitless |
1 | Inches |
2 | Feet |
3 | Miles |
4 | Millimeters |
5 | Centimeters |
6 | Meters |
7 | Kilometers |
8 | Microinches |
9 | Mils |
10 | Yards |
11 | Angstroms |
12 | Nanometers |
13 | Microns |
14 | Decimeters |
15 | Decameters |
16 | Hectometers |
17 | Gigameters |
18 | Astronomical units |
19 | Light years |
20 | Parsecs |
21 | US Survey Feet |
22 | US Survey Inch |
23 | US Survey Yard |
24 | US Survey Mile |
DXF files are plain text files, you can open this files with every text editor which handles bigger files. But it is not really easy to get quick the information you want.
Create a more readable HTML file (DXF Pretty Printer):
# on Windows py -3 -m ezdxf.pp your_dxf_file.dxf # on Linux/Mac python3 -m ezdxf.pp your_dxf_file.dxf
This produces a HTML file your_dxf_file.html with a nicer layout than a plain DXF file and DXF handles as links between DXF entities, this simplifies the navigation between the DXF entities.
Changed in version 0.8.3: Since ezdxf v0.8.3, a script called dxfpp will be added to your Python script path:
usage: dxfpp [-h] [-o] [-r] [-x] [-l] FILE [FILE ...] positional arguments:
FILE DXF files pretty print optional arguments:
-h, --help show this help message and exit
-o, --open open generated HTML file with the default web browser
-r, --raw raw mode - just print tags, no DXF structure interpretation
-x, --nocompile don't compile points coordinates into single tags (only in
raw mode)
-l, --legacy legacy mode - reorders DXF point coordinates
IMPORTANT:
To show an arbitrary location of the modelspace centered in the CAD application window, set the '*Active' VPORT to this location. The DXF attribute dxf.center defines the location in the modelspace, and the dxf.height specifies the area of the modelspace to view. Shortcut function:
doc.set_modelspace_vport(height=10, center=(10, 10))
New in version 0.11.
AutoDesk web service A360 seems to be more picky than the AutoCAD desktop applications, may be it helps to use the latest DXF version supported by ezdxf, which is DXF R2018 (AC1032) in the year of writing this lines (2018).
ezdxf does not automatically locate the main viewport of the modelspace at the entities, you have to perform the “Zoom to Extends” command, here in TrueView 2020: [image]
And here in the Autodesk Online Viewer: [image]
Add this line to your code to relocate the main viewport, adjust the center (in modelspace coordinates) and the height (in drawing units) arguments to your needs:
doc.set_modelspace_vport(height=10, center=(0, 0))
If you are adding XREFS and IMAGES with relative paths to existing drawings and they do not show up in AutoCAD immediately, change the HEADER variable $PROJECTNAME='' to (not really) solve this problem. The ezdxf templates for DXF R2004 and later have $PROJECTNAME='' as default value.
Thanks to David Booth:
A workaround (to show IMAGES on loading) appears to be to save the full file path in the DXF or save it as a DWG.
So far - no solution for showing IMAGES with relative paths on loading.
To show an arbitrary location of the modelspace centered in the CAD application window, set the '*Active' VPORT to this location. The DXF attribute dxf.center defines the location in the modelspace, and the dxf.height specifies the area of the modelspace to view. Shortcut function:
doc.set_modelspace_vport(height=10, center=(10, 10))
New in version 0.11.
General preconditions:
import sys import ezdxf try:
doc = ezdxf.readfile("your_dxf_file.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) msp = doc.modelspace()
The entity color is stored as ACI (AutoCAD Color Index):
aci = entity.dxf.color
Default value is 256 which means BYLAYER:
layer = doc.layers.get(entity.dxf.layer) aci = layer.get_color()
The special get_color() method is required, because the color attribute Layer.dxf.color is misused as layer on/off flag, a negative color value means the layer is off.
ACI value 0 means BYBLOCK, which means the color from the block reference (INSERT entity).
Set color as ACI value as int in range [0, 256]:
entity.dxf.color = 1
The RGB values of the AutoCAD default colors are not officially documented, but an accurate translation table is included in ezdxf:
from ezdxf.tools.rgb import DXF_DEFAULT_COLORS, int2rgb # 24 bit value RRRRRRRRGGGGGGGGBBBBBBBB rgb24 = DXF_DEFAULT_COLORS[aci] print(f'RGB Hex Value: #{rgb24:06X}') r, g, b = int2rgb(rgb24) print(f'RGB Channel Values: R={r:02X} G={g:02X} b={b:02X}')
The ACI value 7 has a special meaning, it is white on dark backgrounds and white on light backgrounds.
RGB true color values are supported since DXF R13 (AC1012), the 24-bit RGB value is stored as integer in the DXF attribute true_color:
# set true color value to red entity.dxf.true_color = 0xFF0000
The rgb property of the DXFGraphic entity add support to get/set RGB value as (r, g, b)-tuple:
# set true color value to red entity.rgb = (255, 0, 0)
If color and true_color values are set, BricsCAD and AutoCAD use the true_color value as display color for the entity.
Block references (Insert) can have attached attributes (Attrib), these are simple text annotations with an associated tag appended to the block reference.
Iterate over all appended attributes:
# get all INSERT entities with entity.dxf.name == "Part12" blockrefs = msp.query('INSERT[name=="Part12"]') if len(blockrefs):
entity = blockrefs[0] # process first entity found
for attrib in entity.attribs:
if attrib.dxf.tag == "diameter": # identify attribute by tag
attrib.dxf.text = "17mm" # change attribute content
Get attribute by tag:
diameter = entity.get_attrib('diameter') if diameter is not None:
diameter.dxf.text = "17mm"
Adding XDATA as list of tuples (group code, value) by set_xdata(), overwrites data if already present:
doc.appids.new('YOUR_APPID') # IMPORTANT: create an APP ID entry circle = msp.add_circle((10, 10), 100) circle.set_xdata(
'YOUR_APPID',
[
(1000, 'your_web_link.org'),
(1002, '{'),
(1000, 'some text'),
(1002, '{'),
(1071, 1),
(1002, '}'),
(1002, '}')
])
For group code meaning see DXF reference section DXF Group Codes in Numerical Order Reference, valid group codes are in the range 1000 - 1071.
Method get_xdata() returns the extended data for an entity as Tags object.
In general the Dimension styling and config attributes are stored in the Dimstyle entity, but every attribute can be overridden for each DIMENSION entity individually, get overwritten values by the DimstyleOverride object as shown in the following example:
for dimension in msp.query('DIMENSION'):
dimstyle_override = dimension.override() # requires v0.12
dimtol = dimstyle_override['dimtol']
if dimtol:
print(f'{str(dimension)} has tolerance values:')
dimtp = dimstyle_override['dimtp']
dimtm = dimstyle_override['dimtm']
print(f'Upper tolerance: {dimtp}')
print(f'Lower tolerance: {dimtm}')
The DimstyleOverride object returns the value of the underlying DIMSTYLE objects if the value in DIMENSION was not overwritten, or None if the value was neither defined in DIMSTYLE nor in DIMENSION.
Same as above, the DimstyleOverride object supports also overriding DIMSTYLE values. But just overriding this values have no effect on the graphical representation of the DIMENSION entity, because CAD applications just show the associated anonymous block which contains the graphical representation on the DIMENSION entity as simple DXF entities. Call the render method of the DimstyleOverride object to recreate this graphical representation by ezdxf, but ezdxf does not support all DIMENSION types and DIMVARS yet, and results will differ from AutoCAD or BricsCAD renderings.
dimstyle_override = dimension.override() dimstyle_override.set_tolerance(0.1) # delete associated geometry block del doc.blocks[dimension.dxf.geometry] # recreate geometry block dimstyle_override.render()
In 2010 I started my first Python package for creating DXF documents called dxfwrite, this package can’t read DXF files and writes only the DXF R12 (AC1009) version. While dxfwrite works fine, I wanted a more versatile package, that can read and write DXF files and maybe also supports newer DXF formats than DXF R12.
This was the start of the ezdxf package in 2011, but the progress was so slow, that I created a spin off in 2012 called dxfgrabber, which implements only the reading part of ezdxf, which I needed for my work and I wasn’t sure if ezdxf will ever be usable. Luckily in 2014 the first usable version of ezdxf could be released. The ezdxf package has all the features of dxfwrite and dxfgrabber and much more, but with a different API. So ezdxf is not a drop-in replacement for dxfgrabber or dxfwrite.
Since ezdxf can do all the things that dxfwrite and dxfgrabber can do, I focused on the development of ezdxf, dxfwrite and dxfgrabber are in maintenance mode only and will not get any new features, just bugfixes.
There are no advantages of dxfwrite over ezdxf, dxfwrite has the smaller memory footprint, but the r12writer add-on does the same job as dxfwrite without any in memory structures by writing direct to a stream or file and there is also no advantage of dxfgrabber over ezdxf for normal DXF files the smaller memory footprint of dxfgrabber is not noticeable and for really big files the iterdxf add-on does a better job.
The ezdxf.render subpackage provides helpful utilities to create complex forms.
Content
Render a B-spline as 2D/3D Polyline, can be used with DXF R12. The advantage over R12Spline is the real 3D support which means the B-spline curve vertices has not to be in a plane and no hassle with UCS for 3D placing.
DXF R12 supports 2D B-splines, but Autodesk do not document the usage in the DXF Reference. The base entity for splines in DXF R12 is the POLYLINE entity. The spline itself is always in a plane, but as any 2D entity, the spline can be transformed into the 3D object by elevation and extrusion (OCS, UCS).
The result is not better than Spline, it is also just a POLYLINE entity, but as with all tools, you never know if someone needs it some day.
Render a bezier curve as 2D/3D Polyline.
The Bezier class is implemented with multiple segments, each segment is an optimized 4 point bezier curve, the 4 control points of the curve are: the start point (1) and the end point (4), point (2) is start point + start vector and point (3) is end point + end vector. Each segment has its own approximation count.
Render an euler spiral as 3D Polyline or Spline.
This is a parametric curve, which always starts at the origin (0, 0).
Random path generators for testing purpose.
2D Forms
3D Forms
3D Form Builder
Argument count defines the count of star spikes, r1 defines the radius of the “outer” vertices and r2 defines the radius of the “inner” vertices, but this does not mean that r1 has to be greater than r2.
WARNING:
Create 3D forms as MeshTransformer objects.
Returns: MeshTransformer
Returns: MeshTransformer
Returns: MeshTransformer
New in version 0.11.
Returns: MeshTransformer
Returns: MeshTransformer
New in version 0.11.
Returns: MeshTransformer
New in version 0.11.
Returns: MeshTransformer
Returns: MeshTransformer
Returns: MeshTransformer
Returns: MeshTransformer
The MeshBuilder is a helper class to create Mesh entities. Stores a list of vertices, a list of edges where an edge is a list of indices into the vertices list, and a faces list where each face is a list of indices into the vertices list.
The MeshBuilder.render() method, renders the mesh into a Mesh entity. The Mesh entity supports ngons in AutoCAD, ngons are polygons with more than 4 vertices.
The basic MeshBuilder class does not support transformations.
e.g. adding 4 vertices to an empty mesh, returns the indices (0, 1, 2, 3), adding additional 4 vertices returns the indices (4, 5, 6, 7).
A mesh can be a MeshBuilder, MeshVertexMerger or Mesh object or requires the attributes vertices, edges and faces.
New in version 0.11.1.
New in version 0.12.
New in version 0.11.1.
Same functionality as MeshBuilder but supports inplace transformation.
Same functionality as MeshBuilder, but created meshes with unique vertices and no doublets, but MeshVertexMerger needs extra memory for bookkeeping and also does not support transformations. Location of merged vertices is the location of the first vertex with the same key.
This class is intended as intermediate object to create a compact meshes and convert them to MeshTransformer objects to apply transformations to the mesh:
mesh = MeshVertexMerger() # create your mesh mesh.add_face(...) # convert mesh to MeshTransformer object return MeshTransformer.from_builder(mesh)
Mesh with unique vertices and no doublets, but needs extra memory for bookkeeping.
MeshVertexMerger creates a key for every vertex by rounding its components by the Python round() function and a given precision value. Each vertex with the same key gets the same vertex index, which is the index of first vertex with this key, so all vertices with the same key will be located at the location of this first vertex. If you want an average location of and for all vertices with the same key look at the MeshAverageVertexMerger class.
This is an extended version of MeshVertexMerger. Location of merged vertices is the average location of all vertices with the same key, this needs extra memory and runtime in comparision to MeshVertexMerger and this class also does not support transformations.
Mesh with unique vertices and no doublets, but needs extra memory for bookkeeping and runtime for calculation of average vertex location.
MeshAverageVertexMerger creates a key for every vertex by rounding its components by the Python round() function and a given precision value. Each vertex with the same key gets the same vertex index, which is the index of first vertex with this key, the difference to the MeshVertexMerger class is the calculation of the average location for all vertices with the same key, this needs extra memory to keep track of the count of vertices for each key and extra runtime for updating the vertex location each time a vertex with an existing key is added.
This module provides tools to create banded lines like LWPOLYLINE with width information. Path rendering as quadrilaterals: Trace, Solid or Face3d.
Accepts 3D input, but z-axis is ignored.
If a document is given, the doc attribute of the new entities will be set and the new entities will be automatically added to the entity database of that document.
Accepts 3D input, but z-axis is ignored.
Adding the last location again, replaces the actual last location e.g. adding lines (a, b), (b, c), creates only 3 stations (a, b, c), this is very important to connect to/from splines.
First and last miter is 90 degrees if the path is not closed, otherwise the intersection of first and last segment is taken into account, a closed path has to have explicit the same last and first vertex.
If a document is given, the doc attribute of the new entities will be set and the new entities will be automatically added to the entity database of that document.
Represents always only one curved entity and all miter of curve segments are perpendicular to curve tangents.
Accepts 3D input, but z-axis is ignored.
If a document is given, the doc attribute of the new entities will be set and the new entities will be automatically added to the entity database of that document.
This module implements a geometrical Path supported by several render backends, with the goal to create such paths from LWPOLYLINE, POLYLINE and HATCH boundary paths and send them to the render backend, see ezdxf.addons.drawing.
Minimum common interface:
ARC and ELLIPSE entities are approximated by multiple cubic Bézier-curves, which are close enough for display rendering. Non-rational SPLINES of 3rd degree can be represented exact as multiple cubic Bézier-curves, other B-splines will be approximated.
Auto-detect if the path end point is connected to the start- or end point of the curves, if none of them is close to the path end point a line from the path end point to the curves start point will be added.
Auto-detect connection point, if none is close a line from the path end point to the ellipse start point will be added (see add_curves()).
By default the start of an empty path is set to the start point of the ellipse, setting argument reset to False prevents this behavior.
Non-rational B-splines of 3rd degree gets a perfect conversion to cubic bezier curves with a minimal count of curve segments, all other B-spline require much more curve segments for approximation.
Auto-detect connection point, if none is close a line from the path end point to the spline start point will be added (see add_curves()).
By default the start of an empty path is set to the start point of the spline, setting argument reset to False prevents this behavior.
The fast file/stream writer creates simple DXF R12 drawings with just an ENTITIES section. The HEADER, TABLES and BLOCKS sections are not present except FIXED-TABLES are written. Only LINE, CIRCLE, ARC, TEXT, POINT, SOLID, 3DFACE and POLYLINE entities are supported. FIXED-TABLES is a predefined TABLES section, which will be written, if the init argument fixed_tables of R12FastStreamWriter is True.
The R12FastStreamWriter writes the DXF entities as strings direct to the stream without creating an in-memory drawing and therefore the processing is very fast.
Because of the lack of a BLOCKS section, BLOCK/INSERT can not be used. Layers can be used, but this layers have a default setting color = 7 (black/white) and linetype = 'Continuous'. If writing the FIXED-TABLES, some predefined text styles and line types are available, else text style is always 'STANDARD' and line type is always 'ByLayer'.
If using FIXED-TABLES, following predefined line types are available:
If using FIXED-TABLES, following predefined text styles are available:
New in version 0.12: Write Binary DXF files.
A simple example with different DXF entities:
from random import random from ezdxf.addons import r12writer with r12writer("quick_and_dirty_dxf_r12.dxf") as dxf:
dxf.add_line((0, 0), (17, 23))
dxf.add_circle((0, 0), radius=2)
dxf.add_arc((0, 0), radius=3, start=0, end=175)
dxf.add_solid([(0, 0), (1, 0), (0, 1), (1, 1)])
dxf.add_point((1.5, 1.5))
# 2d polyline, new in v0.12
dxf.add_polyline_2d([(5, 5), (7, 3), (7, 6)])
# 2d polyline with bulge value, new in v0.12
dxf.add_polyline_2d([(5, 5), (7, 3, 0.5), (7, 6)], format='xyb')
# 3d polyline only, changed in v0.12
dxf.add_polyline([(4, 3, 2), (8, 5, 0), (2, 4, 9)])
dxf.add_text("test the text entity", align="MIDDLE_CENTER")
A simple example of writing really many entities in a short time:
from random import random from ezdxf.addons import r12writer MAX_X_COORD = 1000.0 MAX_Y_COORD = 1000.0 CIRCLE_COUNT = 1000000 with r12writer("many_circles.dxf") as dxf:
for i in range(CIRCLE_COUNT):
dxf.add_circle((MAX_X_COORD*random(), MAX_Y_COORD*random()), radius=2)
Show all available line types:
import ezdxf LINETYPES = [
'CONTINUOUS', 'CENTER', 'CENTERX2', 'CENTER2',
'DASHED', 'DASHEDX2', 'DASHED2', 'PHANTOM', 'PHANTOMX2',
'PHANTOM2', 'DASHDOT', 'DASHDOTX2', 'DASHDOT2', 'DOT',
'DOTX2', 'DOT2', 'DIVIDE', 'DIVIDEX2', 'DIVIDE2', ] with r12writer('r12_linetypes.dxf', fixed_tables=True) as dxf:
for n, ltype in enumerate(LINETYPES):
dxf.add_line((0, n), (10, n), linetype=ltype)
dxf.add_text(ltype, (0, n+0.1), height=0.25, style='OpenSansCondensed-Light')
New in version 0.12: Set argument fmt to 'asc' to write ASCII DXF file (default) or 'bin' to write Binary DXF files. ASCII DXF require a TextIO stream and Binary DXF require a BinaryIO stream.
bit coded flag to define the invisible edges,
Add edge values to set multiple edges invisible, 1. edge + 3. edge = 1 + 4 = 5, all edges = 15
Format codes:
x | x-coordinate |
y | y-coordinate |
s | start width |
e | end width |
b | bulge value |
v | (x, y) tuple (z-axis is ignored) |
Changed in version 0.12: Write only 3D POLYLINE entity, added closed argument.
v0 = (0, 0, 0) v1 = (1, 0, 0) v2 = (1, 1, 0) v3 = (0, 1, 0) dxf.add_polyface(vertices=[v0, v1, v2, v3], faces=[(0, 1, 2, 3)])
All 3D form functions of the ezdxf.render.forms module return MeshBuilder objects, which provide the required vertex and face lists.
See sphere example: https://github.com/mozman/ezdxf/blob/master/examples/r12writer.py
See example: https://github.com/mozman/ezdxf/blob/master/examples/r12writer.py
Vert/Horiz | Left | Center | Right |
Top | TOP_LEFT | TOP_CENTER | TOP_RIGHT |
Middle | MIDDLE_LEFT | MIDDLE_CENTER | MIDDLE_RIGHT |
Bottom | BOTTOM_LEFT | BOTTOM_CENTER | BOTTOM_RIGHT |
Baseline | LEFT | CENTER | RIGHT |
The special alignments ALIGNED and FIT are not available.
This add-on allows iterating over entities of the modelspace of really big (> 5GB) DXF files which do not fit into memory by only loading one entity at the time. Only ASCII DXF files are supported.
The entities are regular DXFGraphic objects with access to all supported DXF attributes, this entities can be written to new DXF files created by the IterDXF.export() method. The new add_foreign_entity() method allows also to add this entities to new regular ezdxf drawings (except for the INSERT entity), but resources like linetype and style are removed, only layer will be preserved but only with default attributes like color 7 and linetype CONTINUOUS.
The following example shows how to split a big DXF files into several separated DXF files which contains only LINE, TEXT or POLYLINE entities.
from ezdxf.addons import iterdxf doc = iterdxf.opendxf('big.dxf') line_exporter = doc.export('line.dxf') text_exporter = doc.export('text.dxf') polyline_exporter = doc.export('polyline.dxf') try:
for entity in doc.modelspace():
if entity.dxftype() == 'LINE':
line_exporter.write(entity)
elif entity.dxftype() == 'TEXT':
text_exporter.write(entity)
elif entity.dxftype() == 'POLYLINE':
polyline_exporter.write(entity) finally:
line_exporter.close()
text_exporter.close()
polyline_exporter.close()
doc.close()
Supported DXF types:
3DFACE, ARC, ATTDEF, ATTRIB, CIRCLE, DIMENSION, ELLIPSE, HATCH, HELIX, IMAGE, INSERT, LEADER, LINE, LWPOLYLINE, MESH, MLEADER, MLINE, MTEXT, POINT, POLYLINE, RAY, SHAPE, SOLID, SPLINE, TEXT, TRACE, VERTEX, WIPEOUT, XLINE
Transfer simple entities to another DXF document, this works for some supported entities, except for entities with strong dependencies to the original document like INSERT look at add_foreign_entity() for all supported types:
newdoc = ezdxf.new() msp = newdoc.modelspace() # line is an entity from a big source file msp.add_foreign_entity(line) # and so on ... msp.add_foreign_entity(lwpolyline) msp.add_foreign_entity(mesh) msp.add_foreign_entity(polyface)
Transfer MESH and POLYFACE (dxftype for POLYFACE and POLYMESH is POLYLINE!) entities into a new DXF document by the MeshTransformer class:
from ezdxf.render import MeshTransformer # mesh is MESH from a big source file t = MeshTransformer.from_mesh(mesh) # create a new MESH entity from MeshTransformer t.render(msp) # polyface is POLYFACE from a big source file t = MeshTransformer.from_polyface(polyface) # create a new POLYMESH entity from MeshTransformer t.render_polyface(msp)
Another way to import entities from a big source file into new DXF documents is to split the big file into smaller parts and use the Importer add-on for a more safe entity import.
Use this function to split up big DXF files as shown in the example above.
specify decoding error handler
Use this function to iterate “quick” over modelspace entities of a DXF file, filtering DXF types may speed up things if many entity types will be skipped.
specify decoding error handler
Use this function to ‘quick’ iterate over modelspace entities of a not seekable binary DXF stream, filtering DXF types may speed up things if many entity types will be skipped.
specify decoding error handler
It is only possible to recreate the objects by factory functions base on attributes of the source entity. For MESH, POLYMESH and POLYFACE it is possible to use the MeshTransformer class to render (recreate) this objects as new entities in another document.
Don’t write entities from different documents than the source DXF file, dependencies and resources will not match, maybe it will work once, but not in a reliable way for different DXF documents.
This add-on is meant to import graphical entities from another DXF drawing and their required table entries like LAYER, LTYPE or STYLE.
Because of complex extensibility of the DXF format and the lack of sufficient documentation, I decided to remove most of the possible source drawing dependencies from imported entities, therefore imported entities may not look the same as the original entities in the source drawing, but at least the geometry should be the same and the DXF file does not break.
Removed data which could contain source drawing dependencies: Extension Dictionaries, AppData and XDATA.
WARNING:
The Importer supports following data import:
Import of DXF objects from the OBJECTS section is not supported.
DIMSTYLE override for entities DIMENSION and LEADER is not supported.
Example:
import ezdxf from ezdxf.addons import Importer sdoc = ezdxf.readfile('original.dxf') tdoc = ezdxf.new() importer = Importer(sdoc, tdoc) # import all entities from source modelspace into modelspace of the target drawing importer.import_modelspace() # import all paperspace layouts from source drawing importer.import_paperspace_layouts() # import all CIRCLE and LINE entities from source modelspace into an arbitrary target layout. # create target layout tblock = tdoc.blocks.new('SOURCE_ENTS') # query source entities ents = sdoc.modelspace().query('CIRCLE LINE') # import source entities into target block importer.import_entities(ents, tblock) # This is ALWAYS the last & required step, without finalizing the target drawing is maybe invalid! # This step imports all additional required table entries and block definitions. importer.finalize() tdoc.saveas('imported.dxf')
To replace an existing block in the target drawing, just delete it before importing: target.blocks.delete_block(block_name, safe=False)
Returns: block name (renamed)
Returns: new created target paperspace Layout
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
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')
The rendering is performed in two stages. The front-end traverses the DXF document structure, converting each encountered entity into primitive drawing commands. These commands are fed to a back-end which implements the interface: Backend. Currently a PyQt5 (QGraphicsScene based) and Matplotlib backend are implemented.
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:
see examples/addons/drawing/cad_viewer.py for an advanced use of the module. See examples/addons/drawing/draw_cad.py for a simple use of the module.
see drawing.md in the ezdxf repository for additional behaviours documented during the development of this add-on.
Translate DXF entities and structures into Python source code.
Short example:
import ezdxf from ezdxf.addons.dxf2code import entities_to_code, block_to_code doc = ezdxf.readfile('original.dxf') msp = doc.modelspace() source = entities_to_code(msp) # create source code for a block definition block_source = block_to_code(doc.blocks['MyBlock']) # merge source code objects source.merge(block_source) with open('source.py', mode='wt') as f:
f.write(source.import_str())
f.write('\n\n')
f.write(source.code_str())
f.write('\n')
CTB and STB files store plot styles used by AutoCAD and BricsCAD for printing and plotting.
If the plot style table is attached to a Paperspace or the Modelspace, a change of a plot style affects any object that uses that plot style. CTB files contain color dependent plot style tables, STB files contain named plot style tables.
SEE ALSO:
Changed in version 0.10: renamed from new()
New in version 0.10.
Color dependent plot style table (CTB file), table entries are PlotStyle objects.
Named plot style table (STB file), table entries are PlotStyle objects.
If you select 100 the drawing will plotted with its full color intensity. In order for screening to work, the dithering option must be active.
Dithering is available only whether you select the object’s color or assign a plot style color.
# | [mm] |
0 | 0.00 |
1 | 0.05 |
2 | 0.09 |
3 | 0.10 |
4 | 0.13 |
5 | 0.15 |
6 | 0.18 |
7 | 0.20 |
8 | 0.25 |
9 | 0.30 |
10 | 0.35 |
11 | 0.40 |
12 | 0.45 |
13 | 0.50 |
14 | 0.53 |
15 | 0.60 |
16 | 0.65 |
17 | 0.70 |
18 | 0.80 |
19 | 0.90 |
20 | 1.00 |
21 | 1.06 |
22 | 1.20 |
23 | 1.40 |
24 | 1.58 |
25 | 2.00 |
26 | 2.11 |
[image]
END_STYLE_BUTT | 0 |
END_STYLE_SQUARE | 1 |
END_STYLE_ROUND | 2 |
END_STYLE_DIAMOND | 3 |
END_STYLE_OBJECT | 4 |
[image]
JOIN_STYLE_MITER | 0 |
JOIN_STYLE_BEVEL | 1 |
JOIN_STYLE_ROUND | 2 |
JOIN_STYLE_DIAMOND | 3 |
JOIN_STYLE_OBJECT | 5 |
[image]
FILL_STYLE_SOLID | 64 |
FILL_STYLE_CHECKERBOARD | 65 |
FILL_STYLE_CROSSHATCH | 66 |
FILL_STYLE_DIAMONDS | 67 |
FILL_STYLE_HORIZONTAL_BARS | 68 |
FILL_STYLE_SLANT_LEFT | 69 |
FILL_STYLE_SLANT_RIGHT | 70 |
FILL_STYLE_SQUARE_DOTS | 71 |
FILL_STYLE_VERICAL_BARS | 72 |
FILL_STYLE_OBJECT | 73 |
[image] [image]
Linetype name | Value |
Solid | 0 |
Dashed | 1 |
Dotted | 2 |
Dash Dot | 3 |
Short Dash | 4 |
Medium Dash | 5 |
Long Dash | 6 |
Short Dash x2 | 7 |
Medium Dash x2 | 8 |
Long Dash x2 | 9 |
Medium Lang Dash | 10 |
Medium Dash Short Dash Short Dash | 11 |
Long Dash Short Dash | 12 |
Long Dash Dot Dot | 13 |
Long Dash Dot | 14 |
Medium Dash Dot Short Dash Dot | 15 |
Sparse Dot | 16 |
ISO Dash | 17 |
ISO Dash Space | 18 |
ISO Long Dash Dot | 19 |
ISO Long Dash Double Dot | 20 |
ISO Long Dash Triple Dot | 21 |
ISO Dot | 22 |
ISO Long Dash Short Dash | 23 |
ISO Long Dash Double Short Dash | 24 |
ISO Dash Dot | 25 |
ISO Double Dash Dot | 26 |
ISO Dash Double Dot | 27 |
ISO Double Dash Double Dot | 28 |
ISO Dash Triple Dot | 29 |
ISO Double Dash Triple Dot | 30 |
Use entity linetype | 31 |
Constructive Solid Geometry (CSG) is a modeling technique that uses Boolean operations like union and intersection to combine 3D solids. This library implements CSG operations on meshes elegantly and concisely using BSP trees, and is meant to serve as an easily understandable implementation of the algorithm. All edge cases involving overlapping coplanar polygons in both solids are correctly handled.
New in version 0.11.
Example for usage:
import ezdxf from ezdxf.render.forms import cube, cylinder_2p from ezdxf.addons.pycsg import CSG # create new DXF document doc = ezdxf.new() msp = doc.modelspace() # create same geometric primitives as MeshTransformer() objects cube1 = cube() cylinder1 = cylinder_2p(count=32, base_center=(0, -1, 0), top_center=(0, 1, 0), radius=.25) # build solid union union = CSG(cube1) + CSG(cylinder1) # convert to mesh and render mesh to modelspace union.mesh().render(msp, dxfattribs={'color': 1}) # build solid difference difference = CSG(cube1) - CSG(cylinder1) # convert to mesh, translate mesh and render mesh to modelspace difference.mesh().translate(1.5).render(msp, dxfattribs={'color': 3}) # build solid intersection intersection = CSG(cube1) * CSG(cylinder1) # convert to mesh, translate mesh and render mesh to modelspace intersection.mesh().translate(2.75).render(msp, dxfattribs={'color': 5}) doc.saveas('csg.dxf')
This CSG kernel supports only meshes as MeshBuilder objects, which can be created from and converted to DXF Mesh entities.
This CSG kernel is not compatible with ACIS objects like Solid3d, Body, Surface or Region.
NOTE:
import sys actual_limit = sys.getrecursionlimit() # default is 1000, increasing too much may cause a seg fault sys.setrecursionlimit(10000) ... # do the CSG stuff sys.setrecursionlimit(actual_limit)
CSG works also with spheres, but with really bad runtime behavior and most likely RecursionError exceptions, and use quadrilaterals as body faces to reduce face count by setting argument quads to True.
import ezdxf from ezdxf.render.forms import sphere, cube from ezdxf.addons.pycsg import CSG doc = ezdxf.new() doc.set_modelspace_vport(6, center=(5, 0)) msp = doc.modelspace() cube1 = cube().translate(-.5, -.5, -.5) sphere1 = sphere(count=32, stacks=16, radius=.5, quads=True) union = (CSG(cube1) + CSG(sphere1)).mesh() union.render(msp, dxfattribs={'color': 1}) subtract = (CSG(cube1) - CSG(sphere1)).mesh().translate(2.5) subtract.render(msp, dxfattribs={'color': 3}) intersection = (CSG(cube1) * CSG(sphere1)).mesh().translate(4) intersection.render(msp, dxfattribs={'color': 5})
Hard Core CSG - Menger Sponge Level 3 vs Sphere
Required runtime on an old Xeon E5-1620 Workstation @ 3.60GHz, with default recursion limit of 1000 on Windows 10:
from ezdxf.render.forms import sphere from ezdxf.addons import MengerSponge from ezdxf.addons.pycsg import CSG doc = ezdxf.new() doc.layers.new('sponge', dxfattribs={'color': 5}) doc.layers.new('sphere', dxfattribs={'color': 6}) doc.set_modelspace_vport(6, center=(5, 0)) msp = doc.modelspace() sponge1 = MengerSponge(level=3).mesh() sphere1 = sphere(count=32, stacks=16, radius=.5, quads=True).translate(.25, .25, 1) subtract = (CSG(sponge1, meshid=1) - CSG(sphere1, meshid=2)) # get mesh result by id subtract.mesh(1).render(msp, dxfattribs={'layer': 'sponge'}) subtract.mesh(2).render(msp, dxfattribs={'layer': 'sphere'})
New 3D solids are created from MeshBuilder objects and results can be exported as MeshTransformer objects to ezdxf by method mesh().
A.union(B) +-------+ +-------+ | | | | | A | | | | +--+----+ = | +----+ +----+--+ | +----+ |
| B | | |
| | | |
+-------+ +-------+
union = A + B
A.subtract(B) +-------+ +-------+ | | | | | A | | | | +--+----+ = | +--+ +----+--+ | +----+
| B |
| |
+-------+
difference = A - B
A.intersect(B) +-------+ | | | A | | +--+----+ = +--+ +----+--+ | +--+
| B |
| |
+-------+
intersection = A * B
Build a 3D Menger sponge.
0 | Original Menger Sponge |
1 | Variant XOX |
2 | Variant OXO |
3 | Jerusalem Cube |
Menger Sponge kind=0: [image]
Menger Sponge kind=1: [image]
Menger Sponge kind=2: [image]
Jerusalem Cube kind=3: [image]
Build a 3D Sierpinsky Pyramid.
Sierpinsky Pyramid with triangle base: [image]
Sierpinsky Pyramid with square base: [image]
Use an installed ODA File Converter for converting between different versions of .dwg, .dxb and .dxf.
WARNING:
To avoid this problem delete the ezdxf.addons.odafc.py module.
The ODA File Converter has to be installed by the user, the application is available for Windows XP, Windows 7 or later, Mac OS X, and Linux in 32/64-bit RPM and DEB format.
At least at Windows the GUI of the ODA File Converter pops up on every call.
ODA File Converter version strings, you can use any of this strings to specify a version, 'R..' and 'AC....' strings will be automatically mapped to 'ACAD....' strings:
ODAFC | ezdxf | Version |
ACAD9 | not supported | AC1004 |
ACAD10 | not supported | AC1006 |
ACAD12 | R12 | AC1009 |
ACAD13 | R13 | AC1012 |
ACAD14 | R14 | AC1014 |
ACAD2000 | R2000 | AC1015 |
ACAD2004 | R2004 | AC1018 |
ACAD2007 | R2007 | AC1021 |
ACAD2010 | R2010 | AC1024 |
ACAD2013 | R2013 | AC1027 |
ACAD2018 | R2018 | AC1032 |
Usage:
from ezdxf.addons import odafc # Load a DWG file doc = odafc.readfile('my.dwg') # Use loaded document like any other ezdxf document print(f'Document loaded as DXF version: {doc.dxfversion}.') msp = doc.modelspace() ... # Export document as DWG file for AutoCAD R2018 odafc.export_dwg(doc, 'my_R2018.dwg', version='R2018')
Saves a temporary DXF file and convert this DXF file into a DWG file by the ODA File Converter. If version is not specified the DXF version of the source document is used.
Drawing files of DXF R2004 (AC1018) and prior are saved as ASCII files with the encoding set by the header variable $DWGCODEPAGE, which is ANSI_1252 by default if $DWGCODEPAGE is not set.
Characters used in the drawing which do not exist in the chosen ASCII encoding are encoded as unicode characters with the schema \U+nnnn. see Unicode table
DXF | Python | Name |
ANSI_874 | cp874 | Thai |
ANSI_932 | cp932 | Japanese |
ANSI_936 | gbk | UnifiedChinese |
ANSI_949 | cp949 | Korean |
ANSI_950 | cp950 | TradChinese |
ANSI_1250 | cp1250 | CentralEurope |
ANSI_1251 | cp1251 | Cyrillic |
ANSI_1252 | cp1252 | WesternEurope |
ANSI_1253 | cp1253 | Greek |
ANSI_1254 | cp1254 | Turkish |
ANSI_1255 | cp1255 | Hebrew |
ANSI_1256 | cp1256 | Arabic |
ANSI_1257 | cp1257 | Baltic |
ANSI_1258 | cp1258 | Vietnam |
Starting with DXF R2007 (AC1021) the drawing file is UTF-8 encoded, the header variable $DWGCODEPAGE is still in use, but I don’t know, if the setting still has any meaning.
Encoding characters in the unicode schema \U+nnnn is still functional.
SEE ALSO:
A Drawing Interchange File is simply an ASCII text file with a file type of .dxf and special formatted text. The basic file structure are DXF tags, a DXF tag consist of a DXF group code as an integer value on its own line and a the DXF value on the following line. In the ezdxf documentation DXF tags will be written as (group code, value).
Group codes are indicating the value type:
Group Code | Value Type |
0-9 | String (with the introduction of extended symbol names in DXF R2000, the 255-character limit has been increased to 2049 single-byte characters not including the newline at the end of the line) |
10-39 | Double precision 3D point value |
40-59 | Double-precision floating-point value |
40-59 | Double-precision floating-point value |
60-79 | 16-bit integer value |
90-99 | 32-bit integer value |
100 | String (255-character maximum, less for Unicode strings) |
102 | String (255-character maximum, less for Unicode strings) |
105 | String representing hexadecimal (hex) handle value |
110-119 | Double precision floating-point value |
120-129 | Double precision floating-point value |
130-139 | Double precision floating-point value |
140-149 | Double precision scalar floating-point value |
160-169 | 64-bit integer value |
170-179 | 16-bit integer value |
210-239 | Double-precision floating-point value |
270-279 | 16-bit integer value |
280-289 | 16-bit integer value |
290-299 | Boolean flag value |
300-309 | Arbitrary text string |
310-319 | String representing hex value of binary chunk |
320-329 | String representing hex handle value |
330-369 | String representing hex object IDs |
370-379 | 16-bit integer value |
380-389 | 16-bit integer value |
390-399 | String representing hex handle value |
400-409 | 16-bit integer value |
410-419 | String |
420-429 | 32-bit integer value |
430-439 | String |
440-449 | 32-bit integer value |
450-459 | Long |
460-469 | Double-precision floating-point value |
470-479 | String |
480-481 | String representing hex handle value |
999 | Comment (string) |
1000-1009 | String (same limits as indicated with 0-9 code range) |
1010-1059 | Double-precision floating-point value |
1060-1070 | 16-bit integer value |
1071 | 32-bit integer value |
Explanation for some important group codes:
Group Code | Meaning |
0 | DXF structure tag, entity start/end or table entries |
1 | The primary text value for an entity |
2 | A name: Attribute tag, Block name, and so on. Also used to identify a DXF section or table name. |
3-4 | Other textual or name values |
5 | Entity handle as hex string (fixed) |
6 | Line type name (fixed) |
7 | Text style name (fixed) |
8 | Layer name (fixed) |
9 | Variable name identifier (used only in HEADER section of the DXF file) |
10 | Primary X coordinate (start point of a Line or Text entity, center of a Circle, etc.) |
11-18 | Other X coordinates |
20 | Primary Y coordinate. 2n values always correspond to 1n values and immediately follow them in the file (expected by ezdxf!) |
21-28 | Other Y coordinates |
30 | Primary Z coordinate. 3n values always correspond to 1n and 2n values and immediately follow them in the file (expected by ezdxf!) |
31-38 | Other Z coordinates |
39 | This entity’s thickness if nonzero (fixed) |
40-48 | Float values (text height, scale factors, etc.) |
49 | Repeated value - multiple 49 groups may appear in one entity for variable length tables (such as the dash lengths in the LTYPE table). A 7x group always appears before the first 49 group to specify the table length |
50-58 | Angles in degree |
62 | Color number (fixed) |
66 | “Entities follow” flag (fixed), only in INSERT and POLYLINE entities |
67 | Identifies whether entity is in modelspace (0) or paperspace (1) |
68 | Identifies whether viewport is on but fully off screen, is not active, or is off |
69 | Viewport identification number |
70-78 | Integer values such as repeat counts, flag bits, or modes |
210, 220, 230 | X, Y, and Z components of extrusion direction (fixed) |
310 | Proxy entity graphics as binary encoded data |
330 | Owner handle as hex string |
347 | MATERIAL handle as hex string |
348 | VISUALSTYLE handle as hex string |
370 | Lineweight in mm times 100 (e.g. 0.13mm = 13). |
390 | PLOTSTYLE handle as hex string |
420 | True color value as 0x00RRGGBB 24-bit value |
430 | Color name as string |
440 | Transparency value 0x020000TT 0 = fully transparent / 255 = opaque |
999 | Comments |
For explanation of all group codes see: DXF Group Codes in Numerical Order Reference provided by Autodesk
Extended data (XDATA) is created by AutoLISP or ObjectARX applications but any other application like ezdxf can also define XDATA. If an entity contains extended data, it follows the entity’s normal definition data but ends before Embedded Objects.
But extended group codes (>=1000) can appear before the XDATA section, an example is the BLOCKBASEPOINTPARAMETER entity in AutoCAD Civil 3D or AutoCAD Map 3D.
Group Code | Description |
1000 | Strings in extended data can be up to 255 bytes long (with the 256th byte reserved for the null character) |
1001 | (fixed) Registered application name (ASCII string up to 31 bytes long) for XDATA |
1002 | (fixed) An extended data control string can be either '{' or '}'. These braces enable applications to organize their data by subdividing the data into lists. Lists can be nested. |
1003 | Name of the layer associated with the extended data |
1004 | Binary data is organized into variable-length chunks. The maximum length of each chunk is 127 bytes. In ASCII DXF files, binary data is represented as a string of hexadecimal digits, two per binary byte |
1005 | Database Handle of entities in the drawing database, see also: About 1005 Group Codes |
1010, 1020, 1030 | Three real values, in the order X, Y, Z. They can be used as a point or vector record. |
1011, 1021, 1031 | Unlike a simple 3D point, the world space coordinates are moved, scaled, rotated, mirrored, and stretched along with the parent entity to which the extended data belongs. |
1012, 1012, 1022 | Also a 3D point that is scaled, rotated, and mirrored along with the parent (but is not moved or stretched) |
1013, 1023, 1033 | Also a 3D point that is scaled, rotated, and mirrored along with the parent (but is not moved or stretched) |
1040 | A real value |
1041 | Distance, a real value that is scaled along with the parent entity |
1042 | Scale Factor, also a real value that is scaled along with the parent. The difference between a distance and a scale factor is application-defined |
1070 | A 16-bit integer (signed or unsigned) |
1071 | A 32-bit signed (long) integer |
The (1001, ...) tag indicates the beginning of extended data. In contrast to normal entity data, with extended data the same group code can appear multiple times, and order is important.
Extended data is grouped by registered application name. Each registered application group begins with a (1001, APPID) tag, with the application name as APPID string value. Registered application names correspond to APPID symbol table entries.
An application can use as many APPID names as needed. APPID names are permanent, although they can be purged if they aren’t currently used in the drawing. Each APPID name can have no more than one data group attached to each entity. Within an application group, the sequence of extended data groups and their meaning is defined by the application.
String values stored in a DXF file is plain ASCII or UTF-8, AutoCAD also supports CIF (Common Interchange Format) and MIF (Maker Interchange Format) encoding. The UTF-8 format is only supported in DXF R2007 and later.
ezdxf on import converts all strings into Python unicode strings without encoding or decoding CIF/MIF.
String values containing Unicode characters are represented with control character sequences \U+nnnn. (e.g. r'TEST\U+7F3A\U+4E4F\U+89E3\U+91CA\U+6B63THIS\U+56FE')
To support the DXF unicode encoding ezdxf registers an encoding codec dxf_backslash_replace, defined in ezdxf.lldxf.encoding().
String values can be stored with these dxf group codes:
If the text string is less than 250 characters, all characters appear in tag (1, ...). If the text string is longer than 250 characters, the string is divided into 250-character chunks, which appear in one or more (3, ...) tags. If (3, ...) tags are used, the last group is a (1, ...) tag and has fewer than 250 characters:
3 ... TwoHundredAndFifty Characters .... 3 ... TwoHundredAndFifty Characters .... 1 less than TwoHundredAndFifty Characters
As far I know this is only supported by the MTEXT entity.
SEE ALSO:
With the introduction of DXF R13 Autodesk added additional group codes and DXF tag structures to the DXF Standard.
Subclass markers (100, Subclass Name) divides DXF objects into several sections. Group codes can be reused in different sections. A subclass ends with the following subclass marker or at the beginning of xdata or the end of the object. See Subclass Marker Example in the DXF Reference.
Do not write programs that rely on the order given here. The end of an entity is indicated by the next 0 group, which begins the next entity or indicates the end of the section.
Note: Accommodating DXF files from future releases of AutoCAD will be easier if you write your DXF processing program in a table-driven way, ignore undefined group codes, and make no assumptions about the order of group codes in an entity. With each new AutoCAD release, new group codes will be added to entities to accommodate additional features.
Some later entities entities contains the same group code twice for different purposes, so order in the sense of which one comes first is important. (e.g. ATTDEF group code 280)
In LWPOLYLINE the order of tags is important, if the count tag is not the first tag in the AcDbPolyline subclass, AutoCAD will not close the polyline when the close flag is set, by the way other applications like BricsCAD ignores the tag order and renders the polyline always correct.
The extension dictionary is an optional sequence that stores the handle of a DICTIONARY object that belongs to the current object, which in turn may contain entries. This facility allows attachment of arbitrary database objects to any database object. Any object or entity may have this section.
The extension dictionary tag sequence:
102 {ACAD_XDICTIONARY 360 Hard-owner ID/handle to owner dictionary 102 }
Persistent reactors are an optional sequence that stores object handles of objects registering themselves as reactors on the current object. Any object or entity may have this section.
The persistent reactors tag sequence:
102 {ACAD_REACTORS 330 first Soft-pointer ID/handle to owner dictionary 330 second Soft-pointer ID/handle to owner dictionary ... 102 }
Starting at DXF R13, DXF objects can contain application-defined codes outside of XDATA. This application-defined codes can contain any tag except (0, ...) and (102, '{...'). “{YOURAPPID” means the APPID string with an preceding “{“. The application defined data tag sequence:
102 {YOURAPPID ... 102 }
(102, 'YOURAPPID}') is also a valid closing tag:
102 {YOURAPPID ... 102 YOURAPPID}
All groups defined with a beginning (102, ...) appear in the DXF reference before the first subclass marker, I don’t know if these groups can appear after the first or any subclass marker. ezdxf accepts them at any position, and by default ezdxf adds new app data in front of the first subclass marker to the first tag section of an DXF object.
Exception XRECORD: Tags with group code 102 and a value string without a preceding “{” or the scheme “YOURAPPID}”, should be treated as usual group codes.
The concept of embedded objects was introduced with AutoCAD 2018 (DXF version AC1032) and this is the only information I found about it at the Autodesk knowledge base: Embedded and Encapsulated Objects
Quote from Embedded and Encapsulated Objects:
A separator is needed between the encapsulating object’s data and the subsequent embedded object’s data. The separator must be similar in function to the group 0 or 100 in that it must cause the filer to stop reading data. The normal DXF group code 0 cannot be used because DXF proxies use it to determine when to stop reading data. The group code 100 could have been used, but it might have caused confusion when manually reading a DXF file, and there was a need to distinguish when an embedded object is about to be written out in order to do some internal bookkeeping. Therefore, the DXF group code 101 was introduced.
Hard facts:
Unconfirmed assumptions:
Real world example from an AutoCAD 2018 file:
100 <<< start of encapsulating object AcDbMText 10 2762.148 20 2327.073 30 0.0 40 2.5 41 18.852 46 0.0 71 1 72 5 1 {\fArial|b0|i0|c162|p34;CHANGE;\P\P\PTEXT} 73 1 44 1.0 101 <<< start of embedded object Embedded Object 70 1 10 1.0 20 0.0 30 0.0 11 2762.148 21 2327.073 31 0.0 40 18.852 41 0.0 42 15.428 43 15.043 71 2 72 1 44 18.852 45 12.5 73 0 74 0 46 0.0
A handle is an arbitrary but in your DXF file unique hex value as string like ‘10FF’. It is common to to use uppercase letters for hex numbers. Handle can have up to 16 hexadecimal digits (8 bytes).
For DXF R10 until R12 the usage of handles was optional. The header variable $HANDLING set to 1 indicate the usage of handles, else $HANDLING is 0 or missing.
For DXF R13 and later the usage of handles is mandatory and the header variable $HANDLING was removed.
The $HANDSEED variable in the header section should be greater than the biggest handle used in the DXF file, so a CAD application can assign handle values starting with the $HANDSEED value. But as always, don’t rely on the header variable it could be wrong, AutoCAD ignores this value.
Entity handle definition is always the (5, ...), except for entities of the DIMSTYLE table (105, ...), because the DIMSTYLE entity has also a group code 5 tag for DIMBLK.
A pointer is a reference to a DXF object in the same DXF file. There are four types of pointers:
Also, a group code range for “arbitrary” handles is defined to allow convenient storage of handle values that are unchanged at any operation (AutoCAD).
A pointer is a reference that indicates usage, but not possession or responsibility, for another object. A pointer reference means that the object uses the other object in some way, and shares access to it. An ownership reference means that an owner object is responsible for the objects for which it has an owner handle. An object can have any number of pointer references associated with it, but it can have only one owner.
Hard references, whether they are pointer or owner, protect an object from being purged. Soft references do not.
In AutoCAD, block definitions and complex entities are hard owners of their elements. A symbol table and dictionaries are soft owners of their elements. Polyline entities are hard owners of their vertex and seqend entities. Insert entities are hard owners of their attrib and seqend entities.
When establishing a reference to another object, it is recommended that you think about whether the reference should protect an object from the PURGE command.
Arbitrary handles are distinct in that they are not translated to session-persistent identifiers internally, or to entity names in AutoLISP, and so on. They are stored as handles. When handle values are translated in drawing-merge operations, arbitrary handles are ignored.
In all environments, arbitrary handles can be exchanged for entity names of the current drawing by means of the handent functions. A common usage of arbitrary handles is to refer to objects in external DXF and DWG files.
(1005, ...) xdata have the same behavior and semantics as soft pointers, which means that they are translated whenever the host object is merged into a different drawing. However, 1005 items are not translated to session-persistent identifiers or internal entity names in AutoLISP and ObjectARX. They are stored as handles.
A DXF File is simply an ASCII text file with a file type of .dxf and special formatted text. The basic file structure are DXF tags, a DXF tag consist of a DXF group code as an integer value on its own line and a the DXF value on the following line. In the ezdxf documentation DXF tags will be written as (group code, value). There exist a binary DXF format, but it seems that it is not often used and for reducing file size, zipping is much more efficient. ezdxf does support reading binary encoded DXF files.
SEE ALSO:
A usual DXF file is organized in sections, starting with the DXF tag (0, ‘SECTION’) and ending with the DXF tag (0, ‘ENDSEC’). The (0, ‘EOF’) tag signals the end of file.
For further information read the original DXF Reference.
Structure of a usual DXF R12 file:
0 <<< Begin HEADER section, has to be the first section SECTION 2 HEADER
<<< Header variable items go here 0 <<< End HEADER section ENDSEC 0 <<< Begin TABLES section SECTION 2 TABLES 0 TABLE 2 VPORT 70 <<< viewport table maximum item count
<<< viewport table items go here 0 ENDTAB 0 TABLE 2 APPID, DIMSTYLE, LTYPE, LAYER, STYLE, UCS, VIEW, or VPORT 70 <<< Table maximum item count, a not reliable value and ignored by AutoCAD
<<< Table items go here 0 ENDTAB 0 <<< End TABLES section ENDSEC 0 <<< Begin BLOCKS section SECTION 2 BLOCKS
<<< Block definition entities go here 0 <<< End BLOCKS section ENDSEC 0 <<< Begin ENTITIES section SECTION 2 ENTITIES
<<< Drawing entities go here 0 <<< End ENTITIES section ENDSEC 0 <<< End of file marker (required) EOF
Contrary to the previous chapter, the DXF R12 format (AC1009) and prior requires just the ENTITIES section:
0 SECTION 2 ENTITIES 0 ENDSEC 0 EOF
DXF version R13/14 and later needs much more DXF content than DXF R12.
Required sections: HEADER, CLASSES, TABLES, ENTITIES, OBJECTS
The HEADER section requires two entries:
The CLASSES section can be empty, but some DXF entities requires class definitions to work in AutoCAD.
The TABLES section requires following tables:
The BLOCKS section requires two BLOCKS:
The ENTITIES section can be empty.
The OBJECTS section requires following entities:
Minimal DXF to download: https://bitbucket.org/mozman/ezdxf/downloads/Minimal_DXF_AC1021.dxf
(from the DXF Reference)
AutoCAD drawings consist largely of structured containers for database objects. Database objects each have the following features:
Symbol tables and symbol table records are database objects and, thus, have a handle. They can also have xdata and persistent reactors in their DXF records.
The DXF R12 data model is identical to the file structure:
References are realized by simple names. The INSERT entity references the BLOCK definition by the BLOCK name, a TEXT entity defines the associated STYLE and LAYER by its name and so on, handles are not needed. Layout association of graphical entities in the ENTITIES section by the paper_space tag (67, 0 or 1), 0 or missing tag means model space, 1 means paperspace. The content of BLOCK definitions is enclosed by the BLOCK and the ENDBLK entity, no additional references are needed.
A clean and simple file structure and data model, which seems to be the reason why the DXF R12 Reference (released 1992) is still a widely used file format and Autodesk/AutoCAD supports the format by reading and writing DXF R12 files until today (DXF R13/R14 has no writing support by AutoCAD!).
TODO: list of available entities
SEE ALSO:
With the DXF R13 file format, handles are mandatory and they are really used for organizing the new data structures introduced with DXF R13.
The HEADER section is still the same with just more available settings.
The new CLASSES section contains AutoCAD specific data, has to be written like AutoCAD it does, but must not be understood.
The TABLES section got a new BLOCK_RECORD table - see Block Management Structures for more information.
The BLOCKS sections is mostly the same, but with handles, owner tags and new ENTITY types. Not active paperspace layouts store their content also in the BLOCKS section - see Layout Management Structures for more information.
The ENTITIES section is also mostly same, but with handles, owner tags and new ENTITY types.
TODO: list of new available entities
And the new OBJECTS section - now its getting complicated!
Most information about the OBJECTS section is just guessed or gathered by trail and error, because the documentation of the OBJECTS section and its objects in the DXF reference provided by Autodesk is very shallow. This is also the reason why I started the DXF Internals section, may be it helps other developers to start one or two steps above level zero.
The OBJECTS sections stores all the non-graphical entities of the DXF drawing. Non-graphical entities from now on just called ‘DXF objects’ to differentiate them from graphical entities, just called ‘entities’. The OBJECTS section follows commonly the ENTITIES section, but this is not mandatory.
DXF R13 introduces several new DXF objects, which resides exclusive in the OBJECTS section, taken from the DXF R14 reference, because I have no access to the DXF R13 reference, the DXF R13 reference is a compiled .hlp file which can’t be read on Windows 10, a drastic real world example why it is better to avoid closed (proprietary) data formats ;):
Still missing the LAYOUT object, which is mandatory in DXF R2000 to manage multiple paperspace layouts. I don’t know how DXF R13/R14 manages multiple layouts or if they even support this feature, but I don’t care much about DXF R13/R14, because AutoCAD has no write support for this two formats anymore. ezdxf tries to upgrade this two DXF versions to DXF R2000 with the advantage of only two different data models to support: DXF R12 and DXF R2000+
New objects introduced by DXF R2000:
New objects in DXF R2004:
New objects in DXF R2007:
New objects in DXF R2013:
New objects in DXF R2018:
Undocumented objects:
Many objects in the OBJECTS section are organized in a tree-like structure of DICTIONARY objects. Starting point for this data structure is the ‘root’ DICTIONARY with several entries to other DICTIONARY objects. The root DICTIONARY has to be the first object in the OBJECTS section. The management dicts for GROUP and LAYOUT objects are really important, but IMHO most of the other management tables are optional and for the most use cases not necessary. The ezdxf template for DXF R2018 contains only these entries in the root dict and most of them pointing to an empty DICTIONARY:
0 SECTION 2 <<< start of the OBJECTS section OBJECTS 0 <<< root DICTIONARY has to be the first object in the OBJECTS section DICTIONARY 5 <<< handle C 330 <<< owner tag 0 <<< always #0, has no owner 100 AcDbDictionary 281 <<< hard owner flag 1 3 <<< first entry ACAD_CIP_PREVIOUS_PRODUCT_INFO 350 <<< handle to target (pointer) 78B <<< points to a XRECORD with product info about the creator application 3 <<< entry with unknown meaning, if I shoul guess: something with about colors ... ACAD_COLOR 350 4FB <<< points to a DICTIONARY 3 <<< entry with unknown meaning ACAD_DETAILVIEWSTYLE 350 7ED <<< points to a DICTIONARY 3 <<< GROUP management, mandatory in all DXF versions ACAD_GROUP 350 4FC <<< points to a DICTIONARY 3 <<< LAYOUT management, mandatory if more than the *active* paperspace is used ACAD_LAYOUT 350 4FD <<< points to a DICTIONARY 3 <<< MATERIAL management ACAD_MATERIAL 350 4FE <<< points to a DICTIONARY 3 <<< MLEADERSTYLE management ACAD_MLEADERSTYLE 350 4FF <<< points to a DICTIONARY 3 <<< MLINESTYLE management ACAD_MLINESTYLE 350 500 <<< points to a DICTIONARY 3 <<< PLOTSETTINGS management ACAD_PLOTSETTINGS 350 501 <<< points to a DICTIONARY 3 <<< plot style name management ACAD_PLOTSTYLENAME 350 503 <<< points to a ACDBDICTIONARYWDFLT 3 <<< SCALE management ACAD_SCALELIST 350 504 <<< points to a DICTIONARY 3 <<< entry with unknown meaning ACAD_SECTIONVIEWSTYLE 350 7EB <<< points to a DICTIONARY 3 <<< TABLESTYLE management ACAD_TABLESTYLE 350 505 <<< points to a DICTIONARY 3 <<< VISUALSTYLE management ACAD_VISUALSTYLE 350 506 <<< points to a DICTIONARY 3 <<< entry with unknown meaning ACDB_RECOMPOSE_DATA 350 7F3 3 <<< entry with unknown meaning AcDbVariableDictionary 350 7AE <<< points to a DICTIONARY with handles to DICTIONARYVAR objects 0 DICTIONARY ... ... 0 ENDSEC
In DXF R12 and prior the HEADER section was optional, but since DXF R13 the HEADER section is mandatory. The overall structure is:
0 <<< Begin HEADER section SECTION 2 HEADER 9 $ACADVER <<< Header variable items go here 1 AC1009 ... 0 ENDSEC <<< End HEADER section
A header variable has a name defined by a (9, Name) tag and following value tags.
SEE ALSO:
DXF Reference: Header Variables
The CLASSES section contains CLASS definitions which are only important for Autodesk products, some DXF entities require a class definition or AutoCAD will not open the DXF file.
The CLASSES sections was introduced with DXF AC1015 (AutoCAD Release R13).
SEE ALSO:
Documentation of ezdxf ClassesSection class.
The CLASSES section in DXF files holds the information for application-defined classes whose instances appear in the BLOCKS, ENTITIES, and OBJECTS sections of the database. It is assumed that a class definition is permanently fixed in the class hierarchy. All fields are required.
Update 2019-03-03:
Class names are not unique, Autodesk Architectural Desktop 2007 uses the same name, but with different CPP class names in the CLASS section, so storing classes in a dictionary by name as key caused loss of class entries in ezdxf, using a tuple of (name, cpp_class_name) as storage key solved the problem.
SEE ALSO:
CLASS entities have no handle and therefore ezdxf does not store the CLASS entity in the drawing entities database!
0 SECTION 2 <<< begin CLASSES section CLASSES 0 <<< first CLASS entity CLASS 1 <<< class DXF entity name; THIS ENTRY IS MAYBE NOT UNIQUE ACDBDICTIONARYWDFLT 2 <<< C++ class name; always unique AcDbDictionaryWithDefault 3 <<< application name ObjectDBX Classes 90 <<< proxy capabilities flags 0 91 <<< instance counter for custom class, since DXF version AC1018 (R2004) 0 <<< no problem if the counter is wrong, AutoCAD doesn't care about 280 <<< was-a-proxy flag. Set to 1 if class was not loaded when this DXF file was created, and 0 otherwise 0 281 <<< is-an-entity flag. Set to 1 if class reside in the BLOCKS or ENTITIES section. If 0, instances may appear only in the OBJECTS section 0 0 <<< second CLASS entity CLASS ... ... 0 <<< end of CLASSES section ENDSEC
TODO
The BLOCKS section contains all BLOCK definitions, beside the normal reusable BLOCKS used by the INSERT entity, all layouts, as there are the modelspace and all paperspace layouts, have at least a corresponding BLOCK definition in the BLOCKS section. The name of the modelspace BLOCK is “*Model_Space” (DXF R12: “$MODEL_SPACE”) and the name of the active paperspace BLOCK is “*Paper_Space” (DXF R12: “$PAPER_SPACE”), the entities of these two layouts are stored in the ENTITIES section, the inactive paperspace layouts are named by the scheme “*Paper_Spacennnn”, and the content of the inactive paperspace layouts are stored in their BLOCK definition in the BLOCKS section.
The content entities of blocks are stored between the BLOCK and the ENDBLK entity.
BLOCKS section structure:
0 <<< start of a SECTION SECTION 2 <<< start of BLOCKS section BLOCKS 0 <<< start of 1. BLOCK definition BLOCK ... <<< Block content ... 0 <<< end of 1. Block definition ENDBLK 0 <<< start of 2. BLOCK definition BLOCK ... <<< Block content ... 0 <<< end of 2. Block definition ENDBLK 0 <<< end of BLOCKS section ENDSEC
SEE ALSO:
TODO
Objects in the OBJECTS section are organized in a hierarchical tree order, starting with the named objects dictionary as the first entity in the OBJECTS section (Drawing.rootdict).
Not all entities in the OBJECTS section are included in this tree, extension_dict_internals and XRECORD data of graphical entities are also stored in the OBJECTS section.
The VIEW entry stores a named view of the model or a paperspace layout. This stored views makes parts of the drawing or some view points of the model in a CAD applications more accessible. This views have no influence to the drawing content or to the generated output by exporting PDFs or plotting on paper sheets, they are just for the convenience of CAD application users.
Using ezdxf you have access to the views table by the attribute Drawing.views. The views table itself is not stored in the entity database, but the table entries are stored in entity database, and can be accessed by its handle.
0 VIEW 2 <<< name of view VIEWNAME 70 <<< flags bit-coded: 1st bit -> (0/1 = modelspace/paperspace) 0 <<< modelspace 40 <<< view width in Display Coordinate System (DCS) 20.01 10 <<< view center point in DCS 40.36 <<< x value 20 <<< group code for y value 15.86 <<< y value 41 <<< view height in DCS 17.91 11 <<< view direction from target point, 3D vector 0.0 <<< x value 21 <<< group code for y value 0.0 <<< y value 31 <<< group code for z value 1.0 <<< z value 12 <<< target point in WCS 0.0 <<< x value 22 <<< group code for y value 0.0 <<< y value 32 <<< group code for z value 0.0 <<< z value 42 <<< lens (focal) length 50.0 <<< 50mm 43 <<< front clipping plane, offset from target 0.0 44 <<< back clipping plane, offset from target 0.0 50 <<< twist angle 0.0 71 <<< view mode 0
SEE ALSO:
Mostly the same structure as DXF R12, but with handle, owner tag and subclass markers.
0 <<< adding the VIEW table head, just for information TABLE 2 <<< table name VIEW 5 <<< handle of table, see owner tag of VIEW table entry 37C 330 <<< owner tag of table, always #0 0 100 <<< subclass marker AcDbSymbolTable 70 <<< VIEW table (max.) count, not reliable (ignore) 9 0 <<< first VIEW table entry VIEW 5 <<< handle 3EA 330 <<< owner, the VIEW table is the owner of the VIEW entry 37C <<< handle of the VIEW table 100 <<< subclass marker AcDbSymbolTableRecord 100 <<< subclass marker AcDbViewTableRecord 2 <<< view name, from here all the same as DXF R12 VIEWNAME 70 0 40 20.01 10 40.36 20 15.86 41 17.91 11 0.0 21 0.0 31 1.0 12 0.0 22 0.0 32 0.0 42 50.0 43 0.0 44 0.0 50 0.0 71 0 281 <<< render mode 0-6 (... too much options) 0 <<< 0= 2D optimized (classic 2D) 72 <<< UCS associated (0/1 = no/yes) 0 <<< 0 = no
DXF R2000+ supports additional features in the VIEW entry, see the VIEW table reference provided by Autodesk.
The VPORT table stores the modelspace viewport configurations. A viewport configuration is a tiled view of multiple viewports or just one viewport. [image]
In contrast to other tables the VPORT table can have multiple entries with the same name, because all VPORT entries of a multi-viewport configuration are having the same name - the viewport configuration name. The name of the actual displayed viewport configuration is '*ACTIVE', as always table entry names are case insensitive ('*ACTIVE' == '*Active').
The available display area in AutoCAD has normalized coordinates, the lower-left corner is (0, 0) and the upper-right corner is (1, 1) regardless of the true aspect ratio and available display area in pixels. A single viewport configuration has one VPORT entry '*ACTIVE' with the lower-left corner (0, 0) and the upper-right corner (1, 1).
The following statements refer to a 2D plan view: the view-target-point defines the origin of the DCS (Display Coordinate system), the view-direction vector defines the z-axis of the DCS, the view-center-point (in DCS) defines the point in modelspace translated to the center point of the viewport, the view height and the aspect-ratio defines how much of the modelspace is displayed. AutoCAD tries to fit the modelspace area into the available viewport space e.g. view height is 15 units and aspect-ratio is 2.0 the modelspace to display is 30 units wide and 15 units high, if the viewport has an aspect ratio of 1.0, AutoCAD displays 30x30 units of the modelspace in the viewport. If the modelspace aspect-ratio is 1.0 the modelspace to display is 15x15 units and fits properly into the viewport area.
But tests show that the translation of the view-center-point to the middle of the viewport not always work as I expected. (still digging…)
NOTE:
Multi-viewport configuration with three viewports.
0 <<< table start TABLE 2 <<< table type VPORT 70 <<< VPORT table (max.) count, not reliable (ignore) 3 0 <<< first VPORT entry VPORT 2 <<< VPORT (configuration) name *ACTIVE 70 <<< standard flags, bit-coded 0 10 <<< lower-left corner of viewport 0.45 <<< x value, virtual coordinates in range [0 - 1] 20 <<< group code for y value 0.0 <<< y value, virtual coordinates in range [0 - 1] 11 <<< upper-right corner of viewport 1.0 <<< x value, virtual coordinates in range [0 - 1] 21 <<< group code for y value 1.0 <<< y value, virtual coordinates in range [0 - 1] 12 <<< view center point (in DCS), ??? 13.71 <<< x value 22 <<< group code for y value 0.02 <<< y value 13 <<< snap base point (in DCS) 0.0 <<< x value 23 <<< group code for y value 0.0 <<< y value 14 <<< snap spacing X and Y 1.0 <<< x value 24 <<< group code for y value 1.0 <<< y value 15 <<< grid spacing X and Y 0.0 <<< x value 25 <<< group code for y value 0.0 <<< y value 16 <<< view direction from target point (in WCS), defines the z-axis of the DCS 1.0 <<< x value 26 <<< group code for y value -1.0 <<< y value 36 <<< group code for z value 1.0 <<< z value 17 <<< view target point (in WCS), defines the origin of the DCS 0.0 <<< x value 27 <<< group code for y value 0.0 <<< y value 37 <<< group code for z value 0.0 <<< z value 40 <<< view height 35.22 41 <<< viewport aspect ratio 0.99 42 <<< lens (focal) length 50.0 <<< 50mm 43 <<< front clipping planes, offsets from target point 0.0 44 <<< back clipping planes, offsets from target point 0.0 50 <<< snap rotation angle 0.0 51 <<< view twist angle 0.0 71 <<< view mode 0 72 <<< circle zoom percent 1000 73 <<< fast zoom setting 1 74 <<< UCSICON setting 3 75 <<< snap on/off 0 76 <<< grid on/off 0 77 <<< snap style 0 78 <<< snap isopair 0 0 <<< next VPORT entry VPORT 2 <<< VPORT (configuration) name *ACTIVE <<< same as first VPORT entry 70 0 10 0.0 20 0.5 11 0.45 21 1.0 12 8.21 22 9.41 ... ... 0 <<< next VPORT entry VPORT 2 <<< VPORT (configuration) name *ACTIVE <<< same as first VPORT entry 70 0 10 0.0 20 0.0 11 0.45 21 0.5 12 2.01 22 -9.33 ... ... 0 ENDTAB
Mostly the same structure as DXF R12, but with handle, owner tag and subclass markers.
0 <<< table start TABLE 2 <<< table type VPORT 5 <<< table handle 151F 330 <<< owner, table has no owner - always #0 0 100 <<< subclass marker AcDbSymbolTable 70 <<< VPORT table (max.) count, not reliable (ignore) 3 0 <<< first VPORT entry VPORT 5 <<< entry handle 158B 330 <<< owner, VPORT table is owner of VPORT entry 151F 100 <<< subclass marker AcDbSymbolTableRecord 100 <<< subclass marker AcDbViewportTableRecord 2 <<< VPORT (configuration) name *ACTIVE 70 <<< standard flags, bit-coded 0 10 <<< lower-left corner of viewport 0.45 <<< x value, virtual coordinates in range [0 - 1] 20 <<< group code for y value 0.0 <<< y value, virtual coordinates in range [0 - 1] 11 <<< upper-right corner of viewport 1.0 <<< x value, virtual coordinates in range [0 - 1] 21 <<< group code for y value 1.0 <<< y value, virtual coordinates in range [0 - 1] 12 <<< view center point (in DCS) 13.71 <<< x value 22 <<< group code for y value 0.38 <<< y value 13 <<< snap base point (in DCS) 0.0 <<< x value 23 <<< group code for y value 0.0 <<< y value 14 <<< snap spacing X and Y 1.0 <<< x value 24 <<< group code for y value 1.0 <<< y value 15 <<< grid spacing X and Y 0.0 <<< x value 25 <<< group code for y value 0.0 <<< y value 16 <<< view direction from target point (in WCS) 1.0 <<< x value 26 <<< group code for y value -1.0 <<< y value 36 <<< group code for z value 1.0 <<< z value 17 <<< view target point (in WCS) 0.0 <<< x value 27 <<< group code for y value 0.0 <<< y value 37 <<< group code for z value 0.0 <<< z value 40 <<< view height 35.22 41 <<< viewport aspect ratio 0.99 42 <<< lens (focal) length 50.0 <<< 50mm 43 <<< front clipping planes, offsets from target point 0.0 44 <<< back clipping planes, offsets from target point 0.0 50 <<< snap rotation angle 0.0 51 <<< view twist angle 0.0 71 <<< view mode 0 72 <<< circle zoom percent 1000 73 <<< fast zoom setting 1 74 <<< UCSICON setting 3 75 <<< snap on/off 0 76 <<< grid on/off 0 77 <<< snap style 0 78 <<< snap isopair 0 281 <<< render mode 1-6 (... too many options) 0 <<< 0 = 2D optimized (classic 2D) 65 <<< Value of UCSVP for this viewport. (0 = UCS will not change when this viewport is activated) 1 <<< 1 = then viewport stores its own UCS which will become the current UCS whenever the viewport is activated. 110 <<< UCS origin (3D point) 0.0 <<< x value 120 <<< group code for y value 0.0 <<< y value 130 <<< group code for z value 0.0 <<< z value 111 <<< UCS X-axis (3D vector) 1.0 <<< x value 121 <<< group code for y value 0.0 <<< y value 131 <<< group code for z value 0.0 <<< z value 112 <<< UCS Y-axis (3D vector) 0.0 <<< x value 122 <<< group code for y value 1.0 <<< y value 132 <<< group code for z value 0.0 <<< z value 79 <<< Orthographic type of UCS 0-6 (... too many options) 0 <<< 0 = UCS is not orthographic 146 <<< elevation 0.0 1001 <<< extended data - undocumented ACAD_NAV_VCDISPLAY 1070 3 0 <<< next VPORT entry VPORT 5 158C 330 151F 100 AcDbSymbolTableRecord 100 AcDbViewportTableRecord 2 <<< VPORT (configuration) name *ACTIVE <<< same as first VPORT entry 70 0 10 0.0 20 0.5 11 0.45 21 1.0 12 8.21 22 9.72 ... ... 0 <<< next VPORT entry VPORT 5 158D 330 151F 100 AcDbSymbolTableRecord 100 AcDbViewportTableRecord 2 <<< VPORT (configuration) name *ACTIVE <<< same as first VPORT entry 70 0 10 0.0 20 0.0 11 0.45 21 0.5 12 2.01 22 -8.97 ... ... 0 ENDTAB
The LTYPE table stores all line type definitions of a DXF drawing. Every line type used in the drawing has to have a table entry, or the DXF drawing is invalid for AutoCAD.
DXF R12 supports just simple line types, DXF R2000+ supports also complex line types with text or shapes included.
You have access to the line types table by the attribute Drawing.linetypes. The line type table itself is not stored in the entity database, but the table entries are stored in entity database, and can be accessed by its handle.
SEE ALSO:
0 <<< start of table TABLE 2 <<< set table type LTYPE 70 <<< count of line types defined in this table, AutoCAD ignores this value 9 0 <<< 1. LTYPE table entry LTYPE
<<< LTYPE data tags 0 <<< 2. LTYPE table entry LTYPE
<<< LTYPE data tags and so on 0 <<< end of LTYPE table ENDTAB
0 <<< start of table TABLE 2 <<< set table type LTYPE 5 <<< LTYPE table handle 5F 330 <<< owner tag, tables has no owner 0 100 <<< subclass marker AcDbSymbolTable 70 <<< count of line types defined in this table, AutoCAD ignores this value 9 0 <<< 1. LTYPE table entry LTYPE
<<< LTYPE data tags 0 <<< 2. LTYPE table entry LTYPE
<<< LTYPE data tags and so on 0 <<< end of LTYPE table ENDTAB
ezdxf setup for line type ‘CENTER’:
dwg.linetypes.new("CENTER", dxfattribs={
description = "Center ____ _ ____ _ ____ _ ____ _ ____ _ ____",
pattern=[2.0, 1.25, -0.25, 0.25, -0.25],
})
0 <<< line type table entry LTYPE 5 <<< handle of line type 1B1 330 <<< owner handle, handle of LTYPE table 5F 100 <<< subclass marker AcDbSymbolTableRecord 100 <<< subclass marker AcDbLinetypeTableRecord 2 <<< line type name CENTER 70 <<< flags 0 3 Center ____ _ ____ _ ____ _ ____ _ ____ _ ____ 72 65 73 4 40 2.0 49 1.25 74 0 49 -0.25 74 0 49 0.25 74 0 49 -0.25 74 0
ezdxf setup for line type ‘GASLEITUNG’:
dwg.linetypes.new('GASLEITUNG', dxfattribs={
'description': 'Gasleitung2 ----GAS----GAS----GAS----GAS----GAS----GAS--',
'length': 1,
'pattern': 'A,.5,-.2,["GAS",STANDARD,S=.1,U=0.0,X=-0.1,Y=-.05],-.25', })
0 LTYPE 5 614 330 5F 100 <<< subclass marker AcDbSymbolTableRecord 100 <<< subclass marker AcDbLinetypeTableRecord 2 GASLEITUNG 70 0 3 Gasleitung2 ----GAS----GAS----GAS----GAS----GAS----GAS-- 72 65 73 3 40 1 49 0.5 74 0 49 -0.2 74 2 75 0 340 11 46 0.1 50 0.0 44 -0.1 45 -0.05 9 GAS 49 -0.25 74 0
ezdxf setup for line type ‘GRENZE2’:
dwg.linetypes.new('GRENZE2', dxfattribs={
'description': 'Grenze eckig ----[]-----[]----[]-----[]----[]--',
'length': 1.45,
'pattern': 'A,.25,-.1,[132,ltypeshp.shx,x=-.1,s=.1],-.1,1', })
0 LTYPE 5 615 330 5F 100 <<< subclass marker AcDbSymbolTableRecord 100 <<< subclass marker AcDbLinetypeTableRecord 2 GRENZE2 70 0 3 Grenze eckig ----[]-----[]----[]-----[]----[]-- 72 65 73 4 40 1.45 49 0.25 74 0 49 -0.1 74 4 75 132 340 616 46 0.1 50 0.0 44 -0.1 45 0.0 49 -0.1 74 0 49 1.0 74 0
The DIMSTYLE table stores all dimension style definitions of a DXF drawing.
You have access to the dimension styles table by the attribute Drawing.dimstyles.
SEE ALSO:
0 <<< start of table TABLE 2 <<< set table type DIMSTYLE 70 <<< count of line types defined in this table, AutoCAD ignores this value 9 0 <<< 1. DIMSTYLE table entry DIMSTYLE
<<< DIMSTYLE data tags 0 <<< 2. DIMSTYLE table entry DIMSTYLE
<<< DIMSTYLE data tags and so on 0 <<< end of DIMSTYLE table ENDTAB
Source: CADDManger Blog [image] [image]
DIMVAR | Code | Description |
DIMALT | 170 | Controls the display of alternate units in dimensions. |
DIMALTD | 171 | Controls the number of decimal places in alternate units. If DIMALT is turned on, DIMALTD sets the number of digits displayed to the right of the decimal point in the alternate measurement. |
DIMALTF | 143 | Controls the multiplier for alternate units. If DIMALT is turned on, DIMALTF multiplies linear dimensions by a factor to produce a value in an alternate system of measurement. The initial value represents the number of millimeters in an inch. |
DIMAPOST | 4 | Specifies a text prefix or suffix (or both) to the alternate dimension measurement for all types of dimensions except angular. For instance, if the current units are Architectural, DIMALT is on, DIMALTF is 25.4 (the number of millimeters per inch), DIMALTD is 2, and DIMPOST is set to “mm”, a distance of 10 units would be displayed as 10”[254.00mm]. |
DIMASZ | 41 | Controls the size of dimension line and leader line arrowheads. Also controls the size of hook lines. Multiples of the arrowhead size determine whether dimension lines and text should fit between the extension lines. DIMASZ is also used to scale arrowhead blocks if set by DIMBLK. DIMASZ has no effect when DIMTSZ is other than zero. |
DIMBLK | 5 | Sets the arrowhead block displayed at the ends of dimension lines. |
DIMBLK1 | 6 | Sets the arrowhead for the first end of the dimension line when DIMSAH is 1. |
DIMBLK2 | 7 | Sets the arrowhead for the second end of the dimension line when DIMSAH is 1. |
DIMCEN | 141 | Controls drawing of circle or arc center marks and centerlines by the DIMCENTER, DIMDIAMETER, and DIMRADIUS commands. For DIMDIAMETER and DIMRADIUS, the center mark is drawn only if you place the dimension line outside the circle or arc. 0.0 • 2 0 = No center marks or lines are drawn • 2 <0 = Centerlines are drawn • 2 >0 = Center marks are drawn 168u |
DIMCLRD | 176 | Assigns colors to dimension lines, arrowheads, and dimension leader lines. 0.0 • 2 0 = BYBLOCK • 2 1-255 = ACI AutoCAD Color Index • 2 256 = BYLAYER 168u |
DIMCLRE | 177 | Assigns colors to dimension extension lines, values like DIMCLRD |
DIMCLRT | 178 | Assigns colors to dimension text, values like DIMCLRD |
DIMDLE | 46 | Sets the distance the dimension line extends beyond the extension line when oblique strokes are drawn instead of arrowheads. |
DIMDLI | 43 | Controls the spacing of the dimension lines in baseline dimensions. Each dimension line is offset from the previous one by this amount, if necessary, to avoid drawing over it. Changes made with DIMDLI are not applied to existing dimensions. |
DIMEXE | 44 | Specifies how far to extend the extension line beyond the dimension line. |
DIMEXO | 42 | Specifies how far extension lines are offset from origin points. With fixed-length extension lines, this value determines the minimum offset. |
DIMGAP | 147 | Sets the distance around the dimension text when the dimension line breaks to accommodate dimension text. Also sets the gap between annotation and a hook line created with the LEADER command. If you enter a negative value, DIMGAP places a box around the dimension text. DIMGAP is also used as the minimum length for pieces of the dimension line. When the default position for the dimension text is calculated, text is positioned inside the extension lines only if doing so breaks the dimension lines into two segments at least as long as DIMGAP. Text placed above or below the dimension line is moved inside only if there is room for the arrowheads, dimension text, and a margin between them at least as large as DIMGAP: 2 * (DIMASZ + DIMGAP). |
DIMLFAC | 144 | Sets a scale factor for linear dimension measurements. All linear dimension distances, including radii, diameters, and coordinates, are multiplied by DIMLFAC before being converted to dimension text. Positive values of DIMLFAC are applied to dimensions in both modelspace and paperspace; negative values are applied to paperspace only. DIMLFAC applies primarily to nonassociative dimensions (DIMASSOC set 0 or 1). For nonassociative dimensions in paperspace, DIMLFAC must be set individually for each layout viewport to accommodate viewport scaling. DIMLFAC has no effect on angular dimensions, and is not applied to the values held in DIMRND, DIMTM, or DIMTP. |
DIMLIM | 72 | Generates dimension limits as the default text. Setting DIMLIM to On turns DIMTOL off. 0.0 • 2 0 = Dimension limits are not generated as default text • 2 1 = Dimension limits are generated as default text 168u |
DIMPOST | 3 | Specifies a text prefix or suffix (or both) to the dimension measurement. For example, to establish a suffix for millimeters, set DIMPOST to mm; a distance of 19.2 units would be displayed as 19.2 mm. If tolerances are turned on, the suffix is applied to the tolerances as well as to the main dimension. Use “<>” to indicate placement of the text in relation to the dimension value. For example, enter “<>mm” to display a 5.0 millimeter radial dimension as “5.0mm”. If you entered mm “<>”, the dimension would be displayed as “mm 5.0”. |
DIMRND | 45 | Rounds all dimensioning distances to the specified value. For instance, if DIMRND is set to 0.25, all distances round to the nearest 0.25 unit. If you set DIMRND to 1.0, all distances round to the nearest integer. Note that the number of digits edited after the decimal point depends on the precision set by DIMDEC. DIMRND does not apply to angular dimensions. |
DIMSAH | 173 | Controls the display of dimension line arrowhead blocks. 0.0 • 2 0 = Use arrowhead blocks set by DIMBLK • 2 1 = Use arrowhead blocks set by DIMBLK1 and DIMBLK2 168u |
DIMSCALE | 40 | Sets the overall scale factor applied to dimensioning variables that specify sizes, distances, or offsets. Also affects the leader objects with the LEADER command. Use MLEADERSCALE to scale multileader objects created with the MLEADER command. 0.0 • 2 0.0 = A reasonable default value is computed based on the scaling between the current model space viewport and paperspace. If you are in paperspace or modelspace and not using the paperspace feature, the scale factor is 1.0. • 2 >0 = A scale factor is computed that leads text sizes, arrowhead sizes, and other scaled distances to plot at their face values. 168u DIMSCALE does not affect measured lengths, coordinates, or angles. Use DIMSCALE to control the overall scale of dimensions. However, if the current dimension style is annotative, DIMSCALE is automatically set to zero and the dimension scale is controlled by the CANNOSCALE system variable. DIMSCALE cannot be set to a non-zero value when using annotative dimensions. |
DIMSE1 | 75 | Suppresses display of the first extension line. 0.0 • 2 0 = Extension line is not suppressed • 2 1 = Extension line is suppressed 168u |
DIMSE2 | 76 | Suppresses display of the second extension line. 0.0 • 2 0 = Extension line is not suppressed • 2 1 = Extension line is suppressed 168u |
DIMSOXD | 175 | Suppresses arrowheads if not enough space is available inside the extension lines. 0.0 • 2 0 = Arrowheads are not suppressed • 2 1 = Arrowheads are suppressed 168u If not enough space is available inside the extension lines and DIMTIX is on, setting DIMSOXD to On suppresses the arrowheads. If DIMTIX is off, DIMSOXD has no effect. |
DIMTAD | 77 | Controls the vertical position of text in relation to the dimension line. 0.0 • 2 0 = Centers the dimension text between the extension lines. • 2 1 = Places the dimension text above the dimension line except when the dimension line is not horizontal and text inside the extension lines is forced horizontal (DIMTIH = 1). The distance from the dimension line to the baseline of the lowest line of text is the current DIMGAP value. • 2 2 = Places the dimension text on the side of the dimension line farthest away from the defining points. • 2 3 = Places the dimension text to conform to Japanese Industrial Standards (JIS). • 2 4 = Places the dimension text below the dimension line. 168u |
DIMTFAC | 146 | Specifies a scale factor for the text height of fractions and tolerance values relative to the dimension text height, as set by DIMTXT. For example, if DIMTFAC is set to 1.0, the text height of fractions and tolerances is the same height as the dimension text. If DIMTFAC is set to 0.7500, the text height of fractions and tolerances is three-quarters the size of dimension text. |
DIMTIH | 73 | Controls the position of dimension text inside the extension lines for all dimension types except Ordinate. 0.0 • 2 0 = Aligns text with the dimension line • 2 1 = Draws text horizontally 168u |
DIMTIX | 174 | Draws text between extension lines. 0.0 • 2 0 = Varies with the type of dimension. For linear and angular dimensions, text is placed inside the extension lines if there is sufficient room. For radius and diameter dimensions hat don’t fit inside the circle or arc, DIMTIX has no effect and always forces the text outside the circle or arc. • 2 1 = Draws dimension text between the extension lines even if it would ordinarily be placed outside those lines 168u |
DIMTM | 48 | Sets the minimum (or lower) tolerance limit for dimension text when DIMTOL or DIMLIM is on. DIMTM accepts signed values. If DIMTOL is on and DIMTP and DIMTM are set to the same value, a tolerance value is drawn. If DIMTM and DIMTP values differ, the upper tolerance is drawn above the lower, and a plus sign is added to the DIMTP value if it is positive. For DIMTM, the program uses the negative of the value you enter (adding a minus sign if you specify a positive number and a plus sign if you specify a negative number). |
DIMTOFL | 172 | Controls whether a dimension line is drawn between the extension lines even when the text is placed outside. For radius and diameter dimensions (when DIMTIX is off), draws a dimension line inside the circle or arc and places the text, arrowheads, and leader outside. 0.0 • 2 0 = Does not draw dimension lines between the measured points when arrowheads are placed outside the measured points • 2 1 = Draws dimension lines between the measured points even when arrowheads are placed outside the measured points 168u |
DIMTOH | 74 | Controls the position of dimension text outside the extension lines. 0.0 • 2 0 = Aligns text with the dimension line • 2 1 = Draws text horizontally 168u |
DIMTOL | 71 | Appends tolerances to dimension text. Setting DIMTOL to on turns DIMLIM off. |
DIMTP | 47 | Sets the maximum (or upper) tolerance limit for dimension text when DIMTOL or DIMLIM is on. DIMTP accepts signed values. If DIMTOL is on and DIMTP and DIMTM are set to the same value, a tolerance value is drawn. If DIMTM and DIMTP values differ, the upper tolerance is drawn above the lower and a plus sign is added to the DIMTP value if it is positive. |
DIMTSZ | 142 | Specifies the size of oblique strokes drawn instead of arrowheads for linear, radius, and diameter dimensioning. 0.0 • 2 0 = Draws arrowheads. • 2 >0 = Draws oblique strokes instead of arrowheads. The size of the oblique strokes is determined by this value multiplied by the DIMSCALE value 168u |
DIMTVP | 145 | Controls the vertical position of dimension text above or below the dimension line. The DIMTVP value is used when DIMTAD = 0. The magnitude of the vertical offset of text is the product of the text height and DIMTVP. Setting DIMTVP to 1.0 is equivalent to setting DIMTAD = 1. The dimension line splits to accommodate the text only if the absolute value of DIMTVP is less than 0.7. |
DIMTXT | 140 | Specifies the height of dimension text, unless the current text style has a fixed height. |
DIMZIN | 78 | Controls the suppression of zeros in the primary unit value. Values 0-3 affect feet-and-inch dimensions only: 0.0 • 2 0 = Suppresses zero feet and precisely zero inches • 2 1 = Includes zero feet and precisely zero inches • 2 2 = Includes zero feet and suppresses zero inches • 2 3 = Includes zero inches and suppresses zero feet • 2 4 (Bit 3) = Suppresses leading zeros in decimal dimensions (for example, 0.5000 becomes .5000) • 2 8 (Bit 4) = Suppresses trailing zeros in decimal dimensions (for example, 12.5000 becomes 12.5) • 2 12 (Bit 3+4) = Suppresses both leading and trailing zeros (for example, 0.5000 becomes .5) 168u |
0 <<< start of table TABLE 2 <<< set table type DIMSTYLE 5 <<< DIMSTYLE table handle 5F 330 <<< owner tag, tables has no owner 0 100 <<< subclass marker AcDbSymbolTable 70 <<< count of dimension styles defined in this table, AutoCAD ignores this value 9 0 <<< 1. DIMSTYLE table entry DIMSTYLE
<<< DIMSTYLE data tags 0 <<< 2. DIMSTYLE table entry DIMSTYLE
<<< DIMSTYLE data tags and so on 0 <<< end of DIMSTYLE table ENDTAB
Source: CADDManger Blog
DIMVAR | code | Description |
DIMADEC | 179 | Controls the number of precision places displayed in angular dimensions. |
DIMALTTD | 274 | Sets the number of decimal places for the tolerance values in the alternate units of a dimension. |
DIMALTTZ | 286 | Controls suppression of zeros in tolerance values. |
DIMALTU | 273 | Sets the units format for alternate units of all dimension substyles except Angular. |
DIMALTZ | 285 | Controls the suppression of zeros for alternate unit dimension values. DIMALTZ values 0-3 affect feet-and-inch dimensions only. |
DIMAUNIT | 275 | Sets the units format for angular dimensions. 0.0 • 2 0 = Decimal degrees • 2 1 = Degrees/minutes/seconds • 2 2 = Grad • 2 3 = Radians 168u |
DIMBLK_HANDLE | 342 | defines DIMBLK as handle to the BLOCK RECORD entry |
DIMBLK1_HANDLE | 343 | defines DIMBLK1 as handle to the BLOCK RECORD entry |
DIMBLK2_HANDLE | 344 | defines DIMBLK2 as handle to the BLOCK RECORD entry |
DIMDEC | 271 | Sets the number of decimal places displayed for the primary units of a dimension. The precision is based on the units or angle format you have selected. |
DIMDSEP | 278 | Specifies a single-character decimal separator to use when creating dimensions whose unit format is decimal. When prompted, enter a single character at the Command prompt. If dimension units is set to Decimal, the DIMDSEP character is used instead of the default decimal point. If DIMDSEP is set to NULL (default value, reset by entering a period), the decimal point is used as the dimension separator. |
DIMJUST | 280 | Controls the horizontal positioning of dimension text. 0.0 • 2 0 = Positions the text above the dimension line and center-justifies it between the extension lines • 2 1 = Positions the text next to the first extension line • 2 2 = Positions the text next to the second extension line • 2 3 = Positions the text above and aligned with the first extension line • 2 4 = =Positions the text above and aligned with the second extension line 168u |
DIMSD1 | 281 | Controls suppression of the first dimension line and arrowhead. When turned on, suppresses the display of the dimension line and arrowhead between the first extension line and the text. 0.0 • 2 0 = First dimension line is not suppressed • 2 1 = First dimension line is suppressed 168u |
DIMSD2 | 282 | Controls suppression of the second dimension line and arrowhead. When turned on, suppresses the display of the dimension line and arrowhead between the second extension line and the text. 0.0 • 2 0 = Second dimension line is not suppressed • 2 1 = Second dimension line is suppressed 168u |
DIMTDEC | 272 | Sets the number of decimal places to display in tolerance values for the primary units in a dimension. This system variable has no effect unless DIMTOL is set to On. The default for DIMTOL is Off. |
DIMTOLJ | 283 | Sets the vertical justification for tolerance values relative to the nominal dimension text. This system variable has no effect unless DIMTOL is set to On. The default for DIMTOL is Off. 0.0 • 2 0 = Bottom • 2 1 = Middle • 2 2 = Top 168u |
DIMTXSTY_HANDLE | 340 | Specifies the text style of the dimension as handle to STYLE table entry |
DIMTZIN | 284 | Controls the suppression of zeros in tolerance values. Values 0-3 affect feet-and-inch dimensions only. 0.0 • 2 0 = Suppresses zero feet and precisely zero inches • 2 1 = Includes zero feet and precisely zero inches • 2 2 = Includes zero feet and suppresses zero inches • 2 3 = Includes zero inches and suppresses zero feet • 2 4 = Suppresses leading zeros in decimal dimensions (for example, 0.5000 becomes .5000) • 2 8 = Suppresses trailing zeros in decimal dimensions (for example, 12.5000 becomes 12.5) • 2 12 = Suppresses both leading and trailing zeros (for example, 0.5000 becomes .5) 168u |
DIMUPT | 288 | Controls options for user-positioned text. 0.0 • 2 0 = Cursor controls only the dimension line location • 2 1 = Cursor controls both the text position and the dimension line location 168u |
Source: CADDManger Blog
DIMVAR | Code | Description |
DIMALTRND | 148 | Rounds off the alternate dimension units. |
DIMATFIT | 289 | Determines how dimension text and arrows are arranged when space is not sufficient to place both within the extension lines. 0.0 • 2 0 = Places both text and arrows outside extension lines • 2 1 = Moves arrows first, then text • 2 2 = Moves text first, then arrows • 2 3 = Moves either text or arrows, whichever fits best 168u A leader is added to moved dimension text when DIMTMOVE is set to 1. |
DIMAZIN | 79 | Suppresses zeros for angular dimensions. 0.0 • 2 0 = Displays all leading and trailing zeros • 2 1 = Suppresses leading zeros in decimal dimensions (for example, 0.5000 becomes .5000) • 2 2 = Suppresses trailing zeros in decimal dimensions (for example, 12.5000 becomes 12.5) • 2 3 = Suppresses leading and trailing zeros (for example, 0.5000 becomes .5) 168u |
DIMFRAC | 276 | Sets the fraction format when DIMLUNIT is set to 4 (Architectural) or 5 (Fractional). 0.0 • 2 0 = Horizontal stacking • 2 1 = Diagonal stacking • 2 2 = Not stacked (for example, 1/2) 168u |
DIMLDRBLK_HANDLE | 341 | Specifies the arrow type for leaders. Handle to BLOCK RECORD |
DIMLUNIT | 277 | Sets units for all dimension types except Angular. 0.0 • 2 1 = Scientific • 2 2 = Decimal • 2 3 = Engineering • 2 4 = Architectural (always displayed stacked) • 2 5 = Fractional (always displayed stacked) • 2 6 = Microsoft Windows Desktop (decimal format using Control Panel settings for decimal separator and number grouping symbols) 168u |
DIMLWD | 371 | Assigns lineweight to dimension lines. 0.0 • 2 -3 = Default (the LWDEFAULT value) • 2 -2 = BYBLOCK • 2 -1 = BYLAYER 168u |
DIMLWE | 372 | Assigns lineweight to extension lines. 0.0 • 2 -3 = Default (the LWDEFAULT value) • 2 -2 = BYBLOCK • 2 -1 = BYLAYER 168u |
DIMTMOVE | 279 | Sets dimension text movement rules. 0.0 • 2 0 = Moves the dimension line with dimension text • 2 1 = Adds a leader when dimension text is moved • 2 2 = Allows text to be moved freely without a leader 168u |
This image shows the default text locations created by BricsCAD for dimension variables dimtad and dimjust: [image]
The following DIMVARS are not documented in the DXF Reference by Autodesk.
DIMVAR | Code | Description |
DIMTFILL | 69 | Text fill 0=off; 1=background color; 2=custom color (see DIMTFILLCLR) |
DIMTFILLCLR | 70 | Text fill custom color as color index |
DIMFXLON | 290 | Extension line has fixed length if set to 1 |
DIMFXL | 49 | Length of extension line below dimension line if fixed (DIMFXLON is 1), DIMEXE defines the the length above the dimension line |
DIMJOGANG | 50 | Angle of oblique dimension line segment in jogged radius dimension |
DIMLTYPE_HANDLE | 345 | Specifies the LINETYPE of the dimension line. Handle to LTYPE table entry |
DIMLTEX1_HANDLE | 346 | Specifies the LINETYPE of the extension line 1. Handle to LTYPE table entry |
DIMLTEX2_HANDLE | 347 | Specifies the LINETYPE of the extension line 2. Handle to LTYPE table entry |
Prior to DXF R2007, some extended settings for the dimension and the extension lines are stored in the XDATA section by following entries, this is not documented by Autodesk:
1001 ACAD_DSTYLE_DIM_LINETYPE <<< linetype for dimension line 1070 380 <<< group code, which differs from R2007 DIMDLTYPE 1005 FFFF <<< handle to LTYPE entry 1001 ACAD_DSTYLE_DIM_EXT1_LINETYPE <<< linetype for extension line 1 1070 381 <<< group code, which differs from R2007 DIMLTEX1 1005 FFFF <<< handle to LTYPE entry 1001 ACAD_DSTYLE_DIM_EXT2_LINETYPE <<< linetype for extension line 1 1070 382 <<< group code, which differs from R2007 DIMLTEX2 1005 FFFF <<< handle to LTYPE entry 1001 ACAD_DSTYLE_DIMEXT_ENABLED <<< extension line fixed 1070 383 <<< group code, which differs from R2007 DIMEXFIX 1070 1 <<< fixed if 1 else 0 1001 ACAD_DSTYLE_DIMEXT_LENGTH <<< extension line fixed length 1070 378 <<< group code, which differs from R2007 DIMEXLEN 1040 1.33 <<< length of extension line below dimension line
This XDATA groups requires also an appropriate APPID entry in the APPID table. This feature is not supported by ezdxf.
Block records are essential elements for the entities management, each layout (modelspace and paperspace) and every block definition has a block record entry. This block record is the hard owner of the entities of layouts, each entity has an owner handle which points to a block record of the layout.
SEE ALSO:
TODO
A BLOCK is a layout like the modelspace or a paperspace layout, with the similarity that all these layouts are containers for graphical DXF entities. This block definition can be referenced in other layouts by the INSERT entity. By using block references, the same set of graphical entities can be located multiple times at different layouts, this block references can be stretched and rotated without modifying the original entities. A block is referenced only by its name defined by the DXF tag (2, name), there is a second DXF tag (3, name2) for the block name, which is not further documented by Autodesk, just ignore it.
The (10, base_point) tag (in BLOCK defines a insertion point of the block, by ‘inserting’ a block by the INSERT entity, this point of the block is placed at the location defined by the (10, insert) tag in the INSERT entity, and it is also the base point for stretching and rotation.
A block definition can contain INSERT entities, and it is possible to create cyclic block definitions (a BLOCK contains a INSERT of itself), but this should be avoided, CAD applications will not load the DXF file at all or maybe just crash. This is also the case for all other kinds of cyclic definitions like: BLOCK “A” -> INSERT BLOCK “B” and BLOCK “B” -> INSERT BLOCK “A”.
SEE ALSO:
Block names has to be unique and they are case insensitive (“Test” == “TEST”). If there are two or more block definitions with the same name, AutoCAD merges these blocks into a single block with unpredictable properties of all these blocks. In my test with two blocks, the final block has the name of the first block and the base-point of the second block, and contains all entities of both blocks.
In DXF R12 the definition of a block is located in the BLOCKS section, no additional structures are needed. The definition starts with a BLOCK entity and ends with a ENDBLK entity. All entities between this two entities are the content of the block, the block is the owner of this entities like any layout.
As shown in the DXF file below (created by AutoCAD LT 2018), the BLOCK entity has no handle, but ezdxf writes also handles for the BLOCK entity and AutoCAD doesn’t complain.
DXF R12 BLOCKS structure:
0 <<< start of a SECTION SECTION 2 <<< start of BLOCKS section BLOCKS ... <<< modelspace and paperspace block definitions not shown, ... <<< see layout management ... 0 <<< start of a BLOCK definition BLOCK 8 <<< layer 0 2 <<< block name ArchTick 70 <<< flags 1 10 <<< base point, x 0.0 20 <<< base point, y 0.0 30 <<< base point, z 0.0 3 <<< second BLOCK name, same as (2, name) ArchTick 1 <<< xref name, if block is an external reference
<<< empty string! 0 <<< start of the first entity of the BLOCK LINE 5 28E 8 0 62 0 10 500.0 20 500.0 30 0.0 11 500.0 21 511.0 31 0.0 0 <<< start of the second entity of the BLOCK LINE ... 0.0 0 <<< ENDBLK entity, marks the end of the BLOCK definition ENDBLK 5 <<< ENDBLK gets a handle by AutoCAD, but BLOCK didn't 2F2 8 <<< as every entity, also ENDBLK requires a layer (same as BLOCK entity!) 0 0 <<< start of next BLOCK entity BLOCK ... 0 <<< end BLOCK entity ENDBLK 0 <<< end of BLOCKS section ENDSEC
The overall organization in the BLOCKS sections remains the same, but additional tags in the BLOCK entity, have to be maintained.
Especially the concept of ownership is important. Since DXF R13 every graphic entity is associated to a specific layout and a BLOCK definition is also a layout. So all entities in the BLOCK definition, including the BLOCK and the ENDBLK entities, have an owner tag (330, ...), which points to a BLOCK_RECORD entry in the BLOCK_RECORD table. This BLOCK_RECORD is the main management structure for all layouts and is the real owner of the layout entities.
As you can see in the chapter about Layout Management Structures, this concept is also valid for modelspace and paperspace layouts, because these layouts are also BLOCKS, with the special difference, that the entities of the modelspace and the active paperspace layout are stored in the ENTITIES section. [image]
SEE ALSO:
DXF R13 BLOCKS structure:
0 <<< start of a SECTION SECTION 2 <<< start of BLOCKS section BLOCKS ... <<< modelspace and paperspace block definitions not shown, ... <<< see layout management 0 <<< start of BLOCK definition BLOCK 5 <<< even BLOCK gets a handle now ;) 23A 330 <<< owner tag, the owner of a BLOCK is a BLOCK_RECORD in the ... BLOCK_RECORD table 238 100 <<< subclass marker AcDbEntity 8 <<< layer of the BLOCK definition 0 100 <<< subclass marker AcDbBlockBegin 2 <<< BLOCK name ArchTick 70 <<< flags 0 10 <<< base point, x 0.0 20 <<< base point, y 0.0 30 <<< base point, z 0.0 3 <<< second BLOCK name, same as (2, name) ArchTick 1 <<< xref name, if block is an external reference
<<< empty string! 0 <<< start of the first entity of the BLOCK LWPOLYLINE 5 239 330 <<< owner tag of LWPOLYLINE 238 <<< handle of the BLOCK_RECORD! 100 AcDbEntity 8 0 6 ByBlock 62 0 100 AcDbPolyline 90 2 70 0 43 0.15 10 -0.5 20 -0.5 10 0.5 20 0.5 0 <<< ENDBLK entity, marks the end of the BLOCK definition ENDBLK 5 <<< handle 23B 330 <<< owner tag, same BLOCK_RECORD as for the BLOCK entity 238 100 <<< subclass marker AcDbEntity 8 <<< ENDBLK requires the same layer as the BLOCK entity! 0 100 <<< subclass marker AcDbBlockEnd 0 <<< start of the next BLOCK BLOCK ... 0 ENDBLK ... 0 <<< end of the BLOCKS section ENDSEC
DXF R13 BLOCK_RECORD structure:
0 <<< start of a SECTION SECTION 2 <<< start of TABLES section TABLES 0 <<< start of a TABLE TABLE 2 <<< start of the BLOCK_RECORD table BLOCK_RECORD 5 <<< handle of the table 1 330 <<< owner tag of the table 0 <<< is always #0 100 <<< subclass marker AcDbSymbolTable 70 <<< count of table entries, not reliable 4 0 <<< start of first BLOCK_RECORD entry BLOCK_RECORD 5 <<< handle of BLOCK_RECORD, in ezdxf often referred to as "layout key" 1F 330 <<< owner of the BLOCK_RECORD is the BLOCK_RECORD table 1 100 <<< subclass marker AcDbSymbolTableRecord 100 <<< subclass marker AcDbBlockTableRecord 2 <<< name of the BLOCK or LAYOUT *Model_Space 340 <<< pointer to the associated LAYOUT object 4AF 70 <<< AC1021 (R2007) block insertion units 0 280 <<< AC1021 (R2007) block explodability 1 281 <<< AC1021 (R2007) block scalability 0 ... <<< paperspace not shown ... 0 <<< next BLOCK_RECORD BLOCK_RECORD 5 <<< handle of BLOCK_RECORD, in ezdxf often referred to as "layout key" 238 330 <<< owner of the BLOCK_RECORD is the BLOCK_RECORD table 1 100 <<< subclass marker AcDbSymbolTableRecord 100 <<< subclass marker AcDbBlockTableRecord 2 <<< name of the BLOCK ArchTick 340 <<< pointer to the associated LAYOUT object 0 <<< #0, because BLOCK doesn't have an associated LAYOUT object 70 <<< AC1021 (R2007) block insertion units 0 280 <<< AC1021 (R2007) block explodability 1 281 <<< AC1021 (R2007) block scalability 0 0 <<< end of BLOCK_RECORD table ENDTAB 0 <<< next TABLE TABLE ... 0 ENDTAB 0 <<< end of TABLES section ENDESC
Layouts are separated entity spaces, there are three different Layout types:
All layouts have at least a BLOCK definition in the BLOCKS section and since DXF R13 exist the BLOCK_RECORD table with an entry for every BLOCK in the BLOCKS section.
SEE ALSO:
The name of the modelspace BLOCK is “*Model_Space” (DXF R12: “$MODEL_SPACE”) and the name of the active paperspace BLOCK is “*Paper_Space” (DXF R12: “$PAPER_SPACE”), the entities of these two layouts are stored in the ENTITIES section, DXF R12 supports just one paperspace layout.
DXF R13+ supports multiple paperspace layouts, the active layout is still called “*Paper_Space”, the additional inactive paperspace layouts are named by the scheme “*Paper_Spacennnn”, where the first inactive paper space is called “*Paper_Space0”, the second “*Paper_Space1” and so on. A none consecutive numbering is tolerated by AutoCAD. The content of the inactive paperspace layouts are stored as BLOCK content in the BLOCKS section. These names are just the DXF internal layout names, each layout has an additional layout name which is displayed to the user by the CAD application.
A BLOCK definition and a BLOCK_RECORD is not enough for a proper layout setup, an LAYOUT entity in the OBJECTS section is also required. All LAYOUT entities are managed by a DICTIONARY entity, which is referenced as “ACAD_LAYOUT” entity in the root DICTIONARY of the DXF file.
NOTE:
Since DXF R2000 modelspace and paperspace layouts require the DXF LAYOUT entity.
0 LAYOUT 5 <<< handle 59 102 <<< extension dictionary (ignore) {ACAD_XDICTIONARY 360 1C3 102 } 102 <<< reactor (required?) {ACAD_REACTORS 330 1A <<< pointer to "ACAD_LAYOUT" DICTIONARY (layout management table) 102 } 330 <<< owner handle 1A <<< pointer to "ACAD_LAYOUT" DICTIONARY (same as reactor pointer) 100 <<< PLOTSETTINGS AcDbPlotSettings 1 <<< page setup name 2 <<< name of system printer or plot configuration file none_device 4 <<< paper size, part in braces should follow the schema ... (width_x_height_unit) unit is 'Inches' or 'MM' ... Letter\_(8.50_x_11.00_Inches) the part in front of the braces is ... ignored by AutoCAD 6 <<< plot view name 40 <<< size of unprintable margin on left side of paper in millimeters, ... defines also the plot origin-x 6.35 41 <<< size of unprintable margin on bottom of paper in millimeters, ... defines also the plot origin-y 6.35 42 <<< size of unprintable margin on right side of paper in millimeters 6.35 43 <<< size of unprintable margin on top of paper in millimeters 6.35 44 <<< plot paper size: physical paper width in millimeters 215.90 45 <<< plot paper size: physical paper height in millimeters 279.40 46 <<< X value of plot origin offset in millimeters, moves the plot origin-x 0.0 47 <<< Y value of plot origin offset in millimeters, moves the plot origin-y 0.0 48 <<< plot window area: X value of lower-left window corner 0.0 49 <<< plot window area: Y value of lower-left window corner 0.0 140 <<< plot window area: X value of upper-right window corner 0.0 141 <<< plot window area: Y value of upper-right window corner 0.0 142 <<< numerator of custom print scale: real world (paper) units, 1.0 ... for scale 1:50 1.0 143 <<< denominator of custom print scale: drawing units, 50.0 ... for scale 1:50 1.0 70 <<< plot layout flags, bit-coded (... too many options) 688 <<< b1010110000 = UseStandardScale(16)/PlotPlotStyle(32) ... PrintLineweights(128)/DrawViewportsFirst(512) 72 <<< plot paper units (0/1/2 for inches/millimeters/pixels), are ... pixels really supported? 0 73 <<< plot rotation (0/1/2/3 for 0deg/90deg counter-cw/upside-down/90deg cw) 1 <<< 90deg clockwise 74 <<< plot type 0-5 (... too many options) 5 <<< 5 = layout information 7 <<< current plot style name, e.g. 'acad.ctb' or 'acadlt.ctb' 75 <<< standard scale type 0-31 (... too many options) 16 <<< 16 = 1:1, also 16 if user scale type is used 147 <<< unit conversion factor 1.0 <<< for plot paper units in mm, else 0.03937... (1/25.4) for inches ... as plot paper units 76 <<< shade plot mode (0/1/2/3 for as displayed/wireframe/hidden/rendered) 0 <<< as displayed 77 <<< shade plot resolution level 1-5 (... too many options) 2 <<< normal 78 <<< shade plot custom DPI: 100-32767, Only applied when shade plot ... resolution level is set to 5 (Custom) 300 148 <<< paper image origin: X value 0.0 149 <<< paper image origin: Y value 0.0 100 <<< LAYOUT settings AcDbLayout 1 <<< layout name Layout1 70 <<< flags bit-coded 1 <<< 1 = Indicates the PSLTSCALE value for this layout when this ... layout is current 71 <<< Tab order ("Model" tab always appears as the first tab ... regardless of its tab order) 1 10 <<< minimum limits for this layout (defined by LIMMIN while this ... layout is current) -0.25 <<< x value, distance of the left paper margin from the plot ... origin-x, in plot paper units and by scale (e.g. x50 for 1:50) 20 <<< group code for y value -0.25 <<< y value, distance of the bottom paper margin from the plot ... origin-y, in plot paper units and by scale (e.g. x50 for 1:50) 11 <<< maximum limits for this layout (defined by LIMMAX while this ... layout is current) 10.75 <<< x value, distance of the right paper margin from the plot ... origin-x, in plot paper units and by scale (e.g. x50 for 1:50) 21 <<< group code for y value 8.25 <<< y value, distance of the top paper margin from the plot ... origin-y, in plot paper units and by scale (e.g. x50 for 1:50) 12 <<< insertion base point for this layout (defined by INSBASE while ... this layout is current) 0.0 <<< x value 22 <<< group code for y value 0.0 <<< y value 32 <<< group code for z value 0.0 <<< z value 14 <<< minimum extents for this layout (defined by EXTMIN while this ... layout is current), AutoCAD default is (1e20, 1e20, 1e20) 1.05 <<< x value 24 <<< group code for y value 0.80 <<< y value 34 <<< group code for z value 0.0 <<< z value 15 <<< maximum extents for this layout (defined by EXTMAX while this ... layout is current), AutoCAD default is (-1e20, -1e20, -1e20) 9.45 <<< x value 25 <<< group code for y value 7.20 <<< y value 35 <<< group code for z value 0.0 <<< z value 146 <<< elevation ??? 0.0 13 <<< UCS origin (3D Point) 0.0 <<< x value 23 <<< group code for y value 0.0 <<< y value 33 <<< group code for z value 0.0 <<< z value 16 <<< UCS X-axis (3D vector) 1.0 <<< x value 26 <<< group code for y value 0.0 <<< y value 36 <<< group code for z value 0.0 <<< z value 17 <<< UCS Y-axis (3D vector) 0.0 <<< x value 27 <<< group code for y value 1.0 <<< y value 37 <<< group code for z value 0.0 <<< z value 76 <<< orthographic type of UCS 0-6 (... too many options) 0 <<< 0 = UCS is not orthographic ??? 330 <<< ID/handle of required block table record 58 331 <<< ID/handle to the viewport that was last active in this layout ... when the layout was current 1B9 1001 <<< extended data (ignore) ...
And as it seems this is also not enough for a well defined LAYOUT, at least a “main” VIEWPORT entity with ID=1 is required for paperspace layouts, located in the entity space of the layout.
The modelspace layout requires (?) a VPORT entity in the VPORT table (group code 331 in the AcDbLayout subclass).
The “main” viewport for layout “Layout1” shown above. This viewport is located in the associated BLOCK definition called “*Paper_Space0”. Group code 330 in subclass AcDbLayout points to the BLOCK_RECORD of “*Paper_Space0”.
Remember: the entities of the active paperspace layout are located in the ENTITIES section, therefore “Layout1” is not the active paperspace layout.
The “main” VIEWPORT describes, how the application shows the paperspace layout on the screen, and I guess only AutoCAD needs this values. [image]
0 VIEWPORT 5 <<< handle 1B4 102 <<< extension dictionary (ignore) {ACAD_XDICTIONARY 360 1B5 102 } 330 <<< owner handle 58 <<< points to BLOCK_RECORD (same as group code 330 in AcDbLayout of ... "Layout1") 100 AcDbEntity 67 <<< paperspace flag 1 <<< 0 = modelspace; 1 = paperspace 8 <<< layer, 0 100 AcDbViewport 10 <<< Center point (in WCS) 5.25 <<< x value 20 <<< group code for y value 4.00 <<< y value 30 <<< group code for z value 0.0 <<< z value 40 <<< width in paperspace units 23.55 <<< VIEW size in AutoCAD, depends on the workstation configuration 41 <<< height in paperspace units 9.00 <<< VIEW size in AutoCAD, depends on the workstation configuration 68 <<< viewport status field -1/0/n 2 <<< >0 On and active. The value indicates the order of stacking for ... the viewports, where 1 is the active viewport, 2 is the next, and so forth 69 <<< viewport ID 1 <<< "main" viewport has always ID=1 12 <<< view center point in Drawing Coordinate System (DCS), defines ... the center point of the VIEW in relation to the LAYOUT origin 5.25 <<< x value 22 <<< group code for y value 4.00 <<< y value 13 <<< snap base point in modelspace 0.0 <<< x value 23 <<< group code for y value 0.0 <<< y value 14 <<< snap spacing in modelspace units 0.5 <<< x value 24 <<< group code for y value 0.5 <<< y value 15 <<< grid spacing in modelspace units 0.5 <<< x value 25 <<< group code for y value 0.5 <<< y value 16 <<< view direction vector from target (in WCS) 0.0 <<< x value 26 <<< group code for y value 0.0 <<< y value 36 <<< group code for z value 1.0 <<< z value 17 <<< view target point 0.0 <<< x value 27 <<< group code for y value 0.0 <<< y value 37 <<< group code for z value 0.0 <<< z value 42 <<< perspective lens length, focal length? 50.0 <<< 50mm 43 <<< front clip plane z value 0.0 <<< z value 44 <<< back clip plane z value 0.0 <<< z value 45 <<< view height (in modelspace units) 9.00 50 <<< snap angle 0.0 51 <<< view twist angle 0.0 72 <<< circle zoom percent 1000 90 <<< Viewport status bit-coded flags (... too many options) 819232 <<< b11001000000000100000 1 <<< plot style sheet name assigned to this viewport 281 <<< render mode (... too many options) 0 <<< 0 = 2D optimized (classic 2D) 71 <<< UCS per viewport flag 1 <<< 1 = This viewport stores its own UCS which will become the ... current UCS whenever the viewport is activated 74 <<< Display UCS icon at UCS origin flag 0 <<< this field is currently being ignored and the icon always ... represents the viewport UCS 110 <<< UCS origin (3D point) 0.0 <<< x value 120 <<< group code for y value 0.0 <<< y value 130 <<< group code for z value 0.0 <<< z value 111 <<< UCS X-axis (3D vector) 1.0 <<< x value 121 <<< group code for y value 0.0 <<< y value 131 <<< group code for z value 0.0 <<< z value 112 <<< UCS Y-axis (3D vector) 0.0 <<< x value 122 <<< group code for y value 1.0 <<< y value 132 <<< group code for z value 0.0 <<< z value 79 <<< Orthographic type of UCS (... too many options) 0 <<< 0 = UCS is not orthographic 146 <<< elevation 0.0 170 <<< shade plot mode (0/1/2/3 for as displayed/wireframe/hidden/rendered) 0 <<< as displayed 61 <<< frequency of major grid lines compared to minor grid lines 5 <<< major grid subdivided by 5 348 <<< visual style ID/handle (optional) 9F 292 <<< default lighting flag, on when no user lights are specified. 1 282 <<< Default lighting type (0/1 = one distant light/two distant lights) 1 <<< one distant light 141 <<< view brightness 0.0 142 <<< view contrast 0.0 63 <<< ambient light color (ACI), write only if not black color 250 421 <<< ambient light color (RGB), write only if not black color 3355443
Information about ezdxf internals.
The pkg-design section shows the structure of the ezdxf package for developers with more experience, which want to have more insight into the package an maybe want to develop add-ons or want contribute to the ezdxf package. !!! UNDER CONSTRUCTION !!!
A DXF document is divided into several sections, this sections are managed by the Drawing object. For each section exist a corresponding attribute in the Drawing object:
Section | Attribute |
HEADER | Drawing.header |
CLASSES | Drawing.classes |
TABLES | Drawing.tables |
BLOCKS | Drawing.blocks |
ENTITIES | Drawing.entities |
OBJECTS | Drawing.objects |
Resource entities (LAYER, STYLE, LTYPE, …) are stored in tables in the TABLES section. A table owns the table entries, the owner handle of table entry is the handle of the table. Each table has a shortcut in the Drawing object:
Table | Attribute |
APPID | Drawing.appids |
BLOCK_RECORD | Drawing.block_records |
DIMSTYLE | Drawing.dimstyles |
LAYER | Drawing.layers |
LTYPE | Drawing.linetypes |
STYLE | Drawing.styles |
UCS | Drawing.ucs |
VIEW | Drawing.views |
VPORT | Drawing.viewports |
Graphical entities are stored in layouts: Modelspace, Paperspace layouts and BlockLayout. The core management object of this layouts is the BLOCK_RECORD entity (BlockRecord), the BLOCK_RECORD is the real owner of the entities, the owner handle of the entities is the handle of the BLOCK_RECORD and the BLOCK_RECORD also owns and manages the entity space of the layout which contains all entities of the layout.
For more information about layouts see also: Layout Management Structures
For more information about blocks see also: Block Management Structures
Non-graphical entities (objects) are stored in the OBJECTS section. Every object has a parent object in the OBJECTS section, most likely a DICTIONARY object, and is stored in the entity space of the OBJECTS section.
For more information about the OBJECTS section see also: objects_section_internals
All table entries, DXF entities and DXF objects are stored in the entities database accessible as Drawing.entitydb. The entity database is a simple key, value storage, key is the entity handle, value is the DXF object.
For more information about the DXF data model see also: Data Model
DXF entities and objects can have different states:
Loading a DXF document from an external source, creates a new Drawing object. This loading process has two stages:
Parse SectionDict:
The ENTITIES section is a relict from older DXF versions and has to be exported including the modelspace and active paperspace entities, but all entities reside in a BLOCK definition, even modelspace and paperspace layouts are only BLOCK definitions and ezdxf has no explicit ENTITIES section.
Source Code: as developer start your journey at ezdxf.document.Drawing.read(), which has no public documentation, because package-user should use ezdxf.read() and ezdxf.readfile().
The default constructor of each entity type creates a new virtual entity:
The DXFEntity.new() constructor creates entities with given owner, handle and doc attributes, if doc is not None and entity is not already bound to a document, the new() constructor automatically bind the entity to the given document doc.
There exist only two scenarios:
The EntityDB is a simple key/value database to store DXFEntity objects by it’s handle, every Drawing has its own EntityDB, stored in the Drawing attribute entitydb.
Every DXF entity/object, except tables and sections, are represented as DXFEntity or inherited types, this entities are stored in the EntityDB, database-key is the dxf.handle as plain hex string.
All iterators like keys(), values(), items() and __iter__() do not yield destroyed entities.
WARNING:
The Modelspace, any Paperspace layout and BlockLayout objects have an EntitySpace container to store their entities.
EntitySpace has a standard Python list like interface, therefore index can be any valid list indexing or slicing term, like a single index layout[-1] to get the last entity, or an index slice layout[:10] to get the first 10 or less entities as List[DXFEntity]. Does not filter destroyed entities.
Required DXF tag interface:
Returns: DXFTag or inherited
A list of DXFTag, inherits from Python standard list. Unlike the statement in the DXF Reference “Do not write programs that rely on the order given here”, tag order is sometimes essential and some group codes may appear multiples times in one entity. At the worst case (Material: normal map shares group codes with diffuse map) using same group codes with different meanings.
Collection of DXFTag as flat list. Low level tag container, only required for advanced stuff.
There exists DXF R12 with subclass markers, technical incorrect but works if the reader ignore subclass marker tags, unfortunately ezdxf tries to use this subclass markers and therefore R12 parsing by ezdxf does not work without removing these subclass markers.
This method removes all subclass markers and flattens all subclasses into ExtendedTags.noclass.
Assumes that no XDATA block with the same appid already exist:
try:
xdata = tags.get_xdata('EZDXF') except ValueError:
xdata = tags.new_xdata('EZDXF')
Assumes that no app data block with the same appid already exist:
try:
app_data = tags.get_app_data('{ACAD_REACTORS', tags) except ValueError:
app_data = tags.new_app_data('{ACAD_REACTORS', tags)
Store DXF tags in compact data structures as list or array.array to reduce memory usage.
This section is only for me, because of the long pauses between develop iterations, I often forget to be consistent in documentation formatting.
Documentation is written with Sphinx and reSturcturedText.
Started integration of documentation into source code and using autodoc features of Sphinx wherever useful.
Sphinx theme provided by Read the Docs :
pip install sphinx-rtd-theme
e = ExampleCls(flag=True)
New in version 0.9: New feature flag
Changed in version 0.10: The new meaning of flag is …
Deprecated since version 0.11: flag is obsolete
Manfred Moitzi
2011-2020, Manfred Moitzi
November 27, 2020 | 0.14.2 |