ezdxfhttps://ezdxf.mozman.at/2024-03-02T00:00:00+01:00A Python interface to DXFRelease v1.22024-03-02T00:00:00+01:002024-03-02T00:00:00+01:00mozmantag:ezdxf.mozman.at,2024-03-02:/release-v1-2.html<p>Release notes for ezdxf v1.2</p><h2>Links to Knowledge Graph</h2>
<ul>
<li><a href="https://ezdxf.mozman.at/notes/#/page/release%20notes%20v1.2.x">Release Notes</a></li>
<li><a href="https://ezdxf.mozman.at/notes/#/page/changelog">Changelog</a></li>
</ul>Release v1.1.42023-12-24T00:00:00+01:002023-12-24T00:00:00+01:00mozmantag:ezdxf.mozman.at,2023-12-24:/release-v1-1-4.html<p>Release notes for ezdxf v1.1.4</p><h2>Links to Knowledge Graph</h2>
<ul>
<li><a href="https://ezdxf.mozman.at/notes/#/page/release%20notes%20v1.1.x">Release Notes</a></li>
<li><a href="https://ezdxf.mozman.at/notes/#/page/changelog">Changelog</a></li>
</ul>Release v1.1.32023-11-25T00:00:00+01:002023-11-25T00:00:00+01:00mozmantag:ezdxf.mozman.at,2023-11-25:/release-v1-1-3.html<p>Release notes for ezdxf v1.1.3</p><h2>Links to Knowledge Graph</h2>
<ul>
<li><a href="https://ezdxf.mozman.at/notes/#/page/release%20notes%20v1.1.x">Release Notes</a></li>
<li><a href="https://ezdxf.mozman.at/notes/#/page/changelog">Changelog</a></li>
</ul>Project Notes in Logseq2023-11-12T00:00:00+01:002023-11-12T00:00:00+01:00mozmantag:ezdxf.mozman.at,2023-11-12:/project-notes-in-logseq.html<p>Using Logseq to manage the project notes.</p><h1>Projects Notes in Logseq</h1>
<p>I have started managing notes and documents that are not included in the <code>ezdxf</code> documentation in <a href="https://www.logseq.com">Logseq</a>. The published edition of this Knowledge Graph is included on this website and is accessible via the link <a href="https://ezdxf.mozman.at/notes">https://ezdxf.mozman.at/notes</a> and via the <em>Knowledge Graph</em> menu entry in the upper right corner of this page.</p>
<p>The notes are included in the source code repository on Github and stored as Markdown files in the <code>ezdxf/notes</code> folder.</p>
<p>The Knowledge Graph includes:</p>
<ul>
<li><code>CHANGELOG.md</code> (renamed from <code>NEWS.md</code>) <a href="https://ezdxf.mozman.at/notes/#/page/changelog">https://ezdxf.mozman.at/notes/#/page/changelog</a></li>
<li><code>IDEAS.md</code> (renamed from <code>TODO.md</code>) <a href="https://ezdxf.mozman.at/notes/#/page/ideas">https://ezdxf.mozman.at/notes/#/page/ideas</a></li>
<li>the release notes of future releases and some versions back</li>
<li>the FAQ and the HOWTO sections from the documentation</li>
<li>the reference section of this page</li>
<li>scattered notes from the source code repository</li>
</ul>
<p><a href="https://www.logseq.com">Logseq</a>'s outline structure is not ideal for all the documents I want to include, but I chose <a href="https://www.logseq.com">Logseq</a> over <a href="https://obsidian.md">Obsidian.md</a> because it is open source and can publish the knowledge graph as static website, <em>static</em> in the sense of no server-side code execution. This feature is important for linking the information from outside the application and cannot be achieved for free with <a href="https://obsidian.md">Obsidian.md</a>.</p>
<p>I also use <a href="https://www.logseq.com">Logseq</a> for my work notes, which it's ideal for, so I'm already familiar with the application. The application is an <a href="https://www.electronjs.org/">Electron</a> application that runs on all platforms, with the disadvantage: it's an <a href="https://www.electronjs.org/">Electron</a> application.</p>
<p>To save time and effort, I will stop posting release notes on this page. The release notes for future versions of <code>ezdxf</code> will be posted on the Github <a href="https://github.com/mozman/ezdxf/discussions">forum</a>. These release notes are also included in the <a href="https://ezdxf.mozman.at/notes/#/page/release%20notes">Knowledge Graph</a>.</p>Release v1.1.22023-11-01T00:00:00+01:002023-11-01T00:00:00+01:00mozmantag:ezdxf.mozman.at,2023-11-01:/release-v1-1.html<p>Release notes for ezdxf v1.1.2</p><h3>New Requirements</h3>
<ul>
<li>This version requires Python 3.8 or newer. </li>
<li>The <code>numpy</code> and <code>fontTools</code> packages are hard dependencies.</li>
</ul>
<p><strong>WARNING:</strong> The font support has changed drastically in this version.
If you directly use the <code>ezdxf.tools.fonts</code> module, your code will break.
We apologize for the inconvenience. To use the previous version, pin the <code>ezdxf</code> version
to v1.0.3 in your <code>requirements.txt</code> file!</p>
<h3>Font Rendering by FontTools</h3>
<p>Font rendering using <code>matplotlib</code> has been replaced by <code>fontTools</code>. It is now faster and
more accurate. However, the convenient multi-platform support provided by <code>matplotlib</code>
must now be handled by <code>ezdxf</code>, and it may not work as smoothly as with <code>matplotlib</code>.</p>
<p>The available fonts on a system are cached in the <code>$XDG_CACHE_HOME/ezdxf</code> directory,
which defaults to <code>~/.cache/ezdxf</code>. Please note that this cache will <strong>not</strong> be updated
automatically if you add or remove fonts.</p>
<p>To update the font cache, use the following command:</p>
<div class="highlight"><pre><span></span><code>ezdxf<span class="w"> </span>--fonts
</code></pre></div>
<p>For more information on this topic, please refer to <a href="https://ezdxf.mozman.at/docs/howto/fonts.html">this link</a>.</p>
<h3>Shape Font Support</h3>
<p>We've added new support for measuring and rendering <code>.shx</code>, <code>.shp</code>, and <code>.lff</code> fonts.</p>
<p>Shape fonts are the basic stroke fonts commonly found in CAD applications. None of these
fonts are included in <code>ezdxf</code> due to licensing restrictions or the restrictive licensing
of the <code>.lff</code> fonts used in LibreCAD.</p>
<p>As there is no universal way to find these fonts, you will need to create a config file
and add the font directories where these fonts are located to the <code>support_dirs</code> entry.</p>
<p>For more information on config files, please read <a href="https://ezdxf.mozman.at/docs/options.html#config-files">this link</a>.</p>
<p>On Linux, you can add symbolic links to these directories in the <code>~/.fonts</code> directory. </p>
<p>Don't forget to update the font cache when adding new font directories!</p>
<h3>New Backends for the Drawing Add-on</h3>
<p>We've introduced new backends to the <code>drawing</code> add-on, allowing you to export DXF content
as SVG, PDF, PNG, PLT/HPGL2, and simplified DXF files.</p>
<p>The new SVG backend is a native implementation and does not require the <code>matplotlib</code>
package. It creates smaller files and supports the new page layout features introduced
in this version.</p>
<p>The new PDF and PNG backends require the <code>PyMuPdf</code> package, offering faster rendering
and support for the new page layout features compared to the <code>matplotlib</code> package.</p>
<p>The PLT/HPGL2 backend creates plot files for raster plotters. It's a native implementation
and does not require additional packages. <strong>CAUTION:</strong> The output of this backend is only
tested with a plot file viewer and not on real hardware!</p>
<p>The DXF backend creates a flattened DXF file with only these DXF primitives:
POINT, LINE, LWPOLYLINE, SPLINE, HATCH.</p>
<p>We've added a new <a href="https://ezdxf.mozman.at/docs/tutorials/image_export.html">tutorial</a>
for using these new backends and the new page layout features.</p>
<h3>New Hpgl2 Add-on</h3>
<p>The <code>hpgl2</code> add-on provides tools to process and convert HPGL/2 plot files. You can use
the <code>hpgl</code> command in the launcher to view and convert plot files via a PyQt GUI:</p>
<div class="highlight"><pre><span></span><code>ezdxf<span class="w"> </span>hpgl
</code></pre></div>
<p>For more information, please refer to the <a href="https://ezdxf.mozman.at/docs/addons/hpgl2.html">docs</a>.</p>
<h3>New ezdxf.xref Module</h3>
<p>We've introduced a new <code>ezdxf.xref</code> module to improve the handling of external references
and the import of resources. This module serves as a replacement for the <code>Importer</code>
add-on but has a completely different API.</p>
<p>For more information, please read the <a href="https://ezdxf.mozman.at/docs/xref.html">docs</a> and
the new <a href="https://ezdxf.mozman.at/docs/tutorials/xref_module.html">tutorial</a>.</p>
<p>If you have any comments, ideas, or suggestions, please feel free to post them in the
<a href="https://github.com/mozman/ezdxf/discussions">discussion forum</a> on GitHub.</p>
<p>See you sometime, take care, stay healthy!</p>
<h3>Version 1.1.2 - 2023-11-01</h3>
<ul>
<li>CHANGE: <a href="https://github.com/mozman/ezdxf/issues/936">#936</a>
improve modelspace extents updates</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/939">#939</a>
<code>Matplotlib</code> requires oriented outer paths and holes to draw correct filled paths </li>
<li>BUGFIX: transform embedded <code>MTEXT</code> entity in <code>ATTRIB</code> and <code>ATTDEF</code> entities</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/949">#949</a>
fixed <code>PyMuPDF</code> deprecated method names, requires <code>PyMuPDF</code> 1.20.0 or newer </li>
</ul>
<h3>Version 1.1.1 - 2023-10-08</h3>
<ul>
<li>NEW: Python 3.12 binary wheel deployment on PyPI</li>
<li>NEW: page alignment support for the <code>drawing</code> add-on for these backends:
<code>SVGBackend</code>, <code>PyMuPdfBackend</code> and the <code>PlotterBackend</code></li>
<li>NEW: cropping content at page margins for the <code>drawing</code> add-on for these backends:
<code>SVGBackend</code>, <code>PyMuPdfBackend</code> and the <code>PlotterBackend</code></li>
<li>NEW: support for decoding of MIF encoded text <code>\M+cxxxx</code> by the <code>recover</code> module</li>
<li>INFO: <code>numpy</code> v1.25 has stopped providing Python 3.8 binary wheels on PyPI</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/929">#929</a>
handling of the minimum hatch line distance</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/932">#932</a>
tolerate MIF encoding <code>\M+cxxxx</code> in table names</li>
</ul>
<h3>Version 1.1.0 - 2023-09-09</h3>
<ul>
<li>WARNING: The font support changed drastically in this version, if you use the
<code>ezdxf.tools.fonts</code> module your code will break, sorry! Pin the <code>ezdxf</code> version to
v1.0.3 in your <code>requirements.txt</code> file to use the previous version!</li>
<li>NEW: <code>numpy</code> is a hard dependency, requires Python version >= 3.8</li>
<li>NEW: <code>fontTools</code> is a hard dependency</li>
<li>NEW: <code>ezdxf.xref</code> new core module to manage XREFs and load resources from DXF files</li>
<li>NEW: <code>ezdxf.addons.hpgl2</code> add-on to convert HPGL/2 plot files to DXF, SVG, PDF, PNG</li>
<li>NEW: <code>ezdxf hpgl</code> command to view and/or convert HPGL/2 plot files to various formats: DXF, SVG, PDF, PNG</li>
<li>NEW: native <code>SVG</code>, <code>HPGL/2</code> and <code>DXF</code> backends for the <code>drawing</code> add-on, these backends
do not need additional libraries to work</li>
<li>NEW: <code>PyMuPdf</code> backend for the <code>drawing</code> add-on, support for PDF, PNG, PPM and PBM export</li>
<li>NEW: <code>ColorPolicy</code> and <code>BackgroundPolicy</code> configuration settings for the <code>drawing</code>
add-on to change/override foreground- and background color by the frontend </li>
<li>NEW: <code>TextPolicy</code> configuration settings for the <code>drawing</code> add-on, render text as
solid filling, outline path, replace text by (filled) rectangles or ignore text at all </li>
<li>NEW: support for measuring and rendering of .shx, .shp and .lff fonts, the basic
stroke fonts included in CAD applications</li>
<li>NEW: added setter to <code>BlockLayout.base_point</code> property</li>
<li>NEW: <code>ezdxf.entities.acad_table_to_block()</code> function, converts a <code>ACAD_TABLE</code> entity
to an <code>INSERT</code> entity</li>
<li>NEW: <code>ACADProxyEntity.explode()</code> method, to explode <code>ACAD_PROXY_ENTITY</code> into proxy
graphic entities</li>
<li>CHANGED: moved font related modules into a new subpackage <code>ezdxf.fonts</code>
including a big refactoring</li>
<li>CHANGED: <code>FontFace</code> class - <code>weight</code> attribute is an int value (0-1000), <code>stretch</code> is
renamed to <code>width</code> and is now also an int value (1-9)</li>
<li>REMOVED: replaced <code>matplotlib</code> font support module by <code>fontTools</code></li>
<li>REMOVED: configuration option <code>use_matplotlib</code> - is not needed anymore</li>
<li>REMOVED: configuration option <code>font_cache_directory</code> - is not needed anymore</li>
<li>CHANGED: text rendering for the <code>drawing</code> add-on and text measurement is done by the
<code>fontTools</code> package</li>
<li>CHANGED: moved text rendering from backend classes to the <code>Frontend</code> class</li>
<li>CHANGED: moved clipping support from backend classes to the <code>Frontend</code> class</li>
<li>CHANGED: <code>BackendInterface</code> and all derived backends support only 2D shapes</li>
<li>REMOVED: Matplotlib/Qt path converters from <code>ezdxf.path.converter</code></li>
<li>REMOVED: <code>Pillow</code> backend and the <code>pillow</code> command</li>
<li>REMOVED: <code>geomdl</code> test dependency</li>
<li>BUGFIX: invalid bulge to Bezier curve conversion for bulge values >= 1</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/855">#855</a>
scale <code>MTEXT/MLEADER</code> inline commands "absolute text height" at transformation</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/898">#898</a>
use <code>dimclrd</code> color for dimension arrow blocks</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/906">#906</a>
linetype and fill flag parsing for proxy graphics </li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/907">#907</a>
fix ATTRIB and ATTDEF handling of version- and lock_position tags which share the
same group code 280 in the same subclass</li>
</ul>
<p><a href="https://ezdxf.mozman.at/release-v1-0.html">Release notes for v1.0</a></p>Release v1.0.32023-03-26T01:03:00+01:002023-03-26T01:03:00+01:00mozmantag:ezdxf.mozman.at,2023-03-26:/release-v1-0.html<p>Release notes for ezdxf v1.0.3</p><p>The project started in 2010 as the next generation of the <code>dxfwrite</code> package
that added loading and editing features and implemented support for DXF versions
newer than R12, and has now finally reached version 1.0 status.</p>
<p>A big thanks to <a href="https://github.com/mbway">Matt Broadway</a> for contributing the
<code>drawing</code> add-on which was the reason for adding a general transform interface
and the path tools. These additions have greatly improved <code>ezdxf</code> as many tools
are based on these basic features: the <code>explode</code>, <code>disassemble</code>, <code>bbox</code> and
<code>zoom</code> modules, the <code>text2path</code> and <code>geo</code> add-ons, and many internal features.
And the <code>drawing</code> add-on itself seems to be one of the most used features of the
entire package - judging by the number of questions and bug reports associated
with it 😉. </p>
<p>And thanks to all people who reported bugs, especially <a href="https://github.com/chibai">Huang Yibin</a>!</p>
<p>Version 1.0.0 is basically version 0.18.1 with the deprecated functions and
methods removed and a major revision of the documentation and type annotations.</p>
<h2>Added Features</h2>
<h3>New Drawing Methods</h3>
<p>The new method <a href="https://ezdxf.mozman.at/docs/drawing/drawing.html#ezdxf.document.Drawing.paperspace"><code>Drawing.paperspace()</code></a>
returns paperspace layouts like the existing method <code>Drawing.layout()</code>, but has
the correct return-type annotation <code>Paperspace</code> and can not return the <code>Modelspace</code>.</p>
<p>The <a href="https://ezdxf.mozman.at/docs/drawing/drawing.html#ezdxf.document.Drawing.page_setup"><code>Drawing.page_setup()</code></a>
method is a simple way to set up new print layouts or reset the properties
of existing layouts. The paper size is specified by a format name as string
like "ISO A0" or "Letter". If you need more control over the page set up
process use the <a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.Paperspace.page_setup"><code>page_setup()</code></a>
method of the <a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#paperspace"><code>Paperspace</code></a> class.</p>
<h3>Paperspace Tutorial</h3>
<p>The new <a href="https://ezdxf.mozman.at/docs/tutorials/psp_viewports.html#drawing-in-paperspace">Tutorial for Viewports in Paperspace</a>
shows how to define the paper size, add entities to the print layout, and add
viewports to the paperspace.</p>
<h3>ODA-FileConverter AppImage Support</h3>
<p>The new <code>UNIX_EXEC_PATH</code> config option for the <code>ODAFC</code> add-on may help if the
<code>which</code> command can not find the <code>ODAFileConverter</code> command and also adds
support for AppImages provided by the <a href="https://www.opendesign.com/guestfiles/oda_file_converter">Open Design Alliance</a>.
For more information read the updated
<a href="https://ezdxf.mozman.at/docs/addons/odafc.html#appimage-support">documentation</a>. </p>
<h2>Last Minute Changes</h2>
<h3>TablePainter Add-on</h3>
<p>This is the formerly undocumented <code>Table</code> add-on which existed for an easy
transition from <code>dxfwrite</code> to <code>ezdxf</code>. It's now an officially supported and
<a href="https://ezdxf.mozman.at/docs/addons/tablepainter.html">documented</a> add-on because
full support for the <code>ACAD_TABLE</code> entity is very unlikely due to the enormous
complexity for both the entity itself, and for the required infrastructure
and also the lack of a usable documentation to implement all that features.</p>
<p>The add-on simply "paints" tables using DXF primitives, no automatically
evaluated fields, no connection to databases or Excel files:</p>
<p><img alt="TablePainterAddon" src="image/table_painter_addon.png"></p>
<h3>MTextSurrogate Add-on</h3>
<p>This is the formerly undocumented <code>MText</code> add-on which existed only for an easy
transition from <code>dxfwrite</code> to <code>ezdxf</code> and implements a <code>MTEXT</code> like feature for
the DXF R12 format. It's now an officially supported and
<a href="https://ezdxf.mozman.at/docs/addons/mtextsurrogate.html">documented</a> add-on
because it's used by the <code>TablePainter</code> add-on. </p>
<h3>ASTM-D6673-10 Exporter</h3>
<p>This add-on creates special DXF files for use by Gerber Technology applications which
have a low quality DXF parser and cannot parse/ignore BLOCKS which do not contain
data according the ASTM-D6673-10 standard, see the
<a href="https://ezdxf.mozman.at/docs/addons/gerber_D6673.html">docs</a>.</p>
<h2>Upcoming</h2>
<p>There will be an extended period of only bug fixes without adding any major new
features that will be released as a 1.0.x series to take a break from the project
and these versions will not change any APIs, dependencies or minimum requirements.
For version 1.1, the minimum Python version will be raised to 3.8 or possibly 3.9
since even the latest LTS version of Ubuntu ships with Python 3.9.
Or I sync the minimal Python version and provided binary wheels on PyPI with
<em>matplotlib</em>, which is still releasing binary wheels for Python 3.8 at the end
of 2022.</p>
<p>As for the new features, there are already many ideas in the <em>TODO.md</em> file, but
I haven't decided yet which ones will be added and when, as this is still a hobby
project, there is no set schedule for future releases: It's done when it's done.</p>
<p>It's also time to expand the DXF-Internals documentation to bring the
knowledge baked into code into a more readable form.</p>
<p>Please post any comments, ideas or suggestions in the
<a href="https://github.com/mozman/ezdxf/discussions">discussion forum</a> on github.</p>
<p>See you sometime, take care, stay healthy!</p>
<h2>Release 1.0.1</h2>
<p>Version v1.0.1 is a bugfix release, that also includes some minor new additions and an
important change in the way how SPLINE entities are created from fit points only.</p>
<p>Up to this version, the control-points calculated by <code>ezdxf</code> for SPLINE entities from
fit-points only did not match the control-points calculated by CAD applications.
After more than two years, <a href="https://stackoverflow.com/users/11796986/antonio-spagnuolo">Antonio Spagnuolo</a>
answered my <a href="https://stackoverflow.com/questions/62472305/how-does-autocad-calculate-end-tangents-for-splines-defined-only-by-fit-points">question</a>
about how to get the same control points as CAD applications on <code>stack overflow</code>.
The solution does not require an end tangent estimate, so the tangent estimate arguments
have been removed from the associated methods and functions.</p>
<h2>Release 1.0.2</h2>
<p>Bugfix release.</p>
<h2>Release 1.0.3</h2>
<p>Bugfix & preview release.</p>
<h3>Version 1.0.3 - 2023-03-26</h3>
<ul>
<li>NEW: <a href="https://github.com/mozman/ezdxf/issues/833">#833</a>
logging non-unique entity handles when loading a DXF document as warnings, auditing
the document may fix this issue</li>
<li>NEW: improved auditing & fixing capabilities</li>
<li>NEW: <code>DXFTagStorage.graphic_properties()</code> returns the graphical properties for unknown
or unsupported DXF entities</li>
<li>NEW: <code>GfxAttribs.from_dict()</code></li>
<li>BUGFIX: audit process preserves dimensional constraints</li>
<li>BUGFIX: MTextExplode add-on created invalid text style table entries</li>
<li>PREVIEW: <code>ezdxf.addons.r12export</code> module to export any DXF document as a simple R12
file, final release in v1.1</li>
<li>PREVIEW: <code>ezdxf.r12strict</code> module to make DXF R12 drawing 100% compatible to Autodesk
products, final release in v1.1</li>
<li>PREVIEW: <code>ezdxf.transform</code> module to apply transformations to multiple DXF entities
inplace in a more convenient and safe way, final release in v1.1</li>
</ul>
<h3>Version 1.0.2 - 2023-02-15</h3>
<ul>
<li>NEW: <code>Drawing.validate()</code> also prints report of resolved issues</li>
<li>NEW: copy and transform support for <code>PDFUNDERLAY</code>, <code>DWFUNDERLAY</code> and <code>DGNUNDERLAY</code></li>
<li>NEW: <a href="https://github.com/mozman/ezdxf/issues/832">#832</a>
support for elliptic arcs in proxy graphics</li>
<li>NEW: <code>Drawing.get_abs_filepath()</code></li>
<li>CHANGE: default flags for <code>UNDERLAY</code> entities is now 10 (underlay is on, adjust for background)</li>
<li>BUGFIX: fix ownership of sub-entities of <code>INSERT</code> and <code>POLYLINE</code> entities</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/830">#830</a>
estimation of MTEXT column width when only white-spaces are present</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/831">#831</a>
fix Bezier interpolation for B-splines of length 0</li>
</ul>
<h3>Version 1.0.1 - 2023-01-14</h3>
<ul>
<li>NEW: function <code>set_lineweight_display_style()</code> in module <code>ezdxf.appsettings</code></li>
<li>NEW: function <code>set_current_dimstyle_attribs()</code> in module <code>ezdxf.appsettings</code></li>
<li>NEW: <code>ezdxf info</code> command shows unknown/unsupported entities in stats</li>
<li>CHANGE: the function <code>fit_points_to_cad_cv()</code> can calculate the control points of
B-splines from fit points like BricsCAD, the argument <code>estimate</code> is not necessary
anymore and was removed</li>
<li>CHANGE: removed argument <code>estimate</code> from factory method <code>add_cad_spline_control_frame()</code>, see above</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/793">#793</a>
fix LWPOLYLINE parsing in <code>ProxyGraphic</code> class</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/800">#800</a>
fix minimum axis-ratio for the ELLIPSE entity, added upperbound tolerance to axis-ratio
validator to take floating point imprecision into account</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/810">#810</a>
fix function <code>ezdxf.render.forms.cylinder_2p()</code> for cylinder axis parallel to z-axis </li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/811">#811</a>
fix function <code>ezdxf.render.forms.cone_2p()</code> for cone axis parallel to z-axis </li>
<li>BUGFIX: add support for multiple shape file entries in the <code>TextstyleTable</code> class </li>
</ul>
<h3>Version 1.0.0 - 2022-12-09</h3>
<ul>
<li>NEW: Python 3.11 binary wheels on PyPI</li>
<li>NEW: <code>Drawing.paperspace()</code>, a correct type-annotated method to get paperspace
layouts </li>
<li>NEW: <code>Drawing.page_setup()</code>, simple way to set up paperspace layouts</li>
<li>NEW: <code>UNIX_EXEC_PATH</code> config option for the ODAFC add-on.
This may help if the <code>which</code> command can not find the <code>ODAFileConverter</code> command
and also adds support for AppImages provided by ODA.</li>
<li>NEW: ASTM-D6673-10 Exporter for Gerber Technology applications, <code>gerber_D6673</code>
<a href="https://ezdxf.mozman.at/docs/addons/gerber_D6673.html">docs</a></li>
<li>CHANGE: removed deprecated features</li>
<li>CHANGE: type annotation refactoring</li>
<li>CHANGE: renaming and refactoring of the <code>MTextSurrogate</code> add-on (formerly
<code>ezdxf.addons.MText</code> class) </li>
<li>CHANGE: renaming and refactoring of the <code>TablePainter</code> add-on (formerly the
undocumented <code>ezdxf.addons.Table</code> class)</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/747">#747</a>
fix virtual entities of 3D DIMENSION entities </li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/748">#748</a>
fix keyword only argument in virtual_block_reference_entities() call</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/749">#749</a>
fix infinite loop in MTEXT rendering with tabulators</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/751">#751</a>
fix invalid DXF attribute name</li>
<li>BUGFIX: fix configuration defaults for pdsize and pdmode for the <code>drawing</code> add-on</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/776">#776</a>
fix swapped bold and italic flag for extended font data in STYLE entity </li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/777">#777</a>
check for empty <code>TextPath</code> in function <code>get_text_line_width()</code> </li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/782">#782</a>
allow DXF-Unicode notion <code>\U+XXXX</code> in table names </li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/783">#783</a>
apply block reference transformation to pattern filling of exploded HATCH entities</li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/791">#791</a>
fix broken POLYGON creation in <code>ProxyGraphic</code> class</li>
</ul>
<p><a href="https://ezdxf.mozman.at/release-v0-18.html">Release notes for v0.18</a></p>Release v0.18.12022-09-03T18:01:00+02:002022-09-03T18:01:00+02:00mozmantag:ezdxf.mozman.at,2022-09-03:/release-v0-18.html<p>Release notes for ezdxf v0.18.1</p><h2>Dimension Types</h2>
<h3>Angular Dimension</h3>
<p>New support for creating angular dimensions. </p>
<p><img alt="dim-angular" src="image/dim_angular.png"></p>
<p>There are several factory methods to add angular dimensions:</p>
<ol>
<li><a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_angular_dim_cra">layout.add_angular_dim_cra()</a> - definition by <strong>c</strong>enter, <strong>r</strong>adius and <strong>a</strong>ngles </li>
<li><a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_angular_dim_2l">layout.add_angular_dim_2l()</a> - definition by two lines</li>
<li><a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_angular_dim_3p">layout.add_angular_dim_3p()</a> - definition by three points</li>
<li><a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_angular_dim_arc">layout.add_angular_dim_arc()</a> - definition by a <code>ConstructionArc</code> object</li>
</ol>
<p>For more information: <a href="https://ezdxf.mozman.at/docs/tutorials/angular_dimension.html">Tutorial for Angular Dimension</a></p>
<h3>Arc Dimension</h3>
<p>New support for creating arc dimensions.</p>
<p><img alt="dim-arc" src="image/dim_arc.png"></p>
<p>There are several factory methods to add arc dimensions:</p>
<ol>
<li><a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_arc_dim_cra">layout.add_arc_dim_cra()</a> - definition by <strong>c</strong>enter, <strong>r</strong>adius and <strong>a</strong>ngles</li>
<li><a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_arc_dim_3p">layout.add_arc_dim_3p()</a> - definition by three points</li>
<li><a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_arc_dim_arc">layout.add_arc_dim_arc()</a> - definition by a <code>ConstructionArc</code> object</li>
</ol>
<p>For more information: <a href="https://ezdxf.mozman.at/docs/tutorials/arc_dimension.html">Tutorial for Arc Dimension</a></p>
<h3>Ordinate Dimension</h3>
<p>New support for creating ordinate dimensions by these factory methods:</p>
<ol>
<li><a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_ordinate_x_dim">layout.add_ordinate_x_dim()</a> - add x-type ordinate dimension</li>
<li><a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_ordinate_y_dim">layout.add_ordinate_y_dim()</a> - add y-type ordinate dimension</li>
</ol>
<p>Global feature location: the ordinate origin is the global WCS origin</p>
<p><img alt="dim-ordinate-global" src="image/dim_ord_global.png"></p>
<p>Local feature location: the ordinate origin is the origin of a user defined <code>UCS</code></p>
<p><img alt="dim-ordinate-local" src="image/dim_ord_local.png"></p>
<p>For more information: <a href="https://ezdxf.mozman.at/docs/tutorials/ordinate_dimension.html">Tutorial for Ordinate Dimension</a></p>
<h2>Extended Entity Query</h2>
<p>Extended usability of the <a href="https://ezdxf.mozman.at/docs/query.html#entityquery-class">EntityQuery</a>
class.</p>
<p>This is a simple entity query which selects all <code>LINE</code> entities from the
modelspace as starting point for the following explanations:</p>
<div class="highlight"><pre><span></span><code><span class="n">lines</span> <span class="o">=</span> <span class="n">msp</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"LINE"</span><span class="p">)</span>
</code></pre></div>
<ol>
<li>Extended <code>__getitem__()</code> method to accept also a DXF attribute name that
returns all entities which support this attribute, this is the base for
supporting queries by relational operators.</li>
<li>New <code>__setitem__()</code> method to assigns a DXF attribute to all supported
entities in the <code>EntityQuery</code> container. E.g. change the layer of all selected
lines: <code>lines["layer"] = "MyLayer"</code></li>
<li>New <code>__delitem__()</code> method to discard a DXF attribute from all entities in<br>
the <code>EntityQuery</code> container. E.g. delete the layer attribute from all selected
lines: <code>del lines["layer"]</code>, which reset the layer to the default value <code>0</code></li>
<li>New descriptors for some basic DXF attributes which simplifies the attribute
selection and has auto-completion support from IDEs. E.g. change the layer of
all selected lines: <code>lines.layer = "MyLayer"</code></li>
<li>New selection by relational operators (<code><, <=, ==, !=, >=, ></code>) which work
in conjunction with the extended attribute selection of <code>__getitem__()</code> to
allow further conditional selections. E.g. select all lines on layer
"MyLayer": <code>lines_on_my_layer = lines.layer == "MyLayer"</code></li>
<li>New selection by regular expression: <code>lines.layer.match("^My.*")</code> </li>
<li>Use your own filter functions to build selections: <code>lines.filter(lambda e: ...)</code></li>
<li><code>Set</code> operators to combine queries by union (<code>|</code>), intersection (<code>&</code>),
difference (<code>-</code>) and symmetric_difference (<code>^</code>). </li>
</ol>
<p>Example for selecting all blue lines and red circles from modelspace:</p>
<div class="highlight"><pre><span></span><code><span class="n">result</span> <span class="o">=</span> <span class="p">(</span><span class="n">msp</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"LINE"</span><span class="p">)</span><span class="o">.</span><span class="n">color</span> <span class="o">==</span> <span class="mi">5</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="n">msp</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"CIRCLE"</span><span class="p">)</span><span class="o">.</span><span class="n">color</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<p>For more information: <a href="https://ezdxf.mozman.at/docs/query.html#extended-entityquery-features">Extended EntityQuery Features</a></p>
<h2>DXF Entity Improvements</h2>
<h3>DXF Attribute Helper Class</h3>
<p>The <a href="https://ezdxf.mozman.at/docs/tools/gfxattribs.html">ezdxf.gfxattribs</a> module
provides the <code>GfxAttribs</code> class to create valid
attribute dictionaries for the most often used DXF attributes supported by all
graphical DXF entities. The advantage of using this class is auto-completion
support by IDEs and an instant validation of the attribute values.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="kn">from</span> <span class="nn">ezdxf.gfxattribs</span> <span class="kn">import</span> <span class="n">GfxAttribs</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
<span class="n">msp</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">modelspace</span><span class="p">()</span>
<span class="n">attribs</span> <span class="o">=</span> <span class="n">GfxAttribs</span><span class="p">(</span><span class="n">layer</span><span class="o">=</span><span class="s2">"MyLayer"</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="n">ezdxf</span><span class="o">.</span><span class="n">colors</span><span class="o">.</span><span class="n">RED</span><span class="p">)</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">msp</span><span class="o">.</span><span class="n">add_line</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">dxfattribs</span><span class="o">=</span><span class="n">attribs</span><span class="p">)</span>
<span class="n">circle</span> <span class="o">=</span> <span class="n">msp</span><span class="o">.</span><span class="n">add_circle</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">radius</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">dxfattribs</span><span class="o">=</span><span class="n">attribs</span><span class="p">)</span>
</code></pre></div>
<p>For more information: <a href="https://ezdxf.mozman.at/docs/tools/gfxattribs.html">Documentation of the gfxattribs module</a></p>
<h3>TEXT, ATTRIB and ATTDEF</h3>
<p><a href="https://ezdxf.mozman.at/docs/enums.html#ezdxf.enums.TextEntityAlignment">TextEntityAlignment</a>
enum replaces the string based alignment definition. </p>
<p>New Text methods:</p>
<ul>
<li><a href="https://ezdxf.mozman.at/docs/dxfentities/text.html#ezdxf.entities.Text.get_placement">Text.get_placement()</a>
replaces the deprecated method <code>Text.get_pos()</code></li>
<li><a href="https://ezdxf.mozman.at/docs/dxfentities/text.html#ezdxf.entities.Text.set_placement">Text.set_placement()</a>
replaces the deprecated method <code>Text.set_pos()</code></li>
<li><a href="https://ezdxf.mozman.at/docs/dxfentities/text.html#ezdxf.entities.Text.get_align_enum">Text.get_align_enum()</a>
replaces the deprecated method <code>Text.get_align()</code></li>
<li><a href="https://ezdxf.mozman.at/docs/dxfentities/text.html#ezdxf.entities.Text.get_align_enum">Text.set_align_enum()</a>
replaces the deprecated method <code>Text.set_align()</code></li>
</ul>
<h4>Extended Factory Methods</h4>
<ul>
<li><a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_text">add_text()</a>
additional keyword arguments <code>height</code> and <code>rotation</code>, <code>dxfattribs</code> is now a keyword argument</li>
<li><a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_attdef">add_attdef()</a>:
additional keyword arguments <code>height</code> and <code>rotation</code>, <code>dxfattribs</code> is now a keyword argument</li>
</ul>
<h3>MTEXT</h3>
<p>New virtual DXF attribute <code>MText.dxf.text</code> which is linked to the <code>MText.text</code>
attribute, this adds API compatibility to other text based entities: <code>TEXT</code>,
<code>ATTRIB</code> and <code>ATTDEF</code></p>
<h3>MULTILEADER</h3>
<p>New support for creating <a href="https://help.autodesk.com/view/OARX/2018/ENU/?guid=GUID-72D20B8C-0F5E-4993-BEB7-0FCF94F32BE0">MULTILEADER</a>
entities.</p>
<h4>New Factory Methods</h4>
<ul>
<li><a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_multileader_mtext">add_multileader_mtext()</a></li>
<li><a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_multileader_block">add_multileader_block()</a></li>
</ul>
<p>Both factory methods return builder objects:</p>
<ul>
<li>Base class <a href="https://ezdxf.mozman.at/docs/render/mleader.html#ezdxf.render.MultiLeaderBuilder">MultiLeaderBuilder</a></li>
<li>MText specialization: <a href="https://ezdxf.mozman.at/docs/render/mleader.html#ezdxf.render.MultiLeaderMTextBuilder">MultiLeaderMTextBuilder</a></li>
<li>Block specialization: <a href="https://ezdxf.mozman.at/docs/render/mleader.html#ezdxf.render.MultiLeaderBlockBuilder">MultiLeaderBlockBuilder</a></li>
</ul>
<p>Due of the lack of good documentation it’s not possible to support all combinations
of <code>MULTILEADER</code> properties with decent quality!</p>
<p>For more information: <a href="https://ezdxf.mozman.at/docs/tutorials/mleader.html">Tutorial for creating MultiLeaders</a></p>
<h3>HELIX</h3>
<p>New support for creating <a href="https://help.autodesk.com/view/OARX/2018/ENU/?guid=GUID-76DB3ABF-3C8C-47D1-8AFB-72942D9AE1FF">HELIX</a>
entities by the factory method <a href="https://ezdxf.mozman.at/docs/layouts/layouts.html#ezdxf.layouts.BaseLayout.add_helix">add_helix()</a>.</p>
<h3>VIEWPORT/LAYER</h3>
<p>New support for layer attribute override in <code>VIEWPORT</code> entities.
This feature is implemented in the <code>LAYER</code> entity. The new method
<a href="https://ezdxf.mozman.at/docs/tables/layer_table_entry.html#ezdxf.entities.Layer.get_vp_overrides">Layer.get_vp_overrides</a>
returns a <a href="https://ezdxf.mozman.at/docs/tables/layer_table_entry.html#layeroverrides">LayoutOverride</a>
object which allows overriding properties for this specific layer for individual
viewports.</p>
<p>For more information: <a href="https://github.com/mozman/ezdxf/blob/master/examples/viewports_override_layer_attributes.py">Example</a>
for overriding layer attributes in viewports</p>
<h2>CAD Application Settings</h2>
<p>The <a href="https://ezdxf.mozman.at/docs/appsettings.html">ezdxf.appsettings</a>
is a high-level module for working with CAD application
settings and behaviors. None of these settings have any influence on the
behavior of <code>ezdxf</code>, since <code>ezdxf</code> only takes care of the content of the DXF file
and not of the way it is presented to the user.</p>
<p>Example for updating the extents of the modelspace:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="kn">from</span> <span class="nn">ezdxf</span> <span class="kn">import</span> <span class="n">zoom</span><span class="p">,</span> <span class="n">appsettings</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">readfile</span><span class="p">(</span><span class="s2">"your.dxf"</span><span class="p">)</span>
<span class="n">extents</span> <span class="o">=</span> <span class="n">appsettings</span><span class="o">.</span><span class="n">update_extents</span><span class="p">(</span><span class="n">doc</span><span class="p">)</span>
</code></pre></div>
<p>The function updates only the values in the HEADER section, to zoom the active
viewport to these extents, use the zoom module:</p>
<div class="highlight"><pre><span></span><code><span class="n">zoom</span><span class="o">.</span><span class="n">center</span><span class="p">(</span><span class="n">doc</span><span class="o">.</span><span class="n">modelspace</span><span class="p">(),</span> <span class="n">extents</span><span class="o">.</span><span class="n">center</span><span class="p">,</span> <span class="n">extents</span><span class="o">.</span><span class="n">size</span><span class="p">)</span>
</code></pre></div>
<p>For more information: <a href="https://ezdxf.mozman.at/docs/appsettings.html">Documentation of the appsettings module</a></p>
<h2>Improved Bounding Box Module</h2>
<p>Refactoring of the <a href="https://ezdxf.mozman.at/docs/bbox.html#ezdxf.bbox.extents">ezdxf.bbox.extents</a>
function to make use of the improved bounding box calculation for Bézier curves,
this eliminates the need to estimate a suitable flattening distance.
The argument <code>flatten</code> is replaced by <code>fast</code>. If argument <code>fast</code> is <code>True</code>
the calculation of Bézier curves is based on their control points, this may
return a slightly larger bounding box. The <code>fast</code> mode also uses a simpler and
mostly inaccurate text size calculation instead of the more precise but very
slow calculation by <code>matplotlib</code>.</p>
<h2>Add-ons</h2>
<h3>New Mesh Exchange Add-on</h3>
<p>The <a href="https://ezdxf.mozman.at/docs/addons/meshex.html">ezdxf.addons.meshex</a>
module provides functions to exchange meshes with other tools by the following
file formats:</p>
<ul>
<li><code>STL</code> - import/export</li>
<li><code>OFF</code> - import/export</li>
<li><code>OBJ</code> - import/export</li>
<li><code>PLY</code> - export only</li>
<li><code>OpenSCAD</code> - export as <code>polyhedron()</code></li>
<li><code>IFC4</code> - export only</li>
</ul>
<p>The source or target object is always a <code>MeshBuilder</code> instance and therefore
the supported features are also limited by this class. Only vertices and faces
are exchanged, colors, textures and explicit face- and vertex normals are lost.</p>
<p>For more information: <a href="https://ezdxf.mozman.at/docs/addons/meshex.html">Documentation of the meshex add-on</a></p>
<h3>New OpenScad Add-on</h3>
<p>Interface to the <a href="https://openscad.org/">OpenSCAD</a> application to apply boolean
operations to <code>MeshBuilder</code> objects. The OpenSCAD application is <strong>not</strong> bundled
with <code>ezdxf</code>, you need to install the application yourself.</p>
<p>This example subtracts a sphere from a Menger sponge by OpenSCAD and exports the
result as <code>MESH</code> entity in a DXF file:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="kn">from</span> <span class="nn">ezdxf.render</span> <span class="kn">import</span> <span class="n">forms</span>
<span class="kn">from</span> <span class="nn">ezdxf.addons</span> <span class="kn">import</span> <span class="n">MengerSponge</span><span class="p">,</span> <span class="n">openscad</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
<span class="n">msp</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">modelspace</span><span class="p">()</span>
<span class="n">sponge</span> <span class="o">=</span> <span class="n">MengerSponge</span><span class="p">(</span><span class="n">level</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span><span class="o">.</span><span class="n">mesh</span><span class="p">()</span>
<span class="n">sponge</span><span class="o">.</span><span class="n">flip_normals</span><span class="p">()</span> <span class="c1"># important for OpenSCAD</span>
<span class="n">sphere</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">sphere</span><span class="p">(</span>
<span class="n">count</span><span class="o">=</span><span class="mi">32</span><span class="p">,</span> <span class="n">stacks</span><span class="o">=</span><span class="mi">16</span><span class="p">,</span> <span class="n">radius</span><span class="o">=</span><span class="mf">0.5</span><span class="p">,</span> <span class="n">quads</span><span class="o">=</span><span class="kc">True</span>
<span class="p">)</span><span class="o">.</span><span class="n">translate</span><span class="p">(</span><span class="mf">0.25</span><span class="p">,</span> <span class="mf">0.25</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">sphere</span><span class="o">.</span><span class="n">flip_normals</span><span class="p">()</span> <span class="c1"># important for OpenSCAD</span>
<span class="n">script</span> <span class="o">=</span> <span class="n">openscad</span><span class="o">.</span><span class="n">boolean_operation</span><span class="p">(</span><span class="n">openscad</span><span class="o">.</span><span class="n">DIFFERENCE</span><span class="p">,</span> <span class="n">sponge</span><span class="p">,</span> <span class="n">sphere</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">openscad</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">script</span><span class="p">)</span>
<span class="n">result</span><span class="o">.</span><span class="n">render_mesh</span><span class="p">(</span><span class="n">msp</span><span class="p">)</span>
<span class="n">doc</span><span class="o">.</span><span class="n">set_modelspace_vport</span><span class="p">(</span><span class="mi">6</span><span class="p">,</span> <span class="n">center</span><span class="o">=</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
<span class="n">doc</span><span class="o">.</span><span class="n">saveas</span><span class="p">(</span><span class="s2">"OpenSCAD.dxf"</span><span class="p">)</span>
</code></pre></div>
<p><img alt="openscad-menger-sponge-minus-sphere" src="image/openscad_menger_minus_sphere.png"></p>
<p>For more information: <a href="https://ezdxf.mozman.at/docs/addons/openscad.html">Documentation of the OpenSCAD add-on</a></p>
<h3>New Binpacking Add-on</h3>
<p>This add-on is based on the 3D bin packing module <a href="https://github.com/enzoruiz/3dbinpacking">py3dbp</a>
to solve the <a href="https://en.wikipedia.org/wiki/Bin_packing_problem">bin packing problem</a>.</p>
<p>For more information: <a href="https://ezdxf.mozman.at/docs/addons/binpacking.html">Documentation of the binpacking add-on</a></p>
<h3>Extended ODAFC Add-on</h3>
<p>New functions added:</p>
<ul>
<li><a href="https://ezdxf.mozman.at/docs/addons/odafc.html#ezdxf.addons.odafc.is_installed">ezdxf.addons.odafc.is_installed()</a></li>
<li><a href="https://ezdxf.mozman.at/docs/addons/odafc.html#ezdxf.addons.odafc.convert">ezdxf.addons.odafc.convert()</a></li>
</ul>
<p>For more information: <a href="https://ezdxf.mozman.at/docs/addons/odafc.html">Documentation of the odafc add-on</a></p>
<h2>Text Tools</h2>
<ul>
<li>New <a href="https://ezdxf.mozman.at/docs/tools/text.html#ezdxf.tools.text.is_upside_down_text_angle">ezdxf.tools.text.is_upside_down_text_angle()</a>
function: Returns <code>True</code> if the given text angle in degrees causes an upside down text in the WCS.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/tools/text.html#ezdxf.tools.text.upright_text_angle">ezdxf.tools.text.upright_text_angle()</a>
function: Returns a readable (upright) text angle.</li>
</ul>
<h2>Path Improvements</h2>
<h3>Fillet and Chamfer Tools</h3>
<ul>
<li>New <a href="https://ezdxf.mozman.at/docs/path.html#ezdxf.path.fillet">ezdxf.path.fillet()</a>
function: Returns a Path with circular fillets of given <code>radius</code> between straight line segments.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/path.html#ezdxf.path.polygonal_fillet">ezdxf.path.polygonal_fillet()</a>
function: Returns a Path with polygonal fillets of given <code>radius</code> between straight line segments.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/path.html#ezdxf.path.chamfer">ezdxf.path.chamfer()</a>
function: Returns a Path with chamfers of given <code>length</code> between straight line segments.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/path.html#ezdxf.path.chamfer2">ezdxf.path.chamfer2()</a>
function: Returns a Path with chamfers at the given distances <code>a</code> and <code>b</code> from the
segment points between straight line segments.</li>
</ul>
<h3>Helix Tool</h3>
<p>New <a href="https://ezdxf.mozman.at/docs/path.html#ezdxf.path.helix">ezdxf.path.helix()</a>
function: Returns a <a href="https://en.wikipedia.org/wiki/Helix">helix</a> as a <code>Path</code> object.</p>
<h3>Bounding Box Calculation</h3>
<p>Improved <a href="https://ezdxf.mozman.at/docs/path.html#ezdxf.path.bbox">ezdxf.path.bbox()</a>
function: New algorithm to determine the exact bounding boxes of Bézier curves,
eliminating the need to estimate a suitable flattening distance.
Added argument <code>fast</code> which allows bounding
box calculation based on Bézier curve control points, this may result in
slightly larger bounding boxes in favor of increased execution speed.
Removed the arguments <code>flatten</code> and <code>segments</code> without deprecation warnings
(raises <code>TypeError</code>).</p>
<h2>Render Tools</h2>
<h3>New Functions</h3>
<ul>
<li>New <a href="https://ezdxf.mozman.at/docs/render/forms.html#ezdxf.render.forms.helix">ezdxf.render.forms.helix()</a>
function: Yields the vertices of a helix.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/forms.html#ezdxf.render.forms.torus">ezdxf.render.forms.torus()</a>
function: Returns a torus as <code>MeshTransformer</code> object.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/forms.html#ezdxf.render.forms.extrude_twist_scale">ezdxf.render.forms.extrude_twist_scale()</a>
function: Extrude, twist and scale a profile polygon along a path polyline.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/forms.html#ezdxf.render.forms.sweep">ezdxf.render.forms.sweep()</a>
function: Returns the mesh from sweeping a profile along a 3D path, where the
sweeping path defines the final location in the <code>WCS</code>.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/forms.html#ezdxf.render.forms.sweep_profile">ezdxf.render.forms.sweep_profile()</a>
function: Returns the intermediate profiles of sweeping a profile along a 3D path
where the sweeping path defines the final location in the <code>WCS</code>.</li>
<li>Extended <a href="https://ezdxf.mozman.at/docs/render/forms.html#ezdxf.render.forms.extrude">ezdxf.render.forms.extrude()</a>
function: added parameter <code>caps</code> to close hull with top- and bottom faces</li>
</ul>
<h3>New MeshBuilder Methods</h3>
<ul>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.bbox">ezdxf.render.MeshBuilder.bbox()</a>
method: Returns the BoundingBox of the mesh.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.diagnose">ezdxf.render.MeshBuilder.diagnose()</a>
method: Returns the <code>MeshDiagnose</code> object for this mesh.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.get_face_vertices">ezdxf.render.MeshBuilder.get_face_vertices()</a>
method: Returns the indexed face as sequence of <code>Vec3</code> objects.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.get_face_normal">ezdxf.render.MeshBuilder.get_face_normal()</a>
method: Returns the normal vector of the indexed face as <code>Vec3</code> object.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.face_normals">ezdxf.render.MeshBuilder.face_normals()</a>
method: Yields all face normals.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.flip_normals">ezdxf.render.MeshBuilder.flip_normals</a>
method: Flips the face normals inplace.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.open_faces">ezdxf.render.MeshBuilder.open_faces()</a>
method: Yields all faces as sequence of integers where the first vertex is not coincident with the last vertex.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.optimize_vertices">ezdxf.render.MeshBuilder.optimize_vertices()</a>
method: Returns a new mesh with optimized vertices.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.subdivide_ngons">ezdxf.render.MeshBuilder.subdivide_ngons()</a>
method: Yields all faces as sequence of <code>Vec3</code> instances, where all ngons which have more than <code>max_vertex_count</code> vertices gets subdivided.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.tessellation">ezdxf.render.MeshBuilder.tessellation()</a>
method: Yields all faces as sequence of <code>Vec3</code> instances, each face has no more vertices than the given <code>max_vertex_count</code>.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.mesh_tessellation">ezdxf.render.MeshBuilder.mesh_tessellation()</a>
method: Returns a new <code>MeshTransformer</code> instance, where each face has no more vertices than the given <code>max_vertex_count</code>.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.separate_meshes">ezdxf.render.MeshBuilder.separate_meshes()</a>
method: Returns separated meshes as multiple <code>MeshTransformer</code> instances.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.normalize_faces">ezdxf.render.MeshBuilder.normalize_faces()</a>
method: Removes duplicated vertex indices from faces and stores all faces as open faces.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.unify_face_normals">ezdxf.render.MeshBuilder.unify_face_normals()</a>
method: Returns a new <code>MeshTransformer</code> object with unified face normal vectors of all faces.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshBuilder.unify_face_normals_by_reference">ezdxf.render.MeshBuilder.unify_face_normals_by_reference()</a>
method: Returns a new <code>MeshTransformer</code> object with unified face normal vectors of all faces. </li>
</ul>
<h3>New MeshDiagnose Tool</h3>
<p>New helper class <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.MeshDiagnose">ezdxf.render.MeshDiagnose</a>
to analyze and detect errors of <code>MeshBuilder</code> objects.</p>
<h3>New FaceOrientationDetector Tool</h3>
<p>New Helper class <a href="https://ezdxf.mozman.at/docs/render/mesh.html#ezdxf.render.FaceOrientationDetector">ezdxf.render.FaceOrientationDetector</a>
for face orientation and face normal vector detection.</p>
<h2>Math Tools</h2>
<h3>New ConstructionPolyline Tool</h3>
<p>New class <a href="https://ezdxf.mozman.at/docs/math/core.html#constructionpolyline">ezdxf.math.ConstructionPolyline</a>
to measure, interpolate and divide anything that can be approximated or flattened
into vertices.</p>
<h3>New ApproxParamT Tool</h3>
<p>New class <a href="https://ezdxf.mozman.at/docs/math/core.html#approxparamt">ezdxf.math.ApproxParamT</a>,
an approximation tool for parametrized curves.</p>
<h3>New Plane Methods</h3>
<ul>
<li>New <a href="https://ezdxf.mozman.at/docs/math/core.html#ezdxf.math.Plane.intersect_line">ezdxf.math.Plane.intersect_line()</a>
method: Returns the intersection point of a 3D line and this plane.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/math/core.html#ezdxf.math.Plane.intersect_ray">ezdxf.math.Plane.intersect_ray()</a>
method: Returns the intersection point of a 3D ray and this plane.</li>
</ul>
<h3>New 2D/3D Construction Function</h3>
<ul>
<li>New <a href="https://ezdxf.mozman.at/docs/math/core.html#ezdxf.math.split_polygon_by_plane">ezdxf.math.split_polygon_by_plane()</a>
function: Split a convex polygon by the given plane if needed.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/math/core.html#ezdxf.math.intersection_line_polygon_3d">ezdxf.math.intersection_line_polygon_3d()</a>
function: Returns the intersection point of the 3D line form start to end and the given polygon.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/math/core.html#ezdxf.math.spherical_envelope">ezdxf.math.spherical_envelope()</a>
function: returns the spherical envelope for the given points.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/math/core.html#ezdxf.math.cubic_bezier_bbox">ezdxf.math.cubic_bezier_bbox()</a>
function: Returns the bounding box of a cubic Bézier curve.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/math/core.html#ezdxf.math.quadratic_bezier_bbox">ezdxf.math.quadratic_bezier_bbox()</a>
function: Returns the bounding box of a quadratic Bézier curve.</li>
</ul>
<h3>Changes of BoundingBox Classes</h3>
<ul>
<li>Change <a href="https://ezdxf.mozman.at/docs/math/core.html#ezdxf.math.BoundingBox.is_empty">ezdxf.math.BoundingBox.is_empty()</a>
method: Returns <code>True</code> if the bounding box is empty or the bounding box has a
size of 0 in any or all dimensions or is undefined.</li>
<li>New <a href="https://ezdxf.mozman.at/docs/math/core.html#ezdxf.math.BoundingBox.has_intersection">ezdxf.math.BoundingBox.has_intersection()</a>
method replaces deprecated method <code>intersect()</code> </li>
<li>New <a href="https://ezdxf.mozman.at/docs/math/core.html#ezdxf.math.BoundingBox.has_overlap">ezdxf.math.BoundingBox.has_overlap()</a>
replaces deprecated method <code>overlap()</code></li>
<li>New <a href="https://ezdxf.mozman.at/docs/math/core.html#ezdxf.math.BoundingBox.intersection">ezdxf.math.BoundingBox.intersection()</a>
method: returns the 3D/2D bounding box of the intersection space</li>
</ul>
<h3>New RTree Tool</h3>
<p>New class <a href="https://ezdxf.mozman.at/docs/math/rtree.html#ezdxf.math.rtree.RTree">ezdxf.math.rtree.RTree</a>:
Immutable spatial search tree loosely based on <a href="https://en.wikipedia.org/wiki/R-tree">R-Trees</a>.</p>
<h3>New Clustering Functions</h3>
<ul>
<li>New <a href="https://ezdxf.mozman.at/docs/math/clustering.html#ezdxf.math.clustering.dbscan">ezdxf.math.clustering.dbscan()</a> </li>
<li>New <a href="https://ezdxf.mozman.at/docs/math/clustering.html#ezdxf.math.clustering.k_means">ezdxf.math.clustering.k_means()</a></li>
</ul>
<h2>ACIS Tools</h2>
<p>The new <a href="https://ezdxf.mozman.at/docs/tools/acis.html">ezdxf.acis</a> sub-package
provides some ACIS data management tools for curious and experienced users.
These tools cannot replace the official ACIS SDK due to the complexity of the
data structures and the absence of an ACIS kernel in <code>ezdxf</code>.</p>
<h2>Launcher</h2>
<p>The new <code>info</code> command show info and optional stats of DXF files.</p>
<div class="highlight"><pre><span></span><code>C:\> ezdxf info gear.dxf
Filename: ".\gear.dxf"
Format: ASCII
Release: R2013
DXF Version: AC1027
Codepage: ANSI_1252
Encoding: utf-8
Created by ezdxf: 0.18b6 @ 2022-07-06T14:21:18.530488+00:00
Written by ezdxf: 0.18b6 @ 2022-07-06T14:21:18.530488+00:00
</code></pre></div>
<p>The new <code>browse-acis</code> command can show and export the SAT or SAB content of
ACIS entities.</p>
<div class="highlight"><pre><span></span><code>C:\> ezdxf browse-acis 3dsolid.dxf
</code></pre></div>
<p><img alt="browse-acis" src="image/browse-acis-3dsolid.png"></p>
<p>For more information read the <a href="https://ezdxf.mozman.at/docs/launcher.html">launcher</a>
documentation. </p>
<h2>Change Log</h2>
<h3>Version 0.18.1 - 2022-09-03</h3>
<ul>
<li>NEW: improved hatch pattern support for the <code>drawing</code> add-on</li>
<li>NEW: <code>drawing</code> add-on got basic <code>VIEWPORT</code> rendering (only top-views),
supported by the <code>PyQtBackend</code> and the <code>PillowBackend</code> </li>
<li>NEW: <code>ezdxf.render.forms.turtle()</code> function to create 2D polyline vertices by
turtle-graphic like commands</li>
<li>NEW: sub-command <code>ezdxf pillow</code> to draw and convert DXF files by <code>Pillow</code></li>
<li>NEW: <code>ezdxf.path.triangulate()</code>, tessellate (nested) paths into triangle-faces</li>
<li>CHANGE: replaced function <code>clip_polygon_2d()</code>, by clipping the classes
<code>ClippingPolygon2d()</code> and <code>ClippingRect2d()</code> </li>
<li>BUGFIX: CPython implementation of <code>Vec2()</code> was not immutable at inplace
operations <code>+=</code>, <code>-=</code>, <code>*=</code> and <code>/=</code> like the Cython implementation</li>
<li>BUGFIX: fixed bounding box calculation for <code>LinePrimitive()</code></li>
<li>BUGFIX: <a href="https://github.com/mozman/ezdxf/issues/729">#729</a>
fixes <code>$FINGERPRINTGUID</code> and <code>$VERSIONGUID</code> handling</li>
</ul>
<h3>Version 0.18 - 2022-07-29</h3>
<ul>
<li>NEW: angular dimension rendering support, new factory methods:
<code>add_angular_dim_2l()</code>, <code>add_angular_dim_3p()</code>, <code>add_angular_dim_cra()</code>,
<code>add_angular_dim_arc()</code> </li>
<li>NEW: arc length dimension rendering support, new factory methods:
<code>add_arc_dim_3p()</code>, <code>add_arc_dim_cra()</code>, <code>add_arc_dim_arc()</code></li>
<li>NEW: ordinate dimension rendering support, new factory methods:
<code>add_ordinate_dim()</code>, <code>add_ordinate_x_dim()</code>, <code>add_ordinate_y_dim()</code></li>
<li>NEW: extended query functionality for the <code>EntityQuery</code> class</li>
<li>NEW: function <code>ezdxf.tools.text.is_upside_down_text_angle()</code> in WCS</li>
<li>NEW: function <code>ezdxf.tools.text.upright_text_angle()</code> in WCS</li>
<li>NEW: helper class <code>ezdxf.math.ConstructionPolyline</code> to measure, interpolate and
divide polylines and anything that can be approximated or flattened into
vertices</li>
<li>NEW: approximation tool for parametrized curves: <code>ezdxf.math.ApproxParamT()</code></li>
<li>NEW: <code>BoundingBox(2d).intersection(other)</code>, returns the 3D/2D bbox of the intersection space</li>
<li>NEW: <code>BoundingBox(2d).has_intersection(other)</code> replaces deprecated method <code>intersect()</code> </li>
<li>NEW: <code>BoundingBox(2d).has_overlap(other)</code> replaces deprecated method <code>overlap()</code> </li>
<li>DEPRECATED: method <code>BoundingBox(2d).intersect()</code> will be removed in v1.0.0</li>
<li>DEPRECATED: method <code>BoundingBox(2d).overlap()</code> will be removed in v1.0.0</li>
<li>CHANGE: <code>BoundingBox(2d).is_empty</code> is <code>True</code> for bounding boxes with a size
of 0 in any dimension or has no data</li>
<li>NEW: <code>ezdxf.gfxattribs.GfxAttribs()</code> class, <a href="https://ezdxf.mozman.at/docs/tools/gfxattribs.html">docs</a></li>
<li>NEW: <code>TextEntityAlignment</code> enum replaces the string based alignment definition</li>
<li>NEW: method <code>Text.get_placement()</code>, replaces <code>get_pos()</code> </li>
<li>NEW: method <code>Text.set_placement()</code>, replaces <code>set_pos()</code> </li>
<li>NEW: method <code>Text.get_align_enum()</code>, replaces <code>get_align()</code></li>
<li>NEW: method <code>Text.set_align_enum()</code>, replaces <code>set_align()</code></li>
<li>NEW: virtual DXF attribute <code>MText.dxf.text</code>, adds compatibility to other text
based entities: <code>TEXT, ATTRIB, ATTDEF</code></li>
<li>NEW: command <code>ezdxf info FILE [FILE ...]</code>, show info and optional stats of DXF files</li>
<li>NEW: module <code>ezdxf.appsettings</code>, <a href="https://ezdxf.mozman.at/docs/appsettings.html">docs</a></li>
<li>NEW: module <code>ezdxf.addons.binpacking</code>, a simple solution for the bin-packing problem
in 2D and 3D, <a href="https://ezdxf.mozman.at/docs/addons/binpacking.html">docs</a></li>
<li>NEW: arguments <code>height</code> and <code>rotation</code>for factory methods <code>add_text()</code> and <code>add_attdef()</code></li>
<li>NEW: argument <code>size_inches</code> in function <code>ezdxf.addons.drawing.matplotlib.qsave()</code></li>
<li>NEW: DXF/DWG converter function <code>ezdxf.addons.odafc.convert()</code></li>
<li>NEW: support for layer attribute override in VIEWPORT entities</li>
<li>NEW: mesh exchange add-on <code>ezdxf.addons.meshex</code>: STL, OFF, and OBJ mesh loader
and STL, OFF, OBJ, PLY, OpenSCAD and IFC4 mesh exporter, <a href="https://ezdxf.mozman.at/docs/addons/meshex.html">docs</a></li>
<li>NEW: <code>ezdxf.addons.openscad</code> add-on as interface to <a href="https://openscad.org">OpenSCAD</a>,
<a href="https://ezdxf.mozman.at/docs/addons/openscad.html">docs</a> </li>
<li>NEW: <code>acis</code> module, a toolbox to handle ACIS data, <a href="https://ezdxf.mozman.at/docs/tools/acis.html">docs</a></li>
<li>NEW: factory function <code>add_helix()</code> to create new <code>HELIX</code> entities</li>
<li>NEW: precise bounding box calculation for Bézier curves</li>
<li>NEW: module <code>ezdxf.math.trianglation</code> for polygon triangulation with hole support</li>
<li>NEW: spatial search tree <code>ezdxf.math.rtree.RTree</code> </li>
<li>NEW: module <code>ezdxf.math.clustering</code> for DBSCAN and K-means clustering </li>
<li>CHANGE: keyword only argument <code>dxfattribs</code> for factory methods <code>add_text()</code> and <code>add_attdef()</code></li>
<li>CHANGE: <code>recover</code> module - recovered integer and float values are logged as severe errors</li>
<li>CHANGE: method <code>Path.all_lines_to_curve3</code> replaced by function <code>path.lines_to_curve3()</code></li>
<li>CHANGE: method <code>Path.all_lines_to_curve4</code> replaced by function <code>path.lines_to_curve4()</code></li>
<li>CHANGE: replaced arguments <code>flatten</code> and <code>segments</code> by argument <code>fast</code> of tool
function <code>Path.bbox()</code> </li>
<li>CHANGE: replaced argument <code>flatten</code> by argument <code>fast</code> in the <code>ezdxf.bbox</code> module</li>
<li>CHANGE: restructure of the <code>ezdxf.math</code> sub-package</li>
<li>BUGFIX <a href="https://github.com/mozman/ezdxf/issues/663">#663</a>:
improve handling of large coordinates in <code>Bezier4P</code> and <code>Bezier3P</code> classes</li>
<li>BUGFIX <a href="https://github.com/mozman/ezdxf/issues/655">#655</a>:
fixed invalid flattening of 3D ARC entities </li>
<li>BUGFIX <a href="https://github.com/mozman/ezdxf/issues/640">#640</a>:
DXF loader ignore data beyond <code>EOF</code> tag </li>
<li>BUGFIX <a href="https://github.com/mozman/ezdxf/issues/620">#620</a>:
add missing caret decoding to <code>fast_plain_mtext()</code> </li>
<li>BUGFIX: <code>3DSOLID</code> export for DXF R2004 has no subclass <code>AcDb3dSolid</code></li>
</ul>
<p><a href="https://ezdxf.mozman.at/release-v0-17.html">Release notes for v0.17</a></p>Release v0.17.22022-01-06T17:02:00+01:002022-01-06T17:02:00+01:00mozmantag:ezdxf.mozman.at,2022-01-06:/release-v0-17.html<p>Release notes for ezdxf v0.17.2</p><h2>Launcher</h2>
<p>The new <code>browse</code> command opens a DXF structure browser to investigate the
internals of a DXF file without interpreting the content. The functionality of
the DXF browser is similar to the DXF Pretty Printer, but without the
disadvantage of creating giant HTML files. The intended usage is debugging
invalid DXF files, which can not be loaded by <code>ezdxf.readfile()</code> or the
<code>ezdxf.recover.readfile()</code> functions. </p>
<div class="highlight"><pre><span></span><code>C:\> ezdxf browse gear.dxf
</code></pre></div>
<p><img alt="gear-pp" src="image/gear-browse.png"></p>
<p>The new command <code>strip</code> removes all comment tags (999) and the <code>THUMBNAILIMAGE</code>
section.</p>
<p>The new command <code>config</code> manages config files.</p>
<p>For more information read the <a href="https://ezdxf.mozman.at/docs/launcher.html">launcher</a>
documentation. </p>
<h2>Support for Config Files</h2>
<p>Config files store global <code>ezdxf</code> options in INI-files.</p>
<p>The default config files are loaded from the user home directory as
"~/.config/ezdxf/ezdxf.ini", and the current working directory as "./ezdxf.ini".
A custom config file can be specified by the environment variable <code>EZDXF_CONFIG_FILE</code>.
Ezdxf follows the XDG Base Directory specification if the environment variable
<code>XDG_CONFIG_HOME</code> is set.</p>
<p>For more information read the documentation about
<a href="https://ezdxf.mozman.at/docs/options.html">global options</a>. </p>
<h2><code>ezdxf</code> Meta Data in DXF files</h2>
<p>For debugging the <code>ezdxf</code> version and date/time of creation or modification of
a DXF file is stored as meta data in DXF file itself. <code>Ezdxf</code> uses standard DXF
features to store its meta data. This meta data is preserved by Autodesk products,
BricsCAD and of course <code>ezdxf</code>. Other 3rd party DXF libraries may remove this
meta data.</p>
<p>The <code>MetaData</code> object is open to store additional user data as strings:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
<span class="n">metadata</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">ezdxf_metadata</span><span class="p">()</span>
<span class="n">metadata</span><span class="p">[</span><span class="s2">"MyAdditionalUserData"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"XYZ"</span>
</code></pre></div>
<p>Keys used by <code>ezdxf</code>:</p>
<ul>
<li><code>CREATED_BY_EZDXF</code></li>
<li><code>WRITTEN_BY_EZDXF</code></li>
</ul>
<p>For more information read the documentation about
<a href="https://ezdxf.mozman.at/docs/drawing/management.html#ezdxf-metadata">document settings</a>. </p>
<h2>Store Custom Data in DXF files</h2>
<p>New helper classes to store custom data in DXF files in a simple way.</p>
<ul>
<li><a href="https://ezdxf.mozman.at/docs/user_record.html#userrecord">ezdxf.urecord.UserRecord</a></li>
<li><a href="https://ezdxf.mozman.at/docs/user_record.html#binaryrecord">ezdxf.urecord.BinaryRecord</a></li>
<li><a href="https://ezdxf.mozman.at/docs/user_xdata.html#xdatauserlist">ezdxf.entities.xdata.XDataUserList</a></li>
<li><a href="https://ezdxf.mozman.at/docs/user_xdata.html#xdatauserdict">ezdxf.entities.xdata.XDataUserDict</a></li>
</ul>
<p>For more information read the new <a href="https://ezdxf.mozman.at/docs/tutorials/custom_data.html">tutorial</a>
about storing custom data in DXF files.</p>
<h2>Support for the MPOLYGON entity</h2>
<p>The <code>MPOLYGON</code> entity is supported by all internal modules and functions and the
following add-ons:</p>
<ul>
<li><code>drawing</code></li>
<li><code>dxf2code</code></li>
<li><code>geo</code></li>
</ul>
<h2><code>upright</code> Module</h2>
<p>The <code>upright()</code> and <code>upright_all()</code> functions convert an inverted OCS defined
by an extrusion vector (0, 0, -1) into a WCS aligned OCS defined by an extrusion
vector (0, 0, 1).</p>
<p>This simplifies 2D entity processing for ezdxf users and creates DXF output for
3rd party DXF libraries which ignore the existence of the OCS.</p>
<p>Supported DXF entities:</p>
<ul>
<li><code>CIRCLE</code></li>
<li><code>ARC</code></li>
<li><code>ELLIPSE</code> (WCS entity, flips only the extrusion vector)</li>
<li><code>SOLID</code></li>
<li><code>TRACE</code></li>
<li><code>LWPOLYLINE</code></li>
<li><code>POLYLINE</code> (only 2D entities)</li>
<li><code>HATCH</code></li>
<li><code>MPOLYGON</code></li>
<li><code>INSERT</code> (block references)</li>
</ul>
<p>The WCS representation of OCS entities with flipped extrusion vector is not 100%
identical to the source entity, curve orientation and vertex order may change,
see additional explanation in the docs. A mirrored text represented by an
extrusion vector (0, 0, -1) cannot represented by an extrusion vector (0, 0, 1),
therefore this CANNOT work for text entities or entities including text: <code>TEXT</code>,
<code>ATTRIB</code>, <code>ATTDEF</code>, <code>MTEXT</code>, <code>DIMENSION</code>, <code>LEADER</code>, <code>MLEADER</code></p>
<p>The functions can be applied to any DXF entity without expecting errors or
exceptions if the DXF entity is not supported or the extrusion vector differs
from (0, 0, -1). This also means you can apply the functions multiple times to
the same entities without any problems. A common case would be to upright all
entities of the model space:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="kn">from</span> <span class="nn">ezdxf.upright</span> <span class="kn">import</span> <span class="n">upright_all</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">readfile</span><span class="p">(</span><span class="s2">"your.dxf"</span><span class="p">)</span>
<span class="n">msp</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">modelspace</span><span class="p">()</span>
<span class="n">upright_all</span><span class="p">(</span><span class="n">msp</span><span class="p">)</span>
<span class="c1"># doing it again is no problem but also has no further effects</span>
<span class="n">upright_all</span><span class="p">(</span><span class="n">msp</span><span class="p">)</span>
</code></pre></div>
<p>For more information read the <a href="https://ezdxf.mozman.at/docs/upright.html">upright</a>
documentation. </p>
<h2><code>MTextExplode</code> Add-on</h2>
<p>This tool is meant to explode <code>MTEXT</code> entities into single line <code>TEXT</code> entities
by replicating the <code>MTEXT</code> layout as close as possible. This tool requires the
optional <code>Matplotlib</code> package to create usable results, nonetheless it also
works without <code>Matplotlib</code>, but then uses a mono-spaced replacement font for
text size measuring which leads to very inaccurate results.</p>
<p>Example to explode all <code>MTEXT</code> entities in the DXF file "mtext.dxf":</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="kn">from</span> <span class="nn">ezdxf.addons</span> <span class="kn">import</span> <span class="n">MTextExplode</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">readfile</span><span class="p">(</span><span class="s2">"mtext.dxf"</span><span class="p">)</span>
<span class="n">msp</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">modelspace</span><span class="p">()</span>
<span class="c1"># msp is the target layout for "exploded" parts of the MTEXT entity</span>
<span class="k">with</span> <span class="n">MTextExplode</span><span class="p">(</span><span class="n">msp</span><span class="p">)</span> <span class="k">as</span> <span class="n">xpl</span><span class="p">:</span>
<span class="k">for</span> <span class="n">mtext</span> <span class="ow">in</span> <span class="n">msp</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"MTEXT"</span><span class="p">):</span>
<span class="n">xpl</span><span class="o">.</span><span class="n">explode</span><span class="p">(</span><span class="n">mtext</span><span class="p">)</span>
<span class="n">doc</span><span class="o">.</span><span class="n">saveas</span><span class="p">(</span><span class="s2">"xpl_mtext.dxf"</span><span class="p">)</span>
</code></pre></div>
<p>For more information read the <a href="https://ezdxf.mozman.at/docs/addons/mtxpl.html">MTextExplode</a>
documentation. </p>
<h2>Configuration of the <code>drawing</code> Add-on</h2>
<p>The previous way to configure the <code>drawing</code> add-on by passing an untyped <code>dict</code>
to the backend, has been replaced by a <a href="https://ezdxf.mozman.at/docs/addons/drawing.html#configuration">Configuration</a>
dataclass, which is passed as the <code>config</code> argument of the <code>Frontend</code> class
initializer.</p>
<p>Excerpt from example file <a href="https://github.com/mozman/ezdxf/blob/master/examples/addons/drawing/draw_cad.py">draw_cad.py</a></p>
<div class="highlight"><pre><span></span><code><span class="c1"># required imports</span>
<span class="kn">from</span> <span class="nn">ezdxf.addons.drawing.config</span> <span class="kn">import</span> <span class="n">Configuration</span><span class="p">,</span> <span class="n">LinePolicy</span>
<span class="c1"># -x-x-x- snip</span>
<span class="c1"># create configuration</span>
<span class="n">config</span> <span class="o">=</span> <span class="n">Configuration</span><span class="o">.</span><span class="n">defaults</span><span class="p">()</span>
<span class="n">config</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">with_changes</span><span class="p">(</span>
<span class="n">line_policy</span><span class="o">=</span><span class="n">LinePolicy</span><span class="o">.</span><span class="n">ACCURATE</span>
<span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">ltype</span> <span class="o">==</span> <span class="s2">"ezdxf"</span>
<span class="k">else</span> <span class="n">config</span><span class="o">.</span><span class="n">line_policy</span>
<span class="p">)</span>
<span class="c1"># -x-x-x- snip</span>
<span class="c1"># pass configuration to Frontend() class</span>
<span class="n">Frontend</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">out</span><span class="p">,</span> <span class="n">config</span><span class="o">=</span><span class="n">config</span><span class="p">)</span><span class="o">.</span><span class="n">draw_layout</span><span class="p">(</span><span class="n">layout</span><span class="p">,</span> <span class="n">finalize</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="c1"># -x-x-x- snip</span>
</code></pre></div>
<h2>Extended MText Rendering for the <code>drawing</code> Add-on</h2>
<p>Columns and inline formatting codes are now supported. Because this feature
depends on the exact same font rendering as done by CAD applications, which
cannot be replicated, results are close to CAD applications but are not perfect. </p>
<p><img alt="complex-mtext" src="image/complex-mtext-draw.png"></p>
<h2>Multi-Path Support for the <code>ezdxf.path.Path</code> Class</h2>
<p>The class <code>ezdxf.path.Path</code> supports now multiple paths in one instance. This
required the new command <code>move_to(location)</code>, which starts a new sub-path
at the given <code>location</code>. The new property <code>Path.has_sub_paths</code> is <code>True</code> if
more than one path is present in an instance. The method <code>Path.sub_paths()</code>
yield all sub paths as single path instances, the utility function
<code>ezdxf.path.single_paths()</code> does the same for an iterable of of single- or
multi-path objects.
The function <code>ezdxf.path.to_multi_path()</code> builds a new multi-path object from
an iterable of single- or multi-path objects.</p>
<p>The converter function <code>ezdxf.path.make_path()</code> supports now the <code>HATCH</code> and the
<code>MPOLYGON</code> entity directly and returns a multi-path instance with a sub-path
for each <code>HATCH</code> boundary path. The converter function <code>ezdxf.path.from_hatch()</code>
still exist and returns all boundary paths of <code>HATCH</code> entities as single-path
objects like in the previous versions of <code>ezdxf</code>:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">ezdxf.path</span> <span class="kn">import</span> <span class="n">make_path</span><span class="p">,</span> <span class="n">from_hatch</span>
<span class="c1"># ...</span>
<span class="n">paths</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">make_path</span><span class="p">(</span><span class="n">hatch</span><span class="p">)</span><span class="o">.</span><span class="n">sub_paths</span><span class="p">())</span>
<span class="c1"># is the same as</span>
<span class="n">paths</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">from_hatch</span><span class="p">(</span><span class="n">hatch</span><span class="p">))</span>
</code></pre></div>
<h2>New Code Formatting Feature for the <code>dxf2code</code> Add-on</h2>
<p>The method <code>black_code_str()</code> returns the same code string as the
<code>code_str()</code> method, but reformatted by the <a href="https://pypi.org/project/black/">Black</a>
formatting tool, if Black is installed.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="kn">from</span> <span class="nn">ezdxf.addons.dxf2code</span> <span class="kn">import</span> <span class="n">entities_to_code</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">readfile</span><span class="p">(</span><span class="s1">'original.dxf'</span><span class="p">)</span>
<span class="n">msp</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">modelspace</span><span class="p">()</span>
<span class="n">source</span> <span class="o">=</span> <span class="n">entities_to_code</span><span class="p">(</span><span class="n">msp</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'source.py'</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">'wt'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">import_str</span><span class="p">())</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">'</span><span class="se">\n\n</span><span class="s1">'</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">black_code_str</span><span class="p">())</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
</code></pre></div>
<h2>Typed Table Factory Methods</h2>
<p>With the addition of support for type annotations, typed factory methods were
required to create resource table entries:</p>
<ul>
<li><code>Drawing.layers.add()</code> factory method to create new layers</li>
<li><code>Drawing.styles.add()</code> factory method to create new text styles</li>
<li><code>Drawing.linetypes.add()</code> factory method to create new line types</li>
</ul>
<p>The new recommended way to create layers, text styles or linetypes is:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">setup</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">doc</span><span class="o">.</span><span class="n">layers</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"MyLayer"</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">linetype</span><span class="o">=</span><span class="s2">"DASHED"</span><span class="p">)</span>
<span class="n">doc</span><span class="o">.</span><span class="n">styles</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"Arial"</span><span class="p">,</span> <span class="n">font</span><span class="o">=</span><span class="s2">"arial.ttf"</span><span class="p">)</span>
<span class="n">doc</span><span class="o">.</span><span class="n">linetypes</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"DASHEDX3"</span><span class="p">,</span> <span class="p">[</span><span class="mf">0.9</span><span class="p">,</span> <span class="mf">0.8</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.1</span><span class="p">],</span> <span class="n">description</span><span class="o">=</span><span class="s2">"Dashed (3x) ___ ___ ___ ___ ___"</span><span class="p">)</span>
</code></pre></div>
<p>There are also new typed factory methods for all remaining resource tables, but
they are not that important to library users:</p>
<ul>
<li><code>Drawing.dimstyles.add()</code></li>
<li><code>Drawing.appids.add()</code></li>
<li><code>Drawing.ucs.add()</code></li>
<li><code>Drawing.views.add()</code></li>
<li><code>Drawing.viewports.add()</code></li>
<li><code>Drawing.block_records.add()</code></li>
</ul>
<h2>Compose MText Content</h2>
<p>The <code>MTextEditor</code> is a helper class to build <code>MTEXT</code> content strings with
support for inline codes to change color, font or paragraph properties.</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">ezdxf.tools.text</span> <span class="kn">import</span> <span class="n">MTextEditor</span>
<span class="n">e</span> <span class="o">=</span> <span class="n">MTextEditor</span><span class="p">(</span><span class="s2">"This example "</span><span class="p">)</span><span class="o">.</span><span class="n">color</span><span class="p">(</span><span class="s2">"red"</span><span class="p">)</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"switches color to red."</span><span class="p">)</span>
<span class="n">mtext</span> <span class="o">=</span> <span class="n">msp</span><span class="o">.</span><span class="n">add_mtext</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
</code></pre></div>
<p>For more information see the <a href="https://ezdxf.mozman.at/docs/tools/text.html#mtexteditor">docs</a>
or the <code>MTEXT</code> <a href="https://ezdxf.mozman.at/docs/tutorials/mtext.html#mtexteditor">tutorial</a>.</p>
<h2>Create MText With Columns</h2>
<p>New factory methods to create <code>MTEXT</code> entities with columns. The current
implementation works best for DXF R2018, because the content is stored as a
continuous text in a single <code>MTEXT</code> entity.
For DXF versions prior to R2018 the content should be distributed across multiple
<code>MTEXT</code> entities (one entity per column), which is not done by <code>ezdxf</code>, but
the result is correct for advanced DXF viewers and CAD application, which
do the <code>MTEXT</code> content distribution completely by itself.</p>
<ul>
<li><code>BaseLayout.add_mtext_static_columns()</code></li>
<li><code>BaseLayout.add_mtext_dynamic_manual_height_columns()</code></li>
<li><code>BaseLayout.add_mtext_dynamic_auto_height_columns()</code></li>
</ul>
<p>It is recommended to use DXF R2018 for <code>MTEXT</code> with columns!</p>
<h2>DXF Entity Enhancements</h2>
<ul>
<li><code>ezdxf.entity.MText</code> column support, parsing tools, composing tools</li>
<li>Support for the <code>ACAD_PROXY_ENTITY</code> entity</li>
<li>Support for multi-line <code>ATTRIB</code> and <code>ATTDEF</code> entities in DXF R2018.</li>
<li><code>Auditor</code> removes invalid DXF entities from layouts, blocks and the
OBJECTS section</li>
<li><code>Auditor</code> removes invalid standalone <code>ATTRIB</code> entities from layouts and
blocks.</li>
<li>Extension dictionaries are copied along with the DXF entity.</li>
<li>Transformation support for points and vectors in the <code>XDATA</code> section of a
DXF entity </li>
</ul>
<h2>Removed features</h2>
<p>Environment variable options, these are config file only options now:</p>
<ul>
<li><code>EZDXF_AUTO_LOAD_FONTS</code></li>
<li><code>EZDXF_FONT_CACHE_DIRECTORY</code></li>
<li><code>EZDXF_PRESERVE_PROXY_GRAPHICS</code></li>
<li><code>EZDXF_LOG_UNPROCESSED_TAGS</code></li>
<li><code>EZDXF_FILTER_INVALID_XDATA_GROUP_CODES</code></li>
</ul>
<p>Removed the <code>Vector</code> alias for the <code>ezdxf.math.Vec3</code> class.</p>
<p>Removed the <code>BaseLayout.add_attrib()</code> factory method to add (invalid) standalone
<code>ATTRIB</code> entities</p>
<p>Removed the deprecated class methods <code>from_...(entity)</code> from the
<code>ezdxf.path.Path</code> class, use <code>ezdxf.path.make_path(entity)</code> instead.
Also removed the deprecated <code>ezdxf.path.Path</code> methods <code>add_...(entity)</code>,
use <code>path.add_...(path, entity)</code> function instead.</p>
<h2>Change Log</h2>
<h3>Version 0.17.2 - 2022-01-06</h3>
<ul>
<li>NEW: extended binary wheels support</li>
<li><code>manylinux2010_x86_64</code> for Python < 3.10 and <code>manylinux2014_x86_64</code>
for Python >= 3.10 </li>
<li><code>musllinux_2010_x86_64</code> for Python < 3.10 and <code>musllinux_2014_x86_64</code>
for Python >= 3.10</li>
<li><code>manylinux_2014_aarch64</code> for ARM64 based Linux</li>
<li><code>musllinux_2014_aarch64</code> for ARM64 based Linux</li>
<li><code>macosx_11_0_arm64</code> for Apple silicon</li>
<li><code>macosx_10_9_universal2</code> for Apple silicon & x86</li>
<li>NEW: Auditor fixes invalid transparency values</li>
<li>NEW: Auditor fixes invalid crease data in <code>MESH</code> entities</li>
<li>NEW: add <code>transparency</code> argument to <code>LayerTable.add()</code></li>
<li>NEW: support for transparency <code>BYLAYER</code> and <code>BYBLOCK</code> for the <code>drawing</code> add-on</li>
<li>NEW: <code>Textstyle.make_font()</code> returns the ezdxf font abstraction</li>
<li>NEW: added <code>dxfattribs</code> argument to method <code>Drawing.set_modelspace_vport()</code></li>
<li>NEW: <code>ezdxf.math.split_bezier()</code> function to split Bezier curves of any degree</li>
<li>NEW: <code>ezdxf.math.intersection_line_line_3d()</code></li>
<li>NEW: <code>ezdxf.math.intersect_poylines_2d()</code></li>
<li>NEW: <code>ezdxf.math.intersect_poylines_3d()</code></li>
<li>NEW: <code>ezdxf.math.quadratic_bezier_from_3p()</code></li>
<li>NEW: <code>ezdxf.math.cubic_bezier_from_3p()</code></li>
<li>NEW: <code>BoundingBox.contains()</code>, check if a bounding box contains completely
another bounding box </li>
<li>NEW: <code>TextEntityAlignment</code> enum replaces the string based alignment definition</li>
<li>NEW: method <code>Text.get_placement()</code>, replaces <code>get_pos()</code> </li>
<li>NEW: method <code>Text.set_placement()</code>, replaces <code>set_pos()</code> </li>
<li>NEW: method <code>Text.get_align_enum()</code>, replaces <code>get_align()</code></li>
<li>NEW: method <code>Text.set_align_enum()</code>, replaces <code>set_align()</code></li>
<li>DEPRECATED: method <code>Text.get_pos()</code> will be removed in v1.0.0</li>
<li>DEPRECATED: method <code>Text.set_pos()</code> will be removed in v1.0.0</li>
<li>DEPRECATED: method <code>Text.get_align()</code> will be removed in v1.0.0</li>
<li>DEPRECATED: method <code>Text.set_align()</code> will be removed in v1.0.0</li>
<li>CHANGE: moved enum <code>MTextEntityAlignment</code> to <code>ezdxf.enums</code></li>
<li>CHANGE: moved enum <code>MTextParagraphAlignment</code> to <code>ezdxf.enums</code></li>
<li>CHANGE: moved enum <code>MTextFlowDirection</code> to <code>ezdxf.enums</code></li>
<li>CHANGE: moved enum <code>MTextLineAlignment</code> to <code>ezdxf.enums</code></li>
<li>CHANGE: moved enum <code>MTextStroke</code> to <code>ezdxf.enums</code></li>
<li>CHANGE: moved enum <code>MTextLineSpacing</code> to <code>ezdxf.enums</code></li>
<li>CHANGE: moved enum <code>MTextBackgroundColor</code> to <code>ezdxf.enums</code></li>
<li>CHANGE: <code>Dimstyle.set_tolerance()</code>: argument <code>align</code> as enum <code>MTextLineAlignment</code></li>
<li>CHANGE: <code>DimstyleOverride.set_tolerance()</code>: argument <code>align</code> as enum <code>MTextLineAlignment</code></li>
<li>CHANGE: <code>MeshData.add_edge()</code> is changed to <code>MeshData.add_edge_crease()</code>,
this fixes my misunderstanding of edge and crease data in the <code>MESH</code> entity. </li>
<li>BUGFIX <a href="https://github.com/mozman/ezdxf/issues/574">#574</a>:
flattening issues in <code>Path()</code> and <code>ConstructionEllipse()</code> </li>
<li>BUGFIX: <code>drawing</code> add-on shows block references in <code>ACAD_TABLE</code> at the
correct location</li>
<li>BUGFIX <a href="https://github.com/mozman/ezdxf/issues/589">#589</a>:
<code>Polyface.virtual_entities()</code> yields correct triangle faces</li>
<li>BUGFIX: prevent invalid DXF export of the <code>MESH</code> entity </li>
</ul>
<h3>Version 0.17.1 - 2021-11-14</h3>
<ul>
<li>CHANGE: using <a href="https://pypi.org/project/PySide6/">PySide6</a> as Qt binding
if installed, <code>PyQt5</code> is still supported as fallback</li>
<li>NEW: tracking feature for DXF entity copies, new properties of <code>DXFEntity</code></li>
<li><code>source_of_copy</code> - the immediate source of an entity copy</li>
<li><code>origin_of_copy</code> - the first non virtual source entity of an entity copy</li>
<li><code>is_copy</code> - is <code>True</code> if the entity is a copy</li>
<li>NEW: source entity tracking for virtual sub-entities for:
<code>POINT</code>, <code>LWPOLYLINE</code>, <code>POLYLINE</code>, <code>LEADER</code>, <code>MLINE</code>, <code>ACAD_PROXY_ENTITY</code> </li>
<li>NEW: source block reference tracking for virtual entities created from block
references, new properties of <code>DXFEntity</code></li>
<li><code>has_source_block_reference</code> - is <code>True</code> if the virtual entity was created
by a block reference</li>
<li><code>source_block_reference</code> - the immediate source block reference (<code>INSERT</code>),
which created the virtual entity, otherwise <code>None</code></li>
<li>NEW: <code>ezdxf.tools.text_size</code> module to measure <code>TEXT</code> and <code>MTEXT</code> entity dimensions</li>
<li>CHANGE: <code>--ltype</code> arguments of the <code>draw</code> command to <code>approximate</code> and <code>accurate</code>
to be in sync with the <code>drawing</code> add-on configuration.</li>
<li>CHANGE: <code>--ltype</code> arguments of the <code>view</code> command to <code>approximate</code> and <code>accurate</code>
to be in sync with the <code>drawing</code> add-on configuration.</li>
<li>REMOVE <code>--scale</code> argument of the <code>view</code> command</li>
<li>REMOVE: <code>PolylinePath.PATH_TYPE</code>, use <code>PolylinePath.type</code> instead</li>
<li>REMOVE: <code>EdgePath.PATH_TYPE</code>, use <code>EdgePath.type</code> instead</li>
<li>BUGFIX: invalid XDATA processing in <code>XData.safe_init()</code> </li>
<li>BUGFIX: group code 1003 is valid in XDATA section </li>
<li>BUGFIX: fix loading error of <code>DIMSTYLE</code> attribute <code>dimtxsty</code> </li>
<li>BUGFIX: fix "Next Entity" and "Previous Entity" actions in the <code>browse</code> command </li>
<li>BUGFIX: export <code>MTEXT</code> entities with column count different than the count of
linked <code>MTEXT</code> entities </li>
<li>BUGFIX: fix invalid text rotation for relative text shifting for linear dimensions</li>
</ul>
<h3>Version 0.17 - 2021-10-01</h3>
<ul>
<li>NEW: column support for MTEXT read and create, but no editing</li>
<li>NEW: factory method <code>BaseLayout.add_mtext_static_columns()</code></li>
<li>NEW: factory method <code>BaseLayout.add_mtext_dynamic_manual_height_columns()</code></li>
<li>NEW: add-on tool <code>MTextExplode()</code> to explode MTEXT entities
into single line TEXT entities and additional LINE entities to emulate
strokes, requires the <code>Matplotlib</code> package</li>
<li>NEW: <code>move_to()</code> command and multi-path support for the <code>ezdxf.path.Path</code> class </li>
<li>NEW: regular <code>make_path()</code> support for the HATCH entity, returns a multi-path object </li>
<li>NEW: regular <code>make_primitive()</code> support for the HATCH entity </li>
<li>NEW: <code>text2path.make_path_from_str()</code> returns a multi-path object </li>
<li>NEW: <code>text2path.make_path_from_enity()</code> returns a multi-path object </li>
<li>NEW: <code>MPOLYGON</code> load/write/create support</li>
<li>NEW: <code>ezdxf.path.to_mpolygons()</code> function: Path() to MPOLYGON converter</li>
<li>NEW: <code>ezdxf.path.render_mpolygons()</code> function: render MPOLYGON entities form paths</li>
<li>NEW: store <em>ezdxf</em> and custom metadata in DXF files</li>
<li>NEW: command <code>ezdxf browse FILE ...</code>, PyQt DXF structure browser</li>
<li>NEW: <code>dxf2code</code> add-on: function <code>black()</code> and method <code>Code.black_code_str()</code>
returns the code string formatted by <a href="https://pypi.org/project/black/">Black</a></li>
<li>NEW: <code>ezdxf.upright</code> module to flip inverted extrusion vectors, for more
information read the <a href="https://ezdxf.mozman.at/docs/upright.html">docs</a> </li>
<li>NEW: support for <code>ACAD_PROXY_ENTITY</code></li>
<li>NEW: <code>BaseLayout.add_mtext_static_columns()</code></li>
<li>NEW: <code>BaseLayout.add_mtext_dynamic_manual_height_columns()</code></li>
<li>NEW: rendering support for inline codes in <code>MTEXT</code> entities for the <code>drawing</code>
add-on</li>
<li>NEW: <code>XDATA</code> transformation support</li>
<li>NEW: copy support for extension dictionaries</li>
<li>CHANGE: <code>drawing</code> add-on: replaced the backend <code>params</code> argument (untyped dict)
by the new typed <code>Configuration</code> object passed to the frontend class as
argument <code>config</code></li>
<li>REMOVED: deprecated class methods <code>from_...(entity)</code> from <code>Path</code> class,
use <code>path.make_path(entity)</code> instead</li>
<li>REMOVED: deprecated <code>Path</code> methods <code>add_...(entity)</code>,
use <code>path.add_...(path, entity)</code> function instead</li>
<li>BUGFIX: entity query did not match default values if the attribute was not present</li>
<li>BUGFIX: groupby query did not match default values if the attribute was not present</li>
<li>BUGFIX: ODAFC add-on - reintroduce accidentally removed global variable <code>exec_path</code> as <code>win_exec_path</code> </li>
<li>BUGFIX: graphic entities are not allowed as <code>DICTIONARY</code> entries </li>
<li>BUGFIX: copied <code>DICTIONARY</code> was not added to the OBJECTS section by calling <code>factory.bind()</code></li>
<li>BUGFIX: <code>XRecord.copy()</code> copies content tags</li>
</ul>
<p>Release notes for v0.16: https://ezdxf.mozman.at/release-v0-16.html</p>Release v0.16.62021-07-18T16:06:00+02:002021-07-18T16:06:00+02:00mozmantag:ezdxf.mozman.at,2021-07-18:/release-v0-16.html<p>Release notes for ezdxf v0.16.6</p><h2>Launcher</h2>
<p>The new command line script <code>ezdxf</code> launches various sub-commands:</p>
<ul>
<li><code>pp</code> the previous <code>dxfpp</code> command, the DXF pretty printer</li>
<li><code>audit</code> DXF files</li>
<li><code>draw</code> and convert DXF files by the Matplotlib backend </li>
<li><code>view</code> DXF files by the PyQt viewer</li>
<li><code>browse</code> PyQt DXF structure browser for DXF debugging and curios people (v0.16.4)</li>
<li><code>strip</code> Strip comments and THUMBNAILIMAGE section from DXF files (v0.16.4)</li>
</ul>
<p>The help option <code>-h</code> is supported by the main script and all sub-commands:</p>
<div class="highlight"><pre><span></span><code>C:\> ezdxf -h
usage: ezdxf [-h] [-V] [-v] [--log LOG] {pp,audit,draw,view} ...
Command launcher for the Python package "ezdxf": https://pypi.org/project/ezdxf/
positional arguments:
{pp,audit,draw,view}
pp pretty print DXF files as HTML file
audit audit and repair DXF files
draw draw and convert DXF files by Matplotlib
view view DXF files by the PyQt viewer
optional arguments:
-h, --help show this help message and exit
-V, --version show version and exit
-v, --verbose give more output
--log LOG path to a verbose appending log
</code></pre></div>
<p>This is the only executable script installed on the user system, if installed
by <code>pip</code>, the <code>dxfpp</code> script is not included anymore.</p>
<h3>Examples</h3>
<p>Pretty print the DXF text content as HTML file and open the file in the
default web browser:</p>
<div class="highlight"><pre><span></span><code>C:\> ezdxf pp -o gear.dxf
</code></pre></div>
<p><img alt="gear-pp" src="image/gear-pp.png"></p>
<p>Audit and recover the DXF file <code>gear.dxf</code> and save the recovered version
as <code>gear.rec.dxf</code>:</p>
<div class="highlight"><pre><span></span><code>C:\> ezdxf audit -s gear.dxf
auditing file: gear.dxf
No errors found.
Saved recovered file as: gear.rec.dxf
</code></pre></div>
<p>Convert the DXF file <code>gear.dxf</code> into a SVG file by the <em>Matplotlib</em> backend:</p>
<div class="highlight"><pre><span></span><code>C:\> ezdxf draw -o gear.svg gear.dxf
</code></pre></div>
<p>The <code>gear.svg</code> created by the <em>Matplotlib</em> backend:</p>
<p><img alt="gear-pp" src="image/gear.svg"></p>
<p>Show all output formats supported by the <em>Matplotlib</em> backend
on your system. This output may vary:</p>
<div class="highlight"><pre><span></span><code>C:\> ezdxf draw --formats
eps: Encapsulated Postscript
jpg: Joint Photographic Experts Group
jpeg: Joint Photographic Experts Group
pdf: Portable Document Format
pgf: PGF code for LaTeX
png: Portable Network Graphics
ps: Postscript
raw: Raw RGBA bitmap
rgba: Raw RGBA bitmap
svg: Scalable Vector Graphics
svgz: Scalable Vector Graphics
tif: Tagged Image File Format
tiff: Tagged Image File Format
</code></pre></div>
<p>View the DXF file <code>gear.dxf</code> by the <em>PyQt</em> backend:</p>
<div class="highlight"><pre><span></span><code>C:\> ezdxf view gear.dxf
</code></pre></div>
<p><img alt="gear-pp" src="image/gear-qt-backend.png"></p>
<p>Show the <em>ezdxf</em> version and configuration:</p>
<div class="highlight"><pre><span></span><code>C:\> ezdxf -Vv
ezdxf v0.16b2 @ d:\source\ezdxf.git\src\ezdxf
Python version: 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, ...
using C-extensions: yes
using Matplotlib: yes
font cache directory: internal
default text style: OpenSans
default dimension text style: OpenSansCondensed-Light
load proxy graphic: yes
store proxy graphic: yes
log unprocessed tags: yes
filter invalid XDATA group codes: no
EZDXF_DISABLE_C_EXT=
EZDXF_TEST_FILES=D:\Source\dxftest
EZDXF_FONT_CACHE_DIRECTORY=
EZDXF_AUTO_LOAD_FONTS=
EZDXF_PRESERVE_PROXY_GRAPHICS=
EZDXF_LOG_UNPROCESSED_TAGS=
EZDXF_FILTER_INVALID_XDATA_GROUP_CODES=
</code></pre></div>
<h2>Bounding Box Module <code>bbox</code></h2>
<p>This module provides methods to calculate axis aligned bounding boxes.
The module can handle nested block reference structures,
see also the description of the new <code>disassamble</code> support module below.</p>
<p>The <code>bbox.extents()</code> function calculates a single bounding box for
multiple DXF entities. This example draws a rectangle around the cog wheel:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="kn">from</span> <span class="nn">ezdxf</span> <span class="kn">import</span> <span class="n">bbox</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">readfile</span><span class="p">(</span><span class="s2">"gear.dxf"</span><span class="p">)</span>
<span class="n">msp</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">modelspace</span><span class="p">()</span>
<span class="n">box</span> <span class="o">=</span> <span class="n">bbox</span><span class="o">.</span><span class="n">extents</span><span class="p">(</span><span class="n">msp</span><span class="p">)</span>
<span class="c1"># draw a rectangle around the cog wheel</span>
<span class="n">p1</span> <span class="o">=</span> <span class="n">box</span><span class="o">.</span><span class="n">extmin</span>
<span class="n">p2</span> <span class="o">=</span> <span class="n">box</span><span class="o">.</span><span class="n">extmax</span>
<span class="n">msp</span><span class="o">.</span><span class="n">add_lwpolyline</span><span class="p">([</span><span class="n">p1</span><span class="p">,</span> <span class="p">(</span><span class="n">p2</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">p1</span><span class="o">.</span><span class="n">y</span><span class="p">),</span> <span class="n">p2</span><span class="p">,</span> <span class="p">(</span><span class="n">p1</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">p2</span><span class="o">.</span><span class="n">y</span><span class="p">)],</span> <span class="n">close</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="c1"># draw an inner hole</span>
<span class="n">diameter</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">box</span><span class="o">.</span><span class="n">size</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">box</span><span class="o">.</span><span class="n">size</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>
<span class="n">radius</span> <span class="o">=</span> <span class="n">diameter</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">*</span> <span class="mf">0.7</span>
<span class="n">msp</span><span class="o">.</span><span class="n">add_circle</span><span class="p">(</span><span class="n">box</span><span class="o">.</span><span class="n">center</span><span class="p">,</span> <span class="n">radius</span><span class="p">)</span>
<span class="n">doc</span><span class="o">.</span><span class="n">saveas</span><span class="p">(</span><span class="s2">"gear_with_bbox.dxf"</span><span class="p">)</span>
</code></pre></div>
<p><img alt="gear-pp" src="image/gear-with-bbox.png"></p>
<p>For more information see the <a href="https://ezdxf.mozman.at/docs/bbox.html">documentation</a></p>
<h2>Module <code>zoom</code></h2>
<p>Set the active viewport of a layout to the bounding box of all DXF entities
in this layout or a subset of these entities. This module solves a problem of
many beginners, to find the content of a DXF file in the DXF viewer.</p>
<p>Set the active viewport to the extents of the model space:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="kn">from</span> <span class="nn">ezdxf</span> <span class="kn">import</span> <span class="n">zoom</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
<span class="n">msp</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">modelspace</span><span class="p">()</span>
<span class="n">msp</span><span class="o">.</span><span class="n">add_circle</span><span class="p">((</span><span class="mi">1000</span><span class="p">,</span> <span class="mi">1000</span><span class="p">),</span> <span class="n">radius</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="n">zoom</span><span class="o">.</span><span class="n">extents</span><span class="p">(</span><span class="n">msp</span><span class="p">)</span>
<span class="n">doc</span><span class="o">.</span><span class="n">saveas</span><span class="p">(</span><span class="s2">"circle.dxf"</span><span class="p">)</span>
</code></pre></div>
<p>For more information see the <a href="https://ezdxf.mozman.at/docs/zoom.html">documentation</a></p>
<h2>Support Module <code>disassemble</code></h2>
<p>This module provides tools for the recursive decomposition of nested block
reference structures into a flat stream of DXF entities and
converting DXF entities into geometric primitives as <code>Path</code> and <code>MeshBuilder</code>
objects encapsulated into intermediate <code>Primitive</code> classes. These primitives
give unified access to the entity vertices or even the shape as <code>Path</code> or
<code>MeshBuilder</code> objects. Text objects are represented by their bounding box as a
<code>Path</code> object. </p>
<p>For more information see the <a href="https://ezdxf.mozman.at/docs/disassemble.html">documentation</a></p>
<h2><code>text2path</code> Add-on</h2>
<p>Add-on to convert text strings and text based DXF entities into <code>Path</code> objects.
These tools depend on the optional <em>Matplotlib</em> package.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="kn">from</span> <span class="nn">ezdxf</span> <span class="kn">import</span> <span class="n">path</span><span class="p">,</span> <span class="n">zoom</span>
<span class="kn">from</span> <span class="nn">ezdxf.tools</span> <span class="kn">import</span> <span class="n">fonts</span>
<span class="kn">from</span> <span class="nn">ezdxf.addons</span> <span class="kn">import</span> <span class="n">text2path</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
<span class="n">msp</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">modelspace</span><span class="p">()</span>
<span class="c1"># convert a text string into Path() objects</span>
<span class="n">ff</span> <span class="o">=</span> <span class="n">fonts</span><span class="o">.</span><span class="n">FontFace</span><span class="p">(</span><span class="n">family</span><span class="o">=</span><span class="s2">"Times New Roman"</span><span class="p">)</span>
<span class="n">paths</span> <span class="o">=</span> <span class="n">text2path</span><span class="o">.</span><span class="n">make_paths_from_str</span><span class="p">(</span><span class="s2">"text outline as splines"</span><span class="p">,</span> <span class="n">ff</span><span class="p">)</span>
<span class="c1"># add Path() objects to the model space as SPLINE and POLYLINE entities</span>
<span class="n">path</span><span class="o">.</span><span class="n">render_splines_and_polylines</span><span class="p">(</span><span class="n">msp</span><span class="p">,</span> <span class="n">paths</span><span class="p">)</span>
<span class="n">zoom</span><span class="o">.</span><span class="n">extents</span><span class="p">(</span><span class="n">msp</span><span class="p">)</span>
<span class="n">doc</span><span class="o">.</span><span class="n">saveas</span><span class="p">(</span><span class="s1">'text2path.dxf'</span><span class="p">)</span>
</code></pre></div>
<p><img alt="text-outline-as-splines" src="image/text-outline-as-splines.png"></p>
<p>For more information see the <a href="https://ezdxf.mozman.at/docs/addons/text2path.html">documentation</a></p>
<h2>Extended <code>path</code> sub-package</h2>
<p>The usability of the <code>Path</code> class expanded by the introduction
of the reverse conversion from <code>Path</code> to DXF entities (LWPOLYLINE,
POLYLINE, LINE), and many other tools in this release of <em>ezdxf</em>.
To emphasize this new usability, the <code>Path</code> class has got its own
sub-package <code>ezdxf.path</code>.</p>
<ul>
<li>factory functions to create <code>Path</code> objects from DXF entities, vertices,
<em>Matplotlib</em> or <em>PyQt</em> paths</li>
<li>entity maker to create DXF entities from <code>Path</code> objects </li>
<li>render functions to render <code>Path</code> objects as DXF entities into layouts</li>
<li>utility functions like bounding box calculation and path transformation</li>
<li>create basic shapes as <code>Path</code> objects like circles or rectangles</li>
</ul>
<p>For more information see the <a href="https://ezdxf.mozman.at/docs/path.html">documentation</a></p>
<h2>Math Tools</h2>
<ul>
<li>Cython implementation of the <code>BSpline</code> construction tool</li>
<li>The <code>ezdxf.math.Bezier3P</code> class is an optimized quadratic Bézier curve
construction tool. </li>
<li>The <code>ezdxf.math.quadratic_to_cubic_bezier()</code> function converts <code>Bezier3P</code> to
<code>Bezier4P</code> objects.</li>
<li>The <code>ezdxf.math.bezier_to_bspline()</code> function convert multiple Bézier curves
into a single cubic <code>BSpline</code> objects. The Bézier curves should have at
least G1 continuity at the connection points, to get good results.</li>
<li>The <code>ezdxf.math.clip_polygon_2d()</code> function implements the <code>Sutherland–Hodgman</code>
algorithm for clipping 2D polygons.</li>
<li>The <code>ezdxf.math.basic_transformation()</code> function returns a combined
transformation matrix for translation, scaling and rotation about the z-axis.</li>
<li>The <code>ezdxf.math.best_fit_normal()</code> function returns the normal vector of
flat spatial planes. This function tolerates imperfect plane vertices.</li>
</ul>
<h2>DXF Entity Enhancements</h2>
<ul>
<li><code>ezdxf.entity.Text</code> getter/setter properties <code>is_backward</code> and <code>is_upside_down</code></li>
<li><code>ezdxf.entity.TextStyle</code> getter/setter properties <code>is_backward</code>,
<code>is_upside_down</code> and <code>is_vertical_stacked</code> </li>
</ul>
<h2>Change Log</h2>
<h3>Version 0.16.6 - 2021-08-28</h3>
<ul>
<li>NEW: <code>MPOLYGON</code> support for the <code>drawing</code> add-on</li>
<li>NEW: <code>MPOLYGON</code> support for the <code>geo</code> add-on</li>
<li>NEW: <code>fast</code> argument for method <code>MText.plain_text()</code></li>
<li>NEW: support for multi-line <code>ATTRIB</code> and <code>ATTDEF</code> entities in DXF R2018 </li>
<li>NEW: <code>Auditor</code> removes invalid DXF entities from layouts, blocks and the
OBJECTS section</li>
<li>NEW: <code>Auditor</code> removes standalone ATTRIB entities from layouts and blocks</li>
<li>NEW: <code>Drawing.layers.add()</code> factory method to create new layers</li>
<li>NEW: <code>Drawing.styles.add()</code> factory method to create new text styles</li>
<li>NEW: <code>Drawing.linetypes.add()</code> factory method to create new line types</li>
<li>CHANGE: renamed <code>RenderContext.current_layer</code> to <code>RenderContext.current_layer_properties</code> </li>
<li>CHANGE: renamed <code>RenderContext.current_block_reference</code> to <code>RenderContext.current_block_reference_properties</code> </li>
<li>CHANGE: extended entity validation for <code>GROUP</code></li>
<li>REMOVED: <code>BaseLayout.add_attrib()</code> factory method to add standalone <code>ATTRIB</code>
entities. <code>ATTRIB</code> entities cannot exist as standalone entities.</li>
<li>BUGFIX: add missing "doc" argument to DXF loaders, DXF version was not
available at loading stage </li>
<li>BUGFIX: DXF export for <code>ARC_DIMENSION</code></li>
<li>BUGFIX: <code>Arc.flattening()</code> always have to return <code>Vec3</code> instances</li>
<li>PREVIEW: new features to try out, API may change until official release in v0.17</li>
<li>PREVIEW: support for <code>ACAD_PROXY_ENTITY</code></li>
<li>PREVIEW: Rendering support for inline codes in <code>MTEXT</code> entities for the <code>drawing</code> add-on.</li>
</ul>
<h3>Version 0.16.5 - 2021-07-18</h3>
<ul>
<li>NEW: hard dependency <code>typing_extensions</code></li>
<li>CHANGE: replaced <code>ezdxf.tools.rgb</code> by <code>ezdxf.colors</code></li>
<li>CHANGE: <code>options</code> module renamed to <code>_options</code>; this eliminates the confusion
between the <code>options</code> module and the global object <code>ezdxf.options</code></li>
<li>NEW: config file support, see <a href="https://ezdxf.mozman.at/docs/options.html#config-files">docs</a></li>
<li>NEW: <code>ezdxf config</code> command to manage config files</li>
<li>NEW: <code>ezdxf.path.have_close_control_vertices(a, b)</code>, test for close control
vertices of two <code>Path</code> objects </li>
<li>REMOVED: environment variable options, these are config file only options:</li>
<li><code>EZDXF_AUTO_LOAD_FONTS</code></li>
<li><code>EZDXF_FONT_CACHE_DIRECTORY</code></li>
<li><code>EZDXF_PRESERVE_PROXY_GRAPHICS</code></li>
<li><code>EZDXF_LOG_UNPROCESSED_TAGS</code></li>
<li><code>EZDXF_FILTER_INVALID_XDATA_GROUP_CODES</code></li>
<li>REMOVED: <code>ezdxf.options.default_text_style</code>, was not used </li>
<li>REMOVED: <code>ezdxf.options.auto_load_fonts</code>, disabling auto load has no advantage</li>
<li>REMOVED: <code>Vector</code> alias for <code>Vec3</code></li>
<li>REMOVED: <code>get_acis_data()</code>, <code>set_acis_data()</code> and context manager <code>edit_data()</code>
from ACIS based entities, use <code>acis_data</code> property instead as <code>List[str]</code> or
<code>List[bytes]</code> </li>
<li>BUGFIX: <code>Spline.construction_tool()</code> recognizes start- and end tangents for
B-splines from fit points if defined </li>
<li>PREVIEW: new features to try out, API may change until official release in v0.17</li>
<li>PREVIEW: <code>dxf2code</code> add-on: function <code>black()</code> and method <code>Code.black_code_str()</code>
returns the code string formatted by <a href="https://pypi.org/project/black/">Black</a></li>
<li>PREVIEW: <code>ezdxf.upright</code> module to flip inverted extrusion vectors, for more
information read the <a href="https://ezdxf.mozman.at/docs/upright.html">docs</a> </li>
</ul>
<h3>Version 0.16.4 - 2021-06-20</h3>
<ul>
<li>NEW: <code>PolylinePath.type</code> and <code>EdgePath.type</code> as <code>ezdxf.entities.BoundaryPathType</code> enum </li>
<li>NEW: <code>LineEdge.type</code>, <code>ArcEdge.type</code>, <code>EllipseEdge.type</code> and <code>SplineEdge.type</code>
as <code>ezdxf.entities.EdgeType</code> enum</li>
<li>NEW: <code>Path.all_lines_to_curve3()</code>, convert all LINE_TO commands into linear
CURVE3_TO commands </li>
<li>NEW: <code>Path.all_lines_to_curve4()</code>, convert all LINE_TO commands into linear
CURVE4_TO commands</li>
<li>NEW: create an AppID <code>EZDXF</code> when saving a DXF file by <em>ezdxf</em> </li>
<li>BUGFIX: loading crash of the PyQt <code>CADViewer</code> class</li>
<li>BUGFIX: loading <code>GEODATA</code> version 1, perhaps data is incorrect,
logged as warning</li>
<li>BUGFIX: <code>HATCH</code> spline edge from fit points require start- and end tangents</li>
<li>BUGFIX: <code>disassemble.make_primitive()</code> transform LWPOLYLINE including width
values into WCS</li>
<li>BUGFIX: ignore open loops in <code>HATCH</code> edge paths </li>
<li>BUGFIX: correct application of the <code>Dimension.dxf.insert</code> attribute</li>
<li>BUGFIX: fixed incorrect "thickness" transformation of OCS entities</li>
<li>BUGFIX: add missing "width" transformation to POLYLINE and LWPOLYLINE</li>
<li>BUGFIX: drawing add-on handles the invisible flag for INSERT correct</li>
<li>PREVIEW: new features to try out, API may change until official release in v0.17</li>
<li>PREVIEW: <code>move_to()</code> command and multi-path support for the <code>ezdxf.path.Path</code> class </li>
<li>PREVIEW: <code>MPOLYGON</code> load/write/create support</li>
<li>PREVIEW: store <em>ezdxf</em> and custom metadata in DXF files, see <a href="https://ezdxf.mozman.at/docs/drawing/management.html#ezdxf-metadata">docs</a></li>
<li>PREVIEW: command <code>ezdxf browse FILE</code>, PyQt DXF structure browser</li>
<li>PREVIEW: command <code>ezdxf strip FILE [FILE ...]</code>, remove comment tags (999) and the
THUMBNAILIMAGE section</li>
</ul>
<h3>Version 0.16.3 - 2021-05-22</h3>
<ul>
<li>NEW: <code>ezdxf.tools.text.MTextEditor</code> class, extracted from the <code>MText</code> class</li>
<li>NEW: <code>MText.set_bg_color()</code>, new argument <code>text_frame</code> to add a text frame</li>
<li>CHANGE: move <code>MText</code> constants to <code>MTextEditor</code> class</li>
<li>CHANGE: move <code>MText.set_font()</code> to <code>MTextEditor.change_font()</code></li>
<li>CHANGE: move <code>MText.set_color()</code> to <code>MTextEditor.change_color()</code></li>
<li>CHANGE: move <code>MText.append_stacked_text()</code> to <code>MTextEditor.stacked_text()</code></li>
<li>BUGFIX: DXF export of GROUP checks for deleted entities</li>
<li>BUGFIX: improved virtual DIMENSION handling</li>
<li>BUGFIX: DIMENSION transformation also transform the content of the
associated anonymous geometry block content</li>
<li>BUGFIX: <code>drawing</code> add-on, true color values always override ACI colors</li>
<li>BUGFIX: <code>drawing</code> add-on, handle SOLID as OCS entity like TRACE</li>
<li>BUGFIX/CHANGE: <code>Vec2/3.__eq__()</code> (<code>==</code> operator) compares
all components with the full floating point precision, use <code>Vec2/3.isclose()</code>
to take floating point imprecision into account.
<strong>This is an annoying but necessary change!</strong></li>
<li>CHANGE: new signature for <code>Vec2/3.isclose(other, *, rel_tol=1e-9, abs_tol=1e-12)</code>,
new argument <code>rel_tol</code>, arguments <code>rel_tol</code> and <code>abs_tol</code> are keyword only</li>
</ul>
<h3>Version 0.16.2 - 2021-04-24</h3>
<ul>
<li>CHANGED: <code>ezdxf.path.add_bezier4p()</code>, add linear Bézier curve segments as LINE_TO commands</li>
<li>CHANGED: <code>ezdxf.path.add_bezier3p()</code>, add linear Bézier curve segments as LINE_TO commands</li>
<li>CHANGED: <code>$FINGERPRINTGUID</code> matches AutoCAD pattern <code>{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}</code></li>
<li>CHANGED: <code>$VERSIONGUID</code> matches AutoCAD pattern <code>{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}</code></li>
<li>BUGFIX: check for degenerated Bézier curves in <code>have_bezier_curves_g1_continuity()</code></li>
<li>BUGFIX: delete and unlink support for DXFTagStorage (unsupported entities)</li>
</ul>
<h3>Version 0.16.1 - 2021-04-10</h3>
<ul>
<li>BUGFIX: <code>disassemble.recursive_decompose()</code> was not recursive </li>
<li>BUGFIX: <code>Frontend</code> font resolver uses XDATA if no regular font file is defined </li>
<li>BUGFIX: version specific group code for header variable <code>$XCLIPFRAME</code> </li>
<li>BUGFIX: <code>INSERT</code> (block reference) transformation </li>
</ul>
<h3>Version 0.16 - 2021-03-27</h3>
<ul>
<li>NEW: <code>ezdxf</code> command line launcher, supported commands:</li>
<li><code>pp</code> the previous <code>dxfpp</code> command, the DXF pretty printer</li>
<li><code>audit</code> DXF files</li>
<li><code>draw</code> and convert DXF files by the Matplotlib backend </li>
<li><code>view</code> DXF files by the PyQt viewer </li>
<li>NEW: <code>text2path</code> add-on to create <code>Path</code> objects from text strings and text
entities, see <a href="https://ezdxf.mozman.at/docs/addons/text2path.html">docs</a></li>
<li>NEW: <code>bbox</code> module to detect the extents (bounding boxes) of DXF entities,
see <a href="https://ezdxf.mozman.at/docs/bbox.html">docs</a></li>
<li>NEW: <code>zoom</code> module to reset the active viewport of layouts,
see <a href="https://ezdxf.mozman.at/docs/zoom.html">docs</a></li>
<li>NEW: <code>path</code> sub-package, an extended version of the previous <code>ezdxf.render.path</code>
module, see <a href="https://ezdxf.mozman.at/docs/path.html">docs</a></li>
<li>NEW: support module <code>disassemble</code>, see <a href="https://ezdxf.mozman.at/docs/disassemble.html">docs</a></li>
<li>deconstruct complex nested DXF entities into a flat sequence</li>
<li>create a "primitive" representation of DXF entities</li>
<li>NEW: Using the optional <code>Matplotlib</code> package by <strong>default</strong> for better font
metric calculation and font rendering if available.</li>
<li>NEW: Cached font metrics are loaded at startup, this can be disabled by the
environment variable <code>EZDXF_AUTO_LOAD_FONTS=False</code>, if this slows down the
interpreter startup too much.</li>
<li>NEW: <code>Layout.reset_extents()</code>, reset layout extents to the given values,
or the AutCAD default values </li>
<li>NEW: <code>Layout.reset_limits()</code>, reset layout limits to the given values,
or the AutCAD default values </li>
<li>NEW: <code>Paperspace.reset_main_viewport()</code>, reset the main viewport of a paper
space layout to custom- or default values </li>
<li>NEW: quadratic Bézier curve support for the <code>Path()</code> class</li>
<li>NEW: <code>ezdxf.entity.Text</code> getter/setter properties <code>is_backward</code> and
<code>is_upside_down</code></li>
<li>NEW: <code>ezdxf.entity.TextStyle</code> getter/setter properties <code>is_backward</code>,
<code>is_upside_down</code> and <code>is_vertical_stacked</code> </li>
<li>NEW: <code>ezdxf.math.Bezier3P</code>, optimized quadratic Bézier curve construction tool </li>
<li>NEW: <code>ezdxf.math.quadratic_to_cubic_bezier()</code>, <code>Bezier3P</code> to <code>Bezier4P</code> converter </li>
<li>NEW: <code>ezdxf.math.bezier_to_bspline()</code>, Bézier curves to B-spline converter</li>
<li>NEW: <code>ezdxf.math.clip_polygon_2d()</code>, clip polygon by a convex clipping polygon </li>
<li>NEW: <code>ezdxf.math.basic_transformation()</code>, returns a combined transformation
matrix for translation, scaling and rotation about the z-axis</li>
<li>NEW: <code>ezdxf.math.best_fit_normal()</code>, returns the normal vector of flat spatial planes</li>
<li>NEW: <code>fit_points_to_cubic_bezier()</code> creates a visual equal SPLINE from fit
points without end tangents like BricsCAD, but only for short B-splines.</li>
<li>CHANGED: <code>fit_points_to_cad_cv()</code>, removed unused arguments <code>degree</code> and <code>method</code> </li>
<li>CHANGED: <code>ezdxf.render.nesting</code> content moved into the <code>ezdxf.path</code> package</li>
<li>CHANGED: renamed <code>MeshBuilder.render()</code> to <code>MeshBuilder.render_mesh()</code></li>
<li>CHANGED: <code>ezdxf.math.BSpline</code> is immutable, all methods return a new <code>BSpline</code> object</li>
<li>CHANGED: replaced <code>BSplineU()</code> class by factory function <code>ezdxf.math.open_uniform_bspline()</code> </li>
<li>CHANGED: replaced <code>BSplineClosed()</code> class by factory function <code>ezdxf.math.closed_uniform_bspline()</code> </li>
<li>CHANGED: renamed <code>rational_spline_from_arc()</code> to <code>rational_bspline_from_arc()</code> </li>
<li>CHANGED: renamed <code>rational_spline_from_ellipse()</code> to <code>rational_bspline_from_ellipse()</code> </li>
<li>BUGFIX: fixed <code>ezdxf.math.rational_bspline_from_ellipse()</code> invalid parameter
conversion </li>
<li>DEPRECATED: <code>ezdxf.render.path</code> module, replaced by <code>ezdxf.path</code> package</li>
<li>DEPRECATED: <code>Path.from_lwpolyline()</code>, replaced by factory <code>path.make_path()</code></li>
<li>DEPRECATED: <code>Path.from_polyline()</code>, replaced by factory <code>path.make_path()</code></li>
<li>DEPRECATED: <code>Path.from_spline()</code>, replaced by factory <code>path.make_path()</code></li>
<li>DEPRECATED: <code>Path.from_ellipse()</code>, replaced by factory <code>path.make_path()</code></li>
<li>DEPRECATED: <code>Path.from_arc()</code>, replaced by factory <code>path.make_path()</code></li>
<li>DEPRECATED: <code>Path.from_circle()</code>, replaced by factory <code>path.make_path()</code></li>
<li>DEPRECATED: <code>Path.add_curve()</code>, replaced by function <code>path.add_bezier4p()</code></li>
<li>DEPRECATED: <code>Path.add_ellipse()</code>, replaced by function <code>path.add_ellipse()</code></li>
<li>DEPRECATED: <code>Path.add_spline()</code>, replaced by function <code>path.add_spline()</code></li>
<li>DEPRECATED: <code>Path.from_vertices()</code>, replaced by factory <code>path.from_vertices()</code></li>
<li>REMOVED: <code>Path.from_hatch_boundary_path()</code>, replaced by factory <code>path.from_hatch()</code></li>
<li>REMOVED: <code>Path.from_hatch_polyline_path()</code></li>
<li>REMOVED: <code>Path.from_hatch_edge_path()</code></li>
<li>REMOVED: <code>BlocksSection.purge()</code>, unsafe operation</li>
<li>REMOVED: <code>dxfpp</code> command, replaced by <code>ezdxf pp ...</code></li>
<li>REMOVED: <code>Layout.add_closed_spline()</code>, broken and nobody noticed it</li>
<li>REMOVED: <code>Layout.add_closed_rational_spline()</code>, broken and nobody noticed it</li>
</ul>Release v0.15.22021-02-07T15:02:00+01:002021-02-07T15:02:00+01:00mozmantag:ezdxf.mozman.at,2021-02-07:/release-v0-15.html<p>Release notes for ezdxf v0.15.2</p><h2>Drawing Add-on</h2>
<h3>Hatch</h3>
<p>Island detection for the HATCH entity is now supported, the example shows the
effect of the HATCH styles <code>NESTED</code>, <code>OUTERMOST</code> and <code>IGNORE</code> (from left to
right), the example script can be found
<a href="https://github.com/mozman/ezdxf/blob/master/examples_dxf/create_hatch_boundary_examples.py">here</a>:</p>
<p><img alt="hatch-islands" src="image/hatch-islands.png"></p>
<p>The HATCH entity also got support for hatch pattern, but this is just an
approximation, because neither matplotlib nor PyQt5 have proper fill pattern
support in the style of a CAD application. </p>
<p>Disabling the hatch pattern support is often the better solution:
Set the <a href="https://ezdxf.mozman.at/docs/addons/drawing.html">backend</a> param
<code>hatch_pattern</code> to <code>0</code> to disable pattern usage, or set it to <code>2</code> to use a
solid fill as replacement for the pattern, or set param <code>show_hatch</code> to <code>0</code> to
disable hatch rendering at all.</p>
<h3>Linetypes</h3>
<p>Support for linetype rendering. The native linetype support by matplotlib and
PyQt5 is fast but not implemented in the way as CAD applications do it. In CAD
applications the linetypes are rendered in real drawing units, this means the
length of lines and gaps is always the same independent of the zoom level.
This is not the case for the matplotlib and the PyQt5 backends, therefore
the <code>drawing</code> add-on provides a custom line renderer, but it's slower than the
native one. The <a href="https://ezdxf.mozman.at/docs/addons/drawing.html">backend</a> param
<code>linetype_renderer</code> controls which line renderer is used, set the param to
<code>"internal"</code> to use the native line rendering of the backend (default), or set
it to <code>"ezdxf"</code> to use the custom line render provided by the add-on. </p>
<p><img alt="linetypes" src="image/linetypes-example.png"></p>
<h3>Fonts</h3>
<p>Font support for TrueType Fonts. SHX fonts have to be substituted by the
according TrueType fonts, but the replacement fonts for the SHX fonts are not
available for free. The best rendering results can be archived by installing an
Autodesk product (TrueView), because this will install the replacement fonts
automatically:</p>
<p><img alt="hatch-islands" src="image/font-example.png"></p>
<p>The current supported SHX fonts, and their replacement TrueType fonts are listed
<a href="https://github.com/mozman/ezdxf/blob/c8a1013e7b79fd61dc1f8cce6c53e8c29ff1937f/src/ezdxf/addons/drawing/properties.py#L34">here</a>.</p>
<h3>Point</h3>
<p>POINT mode support, see the
<a href="https://ezdxf.mozman.at/docs/dxfentities/point.html">docs</a> about the POINT
entity and the various point modes. The DXF format supports only one point mode
for ALL points in a DXF document, because the point mode is defined by the
global header variable <code>$PDMODE</code>. Relative sizing to the viewport is not supported.
Example for POINT mode 66:</p>
<p><img alt="point-mode-66" src="image/point-mode-66.png"></p>
<h3>MLine</h3>
<p>MLINE support, but without line break and fill break features (gaps).</p>
<p><img alt="mline-exampel" src="image/mline-example.png"></p>
<h3>Proxy Graphic</h3>
<p>Proxy graphic support. If no native rendering support for an entity exist, the
proxy graphic will be shown if present (e.g. MLEADER).</p>
<h2>Geo Add-on</h2>
<p>The <code>ezdxf.addons.geo</code> module adds support for the <a href="https://gist.github.com/sgillies/2217756"><code>__geo_interface__</code></a>.
See the <a href="https://ezdxf.mozman.at/docs/addons/geo.html">docs</a> and the
<a href="https://ezdxf.mozman.at/docs/tutorials/geo.html">tutorial</a> for more
information.</p>
<h2>DXF Entities</h2>
<ul>
<li>MLINE support but without line break and fill break (gaps) features.</li>
<li>Adaptive recursive flattening (approximation) for all curved entities.</li>
<li>Common interface <code>wcs_vertices()</code> for SOLID, TRACE and 3DFACE.</li>
<li><code>GeoData.setup_local_grid()</code> setup geo data for CRS similar to EPSG:3395 World
Mercator</li>
<li>HATCH support functions to iterate over all boundary path.</li>
</ul>
<h2>Math Tools</h2>
<ul>
<li><code>Vector()</code> is renamed to <code>Vec3()</code>, but an alias <code>Vector()</code> still exist.</li>
<li>Adaptive recursive flattening (approximation) for all curved entities.</li>
<li>Helper function <code>ezdxf.math.distance_point_line_3d()</code> to calculate the
distance between a 3D vertex and a 3D line.</li>
</ul>
<h2>Cython Optimized Math Objects</h2>
<p>Cython implementations for some math tools and objects:</p>
<ul>
<li>Vec2()</li>
<li>Vec3()</li>
<li>Matrix44()</li>
<li>Bezier4P()</li>
</ul>
<p>This speed up some rendering tasks, but not the loading or writing process.</p>
<h2>Change Log</h2>
<h3>Version 0.15.2 - 2021-02-07</h3>
<ul>
<li>Active Python 3.6 support removed, no tests and no deployment of binary
wheels for Python 3.6</li>
<li>NEW: <code>BoundingBox()</code> intersection test, inside- and outside tests, union of
two bounding boxes.</li>
<li>NEW: <code>ezdxf.math.ellipse_param_span()</code>, works the same way as
<code>arc_angle_span_deg()</code> for special cases</li>
<li>NEW: <code>DXFEntity.uuid</code> property, returns an UUID on demand, which allows
distinguishing even virtual entities without a handle </li>
<li>CHANGE: extraction of many text utility functions into <code>ezdxf.tools.text</code></li>
<li>CHANGE: <code>add_polyline2d()</code>, <code>add_polyline3d()</code>, <code>add_lwpolyline()</code> and
<code>add_mline()</code> got argument <code>close</code> to create a closed polygon and
dxfattrib <code>closed</code> is deprecated, <code>close</code> and <code>dxfattribs</code> for these factories
are keyword only arguments.</li>
<li>CHANGE: improved text alignment rendering in the drawing add-on</li>
<li>CHANGE: moved <code>ezdxf.addons.drawing.fonts.py</code> into <code>ezdxf.tools</code> and added a
font measurement cache. </li>
<li>BUGFIX: <code>FIT</code> and <code>ALIGNED</code> text rendering in the drawing add-on </li>
<li>BUGFIX: matplotlib backend uses linewidth=0 for solid filled polygons and
the scaled linewidth for polygons with pattern filling</li>
<li>BUGFIX: clipping path calculation for IMAGE and WIPEOUT</li>
<li>BUGFIX: transformation of a closed (360deg) arc preserves a closed arc</li>
<li>BUGFIX: bulge values near 0 but != 0 caused an exception in <code>Path.add_2d_polyline()</code></li>
<li>BUGFIX: invalid polygon building in the <code>geo</code> add-on</li>
</ul>
<h3>Version 0.15.1 - 2021-01-15</h3>
<ul>
<li>NEW: <code>Spline.audit()</code> audit support for the SPLINE entity</li>
<li>NEW: The <code>recover</code> module tolerates malformed group codes and value tags.</li>
<li>Changed the <code>Matrix44.matrix</code> attribute in the Python implementation to a
"private" attribute <code>Matrix44._matrix</code>, because this attribute is not
available in the Cython implementation </li>
<li>BUGFIX: proxy graphic decoding error on big-endian systems</li>
<li>BUGFIX: invalid vertex subscript access in <code>dxf2code</code> add-on </li>
<li>BUGFIX: <code>cubic_bezier_from_ellipse()</code> recognizes full ellipses </li>
<li>BUGFIX: <code>cubic_bezier_from_arc()</code> recognizes full circles </li>
<li>BUGFIX: pickle support for C-extensions <code>Vec2</code>, <code>Vec3</code>, <code>Matrix44</code> and
<code>Bezier4P</code></li>
<li>BUGFIX: attribute error when exporting matrices in the MATERIAL entity</li>
</ul>
<h3>Version 0.15.0 - 2020-12-30</h3>
<ul>
<li>NEW: linetype support for matplotlib- and pyqt drawing backend</li>
<li>NEW: HATCH island support for matplotlib- and pyqt drawing backend</li>
<li>NEW: basic HATCH pattern support for matplotlib- and pyqt drawing backend</li>
<li>NEW: Font support for matplotlib- and pyqt drawing backend</li>
<li>NEW: POINT mode support for matplotlib- and pyqt drawing backend, relative
point size is not supported</li>
<li>NEW: Proxy graphic support for the drawing add-on</li>
<li>NEW: recover misplaced tags of the <code>AcDbEntity</code> subclass (color, layer,
linetype, ...), supported by all loading modes</li>
<li>NEW: <code>ezdxf.addons.geo</code> module, support for the
<a href="https://gist.github.com/sgillies/2217756"><code>__geo_interface__</code></a>,
see <a href="https://ezdxf.mozman.at/docs/addons/geo.html">docs</a> and
<a href="https://ezdxf.mozman.at/docs/tutorials/geo.html">tutorial</a></li>
<li>NEW: <code>GeoData.setup_local_grid()</code> setup geo data for CRS similar to EPSG:3395
World Mercator</li>
<li>NEW: MLINE support but without line break and fill break (gaps) features</li>
<li>NEW: <code>Bezier.flattening()</code> adaptive recursive flattening (approximation)</li>
<li>NEW: <code>Bezier4P.flattening()</code> adaptive recursive flattening (approximation)</li>
<li>NEW: <code>Path.flattening()</code> adaptive recursive flattening (approximation)</li>
<li>NEW: <code>Circle.flattening()</code> approximation determined by a max. sagitta value</li>
<li>NEW: <code>Arc.flattening()</code> approximation determined by a max. sagitta value</li>
<li>NEW: <code>ConstructionArc.flattening()</code> approximation determined by a max. sagitta value</li>
<li>NEW: <code>ezdxf.math.distance_point_line_3d()</code></li>
<li>NEW: <code>ConstructionEllipse.flattening()</code> adaptive recursive flattening (approximation)</li>
<li>NEW: <code>Ellipse.flattening()</code> adaptive recursive flattening (approximation)</li>
<li>NEW: <code>BSpline.flattening()</code> adaptive recursive flattening (approximation)</li>
<li>NEW: <code>Spline.flattening()</code> adaptive recursive flattening (approximation)</li>
<li>NEW: <code>matplotlib.qsave()</code>, <code>ltype</code> argument to switch between matplotlib dpi
based linetype rendering and AutoCAD like drawing units based linetype
rendering</li>
<li>NEW: <code>Solid.vertices()</code> returns OCS vertices in correct order (also <code>Trace</code>)</li>
<li>NEW: <code>Solid.wcs_vertices()</code> returns WCS vertices in correct order (also <code>Trace</code>)</li>
<li>NEW: <code>Face3D.wcs_vertices()</code> compatibility interface to SOLID and TRACE</li>
<li>NEW: <code>Hatch.paths.external_paths()</code> returns iterable of external boundary paths</li>
<li>NEW: <code>Hatch.paths.outermost_paths()</code> returns iterable of outer most boundary paths</li>
<li>NEW: <code>Hatch.paths.default_paths()</code> returns iterable of default boundary paths</li>
<li>NEW: <code>Hatch.paths.rendering_paths()</code> returns iterable of paths to process for rendering</li>
<li>NEW: <code>Drawing.units</code> property to get/set document/modelspace units</li>
<li>NEW: <code>ezdxf.new()</code> argument <code>units</code> to setup document and modelspace units and
$MEASUREMENT setting and the linetype setup is based on this $MEASUREMENT
setting.</li>
<li>NEW: <code>pattern.load(measurement, factor)</code> load scaled hatch pattern</li>
<li>NEW: <code>Path.from_hatch_boundary_path()</code></li>
<li>NEW: <code>odafc.export_dwg()</code> new replace option to delete existing DWG files</li>
<li>NEW <code>Style</code> table entry supports extended font data</li>
<li>NEW: <code>Point.virtual_entities()</code>, yield POINT entities as DXF primitives</li>
<li>NEW: <code>ezdxf.render.point</code>, support module for <code>Point.virtual_entities()</code></li>
<li>NEW: Optional Cython implementation of some low level math classes:
Vec2, Vec3, Matrix44, Bezier4P </li>
<li>NEW: support for complex linetypes for the Importer add-on</li>
<li>CHANGE: Optimized infrastructure for loading DXF attributes </li>
<li>CHANGE: <code>Hatch.set_pattern_fill()</code> uses HEADER variable $MEASUREMENT to
determine the default scaling of predefined hatch pattern. </li>
<li>CHANGE: fix invalid linetype setup - new linetype scaling like common CAD
applications</li>
<li>CHANGE: <code>ezdxf.colors</code> module will consolidate all color/transparency related
features</li>
<li>CHANGE: renamed <code>ezdxf.math.Vector</code> to <code>Vec3</code>, but <code>Vector</code> remains as synonym</li>
<li>DEPRECATED: <code>ezdxf.tools.rgb</code> module replaced by <code>ezdxf.colors</code></li>
<li>REMOVED: deprecated <code>DXFEntity.transform_to_wcs()</code> interface,
use <code>DXFEntity.transform(ucs.matrix)</code></li>
<li>REMOVED: deprecated <code>Hatch.edit_boundary()</code> context manager,
use <code>Hatch.paths</code> attribute</li>
<li>REMOVED: deprecated <code>Hatch.get_gradient()</code> method,
use <code>Hatch.gradient</code> attribute</li>
<li>REMOVED: deprecated <code>Hatch.edit_gradient()</code> context manager,
use <code>Hatch.gradient</code> attribute</li>
<li>REMOVED: deprecated <code>Hatch.edit_pattern()</code> context manager,
use <code>Hatch.pattern</code> attribute</li>
<li>REMOVED: deprecated <code>Hatch.get_seed_points()</code> method,
use <code>Hatch.seeds</code> attribute</li>
<li>REMOVED: unnecessary argument <code>non_uniform_scaling</code> from <code>Insert.explode()</code></li>
<li>REMOVED: unnecessary argument <code>non_uniform_scaling</code> from
<code>Insert.virtual_entities()</code></li>
<li>REMOVED: deprecated <code>Spline.edit_data()</code> context manager,
use <code>fit_points</code>, <code>control_points</code>, <code>knots</code> and <code>weights</code> attributes</li>
<li>BUGFIX: <code>ezdxf.math.has_clockwise_orientation()</code> returns <code>True</code> for
counter-clock wise and vice versa</li>
<li>BUGFIX: default color for HATCH is 256 (by layer)</li>
<li>BUGFIX: fixed broken complex linetype setup</li>
<li>BUGFIX: validate loaded handle seed</li>
</ul>Release v0.14.22020-09-19T14:02:00+02:002020-09-19T14:02:00+02:00mozmantag:ezdxf.mozman.at,2020-09-19:/release-v0-14.html<p>Release notes for ezdxf v0.14.2</p><h2>Recover Module</h2>
<p>The indention of the recover module is to provide a more stable and reliable
DXF loading function. This is required because the DXF reference is often not
precise about valid data ranges or does not show the correct usage of DXF
attributes and structures and therefore exist many DXF files with structural
flaws.</p>
<p>The <code>recover.read()</code> and <code>recover.readfile()</code> functions will repair as much
flaws as possible and run the required audit process automatically
afterwards and return the result of this audit process:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="kn">from</span> <span class="nn">ezdxf</span> <span class="kn">import</span> <span class="n">recover</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">doc</span><span class="p">,</span> <span class="n">auditor</span> <span class="o">=</span> <span class="n">recover</span><span class="o">.</span><span class="n">readfile</span><span class="p">(</span><span class="s2">"messy.dxf"</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'Not a DXF file or a generic I/O error.'</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="k">except</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">DXFStructureError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'Invalid or corrupted DXF file.'</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="k">if</span> <span class="n">auditor</span><span class="o">.</span><span class="n">has_errors</span><span class="p">:</span>
<span class="n">auditor</span><span class="o">.</span><span class="n">print_error_report</span><span class="p">()</span>
</code></pre></div>
<p>A recovered DXF file can still have unrecoverable errors, but this is
just a problem when saving the recovered DXF file.</p>
<p>This extra work requires additional efforts and longer loading times,
to avoid this penalty for DXF files from trusted sources like AutoCAD or
BricsCAD, the current loading function <code>ezdxf.readfile()</code> remains as it was,
except the <code>legacy_mode</code> argument was removed to force usage of the <code>recover</code>
module.</p>
<h2>Drawing Add-on</h2>
<p>Support for the start- and end width attributes of LWPOLYLINE and 2D POLYLINE
vertices to draw banded 2D lines.</p>
<p><img alt="Controller-M128-top" src="image/Controller-M128-top.png"></p>
<p>A simple <code>qsave()</code> function to export renderings of DXF layouts as raster- or
vector graphic by <code>matplotlib</code>:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="kn">from</span> <span class="nn">ezdxf.addons.drawing</span> <span class="kn">import</span> <span class="n">matplotlib</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">readfile</span><span class="p">(</span><span class="s1">'your.dxf'</span><span class="p">)</span>
<span class="n">matplotlib</span><span class="o">.</span><span class="n">qsave</span><span class="p">(</span><span class="n">doc</span><span class="o">.</span><span class="n">modelspace</span><span class="p">(),</span> <span class="s1">'your.png'</span><span class="p">)</span>
</code></pre></div>
<p>Further Improvements:</p>
<ul>
<li>Support for the LEADER, WIPEOUT and the MINSERT entity.</li>
<li>Support for stored entity reordering.</li>
<li>The <code>matplotlib</code> back-end got line-weight (width) support.</li>
<li>Using the <code>Path()</code> tool as basic rendering tool.</li>
</ul>
<h2>DXF Entities</h2>
<ul>
<li><code>Arc()</code> got support for using <code>ConstructionArc()</code> as construction tool.</li>
<li><code>Leader()</code> got methods <code>virtual_entities()</code> and <code>explode()</code> as render support
tools.</li>
<li>New <code>LWPolyline.has_width</code> property is <code>True</code> if any width attribute is set.</li>
<li>New <code>Polyline.has_width</code> property is <code>True</code> if any width attribute is set.</li>
<li>New <code>Polyline.audit()</code> for extended verify and repair support.</li>
<li><code>Insert.explode()</code> got support for MINSERT (multi insert).</li>
<li><code>Insert.virtual_entities()</code> got support for MINSERT (multi insert).</li>
<li>New <code>Insert.mcount</code> property returns multi insert count.</li>
<li>New <code>Insert.multi_insert()</code> yields a virtual INSERT entity for each grid
element of a MINSERT entity.</li>
<li>New <code>Polyline.append_formatted_vertices()</code> with support for user defined
point format like LWPOLYLINE.</li>
<li>New <code>DXFVertex.format()</code> method to support user defined point format like
LWPOLYLINE.</li>
<li>New <code>Image.boundary_path_wcs()</code> method returns the clipping boundary path in
WCS coordinates.</li>
<li>New <code>Wipeout.boundary_path_wcs()</code> method returns the clipping boundary path
in WCS coordinates.</li>
<li>New <code>Wipeout.set_masking_area()</code> method set the masking area (clipping
boundary path) from WCS coordinates.</li>
<li>New <code>Layout.add_wipeout()</code> factory function to create WIPEOUT entities.</li>
<li>New <code>DXFEntity.new_extension_dict()</code> to create explicit a new extension
dictionary.</li>
</ul>
<h2>Render Tools</h2>
<p><code>TraceBuilder()</code> class to create banded 2D lines and curves by quadrilaterals,
see <a href="https://ezdxf.mozman.at/docs/render/trace.html">docs</a>.</p>
<p><code>Path()</code> class to create complex paths only by lines and cubic Bèzier curves.
Supports splines, circular- and elliptic arcs as path elements all approximated
by cubic Bèzier curves, see <a href="https://ezdxf.mozman.at/docs/render/path.html">docs</a>.</p>
<h2>Reorder Module</h2>
<p>Tools to reorder DXF entities by handle or a special sort handle mapping,
see <a href="https://ezdxf.mozman.at/docs/reorder.html">docs</a>.</p>
<h2>Math Tools</h2>
<ul>
<li>The new <code>BSpline.is_clamped</code> property is <code>True</code> for a clamped (open) B-spline.</li>
<li><code>Bezier()</code> and <code>Bezier4p()</code> classes got methods to revers and transform curves.</li>
<li><code>arc_segment_count()</code> tool function to calculate the required segment count for
an arc approximation defined by a maximum sagitta value.</li>
<li><code>UCS()</code> got a <code>transform()</code> method as general transformation interface.</li>
</ul>
<h2>Unicode Handling</h2>
<p>New <code>errors</code> argument for all DXF loading functions like <code>ezdxf.readfile()</code>
to support different methods for unicode error handling:</p>
<ul>
<li>"surrogateescape" to preserve possible binary data (default)</li>
<li>"ignore" to use the replacement char U+FFFD "�" for invalid data</li>
<li>"strict" to raise an <code>UnicodeDecodeError()</code> exception for invalid data</li>
</ul>
<p>The <code>ezdxf.has_dxf_unicode(s)</code> and <code>ezdxf.decode_dxf_unicode(s)</code> are new support
functions to decode unicode characters "\U+xxxx" manually,
see <a href="https://ezdxf.mozman.at/docs/tools.html">docs</a>.</p>
<p>The decoding of unicode characters "\U+xxxx" is not done automatically by the
regular loading functions like <code>ezdxf.readfile()</code> to avoid a speed penalty,
only the <code>recover</code> module does the decoding automatically, because this loading
mode is already slow.</p>
<p>This kind of encoding is most likely used only in older DXF versions, because
since DXF R2007 the whole DXF file is encoded in <code>utf8</code> and a special unicode
encoding is not necessary.</p>
<p>New <code>Drawing.encode(s)</code> function to encode unicode strings with correct encoding
and error handler.</p>
<h2>Change Log</h2>
<h3>Version 0.14.2 - 2020-10-18</h3>
<ul>
<li>BUGFIX: fix invalid attribute reference <code>self.drawing</code></li>
</ul>
<h3>Version 0.14.1 - 2020-09-19</h3>
<ul>
<li>BUGFIX: MLEADER and MLEADERSTYLE min DXF version changed to R2000</li>
<li>BUGFIX: AutoCAD ignores not existing default objects in ACDBDICTIONARYWDFLT
and so ezdxf have to. <code>Auditor()</code> creates a place holder object as default
value.</li>
</ul>
<h3>Version 0.14.0 - 2020-09-12</h3>
<ul>
<li>NEW: DXF attribute setter validation, some special and undocumented Autodesk
table names may raise <code>ValueError()</code> exceptions, please report this table
names (layers, linetypes, styles, ...). DXF unicode notation "\U+xxxx" raises
a <code>ValueError()</code> if used as resource names like layer name or text style names,
such files can only be loaded by the new <code>recover</code> module.</li>
<li>NEW: <code>ezdxf.recover</code> module to load DXF Documents with structural flaws, see
<a href="https://ezdxf.mozman.at/docs/drawing/recover.html">docs</a></li>
<li>NEW: All DXF loading functions accept an unicode decoding error handler:
"surrogateescape", "ignore" or "strict", see <a href="https://ezdxf.mozman.at/docs/drawing/recover.html">docs</a>
of the <code>recover</code> module for more information.</li>
<li>NEW: <code>addons.drawing.Frontend()</code> supports width attributes of LWPOLYLINE and
2D POLYLINE entities</li>
<li>NEW: <code>TraceBuilder()</code> a render tool to generate quadrilaterals (TRACE, SOLID
or 3DFACE), from LWPOLYLINE or 2D POLYLINE with width information,
see <a href="https://ezdxf.mozman.at/docs/render/trace.html">docs</a></li>
<li>NEW: <code>Path()</code> a render tool for paths build of lines and cubic Bèzier curves,
used for faster rendering of LWPOLYLINE, POLYLINE and SPLINE entities for
render back-ends, see <a href="https://ezdxf.mozman.at/docs/render/path.html">docs</a></li>
<li>NEW: <code>drawing.matplotlib.qsave()</code> function, a simplified matplotlib export interface</li>
<li>NEW: <code>Arc.construction_tool()</code> returns the 2D <code>ConstructionArc()</code></li>
<li>NEW: <code>Arc.apply_construction_tool()</code> apply parameters from <code>ConstructionArc()</code></li>
<li>NEW: <code>Leader.virtual_entities()</code> yields 'virtual' DXF primitives</li>
<li>NEW: <code>Leader.explode()</code> explode LEADER as DXF primitives into target layout</li>
<li>NEW: <code>LWPolyline.has_width</code> property is <code>True</code> if any width attribute is set</li>
<li>NEW: <code>Polyline.has_width</code> property is <code>True</code> if any width attribute is set</li>
<li>NEW: <code>Polyline.audit()</code> extended verify and repair support</li>
<li>NEW: <code>Polyline.append_formatted_vertices()</code>, support for user defined point format</li>
<li>NEW: <code>DXFVertex.format()</code> support for user defined point format </li>
<li>NEW: <code>Drawing.blocks.purge()</code> delete all unused blocks but protect modelspace-
and paperspace layouts, special arrow blocks and DIMENSION and ACAD_TABLE
blocks in use, but see also warning in the
<a href="https://ezdxf.mozman.at/docs/sections/blocks.html">docs</a></li>
<li>NEW: <code>Insert.explode()</code> support for MINSERT (multi insert)</li>
<li>NEW: <code>Insert.virtual_entities()</code> support for MINSERT (multi insert)</li>
<li>NEW: <code>Insert.mcount</code> property returns multi insert count</li>
<li>NEW: <code>Insert.multi_insert()</code> yields a virtual INSERT entity for each grid
element of a MINSERT entity</li>
<li>NEW: <code>Layout.add_wipeout()</code> interface to create WIPEOUT entities</li>
<li>NEW: <code>Image.boundary_path_wcs()</code>, returns boundary path in WCS coordinates</li>
<li>NEW: <code>Wipeout.boundary_path_wcs()</code>, returns boundary path in WCS coordinates</li>
<li>NEW: <code>Wipeout.set_masking_area()</code></li>
<li>NEW: <code>BSpline.is_clamped</code> property is <code>True</code> for a clamped (open) B-spline</li>
<li>NEW: <code>UCS.transform()</code> general transformation interface</li>
<li>NEW: <code>Bezier4P.transform()</code> general transformation interface</li>
<li>NEW: <code>Bezier4P.reverse()</code> returns object with reversed control point order</li>
<li>NEW: <code>Bezier.transform()</code> general transformation interface</li>
<li>NEW: <code>Bezier.reverse()</code> returns object with reversed control point order</li>
<li>NEW: <code>has_clockwise_orientation(vertices)</code> returns <code>True</code> if the closed
polygon of 2D vertices has clockwise orientation</li>
<li>NEW: <code>DXFEntity.new_extension_dict()</code>, create explicit a new extension dictionary</li>
<li>NEW: <code>ezdxf.reorder</code>, support module to implement modified entities redraw order</li>
<li>NEW: get DXF test file path from environment variable <code>EZDXF_TEST_FILES</code>,
imported automatically as <code>ezdxf.EZDXF_TEST_FILES</code></li>
<li>NEW: <code>arc_chord_length()</code> and <code>arc_segment_count()</code> tool functions in
<code>ezdxf.math</code></li>
<li>NEW: <code>Drawing.encode()</code> to encode unicode strings with correct encoding and
error handler</li>
<li>NEW: <code>ezdxf.has_dxf_unicode()</code> to detect "\U+xxxx" encoded chars</li>
<li>NEW: <code>ezdxf.decode_dxf_unicode()</code> to decode strings containing<br>
"\U+xxxx" encoded chars, the new <code>recover</code> module decodes such strings
automatically.</li>
<li>CHANGE: <code>DXFEntity.get_extension_dict()</code>, raises <code>AttributeError</code> if entity
has no extension dictionary </li>
<li>CHANGE: <code>DXFEntity.has_extension_dict</code> is now a property not a method</li>
<li>CHANGE: <code>linspace()</code> uses <code>Decimal()</code> for precise calculations, but still
returns an iterable of <code>float</code></li>
<li>CHANGE: <code>Drawing.blocks.delete_all_blocks()</code>, unsafe mode is disabled and
argument <code>safe</code> is deprecated, will be removed in v0.16</li>
<li>CHANGE: Dictionary raise <code>DXFValueError</code> for adding invalid handles</li>
<li>CHANGE: <code>BaseLayout.add_entity()</code> will bind entity automatically to doc/db if possible</li>
<li>CHANGE: handle all layout names as case insensitive strings: <code>Model == MODEL</code></li>
<li>REMOVE: <code>option.check_entity_tag_structure</code>, entity check is done only in
recover mode</li>
<li>REMOVE: <code>legacy_mode</code> in <code>ezdxf.read()</code> and <code>ezdxf.readfile()</code>, use the
<code>ezdxf.recover</code> module to load DXF Documents with structural flaws</li>
<li>REMOVE: Alias <code>DXFEntity.drawing</code> use <code>DXFEntity.doc</code></li>
<li>REMOVE: <code>DXFEntity.entitydb</code></li>
<li>REMOVE: <code>DXFEntity.dxffactory</code></li>
<li>REMOVE: <code>DXFInvalidLayerName</code>, replaced by <code>DXFValueError</code> </li>
<li>REMOVE: <code>Image.get_boundary_path()</code>, replaced by property <code>Image.boundary_path</code> </li>
<li>REMOVE: <code>Image.get_image_def()</code>, replaced by property <code>Image.image_def</code> </li>
<li>REMOVE: <code>filter_stack</code> argument in <code>ezdxf.read()</code> and <code>ezdxf.readfile()</code> </li>
<li>BUGFIX: Set <code>non-constant-attribs</code> flag (2) in BLOCK at DXF export if non
constant ATTDEF entities are present.</li>
<li>BUGFIX: DXF R2018 - <code>HATCH</code> extrusion vector (210) is mandatory?</li>
<li>BUGFIX: Layout names are case insensitive; "MODEL" == "Model" </li>
<li>BUGFIX: Using "surrogateescape" error handler to preserve binary data in
ASCII DXF files. Prior versions of ezdxf corrupted this data by using the
"ignore" error handler; Example file with binary data in XRECORD is not valid
for TrueView 2020 - so binary data is maybe not allowed.</li>
</ul>Release v0.13.12020-07-18T13:01:00+02:002020-07-18T13:01:00+02:00mozmantag:ezdxf.mozman.at,2020-07-18:/release-v0-13.html<p>Release notes for ezdxf v0.13.1</p><h2>General Transformation Interface</h2>
<p>New general transformation interface based on homogeneous transformation matrices.
Supported transformations are scale & reflection, rotate and translate. </p>
<p>Transformation works best for entities with WCS vertices only like POINT, LINE or MESH. Uniform scale transformation
works well for OCS entities like TEXT or INSERT.
Problems exist for non uniform scaling and reflections for OCS entities including text or curves, especially the
HATCH entity with arc- or ellipse edge paths, but ARC and ELLIPSE entities itself should work as expected.</p>
<p>Good support for:</p>
<ul>
<li>POINT</li>
<li>LINE</li>
<li>ELLIPSE</li>
<li>MESH</li>
<li>SPLINE</li>
<li>3D POLYLINE, POLYMESH & POLYFACE</li>
<li>SOLID</li>
<li>TRACE</li>
<li>3DFACE</li>
<li>XLINE</li>
<li>RAY</li>
<li>IMAGE</li>
</ul>
<p>Problems with non uniform scaling and/or reflections:</p>
<ul>
<li>CIRCLE, must be converted to ELLIPSE for non uniform scaling</li>
<li>ARC, must be converted to ELLIPSE for non uniform scaling</li>
<li>LWPOLYLINE, must be exploded for non uniform scaling if has arcs; ARC converted to ELLIPSE</li>
<li>2D POLYLINE, must be exploded for non uniform scaling if has arcs; ARC converted to ELLIPSE</li>
<li>HATCH with arc edges or bulges in polyline paths, have to be converted into ellipse edges for non uniform scaling </li>
<li>INSERT: DXF attributes can only represent orthogonal target coordinate systems</li>
<li>TEXT, ATTRIB, ATTDEF, MTEXT, SHAPE: transformations are limited by available DXF attributes</li>
</ul>
<p>Untested:</p>
<ul>
<li>HELIX</li>
<li>LIGHT</li>
<li>LEADER</li>
<li>TOLERANCE</li>
<li>DIMENSION</li>
</ul>
<p>Unsupported:</p>
<ul>
<li>ACAD_TABLE, MLEADER, MLINE: just preserved entity types</li>
<li>ACIS entities like 3DSOLID, BODY or REGION (no access to geometry data)</li>
<li>Proxy entities (unknown data)</li>
<li>External references</li>
<li>Underlays</li>
<li>VIEWPORT</li>
</ul>
<p>This new transformation interface also improves results for non uniform scaling for <code>Insert.virtual_entities()</code>
and <code>Insert.explode()</code>, therefore the argument <code>non_uniform_scaling</code> to explicit enable non uniform scaling is
marked as deprecated. </p>
<p>Example: rotate first line in <code>"my.dxf"</code> 90 degrees about the z-axis</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">math</span>
<span class="kn">import</span> <span class="nn">ezdxf</span>
<span class="kn">from</span> <span class="nn">ezdxf.math</span> <span class="kn">import</span> <span class="n">Matrix44</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">readfile</span><span class="p">(</span><span class="s1">'my.dxf'</span><span class="p">)</span>
<span class="n">msp</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">modelspace</span><span class="p">()</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">msp</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s1">'LINE'</span><span class="p">)</span><span class="o">.</span><span class="n">first</span>
<span class="k">if</span> <span class="n">line</span><span class="p">:</span>
<span class="n">m</span> <span class="o">=</span> <span class="n">Matrix44</span><span class="o">.</span><span class="n">z_rotate</span><span class="p">(</span><span class="n">math</span><span class="o">.</span><span class="n">pi</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span>
<span class="n">line</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
</code></pre></div>
<p>Specialized entity transformation interfaces:</p>
<ul>
<li><code>translate(dx, dy, dz)</code>, translation in x-, y- and z-axis</li>
<li><code>scale(sx, sy, sz)</code>, use negative values for reflections</li>
<li><code>scale_uniform(s)</code>, uniform scaling in x-, y- and z-axis</li>
<li><code>rotate_axis(axis, angle)</code>, rotate about arbitrary axis, rotation center is the origin at (0, 0, 0)</li>
<li><code>rotate_x(angle)</code>, rotation about the x-axis</li>
<li><code>rotate_y(angle)</code>, rotation about the y-axis</li>
<li><code>rotate_z(angle)</code>, rotation about the z-axis</li>
</ul>
<p>Simplified example:</p>
<div class="highlight"><pre><span></span><code><span class="o">...</span>
<span class="k">if</span> <span class="n">line</span><span class="p">:</span>
<span class="n">line</span><span class="o">.</span><span class="n">rotate_z</span><span class="p">(</span><span class="n">math</span><span class="o">.</span><span class="n">pi</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span>
</code></pre></div>
<h2>Drawing Add-on</h2>
<p>The new <a href="https://ezdxf.mozman.at/docs/addons/draw.html">drawing</a> add-on by Matt Broadway is a translation
layer to send DXF data to a render backend.</p>
<p>Basic supported for following backends are included:</p>
<ul>
<li><a href="https://pypi.org/project/matplotlib/">matplotlib</a></li>
<li><a href="https://pypi.org/project/PyQt5/">PyQt5</a></li>
</ul>
<p>Both packages are optional and <strong>not required</strong> to install <em>ezdxf</em>. </p>
<p>The implementation uses a <code>Frontend</code> object to break DXF entities down into graphic primitives and send this data to
the <code>Backend</code> object. Not all DXF entities are supported yet and embedded ACIS data like in BODY, 3DSOLID or REGION
will never be supported. Some of these missing DXF entities may get support in the future
(LEADER, MLEADER, ACAD_TABLE). Support of start- and end width attributes for 2D polylines is also planned. </p>
<p>There are two example scripts to show how to use the <code>drawing</code> add-on to implement a DXF converter or DXF viewer.</p>
<ul>
<li><a href="https://github.com/mozman/ezdxf/blob/master/examples/addons/drawing/draw_cad.py">draw_cad.py</a> uses matplotlib
as backend to convert DXF documents into pixel- or vector graphic. </li>
<li><a href="https://github.com/mozman/ezdxf/blob/master/examples/addons/drawing/cad_viewer.py">cad_viewer.py</a> is a DXF viewer,
using PyQt5 as backend.</li>
</ul>
<p>Both are basic implementations without support for lineweights, linetypes, hatch pattern or multiple fonts and
3D objects are rendered flat into the xy-plane in wire-frame style. Additional features are planned, but don't
expect a <a href="https://www.autodesk.com/products/dwg/viewers">TrueView</a> replacement, this is beyond our capabilities,
time resources and the performance of a Python based project.</p>
<p><img alt="Example 1" src="image/cad_view_1.png"></p>
<p><img alt="Example 2" src="image/cad_view_2.png"></p>
<p><img alt="Example 3" src="image/cad_view_3.png"></p>
<h2>Entity Converter</h2>
<p>Convert CIRCLE and ARC to ELLIPSE entities by default the source ARC will be replaced by the new ELLIPSE entity:</p>
<div class="highlight"><pre><span></span><code><span class="k">for</span> <span class="n">arc</span> <span class="ow">in</span> <span class="n">msp</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s1">'ARC'</span><span class="p">):</span>
<span class="n">arc</span><span class="o">.</span><span class="n">to_ellipse</span><span class="p">()</span>
</code></pre></div>
<p>Set argument <code>replace</code> to <code>False</code> to add an additional ELLIPSE entity without deleting the source ARC:</p>
<div class="highlight"><pre><span></span><code><span class="k">for</span> <span class="n">arc</span> <span class="ow">in</span> <span class="n">msp</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s1">'ARC'</span><span class="p">):</span>
<span class="n">arc</span><span class="o">.</span><span class="n">to_ellipse</span><span class="p">(</span><span class="n">replace</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</code></pre></div>
<p>Convert CIRCLE, ARC and ELLIPSE to SPLINE entities:</p>
<div class="highlight"><pre><span></span><code><span class="k">for</span> <span class="n">arc</span> <span class="ow">in</span> <span class="n">msp</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s1">'ARC'</span><span class="p">):</span>
<span class="n">arc</span><span class="o">.</span><span class="n">to_spline</span><span class="p">()</span>
</code></pre></div>
<p>The SPLINE entities have the best approximation with a minimum number of control points.</p>
<p><img alt="SPLINE from ARC" src="image/splines_from_arc.png"></p>
<h2>Math Tools</h2>
<p>Constructors to create rational splines from arc (<code>BSpline.from_arc()</code>) and ellipses (<code>BSpline.from_ellipse()</code>).</p>
<p>Decomposition of non-rational B-splines into multiple Bezier curves by <code>BSpline.bezier_decomposition()</code> to
feed B-splines into render engines with Bezier curve support. Works best with non-rational B-splines of 3rd degree,
perhaps the the most common used B-spline, yielding cubic bezier curves, which are supported by many render engines.</p>
<p>Interface between the SPLINE DXF entity class and the construction tool <code>BSpline()</code>, <code>Spline.construction_tool()</code>
returns the spline as <code>BSpline()</code> object and <code>Spline.apply_construction_tool()</code> transfer data from the <code>BSpline()</code> to
the DXF entity. The same interface exist for the ELLIPSE entity and the <code>ConstructionEllipse()</code> class.</p>
<p>Interface to <a href="https://github.com/orbingol/NURBS-Python">NURBS-Python</a> to convert <code>BSpline()</code> objects to
NURBS-Python curves by <code>BSpline.to_nurbs_python_curve()</code> and back by <code>BSpline.from_nurbs_python_curve()</code>. This
requires the installation of the <code>geomdl</code> package which is the PyPI name of NURBS-Python:</p>
<div class="highlight"><pre><span></span><code><span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>--user<span class="w"> </span>geomdl
</code></pre></div>
<p>An interface to surfaces and volumes may follow, but only from NURBS-Python to <em>ezdxf</em>, because
without ACIS support, <em>ezdxf</em> is restricted to mesh objects.</p>
<p>Rewritten spline interpolation without and with end derivative (tangents) support as function
<code>global_spline_interpolation()</code> including helper tools to estimate tangents and end tangent magnitudes.
A new <code>local_bspline_interpolation()</code> function and a fast <code>cubic_bezier_interpolation()</code> function also exist.</p>
<p>A faster linear equation solver for interpolation tasks was required: the new <code>LUDecomposition()</code> is faster than the
previous <code>gauss_*_solver()</code> functions and a new banded diagonal matrix solver <code>BandedMatrixLU()</code> for even faster
results for bigger matrices was added, <code>compact_banded_matrix()</code> is a helper function to create banded diagonal
matrices and <code>detect_banded_matrix()</code> is its sidekick to auto-detect the required parameters.</p>
<p>Integrated derivative computation into <code>BSpline()</code> and <code>Bezier()</code> from special derivative classes. Instead of
overriding the <code>point()</code> method, a new <code>derivative()</code> method exists which returns the curve point and derivatives.</p>
<p>Most of this new math tools are based on two books:</p>
<ol>
<li>B-Splines: "The NURBS Book" by Piegl and Tiller</li>
<li>Linear Equation Solver: "Numerical Receipes" by Press, Teukolsky, Vetterling and Flannery</li>
</ol>
<h2>Change Log</h2>
<h3>Version 0.13.1 - 2020-07-18</h3>
<ul>
<li>BUGFIX: remove white space from structure tags like "SECTION "</li>
<li>BUGFIX: <code>MeshBuilder.from_polyface()</code> processing error of POLYMESH entities</li>
</ul>
<h3>Version 0.13 - 2020-07-04</h3>
<ul>
<li>NEW: general transformation interface: <code>DXFGraphic.transform(m)</code>,
transform entity by a transformation matrix <code>m</code> inplace</li>
<li>NEW: specialized entity transformation interfaces:<ul>
<li><code>DXFGraphic.translate(dx, dy, dz)</code></li>
<li><code>DXFGraphic.scale(sx, sy, sz)</code></li>
<li><code>DXFGraphic.scale_uniform(s)</code></li>
<li><code>DXFGraphic.rotate_axis(axis, angle)</code></li>
<li><code>DXFGraphic.rotate_x(angle)</code></li>
<li><code>DXFGraphic.rotate_y(angle)</code></li>
<li><code>DXFGraphic.rotate_z(angle)</code></li>
</ul>
</li>
<li>NEW: <a href="https://ezdxf.mozman.at/docs/addons/draw.html">drawing</a> add-on by Matt Broadway is a translation
layer to send DXF data to a render backend, supported backends for now:
<a href="https://pypi.org/project/matplotlib/">matplotlib</a> and <a href="https://pypi.org/project/PyQt5/">PyQt5</a>, both packages
are optional and not required to install <em>ezdxf</em>. </li>
<li>NEW: <code>DXFGraphic.unlink_from_layout()</code> to unlink entity from associated layout</li>
<li>NEW: <code>Arc.angles(num)</code>, yields <code>num</code> angles from start- to end angle in counter clockwise order</li>
<li>NEW: <code>Circle.to_ellipse()</code>, convert CIRCLE/ARC to ELLIPSE entity</li>
<li>NEW: <code>Circle.to_spline()</code>, convert CIRCLE/ARC to SPLINE entity</li>
<li>NEW: <code>Ellipse.params(num)</code>, yields <code>num</code> params from start- to end param in counter clockwise order</li>
<li>NEW: <code>Ellipse.construction_tool()</code>, return ellipse data as <code>ConstructionEllipse()</code></li>
<li>NEW: <code>Ellipse.apply_construction_tool()</code>, apply <code>ConstructionEllipse()</code> data</li>
<li>NEW: <code>Ellipse.to_spline()</code>, convert ELLIPSE to SPLINE entity </li>
<li>NEW: <code>Ellipse.from_arc()</code>, create a new ELLIPSE entity from CIRCLE or ARC entity (constructor)</li>
<li>NEW: <code>Spline.construction_tool()</code>, return spline data as <code>ezdxf.math.BSpline()</code></li>
<li>NEW: <code>Spline.apply_construction_tool()</code>, apply <code>ezdxf.math.BSpline()</code> data</li>
<li>NEW: <code>Spline.from_arc()</code>, create a new SPLINE entity from CIRCLE, ARC or ELLIPSE entity (constructor)</li>
<li>NEW: <code>Hatch.set_pattern_scale()</code> to set scaling of pattern definition</li>
<li>NEW: <code>Hatch.set_pattern_angle()</code> to set rotation angle of pattern definition</li>
<li>NEW: <code>Hatch.paths.polyline_to_edge_path()</code> convert polyline paths with bulge values to edge paths with lines and arcs</li>
<li>NEW: <code>Hatch.paths.arc_edges_to_ellipse_edges()</code> convert arc edges to ellipse edges</li>
<li>NEW: <code>Hatch.paths.ellipse_edges_to_spline_edges()</code> convert ellipse edges to spline edges</li>
<li>NEW: <code>Hatch.paths.all_to_spline_edges()</code> convert all curves to approximated spline edges</li>
<li>NEW: <code>Hatch.paths.all_to_line_edges()</code> convert all curves to approximated line edges</li>
<li>NEW: <code>Text.plain_text()</code> returns text content without formatting codes</li>
<li>NEW: <code>ezdxf.math.ConstructionEllipse()</code></li>
<li>NEW: <code>ezdxf.math.linspace()</code> like <code>numpy.linspace()</code></li>
<li>NEW: <code>ezdxf.math.global_bspline_interpolation()</code> supports start- and end tangent constraints</li>
<li>NEW: <code>ezdxf.math.estimate_tangents()</code> curve tangent estimator for given fit points</li>
<li>NEW: <code>ezdxf.math.estimate_end_tangent_magnitude()</code> curve end tangent magnitude estimator for given fit points</li>
<li>NEW: <code>ezdxf.math.rational_spline_from_arc()</code> returns a rational B-spline for a circular arc</li>
<li>NEW: <code>ezdxf.math.rational_spline_from_ellipse()</code> returns a rational B-spline for an elliptic arc</li>
<li>NEW: <code>ezdxf.math.local_cubic_bspline_interpolation()</code></li>
<li>NEW: <code>ezdxf.math.cubic_bezier_from_arc()</code> returns an approximation for a circular 2D arc by multiple cubic Bezier curves</li>
<li>NEW: <code>ezdxf.math.cubic_bezier_from_ellipse()</code> returns an approximation for an elliptic arc by multiple cubic Bezier curves</li>
<li>NEW: <code>ezdxf.math.cubic_bezier_interpolation()</code> returns an interpolation curve for arbitrary data points as multiple cubic Bezier curves</li>
<li>NEW: <code>ezdxf.math.LUDecomposition</code> linear equation solver, for more linear algebra tools see module <code>ezdxf.math.linalg</code></li>
<li>NEW: <code>ezdxf.render.random_2d_path()</code> generate random 2D path for testing purpose</li>
<li>NEW: <code>ezdxf.render.random_3d_path()</code> generate random 3D path for testing purpose</li>
<li>NEW: <code>BSpline()</code> uses normalized knot vector for 'clamped' curves by default (open uniform knots)</li>
<li>NEW: <code>BSpline.points()</code> compute multiple points</li>
<li>NEW: <code>BSpline.derivative()</code> compute point and derivative up to n <= degree</li>
<li>NEW: <code>BSpline.derivatives()</code> compute multiple points and derivatives up to n <= degree</li>
<li>NEW: <code>BSpline.params()</code> return evenly spaced B-spline params from start- to end param</li>
<li>NEW: <code>BSpline.reverse()</code> returns a new reversed B-spline</li>
<li>NEW: <code>BSpline.from_arc()</code> B-spline from an arc, best approximation with a minimum number of control points</li>
<li>NEW: <code>BSpline.from_ellipse()</code> B-spline from an ellipse, best approximation with a minimum number of control points</li>
<li>NEW: <code>BSpline.from_fit_points()</code> B-spline from fit points </li>
<li>NEW: <code>BSpline.arc_approximation()</code> B-spline approximation from arc vertices as fit points</li>
<li>NEW: <code>BSpline.ellipse_approximation()</code> B-spline approximation from ellipse vertices as fit points</li>
<li>NEW: <code>BSpline.transform()</code> transform B-spline by transformation matrix inplace</li>
<li>NEW: <code>BSpline.transform()</code> transform B-spline by transformation matrix inplace</li>
<li>NEW: <code>BSpline.to_nurbs_python_curve()</code> and <code>BSpline.from_nurbs_python_curve()</code>, interface to
<a href="https://github.com/orbingol/NURBS-Python">NURBS-Python</a>, <code>NURBS-Python</code> is now a testing dependency</li>
<li>NEW: <code>BSpline.bezier_decomposition()</code> decompose a non-rational B-spline into multiple Bezier curves </li>
<li>NEW: <code>BSpline.cubic_bezier_approximation()</code> approximate any B-spline by multiple cubic Bezier curves </li>
<li>NEW: <code>Bezier.points()</code> compute multiple points</li>
<li>NEW: <code>Bezier.derivative()</code> compute point, 1st and 2nd derivative for one parameter</li>
<li>NEW: <code>Bezier.derivatives()</code> compute point and derivative for multiple parameters</li>
<li>CHANGE: <code>Hatch</code> full support for rotated patterns.</li>
<li>CHANGE: <code>Hatch.set_pattern_definition()</code> added argument <code>angle</code> for pattern rotation. </li>
<li>CHANGE: <code>Hatch.path.add_arc</code> renamed argument <code>is_counter_clockwise</code> to <code>ccw</code>, type <code>bool</code> and <code>True</code> by default </li>
<li>CHANGE: <code>Hatch.path.add_ellipse</code> renamed argument <code>is_counter_clockwise</code> to <code>ccw</code>, type <code>bool</code> and <code>True</code> by default </li>
<li>CHANGE: renamed 2D <code>ConstructionXXX.move()</code> methods to <code>translate()</code></li>
<li>CHANGE: renamed old <code>Insert.scale()</code> to <code>Insert.set_scale()</code>, name conflict with transformation interface</li>
<li>CHANGE: renamed <code>Spline.set_periodic()</code> to <code>Spline.set_closed()</code></li>
<li>CHANGE: renamed <code>Spline.set_periodic_rational()</code> to <code>Spline.set_closed_rational()</code></li>
<li>CHANGE: renamed <code>ezdxf.math.bspline_control_frame()</code> to <code>ezdxf.math.global_bspline_interpolation()</code></li>
<li>REMOVED: <code>ezdxf.math.Matrix33</code> class, <code>UCS</code> and <code>OCS</code> uses <code>Matrix44</code>for transformations </li>
<li>REMOVED: <code>ezdxf.math.BRCS</code> class and <code>Insert.brcs()</code></li>
<li>REMOVED: <code>ezdxf.math.ConstructionTool</code> base class</li>
<li>REMOVED: <code>ezdxf.math.normalize_angle(angle)</code>, replace call by expression: <code>angle % math.tau</code></li>
<li>REMOVED: <code>ezdxf.math.DBSpline</code>, integrated as <code>BSpline.derivatives()</code></li>
<li>REMOVED: <code>ezdxf.math.DBSplineU</code>, integrated as <code>BSplineU.derivatives()</code></li>
<li>REMOVED: <code>ezdxf.math.DBSplineClosed</code>, integrated as <code>BSplineClosed.derivatives()</code></li>
<li>REMOVED: <code>ezdxf.math.DBezier</code>, integrated as <code>Bezier.derivatives()</code></li>
<li>REMOVED: <code>BaseLayout.add_spline_approx()</code>, incorrect and nobody noticed it - so it's not really needed, if required
use the <code>geomdl.fitting.approximate_curve()</code> function from the package
<a href="https://github.com/orbingol/NURBS-Python">NURBS-Python</a>, see example <code>using_nurbs_python.py</code></li>
<li>REMOVED: <code>ezdxf.math.bspline_control_frame_approx()</code>, incorrect and nobody noticed it - so it's not really needed </li>
<li>DEPRECATED: <code>DXFGraphic.transform_to_wcs(ucs)</code>, replace call by <code>DXFGraphic.transform(ucs.matrix)</code></li>
<li>DEPRECATED: <code>non_uniform_scaling</code> argument for <code>Insert.explode()</code> </li>
<li>DEPRECATED: <code>non_uniform_scaling</code> argument for <code>Insert.virtual_entities()</code> </li>
<li>DEPRECATED: getter and edit methods in <code>Hatch</code> for attributes <code>paths</code>, <code>gradient</code>, <code>pattern</code> and <code>seeds</code> </li>
<li>DEPRECATED: <code>Spline.edit_data()</code> all attributes accessible by properties</li>
<li>BUGFIX: <code>ezdxf.math.intersection_ray_ray_3d()</code> </li>
<li>BUGFIX: <code>Spline.set_periodic()</code> created invalid data for BricsCAD - misleading information by Autodesk</li>
</ul>Release v0.12.52020-05-22T12:05:00+02:002020-05-22T12:05:00+02:00mozmantag:ezdxf.mozman.at,2020-05-22:/release-v0-12.html<p>Release notes for ezdxf v0.12.5</p><h2>Virtual Entities</h2>
<p>It is possible to examine the content of block references as "virtual" entities, this entities are located at
the "exploded" positions, but are not stored in the entity database, have no handle and are not assigned to any layout.</p>
<p>This is an experimental feature and good enough for simple tasks, but not everything will work as expected
from a CAD application, as example <strong>non uniform scaling</strong> returns incorrect results for text entities (<code>TEXT</code>,
<code>MTEXT</code>, <code>ATTRIB</code>) and some other entities like <code>ELLIPSE</code>, <code>SHAPE</code>, <code>HATCH</code> with arc or ellipse path segments
and <code>POLYLINE</code>/<code>LWPOLYLINE</code> with arc segments.</p>
<p>Virtual entities are also supported by <code>LWPOLYLINE</code> and 2D/3D <code>POLYLINE</code>, <code>POLYMESH</code>, <code>POLYFACE</code> and
<code>DIMENSION</code> entities. This entities will be broken down to <code>LINE</code>, <code>ARC</code>, <code>3DFACE</code> and <code>TEXT</code> entities.</p>
<ul>
<li><a href="https://ezdxf.mozman.at/docs/blocks/insert.html#ezdxf.entities.Insert.virtual_entities">Insert.virtual_entities()</a></li>
<li><a href="https://ezdxf.mozman.at/docs/dxfentities/lwpolyline.html#ezdxf.entities.LWPolyline.virtual_entities">LWPolyline.virtual_entities()</a></li>
<li><a href="https://ezdxf.mozman.at/docs/dxfentities/polyline.html#ezdxf.entities.Polyline.virtual_entities">Polyline.virtual_entities()</a></li>
<li><a href="https://ezdxf.mozman.at/docs/dxfentities/dimension.html#ezdxf.entities.Dimension.virtual_entities">Dimension.virtual_entities()</a></li>
</ul>
<h2>Explode</h2>
<p>The "explode" feature add the "virtual" entities to the drawing entity database and places this entities at
a target layout, which is the same layout as for the source entity by default and delete the source entity.
All limitations of "virtual" entities apply also to the "explode" feature. </p>
<ul>
<li><a href="https://ezdxf.mozman.at/docs/blocks/insert.html#ezdxf.entities.Insert.explode">Insert.explode()</a></li>
<li><a href="https://ezdxf.mozman.at/docs/dxfentities/lwpolyline.html#ezdxf.entities.explode">LWPolyline.explode()</a></li>
<li><a href="https://ezdxf.mozman.at/docs/dxfentities/polyline.html#ezdxf.entities.Polyline.explode">Polyline.explode()</a></li>
<li><a href="https://ezdxf.mozman.at/docs/dxfentities/dimension.html#ezdxf.entities.Dimension.explode">Dimension.explode()</a></li>
</ul>
<h2>Block Reference Attributes</h2>
<p><code>Insert.add_auto_attribs()</code> add <code>ATTRIB</code> entities defined as <code>ATTDEF</code> in the block layout and fill tags
with values defined by a <code>dict</code>, this method avoids the wrapper block of the
<code>BaseLayout.add_auto_blockref</code> method, but the visual results may not match the results of CAD applications,
especially for <strong>non uniform scaling</strong>. </p>
<p>If the visual result is very important to you, use the <code>add_auto_blockref()</code> method.</p>
<ul>
<li><a href="https://ezdxf.mozman.at/docs/blocks/insert.html#ezdxf.entities.Insert.add_auto_attribs">Insert.add_auto_attribs()</a></li>
</ul>
<h2>Hyperlinks</h2>
<p>Get/set hyperlinks for graphical DXF entities.</p>
<ul>
<li><a href="https://ezdxf.mozman.at/docs/dxfentities/dxfgfx.html#ezdxf.entities.DXFGraphic.has_hyperlink">DXFGraphic.has_hyperlink()</a></li>
<li><a href="https://ezdxf.mozman.at/docs/dxfentities/dxfgfx.html#ezdxf.entities.DXFGraphic.get_hyperlink">DXFGraphic.get_hyperlink()</a></li>
<li><a href="https://ezdxf.mozman.at/docs/dxfentities/dxfgfx.html#ezdxf.entities.DXFGraphic.set_hyperlink">DXFGraphic.set_hyperlink()</a></li>
</ul>
<h2>Binary DXF</h2>
<p><em>ezdxf</em> can read and write binary encoded DXF files. The binary DXF format is also supported by
the <code>r12writer</code> add-on, but <strong>not</strong> by the <code>iterdxf</code> add-on.</p>
<ul>
<li><a href="https://ezdxf.mozman.at/docs/drawing/drawing.html#ezdxf.drawing.Drawing.saveas">Drawing.saveas()</a></li>
</ul>
<h3>Warning!</h3>
<p>DXF files containing <code>ACSH_SWEEP_CLASS</code> objects which are saved as binary DXF by <em>ezdxf</em> can not be opened
by AutoCAD, this is maybe also true for other 3rd party entities. BricsCAD opens this binary DXF files
without complaining, but saves the <code>ACSH_SWEEP_CLASS</code> entities as <code>ACAD_PROXY_OBJECT</code> when writing back,
so error analyzing is not possible without the full version of AutoCAD.</p>
<h2>ODAFC Add-on</h2>
<p>Use an installed <a href="https://www.opendesign.com/guestfiles/oda_file_converter">ODA File Converter</a> for
converting between different versions of <code>.dwg</code>, <code>.dxb</code> and <code>.dxf</code>.</p>
<p>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.</p>
<p>At least at Windows the GUI of the ODA File Converter pops up on every call.</p>
<ul>
<li>docs for <a href="https://ezdxf.mozman.at/docs/addons/odafc.html">odafc</a> add-on</li>
</ul>
<h2>Change Log</h2>
<h3>Version 0.12 - 2020-04-12</h3>
<ul>
<li>NEW: <code>Insert.block()</code> returns associated <code>BlockLayout()</code> or <code>None</code> if block not exist or is an XREF</li>
<li>NEW: <code>Insert.has_scaling</code> returns <code>True</code> if any axis scaling is applied</li>
<li>NEW: <code>Insert.has_uniform_scaling</code> returns <code>True</code> if scaling is uniform in x-, y- and z-axis.</li>
<li>NEW: <code>Insert.scale(factor)</code> set uniform scaling.</li>
<li>NEW: <code>Insert.virtual_entities()</code> yields 'virtual' entities of a block reference (experimental)</li>
<li>NEW: <code>Insert.explode()</code> explode block reference entities into target layout (experimental)</li>
<li>NEW: <code>Insert.add_auto_attribs()</code> add ATTRIB entities defined as ATTDEF in the block layout and fill tags
with values defined by a <code>dict</code> (experimental)</li>
<li>NEW: <code>LWPolyline.virtual_entities()</code> yields 'virtual' LINE and ARC entities</li>
<li>NEW: <code>LWPolyline.explode()</code> explode LWPOLYLINE as LINE and ARC entities into target layout</li>
<li>NEW: <code>Polyline.virtual_entities()</code> yields 'virtual' LINE, ARC or 3DFACE entities</li>
<li>NEW: <code>Polyline.explode()</code> explode POLYLINE as LINE, ARC or 3DFACE entities into target layout</li>
<li>NEW: <code>Dimension.virtual_entities()</code> yields 'virtual' DXF entities</li>
<li>NEW: <code>Dimension.explode()</code> explode DIMENSION as basic DXF entities into target layout</li>
<li>NEW: <code>Dimension.transform_to_wcs()</code> support for UCS based entity transformation</li>
<li>NEW: <code>Dimension.override()</code> returns <code>DimStyleOverride()</code> object</li>
<li>NEW: <code>Dimension.render()</code> render graphical representation as anonymous block</li>
<li>NEW: <code>Block()</code> properties <code>is_anonymous</code>, <code>is_xref</code> and <code>is_xref_overlay</code></li>
<li>NEW: <code>R12FastStreamWriter.add_polyline_2d()</code>, add 2D POLYLINE with start width, end width and bulge value support</li>
<li>NEW: <code>Ellipse.minor_axis</code> property returns minor axis as <code>Vector</code></li>
<li>NEW: Option <code>ezdxf.options.write_fixed_meta_data_for_testing</code>, writes always same timestamps and GUID</li>
<li>NEW: Support for loading and exporting proxy graphic encoded as binary data, by default disabled</li>
<li>NEW: <code>ezdxf.proxygraphic.ProxyGraphic()</code> class to examine binary encoded proxy graphic (Need more example data for testing!)</li>
<li>NEW: Get/set hyperlink for graphic entities</li>
<li>NEW: <code>odafc</code> add-on to use an installed ODA File Converter for reading and writing DWG files</li>
<li>NEW: Support for reading and writing Binary DXF files</li>
<li>NEW: Binary DXF support for <code>r12writer</code> add-on</li>
<li>CHANGE: <code>R12FastStreamWriter.add_polyline()</code>, add 3D POLYLINE only, closed flag support</li>
<li>CHANGE: renamed <code>Insert.ucs()</code> to <code>Insert.brcs()</code> which now returns a <code>BRCS()</code> object</li>
<li>CHANGE: <code>Polyline.close()</code>, <code>Polyline.m_close()</code> and <code>Polyline.n_close()</code> can set and <strong>clear</strong> closed state.</li>
<li>BUGFIX: <code>Dimension.destroy()</code> should not not destroy associated anonymous block, because if DIMENSION is used in a
block, the anonymous block may be used by several block references</li>
<li>BUGFIX: floating point precision error in <code>intersection_line_line_2d()</code></li>
<li>BUGFIX: attribute error in <code>Polyline.transform_to_wcs()</code> for 2d polylines</li>
<li>BUGFIX: LWPOLYLINE was always exported with <code>const_width=0</code></li>
<li>BUGFIX: <code>Face3d.set_edge_visibility()</code> set inverted state (visible <-> invisible)</li>
<li>BUGFIX: Load <code>AcDbEntity</code> group codes from base class</li>
</ul>
<h3>Version 0.12.1 - 2020-04-25</h3>
<ul>
<li>BUGFIX: fixed uniform scaled ellipse handling in <code>explode.virtual_block_reference_entities()</code></li>
<li>BUGFIX: fixed crash caused by floating point inaccuracy in <code>Vector.angle_between()</code> (Matt Broadway)</li>
<li>BUGFIX: fixed crash for axis transformation of nearly perpendicular ellipse axis</li>
<li>BUGFIX: fixed <code>Hatch.has_critical_elements()</code></li>
</ul>
<h3>Version 0.12.2 - 2020-05-03</h3>
<ul>
<li>BUGFIX: <code>XData.get()</code> now raises <code>DXFValueError</code> for not existing appids, like all other methods of the <code>XData()</code> class</li>
<li>BUGFIX: <code>Layer.description</code> returns an empty string for unknown XDATA structure in <code>AcAecLayerStandard</code></li>
<li>BUGFIX: Initialize/Load <code>Hatch</code> edge coordinates as <code>Vec2()</code> objects</li>
<li>BUGFIX: typo in 3 point angular dimension subclass marker (vshu3000)</li>
<li>BUGFIX: HATCH/SplineEdge did export length tag 97 if no fit points exist, creates invalid DXF for AutoCAD/BricsCAD (vshu3000) </li>
<li>BUGFIX: Ellipse handling in <code>virtual_block_reference_entities()</code> (Matt Broadway) </li>
</ul>
<h3>Version 0.12.3 - 2020-05-16</h3>
<ul>
<li>BUGFIX: DXF R2010+ requires zero length tag 97 for HATCH/SplineEdge if no fit points exist (vshu3000)</li>
<li>BUGFIX: Export order of XDATA and embedded objects (vshu3000)</li>
<li>BUGFIX: ATTRIB and ATTDEF did not load basic DXF attributes</li>
<li>NEW: <code>BlockLayout()</code> properties <code>can_explode</code> and <code>scale_uniformly</code></li>
<li>NEW: <code>Hatch.remove_association()</code></li>
</ul>
<h3>Version 0.12.4 - 2020-05-22</h3>
<ul>
<li>BUGFIX: structure validator for XRECORD</li>
</ul>Release v0.11.12020-02-29T06:00:00+01:002020-02-29T06:00:00+01:00mozmantag:ezdxf.mozman.at,2020-02-29:/release-v0-11-1.html<p>Release notes for ezdxf v0.11.1</p><h2>MeshBuilder</h2>
<p>Added interface to create <code>MeshBuilder()</code> objects from <code>POLYFACE</code> and <code>POLYMESH</code> entities as
<code>MeshBuilder.from_polymesh()</code>.
And support to render <code>MeshBuilder()</code> objects as <code>POLYFACE</code> entities as <code>MeshBuilder.render_polymesh()</code>.
Important difference between <code>MESH</code> and <code>POLYFACE</code> is the support of ngons by the <code>MESH</code> entity and not by
the <code>POLYFACE</code> entity. The <code>render_polyface()</code> method will not raise an error if ngons occur at rendering,
but these faces will have only the first 4 vertices the rest is ignored.</p>
<h2>MeshAverageVertexMerger</h2>
<p>This is an extended version of <code>MeshVertexMerger()</code>.
Location of merged vertices is the average location of all vertices with the same key, this needs extra
memory and runtime in comparision to <code>MeshVertexMerger()</code> and this class also does not support
transformations.</p>
<ul>
<li>see <a href="https://ezdxf.mozman.at/docs/render/mesh.html#meshaveragevertexmerger">Documentation</a></li>
</ul>
<h2>iterdxf</h2>
<p>This add-on allows iterating over entities of the modelspace of really big (> 1GB) DXF files which do not fit into
memory by only loading one entity at the time.</p>
<ul>
<li>see <a href="https://ezdxf.mozman.at/docs/addons/iterdxf.html">Documentation</a></li>
<li>see <a href="https://github.com/mozman/ezdxf/blob/master/examples/addons/iterdxf.py">example</a> for <code>iterdxf.opendxf()</code> </li>
<li>see <a href="https://github.com/mozman/ezdxf/blob/master/examples/addons/iterdxf_single_pass.py">example</a>
for <code>iterdxf.modelspace()</code> and <code>iterdxf.single_pass_modelspace()</code> </li>
</ul>
<h2>r12writer</h2>
<p>Added support for writing big <code>POLYMESH</code> and <code>POLYFACE</code> entities.</p>
<ul>
<li>see <a href="https://ezdxf.mozman.at/docs/addons/r12writer.html">Documentation</a></li>
</ul>
<h2>Auditor</h2>
<p>Refactored <code>Auditor()</code> into a DXF document fixer, fixes will be applied automatically (work in progress)</p>
<h2>MText</h2>
<p>Added <code>MText.plain_text()</code>, which returns the text content without formatting codes and converts page breaks <code>\P</code>
into <code>\n</code>.</p>
<h2>Moved Packages</h2>
<ul>
<li>Moved: <code>ezdxf.r12writer</code> to <code>ezdxf.addons.r12writer</code></li>
<li>Moved <code>ezdxf.acadctb</code> to <code>ezdxf.addons.acadctb</code></li>
</ul>
<h2>Change Log</h2>
<ul>
<li>NEW: <code>Meshbuilder.from_polyface()</code> to interface to <code>POLYFACE</code> and <code>POLYMESH</code> </li>
<li>NEW: <code>Meshbuilder.render_polyface()</code> create <code>POLYFACE</code> objects</li>
<li>NEW: <code>MeshAverageVertexMerger()</code> an extended version of <code>MeshVertexMerger()</code>, location of merged vertices
is the average location of all vertices with the same key</li>
<li>NEW: <code>ezdxf.addons.iterdxf</code> iterate over modelspace entities of really big DXF files (>1 GB) without loading
them into memory</li>
<li>NEW: <code>ezdxf.addons.r12writer</code> supports <code>POLYFACE</code> and <code>POLYMESH</code> entities</li>
<li>NEW: <code>Layout.add_foreign_entity()</code> copy/move <strong>simple</strong> entities from another DXF document or add unassigned
DXF entities to a layout</li>
<li>NEW: <code>MText.plain_text()</code> returns text content without formatting codes</li>
<li>CHANGES: refactor Auditor() into a DXF document fixer, fixes will be applied automatically (work in progress)</li>
<li>CHANGES: moved <code>r12writer</code> into <code>addons</code> subpackage</li>
<li>CHANGES: moved <code>acadctb</code> into <code>addons</code> subpackage</li>
</ul>Release v0.112020-02-15T06:00:00+01:002020-02-15T06:00:00+01:00mozmantag:ezdxf.mozman.at,2020-02-15:/release-v0-11.html<p>Release notes for ezdxf v0.11</p><h2>Development</h2>
<p><em>ezdxf</em> v0.11 requires CPython 3.6 or the latest pypy3 version for installation, testing and development.</p>
<p>Now using standard git branches <code>master</code> and <code>stable</code>:</p>
<ul>
<li><code>master</code> actual development state, pull requests should be targeted to this branch</li>
<li><code>stable</code> latest stable release</li>
</ul>
<h2>Dimension Support</h2>
<p>Additional support for creating radial and diameter dimensions</p>
<ul>
<li>Tutorial for <a href="https://ezdxf.mozman.at/docs/tutorials/radius_dimension.html">Radial Dimension</a></li>
<li>Tutorial for <a href="https://ezdxf.mozman.at/docs/tutorials/diameter_dimension.html">Diameter Dimension</a></li>
</ul>
<h2>UCS based Transformation</h2>
<p>For a more simple usage many entities support a <code>transform_to_wcs()</code> method. This entities can
be created by using <a href="https://ezdxf.mozman.at/docs/math.html#ucs-class">UCS</a> (User Coordinate System)
locations and transform them into WCS coordinates by <code>transform_to_wcs(ucs)</code>.
Therefore the <code>UCS()</code> class got new transformation features:</p>
<ul>
<li><code>UCS.rotate(axis, angle)</code> returns a new UCS rotated around WCS vector <code>axis</code></li>
<li><code>UCS.rotate_local_x(angle)</code> returns a new UCS rotated around local x-axis</li>
<li><code>UCS.rotate_local_y(angle)</code> returns a new UCS rotated around local y-axis</li>
<li><code>UCS.rotate_local_z(angle)</code> returns a new UCS rotated around local z-axis</li>
<li><code>UCS.copy()</code> returns a new copy of UCS</li>
<li><code>UCS.shift(delta)</code> shifts UCS inplace by vector <code>delta</code></li>
<li><code>UCS.moveto(location)</code> set new UCS origin to <code>location</code> inplace</li>
</ul>
<p>Tutorial for <a href="https://ezdxf.mozman.at/docs/tutorials/ucs_transform.html">UCS based Transformation</a></p>
<p>Following DXF entities support <code>transform_to_wcs()</code>:</p>
<ul>
<li>3DFACE</li>
<li>ARC</li>
<li>ATTDEF</li>
<li>ATTRIB</li>
<li>CIRCLE</li>
<li>ELLIPSE</li>
<li>HATCH</li>
<li>IMAGE</li>
<li>INSERT </li>
<li>LEADER</li>
<li>LINE</li>
<li>LWPOLYLINE</li>
<li>MESH</li>
<li>MTEXT</li>
<li>POINT</li>
<li>POLYLINE (POLYMESH & POLYFACE)</li>
<li>RAY</li>
<li>SHAPE</li>
<li>SOLID</li>
<li>SPLINE</li>
<li>TEXT</li>
<li>TRACE</li>
<li>XLINE</li>
</ul>
<p>Embedded ACIS entities like 3DSOLID, REGION, SURFACE and so on, do not expose their geometry without a commercial
license from Spatial Inc. and therefore can not be modified by <em>ezdxf</em>!</p>
<h2>Mesh Transformation</h2>
<p>The <a href="https://ezdxf.mozman.at/docs/render/mesh.html#meshtransformer">MeshTransformer</a> class supports many inplace
transformations like translate, scale and rotate, it is a subclass of <code>MeshBuilder()</code> and therefore compatible
to the DXF MESH entity, POLYMESH and POLYFACE support will be added soon.</p>
<p>Following factory functions from module <code>ezdxf.render</code> return <code>MeshTransformer()</code> objects:</p>
<ul>
<li><code>cube()</code></li>
<li><code>cylinder()</code></li>
<li><code>cylinder_2p()</code></li>
<li><code>cone()</code></li>
<li><code>cone_2p()</code></li>
<li><code>sphere()</code></li>
<li><code>extrude()</code></li>
<li><code>from_profiles_linear()</code></li>
<li><code>from_profiles_spline()</code></li>
<li><code>rotation_form()</code></li>
</ul>
<h2>PyCSG Add-On</h2>
<p>Constructive Solid Geometry (CSG) is a modeling technique that uses Boolean operations like union and intersection
to combine 3D solids. The <code>MeshTransformer()</code> class is the interface between <em>ezdxf</em> and pycsg.</p>
<p>For more information go to <a href="https://ezdxf.mozman.at/docs/addons/pycsg.html">ezdxf.addons.pycsg</a>.</p>
<h2>Change Log</h2>
<ul>
<li>Using standard git branches: </li>
<li><code>master</code>: development state</li>
<li><code>stable</code>: latest stable release</li>
<li>Requires Python 3.6</li>
<li>NEW: <code>Dimension.get_measurement()</code> supports angular, angular3p and ordinate dimensions</li>
<li>NEW: <code>Layout.add_radius_dim()</code> implemented</li>
<li>NEW: shortcut calls <code>Layout.add_radius_dim_2p()</code> and <code>Layout.add_radius_dim_cra()</code></li>
<li>NEW: <code>Layout.add_diameter_dim()</code> implemented</li>
<li>NEW: shortcut <code>Layout.add_diameter_dim_2p()</code></li>
<li>NEW: <code>Circle.vertices(angles)</code> yields vertices for iterable angles in WCS</li>
<li>NEW: <code>Ellipse.vertices(params)</code> yields vertices for iterable params in WCS</li>
<li>NEW: Arc properties <code>start_point</code> and <code>end_point</code> returns start- and end point of arc in WCS</li>
<li>NEW: Ellipse properties <code>start_point</code> and <code>end_point</code> returns start- and end point of ellipse in WCS</li>
<li>NEW: user defined point format support for 2d POLYLINE entities:
<code>add_polyline2d([(1, 2, 0.5), (3, 4, 0)], format='xyb')</code> </li>
<li>NEW: <code>Polyline.append_formatted_points()</code> with user defined point format support</li>
<li>NEW: <code>Drawing.set_modelspace_vport(height, center)</code> set initial view/zoom location for the modelspace</li>
<li>NEW: support for associating HATCH boundary paths to geometry entities</li>
<li>NEW: <code>Drawing.output_encoding</code> returns required output encoding</li>
<li>NEW: User Coordinate System (UCS) based entity transformation, allows to work with UCS coordinates, which are
simpler if the UCS is chosen wisely, and transform them later into WCS coordinates. Entities which have a
<code>transform_to_wcs(ucs)</code> method, automatically take advantage of the new UCS transformation methods, but not all entity
types are supported, embedded ACIS entities like 3DSOLID, REGION, SURFACE and so on, do not expose their geometry.</li>
<li>NEW: <code>transform_to_wcs(ucs)</code> implemented for: 3DFACE, ARC, ATTDEF, ATTRIB, CIRCLE, ELLIPSE, HATCH, IMAGE, INSERT,
LEADER, LINE, LWPOLYLINE, MESH, MTEXT, POINT, POLYLINE, RAY, SHAPE, SOLID, SPLINE, TEXT, TRACE, XLINE</li>
<li>NEW: <code>UCS.rotate(axis, angle)</code> returns a new UCS rotated around WCS vector <code>axis</code></li>
<li>NEW: <code>UCS.rotate_local_x(angle)</code> returns a new UCS rotated around local x-axis</li>
<li>NEW: <code>UCS.rotate_local_y(angle)</code> returns a new UCS rotated around local y-axis</li>
<li>NEW: <code>UCS.rotate_local_z(angle)</code> returns a new UCS rotated around local z-axis</li>
<li>NEW: <code>UCS.copy()</code> returns a new copy of UCS</li>
<li>NEW: <code>UCS.shift(delta)</code> shifts UCS inplace by vector <code>delta</code></li>
<li>NEW: <code>UCS.moveto(location)</code> set new UCS origin to <code>location</code> inplace</li>
<li>NEW: <code>size</code> and <code>center</code> properties for bounding box classes</li>
<li>NEW: <code>Insert.ucs()</code> returns an UCS placed in block reference <code>insert</code> location, UCS axis aligned to the block axis.</li>
<li>NEW: <code>Insert.reset_transformation()</code> reset block reference location, rotation and extrusion vector.</li>
<li>CHANGE: renamed <code>ezdxf.math.left_of_line</code> to <code>ezdxf.math.is_point_left_of_line</code> </li>
<li>NEW: <code>ezdxf.math.point_to_line_relation()</code> 2D function returns <code>-1</code> for left oft line, <code>+1</code> for right oif line , <code>0</code> on the line</li>
<li>NEW: <code>ezdxf.math.is_point_on_line_2d()</code> test if 2D point is on 2D line </li>
<li>NEW: <code>ezdxf.math.distance_point_line_2d()</code> distance of 2D point from 2D line</li>
<li>NEW: <code>ezdxf.math.is_point_in_polygon_2d()</code> test if 2D point is inside of a 2D polygon </li>
<li>NEW: <code>ezdxf.math.intersection_line_line_2d()</code> calculate intersection for 2D lines </li>
<li>NEW: <code>ezdxf.math.offset_vertices_2d()</code> calculate 2D offset vertices for a 2D polygon </li>
<li>NEW: <code>ezdxf.math.normal_vector_3p()</code> returns normal vector for 3 points</li>
<li>NEW: <code>ezdxf.math.is_planar_face()</code> test if 3D face is planar</li>
<li>NEW: <code>ezdxf.math.subdivide_face()</code> linear subdivision for 2D/3D faces/polygons </li>
<li>NEW: <code>ezdxf.math.intersection_ray_ray_3d()</code> calculate intersection for 3D rays </li>
<li>NEW: <code>ezdxf.math.Plane()</code> 3D plane construction tool </li>
<li>NEW: <code>ezdxf.render.MeshTransformer()</code> inplace mesh transformation class, subclass of <code>MeshBuilder()</code></li>
<li>NEW: <code>MeshBuilder.render()</code> added UCS support</li>
<li>NEW: <code>MeshBuilder.render_normals()</code> render face normals as LINE entities, useful to check face orientation</li>
<li>NEW: <code>ezdxf.render.forms.cone_2p()</code> create 3D cone mesh from two points</li>
<li>NEW: <code>ezdxf.render.forms.cylinder_2p()</code> create 3D cylinder mesh from two points</li>
<li>NEW: <code>ezdxf.render.forms.sphere()</code> create 3D sphere mesh</li>
<li>NEW: <code>pycsg</code> add-on, a simple Constructive Solid Geometry (CSG) kernel created by Evan Wallace (Javascript) and
Tim Knip (Python)</li>
<li>CHANGE: Changed predefined pattern scaling to BricsCAD and AutoCAD standard, set global option
<code>ezdxf.options.use_old_predefined_pattern_scaling</code> to True, to use the old pattern scaling before v0.11 </li>
<li>CHANGE: removed <code>ezdxf.PATTERN</code> constant, use <code>PATTERN = ezdxf.pattern.load()</code> instead, set argument
<code>old_pattern=True</code> to use the old pattern scaling before v0.11</li>
<li>CHANGE: <code>Table.key()</code> accepts only strings, therefore tables check <code>in</code> accepts also only strings
like <code>entity.dxf.name</code></li>
<li>NEW: load DXF comments from file (<code>ezdxf.comments.from_file</code>) or stream (<code>ezdxf.comments.from_stream</code>)</li>
<li>BUGFIX: fixed incorrect HATCH pattern scaling</li>
<li>BUGFIX: fixed base point calculation of aligned dimensions</li>
<li>BUGFIX: fixed length extension line support for linear dimensions</li>
<li>BUGFIX: <code>UCS.to_ocs_angle_deg()</code> and <code>UCS.to_ocs_angle_rad()</code></li>
<li>BUGFIX: check for unsupported DXF versions at <code>new()</code></li>
<li>BUGFIX: fixed dxf2src error for the HATCH entity</li>
<li>BUGFIX: <code>is_point_left_of_line()</code> algorithm was incorrect</li>
<li>BUGFIX: default <code>dimtxsty</code> is <code>Standard</code> if <code>options.default_dimension_text_style</code> is not defined</li>
<li>BUGFIX: default arrows for minimal defined dimstyles are closed filled arrows </li>
<li>BUGFIX: use <code>Standard</code> as default for undefined dimension styles, e.g. <code>EZDXF</code> without setup </li>
</ul>Bugfix release v0.10.42020-01-31T06:00:00+01:002020-01-31T06:00:00+01:00mozmantag:ezdxf.mozman.at,2020-01-31:/release-v0-10-4.html<p>Release notes for ezdxf v0.10.4</p><ul>
<li>BUGFIX: height group code (40) for TEXT, ATTRIB and ATTDEF is mandatory</li>
</ul>Bugfix release v0.10.32020-01-29T06:00:00+01:002020-01-29T06:00:00+01:00mozmantag:ezdxf.mozman.at,2020-01-29:/release-v0-10-3.html<p>Release notes for ezdxf v0.10.3</p><ul>
<li>BUGFIX: minimal DXF version for VISUALSTYLE object is R2000 (AC1015)</li>
</ul>Bugfix release v0.10.22019-10-05T06:00:00+02:002019-10-05T06:00:00+02:00mozmantag:ezdxf.mozman.at,2019-10-05:/release-v0-10-2.html<p>Release notes for ezdxf v0.10.2</p><ul>
<li>NEW: <code>Dimension.get_measurement()</code> returns the actual dimension measurement in WCS units, no scaling applied; angular
and ordinate dimension are not supported yet. </li>
<li>BUGFIX: ordinate dimension exports wrong feature location</li>
<li>BUGFIX: <code>Hatch.set_pattern_fill()</code> did not set pattern scale, angle and double values</li>
</ul>Bugfix release v0.10.12019-09-07T06:00:00+02:002019-09-07T06:00:00+02:00mozmantag:ezdxf.mozman.at,2019-09-07:/release-v0-10-1.html<p>Release notes for ezdxf v0.10.1</p><ul>
<li>BUGFIX: group code for header var $ACADMAINTVER is 90 for DXF R2018+ and 70 for previous DXF versions. This is a
critical bug because AutoCAD 2012/2013 (and possibly earlier versions) will not open DXF files with the new group
code 90 for header variable $ACADMAINTVER.</li>
</ul>Release v0.102019-09-01T06:00:00+02:002019-09-01T06:00:00+02:00mozmantag:ezdxf.mozman.at,2019-09-01:/release-v0-10.html<p>Release notes for ezdxf v0.10</p><h1>New Entity System</h1>
<p>Complete rewrite of the entity system by keeping the high level interface unchanged, changes for users should be
minimal, but there are some bigger changes that could impact users too. </p>
<p>Entities are no more stored as tag lists, instead each DXF entity is represented by a proper Python object like
the wrapper classes in previous <em>ezdxf</em> versions, by overhauling the complete system I decided to use a unified entity
system for <strong>ALL</strong> DXF versions. </p>
<p>Advantage is a faster and <strong>easier</strong> internal processing, and you can save as any DXF version you want by the cost
of losing data and attributes if you choose to save in an older DXF version, because <em>ezdxf</em> is still not a DXF
converter or CAD application. Otherwise saving an older DXF versions as a newer DXF version should work properly e.g.
open a DXF R12 and save it as DXF R2018.</p>
<p>Creating new drawings by <code>exdxf.new()</code> is about 6x faster than before, because no templates from file system are needed
anymore, new drawings are build from scratch in memory.</p>
<p>Disadvantage, <em>ezdxf</em> has to interpret all group codes of supported entities and Autodesk do not document <strong>all</strong> group
codes in the official DXF reference, this unknown group codes will be lost by saving a modified DXF drawing,
unsupported and unknown entities are still stored and preserved as dumb tag lists (<em>unsupported</em> is my term for
documented entities, just stored for preservation). <em>ezdxf</em> logs unknown tags, but I don't have the time and will
to research the functionality of these unknown tags. This new entity system also causes a little time penalty for
loading and saving DXF files, the actual loading process is optimized for the old entity system and could be
optimized for the new entity system later, but the penalty is only ~1.5x to 2x and is only noticeable
at really large files (>5MB).</p>
<p><strong>CAUTION: SOME DATA MAYBE LOST BY MODIFYING EXISTING DXF FILES.</strong></p>
<h2>API changes</h2>
<p>Renamed all DXF attributes which represent a handle to clarify the type of the attribute, except for <code>handle</code> and
<code>owner</code> all handle attributes have a "_handle" suffix. </p>
<h3>DXFEntity</h3>
<p>The <code>DXFEntity</code> class is still the base class of all DXF entities, but some major changes had be done, mostly
important for developers which go beyond the high level API:</p>
<ul>
<li>renamed <code>DXFEntity.drawing</code> to <code>DXFEntity.doc</code></li>
<li>renamed <code>get_xdata()</code> keyword <code>xdata_tag</code> to <code>tags</code></li>
<li>renamed <code>set_xdata()</code> keyword <code>xdata_tag</code> to <code>tags</code></li>
<li>renamed <code>remove_reactor_handle()</code> to <code>discard_reactor_handle()</code></li>
<li>renamed <code>supports_dxf_attrib()</code> to <code>is_supported_dxf_attrib()</code></li>
<li>renamed <code>dxf_attrib_exists()</code> to <code>has_dxf_attrib()</code></li>
<li><code>get_extension_dict()</code> returns <code>ExtensionDict</code> object instead of the raw DICTIONARY object</li>
</ul>
<p>See also the <a href="https://ezdxf.mozman.at/docs/dxfentities/dxfentity.html">DXFEntity</a> reference.</p>
<h3>Layer</h3>
<ul>
<li>removed <code>line_weight</code> as synonym for <code>lineweight</code></li>
<li>renamed <code>plot_style_name</code> to <code>plotstyle_handle</code> </li>
<li>renamed <code>material</code> to <code>material_handle</code></li>
<li>support for <code>true_color</code> attribute (DXF R2004+, undocumented)</li>
<li><code>Layer.color</code> property to set/get ACI color values </li>
<li><code>Layer.rgb</code> property to set/get true color values as (R, G, B) tuples </li>
<li><code>Layer.transparency</code> property to set/get layer transparency as float value between 0 and 1 </li>
<li><code>Layer.description</code> property to set/get layer description </li>
<li><code>rename()</code>: rename layer and all known (documented) references to this layer</li>
</ul>
<p>See also the <a href="https://ezdxf.mozman.at/docs/tables/layer_table_entry.html">Layer</a> reference.</p>
<h3>Polyline</h3>
<p>Polyline vertices are now stored as <code>Vertex</code> objects in a standard Python list called <code>Polyline.vertices</code>.</p>
<p>See also the <a href="https://ezdxf.mozman.at/docs/dxfentities/polyline.html">Polyline</a> reference.</p>
<h3>Insert</h3>
<p>Block reference attributes (attached ATTRIB entites) are stored as <code>Attrib</code> objects in a standard Python list called
<code>Insert.attribs</code>.</p>
<p>See also the <a href="https://ezdxf.mozman.at/docs/blocks/insert.html">Insert</a> reference.</p>
<h3>Hatch</h3>
<p>Direct access to paths (<code>Hatch.paths</code>), pattern (<code>Hatch.pattern</code>) and gradient (<code>Hatch.gradient</code>) objects, context
manager to edit this data is not needed anymore, but still available for backward compatibility </p>
<p>See also the <a href="https://ezdxf.mozman.at/docs/dxfentities/hatch.html">Hatch</a> reference.</p>
<h3>MText</h3>
<p>Integration of <code>MTextData</code> methods into <code>MText</code>, removed methods <code>edit_data()</code>, <code>get_text()</code>, <code>set_text()</code> from <code>MText</code>,
<code>get_text()</code> and <code>set_text()</code> are replaced by the property <code>MText.text</code> and context manager <code>edit_data()</code> is not needed
anymore.</p>
<p>See also the <a href="https://ezdxf.mozman.at/docs/dxfentities/mtext.html#ezdxf.entities.MText">MText</a> reference and the new
MText <a href="https://ezdxf.mozman.at/docs/tutorials/mtext.html">tutorial</a>.</p>
<h3>Dimension</h3>
<p>Deleting a <code>Dimension</code> entity also removes the associated anonymous dimension block.</p>
<h3>Viewport</h3>
<p>Same handling of the VIEWPORT entity for all DXF versions, but DXF R12 does not support all features, unsupported
features are ignored at saving as DXF R12.</p>
<ul>
<li>renamed <code>Viewport.dxf.center_point</code> to <code>Viewport.dxf.center</code> </li>
<li>renamed <code>Viewport.dxf.target_point</code> to <code>Viewport.dxf.target</code></li>
</ul>
<p>See also the <a href="https://ezdxf.mozman.at/docs/dxfentities/viewport.html">Viewport</a> reference.</p>
<h3>Options</h3>
<ul>
<li>removed <code>ezdxf.options.template_dir</code>, no more needed</li>
<li>new option <code>ezdxf.options.log_unprocessed_tags</code> to log unprocessed (unknown) DXF tags, default is <code>True</code> </li>
</ul>
<h2>New Features</h2>
<h3>Layer</h3>
<p>Renaming layers by<code>Layer.rename()</code>, renames the layer and all known (documented) references to this layer. Support for
true color, transparency and layer description.</p>
<h3>Leader</h3>
<p>Added support for the <a href="https://ezdxf.mozman.at/docs/dxfentities/leader.html">LEADER</a> entity.</p>
<h3>Query</h3>
<p>Result container <code>EntityQuery</code> got <code>first</code> and <code>last</code> properties, to get first or last entity or <code>None</code> if query
result is empty.</p>
<p>Exclude DXF types from <code>'*'</code> search, by appending type name with a preceding '!' e.g. query for all entities
except LINE = <code>"* !LINE"</code></p>
<h3>Forms/Shapes</h3>
<p>Added <code>ngon()</code>, <code>star()</code> and <code>gear()</code> to <code>ezdxf.render.forms</code></p>
<p>See also <a href="https://ezdxf.mozman.at/docs/render/forms.html">ezdxf.render.forms</a> documentation.</p>
<h3>Importer add-on</h3>
<p>Importer add-on rewritten, API incompatible to previous <em>ezdxf</em> versions, but previous implementation was
already broken. </p>
<p>See also <a href="https://ezdxf.mozman.at/docs/addons/importer.html">Importer</a> documentation.</p>
<h3>Source code generator add-on</h3>
<p>Source code generator to create Python source code from DXF entities, to recreate this entities by <em>ezdxf</em>. </p>
<p>This tool creates only simple structures as a useful starting point for parametric DXF entity creation from existing
DXF files. Not all DXF entities are supported!</p>
<p>See also <a href="https://ezdxf.mozman.at/docs/addons/dxf2code.html">dxf2code</a> documentation.</p>
<h3>STB files</h3>
<p>Added support for named plot style tables ('.stb' files), see also
<a href="https://ezdxf.mozman.at/docs/acadctb.html#">Plot Style Files</a> documentation.</p>Release v0.92019-02-24T06:00:00+01:002019-02-24T06:00:00+01:00mozmantag:ezdxf.mozman.at,2019-02-24:/release-v0-9.html<p>Release notes for ezdxf v0.9</p><h2>News</h2>
<ul>
<li>IMPORTANT: Python 2 support REMOVED, if Python 2 support needed: add <code>ezdxf<0.9</code> to your <code>requirements.txt</code> </li>
<li>NEW: testing on Manjaro Linux in a VM by tox</li>
<li>CHANGE: converted NEWS.rst to NEWS.md and README.rst to README.md </li>
<li>CHANGE: moved <code>Importer()</code> from <code>ezdxf.tools</code> to <code>ezdxf.addons</code> - internal structures of modern DXF files are too complex
and too undocumented to support importing data in a reliable way - using <code>Importer()</code> may corrupt your DXF files or just
don't work!</li>
<li>NEW: type annotations to core package and add-ons.</li>
<li>NEW: argument <code>setup</code> in <code>ezdxf.new('R12', setup=True)</code> to setup default line types, text styles and dimension styles,
this feature is disabled by default.</li>
<li>NEW: Duplicate table entries: <code>dwg.styles.duplicate_entry('OpenSans', new_name='OpenSansNew')</code>, this works for
all tables, but is intended to duplicate STYLES and DIMSTYLES.</li>
<li>CHANGED: replaced proprietary fonts in style declarations by open source fonts</li>
<li>NEW: open source fonts to download https://github.com/mozman/ezdxf/tree/master/fonts</li>
<li><strong>OpenSansCondensed-Light</strong> font used for default dimension styles</li>
<li>NEW: subpackage <code>ezdxf.render</code>, because of DIMENSION rendering</li>
<li>NEW: support for AutoCAD standard arrows</li>
<li>NEW: support for creating linear DIMENSION entities</li>
<li>NEW: background color support for MTEXT</li>
<li>CHANGE: DXF template cleanup, removed non standard text styles, dimension styles, layers and blocks</li>
<li>CHANGE: text style STANDARD uses <code>txt</code> font </li>
<li>CHANGE: renamed subpackage <code>ezdxf.algebra</code> to <code>ezdxf.math</code></li>
<li>CHANGE: moved <code>addons.curves</code> to <code>render.curves</code></li>
<li>CHANGE: moved <code>addons.mesh</code> to <code>render.mesh</code></li>
<li>CHANGE: moved <code>addons.r12spline</code> to <code>render.r12spline</code></li>
<li>CHANGE: moved <code>addons.forms</code> to <code>render.forms</code></li>
<li>CHANGE: renamed construction helper classes into Construction...()</li>
<li><code>Ray2D()</code> renamed to <code>ConstructionRay()</code></li>
<li><code>Circle()</code> renamed to <code>ConstructionCircle()</code></li>
<li><code>Arc()</code> renamed to <code>ConstructionArc()</code></li>
<li>NEW: construction tools <code>ConstructionLine()</code> and <code>ConstructionBox()</code></li>
<li>REMOVED: <code>almost_equal</code> use <code>math.isclose</code></li>
<li>REMOVED: <code>almost_equal_points</code> use <code>ezdxf.math.is_close_points</code></li>
<li>BUGFIX: closed LWPOLYLINE did not work in AutoCAD (tag order matters), introduced with v0.8.9 packed data structure</li>
<li>BUGFIX: <code>UCS.to_ocs_angle_deg()</code> corrected</li>
</ul>
<h2>Python 2</h2>
<p>Python 2 support dropped</p>
<h2>Dimension</h2>
<p>Support for linear dimension (more dimension types to come), but I have no time to write a documentation now, please
look at the script <a href="https://github.com/mozman/ezdxf/blob/master/examples/render/dimension_linear.py">dimensions_linear.py</a>
for many examples. DIMENSION works with DXF R12, but you will get better results with DXF R2000 and later.</p>
<h2>Linux</h2>
<p>Run tests by tox on Manjaro Linux in an VM on VirtualBox.</p>
<h2>Fonts</h2>
<p>Replaced all fonts by open source fonts.</p>Release v0.8.102019-02-24T00:00:00+01:002019-02-24T00:00:00+01:00mozmantag:ezdxf.mozman.at,2019-02-24:/release-v0-8-10.html<div class="section" id="news">
<h2>News</h2>
<blockquote>
<ul class="simple">
<li>BUGFIX release for Python 2 compatible main version 0.8</li>
<li>renamed groups.py into dxfgroups.py to avoid conflicts with cython</li>
<li>added encoding to files containing utf-8 characters (chr15m)</li>
<li>fixed some issues when running on linux</li>
<li>BUGFIX: closed LWPOLYLINE did not work with AutoCAD (order matters), introduced with v0 …</li></ul></blockquote></div><div class="section" id="news">
<h2>News</h2>
<blockquote>
<ul class="simple">
<li>BUGFIX release for Python 2 compatible main version 0.8</li>
<li>renamed groups.py into dxfgroups.py to avoid conflicts with cython</li>
<li>added encoding to files containing utf-8 characters (chr15m)</li>
<li>fixed some issues when running on linux</li>
<li>BUGFIX: closed LWPOLYLINE did not work with AutoCAD (order matters), introduced with v0.8.9 packed data</li>
</ul>
</blockquote>
</div>
Release v0.8.92018-11-28T00:00:00+01:002018-11-28T00:00:00+01:00mozmantag:ezdxf.mozman.at,2018-11-28:/release-v0-8-9.html<div class="section" id="news">
<h2>News</h2>
<blockquote>
<ul class="simple">
<li>IMPORTANT: Python 2 support will be dropped in ezdxf v0.9.0, because Python 2 support get more and more annoying.</li>
<li>CHANGE: refactoring of internal tag representation for a smaller memory footprint, but with some speed penalty</li>
<li>NEW: packed data for LWPOLYLINE, SPLINE, MESH</li>
<li>NEW: data queries over all …</li></ul></blockquote></div><div class="section" id="news">
<h2>News</h2>
<blockquote>
<ul class="simple">
<li>IMPORTANT: Python 2 support will be dropped in ezdxf v0.9.0, because Python 2 support get more and more annoying.</li>
<li>CHANGE: refactoring of internal tag representation for a smaller memory footprint, but with some speed penalty</li>
<li>NEW: packed data for LWPOLYLINE, SPLINE, MESH</li>
<li>NEW: data queries over all layouts and blocks</li>
<li>NEW: change entity redraw order in layouts</li>
<li>NEW: <code>ezdxf.algebra.Arc</code> helper class for arcs</li>
<li>CHANGE: Safe deleting of block definitions</li>
<li>NEW: rename paper space layouts by <code>Drawing.layouts.rename(old_name, new_name)</code></li>
<li>NEW: <code>BlockLayout.is_layout_block</code>, True if block is a model space or paper space block definition</li>
<li>NEW: Basic support for embedded objects (new in AutoCAD 2018)</li>
<li>BUGFIX: invalid CLASS definition for DXF version R2000 (AC1015) fixed, bug was only triggered at upgrading from R13/R14 to R2000</li>
<li><cite>Basic</cite> read support for many missing DXF entities/objects</li>
</ul>
</blockquote>
</div>
<div class="section" id="dropping-python-2-support">
<h2>Dropping Python 2 support</h2>
<p><strong>Python 2</strong> support will be dropped in <em>ezdxf</em> v0.9.0, for more information look at this
<a class="reference external" href="/dropping-python2-support.html">posting</a> .</p>
</div>
<div class="section" id="refactoring-for-a-smaller-memory-footprint">
<h2>Refactoring for a smaller memory footprint</h2>
<p>Some entities (LWPOLYLINE, SPLINE, MESH, ...) using now <code>array.array()</code> for repeating tags like vertices, edge and face
indices (packed data), this reduces the memory usage, but also adds some runtime penalty.</p>
</div>
<div class="section" id="lwpolyline">
<h2>LWPOLYLINE</h2>
<p>LWPOLYLINE has now packed data, (x, y) coordinates, start- and end width and bulge are stored as 8-byte double values in
an <code>array.array()</code>. Faster point access by <code>__getitem__()</code>, added <code>__setitem__()</code>, <code>__delitem__()</code>,
<code>insert()</code> and <code>append()</code> methods.</p>
<p>With the new data structure, getting vertices is now faster and has full support for slicing operations:</p>
<pre class="literal-block">
line = layout.add_lwpolyline([(1, 1), (2, 2), (3, 3)])
# modify existing vertex
line[0] = (4, 4)
assert (4, 4, 0, 0, 0) == line[0]
# slicing vertices
assert len(line[:-1]) == 2
# len support
# assert len(line) == 3
</pre>
<p>User defined point format for append(), insert(), append_points(), points(), get_points() and set_points(). The user
defined format allows reordering of point components: coordinates 'x, y' , start width 's', end width 'e' and
bulge value 'b' , default format is 'xyseb'.</p>
<p>If you just need x, y and bulge value:</p>
<pre class="literal-block">
points = line.get_points(format="xyb")
</pre>
<p>Renamed <code>discard_points()</code> in <code>clear()</code>. Removed <code>get_rstrip_points()</code> and context manager
<code>rstrip_points()</code>, which can be replaced by using an user defined point format.</p>
<p>For more see the documentation for LWPolyline: <a class="reference external" href="https://ezdxf.mozman.at/docs/dxfentities/lwpolyline.html">https://ezdxf.mozman.at/docs/dxfentities/lwpolyline.html</a></p>
</div>
<div class="section" id="spline">
<h2>SPLINE</h2>
<p>SPLINE has packed data:</p>
<blockquote>
<ul class="simple">
<li>knots and weights are stored as 4-byte float arrays</li>
<li>fit- and control points are stored as 8-byte double arrays</li>
</ul>
</blockquote>
<p>Access methods <code>get_knot_values()</code>, <code>get_weights()</code>, <code>get_control_points()</code> and
<code>get_fit_points()</code> are deprecated, direct access to this attributes by <code>Spline.knot_values</code>,
<code>Spline.weights</code>, <code>Spline.control_points</code> and <code>Spline.fit_points</code>, all with a list-like interface.</p>
<p>Knot, fit- and control point counter updated automatically, therefore counters are read only now.</p>
<p>Editing a mesh by <code>Spline.edit_data()</code> context manager still works the same way as in previous versions.</p>
<p>For more see the documentation for Spline: <a class="reference external" href="https://ezdxf.mozman.at/docs/dxfentities/spline.html">https://ezdxf.mozman.at/docs/dxfentities/spline.html</a></p>
</div>
<div class="section" id="mesh">
<h2>MESH</h2>
<p>MESH has packed data.</p>
<blockquote>
<ul class="simple">
<li>vertices are stored as 8-byte double arrays</li>
<li>edges are stored as 8-byte double arrays</li>
<li>faces ands creases are stored as list of arrays(), array type depends from data: byte, integer or long</li>
</ul>
</blockquote>
<p>Editing a mesh by <code>Mesh.edit_data()</code> context manager still works the same way as in previous versions.</p>
<p>For more see the documentation for Mesh: <a class="reference external" href="https://ezdxf.mozman.at/docs/dxfentities/mesh.html">https://ezdxf.mozman.at/docs/dxfentities/mesh.html</a></p>
</div>
<div class="section" id="data-queries-over-all-layouts-and-blocks">
<h2>Data queries over all layouts and blocks</h2>
<blockquote>
<ul class="simple">
<li><code>Drawing.layouts_and_blocks()</code>: iterate over all layouts (mode space and paper space) and all block definitions</li>
<li><code>Drawing.chain_layouts_and_blocks()</code>: chain entity spaces of all layouts and blocks. Yields an iterator for all entities in all layouts and blocks</li>
<li><code>Drawing.query()</code>: entity query over all layouts and blocks</li>
<li><code>Drawing.groupby()</code>: groups DXF entities of all layouts and blocks by an DXF attribute or a key function</li>
</ul>
</blockquote>
<p>For more see the documentation for Drawing: <a class="reference external" href="https://ezdxf.mozman.at/docs/drawing.html">https://ezdxf.mozman.at/docs/drawing.html</a></p>
</div>
<div class="section" id="change-entity-redraw-order-in-layouts">
<h2>Change entity redraw order in layouts</h2>
<p>To change redraw order associate a different sort handle to entities, this redefines the order in which the entities
are regenerated.</p>
<blockquote>
<ul class="simple">
<li><code>Layout.get_redraw_order()</code></li>
<li><code>Layout.set_redraw_order(handles)</code>: set redraw order of entities in model space or paper space layouts</li>
</ul>
</blockquote>
<p>For more see the documentation for Layout: <a class="reference external" href="https://ezdxf.mozman.at/docs/layouts.html#change-redraw-order">https://ezdxf.mozman.at/docs/layouts.html#change-redraw-order</a></p>
</div>
<div class="section" id="safe-deleting-of-block-definitions">
<h2>Safe deleting of block definitions</h2>
<p>Changed behavior for deleting BLOCK definitions.</p>
<blockquote>
<ul class="simple">
<li><code>Drawing.blocks.delete_block(name, safe=True)</code>, new parameter save, check if block is still referenced(raises DXFValueError)</li>
<li><code>Drawing.blocks.delete_all_blocks(safe=True)</code>, if parameter safe is True, do not delete blocks that are still referenced</li>
</ul>
</blockquote>
</div>
<div class="section" id="algebra-helper-class-for-arcs">
<h2>Algebra helper class for arcs</h2>
<p>New helper class <code>ezdxf.algebra.Arc</code> to create arcs from 2 points and an angle or radius, or from 3 points.</p>
<p>For more see the documentation for ezdxf.algebra.Arc: <a class="reference external" href="https://ezdxf.mozman.at/docs/algebra/arc.html">https://ezdxf.mozman.at/docs/algebra/arc.html</a></p>
</div>
<div class="section" id="support-for-dxf-r2018-embedded-objects">
<h2>Support for DXF R2018 embedded objects</h2>
<p>Basic support for embedded objects (new in AutoCAD 2018), ezdxf reads and writes the embedded data as it is, no
interpretation no modification, just enough to not break DXF files with embedded objects at saving.</p>
</div>
<div class="section" id="basic-read-support-many-additional-dxf-entities">
<h2>Basic read support many additional DXF entities</h2>
<blockquote>
<ul class="simple">
<li>ACAD_PROXY_GRAPHIC</li>
<li>HELIX</li>
<li>LEADER</li>
<li>LIGHT</li>
<li>MLEADER (incomplete)</li>
<li>MLINE (incomplete)</li>
<li>OLEFRAME</li>
<li>OLE2FRAME</li>
<li>SECTION</li>
<li>TABLE (incomplete)</li>
<li>TOLERANCE</li>
<li>WIPEOUT</li>
<li>ACAD_PROXY_OBJECT</li>
<li>DATATABLE</li>
<li>DICTIONARYVAR</li>
<li>DIMASSOC</li>
<li>FIELD (incomplete)</li>
<li>FIELDLIST (not documented by Autodesk)</li>
<li>IDBUFFER</li>
<li>LAYER_FILTER</li>
<li>MATERIAL</li>
<li>MLEADERSTYLE</li>
<li>MLINESTYLE</li>
<li>SORTENTSTABLE</li>
<li>SUN</li>
<li>SUNSTUDY (incomplete) (no real world DXF files with SUNSTUDY for testing available)</li>
<li>TABLESTYLE (incomplete)</li>
<li>VBA_PROJECT (no real world DXF files with embedded VBA for testing available)</li>
<li>VISUALSTYLE</li>
<li>WIPEOUTVARIABLES</li>
<li>for all other unsupported entities/objects exists only raw DXF tag support</li>
</ul>
</blockquote>
</div>
Relationship of dxfwrite, dxfgrabber and ezdxf2018-07-28T00:00:00+02:002018-07-28T00:00:00+02:00mozmantag:ezdxf.mozman.at,2018-07-28:/relationship-dxfwrite-dxfgrabber-ezdxf.html<p>This post should clarify the relationship between <em>dxfwrite</em>, <em>dxfgrabber</em> an <em>ezdxf</em>.</p>
<p><strong>TL;DR:</strong> use <em>ezdxf</em>, it includes all features of <em>dxfwrite</em> and <em>dxfgrabber</em> and more</p>
<div class="section" id="dxfwrite">
<h2>dxfwrite</h2>
<p><em>dxfwrite</em> is my first DXF related Python package, I started the project in 2010:</p>
<ul class="simple">
<li><em>dxfwrite</em> just writes DXF R12 compatible DXF files</li>
<li>has no …</li></ul></div><p>This post should clarify the relationship between <em>dxfwrite</em>, <em>dxfgrabber</em> an <em>ezdxf</em>.</p>
<p><strong>TL;DR:</strong> use <em>ezdxf</em>, it includes all features of <em>dxfwrite</em> and <em>dxfgrabber</em> and more</p>
<div class="section" id="dxfwrite">
<h2>dxfwrite</h2>
<p><em>dxfwrite</em> is my first DXF related Python package, I started the project in 2010:</p>
<ul class="simple">
<li><em>dxfwrite</em> just writes DXF R12 compatible DXF files</li>
<li>has no dependencies</li>
<li>can't read DXF files</li>
<li><em>dxfwrite</em> is in maintenance only mode, no further development, just bugfxes.</li>
<li>smaller memory footprint than <em>ezdxf</em></li>
<li><em>dxfwrite</em> has a different API than <em>ezdxf</em></li>
</ul>
</div>
<div class="section" id="dxfgrabber">
<h2>dxfgrabber</h2>
<p>While <em>dxfwrite</em> 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 <em>ezdxf</em> in 2011, but the progress was so slow, that I
created a spin off in 2012: <em>dxfgrabber</em>, which implements only the reading part of <em>ezdxf</em>, which I needed for my work
and I wasn't sure if <em>ezdxf</em> will ever be usable.</p>
<ul class="simple">
<li><em>dxfgrabber</em> is a read only package for DXF files.</li>
<li>supports all DXF versions</li>
<li>has no dependencies</li>
<li>can't write DXF files</li>
<li><em>dxfgrabber</em> is in maintenance only mode, no further development, just bugfixes.</li>
<li>smaller memory footprint than ezdxf</li>
<li><em>dxfgrabber</em> has a different API than <em>ezdxf</em></li>
</ul>
</div>
<div class="section" id="ezdxf">
<h2>ezdxf</h2>
<p>2014 the first usable versions (> 0.4) of <em>ezdxf</em> was released. <em>ezdxf</em> has all the features of <em>dxfwrite</em> and
<em>dxfgrabber</em> and much more, but with a different API. So <em>ezdxf</em> is not a drop-in replacement for <em>dxfgrabber</em> or
<em>dxfwrite</em>.</p>
<ul class="simple">
<li>read/write/new support for DXF versions: R12, R2000, R2004, R2007, R2010, R2013 and R2018</li>
<li>additional read support for DXF versions R13/R14 (upgraded to R2000)</li>
<li>additional read support for older DXF versions than R12 (upgraded to R12)</li>
<li>keeps the whole drawing as tags in memory</li>
<li>preserves third-party DXF content</li>
<li>under SLOW development, but it's still alive</li>
<li>requires <a class="reference external" href="https://pypi.org/project/pyparsing/">pyparsing</a></li>
<li>additional fast DXF R12 writer, that creates just an ENTITIES section with support for the basic DXF entities</li>
</ul>
<p>Since <em>ezdxf</em> can do all the things that <em>dxfwrite</em> and <em>dxfgrabber</em> can do, I focused on the development of <em>ezdxf</em>,
<em>dxfwrite</em> and <em>dxfgrabber</em> are in maintenance mode only and will not get any new features, just bugfixes.</p>
</div>
Dropping Python 2 Support2018-05-06T00:00:00+02:002018-05-06T00:00:00+02:00mozmantag:ezdxf.mozman.at,2018-05-06:/dropping-python2-support.html<p><strong>Python 2</strong> support will be dropped in <em>ezdxf</em> v0.9.0, because <strong>Python 2</strong> support get more and more annoying.
<em>ezdxf</em> v0.9.0 requires at least <strong>Python 3.5</strong>. I wanted Python 3.6 because I would like to use f-strings, but pypy
is just at Python 3.5 …</p><p><strong>Python 2</strong> support will be dropped in <em>ezdxf</em> v0.9.0, because <strong>Python 2</strong> support get more and more annoying.
<em>ezdxf</em> v0.9.0 requires at least <strong>Python 3.5</strong>. I wanted Python 3.6 because I would like to use f-strings, but pypy
is just at Python 3.5 support level.</p>
<p>Some reasons are:</p>
<blockquote>
<ul class="simple">
<li>problems by implementing DXFBinaryTags() based on bytes</li>
<li>can't use <code>yield from</code></li>
<li>can't use <code>nonlocal</code></li>
<li>array.array() has no 64-bit integer type in Python 2</li>
<li>can't use f-strings (until pypy supports Python 3.6)</li>
</ul>
</blockquote>
<p>An important fact is also, that I am coding for fun, and sticking on Python 2 features is not fun.</p>
<p>There will be an <em>ezdxf</em> v0.8.9 release with Python 2 support and may be some 0.8.* bugfix releases, but that's it.</p>
<p>If you have to stay on Python 2, add this line to your requirements.txt:</p>
<pre class="literal-block">
ezdxf<0.9.0
</pre>
Release v0.8.82018-04-02T00:00:00+02:002018-04-02T00:00:00+02:00mozmantag:ezdxf.mozman.at,2018-04-02:/release-v0-8-8.html<div class="section" id="news">
<h2>News</h2>
<ul class="simple">
<li>NEW: Object Coordinate System support by DXFEntity.ocs() and OCS() class in module ezdxf.algebra</li>
<li>NEW: User Coordinate System support by UCS() class in module ezdxf.algebra</li>
<li>NEW: read/write support for GEODATA entity</li>
<li>NEW: support for extension dictionaries</li>
<li>NEW: read/(limited)write support for SURFACE, EXTRUDEDSURFACE, REVOLVEDSURFACE, LOFTEDSURFACE …</li></ul></div><div class="section" id="news">
<h2>News</h2>
<ul class="simple">
<li>NEW: Object Coordinate System support by DXFEntity.ocs() and OCS() class in module ezdxf.algebra</li>
<li>NEW: User Coordinate System support by UCS() class in module ezdxf.algebra</li>
<li>NEW: read/write support for GEODATA entity</li>
<li>NEW: support for extension dictionaries</li>
<li>NEW: read/(limited)write support for SURFACE, EXTRUDEDSURFACE, REVOLVEDSURFACE, LOFTEDSURFACE and SWEPTSURFACE entity</li>
<li>NEW: add_spline_control_frame(), create and add B-spline control frame from fit points</li>
<li>NEW: add_spline_approx(), approximate B-spline by a reduced count of control points</li>
<li>NEW: ezdxf.setup_linetypes(dwg), setup standard line types</li>
<li>NEW: ezdxf.setup_styles(dwg), setup standard text styles</li>
<li>NEW: LWPolyline.vertices() yields all points as (x, y) tuples in OCS, LWPolyline.dxf.elevation is the z-axis value</li>
<li>NEW: LWPolyline.vertices_in_wcs() yields all points as (x, y, z) tuples in WCS</li>
<li>NEW: bulge related function in module ezdxf.algebra.bulge</li>
<li>NEW: basic __str__() and __repr__() support for DXF entities, returns just DXF type and handle</li>
<li>CHANGE: DXFEntity.set_app_data() and DXFEntity.set_xdata() accept also list of tuples as tags, DXFTag() is not required</li>
<li>BUGFIX: entity structure validator excepts group code >= 1000 before XDATA section (used in AutoCAD Civil 3D and AutoCAD Map 3D)</li>
</ul>
</div>
<div class="section" id="ocs-and-ucs-support">
<h2>OCS and UCS Support</h2>
<p>For placing 2D entities like CIRCLE, ARC or TEXT in 3D space, you have to use the Object Coordinate System (OCS).
This release adds support for <a class="reference external" href="https://ezdxf.mozman.at/docs/dxfinternals/coordinate_systems.html#ocs">OCS</a> and <a class="reference external" href="https://ezdxf.mozman.at/docs/dxfinternals/coordinate_systems.html#ucs">UCS</a> and a <a class="reference external" href="https://ezdxf.mozman.at/docs/tutorials/ocs_usage.html">tutorial</a> how to use it. For deeper insights into OCS go
<a class="reference external" href="https://ezdxf.mozman.at/docs/dxfinternals/ocs.html#object-coordinate-system">here</a></p>
<img alt="2D text placed in 3D space" class="align-center" src="image/text_in_3d_space.png" style="width: 280px;" />
<p>Because of the nature of <em>ezdxf</em> as interface to the DXF format, the conversion from OCS and to OCS will not applied
automatically, you always get the data that is written in the DXF file. You have to do this conversion manually
(<a class="reference external" href="https://ezdxf.mozman.at/docs/tutorials/ocs_usage.html">tutorial</a>), but most of the time this conversion is not necessary, because the default extrusion is (0, 0, 1)
and for extrusion = (0, 0, 1) OCS and WCS are identical.</p>
</div>
<div class="section" id="geodata-entity">
<h2>GEODATA Entity</h2>
<p>Support for the <a class="reference external" href="https://ezdxf.mozman.at/docs/geodata_entity.html">GEODATA</a> entity in the objects section. I don't know how it works, but if you do, you can use it now,
and maybe you write me an email to explain how it works.</p>
<p>The GEODATA entity is linked to an entity by an extension dictionary, so it is possible to link GEODATA to any DXF
entity you want, but I think just a link to the model space is useful. The method <code>get_geodata()</code> and
<code>new_geodata()</code> are members of the <code>Layout()</code> class. So model space and paper space layouts are supported,
but as I said, I don't think paper space layout really use GEODATA. For usage see example: <a class="reference external" href="https://github.com/mozman/ezdxf/blob/master/examples/using_geodata.py">examples/using_geodata.py</a></p>
</div>
<div class="section" id="extension-dictionary">
<h2>Extension Dictionary</h2>
<p>For the implementation of GEODATA was also support for extension dictionary usage required.</p>
</div>
<div class="section" id="surface-entity">
<h2>SURFACE Entity</h2>
<p>The <a class="reference external" href="https://ezdxf.mozman.at/docs/surface_entity.html">SURFACE</a> entity has some sub types as individual DXF types, which are supported now:</p>
<ul class="simple">
<li>EXTRUDEDSURFACE</li>
<li>REVOLVEDSURFACE</li>
<li>LOFTEDSURFACE</li>
<li>SWEPTSURFACE</li>
</ul>
</div>
<div class="section" id="additional-spline-factory-functions">
<h2>Additional Spline Factory Functions</h2>
<p>All layouts support the following spline factory functions:</p>
<ul class="simple">
<li><code>add_spline_control_frame()</code>, create and add B-spline control frame from fit points.</li>
<li><code>add_spline_approx()</code>, approximate B-spline by a reduced count of control points, given are the fit points and the degree of the B-spline.</li>
</ul>
</div>
<div class="section" id="drawing-setup">
<h2>Drawing Setup</h2>
<p>Setup some standard linetypes and text styles: <a class="reference external" href="https://github.com/mozman/ezdxf/blob/master/ezdxf/tools/standards.py">standards.py</a></p>
<ul class="simple">
<li><code>ezdxf.setup_linetypes(dwg)</code>, setup standard line types</li>
<li><code>ezdxf.setup_styles(dwg)</code>, setup standard text styles</li>
</ul>
</div>
<div class="section" id="lwpolyline">
<h2>LWPolyline</h2>
<p><code>LWPolyline.vertices()</code> yields all points as (x, y) tuples in <a class="reference external" href="https://ezdxf.mozman.at/docs/dxfinternals/coordinate_systems.html#ocs">OCS</a>, <code>LWPolyline.dxf.elevation</code> is the
z-axis value for all the vertices. <code>LWPolyline.vertices_in_wcs()</code> yields all points as (x, y, z) tuples in WCS as
3D points.</p>
</div>
<div class="section" id="bulge-calculation">
<h2>Bulge Calculation</h2>
<p>The bulge value is used to create arc shaped line segments. The bulge defines the ratio of the arc sagitta (versine) to
half line segment length, a bulge value of 1 defines a semicircle. Bulge values are used in LWPolyline and 2D Polyline
entities.</p>
<p>Added some <a class="reference external" href="https://ezdxf.mozman.at/docs/algebra.html#bulge-related-functions">bulge related functions</a>, source of algorithms:</p>
<ul class="simple">
<li><a class="reference external" href="http://www.lee-mac.com/bulgeconversion.html">http://www.lee-mac.com/bulgeconversion.html</a></li>
<li><a class="reference external" href="http://www.afralisp.net/archive/lisp/Bulges1.htm">http://www.afralisp.net/archive/lisp/Bulges1.htm</a></li>
</ul>
</div>
<div class="section" id="misc">
<h2>Misc</h2>
<ul class="simple">
<li>Added basic <code>__str__()</code> and <code>__repr__()</code> support for DXF entities, returns just DXF type and its handle
like <tt class="docutils literal"><span class="pre">LINE(#FFFF)</span></tt></li>
<li><code>DXFEntity.set_app_data()</code> and <code>DXFEntity.set_xdata()</code> accept also list of tuples as tags, import of
<code>DXFTag()</code> is not required.</li>
<li>The entity structure validator excepts group code >= 1000 before XDATA section, I wasn't aware that group code >= 1000
out side of the XDATA section at the end of an entity is allowed, and I am still not convinced that it is, but
because Autodesk uses such group code before the XDATA section in undocumented entities in Civil 3D and Map 3D, I
assume it is now part of the DXF standard.</li>
</ul>
</div>
Release v0.8.72018-03-04T00:00:00+01:002018-03-04T00:00:00+01:00mozmantag:ezdxf.mozman.at,2018-03-04:/release-v0-8-7.html<div class="section" id="news">
<h2>News</h2>
<ul class="simple">
<li>NEW: entity.get_layout() returns layout in which entity resides or None if unassigned</li>
<li>NEW: copy any DXF entity by entity.copy() without associated layout, add copy to any layout you want, by
layout.add_entity().</li>
<li>NEW: copy entity to another layout by entity.copy_to_layout(layout)</li>
<li>NEW: move entity from actual …</li></ul></div><div class="section" id="news">
<h2>News</h2>
<ul class="simple">
<li>NEW: entity.get_layout() returns layout in which entity resides or None if unassigned</li>
<li>NEW: copy any DXF entity by entity.copy() without associated layout, add copy to any layout you want, by
layout.add_entity().</li>
<li>NEW: copy entity to another layout by entity.copy_to_layout(layout)</li>
<li>NEW: move entity from actual layout to another layout by entity.move_to_layout(layout)</li>
<li>NEW: support for splines by control points: add_open_spline(), add_closed_spline(), add_rational_spline(),
add_closed_rational_spline()</li>
<li>NEW: bspline_control_frame() calculates B-spline control points from fit points, but not the same as AutoCAD</li>
<li>NEW: R12Spline add-on, 2d B-spline with control frame support by AutoCAD, but curve is just an approximated POLYLINE</li>
<li>NEW: added entity.get_flag_state() and entity.set_flag_state() for easy access to binary coded flags</li>
<li>NEW: set new $FINGERPRINTGUID for new drawings</li>
<li>NEW: set new $VERSIONGUID on saving a drawing</li>
<li>NEW: improved IMAGE support, by adding RASTERVARIABLES entity, use Drawing.set_raster_variables(frame, quality, units)</li>
<li>BUGFIX: closing user defined image boundary path automatically, else AutoCAD crashes</li>
</ul>
</div>
<div class="section" id="copying-entities">
<h2>Copying Entities</h2>
<p>Create a copy of an entity by <code>entity.copy()</code>, the new entity has a new handle but no owner
(correct owner handle = '0') everything else is identical to the source entity.
Without adding the new entity to a layout by <code>layout.add_entity()</code>, the new entity will not show up in
the saved DXF file. You can add the new entity to any layout type: model space, paper space layout or block layout</p>
<p>Copy entity to another layout by simplified method call <code>entity.copy_to_layout()</code>:</p>
<div class="highlight"><pre><span></span><span class="c1"># create a duplicate</span>
<span class="n">new_entity</span> <span class="o">=</span> <span class="n">entity</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="c1"># add duplicate to another layout</span>
<span class="n">another_layout</span><span class="o">.</span><span class="n">add_entity</span><span class="p">(</span><span class="n">new_entity</span><span class="p">)</span>
<span class="c1"># simplified method call</span>
<span class="n">entity</span><span class="o">.</span><span class="n">copy_to_layout</span><span class="p">(</span><span class="n">another_layout</span><span class="p">)</span>
</pre></div>
</div>
<div class="section" id="moving-entities-between-layouts">
<h2>Moving Entities Between Layouts</h2>
<p>Move entity to another layout by <code>entity.move_to_layout()</code>:</p>
<div class="highlight"><pre><span></span><span class="c1"># move entity from old_layout to new_layout</span>
<span class="n">old_layout</span><span class="o">.</span><span class="n">move_to_layout</span><span class="p">(</span><span class="n">entity</span><span class="p">,</span> <span class="n">new_layout</span><span class="p">)</span>
<span class="c1"># simplified method call, but works only for entities in model space or</span>
<span class="c1"># paper space layouts</span>
<span class="n">entity</span><span class="o">.</span><span class="n">move_to_layout</span><span class="p">(</span><span class="n">new_layout</span><span class="p">)</span>
<span class="c1"># for DXF R12 and entity resides in a block layout, it is faster to provide the source layout</span>
<span class="c1"># because ezdxf has to search all block layouts</span>
<span class="n">entity</span><span class="o">.</span><span class="n">move_to_layout</span><span class="p">(</span><span class="n">new_layout</span><span class="p">,</span> <span class="n">source</span><span class="o">=</span><span class="n">old_block_layout</span><span class="p">)</span>
</pre></div>
</div>
<div class="section" id="spline-by-control-points">
<h2>Spline by Control Points</h2>
<p>Splines defined by control points do not go through control points as splines defined by fit points.</p>
<p>The <code>layout.add_spline()</code> just created splines with fit points automatically, if you wanted splines with control
points the setup had to be done by yourself.</p>
<div class="highlight"><pre><span></span><span class="n">spline</span> <span class="o">=</span> <span class="n">layout</span><span class="o">.</span><span class="n">add_spline</span><span class="p">()</span>
<span class="n">spline</span><span class="o">.</span><span class="n">set_control_points</span><span class="p">(</span><span class="n">control_points</span><span class="p">)</span>
<span class="c1"># set correct knot vector, if you know how to construct a valid knot array</span>
<span class="n">spline</span><span class="o">.</span><span class="n">set_knot_values</span><span class="p">(</span><span class="n">knot_values</span><span class="p">)</span>
<span class="c1"># and set flags</span>
<span class="n">spline</span><span class="o">.</span><span class="n">dxf</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">spline</span><span class="o">.</span><span class="n">PERIODIC</span> <span class="o">|</span> <span class="n">spline</span><span class="o">.</span><span class="n">RATIONAL</span>
</pre></div>
<p>This procedure is now simplified by 4 new factory functions.</p>
<div class="section" id="open-b-spline">
<h3>Open B-Spline</h3>
<p><code>Layout.add_open_spline(control_points, degree=3, knots=None, dxfattribs=None)</code></p>
<p>Add an open uniform B-spline, control_points is a list of (x, y, z) tuples,
degree specifies degree of spline, knots values by default not necessary.
(requires DXF version R2000+)</p>
<p>Open uniform B-splines start and end at your first and last control points.</p>
</div>
<div class="section" id="closed-b-spline">
<h3>Closed B-Spline</h3>
<p><code>Layout.add_closed_spline(control_points, degree=3, knots=None, dxfattribs=None)</code></p>
<p>Add a closed uniform B-spline, control_points is a list of (x, y, z) tuples,
degree specifies degree of spline, knots values by default not necessary.
(requires DXF version R2000+)</p>
<p>Closed uniform B-splines is a closed curve start and end at the first control points.</p>
</div>
<div class="section" id="open-rational-b-spline">
<h3>Open Rational B-Spline</h3>
<p><code>Layout.add_rational_spline(control_points, weights, degree=3, knots=None, dxfattribs=None)</code></p>
<p>Add an open rational uniform B-spline, control_points is a list of (x, y, z)
tuples, weights is a list of values, which defines the influence of the associated
control point, therefor count of control points has to be equal to the count of
weights, degree specifies degree of spline, knots values by default not necessary.
(requires DXF version R2000+)</p>
<p>Open rational uniform B-splines start and end at your first and last control points,
and have additional control possibilities by weighting each control point.</p>
</div>
<div class="section" id="closed-rational-b-spline">
<h3>Closed Rational B-Spline</h3>
<p><code>Layout.add_closed_rational_spline(control_points, weights, degree=3, knots=None, dxfattribs=None)</code></p>
<p>Add a closed rational uniform B-spline, control_points is a list of (x, y, z) tuples,
weights is a list of values, which defines the influence of the associated control point,
therefor count of control points has to be equal to the count of weights, degree specifies
degree of spline, knots values by default not necessary. (requires DXF version R2000+)</p>
<p>Closed rational uniform B-splines start and end at the first control point, and have
additional control possibilities by weighting each control point.</p>
<p>Examples:</p>
<ul class="simple">
<li><a class="reference external" href="https://github.com/mozman/ezdxf/blob/develop/examples/using_spline.py">examples/using_spline.py</a></li>
<li><a class="reference external" href="https://github.com/mozman/ezdxf/blob/develop/examples/addons/using_spline_addon.py">examples/addons/using_spline_addon.py</a></li>
</ul>
</div>
<div class="section" id="get-set-binary-coded-flags">
<h3>Get/Set Binary Coded Flags</h3>
<p>Added a more convenient method to get/set binary coded flags.</p>
</div>
</div>
Release v0.8.62018-02-17T00:00:00+01:002018-02-17T00:00:00+01:00mozmantag:ezdxf.mozman.at,2018-02-17:/release-v0-8-6.html<div class="section" id="news">
<h2>News</h2>
<ul class="simple">
<li>NEW: ezdxf project website: <a class="reference external" href="https://ezdxf.mozman.at/">https://ezdxf.mozman.at/</a></li>
<li>CHANGE: create all missing tables of the TABLES sections for DXF R12</li>
<li>BUGFIX: entities on new layouts will be saved</li>
<li>NEW: Layout.page_setup() and correct 'main' viewport for DXF R2000+; For DXF R12 page_setup() exists, but does not
provide useful results …</li></ul></div><div class="section" id="news">
<h2>News</h2>
<ul class="simple">
<li>NEW: ezdxf project website: <a class="reference external" href="https://ezdxf.mozman.at/">https://ezdxf.mozman.at/</a></li>
<li>CHANGE: create all missing tables of the TABLES sections for DXF R12</li>
<li>BUGFIX: entities on new layouts will be saved</li>
<li>NEW: Layout.page_setup() and correct 'main' viewport for DXF R2000+; For DXF R12 page_setup() exists, but does not
provide useful results. Page setup for DXF R12 is still a mystery to me.</li>
<li>NEW: Table(), MText(), Ellipse(), Spline(), Bezier(), Clothoid(), LinearDimension(), RadialDimension(),
ArcDimension() and AngularDimension() composite objects from dxfwrite as addons, these addons support DXF R12</li>
<li>NEW: geometry builder as addons: MeshBuilder(), MeshVertexMerger(), MengerSponge(), SierpinskyPyramid(), these
addons require DXF R2000+ (MESH entity)</li>
<li>BUGFIX: fixed invalid implementation of context manager for r12writer</li>
</ul>
</div>
<div class="section" id="paper-space-layout-page-setup">
<h2>Paper Space Layout Page Setup</h2>
<p>This release brings page setup for paper space layouts, at least for DXF R2000+, for DXF R12 I still don't
know how page setup works.</p>
<div class="highlight"><pre><span></span><span class="n">layout</span> <span class="o">=</span> <span class="n">dwg</span><span class="o">.</span><span class="n">layouts</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">'Layout2'</span><span class="p">)</span>
<span class="n">layout</span><span class="o">.</span><span class="n">page_setup</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="p">(</span><span class="mi">297</span><span class="p">,</span> <span class="mi">210</span><span class="p">),</span> <span class="n">margins</span><span class="o">=</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">15</span><span class="p">),</span> <span class="n">units</span><span class="o">=</span><span class="s1">'mm'</span><span class="p">)</span>
</pre></div>
<p>This defines an ISO A4 page with a width of 297mm and a height of 210mm, and margin values in clockwise order: top-,
right-, bottom- and left-margin. See also example file: <a class="reference external" href="https://github.com/mozman/ezdxf/blob/master/examples/page_setup_R2000.py">examples/page_setup_R2000.py</a></p>
<p>Bugfix to save entities added to a paper space layout.</p>
</div>
<div class="section" id="add-ons-subpackage">
<h2>Add-ons Subpackage</h2>
<p>the subpackage <em>ezdxf.addons</em> contains additional modules, functions and high level helper classes.
The core <em>ezdxf</em> package stays independent from this addons.</p>
<p>For an easier transition from <em>dxfwrite</em> to <em>ezdxf</em>, I added the composite entities of <em>dxfwrite</em> as helper classes:</p>
<ul class="simple">
<li>Table(), a HTML table like entity, built from basic DXF entities</li>
<li>MText(), a MTEXT like composite for DXF R12, rendering as TEXT entities</li>
<li>Ellipse(), Spline(), Bezier(), Clothoid(): 2D curves, rendering as POLYLINE entities</li>
</ul>
<p>Other helper classes in the subpackage <em>ezdxf.addons</em>:</p>
<ul class="simple">
<li>MeshBuilder(): simple helper class for building MESH objects, renders to MESH - but a POLYLINE (Polyface) renderer is
planned</li>
<li>MeshVertexMerger(): like MeshBuilder() but removes vertex doublets.</li>
<li>MengerSponge(): just a show case entity, renders to a MESH entity</li>
<li>SierpinskyPyramid(): just a show case entity, renders to a MESH entity</li>
</ul>
</div>
<div class="section" id="tox">
<h2>Tox</h2>
<p>Because I forgot the <em>audit</em> subpackage in release v0.8.5 in setup.py, I have installed <a class="reference external" href="https://tox.readthedocs.io/en/latest/">tox</a>
in my develop environment, to verify a complete install process. I also added the <em>integration_tests</em> and associated
test data to the source install package which now has more than 1MB, but the wheel package still has less than 300kB.</p>
</div>
Release v0.8.52018-01-28T00:00:00+01:002018-01-28T00:00:00+01:00mozmantag:ezdxf.mozman.at,2018-01-28:/release-v0-8-5.html<ul class="simple">
<li>CHANGE: block names are case insensitive 'TEST' == 'Test' (like AutoCAD)</li>
<li>CHANGE: table entry (layer, linetype, style, dimstyle, ...) names are case insensitive 'TEST' == 'Test' (like AutoCAD)</li>
<li>CHANGE: raises DXFInvalidLayerName() for invalid characters in layer names: <>/":;?*|=`</li>
<li>CHANGE: audit process rewritten</li>
<li>CHANGE: skip all comments, group code 999</li>
<li>CHANGE: removed compression for unused …</li></ul><ul class="simple">
<li>CHANGE: block names are case insensitive 'TEST' == 'Test' (like AutoCAD)</li>
<li>CHANGE: table entry (layer, linetype, style, dimstyle, ...) names are case insensitive 'TEST' == 'Test' (like AutoCAD)</li>
<li>CHANGE: raises DXFInvalidLayerName() for invalid characters in layer names: <>/":;?*|=`</li>
<li>CHANGE: audit process rewritten</li>
<li>CHANGE: skip all comments, group code 999</li>
<li>CHANGE: removed compression for unused sections (THUMBNAILSECTION, ACDSDATA)</li>
<li>NEW: write DXF R12 files without handles: set dwg.header['$HANDLING']=0, default value is 1</li>
<li>added subclass marker filter for R12 and prior files in legacy_mode=True (required for malformed DXF files)</li>
<li>removed special check for malformed Leica Disto Unit DXF R12 files, use readfile(filename, legacy_mode=True)</li>
</ul>
<p>The intention of the actual progress is, to improve the stability of <em>ezdxf</em>. The low level setup process is
mostly rewritten. For debugging problems of reported issues with existing DXF files the audit functionality
is improved and <em>dxfpp</em> (DXF Pretty Printer) got a raw mode:</p>
<div class="highlight"><pre><span></span>dxfpp -r -x filename
</pre></div>
<p>Option -r for using raw mode, option -x to not compile tags, so <em>dxfpp</em> works even when <em>ezdxf</em>
breaks at reading the DXF file.</p>
Release v0.8.42018-01-14T00:00:00+01:002018-01-14T00:00:00+01:00mozmantag:ezdxf.mozman.at,2018-01-14:/release-v0-8-4.html<ul class="simple">
<li>NEW: Support for complex line types with text or shapes</li>
<li>NEW: DXF file structure validator at SECTION level, tags outside of sections will be removed</li>
<li>NEW: Basic read support for DIMENSION</li>
<li>CHANGE: improved exception management, in the future ezdxf should only raise exceptions inherited from DXFError for</li>
<li>DXF related errors …</li></ul><ul class="simple">
<li>NEW: Support for complex line types with text or shapes</li>
<li>NEW: DXF file structure validator at SECTION level, tags outside of sections will be removed</li>
<li>NEW: Basic read support for DIMENSION</li>
<li>CHANGE: improved exception management, in the future ezdxf should only raise exceptions inherited from DXFError for</li>
<li>DXF related errors, previous exception classes still work</li>
<li>speedup low level tag reader around 5%, and speedup tag compiler around 5%</li>
</ul>
<p>DXFError() Based Exceptions:</p>
<ul class="simple">
<li>DXFStructureError(DXFError)</li>
<li>DXFInternalEzdxfError(DXFError)</li>
<li>DXFEncodingError(DXFError)</li>
<li>DXFDecodingError(DXFError)</li>
<li>DXFAppDataError(DXFStructureError)</li>
<li>DXFValueError(DXFError, ValueError)</li>
<li>DXFKeyError(DXFError, KeyError)</li>
<li>DXFAttributeError(DXFError, AttributeError)</li>
<li>DXFIndexError(DXFError, IndexError)</li>
<li>DXFTypeError(DXFError, TypeError)</li>
<li>DXFInvalidLayerName(DXFValueError)</li>
<li>DXFTableEntryError(DXFValueError)</li>
</ul>
<p>The intended usage is:</p>
<div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">dwg</span> <span class="o">=</span> <span class="n">ezdxf</span><span class="o">.</span><span class="n">readfile</span><span class="p">(</span><span class="s1">'name.dxf'</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">IOError</span><span class="p">,</span> <span class="ne">FileNotFoundError</span><span class="p">):</span>
<span class="c1"># file related error handling</span>
<span class="k">except</span> <span class="n">DXFError</span><span class="p">:</span>
<span class="c1"># DXF parsing errors</span>
</pre></div>
Release v0.8.32018-01-02T00:00:00+01:002018-01-02T00:00:00+01:00mozmantag:ezdxf.mozman.at,2018-01-02:/release-v0-8-3.html<ul class="simple">
<li>CHANGE: Lwpolyline - suppress yielding z coordinates if they exists (DXFStructureError: z coordinates are not defined
in the DXF standard)</li>
<li>NEW: setup creates a script called dxfpp (DXF Pretty Printer) in the Python script folder</li>
<li>NEW: basic support for DXF format AC1032 introduced by AutoCAD 2018</li>
<li>NEW: ezdxf use logging and …</li></ul><ul class="simple">
<li>CHANGE: Lwpolyline - suppress yielding z coordinates if they exists (DXFStructureError: z coordinates are not defined
in the DXF standard)</li>
<li>NEW: setup creates a script called dxfpp (DXF Pretty Printer) in the Python script folder</li>
<li>NEW: basic support for DXF format AC1032 introduced by AutoCAD 2018</li>
<li>NEW: ezdxf use logging and writes all logs to a logger called ezdxf. Logging setup is the domain of the application!</li>
<li>NEW: warns about multiple block definitions with the same name in a DXF file. (DXFStructureError)</li>
<li>NEW: legacy_mode parameter in ezdxf.read() and ezdxf.readfile(): tries do fix coordinate order in LINE entities (10,
11, 20, 21) by the cost of around 5% overall speed penalty at DXF file loading</li>
</ul>