如何在 Python 中以编程方式更改 AutoCAD 对象的属性
How to change the properties of an AutoCAD object programmatically in Python
我想使用 Python 自动处理一堆 AutoCAD 图纸。为此,我需要以编程方式更改绘图实体的属性。苦苦挣扎了一段时间,无果。
这是我用来读取 .dxf
和打开 .dwg
文件的代码:
import win32com.client
import dxfgrabber
import os
folder = r'C:\path\to\my\folder'
filename = 'my_file'
dwg_path = os.path.join(folder, filename + '.dwg')
dxf_path = os.path.join(folder, filename + '.dxf')
acad = win32com.client.dynamic.Dispatch("AutoCAD.Application")
doc = acad.Documents.Open(dwg_path)
acad.Visible = True
dxf = dxfgrabber.readfile(dxf_path)
然后我遍历放置在名为 FirstLayer
和 select 层中的对象,其中之一是:
item = [obj for obj in dxf.entities if obj.layer == 'FirstLayer'][0]
这个特定的实体是一个文本对象:
In [1122]: type(item)
Out[1122]: dxfgrabber.dxfentities.Text
In [1123]: item.insert
Out[1123]: (4022.763956904745, 3518.371877135191, 0.0)
In [1124]: item.layer
Out[1124]: 'FirstLayer'
In [1125]: item.handle
Out[1125]: '298'
我的目标是更改 color
、layer
等属性。这是我尝试将文本对象移动到另一个名为 SecondLayer
的层的尝试之一:
doc.SendCommand(f'CHPROP {item.insert[0]},{item.insert[1]} LA\n SecondLayer\n ')
我猜问题是无法通过插入点的坐标 select 编辑对象。我还尝试(未成功)使用以下脚本通过其句柄 select 对象:
_CHPROP (handent 298) _LA SecondLayer
关于如何解决这个问题有什么想法吗?
编辑
在@Lee Mac 发布他的优秀答案之前,我想出了以下解决方案:
doc.SendCommand(f'CHPROP (handent "{item.handle}") \n_LA SecondLayer\n ')
DXF 文件中的句柄存储为 HEX 字符串,也许 AutoCAD 需要一个整数值,但我不是 AutoCAD 专家 (@LeeMac)。通过 int('298', 16)
.
将 Python 中的 HEX 字符串转换为 int
发出 CHPROP
命令后,随后的对象选择提示将要求您提供一个或多个实体名称(可以通过使用 AutoLISP handent
函数转换句柄获得) ,或提供一个选择集(可以使用 AutoLISP ssget
函数获得)。
您对 handent
的使用非常接近,但是 AutoCAD 中的实体句柄由十六进制字符串表示,因此您需要为 handent
函数提供一个由双精度包围的字符串参数-引号,例如:
(handent "298")
如果提供的句柄有效,handent
将 return 实体名称指针:
_$ (handent "3B8")
<Entity name: 7ffff706880>
但是,由于 CHPROP
接受选择集参数,因此您无需遍历每个实体,而只需向 CHPROP
提供过滤器选择集,例如:
doc.SendCommand(f'CHPROP (ssget "_x" (list (cons 8 "FirstLayer"))) LA\n SecondLayer\n ')
我想使用 Python 自动处理一堆 AutoCAD 图纸。为此,我需要以编程方式更改绘图实体的属性。苦苦挣扎了一段时间,无果。
这是我用来读取 .dxf
和打开 .dwg
文件的代码:
import win32com.client
import dxfgrabber
import os
folder = r'C:\path\to\my\folder'
filename = 'my_file'
dwg_path = os.path.join(folder, filename + '.dwg')
dxf_path = os.path.join(folder, filename + '.dxf')
acad = win32com.client.dynamic.Dispatch("AutoCAD.Application")
doc = acad.Documents.Open(dwg_path)
acad.Visible = True
dxf = dxfgrabber.readfile(dxf_path)
然后我遍历放置在名为 FirstLayer
和 select 层中的对象,其中之一是:
item = [obj for obj in dxf.entities if obj.layer == 'FirstLayer'][0]
这个特定的实体是一个文本对象:
In [1122]: type(item)
Out[1122]: dxfgrabber.dxfentities.Text
In [1123]: item.insert
Out[1123]: (4022.763956904745, 3518.371877135191, 0.0)
In [1124]: item.layer
Out[1124]: 'FirstLayer'
In [1125]: item.handle
Out[1125]: '298'
我的目标是更改 color
、layer
等属性。这是我尝试将文本对象移动到另一个名为 SecondLayer
的层的尝试之一:
doc.SendCommand(f'CHPROP {item.insert[0]},{item.insert[1]} LA\n SecondLayer\n ')
我猜问题是无法通过插入点的坐标 select 编辑对象。我还尝试(未成功)使用以下脚本通过其句柄 select 对象:
_CHPROP (handent 298) _LA SecondLayer
关于如何解决这个问题有什么想法吗?
编辑
在@Lee Mac 发布他的优秀答案之前,我想出了以下解决方案:
doc.SendCommand(f'CHPROP (handent "{item.handle}") \n_LA SecondLayer\n ')
DXF 文件中的句柄存储为 HEX 字符串,也许 AutoCAD 需要一个整数值,但我不是 AutoCAD 专家 (@LeeMac)。通过 int('298', 16)
.
发出 CHPROP
命令后,随后的对象选择提示将要求您提供一个或多个实体名称(可以通过使用 AutoLISP handent
函数转换句柄获得) ,或提供一个选择集(可以使用 AutoLISP ssget
函数获得)。
您对 handent
的使用非常接近,但是 AutoCAD 中的实体句柄由十六进制字符串表示,因此您需要为 handent
函数提供一个由双精度包围的字符串参数-引号,例如:
(handent "298")
如果提供的句柄有效,handent
将 return 实体名称指针:
_$ (handent "3B8")
<Entity name: 7ffff706880>
但是,由于 CHPROP
接受选择集参数,因此您无需遍历每个实体,而只需向 CHPROP
提供过滤器选择集,例如:
doc.SendCommand(f'CHPROP (ssget "_x" (list (cons 8 "FirstLayer"))) LA\n SecondLayer\n ')