ezdxf 中未实现重命名层。图层的使用不受表格条目的约束,这意味着如果您重命名图层表格条目,该图层的所有实体仍然具有存储为 DXF 属性的旧图层名称,请记住 ezdxf 是 DXF 文件格式的接口而不是 CAD应用。在您的特殊情况下,DIMENSION 实体也具有匿名 BLOCK 的图形表示,该 BLOCK 的所有实体仍可能引用旧图层名称,其他 BLOCKS 和图纸空间布局的一些实体也可能。这是重命名层和引用该层的所有实体的代码,测试版本为 v0.10:
import ezdxf
def rename_layer(doc, old, new):
"""
Works only for layers with an entry in the layer table,
layers can be used without such an entry.
"""
if old not in doc.layers:
raise ValueError('Old layer "{}" does not exist.'.format(old))
if new in doc.layers:
raise ValueError('New layer "{}" does already exist.'.format(new))
def rename_layer_table_entry():
layer = doc.layers.get(old)
layer.dxf.name = new
# this is an internal API call, renaming table entries isn't implemented (yet)
doc.layers.replace(old, layer)
def rename_entities_layer_attribute():
# layer names are case insensitive
old_lower = old.lower()
# iterate over all entities of modelspace, paperspace layouts
# and block definitions
for e in doc.chain_layouts_and_blocks():
if e.get_dxf_attrib('layer', '0').lower() == old_lower:
e.dxf.layer = new
rename_layer_table_entry()
rename_entities_layer_attribute()
# TESTING
def add_entities(layout):
layout.add_text('A', dxfattribs={'layer': 'text'})
layout.add_line((0, 0), (1, 1), dxfattribs={'layer': 'line'})
doc = ezdxf.new('R2010')
doc.layers.new('text')
doc.layers.new('line')
msp = doc.modelspace()
add_entities(msp)
blk = doc.blocks.new('Test')
add_entities(blk)
rename_layer(doc, 'text', 'text1')
rename_layer(doc, 'line', 'line1')
assert msp[0].dxf.layer == 'text1'
assert msp[1].dxf.layer == 'line1'
assert blk[0].dxf.layer == 'text1'
assert blk[1].dxf.layer == 'line1'
assert 'text1' in doc.layers
assert 'line1' in doc.layers
此功能不关心现有的图层过滤器,这些过滤器可能会损坏或冻结视口中的图层以及我仍然不知道的所有事情。整体重命名图层不是一个好主意,可能会产生不可读的 DXF 文件。
更新:
将rename 方法添加到Layer,将与v0.10b4 一起发布:
layer = doc.layers.get(old_name)
layer.rename(new_name)
重命名所有已知层引用,但不用于 LAYER_INDEX 和 LAYER_FILTER,ezdxf 只是将这两个实体保存为一堆标签,所以要小心 - 用 ezdxf 重命名层可能会损坏 DXF 文件。