分析DXF文件中的直线、圆和圆弧

我编写了一个从AutoCAD DXF文件中提取直线和圆数据的脚本:

选择 | 换行 | 行号
  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. '''

如有任何改进建议,我们将不胜感激。

# 回答1


谢谢,布鲁斯。我已经把你的帖子复制到了文章部分。
# 回答2


嗨,你好啊。我正在看你的代码,并试图弄清楚它是如何工作的。
我想要做的是从3D多段线中解析出一个坐标列表。
我的具体问题是,如何知道在DXF文件中的何处查找坐标?
我一直在记事本上查看DXF文件,可以找到坐标,但不知道如何提取它们。
谢谢
米格尔
# 回答3


你好,米格尔,
在我的代码中,我要查找'line'、'Circle'和'ARC'实体。当遇到这些关键字之一时,对于文件对象的下一次迭代,我将该实体类型的标志设置为True。您可以在代码中看到
Elif inline==True
是找到直线实体的位置。我需要终点的数据-左端10、20、30 XZ值和右端11、21、31 XZ值。这就是我感兴趣的全部内容,所以我使用这些键创建了一个词典,将数据分配给适当的键,跳过任何其他不需要的数据,并使用文件对象方法迭代到下一节
下一个()
。您可以执行类似的操作来查找多段线实体。

标签: python

添加新评论