diff --git a/io_import_scene_dxf.py b/io_import_scene_dxf.py
new file mode 100644
index 0000000000000000000000000000000000000000..6fef79496c950fed5b2efdf5a6150d9ee52c9e6a
--- /dev/null
+++ b/io_import_scene_dxf.py
@@ -0,0 +1,2506 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+"""
+Release note by migius (DXF support maintainer) 2011.01.02:
+Script supports only a small part of DXF specification:
+- imports LINE, ARC, CIRCLE, ELLIPSE, SOLID, TRACE, POLYLINE, LWPOLYLINE
+- imports TEXT, MTEXT
+- supports 3d-rotation of entities (210 group)
+- supports THICKNESS for SOLID, TRACE, LINE, ARC, CIRCLE, ELLIPSE
+- ignores WIDTH, THICKNESS, BULGE in POLYLINE/LWPOLYLINE
+- ignores face-data in POLYFACE / POLYMESH
+- ignores TEXT 2d-rotation
+- ignores hierarchies (BLOCK, INSERT, GROUP)
+- ignores LAYER
+- ignores COLOR, LINEWIDTH, LINESTYLE
+
+This script is a temporary solution.
+Probably no more improvements will be done to this script.
+The full-feature importer script from 2.49 will be back in 2.6 release.
+
+Installation:
+Place this file to Blender addons directory (on Windows it is %Blender_directory%\2.53\scripts\addons\)
+You must activate the script in the "Add-Ons" tab (user preferences).
+Access it from File > Import menu.
+
+History:
+ver 0.1.3 - 2011.01.02 by migius
+- added draw curves as sequence for "Draw_as_Curve"
+- added toggle "Draw as one" as user preset in UI
+- added draw POINT as mesh-vertex
+- added draw_THICKNESS for LINE, ARC, CIRCLE, ELLIPSE, LWPOLYLINE and POLYLINE
+- added draw_THICKNESS for SOLID, TRACE
+ver 0.1.2 - 2010.12.27 by migius
+- added draw() for TRACE
+- fixed wrong vertex order in SOLID
+- added CIRCLE resolution as user preset in UI
+- added closing segment for circular LWPOLYLINE and POLYLINE
+- fixed registering for 2.55beta
+ver 0.1.1 - 2010.09.07 by migius
+- fixed dxf-file names recognition limited to ".dxf"
+- fixed registering for 2.53beta
+ver 0.1 - 2010.06.10 by Thomas Larsson
+"""
+
+bl_addon_info = {
+    'name': 'Import Autocad DXF (.dxf)',
+    'author': 'Thomas Larsson',
+    'version': (0,1,3),
+    'blender': (2, 5, 6),
+    'api': 32738,
+    'location': 'File > Import',
+    'description': 'Import files in the Autocad DXF format (.dxf)',
+    'warning': 'supporting only a sub-set of DXF specification',
+    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Import-Export/DXF_Importer',
+    'tracker_url': 'https://projects.blender.org/tracker/index.php?func=detail&aid=23480&group_id=153&atid=468',
+    'category': 'Import-Export'}
+
+__version__ = '.'.join([str(s) for s in bl_addon_info['version']])
+
+import os
+import codecs
+import math
+from math import sin, cos, radians
+import bpy
+import mathutils
+from mathutils import Vector, Matrix
+
+#
+#    Global flags
+#
+
+T_Merge = 0x01
+T_NewScene = 0x02
+T_Curves = 0x04
+T_DrawOne = 0x08
+T_Debug = 0x10
+T_Verbose = 0x20
+T_ThicON = 0x40
+
+toggle = T_Merge | T_NewScene | T_DrawOne | T_ThicON
+theCircleRes = 32
+theMergeLimit = 1e-5
+
+#
+#    class CSection:
+#
+
+class CSection:
+    type = None
+
+    def __init__(self):
+        self.data = []
+
+    def display(self):
+        print("Section", self.type)
+        for datum in self.data:
+            datum.display()
+
+#
+#    class CTable:
+#
+
+class CTable:
+    def __init__(self):
+        self.type = None
+        self.name = None
+        self.handle = None
+        self.owner = None
+        self.subclass = None
+        self.nEntries = 0
+    def display(self):
+        print("Table %s %s %s %s %s %d" % (self.type, self.name, self.handle, self.owner, self.subclass, self.nEntries))
+
+#
+#    class CEntity:
+#
+class CEntity:
+    def __init__(self, typ, drawtype):
+        self.type = typ
+        self.drawtype = drawtype
+        self.handle = None
+        self.owner = None
+        self.subclass = None
+        self.layer = 0
+        self.color = 0
+        self.invisible = 0
+        self.linetype_name = ''
+        self.linetype_scale = 1.0
+        self.paperspace = 0
+        #self.normal = Vector((0,0,1))
+
+    def display(self):
+        print("Entity %s %s %s %s %s %s %x" % 
+            (self.type, self.handle, self.owner, self.subclass, self.layer, self.color, self.invisible))
+
+    def build(self, vn=0):
+        global toggle
+        if toggle & T_Debug:
+            raise NameError("Warning: can not build - unsupported entity type: %s" % self.type)
+        return(([], [], [], vn)) 
+
+    def draw(self):
+        global toggle
+        if toggle & T_Debug:
+            raise NameError("Warning: can not draw - unsupported entity type: %s" % self.type)
+        return
+
+
+DxfCommonAttributes = {
+    5 : 'handle',
+    6 : 'linetype_name',
+    8 : 'layer',
+    48 : 'linetype_scale',
+    60 : 'invisible',
+    62 : 'color',
+    67 : 'paperspace',
+    100 : 'subclass',
+    330 : 'owner',
+    360 : 'owner',
+}
+
+#
+#    class C3dFace(CEntity):
+#    10 : 'point0.x', 20 : 'point0.y', 30 : 'point0.z', 
+#    11 : 'point1.x', 21 : 'point1.y', 31 : 'point1.z', 
+#    12 : 'point2.x', 22 : 'point2.y', 32 : 'point2.z', 
+#    13 : 'point3.x', 23 : 'point3.y', 33 : 'point3.z', 
+#    70 : 'flags',
+#
+
+class C3dFace(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, '3DFACE', 'Mesh')
+        self.point0 = Vector()
+        self.point1 = Vector()
+        self.point2 = Vector()
+        self.point3 = Vector()
+
+    def display(self):
+        CEntity.display(self)
+        print(self.point0)
+        print(self.point1)
+        print(self.point2)
+        print(self.point3)
+
+    def build(self, vn=0):
+        verts = [self.point0, self.point1, self.point2]
+        if self.point3 == Vector((0,0,0)) or self.point2 == self.point3:
+            faces = [(vn+0, vn+1, vn+2)]
+            vn += 3
+        else:
+            verts.append( self.point3 )
+            faces = [(vn+0, vn+1, vn+2, vn+3)]
+            vn += 4            
+        return((verts, [], faces, vn))
+
+#
+#    class C3dSolid(CEntity):
+#    1 : 'data', 3 : 'more', 70 : 'version',
+#
+
+class C3dSolid(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, '3DSOLID', 'Mesh')
+        self.data = None
+        self.more = None
+        self.version = 0
+
+#
+#    class CAcadProxyEntity(CEntity):
+#    70 : 'format',
+#    90 : 'id', 91 : 'class', 92 : 'graphics_size', 93 : 'entity_size', 95: 'format',
+#    310 : 'data', 330 : 'id1', 340 : 'id2', 350 : 'id3', 360 : 'id4', 
+#
+
+class CAcadProxyEntity(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'ACAD_PROXY_ENTITY', None)
+
+
+#
+#    class CArc(CEntity):
+#    10 : 'center.x', 20 : 'center.y', 30 : 'center.z', 
+#    40 : 'radius',
+#    50 : 'start_angle', 51 : 'end_angle'
+#
+
+class CArc(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'ARC', 'Mesh')
+        self.center = Vector()
+        self.radius = 0.0
+        self.start_angle = 0.0
+        self.end_angle = 0.0
+        self.thickness = 0.0
+        self.normal = Vector((0,0,1))
+        
+    def display(self):
+        CEntity.display(self)
+        print(self.center)
+        print("%.4f %.4f %.4f " % (self.radius, self.start_angle, self.end_angle))
+
+    def build(self, vn=0):
+        start, end = self.start_angle, self.end_angle
+        if end > 360: end = end % 360.0
+        if end < start: end +=360.0
+        angle = end - start
+
+        deg2rad = math.pi/180.0
+        start *= deg2rad
+        end *= deg2rad
+        dphi = end - start
+        phi0 = start
+        w = dphi/theCircleRes
+        r = self.radius
+        center = self.center
+        v0 = vn
+        points = []
+        edges, faces = [], []
+        for n in range(theCircleRes):
+            s = math.sin(n*w + phi0)
+            c = math.cos(n*w + phi0)
+            v = center + Vector((r*c, r*s, 0.0))
+            points.append(v)
+        pn = len(points)
+        thic = self.thickness
+        t_vector = Vector((0, 0, thic))
+        if thic != 0 and (toggle & T_ThicON):
+            thic_points = [v + t_vector for v in points]
+            if thic < 0.0:
+                thic_points.extend(points)
+                points = thic_points
+            else:
+                points.extend(thic_points)
+            faces = [(v0+nr+0,v0+nr+1,v0+pn+nr+1,v0+pn+nr+0) for nr in range(pn)]
+            faces.pop()
+            self.drawtype = 'Mesh'
+            vn += 2*pn
+        else:
+            edges = [(v0+nr+0,v0+nr+1) for nr in range(pn)]
+            edges.pop()
+            vn += pn
+
+        if self.normal!=Vector((0,0,1)):
+            ma = getOCS(self.normal)
+            if ma:
+                #ma.invert()
+                points = [v * ma for v in points]
+        #print ('arc vn=', vn)
+        #print ('faces=', len(faces))
+        return ((points, edges, faces, vn))
+
+#
+#    class CArcAlignedText(CEntity):
+#    1 : 'text', 2 : 'font', 3 : 'bigfont', 7 : 'style',
+#    10 : 'center.x', 20 : 'center.y', 30 : 'center.z', 
+#    40 : 'radius', 41 : 'width', 42 : 'height', 43 : 'spacing', 
+#    44 : 'offset', 45 : 'right_offset', 46 : 'left_offset', 
+#    50 : 'start_angle', 51 : 'end_angle',
+#    70 : 'order', 71 : 'direction', 72 : 'alignment', 73 : 'side', 
+#    74 : 'bold', 75 : 'italic', 76 : 'underline',
+#    77 : 'character_set', 78 : 'pitch', 79 'fonttype',
+#    90 : 'color',
+#    280 : 'wizard', 330 : 'id'
+#
+
+class CArcAlignedText(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'ARCALIGNEDTEXT', 'Mesh')
+        self.text = ""
+        self.style = ""
+        self.center = Vector()
+        self.radius = 0.0
+        self.width = 1.0
+        self.height = 1.0
+        self.spacing = 1.0
+        self.offset = 0.0
+        self.right_offset = 0.0
+        self.left_offset = 0.0
+        self.start_angle = 0.0
+        self.end_angle = 0.0
+        self.order = 0
+        self.directions = 0
+        self.alignment = 0
+        self.side = 0
+        self.bold = 0
+        self.italic = 0
+        self.underline = 0
+        self.character_set = 0
+        self.pitch = 0
+        self.fonttype = 0
+        self.color = 0
+        self.wizard = None
+        self.id = None
+        self.normal = Vector((0,0,1))
+
+
+#
+#    class CAttdef(CEntity):
+#    1 : 'text', 2 : 'tag', 3 : 'prompt', 7 : 'style',
+#    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+#    11 : 'alignment_point.x', 21 : 'alignment_point.y', 31 : 'alignment_point.z', 
+#    40 : 'height', 41 : 'x_scale', 
+#    50 : 'rotation_angle', 51 : 'oblique_angle', 
+#    70 : 'flags', 71 : 'text_generation_flags', 
+#    72 : 'horizontal_justification',  74 : 'vertical_justification',    
+#
+
+class CAttdef(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'ATTDEF', None)
+        self.value = ""
+        self.tag = ""
+        self.prompt = ""
+        self.style = ""
+        self.insertion_point = Vector()
+        self.alignment_point = Vector()
+        self.height = 1.0
+        self.x_scale = 1.0
+        self.rotation_angle = 0.0
+        self.oblique_angle = 0.0
+        self.flags = 0
+        self.text_generation_flags = 0
+        self.horizontal_justification = 0.0
+        self.vertical_justification = 0.0
+        self.normal = Vector((0,0,1))
+
+    def draw(self):
+        drawText(self.text,  self.insertion_point, self.height, self.x_scale, self.rotation_angle, self.oblique_angle, self.normal)
+        return
+
+#
+#    class CAttrib(CEntity):
+#    1 : 'text', 2 : 'tag', 3 : 'prompt', 7 : 'style',
+#    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+#    11 : 'alignment_point.x', 21 : 'alignment_point.y', 31 : 'alignment_point.z', 
+#    40 : 'height', 41 : 'x_scale', 
+#    50 : 'rotation_angle', 51 : 'oblique_angle', 
+#    70 : 'flags', 73 : 'length', 
+#    71 : 'text_generation_flags', 72 : 'horizontal_justification',  74 : 'vertical_justification',     
+#
+
+class CAttrib(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'ATTRIB', None)
+        self.text = ""
+        self.tag = ""
+        self.prompt = ""
+
+        self.style = ""
+        self.insertion_point = Vector()
+        self.alignment_point = Vector()
+        self.height = 1.0
+        self.x_scale = 1.0
+        self.rotation_angle = 0.0
+        self.oblique_angle = 0.0
+        self.flags = 0
+        self.length = 1.0
+        self.text_generation_flags = 0
+        self.horizontal_justification = 0.0
+        self.vertical_justification = 0.0
+        self.normal = Vector((0,0,1))
+
+    def draw(self):
+        drawText(self.text,  self.insertion_point, self.height, self.x_scale, self.rotation_angle, self.oblique_angle, self.normal)
+        return
+
+
+#
+#    class CBlock(CEntity):
+#    1 : 'xref', 2 : 'name', 3 : 'also_name', 
+#    10 : 'base_point.x', 20 : 'base_point.y', 30 : 'base_point.z', 
+#    40 : 'size', 41 : 'x_scale', 
+#    50 : 'rotation_angle', 51 : 'oblique_angle',     
+#    70 : 'flags', 
+#
+
+class CBlock(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'BLOCK', None)
+        self.xref = ""
+        self.name = ""
+        self.also_name = ""
+        self.base_point = Vector()
+        self.size = 1.0
+        self.x_scale = 1.0
+        self.rotation_angle = 0.0
+        self.oblique_angle = 0.0
+        self.flags = 0
+        self.normal = Vector((0,0,1))
+
+    def display(self):
+        CEntity.display(self)
+        print("%s %s %s " % (self.xref, self.name, self.also_name))
+        print(self.base_point)
+
+    def draw(self):
+        # Todo
+        return
+
+#
+#    class CCircle(CEntity):
+#    10 : 'center.x', 20 : 'center.y', 30 : 'center.z', 
+#    40 : 'radius'
+#
+
+class CCircle(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'CIRCLE', 'Mesh')
+        self.center = Vector()
+        self.radius = 0.0
+        self.thickness = 0.0
+        self.normal = Vector((0,0,1))
+
+    def display(self):
+        CEntity.display(self)
+        print(self.center)
+        print("%.4f" % self.radius)
+
+    def build(self, vn=0):
+        w = 2*math.pi/theCircleRes
+        r = self.radius
+        center = self.center
+        points = []
+        edges, faces = [], []
+        v0 = vn
+        for n in range(theCircleRes):
+            s = math.sin(n*w)
+            c = math.cos(n*w)
+            v = center + Vector((r*c, r*s, 0))
+            points.append(v)
+
+        pn = len(points)
+        thic = self.thickness
+        t_vector = Vector((0, 0, thic))
+        if thic != 0 and (toggle & T_ThicON):
+            thic_points = [v + t_vector for v in points]
+            if thic < 0.0:
+                thic_points.extend(points)
+                points = thic_points
+            else:
+                points.extend(thic_points)
+            faces = [(v0+nr,v0+nr+1,pn+v0+nr+1,pn+v0+nr) for nr in range(pn)]
+            nr = pn -1
+            faces[-1] = (v0+nr,v0,pn+v0,pn+v0+nr)
+            self.drawtype = 'Mesh'
+            vn += 2*pn
+        else:
+            edges = [(v0+nr,v0+nr+1) for nr in range(pn)]
+            nr = pn -1
+            edges[-1] = (v0+nr,v0)
+            vn += pn
+        if self.normal!=Vector((0,0,1)):
+            ma = getOCS(self.normal)
+            if ma:
+                #ma.invert()
+                points = [v * ma for v in points]
+        #print ('cir vn=', vn)
+        #print ('faces=',len(faces))
+        return( (points, edges, faces, vn) )
+            
+#
+#    class CDimension(CEntity):
+#    1 : 'text', 2 : 'name', 3 : 'style',
+#    10 : 'def_point.x', 20 : 'def_point.y', 30 : 'def_point.z', 
+#    11 : 'mid_point.x', 21 : 'mid_point.y', 31 : 'mid_point.z', 
+#    12 : 'vector.x', 22 : 'vector.y', 32 : 'vector.z', 
+#    13 : 'def_point2.x', 23 : 'def_point2.y', 33 : 'def_point2.z', 
+#    14 : 'vector2.x', 24 : 'vector2.y', 34 : 'vector2.z', 
+#    15 : 'vector3.x', 25 : 'vector3.y', 35 : 'vector3.z', 
+#    16 : 'vector4.x', 26 : 'vector4.y', 36 : 'vector4.z', 
+#    70 : 'dimtype',
+#
+
+class CDimension(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'DIMENSION', None)
+        self.text = ""
+        self.name = ""
+        self.style = ""
+        self.def_point = Vector()
+        self.mid_point = Vector()
+        self.vector = Vector()
+        self.def_point2 = Vector()
+        self.vector2 = Vector()
+        self.vector3 = Vector()
+        self.vector4 = Vector()
+        self.dimtype = 0
+        self.normal = Vector((0,0,1))
+
+    def draw(self):
+        return
+
+#
+#    class CEllipse(CEntity):
+#    10 : 'center.x', 20 : 'center.y', 30 : 'center.z', 
+#    11 : 'end_point.x', 21 : 'end_point.y', 31 : 'end_point.z', 
+#    40 : 'ratio', 41 : 'start', 42 : 'end',
+#
+
+class CEllipse(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'ELLIPSE', 'Mesh')
+        self.center = Vector()
+        self.end_point = Vector()
+        self.ratio = 1.0
+        self.start = 0.0
+        self.end = 2*math.pi
+        self.thickness = 0.0
+        self.normal = Vector((0,0,1))
+
+    def display(self):
+        CEntity.display(self)
+        print(self.center)
+        print("%.4f" % self.ratio)
+                
+    def build(self, vn=0):
+        dphi = (self.end - self.start)
+        phi0 = self.start
+        w = dphi/theCircleRes
+        r = self.end_point.length
+        f = self.ratio
+        a = self.end_point.x/r
+        b = self.end_point.y/r
+        center = self.center
+        v0 = vn
+        points = []
+        edges, faces = [], []
+        for n in range(theCircleRes):
+            x = r*math.sin(n*w + phi0)
+            y = f*r*math.cos(n*w + phi0)
+            v = (center.x - a*x + b*y, center.y - a*y - b*x, center.z)
+            points.append(v)
+
+        pn = len(points)
+        thic = self.thickness
+        t_vector = Vector((0, 0, thic))
+        if thic != 0 and (toggle & T_ThicON):
+            thic_points = [v + t_vector for v in points]
+            if thic < 0.0:
+                thic_points.extend(points)
+                points = thic_points
+            else:
+                points.extend(thic_points)
+            faces = [(v0+nr,v0+nr+1,pn+v0+nr+1,pn+v0+nr) for nr in range(pn)]
+            nr = pn -1
+            faces[-1] = (v0+nr,v0,pn+v0,pn+v0+nr)
+            #self.drawtype = 'Mesh'
+            vn += 2*pn
+        else:
+            edges = [(v0+nr,v0+nr+1) for nr in range(pn)]
+            nr = pn -1
+            edges[-1] = (v0+nr,v0)
+            vn += pn
+
+
+        if thic != 0 and (toggle & T_ThicON):
+            pass
+        if self.normal!=Vector((0,0,1)):
+            ma = getOCS(self.normal)
+            if ma:
+                #ma.invert()
+                points = [v * ma for v in points]
+        return ((points, edges, faces, vn))
+
+#
+#    class CHatch(CEntity):
+#    2 : 'pattern',
+#    10 : 'point.x', 20 : 'point.y', 30 : 'point.z', 
+#    41 : 'scale', 47 : 'pixelsize', 52 : 'angle',
+#    70 : 'fill', 71 : 'associativity', 75: 'style', 77 : 'double', 
+#    78 : 'numlines', 91 : 'numpaths', 98 : 'numseeds',
+#
+
+class CHatch(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'HATCH', None)
+        self.pattern = 0
+        self.point = Vector()
+        self.scale = 1.0
+        self.pixelsize = 1.0
+        self.angle = 0.0
+        self.fill = 0
+        self.associativity = 0
+        self.style = 0
+        self.double = 0
+        self.numlines = 0
+        self.numpaths = 0
+        self.numseeds = 0
+        self.normal = Vector((0,0,1))
+
+
+#    class CImage(CEntity):
+#    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+#    11 : 'u_vector.x', 21 : 'u_vector.y', 31 : 'u_vector.z', 
+#    12 : 'v_vector.x', 22 : 'v_vector.y', 32 : 'v_vector.z', 
+#    13 : 'size.x', 23 : 'size.y', 33 : 'size.z', 
+#    14 : 'clip.x', 24 : 'clip.y', 34 : 'clip.z', 
+#    70 : 'display', 71 : 'cliptype', 
+#    90 : 'version',
+#    280 : 'clipstate', 281 : 'brightness', 282 : 'contrast', 283 : 'fade', 
+#    340 : 'image', 360 : 'reactor'
+#
+
+class CImage(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'IMAGE', None)
+        self.insertion_point = Vector()
+        self.u_vector = Vector()
+        self.v_vector = Vector()
+        self.size = Vector()
+        self.clip = Vector()
+        self.display = 0
+        self.cliptype = 0
+        self.version = 1
+        self.clipstate = 0
+        self.brightness = 0
+        self.constrast = 0
+        self.fade = 0
+        self.image = None
+        self.reactor = None
+        self.normal = Vector((0,0,1))
+
+#
+#    class CInsert(CEntity):
+#    1 : 'attributes_follow', 2 : 'name',
+#    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+#    41 : 'x_scale', 42 : 'y_scale', 43 : 'z_scale', 
+#    44 : 'column_spacing', 45 : 'row_spacing', 
+#    50 : 'rotation_angle', 66 : 'attributes_follow',
+#    70 : 'column_count', 71 : 'row_count', 
+#
+
+class CInsert(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'INSERT', None)
+        self.attributes_follow = 1
+        self.name = ""
+        self.insertion_point = Vector()
+        self.x_scale = 1.0
+        self.y_scale = 1.0
+        self.z_scale = 1.0
+        self.column_spacing = 1.0
+        self.row_spacing = 1.0
+        self.rotation_angle = 0.0
+        self.column_count = 1
+        self.row_count = 1
+        self.attributes_follow = 0
+        self.normal = Vector((0,0,1))
+
+    def display(self):
+        CEntity.display(self)
+        print(self.insertion_point)
+
+    def draw(self):
+        # Todo
+        return
+
+#
+#    class CLeader(CEntity):
+#    3 : 'style',
+#    10 : ['new_vertex(data)'], 20 : 'vertex.y', 30 : 'vertex.z', 
+#    40 : 'height', 41 : 'width',
+#    71 : 'arrowhead', 72 : 'pathtype', 73 : 'creation', 
+#    74 : 'hookdir', 75 : 'hookline', 76 : 'numverts', 77 : 'color',
+#    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+#    211 : 'horizon.x', 221 : 'horizon.y', 231 : 'horizon.z', 
+#    212 : 'offset_ins.x', 222 : 'offset_ins.y', 232 : 'offset_ins.z', 
+#    213 : 'offset_ann.x', 223 : 'offset_ann.y', 233 : 'offset_ann.z', 
+#
+
+class CLeader(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'LEADER', 'Mesh')
+        self.style = ""
+        self.vertex = None
+        self.verts = []
+        self.height = 1.0
+        self.width = 1.0
+        self.arrowhead = 0
+        self.pathtype = 0
+        self.creation = 0
+        self.hookdir = 0
+        self.hookline = 0
+        self.numverts = 0
+        self.color = 0
+        self.normal = Vector((0,0,1))
+        self.horizon = Vector()
+        self.offset_ins = Vector()
+        self.offset_ann = Vector()
+
+    def new_vertex(self, data):
+        self.vertex = Vector()
+        self.vertex.x = data
+        self.verts.append(self.vertex)
+
+    def build(self, vn=0):
+        edges = []
+        for v in self.verts:
+            edges.append((vn, vn+1))
+            vn += 1
+        edges.pop()
+        return (self.verts, edges, [], vn)
+
+#    class CLwPolyLine(CEntity):
+#    10 : ['new_vertex(data)'], 20 : 'vertex.y', 30 : 'vertex.z', 
+#    38 : 'elevation', 39 : 'thickness',
+#    40 : 'start_width', 41 : 'end_width', 42 : 'bulge', 43 : 'constant_width',
+#    70 : 'flags', 90 : 'numverts'
+#
+
+class CLWPolyLine(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'LWPOLYLINE', None)
+        self.vertex = None
+        self.verts = []
+        self.elevation = 0
+        self.thickness = 0.0
+        self.start_width = 0.0
+        self.end_width = 0.0
+        self.bulge = 0.0
+        self.constant_width = 0.0
+        self.flags = 0
+        self.numverts = 0
+        self.normal = Vector((0,0,1))
+
+    def new_vertex(self, data):
+        self.vertex = Vector()
+        self.vertex.x = data
+        self.verts.append(self.vertex)
+
+    def build(self, vn=0):
+        edges = []
+        v_start = vn
+        for v in self.verts:
+            edges.append((vn, vn+1))
+            vn += 1
+        if self.flags & PL_CLOSED:
+            edges[-1] = (vn-1, v_start)
+        else:
+            edges.pop()
+        verts = self.verts
+        if self.normal!=Vector((0,0,1)):
+            ma = getOCS(self.normal)
+            if ma:
+                #ma.invert()
+                verts = [v * ma for v in verts]
+        return (verts, edges, [], vn-1)
+        
+#
+#    class CLine(CEntity):
+#    10 : 'start_point.x', 20 : 'start_point.y', 30 : 'start_point.z', 
+#    11 : 'end_point.x', 21 : 'end_point.y', 31 : 'end_point.z', 
+#    39 : 'thickness',
+#
+
+class CLine(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'LINE', 'Mesh')
+        self.start_point = Vector()
+        self.end_point = Vector()
+        self.thickness = 0.0
+        self.normal = Vector((0,0,1))
+
+    def display(self):
+        CEntity.display(self)
+        print(self.start_point)
+        print(self.end_point)
+
+    def build(self, vn=0):
+        points = [self.start_point, self.end_point]
+        faces, edges = [], []
+        n = vn
+        thic = self.thickness
+        if thic != 0 and (toggle & T_ThicON):
+            t_vector = thic * self.normal
+            #print 'deb:thic_vector: ', t_vector #---------------------
+            points.extend([v + t_vector for v in points])
+            faces = [[0+n, 1+n, 3+n, 2+n]]
+            self.drawtype = 'Mesh'
+        else:
+            edges = [[0+n, 1+n]]
+        vn +=2
+        return((points, edges, faces, vn))
+
+#    class CMLine(CEntity):
+#    10 : 'start_point.x', 20 : 'start_point.y', 30 : 'start_point.z', 
+#    11 : ['new_vertex(data)'], 21 : 'vertex.y', 31 : 'vertex.z', 
+#    12 : ['new_seg_dir(data)'], 22 : 'seg_dir.y', 32 : 'seg_dir.z', 
+#    13 : ['new_miter_dir(data)'], 23 : 'miter_dir.y', 33 : 'miter_dir.z', 
+#    40 : 'scale', 41 : 'elem_param', 42 : 'fill_param',
+#    70 : 'justification', 71 : 'flags'
+#    72 : 'numverts', 73 : 'numelems', 74 : 'numparam', 75 : 'numfills',
+#    340 : 'id'
+#
+
+class CMLine(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'MLINE', None)
+        self.start_point = Vector()
+        self.vertex = None
+        self.seg_dir = None
+        self.miter_dir = None
+        self.verts = []
+        self.seg_dirs = []
+        self.miter_dirs = []
+        self.scale = 1.0
+        self.elem_param = 0
+        self.fill_param = 0
+        self.justification = 0
+        self.flags = 0
+        self.numverts = 0
+        self.numelems = 0
+        self.numparam = 0
+        self.numfills = 0
+        self.id = 0
+        self.normal = Vector((0,0,1))
+
+    def new_vertex(self, data):
+        self.vertex = Vector()
+        self.vertex.x = data
+        self.verts.append(self.vertex)
+
+    def new_seg_dir(self, data):
+        self.seg_dir = Vector()
+        self.seg_dir.x = data
+        self.seg_dirs.append(self.seg_dir)
+
+    def new_miter_dir(self, data):
+        self.miter_dir = Vector()
+        self.miter_dir.x = data
+        self.miter_dirs.append(self.miter_dir)
+
+
+
+#
+#    class CMText(CText):
+#    1 : 'text', 3: 'more_text', 7 : 'style',
+#    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+#    11 : 'alignment_point.x', 21 : 'alignment_point.y', 31 : 'alignment_point.z', 
+#    40 : 'nominal_height', 41 : 'reference_width', 42: 'width', 43 : 'height', 44 : 'line_spacing',
+#    50 : 'rotation_angle', 
+#    71 : 'attachment_point', 72 : 'drawing_direction',  73 : 'spacing_style',    
+#
+
+class CMText(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'MTEXT', 'Text')
+        self.text = ""
+        self.more_text = ""
+        self.style = ""
+        self.insertion_point = Vector()
+        self.alignment_point = Vector()
+        self.nominal_height = 1.0
+        self.reference_width = 1.0
+        self.width = 1.0
+        self.height = 1.0
+        self.rotation_angle = 0.0
+        self.attachment_point = 0
+        self.drawing_direction = 0
+        self.spacing_style = 0
+        self.normal = Vector((0,0,1))
+
+    def display(self):
+        CEntity.display(self)
+        print("%s %s" % (self.text, self.style))
+        print('MTEXTinsertion_point=',self.insertion_point)
+        print('MTEXTalignment_point=',self.alignment_point)
+
+    def draw(self):
+        drawText(self.text,  self.insertion_point, self.height, self.width, self.rotation_angle, 0.0, self.normal)
+        return
+
+#
+#    class CPoint(CEntity):
+#    10 : 'point.x', 20 : 'point.y', 30 : 'point.z', 
+#    39 : 'thickness', 50 : 'orientation'
+#
+
+class CPoint(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'POINT', 'Mesh')
+        self.point = Vector()
+        self.thickness = 0.0
+        self.orientation = 0.0
+
+    def display(self):
+        CEntity.display(self)
+        print(self.point)
+        print("%.4f" % self.orientation)
+
+    def build(self, vn=0):
+        # draw as mesh-vertex
+        verts = [self.point]
+        return((verts, [], [], vn+1))
+
+    def draw(self):
+        #todo
+        # draw as empty-object
+        loc = self.point
+        #bpy.ops.object.new('DXFpoint')
+
+#
+#    class CPolyLine(CEntity):
+#    1 : 'verts_follow', 2 : 'name',
+#    10 : 'elevation.x', 20 : 'elevation.y', 30 : 'elevation.z', 
+#    40 : 'start_width', 41 : 'end_width', 
+#    66 : 'verts_follow_flag',
+#    70 : 'flags', 71 : 'row_count', 72 : 'column_count', 
+#    73 : 'row_density', 74 : 'column_density', 75 : 'linetype',
+#
+
+class CPolyLine(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'POLYLINE', 'Mesh')
+        self.verts = []
+        self.verts_follow = 1
+        self.name = ""
+        self.elevation = Vector()
+        self.thickness = 0.0
+        self.start_width = 0.0
+        self.end_width = 0.0
+        self.verts_follow_flags = 0
+        self.flags = 0
+        self.row_count = 1
+        self.column_count = 1
+        self.row_density = 1.0
+        self.column_density = 1.0
+        self.linetype = 1
+        self.normal = Vector((0,0,1))
+
+    def display(self):
+        CEntity.display(self)
+        print("VERTS")
+        for v in self.verts:
+            print(v.location)
+        print("END VERTS")
+
+    def build(self, vn=0):
+        verts = []
+        lines = []
+        v_start = vn
+        for vert in self.verts:
+            verts.append(vert.location)
+            lines.append((vn, vn+1))
+            vn += 1
+        if self.flags & PL_CLOSED:
+            lines[-1] = (vn-1, v_start)
+        else:
+            lines.pop()
+        if self.normal!=Vector((0,0,1)):
+            ma = getOCS(self.normal)
+            if ma:
+                verts = [v * ma for v in verts]
+        return((verts, lines, [], vn-1))
+
+#
+#    class CShape(CEntity):
+#    2 : 'name', 
+#    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+#    39 : 'thickness',
+#    40 : 'size', 41 : 'x_scale', 
+#    50 : 'rotation_angle', 51 : 'oblique_angle',     
+#
+
+class CShape(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'SHAPE', None)
+        self.name = ""
+        self.insertion_point = Vector()
+        self.thickness = 0.0
+        self.size = 1.0
+        self.x_scale = 1.0
+        self.rotation_angle = 0.0
+        self.oblique_angle = 0.0
+
+    def display(self):
+        CEntity.display(self)
+        print("%s" % (self.name))
+        print(self.insertion_point)
+
+#
+#    class CSpline(CEntity):
+#    10 : ['new_control_point(data)'], 20 : 'control_point.y', 30 : 'control_point.z', 
+#    11 : ['new_fit_point(data)'], 21 : 'fit_point.y', 31 : 'fit_point.z', 
+#    40 : ['new_knot_value(data)'], 
+#    12 : 'start_tangent.x', 22 : 'start_tangent.y', 32 : 'start_tangent.z', 
+#    13 : 'end_tangent.x', 23 : 'end_tangent.y', 33 : 'end_tangent.z', 
+#    41 : 'weight', 42 : 'knot_tol', 43 : 'control_point_tol', 44 : 'fit_tol',
+#    70 : 'flag', 71 : 'degree', 
+#    72 : 'num_knots', 73 : 'num_control_points', 74 : 'num_fit_points',
+#    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+#
+
+class CSpline(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'SPLINE', 'Mesh')
+        self.control_points = []
+        self.fit_points = []
+        self.knot_values = []
+        self.control_point = None
+        self.fit_point = None
+        self.knot_value = None
+        self.start_tangent = Vector()
+        self.end_tangent = Vector()
+        self.weight = 1.0
+        self.knot_tol = 1e-6
+        self.control_point_tol = 1e-6
+        self.fit_tol = 1e-6
+        self.flag = 0
+        self.degree = 3
+        self.num_knots = 0
+        self.num_control_points = 0
+        self.num_fit_points = 0
+        self.thickness = 0.0
+        self.normal = Vector((0,0,1))
+        
+    def new_control_point(self, data):
+        self.control_point = Vector()
+        self.control_point.x = data
+        self.control_points.append(self.control_point)
+        
+    def new_fit_point(self, data):
+        self.fit_point = Vector()
+        self.fit_point.x = data
+        self.fit_points.append(self.fit_point)
+
+    def new_knot_value(self, data):
+        self.knot_value = data
+        self.knot_values.append(self.knot_value)
+        
+    def display(self):
+        #not testet yet (migius)
+        CEntity.display(self)
+        print("CONTROL")
+        for p in self.control_points:
+            print(p)
+        print("FIT")
+        for p in self.fit_points:
+            print(p)
+        print("KNOT")
+        for v in self.knot_values:
+            print(v)
+
+    def build(self, vn=0):
+        verts = []
+        lines = []
+        for vert in self.control_points:
+            verts.append(vert)
+            lines.append((vn, vn+1))
+            vn += 1
+        lines.pop()
+        return((verts, lines, [], vn))
+
+
+#
+#    class CSolid(CEntity):
+#    10 : 'point0.x', 20 : 'point0.y', 30 : 'point0.z', 
+#    11 : 'point1.x', 21 : 'point1.y', 31 : 'point1.z', 
+#    12 : 'point2.x', 22 : 'point2.y', 32 : 'point2.z', 
+#    13 : 'point3.x', 23 : 'point3.y', 33 : 'point3.z', 
+#    39 : 'thickness',
+#
+
+class CSolid(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'SOLID', 'Mesh')
+        self.point0 = Vector()
+        self.point1 = Vector()
+        self.point2 = Vector()
+        self.point3 = Vector()
+        self.normal = Vector((0,0,1))
+        self.thickness = 0.0
+        
+    def display(self):
+        CEntity.display(self)
+        print(self.point0)
+        print(self.point1)
+        print(self.point2)
+        print(self.point3)
+
+    def build(self, vn=0):
+        points, edges, faces = [],[],[]
+        if self.point2 == self.point3:
+            points = [self.point0, self.point1, self.point2]
+        else:
+            points = [self.point0, self.point1, self.point2, self.point3]
+        pn = len(points)
+        v0 = vn
+        
+        thic = self.thickness
+        t_vector = Vector((0, 0, thic))
+        if thic != 0 and (toggle & T_ThicON):
+            thic_points = [v + t_vector for v in points]
+            if thic < 0.0:
+                thic_points.extend(points)
+                points = thic_points
+            else:
+                points.extend(thic_points)
+
+            if   pn == 4:
+                faces = [[0,1,3,2], [4,6,7,5], [0,4,5,1],
+                         [1,5,7,3], [3,7,6,2], [2,6,4,0]]
+            elif pn == 3:
+                faces = [[0,1,2], [3,5,4], [0,3,4,1], [1,4,5,2], [2,5,3,0]]
+            elif pn == 2: faces = [[0,1,3,2]]
+            vn += 2*pn
+        else:
+            if   pn == 4: faces = [[0,2,3,1]]
+            elif pn == 3: faces = [[0,2,1]]
+            elif pn == 2:
+                edges = [[0,1]]
+                self.drawtype = 'Mesh'
+            vn += pn
+        if self.normal!=Vector((0,0,1)):
+            ma = getOCS(self.normal)
+            if ma:
+                points = [v * ma for v in points]
+        return((points, edges, faces, vn))
+        
+#
+#    class CText(CEntity):
+#    1 : 'text', 7 : 'style',
+#    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+#    11 : 'alignment_point.x', 21 : 'alignment_point.y', 31 : 'alignment_point.z', 
+#    40 : 'height', 41 : 'x_scale', 
+#    50 : 'rotation_angle', 51 : 'oblique_angle', 
+#    71 : 'flags', 72 : 'horizontal_justification',  73 : 'vertical_justification',    
+#
+
+class CText(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'TEXT', 'Text')
+        self.text = ""
+        self.style = ""
+        self.insertion_point = Vector()
+        self.alignment_point = Vector()
+        self.height = 1.0
+        self.x_scale = 1.0
+        self.rotation_angle = 0.0
+        self.oblique_angle = 0.0
+        self.flags = 0
+        self.horizontal_justification = 0.0
+        self.vertical_justification = 0.0
+        self.thickness = 0.0
+        self.normal = Vector((0,0,1))
+       
+    def display(self):
+        CEntity.display(self)
+        print("%s %s" % (self.text, self.style))
+        print(self.insertion_point)
+        print(self.alignment_point)
+        
+    def draw(self):
+        drawText(self.text,  self.insertion_point, self.height, self.x_scale, self.rotation_angle, self.oblique_angle, self.normal)
+        return
+
+
+def drawText(text, loc, size, spacing, angle, shear, normal=Vector((0,0,1))):
+        #print('angle_deg=',angle)
+        bpy.ops.object.text_add(
+            view_align=False, 
+            enter_editmode=False, 
+            location= loc, 
+            #rotation=(0, 0, angle), #need radians here
+            )
+        cu = bpy.context.object.data
+        cu.body = text
+        cu.size = size #up 2.56
+        cu.space_word = spacing #up 2.56
+        cu.shear = shear
+        if angle!=0.0 or normal!=Vector((0,0,1)):
+            obj = bpy.context.object
+            transform(normal, angle, obj)
+        return
+
+#
+#    class CTolerance(CEntity):
+#    3 : 'style',
+#    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+#    11 : 'direction.x', 21 : 'direction.y', 31 : 'direction.z', 
+#
+
+class CTolerance(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'TOLERANCE', None)
+        self.stype = ""
+        self.insertion_point = Vector()
+        self.direction = Vector()
+
+#
+#    class CTrace(CEntity):
+#    10 : 'point0.x', 20 : 'point0.y', 30 : 'point0.z', 
+#    11 : 'point1.x', 21 : 'point1.y', 31 : 'point1.z', 
+#    12 : 'point2.x', 22 : 'point2.y', 32 : 'point2.z', 
+#    13 : 'point3.x', 23 : 'point3.y', 33 : 'point3.z', 
+#    39 : 'thickness',
+#
+
+class CTrace(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'TRACE', 'Mesh')
+        self.point0 = Vector()
+        self.point1 = Vector()
+        self.point2 = Vector()
+        self.point3 = Vector()
+        self.normal = Vector((0,0,1))
+        self.thickness = 0.0
+    
+    def display(self):
+        CEntity.display(self)
+        print(self.point0)
+        print(self.point1)
+        print(self.point2)
+        print(self.point3)
+   
+    def build(self, vn=0):
+        points, edges, faces = [],[],[]
+        if self.point2 == self.point3:
+            points = [self.point0, self.point2, self.point1]
+        else:
+            points = [self.point0, self.point2, self.point1, self.point3]
+        pn = len(points)
+        v0 = vn
+        thic = self.thickness
+        t_vector = Vector((0, 0, thic))
+        if thic != 0 and (toggle & T_ThicON):
+            thic_points = [v + t_vector for v in points]
+            if thic < 0.0:
+                thic_points.extend(points)
+                points = thic_points
+            else:
+                points.extend(thic_points)
+
+            if   pn == 4:
+                faces = [[0,1,3,2], [4,6,7,5], [0,4,5,1],
+                         [1,5,7,3], [3,7,6,2], [2,6,4,0]]
+            elif pn == 3:
+                faces = [[0,1,2], [3,5,4], [0,3,4,1], [1,4,5,2], [2,5,3,0]]
+            elif pn == 2: faces = [[0,1,3,2]]
+            vn += 2*pn
+        else:
+            if   pn == 4: faces = [[0,2,3,1]]
+            elif pn == 3: faces = [[0,2,1]]
+            elif pn == 2:
+                edges = [[0,1]]
+                self.drawtype = 'Mesh'
+        if self.normal!=Vector((0,0,1)):
+            ma = getOCS(self.normal)
+            if ma:
+                points = [v * ma for v in points]
+        return ((points, edges, faces, vn))
+
+#
+#    class CVertex(CEntity):
+#    10 : 'location.x', 20 : 'location.y', 30 : 'location.z', 
+#    40 : 'start_width', 41 : 'end_width', 42 : 'bulge', 
+#    50 : 'tangent',
+#    70 : 'flags',
+#    71 : 'index1', 72 : 'index2', 73 : 'index3', 74 : 'index4', 
+#
+
+class CVertex(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'VERTEX', None)
+        self.location = Vector()
+        self.start_width = 0.0
+        self.end_width = 0.0
+        self.bulge = 0.0
+        self.tangent = 0.0
+        self.flags = 0
+
+    def display(self):
+        return
+
+    def draw(self):
+        return
+
+#            
+#    class CViewPort(CEntity):
+#    10 : 'center.x', 20 : 'center.y', 30 : 'center.z', 
+#    12 : 'view_center.x', 22 : 'view_center.y', 32 : 'view_center.z', 
+#    13 : 'snap_base.x', 23 : 'snap_base.y', 33 : 'snap_base.z', 
+#    14 : 'snap_spacing.x', 24 : 'snap_spacing.y', 34 : 'snap_spacing.z', 
+#    15 : 'grid_spacing.x', 25 : 'grid_spacing.y', 35 : 'grid_spacing.z', 
+#    16 : 'view_direction.x', 26 : 'view_direction.y', 36 : 'view_direction.z', 
+#    40 : 'width', 41 : 'height',
+#    68 : 'status', 69 : 'id',
+#
+
+class CViewPort(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'VIEWPORT', None)
+        self.center = Vector()
+        self.view_center = Vector()
+        self.snap_base = Vector()
+        self.snap_spacing = Vector()
+        self.grid_spacing = Vector()
+        self.view_direction = Vector()
+        self.width = 1.0
+        self.height = 1.0
+        self.status = 0
+        self.id = 0
+
+    def draw(self):
+        # Todo
+        return
+
+#
+#    class CWipeOut(CEntity):
+#    10 : 'point.x', 20 : 'point.y', 30 : 'point.z', 
+#    11 : 'direction.x', 21 : 'direction.y', 31 : 'direction.z', 
+#
+
+class CWipeOut(CEntity):
+    def __init__(self):
+        CEntity.__init__(self, 'WIPEOUT', None)
+        self.point = Vector()
+        self.direction = Vector()
+
+#
+#
+#
+WORLDX = Vector((1.0,0.0,0.0))
+WORLDY = Vector((0.0,1.0,0.0))
+WORLDZ = Vector((0.0,0.0,1.0))
+
+
+def getOCS(az):  #-----------------------------------------------------------------
+    """An implimentation of the Arbitrary Axis Algorithm.
+    """
+    #decide if we need to transform our coords
+    #if az[0] == 0 and az[1] == 0: 
+    if abs(az.x) < 0.00001 and abs(az.y) < 0.00001:
+        if az.z > 0.0:
+            return False
+        elif az.z < 0.0:
+            return Matrix(-WORLDX, WORLDY*1, -WORLDZ)
+
+    cap = 0.015625 # square polar cap value (1/64.0)
+    if abs(az.x) < cap and abs(az.y) < cap:
+        ax = WORLDY.cross(az)
+    else:
+        ax = WORLDZ.cross(az)
+    ax = ax.normalize()
+    ay = az.cross(ax)
+    ay = ay.normalize()
+    return Matrix(ax, ay, az)
+
+
+
+def transform(normal, rotation, obj):  #--------------------------------------------
+    """Use the calculated ocs to determine the objects location/orientation in space.
+    """
+    ma = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1])
+    o = Vector(obj.location)
+    ma_new = getOCS(normal)
+    if ma_new:
+        ma = ma_new.resize4x4()
+        o = o * ma #.copy().invert()
+
+    if rotation != 0:
+        g = radians(-rotation)
+        rmat = Matrix([cos(g), -sin(g), 0], [sin(g), cos(g), 0], [0, 0, 1])
+        ma = ma * rmat.resize4x4()
+
+    obj.matrix_world = ma #must be matrix4x4
+    obj.location = o
+
+
+DxfEntityAttributes = {
+'3DFACE'    : {
+    10 : 'point0.x', 20 : 'point0.y', 30 : 'point0.z', 
+    11 : 'point1.x', 21 : 'point1.y', 31 : 'point1.z', 
+    12 : 'point2.x', 22 : 'point2.y', 32 : 'point2.z', 
+    13 : 'point3.x', 23 : 'point3.y', 33 : 'point3.z', 
+    70 : 'flags',
+    },
+
+'3DSOLID'    : {
+    1 : 'data', 3 : 'more', 70 : 'version',
+    },
+
+'ACAD_PROXY_ENTITY'    : {
+    70 : 'format',
+    90 : 'id', 91 : 'class', 92 : 'graphics_size', 93 : 'entity_size', 95: 'format',
+    310 : 'data', 330 : 'id1', 340 : 'id2', 350 : 'id3', 360 : 'id4', 
+    },
+
+'ARC'        : {
+    10 : 'center.x', 20 : 'center.y', 30 : 'center.z', 
+    40 : 'radius',
+    50 : 'start_angle', 51 : 'end_angle',
+    39 : 'thickness',
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+
+'ARCALIGNEDTEXT'    : {
+    1 : 'text', 2 : 'font', 3 : 'bigfont', 7 : 'style',
+    10 : 'center.x', 20 : 'center.y', 30 : 'center.z', 
+    40 : 'radius', 41 : 'width', 42 : 'height', 43 : 'spacing', 
+    44 : 'offset', 45 : 'right_offset', 46 : 'left_offset', 
+    50 : 'start_angle', 51 : 'end_angle',
+    70 : 'order', 71 : 'direction', 72 : 'alignment', 73 : 'side', 
+    74 : 'bold', 75 : 'italic', 76 : 'underline',
+    77 : 'character_set', 78 : 'pitch', 79 : 'fonttype',
+    90 : 'color',
+    280 : 'wizard', 330 : 'id'
+    },
+
+'ATTDEF'    : {
+    1 : 'text', 2 : 'tag', 3 : 'prompt', 7 : 'style',
+    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+    11 : 'alignment_point.x', 21 : 'alignment_point.y', 31 : 'alignment_point.z', 
+    40 : 'height', 41 : 'x_scale', 
+    50 : 'rotation_angle', 51 : 'oblique_angle', 
+    70 : 'flags', 71 : 'text_generation_flags', 
+    72 : 'horizontal_justification',  74 : 'vertical_justification',    
+    },
+
+
+'ATTRIB'    : {
+    1 : 'text', 2 : 'tag', 3 : 'prompt', 7 : 'style',
+    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+    11 : 'alignment_point.x', 21 : 'alignment_point.y', 31 : 'alignment_point.z', 
+    40 : 'height', 41 : 'x_scale', 
+    50 : 'rotation_angle', 51 : 'oblique_angle', 
+    70 : 'flags', 73 : 'length', 
+    71 : 'text_generation_flags', 72 : 'horizontal_justification',  74 : 'vertical_justification',     
+    },
+
+'BLOCK'        : {
+    1 : 'xref', 2 : 'name', 3 : 'also_name', 
+    10 : 'base_point.x', 20 : 'base_point.y', 30 : 'base_point.z', 
+    40 : 'size', 41 : 'x_scale', 
+    50 : 'rotation_angle', 51 : 'oblique_angle',     
+    70 : 'flags', 
+    },
+
+'CIRCLE'    : {
+    10 : 'center.x', 20 : 'center.y', 30 : 'center.z', 
+    40 : 'radius',
+    39 : 'thickness',
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+
+'DIMENSION'    : {
+    1 : 'text', 2 : 'name', 3 : 'style',
+    10 : 'def_point.x', 20 : 'def_point.y', 30 : 'def_point.z', 
+    11 : 'mid_point.x', 21 : 'mid_point.y', 31 : 'mid_point.z', 
+    12 : 'vector.x', 22 : 'vector.y', 32 : 'vector.z', 
+    13 : 'def_point2.x', 23 : 'def_point2.y', 33 : 'def_point2.z', 
+    14 : 'vector2.x', 24 : 'vector2.y', 34 : 'vector2.z', 
+    15 : 'vector3.x', 25 : 'vector3.y', 35 : 'vector3.z', 
+    16 : 'vector4.x', 26 : 'vector4.y', 36 : 'vector4.z', 
+    70 : 'dimtype',
+    },
+
+'ELLIPSE'    : {
+    10 : 'center.x', 20 : 'center.y', 30 : 'center.z', 
+    11 : 'end_point.x', 21 : 'end_point.y', 31 : 'end_point.z', 
+    40 : 'ratio', 41 : 'start', 42 : 'end',
+    39 : 'thickness',
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+
+'HATCH'        : {
+    2 : 'pattern',
+    10 : 'point.x', 20 : 'point.y', 30 : 'point.z', 
+    41 : 'scale', 47 : 'pixelsize', 52 : 'angle',
+    70 : 'fill', 71 : 'associativity', 75: 'style', 77 : 'double', 
+    78 : 'numlines', 91 : 'numpaths', 98 : 'numseeds',
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+
+'IMAGE'        : {
+    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+    11 : 'u_vector.x', 21 : 'u_vector.y', 31 : 'u_vector.z', 
+    12 : 'v_vector.x', 22 : 'v_vector.y', 32 : 'v_vector.z', 
+    13 : 'size.x', 23 : 'size.y', 33 : 'size.z', 
+    14 : 'clip.x', 24 : 'clip.y', 34 : 'clip.z', 
+    70 : 'display', 71 : 'cliptype', 
+    90 : 'version',
+    280 : 'clipstate', 281 : 'brightness', 282 : 'contrast', 283 : 'fade', 
+    340 : 'image', 360 : 'reactor',
+    },
+
+'INSERT'    : {
+    1 : 'attributes_follow', 2 : 'name',
+    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+    41 : 'x_scale', 42 : 'y_scale', 43 : 'z_scale', 
+    44 : 'column_spacing', 45 : 'row_spacing', 
+    50 : 'rotation_angle', 66 : 'attributes_follow',
+    70 : 'column_count', 71 : 'row_count', 
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+
+'LEADER'    : {
+    3 : 'style',
+    10 : ['new_vertex(data)'], 20 : 'vertex.y', 30 : 'vertex.z', 
+    40 : 'height', 41 : 'width',
+    71 : 'arrowhead', 72 : 'pathtype', 73 : 'creation', 
+    74 : 'hookdir', 75 : 'hookline', 76 : 'numverts', 77 : 'color',
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    211 : 'horizon.x', 221 : 'horizon.y', 231 : 'horizon.z', 
+    212 : 'offset_ins.x', 222 : 'offset_ins.y', 232 : 'offset_ins.z', 
+    213 : 'offset_ann.x', 223 : 'offset_ann.y', 233 : 'offset_ann.z', 
+    },
+
+'LINE'        : {
+    10 : 'start_point.x', 20 : 'start_point.y', 30 : 'start_point.z', 
+    11 : 'end_point.x', 21 : 'end_point.y', 31 : 'end_point.z', 
+    39 : 'thickness',
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+
+'LWPOLYLINE'    : {
+    10 : ['new_vertex(data)'], 20 : 'vertex.y', 30 : 'vertex.z', 
+    38 : 'elevation', 39 : 'thickness',
+    40 : 'start_width', 41 : 'end_width', 42 : 'bulge', 43 : 'constant_width',
+    70 : 'flags', 90 : 'numverts',
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+        
+'MLINE'    : {
+    10 : 'start_point.x', 20 : 'start_point.y', 30 : 'start_point.z', 
+    11 : ['new_vertex(data)'], 21 : 'vertex.y', 31 : 'vertex.z', 
+    12 : ['new_seg_dir(data)'], 22 : 'seg_dir.y', 32 : 'seg_dir.z', 
+    13 : ['new_miter_dir(data)'], 23 : 'miter_dir.y', 33 : 'miter_dir.z', 
+    39 : 'thickness',
+    40 : 'scale', 41 : 'elem_param', 42 : 'fill_param',
+    70 : 'justification', 71 : 'flags',
+    72 : 'numverts', 73 : 'numelems', 74 : 'numparam', 75 : 'numfills',
+    340 : 'id',
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+        
+'MTEXT'        : {
+    1 : 'text', 3: 'more_text', 7 : 'style',
+    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+    11 : 'alignment_point.x', 21 : 'alignment_point.y', 31 : 'alignment_point.z', 
+    40 : 'nominal_height', 41 : 'reference_width', 42: 'width', 43 : 'height', 44 : 'line_spacing',
+    50 : 'rotation_angle', 
+    71 : 'attachment_point', 72 : 'drawing_direction',  73 : 'spacing_style',    
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+
+'POINT'        : {
+    10 : 'point.x', 20 : 'point.y', 30 : 'point.z', 
+    39 : 'thickness', 50 : 'orientation',
+    },
+
+'POLYLINE'    : {
+    1 : 'verts_follow', 2 : 'name',
+    10 : 'elevation.x', 20 : 'elevation.y', 30 : 'elevation.z', 
+    39 : 'thickness',
+    40 : 'start_width', 41 : 'end_width', 
+    66 : 'verts_follow_flag',
+    70 : 'flags', 71 : 'row_count', 72 : 'column_count', 
+    73 : 'row_density', 74 : 'column_density', 75 : 'linetype',
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+
+'RAY'        : {
+    10 : 'point.x', 20 : 'point.y', 30 : 'point.z', 
+    11 : 'direction.x', 21 : 'direction.y', 31 : 'direction.z', 
+    },
+
+'RTEXT'        : {
+    1 : 'text', 7 : 'style',
+    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+    39 : 'thickness',
+    40 : 'height', 
+    50 : 'rotation_angle',
+    70 : 'flags',
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+
+'SHAPE'        : {
+    2 : 'name', 
+    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+    39 : 'thickness',
+    40 : 'size', 41 : 'x_scale', 
+    50 : 'rotation_angle', 51 : 'oblique_angle',     
+    39 : 'thickness',
+    },
+
+'SOLID'        : {
+    10 : 'point0.x', 20 : 'point0.y', 30 : 'point0.z', 
+    11 : 'point1.x', 21 : 'point1.y', 31 : 'point1.z', 
+    12 : 'point2.x', 22 : 'point2.y', 32 : 'point2.z', 
+    13 : 'point3.x', 23 : 'point3.y', 33 : 'point3.z', 
+    39 : 'thickness',
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+
+'SPLINE'    : {
+    10 : ['new_control_point(data)'], 20 : 'control_point.y', 30 : 'control_point.z', 
+    11 : ['new_fit_point(data)'], 21 : 'fit_point.y', 31 : 'fit_point.z', 
+    40 : ['new_knot_value(data)'], 
+    12 : 'start_tangent.x', 22 : 'start_tangent.y', 32 : 'start_tangent.z', 
+    13 : 'end_tangent.x', 23 : 'end_tangent.y', 33 : 'end_tangent.z', 
+    39 : 'thickness',
+    41 : 'weight', 42 : 'knot_tol', 43 : 'control_point_tol', 44 : 'fit_tol',
+    70 : 'flag', 71 : 'degree', 
+    72 : 'num_knots', 73 : 'num_control_points', 74 : 'num_fit_points',
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+
+'TEXT'        : {
+    1 : 'text', 7 : 'style',
+    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+    11 : 'alignment_point.x', 21 : 'alignment_point.y', 31 : 'alignment_point.z', 
+    40 : 'height', 41 : 'x_scale', 
+    50 : 'rotation_angle', 51 : 'oblique_angle', 
+    71 : 'flags', 72 : 'horizontal_justification',  73 : 'vertical_justification',    
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+
+'TOLERANCE'    : {
+    3 : 'style',
+    10 : 'insertion_point.x', 20 : 'insertion_point.y', 30 : 'insertion_point.z', 
+    11 : 'direction.x', 21 : 'direction.y', 31 : 'direction.z', 
+    },
+
+'TRACE'        : {
+    10 : 'point0.x', 20 : 'point0.y', 30 : 'point0.z', 
+    11 : 'point1.x', 21 : 'point1.y', 31 : 'point1.z', 
+    12 : 'point2.x', 22 : 'point2.y', 32 : 'point2.z', 
+    13 : 'point3.x', 23 : 'point3.y', 33 : 'point3.z', 
+    39 : 'thickness',
+    210 : 'normal.x', 220 : 'normal.y', 230 : 'normal.z', 
+    },
+
+'VERTEX'    : {
+    10 : 'location.x', 20 : 'location.y', 30 : 'location.z', 
+    40 : 'start_width', 41 : 'end_width', 42 : 'bulge', 
+    50 : 'tangent',
+    70 : 'flags',
+    71 : 'index1', 72 : 'index2', 73 : 'index3', 74 : 'index4', 
+    },
+
+'VIEWPORT'    : {
+    10 : 'center.x', 20 : 'center.y', 30 : 'center.z', 
+    12 : 'view_center.x', 22 : 'view_center.y', 32 : 'view_center.z', 
+    13 : 'snap_base.x', 23 : 'snap_base.y', 33 : 'snap_base.z', 
+    14 : 'snap_spacing.x', 24 : 'snap_spacing.y', 34 : 'snap_spacing.z', 
+    15 : 'grid_spacing.x', 25 : 'grid_spacing.y', 35 : 'grid_spacing.z', 
+    16 : 'view_direction.x', 26 : 'view_direction.y', 36 : 'view_direction.z', 
+    40 : 'width', 41 : 'height',
+    68 : 'status', 69 : 'id',
+    },
+
+'WIPEOUT'    : {
+    10 : 'point.x', 20 : 'point.y', 30 : 'point.z', 
+    11 : 'direction.x', 21 : 'direction.y', 31 : 'direction.z', 
+    },
+
+}
+
+
+#
+#    Flags
+#
+
+# Polyline flags
+PL_CLOSED         = 0x01
+PL_CURVE_FIT_VERTS    = 0x02
+PL_SPLINE_FIT_VERTS    = 0x04
+PL_3D_POLYLINE        = 0x08
+PL_3D_POLYGON_MESH    = 0x10
+PL_CLOSED_IN_N_DIR    = 0x20
+PL_POLYFACE_MESH    = 0x40
+PL_CONTINUOUS        = 0x80
+
+
+# Vertex flags
+VX_EXTRA_FLAG_CREATED        = 0x01
+VX_CURVE_FIT_TANGENT_DEFINED    = 0x02
+VX_SPLINE_VERTEX_CREATED    = 0x08
+VX_SPLINE_FRAME_CONTROL_POINT    = 0x10
+VX_3D_POLYLINE_VERTEX        = 0x20
+VX_3D_POLYGON_MESH_VERTEX    = 0x40
+VX_POLYFACE_MESH_VERTEX        = 0x80
+
+# 3DFACE flags
+
+F3D_EDGE0_INVISIBLE = 0x01
+F3D_EDGE1_INVISIBLE = 0x02
+F3D_EDGE2_INVISIBLE = 0x04
+F3D_EDGE3_INVISIBLE = 0x08
+
+#
+#    readDxfFile(filePath):
+#
+
+def readDxfFile(fileName):    
+    global toggle, theCodec
+
+    print( "Opening DXF file "+ fileName )
+
+    # fp= open(fileName, "rU")
+    fp = codecs.open(fileName, "r", encoding=theCodec)
+    first = True
+    statements = []
+    no = 0
+    for line in fp: 
+        word = line.strip()
+        no += 1
+        if first:
+            if word:
+                code = int(word)
+                first = False
+        else:
+            if toggle & T_Verbose:
+                print("%4d: %4d %s" % (no, code, word))
+            if code < 10:
+                data = word
+            elif code < 60:
+                data = float(word)
+            elif code < 100:
+                data = int(word)
+            elif code < 140:
+                data = word
+            elif code < 150:
+                data = float(word)
+            elif code < 200:
+                data = int(word)
+            elif code < 300:
+                data = float(word)
+            elif code < 370:
+                data = word
+            elif code < 390:
+                data = int(word)
+            elif code < 400:
+                data = word
+            elif code < 410:
+                data = int(word)
+            elif code < 1010:
+                data = word
+            elif code < 1060:
+                data = float(word)
+            elif code < 1080:
+                data = int(word)
+
+            statements.append((code,data))
+            first = True
+    fp.close()
+
+    statements.reverse()
+    sections = {}
+    handles = {}
+    while statements:
+        (code,data) = statements.pop()
+        if code == 0:
+            if data == 'SECTION':
+                section = CSection()
+        elif code == 2:
+            section.type = data
+            if data == 'HEADER':
+                parseHeader(section, statements, handles)
+                known = False
+            elif data == 'CLASSES':
+                parseClasses(section, statements, handles)
+                known = False
+            elif data == 'TABLES':
+                parseTables(section, statements, handles)
+                known = False
+            elif data == 'BLOCKS':
+                parseBlocks(section, statements, handles)
+                known = False
+            elif data == 'ENTITIES':
+                parseEntities(section, statements, handles)
+                known = False
+            elif data == 'OBJECTS':
+                parseObjects(section, statements, handles)
+            sections[data] = section
+        elif code == 999:
+            pass
+        else:
+            raise NameError("Unexpected code in SECTION context: %d %s" % (code,data))
+
+    if toggle & T_Verbose:
+        for (typ,section) in sections.items():
+            section.display()
+    return sections
+    
+
+#
+#     0
+#    SECTION
+#      2
+#    HEADER
+#    
+#      9
+#    $<variable>
+#    <group code>
+#    <value>
+#    
+#      0
+#    ENDSEC
+
+    
+def parseHeader(section, statements, handles):
+    while statements:
+        (code,data) = statements.pop()
+        if code == 0:
+            if data == 'ENDSEC':
+                return
+
+    return
+
+
+#      0
+#    SECTION
+#      2
+#    CLASSES
+#    
+#      0
+#    CLASS
+#      1
+#    <class dxf record>
+#      2
+#    <class name>
+#      3
+#    <app name>
+#    90
+#    <flag>
+#    280
+#    <flag>
+#    281
+#    <flag>
+#    
+#      0
+#    ENDSEC         
+
+def parseClasses(section, statements, handles):
+    while statements:
+        (code,data) = statements.pop()
+        if code == 0:
+            if data == 'ENDSEC':
+                return
+
+    return
+    
+
+#      0
+#    SECTION
+#      2
+#    TABLES
+#    
+#      0
+#    TABLE
+#      2
+#    <table type>
+#      5
+#    <handle>
+#    100
+#    AcDbSymbolTable
+#    70
+#    <max. entries>
+#    
+#      0
+#    <table type>
+#      5
+#    <handle>
+#    100
+#    AcDbSymbolTableRecord
+#    .
+#    . <data>
+#    .
+#    
+#      0
+#    ENDTAB
+#    
+#      0
+#    ENDSEC 
+
+#
+#      APPID (application identification table)
+#
+#      BLOCK_RECORD (block reference table)
+#
+#      DIMSTYLE (dimension style table)
+#
+#      LAYER (layer table)
+#
+#      LTYPE (linetype table)
+#
+#      STYLE (text style table)
+#
+#      UCS (User Coordinate System table)
+#
+#      VIEW (view table)
+#
+#      VPORT (viewport configuration table)
+
+
+def parseTables(section, statements, handles):
+    tables = []
+    section.data = tables
+    while statements:
+        (code,data) = statements.pop()
+        if code == 0:
+            if data == 'ENDSEC':
+                return
+    '''
+                known = False
+            elif data == 'TABLE':
+                table = CTable()
+                tables.append(table)
+                known = False
+            elif data == 'ENDTAB':
+                pass
+                known = False
+            elif data == table.type:
+                parseTableType
+                table = CTable()
+                tables.append(table)
+                table.type = word
+        elif code == 2:
+            table.type = word
+        elif code == 5:
+            table.handle = word
+            handles[word] = table
+        elif code == 330:
+            table.owner = word
+        elif code == 100:
+            table.subclass = word
+        elif code == 70:
+            table.nEntries = int(word)
+    '''
+    return
+    
+#      0
+#    SECTION
+#      2
+#    BLOCKS
+#    
+#      0
+#    BLOCK
+#      5
+#    <handle>
+#    100
+#    AcDbEntity
+#      8
+#    <layer>
+#    100
+#    AcDbBlockBegin
+#      2
+#    <block name>
+#    70
+#    <flag>
+#    10
+#    <X value>
+#    20
+#    <Y value>
+#    30
+#    <Z value>
+#      3
+#    <block name>
+#      1
+#    <xref path>
+#    
+#      0
+#    <entity type>
+#    .
+#    . <data>
+#    .
+#    
+#      0
+#    ENDBLK
+#      5
+#    <handle>
+#    100
+#    AcDbBlockEnd
+#    
+#      0
+#    ENDSEC 
+
+def parseBlocks(section, statements, handles):
+    while statements:
+        (code,data) = statements.pop()
+        if code == 0:
+            if data == 'ENDSEC':
+                return
+
+    return
+
+#      0
+#    SECTION
+#      2
+#    ENTITIES
+#    
+#      0
+#    <entity type>
+#      5
+#    <handle>
+#    330
+#    <pointer to owner>
+#    100
+#    AcDbEntity
+#      8
+#    <layer>
+#    100
+#    AcDb<classname>
+#    .
+#    . <data>
+#    .
+#    
+#      0
+#    ENDSEC
+
+Ignorables = ['DIMENSION', 'TEXT', 'VIEWPORT']
+
+ClassCreators = {
+    '3DFACE':         'C3dFace()', 
+    '3DSOLID':        'C3dSolid()',
+    'ACAD_PROXY_ENTITY':    'CAcadProxyEntity()',
+    'ACAD_ZOMBIE_ENTITY':    0,
+    'ARC':            'CArc()',
+    'ARCALIGNEDTEXT':    'CArcAlignedText()',
+    'ATTDEF':        'CAttdef()',
+    'ATTRIB':        'CAttrib()',
+    'BODY':            0,
+    'CIRCLE':        'CCircle()',
+    'DIMENSION':        'CDimension()',
+    'ELLIPSE':        'CEllipse()',
+    'HATCH':        'CHatch()',
+    'IMAGE':        'CImage()',
+    'INSERT':        'CInsert()',
+    'LEADER':        'CLeader()',
+    'LINE':            'CLine()',
+    'LWPOLYLINE':        'CLWPolyLine()',
+    'MLINE':        'CMLine()',
+    'MTEXT':        'CMText()',
+    'OLEFRAME':        0,
+    'OLE2FRAME':        0,
+    'POINT':        'CPoint()',
+    'POLYLINE':        'CPolyLine()',
+    'RAY':            'CRay()',
+    'REGION':        0,
+    'RTEXT':        'CRText',
+    'SEQEND':        0,
+    'SHAPE':        'CShape()',
+    'SOLID':        'CSolid()',
+    'SPLINE':        'CSpline()',
+    'TEXT':            'CText()',
+    'TOLERANCE':        'CTolerance()',
+    'TRACE':        'CTrace()',
+    'VERTEX':        'CVertex()',
+    'VIEWPORT':        'CViewPort()',
+    'WIPEOUT':        'CWipeOut()',
+    'XLINE':        'CXLine()',
+}
+
+def parseEntities(section, statements, handles):
+    entities = []
+    section.data = entities
+    while statements:
+        (code,data) = statements.pop()
+        if toggle & T_Verbose:
+            print("ent", code,data)
+        if code == 0:
+            known = True
+            if data in Ignorables:
+                ignore = True
+            else:
+                ignore = False
+
+            try:
+                creator = ClassCreators[data]
+            except:
+                creator = None
+                
+            if creator:
+                entity = eval(creator)
+            elif data == 'ENDSEC':
+                return
+            else:
+                known = False
+                
+            if data == 'POLYLINE':
+                verts = entity.verts
+            elif data == 'VERTEX':
+                verts.append(entity)
+            
+            if data == 'SEQEND':
+                attributes = []
+                known = False
+            elif creator == 0:
+                ignore = True
+            elif known:
+                entities.append(entity)
+                attributes = DxfEntityAttributes[data]
+            else:
+                raise NameError("Unknown data %s" % data)
+
+        elif not known:
+            pass
+        else:
+            expr = getAttribute(attributes, code)
+            if expr:
+                exec(expr)
+            else:
+                expr = getAttribute(DxfCommonAttributes, code)
+                if expr:
+                    exec(expr)
+                elif code >= 1000 or ignore:
+                    pass
+                elif toggle & T_Debug:
+                    raise NameError("Unknown code %d for %s" % (code, entity.type))
+                
+    return
+
+def getAttribute(attributes, code):
+    try:
+        ext = attributes[code]
+        if type(ext) == str:
+            expr = "entity.%s = data" % ext
+        else:
+            name = ext[0]
+            expr = "entity.%s" % name
+    except:
+        expr = None
+    return expr
+
+
+#      0
+#    SECTION
+#      2
+#    OBJECTS
+#    
+#      0
+#    DICTIONARY
+#      5
+#    <handle>
+#    100
+#    AcDbDictionary
+#    
+#      3
+#    <dictionary name>
+#    350
+#    <handle of child>
+#    
+#      0
+#    <object type>
+#    .
+#    . <data>
+#    .
+#    
+#      0
+#    ENDSEC 
+
+def parseObjects(data, statements, handles):
+    while statements:
+        (code,data) = statements.pop()
+        if code == 0:
+            if data == 'ENDSEC':
+                return
+
+    return
+            
+#
+#    buildGeometry(entities):
+#    addMesh(name, verts, edges, faces):                            
+#
+
+def buildGeometry(entities):
+    try: bpy.ops.object.mode_set(mode='OBJECT')
+    except: pass
+    v_verts = []
+    v_vn = 0
+    e_verts = []
+    e_edges = []
+    e_vn = 0
+    f_verts = []
+    f_edges = []
+    f_faces = []
+    f_vn = 0
+    for ent in entities:
+        if ent.drawtype in ('Mesh','Curve'):
+            (verts, edges, faces, vn) = ent.build()
+            if not toggle & T_DrawOne:
+                drawGeometry(verts, edges, faces)
+            else:
+                if verts:
+                    if faces:
+                        for i,f in enumerate(faces):
+                            #print ('face=', f)
+                            faces[i] = tuple(it+f_vn for it in f)
+                        for i,e in enumerate(edges):
+                            edges[i] = tuple(it+f_vn for it in e)
+                        f_verts.extend(verts)
+                        f_edges.extend(edges)
+                        f_faces.extend(faces)
+                        f_vn += len(verts)
+                    elif edges:
+                        for i,e in enumerate(edges):
+                            edges[i] = tuple(it+e_vn for it in e)
+                        e_verts.extend(verts)
+                        e_edges.extend(edges)
+                        e_vn += len(verts)
+                    else:
+                        v_verts.extend(verts)
+                        v_vn += len(verts)
+        else:
+            ent.draw()
+                    
+    if toggle & T_DrawOne:
+        drawGeometry(f_verts, f_edges, f_faces)
+        drawGeometry(e_verts, e_edges)
+        drawGeometry(v_verts)
+
+
+
+def drawGeometry(verts, edges=[], faces=[]):
+    if verts:
+        if edges and (toggle & T_Curves):
+            print ('draw Curve')
+            cu = bpy.data.curves.new('DXFLines', 'CURVE')
+            cu.dimensions = '3D'
+            buildSplines(cu, verts, edges)
+            ob = addObject('DXFLines', cu)
+        else:
+            #for v in verts: print(v)
+            #print ('draw Mesh with %s vertices' %(len(verts)))
+            #for e in edges: print(e)
+            #print ('draw Mesh with %s edges' %(len(edges)))
+            #for f in faces: print(f)
+            #print ('draw Mesh with %s faces' %(len(faces)))
+            me = bpy.data.meshes.new('DXFmesh')
+            me.from_pydata(verts, edges, faces)
+            ob = addObject('DXFmesh', me)
+            removeDoubles(ob)
+    return
+
+
+
+def buildSplines(cu, verts, edges):
+    if edges:
+        point_list = []
+        (v0,v1) = edges.pop()
+        v1_old = v1
+        newPoints = [tuple(verts[v0]),tuple(verts[v1])]
+        for (v0,v1) in edges:
+            if v0==v1_old:
+                newPoints.append(tuple(verts[v1]))
+            else:
+                #print ('newPoints=', newPoints)
+                point_list.append(newPoints)
+                newPoints = [tuple(verts[v0]),tuple(verts[v1])]
+            v1_old = v1
+        point_list.append(newPoints)
+        for points in point_list:
+            #spline = cu.splines.new('BEZIER')
+            spline = cu.splines.new('POLY')
+            #spline.endpoint_u = True
+            #spline.order_u = 2
+            #spline.resolution_u = 1
+            #spline.bezier_points.add(2)
+
+            spline.points.add(len(points)-1)
+            #spline.points.foreach_set('co', points)
+            for i,p in enumerate(points):
+                spline.points[i].co = (p[0],p[1],p[2],0)
+                
+        print ('spline.type=', spline.type)
+        print ('cu spline number=', len(cu.splines))
+    
+    
+def addObject(name, data):
+    ob = bpy.data.objects.new(name, data)
+    scn = bpy.context.scene
+    scn.objects.link(ob)
+    return ob
+
+
+def removeDoubles(ob):
+    global theMergeLimit
+    if toggle & T_Merge:
+        scn = bpy.context.scene
+        scn.objects.active = ob
+        bpy.ops.object.mode_set(mode='EDIT')
+        bpy.ops.mesh.remove_doubles(limit=theMergeLimit)
+        bpy.ops.object.mode_set(mode='OBJECT')
+
+
+
+#
+#    clearScene(context):
+#
+    
+def clearScene():
+    global toggle
+    scn = bpy.context.scene
+    print("clearScene %s %s" % (toggle & T_NewScene, scn))
+    if not toggle & T_NewScene:
+        return scn
+
+    for ob in scn.objects:
+        if ob.type in ["MESH", "CURVE", "TEXT"]:
+            scn.objects.active = ob
+            bpy.ops.object.mode_set(mode='OBJECT')
+            scn.objects.unlink(ob)
+            del ob
+    return scn
+
+#
+#    readAndBuildDxfFile(filepath):
+#
+
+def readAndBuildDxfFile(filepath):
+    fileName = os.path.expanduser(filepath)
+    if fileName:
+        (shortName, ext) = os.path.splitext(fileName)
+        #print("filepath: ", filepath)
+        #print("fileName: ", fileName)
+        #print("shortName: ", shortName)
+        if ext.lower() != ".dxf":
+            print("Error: Not a dxf file: " + fileName)
+            return
+        if toggle & T_NewScene:
+            clearScene()
+            if 0: # how to switch to the new scene?? (migius)
+                new_scn = bpy.data.scenes.new(shortName[-20:])
+                #new_scn.layers = (1<<20) -1
+                new_scn_name = new_scn.name
+                bpy.data.screens.scene = new_scn
+                #print("newScene: %s" % (new_scn))
+        sections = readDxfFile(fileName)
+        print("Building geometry")
+        buildGeometry(sections['ENTITIES'].data)
+        print("Done")
+        return
+    print("Error: Not a dxf file: " + filepath)
+    return
+
+#
+#    User interface
+#
+
+DEBUG= False
+from bpy.props import *
+
+def tripleList(list1):
+    list3 = []
+    for elt in list1:
+        list3.append((elt,elt,elt))
+    return list3
+
+class IMPORT_OT_autocad_dxf(bpy.types.Operator):
+    '''Import from DXF file format (.dxf)'''
+    bl_idname = "import_scene.autocad_dxf"
+    bl_description = 'Import from DXF file format (.dxf)'
+    bl_label = "Import DXF" +' v.'+ __version__
+    bl_space_type = "PROPERTIES"
+    bl_region_type = "WINDOW"
+
+    filepath = StringProperty(name="File Path", description="Filepath used for importing the DXF file", maxlen= 1024, default= "")
+
+    new_scene = BoolProperty(name="Replace scene", description="Replace scene", default=toggle&T_NewScene)
+    #new_scene = BoolProperty(name="New scene", description="Create new scene", default=toggle&T_NewScene)
+    curves = BoolProperty(name="Draw curves", description="Draw entities as curves", default=toggle&T_Curves)
+    thic_on = BoolProperty(name="Thic ON", description="Support THICKNESS", default=toggle&T_ThicON)
+
+    merge = BoolProperty(name="Remove doubles", description="Merge coincident vertices", default=toggle&T_Merge)
+    mergeLimit = FloatProperty(name="Limit", description="Merge limit", default = theMergeLimit*1e4,min=1.0, soft_min=1.0, max=100.0, soft_max=100.0)
+
+    draw_one = BoolProperty(name="Merge all", description="Draw all into one mesh-object", default=toggle&T_DrawOne)
+    circleResolution = IntProperty(name="Circle resolution", description="Circle/Arc are aproximated will this factor", default = theCircleRes,
+                min=4, soft_min=4, max=360, soft_max=360)
+    codecs = tripleList(['iso-8859-15', 'utf-8', 'ascii'])
+    codec = EnumProperty(name="Codec", description="Codec",  items=codecs, default = 'ascii')
+
+    debug = BoolProperty(name="Debug", description="Unknown DXF-codes generate errors", default=toggle&T_Debug)
+    verbose = BoolProperty(name="Verbose", description="Print debug info", default=toggle&T_Verbose)
+
+    ##### DRAW #####
+    def draw(self, context):
+        layout0 = self.layout
+        #layout0.enabled = False
+
+        #col = layout0.column_flow(2,align=True)
+        layout = layout0.box()
+        col = layout.column()
+        #col.prop(self, 'KnotType') waits for more knottypes
+        #col.label(text="import Parameters")
+        #col.prop(self, 'replace')
+        col.prop(self, 'new_scene')
+        
+        row = layout.row(align=True)
+        row.prop(self, 'curves')
+        row.prop(self, 'circleResolution')
+
+        row = layout.row(align=True)
+        row.prop(self, 'merge')
+        if self.merge:
+            row.prop(self, 'mergeLimit')
+ 
+        row = layout.row(align=True)
+        #row.label('na')
+        row.prop(self, 'draw_one')
+        row.prop(self, 'thic_on')
+
+        col = layout.column()
+        col.prop(self, 'codec')
+ 
+        row = layout.row(align=True)
+        row.prop(self, 'debug')
+        if self.debug:
+            row.prop(self, 'verbose')
+         
+    def execute(self, context):
+        global toggle, theMergeLimit, theCodec, theCircleRes
+        O_Merge = T_Merge if self.properties.merge else 0
+        #O_Replace = T_Replace if self.properties.replace else 0
+        O_NewScene = T_NewScene if self.properties.new_scene else 0
+        O_Curves = T_Curves if self.properties.curves else 0
+        O_ThicON = T_ThicON if self.properties.thic_on else 0
+        O_DrawOne = T_DrawOne if self.properties.draw_one else 0
+        O_Debug = T_Debug if self.properties.debug else 0
+        O_Verbose = T_Verbose if self.properties.verbose else 0
+
+        toggle =  O_Merge | O_DrawOne | O_NewScene | O_Curves | O_ThicON | O_Debug | O_Verbose
+        theMergeLimit = self.properties.mergeLimit*1e-4
+        theCircleRes = self.properties.circleResolution
+        theCodec = self.properties.codec
+
+        readAndBuildDxfFile(self.properties.filepath)
+        return {'FINISHED'}
+
+    def invoke(self, context, event):
+        wm = context.window_manager
+        wm.fileselect_add(self)
+        return {'RUNNING_MODAL'}
+
+def menu_func(self, context):
+    self.layout.operator(IMPORT_OT_autocad_dxf.bl_idname, text="Autocad (.dxf)")
+
+def register():
+     bpy.types.INFO_MT_file_import.append(menu_func)
+ 
+def unregister():
+    bpy.types.INFO_MT_file_import.remove(menu_func)
+
+if __name__ == "__main__":
+    register()
+
+