0

我有一个例程,旨在在 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
;************************************************************************
4

1 回答 1

0

您的代码存在一些问题:

  • (alert ("No LP-DUCT Layer!"))会出错。

    这应该是:(alert "No LP-DUCT Layer!")

  • 在继续之前,您应该测试您的每个getXXX调用(例如getpointgetdist等等)是否返回一个非零值。由于在 AutoLISP 中,任何非 nil 都被视为True结果,因此可以使用 和 的组合轻松实现这一点ifand例如:

    (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。因此,如果用户没有为Initial Width提供值,则and表达式将不会被验证,并且不会提示他们指定Final Width

  • 我建议通过INSERT在命令前加上连字符(即-INSERT)来使用命令的命令行版本。

    我还建议使用此命令提供的关键字明确指定比例和旋转,例如:

    (command "_.-insert" "tvain" "_S" (distance p2 p5) "_R" (angtos (+ ang (/ pi 2))) "_non" p2)
    

    在这种情况下,该angtos函数是必需的,因为该-INSERT命令(以及使用该函数评估的任何命令command)使用图形中设置的角度单位,而不是弧度。

  • 您的代码中定义的dtr函数没有被评估,因此可以省略。

  • 您可能希望使用以下表达式来设置 bit ,而不是将OSMODE系统变量设置为:016384

    (setvar 'osmode (logior 16384 (getvar 'osmode)))
    

    这相当于用户按下F3禁用对象捕捉而不是设置OSMODE0,这相当于用户取消选中对话框中的所有对象捕捉模式。

    这样做的好处是,如果您的代码因任何原因出错(包括如果用户Esc在程序执行期间按下),对象捕捉将仅被禁用并且可以使用 重新启用F3,而不是完全擦除用户的对象捕捉设置。

    或者,您可以避免OSMODE完全更改系统变量,而是在点输入前加上"_non"捕捉修饰符(意思是“无”),这会导致 AutoCAD 忽略下一个点输入的所有活动捕捉模式,例如:

    (command "_.pline" "_non" ip "_non" p1 ... etc ... "_close")
    

    或者,作为另一种选择,您可以使用本地定义的错误处理程序,它会OSMODE在代码中出现错误后重置系统变量(和所有其他修改的系统变量)。我在我的错误处理教程中描述了如何做到这一点。

于 2018-03-03T13:54:48.273 回答