如何使用 ezdxf python 包修改现有的 dxf 文件?
How to modify an existing dxf file using ezdxf python package?
我正在尝试使用 ezdxf 将实体添加到现有 .dxf 文件的模型空间。插入实体的位置完全偏离我预期的位置。
对于一个圆,我通过e.dxf.insert得到了一个实体的位置坐标,并以此点作为圆心。我使用了以下代码:
import ezdxf
dwg = ezdxf.readfile("drainage.dxf")
msp = dwg.modelspace()
dwg.layers.new(name='MyCircles', dxfattribs={'color': 7})
def encircle_entity(e):
if e.dxftype()=='INSERT':
circleCenter = e.dxf.insert
msp.add_circle(circleCenter, 10, dxfattribs={'layer': 'MyCircles'})
print("Circle entity added")
washBasins = msp.query('*[layer=="WASH BASINS"]')
for e in washBasins:
encircle_entity(e)
dwg.saveas('encircle.dxf')
Link 到 drainage.dxf(输入)和 encircle.dxf(输出)文件:https://drive.google.com/open?id=1aIhZiuEdClt0warjPPcKiz4XJ7A7QWf_
这创建了一个圆圈,但位置不正确。
dxf文件的来源和ezdxf使用的来源在哪里?
如何获得所有实体的正确位置,尤其是 INSERT、LINES 和 CIRCLES?
如何使用 ezdxf 将我的实体放置在现有 dxf 文件中的所需位置?
直线相对于坐标的 e.dxf.start 和 e.dxf.end 点在哪里?
我想我在这里的坐标中遗漏了一些东西。请解释坐标的工作原理。
平面对象(例如圆弧、圆、二维多段线 (LWPOLYLINEs
)、块引用 (INSERTs
),仅举几例)是相对于 定义的为它们所在的平面计算的对象坐标系 (OCS)。
此坐标系与世界坐标系 (WCS) 具有相同的原点,但 X 轴和 Y 轴矢量是使用 Arbitrary Axis Algorithm 计算的,对于给定的挤压矢量或法向平面平面对象驻留。
我可以看到您当前的代码正在驻留在图层 WASH BASINS
上的所有块引用 (INSERTs
) 的插入点坐标处生成圆。
每个块参考的插入点坐标是相对于使用与块参考关联的挤压矢量(DXF 组 210
)计算的 OCS 表示的。
圆的中心点坐标也是相对于圆的 OCS 表示的,因此,要匹配块参考的位置,您需要提供add_circle
方法 块参考的拉伸矢量,因此插入点坐标和中心坐标都是相对于 相同坐标系.
因此,代码应该变成:
def encircle_entity(e):
if e.dxftype()=='INSERT':
circleCenter = e.dxf.insert
msp.add_circle(circleCenter, 10, dxfattribs={'layer': 'MyCircles', 'extrusion': e.dxf.extrusion})
print("Circle entity added")
Python @LeeMac 解决方案的版本,但忽略了 OCS:
import ezdxf
from ezdxf.math import Vector
DXFFILE = 'drainage.dxf'
OUTFILE = 'encircle.dxf'
dwg = ezdxf.readfile(DXFFILE)
msp = dwg.modelspace()
dwg.layers.new(name='MyCircles', dxfattribs={'color': 4})
def get_first_circle_center(block_layout):
block = block_layout.block
base_point = Vector(block.dxf.base_point)
circles = block_layout.query('CIRCLE')
if len(circles):
circle = circles[0] # take first circle
center = Vector(circle.dxf.center)
return center - base_point
else:
return Vector(0, 0, 0)
# block definition to examine
block_layout = dwg.blocks.get('WB')
offset = get_first_circle_center(block_layout)
for e in msp.query('INSERT[name=="WB"]'):
scale = e.get_dxf_attrib('xscale', 1) # assume uniform scaling
_offset = offset.rotate_deg(e.get_dxf_attrib('rotation', 0)) * scale
location = e.dxf.insert + _offset
msp.add_circle(center=location, radius=1, dxfattribs={'layer': 'MyCircles'})
dwg.saveas(OUTFILE)
我正在尝试使用 ezdxf 将实体添加到现有 .dxf 文件的模型空间。插入实体的位置完全偏离我预期的位置。
对于一个圆,我通过e.dxf.insert得到了一个实体的位置坐标,并以此点作为圆心。我使用了以下代码:
import ezdxf
dwg = ezdxf.readfile("drainage.dxf")
msp = dwg.modelspace()
dwg.layers.new(name='MyCircles', dxfattribs={'color': 7})
def encircle_entity(e):
if e.dxftype()=='INSERT':
circleCenter = e.dxf.insert
msp.add_circle(circleCenter, 10, dxfattribs={'layer': 'MyCircles'})
print("Circle entity added")
washBasins = msp.query('*[layer=="WASH BASINS"]')
for e in washBasins:
encircle_entity(e)
dwg.saveas('encircle.dxf')
Link 到 drainage.dxf(输入)和 encircle.dxf(输出)文件:https://drive.google.com/open?id=1aIhZiuEdClt0warjPPcKiz4XJ7A7QWf_
这创建了一个圆圈,但位置不正确。
dxf文件的来源和ezdxf使用的来源在哪里? 如何获得所有实体的正确位置,尤其是 INSERT、LINES 和 CIRCLES? 如何使用 ezdxf 将我的实体放置在现有 dxf 文件中的所需位置? 直线相对于坐标的 e.dxf.start 和 e.dxf.end 点在哪里?
我想我在这里的坐标中遗漏了一些东西。请解释坐标的工作原理。
平面对象(例如圆弧、圆、二维多段线 (LWPOLYLINEs
)、块引用 (INSERTs
),仅举几例)是相对于 定义的为它们所在的平面计算的对象坐标系 (OCS)。
此坐标系与世界坐标系 (WCS) 具有相同的原点,但 X 轴和 Y 轴矢量是使用 Arbitrary Axis Algorithm 计算的,对于给定的挤压矢量或法向平面平面对象驻留。
我可以看到您当前的代码正在驻留在图层 WASH BASINS
上的所有块引用 (INSERTs
) 的插入点坐标处生成圆。
每个块参考的插入点坐标是相对于使用与块参考关联的挤压矢量(DXF 组 210
)计算的 OCS 表示的。
圆的中心点坐标也是相对于圆的 OCS 表示的,因此,要匹配块参考的位置,您需要提供add_circle
方法 块参考的拉伸矢量,因此插入点坐标和中心坐标都是相对于 相同坐标系.
因此,代码应该变成:
def encircle_entity(e):
if e.dxftype()=='INSERT':
circleCenter = e.dxf.insert
msp.add_circle(circleCenter, 10, dxfattribs={'layer': 'MyCircles', 'extrusion': e.dxf.extrusion})
print("Circle entity added")
Python @LeeMac 解决方案的版本,但忽略了 OCS:
import ezdxf
from ezdxf.math import Vector
DXFFILE = 'drainage.dxf'
OUTFILE = 'encircle.dxf'
dwg = ezdxf.readfile(DXFFILE)
msp = dwg.modelspace()
dwg.layers.new(name='MyCircles', dxfattribs={'color': 4})
def get_first_circle_center(block_layout):
block = block_layout.block
base_point = Vector(block.dxf.base_point)
circles = block_layout.query('CIRCLE')
if len(circles):
circle = circles[0] # take first circle
center = Vector(circle.dxf.center)
return center - base_point
else:
return Vector(0, 0, 0)
# block definition to examine
block_layout = dwg.blocks.get('WB')
offset = get_first_circle_center(block_layout)
for e in msp.query('INSERT[name=="WB"]'):
scale = e.get_dxf_attrib('xscale', 1) # assume uniform scaling
_offset = offset.rotate_deg(e.get_dxf_attrib('rotation', 0)) * scale
location = e.dxf.insert + _offset
msp.add_circle(center=location, radius=1, dxfattribs={'layer': 'MyCircles'})
dwg.saveas(OUTFILE)