home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 v2.4 Fix / W95-v2.4fix.iso / ACADWIN / SUPPORT / AI_UTILS.LSP < prev    next >
Encoding:
Lisp/Scheme  |  1995-02-08  |  18.6 KB  |  636 lines

  1. ; Next available MSG number is    20 
  2. ; MODULE_ID AI_UTILS_LSP_
  3. ;;;----------------------------------------------------------------------------
  4. ;;;
  5. ;;;    ai_utils.lsp
  6. ;;;    
  7. ;;;    Copyright (C) 1992, 1994 by Autodesk, Inc.
  8. ;;;
  9. ;;;    Permission to use, copy, modify, and distribute this software
  10. ;;;    for any purpose and without fee is hereby granted, provided
  11. ;;;    that the above copyright notice appears in all copies and
  12. ;;;    that both that copyright notice and the limited warranty and
  13. ;;;    restricted rights notice below appear in all supporting
  14. ;;;    documentation.
  15. ;;;
  16. ;;;    AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
  17. ;;;    AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
  18. ;;;    MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
  19. ;;;    DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
  20. ;;;    UNINTERRUPTED OR ERROR FREE.
  21. ;;;
  22. ;;;    Use, duplication, or disclosure by the U.S. Government is subject to
  23. ;;;    restrictions set forth in FAR 52.227-19 (Commercial Computer
  24. ;;;    Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) 
  25. ;;;    (Rights in Technical Data and Computer Software), as applicable.
  26. ;;;
  27. ;;;.
  28. ;;;
  29. ;;;----------------------------------------------------------------------------
  30. ;;; (ai_abort <appname> [<error message>] )
  31. ;;;
  32. ;;; Displays critical error message in alert box and terminates all
  33. ;;; running applications.
  34. ;;;
  35. ;;; If <errmsg> is nil, no alert box or error message is displayed.
  36.  
  37.   (defun ai_abort (app msg)
  38.      (defun *error* (s)
  39.         (if old_error (setq *error* old_error))
  40.         (princ)
  41.      )
  42.      (if msg
  43.        (alert (strcat " Error en la aplicaci≤n: "
  44.                       app
  45.                       " \n\n  "
  46.                       msg
  47.                       "  \n"
  48.               )
  49.        )
  50.      )
  51.      (exit)
  52.   )
  53.  
  54.  
  55. (defun ai_return (value) value)  ; Make act of returning value explicit
  56.  
  57. ;;; Beep function conditional on user-preferred setting.
  58.  
  59.     (defun ai_beep ( / f)
  60.        (write-line "\007" (setq f (open ;|MSG0|;"CON" "w")))
  61.        (setq f (close f))
  62.     )
  63.  
  64. ;;; (ai_alert <message> )
  65. ;;;
  66. ;;; Shell for (alert)
  67.  
  68.     (defun ai_alert (msg)
  69.        (if ai_beep? (ai_beep))
  70.        (alert (strcat " " msg "  "))
  71.     )
  72.  
  73. ;;;  (ai_acadapp)
  74. ;;;
  75. ;;;  Check to see if acadapp is loaded (and load if necessary).
  76. ;;;
  77. ;;;  If ACADAPP is not loaded, then display a message indicating
  78. ;;;  such in an alert box, and return NIL to the caller.  This
  79. ;;;  function does not generate an error condition, so if that is
  80. ;;;  appropriate, then the caller must test the result and generate
  81. ;;;  the error condition itself.
  82. ;;;
  83.  
  84. (defun ai_acadapp ( / fname)
  85.    (setq fname (ai_acadapp_fn))
  86.    (cond
  87.       (  (= (type acad_colordlg) 'EXSUBR))              ; it's already loaded.
  88.  
  89.       (  (not (findfile fname))                         ; find it
  90.          (ai_alert (strcat "Imposible encontrar " fname "."))
  91.          (ai_return nil))
  92.  
  93.       (  (eq ;|MSG0|;"failed" (xload fname ;|MSG0|;"failed"))        ; load it
  94.          (ai_alert (strcat "Imposible cargar " fname "."))
  95.          (ai_return nil))
  96.      (t)
  97.    )
  98. )
  99.  
  100. ;;; (ai_acadapp_fn)
  101. ;;;
  102. ;;; This function returns the filename & extension of the ADS
  103. ;;; ACADAPP executable for every platform.
  104.  
  105. ;;; Default filename is "acadapp" (in lower-case).
  106.  
  107. (defun ai_acadapp_fn ( / platform)
  108.    (setq platform (getvar "platform"))
  109.    (cond
  110.       (  (eq platform ;|MSG0|;"Microsoft Windows") ;|MSG0|;"ACADAPP.EXE")
  111.       (  (eq platform ;|MSG0|;"386 DOS Extender")  ;|MSG0|;"ACADAPP.EXP")
  112.       (  (eq platform ;|MSG0|;"Microsoft Windows (Intel) Version 3.10") ;|MSG0|;"ACADAPP.EXE")
  113.  
  114.       ;;;
  115.       ;;; insert other cases as required.
  116.       ;;;
  117.  
  118.       (t ;|MSG0|;"acadapp")             ; Default extension 
  119.    )
  120. )
  121.  
  122. ;;; (ai_table <table name> <bit> )
  123. ;;;
  124. ;;; Returns a list of items in the specified table.  The bit values have the
  125. ;;; following meaning:
  126. ;;;  0  List all items in the specified table.
  127. ;;;  1  Do not list Layer 0 and Linetype CONTINUOUS.
  128. ;;;  2  Do not list anonymous blocks or anonymous groups.
  129. ;;;         A check against the 70 flag for the following bit:
  130. ;;;                  1  anonymous block/group
  131. ;;;  4  Do not list externally dependant items.
  132. ;;;         A check against the 70 flag is made for any of the following 
  133. ;;;         bits, which add up to 48:
  134. ;;;                 16  externally dependant
  135. ;;;                 32  resolved external or dependant
  136. ;;;  8  Do not list Xrefs.
  137. ;;;         A check against the 70 flag for the following bit:
  138. ;;;                  4  external reference
  139. ;;;  16 Add BYBLOCK and BYLAYER items to list.
  140. ;;;
  141. (defun ai_table (table_name bit / tbldata table_list just_name)
  142.   (setq tbldata nil)
  143.   (setq table_list '())
  144.   (setq table_name (xstrcase table_name))
  145.   (while (setq tbldata (tblnext table_name (not tbldata)))
  146.     (setq just_name (cdr (assoc 2 tbldata)))
  147.     (cond 
  148.       ((= "" just_name))               ; Never return null Shape names.
  149.       ((and (= 1 (logand bit 1))
  150.             (or (and (= table_name "LAYER") (= just_name "0"))
  151.                 (and (= table_name "LTYPE")
  152.                      (= just_name "CONTINUOUS")
  153.                 )
  154.             )
  155.       ))
  156.       ((and (= 2 (logand bit 2))
  157.             (= table_name "BLOCK")
  158.             (= 1 (logand 1 (cdr (assoc 70 tbldata))))
  159.       )) 
  160.       ((and (= 4 (logand bit 4))
  161.             ;; Check for Xref dependents only. 
  162.             (zerop (logand 4 (cdr (assoc 70 tbldata)))) 
  163.             (not (zerop (logand 48 (cdr (assoc 70 tbldata)))))
  164.             
  165.       ))
  166.       ((and (= 8 (logand bit 8))
  167.             (not (zerop (logand 4 (cdr (assoc 70 tbldata)))))
  168.       ))
  169.       ;; Vports tables can have similar names, only display one.
  170.       ((member just_name table_list)
  171.       )
  172.       (T (setq table_list (cons just_name table_list)))
  173.     )
  174.   )
  175.   (cond
  176.     ((and (= 16 (logand bit 16))
  177.           (= table_name "LTYPE") ) (setq table_list (cons ;|MSG0|;"BYBLOCK" 
  178.      (cons ;|MSG0|;"BYLAYER" table_list))) ) 
  179.     (t) 
  180.   ) 
  181.   (ai_return table_list) 
  182. )
  183.  
  184. ;;;
  185. ;;; (ai_strtrim <string> )
  186. ;;;
  187. ;;; Trims leading and trailing spaces from strings.
  188. (defun ai_strtrim (s)
  189.   (cond 
  190.     ((/= (type s) 'str) nil)
  191.     (t (ai_strltrim (ai_strrtrim s)))
  192.   )
  193. )
  194. (defun ai_strltrim (s)
  195.   (cond 
  196.     ((eq s "") s)
  197.     ((/= " " (substr s 1 1)) s)
  198.     (t (ai_strltrim (substr s 2)))
  199.   )
  200. )
  201. (defun ai_strrtrim (s)
  202.   (cond 
  203.     ((eq s "") s)
  204.     ((/= " " (substr s (strlen s) 1)) s)
  205.     (t (ai_strrtrim (substr s 1 (1- (strlen s)))))
  206.   )
  207. )
  208.  
  209. ;;;
  210. ;;; Pass a number, an error message, and a range.  If the value is good, it is
  211. ;;; returned, else an error is displayed.  
  212. ;;;  Range values:
  213. ;;;                 0 - any numeric input OK
  214. ;;;                 1 - reject positive
  215. ;;;                 2 - reject negative
  216. ;;;                 4 - reject zero
  217. ;;;                 
  218. (defun ai_num (value error_msg range / good_value)
  219.   (cond
  220.     ;; is it a number
  221.     ((not (setq good_value (distof value)))
  222.       (set_tile ;|MSG0|;"error" error_msg)
  223.       nil
  224.     )
  225.     ;; is it positive
  226.     ((and (= 1 (logand 1 range))
  227.        (= (abs good_value) good_value)
  228.      )
  229.       (set_tile ;|MSG0|;"error" error_msg)
  230.       nil
  231.     )
  232.     ;; is it zero
  233.     ((and (= 2 (logand 2 range))
  234.        (= 0.0 good_value)
  235.      )
  236.       (set_tile ;|MSG0|;"error" error_msg)
  237.       nil
  238.     )
  239.     ;; is it negative
  240.     ((and (= 4 (logand 4 range))
  241.        (/= (abs good_value) good_value)
  242.      )
  243.       (set_tile ;|MSG0|;"error" error_msg)
  244.       nil
  245.     )
  246.     (T good_value)
  247.   )
  248. )
  249.  
  250. ;;;
  251. ;;; Pass an angle and an error message.  If good, the angle is returned else
  252. ;;; nil and an error message displayed.
  253. ;;;
  254. (defun ai_angle(value error_msg / good_value)
  255.   (cond
  256.     ((and (setq good_value (angtof value))
  257.      )
  258.       (set_tile ;|MSG0|;"error" "")
  259.       (atof (angtos good_value))
  260.     )
  261.     (T (set_tile ;|MSG0|;"error" error_msg) nil)
  262.   )
  263. )
  264.  
  265. ;;;
  266. ;;;  Error routine.
  267. ;;;
  268. (defun ai_error (s)              ; If an error (such as CTRL-C) occurs
  269.   (if (not (member s '("Funci≤n cancelada" "interrupci≤n desde el teclado")))
  270.     (princ (strcat "\nError: " s))
  271.   )
  272.   (if undo_init (ai_undo_pop))              ; Deal with UNDO
  273.   (if old_error (setq *error* old_error))   ; Restore old *error* handler
  274.   (if old_cmd (setvar "cmdecho" old_cmd))   ; Restore cmdecho value
  275.   (princ)
  276. )
  277.  
  278. ;;;
  279. ;;; Routines that check CMDACTIVE and post an alert if the calling routine
  280. ;;; should not be called in the current CMDACTIVE state.  The calling 
  281. ;;; routine calls (ai_trans) if it can be called transparently or 
  282. ;;; (ai_notrans) if it cannot.
  283. ;;;
  284. ;;;           1 - Ordinary command active.
  285. ;;;           2 - Ordinary and transparent command active.
  286. ;;;           4 - Script file active.
  287. ;;;           8 - Dialogue box active.
  288. ;;;
  289. (defun ai_trans ()
  290.   (if (zerop (logand (getvar "cmdactive") (+ 2 8) ))
  291.     T
  292.     (progn 
  293.       (alert "Imposible solicitar este comando de modo transparente.")
  294.       nil
  295.     )
  296.   )
  297. )
  298.  
  299. (defun ai_transd ()
  300.   (if (zerop (logand (getvar "cmdactive") (+ 2) ))
  301.     T
  302.     (progn 
  303.       (alert "Imposible solicitar este comando de modo transparente.")
  304.       nil
  305.     )
  306.   )
  307. )
  308.  
  309. (defun ai_notrans ()
  310.   (if (zerop (logand (getvar "cmdactive") (+ 1 2 8) ))
  311.     T
  312.     (progn 
  313.       (alert "Imposible solicitar este comando de modo transparente.")
  314.       nil
  315.     )
  316.   )
  317. )
  318.  
  319. ;;; (ai_aselect)
  320. ;;;
  321. ;;; Looks for a current selection set, and returns it if found,
  322. ;;; or throws user into interactive multiple object selection,
  323. ;;; and returns the resulting selection set if one was selected.
  324. ;;;
  325. ;;; Sets the value of ai_seltype to:
  326. ;;;
  327. ;;;    1 = resulting selection set was autoselected
  328. ;;;    2 = resulting selection set was prompted for.
  329.  
  330.    (defun ai_aselect ( / ss)
  331.       (cond
  332.          (  (and (eq 1 (logand 1 (getvar "pickfirst")))
  333.                  (setq ss (ssget ;|MSG0|;"_i")))
  334.             (setq ss (ai_ssget ss))  ;; only if ss exists.
  335.             (setq ai_seltype 1)
  336.             (ai_return ss))
  337.          (  (setq ss (ssget))
  338.             (if ss (setq ss (ai_ssget ss)))
  339.             (setq ai_seltype 2)
  340.             (ai_return ss))
  341.       )
  342.    )
  343.  
  344. ;;; (ai_aselect1 <msg> )
  345. ;;;
  346. ;;; Looks for ONE autoselected entity, or throws the user into
  347. ;;; interactive entity selection (one entity, where a selection
  348. ;;; point is insignificant).  <msg> is the prompt generated if
  349. ;;; interactive selection is invoked.
  350. ;;;
  351. ;;; Sets the value of ai_seltype to:
  352. ;;;
  353. ;;;    1 = resulting entity was autoselected
  354. ;;;    2 = resulting entity was prompted for.
  355.  
  356.  
  357.    (defun ai_aselect1 (msg / ent)
  358.       (cond
  359.          (  (and (eq 1 (logand 1 (getvar "pickfirst")))
  360.                  (setq ent (ssget ;|MSG0|;"_i"))
  361.                  (eq 1 (sslength ent)))
  362.             (setq ai_seltype 1)
  363.             (if (ai_entity_locked (ssname ent 0) 1)
  364.               (ai_return nil)
  365.               (ai_return (ssname ent 0))
  366.             )
  367.          )
  368.          (  (setq ent (entsel msg))
  369.             (if (ai_entity_locked (car ent) 1)
  370.               (setq ent nil)
  371.             )
  372.             (setq ai_seltype 2)
  373.             (ai_return (car ent)))
  374.       )
  375.    )
  376.  
  377. ;;;
  378. ;;; A function that turns on UNDO so that some existing routines will work.
  379. ;;; Do not use with new routines as they should be designed to operate with
  380. ;;; any UNDO setting.
  381. ;;;
  382. (defun ai_undo_on ()
  383.   (setq undo_setting (getvar "undoctl"))
  384.   (cond
  385.     ((= 2 (logand undo_setting 2))     ; Undo is one
  386.       (command "_.undo" "_control" "_all" "_.undo" "_auto" "_off")
  387.     )
  388.     ((/= 1 (logand undo_setting 1))    ; Undo is disabled
  389.       (command "_.undo" "_all" "_.undo" "_auto" "_off")
  390.     )
  391.   )
  392. )
  393.  
  394. ;;;
  395. ;;; Return UNDO to the initial setting.  Do not use with new routines as they 
  396. ;;; should be designed to operate with any UNDO setting.
  397. ;;;
  398. (defun ai_undo_off ()
  399.   (cond 
  400.     ((/= 1 (logand undo_setting 1))
  401.       (command "_.undo" "_control" "_none")
  402.     )
  403.     ((= 2 (logand undo_setting 2))
  404.       (command "_.undo" "_control" "_one")
  405.     )
  406.   )
  407. )
  408.  
  409. ;;;
  410. ;;; UNDO handlers.  When UNDO ALL is enabled, Auto must be turned off and 
  411. ;;; GROUP and END added as needed. 
  412. ;;;
  413. (defun ai_undo_push()
  414.   (setq undo_init (getvar "undoctl"))
  415.   (cond
  416.     ((and (= 1 (logand undo_init 1))   ; enabled
  417.           (/= 2 (logand undo_init 2))  ; not ONE (ie ALL is ON)
  418.           (/= 8 (logand undo_init 8))   ; no GROUP active
  419.      )
  420.       (command "_.undo" "_group")
  421.     )
  422.     (T)
  423.   )  
  424.   ;; If Auto is ON, turn it off.
  425.   (if (= 4 (logand 4 undo_init))
  426.       (command "_.undo" "_auto" "_off")
  427.   )
  428. )
  429.  
  430. ;;;
  431. ;;; Add an END to UNDO and return to initial state.
  432. ;;;
  433. (defun ai_undo_pop()
  434.   (cond 
  435.     ((and (= 1 (logand undo_init 1))   ; enabled
  436.           (/= 2 (logand undo_init 2))  ; not ONE (ie ALL is ON)
  437.           (/= 8 (logand undo_init 8))   ; no GROUP active
  438.      )
  439.       (command "_.undo" "_end")
  440.     )
  441.     (T)
  442.   )  
  443.   ;; If it has been forced off, turn it back on.
  444.   (if (= 4 (logand undo_init 4))
  445.     (command "_.undo" "_auto" "_on")
  446.   )  
  447. )
  448. ;;;
  449. ;;; (get_dcl "FILTER")
  450. ;;;
  451. ;;; Checks for the existence of, and loads the specified .DCL file,
  452. ;;; or aborts with an appropriate error message, causing the initial
  453. ;;; load of the associated application's .LSP file to be aborted as
  454. ;;; well, disabling the application.
  455. ;;;
  456. ;;; If the load is successful, the handle of the .DCL file is then
  457. ;;; added to the ASSOCIATION LIST ai_support, which would have the
  458. ;;; following structure:
  459. ;;;
  460. ;;;
  461. ;;;   (("DCLFILE1" . 1) ("DCLFILE2" . 2)...)
  462. ;;;
  463. ;;; If result of (ai_dcl) is NIL, then .DCL file is not avalable,
  464. ;;; or cannot be loaded (the latter can result from a DCL audit).
  465. ;;;
  466. ;;; Applications that call (ai_dcl) should test its result, and
  467. ;;; terminate or abort if it is nil.  Normal termination rather
  468. ;;; than aborting with an error condition, is desirable if the
  469. ;;; application can be invoked transparently.
  470. ;;;
  471. (defun ai_dcl (dcl_file / dcl_handle)
  472.   (cond
  473.     ;; If the specified .DCL is already loaded then
  474.     ;; just return its handle to the caller.
  475.     ((ai_return (cdr (assoc dcl_file ai_support))))
  476.  
  477.     ;; Otherwise, try to FIND the .DCL file, and display a
  478.     ;; an appropriate message if it can't be located, and
  479.     ;; return Nil to the caller:
  480.     ((not (findfile (strcat dcl_file ;|MSG0|;".dcl")))
  481.       (ai_alert
  482.         (strcat
  483.           "Imposible localizar archivo de definici≤n de cuadros de dißlogo " dcl_file
  484.           ".dcl\n Compruebe el directorio de soporte."))
  485.       (ai_return nil)
  486.     )
  487.     ;; The file has been found.  Now try to load it.  If it
  488.     ;; can't be succesfully loaded, then indicate such, and
  489.     ;; abort the caller:
  490.     ((or (not (setq dcl_handle (load_dialog dcl_file)))
  491.          (> 1 dcl_handle))
  492.       (ai_alert
  493.         (strcat
  494.           "Imposible cargar el archivo de control de cuadros de dißlogo " dcl_file ;|MSG0|;".dcl"
  495.           "\n Compruebe el directorio de soporte."))
  496.       (ai_return nil)
  497.     )
  498.     ;; Otherwise, the file has been loaded, so add it's handle
  499.     ;; to the FILE->HANDLE association list AI_SUPPORT, and
  500.     ;; return the handle to the caller:
  501.     (t (setq ai_support (cons (cons dcl_file dcl_handle) ai_support))
  502.       (ai_return dcl_handle)
  503.     )
  504.   )
  505. )
  506.  
  507. ;;; Enable/Disable the common fields depending on the selection set.
  508. ;;; Layer 1; Color 2; Linetype 4; Linetype Scale 8; Thickness 16;
  509. ;;;
  510. ;;; Used by DDCHPROP and DDMODIFY.
  511. ;;;
  512. (defun ai_common_state (ss_ename / bit_value)
  513.   (setq bit_value 0)
  514.   (setq ss_ename (strcase ss_ename))
  515.   (cond
  516.     ( (member ss_ename '("ARC" "ATTDEF" "CIRCLE" "INSERT" "LINE" "POINT"
  517.                          "POLYLINE" "SHAPE" "SOLID" "TRACE" "TEXT" "XREF"))
  518.       (setq bit_value (logior 1 2 4 8 16))
  519.     )
  520.     ( (member ss_ename '("3DFACE" "DIMENSION" "ELLIPSE" "BODY"
  521.                          "REGION" "3DSOLID" "SPLINE"
  522.                          "XLINE" "TOLERANCE" "LEADER" "RAY"))
  523.       (setq bit_value (logior 1 2 4 8))
  524.     )
  525.     ( (member ss_ename '("VIEWPORT" "MTEXT"))
  526.       (setq bit_value (logior 1 2))
  527.     )
  528.     ( (member ss_ename '("MLINE"))
  529.       (setq bit_value (logior 1 8))
  530.     )
  531.     (T (setq bit_value (logior 1 2 4 8 16)) ; Enable all fields if unknown.
  532.     )
  533.   )
  534.   bit_value                         ; Return bit value of fields.
  535. )
  536.  
  537. ;;;
  538. ;;;
  539. ;;; (ai_helpfile) returns an empty string.  Let the core code figure out 
  540. ;;; the default platform helpfile.
  541. ;;;
  542. (defun ai_helpfile ( / platform)
  543.   ""
  544. )
  545.  
  546. ;;;
  547. ;;; Returns val with the any trailing zeros beyond the current 
  548. ;;; setting of luprec removed.
  549. ;;; 
  550. (defun ai_rtos(val / a b)
  551.   (setq old_dimzin (getvar "dimzin"))
  552.   ;; Turn off bit 8
  553.   (setvar "dimzin" (logand old_dimzin (~ 8)))
  554.   (setq a (rtos val))
  555.   ;; Turn on bit 8
  556.   (setvar "dimzin" (logior old_dimzin 8))
  557.   (setq b (rtos val (getvar "lunits") 15))
  558.   ;; Restore dimzin
  559.   (setvar "dimzin" old_dimzin)
  560.   
  561.   ;; Fuzz factor used in equality check.
  562.   (if (equal (distof a) (distof b) 0.000001)
  563.     a
  564.     b
  565.   )
  566. )
  567.  
  568. ;;;
  569. ;;; Returns angle val with the any trailing zeros beyond the current 
  570. ;;; setting of luprec removed.
  571. ;;; 
  572. (defun ai_angtos(val / a b)
  573.   (setq old_dimzin (getvar "dimzin"))
  574.   ;; Turn off bit 8
  575.   (setvar "dimzin" (logand old_dimzin (~ 8)))
  576.   (setq a (angtos val))
  577.   ;; Turn on bit 8
  578.   (setvar "dimzin" (logior old_dimzin 8))
  579.   (setq b (angtos val (getvar "aunits") 15))
  580.   ;; Restore dimzin
  581.   (setvar "dimzin" old_dimzin)
  582.   
  583.   ;; Fuzz factor used in equality check. Reminder a & b are radians.
  584.   (if (equal (angtof a) (angtof b) 0.00000001)
  585.     a
  586.     b
  587.   )
  588. )
  589.  
  590. ;;;
  591. ;;; When passed a selection set, (ai_ssget) removes objects on locked 
  592. ;;; layers from the returned selection set.  Nil is returned if all objects
  593. ;;; in the selection set are locked.  
  594. ;;;
  595. (defun ai_ssget(ss / start_size end_size a diff)
  596.   (setq start_size (sslength ss))
  597.  
  598.   (setq a 0)
  599.   (while (< a (sslength ss))
  600.     (if (ai_entity_locked (ssname ss a) 0)
  601.       (ssdel (ssname ss a) ss)
  602.       (setq a (1+ a))  ; Only increment if non-deleted item.
  603.     )
  604.   )
  605.  
  606.   (setq end_size (sslength ss))
  607.  
  608.   (if (/= 0 (setq diff (- start_size end_size)))
  609.     (princ (strcat "\n" (itoa diff) " objetos en una capa bloqueada.")) 
  610.   )
  611.   (if (> (sslength ss) 0)
  612.     ss   
  613.     nil
  614.   )
  615. )
  616.  
  617. ;;;
  618. ;;; Returns T if passed ename is on a locked layer. 
  619. ;;;
  620. (defun ai_entity_locked (ename message)
  621.   (if (= 4 (logand 4 (cdr (assoc 70 
  622.                             (tblsearch "layer" (cdr (assoc 8 (entget ename))))
  623.                           ))))
  624.     (progn
  625.       (if (= 1 message)
  626.         (princ "\n1 objeto en una capa bloqueada. ")
  627.       )
  628.       T
  629.     )
  630.     nil
  631.   )
  632. )
  633.  
  634. ;;;Clean loading of ai_utils.lsp
  635. (princ)
  636.