dxfezdxf

DXF generation using ezdxf: polyline containing spline fit points


I am developing a program, and one of the requirements is to take DXF as input. The input is limited to 2D case only. The program itself is in C++/Qt, but to test it I need some sample DXF input. The spline import is already implemented, the next step is polyline with spline fit points or control points added. I decided to use Python/ezdxf to generate such polyline, as I don't have Autocad.

My first approach was to create a spline from fit points utilizing add_spline_control_frame, then convert it to polyline. The problem is there turned out to be no conversion from spline to polyline (although I think I saw it in the docs, but cannot find it anymore).

The current approach is to make polyline by add_polyline2d(points), making each point to be with DXF flag field equal 8 (spline vertex created by spline-fitting). The problem is points need to be of type DXFVertex (docs state Vertex, but it is absent), and that type is private for ezdxf.

Please share your approaches either to the problems I've faced with ezdxf, or to the initial problem.

P.S. I tried to use LibreCAD to generate such a polyline, but it's hardly possible to make a closed polyline from spline fit points there.


Solution

  • The ability to create B-splines by the POLYLINE entity was used by AutoCAD before in DXF R2000 the SPLINE entity was added. The usage of this feature is not documented by Autodesk and also not promoted by ezdxf in any way.

    Use the SPLINE entity if you can, but if you have to use DXF R12 - there is a helper class in ezdxf to create such splines ezdxf.render.R12Spline and an usage example here.

    But you will be disappointed BricsCAD and AutoCAD show a very visible polygon structure: enter image description here

    Because not only the control points, but also the approximated curve points have to be stored as polyline points, to get a smoother curve you have to use many approximation points, but then you can also use a regular POLYLINE as approximation. I assume the control points were only stored to keep the spline editable.

    All I know about this topic is documented in the r12spline.py file. If you find a better way to create smooth B-splines for DXF R12 with fewer approximation points, please let me know.

    Example to approximate a SPLINE entity spline as points, which can be used by the POLYLINE entity:

    bspline = spline.construction_tool()
    msp.add_polyline3d(bpline.approximate(segments=20))
    
    

    The SPLINE entity is a 3D entity, if you want to squash the spline into the xy-plane, remove the z-axis:

    xy_pts = [p.xy for p in bpline.approximate(segments=20)]
    msp.add_polyline2d(xy_pts)
    
    # or as LWPOLYLINE entity:
    msp.add_lwpolyline(xy_pts, format='xy')