📄 ai_utils.lsp
字号:
;;;
;;; Same as ai_aselect1, but allows SELECT options, e.g. "Previous",
;;; and returns the first entity in the selection set.
;;; Looks for ONE autoselected entity, or throws the user into
;;; interactive entity selection (for one entity, where a selection
;;; point is insignificant). The <msg> argument is the prompt used if
;;; interactive selection is invoked.
;;;
;;; Sets the value of ai_seltype to:
;;;
;;; 1 = resulting entity was autoselected
;;; 2 = resulting entity was prompted for.
(defun ai_autossget1 (msg / ent ss)
(cond
((and (eq 1 (logand 1 (getvar "pickfirst")))
(setq ent (ssget "_i"))
(eq 1 (sslength ent))
)
(setq ai_seltype 1)
(if (ai_entity_locked (ssname ent 0) 1)
(ai_return nil)
(ai_return (ssname ent 0))
)
)
(T
(while (not ss)
(princ msg)
(command "_.SELECT" "_SI" "_AU" pause)
(if (and
(setq ss (ssget "_P"))
(eq 1 (sslength ss))
(setq ss (ai_ssget ss)) ;; removed locked entities
)
(setq ent (ssname ss 0))
(setq ss nil ent nil)
)
(setq ai_seltype 2)
(ai_return ent)
)
)
)
)
;;;
;;; A function that turns on UNDO so that some existing routines will work.
;;; Do not use with new routines as they should be designed to operate with
;;; any UNDO setting.
;;;
(defun ai_undo_on ()
(setq undo_setting (getvar "undoctl"))
(cond
((= 2 (logand undo_setting 2)) ; Undo is one
(command "_.undo" "_control" "_all" "_.undo" "_auto" "_off")
)
((/= 1 (logand undo_setting 1)) ; Undo is disabled
(command "_.undo" "_all" "_.undo" "_auto" "_off")
)
)
)
;;;
;;; Return UNDO to the initial setting. Do not use with new routines as they
;;; should be designed to operate with any UNDO setting.
;;;
(defun ai_undo_off ()
(cond
((/= 1 (logand undo_setting 1))
(command "_.undo" "_control" "_none")
)
((= 2 (logand undo_setting 2))
(command "_.undo" "_control" "_one")
)
)
)
;;;
;;; UNDO handlers. When UNDO ALL is enabled, Auto must be turned off and
;;; GROUP and END added as needed.
;;;
(defun ai_undo_push()
(setq undo_init (getvar "undoctl"))
(cond
((and (= 1 (logand undo_init 1)) ; enabled
(/= 2 (logand undo_init 2)) ; not ONE (ie ALL is ON)
(/= 8 (logand undo_init 8)) ; no GROUP active
)
(command "_.undo" "_group")
)
(T)
)
;; If Auto is ON, turn it off.
(if (= 4 (logand 4 undo_init))
(command "_.undo" "_auto" "_off")
)
)
;;;
;;; Add an END to UNDO and return to initial state.
;;;
(defun ai_undo_pop()
(cond
((and (= 1 (logand undo_init 1)) ; enabled
(/= 2 (logand undo_init 2)) ; not ONE (ie ALL is ON)
(/= 8 (logand undo_init 8)) ; no GROUP active
)
(command "_.undo" "_end")
)
(T)
)
;; If it has been forced off, turn it back on.
(if (= 4 (logand undo_init 4))
(command "_.undo" "_auto" "_on")
)
)
;;;
;;; (get_dcl "FILTER")
;;;
;;; Checks for the existence of, and loads the specified .DCL file,
;;; or aborts with an appropriate error message, causing the initial
;;; load of the associated application's .LSP file to be aborted as
;;; well, disabling the application.
;;;
;;; If the load is successful, the handle of the .DCL file is then
;;; added to the ASSOCIATION LIST ai_support, which would have the
;;; following structure:
;;;
;;;
;;; (("DCLFILE1" . 1) ("DCLFILE2" . 2)...)
;;;
;;; If result of (ai_dcl) is NIL, then .DCL file is not avalable,
;;; or cannot be loaded (the latter can result from a DCL audit).
;;;
;;; Applications that call (ai_dcl) should test its result, and
;;; terminate or abort if it is nil. Normal termination rather
;;; than aborting with an error condition, is desirable if the
;;; application can be invoked transparently.
;;;
(defun ai_dcl (dcl_file / dcl_handle)
(cond
;; If the specified .DCL is already loaded then
;; just return its handle to the caller.
((ai_return (cdr (assoc dcl_file ai_support))))
;; Otherwise, try to FIND the .DCL file, and display a
;; an appropriate message if it can't be located, and
;; return Nil to the caller:
((not (findfile (strcat dcl_file ".dcl")))
(ai_alert
(strcat
"Can't locate dialog definition file " dcl_file
".dcl\n Check your support directory."))
(ai_return nil)
)
;; The file has been found. Now try to load it. If it
;; can't be succesfully loaded, then indicate such, and
;; abort the caller:
((or (not (setq dcl_handle (load_dialog dcl_file)))
(> 1 dcl_handle))
(ai_alert
(strcat
"Can't load dialog control file " dcl_file ".dcl"
"\n Check your support directory."))
(ai_return nil)
)
;; Otherwise, the file has been loaded, so add it's handle
;; to the FILE->HANDLE association list AI_SUPPORT, and
;; return the handle to the caller:
(t (setq ai_support (cons (cons dcl_file dcl_handle) ai_support))
(ai_return dcl_handle)
)
)
)
;;; Enable/Disable the common fields depending on the selection set.
;;; Layer 1; Color 2; Linetype 4; Linetype Scale 8; Thickness 16;
;;;
;;; Used by DDCHPROP and DDMODIFY.
;;;
(defun ai_common_state (ss_ename / bit_value)
(setq bit_value 0)
(setq ss_ename (strcase ss_ename))
(cond
( (member ss_ename '("ARC" "ATTDEF" "CIRCLE" "LINE" "POINT"
"POLYLINE" "SHAPE" "SOLID" "TRACE" "TEXT" "XREF"))
(setq bit_value (logior 1 2 4 8 16))
)
( (member ss_ename '("3DFACE" "ELLIPSE" "BODY"
"REGION" "3DSOLID" "SPLINE"
"XLINE" "TOLERANCE" "LEADER" "RAY"))
(setq bit_value (logior 1 2 4 8))
)
( (member ss_ename '("DIMENSION" "INSERT"))
(setq bit_value (logior 1 2 4))
)
( (member ss_ename '("VIEWPORT" "MTEXT"))
(setq bit_value (logior 1 2))
)
( (member ss_ename '("MLINE"))
(setq bit_value (logior 1 8))
)
(T (setq bit_value (logior 1 2 4 8 16)) ; Enable all fields if unknown.
)
)
bit_value ; Return bit value of fields.
)
;;;
;;;
;;; (ai_helpfile) returns an empty string. Let the core code figure out
;;; the default platform helpfile.
;;;
(defun ai_helpfile ( / platform)
""
)
;;;
;;; Returns val with the any trailing zeros beyond the current
;;; setting of luprec removed.
;;;
(defun ai_rtos(val / a b units old_dimzin)
(setq units (getvar "lunits"))
;; No fiddling if units are Architectural or Fractional
(if (or (= units 4) (= units 5))
(rtos val)
;; Otherwise work off trailing zeros
(progn
(setq old_dimzin (getvar "dimzin"))
;; Turn off bit 8
(setvar "dimzin" (logand old_dimzin (~ 8)))
(setq a (rtos val))
;; Turn on bit 8
(setvar "dimzin" (logior old_dimzin 8))
(setq b (rtos val units 15))
;; Restore dimzin
(setvar "dimzin" old_dimzin)
;; Fuzz factor used in equality check.
(if (equal (distof a) (distof b) 0.000001) a b)
)
)
)
;;;
;;; Returns angle val with the any trailing zeros beyond the current
;;; setting of luprec removed.
;;;
(defun ai_angtos(val / a b old_dimzin)
(setq old_dimzin (getvar "dimzin"))
;; Turn off bit 8
(setvar "dimzin" (logand old_dimzin (~ 8)))
(setq a (angtos val))
;; Turn on bit 8
(setvar "dimzin" (logior old_dimzin 8))
(setq b (angtos val (getvar "aunits") 15))
;; Restore dimzin
(setvar "dimzin" old_dimzin)
;; Fuzz factor used in equality check. Reminder a & b are radians.
(if (equal (angtof a) (angtof b) 0.00000001) a b)
)
;;;
;;; When passed a selection set, (ai_ssget) removes objects on locked
;;; layers from the returned selection set. Nil is returned if all objects
;;; in the selection set are locked.
;;;
(defun ai_ssget(ss / start_size end_size a diff)
(setq start_size (sslength ss))
(setq a 0)
(while (< a (sslength ss))
(if (ai_entity_locked (ssname ss a) 0)
(ssdel (ssname ss a) ss)
(setq a (1+ a)) ; Only increment if non-deleted item.
)
)
(setq end_size (sslength ss))
(if (/= 0 (setq diff (- start_size end_size)))
(princ (strcat "\n" (itoa diff) " objects(s) on a locked layer."))
)
(if (> (sslength ss) 0)
ss
nil
)
)
;;;
;;; Returns T if passed ename is on a locked layer.
;;;
(defun ai_entity_locked (ename message)
(if (= 4 (logand 4 (cdr (assoc 70
(tblsearch "layer" (cdr (assoc 8 (entget ename))))
))))
(progn
(if (= 1 message)
(princ "\n1 object on a locked layer. ")
)
T
)
nil
)
)
;;; Integers in AutoLISP are 32-bit values. However, when integers
;;; are transferred between AutoLISP and AutoCAD, they are restricted
;;; to 16-bit values (+32767 to -32768). (sslength) returns real
;;; numbers when the number of entities exceeds 32767, and subsequent
;;; use of a variable expected to contain an int that actually contains
;;; a real causes those functions to fail ((ssname) for instance.)
;;;
;;; This wrapper ensures that the returned number is an int. LTK, 1.96
(defun ai_sslength (ss)
(if ss
(fix (sslength ss))
0
)
)
;;;
;;; Set CMDECHO without undo recording
;;;
;;; This is useful for LISP defined commands that use UNDO grouping
;;; so that a single undo group is recorded in the undo/redo history
;;; Otherwise, the setting of the CMDECHO value may result in an
;;; additional "Group of Commands" entry in the undo/redo history.
;;;
(defun ai_setCmdEcho ( newVal / _oldEnvVal)
; Only do it if the value is different than the current value
(if (/= newVal (getvar "CMDECHO"))
(progn
(setq _oldEnvVal (getenv "acedChangeCmdEchoWithoutUndo"))
; If not set yet, use 0 for default
(if (not _oldEnvVal)
(setq _oldEnvVal "0"))
(setenv "acedChangeCmdEchoWithoutUndo" "1")
(setvar "cmdecho" newVal)
(setenv "acedChangeCmdEchoWithoutUndo" _oldEnvVal)
)
)
)
;;;Clean loading of ai_utils.lsp
(princ)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -