我想用python制作一个表格,就像绘图中使用的COUNT LIST命令一样。我正在提取绘图中使用的块的数量,但无法提取动态块的数量。我想要做的是计算我确定的动态和正常块,例如“门,窗,厕所”,并将它们打印在表中。从现在开始谢谢你。
import ezdxf
doc = ezdxf.readfile("Python.dxf")
blocks = doc.blocks
msp = doc.modelspace()
block_usage_count = {}
inserts = msp.query('INSERT')
for insert in inserts:
block_name = insert.dxf.name
block_usage_count[block_name] = block_usage_count.get(block_name, 0) + 1
print("Block Name | Usage Count")
print("------------------------")
for block_name, usage_count in block_usage_count.items():
print(f"{block_name:10} | {usage_count:11}")
为什么不使用 AutoCAD 中包含的“计数”命令?
我最终遇到了类似的问题,但找不到任何解决方案。 经过大量挖掘后,我找到了一个。我在这里分享它是为了帮助未来遇到同样问题的人。
autocad 中动态块的问题是,从它们创建的块具有不同的名称(通常以 * 开头)。 ezdxf 只是一个 dxf 阅读器,不提供开箱即用的处理。但所有相关信息实际上都可以在 ezdxf 中找到
对于动态块,有关原始块的信息将作为扩展数据保存在创建的块中。
所以需要的步骤是:
这里是这样的:
import ezdxf
from collections import defaultdict
doc = ezdxf.readfile("Python.dxf")
msp = doc.modelspace()
block_usage_count = defaultdict(int)
inserts = msp.query('INSERT')
def get_xdata_name(name):
try:
xdata = doc.blocks[name].block_record.get_xdata('AcDbBlockRepBTag')
except Exception as exc:
print(f"Error reading xdata for {name}")
print(exc)
return name
for tag, value in xdata:
if tag == 1005:
new_name = doc.entitydb[value].dxf.name
print(f"new name {new_name}")
return new_name
for insert in inserts:
block_name = insert.dxf.name
if block_name.startswith('*'):
print(f"anonymous name {block_name}")
name = get_xdata_name(block_name)
else:
name = block_name
block_usage_count[name] += 1
print("Block Name | Usage Count")
print("------------------------")
for block_name, usage_count in block_usage_count.items():
print(f"{block_name} | {usage_count}")
它并非万无一失,但可以处理大多数情况。 如果在尝试检索 AcDbBlockRepBTag 时出现错误,我建议查看有关 xdata 的详细信息并查看存在哪些 APPID。
如果您好奇为什么
tag == 1005
请查看此处: