【AI+CAD】(一)ezdxf 解析DXF文件

DXF文件格式理解

DXF文件格式是矢量图形文件格式,其详细说明了如何表示不同的图形元素。
DXF是一个矢量图形文件,它捕获CAD图形的所有元素,例如文本,线条和形状。更重要的是,DXF是用于在CAD应用程序之间传输数据的图形交换文件。

使用组代码表示数据

DXF文件中的每个变量都与一个组码相关联(组码的范围从1到1071)。
每个组代码都在特定情况下使用,并包含特定类型的信息。
例如,组代码2用于名称,例如节的名称或块的名称。
组代码0表示实体的开头或文件的结尾。
与每个变量关联的值存储为整数,浮点数或字符串。例如,线的长度存储为整数,而点坐标存储为浮点数。

DXF文件结构

DXF文件分为几个部分:每个部分都由记录组成,而记录又由组代码和关联的数据值组成。

您可以按以下顺序在DXF文件中找到以下部分:

在这里插入图片描述

Drawing 类

在一个 DXF 文档中,Drawing 类是一个核心的管理结构,它负责组织和管理整个绘图的元素。Drawing 类提供了创建、修改和访问DXF文件中不同部分的方法,如实体(entities)、块(blocks)、图层(layers)、样式(styles)等

Drawing 类充当了绘图元素的容器,允许轻松地对绘图元素进行操作和互动。它通常代表整个 DXF 文档,并提供了与文档内容有效交互的功能。

获取DXF Drawing 对象

doc = ezdxf.new()
doc = ezdxf.readfile(file_path)

访问DXF的各个部分

import ezdxf,matplotlib
file_path = "E:\\7创业\\AI+Clothes\\data\\裤子版dxf\\K009.dxf"
doc = ezdxf.readfile(file_path)

print(doc.header) # HeaderSection
print(doc.classes) # ClassesSection
print(doc.tables) # TablesSection
print(doc.blocks) # BlocksSection
print(doc.entities) # EntitySection 
print(doc.objects) # ObjectsSection

提供了访问Layouts的方法:

Drawing.modelspace()
Drawing.paperspace()

提供了访问全局资源/属性的方法:

Application ID Table: Drawing.appids

Block Definition Table: Drawing.blocks

Dimension Style Table: Drawing.dimstyles

Layer Table: Drawing.layers

Linetype Table: Drawing.linetypes

MLeader Style Table: Drawing.mleader_styles

MLine Style Table: Drawing.mline_styles

Material Table: Drawing.materials

Text Style Table: Drawing.styles

UCS Table: Drawing.ucs

VPort Table: Drawing.viewports

View Table: Drawing.views

Classes Section: Drawing.classes

Object Section: Drawing.objects

Entity Database: Drawing.entitydb

Entity Groups: Drawing.groups

Header Variables: Drawing.header

Header Section

Drawing的设置存储在 HEADER 部分,可通过对象header的属性访问。具体key看这里。

0           <<< Begin HEADER section
SECTION
2
HEADER
9
$ACADVER    <<< Header variable items go here
1
AC1009
...
0
ENDSEC      <<< End HEADER section

例如看header中CAD的版本:

import ezdxf
file_path = "E:\\7创业\\AI+Clothes\\data\\裤子版dxf\\K009.dxf"
doc = ezdxf.readfile(file_path)
print(doc.header['$ACADVER'])

Classes Section

DXF 文件中的 CLASSES 部分保存应用程序定义的类的信息,这些类的实例出现在Layout对象中。作为通常的包用户,无需担心类。

Tables Section

Tables Section是DXF 文档的资源表,用于 图层layers、线型linetypes、文本样式和形状文件 styles、尺寸样式 dimstyles、唯一应用程序ID appids、用户坐标系 ucs、msp视图 views、psp视图 viewports、块记录block_records等全局资源信息的table

0
SECTION
2           <<< begin TABLES section
TABLES
0           <<< first TABLE
TABLE
2           <<< name of table "LTYPE"
LTYPE
5           <<< handle of the TABLE
8
330         <<< owner handle is always "0"
0
100         <<< subclass marker
AcDbSymbolTable
70          <<< count of table entries
4           <<< do not rely on this value!
0           <<< first table entry
LTYPE
...
0           <<< second table entry
LTYPE
...
0           <<< end of TABLE
ENDTAB
0           <<< next TABLE
TABLE
2           <<< name of table "LAYER"
LAYER
5           <<< handle of the TABLE
2
330         <<< owner handle is always "0"
0
100         <<< subclass marker
AcDbSymbolTable
70          <<< count of table entries
1
0           <<< first table entry
LAYER
...
0           <<< end of TABLE
ENDTAB
0           <<< end of SECTION
ENDSEC
import ezdxf
file_path = "E:\\7创业\\AI+Clothes\\data\\裤子版dxf\\K009.dxf"
doc = ezdxf.readfile(file_path)

for i in doc.tables.appids:
    print(i)
for i in doc.tables.layers:
    print(i)
for i in doc.tables.linetypes:
    print(i)
for i in doc.tables.styles:
    print(i)
for i in doc.tables.dimstyles:
    print(i)
for i in doc.tables.ucs:
    print(i)
for i in doc.tables.views:
    print(i)
for i in doc.tables.viewports:
    print(i)
for i in doc.tables.block_records:
    print(i)

Blocks Section

Blocks Section是DXF 文档的所有块定义 ( BlockLayout ) 的所在地。除了INSERT 实体使用的正常可重用 BLOCKS 之外,所有布局(因为有MODEL_SPACE和所有PAPER_SPACE)在 BLOCKS 部分中至少有一个相应的 BLOCK 定义。模型空间 BLOCK 的名称为“*Model_Space”,图纸空间 BLOCK 的名称为“*Paper_Space”。

import ezdxf
file_path = "E:\\7创业\\AI+Clothes\\data\\裤子版dxf\\K009.dxf"
doc = ezdxf.readfile(file_path)

for i in doc.blocks:
    print(i.dxf.name)

Entities Section

Entities Section是Modelspace 和 active Paperspace中图像实体的主页。查看Modelspace 和 active Paperspace中entity的个数。

import ezdxf
file_path = "E:\\7创业\\AI+Clothes\\data\\裤子版dxf\\K009.dxf"
doc = ezdxf.readfile(file_path)

print(len(doc.entities))

Objects Section

Objects Section 是 DXF 文档中所有非图形对象的主页。

DXF Entities

DXF Entities 是存储在 Modelspace, PaperspaceBlockLayout 三种Layouts中的 可见对象。它们代表构成 2D 或 3D 设计的各种形状、线条和其他元素。

查看modelspace中各个实体的类型:CIRCLE、POLYLINE、LINE等

import ezdxf
doc = ezdxf.readfile("shapes.dxf")

# iterate over all entities in modelspace
msp = doc.modelspace()
for e in msp:
    print(e.dxftype())

DXF 实体的一些常见类型包括:(所有DXF entity的基类ezdxf.entities.DXFEntity

  • LINEPOLYLINE: 这些是 DXF 文件的基本构建块。它们代表直线和曲线

  • CIRCLEARC: 这些实体分别表示圆的一部分

  • TEXTMTEXT: 文本实体,可用于标记设计的各个部分或提供其他信息。

  • HATCH: 填充图案实体,用于填充具有特定图案或纹理的区域。

  • DIMENSION: 尺寸实体,它提供设计中各种元素的精确测量。

  • INSERT: BlockLayouts是一组实体,其中每个实体是 INSERT类型的重用实体,可用用于多次插入到其他layouts中,这使其成为重用设计元素的有用方法。

DXFEntity 和 DXFGraphic

DXFEntity是所有DXF实体的基类,查看DXFEntity的.dxf属性命名空间

doc = ezdxf.readfile(file_path)
# iterate over all entities in modelspace
msp = doc.modelspace()
for e in msp:
    # dxf属性命名空间
    if e.dxf.dxftype != 'TEXT':
        print(e.dxf.name, e.dxf.dxftype, e.dxf.layer)

DXFGraphic是所有图像DXF实体的基类,继承了DXFEntity,拥有众多图形实体的属性:color, linetype, lineweight, true_color, transparency, ltscaleinvisiblegraphic_properties方法会返回各种图形实体的属性。

msp = doc.modelspace()
for e in msp:
    if e.dxftype() == 'LINE':
        print(e.dxftype(), e.graphic_properties())

Graphical Entity Attributes 图形实体属性

所有图形实体的属性color, linetype, lineweight, true_color, transparency, ltscaleinvisible都可以通过.dxf属性命名空间获取:e.dxf.attribute。 除了true_color 和transparency是必须的,有默认值,其他属性都是可选的。

不同DXF版本支持不同的属性:
在这里插入图片描述

  • AutoCAD 颜色索引 (ACI):该e.dxf.color属性表示ACI (AutoCAD 颜色索引)。该color属性的默认值为 256,这意味着采用与实体关联的layer定义的颜色
    在这里插入图片描述
msp = doc.modelspace()
for e in msp:
    if e.dxftype() == 'LINE':
        print(e.dxf.color)
  • 真彩色True Color:所有图形实体都直接支持 e.true_color/e.rgb属性来获取和设置真彩色作为 (r, g, b) 元组,其中分量必须在 0 到 255 的范围内。真实颜色值True Color的优先级高于AutoCAD 颜色索引 (ACI)值。
import ezdxf

doc = ezdxf.new()
msp = doc.modelspace()
line = msp.add_line((0, 0), (10, 0))
line.rgb = (255, 128, 32)
  • 透明度Transparency:所有图形实体都支持 transparency获取和设置透明度的属性,该e.transparency属性是一个介于 0.0 到 1.0 范围内的浮点值,其中 0.0 表示不透明,1.0 表示完全透明:
import ezdxf

doc = ezdxf.new()
msp = doc.modelspace()
line = msp.add_line((0, 0), (10, 0))
line.transparency = 0.5
  • 线型Linetypese.dxf.linetype定义线性图形实体(如 LINE、ARC、CIRCLE 等)的渲染模式。查看dxf文件中可用的线性及其描述。默认值为“BYLAYER”:ByLayer随层,图形对象的属性使用它所在图层的属性。图形对象的默认属性是ByLayer,也就是将同类的很多图形放到一个图层上,通过图层来控制图形的属性。未设置默认Cotinuous。
import ezdxf,matplotlib
file_path = "E:\\7创业\\AI+Clothes\\data\\裤子版dxf\\K009.dxf"
doc = ezdxf.readfile(file_path)

# iterate over all entities in modelspace
msp = doc.modelspace()
for e in msp:
    if e.dxftype() == 'LINE':
        print(e.dxf.linetype)

# iteration
print(f"There are {len(doc.linetypes)} available linetypes: ")
for lt in doc.linetypes:
    print(f"{lt.dxf.name}: {lt.dxf.description}")

在这里插入图片描述

  • 线宽Lineweightse.dxf.lineweight毫米 * 100 为单位的整数值,例如 0.25mm = 25,与 DXF 文档中使用的单位系统无关。ByBlock:随块,图形对象的属性使用它所在图块的属性。如果图形对象属性设置成ByBlock,但没有被定义成块,此对象将使用默认的属性,颜色是白色、线宽为默认线宽、线型为实线。默认值为 -1
    在这里插入图片描述
msp = doc.modelspace()
for e in msp:
    if e.dxftype() == 'LINE':
        print(e.dxf.lineweight)

将 HEADER 变量设置$LWDISPLAY为 1,激活对在屏幕上显示线宽的支持:

# activate on screen lineweight display
doc.header["$LWDISPLAY"] = 1

在这里插入图片描述

  • 线型比例 ltscale:ltscale属性通过浮点值缩放线型图案,是可选的,默认值为 1.0
# iterate over all entities in modelspace
msp = doc.modelspace()
for e in msp:
    if e.dxftype() == 'LINE':
        print(e.dxf.ltscale )
  • 不可见性invisible:invisible属性是一个布尔值(0/1),定义实体是不可见还是可见。默认值为 0可见。
msp = doc.modelspace()
for e in msp:
    if e.dxftype() == 'LINE':
        print(e.dxf.invisible )
  • 世界坐标系(WCS):世界坐标系——参考坐标系。所有其他坐标系都是相对于 WCS 定义的,永远不会改变。
  • 用户坐标系(UCS): 用户定义的工作坐标系,使绘图任务更容易。DXF 文件中存储的所有坐标都是 WCS 或 OCS,而不是 UCS。
  • 对象坐标系 (OCS):对象坐标系是相对于对象本身的坐标。OCS 的主要目标是将 2D 元素放置在 3D 空间中,OCS 由实体的挤压向量定义。只要挤压矢量为 (0, 0, 1)(WCS z 轴),OCS 就与 WCS 重合,这意味着 OCS 坐标等于 WCS 坐标,大多数情况下对于 2D 实体来说都是如此。
    • 以下3D实体不位于特定平面内。所有点均以世界坐标表示。在这些实体中,只能挤出线和点。它们的挤出方向可能与世界 z 轴不同:Line、Point、3DFace、Polyline(3D)、Vertex(3D)、Polymesh、Polyface、Viewport。
    • 以下2D实体本质上是平面的。所有点均以对象坐标表示。所有这些实体都可以被挤压。它们的挤出方向可能与世界 z 轴不同:Circle、Arc、Solid、Trace、Text、Attrib、Attdef、Shape、Insert、Polyline(二维)、Vertex(二维)、LWPolyline、Hatch、Image。
if (abs(Az.x) < 1/64.) and (abs(Az.y) < 1/64.):
     Ax = Vec3(0, 1, 0).cross(Az).normalize()  # the cross-product operator
else:
     Ax = Vec3(0, 0, 1).cross(Az).normalize()  # the cross-product operator
Ay = Az.cross(Ax).normalize()
Az = Vec3(entity.dxf.extrusion).normalize()  # normal (extrusion) vector

def wcs_to_ocs(point):
    px, py, pz = Vec3(point)  # point in WCS
    x = px * Ax.x + py * Ax.y + pz * Ax.z
    y = px * Ay.x + py * Ay.y + pz * Ay.z
    z = px * Az.x + py * Az.y + pz * Az.z
    return Vec3(x, y, z)

Wx = wcs_to_ocs((1, 0, 0))
Wy = wcs_to_ocs((0, 1, 0))
Wz = wcs_to_ocs((0, 0, 1))

def ocs_to_wcs(point):
    px, py, pz = Vec3(point)  # point in OCS
    x = px * Wx.x + py * Wx.y + pz * Wx.z
    y = px * Wy.x + py * Wy.y + pz * Wy.z
    z = px * Wz.x + py * Wz.y + pz * Wz.z
    return Vec3(x, y, z)
  • 图层Layers:Layers是一种entity属性的集合属性。每个对象都有一个Layers作为其属性之一。layer 然后通过将传递Layers name字符串,将这些Layers 的属性分配给其他 DXF 实体。如实体可以通过使用字符串’BYLAYER’作为线型字符串、256颜色或-1线宽,从名称为’BYLAYER’的Layers继承此属性,所有这些值都是新实体的默认值。
import ezdxf

doc = ezdxf.new(setup=True)  # setup required line types
msp = doc.modelspace()
doc.layers.add(name="MyLines", color=7, linetype="DASHED")
# 新entity继承名为"MyLines"的layers的属性
msp.add_line((0, 0), (10, 0), dxfattribs={"layer": "MyLines"})
# 灵活切换layers
# move the entity to layer "OtherLayer"
line.dxf.layer = "OtherLayer"

# 查看dxf文件中的所有layers
import ezdxf,matplotlib
file_path = "E:\\7创业\\AI+Clothes\\data\\裤子版dxf\\K009.dxf"
doc = ezdxf.readfile(file_path)
for l in doc.layers:
    print(l.dxf.name)

Point,LINE,Circle,Arc,Ellipse,Text,Insert

以下示例中的图元始终放置在 WCS 的 xy 平面(即 2D 绘图空间)中。 其中一些实体只能放置在 3D 空间的 xy 平面之外 利用 OCS,这里没用涉及。

Point 在 WCS 中标记一个 3D 点:

import ezdxf
from ezdxf.gfxattribs import GfxAttribs
file_path = "E:\\7创业\\AI+Clothes\\shapes.dxf"
doc = ezdxf.readfile(file_path)
msp = doc.modelspace()

point = msp.add_point((10, 10))
p = msp.query('POINT')[0]
print(p.dxf.location, p.dxf.angle)
# (10.0, 10.0, 0.0) 0

Line 包含 start 和 end Point 在世界坐标系WCS:

import ezdxf
from ezdxf.gfxattribs import GfxAttribs
file_path = "E:\\7创业\\AI+Clothes\\shapes.dxf"
doc = ezdxf.readfile(file_path)
msp = doc.modelspace()

line = msp.add_line((0, 0), (10, 10))
l = msp.query('LINE')[0]
# 起点,终点,粗细,缩放拉伸
print(l.dxf.start, l.dxf.end, l.dxf.thickness, l.dxf.extrusion)
# (0.0, 0.0, 0.0) (10.0, 10.0, 0.0) 0 (0.0, 0.0, 1.0)

Circle包含在OCS中的 中心点center point 和 半径radius:

import ezdxf
from ezdxf.gfxattribs import GfxAttribs
file_path = "E:\\7创业\\AI+Clothes\\shapes.dxf"
# doc = ezdxf.readfile(file_path)
doc = ezdxf.new()
msp = doc.modelspace()

circle = msp.add_circle((10, 10), radius=3)

c = msp.query('CIRCLE')[0]
# 圆心,半径
print(c.dxf.center, c.dxf.radius)
# (10.0, 10.0, 0.0) 3.0

Arc圆弧 包括 中心点center point, radius半径, 起始角 start angl,结束角 end angle(以度为单位):

import ezdxf
from ezdxf.gfxattribs import GfxAttribs
file_path = "E:\\7创业\\AI+Clothes\\shapes.dxf"
# doc = ezdxf.readfile(file_path)
doc = ezdxf.new()
msp = doc.modelspace()

arc = msp.add_arc((10, 10), radius=3, start_angle=30, end_angle=120,)

a = msp.query('ARC')[0]
# 圆心,半径,起始角度,终止角度
print(a.dxf.center, a.dxf.radius, a.dxf.start_angle, a.dxf.end_angle)
# (10.0, 10.0, 0.0) 3.0 30.0 120.0

Ellipse椭圆 需要 DXF R2000 或更高版本,并且是 真正的 WCS 实体。椭圆包括 中心点,长轴major axis,长轴和短轴之间的比率ratio,起点start_param和终点end_param (以弧度为单位):

import ezdxf
import math
from ezdxf.gfxattribs import GfxAttribs
file_path = "E:\\7创业\\AI+Clothes\\shapes.dxf"
# doc = ezdxf.readfile(file_path)
doc = ezdxf.new()
msp = doc.modelspace()

ellipse = msp.add_ellipse((10, 10), major_axis=(5, 0), ratio=0.5, start_param=0, end_param=math.pi )
e = msp.query('ELLIPSE')[0]
print(e.dxf.center, e.dxf.major_axis, e.dxf.ratio, e.dxf.start_param, e.dxf.end_param)
# (10.0, 10.0, 0.0) (5.0, 0.0, 0.0) 0.5 0.0 3.141592653589793

TEXT 实体 表示一行文本。t.dxf.text表示文本内容字符串, t.dxf.insert表示 第一个LEFT, ALIGNED 和 FIT对齐的2D/3D Point in OCS, t.dxf.align_point表示主对齐点非LEFT对齐或者ALIGNED和FIT对齐的第二个对齐点, t.dxf.halign水平对齐标志作为 int 值默认0, t.dxf.valign垂直对齐标志作为 int 值默认0, t.dxf.height文本高度为浮点值,默认值为 1, t.dxf.width宽度比例因子作为浮点值,默认值为 1, t.dxf.rotation文本旋转(以度为单位)作为浮点值,默认值为 0, t.dxf.style表示Textstyle的名字默认Standard。

水平对齐标志:
在这里插入图片描述
垂直对齐标志:
在这里插入图片描述

doc = ezdxf.new()
msp = doc.modelspace()

# Use method set_placement() to define the TEXT alignment, because the
# relations between the DXF attributes 'halign', 'valign', 'insert' and
# 'align_point' are tricky.
msp.add_text("A Simple Text").set_placement((2, 3), align=TextEntityAlignment.MIDDLE_RIGHT)

# Using a predefined text style:
msp.add_text("Text Style Example: Liberation Serif", height=0.35, dxfattribs={"style": "LiberationSerif"}).set_placement((2, 6), align=TextEntityAlignment.LEFT)

t = msp.query('TEXT')[0]
print(t.dxf.text, t.dxf.insert, t.dxf.align_point, t.dxf.halign, t.dxf.valign, t.dxf.height, t.dxf.width, t.dxf.rotation, t.dxf.style)
# A Simple Text (2.0, 3.0, 0.0) (2.0, 3.0, 0.0) 2 2 2.5 1 0 Standard

INSERT实体:代表一个 块引用block reference,其中i.dxf.insert代表BLOCK基点的插入位置(OCS中的2D/3D点),dxf.xscale代表x 方向的比例因子(浮点数),dxf.yscale代表y 方向的比例因子(浮点数),dxf.zscale代表z 方向的比例因子(浮点数),dxf.rotation代表以度为单位的旋转角度(浮动)

DXF Objects

DXF Objects非图形实体,没有视觉表示,它们存储管理数据、图纸空间布局定义、多种实体类型的样式定义、自定义数据和对象。DXF 文件中的 OBJECTS 部分充当这些非图形对象的容器。

DXF 对象的一些常见 DXF 类型包括:

  • DICTIONARY:字典对象由一系列<名称-值 >对组成,其中名称是标识字典中特定对象的字符串,值是对该对象的引用。对象本身可以是任何类型的 DXF 实体或 DXF 文件中定义的自定义对象。

  • XRECORD 实体用于将自定义应用程序数据存储在 DXF 文件中。

  • LAYOUT 实体是一个 DXF 实体,表示 DXF 文件中的单个图纸空间布局。图纸空间是 CAD 绘图中的区域,表示将在其上绘制或打印设计的纸张或其他物理介质。

  • MATERIAL、MLINESTYLE、MLEADERSTYLE 定义存储在某些 DICTIONARY 对象中。

  • GROUP 实体包含引用绘图中其他 DXF 实体的句柄列表。组中的实体可以是任何类型,包括来自模型空间或图纸空间布局的实体。

TagStorage

ezdxf包支持许多但不是所有实体类型,所有这些不支持的类型都存储为实例,以便在通过ezdxf TagStorage导出编辑的 DXF 内容时保留其数据。

Layouts

作为存储DXF entities的容器,如LINE, CIRCLE, TEXT 等等。每个 DXF entity只能驻留在一个Layouts中。

共有三种不同的Layouts类型:(DXF文件由一个Modelspace和至少一个Paperspace组成,且所有Layouts对象都是可迭代对象

  • Modelspace:模型空间是 DXF 文件中用来表示实际绘图内容的部分。在模型空间中,用户可以绘制和编辑实际的图形元素,比如线条、圆形、多边形等。模型空间通常用于表示实际的设计内容。

  • Paperspace:纸张空间用来表示图纸的布局和显示方式,通常用于设置图纸的打印布局、视图窗口等。在纸张空间中,用户可以安排模型空间的内容,设置视图窗口的大小和位置,以便在打印或显示时呈现出所需的效果。

  • BlockLayout:块是 DXF 文件中的可重用图形元素,类似于 CAD 软件中的符号库。块可以包含线条、弧线、文本等元素,并被定义为一个单独的对象。这使得用户可以多次插入相同的块,而不必重复绘制相同的图形元素。

Modelspace

Modelspace始终存在且无法删除。

import ezdxf
doc = ezdxf.readfile("shapes.dxf")
msp = doc.modelspace()

Modelspace可以具有一个或多个称为Modelspace Viewport的矩形区域。Modelspace Viewport可用于从Modelspace的不同观察方向显示Modelspace的不同视图。重要的是要知道Modelspace Viewport ( VPort) 与Paperspace Viewport(Viewport) 不同。
在这里插入图片描述

Paperspace

Paperspace 是为了 2D 输出而组装和组织模型空间绘图内容的地方,例如打印在一张纸上,或作为数字文档(例如 PDF 文件)。

import ezdxf
doc = ezdxf.readfile("shapes.dxf")
psp = doc.paperspace("Layout1")

每个 DXF 文档可以有一个或多个Paperspace ,但 DXF 版本 R12 仅支持一种Paperspace ,因此不建议依赖 DXF 版本 R12 中的Paperspace 。

BlockLayout

BlockLayout只是另一种Entity集合空间,它可以通过 INSERT 实体多次重用,插入到其他Layouts和BlockLayout中,也称为块引用,这是 DXF 格式的一个非常强大且重要的概念。块参考 (INSERT) 可以旋转、缩放、通过OCS放置在 3D 空间中并以类似网格的方式排列,每个INSERT实体可以块属性(Attrib)附加单独的属性 。

通过block name 获取BlockLayout:

import ezdxf
doc = ezdxf.readfile("shapes.dxf")
blk = doc.blocks.get("NAME")

查看msp中所有INSERT的实体及其属性:

import ezdxf
file_path = "E:\\7创业\\AI+Clothes\\data\\裤子版dxf\\K009.dxf"
doc = ezdxf.readfile(file_path)

blockrefs = msp.query('INSERT')
print(len(blockrefs))
for be in blockrefs:
    print(be.dxftype(), be.dxf.name)
    print(be.get_attrib('diameter'), be.get_attrib('color'), be.get_attrib("rgb"))

解析DXF实体并可视化

import ezdxf, matplotlib
import matplotlib.pyplot as plt
matplotlib.use('TkAgg')  # 避免Matplotlib版本与其他相关库的兼容性问题


def save_dxf(file_path, save_path):
    doc = ezdxf.readfile(file_path)
    msp = doc.modelspace()
    fig, ax = plt.subplots()
    for entity in msp:
        if entity.dxftype() == 'LINE':
            start_point = entity.dxf.start
            end_point = entity.dxf.end
            ax.plot([start_point[0], end_point[0]], [start_point[1], end_point[1]], 'b-')
        elif entity.dxftype() == 'POLYLINE':
            all_points = []
            for p in entity.points(): 
                all_points.append((p.x, p.y))
            x, y = zip(*all_points)
            ax.plot(x, y, 'r-')
        elif entity.dxftype() == 'LWPOLYLINE':
            points = list(entity.get_points('xy'))
            x, y = zip(*points)
            ax.plot(x, y, 'r-')
        elif entity.dxftype() == 'CIRCLE':
            center = entity.dxf.center
            radius = entity.dxf.radius
            circle = plt.Circle(center, radius, color='g', fill=False)
            ax.add_patch(circle)
        elif entity.dxftype() == 'TEXT':
            insertion_point = entity.dxf.insert
            text = entity.dxf.text
            ax.text(insertion_point[0], insertion_point[1], text, fontsize=8)
        elif entity.dxftype() == 'SOLID':
            vtx0 = entity.dxf.vtx0
            vtx1 = entity.dxf.vtx1
            vtx2 = entity.dxf.vtx2
            vtx3 = entity.dxf.vtx3
            vertices = [(vtx0.x, vtx0.y), (vtx1.x, vtx1.y), (vtx2.x, vtx2.y), (vtx3.x, vtx3.y)]
            vertices_list = []
            for vertice in vertices:
                vertices_list.append([round(vertice[0], 1), round(vertice[1], 1)])
            polygon = plt.Polygon(xy=vertices_list, color='gray', alpha=0.8)
            ax.add_patch(polygon)
        if entity.dxftype() == 'INSERT':
            for e in entity.virtual_entities():
                if e.dxftype() == 'LWPOLYLINE':
                    points = list(e.get_points('xy'))
                    x, y = zip(*points)
                    ax.plot(x, y, 'r-')
                elif e.dxftype() == 'POLYLINE':
                    all_points = []
                    for p in e.points(): 
                        all_points.append((p.x, p.y))
                    x, y = zip(*all_points)
                    ax.plot(x, y, 'r-')
                elif e.dxftype() == 'LINE':
                    start_point = e.dxf.start
                    end_point = e.dxf.end
                    ax.plot([start_point[0], end_point[0]], [start_point[1], end_point[1]], 'b-')
                elif e.dxftype() == 'CIRCLE':
                    center = e.dxf.center
                    radius = e.dxf.radius
                    circle = plt.Circle(center, radius, color='g', fill=False)
                    ax.add_patch(circle)

    ax.set_aspect('equal', adjustable='box')
    plt.xlabel('X')
    plt.ylabel('Y')
    plt.title('DXF Display')
    plt.grid(True)
    plt.savefig(save_path)
    plt.close(fig)


if __name__ == "__main__":
    file_path = "E:\\7创业\\AI+Clothes\\data\\裤子版dxf\\K009.dxf"
    save_path = 'save.png'
    save_dxf(file_path, save_path)
import ezdxf
from typing import cast
from ezdxf.entities import Polyface
from ezdxf.math import Vec3
from ezdxf.render import TraceBuilder

file_path = "E:\\7创业\\AI+Clothes\\data\\裤子版dxf\\K009.dxf"
doc = ezdxf.readfile(file_path)

def print_entity(e):
    if e.dxftype() == 'POLYLINE':
        all_points = []
        for p in e.points(): all_points.append((p.x, p.y))
        print(e.dxftype(), all_points)
    if e.dxftype() == 'POINT':
        print(e.dxftype(), e.dxf.layer, e.dxf.location, e.dxf.angle)
    if e.dxftype() == 'LINE':
        print(e.dxftype(), e.dxf.layer, e.dxf.start, e.dxf.end, e.dxf.thickness, e.dxf.extrusion)
    if e.dxftype() == 'CIRCLE':
        print(e.dxftype(), e.dxf.layer, e.dxf.center, e.dxf.radius)
    if e.dxftype() == 'ARC':
        print(e.dxftype(), e.dxf.layer, e.dxf.center, e.dxf.radius, e.dxf.start_angle, e.dxf.end_angle)
    if e.dxftype() == 'TEXT':
        print(e.dxftype(), e.dxf.text, e.dxf.insert, e.dxf.align_point, e.dxf.halign, e.dxf.valign, e.dxf.height, e.dxf.width, e.dxf.rotation, e.dxf.style)
        

# 1. 解析layers
print(f"There are {len(doc.layers)} layers:")
for layer in doc.layers:
    print(layer.dxf.name, layer.dxf.color, layer.dxf.linetype, layer.dxf.lineweight)
print('\n')
# 2.解析modelsapce的entity
msp = doc.modelspace()
print(f"There are {len(msp)} entities in msp:")
for i, e in enumerate(msp):
    if e.dxftype() == 'INSERT':
        print(f'Entity {i+1} type is',e.dxftype(), ', name is', e.dxf.name, ':')
        print('#'*50)
        for entity in e.virtual_entities():  # 每个insert都包含很多组件
            pass
            print_entity(entity)
        print('#'*50)
    elif e.dxftype() != 'TEXT':
        print(f'Entity {i+1} type is',e.dxftype(), ', name is', e.dxf.name, ':')
        print_entity(e)
    else:
        print(f'Entity {i+1} type is TEXT :')
        print_entity(e)
  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 解析DXF文件是通过读取文件中的数据并将其转化为几何图形,在LabVIEW中实现的。 DXF文件是一种常用的CAD绘图文件格式,包含了二维和三维图形的坐标和属性信息。在LabVIEW中,可以使用各种方法来解析这些文件。 首先,需要使用LabVIEW中的文件读取功能打开DXF文件,并逐行读取文件中的数据。可以使用“读取到文件末尾”函数来确保读取全部数据。 接下来,需要使用字符串操作函数将每行数据分割为单个的数据项。可以使用“拆分字符串”函数按照指定的分隔符拆分字符串,并将拆分得到的数据项存储在相应的数组中。 根据DXF文件的格式,可以确定需要解析的数据项。例如,对于线段绘图,在DXF文件中会用到坐标点数据和线型数据。可以使用LabVIEW中的数组索引和替换功能来提取这些数据。 对于不同的图形类型,可以使用不同的方法解析和绘制。例如,对于矩形,可以通过读取坐标点数据,确定矩形的四个顶点,并使用绘图功能在图形界面上绘制矩形。 最后,根据需要,可以将解析得到的数据存储在LabVIEW的数据结构中,以便后续使用和处理。可以使用数组、簇或其他数据结构来存储解析得到的图形数据,并进行进一步的分析和展示。 在解析DXF文件的过程中,需要仔细分析文件的结构和格式,确定所需的数据项,并使用合适的LabVIEW功能进行相应的解析和处理。通过LabVIEW的强大功能,可以方便地实现对DXF文件解析,并将其展示在用户界面上。 ### 回答2: 解析DXF文件是指将DXF文件的数据提取出来以供进一步处理或显示。DXF(Drawing Exchange Format)是一种针对计算机辅助设计(CAD)软件的文件格式,其中包含了几何形状、属性、图层和其他相关信息。 要解析DXF文件,可以使用LabVIEW软件进行操作。LabVIEW是一款流程化编程语言,它具有强大的数据处理和图形化编程环境,非常适合用于解析各种文件格式。 首先,需要在LabVIEW中加载DXF文件。可以使用LabVIEW中的文件I/O函数来读取DXF文件的内容。通过逐行读取文件,可以获取文件中的点、线、圆、多边形等几何图形的坐标信息,并将其保存在适当的数据结构中,例如数组或集合等。 然后,解析DXF文件中的属性信息。DXF文件中可能包含与几何图形相关的属性(如颜色、线型、线宽等),以及实体上的文本注释。可以使用正则表达式或字符串处理函数来解析这些属性信息,并将其与相应的几何图形进行关联。 最后,可以根据需要对解析得到的几何数据和属性进行进一步处理。例如,可以根据几何坐标信息绘制图形,或根据属性信息进行颜色填充、线型设置等。 总之,借助LabVIEW的强大功能,我们可以方便地解析DXF文件,提取其中的几何图形和属性信息,并进行后续的数据处理或可视化操作。这样,我们可以充分利用DXF文件中所包含的设计数据,为各类CAD应用程序增值。 ### 回答3: 解析dxf文件在LabVIEW中可以通过使用相关的工具和函数来完成。首先,需要使用LabVIEW中的文件操作函数来读取dxf文件的数据。可以使用"Open/Create/Replace File"函数来打开dxf文件,并将文件句柄作为输入。接下来,可以使用"Read From Binary File"函数按照特定的格式读取文件内容。由于dxf文件是一种二进制文件,因此需要按照特定的规则解析数据。 在解析dxf文件时,需要了解dxf文件的结构和格式。dxf文件包含了各种实体对象,如点、线、圆、多边形等。每个实体对象都有一些属性和参数,如坐标、颜色、线型等。可以使用LabVIEW中的字符串处理函数来解析每个实体对象的属性和参数。例如,可以使用"Scan From String"函数来按照指定的格式从字符串中提取需要的数据。 解析dxf文件后,可以将得到的数据进行处理和显示。可以使用LabVIEW中的图形函数库来绘制dxf文件中的实体对象。例如,可以使用"Draw Line"函数绘制线段,使用"Draw Circle"函数绘制圆等。可以根据实体对象的属性和参数来设置图形的颜色、线型等属性。 总结起来,解析dxf文件在LabVIEW中可以通过使用文件操作函数、字符串处理函数和图形函数库来完成。首先,通过文件操作函数读取dxf文件的数据,然后使用字符串处理函数解析实体对象的属性和参数,最后使用图形函数库绘制实体对象。通过这些步骤,可以在LabVIEW中实现dxf文件解析和显示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yuezero_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值