Python AutoCAD 选择集


阿阳的 AutoCAD 二次开发简明教程,本系列博客仅用于个人学习,除此之外,无其他任何用途。


Blog Links



因个人能力有限,该系列博客难免有所疏漏/错误,不妥之处还请各位批评指正。



转载请注明出处!



一、前沿


  用户要对已有的一些对象进行删除、复制、移动等编辑操作,都需要选中被操作的对象。选择对象或对操作对象进行筛选的过程,称为构造选择集。选择对象可以只选择一个对象,也可以同时选择多个对象。AutoCAD 中常用构造选择集有直接拾取、窗口、窗交、栏选等多种方式。[1]

  本文简要介绍在 CAD 二次开发过程中几种常用选择对象即构造选择集的方法。


二、连接CAD的方式


  为了保证代码的顺利运行,本文采用 win32com 库连接 CAD,具体代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''
=============================
Author:DalNur
Email: [email protected]
=============================
'''

import win32com.client
import pythoncom

acad = win32com.client.Dispatch("AutoCAD.Application.19")  
       # AutoCAD.Application.19为 ProgID
doc = acad.ActiveDocument
doc.Utility.Prompt("Hello AutoCAD\n")
mp = doc.ModelSpace
print(doc.Name)

2.1. ProgID


  根据 CAD 版本的不同, ProgID 可能发生变化,部分版本 CAD 的 ProgID 如下:


AutoCAD 版本 ProgID
2010 AutoCAD.Application.18
2014 AutoCAD.Application.19

  常见版本 CAD 的 ProgID 详见博文: autocad application 版本

  其余版本 CAD 的 ProgID 在官方二次开发帮助文档中查看,具体查找位置如下图所示。


在这里插入图片描述


  官方二次开发帮助文档的获取方式详见博文:Python pyautocad库 使用简介 前沿部分。


三、数据转换


  说明:本人非计算机专业出身,文中某些表述可能不严谨甚至错误,还请各位见谅。

  Python 中的数据类型较少,且对数据本身的要求也较为宽松,如一个列表中的各个元素可以分别属于不同的数据类型,这虽然有利于降低程序的编写难度,但也对 CAD 的二次开发产生了一些不必要的麻烦。

  在 CAD 二次开发过程中,很多函数/方法的参数要求输入的数据类型为 Variant (array of objects) ,但在 Python 中似乎又没有哪一种数据类型与之直接相对应,若采用 list 代替 Variant,那么程序无法顺利执行,报错为 “ 对象数组无效 ”。因此,需要某种转换方式,将Python中定义的变量转换为能够被CAD识别的数据类型 Variant

  VARIANT 结构体主要是使用在 COM(组件对象模型)中用于传递参数使用,它的存在主要是为了保持一个在 COM 参数传递方法的统一性,它几乎包含了所有普通常用类型的数据类型的传递,如整型,浮点型,布尔型等,以及相应类型的指针类型,如整型指针。[3]


  部分类型与变量对应关系如下表:


Member name Description
VT_EMPTY Indicates that a value was not specified.
VT_R8 Indicates a double value.
VT_DISPATCH Indicates an IDispatch pointer.

  另外,NumPy arrays can be passed as VARIANT arrays arguments. The array is converted to a SAFEARRAY according to its type. [4] ( 此为 comptypes 库帮助文档原文,本人对计算机了解有限,为了不曲解原文,此处不做翻译),部分对应关系如下:


NumPy type VARIANT type
int32, int, intc, int_ VT_I4
uint32, uint, uintc VT_UI4
float64, float_ VT_R8

  comtypes 是一个轻量级的 python com 包,其中文网站详见:https://www.cnpython.com/pypi/comtypes;官方文档详见:comtypes 1.1.3 documentation

  NumPy 是用 Python 进行科学计算的基础软件包,其官方的中文文档详见网站: Numpy 中文网



  本文用到的数据转化函数代码如下:

def vtpnt(x, y, z=0):
    """座标点转化为浮点数"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y, z))

def vtobj(obj):
    """转化为对象数组"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, obj)

def vtFloat(list):
    """列表转化为浮点数"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, list)
    
def vtInt(list):
    """列表转化为整数"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, list)

def vtVariant(list):
    """列表转化为变体"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, list)

  其他数据类型的转化方式可查询 PyWin32 的官方帮助文档,它的获取方式如下:首先确保你已经成功安装了 pywin32 模块,然后在搜索神器 Everything 的搜索栏中输入 PyWin32.chm,便可得到其所在的路径,打开文件 PyWin32.chm,在搜索栏中输入 pythoncom.VT_ARRAY , 便可查看各种数据类型的转化。


在这里插入图片描述

PyWin32帮助文档的获取

在这里插入图片描述

VARIANT的查询

四、创建测试图元

[pnt1, pnt2, pnt3, pnt4, pnt5, pnt6] = [vtpnt(-40, -40), vtpnt(500, 500), vtpnt(300, 200),
                                        vtpnt(600, 200), vtpnt(700, 200), vtpnt(100, 0)]

LineObj = mp.AddLine(pnt1, pnt2)
CircleObj = mp.AddCircle(pnt3, 100)
ArcObj = mp.AddArc(pnt4, 50, 0, 1.57)
EllObj = mp.AddEllipse(pnt5, pnt6, 0.5)

五、创建选择集


  创建名称为 SS1 的选择集。

try:
    doc.SelectionSets.Item("SS1").Delete()
except:
    print("Delete selection failed")
    
slt = doc.SelectionSets.Add("SS1")

六、常规选择


6.1. 屏幕拾取

slt.SelectOnScreen()
print("请在屏幕拾取图元,以Enter键结束")
obj = slt[0]
print(obj.ObjectID)
print(slt)

6.2. 选择过定点图元

pnt = APoint(0, 0)
slt.SelectAtPoint(pnt)
obj = slt[0]
print(obj.StartPoint) # 当不止一个图元过点pnt时,slt中的元素也不止一个。

6.3. 多边形框选

  多边形由给定各点依次连直线形成,最终实现该多边形区域内的全选。

pnts = [-50, -50, 0, -50, 550, 0, 550, 550, 0, 550, -50, 0, -50, -50, 0]
pnts=vtFloat(pnts)

slt.SelectByPolygon(6, pnts) # acSelectionSetWindowPolygon = 6

obj = slt[0]
print(obj.ObjectID)
obj = slt[1]
print(obj.ObjectID)

6.4. 全选

slt.Select(5) # acSelectionSetAll = 5
obj = slt[0]
print(obj.layer)

七、快速选择


7.1. 语法


  • object.Select(Mode, Point1, Point2, FilterType, FilterData)

   - object:SelectionSet. The object this method applies to 。

   - Mode:选择模式,AcSelect enum,具体含义下表。

   - Point1:3维座标点。

   - Point2:3维座标点。

   - FilterType:A DXF group code specifying the type of filter to use 。

   - FilterData:The value to filter on 。


Mode enum Description
acSelectionSetWindow 0 Selects all objects completely inside a rectangular area whose corners are defined by Point1 and Point2.
acSelectionSetCrossing 1 Selects objects within and crossing a rectangular area whose corners are defined by Point1 and Point2.
acSelectionSetPrevious 3 Selects the most recent selection set. This mode is ignored if you switch between paper space and model space and attempt to use the selection set.
acSelectionSetLast 4 Selects the most recently created visible objects.
acSelectionSetAll 5 Selects all objects.

7.2. DXF组码


  详见:CADVBA中的选择集过滤及DXF组码表

     CAD中的选择集过滤----有条件选择AutoCAD实体 (二)


  此外,在二次开发帮助文档 ActiveX Developer’s Guide 中,搜索 DXF ,便可得到官方的权威解释,操作如下:


在这里插入图片描述

7.3. 实例


  选择 0 图层上所有半径大于 5 的圆并删除,代码如下:

filterType = [0, -4, 40, 8]  # 定义过滤类型
filterData = ["Circle", ">=", 5, "0"]  # 设置过滤参数

filterType = vtInt(filterType)  # 数据类型转化
filterData = vtVariant(filterData)  # 数据类型转化

slt.Select(5, 0, 0, filterType, filterData)  # 实现过滤

obj = slt[0]
print(obj.Diameter)

slt.Erase()  # 删除符合条件的所有圆


八、GetEntity


在这里插入图片描述


  以下代码实现将用户选择的图元的颜色更改为红色。


print("请在屏幕中鼠标左键点选图元,未选中则报错!")  # try...except处理报错
rtnObj = doc.Utility.GetEntity()  # 返回对象

print(rtnObj)

print("所选图元的ID:", rtnObj[0].ObjectID)
print("鼠标单击处的座标:", rtnObj[1])

sltObject = doc.ObjectIdToObject(rtnObj[0].ObjectID) # 图元ID转化为对应的图元

clr = doc.Application.GetInterfaceObject("AutoCAD.AcCmColor.19")
clr.SetRGB(255, 0, 0)  # 创建红色
sltObject.TrueColor = clr  # 指定颜色

doc.Application.Update()


九、致谢


  选择集功能的顺利实现离不开 ke1078 同学的大力支持,特此感谢!


十、尾声


  以上,便是关于 AutoCAD 选择集 的一些基本代码,因篇幅有限,某些非关键功能未做详细介绍,如有疑问,欢迎邮件来询。

  鉴于,相关示例代码相对较少,特写本文,一方面是为自己的阶段性学习做一个总结,另一方面更是为有需要的人提供多一点参考。

  如果您已实现一些本文未提及的功能,还请在评论区呈现,以便为后续学习者提供更多的帮助。

  胸藏文墨怀若谷,腹有诗书气自华,希望各位都能在知识的 pāo 子里快乐徜徉。

  因本人野生学习 Python,水平确实有限,文中难免有所疏漏,还请各位大神不吝批评指正。

  最后,祝各位攻城狮们,珍爱生命,保护发际线!

  本文部分内容,源于网络!

  欢迎大家点赞、评论及转载,转载请注明出处!

  为我打call,不如为我打款!

  打赏可备注邮箱,本人将赠送本系列博客的全部 Python 源代码。



在这里插入图片描述




十、参考文献


[1]. AutoCAD中构造选择集的方法. 机械制图课堂.

[2]. 基于Python AutoCAD ActiveX 二次开发,pyautocad应用技术. 为中华崛起而.

[3]. VARIANT的使用方法. xinzhiyounizhiyouni.

[4]. comtypes 1.1.3 documentation




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章