我有一个例行程序,用于在AutoCAD中创建管道弯头,然后插入转向叶片。
我让程序工作得非常完美,只是当我去插入块时,我将它设置为使得块的比例是从点2到点5的横截面距离(这分别是肘部的内角和外角)插入的块可怕地扭曲。
我不知道是否有办法避免这种情况。
; Garrett Ford 6/23/17
; The purpose of this program is to allow the user to enter a few
; dimensions and then insert and elbow with a turning vane
(defun C:bow(/ oldsnap oldlayer oldblip flag iw fw tt rot ip ang bend p1 p2 p3 p4 p5 p6 ss)
;***********************************************************************
; Save System Variables
(setq oldsnap (getvar "osmode"))
(setq oldlayer (getvar "clayer"))
(setq oldblip (getvar "blipmode"))
;***********************************************************************
;Change Settings & User Input
(setvar "osmode" 35)
(setvar "blipmode" 0)
(setq flag (tblsearch "Layer" "LP-DUCT")) ; checks for LP-DUCT
(if flag
(setvar "clayer" "LP-DUCT") ; changes layer to LP-DUCT
(alert ("No LP-DUCT Layer!")) ; if layer doesn't exist fuction terminates
)
(setq iw (getdist "\nWhat is the Initial Width? : "))
(setq fw (getdist "\nWhat is the Final Width? : "))
(setq tt (getdist "\nWhat is the Throat Length: "))
;(setq rot (getangle "\nWhat is the Angle of Rotation? : "))
(setq ip (getpoint "\nSelect an Insertion Point: "))
(setq ang (getangle ip "\nWhat is the Initial Throat direction from the Insertion point?: "))
(initget 1 "Left Right")
(setq bend (if (= (getkword "\nBend direction [Left/Right]: ") "Right") - +))
;***********************************************************************
; Polar Calculations
(setq p1 (polar ip (bend ang (/ pi 2)) (/ iw 2)))
(setq p2 (polar p1 ang tt)) ; Inside Corner
(setq p3 (polar p2 (bend ang (/ pi 2)) tt))
(setq p4 (polar p3 ang fw))
(setq p5 (polar p4 (bend ang (- (/ pi 2))) (+ tt iw))) ; Outside Corner
(setq p6 (polar p5 (+ ang pi) (+ tt fw)))
;***********************************************************************
; Line & Insert Commands
;(setq ss (ssadd))
(setvar "osmode" 0)
(command "_.pline" ip p1 p2 p3 p4 p5 p6 "_close")
;(ssadd (entlast) ss)
(setvar "osmode" 7079)
(command "_.insert" "tvain" p2 (distance p2 p5) (+ ang (/ pi 2)))
;(ssadd (entlast) ss)
;(command "rotate" ss "rot" ip pause)
(setvar "osmode" oldsnap)
(setvar "clayer" oldlayer)
(setvar "blipmode" oldblip)
) ; End Defun
;************************************************************************
;Converts the Degrees into Radians
(defun dtr (ang) ;define degrees to radians function
(* pi (/ ang 180.0))
;divide the angle by 180 then
;multiply the result by the constant PI
) ;end of function
;************************************************************************
答案 0 :(得分:0)
您的代码存在一些问题:
(alert ("No LP-DUCT Layer!"))
会出错。
应改为:(alert "No LP-DUCT Layer!")
您应该测试每个getXXX
个来电(例如getpoint
,getdist
等)是否会在继续之前返回非零值。由于在AutoLISP中,任何非零的结果都被视为True
结果,因此可以使用if
和and
的组合轻松实现此目标,例如:
(if
(and
(setq iw (getdist "\nWhat is the Initial Width? : "))
(setq fw (getdist "\nWhat is the Final Width? : "))
(setq tt (getdist "\nWhat is the Throat Length: "))
(setq ip (getpoint "\nSelect an Insertion Point: "))
(setq ang (getangle ip "\nWhat is the Initial Throat direction from the Insertion point?: "))
...
)
(progn
;; Do your thing
)
)
由于AutoLISP支持短路评估,因此只要表达式返回and
,nil
函数就会停止对参数的求值。因此,如果用户未提供初始宽度的值,则不会验证and
表达式,并且不会提示他们指定最终宽度
我建议使用INSERT
命令的命令行版本,在命令前面加一个连字符(即-INSERT
)。
我还建议明确指定比例&使用此命令提供的关键字进行轮换,例如:
(command "_.-insert" "tvain" "_S" (distance p2 p5) "_R" (angtos (+ ang (/ pi 2))) "_non" p2)
在这种情况下需要angtos
函数作为-INSERT
命令(实际上使用command
函数评估的任何命令)使用图形中设置的角度单位,而不是弧度。
您的代码中定义的dtr
函数未被评估,因此可能会被省略。
您可能希望使用以下表达式来设置位OSMODE
,而不是将0
系统变量设置为16384
:
(setvar 'osmode (logior 16384 (getvar 'osmode)))
这相当于用户按 F3 禁用对象捕捉而不是将OSMODE
设置为0
,这相当于用户取消选中所有对话框中的对象捕捉模式。
这样做的好处是,如果您的代码出于任何原因出错(包括用户在程序执行期间按下 Esc ),Object Snap将仅被禁用,并且可以使用重新启用F3 ,而不是完全擦除用户的对象捕捉设置。
或者,您可以完全避免更改OSMODE
系统变量,而是使用"_non"
捕捉修饰符(意为“无”)为点输入添加前缀,这会导致AutoCAD忽略所有活动捕捉模式下一个点输入,例如:
(command "_.pline" "_non" ip "_non" p1 ... etc ... "_close")
或者,作为另一种选择,您可以使用本地定义的错误处理程序,该错误处理程序会在代码中出现错误后重置OSMODE
系统变量(以及所有其他已修改的系统变量)。我在Error Handling的教程中描述了如何执行此操作。