2
;;----------------=={ Add Objects to Block }==----------------;;
;;                                                            ;;
;;  Adds all objects in the provided SelectionSet to the      ;;
;;  definition of the specified block.                        ;;
;;------------------------------------------------------------;;
;;  Author: Lee Mac, Copyright © 2011 - www.lee-mac.com       ;;
;;------------------------------------------------------------;;

(defun LM:AddObjectstoBlock ( doc block ss / lst mat )

    (setq lst (LM:ss->vla ss)
          mat (LM:Ref->Def block)
          mat (vlax-tmatrix (append (mapcar 'append (car mat) (mapcar 'list (cadr mat))) '((0. 0. 0. 1.))))
    )
    (foreach obj lst (vla-transformby obj mat))

    (vla-CopyObjects doc (LM:SafearrayVariant vlax-vbobject lst)
        (vla-item (vla-get-Blocks doc) (cdr (assoc 2 (entget block))))
    )
    (foreach obj lst (vla-delete obj))
    (vla-regen doc acAllViewports)

这是我第一次在 AutoLISP 中看到这种类型的语法。

我正在尝试对"LM:"实际含义进行一些解释。

使用"Ref->"对我来说也是一个问题。"Ref"似乎没有定义,所以它似乎必须以某种方式成为系统的一部分,尽管我无法提取任何描述"Ref->".

为什么ss用 访问局部变量"LM:ss->"

谢谢你。

4

2 回答 2

3

这种类型的语法不是 AutoLISP/Visual LISP 的构造。这是李麦克的标准。我是这样理解的:

“LM:”实际上是“Lee Mac”的快捷方式;)

(LM:ss->vla ss) 应该将数据类型从选择集切换到 vla 对象列表,其中选择集类似于选定元素列表,但定义为类型实体,而不是 vla 对象。也许通过 (ssget) 或 (ssgetfirst)

(LM:Ref->Def 块) 根据它的引用获取块定义。其中“LM:Ref->Def”只是函数的全名。“Ref”不是任何类型的变量,它是函数名的一部分。

“LM:ss->”不是说我们使用ss定义为函数的参数,而是“LM:ss->vla”是函数的名称。

于 2016-08-22T06:19:44.623 回答
1

在 AutoLISP 中定义函数时,对结果函数赋予替代行为的唯一命名约定是前缀c:

例如:

(defun c:test ( )
    (princ "\nHello World!")
    (princ)
)

在函数名称中使用c:前缀意味着函数可以直接在 AutoCAD 命令行中作为命令进行评估。

在这里,test在 AutoCAD 命令行中键入会导致Hello World!在命令行窗口的新行上打印。

如果函数被定义为:

(defun test ( )
    (princ "\nHello World!")
    (princ)
)

在 AutoCAD 命令行中键入test会导致错误消息:

Command: test Unknown command "TEST". Press F1 for help.

对于要评估的函数,用户需要键入:(test)


考虑到这一点,使用 ofLM:除了标识为我的库中的函数之外没有其他意义,并降低在同一命名空间中定义同名函数的可能性。

例如,如果我要定义一个函数,例如:

(defun AddLine ( pt1 pt2 )
    (entmakex
        (list
           '(0 . "LINE")
            (cons 10 pt1)
            (cons 11 pt2)
        )
    )
)

鉴于此函数的通用命名和它执行的普遍操作(至少在涉及 AutoCAD 的情况下),很可能在文档命名空间中定义了另一个具有相同名称的此类函数。

因此,在计算上述表达式时将重新定义现有函数,或者如果稍后要计算defun其自己的表达式,则现有函数将重新定义上述函数。defun

通过在函数名称前加上我自己的作者前缀LM:

(defun LM:AddLine ( pt1 pt2 )
    (entmakex
        (list
           '(0 . "LINE")
            (cons 10 pt1)
            (cons 11 pt2)
        )
    )
)

我正在帮助确保当我LM:AddLine在文档命名空间中进行评估时,我自己对该函数的定义将始终被使用,并且我可以“污染”另一个加载程序使用的函数定义的可能性较小。


同样,->在函数名中使用 纯粹是一种命名约定,对函数没有其他含义。

例如,我命名了我的函数LM:ss->vla,因为它是我的库中的一个标准函数,它将选择集(我已缩写ss)转换为 VLA 对象列表。

于 2018-02-13T19:38:47.693 回答