By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,767 Members | 1,987 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,767 IT Pros & Developers. It's quick & easy.

Parse a DXF file for lines, circles and arcs

bvdet
Expert Mod 2.5K+
P: 2,851
I wrote a script that extracts line and circle data from an Autocad DXF file:
Expand|Select|Wrap|Line Numbers
  1. ##  GridDXF.py Version 1.02
  2. ##  Copyright (c) 2006 Bruce Vaughan, BV Detailing & Design, Inc.
  3. ##  All rights reserved.
  4. ##  NOT FOR SALE. The software is provided "as is" without any warranty.
  5. ########################################################################
  6. '''
  7. parseDXFpts(file_name) - 'file_name' is the name of the DXF file to parse.
  8.                          The function returns a list of lines and a list of circles.
  9.                          All other entities are ignored.
  10.                          Each element of the line list (ptList) is a list of the x, y, z values of the two end points.
  11.                          Each element of the circle list (cirList) is a list of the x, y, z value of the end point and the radius.
  12.  
  13. formatDXFpts(ptList, cirList) - Returns a formatted string suitable for file method 'write()'.
  14.                                 The strings are formatted to be compatible with parametric GridLayout version 1.03 and greater.
  15.  
  16. Example usage:
  17.     file_name = r'C:\SDS2_7.0\macro\New Versions\Ref\grids.dxf'
  18.     gridFile = r'C:\SDS2_7.0\macro\New Versions\Ref\grid_test.txt'
  19.     f = open(gridFile, 'w')
  20.     f.write(formatDXFpts(*(parseDXFpts(file_name))))
  21.     f.close()
  22.  
  23. Version 1.00 (5/8/07)
  24. Version 1.01 (5/9/07) -     Skip until ENTITIES section using f.next()
  25.                             Remove unnecessary variable assignments
  26. Version 1.02 (5/10/07) -    Use dict.fromkeys() and f.next() to compile entity data
  27. '''
  28. def parseDXFpts(fn):
  29.     f = open(fn)
  30.  
  31.     # skip to entities section
  32.     s = f.next()
  33.     while s.strip() != 'ENTITIES':
  34.         s = f.next()
  35.  
  36.     inLine = False
  37.     inCircle = False
  38.  
  39.     ptList = []
  40.     cirList = []
  41.  
  42.     for line in f:
  43.         line = line.strip()
  44.         # In ENTITIES section, iteration can cease when ENDSEC is reached
  45.         if line == 'ENDSEC':
  46.             break
  47.  
  48.         elif inLine == True:
  49.             dd = dict.fromkeys(['10','20','30','11','21','31'], 0.0)
  50.             while line != '0':
  51.                 if line in dd:
  52.                     dd[line] = f.next().strip()
  53.                 line = f.next().strip()
  54.             ptList.append([[dd['10'], dd['20'], dd['30']], [dd['11'], dd['21'], dd['31']]])
  55.             inLine = False
  56.  
  57.         elif inCircle == True:
  58.             dd = dict.fromkeys(['10','20','30','40'], 0.0)
  59.             while line != '0':
  60.                 if line in dd:
  61.                     dd[line] = f.next().strip()
  62.                 line = f.next().strip()
  63.             cirList.append([[dd['10'], dd['20'], dd['30']], dd['40']])
  64.             inCircle = False
  65.  
  66.         else:
  67.             if line == 'LINE':
  68.                 inLine = True
  69.             elif line == 'CIRCLE' or line == 'ARC':
  70.                 inCircle = True
  71.  
  72.     f.close()
  73.  
  74.     return ptList, cirList
  75.  
  76. # base must be a tuple or list, not a Point object
  77. def formatDXFpts(ptList, cirList, base=False):
  78.     outList = []
  79.     for pt1, pt2 in ptList:
  80.         if base:
  81.             pt1 = map(str, [i+j for i,j in zip(map(float, pt1), base)])
  82.             pt2 = map(str, [i+j for i,j in zip(map(float, pt2), base)])
  83.         # ExplicitL: 20-0, 20-0, 20-0 : 40-0, 40-0, 40-0
  84.         outList.append('ExplicitL: %s : %s' % (', '.join(pt1), ', '.join(pt2)))
  85.     for pt1, rad in cirList:
  86.         if base:
  87.             pt1 = map(str, [i+j for i,j in zip(map(float, pt1), base)])
  88.         # ExplicitR: 20-0, 20-0, 20-0 : 15-0    
  89.         outList.append('ExplicitR: %s : %s' % (', '.join(pt1), rad))
  90.     return '\n'.join(outList)
  91.  
  92. if __name__ == '__main__':
  93.  
  94.     fn = r'C:\SDS2_7.0\macro\New Versions\Ref\grids2.dxf'
  95.     gridStr = formatDXFpts(base=(0.0, -2000.0, -2000.0),*(parseDXFpts(fn)))
  96.     print gridStr
  97.     '''
  98.     file_name = r'C:\SDS2_7.0\macro\New Versions\Ref\grids.dxf'
  99.     gridFile = r'C:\SDS2_7.0\macro\New Versions\Ref\grid_test.txt'
  100.     f = open(gridFile, 'w')
  101.     f.write(formatDXFpts(*(parseDXFpts(file_name))))
  102.     f.close()
  103.     '''
  104.  
  105. '''
  106. >>> ExplicitL: 9816.68821752379, 9342.150641757189, 0.0 : 5891.694641987371, 7589.498197195453, 0.0
  107. ExplicitL: 13837.65104243732, 8933.988514331103, 0.0 : 14456.10878705126, 5947.569025541323, 0.0
  108. ExplicitL: 13863.97763099647, 8944.937937731237, 0.0 : 14483.88419985993, 5951.522341265071, 0.0
  109. ExplicitL: 15455.83326287129, 6340.472643957712, 0.0 : 14921.10765265826, 6149.932906111864, 0.0
  110. ExplicitL: 16488.77763008338, 6904.236993653539, 0.0 : 15978.35671679392, 6590.049547387251, 0.0
  111. ExplicitL: 3966.563802256045, 10246.06975532415, 0.0 : 18100.41385149004, 10246.06975532415, 0.0
  112. ExplicitR: 16534.87751064366, 4916.545768317483, 0.0 : 380.8099725875799
  113. ExplicitR: 17010.88992108956, 14650.96205330669, 0.0 : 299.1021903913424
  114. >>>
  115. '''
Any suggestions for improvement would be appreciated.
May 10 '07 #1
Share this Question
Share on Google+
3 Replies


bartonc
Expert 5K+
P: 6,596
Thanks, Bruce. I've copied you post to the Articles section.
May 10 '07 #2

P: 39
Hi there. I was looking at your code and was trying to figure out how it works.
What I'm looking to do is to parse out a list of coordinates from a 3D polyline.
My specific question is how to you know where in the dxf file to look for the coordinates?
I've been viewing the dxf file from notepad and can find the coordinates but don't understand how to extract them.
Thanks
Miguel
Nov 28 '11 #3

bvdet
Expert Mod 2.5K+
P: 2,851
Hello Miguel,

In my code, I am looking for 'LINE', 'CIRCLE', and 'ARC' entities. When one of these keywords is encountered, I set a flag for that entity type to True for the next iteration on the file object. You can see in the code elif inLine == True is where a line entity is found. I need data for the end points - left end 10, 20, 30 xyz and right end 11, 21, 31 xyz values. That's all I am interested in, so I create a dictionary with those keys, assign the data to the appropriate key, skip any other unwanted data, and iterate to the next section using file object method next(). You could do something similar looking for POLYLINE entities.
Nov 29 '11 #4

Post your reply

Sign in to post your reply or Sign up for a free account.