Lee Mac 发表于 2022-7-6 17:07:24

中线LISP错误

好的,所以我今天有一个绝对的nightmaire-两个线程在几分钟内!今天我的Lisp程序似乎都不想用了。。。
 
好的,我一直在尝试创建一个LISP来在一个圆上画一条中心线——像pi一样简单。
 
但我不断返回一个错误,我不知道为什么-毫无疑问,这可能是这么简单的事情。。。
 
无论如何,我将感谢任何可用的帮助,用JONTHEPOPE的话来说,“很抱歉所有的帖子……”
 

;|

   Centre-Line by Lee McDonnell

       November 2008

|;


(defun c:cl (/ oldlay oldsnap c1 c1ent c1cent c1rad crat)
   
;   --- Error Trap ---
   
   (defun *error*(msg)
   (if oldVars
       (mapcar 'setvar varLstoldVars)
   ); end if
   (princ "\nError or Esc pressed... ")
   (princ)
   ); end of *error*

       (setq varLst    (list "CMDECHO" "OSMODE" "CLAYER" "DIMSCALE")
         oldVars    (mapcar 'getvar varLst)
   ); end setq

;    --- Error Trap ---

   (setvar "cmdecho" 0)
   (setq oldlay (getvar "clayer"))
   (setq oldsnap (getvar "osmode"))
   (mapcar 'cllayer '("1" "2" "3" "4" "5"))
   (if   (not (getenv "cl:ratio"))
       (setenv "cl:ratio" "122")
   ) ; end if
   (princ (strcat "\nType \"CLSET\" to Change Base Variables. << Current Settings >> C/L Ratio: "
         (getvar "cl:ratio")))
   (while
       (setq c1 (entsel "\nSelect Circle for Centre-line: "))
       (setq c1ent (entget (car c1)))
       (if   (= (cdr (assoc 0 c1ent)) "CIRCLE")
         (progn
               (setq   c1cent   (assoc 10 c1ent)
                   c1rad    (assoc 40 c1ent)
                   crat    (/ (atof (getenv "cl:ratio")) 100)
               ) ; end setq
               (setvar "osmode" 0)
               (setvar "clayer" "5")
               (command "-linetype" "S" "CENTER" "")
               (command "_line"
                   (polar
                     c1cent
                     pi
                     (* clrad crat)
                   ) ; end polar
                   (polar
                     c1cent
                     0
                     (* clrad crat)
                   ) ; end polar
                   ""
               ) ;end line
               (command "_line"
                   (polar
                     c1cent
                     (/ (* 3 pi) 2)
                     (* clrad crat)
                   ) ; end polar
                   (polar
                     c1cent
                     (/ pi 2)
                     (* clrad crat)
                   ) end polar
                   ""
               ) ; end line
         ) ; end progn
         (alert "\nEntity is not a Circle.")
       ) ; end if
   ) ; end while
   (setvar "clayer" oldlay)
   (setvar "osmode" oldsnap)
   (setvar "cmdecho" 1)
   (princ "\nFunction Complete.")
   (princ)
) ; end cl

(defun cllayer (lay)
   (if   (not (tblsearch "LAYER" lay))
         (command "_.-layer" "_m" lay "_c" lay lay "")
   ) ; end if
   (princ)
) end cllayer

(defun c:clset (/ cratio)
   (if   (not (getenv "cl:ratio"))
       (setenv "cl:ratio" "122")
   ) ; end if
   (princ (strcat "\n<< Current Settings >> C/L Ratio: " (getvar "cl:ratio") "%"))
   (if    (setq cratio (getreal (strcat "\nSpecify C/L as % of Circle Radius <"
                     (getenv "cl:ratio")
                     "> : ")))
       (setenv "cl:ratio" (rtos cratio))
   ) ; end if
   (princ "\nBase Variables Set.")
   (princ)
) ; end clset


 
谢谢大家

paulmcz 发表于 2022-7-6 17:14:53

你现在可以借我的。。。
 
(defun c:cce (/ lt osn oucs ss b d d1 ename elist cp r pn ps pw pe r2)
(command "cmdecho" (getvar "cmdecho"))
(setq lt "center")
(if (= (tblsearch "ltype" lt) nil)
   (command "-linetype" "l" lt "acad.lin" ""))
(princ "\n Center cross: ")
(cond
   ((setq ss (ssget '((-4 . "<OR")
             (0 . "CIRCLE,ARC,ELLIPSE")
             (-4 . "OR>")
              )
      )
    )
    (setq b (sslength ss))                ; = number of circles in ss
    (setq d b)
    (repeat b
      (setq d1           (1- d)
   ename (ssname ss d1)        ; = last entity in ss
   elist (entget ename)
   cp           (cdr (assoc 10 elist))
   r           (cdr (assoc 40 elist))
   d           (* r 1.5)                ; greater this number, greater overlap of center lines (%)
   pn           (polar cp (* pi 0.5) d)
   ps           (polar cp (* pi 1.5) d)
   pw           (polar cp pi d)
   pe           (polar cp 0 d)
   d           d1
   r2           (* r 0.25)
      )
                                ;(setvar "osmode" 0)
      (entmake        (list
          (cons 0 "LINE")
          (cons 6 lt)
          (cons 62 3)
          (cons 10 pn)
          (cons 11 ps)
          (cons 48 r2)
          (cons 210 (list 0.0 0.0 1.0))
        )
      )
      (entmake        (list
          (cons 0 "LINE")
          (cons 6 lt)
          (cons 62 3)
          (cons 10 pw)
          (cons 11 pe)
          (cons 48 r2)
          (cons 210 (list 0.0 0.0 1.0))
        )
      )
    )
   )
   (T (princ "\n No circle selected! "))
)
(if (not (tblsearch "ltype" lt))
   (princ (strcat "\n Linetype \"" lt "\" was not loaded."))
)
(princ)
)
(prompt "\n Type < cce > for circle or arc center lines")

CALCAD 发表于 2022-7-6 17:20:25

李,
我发现了很多小东西:“cl”的许多实例需要“c1”和几个“getvar”而不是“getenv”。需要几个(assoc)调用(cdr(assoc))。还发现了几个没有前导分号的注释。这可能没有必要,但我将错误陷阱和其他defuns移出了主程序,因为它使我更容易理解。我添加了一些代码来保存和恢复系统*错误*处理程序。也许这不是严格要求的,但这是我学会做这件事的方式,我想确保这不会造成麻烦。我不得不将主程序重命名为CLDRAW,因为CL是我系统上COPYLINK的别名。
该程序确实绘制了中心线,但我不确定它是否完全按照您的预期运行。“WHILE”循环是无限的-这可能是有意的,因此您可以在任意数量的圆上绘制中心线,但这确实意味着必须强制程序以“ESC”结束。此外,提示提示提示您可以使用CLSET重置值,但在主程序中没有暂停来允许它。程序结束时线型不会重置-它保持中心线。创建了五个层-第5层被设置为活动,并在程序结束时保持活动。
我只是不知道你的意图。我希望这个节目能达到你想要的效果。如果你完成了,请发布最终版本。我可能想自己用!
 
 

(defun c:clset (/ cratio)
(if (not (getenv "cl:ratio"))
(setenv "cl:ratio" "122")
) ; end if
(princ (strcat "\n<< Current Settings >> C/L Ratio: " (getenv "cl:ratio") "%")) ; chg getvar to getenv
(if (setq cratio (getreal (strcat "\nSpecify C/L as % of Circle Radius <"
(getenv "cl:ratio")
"> : ")))
(setenv "cl:ratio" (rtos cratio))
) ; end if
(princ "\nBase Variables Set.")
(princ)
) ; end clset
(defun cllayer (lay) ; moved from end
(if (not (tblsearch "LAYER" lay))
(command "_.-layer" "_m" lay "_c" lay lay "")
) ; end if
(princ)
) ; end cllayer - added semicolon
; --- Error Trap ---

(defun cl_error (msg)
(if oldVars
(mapcar 'setvar varLst oldVars)
); end if
(princ "\nError or Esc pressed... ")
(setq *ERROR* sys_error)
(princ)
); end of *error*
; --- Error Trap ---
(defun c:cldraw (/ oldlay oldsnap c1 c1ent c1cent c1rad crat)

(setq sys_error *ERROR*)
(setq *ERROR* cl_error)
(setq varLst (list "CMDECHO" "OSMODE" "CLAYER" "DIMSCALE")
oldVars (mapcar 'getvar varLst)
); end setq
(setvar "cmdecho" 0)
(setq oldlay (getvar "clayer"))
(setq oldsnap (getvar "osmode"))
(mapcar 'cllayer '("1" "2" "3" "4" "5"))
(if (not (getenv "cl:ratio"))
(setenv "cl:ratio" "122")
) ; end if
(princ (strcat "\nType \"CLSET\" to Change Base Variables. << Current Settings >> C/L Ratio: "
(getenv "cl:ratio"))) ; fix
(while
(setq c1 (entsel "\nSelect Circle for Centre-line: "))
(setq c1ent (entget (car c1)))
(if (= (cdr (assoc 0 c1ent)) "CIRCLE")
; fixed c1rad & add cdr in progn
(progn
(setq c1cent (cdr (assoc 10 c1ent))
c1rad (cdr (assoc 40 c1ent))
crat (/ (atof (getenv "cl:ratio")) 100)
) ; end setq

(princ "\nc1rad = ")(princ c1rad)
(princ "\ncrat = ")(princ crat)

(setvar "osmode" 0)
(setvar "clayer" "5")
(command "-linetype" "S" "CENTER" "")
(command "_line"
(polar
c1cent
pi
(* c1rad crat)
) ; end polar
(polar
c1cent
0
(* c1rad crat)
) ; end polar
""
) ; end line
(command "_line"
(polar
c1cent
(/ (* 3 pi) 2)
(* c1rad crat)
) ; end polar
(polar
c1cent
(/ pi 2)
(* c1rad crat)
) ; end polar
""
) ; end line
) ; end progn
(alert "\nEntity is not a Circle.")
) ; end if
) ; end while
(setvar "clayer" oldlay)
(setvar "osmode" oldsnap)
(setvar "cmdecho" 1)
(setq *ERROR* sys_error)
(princ "\nFunction Complete.")
(princ)
) ; end cl

Lee Mac 发表于 2022-7-6 17:22:41

你是一个传奇人物-我很尴尬地看到我在Lisp程序中犯了那么多荒谬的错误。。。。
 
多亏了你,Lisp程序现在效果很好…-我没有使用你的错误陷阱版本-只是因为我不完全理解它,但谢谢你的帮助。
 
但是,我不明白为什么层没有重置为原始的当前层。我已经包括:
 
然而,在“While”功能完成后,层“5”在“While”功能完成后仍保持活动状态。
 
再次感谢
 
 
LISP:
 

;|

   Centre-Line by Lee McDonnell

       November 2008

|;


(defun c:cl (/ oldlay oldsnap c1 c1ent c1cent c1rad crat)
   
;   --- Error Trap ---
   
   (defun *error*(msg)
   (if oldVars
       (mapcar 'setvar varLstoldVars)
   ); end if
   (princ "\nError or Esc pressed... ")
   (princ)
   ); end of *error*

       (setq varLst    (list "CMDECHO" "OSMODE" "CLAYER" "DIMSCALE")
         oldVars    (mapcar 'getvar varLst)
   ); end setq

;    --- Error Trap ---

   (setvar "cmdecho" 0)
   (setq oldlay (getvar "clayer"))
   (setq oldsnap (getvar "osmode"))
   (mapcar 'cllayer '("1" "2" "3" "4" "5"))
   (if   (not (getenv "cl:ratio"))
       (setenv "cl:ratio" "122")
   ) ; end if
   (princ (strcat "\nType \"CLSET\" to Change Base Variables. << Current Settings >> C/L Ratio: "
         (getenv "cl:ratio")))
   (while
       (/= (setq c1 (entsel "\nSelect Circle for Centre-line: ")) nil)
       (setq c1ent (entget (car c1)))
       (if   (= (cdr (assoc 0 c1ent)) "CIRCLE")
         (progn
               (setq   c1cent   (cdr (assoc 10 c1ent))
                   c1rad    (cdr (assoc 40 c1ent))
                   crat    (/ (atof (getenv "cl:ratio")) 100)
               ) ; end setq
               (setvar "osmode" 0)
               (setvar "clayer" "5")
               (command "-linetype" "S" "CENTER" "")
               (command "_line"
                   (polar
                     c1cent
                     pi
                     (* c1rad crat)
                   ) ; end polar
                   (polar
                     c1cent
                     0
                     (* c1rad crat)
                   ) ; end polar
                   ""
               ) ;end line
               (command "_line"
                   (polar
                     c1cent
                     (/ (* 3 pi) 2)
                     (* c1rad crat)
                   ) ; end polar
                   (polar
                     c1cent
                     (/ pi 2)
                     (* c1rad crat)
                   ) ; end polar
                   ""
               ) ; end line
         ) ; end progn
         (alert "\nEntity is not a Circle.")
       ) ; end if
       (command "-linetype" "S" "Bylayer" "")
   ) ; end while
   (setvar "clayer" oldlay)
   (setvar "osmode" oldsnap)
   (setvar "cmdecho" 1)
   (princ "\nFunction Complete.")
   (princ)
) ; end cl

(defun cllayer (lay)
   (if   (not (tblsearch "LAYER" lay))
         (command "_.-layer" "_m" lay "_c" lay lay "")
   ) ; end if
   (princ)
) ; end cllayer

(defun c:clset (/ cratio)
   (if   (not (getenv "cl:ratio"))
       (setenv "cl:ratio" "122")
   ) ; end if
   (princ (strcat "\n<< Current Settings >> C/L Ratio: " (getenv "cl:ratio") "%"))
   (if    (setq cratio (getreal (strcat "\nSpecify C/L as % of Circle Radius <"
                     (getenv "cl:ratio")
                     "> : ")))
       (setenv "cl:ratio" (rtos cratio))
   ) ; end if
   (princ "\nBase Variables Set.")
   (princ)
) ; end clset

CALCAD 发表于 2022-7-6 17:28:51

李,
使用你最新的代码,我的系统似乎一切正常。活动图层和线型恢复为原始图层。我可以通过ESC退出程序,也可以输入或只是在屏幕上选取空白。如果我选择了任何不是圆的东西,则会出现警报框,单击“确定”返回循环。CLSET程序也运行良好。这里一切都很好,我不知道为什么图层不能为你重置。正如您所说,(setvar“clayer”oldlay)应该处理它,您的错误陷阱也通过恢复oldvar来处理它。所以,很抱歉,我对图层问题没有想法。
 
关于*错误*处理程序:这主要是一个“好形式”问题。当您写入(defun*error*(msg)时,您正在重新定义系统错误处理程序。如果不保存和恢复默认处理程序,则定义的处理程序将成为新的系统处理程序,在某些情况下,这不是您想要的。当我第一次开始学习Autolisp时,我给自己带来了一些痛苦,因为我会编写一个类似于您的处理程序,然后继续编写另一个程序,并感到困惑,因为当程序中出现错误时,显示的消息不是我所期望的。有时系统变量会包含奇怪的非默认值,需要一段时间才能找到原因。由于许多行为良好的程序很少或从不导致调用系统处理程序的错误,因此您可能会在很长一段时间内没有意识到系统处理程序已被无意中修改。因此,在研究了其他程序员的代码后,我采用了我的标准方法。在lisp的开头或附近,我用(setq sys\u error*error*)保存默认处理程序,然后是新的定义(setq*error*my\u error)。然后我编写一个单独的函数
 
(defun my_error(msg)
.
.
.
(setq*错误*系统错误)
)
 
每当调用我的处理程序时,最后一行恢复默认处理程序。我还包括主程序末尾或附近的(setq*error*sys\u error),因此处理程序在每个正常出口中都会恢复。
这种方法对我来说很可靠。如果有更好的方法,我很乐意被告知。

Lee Mac 发表于 2022-7-6 17:31:09

感谢您提供有关错误处理程序的信息-我现在将在代码中使用它。
 
我有一些关于我的问题的更多信息-当我通过按enter键或点击空白退出功能时,该层不会恢复。
 
但是,如果我按Esc键结束函数,图层和线型将恢复,但这只是因为我的错误处理程序正在运行。(出现错误消息)

CALCAD 发表于 2022-7-6 17:38:00

李,
您可以尝试在结束时使用在错误陷阱中使用的相同方法,即mapcar:
 
(如果是oldVars
(mapcar的setvar varLst oldVars)
); 如果结束
 
可能值得一试,它确实在一定程度上简化了代码。

Lee Mac 发表于 2022-7-6 17:41:59

谢谢CALCAD,我会尝试一下的——谢谢你在这件事上的帮助,一如既往,非常感谢你的任何建议。

CAB 发表于 2022-7-6 17:45:56

在某些情况下,我很快改变了自己的风格,并根据自己的喜好进行了调整。
 
5

CALCAD 发表于 2022-7-6 17:51:23

页: [1] 2
查看完整版本: 中线LISP错误