一些简单的Autolisp问题
我已经阅读了jeffsanders的一些教程,因为你们中有相当一部分人推荐了它。我的一个问题是;如何建立选择集和实体之间的关系?例如(也是我的问题)(&A):
首先,我选择层为“STR”的所有对象:
然后(暂时假设选择都是文本)(&T)我想更改我所有选择的文本高度(因此使用他教程中的另一个复制片段):
我可以使用什么从选择集(mySet)跳转到更改实体(ent)?
毫无疑问,有更好的方法可以做到这一点,但这部分是解决问题,部分是理解。谢谢 嗨,史蒂夫,
有许多方法可以将选择集转换为其中包含的各种实体。
这里有几个不同方法的示例,在所有示例中,假设“ss”是一个变量,其选择集与之绑定。
(setq i -1)
(while (setq ent (ssname ss (setq i (1+ i))))
(setq lst (cons ent lst)))
(reverse lst)
上面使用了带有SSNAME函数的WHILE循环。SSNAME函数将返回位于选择集中某个索引处的实体的实体名称。索引从0开始,因此在循环之前i设置为-1。
以上内容将返回选择集中包含的实体列表。然后,可以使用此列表,使用FOREACH或MAPCAR等函数对实体执行操作。
或者,您可以在迭代集合的同时执行该操作:
(setq i -1)
(while (setq en (ssname ss (setq i (1+ i))))
(setq enlist(entget en))
(setq enlist (subst (cons 40 50) (assoc 40 enlist) enlist))
(entmod enlist)
(entupd en)
) ; end while
或者,您可以使用重复功能(稍微慢一点,但几乎不明显……):
(repeat (setq n (sslength ss))
(setq en (ssname ss (setq n (1- n))))
(setq enlist(entget en))
(setq enlist (subst (cons 40 50) (assoc 40 enlist) enlist))
(entmod enlist)
(entupd en)
) ; end Repeat
上面的步骤在集合中向后移动,从最高的索引数下降到零,然后依次对每个实体进行操作。
其他更先进的方法包括:
(setq lst (vl-remove-if 'listp
(mapcar 'cadr (ssnamex ss))))
它将再次返回选择集中所有实体的列表,但需要调用(vl load com)来加载Visual LISP函数。这种方法虽然更加优雅,但比前面的示例慢。
希望这能有所帮助,如果你不理解我发布的内容,尽管问。。
李 李,谢谢你的快速回复。还有很多问题要处理,所以我会再问你。至于最后一种(高级)方法;那么Visual Lisp是大多数Autolisp用户的使用方式?
有些人只是坚持使用AutoLISP,因为我相信VL只是完全整合到AutoCAD 2000中。
VL在AutoCAD中提供了更多的访问权限和灵活性,因为它是比AutoLISP更低级别的编程语言。但我只会在你完全精通AutoLISP之后才迁移到VL,因为VL拥有AutoLISP的所有功能&还有更多。。。
李 好的,我已经在我的计划中实施了第二个建议:
(defun C:CTS()
(if (setq ss (ssget "X" (list (cons 8 "STR")))) ;Create selection set with all objects with specified layer
(progn
(setq i -1)
(while (setq en (ssname ss (setq i (1+ i))))
(setq enlist (entget en))
;(if (= "TEXT" (cdr(assoc 0 enlist)))(
(setq enlist (subst (cons 72 1) (assoc 72 enlist) enlist) ; vertical align - middle = 1
enlist (subst (cons 73 2) (assoc 73 enlist) enlist) ; horizontal align - center = 2
enlist (subst (cons 7 "ISOCP") (assoc 7 enlist) enlist) ; text style
enlist (subst (cons 40 300) (assoc 40 enlist) enlist)) ; text height
(entmod enlist)
(entupd en)
) ; end if
) ; end while
)
(alert "Error: no layer exists")
)
(princ)
)
给出的代码运行良好,是我添加到代码中的行导致了问题:
我认为注释掉的if语句有助于告诉程序哪些实体是文本,但(1)它不起作用(它说:错误:输入时虚线对中有额外的CDR)和(2)它似乎无论如何都不需要它。应该包括这样的if语句吗?如果是这样,我的有什么问题?
我遇到的另一个问题与文本对齐有关。出于某种原因,最初设置为“左”对齐的所有文本将移动到0,0。是什么让它这样做的?
谢谢 良好的开端Steve,
我提出了一些改进意见:
(defun c:cts (/ ss i en enlist)
;; Always remember to localise your variables
(if (setq ss (ssget "X" (list (cons 0 "TEXT") (cons 8 "0"))))
;; I have also filtered for TEXT items only
(progn
(setq i -1)
(while (setq en (ssname ss (setq i (1+ i))))
(setq enlist (entget en)
enlist (subst (cons 11 (cdr (assoc 10 enlist))) (assoc 11 enlist) enlist)
;| When Changing the Alignment Setting of Text, unless it is
the default: 72=0 73=0, then you need to specify an Alignment point
in DXF 11. I have used the insertion point from DXF 10.
|;
enlist (subst (cons 72 1) (assoc 72 enlist) enlist) ; vertical align - middle = 1
enlist (subst (cons 73 2) (assoc 73 enlist) enlist) ; horizontal align - center = 2
enlist (subst (cons 7 "ISOCP") (assoc 7 enlist) enlist) ; text style
enlist (subst (cons 40 300) (assoc 40 enlist) enlist)); text height
(entmod enlist)
(entupd en)
) ; end while
)
(alert "Nothing Found")
)
(princ)
)
再次感谢,这是一个很大的帮助。这种对齐设置很有意义。
为了说明我对Lisp有多少不了解,我不得不问,如果可以使用ssget在整个图形中轻松搜索文本或某个图层的对象,难道不可能使用ssset函数将对象设置为相同的运动吗? @Steve1:
代码中带注释的“if”行不起作用,因为您试图使用简单的括号对语句进行分组-必须使用“progn”语句才能对if和else动作进行分组:
问候
好主意,但恐怕不行-(ssget“_X”)是执行此操作的最简单方法。
巧合的是,没有函数ssset,closest is,sssetfirst来控制夹点和选择集的选择。
顺便说一句,Msasu不错-我没有过多地讨论IF语句,因为我想用另一种方法,使用ss过滤器。
但是,有关IF语句等的更多信息,请参阅这里的Steve。
李 还有一件事,史蒂夫。
您使用什么创建LISP文件?我发现大多数没有经验的用户都使用记事本来写文件,因为这是他们习惯的格式。但我建议您改用ACAD附带的Visual LISP编辑器(当然,如果您还没有使用它的话)。只需在命令提示符下键入VLIDE,然后转到“文件”>“新建文件”,然后关闭。
Visual LISP编辑器中的帮助文件非常宝贵,您可以从中学到很多东西。
李
页:
[1]
2