如何使用ezdxf查找诸如块/圆之类的镜像实体的位置?

时间:2019-12-14 06:56:05

标签: python autocad cad dxf ezdxf

如何计算已镜像的块或插入实体的位置?

“ wb”插入/块实体内有一个圆圈。我试图确定它在msp上的位置并画一个圆圈。附件DXF文件中有2个“ wb”块,其中一个已镜像。

DXF文件链接:the iteratee design pattern

import ezdxf
from ezdxf.math import Vector

DXFFILE = 'washbasins.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=3, dxfattribs={'layer': 'MyCircles'})

dwg.saveas(OUTFILE)

上面的代码不适用于AutoCAD文件中镜像的块。它的圆是在非常不同的位置绘制的。对于通过mirror命令放置的块,entity.dxf.insert和entity.dxf.rotation返回的点和旋转与通过复制和旋转将块放置在其中的点和旋转不同。

在这种情况下,请提供帮助。同样,我们将如何处理线和圆实体?请共享相同的python函数/代码。

1 个答案:

答案 0 :(得分:0)

由于要获得相对于块定义基点的圆心,因此需要构造一个4x4转换矩阵,该矩阵对for循环中遇到的每个块参考的XYZ比例,旋转和方向进行编码。

库有用地包含Matrix44 class,它将为您处理矩阵乘法。这样的矩阵的构建将遵循以下方式:

import math
import ezdxf
from ezdxf.math import OCS, Matrix44

ocs = math.OCS(e.dxf.extrusion)
Matrix44.chain
(
    Matrix44.ucs(ocs.ux, ocs.uy, ocs.uz),
    Matrix44.z_rotate(e.get_dxf_attrib('rotation', 0)),
    Matrix44.scale
    (
        e.get_dxf_attrib('xscale', 1),
        e.get_dxf_attrib('yscale', 1),
        e.get_dxf_attrib('zscale', 1)
    )
)

然后,您可以使用此矩阵transform从坐标系相对于块定义到相对于块参照的圆心坐标。 strong>,即对象坐标系(OCS)。

转换后,还需要使用一个向量转换坐标,该向量是使用上述矩阵计算的,作为块参考插入点和transformation之后的块定义基点之间的差。

mat = Matrix44.chain ...
vec = e.dxf.insert - mat.transform(block.dxf.base_point) 

然后最终位置为:

location = mat.transform(circle.dxf.center) + vec