如何使用AutoLISP创建一个插入块的Lisp代码?

huangapple go评论160阅读模式
英文:

How to create a lisp to insert blocks with AutoLISP?

问题

这段代码的目标是创建一个名为"FF"的AutoLisp命令,用于插入特定的块。用户输入"FF",定义第一个点,然后输入类似"TFN"的字符串。在这个字符串中,每个字符都对应一个块,F、N和T都是块。代码中的"aux"变量用于在块之间创建间隔。

请注意,Autocad 2010会识别"FF"命令,然后要求输入一个点,但当点被定义后,出现了错误:"error: bad argument type: (or stringp symbolp): nil"。

英文:

So, I am kinda new to the AutoLisp world and I wanted to create a lisp that defines a command named "FF" to insert specific blocks. For example, the user types FF, then defines the first point and then types a string like "TFN". The thing is, in this string all characters are blocks, F corresponds to a block, and so do N and T. Here is the code:

(defun c:FF () 
(setq P (getpoint "Define origin:"))
(setvar aux 1)
(setq seq (getstring "Define the sequence of blocks:"))
(foreach str seq
	 (command "insert" str (polar P (* pi 2) (aux*2)))
	 (incf aux)	
)
)

It's supossed to look like this:

如何使用AutoLISP创建一个插入块的Lisp代码?

By the way, the "aux" variable is used to create separation between the blocks.

Autocad 2010 does recognize the command FF, then requires a point, but when the point is defined it returns this: error: bad argument type: (or stringp symbolp): nil

答案1

得分: 0

你的代码存在一些问题,但错误是因为在表达式中使用了 setvar:

(setvar aux 1)

在这里,符号 aux 被评估为 setvar 函数的参数,返回值是 nil,这不是 setvar 函数所需的有效字符串或符号来表示系统变量。

相反,你应该使用 setq(又称 "set quote"),它不会评估第一个提供的参数:

(setq aux 1)

你还将遇到与你的 foreach 语句相关的错误,因为 seq 是一个字符串,而 foreach 只能迭代列表。

相反,你需要将字符串分割成单个字符的列表,可以使用 substrvl-string->listchr 的组合。

或者,你可以使用 substr 迭代字符串,直到你得到一个空字符串,例如:

(while (/= "" seq)
    (setq blk (substr seq 1 1)
          seq (substr seq 2)
    )
    (if (or (tblsearch "block" blk) 
            (setq blk (findfile (strcat blk ".dwg")))
        )
        (command "_-insert" blk "_S" 1.0 "_R" 0.0 "_non" (polar p 0.0 (* aux 2.0)))
    )
)

这还可以处理用户在 getstring 提示处按下 ENTER 键的情况,因为 while 循环的测试表达式将不满足条件。

请注意,incf 不是有效的 AutoLISP 函数,除非这是你单独定义的函数。

你还可以考虑在插入块之前将 ATTREQ 系统变量设置为 0,这样你就不会收到提示以提供属性值。

英文:

There are several issues with your code, but the error arises from the use of setvar in the expression:

(setvar aux 1)

Here, the symbol aux is being evaluated as an argument to the setvar function and is yielding a value of nil, which is an invalid string or symbol representing a system variable as required by the setvar function.

Instead, you should assign variables using the setq (aka "set quote"), which will not evaluate the first supplied argument:

(setq aux 1)

You'll also encounter an error with your foreach statement, as seq is a string and foreach can only iterate over lists.

Instead, you'll need to separate the string into a list of individual characters, either using substr or a combination of vl-string->list & chr.

Or alternatively, iterate over the string using substr until you're left with an empty string, for example:

(while (/= "" seq)
    (setq blk (substr seq 1 1)
          seq (substr seq 2)
    )
    (if (or (tblsearch "block" blk) 
            (setq blk (findfile (strcat blk ".dwg")))
        )
        (command "_.-insert" blk "_S" 1.0 "_R" 0.0 "_non" (polar p 0.0 (* aux 2.0)))
    )
)

This will also account for the user pressing <kbd>ENTER</kbd> at the getstring prompt, as the test expression for the while loop will not be satisfied.

Note that incf is not a valid AutoLISP function, unless this is a function that you have separately defined.

You may also want to consider setting the ATTREQ system variable to 0 prior to inserting the blocks, so that you do not receive the prompt to supply attribute values.

huangapple
  • 本文由 发表于 2023年4月4日 04:37:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/75923586.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定