Provided by: python3-ezdxf_0.14.2-3_all bug

NAME

       ezdxf - ezdxf Documentation [image]

       Welcome! This is the documentation for ezdxf release 0.14.2, last updated Nov 27, 2020.

       • ezdxf is a Python package to create new DXF files and read/modify/write existing DXF files

       • the intended audience are developers

       • requires at least Python 3.6

       • OS independent

       • additional required packages: pyparsing

       • MIT-License

       • read/write/new support for DXF versions: R12, R2000, R2004, R2007, R2010, R2013 and R2018

       • additional read support for DXF versions R13/R14 (upgraded to R2000)

       • additional read support for older DXF versions than R12 (upgraded to R12)

       • read/write support for ASCII DXF and Binary DXF

       • preserves third-party DXF content

INCLUDED EXTENSIONS

drawing  add-on to visualise and convert DXF files to images which can be saved to various formats such
         as png, pdf and svg

       • r12writer add-on to write basic DXF entities direct and fast into a DXF R12 file or stream

       • iterdxf add-on to iterate over entities of the modelspace of really big (> 5GB) DXF files which do  not
         fit into memory

       • importer add-on to import entities, blocks and table entries from another DXF document

       • dxf2code  add-on to generate Python code for DXF structures loaded from DXF documents as starting point
         for parametric DXF entity creation

       • acadctb add-on to read/write plot_style_files

       • pycsg add-on for Constructive Solid Geometry (CSG) modeling technique

WEBSITE

       https://ezdxf.mozman.at/

DOCUMENTATION

       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

QUESTIONS AND FEEDBACK AT GOOGLE GROUPS

       Please post questions at the forum or stack overflow to make answers available to other users as well.

INTRODUCTION

   What is ezdxf
       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

   What ezdxf can’t doezdxf  is  not  a  DXF  converter:  ezdxf can not convert between different DXF versions, if you are
            looking for an appropriate application, try the free ODAFileConverter from the Open Design Alliance,
            which converts between different DXF version and also between the DXF and the DWG file format.

          • ezdxf  is not a CAD file format converter: ezdxf can not convert DXF files to other CAD formats such
            as DWG

          • ezdxf is not a CAD kernel and does not provide high level functionality for construction work, it is
            just  an interface to the DXF file format. If you are looking for a CAD kernel with Python scripting
            support, look at FreeCAD.

   Supported Python Versions
       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.

   Supported Operating Systems
       ezdxf  is  OS  independent  and  runs  on  all  platforms which provide an appropriate Python interpreter
       (>=3.6).

   Supported DXF Versions
                                           ┌────────┬──────────────────────┐
                                           │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.

   Embedded DXF Information of 3rd Party Applications
       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.

   License
       ezdxf is licensed under the very liberal MIT-License.

USAGE FOR BEGINNERS

       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

   Loading DXF Files
       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:
          Documentation for ezdxf.readfile(), ezdxf.readzip() and ezdxf.read(), for more information about  file
          management  go  to the dwgmanagement section. For loading DXF files with structural errors look at the
          ezdxf.recover module.

   Saving DXF Files
       Save the DXF document with a new name:

          doc.saveas('new_name.dxf')

       or with the same name as loaded:

          doc.save()

       SEE ALSO:
          Documentation  for  ezdxf.document.Drawing.save()  and   ezdxf.document.Drawing.saveas(),   for   more
          information about file management go to the dwgmanagement section.

   Create a New DXF File
       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:
          Documentation  for  ezdxf.new(),  for  more  information about file management go to the dwgmanagement
          section.

   Layouts and Blocks
       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

   Create New Blocks
       The block definitions of a DXF document are managed by the BlocksSection object:

          my_block = doc.blocks.new('MyBlock')

       SEE ALSO:
          tut_blocks

   Query DXF Entities
       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:
          For more information go to the tut_getting_data

   Examine DXF Entities
       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:
          Common graphical DXF attributes

   Create New DXF Entities
       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:

          • ModelspacePaperspaceBlockLayout

       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:
          Do not instantiate DXF entities by yourself and add them to layouts, always use the  provided  factory
          function to create new graphical entities, this is the intended way to use ezdxf.

   Create Block References
       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:
          See tut_blocks for more advanced features like using Attrib entities.

   Create New Layers
       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:
          layer_concept

   Delete Entities
       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.

   Further Information
       • reference documentation

       • Documentation of package internals: Developer Guides.

BASIC CONCEPTS

       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.

   AutoCAD Color Index (ACI)
       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:
          plot_style_files

   Layer Concept
       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:

       • Layers give you a way to turn groups of objects on and off - both on the screen and on the plot.

       • Layers provide the most efficient way of controlling object color and linetype

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

   Linetypes
       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)
       [image]

       In DXF R13 Autodesk introduced complex linetypes, containing TEXT or SHAPES in  linetypes.  ezdxf  v0.8.4
       and later supports complex linetypes.

       SEE ALSO:
          tut_linetypes

   Linetype Scaling
       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.

   Coordinate Systems
       AutoLISP Reference to Coordinate Systems provided by Autodesk.

       To brush up you knowledge about vectors, watch the YouTube tutorials of 3Blue1Brown about Linear Algebra.

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

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

          • Table entry UCSezdxf.math.UCS - converter between WCS and UCS

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

          • Object Coordinate System - deeper insights into OCS

          • ezdxf.math.OCS - converter between WCS and OCS

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

   Object Coordinate System (OCS)DXF Reference for OCS provided by Autodesk.

       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:

       • Its origin coincides with the WCS origin.

       • The orientation of the x- and y-axis within the xy-plane are calculated in an arbitrary but  consistent
         manner.  AutoCAD performs this calculation using the arbitrary axis algorithm.

       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.

       • LinePoint3DFacePolyline (3D)

       • Vertex (3D)

       • PolymeshPolyfaceViewport

       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.

       • CircleArcSolidTraceTextAttribAttdefShapeInsertPolyline (2D)

       • Vertex (2D)

       • LWPolylineHatchImage

       Some of a Dimension’s points are expressed in WCS and some in OCS.

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

   Arbitrary Axis AlgorithmDXF Reference for Arbitrary Axis Algorithm provided by Autodesk.

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

   WCS to OCS
          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)

   OCS to WCS
          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)

TUTORIALS

   Tutorial for getting data from DXF files
       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:
          dwgmanagement

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

       • Modelspace: this is the common construction space

       • Paperspace: used to to create print layouts

       • BlockLayout: reusable elements, every block has its own entity space

       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 DXF entities of a layout
       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.

   Access DXF attributes of an entity
       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.

   Getting a paperspace layout
          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().

   Retrieve entities by query language
       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:
          entity query string

       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"]')

   Retrieve entities by groupby() function
       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:
          groupby() documentation

   Tutorial for creating simple DXF drawings
       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:
          r12writer

       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:
          Look at factory methods of the BaseLayout class to see all the available DXF entities.

   Tutorial for Layers
       If you are not familiar with the concept of layers, please read this first: layer_concept

   Create a Layer Definition
          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'.

   Changing Layer State
       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:
          For all methods and attributes see class Layer.

   Check Available Layers
       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

   Deleting a Layer
       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.

   Tutorial for Blocks
   What are Blocks?
       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.

   Create a Block
       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

   Block References (Insert)
       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))

   What are Attributes?
       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.

   Using Attribute Definitions
       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")

   Get/Set Attributes of Existing Block References
       See the howto: howto_get_attribs

   Evaluate Wrapped Block References
       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)

   Exploding Block References
       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()

   Examine Entities of Block References
       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)}.')

   Tutorial for LWPolyline
       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")
       [image]

       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:

          • x = x coordinate

          • y = y coordinate

          • s = start width

          • e = end width

          • b = bulge value

          • v = (x, y) as tuple

          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')
       [image]

   Tutorial for Text
       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_LEFTTOP_CENTERTOP_RIGHT    │
                               ├───────────┼─────────────┼───────────────┼──────────────┤
                               │Middle     │ MIDDLE_LEFTMIDDLE_CENTERMIDDLE_RIGHT │
                               ├───────────┼─────────────┼───────────────┼──────────────┤
                               │Bottom     │ BOTTOM_LEFTBOTTOM_CENTERBOTTOM_RIGHT │
                               ├───────────┼─────────────┼───────────────┼──────────────┤
                               │Baseline   │ LEFTCENTERRIGHT        │
                               └───────────┴─────────────┴───────────────┴──────────────┘

       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.                        │
                                  └──────────┴───────────────────────────────────────┘

   Standard Text Styles
       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]

   New Text Style
       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:

          • open font folder c:\windows\fonts

          • select and open the font-family Open Sans

          • right-click on Open Sans Standard and select Properties

          • on top of the first tab you see the font name: 'OpenSans-Regular.ttf'

       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.

   3D Text
       It  is  possible to place the 2D Text entity into 3D space by using the OCS, for further information see:
       tut_ocs.

   Tutorial for MText
       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.
          """

   Adding a MText entity
       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.'
       [image]

       IMPORTANT:
          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.

   Text placement
       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()

   Character height
       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.

   Text rotation (direction)
       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.

   Defining a wrapping border
       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
       [image]

   MText formatting
       MText supports inline formatting by special codes: mtext_inline_codes

          mtext.text = "{\\C1red text} - {\\C3green text} - {\\C5blue text}"
       [image]

   Stacked 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;"
       [image]

       Available helper function for text formatting:

          • set_color() - append text color change

          • set_font() - append text font change

          • add_stacked_text() - append stacked text

   Background color (filling)
       The MText entity can have a background filling:

          • ACI

          • true color value as (r, g, b) tuple

          • color name as string, use special name 'canvas' to use the canvas background color

       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]

   Tutorial for Spline
       Background information about B-spline at Wikipedia.

   Splines from fit points
       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)
       [image]

       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))
       [image]

       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 = []

   Splines by control points
       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})

       • black curve: AutoCAD/BricsCAD spline generated from fit points

       • red curve: spline curve interpolation, “uniform” method

       • green curve: spline curve interpolation, “chord” method

       • blue curve: spline curve interpolation, “centripetal” method
       [image]

   Open Spline
       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)
       [image]

   Closed Spline
       A closed spline is continuous closed curve.

          msp.add_closed_spline(control_points)
       [image]

   Rational Spline
       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])
       [image]

   Spline properties
       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

   Tutorial for Polyface
       coming soon …

   Tutorial for Mesh
       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")

   Tutorial for Hatch
   Create hatches with one boundary path
       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:

          • line EdgePath.add_line()

          • arc EdgePath.add_arc()

          • ellipse EdgePath.add_ellipse()

          • spline EdgePath.add_spline()

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

   Create hatches with multiple boundary paths (islands)
       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)

       [image]

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

       [image]

       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.

   Example for Edge Path Boundary
          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]

   Associative Boundary Paths
       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.

   Predefined Hatch Pattern
       Use predefined hatch pattern by name:

          hatch.set_pattern_fill('ANSI31', scale=0.5)
       [image]

   Create hatches with gradient fill
       TODO

   Tutorial for Hatch Pattern Definition
       TODO

   Tutorial for Image and ImageDef
       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")

   Tutorial for Underlay and UnderlayDefinition
       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")

   Tutorial for Linetypes
       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, ...]

       total_pattern_length
              Sum of all linetype elements (absolute vaues)

       elem   if elem > 0 it is a line, if elem < 0 it is gap, if elem == 0.0 it is a dot

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

   Check Available Linetypes
       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

   Removing Linetypes
       WARNING:
          Deleting of linetypes still in use generates invalid DXF files.

       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.

   Tutorial for Complex Linetypes
       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:

          • S … scaling factor, always > 0, if S=0 the TEXT or SHAPE is not visible

          • R or U … rotation relative to the line direction

          • X … x direction offset (along the line)

          • Y … y direction offset (perpendicular to the line)

       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.

   Tutorial for OCS/UCS Usage
       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.

   Object Coordinate System (OCS)
       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.

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

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

   Thickness
       Defines the extrusion distance for an entity.

       NOTE:
          There is a new edition of this tutorial using UCS based transformation, which are available  in  ezdxf
          v0.11 and later: tut_ucs_transform

          This edition shows the hard way to accomplish the transformations by low level operations.

   Placing 2D Circle in 3D Space
       The colors for axis follow the AutoCAD standard:

          • red is x-axis

          • green is y-axis

          • blue is z-axis

          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]

   Placing LWPolyline in 3D Space
       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]

   Using UCS to Place 3D Polyline
       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})

       [image: 3d poyline with UCS] [image]

   Placing 2D Text in 3D Space
       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')

       [image: text in ucs as top view] [image] [image: text in ucs as front view] [image]

       HINT:
          For calculating OCS angles from an UCS, be aware that 2D  entities,  like  TEXT  or  ARC,  are  placed
          parallel to the xy-plane of the UCS.

   Placing 2D Arc in 3D Space
       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},
          )

       [image: arc in ucs as top view] [image] [image: arc in ucs as front view] [image]

   Placing Block References in 3D Space
       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,
          })

       [image] [image]

       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,
          })

       [image] [image]

       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)

       [image] [image]

       And here is the point, where my math knowledge ends, for more advanced CAD operation  you  have  to  look
       elsewhere.

   Tutorial for UCS Based Transformations
       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.

   Placing 2D Circle in 3D Space
       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)

       [image: circle in ucs as side view] [image] [image: circle in ucs as front view] [image]

   Placing LWPolyline in 3D Space
       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]

   Using UCS to Place 3D Polyline
       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)

       [image: 3d poyline with UCS] [image]

   Placing 2D Text in 3D Space
       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)

       [image: text in ucs as top view] [image] [image: text in ucs as front view] [image]

   Placing 2D Arc in 3D Space
       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)

       [image: arc in ucs as top view] [image] [image: arc in ucs as front view] [image]

   Placing Block References in 3D Space
       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)

       [image] [image]

       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)

       [image] [image]

       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)

       [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. 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)

       [image] [image]

   Tutorial for Linear Dimensions
       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:

          • Graphical reference of many DIMVARS and some advanced information: dimstyle_table_internals

          • Source code file standards.py shows how to create your own DIMSTYLES.

          • dimension_linear.py for linear dimension examples.

   Horizontal Dimension
          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.

   Vertical and Rotated 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')
       [image]

       For a vertical dimension set argument angle to 90 degree, but in this example the vertical distance would
       be 0.

   Aligned Dimension
       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')
       [image]

   Dimension Style Override
       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.

   Placing Measurement Text
       The  “default”  location of the measurement text depends on various DimStyle parameters and is applied if
       no user defined text location is defined.

   Default Text Locations
       “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()
       [image]

       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()
       [image]

       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.

   User Defined Text Locations
       Beside the default location, it is possible to locate the measurement text freely.

   Location Relative to Origin
       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()
       [image]

       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().

   Location Relative to Center of Dimension Line
       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()
       [image]

   Location Relative to Default Location
       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()
       [image]

   Measurement Text Formatting and Styling
   Text Properties
                                  ┌─────────┬───────────────────────────────────────┐
                                  │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 Filling
       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()
       [image]

   Text Formatting
       • Set decimal places: dimdec defines the number of decimal places displayed for the primary  units  of  a
         dimension. (DXF R2000)

       • Set decimal point character: dimdsep defines the decimal point as ASCII code, use ord('.')

       • Set rounding: dimrnd, 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 dimrnd is set to 1.0,  all  distances
         round to the nearest integer. For more information look at the documentation of the ezdxf.math.xround()
         function.

       • Set zero trimming: dimzin, ezdxf supports only: 4 suppress leading zeros and 8: suppress trailing zeros
         and both as 12.

       • Set  measurement  factor:  scale measurement by factor dimlfac, e.g. to get the dimensioning text in cm
         for a DXF file where 1 drawing unit represents 1m, set dimlfac to 100.

       • Text template for measurement text is defined by dimpost, '<>' represents the  measurement  text,  e.g.
         '~<>cm' produces '~300cm' for measurement in previous example.

       To        set       this       values       the       ezdxf.entities.DimStyle.set_text_format()       and
       ezdxf.entities.DimStyleOverride.set_text_format() methods are very recommended.

   Overriding Measurement Text
       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()
       [image]

   Dimension Line Properties
       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()

   Extension Line Properties
       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()
       [image]

       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()
       [image]

       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()
       [image]

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

       • "ARCHTICK""OBLIQUE""NONE""SMALL""DOTSMALL""INTEGRAL"

   Arrow Shapes
       [image]

   Arrow Names
       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" │
                                      └──────────────────────┴───────────────────┘

   Tolerances and Limits
       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.

   Tolerances
       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()
       [image]

       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()
       [image]

       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.             │
                                   ├────────┼───────────────────────────────────────┤
                                   │dimtzin4  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           │
                                   └────────┴───────────────────────────────────────┘

   Limits
       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()
       [image]

                                         ┌───────┬───────────────────────────┐
                                         │DIMVAR │ Description               │
                                         ├───────┼───────────────────────────┤
                                         │dimlim │ set to 1 to enable limits │
                                         └───────┴───────────────────────────┘

   Alternative Units
       Alternative units are not supported.

   Tutorial for Radius Dimensions
       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.

   Placing Measurement Text
       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:
          Not  all  possibles  features  of DIMSTYLE are supported and especially for radial dimension there are
          less features supported as for linear dimension because of the lack of good documentation.

       SEE ALSO:

          • Graphical reference of many DIMVARS and some advanced information: dimstyle_table_internals

          • Source code file standards.py shows how to create your own DIMSTYLES.

          • dimension_radius.py for radius dimension examples.

   Default Text Locations Outside
       '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}
                                   )
       [image]

   Default Text Locations Inside
       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'
                                   )
       [image] [image]

       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}
                                   )
       [image]

   User Defined Text Locations
       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'
                                   )
       [image]

       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}
                                   )
       [image]

       User defined location inside of the circle:

          dim = msp.add_radius_dim(center=(0, 0), radius=2.5, location=(1, 1),
                                   dimstyle='EZ_RADIUS'
                                   )
       [image] [image]

       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},
                                   )
       [image]

   Center Mark/Lines
       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]

   Overriding Measurement Text
       See Linear Dimension Tutorial: tut_overriding_measurement_text

   Measurement Text Formatting and Styling
       See Linear Dimension Tutorial: tut_measurement_text_formatting_and_styling

   Tutorial for Diameter Dimensions
       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.

   Placing Measurement Text
       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:
          Not  all  possibles features of DIMSTYLE are supported and especially for diameter dimension there are
          less features supported as for linear dimension because of the lack of good documentation.

       SEE ALSO:

          • Graphical reference of many DIMVARS and some advanced information: dimstyle_table_internals

          • Source code file standards.py shows how to create your own DIMSTYLES.

          • dimension_diameter.py for diameter dimension examples.

   Default Text Locations Outside
       '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}
                                    )
       [image]

   Default Text Locations Inside
       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'
                                     )
       [image]

       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}
                                     )
       [image]

   User Defined Text Locations
       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'
                                    )
       [image]

       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}
                                    )
       [image]

       User defined location inside of the circle:

          dim = msp.add_diameter_dim(center=(0, 0), radius=2.5, location=(1, 1),
                                     dimstyle='EZ_RADIUS'
                                    )
       [image]

       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},
                                     )
       [image]

   Center Mark/Lines
       See Radius Dimension Tutorial: tut_center_mark

   Overriding Measurement Text
       See Linear Dimension Tutorial: tut_overriding_measurement_text

   Measurement Text Formatting and Styling
       See Linear Dimension Tutorial: tut_measurement_text_formatting_and_styling

REFERENCE

       The DXF Reference is online available at Autodesk.

       Quoted from the original DXF 12 Reference which is not available on the web:
          Since  the  AutoCAD  drawing  database  (.dwg  file)  is  written  in  a  compact  format that changes
          significantly as new features are added to AutoCAD, we do not document its format and do not recommend
          that  you  attempt  to write programs to read it directly. To assist in interchanging drawings between
          AutoCAD  and  other  programs,  a  Drawing  Interchange  file  format  (DXF)  has  been  defined.  All
          implementations  of  AutoCAD  accept this format and are able to convert it to and from their internal
          drawing file representation.

   DXF Document
   Document Management
   Create New Drawings
       ezdxf.new(dxfversion='AC1027', setup=False) -> Drawing
              Create a new Drawing from scratch, dxfversion can be either “AC1009” the official DXF version name
              or “R12” the AutoCAD release name.

              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   │
                                                 └────────┴─────────────────┘

              Parametersdxfversion – DXF version specifier as string, default is “AC1027” respectively “R2013”

                     • setup –

                       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 Drawings
       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          │
                             └─────────┴─────────┴──────────────┴────────────────────────┘

       ezdxf.readfile(filename: str, encoding: str = None, errors: str = 'surrogateescape') -> Drawing
              Read the DXF document filename from the file-system.

              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.

              Parametersfilename – filename of the ASCII- or Binary DXF document

                     • encoding  –  use None for auto detect (default), or set a specific encoding like “utf-8”,
                       argument is ignored for Binary DXF files

                     • errors –

                       specify decoding error handler

                       • ”surrogateescape” to preserve possible binary data (default)

                       • ”ignore” to use the replacement char U+FFFD “�” for invalid data

                       • ”strict” to raise an UnicodeDecodeError exception for invalid data

              RaisesIOError – not a DXF file or file does not exist

                     • DXFStructureError – for invalid or corrupted DXF structures

                     • UnicodeDecodeError – if errors is “strict” and a decoding error occurs

              Deprecated since version v0.14:  argument  legacy_mode,  use  module  ezdxf.recover  to  load  DXF
              documents with structural flaws.

       ezdxf.read(stream: TextIO) -> Drawing
              Read  a DXF document from a text-stream. Open stream in text mode (mode='rt') and set correct text
              encoding, the stream requires at least a readline() method.

              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.

              Parameters
                     stream – input text stream opened with correct encoding

              Raises DXFStructureError – for invalid or corrupted DXF structures

              Deprecated  since  version  v0.14:  argument  legacy_mode,  use  module  ezdxf.recover to load DXF
              documents with structural flaws.

       ezdxf.readzip(zipfile: str, filename: str = None, errors: str = 'surrogateescape') -> Drawing
              Load a DXF document specified by filename from a zip archive, or if filename is None the first DXF
              document in the zip archive.

              Parameterszipfile – name of the zip archive

                     • filename  –  filename  of  DXF  file, or None to load the first DXF document from the zip
                       archive.

                     • errors –

                       specify decoding error handler

                       • ”surrogateescape” to preserve possible binary data (default)

                       • ”ignore” to use the replacement char U+FFFD “�” for invalid data

                       • ”strict” to raise an UnicodeDecodeError exception for invalid data

              RaisesIOError – not a DXF file or file does not exist or
                           if filename is None - no DXF file found

                     • DXFStructureError – for invalid or corrupted DXF structures

                     • UnicodeDecodeError – if errors is “strict” and a decoding error occurs

       ezdxf.decode_base64(data: bytes, errors: str = 'surrogateescape') -> Drawing
              Load a DXF document from base64 encoded binary data, like uploaded data to web applications.

              Parametersdata – DXF document base64 encoded binary data

                     • errors –

                       specify decoding error handler

                       • ”surrogateescape” to preserve possible binary data (default)

                       • ”ignore” to use the replacement char U+FFFD “�” for invalid data

                       • ”strict” to raise an UnicodeDecodeError exception for invalid data

              RaisesDXFStructureError – for invalid or corrupted DXF structures

                     • UnicodeDecodeError – if errors is “strict” and a decoding error occurs

       HINT:
          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.

   Save Drawings
       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

   Drawing Settings
       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.

   Header variables set at new
                                ┌─────────────────┬───────────────────────────────────┐
                                │$ACADVER         │ DXF version                       │
                                ├─────────────────┼───────────────────────────────────┤
                                │$TDCREATE        │ date/time at creating the drawing │
                                ├─────────────────┼───────────────────────────────────┤
                                │$FINGERPRINTGUID │ every drawing gets a GUID         │
                                └─────────────────┴───────────────────────────────────┘

   Header variables updated at saving
                                 ─────────────────────────────────────────────────────
                                  $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:                 │             │                                     │
                                 │             │                                     │
          • Howto: set/get header│variables    │                                     │
                                 │             │                                     │
--

HOWTO

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

   Load DXF Files with Structure Errors
       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

   Set/Get Header Variables
       ezdxf has an interface to get and set HEADER variables:

          doc.header['VarName'] = value
          value = doc.header['VarName']

       SEE ALSO:
          HeaderSection and online documentation from Autodesk for available header variables.

   Set DXF Drawing Units
       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     │
                                               └───┴────────────────────┘

   Create More Readable DXF Files (DXF Pretty Printer)
       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:
          This does not render the graphical content of the DXF file to a HTML canvas element.

   Set Initial View/Zoom for the Modelspace
       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.

   DXF Viewer
   A360 Viewer Problems
       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).

   DXF Entities Are Not Displayed in the Viewer
       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))

   Show IMAGES/XREFS on Loading in AutoCAD
       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:
          If the filename in the IMAGEDEF contains the full path (absolute in AutoCAD) then it shows on loading,
          otherwise it won’t display (reports as unreadable) until you manually reload using XREF manager.

          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.

   Set Initial View/Zoom for the Modelspace
       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.

   DXF Content
       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()

   Get/Set Entity Color
       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.

   Get/Set Entity RGB Color
       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.

   Get/Set Block Reference Attributes
       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 to Entities
       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.

   Get Overridden DIMSTYLE Values from DIMENSION
       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.

   Override DIMSTYLE Values for 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()

FAQ

   What is the Relationship between ezdxf, dxfwrite and dxfgrabber?
       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.

RENDERING

       The ezdxf.render subpackage provides helpful utilities to create complex forms.

          • create complex meshes as Mesh entity.

          • render complex curves like bezier curves, euler spirals or splines as Polyline entity

          • vertex generators for simple and complex forms like circle, ellipse or euler spiral

       Content

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

       class ezdxf.render.Spline

              __init__(points: Iterable[Vertex] = None, segments: int = 100)

                     Parameterspoints – spline definition points as Vector or (x, y, z) tuple

                            • segments – count of line segments for approximation, vertex count is segments + 1

              subdivide(segments: int = 4) -> None
                     Calculate  overall  segment  count,  where segments is the sub-segment count, segments = 4,
                     means 4 line segments between two definition points e.g. 4 definition points and 4 segments
                     = 12 overall segments, useful for fit point rendering.

                     Parameters
                            segments – sub-segments count between two definition points

              render_as_fit_points(layout:  BaseLayout, degree: int = 3, method: str = 'chord', dxfattribs: dict
              = None) -> None
                     Render a B-spline as 2D/3D Polyline, where the definition points are fit points.

                        • 2D spline vertices uses: add_polyline2d()

                        • 3D spline vertices uses: add_polyline3d()

                     ParameterslayoutBaseLayout object

                            • degree – degree of B-spline (order = degree + 1)

                            • method  –  “uniform”,  “distance”/”chord”,  “centripetal”/”sqrt_chord”  or   “arc”
                              calculation method for parameter t

                            • dxfattribs – DXF attributes for Polyline

              render_open_bspline(layout: BaseLayout, degree: int = 3, dxfattribs: dict = None) -> None
                     Render an open uniform BSpline as 3D Polyline. Definition points are control points.

                     ParameterslayoutBaseLayout object

                            • degree – degree of B-spline (order = degree + 1)

                            • dxfattribs – DXF attributes for Polyline

              render_uniform_bspline(layout: BaseLayout, degree: int = 3, dxfattribs: dict = None) -> None
                     Render a uniform BSpline as 3D Polyline. Definition points are control points.

                     ParameterslayoutBaseLayout object

                            • degree – degree of B-spline (order = degree + 1)

                            • dxfattribs – DXF attributes for Polyline

              render_closed_bspline(layout: BaseLayout, degree: int = 3, dxfattribs: dict = None) -> None
                     Render a closed uniform BSpline as 3D Polyline. Definition points are control points.

                     ParameterslayoutBaseLayout object

                            • degree – degree of B-spline (order = degree + 1)

                            • dxfattribs – DXF attributes for Polyline

              render_open_rbspline(layout:  BaseLayout,  weights:  Iterable[float], degree: int = 3, dxfattribs:
              dict = None) -> None
                     Render a rational open uniform BSpline  as  3D  Polyline.  Definition  points  are  control
                     points.

                     ParameterslayoutBaseLayout object

                            • weights  –  list  of  weights, requires a weight value (float) for each definition
                              point.

                            • degree – degree of B-spline (order = degree + 1)

                            • dxfattribs – DXF attributes for Polyline

              render_uniform_rbspline(layout: BaseLayout, weights: Iterable[float], degree: int = 3, dxfattribs:
              dict = None) -> None
                     Render a rational uniform BSpline as 3D Polyline. Definition points are control points.

                     ParameterslayoutBaseLayout object

                            • weights  –  list  of  weights, requires a weight value (float) for each definition
                              point.

                            • degree – degree of B-spline (order = degree + 1)

                            • dxfattribs – DXF attributes for Polyline

              render_closed_rbspline(layout: BaseLayout, weights: Iterable[float], degree: int = 3,  dxfattribs:
              dict = None) -> None
                     Render a rational BSpline as 3D Polyline. Definition points are control points.

                     ParameterslayoutBaseLayout object

                            • weights  –  list  of  weights, requires a weight value (float) for each definition
                              point.

                            • degree – degree of B-spline (order = degree + 1)

                            • dxfattribs – DXF attributes for Polyline

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

       class ezdxf.render.R12Spline

              __init__(control_points: Iterable[Vertex], degree: int = 2, closed: bool = True)

                     Parameterscontrol_points  –  B-spline  control  frame  vertices  as  (x, y) tuples or Vector
                              objects

                            • degree – degree of B-spline, 2 or 3 are valid values

                            • closedTrue for closed curve

              render(layout: BaseLayout, segments: int = 40, ucs: UCS  =  None,  dxfattribs:  dict  =  None)  ->
              Polyline
                     Renders  the B-spline into layout as 2D Polyline entity.  Use an UCS to place the 2D spline
                     in 3D space, see approximate() for more information.

                     ParameterslayoutBaseLayout object

                            • segments – count of line segments for approximation, vertex count is segments + 1

                            • ucsUCS definition, control points in ucs coordinates.

                            • dxfattribs – DXF attributes for Polyline

              approximate(segments: int = 40, ucs: UCS = None) -> List[Vertex]
                     Approximate B-spline by a polyline with segments line segments. If ucs  is  not  None,  ucs
                     defines  an  UCS, to transformed the curve into OCS. The control points are placed xy-plane
                     of the UCS, don’t use z-axis coordinates, if so make sure all control points are in a plane
                     parallel to the OCS base plane (UCS xy-plane), else the result is unpredictable and depends
                     on the CAD application used to open the DXF file, it maybe crash.

                     Parameterssegments – count of line segments for approximation, vertex count is segments + 1

                            • ucsUCS definition, control points in ucs coordinates.

                     Returns
                            list of vertices in OCS as Vector objects

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

       class ezdxf.render.Bezier

              start(point: Vertex, tangent: Vertex) -> None
                     Set start point and start tangent.

                     Parameterspoint – start point as Vector or (x, y, z) tuple

                            • tangent  –  start tangent as vector, example: (5, 0, 0) means a horizontal tangent
                              with a length of 5 drawing units

              append(point: Vertex, tangent1: Vertex, tangent2: Vertex = None, segments: int = 20)
                     Append a control point with two control tangents.

                     Parameterspoint – control point as Vector or (x, y, z) tuple

                            • tangent1 – first control tangent as vector “left” of control point

                            • tangent2 – second control tangent as vector “right” of control point,  if  omitted
                              tangent2 = -tangent1segments  –  count  of  line  segments  for  polyline approximation, count of line
                              segments from previous control point to appended control point.

              render(layout: BaseLayout, force3d: bool = False, dxfattribs: dict = None) -> None
                     Render bezier curve as 2D/3D Polyline.

                     ParameterslayoutBaseLayout object

                            • force3d – force 3D polyline rendering

                            • dxfattribs – DXF attributes for Polyline

   EulerSpiral
       Render an euler spiral as 3D Polyline or Spline.

       This is a parametric curve, which always starts at the origin (0, 0).

       class ezdxf.render.EulerSpiral

              __init__(curvature: float = 1)

                     Parameters
                            curvature – Radius of curvature

              render_polyline(layout: BaseLayout, length: float = 1, segments: int =  100,  matrix:  Matrix44  =
              None, dxfattribs: dict = None)
                     Render curve as Polyline.

                     ParameterslayoutBaseLayout object

                            • length – length measured along the spiral curve from its initial position

                            • segments – count of line segments to use, vertex count is segments + 1

                            • matrix – transformation matrix as Matrix44dxfattribs – DXF attributes for Polyline

                     Returns
                            Polyline

              render_spline(layout:  BaseLayout,  length:  float  =  1,  fit_points:  int = 10, degree: int = 3,
              matrix: Matrix44 = None, dxfattribs: dict = None)
                     Render curve as Spline.

                     ParameterslayoutBaseLayout object

                            • length – length measured along the spiral curve from its initial position

                            • fit_points – count of spline fit points to use

                            • degree – degree of B-spline

                            • matrix – transformation matrix as Matrix44dxfattribs – DXF attributes for Spline

                     Returns
                            Spline

   Random Paths
       Random path generators for testing purpose.

       ezdxf.render.random_2d_path(steps=100,   max_step_size=1,   max_heading=pi   /   2,    retarget=20)    ->
       Iterable[Vec2]
              Returns a random 2D path as iterable of Vec2 objects.

              Parameterssteps – count of vertices to generate

                     • max_step_size – max step size

                     • max_heading – limit heading angle change per step to ± max_heading/2 in radians

                     • retarget – specifies steps before changing global walking target

       ezdxf.render.random_3d_path(steps=100,   max_step_size=1,   max_heading=pi   /   2,   max_pitch=pi  /  8,
       retarget=20) -> Iterable[Vector]
              Returns a random 3D path as iterable of Vector objects.

              Parameterssteps – count of vertices to generate

                     • max_step_size – max step size

                     • max_heading – limit heading angle change per step to ± max_heading/2, rotation about  the
                       z-axis in radians

                     • max_pitch – limit pitch angle change per step to ± max_pitch/2, rotation about the x-axis
                       in radians

                     • retarget – specifies steps before changing global walking target

   Forms
          This module provides functions to create 2D and 3D forms as vertices or mesh objects.

          2D Forms

          • circle()square()box()ellipse()euler_spiral()ngon()star()gear()

          3D Forms

          • cube()cylinder()cylinder_2p()cone()cone_2p()sphere()

          3D Form Builder

          • extrude()from_profiles_linear()from_profiles_spline()rotation_form()

   2D Forms
          Basic 2D shapes as iterable of Vector.

       ezdxf.render.forms.circle(count: int, radius: float = 1, elevation: float = 0, close: bool  =  False)  ->
       Iterable[Vector]
              Create  polygon  vertices  for a circle with radius and count corners, elevation is the z-axis for
              all vertices.

              Parameterscount – count of polygon vertices

                     • radius – circle radius

                     • elevation – z-axis for all vertices

                     • close – yields first vertex also as last vertex if True.

              Returns
                     vertices in counter clockwise orientation as Vector objects

       ezdxf.render.forms.square(size: float = 1.) -> Tuple[Vector, Vector, Vector, Vector]
              Returns 4 vertices for a square with a side length of size, lower left corner  is  (0,  0),  upper
              right corner is (size, size).

       ezdxf.render.forms.box(sx: float = 1., sy: float = 1.) -> Tuple[Vector, Vector, Vector, Vector]
              Returns  4  vertices  for  a box sx by sy, lower left corner is (0, 0), upper right corner is (sx,
              sy).

       ezdxf.render.forms.ellipse(count: int, rx: float = 1, ry: float = 1, start_param: float =  0,  end_param:
       float = 2 * pi, elevation: float = 0) -> Iterable[Vector]
              Create  polygon  vertices  for  an  ellipse with rx as x-axis radius and ry for y-axis radius with
              count vertices, elevation is the z-axis for all vertices. The ellipse  goes  from  start_param  to
              end_param in counter clockwise orientation.

              Parameterscount – count of polygon vertices

                     • rx – ellipse x-axis radius

                     • ry – ellipse y-axis radius

                     • start_param – start of ellipse in range 0 .. 2*piend_param – end of ellipse in range 0 .. 2*pielevation – z-axis for all vertices

              Returns
                     vertices in counter clockwise orientation as Vector objects

       ezdxf.render.forms.euler_spiral(count:  int,  length: float = 1, curvature: float = 1, elevation: float =
       0) -> Iterable[Vector]
              Create polygon vertices for an euler spiral of a given length and radius of curvature. This  is  a
              parametric curve, which always starts at the origin (0, 0).

              Parameterscount – count of polygon vertices

                     • length – length of curve in drawing units

                     • curvature – radius of curvature

                     • elevation – z-axis for all vertices

              Returns
                     vertices as Vector objects

       ezdxf.render.forms.ngon(count:  int,  length:  float  = None, radius: float = None, rotation: float = 0.,
       elevation: float = 0., close: bool = False) -> Iterable[Vector]
              Returns the corner vertices of a regular polygon.  The polygon size  is  determined  by  the  edge
              length or the circum radius argument.  If both are given length has higher priority.

              Parameterscount – count of polygon corners >= 3length – length of polygon side

                     • radius – circum radius

                     • rotation – rotation angle in radians

                     • elevation – z-axis for all vertices

                     • close – yields first vertex also as last vertex if True.

              Returns
                     vertices as Vector objects

       ezdxf.render.forms.star(count:  int,  r1:  float, r2: float, rotation: float = 0., elevation: float = 0.,
       close: bool = False) -> Iterable[Vector]
              Returns corner vertices for star shapes.

              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.

              Parameterscount – spike count >= 3r1 – radius 1

                     • r2 – radius 2

                     • rotation – rotation angle in radians

                     • elevation – z-axis for all vertices

                     • close – yields first vertex also as last vertex if True.

              Returns
                     vertices as Vector objects

       ezdxf.render.forms.gear(count: int, top_width: float, bottom_width: float, height: float, outside_radius:
       float, elevation: float = 0, close: bool = False) -> Iterable[Vector]
              Returns gear (cogwheel) corner vertices.

              WARNING:
                 This function does not create correct gears for mechanical engineering!

              Parameterscount – teeth count >= 3top_width – teeth width at outside radius

                     • bottom_width – teeth width at base radius

                     • height – teeth height; base radius = outside radius - height

                     • outside_radius – outside radius

                     • elevation – z-axis for all vertices

                     • close – yields first vertex also as last vertex if True.

              Returns
                     vertices in counter clockwise orientation as Vector objects

   3D Forms
       Create 3D forms as MeshTransformer objects.

       ezdxf.render.forms.cube(center: bool = True) -> MeshTransformer
              Create a cube as MeshTransformer object.

              Parameters
                     center – ‘mass’ center of cube, (0, 0, 0) if True, else first corner at (0, 0, 0)

              Returns: MeshTransformer

       ezdxf.render.forms.cylinder(count:  int, radius: float = 1., top_radius: float = None, top_center: Vertex
       = (0, 0, 1), caps=True, ngons=True) -> MeshTransformer
              Create a cylinder as MeshTransformer object, the base center is fixed in the origin (0, 0, 0).

              Parameterscount – profiles edge count

                     • radius – radius for bottom profile

                     • top_radius – radius for top profile, if None top_radius == radius

                     • top_center – location vector for the center of the top profile

                     • caps – close hull with bottom cap and top cap (as N-gons)

                     • ngons – use ngons for caps if True else subdivide caps into triangles

              Returns: MeshTransformer

       ezdxf.render.forms.cylinder_2p(count: int = 16, radius: float = 1, base_center=(0, 0, 0),  top_center=(0,
       0, 1)) -> MeshTransformer
              Create a cylinder as MeshTransformer object from two points, base_center is the center of the base
              circle and, top_center the center of the top circle.

              Parameterscount – profiles edge count

                     • radius – radius for bottom profile

                     • base_center – center of base circle

                     • top_center – center of top circle

              Returns: MeshTransformer

              New in version 0.11.

       ezdxf.render.forms.cone(count: int, radius: float, apex: Vertex = (0, 0, 1),  caps=True,  ngons=True)  ->
       MeshTransformer
              Create a cone as MeshTransformer object, the base center is fixed in the origin (0, 0, 0).

              Parameterscount – edge count of basis_vector

                     • radius – radius of basis_vector

                     • apex – tip of the cone

                     • caps – add a bottom face if Truengons – use ngons for caps if True else subdivide caps into triangles

              Returns: MeshTransformer

       ezdxf.render.forms.cone_2p(count: int, radius: float, apex: Vertex = (0, 0, 1)) -> MeshTransformer
              Create  a  cone  as  MeshTransformer object from two points, base_center is the center of the base
              circle and apex as the tip of the cone.

              Parameterscount – edge count of basis_vector

                     • radius – radius of basis_vector

                     • base_center – center point of base circle

                     • apex – tip of the cone

              Returns: MeshTransformer

              New in version 0.11.

       ezdxf.render.forms.sphere(count: int  =  16,  stacks:  int  =  8,  radius:  float  =  1,  quads=True)  ->
       MeshTransformer
              Create a sphere as MeshTransformer object, center is fixed at origin (0, 0, 0).

              Parameterscount – longitudinal slices

                     • stacks – latitude slices

                     • radius – radius of sphere

                     • quads – use quads for body faces if True else triangles

              Returns: MeshTransformer

              New in version 0.11.

   3D Form Builder
       ezdxf.render.forms.extrude(profile:    Iterable[Vertex],    path:    Iterable[Vertex],   close=True)   ->
       MeshTransformer
              Extrude a profile polygon along a  path  polyline,  vertices  of  profile  should  be  in  counter
              clockwise order.

              Parametersprofile – sweeping profile as list of (x, y, z) tuples in counter clock wise order

                     • path – extrusion path as list of (x, y, z) tuples

                     • close – close profile polygon if True

              Returns: MeshTransformer

       ezdxf.render.forms.from_profiles_linear(profiles:   Iterable[Iterable[Vertex]],  close=True,  caps=False,
       ngons=True) -> MeshTransformer
              Create MESH entity by linear connected profiles.

              Parametersprofiles – list of profiles

                     • close – close profile polygon if Truecaps – close hull with bottom cap and top cap

                     • ngons – use ngons for caps if True else subdivide caps into triangles

              Returns: MeshTransformer

       ezdxf.render.forms.from_profiles_spline(profiles:  Iterable[Iterable[Vertex]],  subdivide:   int   =   4,
       close=True, caps=False, ngons=True) -> MeshTransformer
              Create  MESH  entity by spline interpolation between given profiles. Requires at least 4 profiles.
              A subdivide value of 4, means, create 4 face loops between two profiles, without interpolation two
              profiles create one face loop.

              Parametersprofiles – list of profiles

                     • subdivide – count of face loops

                     • close – close profile polygon if Truecaps – close hull with bottom cap and top cap

                     • ngons – use ngons for caps if True else subdivide caps into triangles

              Returns: MeshTransformer

       ezdxf.render.forms.rotation_form(count:  int,  profile:  Iterable[Vertex],  angle:  float = 2 * pi, axis:
       Vertex = (1, 0, 0)) -> MeshTransformer
              Create MESH entity by rotating a profile around an axis.

              Parameterscount – count of rotated profiles

                     • profile – profile to rotate as list of vertices

                     • angle – rotation angle in radians

                     • axis – rotation axis

              Returns: MeshTransformer

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

       class ezdxf.render.MeshBuilder

              vertices
                     List of vertices as Vector or (x, y, z) tuple

              edges  List of edges as 2-tuple of vertex indices, where a vertex index is the index of the vertex
                     in the vertices list.

              faces  List of faces as list of vertex indices,  where a vertex index is the index of  the  vertex
                     in  the vertices list. A face requires at least three vertices, Mesh supports ngons, so the
                     count of vertices is not limited.

              copy() Returns a copy of mesh.

              faces_as_vertices() -> Iterable[List[Vector]]
                     Iterate over all mesh faces as list of vertices.

              edges_as_vertices() -> Iterable[Tuple[Vector, Vector]]
                     Iterate over all mesh edges as tuple of two vertices.

              add_vertices(vertices: Iterable[Vertex]) -> Sequence[int]
                     Add new vertices to the mesh, each vertex is a (x, y, z) tuple or a Vector object,  returns
                     the indices of the vertices added to the vertices list.

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

                     Parameters
                            vertices – list of vertices, vertex as (x, y, z) tuple or Vector objects

                     Returns
                            indices of the vertices added to the vertices list

                     Return type
                            tuple

              add_edge(vertices: Iterable[Vertex]) -> None
                     An edge consist of two vertices [v1, v2], each vertex is a (x, y,  z)  tuple  or  a  Vector
                     object. The new vertex indices are stored as edge in the edges list.

                     Parameters
                            vertices – list of 2 vertices : [(x1, y1, z1), (x2, y2, z2)]

              add_face(vertices: Iterable[Vertex]) -> None
                     Add  a  face as vertices list to the mesh. A face requires at least 3 vertices, each vertex
                     is a (x, y, z) tuple or Vector object. The new vertex indices are stored  as  face  in  the
                     faces list.

                     Parameters
                            vertices  –  list  of at least 3 vertices [(x1, y1, z1), (x2, y2, z2), (x3, y3, y3),
                            ...]

              add_mesh(vertices=None, faces=None, edges=None, mesh=None) -> None
                     Add another mesh to this mesh.

                     A mesh can be a MeshBuilder, MeshVertexMerger or Mesh object  or  requires  the  attributes
                     vertices, edges and faces.

                     Parametersvertices – list of vertices, a vertex is a (x, y, z) tuple or Vector object

                            • faces – list of faces, a face is a list of vertex indices

                            • edges – list of edges, an edge is a list of vertex indices

                            • mesh – another mesh entity

              has_none_planar_faces() -> bool
                     Returns True if any face is none planar.

              render(layout: BaseLayout, dxfattribs: dict = None, matrix: Matrix44 = None, ucs: UCS = None)
                     Render mesh as Mesh entity into layout.

                     ParameterslayoutBaseLayout object

                            • dxfattribs – dict of DXF attributes e.g. {'layer': 'mesh', 'color': 7}matrix – transformation matrix of type Matrix44ucs – transform vertices by UCS to WCS

              render_polyface(layout:  BaseLayout,  dxfattribs: dict = None, matrix: Matrix44 = None, ucs: UCS =
              None)
                     Render mesh as Polyface entity into layout.

                     New in version 0.11.1.

                     ParameterslayoutBaseLayout object

                            • dxfattribs – dict of DXF attributes e.g. {'layer': 'mesh', 'color': 7}matrix – transformation matrix of type Matrix44ucs – transform vertices by UCS to WCS

              render_3dfaces(layout: BaseLayout, dxfattribs: dict = None, matrix: Matrix44 = None,  ucs:  UCS  =
              None)
                     Render mesh as Face3d entities into layout.

                     New in version 0.12.

                     ParameterslayoutBaseLayout object

                            • dxfattribs – dict of DXF attributes e.g. {'layer': 'mesh', 'color': 7}matrix – transformation matrix of type Matrix44ucs – transform vertices by UCS to WCS

              render_normals(layout: BaseLayout, length: float = 1, relative=True, dxfattribs: dict = None)
                     Render  face  normals  as  Line  entities  into layout, useful to check orientation of mesh
                     faces.

                     ParameterslayoutBaseLayout object

                            • length – visual length of normal, use length < 0  to  point  normals  in  opposite
                              direction

                            • relative – scale length relative to face size if Truedxfattribs – dict of DXF attributes e.g. {'layer': 'normals', 'color': 6}

              classmethod from_mesh(other) -> ezdxf.render.mesh.MeshBuilder
                     Create new mesh from other mesh as class method.

                     Parameters
                            othermesh  of  type  MeshBuilder and inherited or DXF Mesh entity or any object
                            providing attributes vertices, edges and faces.

              classmethod from_polyface(other: Union[Polymesh, Polyface]) -> MeshBuilder
                     Create new mesh from a  Polyface or Polymesh object.

                     New in version 0.11.1.

              classmethod from_builder(other: MeshBuilder)
                     Create new mesh from  other  mesh  builder,  faster  than  from_mesh()  but  supports  only
                     MeshBuilder and inherited classes.

   MeshTransformer
       Same functionality as MeshBuilder but supports inplace transformation.

       class ezdxf.render.MeshTransformer
              Subclass of MeshBuilder

              subdivide(level: int = 1, quads=True, edges=False) -> MeshTransformer
                     Returns a new MeshTransformer object with subdivided faces and edges.

                     Parameterslevel – subdivide levels from 1 to max of 5

                            • quads – create quad faces if True else create triangles

                            • edges – also subdivide edges if True

              transform(matrix: Matrix44)
                     Transform mesh inplace by applying the transformation matrix.

                     Parameters
                            matrix – 4x4 transformation matrix as Matrix44 object

              translate(dx: float = 0, dy: float = 0, dz: float = 0)
                     Translate mesh inplace.

                     Parametersdx – translation in x-axis

                            • dy – translation in y-axis

                            • dz – translation in z-axis

              scale(sx: float = 1, sy: float = 1, sz: float = 1)
                     Scale mesh inplace.

                     Parameterssx – scale factor for x-axis

                            • sy – scale factor for y-axis

                            • sz – scale factor for z-axis

              scale_uniform(s: float)
                     Scale mesh uniform inplace.

                     Parameters
                            s – scale factor for x-, y- and z-axis

              rotate_x(angle: float)
                     Rotate mesh around x-axis about angle inplace.

                     Parameters
                            angle – rotation angle in radians

              rotate_y(angle: float)
                     Rotate mesh around y-axis about angle inplace.

                     Parameters
                            angle – rotation angle in radians

              rotate_z(angle: float)
                     Rotate mesh around z-axis about angle inplace.

                     Parameters
                            angle – rotation angle in radians

              rotate_axis(axis: Vertex, angle: float)
                     Rotate mesh around an arbitrary axis located in the origin (0, 0, 0) about angle.

                     Parametersaxis – rotation axis as Vector

                            • angle – rotation angle in radians

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

       class ezdxf.render.MeshVertexMerger(precision: int = 6)
              Subclass of MeshBuilder

              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.

              Parameters
                     precision – floating point precision for vertex rounding

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

       class ezdxf.render.MeshAverageVertexMerger(precision: int = 6)
              Subclass of MeshBuilder

              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.

              Parameters
                     precision – floating point precision for vertex rounding

   Trace
       This module provides tools to create banded lines like LWPOLYLINE with width information.  Path rendering
       as quadrilaterals: Trace, Solid or Face3d.

       class ezdxf.render.trace.TraceBuilder
              Sequence of 2D banded lines like polylines with start- and end width or curves with start- and end
              width.

              Accepts 3D input, but z-axis is ignored.

              abs_tol
                     Absolute tolerance for floating point comparisons

              append(trace: ezdxf.render.trace.AbstractTrace) -> None
                     Append a new trace.

              close()
                     Close multi traces by merging first and last trace, if linear traces.

              faces() -> Iterable[Tuple[Vec2, Vec2, Vec2, Vec2]
                     Yields all faces as 4-tuples of Vec2 objects.

              virtual_entities(dxftype='TRACE', dxfattribs: Dict = None, doc: Drawing =  None)  ->  Union[Solid,
              Trace, Face3d]
                     Yields faces as SOLID, TRACE or 3DFACE entities with DXF attributes given in dxfattribs.

                     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.

                     Parametersdxftype – DXF type as string, “SOLID”, “TRACE” or “3DFACE”

                            • dxfattribs – DXF attributes for SOLID, TRACE or 3DFACE entities

                            • doc – associated document

              classmethod from_polyline(polyline: DXFGraphic, segments: int = 64) -> TraceBuilder
                     Create a complete trace from a LWPOLYLINE or a 2D POLYLINE entity,  the  trace  consist  of
                     multiple sub-traces if bulge values are present.

                     ParameterspolylineLWPolyline or 2D Polylinesegments  –  count  of segments for bulge approximation, given count is for a full
                              circle, partial arcs have proportional less segments, but at least 3

              __len__()

              __getitem__(item)

       class ezdxf.render.trace.LinearTrace
              Linear 2D banded lines like polylines with start- and end width.

              Accepts 3D input, but z-axis is ignored.

              abs_tol
                     Absolute tolerance for floating point comparisons

              is_started
                     True if at least one station exist.

              add_station(point: Vertex, start_width: float, end_width: float = None) -> None
                     Add a trace station (like a vertex) at location point, start_width is the width of the next
                     segment starting at this station, end_width is the end width of the next segment.

                     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.

                     Parameterspoint – 2D location (vertex), z-axis of 3D vertices is ignored.

                            • start_width – start width of next segment

                            • end_width – end width of next segment

              faces() -> Iterable[Tuple[Vec2, Vec2, Vec2, Vec2]
                     Yields all faces as 4-tuples of Vec2 objects.

                     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.

              virtual_entities(dxftype='TRACE',  dxfattribs:  Dict  = None, doc: Drawing = None) -> Union[Solid,
              Trace, Face3d]
                     Yields faces as SOLID, TRACE or 3DFACE entities with DXF attributes given in dxfattribs.

                     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.

                     Parametersdxftype – DXF type as string, “SOLID”, “TRACE” or “3DFACE”

                            • dxfattribs – DXF attributes for SOLID, TRACE or 3DFACE entities

                            • doc – associated document

       class ezdxf.render.trace.CurvedTrace
              2D banded curves like arcs or splines with start- and end width.

              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.

              faces() -> Iterable[Tuple[Vec2, Vec2, Vec2, Vec2]
                     Yields all faces as 4-tuples of Vec2 objects.

              virtual_entities(dxftype='TRACE', dxfattribs: Dict = None, doc: Drawing =  None)  ->  Union[Solid,
              Trace, Face3d]
                     Yields faces as SOLID, TRACE or 3DFACE entities with DXF attributes given in dxfattribs.

                     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.

                     Parametersdxftype – DXF type as string, “SOLID”, “TRACE” or “3DFACE”

                            • dxfattribs – DXF attributes for SOLID, TRACE or 3DFACE entities

                            • doc – associated document

              classmethod from_arc(arc: ezdxf.math.arc.ConstructionArc, start_width:  float,  end_width:  float,
              segments: int = 64) -> ezdxf.render.trace.CurvedTrace
                     Create curved trace from an arc.

                     ParametersarcConstructionArc object

                            • start_width – start width

                            • end_width – end width

                            • segments  –  count of segments for full circle (360 degree) approximation, partial
                              arcs have proportional less segments, but at least 3

                     Raises ValueError – if arc.radius <= 0

              classmethod from_spline(spline: ezdxf.math.bspline.BSpline, start_width: float, end_width:  float,
              segments: int) -> ezdxf.render.trace.CurvedTrace
                     Create curved trace from a B-spline.

                     ParameterssplineBSpline object

                            • start_width – start width

                            • end_width – end width

                            • segments – count of segments for approximation

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

       •

         matplotlib: PathPatch

                • matplotlib.path.Path() codes:

                • MOVETO

                • LINETO

                • CURVE4 - cubic Bèzier-curve

       •

         PyQt: QPainterPath

                • moveTo()

                • lineTo()

                • cubicTo() - cubic Bèzier-curve

       •

         PyCairo: Context

                • move_to()

                • line_to()

                • curve_to() - cubic Bèzier-curve

       •

         SVG: SVG-Path

                • “M” - absolute move to

                • “L” - absolute line to

                • “C” - absolute cubic Bèzier-curve

       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.

       class ezdxf.render.path.Path

              start  Path start point, resetting the start point of an empty path is possible.

              end    Path end point.

              is_closed
                     Returns True if the start point is close to the end point.

              classmethod from_lwpolyline(lwpolyline: LWPolyline) -> Path
                     Returns a Path from a LWPolyline entity, all vertices transformed to WCS.

              classmethod from_polyline(polyline: Polyline) -> Path
                     Returns a Path from a Polyline entity, all vertices transformed to WCS.

              classmethod from_spline(spline: Spline, level: int = 4) -> Path
                     Returns a Path from a Spline.

              classmethod from_ellipse(ellipse: Ellipse, segments: int = 1) -> Path
                     Returns a Path from a Ellipse.

              classmethod from_arc(arc: Arc, segments: int = 1) -> Path
                     Returns a Path from an Arc.

              classmethod from_circle(circle: Circle, segments: int = 1) -> Path
                     Returns a Path from a Circle.

              classmethod  from_hatch_polyline_path(polyline:  PolylinePath,  ocs:  ezdxf.math.ucs.OCS  =  None,
              elevation: float = 0) -> Path
                     Returns a Path from a Hatch polyline path.

              classmethod from_hatch_edge_path(edges: EdgePath, ocs: ezdxf.math.ucs.OCS = None, elevation: float
              = 0) -> Path
                     Returns a Path from a Hatch edge path.

              control_vertices()
                     Yields all path control vertices in consecutive order.

              has_clockwise_orientation() -> bool
                     Returns True if 2D path has clockwise orientation, ignores z-axis of all control vertices.

              line_to(location: Vector)
                     Add a line from actual path end point to location.

              curve_to(location: Vector, ctrl1: Vector, ctrl2: Vector)
                     Add  a  cubic  Bèzier-curve from actual path end point to location, ctrl1 and ctrl2 are the
                     control points for the cubic Bèzier-curve.

              close() -> None
                     Close path by adding a line segment from the end point to the start point.

              clone() -> Path
                     Returns a new copy of Path with shared immutable data.

              reversed() -> Path
                     Returns a new Path with reversed segments and control vertices.

              clockwise() -> Path
                     Returns new Path in clockwise orientation.

              counter_clockwise() -> Path
                     Returns new Path in counter-clockwise orientation.

              add_curves(curves: Iterable[Bezier4P])
                     Add multiple cubic Bèzier-curves to the path.

                     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.

              add_ellipse(ellipse: ConstructionEllipse, segments=1)
                     Add an elliptical arc as multiple cubic Bèzier-curves, use from_arc() constructor of  class
                     ConstructionEllipse to add circular arcs.

                     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.

                     Parametersellipse – ellipse parameters as ConstructionEllipse object

                            • segments  –  count of Bèzier-curve segments, at least one segment for each quarter
                              (pi/2), 1 for as few as possible.

                            • reset – set start point to start of ellipse if path is empty

              add_spline(spline: BSpline, level=4)
                     Add a B-spline as multiple cubic Bèzier-curves.

                     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.

                     Parametersspline – B-spline parameters as BSpline object

                            • level – subdivision level of approximation segments

                            • reset – set start point to start of spline if path is empty

              transform(m: Matrix44) -> Path
                     Returns a new transformed path.

                     Parameters
                            m – transformation matrix of type Matrix44

              approximate(segments: int) -> Iterable[Vector]
                     Approximate path by vertices, segments is the count  of  approximation  segments  for  each
                     cubic bezier curve.

ADD-ONS

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

       • CONTINUOUS

       • CENTER ____ _ ____ _ ____ _ ____ _ ____ _ ____

       • CENTERX2 ________  __  ________  __  ________

       • CENTER2 ____ _ ____ _ ____ _ ____ _ ____

       • DASHED __ __ __ __ __ __ __ __ __ __ __ __ __ _

       • DASHEDX2 ____  ____  ____  ____  ____  ____

       • DASHED2 _ _ _ _ _ _ _ _ _ _ _ _ _ _

       • PHANTOM ______  __  __  ______  __  __  ______

       • PHANTOMX2 ____________    ____    ____    ____________

       • PHANTOM2 ___ _ _ ___ _ _ ___ _ _ ___ _ _ ___

       • DASHDOT __ . __ . __ . __ . __ . __ . __ . __

       • DASHDOTX2 ____  .  ____  .  ____  .  ____

       • DASHDOT2 _ . _ . _ . _ . _ . _ . _ . _

       • DOT .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .

       • DOTX2 .    .    .    .    .    .    .    .

       • DOT2 . . . . . . . . . . . . . . . . . . .

       • DIVIDE __ . . __ . . __ . . __ . . __ . . __

       • DIVIDEX2 ____  . .  ____  . .  ____  . .  ____

       • DIVIDE2 _ . _ . _ . _ . _ . _ . _ . _

       If using FIXED-TABLES, following predefined text styles are available:

       • OpenSans

       • OpenSansCondensed-Light

       New in version 0.12: Write Binary DXF files.

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

   Reference
       ezdxf.addons.r12writer.r12writer(stream: Union[TextIO, BinaryIO, str], fixed_tables=False, fmt='asc')  ->
       R12FastStreamWriter
              Context manager for writing DXF entities to a stream/file. stream can be any file like object with
              a write() method or just a string for writing DXF entities to the file system.  If fixed_tables is
              True,  a  standard  TABLES section is written in front of the ENTITIES section and some predefined
              text styles and line types can be used.

              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.

       class     ezdxf.addons.r12writer.R12FastStreamWriter(stream:     [<class     'typing.TextIO'>,     <class
       'ezdxf.addons.r12writer.BinaryDXFWriter'>], fixed_tables=False)
              Fast stream writer to create simple DXF R12 drawings.

              Parametersstream – a file like object with a write() method.

                     • fixed_tables – if fixed_tables is True, a standard TABLES section is written in front  of
                       the ENTITIES section and some predefined text styles and line types can be used.

              close() -> None
                     Writes the DXF tail. Call is not necessary when using the context manager r12writer().

              add_line(start:  Sequence[float],  end:  Sequence[float],  layer:  str  =  '0', color: int = None,
              linetype: str = None) -> None
                     Add a LINE entity from start to end.

                     Parametersstart – start vertex as (x, y[, z]) tuple

                            • end – end vertex as  as (x, y[, z]) tuple

                            • layer – layer name as string, without a layer definition the assigned  color  =  7
                              (black/white) and line type is 'Continuous'.

                            • color  – color as ACI in the range from 0 to 256, 0 is ByBlock and 256 is ByLayer,
                              default is ByLayer which is  always  color  =  7  (black/white)  without  a  layer
                              definition.

                            • linetype  –  line type as string, if FIXED-TABLES are written some predefined line
                              types  are  available,  else  line  type  is  always  ByLayer,  which  is   always
                              'Continuous' without a LAYERS table.

              add_circle(center:  Sequence[float], radius: float, layer: str = '0', color: int = None, linetype:
              str = None) -> None
                     Add a CIRCLE entity.

                     Parameterscenter – circle center point as (x, y) tuple

                            • radius – circle radius as float

                            • layer – layer name as string see add_line()color – color as ACI see add_line()linetype – line type as string see add_line()

              add_arc(center: Sequence[float], radius: float, start: float = 0, end: float = 360, layer:  str  =
              '0', color: int = None, linetype: str = None) -> None
                     Add an ARC entity. The arc goes counter clockwise from start angle to end angle.

                     Parameterscenter – arc center point as (x, y) tuple

                            • radius – arc radius as float

                            • start – arc start angle in degrees as float

                            • end – arc end angle in degrees as float

                            • layer – layer name as string see add_line()color – color as ACI see add_line()linetype – line type as string see add_line()

              add_point(location: Sequence[float], layer: str = '0', color: int = None, linetype: str = None) ->
              None
                     Add a POINT entity.

                     Parameterslocation – point location as (x, y [,z]) tuple

                            • layer – layer name as string see add_line()color – color as ACI see add_line()linetype – line type as string see add_line()

              add_3dface(vertices: Iterable[Sequence[float]], invisible: int = 0, layer: str = '0', color: int =
              None, linetype: str = None) -> None
                     Add a 3DFACE entity. 3DFACE is a spatial area with 3 or 4 vertices, all vertices have to be
                     in the same plane.

                     Parametersvertices – iterable of 3 or 4 (x, y, z) vertices.

                            • invisible –

                              bit coded flag to define the invisible edges,

                              1. edge = 1

                              2. edge = 2

                              3. edge = 4

                              4. edge = 8

                              Add edge values to set multiple edges invisible, 1. edge + 3. edge = 1 +  4  =  5,
                              all edges = 15

                            • layer – layer name as string see add_line()color – color as ACI see add_line()linetype – line type as string see add_line()

              add_solid(vertices:  Iterable[Sequence[float]], layer: str = '0', color: int = None, linetype: str
              = None) -> None
                     Add a SOLID entity. SOLID is a solid filled area with 3 or  4  edges  and  SOLID  is  a  2D
                     entity.

                     Parametersvertices – iterable of 3 or 4 (x, y[, z]) tuples, z-axis will be ignored.

                            • layer – layer name as string see add_line()color – color as ACI see add_line()linetype – line type as string see add_line()

              add_polyline_2d(points: Iterable[Sequence], format: str = 'xy', closed: bool = False, start_width:
              float = 0, end_width: float = 0, layer: str = '0', color: int = None, linetype:  str  =  None)  ->
              None
                     Add a 2D POLYLINE entity with start width, end width and bulge value support.

                     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) │
                                               └──┴──────────────────────────────────┘

                     Parameterspoints  –  iterable  of  (x,  y, [start_width, [end_width, [bulge]]]) tuple, value
                              order according to the format string, unset values default to 0format – format: format string, default is 'xy'closedTrue creates a closed polyline

                            • start_width – default start width, default is 0end_width – default end width, default is 0layer – layer name as string see add_line()color – color as ACI see add_line()linetype – line type as string see add_line()

              add_polyline(vertices: Iterable[Sequence[float]], closed: bool = False, layer: str =  '0',  color:
              int = None, linetype: str = None) -> None
                     Add a 3D POLYLINE entity.

                     Parametersvertices – iterable of (x, y[, z]) tuples, z-axis is 0 by default

                            • closedTrue creates a closed polyline

                            • layer – layer name as string see add_line()color – color as ACI see add_line()linetype – line type as string see add_line()

                     Changed in version 0.12: Write only 3D POLYLINE entity, added closed argument.

              add_polyface(vertices:  Iterable[Sequence[float]],  faces:  Iterable[Sequence[int]],  layer: str =
              '0', color: int = None, linetype: str = None) -> None
                     Add a POLYFACE entity. The POLYFACE entity supports only faces of maximum 4 vertices,  more
                     indices will be ignored. A simple square would be:

                        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

                     Parametersvertices – iterable of (x, y, z) tuples

                            • faces – iterable of 3 or 4 vertex indices, indices have to be 0-based

                            • layer – layer name as string see add_line()color – color as ACI see add_line()linetype – line type as string see add_line()

              add_polymesh(vertices: Iterable[Sequence[float]], size: Tuple[int,  int],  closed=(False,  False),
              layer: str = '0', color: int = None, linetype: str = None) -> None
                     Add  a  POLYMESH entity. A POLYMESH is a mesh of m rows and n columns, each mesh vertex has
                     its own x-, y- and z coordinates. The mesh can be closed  in  m-  and/or  n-direction.  The
                     vertices  have  to  be  in column order:  (m0, n0), (m0, n1), (m0, n2), (m1, n0), (m1, n1),
                     (m1, n2), …

                     See example: https://github.com/mozman/ezdxf/blob/master/examples/r12writer.py

                     Parametersvertices – iterable of (x, y, z) tuples, in column order

                            • size – mesh dimension as (m, n)-tuple, requirement: len(vertices) == m*nclosed – (m_closed, n_closed) tuple, for closed mesh in m and/or n direction

                            • layer – layer name as string see add_line()color – color as ACI see add_line()linetype – line type as string see add_line()

              add_text(text: str, insert: Sequence[float] = (0, 0), height: float = 1.0,  width:  float  =  1.0,
              align:  str = 'LEFT', rotation: float = 0.0, oblique: float = 0.0, style: str = 'STANDARD', layer:
              str = '0', color: int = None) -> None
                     Add a one line TEXT entity.

                     Parameterstext – the text as string

                            • insert – insert location as (x, y) tuple

                            • height – text height in drawing units

                            • width – text width as factor

                            • align – text alignment, see table below

                            • rotation – text rotation in degrees as float

                            • oblique – oblique in degrees as float, vertical = 0 (default)

                            • style – text style name as string, if FIXED-TABLES  are  written  some  predefined
                              text styles are available, else text style is always 'STANDARD'.

                            • layer – layer name as string see add_line()color – color as ACI see add_line()

                                      ┌───────────┬─────────────┬───────────────┬──────────────┐
                                      │Vert/Horiz │ Left        │ Center        │ Right        │
                                      ├───────────┼─────────────┼───────────────┼──────────────┤
                                      │Top        │ TOP_LEFTTOP_CENTERTOP_RIGHT    │
                                      ├───────────┼─────────────┼───────────────┼──────────────┤
                                      │Middle     │ MIDDLE_LEFTMIDDLE_CENTERMIDDLE_RIGHT │
                                      ├───────────┼─────────────┼───────────────┼──────────────┤
                                      │Bottom     │ BOTTOM_LEFTBOTTOM_CENTERBOTTOM_RIGHT │
                                      ├───────────┼─────────────┼───────────────┼──────────────┤
                                      │Baseline   │ LEFTCENTERRIGHT        │
                                      └───────────┴─────────────┴───────────────┴──────────────┘

                     The special alignments ALIGNED and FIT are not available.

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

       ezdxf.addons.iterdxf.opendxf(filename: str, errors: str = 'surrogateescape') -> IterDXF
              Open  DXF  file  for  iterating,  be sure to open valid DXF files, no DXF structure checks will be
              applied.

              Use this function to split up big DXF files as shown in the example above.

              Parametersfilename – DXF filename of a seekable DXF file.

                     • errors –

                       specify decoding error handler

                       • ”surrogateescape” to preserve possible binary data (default)

                       • ”ignore” to use the replacement char U+FFFD “�” for invalid data

                       • ”strict” to raise an UnicodeDecodeError exception for invalid data

              RaisesDXFStructureError – invalid or incomplete DXF file

                     • UnicodeDecodeError – if errors is “strict” and a decoding error occurs

       ezdxf.addons.iterdxf.modelspace(filename:   str,   types:   Iterable[str]   =   None,   errors:   str   =
       'surrogateescape') -> Iterable[DXFGraphic]
              Iterate over all modelspace entities as DXFGraphic objects of a seekable file.

              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.

              Parametersfilename – filename of a seekable DXF file

                     • types – DXF types like ['LINE', '3DFACE'] which should  be  returned,  None  returns  all
                       supported types.

                     • errors –

                       specify decoding error handler

                       • ”surrogateescape” to preserve possible binary data (default)

                       • ”ignore” to use the replacement char U+FFFD “�” for invalid data

                       • ”strict” to raise an UnicodeDecodeError exception for invalid data

              RaisesDXFStructureError – invalid or incomplete DXF file

                     • UnicodeDecodeError – if errors is “strict” and a decoding error occurs

       ezdxf.addons.iterdxf.single_pass_modelspace(stream:  BinaryIO, types: Iterable[str] = None, errors: str =
       'surrogateescape') -> Iterable[DXFGraphic]
              Iterate over all modelspace entities as DXFGraphic objects in one single pass.

              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.

              Parametersstream – (not seekable) binary DXF stream

                     • types  –  DXF  types  like  ['LINE', '3DFACE'] which should be returned, None returns all
                       supported types.

                     • errors –

                       specify decoding error handler

                       • ”surrogateescape” to preserve possible binary data (default)

                       • ”ignore” to use the replacement char U+FFFD “�” for invalid data

                       • ”strict” to raise an UnicodeDecodeError exception for invalid data

              RaisesDXFStructureError – Invalid or incomplete DXF file

                     • UnicodeDecodeError – if errors is “strict” and a decoding error occurs

       class ezdxf.addons.iterdxf.IterDXF

              export(name: str) -> IterDXFWriter
                     Returns a companion object to export parts from the source DXF file into another DXF  file,
                     the new file will have the same HEADER, CLASSES, TABLES, BLOCKS and OBJECTS sections, which
                     guarantees all necessary dependencies are present in the new file.

                     Parameters
                            name – filename, no special requirements

              modelspace(types: Iterable[str] = None) -> Iterable[DXFGraphic]
                     Returns an iterator for all supported DXF entities in the modelspace.  These  entities  are
                     regular DXFGraphic objects but without a valid document assigned. It is not possible to add
                     these entities to other ezdxf documents.

                     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.

                     Parameters
                            types – DXF types like ['LINE', '3DFACE'] which should be returned, None returns all
                            supported types.

              close()
                     Safe closing source DXF file.

       class ezdxf.addons.iterdxf.IterDXFWriter

              write(entity: DXFGraphic)
                     Write a DXF entity from the source DXF file to the export file.

                     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.

              close()
                     Safe  closing  of exported DXF file. Copying of OBJECTS section happens only at closing the
                     file, without closing the new DXF file is invalid.

   Importer
       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:
          DON’T EXPECT PERFECT RESULTS!

       The Importer supports following data import:

          • entities which are really safe to import: LINE, POINT, CIRCLE,  ARC,  TEXT,  SOLID,  TRACE,  3DFACE,
            SHAPE,  POLYLINE,  ATTRIB,  ATTDEF,  INSERT, ELLIPSE, MTEXT, LWPOLYLINE, SPLINE, HATCH, MESH, XLINE,
            RAY, DIMENSION, LEADER, VIEWPORT

          • table and table entry import is restricted to LAYER, LTYPE, STYLE, DIMSTYLE

          • import of BLOCK definitions is supported

          • import of paper space layouts is supported

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

       class ezdxf.addons.importer.Importer(source: Drawing, target: Drawing)
              The Importer class is central element for importing data from other DXF drawings.

              Parameterssource – source Drawingtarget – target Drawing

              Variablessource – source drawing

                     • target – target drawing

                     • used_layer – Set of used layer names as string, AutoCAD accepts  layer  names  without  a
                       LAYER table entry.

                     • used_linetypes  –  Set  of used linetype names as string, these linetypes require a TABLE
                       entry or AutoCAD will crash.

                     • used_styles – Set of used text style names, these text styles require a  TABLE  entry  or
                       AutoCAD will crash.

                     • used_dimstyles  –  Set  of  used  dimension style names, these dimension styles require a
                       TABLE entry or AutoCAD will crash.

              finalize() -> None
                     Finalize  import  by  importing  required  table  entries  and  block  definition,  without
                     finalization the target drawing is maybe invalid fore AutoCAD. Call finalize() as last step
                     of the import process.

              import_block(block_name: str, rename=True) -> str
                     Import one block definition. If block already exist the block will be renamed  if  argument
                     rename  is  True,  else the existing target block will be used instead of the source block.
                     Required  name  resolving  for  imported  block  references  (INSERT),  will  be  done   in
                     Importer.finalize().

                     To  replace  an  existing  block  in  the  target drawing, just delete it before importing:
                     target.blocks.delete_block(block_name, safe=False)

                     Parametersblock_name – name of block to import

                            • rename – rename block if exists in target drawing

                     Returns: block name (renamed)

                     Raises ValueError – source block not found

              import_blocks(block_names: Iterable[str], rename=False) -> None
                     Import all block definitions. If block already exist the block will be renamed if  argument
                     rename  is  True,  else the existing target block will be used instead of the source block.
                     Required  name  resolving  for  imported  block  references  (INSERT),  will  be  done   in
                     Importer.finalize().

                     Parametersblock_names – names of blocks to import

                            • rename – rename block if exists in target drawing

                     Raises ValueError – source block not found

              import_entities(entities: Iterable[DXFEntity], target_layout: BaseLayout = None) -> None
                     Import  all  entities  into  target_layout  or  the  modelspace  of  the target drawing, if
                     target_layout is None.

                     Parametersentities – Iterable of DXF entities

                            • target_layout – any layout (modelspace,  paperspace  or  block)  from  the  target
                              drawing

                     Raises DXFStructureErrortarget_layout is not a layout of target drawing

              import_entity(entity: DXFEntity, target_layout: BaseLayout = None) -> None
                     Imports  a single DXF entity into target_layout or the modelspace of the target drawing, if
                     target_layout is None.

                     Parametersentity – DXF entity to import

                            • target_layout – any layout (modelspace,  paperspace  or  block)  from  the  target
                              drawing

                     Raises DXFStructureErrortarget_layout is not a layout of target drawing

              import_modelspace(target_layout: BaseLayout = None) -> None
                     Import  all  entities  from  source  modelspace into target_layout or the modelspace of the
                     target drawing, if target_layout is None.

                     Parameters
                            target_layout – any layout (modelspace, paperspace or block) from the target drawing

                     Raises DXFStructureErrortarget_layout is not a layout of target drawing

              import_paperspace_layout(name: str) -> Layout
                     Import paperspace layout name into target drawing. Recreates the source  paperspace  layout
                     in the target drawing, renames the target paperspace if already a paperspace with same name
                     exist and imports all entities from source paperspace into target paperspace.

                     Parameters
                            name – source paper space name as string

                     Returns: new created target paperspace Layout

                     RaisesKeyError – source paperspace does not exist

                            • DXFTypeError – invalid modelspace import

              import_paperspace_layouts() -> None
                     Import all paperspace layouts and their content into target drawing. Target layouts will be
                     renamed  if already a layout with same name exist. Layouts will be imported in original tab
                     order.

              import_table(name: str, entries: Union[str, Iterable[str]] = '*', replace=False) -> None
                     Import specific table entries from source drawing into target drawing.

                     Parametersname – valid table names are layers, linetypes and stylesentries – Iterable of table names as strings, or a single table name or * for  all
                              table entries

                            • replace – True to replace already existing table entry else ignore existing entry

                     Raises TypeError – unsupported table type

              import_tables(table_names: Union[str, Iterable[str]] = '*', replace=False) -> None
                     Import DXF tables from source drawing into target drawing.

                     Parameterstable_names  –  iterable  of  tables  names  as strings, or a single table name as
                              string or * for all supported tables

                            • replace – True to replace already existing  table  entries  else  ignore  existing
                              entries

                     Raises TypeError – unsupported table type

              recreate_source_layout(name: str) -> Layout
                     Recreate source paperspace layout name in the target drawing. The layout will be renamed if
                     name already exist in the  target  drawing.  Returns  target  modelspace  for  layout  name
                     “Model”.

                     Parameters
                            name – layout name as string

                     Raises KeyError – if source layout name not exist

   Drawing / Export Addon
       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')

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

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

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

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

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

   Limitations
       • Line types and hatch patterns/gradients are ignored

       • rich text formatting is ignored (drawn as plain text)

       • If  the  backend does not match the font then the exact text placement and wrapping may appear slightly
         different

       • No support for MULTILEADER

       • The style which POINT entities are drawn in are not stored in the dxf file and so cannot be  replicated
         exactly

       • only basic support for:

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

         • hatches with holes (holes are rendered filled)

         • viewports (rendered as rectangles)

         • 3D  (some  entities  may  not display correctly in 3D (see possible improvements below)) however many
           things should already work in 3D.

         • vertical text (will render as horizontal text)

         • multiple columns of text (placement of additional columns may be incorrect)

   Future Possible Improvements
       • pass the font to backend if available

       • deal with nested polygons/hatches by triangulating them: Triangulation

       • both the matplotlib and pyqt backends  have  built-in  support  for  rendering  hatched  patterns  (see
         MatplotlibHatch  and  QtBrushHatch)  so  the interface could pass that information through or query the
         backend to determine whether it automatically supports complex drawing commands such  as  hatching,  or
         whether the frontend should break the shape into simpler commands (i.e. calculate and draw each line of
         a hatch)

       • text formatting commands could be interpreted and broken into text chunks which can  be  drawn  with  a
         single font weight or modification such as italics

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

       ezdxf.addons.dxf2code.entities_to_code(entities:  Iterable[DXFEntity],  layout:  str  = 'layout', ignore:
       Iterable[str] = None) -> Code
              Translates DXF entities into Python source code to recreate this entities by ezdxf.

              Parametersentities – iterable of DXFEntity

                     • layout – variable name of the layout (model space or block) as string

                     • ignore – iterable of entities types to ignore as strings like ['IMAGE', 'DIMENSION']

              Returns
                     Code

       ezdxf.addons.dxf2code.block_to_code(block: BlockLayout, drawing: str =  'doc',  ignore:  Iterable[str]  =
       None) -> Code
              Translates a BLOCK into Python source code to recreate the BLOCK by ezdxf.

              Parametersblock – block definition layout

                     • drawing – variable name of the drawing as string

                     • ignore – iterable of entities types to ignore as strings like [‘IMAGE’, ‘DIMENSION’]

              Returns
                     Code

       ezdxf.addons.dxf2code.table_entries_to_code(entities: Iterable[DXFEntity], drawing='doc') -> Code

       class ezdxf.addons.dxf2code.Code
              Source code container.

              code   Source code line storage, store lines without line ending \\n

              imports
                     source code line storage for global imports, store lines without line ending \\n

              layers Layers used by the generated source code, AutoCAD accepts layer names without a LAYER table
                     entry.

              linetypes
                     Linetypes used by the generated source code, these  linetypes  require  a  TABLE  entry  or
                     AutoCAD will crash.

              styles Text  styles  used by the generated source code, these text styles require a TABLE entry or
                     AutoCAD will crash.

              dimstyles
                     Dimension styles  used by the generated source code, these dimension styles require a TABLE
                     entry or AutoCAD will crash.

              blocks Blocks  used  by  the generated source code, these blocks require a BLOCK definition in the
                     BLOCKS section or AutoCAD will crash.

              code_str(indent: int = 0) -> str
                     Returns the source code as a single string.

                     Parameters
                            indent – source code indentation count by spaces

              import_str(indent: int = 0) -> str
                     Returns required imports as a single string.

                     Parameters
                            indent – source code indentation count by spaces

              merge(code: ezdxf.addons.dxf2code.Code, indent: int = 0) -> None
                     Add another Code object.

              add_import(statement: str) -> None
                     Add import statement, identical import statements are merged together.

              add_line(code: str, indent: int = 0) -> None
                     Add a single source code line without line ending \n.

              add_lines(code: Iterable[str], indent: int = 0) -> None
                     Add multiple source code lines without line ending \n.

   Plot Style Files (CTB/STB)
       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:Using plot style tables in AutoCADAutoCAD Plot Style Table EditorBricsCAD Plot Style Table Editor

          • AUTODESK KNOWLEDGE NETWORK: How to install CTB files in AutoCAD

       ezdxf.addons.acadctb.load(filename: str) -> Union[ColorDependentPlotStyles, NamedPlotStyles]
              Load the CTB or STB file filename from file system.

       ezdxf.addons.acadctb.new_ctb() -> ColorDependentPlotStyles
              Create a new CTB file.

              Changed in version 0.10: renamed from new()

       ezdxf.addons.acadctb.new_stb() -> NamedPlotStyles
              Create a new STB file.

              New in version 0.10.

   ColorDependentPlotStyles
       Color dependent plot style table (CTB file), table entries are PlotStyle objects.

       class ezdxf.addons.acadctb.ColorDependentPlotStyles

              description
                     Custom description of plot style file.

              scale_factor
                     Specifies the factor by which to scale non-ISO linetypes and fill patterns.

              apply_factor
                     Specifies whether or not you want to apply the scale_factor.

              custom_lineweight_display_units
                     Set 1 for showing lineweight in inch in AutoCAD CTB  editor  window,  but  lineweights  are
                     always defined in millimeters.

              lineweights
                     Lineweights table as array.array

              __getitem__(aci: int) -> PlotStyle
                     Returns PlotStyle for ACI aci.

              __iter__() -> Iterable[PlotStyle]
                     Iterable of all plot styles.

              new_style(aci: int, data: dict = None) -> PlotStyle
                     Set aci to new attributes defined by data dict.

                     Parametersaci – ACI

                            • datadict  of  PlotStyle  attributes: description, color, physical_pen_number,
                              virtual_pen_number,   screen,   linepattern_size,   linetype,   adaptive_linetype,
                              lineweight, end_style, join_style, fill_style

              get_lineweight(aci: int)
                     Returns the assigned lineweight for PlotStyle aci in millimeter.

              get_lineweight_index(lineweight: float) -> int
                     Get index of lineweight in the lineweight table or append lineweight to lineweight table.

              get_table_lineweight(index: int) -> float
                     Returns lineweight in millimeters of lineweight table entry index.

                     Parameters
                            index – lineweight table index = PlotStyle.lineweight

                     Returns
                            lineweight in mm or 0.0 for use entity lineweight

              set_table_lineweight(index: int, lineweight: float) -> int
                     Argument index is the lineweight table index, not the ACI.

                     Parametersindex – lineweight table index = PlotStyle.lineweightlineweight – in millimeters

              save(filename: str) -> None
                     Save CTB file as filename to the file system.

              write(stream: BinaryIO) -> None
                     Compress and write CTB file to binary stream.

   NamedPlotStyles
       Named plot style table (STB file), table entries are PlotStyle objects.

       class ezdxf.addons.acadctb.NamedPlotStyles

              description
                     Custom description of plot style file.

              scale_factor
                     Specifies the factor by which to scale non-ISO linetypes and fill patterns.

              apply_factor
                     Specifies whether or not you want to apply the scale_factor.

              custom_lineweight_display_units
                     Set  1  for  showing  lineweight  in inch in AutoCAD CTB editor window, but lineweights are
                     always defined in millimeters.

              lineweights
                     Lineweights table as array.array

              __getitem__(name: str) -> PlotStyle
                     Returns PlotStyle by name.

              __delitem__(name: str)
                     Delete plot style name. Plot style 'Normal' is not deletable.

              __iter__() -> Iterable[str]
                     Iterable of all plot style names.

              new_style(name: str, localized_name: str = None, data: dict = None) -> PlotStyle
                     Create new class:PlotStyle name by attribute dict data, replaces  existing  class:PlotStyle
                     objects.

                     Parametersname – plot style name

                            • localized_name – name shown in plot style editor, uses name if Nonedatadict  of  PlotStyle  attributes: description, color, physical_pen_number,
                              virtual_pen_number,   screen,   linepattern_size,   linetype,   adaptive_linetype,
                              lineweight, end_style, join_style, fill_style

              get_lineweight(name: str)
                     Returns the assigned lineweight for PlotStyle name in millimeter.

              get_lineweight_index(lineweight: float) -> int
                     Get index of lineweight in the lineweight table or append lineweight to lineweight table.

              get_table_lineweight(index: int) -> float
                     Returns lineweight in millimeters of lineweight table entry index.

                     Parameters
                            index – lineweight table index = PlotStyle.lineweight

                     Returns
                            lineweight in mm or 0.0 for use entity lineweight

              set_table_lineweight(index: int, lineweight: float) -> int
                     Argument index is the lineweight table index, not the ACI.

                     Parametersindex – lineweight table index = PlotStyle.lineweightlineweight – in millimeters

              save(filename: str) -> None
                     Save STB file as filename to the file system.

              write(stream: BinaryIO) -> None
                     Compress and write STB file to binary stream.

   PlotStyle
       class ezdxf.addons.acadctb.PlotStyle

              index  Table index (0-based). (int)

              aci    ACI in range from 1 to 255. Has no meaning for named plot styles. (int)

              description
                     Custom description of plot style. (str)

              physical_pen_number
                     Specifies physical plotter pen, valid range from 1 to 32 or AUTOMATIC. (int)

              virtual_pen_number
                     Only used by non-pen plotters and only if they are configured for virtual pens. valid range
                     from 1 to 255 or AUTOMATIC. (int)

              screen Specifies the color intensity of the plot on the paper, valid range is from 0 to 100. (int)

                     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.

              linetype
                     Overrides the entity linetype, default value is OBJECT_LINETYPE. (bool)

              adaptive_linetype
                     True  if  a  complete  linetype  pattern is more important than a correct linetype scaling,
                     default is True. (bool)

              linepattern_size
                     Line pattern size, default = 0.5. (float)

              lineweight
                     Overrides the entity lineWEIGHT, default value is OBJECT_LINEWEIGHT. This is an index  into
                     the UserStyles.lineweights table. (int)

              end_style
                     Line end cap style, see table below, default is END_STYLE_OBJECT (int)

              join_style
                     Line join style, see table below, default is JOIN_STYLE_OBJECT (int)

              fill_style
                     Line fill style, see table below, default is FILL_STYLE_OBJECT (int)

              dithering
                     Depending  on  the capabilities of your plotter, dithering approximates the colors with dot
                     patterns.  When this option is False, the colors are mapped to the nearest color, resulting
                     in a smaller range of colors when plotting.

                     Dithering  is  available  only whether you select the object’s color or assign a plot style
                     color.

              grayscale
                     Plot colors in grayscale. (bool)

   Default Line Weights
                                                      ┌───┬──────┐
                                                      │#  │ [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 │
                                                      └───┴──────┘

   Predefined Values
       ezdxf.addons.acadctb.AUTOMATIC

       ezdxf.addons.acadctb.OBJECT_LINEWEIGHT

       ezdxf.addons.acadctb.OBJECT_LINETYPE

       ezdxf.addons.acadctb.OBJECT_COLOR

       ezdxf.addons.acadctb.OBJECT_COLOR2

   Line End Style
       [image]

                                                ┌──────────────────┬───┐
                                                │END_STYLE_BUTT    │ 0 │
                                                ├──────────────────┼───┤
                                                │END_STYLE_SQUARE  │ 1 │
                                                ├──────────────────┼───┤
                                                │END_STYLE_ROUND   │ 2 │
                                                ├──────────────────┼───┤
                                                │END_STYLE_DIAMOND │ 3 │
                                                ├──────────────────┼───┤
                                                │END_STYLE_OBJECT  │ 4 │
                                                └──────────────────┴───┘

   Line Join Style
       [image]

                                               ┌───────────────────┬───┐
                                               │JOIN_STYLE_MITER   │ 0 │
                                               ├───────────────────┼───┤
                                               │JOIN_STYLE_BEVEL   │ 1 │
                                               ├───────────────────┼───┤
                                               │JOIN_STYLE_ROUND   │ 2 │
                                               ├───────────────────┼───┤
                                               │JOIN_STYLE_DIAMOND │ 3 │
                                               └───────────────────┴───┘

                                               │JOIN_STYLE_OBJECT  │ 5 │
                                               └───────────────────┴───┘

   Fill Style
       [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 │
                                           └───────────────────────────┴────┘

   Linetypes
       [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    │
                                      └──────────────────────────────────┴───────┘

   PyCSG
       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')
       [image: Cube vs Cylinder] [image]

       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:
          This is a pure Python implementation, don’t expect great performance and the implementation  is  based
          on an unbalanced BSP tree, so in the case of RecursionError, increase the recursion limit:

              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})
       [image: Cube vs Sphere] [image]

       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:

          • CPython 3.8.1 64bit: ~60 seconds,

          • pypy3  [PyPy  7.2.0]  32bit:  ~6 seconds, and using __slots__ reduced runtime below 5 seconds, yes -
            pypy is worth a look for long running scripts!

          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'})
       [image: Menger Sponge vs Sphere] [image]

   CSG Class
       class ezdxf.addons.pycsg.CSG(mesh: MeshBuilder, meshid: int = 0)
              Constructive Solid Geometry (CSG) is a modeling technique that uses Boolean operations like  union
              and intersection to combine 3D solids. This class implements CSG operations on meshes.

              New  3D solids are created from MeshBuilder objects and results can be exported as MeshTransformer
              objects to ezdxf by method mesh().

              Parametersmeshezdxf.render.MeshBuilder or inherited object

                     • meshid – individual mesh ID to separate result meshes, 0 is default

              mesh(meshid: int = 0) -> MeshTransformer
                     Returns a ezdxf.render.MeshTransformer object.

                     Parameters
                            meshid – individual mesh ID, 0 is default

              union(other: CSG) -> CSG
                     Return a new CSG solid representing space in either this  solid  or  in  the  solid  other.
                     Neither this solid nor the solid other are modified:

                        A.union(B)

                        +-------+            +-------+
                        |       |            |       |
                        |   A   |            |       |
                        |    +--+----+   =   |       +----+
                        +----+--+    |       +----+       |
                             |   B   |            |       |
                             |       |            |       |
                             +-------+            +-------+

              __add__(other: CSG) -> CSG

                        union = A + B

              subtract(other: CSG) -> CSG
                     Return a new CSG solid representing space in this solid but not in the solid other. Neither
                     this solid nor the solid other are modified:

                        A.subtract(B)

                        +-------+            +-------+
                        |       |            |       |
                        |   A   |            |       |
                        |    +--+----+   =   |    +--+
                        +----+--+    |       +----+
                             |   B   |
                             |       |
                             +-------+

              __sub__(other: CSG) -> CSG

                        difference = A - B

              intersect(other: CSG) -> CSG
                     Return a new CSG solid representing space both this solid and in the solid  other.  Neither
                     this solid nor the solid other are modified:

                        A.intersect(B)

                        +-------+
                        |       |
                        |   A   |
                        |    +--+----+   =   +--+
                        +----+--+    |       +--+
                             |   B   |
                             |       |
                             +-------+

              __mul__(other: CSG) -> CSG

                        intersection = A * B

              inverse() -> CSG
                     Return a new CSG solid with solid and empty space switched. This solid is not modified.

   License
       • Original implementation csg.js, Copyright (c) 2011 Evan Wallace (http://madebyevan.com/), under the MIT
         license.

       • Python port pycsg, Copyright (c) 2012 Tim Knip (http://www.floorplanner.com), under the MIT license.

       • Additions by Alex Pletzer (Pennsylvania State University)

       • Integration as ezdxf add-on, Copyright (c) 2020, Manfred Moitzi, MIT License.

   Showcase Forms
   MengerSponge
       Build a 3D Menger sponge.

       class ezdxf.addons.MengerSponge(location: Vertex = (0.0, 0.0, 0.0), length: float = 1.0, level: int =  1,
       kind: int = 0)

              Parameterslocation – location of lower left corner as (x, y, z) tuple

                     • length – side length

                     • level – subdivide level

                     • kind – type of menger sponge

                                                 ┌──┬────────────────────────┐
                                                 │0 │ Original Menger Sponge │
                                                 ├──┼────────────────────────┤
                                                 │1 │ Variant XOX            │
                                                 ├──┼────────────────────────┤
                                                 │2 │ Variant OXO            │
                                                 ├──┼────────────────────────┤
                                                 │3 │ Jerusalem Cube         │
                                                 └──┴────────────────────────┘

              render(layout: GenericLayoutType, merge: bool = False, dxfattribs: dict = None, matrix: Matrix44 =
              None, ucs: UCS = None) -> None
                     Renders the menger sponge into layout, set merge to True for  rendering  the  whole  menger
                     sponge  into  one MESH entity, set merge to False for rendering the individual cubes of the
                     menger sponge as MESH entities.

                     Parameterslayout – DXF target layout

                            • mergeTrue for one MESH entity, False for individual MESH entities per cube

                            • dxfattribs – DXF attributes for the MESH entities

                            • matrix – apply transformation matrix at rendering

                            • ucs – apply UCS transformation at rendering

              cubes() -> Iterable[ezdxf.render.mesh.MeshTransformer]
                     Yields all cubes of the menger sponge as individual MeshTransformer objects.

              mesh() -> ezdxf.render.mesh.MeshTransformer
                     Returns geometry as one MeshTransformer object.

       Menger Sponge kind=0: [image]

       Menger Sponge kind=1: [image]

       Menger Sponge kind=2: [image]

       Jerusalem Cube kind=3: [image]

   SierpinskyPyramid
       Build a 3D Sierpinsky Pyramid.

       class ezdxf.addons.SierpinskyPyramid(location: Vertex = (0.0, 0.0, 0.0), length: float = 1.0, level:  int
       = 1, sides: int = 4)

              Parameterslocation – location of base center as (x, y, z) tuple

                     • length – side length

                     • level – subdivide level

                     • sides – sides of base geometry

              render(layout: GenericLayoutType, merge: bool = False, dxfattribs: dict = None, matrix: Matrix44 =
              None, ucs: UCS = None) -> None
                     Renders the sierpinsky pyramid into layout, set merge  to  True  for  rendering  the  whole
                     sierpinsky pyramid into one MESH entity, set merge to False for individual pyramids as MESH
                     entities.

                     Parameterslayout – DXF target layout

                            • mergeTrue for one MESH entity, False for individual MESH entities per pyramid

                            • dxfattribs – DXF attributes for the MESH entities

                            • matrix – apply transformation matrix at rendering

                            • ucs – apply UCS at rendering

              pyramids() -> Iterable[ezdxf.render.mesh.MeshTransformer]
                     Yields all pyramids of the sierpinsky pyramid as individual MeshTransformer objects.

              mesh() -> ezdxf.render.mesh.MeshTransformer
                     Returns geometry as one MeshTransformer object.

       Sierpinsky Pyramid with triangle base: [image]

       Sierpinsky Pyramid with square base: [image]

   ODA File Converter Support
       Use an installed ODA File Converter for converting between different versions of .dwg, .dxb and .dxf.

       WARNING:
          Execution of an external application is a  big  security  issue!  Especially  when  the  path  to  the
          executable can be altered.

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

       ezdxf.addons.odafc.exec_path
              Path    to    installed    ODA    File    Converter    executable,    default    is    "C:\Program
              Files\ODA\ODAFileConverter\ODAFileConverter.exe".

       ezdxf.addons.odafc.temp_path
              Path to a temporary folder by default the system temp folder defined by environment  variable  TMP
              or TEMP.

       ezdxf.addons.odafc.readfile(filename: str, version: str = None, audit=False) -> Drawing
              Use  an  installed  ODA File Converter to convert a DWG/DXB/DXF file into a temporary DXF file and
              load this file by ezdxf.

              Parametersfilename – file to load by ODA File Converter

                     • version – load file as specific DXF version, by default the same version  as  the  source
                       file or if not detectable the latest by ezdxf supported version.

                     • audit – audit source file before loading

       ezdxf.addons.odafc.export_dwg(doc: Drawing, filename: str, version: str = None, audit=False)
              Use an installed ODA File Converter to export a DXF document doc as a DWG file.

              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.

              Parametersdocezdxf DXF document as Drawing object

                     • filename – export filename of DWG file, extension will be changed to '.dwg'version – export file as specific version, by default the  same  version  as  the  source
                       document.

                     • audit – audit source file by ODA File Converter at exporting

DXF INTERNALS

DXF Reference provided by Autodesk.

       • DXF Developer Documentation provided by Autodesk.

   Basic DXF Structures
   DXF File Encoding
   DXF R2004 and prior
       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

   Known $DWGCODEPAGE encodings
                                         ┌──────────┬────────┬────────────────┐
                                         │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        │
                                         └──────────┴────────┴────────────────┘

   DXF R2007 and later
       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:
          String Value Encoding

   DXF Tags
       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
       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 value encoding
       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:

       • 0 - 9

       • 100 - 101

       • 300 - 309

       • 410 - 419

       • 430 - 439

       • 470 - 479

       • 999 - 1003

   Multi tag text (MTEXT)
       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:
          DXF File Encoding

   DXF R13 and later tag structure
       With  the introduction of DXF R13 Autodesk added additional group codes and DXF tag structures to the DXF
       Standard.

   Subclass Markers
       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.

   Quote about group codes from the DXF reference
          Some group codes that define an entity always appear; others are optional and  appear  only  if  their
          values differ from the defaults.

          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.

   Usage of group codes in subclasses twice
       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)

   Tag order is sometimes important especially for AutoCAD
       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.

   Extension Dictionary
       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
       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
          }

   Application-Defined Codes
       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.

   Embedded Objects
       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:
          For DXF filing, the embedded object must be filed out and in after all the data of  the  encapsulating
          object has been filed out and in.

          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:

       • Embedded object start with (101, "Embedded Object") tag

       • Embedded object is appended to the encapsulated object

       • (101, "Embedded Object") tag is the end of the encapsulating object, also of its Extended Data

       • Embedded object tags can contain any group code except the DXF structure tag (0, ...)

       Unconfirmed assumptions:

       • The encapsulating object can contain more than one embedded object.

       • Embedded objects separated by (101, "Embedded Object") tags

       • every entity can contain embedded objects

       • XDATA sections replaced by embedded objects, at least for the MTEXT entity

       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

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

   Handle Definition
       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.

   Handle Pointer
       A pointer is a reference to a DXF object in the same DXF file. There are four types of pointers:

       • Soft-pointer handle

       • Hard-pointer handle

       • Soft-owner handle

       • Hard-owner handle

       Also, a group code range for “arbitrary” handles is defined to allow convenient storage of handle  values
       that are unchanged at any operation (AutoCAD).

   Pointer and Ownership
       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 and Soft References
       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
       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.

   About 1005 Group Codes
       (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.

   DXF File Structure
       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:
          For more information about DXF tags see: dxf_tags_internals

       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.

       1. HEADER:  General  information  about  the  drawing  is  found  in  this section of the DXF file.  Each
          parameter has a variable name starting with ‘$’ and an associated value. Has to be the first section.

       2. CLASSES: Holds the information for application defined classes. (DXF R13 and later)

       3. TABLES:: Contains several tables for style and property definitions.

          • Linetype table (LTYPE)

          • Layer table (LAYER)

          • Text Style table (STYLE)

          • View table (VIEW): (IMHO) layout of the CAD working space,  only  interesting  for  interactive  CAD
            applications

          • Viewport  configuration  table  (VPORT):  The  VPORT  table is unique in that it may contain several
            entries with the same name (indicating a multiple-viewport configuration). The entries corresponding
            to  the  active viewport configuration all have the name *ACTIVE. The first such entry describes the
            current viewport.

          • Dimension Style table (DIMSTYLE)

          • User Coordinate System table (UCS) (IMHO) only interesting for interactive CAD applications

          • Application Identification table (APPID): Table of names for  all  applications  registered  with  a
            drawing.

          • Block Record table (BLOCK_RECORD) (DXF R13 and Later)

       4. BLOCKS:  Contains  all  block definitions. The block name *Model_Space or *MODEL_SPACE is reserved for
          the drawing modelspace and the block name *Paper_Space or *PAPER_SPACE  is  reserved  for  the  active
          paperspace  layout.   Both  block  definitions are empty, the content of the modelspace and the active
          paperspace is stored in the ENTITIES section. The entities of other  layouts  are  stored  in  special
          block definitions called *Paper_Spacennn, nnn is an arbitrary but unique number.

       5. ENTITIES: Contains all graphical entities of the modelspace and the active paperspace layout. Entities
          of other layouts are stored in the BLOCKS sections.

       6. OBJECTS: Contains all non-graphical objects of the drawing (DXF R13 and later)

       7. THUMBNAILIMAGE: Contains a preview image of the DXF file, it is optional and can usually  be  ignored.
          (DXF R13 and later)

       8. ACDSDATA: (DXF R2013 and later) No information in the DXF reference about this section

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

   Minimal DXF Content
   DXF R12
       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 R13/R14 and later
       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:

       • $ACADVER

       • $HANDSEED

       The CLASSES section can be empty, but some DXF entities requires class definitions to work in AutoCAD.

       The TABLES section requires following tables:

       • VPORT entry *ACTIVE is not required! Empty table is ok for AutoCAD.

       • LTYPE with at least the following line types defined:

         • BYBLOCK

         • BYLAYER

         • CONTINUOUS

       • LAYER with at least an entry for layer ‘0’

       • STYLE with at least an entry for style STANDARD

       • VIEW can be empty

       • UCS can be empty

       • APPID with at least an entry for ACAD

       • DIMSTYLE with at least an entry for style STANDARD

       • BLOCK_RECORDS with two entries:

         • *MODEL_SPACE

         • *PAPER_SPACE

       The BLOCKS section requires two BLOCKS:

       • *MODEL_SPACE

       • *PAPER_SPACE

       The ENTITIES section can be empty.

       The OBJECTS section requires following entities:

       • DICTIONARY - the root dict - one entry named ACAD_GROUP

       • DICTONARY ACAD_GROUP can be empty

       Minimal DXF to download: https://bitbucket.org/mozman/ezdxf/downloads/Minimal_DXF_AC1021.dxf

   Data Model
   Database Objects
       (from the DXF Reference)

       AutoCAD drawings consist largely of structured containers for database  objects.  Database  objects  each
       have the following features:

          • A  handle  whose  value  is  unique to the drawing/DXF file, and is constant for the lifetime of the
            drawing. This format has existed since AutoCAD Release 10, and as of AutoCAD Release 13, handles are
            always enabled.

          • An optional XDATA table, as entities have had since AutoCAD Release 11.

          • An optional persistent reactor table.

          • An  optional  ownership pointer to an extension dictionary which, in turn, owns subobjects placed in
            it by an application.

       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.

   DXF R12 Data Model
       The DXF R12 data model is identical to the file structure:

          • HEADER section: common settings for the DXF drawing

          • TABLES section: definitions for LAYERS, LINETYPE, STYLES ….

          • BLOCKS section: block definitions and its content

          • ENTITIES section: modelspace and paperspace content

       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:
          More information about the DXF File Structure

   DXF R13+ Data Model
       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 ;):

          • DICTIONARY: a general structural entity as a <name: handle> container

          • ACDBDICTIONARYWDFLT: a DICTIONARY with a default value

          • DICTIONARYVAR: used by AutoCAD to store named values in the database

          • ACAD_PROXY_OBJECT: proxy object for entities created by other applications than AutoCAD

          • GROUP: groups graphical entities without the need of a BLOCK definition

          • IDBUFFER: just a list of references to objects

          • IMAGEDEF: IMAGE definition structure, required by the IMAGE entity

          • IMAGEDEF_REACTOR: also required by the IMAGE entity

          • LAYER_INDEX: container for LAYER names

          • MLINESTYLE

          • OBJECT_PTR

          • RASTERVARIABLES

          • SPATIAL_INDEX: is always written out empty to a DXF file. This object can be ignored.

          • SPATIAL_FILTER

          • SORTENTSTABLE: control for regeneration/redraw order of entities

          • XRECORD:  used to store and manage arbitrary data. This object is similar in concept to XDATA but is
            not limited by size or order. Not supported by R13c0 through R13c3.

       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:

          • LAYOUT: management object for modelspace and multiple paperspace layouts

          • ACDBPLACEHOLDER: surprise - just a place holder

       New objects in DXF R2004:

          • DIMASSOC

          • LAYER_FILTER

          • MATERIAL

          • PLOTSETTINGS

          • VBA_PROJECT

       New objects in DXF R2007:

          • DATATABLE

          • FIELD

          • LIGHTLIST

          • RENDER

          • RENDERENVIRONMENT

          • MENTALRAYRENDERSETTINGS

          • RENDERGLOBAL

          • SECTION

          • SUNSTUDY

          • TABLESTYLE

          • UNDERLAYDEFINITION

          • VISUALSTYLE

          • WIPEOUTVARIABLES

       New objects in DXF R2013:

          • GEODATA

       New objects in DXF R2018:

          • ACDBNAVISWORKSMODELDEF

       Undocumented objects:

          • SCALE

          • ACDBSECTIONVIEWSTYLE

          • FIELDLIST

   Objects Organisation
       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:

          • ACAD_COLOR: points to an empty DICTIONARY

          • ACAD_GROUP: supported by ezdxf

          • ACAD_LAYOUT: supported by ezdxf

          • ACAD_MATERIAL: points to an empty DICTIONARY

          • ACAD_MLEADERSTYLE: points to an empty DICTIONARY

          • ACAD_MLINESTYLE: points to an empty DICTIONARY

          • ACAD_PLOTSETTINGS: points to an empty DICTIONARY

          • ACAD_PLOTSTYLENAME: points to ACDBDICTIONARYWDFLT with one entry: ‘Normal’

          • ACAD_SCALELIST: points to an empty DICTIONARY

          • ACAD_TABLESTYLE: points to an empty DICTIONARY

          • ACAD_VISUALSTYLE: points to an empty DICTIONARY

   Root DICTIONARY content for DXF R2018
          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

   DXF Structures
   DXF Sections
   HEADER Section
       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:
          Documentation of ezdxf HeaderSection class.

          DXF Reference: Header Variables

   CLASSES Section
       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:
          DXF Reference: About the DXF CLASSES Section

          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.

   CLASS Entities
       SEE ALSO:
          DXF Reference: Group Codes for the CLASS entity

       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

   TABLES Section
       TODO

   BLOCKS Section
       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:
          Block Management Structures Layout Management Structures

   ENTITIES Section
       TODO

   OBJECTS Section
       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.

   DXF Tables
   VIEW Table
       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.

   DXF R12
          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:
          Coordinate Systems

   DXF R2000+
       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.

   VPORT Configuration Table
       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:
          All floating point values are rounded to 2 decimal places for better readability.

   DXF R12
       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

   DXF R2000+
       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

   LTYPE Table
       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:

          • DXF Reference: TABLES Section

          • DXF Reference: LTYPE Table

   Table Structure DXF R12
          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

   Table Structure DXF R2000+
          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

   Simple Line Type
       ezdxf setup for line type ‘CENTER’:

          dwg.linetypes.new("CENTER", dxfattribs={
              description = "Center ____ _ ____ _ ____ _ ____ _ ____ _ ____",
              pattern=[2.0, 1.25, -0.25, 0.25, -0.25],
           })

   Simple Line Type Tag Structure DXF R2000+
          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

   Complex Line Type TEXT
       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',
          })

   TEXT Tag Structure
          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

   Complex Line Type SHAPE
       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',
          })

   SHAPE Tag Structure
          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

   DIMSTYLE Table
       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:

          • DXF Reference: TABLES Section

          • DXF Reference: DIMSTYLE Table

   Table Structure DXF R12
          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

   DIMSTYLE Entry DXF R12
   DIMSTYLE Variables DXF R12
       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  =    No   center │
                                   │         │      │          marks  or lines are │
                                   │         │      │          drawn               │
                                   │         │      │                              │
                                   │         │      │        • <0  =   Centerlines │
                                   │         │      │          are drawn           │
                                   │         │      │                              │
                                   │         │      │        • >0  =  Center marks │
                                   │         │      │          are drawn           │
                                   ├─────────┼──────┼──────────────────────────────┤
                                   │DIMCLRD  │ 176  │ Assigns colors to  dimension │
                                   │         │      │ lines,    arrowheads,    and │
                                   │         │      │ dimension leader lines.      │
                                   │         │      │                              │
                                   │         │      │        • 0 =  BYBLOCK        │
                                   │         │      │                              │
                                   │         │      │        • 1-255 = ACI AutoCAD │
                                   │         │      │          Color Index         │
                                   │         │      │                              │
                                   │         │      │        • 256 =  BYLAYER      │
                                   ├─────────┼──────┼──────────────────────────────┤
                                   │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    =    Dimension │
                                   │         │      │          limits    are   not │
                                   │         │      │          generated        as │
                                   │         │      │          default text        │
                                   │         │      │                              │
                                   │         │      │        • 1    =    Dimension │
                                   │         │      │          limits          are │
                                   │         │      │          generated        as │
                                   │         │      │          default text        │
                                   ├─────────┼──────┼──────────────────────────────┤
                                   │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  =  Use arrowhead │
                                   │         │      │          blocks    set    by │
                                   │         │      │          DIMBLK              │
                                   │         │      │                              │
                                   │         │      │        • 1  =  Use arrowhead │
                                   │         │      │          blocks    set    by │
                                   │         │      │          DIMBLK1 and DIMBLK2 │
                                   ├─────────┼──────┼──────────────────────────────┤
                                   │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  = 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.                │
                                   │         │      │                              │
                                   │         │      │        • >0 = A scale factor │
                                   │         │      │          is  computed   that │
                                   │         │      │          leads  text  sizes, │
                                   │         │      │          arrowhead    sizes, │
                                   │         │      │          and   other  scaled │
                                   │         │      │          distances  to  plot │
                                   │         │      │          at    their    face │
                                   │         │      │          values.             │
                                   │         │      │                              │
                                   │         │      │        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 = Extension  line │
                                   │         │      │          is not suppressed   │
                                   │         │      │                              │
                                   │         │      │        • 1  = Extension line │
                                   │         │      │          is suppressed       │
                                   ├─────────┼──────┼──────────────────────────────┤
                                   │DIMSE2   │ 76   │ Suppresses  display  of  the │
                                   │         │      │ second extension line.       │
                                   │         │      │                              │
                                   │         │      │        • 0  = Extension line │
                                   │         │      │          is not suppressed   │
                                   │         │      │                              │
                                   │         │      │        • 1 = Extension  line │
                                   │         │      │          is suppressed       │
                                   ├─────────┼──────┼──────────────────────────────┤
                                   │DIMSOXD  │ 175  │ Suppresses arrowheads if not │
                                   │         │      │ enough  space  is  available │
                                   │         │      │ inside the extension lines.  │
                                   │         │      │                              │
                                   │         │      │        • 0  = Arrowheads are │
                                   │         │      │          not suppressed      │
                                   │         │      │                              │
                                   │         │      │        • 1 = Arrowheads  are │
                                   │         │      │          suppressed          │
                                   │         │      │                              │
                                   │         │      │        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   =  Centers  the │
                                   │         │      │          dimension      text │
                                   │         │      │          between         the │
                                   │         │      │          extension lines.    │
                                   │         │      │                              │
                                   │         │      │        • 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   =   Places  the │
                                   │         │      │          dimension  text  on │
                                   │         │      │          the   side  of  the │
                                   │         │      │          dimension      line │
                                   │         │      │          farthest  away from │
                                   │         │      │          the        defining │
                                   │         │      │          points.             │
                                   │         │      │                              │
                                   │         │      │        • 3   =   Places  the │
                                   │         │      │          dimension  text  to │
                                   │         │      │          conform to Japanese │
                                   │         │      │          Industrial          │
                                   │         │      │          Standards (JIS).    │
                                   │         │      │                              │
                                   │         │      │        • 4   =   Places  the │
                                   │         │      │          dimension      text │
                                   │         │      │          below the dimension │
                                   │         │      │          line.               │
                                   ├─────────┼──────┼──────────────────────────────┤
                                   │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   =  Aligns  text │
                                   │         │      │          with the  dimension │
                                   │         │      │          line                │
                                   │         │      │                              │
                                   │         │      │        • 1   =   Draws  text │
                                   │         │      │          horizontally        │
                                   ├─────────┼──────┼──────────────────────────────┤
                                   │DIMTIX   │ 174  │ Draws text between extension │
                                   │         │      │ lines.                       │
                                   │         │      │                              │
                                   │         │      │        • 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.             │
                                   │         │      │                              │
                                   │         │      │        • 1 = Draws dimension │
                                   │         │      │          text   between  the │
                                   │         │      │          extension     lines │
                                   │         │      │          even  if  it  would │
                                   │         │      │          ordinarily       be │
                                   │         │      │          placed      outside │
                                   │         │      │          those lines         │
                                   ├─────────┼──────┼──────────────────────────────┤
                                   │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  =  Does not draw │
                                   │         │      │          dimension     lines │
                                   │         │      │          between         the │
                                   │         │      │          measured     points │
                                   │         │      │          when arrowheads are │
                                   │         │      │          placed outside  the │
                                   │         │      │          measured points     │
                                   │         │      │                              │
                                   │         │      │        • 1 = Draws dimension │
                                   │         │      │          lines  between  the │
                                   │         │      │          measured     points │
                                   │         │      │          even           when │
                                   │         │      │          arrowheads      are │
                                   │         │      │          placed outside  the │
                                   │         │      │          measured points     │
                                   ├─────────┼──────┼──────────────────────────────┤
                                   │DIMTOH   │ 74   │ Controls   the  position  of │
                                   │         │      │ dimension text  outside  the │
                                   │         │      │ extension lines.             │
                                   │         │      │                              │
                                   │         │      │        • 0   =  Aligns  text │
                                   │         │      │          with the  dimension │
                                   │         │      │          line                │
                                   │         │      │                              │
                                   │         │      │        • 1   =   Draws  text │
                                   │         │      │          horizontally        │
                                   ├─────────┼──────┼──────────────────────────────┤
                                   │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      =      Draws │
                                   │         │      │          arrowheads.         │
                                   │         │      │                              │
                                   │         │      │        • >0  = Draws oblique │
                                   │         │      │          strokes instead  of │
                                   │         │      │          arrowheads.     The │
                                   │         │      │          size of the oblique │
                                   │         │      │          strokes          is │
                                   │         │      │          determined by  this │
                                   │         │      │          value multiplied by │
                                   │         │      │          the DIMSCALE value  │
                                   ├─────────┼──────┼──────────────────────────────┤
                                   │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 = 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   (Bit    3)    = │
                                   │         │      │          Suppresses  leading │
                                   │         │      │          zeros  in   decimal │
                                   │         │      │          dimensions     (for │
                                   │         │      │          example,     0.5000 │
                                   │         │      │          becomes .5000)      │
                                   │         │      │                              │
                                   │         │      │        • 8    (Bit    4)   = │
                                   │         │      │          Suppresses trailing │
                                   │         │      │          zeros   in  decimal │
                                   │         │      │          dimensions     (for │
                                   │         │      │          example,    12.5000 │
                                   │         │      │          becomes 12.5)       │
                                   │         │      │                              │
                                   │         │      │        • 12  (Bit   3+4)   = │
                                   │         │      │          Suppresses     both │
                                   │         │      │          leading         and │
                                   │         │      │          trailing zeros (for │
                                   │         │      │          example,     0.5000 │
                                   │         │      │          becomes .5)         │
                                   └─────────┴──────┴──────────────────────────────┘

   Table Structure DXF R2000+
          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

   Additional DIMSTYLE Variables DXF R13/14
       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 = Decimal degrees     │
                              │                │      │                                  │
                              │                │      │        • 1                 =     │
                              │                │      │          Degrees/minutes/seconds │
                              │                │      │                                  │
                              │                │      │        • 2 = Grad                │
                              │                │      │                                  │
                              │                │      │        • 3 = Radians             │
                              ├────────────────┼──────┼──────────────────────────────────┤
                              │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 = Positions the  text │
                              │                │      │          above   the   dimension │
                              │                │      │          line                and │
                              │                │      │          center-justifies     it │
                              │                │      │          between  the  extension │
                              │                │      │          lines                   │
                              │                │      │                                  │
                              │                │      │        • 1  = Positions the text │
                              │                │      │          next   to   the   first │
                              │                │      │          extension line          │
                              │                │      │                                  │
                              │                │      │        • 2  = Positions the text │
                              │                │      │          next  to   the   second │
                              │                │      │          extension line          │
                              │                │      │                                  │
                              │                │      │        • 3  = Positions the text │
                              │                │      │          above and aligned  with │
                              │                │      │          the   first   extension │
                              │                │      │          line                    │
                              │                │      │                                  │
                              │                │      │        • 4  =   =Positions   the │
                              │                │      │          text  above and aligned │
                              │                │      │          with     the     second │
                              │                │      │          extension line          │
                              ├────────────────┼──────┼──────────────────────────────────┤
                              │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   =  First  dimension │
                              │                │      │          line is not suppressed  │
                              │                │      │                                  │
                              │                │      │        • 1  =  First   dimension │
                              │                │      │          line is suppressed      │
                              ├────────────────┼──────┼──────────────────────────────────┤
                              │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  =  Second  dimension │
                              │                │      │          line is not suppressed  │
                              │                │      │                                  │
                              │                │      │        • 1  =  Second  dimension │
                              │                │      │          line is suppressed      │
                              ├────────────────┼──────┼──────────────────────────────────┤
                              │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 = Bottom              │
                              │                │      │                                  │
                              │                │      │        • 1 = Middle              │
                              │                │      │                                  │
                              │                │      │        • 2 = Top                 │
                              ├────────────────┼──────┼──────────────────────────────────┤
                              │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   =  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)      │
                              ├────────────────┼──────┼──────────────────────────────────┤
                              │DIMUPT          │ 288  │ Controls       options       for │
                              │                │      │ user-positioned text.            │
                              │                │      │                                  │
                              │                │      │        • 0   =  Cursor  controls │
                              │                │      │          only the dimension line │
                              │                │      │          location                │
                              │                │      │                                  │
                              │                │      │        • 1   =  Cursor  controls │
                              │                │      │          both the text  position │
                              │                │      │          and  the dimension line │
                              │                │      │          location                │
                              └────────────────┴──────┴──────────────────────────────────┘

   Additional DIMSTYLE Variables DXF R2000
       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   =  Places  both │
                               │                 │      │          text   and   arrows │
                               │                 │      │          outside   extension │
                               │                 │      │          lines               │
                               │                 │      │                              │
                               │                 │      │        • 1  =  Moves  arrows │
                               │                 │      │          first, then text    │
                               │                 │      │                              │
                               │                 │      │        • 2   =   Moves  text │
                               │                 │      │          first, then arrows  │
                               │                 │      │                              │
                               │                 │      │        • 3  =  Moves  either │
                               │                 │      │          text   or   arrows, │
                               │                 │      │          whichever fits best │
                               │                 │      │                              │
                               │                 │      │        A leader is added  to │
                               │                 │      │        moved  dimension text │
                               │                 │      │        when DIMTMOVE is  set │
                               │                 │      │        to 1.                 │
                               ├─────────────────┼──────┼──────────────────────────────┤
                               │DIMAZIN          │ 79   │ Suppresses zeros for angular │
                               │                 │      │ dimensions.                  │
                               │                 │      │                              │
                               │                 │      │        • 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)         │
                               ├─────────────────┼──────┼──────────────────────────────┤
                               │DIMFRAC          │ 276  │ Sets  the  fraction   format │
                               │                 │      │ when  DIMLUNIT  is  set to 4 │
                               │                 │      │ (Architectural)     or     5 │
                               │                 │      │ (Fractional).                │
                               │                 │      │                              │
                               │                 │      │        • 0    =   Horizontal │
                               │                 │      │          stacking            │
                               │                 │      │                              │
                               │                 │      │        • 1    =     Diagonal │
                               │                 │      │          stacking            │
                               │                 │      │                              │
                               │                 │      │        • 2   =  Not  stacked │
                               │                 │      │          (for example, 1/2)  │
                               ├─────────────────┼──────┼──────────────────────────────┤
                               │DIMLDRBLK_HANDLE │ 341  │ Specifies the arrow type for │
                               │                 │      │ leaders.   Handle  to  BLOCK │
                               │                 │      │ RECORD                       │
                               ├─────────────────┼──────┼──────────────────────────────┤
                               │DIMLUNIT         │ 277  │ Sets units for all dimension │
                               │                 │      │ types except Angular.        │
                               │                 │      │                              │
                               │                 │      │        • 1 = Scientific      │
                               │                 │      │                              │
                               │                 │      │        • 2 = Decimal         │
                               │                 │      │                              │
                               │                 │      │        • 3 = Engineering     │
                               │                 │      │                              │
                               │                 │      │        • 4  =  Architectural │
                               │                 │      │          (always   displayed │
                               │                 │      │          stacked)            │
                               │                 │      │                              │
                               │                 │      │        • 5    =   Fractional │
                               │                 │      │          (always   displayed │
                               │                 │      │          stacked)            │
                               │                 │      │                              │
                               │                 │      │        • 6    =    Microsoft │
                               │                 │      │          Windows     Desktop │
                               │                 │      │          (decimal     format │
                               │                 │      │          using Control Panel │
                               │                 │      │          settings        for │
                               │                 │      │          decimal   separator │
                               │                 │      │          and number grouping │
                               │                 │      │          symbols)            │
                               ├─────────────────┼──────┼──────────────────────────────┤
                               │DIMLWD           │ 371  │ Assigns    lineweight     to │
                               │                 │      │ dimension lines.             │
                               │                 │      │                              │
                               │                 │      │        • -3  =  Default (the │
                               │                 │      │          LWDEFAULT value)    │
                               │                 │      │                              │
                               │                 │      │        • -2 = BYBLOCK        │
                               │                 │      │                              │
                               │                 │      │        • -1 = BYLAYER        │
                               ├─────────────────┼──────┼──────────────────────────────┤
                               │DIMLWE           │ 372  │ Assigns    lineweight     to │
                               │                 │      │ extension lines.             │
                               │                 │      │                              │
                               │                 │      │        • -3  =  Default (the │
                               │                 │      │          LWDEFAULT value)    │
                               │                 │      │                              │
                               │                 │      │        • -2 = BYBLOCK        │
                               │                 │      │                              │
                               │                 │      │        • -1 = BYLAYER        │
                               ├─────────────────┼──────┼──────────────────────────────┤
                               │DIMTMOVE         │ 279  │ Sets dimension text movement │
                               │                 │      │ rules.                       │
                               │                 │      │                              │
                               │                 │      │        • 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    │
                               └─────────────────┴──────┴──────────────────────────────┘

   Text Location
       This  image  shows  the  default  text  locations  created by BricsCAD for dimension variables dimtad and
       dimjust: [image]

   Unofficial DIMSTYLE Variables for DXF R2007 and later
       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         │
                                └────────────────┴──────┴──────────────────────────────┘

   Extended Settings as Special XDATA Groups
       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_RECORD Table
       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.

   DXF Entities
   DIMENSION Entity
       SEE ALSO:

          • DXF Reference: DIMENSION

          • DXFInternals: dimstyle_table_internals
       [image]

   DXF Objects
       TODO

   Management Structures
   Block Management Structures
       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:

          • ezdxf DXF Internals: blocks_section_internals

          • DXF Reference: BLOCKS Section

          • DXF Reference: BLOCK Entity

          • DXF Reference: ENDBLK Entity

          • DXF Reference: INSERT Entity

   Block Names
       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.

   Block Definitions in DXF R12
       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

   Block Definitions in DXF R2000+
       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:

          • Tag Structure DXF R13 and later

          • ezdxf DXF Internals: tables_section_internals

          • DXF Reference: TABLES Section

          • DXF Reference: BLOCK_RECORD Entity

       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

   Layout Management Structures
       Layouts are separated entity spaces, there are three different Layout types:

          1. modelspace contains the ‘real’ world representation of the drawing subjects in real world units.

          2. paperspace layouts are used to create different drawing  sheets  of  the  modelspace  subjects  for
             printing or PDF export

          3. Blocks are reusable sets of graphical entities, inserted/referenced by the INSERT entity.

       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:
          Information about Block Management Structures

       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:
          All floating point values are rounded to 2 decimal places for better readability.

   LAYOUT Entity
       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).

   Main VIEWPORT Entity for LAYOUT
       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

DEVELOPER GUIDES

       Information about ezdxf internals.

   Design
       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 !!!

   Package Design for Developers
       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

   Terminology
   States
       DXF entities and objects can have different states:

       UNBOUND
              Entity is not stored in the Drawing entity database and DXF attribute handle is None and attribute
              doc can be None

       BOUND  Entity  is stored in the Drawing entity database, attribute doc has a reference to Drawing and DXF
              attribute handle is not None

       UNLINKED
              Entity is not linked to a layout/owner, DXF attribute owner is None

       LINKED Entity is linked to a layout/owner, DXF attribute owner is not None

       Virtual Entity
              State: UNBOUND & UNLINKED

       Unlinked Entity
              State: BOUND & UNLINKED

       Bound Entity
              State: BOUND & LINKED

   Actions
       NEW    Create a new DXF document

       LOAD   Load a DXF document from an external source

       CREATE Create DXF structures from NEW or LOAD data

       DESTROY
              Delete DXF structures

       BIND   Bind an entity to a Drawing, set entity state to BOUND & UNLINKED and  check  or  create  required
              resources

       UNBIND unbind …

       LINK   Link  an  entity  to  an  owner/layout.   This makes an entity to a real DXF entity, which will be
              exported at the saving process. Any DXF entity can only  be  linked  to  one  parent  entity  like
              DICTIONARY or BLOCK_RECORD.

       UNLINK unlink …

   Loading a DXF Document
       Loading  a  DXF  document from an external source, creates a new Drawing object. This loading process has
       two stages:

   First Loading Stage
       • LOAD content from external source as SectionDict: loader.load_dxf_structure()

       • LOAD tag structures as DXFEntity objects: loader.load_dxf_entities()

       • BIND entities: loader.load_and_bind_dxf_content(); Special handling of the BIND  process,  because  the
         Drawing is not full initialized, a complete validation is not possible at this stage.

   Second Loading Stage
       Parse SectionDict:

       • CREATE sections: HEADER, CLASSES, TABLES, BLOCKS and OBJECTS

       • CREATE layouts: Blocks, Layouts

       • LINK entities to a owner/layout

       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().

   New DXF Document
   Creating New DXF Entities
       The default constructor of each entity type creates a new virtual entity:

       • DXF attribute owner is None

       • DXF attribute handle is None

       • Attribute doc is None

       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:

       1. UNBOUND: doc is None and handle is None

       2. BOUND: doc is not None and handle is not None

   Factory functionsnew(), create a new virtual DXF object/entity

       • load(), load (create) virtual DXF object/entity from DXF tags

       • bind(), bind an entity to a document, create required resources  if  necessary  (e.g.  ImageDefReactor,
         SEQEND) and raise exceptions for non-existing resources.

         • Bind  entity  loaded  from an external source to a document, all referenced resources must exist, but
           try to repair as many flaws as possible because errors were created by another  application  and  are
           not the responsibility of the package-user.

         • Bind  an  entity from another DXF document, all invalid resources will be removed silently or created
           (e.g. SEQEND). This is a simple import from another document without  resource  import,  for  a  more
           advanced import including resources exist the importer add-on.

         • Bootstrap  problem  for  binding  loaded  table entries and objects in the OBJECTS section! Can’t use
           Auditor to repair this objects, because the DXF document is not fully initialized.

       • is_bound() returns True if entity is bound to document docunbind() function to remove an entity from a document and set state to a virtual entity,  which  should
         also UNLINK the entity from layout, because an layout can not store a virtual entity.

       • cls(), returns the class

       • register_entity(), registration decorator

       • replace_entity(), registration decorator

   Class Interfaces
   DXF Entities
       • NEW constructor to create an entity from scratch

       • LOAD constructor to create an entity loaded from an external source

       • DESTROY  interface  to  kill  an  entity, set entity state to dead, which means entity.is_alive returns
         False. All entity iterators like EntitySpace, EntityQuery,  and  EntityDB  must  filter  (ignore)  dead
         entities.  Calling DXFEntity.destroy() is a regular way to delete entities.

       • LINK  an entity to a layout by BlockRecord.link(), which set the owner handle to BLOCK_RECORD handle (=
         layout key) and add the entity to the entity space of the BLOCK_RECORD  and  set/clear  the  paperspace
         flag.

   DXF Objects
       • NEW, LOAD, DESTROY see DXF entities

       • LINK:  Linking  an  DXF  object means adding the entity to a parent object in the OBJECTS section, most
         likely a DICTIONARY object, and adding the object to the entity  space  of  the  OBJECTS  section,  the
         root-dict  is  the  only entity in the OBJECTS section which has an invalid owner handle “0”. Any other
         object with an invalid or destroyed owner is an  orphaned  entity.   The  audit  process  destroys  and
         removes orphaned objects.

       • Extension  dictionaries  (ACAD_XDICTIONARY)  are DICTIONARY objects located in the OBJECTS sections and
         can reference/own other entities of the OBJECTS section.

       • The root-dictionary is the only entity in the OBJECTS section which has an invalid  owner  handle  “0”.
         Any other object with an invalid or destroyed owner is an orphaned entity.

   Layouts
       • LINK interface to link an entity to a layout

       • UNLINK interface to remove an entity from a layout

   Database
       • BIND interface to add an entity to the database of a document

       • delete_entity() interface, same as UNBIND and DESTROY an entity

   Internal Data Structures
   Entity Database
       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 get() method and the index operator [], return destroyed entities and entities from the trashcan.

       class ezdxf.entitydb.EntityDB

              __getitem__(handle: str) -> DXFEntity
                     Get entity by handle, does not filter destroyed entities nor entities in the trashcan.

              __setitem__(handle: str, entity: DXFEntity) -> None
                     Set entity for handle.

              __delitem__(handle: str) -> None
                     Delete entity by handle. Removes entity only from database, does not destroy the entity.

              __contains__(item: Union[str, DXFEntity]) -> bool
                     True if database contains handle.

              __len__() -> int
                     Count of database items.

              __iter__() -> Iterable[str]
                     Iterable of all handles, does filter destroyed entities but not entities in the trashcan.

              get(handle: str) -> Optional[DXFEntity]
                     Returns entity for handle or None if no entry exist, does not filter destroyed entities.

              next_handle() -> str
                     Returns next unique handle.

              keys() -> Iterable[str]
                     Iterable of all handles, does filter destroyed entities.

              values() -> Iterable[DXFEntity]
                     Iterable of all entities, does filter destroyed entities.

              items() -> Iterable[Tuple[str, DXFEntity]]
                     Iterable of all (handle, entities) pairs, does filter destroyed entities.

              add(entity: DXFEntity) -> None
                     Add  entity  to  database, assigns a new handle to the entity if entity.dxf.handle is None.
                     Adding the same entity multiple times is possible and creates only a single database entry.

              new_trashcan() -> ezdxf.entitydb.EntityDB.Trashcan
                     Returns a new trashcan, empty trashcan manually by: : func:Trashcan.clear().

              trashcan() -> ezdxf.entitydb.EntityDB.Trashcan
                     Returns a new trashcan in context manager mode,  trashcan  will  be  emptied  when  leaving
                     context.

              purge() -> None
                     Remove all destroyed entities from database, but does not empty the trashcan.

   Entity Space
       class ezdxf.entitydb.EntitySpace(entities=None)
              An  EntitySpace  is  a  collection of DXFEntity objects, that stores only  references to DXFEntity
              objects.

              The Modelspace, any Paperspace layout and BlockLayout objects have  an  EntitySpace  container  to
              store their entities.

              __iter__() -> Iterable[DXFEntity]
                     Iterable of all entities, filters destroyed entities.

              __getitem__(index) -> DXFEntity
                     Get entity at index item

                     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.

              __len__() -> int
                     Count of entities inluding destroyed entities.

              has_handle(handle: str) -> bool
                     True if handle is present, does filter destroyed entities.

              purge()
                     Remove all destroyed entities from entity space.

              add(entity: DXFEntity) -> None
                     Add entity.

              extend(entities: Iterable[DXFEntity]) -> None
                     Add multiple entities.

              remove(entity: DXFEntity) -> None
                     Remove entity.

              clear() -> None
                     Remove all entities.

   DXF Types
       Required DXF tag interface:

          • property code: group code as int

          • property value: tag value of unspecific type

          • dxfstr(): returns the DXF string

          • clone(): returns a deep copy of tag

   DXFTag Factory Functions
       ezdxf.lldxf.types.dxftag(code: int, value: TagValue) -> ezdxf.lldxf.types.DXFTag
              DXF tag factory function.

              Parameterscode – group code

                     • value – tag value

              Returns: DXFTag or inherited

       ezdxf.lldxf.types.tuples_to_tags(iterable:          Iterable[Tuple[int,          TagValue]])           ->
       Iterable[ezdxf.lldxf.types.DXFTag]
              Returns an iterable if :class: DXFTag or inherited, accepts an iterable of (code, value) tuples as
              input.

   DXFTag
       class ezdxf.lldxf.types.DXFTag(code: int, value: TagValue)
              Immutable DXFTag class - immutable by design, not by implementation.

              Parameterscode – group code as int

                     • value – tag value, type depends on group code

              Variablescode – group code as int (do not change)

                     • value – tag value (read-only property)

              __eq__(other) -> bool
                     True if other and self has same content for code and value.

              __getitem__(index: int)
                     Returns code for index 0 and value for index 1, emulates a tuple.

              __hash__()
                     Hash support, DXFTag can be used in sets and as dict key.

              __iter__() -> Iterable
                     Returns (code, value) tuples.

              __repr__() -> str
                     Returns representation string 'DXFTag(code, value)'.

              __str__() -> str
                     Returns content string '(code, value)'.

              clone() -> ezdxf.lldxf.types.DXFTag
                     Returns a clone of itself,  this  method  is  necessary  for  the  more  complex  (and  not
                     immutable) DXF tag types.

              dxfstr() -> str
                     Returns the DXF string e.g. '  0\nLINE\n'

   DXFBinaryTag
       class ezdxf.lldxf.types.DXFBinaryTag(DXFTag)
              Immutable BinaryTags class - immutable by design, not by implementation.

              dxfstr() -> str
                     Returns the DXF string for all vertex components.

              tostring() -> str
                     Returns binary value as single hex-string.

   DXFVertex
       class ezdxf.lldxf.types.DXFVertex(DXFTag)
              Represents a 2D or 3D vertex, stores only the group code of the x-component of the vertex, because
              the y-group-code is x-group-code + 10 and z-group-code id x-group-code+20, this  is  a  rule  that
              ALWAYS applies.  This tag is immutable by design, not by implementation.

              Parameterscode – group code of x-component

                     • value – sequence of x, y and optional z values

              dxfstr() -> str
                     Returns the DXF string for all vertex components.

              dxftags() -> Iterable[Tuple]
                     Returns all vertex components as single DXFTag objects.

   NONE_TAG
       ezdxf.lldxf.types.NONE_TAG
              Special tag representing a none existing tag.

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

       class ezdxf.lldxf.tags.Tags
              Subclass of list.

              Collection of DXFTag as flat list. Low level tag container, only required for advanced stuff.

              classmethod from_text(text: str) -> Tags
                     Constructor from DXF string.

              dxftype() -> str
                     Returns DXF type of entity, e.g. 'LINE'.

              get_handle() -> str
                     Get DXF handle. Raises DXFValueError if handle not exist.

                     Returns
                            handle as plain hex string like 'FF00'

                     Raises DXFValueError – no handle found

              replace_handle(new_handle: str) -> None
                     Replace existing handle.

                     Parameters
                            new_handle – new handle as plain hex string e.g. 'FF00'

              has_tag(code: int) -> bool
                     Returns True if a DXFTag with given group code is present.

                     Parameters
                            code – group code as int

              has_embedded_objects() -> bool

              get_first_tag(code: int, default=DXFValueError) -> DXFTag
                     Returns first DXFTag with given group code or default, if default  !=  DXFValueError,  else
                     raises DXFValueError.

                     Parameterscode – group code as int

                            • default – return value for default case or raises DXFValueError

              get_first_value(code: int, default=DXFValueError) -> Any
                     Returns value of first DXFTag with given group code or default if default != DXFValueError,
                     else raises DXFValueError.

                     Parameterscode – group code as int

                            • default – return value for default case or raises DXFValueError

              find_all(code: int) -> List[DXFTag]
                     Returns a list of DXFTag with given group code.

                     Parameters
                            code – group code as int

              filter(codes: Iterable[int]) -> Iterable[DXFTag]
                     Iterate and filter tags by group codes.

                     Parameters
                            codes – group codes to filter

              collect_consecutive_tags(codes: Iterable[int], start: int = 0, end: int = None) -> Tags
                     Collect all consecutive tags with group code in codes, start and end  delimits  the  search
                     range. A tag code not in codes ends the process.

                     Parameterscodes – iterable of group codes

                            • start – start index as int

                            • end – end index as int, None for end index = len(self)

                     Returns
                            collected tags as Tags

              tag_index(code: int, start: int = 0, end: int = None) -> int
                     Return index of first DXFTag with given group code.

                     Parameterscode – group code as int

                            • start – start index as int

                            • end – end index as int, None for end index = len(self)

              update(tag: DXFTag)
                     Update  first  existing  tag  with  same group code as tag, raises DXFValueError if tag not
                     exist.

              set_first(tag: DXFTag)
                     Update first existing tag with group code tag.code or append tag.

              remove_tags(codes: Iterable[int]) -> None
                     Remove all tags inplace with group codes specified in codes.

                     Parameters
                            codes – iterable of group codes as int

              remove_tags_except(codes: Iterable[int]) -> None
                     Remove all tags inplace except those with group codes specified in codes.

                     Parameters
                            codes – iterable of group codes

              pop_tags(codes: Iterable[int]) -> Iterable[DXFTag]
                     Pop tags with group codes specified in codes.

                     Parameters
                            codes – iterable of group codes

              classmethod strip(tags: Tags, codes: Iterable[int]) -> Tags
                     Constructor from tags, strips all tags with group codes in codes from tags.

                     Parameterstags – iterable of DXFTagcodes – iterable of group codes as int

       ezdxf.lldxf.tags.group_tags(tags: Iterable[DXFTag], splitcode: int = 0) -> Iterable[Tags]
              Group of tags starts with a SplitTag and ends before the next SplitTag.  A SplitTag is a tag  with
              code == splitcode, like (0, ‘SECTION’) for splitcode == 0.

              Parameterstags – iterable of DXFTagint (splitcode) – group code of split tag

       class ezdxf.lldxf.extendedtags.ExtendedTags(tags: Iterable[DXFTag] = None, legacy=False)
              Represents the extended DXF tag structure introduced with DXF R13.

              Args:  tags: iterable of DXFTag legacy: flag for DXF R12 tags

              appdata
                     Application defined data as list of Tags

              subclasses
                     Subclasses as list of Tags

              xdata  XDATA as list of Tags

              embedded_objects
                     embedded objects as list of Tags

              noclass
                     Short cut to access first subclass.

              get_handle() -> str
                     Returns handle as hex string.

              dxftype() -> str
                     Returns DXF type as string like “LINE”.

              replace_handle(handle: str) -> None
                     Replace the existing entity handle by a new value.

              legacy_repair()
                     Legacy (DXF R12) tags handling and repair.

              clone() -> ExtendedTags
                     Shallow copy.

              flatten_subclasses()
                     Flatten subclasses in legacy mode (DXF R12).

                     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.

              get_subclass(name: str, pos: int = 0) -> Tags
                     Get subclass name.

                     Parametersname – subclass name as string like “AcDbEntity”

                            • pos – start searching at subclass pos.

              has_xdata(appid: str) -> bool
                     True if has XDATA for appid.

              get_xdata(appid: str) -> Tags
                     Returns XDATA for appid as Tags.

              set_xdata(appid: str, tags: IterableTags) -> None
                     Set tags as XDATA for appid.

              new_xdata(appid: str, tags: IterableTags = None) -> Tags
                     Append a new XDATA block.

                     Assumes that no XDATA block with the same appid already exist:

                        try:
                            xdata = tags.get_xdata('EZDXF')
                        except ValueError:
                            xdata = tags.new_xdata('EZDXF')

              has_app_data(appid: str) -> bool
                     True if has application defined data for appid.

              get_app_data(appid: str) -> Tags
                     Returns application defined data for appid as Tags including marker tags.

              get_app_data_content(appid: str) -> Tags
                     Returns application defined data for appid as Tags without first and last marker tag.

              set_app_data_content(appid: str, tags: IterableTags) -> None
                     Set application defined data for appid for already exiting data.

              new_app_data(appid: str, tags: IterableTags = None, subclass_name: str = None) -> Tags
                     Append a new application defined data to subclass subclass_name.

                     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)

              classmethod from_text(text: str, legacy: bool = False) -> ExtendedTags
                     Create ExtendedTags from DXF text.

   Packed DXF Tags
       Store DXF tags in compact data structures as list or array.array to reduce memory usage.

       class ezdxf.lldxf.packedtags.TagList(data: Iterable = None)
              Store data in a standard Python list.

              Args:  data: iterable of DXF tag values.

              values Data storage as list.

              clone() -> TagList
                     Returns a deep copy.

              classmethod from_tags(tags: Tags, code: int) -> TagList
                     Setup list from iterable tags.

                     Parameterstags – tag collection as Tagscode – group code to collect

              clear() -> None
                     Delete all data values.

       class ezdxf.lldxf.packedtags.TagArray(data: Iterable = None)
              TagArray is a subclass of TagList, which store data in an array.array.  Array type is  defined  by
              class variable DTYPE.

              Args:  data: iterable of DXF tag values.

              DTYPE  array.array type as string

              values Data storage as array.array

              set_values(values: Iterable) -> None
                     Replace data by values.

       class ezdxf.lldxf.packedtags.VertexArray(data: Iterable = None)
              Store vertices in an array.array('d').  Vertex size is defined by class variable VERTEX_SIZE.

              Args:  data: iterable of vertex values as linear list e.g. [x1, y1, x2, y2, x3, y3, ...].

              VERTEX_SIZE
                     Size of vertex (2 or 3 axis).

              __len__() -> int
                     Count of vertices.

              __getitem__(index: int)
                     Get vertex at index, extended slicing supported.

              __setitem__(index: int, point: Sequence[float]) -> None
                     Set vertex point at index, extended slicing not supported.

              __delitem__(index: int) -> None
                     Delete vertex at index, extended slicing supported.

              __iter__() -> Iterable[Sequence[float]]
                     Returns iterable of vertices.

              __str__() -> str
                     String representation.

              insert(pos: int, point: Sequence[float])
                     Insert point in front of vertex at index pos.

                     Parameterspos – insert position

                            • point – point as tuple

              append(point: Sequence[float]) -> None
                     Append point.

              extend(points: Iterable[Sequence[float]]) -> None
                     Extend array by points.

              set(points: Iterable[Sequence[float]]) -> None
                     Replace all vertices by points.

              clear() -> None
                     Delete all vertices.

              clone() -> VertexArray
                     Returns a deep copy.

              classmethod from_tags(tags: Iterable[DXFTag], code: int = 10) -> VertexArray
                     Setup point array from iterable tags.

                     Parameterstags – iterable of DXFVertexcode – group code to collect

              export_dxf(tagwriter: ezdxf.lldxf.tagwriter.TagWriter, code=10)

   Documentation Guide
   Formatting Guide
       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

   guide  Example module
       guide.example_func(a: int, b: str, test: str = None, flag: bool = True) -> None
              Parameters a and b are positional arguments, argument test defaults to None and flag to True.  Set
              a to 70 and b to “x”  as  an  example.  Inline  code  examples  example_func(70,  'x')  or  simple
              example_func(70, "x")

                 • arguments: a, b, test and flags

                 • literal number values: 1, 2 … 999

                 • literal string values: “a String”

                 • literal tags: (5, “F000”)

                 • inline code: call a example_func(x)

                 • Python keywords: None, True, False, tuple, list, dict, str, int, float

                 • Exception classes: DXFAttributeError

       class guide.ExampleCls(**kwargs)
              The  ExampleCls constructor accepts a number of optional keyword arguments.  Each keyword argument
              corresponds to an instance attribute, so for example

                 e = ExampleCls(flag=True)

              flag   This is the attribute flag.

                     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

              set_axis(axis)
                     axis as (x, y, z) tuple

                     Args:  axis: (x, y, z) tuple

              example_method(flag: bool = False) -> None
                     Method example_method() of class ExampleCls

   Text Formatting
       DXF version
              DXF R12 (AC1009), DXF R2004 (AC1018)

       DXF Types
              DXF types are always written in uppercase letters  but  without  further  formatting:  DXF,  LINE,
              CIRCLE

       (internal API)
              Marks methods as internal API, gets no public documentation.

       (internal class)
              Marks classes only for internal usage, gets not public documentation.

       Spatial Dimensions
              2D and 3D with an uppercase letter D

       Axis   x-axis, y-axis and z-axis

       Planes xy-plane, xz-plane, yz-plane

       Layouts
              modelspace, paperspace [layout], block [layout]

       Extended Entity Data
              AppData, XDATA, embedded object, APPID

GLOSSARY

       ACI    ACI

       ACIS   The  3D  ACIS Modeler (ACIS) is a geometric modeling kernel developed by Spatial Corp. ® (formerly
              Spatial Technology), part of Dassault Systems.

       bulge  The bulge value is used to create arc shaped line segments in Polyline and LWPolyline entities.

       CAD    Computer-Assisted Drafting or Computer-Aided Design

       CTB    Color dependent plot style table (ColorDependentPlotStyles)

       DWG    Proprietary file format of AutoCAD ®. Documentation for this format is  available  from  the  Open
              Design  Alliance  (ODA)  at  their  Downloads  section.  This  documentation is created by reverse
              engineering therefore not perfect nor complete.

       DXF    Drawing eXchange Format is a file format used by AutoCAD ® to  interchange  data  with  other  CAD
              applications. DXF is a trademark of Autodesk ®.

       STB    Named plot style table (NamedPlotStyles)

       true color
              RGB color representation, a combination red, green and blue values to define a color.

INDICES AND TABLES

       • genindex

       • search

AUTHOR

       Manfred Moitzi

COPYRIGHT

       2011-2020, Manfred Moitzi