home *** CD-ROM | disk | FTP | other *** search
- From: rurban@x-ray.at (Reini Urban)
- Newsgroups: comp.cad.autocad,alt.cad.autocad,alt.answers,comp.answers,news.answers
- Subject: comp.cad.autocad AutoLISP FAQ (part 2/2) - samples, code
- References: <autolisp-faq-1-1083403804>
- Reply-To: rurban@xarch.tu-graz.ac.at (Reini Urban)
- Followup-To: comp.cad.autocad
- Distribution: world
- Organization: TU Graz-Fac.of Architecture & X-RAY Graz
- Approved: news-answers-request@mit.edu
- Keywords: FAQ, AutoLISP, AutoCAD
- Summary: AutoLISP is a scripting language for AutoCAD, a wellknown CAD
- package. This AutoLISP FAQ is posted to comp.cad.autocad, alt.cad.autocad
- and *.answers monthly.
- NNTP-Posting-Host: oma.graz.inode.at
- Message-ID: <40936e27@e-post.inode.at>
- Date: 1 May 2004 11:30:15 +0200
- X-Trace: e-post.inode.at 1083403815 195.58.172.138 (1 May 2004 11:30:15 +0200)
- Lines: 1318
- Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!news.rediris.es!newsmi-us.news.garr.it!NewsITBone-GARR!news.mailgate.org!newsfeed.stueberl.de!newsfeed.utanet.at!newscore.univie.ac.at!e-post.inode.at!not-for-mail
- Xref: senator-bedfellow.mit.edu comp.cad.autocad:164734 alt.cad.autocad:148003 alt.answers:72709 comp.answers:57014 news.answers:270655
-
- Posted-By: auto-faq 3.2.1.5
- Archive-name: CAD/autolisp-faq/part2
- URL: http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp.html
- Version: 2.28
- Last-modified: 2002-06-25
- Posted-By: Reini Urban <rurban@x-ray.at>
- Posting-Frequency: monthly
- Copyright: see Appendix [A]
-
- Welcome to the comp.cad.autocad AutoLISP FAQ
- by Reini Urban <rurban@x-ray.at>
-
- AutoLISP is a scripting language for AutoCAD, a well known CAD package.
- This AutoLISP FAQ is posted to comp.cad.autocad, alt.cad.autocad and
- the *.answers groups monthly. Some AutoCAD FAQ's are at
- http://www.autodesk.com/support/autocad/ but not posted to
- comp.cad.autocad. The contents and the samples apply to all
- releases of AutoLISP since Release 10, including Visual Lisp, Vital Lisp
- and ACOMP. There's no special AutoLISP newsgroup.
- Best are comp.cad.autocad and autodesk.autocad.customization,
- but please don't bother comp.lang.lisp.
- Source code of all functions in this FAQ is in FAQ-CODE.LSP
- (for location see [A.1]), there's also a Winhelp file.
- Thanks to all who have contributed. Corrections and contributions
- always welcome.
- Please see http://xarch.tu-graz.ac.at/acadwiki/RulesToLiveBy
-
- This is part 2/2 of the AutoLISP FAQ v2.28, which consists of:
-
- AutoLISP FAQ (part 1/2) - General
- AutoLISP FAQ (part 2/2) - Samples, code
-
- | changes, + new in items from this version to the last posted version,
- intermediate personal comments and uncertainties in <..>
-
- -----------------
- Table of Contents
- -----------------
- part 1: General
- [0] The Future of AutoLISP? Should I learn it or VB instead?
- [0.1] What changed with AutoCAD 2000?
- [0.2] We cannot create ARX anymore?
- [1] Where can I find AutoLISP routines on the Internet?
- [1.1] Are the comp.cad.autocad articles stored somewhere?
- [1.2] Autodesk's SDK
- [2] What are the best books to learn AutoLISP?
- [2.1] Online AutoLISP documents, Winhelp [deleted]
- [2.2] AutoLISP Coding Style
- [3] How do I debug AutoLISP programs?
- [3.1] Native AutoLISP debuggers
- [3.2] Modular style, TRACE
- [3.3] BREAK function, debug-print
- [4] How can I protect my AutoLISP programs? Security
- [4.1] Kelvinate
- [4.2] Protect
- [4.3] Kelvinate and Protect
- [4.4] Convert
- [4.5] ACOMP
- [4.7] Lisp2C
- [4.6] Vital LISP Professional
- [4.8] Visual Lisp by Autodesk
- [5] AutoLISP compilers
- [5.1] ACOMP
- [5.2] Vital LISP Professional
- [5.3] Visual Lisp by Autodesk
- [5.4] Better ones: Common Lisp and Scheme
- [6] AutoLISP editors and other tools
- [6.1] AutoLISP editors
- [6.2] Analyzers, Packager and Parenthesis checkers
- [6.3] Pretty Printers
- [7] AutoLISP problems and bugs
- [8] Sorting with AutoLISP
- [9] Recursion
- [10] Iteration with MAPCAR,...
- | [11] S::STARTUP, My LISPs aren't loading at startup anymore
- [12] How to AUTOLOAD my programs?
- [13] How can I pass a variable number of
- arguments to a LISP function?
- | [14] How can I avoid stack overflows?
- [15] (command "ROTATE3D") does not work! Why?
- [16] Lisp programs operating over multiple drawings
- [17] How to export Visual Lisp functions to AutoLISP/AutoCAD?
- --
- [A] Disclaimer, Notes from the authors
- [A.1] FAQ Locations
-
- part 2: Samples, code
- [20] General Helper functions
- [20.1] List manipulation
- [20.2] String manipulation
- [20.3] symbol->string
- [20.4] AutoCAD entity access
- [21] Sample Lisp programs
- [21.1] Globally change text, polylines, layer utils, date stamp
- [21.2] Plot dialog from within LISP. Using DDE or ActiveX
- [21.3] (entmod),(entmake) Layers, without (command "_LAYER"...)
- [21.4] How to select multiple files in LISP? (as in FILES-Unlock)
- [21.5] Replace multiple blocks
- [21.6] (vports), VIEWPORT entity, pixel conversion
- [21.7] Select all visible objects: zoom coordinates
- [21.8] How to write XYZ data of selected objects to a file?
- [22] Block Attributes
- [22.1] How to access block attributes?
- [22.2] How to MODIFY block attributes? DATESTAMP.LSP
- [22.3] How to UPDATE block attributes?
- [22.4] How to ENTMAKE a Block Complex Entity in AutoLISP
- [23] Polylines
- [23.1] How to access polyline VERTICES?
- [23.2] How to JOIN multiple lines to polylines?
- [23.3] Change WIDTH of multiple polylines
- [23.4] Create a polyline or spline: with (ENTMAKE) or (COMMAND)
- [23.5] How to calculate the LENGTH of polylines?
- [23.6] How to revert the polyline direction?
- [23.7] How to get the CENTER of a polyline?
- [24] Circle/Arc Geometry: BULGE conversion, some trigonometry
- [25] DCL: listboxes with tabs or monotext font
- [26] EED Extended Entity Data: Get and Store
- [26.1] Select objects on their EED with (ssget "X")
- [26.2] Get EED from an object
- [27] How to break a command in LISP?
- [27.1] How to do an unlimited number user prompts?
- [28] How to decode ACIS internal geometry with LISP
- --
- [A] Disclaimer, Notes from the author
- + [A.1] FAQ Locations
- [B] Acknowledgements
- [C] Recent Changes
-
- ----------------------------------------------------------------------
-
- Subject: [20] General helper functions
-
- For more general AutoLISP functions please see the AutoLISP Standard
- Library at http://xarch.tu-graz.ac.at/autocad/stdlib/
- Other code is also available at some AutoLISP sites [1] or included in
- the SDK's by AutoDESK [1.2]
-
- I included here some very useful helper functions for shorter
- samples in answers on the net.
- You could rely on the fact that these functions are in common
- knowledge such as the famous dxf function, which is defined as
- (defun dxf (grp ele) (cdr (assoc grp ele))) and the specific
- counterpart (getval) which works with either an ename or entget list.
-
- [20.1] List manipulation
-
- See also http://xarch.tu-graz.ac.at/autocad/stdlib/STDLIST.LSP
- Useful sample functions for *list manipulation* are:
-
- ;;; a not empty list?
- (defun CONSP (x) (and x (listp x)))
-
- ;;; returns the index of the first element in the list,
- ;;; base 0, or nil if not found
- ;;; (position 'x '(a b c)) -> nil, (position 'b '(a b c d)) -> 1
- (defun POSITION (x lst / ret)
- (if (not (zerop (setq ret (length (member x lst)))))
- (- (length lst) ret)))
-
- ;;; Removes an item from a list (double elements allowed)
- ;;; (remove 0 '(0 1 2 3 0)) -> (1 2 3)
- (defun REMOVE (ele lst) ; by Serge Volkov
- (apply 'append (subst nil (list ele) (mapcar 'list lst))))
-
- ;;; Conditional remove from flat list,
- ;;; pred requires exactly 1 arg
- ;;; (remove-if 'zerop '(0 1 2 3 0)) -> (1 2 3)
- ;;; (remove-if 'numberp '(0 (0 1) "")) -> ((0 1) "")
- (defun REMOVE-IF (pred from)
- (cond
- ((atom from) from) ;nil or symbol (return that)
- ((apply pred (list (car from))) (remove-if pred (cdr from)))
- (t (cons (car from) (remove-if pred (cdr from))))
- )
- )
-
- ;;; Keeps all elements to which the predicate applies
- ;;; Say: "keep if", it need not be defined recursively, also like this.
- ;;; [fixed, thanks to Serge Pashkov, in FAQ-CODE.LSP it was okay]
- (defun REMOVE-IF-NOT (pred lst) ; by Vladimir Nesterowsky
- (apply 'append
- (mapcar '(lambda (e)
- (if (apply pred (list e)) (list e))) lst)))
-
- ;;; Conses ele to list if not already in list
- ;;; Trick: Accepts quoted lists too, such as
- ;;; (setq l '(1 2 3) (adjoin 0 'l)
- ;;; -> !l (0 1 2 3)
- (defun ADJOIN (ele lst / tmp)
- (if (= (type lst) 'SYM) (setq tmp lst lst (eval tmp)))
- (setq lst (cond ((member ele lst) lst)
- (t (cons ele lst))))
- (if tmp (set tmp lst) lst)
- )
-
- ;;; put the first element to the end, simple version
- ;;; ("rotate by one")
- (defun ROT1 (lst) (append (cdr lst) (list (car lst))))
-
- ;;; the list without the last element
- (defun BUTLAST (lst)
- (reverse (cdr (reverse lst))))
-
- ------------------------------
-
- [20.2] String manipulation
-
- Please check http://xarch.tu-graz.ac.at/autocad/stdlib/STDSTR.LSP
- Some useful *string functions* would be:
-
- Predicates:
- (stringp expr) - string predicate, is expr a string?
- (defun stringp (s) (= (type s) 'STR))
-
- (string-not-emptyp str) - is str a not empty string?
- (defun string-not-emptyp (s) (and (stringp s) (/= s "")))
-
- Trimming:
- (str-trim string) - str without any whitespace, to the right
- and left, defined in AI_UTILS.LSP as well as
- (str-left-trim string), (str-right-trim string)
-
- (str-left-trim-bag string bag), (str-right-trim-bag string bag)
- - remove all chars in bag (=STR)
- Search:
- (strpos string substr) - position of substring in string (1 based)
-
- Parsing and gathering functions, (list<->string):
- (strtok str tokens) - string -> list delimited by tokens (SDK2)
- (strlcat lst delim) - concat list -> string seperated by delim
-
- (string->list str) - string -> list of chars
- (list->string lst) - list of chars -> string
-
- All of them and much more are in the Stdlib (see above).
- Some are at http://xarch.tu-graz.ac.at/autocad/code/vnestr/strtok.lsp
- or in your AI_UTILS.LSP. You'll need them esp. for DCL functions.
-
- ------------------------------
-
- [20.3] symbol->string
-
- The inverse function to (read) would be (symbol-name). The following
- is the only general way, but there exist better special methods.
-
- ;;; SYMBOL-NAME - returns the name of a symbol as string
- ;;; converts any valid lisp expression to its printed representation
- ;;; (symbol-name a) -> "a", (symbol-name '(0 1 2 a)) -> "(0 1 2 A)"
- (defun SYMBOL-NAME (sym / f str tmp)
- (setq tmp "$sym.tmp") ;temp. filename, should be deleted
- (setq f (open tmp "w"))(princ sym f) (close f)
- (setq f (open tmp "r") str (read-line f) f (close f))
- str)
-
- For plain symbols exists a better trick explained by Christoph
- Candido at http://xarch.tu-graz.ac.at/autocad/news/symbol-string.txt
- Vill/VLISP introduced a fast vl-symbol-name.
- See also http://xarch.tu-graz.ac.at/autocad/stdlib/STDINIT.LSP
-
- ------------------------------
-
- [20.4] AutoCAD entity access [renamed SSAPPLY to SSMAP]
-
- See also http://xarch.tu-graz.ac.at/autocad/stdlib/STDENT.LSP
-
- ;;; returns the first group value of an entity.
- ;;; like the wellknown (dxf) function but accepts all kinds of
- ;;; entity representations (ename, entget list, entsel list)
- ;;; NOTE: For getting 10 groups in LWPOLYLINE's not usable!
- (defun GETVAL (grp ele) ;"dxf value" of any ent...
- (cond ((= (type ele) 'ENAME) ;ENAME
- (cdr (assoc grp (entget ele))))
- ((not ele) nil) ;empty value
- ((not (listp ele)) nil) ;invalid ele
- ((= (type (car ele)) 'ENAME) ;entsel-list
- (cdr (assoc grp (entget (car ele)))))
- (T (cdr (assoc grp ele))))) ;entget-list
-
- ;;; Ex: (gettyp pline) => "POLYLINE"
- (defun GETTYP (ele) ;return type
- (getval 0 ele))
-
- ;;; assure ENAME
- ;;; convert the entity to type ENAME (to write shorter code)
- (defun ENTITY (ele) ;convert to element name
- (cond ;accepts the following types:
- ((= (type ele) 'ENAME) ele) ; ENAME
- ((not (listp ele)) nil) ; error: no list
- ((= (type (car ele)) 'ENAME) (car ele)) ; entsel-list
- ((cdr (assoc -1 ele))) ; entget-list or nil
- )
- )
- ;and now just:
- (defun getval (grp ele) (cdr (assoc grp (entget (entity ele)))))
-
- ;;; Ex: (istypep ele "TEXT")
- ;;; is element a "SOLID"?
- (defun istypep (ele typ) ;check type
- (= (gettyp ele) typ))
-
- ;;; Ex: (istypep ele '("TEXT" "ATTDEF"))
- ;;; is element a "TEXT" or a "ATTDEF"?
- (defun ISTYPEP (ele typ) ;better implementation to accept lists too
- (cond
- ((listp typ) (member (gettyp ele) typ)) ;bugfixed
- ((stringp typ) (= (gettyp ele) typ)) ;assume typ uppercase
- (T nil)))
-
- ;;; Ex: (getpt (entsel)) => ( 0.1 10.0 24)
- (defun GETPT (ele) ;return the startpoint of any element
- (getval 10 ele)) ;group 10
-
- ;;; Ex: (getflag pline) => 1 if closed
- (defun GETFLAG (ele) (getval 70 ele)) ;same with the entity flag
-
- ;;; bitvalue val in flag of element set?
- ;;; Ex: (flagsetp 1 pline) => T if closed
- ;;; Ex: (flagsetp 16 vertex) => T if spline control point
- (defun FLAGSETP (val ele)
- (bitsetp val (getflag ele)))
-
- ;;; Ex: (bitsetp 4 12) => T ;bitvalue 4 (=2.Bit) in 12 (=4+8) is set
- (defun BITSETP (val flag)
- (= (logand val flag) val))
-
- ;;; convert selection set to list,
- ;;; Note: it's also wise to use ai_ssget, because some ents could be
- ;;; on locked layers
- ;;; Ex: (sslist (ai_ssget (ssget))) => list of selected unlocked ents
- ;;; or (mapcar 'entupd (sslist (ssget "X" '((8 . "TEMP")))))
- ;;; - regens all entities on layer TEMP
- (defun SSLIST (ss / n lst)
- (if (= (type ss) 'PICKSET)
- (repeat (setq n (sslength ss))
- (setq n (1- n)
- lst (cons (ssname ss n) lst)))))
-
- ;;; apply a function to each ent in ss, in reversed order
- ;;; Faster, but not so easy to understand. see [22.2]
- ;;; [renamed from SSAPPLY to SSMAP to match the stdlib name]
- ;;; Ex: (ssmap 'entupd (ssget)) ; regenerate only some entities
- (defun SSMAP (fun ss / n)
- (if (= 'PICKSET (type ss))
- (repeat (setq n (sslength ss))
- (apply fun (list (ssname ss (setq n (1- n))))))))
-
- ------------------------------
-
- Subject: [21] Sample Lisp Programs:
-
- [21.1] Globally change texts, polylines, layer utils, datestamp
-
- For globally changing text attributes use CHTEXT.LSP in your
- sample directory.
-
- For globally changing polyline attributes, freeze layers by pick
- and other similar tasks search for free lisp tools at any AutoLISP
- site. See "[1]" and some code at "[22]","[23]","[24]"
-
- For putting a datestamp and others onto your plots automatically
- first check out if your plotter supports HPGL/2. Then use the
- internal HPGL/2 driver and configure the datestamp in HPCONFIG.
-
- DATESTAMP.LSP: Change the plot header attributes by yourself
- as in [22.2]. A profi plotstamp routine is here:
- http://ourworld.compuserve.com/homepages/tonyt/plotstmp.htm
-
- ------------------------------
-
- [21.2] Plot dialog from within Lisp. Using DDE or ActiveX or initdia
-
- (initdia)(command "_PLOT")
-
- Calling the PLOT dialogbox from AutoLISP *before R14* was possible
- only under Windows i.e. with LISPPLOT by Mike Dickason. This fed
- the keyboard buffer with keystrokes.
- http://www.cadalog.com/ files/lispd-l/lspplw.zip
- or also: ftp://ftp.mcwi.com/pub/mcwi/lisp/winplt.lsp
- Otherwise create a script and call this at the end of your lisp, but
- this will not show up the dialogbox.
-
- Xiang Zhu: You could have used "DDELISP" under Windows. [shortened]
- ;;; [fixed for all releases]
- (defun DDECMD (str / tmp acadver ddestr)
- (if (not (boundp 'initiate))
- (cond
- ((= 14 (setq acadver (atoi (getvar "ACADVER"))))
- (setq ddestr "AutoCAD.R14.DDE") (arxload "ddelisp"))
- ((= 13 acadver)
- (setq ddestr "autocad.r13.dde") (xload "ddelisp"))
- ((= 12 acadver)
- (setq ddestr "autocad.dde") (xload "ddelisp"))
- (T (princ "DDE not supported")(exit))))
- (if (not (zerop (setq tmp (initiate ddestr "system"))))
- (progn
- (execute tmp (strcat "[" str "]"))
- (terminate tmp)
- str)))
- (ddecmd "_plot ") ; return would be "^13"
-
- Beware that Acad accepts only DDE commands if the command line is
- active, that means no dialogbox must be open.
-
- With vlisp/ViLL ActiveX methods can be used to plot, but the
- dialog can not be called:
-
- ;;; vlisp syntax:
- (setq vlax:ActiveDocument (vla-get-ActiveDocument
- (vlax-get-Acad-Object)))
- (setq plt (vla-get-plot vlax:ActiveDocument)) ;=> plot object
- (vla-PlotWindow plt pt1 pt2) ;WCS pts
- (vla-PlotPreview plt 1) ;0; partial, 1: full
- (vla-PlotToDevice plt "Default System Printer") ;if it exists
-
- With R14 INITDIA was introduced, which can be applied to most but not
- all dialogs:
- (initdia)(command "_PLOT")
-
- With A2000 use OLE (VLA- methods) instead of DDE. DDE support is
- discontinued by Microsoft. OLE provides a better object-oriented
- interface.
-
- ------------------------------
-
- [21.3] (entmod) and (entmake) Layers, without (command "_LAYER"...)
-
- ENTMOD a layer
- I try to change a layer property without calling COMMAND function
- inside a lisp routine.
-
- Since R13, using the following lisp
- (setq tbl_lst (entget (tblobjname "LAYER" "ANY_LAYER"))
- clr_grp (assoc 62 tbl_lst)
- )
- (entmod (subst (cons 62 (- (cdr clr_grp))) clr_grp tbl_lst))
- you can toggle "ANY_LAYER" On or Off, even it is the current layer.
-
- But AutoCAD doesn't know a table entry has been changed until you
- click the Layer Control on the toolbar or something similar.
- Besides, you can issue 'DDLMODES to see On/OFf property of
- "ANY_LAYER" changed.
- Doing the same way to freeze a layer, you will still see entities on
- that layer shown on screen, but you can not select them, until you do
- something related to layer settings, and AutoCAD will hide those
- entities.
-
- ENTMAKE a layer
- You must get your pattern with entget, using the table object name as
- argument. This table object name can be retrieved with the TBLOBJNAME
- function:
- (entget (tblobjname "LAYER" "Any Layer Name")) ; R2000 can have spaces!
-
- ;;; This routine will create a layer with any name you type:
- (defun C:MLAY () ; by Reinaldo Togores <rtogores@mundivia.es>
- (setq laynam (getstring "\nLayer name: "))
- (entmake
- (list
- '(0 . "LAYER")
- '(5 . "28")
- '(100 . "AcDbSymbolTableRecord")
- '(100 . "AcDbLayerTableRecord")
- (cons 2 laynam)
- '(70 . 64)
- '(62 . 7)
- '(6 . "CONTINUOUS")
- )))
-
- ------------------------------
-
- [21.4] How to select multiple files in Lisp? (as in FILES - Unlock) [new]
-
- * DOSLIB v4.3 from McNeel contains dos_getfilem,
- http://www.mcneel.com/products.htm#Utilities
- * STDLIB contains std-getfilem
- http://xarch.tu-graz.ac.at/autocad/stdlib/GETFILEM.LSP
- * At http://xarch.tu-graz.ac.at/autocad/progs/MGETFILD.ZIP
- is another lisp helper routine to select multiple files with DCL.
- You will also need VLISP, DOSLIB or the STDLIB to access the
- directory functions. Another lisp version is at
- http://xarch.tu-graz.ac.at/autocad/stdlib/Reini_MFD.LSP
-
- ------------------------------
-
- [21.5] Replace multiple blocks
-
- A search at the lisp archives yielded those hits:
- Cadalyst: http://www.cadonline.com/search.phtml
- => 97code.htm and a question for your username which can be obtained
- free and automatically
- or xarch: http://xarch.tu-graz.ac.at/autocad/code and search for
- "BLOCK;REPLACE"
- => http://xarch.tu-graz.ac.at/autocad/code/cadalyst/94-02/replace.lsp
- also at the Cadalog:
- http://www.cadalog.com/ OpenSource Freeware Keyword: "Block Replace"
- => replace.zip (this one is the best)
-
- ------------------------------
-
- [21.6] (vports), VIEWPORT entity, pixel conversion
-
- VIEWPORT entity:
- The answer to "I can do an (entget) on a VIEWPORT and get its lower
- left (DXF group 10) and upper right (DXF group 11) corner. But it
- appears that these coordinates are in the paper space system. What
- I'm interested in finding out is what portion of the "real" drawing
- (the model space drawing) are currently shown in that viewport."
- is at http://xarch.tu-graz.ac.at/autocad/news/vports.lsp
-
- http://www.ez-sys.net/~coopfra/lisp.htm#view has also some tricks.
-
- How to change viewports in AutoLISP?
- with (setvar "CVPORT" vport-id)
- see http://xarch.tu-graz.ac.at/autocad/news/change_vports.html
-
- With the following functions you convert pixel<->drawing units:
-
- ;;; Conversion pixel to drawing units
- (defun PIX2UNITS (pix)
- (* pix (/ (getvar "VIEWSIZE") (cadr (getvar "SCREENSIZE")))))
-
- ;;; Conversion drawing units to pixel
- (defun UNITS2PIX (units)
- (* units (/ (cadr (getvar "SCREENSIZE"))(getvar "VIEWSIZE"))))
-
- Note also the "Pixel Off by One" Errors in AutoCAD, written by Vibrant
- http://xarch.tu-graz.ac.at/autocad/news/pixel-off-by-one-error.txt
-
- ------------------------------
-
- [21.7] Select all visible objects: zoom coordinates
-
- Beware that with (ssget) you will only get visible objects, because
- all interface functions (entsel,ssget,osnap) work with pixel, only
- (ssget "X") will select not visible objects.
-
- ;;; returns a list of the actual viewport corners in WCS
- (defun ZOOMPTS ( / ctr h screen ratio size size_2)
- (setq ctr (xy-of (getvar "VIEWCTR")) ;3D -> 2D
- h (getvar "VIEWSIZE") ;real
- screen (getvar "SCREENSIZE") ;2D: Pixel x,y
- ratio (/ (float (car screen)) ;aspect ratio
- (cadr screen))
- size (list (* h ratio) h) ;screensize in coords
- size_2 (mapcar '/ size '(2.0 2.0)))
- (list (mapcar '- ctr size_2)
- (mapcar '+ ctr size_2)))
- (defun XY-OF (pt) (list (car pt)(cadr pt))) ;assure 2D coords
-
- Note: The points returned are in WCS but this is ok, because the
- "CP" "WP" and "P" options of ssget expect WCS points.
- "W" and "C" require UCS points - why the difference I don't know.
-
- ;;; one way to define this function
- (defun SSALL-VISIBLE (/ l)
- (ssget "C" (car (setq l (maptrans0-1 (zoompts)))) (cadr l)))
- ;;; or another
- (defun SSALL-VISIBLE-1 () ;combine "C" and (p1 p2) to one list
- (apply 'ssget (append '("C") (maptrans0-1 (zoompts)))))
-
- ;;; map some pts from WCS to UCS, easier with just one argument
- (defun MAPTRANS0-1 (pts) (mapcar '(lambda (pt)(trans pt 0 1)) pts))
-
- ------------------------------
-
- Subject: [21.8] How to write XYZ data of selected objects to a file?
-
- ;;; CDF - comma delimited string
- (defun CDF-POINT (pt)
- (strcat (car pt) ", " (cadr pt) ", " (caddr pt)))
- ;;; SDF - space delimited, may easier be read back in to AutoCAD
- (defun SDF-POINT (pt)
- (strcat (car pt) " " (cadr pt) " " (caddr pt)))
- ;;; convert this SDF format back to a point with
- (defun STR->POINT (s)
- (eval (read (strcat "(" s ")"))))
-
- ;;; Write a XYZ file of all selected objects (SDF see below)
- (defun C:XYZ (/ ss fname f)
- (if (and (setq ss (ssget))
- (setq fname (getfiled "Write XYZ to file"
- (strcat (getvar "DWGNAME") ".XYZ") "XYZ" 7))
- (setq f (open fname "w")))
- (foreach ele (sslist ss) ; -> [20.4]
- (foreach pt (getpts ele) ; -> [23.1]
- (write-line (cdf-point pt) f))))
- (if f (close f)))
-
- ;;; => <fname>.xyz
- ;;; 0.45, 12.3, -34.0
-
- For a ASC file (SDF-format) simply change all XYZ to ASC
- and cdf-point to sdf-point above.
-
- For the other way 'round, creating PLINES from a ascii x,y file
- best convert the file to a script like:
- PLINE
- 300.2,10
- 350.4,10.4
-
- ------------------------------
-
- Subject: [22] Block Attributes
-
- [22.1] How to access block attributes?
-
- Check all subentities after the INSERT until the attribute is found.
- See http://xarch.tu-graz.ac.at/autocad/stdlib/STDENT.LSP
-
- ;;; returns entget-list of attribute attname (STRING) in element ele
- ;;; or nil if not found
- (defun ATTELE (ele attname / rslt)
- (if (and (istypep ele "INSERT")
- (= (getval 66 ele) 1))
- (progn
- (setq ele (entnext (entity ele)))
- (while (istypep ele "ATTRIB")
- (if (= (strcase (getval 2 ele)) (strcase attname))
- (setq rslt (entget ele) ele nil) ;break the loop
- (setq ele (entnext ele))))))
- rslt
- )
-
- ;;;Example:
- (attele (entsel) "TEST") ; returns entget-list of
- ; attribute "TEST" if the block has it
-
- BTW: Even trickier functions to get entities DXF group codes are
- GET and EDLGETENT by Vladimir Nesterowsky.
- ;;;Sample calls:
- ;;; return list of 2,1 and -1 group values
- (defun GET-ATTRIBS-LOOK-UP (block-ename)
- (get '(2 1 -1) (cdr (edlgetent block-ename))))
-
- (defun ALL-VERTICES-AND-BULGES (pline-ename)
- (get '(10 42) (cdr (edlgetent pline-ename))))
-
- available at http://members.tripod.com/~vnestr/
-
- ------------------------------
-
- [22.2] How to MODIFY block attributes? DATESTAMP.LSP
-
- For a very simple DATESTAMP.LSP simply entmod the entget-list
- of the DATE attribute in your plotstamp block, retrieved from
- (attele) as above.
-
- ;;; change the attribute value of INSERT ele to new (group 1)
- (defun ATTCHG (ele attname new / b)
- (if (setq b (attele ele attname))
- (entmod (subst (cons 1 new) (getval 1 b) b))))
-
- ;;; Change all DATESTAMP attributes in all inserted PLOT* blocks
- (defun C:DATESTAMP ()
- (ssmap ;fixed by Alan Williams, wrong arg order
- '(lambda (ele)
- (attchg ele "DATESTAMP" (today))
- (entupd ele)
- )
- (ssget "X" '((0 . "INSERT")(2 . "PLOT*")))))
- ;;;return todays date, could be a DIESEL or this string conversion
- (defun TODAY (/ s)
- (setq s (rtos (getvar "CDATE") 2)) ;gets the julian date
- (strcat (substr s 5 2) "-" (substr s 7 2)"-"(substr s 3 2)))
-
- Automatic datestamps are normally done with either RTEXT
- (bonus/express tools) or HPCONFIG with a HPGL/2 plotter. (<a2000i)
-
- ------------------------------
-
- [22.3] How to UPDATE block attributes?
-
- There exists a support/ATTREDEF.LSP to update attribute properties
- (position, layer, ...) for already inserted blocks.
-
- On complex entities you must (entupd) the header entity, to see
- the update on the screen (forces an element REGEN).
-
- ;;; Example:
- (setq s (getstring "Change Attribute to: "))
- (attchg (attele (setq b (entsel "of block: ")) s)))
- (entupd (car b)) ; the block, not the attribute
-
- ;;; some more helper funcs to get the main entity of any attribute
- ;;; or vertex
- (defun MAIN-ENTITY (ele)
- (setq b (entity b)) ;force ENAME
- (while (istypep b '("ATTRIB" "ATTDEF" "VERTEX"))
- (setq b (entnext b))) ;loop until no more sub-ents
- (if (istypep b '("SEQEND" "ENDBLK"))
- (getval -2 b) ;complex entity -> header
- b ;normal entity
- )
- )
-
- ------------------------------
-
- [22.4] How to ENTMAKE a Block Complex Entity in AutoLISP
-
- See http://xarch.tu-graz.ac.at/autocad/stdlib/ENTMAKE.LSP or
- http://www.autodesk.com/support/techdocs/td30/td301515.htm (broken)
- There is an example how to use multiple calls to (entmake) to create
- the block header, the entities, closes the block and finally
- (entmake) the INSERT.
- For anonymous blocks beware that only
- (setq bn (entmake '((0 . "ENDBLK")))) returns the blockname for
- (entmake (list '(0 . "INSERT")'(70 . 1)(cons 2 bn) ...))
-
- ------------------------------
-
- Subject: [23] Polylines
-
- Since R14 LWPOLYLINE's store the vertices in one entity as multiple 10
- groups. So (assoc) will not work.
-
- [23.1] How to access polyline VERTICES? [updated for R14]
-
- A polyline VERTEX is a subentity of a POLYLINE (same as an ATTRIBUTE
- is a subentity of an INSERT element or a ATTDEF of a BLOCK).
- Therefore the same functions as in [22.1]-[22.3] can be used.
-
- ;;; return only some assoc values in the list (for LWPOLYLINE)
- (defun GROUP-ONLY (grp lst)
- (mapcar 'cdr (remove-if-not '(lambda(pair)(= grp (car pair))) lst)))
-
- ;;; return the vertex list of a polyline or of any other element
- ;;; Note that with edlgetent mentioned in [22.1] it's a one-liner
- (defun GETPTS (ele / pts)
- (setq ele (entity ele)) ;force type ENAME
- (cond
- ((istypep ele "POLYLINE")
- (while (istypep (setq ele (entnext ele)) "VERTEX")
- ;; omit fit and spline points (conservative style)
- (if (not (or (flagsetp 1 ele) (flagsetp 8 ele))) ;bugfix!
- (setq pts (cons (trans (getpt ele) ele 0) pts)))
- (reverse pts)))
- ;; Special case: you have to map it, assoc finds only the first.
- ;; Fix a LWPOLYLINE bug in R14: internally stored as 2d point,
- ;; (entget) returns fantasy z-values.
- ((istypep ele "LWPOLYLINE")
- (mapcar '(lambda(pt)(trans (list (car pt)(cadr pt) 0.0) ele 0))
- (group-only 10 (entget ele))))
- ;; insert here possible other types, such as
- ((istypep ele '("TEXT" "CIRCLE")) (list (getpt ele)))
- ;; more like this (serge's style)
- (T (apply 'append (mapcar
- '(lambda (n / p) (if (setq p (getval n ele)) (list p)))
- '(10 11 12 13)))
- )
- ;; or like this (conservative style)
- ;;(T (foreach n '(10 11 12 13)
- ;; (if (setq p (getval n ele)) (setq pts (cons p pts))))
- ;; pts
- ;;)
- )
- )
-
- Suggestions by Vladimir Nesteroswky for a different vertex structure:
- (defun VERTICES-AND-BULGES (pline-ename)
- (mapcar 'cdr
- (remove-if-not '(lambda (ele) (bitsetp 9 x))
- (get '(70 10 42) (cdr (edlgetent pline-ename))
- => list of (10 42) pairs of the pline
-
- See also [23.5] for a different edge structure (segments) of plines.
-
- ------------------------------
-
- [23.2] How to JOIN multiple lines to polylines?
-
- Simply try to join each element with all selected, but beware that
- an entity already joined cannot be entget'ed anymore, because it's
- deleted.
-
- ;;; This sample converts all selected elements to polylines and
- ;;; tries to join as much as possible.
- (defun C:JOINPOLY (/ ele ss)
- (foreach ele (sslist (setq ss (ssget))) ;better process lists
- (if (entget ele) ;not already joined
- (cond ;(then it would be nil)
- ((istypep ele '("ARC" "LINE"))
- ;; in fact you should check Z of lines and UCS here too
- (command "_PEDIT" ele "_Y" "_J" ss "" ""); convert and JOIN
- )
- ((and (istypep ele '("POLYLINE" "LWPOLYLINE")) ;bugfix
- (not (flagsetp 1 ele)) ;not closed
- (< (rem (getflag ele) 128) 8)) ;ignore meshes and such
- (command "_PEDIT" ele "_J" ss "" "");ucs check omitted
- )
- )
- )
- )
- )
-
- ------------------------------
-
- [23.3] Change WIDTH of multiple polylines
-
- With the help of the above defined helper function it's a short one:
-
- (defun C:POLYWID (/ wid ele)
- (initget 5)(setq wid (getdist "New Polyline Width: ")) ;not negative
- (foreach ele (sslist (ssget '((0 . "*POLYLINE")))) ;only PLINES
- (command "_PEDIT" ele "_W" wid "")))
-
- ------------------------------
-
- [23.4] Create a polyline or spline: with (ENTMAKE) or (COMMAND)
-
- 1. You can create a script-file with a LISP-program and then run it.
- It seems to be the simpliest way, but I/O errors may occur when
- reading/writing the script. If your soft is commercial, it must handle
- such errors.
-
- 2. The second way is to create the entities list and use ENTMAKE.
- Advantage: fast, in WCS, independent of actual osnaps.
- See http://xarch.tu-graz.ac.at/autocad/stdlib/ENTMAKE.LSP
-
- 3. The third solution is based on command and mapcar. It works with
- Polylines, Splines or Lines. Disadvantage: UCS, Osnaps
-
- ;;; Draws a POLYLINE entity from a list of points (same with SPLINE,
- ;;; or LINE), on the actual UCS, with actual OSNAP settings
- (defun DRAW-PLINE (pts)
- (command "_PLINE")
- (mapcar 'command pts)
- (command ""))
- (defun DRAW-SPLINE (pts)
- (command "_SPLINE")
- (mapcar 'command pts) ; the pts must be the fitpoints then
- (command "" "" ""))
-
- ------------------------------
-
- [23.5] How to calculate the LENGTH of polylines?
-
- There are two ways:
- 1. the obvious, using the AREA command which is quite "noisy"
- (prints the result), but works even with splines.
-
- ;;; add up the LENGTH of all selected objects, NOISY, you can do the
- ;;; same with AREAs: simply change the last line to (getvar "AREA")
- (defun C:LEN-OF ()
- (command "_AREA" "_A" "_E") ;add up objects (for R12+13)
- (ssmap 'command (ssget)) ;pass all elements to AutoCAD
- (command "" "") ;two returns
- (getvar "PERIMETER")) ;this is the length
-
- 2. Doing some math, but only for simple entities. Here it is best to
- define some helper functions again. This is also an introduction for
- the next chapter [24], some bulge trigonometry for curved segments.
-
- ;;; calculates length of a pline, quiet
- (defun POLY-LENGTH (poly / seg)
- (apply '+ ; the sum of all single segment lengths
- (mapcar
- '(lambda (seg) ;length of one segment
- (if (zerop (car seg)) ;is it straight?
- (distance (cadr seg) (caddr seg)) ; line segment or
- (abs (arclen seg)))) ; curved: -> [24]
- (pline-segs poly)))) ;segment list (bulge p1 p2)
-
- ;;; returns all group codes of the complex element
- ;;; (vertices, attributes) as list, similar to (edlgetent)
- (defun CPLX-LIST (grp ele / lst)
- (if (= 1 (getval 66 ele))
- (progn (setq ele (entnext (entity ele)))
- (while (and ele (not (istypep ele "SEQEND")))
- (setq lst (cons (getval grp ele) lst)
- ele (entnext ele)))
- (reverse lst))))
-
- ;;; Creates a segment list for the polyline pname
- ;;; as a list of '(bulge p1 p2). A straight line has bulge 0.0
- ;;; Compute pts in ECS of pname. Accepts LWPOLYLINE's
- (defun PLINE-SEGS (pname / pts segs)
- (setq segs
- (mapcar 'list
- (if (istypep pname "LWPOLYLINE")
- (group-only 42 (entget pname))
- (cplx-list 42 pname))
- (setq pts (getpts pname)) ; ->[23.1]
- (rot1 pts))) ; ->[20.1]
- (if (flagsetp 1 pname)
- segs ;closed
- (butlast segs))) ;open: without the last segment, ->[20.1]
-
- ;;; Example: (a bit optimized for brevity :)
- ;;; Add up all the lengths of all selected polylines, quiet
- ;;; To accept also other entities, add those to pline-segs
- (defun C:POLYLEN ()
- (apply '+ (ssmap 'poly-length (ssget '((0 . "*POLYLINE"))))))
-
- For the sum of areas use either the noisy AREA command or implement
- Heron's formula for polygon areas (just for simple closed polygons).
-
- ------------------------------
-
- [23.6] How to REVERT a polyline direction?
-
- Sergei Komarov submitted a REVPOLY.LSP which takes care of
- bulges and widths too.
- http://xarch.tu-graz.ac.at/autocad/news/lisp_progs/revpoly.lsp
-
- A short stdlib version is this:
- ;;; ignoring any width information
- (defun POLY-REVERSE (segs)
- (reverse (mapcar '(lambda (seg) (std-make-seg (std-seg-p2 seg)
- (std-seg-p1 seg)
- (- (std-seg-bulge-num seg))))
- segs)))
- (defun C:POLYREV (/ ele)
- (std-require "ENTMAKE")
- (if (setq ele (car (entsel "\nRevert Poly: ")))
- (std-entmake-pline (entget ele '("*")) ; keep EED information
- (poly-reverse (std-pline-segs ele)))))
-
- ------------------------------
-
- [23.7] How to get the CENTER of a polyline?
-
- The centroid of SOLID's has to be extracted with MASSPROP.
- You can let it write to a file and analyse this then.
- The centroid of polylines is different to the mean vector.
- The 2D geometric mean of some pts is simply:
-
- (setq n (float (length pts)))
- (list (/ (apply '+ (mapcar 'car pts)) n)
- (/ (apply '+ (mapcar 'cadr pts)) n))
-
- The true centriod is more difficult. The stdlib version is at
- http://xarch.tu-graz.ac.at/autocad/stdlib/STDPOINT.LSP STD-CENTROID-2D
- In the stdlib.arx or at www.manusoft.com (under freebies) are also a
- better massprop lisp function for solids. Then you do
- (command "_REGION" ele)...(massprop entlast)...(command "_UNDO" 1)
- For VLA there's also a massprop property for Acis objects.
-
- ------------------------------
-
- Subject: [24] Circle/Arc Geometry: BULGE conversion, some trigonometry
-
- What is the *BULGE* in a polyline?
-
- The bulge is the tangent of one forth of the included angle of a
- curved segment. A bulge 0.0 means a straight segment.
- Together with the start- and endpoint it is sufficient information to
- quickly calculate all other required information of a curved segment.
- A negative bulge is a rotation in clockwise direction ("mathematically
- negative").
-
- arclength = radius*angle
- bulge = tan( ang/4 ) (CCW: +, CW: -)
- angle = 4*atan( bulge )
- bulge = ( 2*altitude ) / chord (CCW: +, CW: -)
-
- See also http://www.autodesk.com/support/techdocs/fax700/fax797.htm
- for a sample program or the book "Maximizing AutoLISP" [2]
- (Note: The R10/11 book -Vol II- contains a wrong bulge formula.)
-
- ;;; converts a bulged segment (bulge pt1 pt2) of a polyline
- ;;; to a circle (ctr rad), the start- and endpoints are known
- ;;; therefore the angles too: (angle ctr pt1)(angle ctr pt2)
- ;;; returns nil on a straight segment!
- ;;; (bugfixed version. Thanks to Sergei Komarov)
- (defun SEG2CIR (seg / bulge p1 p2 cot x y rad dummy)
- (if (zerop (car seg)) ;straight line => invalid circle
- nil
- (setq bulge (car seg) p1 (cadr seg) p2 (caddr seg)
- cot (* 0.5 (- (/ 1.0 bulge) bulge))
- x (/ (- (+ (car p1) (car p2))
- (* (- (cadr p2) (cadr p1)) cot)) 2.0)
- y (/ (+ (+ (cadr p1) (cadr p2))
- (* (- (car p2) (car p1)) cot)) 2.0)
- rad (distance (list (car p1) (cadr p1)) (list x y))
- dummy (list (list x y) rad)))) ; return this, I hate progn's
-
- ;;; inverse conversion
- ;;; calculates segment (bulge p1 p2) of arc
- ;;; with given circle (ctr rad), start-angle, end-angle
- (defun ARC2SEG (cir ang1 ang2 / p1 p2)
- (setq p1 (polar (car cir) ang1 (cadr cir))
- p2 (polar (car cir) ang2 (cadr cir)))
- (list (arc2bul p1 p2 cir) p1 p2))
-
- ;;; calculates bulge of arc given the arc points and the
- ;;; circle (ctr rad) [fixed by Serge Pashkov]
- (defun ARC2BUL (p1 p2 cir / ang)
- (setq ang (- (angle (car cir) p2) (angle (car cir) p1)))
- (if (minusp ang) (setq ang (+ (* 2.0 pi) ang)))
- (tan (/ ang 4.0)))
-
- ;;; returns angle of arc (bulge)
- ;;; The seg format is (bulge p1 p2)
- (defun BUL2ANG (seg / ctr)
- (- (angle (setq ctr (car (seg2cir seg))) (cadr seg))
- (angle ctr (caddr seg))))
-
- ;;; calculates angle of arc given the chord distance and radius
- (defun ARC2ANG (chord rad)
- (* 2.0 (atan
- (/ chord 2.0
- (sqrt (- (expt rad 2)
- (expt (/ chord 2.0) 2)
- ) ) ) ) ) ) ;another way in the paren's world
-
- ;;; length of arc = radius*angle,
- ;;; Note: +/-, you'll need (abs (arclen seg)) for the distance
- (defun ARCLEN (seg)
- (* (cadr (seg2cir seg)) ;radius
- 4.0 (atan (car seg)))) ;angle = 4*atan(bulge)
-
- (setq *INFINITY* 1.7e308) ; largest double
- (defun TAN (z / cosz) ; [fixed]
- (if (zerop (setq cosz (cos z))) *INFINITY*
- (/ (sin z) cosz)))
- (defun DTR (ang)(* pi (/ ang 180.0))) ;degree to radian
- (defun RTD (ang)(/ (* ang 180.0) pi)) ;radian to degree
-
- ------------------------------
-
- Subject: [25] DCL: listboxes with tabs or monotext font
-
- Under Windows it's difficult to layout texts because of non-monospaced
- fonts. Try it with the tabs attribute in the list_box tile,
- such as:
- tabs = "0 20 40";
- and (set_tile "listbox" "Layer:\t0\twhite")
- try the following to use monospaced characters:
-
- : list_box {
- label = "Drawing";
- key = "dwglist";
- width = 50;
- fixed_width_font = true; // <- monotext
- }
-
- Also might want to look at the detab routine (TAB -> Spaces) at
- http://xarch.tu-graz.ac.at/autocad/news/detab.lsp or STD-DETAB in
- http://xarch.tu-graz.ac.at/autocad/stdlib/STDSTR.LSP
-
- ------------------------------
-
- Subject: [26] EED Extended Entity Data: Select, Get and Store
-
- [26.1] Select objects on their EED with (ssget "X")
-
- ;;; defines your appname header and delimiter (4 char regapp name
- ;;; according AAIG, AutoDESK Application Interoperation Guidelines)
- (setq appname "HUBU-")
- ;;; defines * for all sub types
- (setq allappnames (strcat appname "*"))
- ;;; eg: HUBU-LIST1, HUBU-LIST2
-
- ;;; here is how to get the first eed list from one element
- (defun get-eed-1st (ele)
- (cdadr (assoc -3 (entget (entity ele) (list allappnames)))))
-
- ;;; this gets all elements of appnames typ (wildcards allowed)
- (defun ssget-app (typ) ;fast
- (ssget "X" (list (list -3 (list typ))))
-
- ;;; this gets only your elements
- (defun ssget-hubu (typ) ;fast
- (ssget "X" (list (list -3 (list (strcat appname typ)))))
-
- (ssget-hubu "*") ; will get all your elements
-
- ------------------------------
-
- [26.2] Get EED from an object
-
- Check any XDATA with: (entget (car (entsel)) '("*"))
-
- ;;; GETXDATA - get all XDATA lists from an element
- ;;; i.e with XDATA:
- ;;; (-3 ("HUBU-1" (1000 ."ASSHATCH")(1002 ."{")
- ;;; (1070 . 1)(1002 ."}")))
- ;;; =>(("HUBU-1" (1000 ."ASSHATCH")(1002 ."{")(1070 . 1)(1002 ."}")))
- (defun getxdata (e apnlst)
- (cdr (assoc -3 (entget e apnlst))))
-
- ;;; GETXDATA-ALL - all lists without the regapp name
- ;;; => ((1000 ."ASSHATCH")(1002 ."{")(1070 . 1)(1002 ."}"))
- (defun getxdata-all (e apnlst)
- (apply 'append (mapcar 'cdr (getxdata e apnlst))))
-
- The regapp name is stripped here, because it's only used for fast
- ssget access. The different apps are divided by different
- (1000 . name) groups as it's used by AutoDESK.
-
- For storing XDATA in an element see XDATA.LSP or XED.LSP though those
- examples are a bit disturbing.
-
- For advanced EED tricks, esp. converting the "{" "}" ADS resbuf style
- to Lisp lists and back, see
- http://xarch.tu-graz.ac.at/autocad/news/eed_retrieval.txt
-
- ------------------------------
-
- Subject: [27] How to break a command in Lisp?
-
- Also: "How do I press Break in AutoLISP?"
-
- (command) without parameters works just like hitting Ctrl-C under
- DOS or Esc under Windows at the command prompt. But it does not
- mimic Esc in a dialog box. And it does not work within
- SCRIPTS. (command nil) is the same as (command).
-
- (command) breaks only the command functions, e.g. if you use the
- command "DIM" inside AutoLISP, you must interrupt it by (command)
- after dimensioning.
-
- But it doesn't work, if you try to interrupt a lisp loop. There is
- another function (exit) or (quit) -they do the same-, which
- immediately break a Lisp program.
-
- Example:
-
- (while T ; do ; a never ending loop
- (princ "\nEnter a=")
- (setq a (getint))
- (if (zerop a)(exit)) ; Breaks Lisp and returns to the command mode.
- )
-
- In this example (command) doesn't work. (exit) works exactly as
- Ctrl-C. It prints "error: quit / exit abort" and outputs all nested
- functions. To provide "silent" break you must include this error
- message to an error handling function, e.g.:
-
- (setq *olderr* *error* *error* my-error)
- (defun MY-ERROR (s)
- (if (not (member s ; msgs of the english version:
- '("Function cancelled" "console break" "quit / exit abort")))
- (princ (strcat "\nError: " s))
- )
- (setq *error* *olderr*)
- )
-
- For scripts use this workaround by defining (cancel) in lisp, simply
- (defun SCRIPT-CANCEL ()
- (command)
- (command "resume")
- )
- and in a SCRIPT.SCR:
- ..
- [<script commands>]
- (script-cancel)
- [<more script commands>]
- ..
-
- ------------------------------
-
- Subject: [27.1] How to do an unlimited number of user prompts? [new]
-
- To let the user end any selected command without having to write
- code for every possible option, just repeat (command PAUSE) until
- the command is ended.
-
- ;; Sample by Owen Wengerd
- (command "_ARC")
- (while (= 1 (logand (getvar "CMDACTIVE") 1)) (command PAUSE))
-
- ------------------------------
-
- Subject: [28] How to decode ACIS internal geometry with Lisp?
-
- All the ACIS objects (3DSOLID) have been documented by Spatial ("SAT
- Format Description"). However the internal representation by (entget)
- is still encrypted, but the encryption scheme was hacked. (XOR 95)
-
- Samples and code are at:
- http://xarch.tu-graz.ac.at/autocad/stdlib/samples/ACIS-REGION.LSP
-
- ------------------------------
-
- Subject: [A] Disclaimer, Notes from the authors
-
- If you think of questions that are appropriate for this FAQ, or
- would like to improve an answer, please send email to Reini Urban
- <rurban@x-ray.at> but don't expect an reply.
-
- This AutoLISP FAQ is Copyright (c) 1996,97,98,99,2000 by Reini Urban.
-
- This FAQ may be freely redistributed in its entirety without
- modification, provided that this copyright notice is not removed. It
- may not be sold for profit or incorporated in commercial documents
- (e.g. published for sale on CD-ROM, floppy disks, books, magazines,
- or other print form) without the prior written permission of the
- copyright holder. Permission is expressly granted for this document
- to be made available for file transfer from installations offering
- unrestricted anonymous file transfer on the Internet (WWW, FTP) and
- esp. to be included into the official AutoCAD FAQ.
-
- The sample code is, if not otherwise stated, (c) 1996,97
- by Reini Urban and may be freely used, but not sold.
- The basic functions in [20] are, if not otherwise stated,
- (c) 1991-97 by Reini Urban and may/should be freely used.
-
- If this FAQ is reproduced in offline media (e.g., CD-ROM, print
- form, etc.), a complimentary copy should be sent to Reini Urban,
- X-RAY, Nibelungeng. 3, 8010 Graz, Austria
-
- This article, the contents and the sample code, is provided AS IS
- without any expressed or implied warranty.
-
- ------------------------------
-
- [A.1] FAQ Locations
-
- Homepage of the HTML'ified version:
- http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp.html
- + Annotated AcadWiki version:
- + http://xarch.tu-graz.ac.at/acadwiki/AutoLispFaq
- The posted ascii versions (and always latest versions) are at
- http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp.1 and
- http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp.2
- The Winhelp version (zipped with faq and code) is at
- ftp://xarch.tu-graz.ac.at/pub/autocad/news/faq/autolisp.zip
- The FAQ usenet archive is at
- http://www.faqs.org/faqs/CAD/autolisp-faq/ resp.
- ftp://rtfm.mit.edu/pub/usenet-by-hierarchy/comp/cad/autocad/
- The Lisp code from this FAQ is at
- ftp://xarch.tu-graz.ac.at/pub/autocad/news/faq/FAQ-CODE.LSP
- A french translation of the FAQ by Roger Rosec
- http://www.newz.net/acadplus/page5101.htm
- A japanese translation of the FAQ by MASAMI Chikahiro
- http://www.page.sannet.ne.jp/chestnutsburr/autolisp-j.html
- A russian translation of the FAQ by Igor Orellana at
- http://www.cad.dp.ua/stats/alfaq_ru.htm
- A german translation by myself at
- http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp.html.de
- + A new spanish translation by Eduardo Magdalena
- + http://www.peletash.com/mecanicad/articulos/art02_0002.htm
- Relevant AutoDesk FAQ's and TechSupport
- http://www.autodesk.com/support/autocad/
- http://search.autodesk.com/query.html?qt=autocad+faq
- http://www.autodesk.com/support/autocad/asa2000.htm
- AutoDesk news groups
- news://discussion.autodesk.com/autodesk.autocad.customization
- http://groups.google.com/groups?oi=djq&as_ugroup=autodesk.autocad.customization
- or the new WebX interface at http://discussion.autodesk.com/
-
- ------------------------------
-
- Subject: [B] Acknowledgements
-
- This FAQ is based on great efforts of the the news://comp.cad.autocad
- community, in particular:
- Tom Berger, Adi Buturovic, Christoph Candido, Mike Clark, Miles
- Constable, Cara Denko, T.J. DiTullio, Chris Ehly, Jeff Foster, Rusty
- Gesner, William Kiernan, Paul Kohut, Sergei M. Komarov, Joseph
- + M. Liston, Lu, Eduardo Magdalena, Masami Chikahiro, Georg Mischler,
- Desi Moreno, Vladimir Nesterovsky, Roger Rosec, Serge Pashkov,
- Dennis Shinn, Tony Tanzillo, Eugene Tenenbaum, Reinaldo Togores,
- Reini Urban, Serge Volkov, Morten Warankov, Owen Wengerd, Alan
- Williams, Doug Wilson, Ian A. White, David Whynot, Darren Young,
- Xiang Zhu and others.
-
- ------------------------------
-
- Subject: [C] Recent Changes
-
- * 25.Jun 2002
- new spanish translation [A.1]
- * 18.Jun 2001
- fixed deja.com to groups.google.com
- * 23.Apr 2001, 14.Jun 2001
- fixed several links
- * v2.28 4.Apr 2001
- changed rurban@sbox to rurban@x-ray.at (defunct in the next year)
- all parts of the faq are now in the acadwiki.
- * v2.27 23.Sep 2000
- added [23.7] "How to get the CENTER of a polyline?"
- * 15.Sep 2000
- changed stack-overflow [14] to better reflect VL/VLIDE, A2000,
- new book [2]
- * 1.Sep 2000
- vl-sort warning with duplicate entries [8]
- * 18.Aug 2000
- changed CodeMagic [6.1] from Freeware to Shareware, thanks to Nir Sullam
- * 1.Aug 2000
- changed adesk faq location
-
- * v2.26 6.Jun 2000
- added LDATA bug [7], fixed DEFUN-Q [11],
- removed most colored [new/changed] notes
- * v2.25 17.May 2000
- added [27.1], added C:POLYREV [23.6], texinfo versions
- * 25.Apr 2000
- added Point A [1.1], shortened the DDE example in [21.2]
- * 24.Apr 2000
- Vladimir fixed www.deja.com to deja.com/usenet [1.1]
- * v2.24 20.Apr 2000
- renamed cadsyst.com to caddepot.com [1], added cadplugins.com [1],
- added rapidlisp [6.2]
- * 30.Mar 2000
- renamed adesknews.autodesk.com to discussion.autodesk.com
- * 9.Mar 2000
- added CodeMagic editor at [6.1], thanks to Nir Sullam
- * 29.Feb 2000
- Masami Chikahiro fixed numeric range [7]: -32766 => -32768
- * 17.Feb 2000
- Added the dotsoft buglist url.
- Mike Tuersley fixed [11] for MNL files.
- Owen: $600 US of ADN [1.2]
-
- * v2.23 14.Feb 2000
- Chris Ehly fixed all broken links.
-
- * v2.22 13.Jan 2000
- additions to numerical precision [7].
- adesk techdocs links are broken again.
- compiled S::STARTUP hooks [11].
-
- * the full history is at
- http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp_faq_history.txt
-
- --
- Reini Urban, Jun 25, 2002
-