AutlLisp版本:Visual LISP 2024 (zh)
三种方法分别为:
代码块
ts
自动换行
复制代码
1
(command "_.-group" "C" "*" "组说明" #ss "")
复制成功
其中:“-group”表示命令行方式调用AutoCAD的group命令,前面的 “_.” 表示调用的是原始定义、未被重定义的命令;“C” 表示创建;“*” 表示组名<字符串>,当为“*”时创建的为未命名组;“组说明”即组说明;#ss 为图元所组成的选择集;34;" 为空格,结束图元选择,完成group命令。
注意:通过 (setq #ss (ssget)) 创建的选择集可能包含一些图元外的选择方式信息,该方法支持,无需对选择集进行数据处理。
在AutoLISP中,编组也具有<图元名>,因此entmake可以用来生成编组,不过我们先了解一下如何查看编组的图元属性。先上结果:
代码块
ts
自动换行
复制代码
1
(entget(cdr(assoc 330 (entget (car (entsel))))))
复制成功
解释如下:
通过:
代码块
ts
自动换行
复制代码
1
(entget (car (entsel)))
复制成功
点选某被编组图元,可以看到其图元属性如下:
代码块
ts
自动换行
复制代码
1
((-1 . <图元名: 1fce6f21e30>) (0 . "LINE") (5 . "1493") (102 . "{ACAD_REACTORS") (330 . <图元名: 1fce6f21e60>) (102 . "}") (330 . <图元名: 1fcd82e79f0>) (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "Defpoints") (100 . "AcDbLine") (10 13569.2 6124.9 0.0) (11 7032.43 6124.9 0.0) (210 0.0 0.0 1.0))
复制成功
其中:
代码块
ts
自动换行
复制代码
1
(102 . "{ACAD_REACTORS") (330 . <图元名: 1fce6f21e60>) (102 . "}")
复制成功
这3项组码为编组给图元添加的反应器,因此,其中330组码项为编组的图元名。对其进行(entget)即可获得编组的属性列表:
代码块
ts
自动换行
复制代码
1
((-1 . <图元名: 1fce6f21e60>) (0 . "GROUP") (5 . "1496") (102 . "{ACAD_REACTORS") (330 . <图元名: 1fcd82e78d0>) (102 . "}") (330 . <图元名: 1fcd82e78d0>) (100 . "AcDbGroup") (300 . "") (70 . 1) (71 . 1) (340 . <图元名: 1fce6f21e50>) (340 . <图元名: 1fce6f21e40>) (340 . <图元名: 1fce6f21e30>))
复制成功
其中包含:
【70】命名标记:1-未命名,0-已命名
【71】可选择性标记:1-可选择,0-未选择
【340】<图元名>指针,指向组内图元,每个图元一个。
另外,此编组是我在AutoCAD中选择图元后鼠标右键->组创建的,属性列表中包含有字典给编组添加的反应器信息:
代码块
ts
自动换行
复制代码
1
(102 . "{ACAD_REACTORS") (330 . <图元名: 1fcd82e78d0>) (102 . "}") (330 . <图元名: 1fcd82e78d0>)
复制成功
继续向上追溯字典的属性列表,如下:
代码块
ts
自动换行
复制代码
1
((-1 . <图元名: 1fcd82e78d0>) (0 . "DICTIONARY") (5 . "D") (102 . "{ACAD_REACTORS") (330 . <图元名: 1fcd82e78c0>) (102 . "}") (330 . <图元名: 1fcd82e78c0>) (100 . "AcDbDictionary") (280 . 0) (281 . 1) (3 . "*A1") (350 . <图元名: 1fce6f21d90>) (3 . "*A2") (350 . <图元名: 1fce6f21dc0>) (3 . "*A3") (350 . <图元名: 1fce6f21e60>) (3 . "TEST") (350 . <图元名: 1fce6f21d80>))
复制成功
这是"ACAD_GROUP34;类的专属字典,是默认存在不需要创建的,可以继续向上追溯330项至绘图文件的命名对象总字典,对应其中的(3 . "ACAD_GROUP34;) (350 . <图元名: 1fcd82e78d0>)项(总字典是绘图中所有非图形对象的根)。字典的句柄(组码5)为"D34;,这也就是为什么在DXF文件中,GROUP节中组码330项为"D34;。可以看到,该字典中保存了编组的名字,我们所查看的编组<图元名: 1fce6f21e60>的名字为“*A3”。对于字典的专门探讨,请见此文章。
作为一个AutoCAD界面正常创建的未命名编组,会在编组属性列表中组码(70 . 1)且在字典属性列表组码 (3 . “*A#”)(350 . <图元名>)。但这只是AutoCAD程序的规范,不是绝对的,下面采用AutoLISP中的entmake方式生成的编组,此处就有所不同。
该方法基于前面对编组属性列表的探讨,构造相同的属性列表。这里示例一个函数,可将一个选择集中所有图元组合为一个编组:
代码块
ts
自动换行
复制代码
12345678910111213141516
(defun fgengroup(#ss / #listG #iC #eNAME)
(setq #listG (list '(0 . "GROUP") ;对象名
'(100 . "AcDbGroup") ;子类标记
'(300 . "") ;组说明
'(70 . 1) ;未命名标志:1-未命名
'(71 . 1) ;可选择性标志:1-可选择
) ;l
) ;s
(setq #iC 0)
(repeat (sslength #ss)
(setq #eNAME (ssname #ss #iC))
(setq #listG (append #listG (list (cons 340 #eNAME)))) ;组中图元的硬指针句柄(每个对象一个条目)
(setq #iC (1+ #iC))
) ;repeat
(entmake #listG) ;或entmakex
) ;d
复制成功
属性列表中包含组码0、100、300、70、71项,然后每个图元追加一个(340 . <图元名>)项。通过entmake属性列表,即可创建编组。
通过(entget)获得该方式创建编组的属性:
代码块
ts
自动换行
复制代码
1
((-1 . <图元名: 1fce7650f50>) (0 . "GROUP") (330 . <图元名: 0>) (5 . "1955") (100 . "AcDbGroup") (300 . "") (70 . 1) (71 . 1) (340 . <图元名: 1fce7650f40>) (340 . <图元名: 1fce7650f30>))
复制成功
其中并不含有上一小节中所示的、"ACAD_GROUP34;字典所赋予的组码102、330项,同时"ACAD_GROUP34;字典中也未添加该编组的名称项,且在AutoCAD的"CLASSICGROUP34;界面也找不到该编组,但是该编组在AutoCAD中事实上已经成功建立,是可以选定的、可以操作的。这说明"ACAD_GROUP34;字典所赋予的反应器组码102、330项并不是必要的。
然而若想在"ACAD_GROUP34;字典中增加该编组的条目,十编组的建立更规范也是可以的,涉及到字典操作(可查看此文章):
代码块
JavaScript
自动换行
复制代码
12
(setq #dictACADGROUP (cdr(assoc -1 (dictsearch (namedobjdict) "ACAD_GROUP"))))
(dictadd #dictACADGROUP "<GroupName>" GroupEntity<ename>)
复制成功
该操作会同时在编组的属性列表中添加向"ACAD_GROUP34;字典的反应器组码102和330。
注:使用repeat+计数器而非foreach是因为,在AutoLISP中,根据选择集建立方式的不同,其中可能不仅含有图元信息,还含有其他选择方式等信息,若要使用foreach,要么在之前使用(ssnamex)获得图元名列表,并对其进行处理,要么在foreach中嵌套if判断进行处理。而我们仅需要获得<图元名>,(ssname)可以很简洁地实现该目标,既不需要复杂的预处理,也不需要不必要的判断环节,即对选择集的兼容性更强。若能保证选择集中仅有图元信息,则如下代码可以实现同样效果:
代码块
JavaScript
自动换行
复制代码
123456789101112131415
(defun fgengroup (#ss / #listG #le #eNAME)
(setq #listG (list '(0 . "GROUP") ;对象名
'(100 . "AcDbGroup") ;子类标记
'(300 . "") ;组说明
'(70 . 1) ;未命名标志:1-未命名
'(71 . 1) ;可选择性标志:1-可选择
) ;l
) ;s
(setq #le (ssnamex #ss))
(setq #le (mapcar 'cadr #le))
(foreach #eNAME #le
(setq #listG (append #listG (list (cons 340 #eNAME)))) ;组中图元的硬指针句柄(每个对象一个条目)
) ;f
(entmake #listG)
) ;d
复制成功
并没有直接创建group的vla函数,通过vla创建group实际上获得vla-groups集合,通过在集合中添加新元素的方式创建,且创建后要通过vla-put命令才能对组进行编辑,示例如下:
代码块
JavaScript
自动换行
复制代码
1234
(setq acadObj (vlax-get-acad-object))
(setq doc (vla-get-ActiveDocument acadObj))
(setq groupColl (vla-get-Groups doc)) ;获得组集合
(setq testGroup (vla-Add groupColl "TEST")) ;创建组(若已经存在则选择组)
复制成功
该创建的组可以在"CLASSICGROUP34;中查看,如图1所示。此时组是空的,向组内添加图元的操作为:
代码块
JavaScript
自动换行
复制代码
1
(vla-appenditems testGroup <variant:obj>)
复制成功
对该方法的详细介绍见官方文档:
https://help.autodesk.com/view/OARX/2023/CHS/?guid=GUID-1CA2C9D1-F8F7-4C11-B361-2998C4869119
alv-appenditems的详细用法及<variant:obj>的创建方法见官方文档:
https://help.autodesk.com/view/OARX/2023/CHS/?guid=GUID-01216A16-2242-4E2A-B98E-C12002594D4E
四、其他
4.1 图形文件中编组情况可用"CLASSICGROUP34;命令查看:

图1 "CLASSICGROUP"界面
4.2 编组相关DXF组码说明见官方文档:
https://help.autodesk.com/view/OARX/2023/CHS/?guid=GUID-5F1372C4-37C8-4056-9303-EE1715F58E67
欢迎留言并发表您的见解!

免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删