SDXF – Python Library for DXF

Stani’s DXF library for python is an excellent tool for writing lines, circles, and polygons in DXF format. DXF (Document Exchange Format) is an ASCII file format published by AutoCad which can be read by a variety of programs, including Blender, Maya, CorelDraw, and a host of others.

I’ll attempt to document the library here as I figure it out, and also release updates to it as I slowly add more element types. I’m learning python and the DXF format as I go along so I can’t guarantee that any of this is correct.

Download SDXF 1.1.1

Changes in 1.1.1

  • Added support for LWPOLYLINE, so you can now make a continuous polyline instead of several separate lines

Example Code

This will draw a line from (0,0) to (1,1) and “Hello World” at (3,0)

import sdxf

d=sdxf.Drawing()

#set the color of the text layer to green
d.layers.append(sdxf.Layer(name="textlayer",color=3))

#add drawing elements
d.append(sdxf.Text('Hello World!',point=(3,0),layer="textlayer"))
d.append(sdxf.Line(points=[(0,0),(1,1)], layer="drawinglayer"))

d.saveas('hello_world.dxf')

Overview

Entities

An Entity is an individual drawing object, like a line or circle. These are appended to the Drawing and rendered in the order they’re added.

Layers

Layers are used to organize entities. Layers can be assigned colors to make drawings easier to read. An entity can be assigned to a new layer on the fly, without explicitly defining the layer first.

Layer(name="mynewlayer",color=8)

Blocks

Blocks are reusable symbols. A block is defined once and can then be appended to the drawing using the Insert entity. A block can be inserted multiple times into a drawing, at different points.

#define the block, a Solid and an Arc
b=Block('test')
b.append(Solid(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=1))
b.append(Arc(center=(1,0,0),color=2))

#create a new drawing
d=Drawing()

#add the block to the Blocks table, so it can be referenced later
d.blocks.append(b)

#add entities to the drawing, including the block using the Insert entity
d.append(Circle(center=(1,1,0),color=3))
d.append(Face(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=4))
d.append(Insert('test',point=(3,3,3),cols=5,colspacing=2))
d.append(Line(points=[(0,0,0),(1,1,1)]))

Supported Entities

These entities are currently in the library. In addition to passing the arguments for the individual entity type, you can pass common arguments (group codes) which are available for all entities.

Common Group Codes

  • color – the color of the entity. Represented by a number. See the Color List below.
  • extrusion – ?
  • layer – which layer to place the element on. You do not need to explicitly declare a layer before assigning entities to it
  • lineType – ?
  • lineTypeScale – ?
  • thickness – thickness of the entity lines
  • parent – ?

Arc

Draws an arc (part of a circle).

  • center (x, y, z) – The center of the circle from which the arc is to be taken. Z is optional.
  • radius – The radius from the center to the arc
  • startAngle – The angle, in degrees, for the start of the arc.
  • endAngle – The angle, in degrees, for the end of the arc
Arc(center=(3,0),radius=2,startAngle=0,endAngle=90)

Circle

Draws a circle.

  • center (x,y,z) – the center of the circle. Z is optional.
  • radius – the radius of the circle
Arc(center=(3,0),radius=2)

Face

Creates a 3d face. A 3d face takes 4 points, which may or may not all be on the same plane.

Insert

Blocks are added to a file using the Insert entity. The block must be added to the Blocks table before it can be used.

  • name – Block name (defined when the block was added to the Blocks table)
  • point – Insertion point (x,y,z) to add the block
  • xscale – x scale factor; optional, defaults to 1
  • yscale – y scale factor; optional, defaults to 1
  • zscale – z scale factor; optional, defaults to 1
  • cols – column count; optional, defaults to 1
  • colspacing – column spacing; optional, defaults to 0
  • rows – row count; optional, defaults to 1
  • rowspacing – row spacing; optional, defaults to 0
  • rotation – rotation angle; optional, defaults to 0
Insert('test',point=(3,3,3),cols=5,colspacing=2)

Line

Makes a line! Takes a list containing two points. Points can be (x,y) or (x,y,z)

Line(points=[(0,0),(1,1)])

LwPolyLine

Makes a line with vertexes. Takes a list of points.

linePoints = [(0,0),(1,1),(1,0)]
LwPolyLine(points=linePoints,flag=1)

Polyline

In the current implementation, actually just makes a bunch of Lines rather than a polyline.

Point

A point in space. Takes a point (duh).

Solid

From what I can tell, this creates a 3D solid by taking either 3 or 4 points and then extruding the face in various directions.

Text

Renders a string as text at the given point.

Text('Hello World!',point=(3,0))

Mtext

I think this is like Text but supports line breaks. In this version of SDXF it just creates multiple Text entities.

Extras

These are not actual DXF entities, but are classes that make building other shapes easier.

Rectangle

Creates a rectangle using 4 lines. Could probably be modified to use LwPolyLine instead.

  • point – lower left (?) corner point
  • width – rectangle width
  • height – rectangle height
  • solid – ?
  • line – ?

Line List

Creates a bunch of lines from a set of points. Currently used instead of PolyLine.

  • points – list of verticies
  • closed – whether to close the shape; defaults to 0

Color List

The colors may vary depending on the rendering software used.
1 – Red
2 – Yellow
3 – Green
4 – Cyan
5 – Blue
6 – Magenta
7 – White
8 – Black

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • RSS
  • StumbleUpon
  • Twitter
  1. Thanks so much for this page Kellbot! I couldn’t find a copy of sdxf anywhere, much less such a useful and concise explanation.

    I am hoping to produce a solar concentrator dish with it — will let you know how it turns out.

    Andy :)

    Reply

  2. Hey! great page! you save mi life.! 1 cuestion: how can open a dxf that alredy exits?

    Reply

  3. I guess that xscale DXF code within Text class should be 40 instead of 41 (line #302)

    Reply

  4. This is a great tool for the kind of thing I’m trying to do (highway alignment related calculations). Unfortunately the LWPOLYLINE object doesn’t seem to work. Whenever I try and import the dxf into AutoCAD, I get an error:

    “Undefined group code 70 for object on line 138.”

    When I use the POLYLINE object (which produces many individual lines) it imports ok, but the LWPOLYLINE doesn’t seem to work.

    I’ll do more tests and see what I can discover.

    Reply

    1. Hm, interesting. I haven’t tried it with AutoCAD, just QCAD, and I honestly haven’t put it through its paces, so there’s bound to be a few snags in LWPOLYLINE. Let me know if you figure out where it’s coming from!

      Reply

  5. I am a Machinist and dxf is practically my life. I am currently working on a C library for dxf, so this can be helpful to me. Thanks!

    Reply

  6. I did a bit of messing around with the original PolyLine class during my morning commute and it seems to work now (ie. it generates a dxf containing a polyline that AutoCAD will accept), but it still needs a lot of testing. In particular I want to see if it works for polylines with different Z coordinates on each vertex. (I only tested it with an XY list.) Kell, let me know if you want me to send it to you as it is now, otherwise I’ll debug it a bit more first.

    Reply

  7. I fussed with the PolyLine class and now Autocad2009 seems to accept it.

    class PolyLine(_Entity):
    def __init__(self,points,flag=1,width=None,**common): #Not sure if any other values of flag will work
    _Entity.__init__(self,**common)
    self.points=points
    self.width=width
    self.flag=flag
    def __str__(self):
    result= ‘0\nPOLYLINE\n%s\n66\n%s\n’%\
    (self._common(),self.flag)
    result+=’%s’ %_point((0.,0.,0.))
    for point in self.points:
    result+=’\n0\nVERTEX\n8\n%s\n%s’% (self.layer,_point(point))
    if self.width:result+=’\n40\n%s\n41\n%s’%(self.width,self.width)
    result+=’\n0\nSEQEND’
    return result

    Reply

  8. I have the same issue about LwPolyLine.
    It’s show “Undefined group code 70 for object on line 138.” when I open dxf file with AutoCAD.
    Please let me know if it can be solved.
    Thanks.

    Reply

  9. thanks a bunch! This saves me a headache!

    Reply

  10. DWG TrueView and Intellicad will open the dxf generated via the module test using the following class modified from the one provided by David:
    ————————————–
    class PolyLine(_Entity):
    ”’Polyline”’
    def __init__(self, points, flag=0, width=None, **common):
    _Entity.__init__(self, **common)
    self.points = points
    self.flag = flag
    self.width = width

    def __str__(self):
    result = ‘0\nPOLYLINE\n%s\n66\n1\n70\n%s\n’ % (self._common(), self.flag)
    result += ‘%s’ % _point((0.0, 0.0, 0.0))
    for point in self.points:
    result += ‘\n0\nVERTEX\n8\n%s\n%s’ % (self.layer,_point(point))
    if self.width:
    result += ‘\n40\n%s\n41\n%s’ % (self.width, self.width)
    result += ‘\n0\nSEQEND’
    return result
    ————————–
    I’ve set code 66 as 1 and added code 70 to accept the standard polyline flags.

    In the “PolyLine” call in the module test, change “closed” to “flag”; leave the value set as “1″ for a closed polyline.

    I’ve been using the following resources to help understand the file format:
    http://autodesk.com/techpubs/autocad/acad2000/dxf/
    http://local.wasp.uwa.edu.au/~pbourke/dataformats/dxf/dxf10.html

    Reply

  11. If you visit the following site you will find a different branch of sdxf that is used by Blender and it supports Polyline. : http://wiki.blender.org/index.php/Extensions:Py/Scripts/Manual/Export/DXF
    You can download the library from here: http://cad4arch.com/blend01/prog/ble2dxf13.zip

    @Kelly
    If you have made significant changes from 1.1 perhaps the two projects could be merged?

    Reply