New general transformation interface based on homogeneous transformation matrices. Supported transformations are scale & reflection, rotate and translate.
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.
Good support for:
Problems with non uniform scaling and/or reflections:
Untested:
Unsupported:
This new transformation interface also improves results for non uniform scaling for Insert.virtual_entities()
and Insert.explode()
, therefore the argument non_uniform_scaling
to explicit enable non uniform scaling is
marked as deprecated.
Example: rotate first line in "my.dxf"
90 degrees about the z-axis
import math
import ezdxf
from ezdxf.math import Matrix44
doc = ezdxf.readfile('my.dxf')
msp = doc.modelspace()
line = msp.query('LINE').first
if line:
m = Matrix44.z_rotate(math.pi/2)
line.transform(m)
Specialized entity transformation interfaces:
translate(dx, dy, dz)
, translation in x-, y- and z-axisscale(sx, sy, sz)
, use negative values for reflectionsscale_uniform(s)
, uniform scaling in x-, y- and z-axisrotate_axis(axis, angle)
, rotate about arbitrary axis, rotation center is the origin at (0, 0, 0)rotate_x(angle)
, rotation about the x-axisrotate_y(angle)
, rotation about the y-axisrotate_z(angle)
, rotation about the z-axisSimplified example:
...
if line:
line.rotate_z(math.pi/2)
The new drawing add-on by Matt Broadway is a translation layer to send DXF data to a render backend.
Basic supported for following backends are included:
Both packages are optional and not required to install ezdxf.
The implementation uses a Frontend
object to break DXF entities down into graphic primitives and send this data to
the Backend
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.
There are two example scripts to show how to use the drawing
add-on to implement a DXF converter or DXF viewer.
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 TrueView replacement, this is beyond our capabilities, time resources and the performance of a Python based project.
Convert CIRCLE and ARC to ELLIPSE entities by default the source ARC will be replaced by the new ELLIPSE entity:
for arc in msp.query('ARC'):
arc.to_ellipse()
Set argument replace
to False
to add an additional ELLIPSE entity without deleting the source ARC:
for arc in msp.query('ARC'):
arc.to_ellipse(replace=False)
Convert CIRCLE, ARC and ELLIPSE to SPLINE entities:
for arc in msp.query('ARC'):
arc.to_spline()
The SPLINE entities have the best approximation with a minimum number of control points.
Constructors to create rational splines from arc (BSpline.from_arc()
) and ellipses (BSpline.from_ellipse()
).
Decomposition of non-rational B-splines into multiple Bezier curves by BSpline.bezier_decomposition()
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.
Interface between the SPLINE DXF entity class and the construction tool BSpline()
, Spline.construction_tool()
returns the spline as BSpline()
object and Spline.apply_construction_tool()
transfer data from the BSpline()
to
the DXF entity. The same interface exist for the ELLIPSE entity and the ConstructionEllipse()
class.
Interface to NURBS-Python to convert BSpline()
objects to
NURBS-Python curves by BSpline.to_nurbs_python_curve()
and back by BSpline.from_nurbs_python_curve()
. This
requires the installation of the geomdl
package which is the PyPI name of NURBS-Python:
pip install --user geomdl
An interface to surfaces and volumes may follow, but only from NURBS-Python to ezdxf, because without ACIS support, ezdxf is restricted to mesh objects.
Rewritten spline interpolation without and with end derivative (tangents) support as function
global_spline_interpolation()
including helper tools to estimate tangents and end tangent magnitudes.
A new local_bspline_interpolation()
function and a fast cubic_bezier_interpolation()
function also exist.
A faster linear equation solver for interpolation tasks was required: the new LUDecomposition()
is faster than the
previous gauss_*_solver()
functions and a new banded diagonal matrix solver BandedMatrixLU()
for even faster
results for bigger matrices was added, compact_banded_matrix()
is a helper function to create banded diagonal
matrices and detect_banded_matrix()
is its sidekick to auto-detect the required parameters.
Integrated derivative computation into BSpline()
and Bezier()
from special derivative classes. Instead of
overriding the point()
method, a new derivative()
method exists which returns the curve point and derivatives.
Most of this new math tools are based on two books:
MeshBuilder.from_polyface()
processing error of POLYMESH entitiesDXFGraphic.transform(m)
,
transform entity by a transformation matrix m
inplaceDXFGraphic.translate(dx, dy, dz)
DXFGraphic.scale(sx, sy, sz)
DXFGraphic.scale_uniform(s)
DXFGraphic.rotate_axis(axis, angle)
DXFGraphic.rotate_x(angle)
DXFGraphic.rotate_y(angle)
DXFGraphic.rotate_z(angle)
DXFGraphic.unlink_from_layout()
to unlink entity from associated layoutArc.angles(num)
, yields num
angles from start- to end angle in counter clockwise orderCircle.to_ellipse()
, convert CIRCLE/ARC to ELLIPSE entityCircle.to_spline()
, convert CIRCLE/ARC to SPLINE entityEllipse.params(num)
, yields num
params from start- to end param in counter clockwise orderEllipse.construction_tool()
, return ellipse data as ConstructionEllipse()
Ellipse.apply_construction_tool()
, apply ConstructionEllipse()
dataEllipse.to_spline()
, convert ELLIPSE to SPLINE entity Ellipse.from_arc()
, create a new ELLIPSE entity from CIRCLE or ARC entity (constructor)Spline.construction_tool()
, return spline data as ezdxf.math.BSpline()
Spline.apply_construction_tool()
, apply ezdxf.math.BSpline()
dataSpline.from_arc()
, create a new SPLINE entity from CIRCLE, ARC or ELLIPSE entity (constructor)Hatch.set_pattern_scale()
to set scaling of pattern definitionHatch.set_pattern_angle()
to set rotation angle of pattern definitionHatch.paths.polyline_to_edge_path()
convert polyline paths with bulge values to edge paths with lines and arcsHatch.paths.arc_edges_to_ellipse_edges()
convert arc edges to ellipse edgesHatch.paths.ellipse_edges_to_spline_edges()
convert ellipse edges to spline edgesHatch.paths.all_to_spline_edges()
convert all curves to approximated spline edgesHatch.paths.all_to_line_edges()
convert all curves to approximated line edgesText.plain_text()
returns text content without formatting codesezdxf.math.ConstructionEllipse()
ezdxf.math.linspace()
like numpy.linspace()
ezdxf.math.global_bspline_interpolation()
supports start- and end tangent constraintsezdxf.math.estimate_tangents()
curve tangent estimator for given fit pointsezdxf.math.estimate_end_tangent_magnitude()
curve end tangent magnitude estimator for given fit pointsezdxf.math.rational_spline_from_arc()
returns a rational B-spline for a circular arcezdxf.math.rational_spline_from_ellipse()
returns a rational B-spline for an elliptic arcezdxf.math.local_cubic_bspline_interpolation()
ezdxf.math.cubic_bezier_from_arc()
returns an approximation for a circular 2D arc by multiple cubic Bezier curvesezdxf.math.cubic_bezier_from_ellipse()
returns an approximation for an elliptic arc by multiple cubic Bezier curvesezdxf.math.cubic_bezier_interpolation()
returns an interpolation curve for arbitrary data points as multiple cubic Bezier curvesezdxf.math.LUDecomposition
linear equation solver, for more linear algebra tools see module ezdxf.math.linalg
ezdxf.render.random_2d_path()
generate random 2D path for testing purposeezdxf.render.random_3d_path()
generate random 3D path for testing purposeBSpline()
uses normalized knot vector for 'clamped' curves by default (open uniform knots)BSpline.points()
compute multiple pointsBSpline.derivative()
compute point and derivative up to n <= degreeBSpline.derivatives()
compute multiple points and derivatives up to n <= degreeBSpline.params()
return evenly spaced B-spline params from start- to end paramBSpline.reverse()
returns a new reversed B-splineBSpline.from_arc()
B-spline from an arc, best approximation with a minimum number of control pointsBSpline.from_ellipse()
B-spline from an ellipse, best approximation with a minimum number of control pointsBSpline.from_fit_points()
B-spline from fit points BSpline.arc_approximation()
B-spline approximation from arc vertices as fit pointsBSpline.ellipse_approximation()
B-spline approximation from ellipse vertices as fit pointsBSpline.transform()
transform B-spline by transformation matrix inplaceBSpline.transform()
transform B-spline by transformation matrix inplaceBSpline.to_nurbs_python_curve()
and BSpline.from_nurbs_python_curve()
, interface to
NURBS-Python, NURBS-Python
is now a testing dependencyBSpline.bezier_decomposition()
decompose a non-rational B-spline into multiple Bezier curves BSpline.cubic_bezier_approximation()
approximate any B-spline by multiple cubic Bezier curves Bezier.points()
compute multiple pointsBezier.derivative()
compute point, 1st and 2nd derivative for one parameterBezier.derivatives()
compute point and derivative for multiple parametersHatch
full support for rotated patterns.Hatch.set_pattern_definition()
added argument angle
for pattern rotation. Hatch.path.add_arc
renamed argument is_counter_clockwise
to ccw
, type bool
and True
by default Hatch.path.add_ellipse
renamed argument is_counter_clockwise
to ccw
, type bool
and True
by default ConstructionXXX.move()
methods to translate()
Insert.scale()
to Insert.set_scale()
, name conflict with transformation interfaceSpline.set_periodic()
to Spline.set_closed()
Spline.set_periodic_rational()
to Spline.set_closed_rational()
ezdxf.math.bspline_control_frame()
to ezdxf.math.global_bspline_interpolation()
ezdxf.math.Matrix33
class, UCS
and OCS
uses Matrix44
for transformations ezdxf.math.BRCS
class and Insert.brcs()
ezdxf.math.ConstructionTool
base classezdxf.math.normalize_angle(angle)
, replace call by expression: angle % math.tau
ezdxf.math.DBSpline
, integrated as BSpline.derivatives()
ezdxf.math.DBSplineU
, integrated as BSplineU.derivatives()
ezdxf.math.DBSplineClosed
, integrated as BSplineClosed.derivatives()
ezdxf.math.DBezier
, integrated as Bezier.derivatives()
BaseLayout.add_spline_approx()
, incorrect and nobody noticed it - so it's not really needed, if required
use the geomdl.fitting.approximate_curve()
function from the package
NURBS-Python, see example using_nurbs_python.py
ezdxf.math.bspline_control_frame_approx()
, incorrect and nobody noticed it - so it's not really needed DXFGraphic.transform_to_wcs(ucs)
, replace call by DXFGraphic.transform(ucs.matrix)
non_uniform_scaling
argument for Insert.explode()
non_uniform_scaling
argument for Insert.virtual_entities()
Hatch
for attributes paths
, gradient
, pattern
and seeds
Spline.edit_data()
all attributes accessible by propertiesezdxf.math.intersection_ray_ray_3d()
Spline.set_periodic()
created invalid data for BricsCAD - misleading information by Autodesk