comp.cad.autocad AutoLISP FAQ (deutsche Übersetzung)

URL: http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp.html.de
Version: 2.28
Last-modified: "2002-06-25 08:44:51"
Posted-By: Reini Urban <rurban@x-ray.at>
Posting Frequenz: wird nicht geposted
Copyright: siehe Appendix [A]

Willkommen beim comp.cad.autocad AutoLISP FAQ!

AutoLISP ist eine Skriptsprache für AutoCAD, ein bekanntes CAD Programm. Dieses AutoLISP FAQ wird jeden Monat in comp.cad.autocad, alt.cad.autocad und in den *.answers newsgroups gepostet.
Es gibt ein paar AutoCAD FAQ's bei Autodesk ( "Suche nach AutoCAD+FAQ"), die werden aber nicht nach comp.cad.autocad oder de.comp.cad geposted.
Der Inhalt und die Beispielprogramme sollten bei allen AutoCAD Versionen ab R10 funktionieren, einschließlich den Versionen für die Lispcompiler Visual LISP, Vital Lisp und ACOMP.
Es gibt keine spezielle AutoLISP Diskussionsgruppe. Die besten sind comp.cad.autocad, autodesk.autocad.customization und de.comp.cad. comp.lang.lisp hat nichts mit AutoLISP zu tun.
Sourcecode von allen Funktionen dieses FAQ's ist in FAQ-CODE.LSP (siehe [A.1]).
Dank alle Kollegen! Korrekturen und Beiträge (an rurban@x-ray.at) sind immer willkommen.

(| Änderungen, + Neue Punkte in dieser Version, vorläufige Kommentare und Unsicherheiten sind in <..>)


Inhaltsverzeichnis


Teil 1: Allgemeines
[0] Die Zukunft von AutoLISP? Soll ich nicht lieber Visual Basic lernen?
[0.1] Was ändert sich mit AutoCAD 2000?
[0.2] Warum kann man keine ARX mehr erzeugen?
[1] Wo gibt's AutoLISP Programme im Internet?
[1.1] Werden die comp.cad.autocad Artikel irgendwo archiviert?
[1.2] AutoDESK's SDK
[2] Was sind die besten Bücher um AutoLISP zu erlernen?
[2.1] Online AutoLISP Dokumente, Windows Hilfe [veraltet]
[2.2] AutoLISP Programmierstil
[3] Wie debugge ich AutoLISP Programme?
[3.1] Richtige AutoLISP Debugger
[3.2] Modularer Stil, TRACE
[3.3] break Funktion, debug print
[4] Wie schütze ich AutoLISP Programme?
[4.1] Kelvinate
[4.2] Protect
[4.3] Kelvinate und Protect
[4.4] Convert
[4.5] ACOMP
[4.6] Vital Lisp Professional
[4.7] Lisp2C
[4.8] Visual Lisp von Autodesk
[5] AutoLISP Compiler?
[5.1] ACOMP
[5.2] Vital Lisp Professional
[5.3] Visual Lisp von Autodesk
[5.4] Bessere Lisp's: Common Lisp und Scheme
[6] AutoLISP Editoren und andere Utilities
[6.1] AutoLISP Editoren
[6.2] Analyzer, Packager und Klammernprüfer
[6.3] Pretty Printer
[7] Probleme und Fehler mit AutoLisp [Änderungen]
[8] Sortieren mit AutoLISP [Änderungen]
[9] Rekursion
[10] Iteration mit MAPCAR,...
[11] S::STARTUP, Mein LISP wird beim Start nicht mehr geladen [Änderungen]
[12] Wie funktioniert AUTOLOAD?
[13] Wie kann ich eine variable Anzahl von Parametern an Lispfunktionen übergeben?
[14] Wie vermeide ich "Stack Overflows"? [Änderungen]
[15] (command "ROTATE3D") funktioniert nicht! Warum?
[16] Lisp Programme über mehrere Zeichnungen laufen lassen
[17] Wie exportiere ich interne Visual Lisp Funktionen nach AutoLISP/AutoCAD?

Teil 2: Beispiele, Quellcode
[20] Allgemeine Hilfsfunktionen
[20.1] Listen
[20.2] Zeichenketten
[20.3] Symbol->String
[20.4] AutoCAD Elementzugriffe
[21] Beispiel Programme:
[21.1] Ersetze Texte global, mehrere Polylinien, Layer Utilities, datestamp, ...
[21.2] Starte den Plotdialog von Lisp aus. Verwendung von DDE
[21.3] (entmod) und (entmake) für Layer, ohne (command "_LAYER"...)
[21.4] Auswahl von mehreren Dateien mit Lisp? (wie zB. in DATEIEN - Entsperren)
[21.5] Ersetze mehrere Blöcke
[21.6] (vports), VIEWPORT Element, Pixel Konversion
[21.7] Auswahl aller sichtbaren Elemente: ZOOM Koordinaten
[21.8] Wie schreibe ich die XYZ Daten von Elementen in eine Datei?
[22] Block Attribute
[22.1] Zugriffsmethoden zu Block Attribute mit AutoLISP?
[22.2] Wie ÄNDERE ich Block Attribute? (DATESTAMP.LSP)
[22.3] Wie UPDATE ich Block Attribute?
[22.4] Wie erzeuge ich Blöcke mit ENTMAKE?
[23] Polylinien
[23.1] Zugriffsmethoden zu Polylinien Knotenpunkten (VERTICES)?
[23.2] Wie VERBINDE ich automatisch mehrere Polylinien?
[23.3] Wie ändere ich die BREITE von mehreren Polylinien?
[23.4] Erzeugung von Polylinien oder Splines mit (ENTMAKE) oder (COMMAND)
[23.5] Wie messe ich die Länge von Polylinien?
[23.6] Wie drehe ich die Richtung von Polylinien um (REVPOLY.LSP)?
[23.7] Wie errechnet man das Zentrum einer Polylinie? [neu]
[24] Kreis/Bogen Geometrie: BULGE Konversion. Ein bißchen Trigonometrie
[25] DCL: listboxen mit TABS oder MONOTXT Schriften
[26] EED Extended Entity Data: Zugriff und Speichern
[26.1] Wähle Objekte über EED mit (ssget "X")
[26.2] Zugriff auf Objekt EED's
[27] Wie breche ich in Lisp einen Befehl ab?
[28] Wie entschlüssele ich die interne ACIS Geometrie mit Lisp?
  --
[A] Urheberrechtliche Bemerkungen
[A.1] FAQ Links
[B] Danksagungen
[C] Revisionsliste


[0] Die Zukunft von AutoLISP? Sollte ich nicht lieber Visual Basic lernen?

AutoLISP wird definitiv weiter unterstützt in allen zukünftigen Releases. Der Sprache an sich scheint nicht weiterentwickelt zu werden. VB wurde eingeführt um die Office Anpassung zu unterstützen: ACAD <-> Excel-Access

Beide Sprachen haben Vor- und Nachteile. Du solltest Dir beide anschauen. VB scheint mehr "grafischer" und AutoLISP "logischer" zu sein. VB ist sicher schneller zu lernen, weil die Objektstruktur sehr übersichtlich ist.
Das neue VBA (ab dem Update R14.01) ist extrem schnell. Siehe auch [5.2].

Die Zukunft von AutoLISP heißt bereits Visual LISP. Siehe dazu [0.1].


[0.1] Was ändert sich mit AutoCAD 2000?

Der Name :) Nein, da ist viel mehr. Man nennt es Release 2000, R15 (15 ist die Versionsnummer und nicht die Release Nummmer), A2000 oder abgekürzt A2K. ('A 2 Kilo')

Der neue Visual Lisp Kernel ersetzt den alten (xlisp) AutoLISP Kernel. Welche Probleme solltest Du mit Visual Lisp in A2000 erwarten?
In http://xarch.tu-graz.ac.at/autocad/docs/r2000-news.txt ist mein White Paper'. Benutze den LCA (LISP Compatibility Analyzer von den Migration Tools) um deine Lisps zu prüfen.
Die wichtigsten Punkte sind:


[0.2] Warum kann man keine ARX mehr erzeugen?

Mit AutoCAD 2000 kann man keine ARX Programme mehr erzeugen, wie mit VLISP 4 oder Vital Lisp. Das hat technische und formale Gründe. Dagegen erzeugt man jetzt VLX ('Visual Lisp Extension'), das dieselbe Funktionalität gegenüber kleinerem Overhead bietet. Die Unterschiede im Detail: In Summe: Man braucht keine ARX Module wie mit VLISP 4 oder Vital Lisp mehr. Das ist ein Fortschritt, keine Rückschritt.


[1] Wo gibt's AutoLISP Programme am Internet?

Die großen AutoCAD Tools Server sind:

AutoCAD Plugin Store auf beyond.com.
Das ist die von AutoDESK "offiziell" empfohlene Seite.
CADalog - Das AutoCAD Shareware Clearinghouse (Mike Clark)
http://www.cadalog.com
The CAD Depot, früher bekannt als "CADSyst" und "Rolling Stock Software" (David Whynot)
http://www.caddepot.com/, vor kurzem von TenLinks.com gekauft.
Diese sind spezialisiert in AutoCAD Software und haben eine sehr gut sortierte AutoLISP Sammlung. Andere professionelle AutoLISP Shareware Server posten Ihre URL's auch in die Newsgroups.

Andere relevante Internet Portale sind:
TenLinks und das UpFront Ezine (auch auf deutsch) sind die besten CAD news services.
Autodesk startete mit ihrem Portal Point A.

Einige andere Server mit AutoLISP Sammlungen sind:

xarch AutoCAD Info & Tools (Reini Urban)
http://xarch.tu-graz.ac.at/autocad/ (mit Suche)
CAD Users Webring [neu]
CADalyst Magazin code (gesammelt von "Hot Tip Harry" Art Liddle)
http://www.cadonline.com/code/
CADshack (Jeff Foster)
http://www.cadshack.com/lispfile.htm
Owen Wengerd
http://www.manusoft.com
Terry Dotson
http://www.dotsoft.com/
Vladimir Nesterowsky
http://members.tripod.com/~vnestr/
UCCB AutoCAD and AutoLISP page (Paul Standing)
http://ucad1.uccb.ns.ca/acad/cad.htm
Theo L.A. Groenenberg
http://members.xoom.com/acadvice/autolisp.htm
Lisp Factory (Jay Garnett)
http://www.enteract.com/~jgarnett/
Rakesh Rao - AutoCAD Tech Center
http://www.4d-technologies.com/techcenter
Veraltete oder nicht funktionierende Links:
AutoCAD Tech Journal code (Peter Sheerin) [alt]
http://www.atj.com
CADENCE magazine code (Peter Sheerin) [alt, broken]
ftp://ftp.mfi.com/pub/cadence/
McNeel's lisp archive [fixed]
ftp://ftp.mcneel.com/pub/lisp/
Dr.Lisp Utilities (Alexander Medwedew)
http://tribeca.ios.com/~compvent/drlutils.html
Bob Jones [broken]
http://www.io.com/~bcjones/files.html
PIRS Online
http://www.insa.com/
Henry Francis [broken]
http://www.ez-sys.net/~coopfra/
Desi Moreno [broken]
http://www.invsn.com/desmos/autolisp.htm
Das SimTel - Coast To Coast - Archiv [uralt, fixed]
http://www.simtel.net/simtel.net/msdos/autocad.html
Auf http://www.autodesk.com/support/autocad/ gibt's offizielle Seiten vom Autodesk Product Support, die technische Fragen erörtern. ("Ihr FAQ")

[1.1] Werden die comp.cad.autocad Artikel irgendwo archiviert?

Es gibt kein offizielles comp.cad.autocad Archiv, aber es gibt einige Suchmaschinen, die Newsartikel speichern. Im Einzelnen:

groups.google.com/ - Das größte und beste News Archiv. [neu]
Vorher bekannt unter deja.com/usenet.
http://www.altavista.com/
http://www.altavista.com/cgi-bin/query?pg=aq&what=news
http://www.excite.com/
http://www.excite.com/search.gw?collection=news
Phoaks - People Helping One Another Know Stuff - Automatic Links Extractor
http://www.phoaks.com/phoaks2/newsgroups/comp/cad/autocad/index.html
Die Autodesk Diskussionsforen haben auch eine Suchfunktion, discussion.autodesk.com. Einige spezielle News Postings gibts auch auf http://xarch.tu-graz.ac.at/autocad/news/contents.html


[1.2] AutoDESK's SDK

Bis einschließlich Release 12 war ein Software Development Kit (SDK) von AutoDESK erhältlich. Das SDK2 war auf der CD für alle internationalen R12 dabei. Es beinhaltete viel ADS und AutoLISP Quellcode und Bibliotheken.

Ab R13 gibt es ein spezielles Entwickler Netzwerk, vergleichbar dem Microsoft's, das ADN (AutoDESK Developer Netzwerk). Die vierteljährlichen CD's sind vergleichbar mit dem alten ADK, aber wenden sich hauptsächlich an professionelle ARX/ObjectARX Entwickler.
Kontaktiere das nächstes AutoDESK Hauptquartier um Mitglied zu werden.

Einige Lisp Bibliotheken sind auch auf http://xarch.tu-graz.ac.at/autocad/code/adesk/SDK2

In den Staaten kostet die ADN Mitgliedschaft US $600.00 pro Jahr. Die CD's beinhalten kein SDK per se, aber das meiste vom alten SDK ist in der einen oder anderen Form enthalten. (Owen)


[2] Was sind die besten Bücher um AutoLISP zu erlernen?

"AutoLISP Referenz Handbuch"
von AutoDESK. Weiters auf Englisch:
AutoLISP to Visual LISP [neu]
Kevin Standiford, Autodesk Press, ISBN 0-7668-1517
AutoLISP: Programming for Productivity,
William Kramer, Autodesk Press, ISBN 0-8273-5832-6
Essential AutoLISP,
Roy Harkow, Springer-Verlag, ISBN 0-387-94571-7
AutoLISP in Plain English; A Practical Guide for Non-Programmers,
George O. Head, Ventana Press, ISBN: 1566041406
"Maximizing AutoLISP"
Rusty Gesner, Tony and Mark Middlebrook, Tony Tanzillo.
Mehr bei http://www.group-a.com/~rusty

Es gibt viele andere AutoLISP Bücher.

Empfehlenswerte generelle LISP Bücher (nicht AutoLISP!) sind:

ANSI Common Lisp,
Paul Graham, Prentice Hall. Auch auf deutsch.
LISP, 3rd Ausgabe,
Patrick Henry Winston und Berthold Klaus Paul Horn, Addison-Wesley Publishing Company. Auch auf deutsch.
Looking at LISP,
Tony Hasemer, Addison-Wesley Publishing Company, ISBN 0-201-12080-1


[2.1] [gelöscht, weil veraltet]


[2.2] AutoLISP Programmier Stil

Die meisten Beispielprogramme, die in verschiedenen Magazinen und auf Webseiten publiziert wurden, sind formal sehr schlecht geschrieben. Deshalb ist AutoLISP auch für Anfänger recht schwierig zu erlernen.
Lisp ist sowieso schwer zu lesen, wegen der Kürze und den endlosen Klammern. Gerade auch deshalb sollte jeder klaren, lesbaren Code schreiben. Die AutoDesk Beispiele sind ziemlich gut geschrieben, aber manchmal übertreiben auch Sie :)

Es gibt Lisp Formatierer ("pretty printers") oder sogenannte "beautifier" (siehe [6.3]) die Code automatisch nach dem Standard formatieren.

Es gibt eine exzellente Beschreibung von AutoDESK über "coding, commenting and intentation standards" (auf englisch) um Lispcode lesbar zu halten. Es ist auf der R12 CD-ROM im SDK2: ACG.DOC oder auf http://xarch.tu-graz.ac.at/autocad/docs/acg.txt

Die wichtigsten Punkte sind:


[3] Wie debugge ich AutoLISP Programme?

[3.1] Drei richtige interne AutoLISP Debugger:

Siehe auch [5] AutoLISP compiler?

[3.2] Modularer Stil, TRACE

Am besten teilt man seine Programme übersichtlich in Funktionen ein, im Gegensatz zum Spagetticode, um Unterfunktionen mit TRACE Funktionsaufrufe, Argumente und Rückgabewerte verfolgen zu können. Außerdem kann man solche Funktionen auch immer weiterverwenden.

[3.3] Füge(BREAK) und DEBUG-PRINT Funktionen in den Quellcode ein

Beispiele:

;;; Debugging Funktionen (defun BREAK (s) (if *BREAK* (progn (princ "BREAK>> (Ende mit <Enter>)\nBREAK>> ")(princ s) (while (/= (setq s (getstring "\nBREAK>> ")) "") (print (eval (read s))))))) (defun DBG-PRINT (s) ;akzepiert Atome und Listen (if *DEBUG* (if (listp s) (mapcar 'print s) (print s)))) (defun C:DEBUG () (setq *DEBUG* (not *DEBUG*))) ;schalte es aus und ein (defun C:BREAK () (setq *BREAK* (not *BREAK*))) (defun CONT () (setq *BREAK* nil)) ;Weitere Ausführung ohne Unterbrechung ;;; Beispiel (setq *BREAK* T *DEBUG* T) (defun C:TEST () (foreach x '("1" "1.0" "1e-3") (break "in foreach") ; stoppt Evaluierung wenn *BREAK* ein ist, ; man kann jedes symbol eingeben (ohne !) ; und der Wert wird ausgedruckt (setq x (atof x)) ; mache etwas mit x (dbg-print x) ; Das druckt x aus, wenn *DEBUG* ein ist. ) ) Befehl: TEST BREAK>> (Ende mit <Enter>) ; in der Break Schleife BREAK>> in foreach BREAK>> x ; wie ist der Wert von x? 1.0 BREAK>> (CONT) ; schalte break aus nil BREAK>> <Enter> ; weiter mit dem Programm 1.0 1.0 0.001 Du kannst auch die Debugging Ausgabe in der Breakschleife mit BREAK>> (setq *DEBUG* nil) ausschalten, um größere Schleifen zu beschleunigen.


[4] Wie kann ich meine AutoLISP Programme schützen?

Bist du dir sicher? Wenn du sie deine Freunden weitergeben willst, warum nicht den Quellcode? Geschützt ist der Quellcode sowieso durch das Urheberrecht, und Zusammenarbeit kann dir sehr weiterhelfen.
Einige der besten Tools sind welche die meine Freunde verbessert haben oder ich habe welche meiner Freunde verbessert. zB. Linux wurde nur so groß, weil viele daran weiterentwickeln können.

[4.1] Kelvinate
Mit kelv.exe (auf der R12 CD-ROM oder auf den großen AutoLISP Servern [1]) De-Kelvinate Lisp's mit einem pretty printer. Aber Symbolnamen bleiben unleserlich und Kommentare bleiben verloren.
[4.2] Protect
Mit protect.exe (auf der R12 CD-ROM oder auf den großen AutoLISP Servern [1])
Beachte: Es gibt freie Entschlüsselungsprogramme.
[4.3] Kelvinate und Protect
Kelviniere zuerst dein Programm um es unlesbar zu machen, dann verschlüssle es mit protect.
[4.4] Convert
Shareware Lisp En-/Decryptor von Maciej Lukasiewicz
Mit Convert verschlüsselte "Protected Lisps" können nur mehr von Convert selber entschlüsselt werden. Decryptor v2.0 sollte nicht mehr verwendet werden.
[4.5] ACOMP
AutoLISP compiler acomp.exe (mit dem R12 International Release oder auf den AutoLISP Servern) Mehr Dokumentation über acomp gibt es auf http://xarch.tu-graz.ac.at/autocad/bi4
Siehe auch [5.1] AutoLISP compiler?
[4.6] Vital Lisp Professional
http://www.basissoftware.com/vill.htm
sprich "ViLL", veraltet, lebt als Visual Lisp weiter. Siehe auch [5.2] AutoLISP compiler?
[4.7] Lisp2C
Lisp nach C Konverter, für R12/R13/R14 Dos/Win, für Watcom, Metaware, MSVC C/C++ Compiler.
http://www.basic.si
[4.8] Visual Lisp von Autodesk
sprich "VLISP". Die Zukunft. Siehe dazu [5.3]

Sicherheit des FAS Formates:
Es gab eine längere Diskussion in beiden Newsgruppen über die Sicherheit des FAS Formates initiert von Tony Tanzillo. Anscheinend gibt es einen FAS Decompiler der "lesbaren" Quellcode erzeugt, aber diesen Decompiler gibt es nicht am Netz. Weitere Gerüchte sprechen seit Jahren von einem MNC Decompiler. Linked and Dropped FAS/VLX (kompiliert mit Optimized/Internal) ist ähnlich der Kelvination. Symbolnamen, Zeichenketten und Zahlen sind nicht so sicher wie Algorithmen.

Zusammenfassend:
Seriöse Verschlüsselung wird jetzt sogar von Autodesk mit Visual LISP unterstützt.
Kelvinierung [4.1] macht Programme nur unleserlich und schneller zu laden. Protected [4.2] Lisp Programme sind leicht zu entschlüsseln, BI4 und FAS nicht.
Mit Convert -e$GUARD verschlüsselte Lisps können nur mit Convert wieder entschlüsselt werden.


[5] AutoLISP Compiler?

Es gibt drei AutoLISP Compiler, bessere vielleicht in der Zukunft. Einige Lisp und Scheme Platformen unterstützen bereits oder werden in naher Zukunft ActiveX Unterstützung oder ein einfaches FFI bieten.

[5.1] ACOMP
ACOMP wurde bis R12 nur für die Internationalen Releases von AutoDesk offiziell unterstützt. Es war gratis und funktioniert nicht mehr ab R13 oder dem englischen R12/Windows.
Es erzeugt .BI4 Programme und benötigt ein spezielles ACADL.EXP (namens ACADLC.EXP). Mehr siehe unter http://xarch.tu-graz.ac.at/autocad/bi4 Die Compiler Warnungen zu lokalen Variablen sind besser als bei ViLL/VLisp.

[5.2] Vital Lisp Professional
von Basis Software Inc. USA. Lizenz-freie Runtime Module für R12/R13/R14 DOS/Windows/NT
Basis entwickelt Vital Lisp nicht weiter, es wurde an AutoDESK als Visual Lisp verkauft. Siehe auch [6.1] und [4.6]

[5.3] Visual Lisp von Autodesk
VLISP 4, der Nachfolger von Vital Lisp, ist intern gleich wie ViLL 3.2. Nur die Oberfläche, einige Funktionsnamen und die Hilfe wurde verbessert: vill- => vlisp-, vlx- => vl- prefixes. Einige vlax- Funktionen haben mehr Bindestriche ("konsistente Hyphenierung").
Mit AutoCAD 2000 ersetzte VLISP den alten AutoLISP Kernel. Siehe [0.1] VLX Dateien sind FAS Dateien mit optionalen DCL Resourcen für A2000 oder R14 mit geladenem RTS. A2000 FAS/VLX sind zu vorigen Versionen inkompatibel (FAS2 -> FAS4) weil neue Sprachfeatures hinzugefügt wurden (zB. getrennte Namensräume).

[5.4] Bessere: Common Lisp und Scheme
Es gibt ein ARX für Corman Common Lisp (eine einfache Textkonsole),
COM Unterstützung gibt es auch für Allegro Common Lisp 5 (ACL5), Lisp Works for Windows (LWW) und bald gibt es VisualScheme mit AutoCAD Unterstützung.
Mittels FFI ("Foreign Function Interface") kann fast jedes Lisp oder Scheme mit AutoCAD kommunizieren.
Etwas Unterstützung gibt es für Corman Lisp und ACL5, momentan verwendet ein kommerzielles Product ACL5: "Design++" von Design Power.
Siehe http://xarch.tu-graz.ac.at/autocad/bi4/.
Zusammenfassend:
AutoLISP Compiler kompilieren wie Java, VB oder manch andere Lisp Compiler zu Bytecode, die ein externes Runtime System (RTS) benötigen. Man kann keine selbstständigen Programme (EXE) erzeugen, mit ViLL und VLisp (<= R14) aber ARX Programme. Die Variablen sind verschlüsselt.


[6] AutoLISP Editoren und andere Tools/A>

[6.1] AutoLISP Editoren

Visual Lisp von Autodesk
siehe [5.3]. Das beste und empfehlenswerteste Lisp Tool. Mit AutoCAD 2000 ist es inkludiert.
Emacs für NT
Riesiger Editor und recht eigenwillig zu erlernen, aber er kann beliebig erweitert werden, mit elisp, das sehr ähnlich zu AutoLISP ist. Die Mutter aller Editoren. Gratis, für alle Platformen. Gibt es in zwei Varianten, XEmacs oder GNU ntemacs.
AutoLisp Mode auf http://xarch.tu-graz.ac.at/autocad/lsp_tools/ntemacs.html.

Vital Lisp Abgelöst von Visual Lisp, und nicht mehr erhältlich.
Es gab eine "Lite Edition" (nur Editor) für US $50, eine "Standard Edition" (+ Debugger) für US $350 und die "Professional Edition" für US $675 (+ Compiler, Zusatzbibliotheken). Siehe [5.2] AutoLISP Compiler?
LispPad
AutoLISP Editor von Tony Tanzillo. http://ourworld.compuserve.com/homepages/tonyt/LispPad.htm
Eine Vorabversion war im Buch Maximizing AutoCAD R14, http://www.group-a.com/~rusty
LispLink 2000
Kommerzieller AutoLISP Editor mit Syntax Hervorhebung, Klammernprüfung, Projekt Manager, Dialog Vorschau, Visual LISP Funktionsunterstützung und FAS Kompilierung. http://www.caelink.com/
CodeMagic
Shareware Texteditor mit AutoLISP Syntax Hervorhebung.
Visual Lisp von WSSW
Alter kleiner Windows Lisp Editor, nicht zu verwechseln mit Autodesk's Visual LISP IDE. Die alte Version 1.0 gibt's frei am Netz. Siehe [1]
WCEDIT 2.02
ADS Editor für DOS R12. Kann Lisp Code evaluieren innerhalb des Editors, frei.
Siehe [1]
CODEKEY
Alte kommerzielle DOS IDE. Interner Pretty Printer, Protector, Unprotector, Kelvinator.
ALLY 3.0 und CADET
Shareware Lisp Analyzer und Editor.
Siehe [6.2]
pred
Gratis, sehr kleiner DOS Editor mit Klammern Ausleuchtung.
At ftp://xarch.tu-graz.ac.at/pub/autocad/lsp_tools/pred.zip ADE ist so ähnlich.

Allgemeine benutzeranpassbare Programmier Editoren wieMultiEdit Pro 7, WinEdit, E!, TextPad, UltraEdit oder PFE werden auch recht häufig benutzt.
Diese unterstützen keine Lisp Syntax Prüfung oder "pretty printing", aber Suchen/Ersetzen über mehrere Dateien (einige sogar mit regulärten Audrücken) und anpassbare Syntax und Schlüsselwort Hervorhebung.

[6.2] Analyzer, Packager und Klammern Prüfer

Externe Klammern Prüfer werden eigentlich nicht mehr benötigt, das sollte im Editor passieren. Analyzers erzeugen Funktions Kreuzreferenzen, Aufruf- und 'Reverse' Aufrufbäume Packager generieren automatisch Bibliotheken aus verschiedenen Quelldateien. es gibt momentan keine 'code-walker', der COMMAND Zeichenketten Internationalisiert (Englisch->Deutsch Übersetzung), aber seit A2000 gibt es einen Lisp Analyzer (LCA).
VLISP's [5.3] Kompilierer analysiert (kompiliere mit 'full messages') und prüft Klammern (Ctrl-Alt-C).
Reini's AutoLISP Packager [new]
http://xarch.tu-graz.ac.at/autocad/lsp_tools/#Packager Browsable Funktions Cross-Referencer, reverse calling tree, erzeugt automatische Projekbibliotheken von Quelldateien. ("Packager" oder "Function Shaker")
PEI's Findvars [new]
Ähnlich dem Packager, aber analysiert nicht nur Funktionen, auch Variablen http://www.perceptual-eng.com
RapidLisp v1.0c, Shareware Lisp analyser für R14. (in deutsch)
http://www.cps.de/cad/rapidlisp/
AVC - AutoLISP Variable Collector
Freeware, findet alle undeklarierte Variablen.
http://users.actcom.co.il/sysoft/vc.htm
LCA - Autodesk's AutoLISP Compatibility Analyser
Auf der AutoCAD 2000 Migration CD. Findet automatisch AutoCAD 2000 Kompatibilitätsprobleme in LSP oder MNL Dateien.

ALLY30.ZIP (alt)
Shareware AutoLISP Analyzer, prüft Syntax und erstellt Statistiken. (wie Funktionsabhängigkeiten), siehe [1]
lck21b.zip (alt)
LCK Lisp Prüfer 2.1b (grafisch)
paran.zip (alt)
einfach
PARNCH.ZIP (alt)
einfach
Es gibt auch einige Lispprogramme, um Klammern zu zählen.

[6.3] Pretty Printers

extern:
LB.EXE
AutoDESK's offizieller Source Sode Beautifier
im SDK2 oder auf [1]
FMT202S.ZIP
Lisp, DCL und FRM Source Code Formatierer
PPRINT.LSP
im SDK2 oder auf [1]
intern:
Emacs, Visual Lisp, Vital Lisp und Codekey haben interne "Beautifier" (automatische Identierung), soviel ich weiß.


[7] AutoLISP Probleme und Bugs

Für AutoCAD 2000 und unerfahrene VLISP Benutzer siehe [0.1]. Es gibt fast keine ernsten AutoLISP Fehler (Bugs). Der Sprachinterpreter an sich (ACADL.EXE,.EXP,VL.ARX) funktioniert zweifelsohne fehlerfrei. Aber es gibt einige Einschränkungen in Zusammenarbeit mit dem Acad Subsystemm ActiceX oder Proteus (DCL). Und es gibt manchmal einige fehlerhafte SUPPORT Lisp Programme. (z.B. DDMODIFY.LSP)

Für Visual Lisp siehe unbedingt das README.txt das alle bekannten Fehler und Einschränkungen auflistet. Abstürze mit Reaktoren (SCHIEBEN, STRECKEN, ...) sind AutoCAD Fehler.

+ LDATA von Tom Berger (VLISP für R14 und A2000)
In Kürze: Verwende überhaupt keine LDATA! Sie können DXF und DWG Dateien in A2000 zerstören. Es ist auch SEHR schwierig sie wieder loszuwerden.
Listen Argumente mit DOTTED PAIRS beim Im-/Export von AutoLISP nach Visual LISP oder zurück können ihre äußeren Klammern verlieren!
Siehe das Visual Lisp README (undokumentiert in Vital Lisp)

Falsche Rückgabe von SINGLE ATOM LISTS von externen Anwendungen
Visual LISP kann nicht zwischen einer LISTE mit einem einfachem ATOM (ein Element) und einem einfachem ATOM bei der Rückgabe von einer externen ObjectARX oder ADS Anwendung unterscheiden. Es verliert dadurch eine Klammernebene, wie oben.

ENTGET mit LWPOLYLINE, HATCH (nur R14)
Die Z Koordinate (caddr (cdr (assoc 10 ele))) verweist auf eine nicht existierende Speicherstelle. Die Zahl ist zufällig und meist sogar ungültig. (Abbruch mit "floating point exception").
Abhilfe: siehe Teil 2, Kapitel [23.1]

ENTMAKE VERTEX von Terry Dotson (nur R14)
Bei (entmake) von Polyline Punkten gibt es Probleme mit Layern. Wenn man einem VERTEX Element eine Layergruppe zuordnet, muß man es auch bei dem abschließendem SEQEND Element tun! Ansonsten wird das SEQEND Element am aktuellem Layer erzeugt, der später gefroren werden kann. Beim Versuch die Polylinie zu verschieben wird ein EREGEN Fehler erzeugt und R14 stürzt ab (nur R14).

ACAD_STRLSORT: Komische Sortierreihenfolge unter Windows.
Unter Windows werden Buchstaben nicht gemäß des ASCII Zeichensatzes sortiert, sondern gemäß dem lokalen Zeichensatz

Windows: (acad_strlsort '("-1" "+1")) -> ("-1" "+1"), DOS: (acad_strlsort '("-1" "+1")) -> ("+1" "-1") Both: (mapcar 'ascii ("-" "+")) -> (45 43)

AI_PROPCHK
(ai_propchk) wurde beim R13c3 Update in (C:AI_PROP) umbenannt.
"The AutoLISP function ai_propchk has been changed to c:ai_prop so that it behaves similarly to other commands. This allows pressing return to bring back DDMODIFY if selected from toolbar."
siehe http://www.autodesk.com/support/techdocs/td11/td111682.htm

Fehlerhafte "action callbacks" in R13 DCL Funktionen bringen ACAD zum Absturz
Es gibt einen Fehler in R13, der ACAD sofort mit einem "Fatal Error" zum Absturz bringt, wenn während der Ausführung eines AutoLISP DCL "action callback" Funktion ein Fehler passiert, zb. wenn die Funktion undefiniert ist. Technisch ist das kein AutoLISP Fehler, eher von ACADAPP, aber wir nennen es trotzdem einen AutoLISP Fehler.

Man kann sich seit R13 nicht mehr auf den Bitwert 64 im Flag 70 in Symboltabellen verlassen.

Was noch? Siehe die unoffizielle AutoCAD Bugliste zusammengestellt von Steve Johnson betr. mehr fehlerhafte AutoLISP Programme und Auswirkungen auf http://www.cadonline.com/exclusive/bugs/bugwatchlist.htm

Protected Lisp Funktionen
Von R13 bis R13_c3 blieben "Protected LISP" Funktionen nicht als geschützt markiert im Speicher! Unserer Meinung nach sollte dieses Problem allen klargemacht werden, um nicht Entwickler im Glauben zu lassen, daß ihre Funktionen geschützt seien. Dieser FAQ Punkt hat größere Problem im moderierten AutoCAD CompuServe Forum verursacht, daß uns daraufhin veranlaßt hat, das FAQ daraus rückzuziehen. Es gibt ordentliche Verschlüsselungsmethoden. Siehe [4]

Beschränkte Anzahl von offenen Auswahlsätzen
Diese wurden in temporären Dateien gespeichert. Lösche nicht gebrauchte Auswahlsätze mittel setzen auf NIL und führe (gc), den Garbage Collector, aus, um diese Dateien zu schliessen.
Die maximale Anzahl von geöffneten Dateien hängt vom Betriebssystem ab, z.B. in DOS vom Wert FILES= in CONFIG.SYS
R13 hat die Anzahl verbessert.

Zahlen: Wertebereich und numerische Genauigkeit
Ganzzahlen (Integer) sind intern longint fixnums (signed long int, 32-bit, +-2147483647), aber die Schnittstelle von AutoLISP nach AutoCAD akzeptiert nur 16-bit kurze Ganzzahlen (signed short int), -32768 .. +32767, weil AutoCAD nur short int benötigt.

Gleitkommazahlen (Float, REAL) sind vom Typ double (64-bit IEEE). (+- 1.7e308, ca. 15 Stellen Genauigkeit) Alle internen numerischen Berechnungen in AutoLISP und AutoCAD arbeiten mit dem selben Format, das ausreichen sollte. Wenigstens die ersten 14 Stellen sind exakt.

Aber mit häufigen trigonometrischen Berechnungen treten oft Rundungsprobleme auf, so daß es besser ist AutoCAD Funktionen wie (trans) zu verwenden und Punkte mit (equal pt1 pt2 1e-6) ; 0.000001 Rundungsfehlertoleranz anstatt eines simplen (equal pt1 pt2) zu verwenden, besonders bei trigonometrischen oder AutoLISP Matrix Berechnungen.

Häufige Probleme enstehen aus der Verwechslung der extakten Zahlen und der inexakten Zeichendarstellung in der Befehlszeile. Die angezeigte Zahl ist immer die Stringrepresentation, die den LUPREC und DIMZIN Variablen unterliegt.

Siehe http://xarch.tu-graz.ac.at/autocad/docs/lisp-genauigkeit.txt oder http://www.autodesk.com/support/techdocs/td30/td301207.htm.

VB: In letzter Zeit häufen sich mysteriöse Problem mit gewissen Automation controls. Numerische Genauigkeit und länderspezifische Einstellungen (Komma anstatt Punkt) scheinen ungewollte Seiteneffekte in AutoLISP Zahlen zu zeigen. Eine allgemeine Erklärung oder Lösung harrt noch aus. (ServicePacks?) Das betrifft besonders Länder mit Komma als Dezimaltrennzeichen. (Ähnlich dem bekannten ACIS 60006 Problem, aber ohne Crash).

ACOMP's (EQ) Problem [alt]
Mit [5.1] ACOMP kompilertem Code muß man darauf achten, daß die Funktion (EQ) wie in einem echtem Lisp viel strenger vergleicht, als in reinem AutoLISP oder VLISP. In AutoLISP (eq "1" "1") ist T aber in acomp kompiliertem Code NIL.

Folgende Punkte sind keine Fehler die AutoLISP zum Absturz bringen oder falsche Ergebnisse retournieren. Sie sind mE. lediglich eine schlechte Sprachimplementierung:

AND und OR sollten den Rückgabewert des letzten nicht-NIL Argumentes zurückgeben und nicht nur T. Siehe http://xarch.tu-graz.ac.at/autocad/docs/and-bug.html

MAX und MIN sollten auch Zeichenketten bearbeiten, weil < und > auch für Zeichenketten funktionieren.

siehe ACAD_STRLSORT oben

Für Stack Overflow Fehler siehe [14]


[8] Sortieren mit AutoLISP

In Kürze: Benutze die eingebauten Funktionen VL-SORT und ACAD_STRLSORT.
aber Achtung: VL-SORT entfernt doppelte Einträge (die EQ sind)!

Ich habe eine Übersicht über Sortiermethoden auf http://xarch.tu-graz.ac.at/autocad/lisp/#sort aufgestellt.

In LISP mit den Daten als einfach verkettete Liste ist die beste Methode entweder merge sort (in (str-sort) in AutoDesk's TABLES.LSP Beispiel) oder tree sort. Es gibt Lisp Code für shell-sort, bubble-sort, insertion-sort, quick-sort für alle Datentypen, Listen, Listen von Listen oder inidices zu Listen. In Lisp übergibt man einfach das Vergleichsprädikat an die Funktion, und kann daher alle Datentypen verarbeiten.

  (sort data method)    ;method: Funktion mit 2 Argumenten, wie "kleiner als"
                        ;Vorgabe für Zahlen oder Strings: '<
Benchmarks, siehe http://xarch.tu-graz.ac.at/autocad/lisp/sort/ur_sort.lsp: Sortiere 100 zufällige Elemente: bubble sort : 13.639008 sec/ 30.08% insertion sort: 13.368042 sec/ 29.48% (schnell für vorsortierte Listen) shell sort : 13.478973 sec/ 29.73% (schlechte Implementierung) merge sort : 2.232971 sec/ 4.92% quick sort : 2.433960 sec/ 5.37% vlx-sort : 0.099976 sec/ 0.22% (Vital LISP intern, auch VLISP) acad_strlsort : 0.089996 sec/ 0.20% (AutoLISP intern, nur Strings) Interessant wären noch Benchmarks für vl-sort, vl-isort, STDLIB std-fast-sort, std-sort, std-stable-sort und Vladimir's neuer merge-sort


[9] Rekursion

Dies ist eine nicht häufig gestellte Frage, aber ein interessantes Thema, weil LISP selbst rekursiv definiert ist und es oft der einfachste Weg ist um Probleme zu beschreiben und zu lösen.

Es gibt einige gute Texte und Beispiele über Rekursion auf http://xarch.tu-graz.ac.at/autocad/lisp/ besonders das http://xarch.tu-graz.ac.at/autocad/lisp/recursive.html Tutorial von Dennis Shinn.

Es erklärt in voller Länge

(defun FACT (n) (cond ((zerop n) 1) (T (* n (fact (1- n))))))

Anmerkung: Von dieser Funktion gibt es auch ein Beispiel einer selbst-modifizierenden Funktion, auf http://xarch.tu-graz.ac.at/autocad/lisp/self-mod.lsp


[10] Iteration mit MAPCAR,...

Wie mit der Rekursion ist das eine nicht so oft gestellte Frage, aber oft auch genauso schwer zu verstehen.
Iterative Ausdrücke in AutoLISP sind: WHILE, REPEAT, FOREACH und MAPCAR. Wir verwenden diese in diesem FAQ oft weil sie kurze Audrücke erlauben.

Eine kurze Einführung in LAMBDA, QUOTE und MAPCAR... von Vladimir Nesterowsky:

>> "Es gibt 14 Wege und 12 Schweine. >> Wie kommt es zu 24 Enten?" >> Gibt eine Lisp Funktion, die es mir erlaubt diese zwei Zeilen Text zu nehmen, >> die Zahlen daraus zu extrahieren, um dann zB. jede Zahl um 2 zu erhöhen? >> Aber der Text sollte intakt bleiben Das ist ein Weg. (Ich bin sicher es gibt noch andere) (defun MULT2 (strng) ; von Vladimir Nesterowsky (strlgather (mapcar '(lambda (s / n) (if (zerop (setq n (atof s))) s (rtos (* n 2)))) (strlparse strng " ")) ; trenne string an spaces " ")) ; und verbinde wieder mit spaces

Dieses Beispiel ist erklärt in http://members.tripod.com/~vnestr/mapcar.txt

;;; Wechselt Zeilen mit Spalten in einer Matrix (defun TRANSPOSE (l) ; von Doug Wilson (apply 'mapcar (cons 'list l)))

ist erklärt in http://xarch.tu-graz.ac.at/autocad/lisp/transpose.002.html


[11] Mein LISP wird beim STARTUP nicht mehr geladen!

LISP Programme können beim Startup mit LOAD in ACAD.LSP automatisch geladen werden. Einige LISP Funktionen, die aus einem Menü aufgerufen werden, sollen aus der korrespondierendem <menu>.MNL datei geladen werden. Diese <menu>.MNL Datei soll wiederum ACAD.MNL laden, wenn eine anderes Hauptmenü als ACAD verwendet wird.

LISP Funktion die AutoCAD Befehle beim Startup aufrufen müssen in einer S::STARTUP Funktion in ACAD.LSP definiert sein. Diese Funktion wird bei der Initialisierung automatisch aufgerufen. Sonst kommt es zu den bekannten "Befehlslistenunterbrechung (6 . 2)" Fehlern.

Wenn der Dateiname ohne .LSP Erweiterung bei (LOAD) angegeben wird, wird .LSP angenommen. Wenn kein Pfad angeben wird, wird er übliche AutoCAD Bibliotheks Pfad durchsucht, der so definiert ist:

  1. ) Das aktuelles Verzeichnis
  2. ) Das Verzeichnis mit der aktuellen DWG Zeichnung
  3. ) Alle Verzeichnisse definiert in der ACAD Umgebungsvariable (Voreinstellungen, SUPPORT Pfade)
  4. ) Das ACAD.EXE Verzeichnis
Wenn dein Programm nicht mehr automatisch geladen wird, überprüfe alle diese Punkte.

Mit ACADLC (von ACOMP) und dem Englischem Release von AutoCAD R12 wird ACAD.LSP nicht mehr automatisch geladen. Daher füge den folgenden Befehl an ACAD.MNL an: (load "ACAD")

Beispiel ACAD.LSP:

;;;ACAD.LSP ;;; Freddy Bär, 12.12.94 (load "init" -1) ; Lade meine Tools, bei Fehler gehe weiter (defun S::STARTUP () (load "new-end" -1) ; Definiere END um )

Das -1 Argument in LOAD verhindert eine Fehlermeldung beim Laden, es wird lediglich -1 zurückgegeben, aber die Ausführung nicht abgebrochen. -1 ist nur ein Beispiel, jeder Wert ist möglich.

Beispiele um S::STARTUP zu erweitern. Mit Visual Lisp/Vital LISP funktioniert das nicht. Entweder definiere S::STARTUP mit DEFUN-Q (VLISP 2000), kompiliere S::STARTUP nicht (VILL) oder lade in S::STARTUP eine Liste von "hooks" -benutzerdefinierten Funktionen- die zur Laufzeit eingefügt und aufgerufen werden können.

(defun MY::STARTUP () ;Deine startup funktionen hier ;.. (princ) ;Unterdrückt Ausdruck des Rückgabewertes ) (setq S::STARTUP (if (and S::STARTUP (listp S::STARTUP)) ;wenn schon in ACAD.LSP definiert ; oder woanders (append S::STARTUP (cdr MY::STARTUP)) ;hänge deine Funktion an oder MY:STARTUP)) ;führe deine Funktion aus

oder noch einfacher:

(if (and S::STARTUP (listp S::STARTUP)) (setq S::STARTUP (append S::STARTUP (list func '(princ)))) (setq S::STARTUP (list nil func '(princ)))) Vladimir Nesterovsky:

The main difference now in A2K+ versions is that functions defined with DEFUN are now a new datatype, USUBRs, and not lists as before. But when the function is defined with DEFUN-Q, it is a list still, like in previous versions.

Here's the utility function to use that works in both cases:

 (defun plug-into-startup (funcname) ;by VladimirNesterovsky
   "to be called with quoted function name"
   (eval (list
     'defun 's::startup ()
     (if s::startup (list (list 'quote s::startup)))
     (list funcname))))

so if you have all your startup code packed into one routine

 (defun my-startup ()
   (alert "My Startup"))

you make it work with the call

 (plug-into-startup 'my-startup)

inside your code that is executed on startup, e.g. acaddoc.lsp or whatever.

Siehe auch das nächste Kapitel [12] Wie funktioniert Autoload?


[12] Wie funktioniert Autoload?

Wie lade ich meine Programme mit AUTOLOAD? Wie laden sich meine Programe automatisch?

Du kannst entweder deine ganzen Programme beim Starten in den Speicher laden. (siehe vorher [11] Mein LISP wird beim STARTUP nicht mehr geladen!) Das braucht mehr Zeit und Speicher beim Startup, oder Du kannst deine Funktionen mit dem AUTOLOAD Mechanismus laden.
Seit R14 gibt es ein neues Autoloading Schema für ARX Programme: "DEMAND-LOAD" mit einigen Registry Einstellungen.

Sonst werden alle AUTOLOAD Funktionen in SUPPORT/ACADRxx.LSP definiert.

;;;===== AutoLoad LISP Anwendungen ===== ... (autoload "dline" '("dline" "dl")) ...

Das definiert 2 kurze Befehle DLINE und DL (2. Argument in der Liste) und erst wenn der Benutzer diese Befehle zum ersten mal aufruft, wird das Programm DLINE.LSP automatisch geladen, die zwei Befehle umdefiniert und aufgerufen. Ein sehr kurzer Autolader kann wie folgt definiert werden:

(defun C:DL () (load "DLINE")(C:DL))

Wegen der Fehlerbehandlung (Ctrl-C, Ladefehler, falsche Datei oder Pfad) ist die wirkliche Definition etwas komplizierter.

Nach dem erstem Aufruf wird die Funktionsdefinition überschrieben mit der Definition in DLINE.LSP

Vorteile von Autoload:
Startup ist schneller, weil nicht alle Programme geladen werden. Das kostest Speicher und Scuhzeit in den Verzeichnissen. Mit dem Aufruf von (autoload) wird lediglich die kurze "wrapper" Funktion wie oben definiert.

Weniger Speicher.

Nachteile:
Bei Fehlern in deinem Program kommt es zu Endlosschleifen, und es komm nur nach Ctrl-C oder einem Stack Overflow zu einem Abbruch.
Anmerkung: Mit acomp kompiliertem Code ist sogar Ctrl-C unmöglich! Füge einen Aufruf zu einer unkompilierten Funktion mit (princ) ein.

Man muß alle Programmnamen und -dateien in der Autoload Definition definieren und warten. Bei Änderungen der Funktions- oder Dateinamen kann es zu obigen Problemen kommen.

Wohin mit meinen (autoload) Definitionen?
Nicht in ACADR13.LSP, (resp. die versionspezifische Datei) und nicht ACAD.LSP! Wir empfehlen eine eigene private Initialisierungsdatei. ACAD.LSP wird oft von anderen Anwendungen geändert. Und ACAD.LSP soll ziemlich klein und übersichtlich bleiben.

z.B. verwende ein eigenes AUTOLOAD.LSP oder INIT.LSP, das von ACAD.LSP oder anders geladen wird. z.B von einem privaten <:menuname>.MNL siehe [11] Mein LISP wird beim STARTUP nicht mehr geladen!

Es wird noch einmal darauf hingewiesen, daß niemand SUPPORT/ACADR13.LSP (resp. die versionspezifische Datei) verändern darf! ACAD.LSP wird bei AutoCAD Patches nicht verändert und ist daher sicher. Mit dem R13c4 Patch wurde ACADR13.LSP verbessert, das Patchen wird aber bei modifierten Dateien abgebrochen!


[13] Wie kann ich eine variable Anzahl von Parametern an Lispfunktionen übergeben?

Mit reinem AutoLISP ist es nicht möglich so eine Funktion zu definieren.

Man kann entweder alle Argumente in einer Liste übergeben, so wie hier:

;;; akzepiert eine beliebige Anzahl von Argumenten belibeigen Typs (defun MY-PRINC (x) ;; einfache Version, siehe auch SDK2: PRINTF.LLB oder weiter unten. (if (listp x) (mapcar 'princ x) (princ x)))

Oder man die Funktion in ADS oder ObjectARX schreiben und nach AutoLISP exportieren. Dann kann man schreiben:

(ads-print "Hello " "World " 1 2 3) oder sogar (ads-printf "Hello %s %i %i" "World" 2 3)

Siehe Reini Urban's und Vladimir Nesterovsky's ADS Code in http://xarch.tu-graz.ac.at/autocad/ads/ für Implementierungen zu den obigen Beispielen.

Offizielle Wünsche wurden bereits an Autodesk gerichtet &optional als AutoLISP Spracherweiterung einzuführen.


[14] Wie vermeide ich Stack Overflows?

neu: In old AutoLISP the stack size was hardcoded. It couldn't be extended, but its size should be sufficient for most purposes. In the Visual Lisp IDE the stack overflow is simulated at 984 recursions, on the A2000 commandline or loaded programs outside the IDE there's no overflow anymore. This is dangerous on recursion errors of yours, see [9]. Most stack overflow errors occur on a program error of yours, preventing the system from falling into an endless loop, or from using recursive functions on large lists. Therefore you are limited to quite short lists with recursive functions and old versions.

alt:
In AutoLISP die Stack Größe ist fixiert pro Release. Sie kann nicht erweitert werden, aber die Größe sollte für alle Anwendungen ausreichen.

Die meisten Stack Overflow Fehlermeldungen passieren in fehlerhaften rekursiven Funktionen (falsche Abbruchbedingungen) und werden erzeugt um Endlosschleifen zu vermeiden oder wenn die Rekursion zu tief ist, zB. bei zu großen Listen, die rekursiv abgearbeitet werden. Die Länge solcher Listen ist beschränkt auf max. ca. ~200 Elemente mit rekursiven Funktionen in reinem AutoLISP.

Man diesen Kennwert nicht vergrößern mit weniger lokalen Parametern in der rekursiven Funktion! Benutze nicht APPLY, EVAL oder MAPCAR um die Funktion rekursiv aufzurufen, wiel sie Stack kosten. Tail-Rekursion hilft auch nicht.

Sonst muß man die problematische rekursive Funktion in eine iterative Version umschreiben, was aber kein Problem sein sollte. (Es gibt ein mathematisches Theorem, das sagt, daß jede Rekursive in Iteration umgewandelt werden kann. Tail-rekursive sogar automatisch) Iterative Versionen verwenden meist Hilfsvariablen aber können auch Stack ähnliche Funktionen wie (push) und (pop) verwenden. Diese Version speichert den Stack auf dem Heap (AutoLISP node space), dessen Größe nur vom verfügbaren virtuellem Speicher begrenzt ist.

Man die max. Stackgröße mit folgender einfacher Funktion testen:

;;; Liste von n natürlichen Zahlen: (defun intlst (l n) (cond ((zerop n) l) (T (intlst (cons (1- n) l) (1- n))))) ;Und jetzt: (setq n 100)(while (intlst nil (setq n (+ 10 n)))(print n)) Mit AutoLISP in R12/DOS wird der Fehler mit (intlst nil 138) erzeugt, mit A13/Win mit (intlst nil 240), in acomp bi4's mit (intlst nil 1240), in der Vital/Visual LISP IDE mit (intlst nil 984). Mit DOS-Extended Lisp Version (R10c10) konnte man den Lisp Stack mit der Environment Variable LISPSTACK setzen. acomp für R10 hatte COMPSTACK. Mit dem Vital LISP oder Visual LISP RTS bzw. in A2000 (aber nur außerhalb der IDE) ist die Stackgröße unlimitiert.

Die Konvertierung in die iterative Version bringt folgendes Resultat:

(defun INTLST (n / l) (repeat n (setq l (cons (setq n (1- n)) l)))) ;furchtbar, aber es funktioniert!


[15] (command "ROTATE3D") funktioniert nicht! Warum?

Einige Befehle sind keine internen AutoCAD Befehle. Sie sind entweder einfache AutoLISP Funktionen deren Namen mit C: beginnen, oder C: Funktionen definiert in ADS. Nur Rx Anwendungen können echte interne Befehle exportieren und mit dann mit (command) aufgerufen oder transparent verwendet werden.

Viele solche Befehle können in ACADRnn.LSP unter AUTOLOAD gefunden werden. (Siehe auch "[12]")
Alle diese C: Funktionen müssen wie (C:ROTATE3D) anstatt mit (command "ROTATE3D") aufgerufen werden.

Allerdings, ADS Funktionen können optionale Argumente akzeptieren. Siehe das Handbuch für Benutzeranpassungen.
z.B. (c:rotate3d ss p1 p2 angle) ist gültig, auch (rotate3d ...)


[16] Lisp Programme über mehrere Zeichnungen laufen lassen

"I am having trouble getting a lisp file that will open a drawing and continue running. Once the new drawing is opened the Lisp file ceases to exist in the Autocads memory. It has to be reloaded to recognise the commands."
AutoLISP wird nach dem Öffnen jeder Zeichnung neu initialisiert. Es gibt einige Tricks um das zu bewerkstelligen:
  1. Ein Script, das mehrere Zeichnungen öffnet: MYSCRIPT.SCR: (load "mylisp") _QSAVE _OPEN !nextdwg (load "mylisp") _QSAVE _OPEN !nextdwg ...
  2. Externe 3rd-party Software wie RunLisp oder DDSCRIPT können das automatisieren.
  3. R14 hat ein neues Feature 'Persistent LISP'.
    Siehe 'Preferences-Compatibility-Persistent Lisp'
  4. Vital LISP hatte eine eingebaute Variable um als Persistent Lisp zu arbeiten:
    (setq *VILL-NEW-FULL-INIT* nil) ;behält Symbolwerte zwischen Sessions.
  5. auch mit Visual LISP: (setq *VLISP-NEW-FULL-INIT* nil)
  6. AutoCAD 2000 ist MDI, das ermöglicht daneben noch bessere Möglichkeiten.


[17] Wie exportiere ich interne R14 Visual Lisp Funktionen nach AutoLISP/AutoCAD?

C: Funktionen werden automatisch nach AutoLISP exportiert. Normale VLISP/VILL Lisp Funktionen entweder dynamisch mit (vl-acad-defun 'myx-funcname) oder statisch mit einem speziellem Kompiler PRAGMA, entweder in der LSP Datei oder besser in der GLD ('global declarations') datei. Besser ist es einen speziellen Prefix für solche Funktionen zu verwenden. .GLD: (AUTOEXPORT-to-ACAD-PREFIX ;| Namens Prefixe für autoexportierte Funktionen (strings) |; "myx-*" ) oder einzeln: .LSP: (pragma '((export-to-acad myx-func1 myx-func2))) Beachte: Es gibt bekannte ADS Kommunikationsprobleme in VLISP/VILL mit Listen von 'atomic symbols' und 'dotted pair' Listen in Argumenten und Rückgabewerten von solchen Funktionen. See [7].

Funktionen, die von externen ADS/ARX Anwendungen in Deiner Lispanwendung aufgerufen werden, müssen mittels XDF Dateien (oder auch dynamisch) deklariert werden.

Symbole (Variablen) deren Werte in Visual Lisp geändert werden und die auch in AutoLISP oder AutoCAD (im Menü zB.) verwendet werden, müssen im Kompiler als extern markiert werden: (pragma '((not-localize myx:symbol)))
und die Werte mit
(vlisp-export-symbol 'myx:symbol) exportiert werden,
jedesmal wenn der Wert in Visual Lisp geändert und die Kontrolle zurück zu AutoCAD übergeben wird, um in AutoLISP oder AutoCAD (!myx:symbol) den aktuellen Wert zu haben.

Mit AutoCAD 2000 ist es viel einfacher, in getrennten Namensbereichen muß kann man die Funktion mit VL-DOC-SET exportieren.
Siehe auch http://www.autodesk.com/support/techdocs/td17/td175363.htm


Teil 2: Beispiele, Programme


[20] Allgemeine Hilfsfunktionen

Für eine komplette Bibliothek von Hilfsfunktionen siehe die freie AutoLISP Standard Library auf http://xarch.tu-graz.ac.at/autocad/stdlib/. Andere aber schlechtere Funktionen gibt es auch auf anderen AutoLISP Seiten [1] oder waren im alten R12 SDK von Autodesk [1.2]

Hier sind einige wichtige Definitionen um die Hilfestellung in den Diskussiongruppen zu erleichtern. Diese sollten im Allgemeinwissen sein, sowie zum Beispiel die berühmte DXF Funktion, die so definiert ist
(defun DXF (grp ele) (cdr (assoc grp ele))) oder die spezifische Erweiterung (GETVAL), die auch mit ENAME und (ENTGET) Listen funktioniert.

[20.1] Listen Funktionen

Siehe besonders http://xarch.tu-graz.ac.at/autocad/stdlib/STDLIST.LSP
Einige nützliche Beispiel Funktionen für Listen sind: ;;; CONSP - nicht leere Liste? (defun CONSP (x) (and x (listp x))) ;;; POSITION - Rückgabe des Index des ersten gefundenen Elementes in der Liste, ;;; Basis 0, oder nil wenn nicht gefunden. ;;; (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))) ;;; REMOVE - "Entfernt" eine Element aus einer Liste (Doubletten erlaubt) ;;; dh. besser: "Rückgabe einer Kopie der Liste ohne dieses Element" ;;; (remove 0 '(0 1 2 3 0)) -> (1 2 3) (defun REMOVE (ele lst) ; von Serge Volkov (apply 'append (subst nil (list ele) (mapcar 'list lst)))) ;;; REMOVE-IF - bedingtes "remove" aus einer flachen Liste. "Alle die" ;;; Funktionsargument func benötigt exakt ein Argument. ;;; (remove-if 'zerop '(0 1 2 3 0)) -> (1 2 3) ;;; (remove-if 'numberp '(0 (0 1) "")) -> ((0 1) "") (defun REMOVE-IF (func from) (cond ((atom from) from) ;nil oder Symbol (gib das zurück) ((apply func (list (car from))) (remove-if func (cdr from))) (t (cons (car from) (remove-if func (cdr from)))) ) ) ;;; REMOVE-IF-NOT - behalte alle Elemente auf die das Prädikat zutrifft. ;;; Sage: "behalte wenn". Es geht auch iterativ, nicht nur rekursiv. ;;; [fixed, thanks to Serge Pashkov, in FAQ-CODE.LSP it was okay] (defun remove-if-not (pred lst) ; von Vladimir Nesterowsky (apply 'append (mapcar '(lambda (e) (if (apply pred (list e)) (list e))) lst))) ;;; ADJOIN - cons'e neues Element zu Liste, wenn nicht bereits enthalten. ;;; Trick: Akzepiert auch gequotete Liste ("destruktiv"). ;;; (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) ) ;;; ROT1 - Stelle das erste Element ans Ende. Einfache Version ;;; "Rotiere um eins" (defun ROT1 (lst) (append (cdr lst) (list (car lst)))) ;;; BUTLAST - Liste ohne dem letzten (defun BUTLAST (lst) (reverse (cdr (reverse lst))))

[20.2] Zeichenketten

Einige nützliche String (Zeichenketten) Funktionen sind:
Siehe evtl. auch http://xarch.tu-graz.ac.at/autocad/code/vnestr/strtok.lsp oder in Deinem AI_UTILS.LSP. Du wirst sie speziell für DCL Funktionen brauchen.

[20.3] Symbol -> String Konvertierung

Die inverse Funktion zu (READ) nennen wir (SYMBOL-NAME). Mit VLISP benutze VL-SYMBOL-NAME. Frage nicht warum, aber die folgende Funktion ist die einzige kompatible Möglichkeit für alle Ausdrücke oder Elementtypen: ;;; SYMBOL-NAME konvertiert den Symbolnamen zu einer Zeichenkette ;;; Konvertiert jeden gültigen Lisp Ausdruck (auch Listen) zu der gedruckten ;;; Repräsentation ;;; (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. Dateiname, sollte gelöscht werden (setq f (open tmp "w"))(princ sym f) (close f) (setq f (open tmp "r") str (read-line f) f (close f)) str ) Für reine Lisp Symbole gibt es bessere Tricks, erklärt von Christoph Candido: http://xarch.tu-graz.ac.at/autocad/news/symbol-string.txt

[20.4] AutoCAD Element Funktionen

;;; Rückgabe des ertsen Gruppenwertes eines Elementes. ;;; Wie die bekannte (DXF) Funktion, aber akzeptiert alle möglichen ;;; Element Repräsentationen (ENAME, entget Liste + entsel Liste) ;;; Beachte: Nicht für 10'er Gruppen in LWPOLYLINIEN geeignet! (defun GETVAL (grp ele) ;"dxf Wert" eines Elementes (cond ((= (type ele) 'ENAME) ;ENAME (cdr (assoc grp (entget ele)))) ((not ele) nil) ;leer ((not (listp ele)) nil) ;ungültiges ele ((= (type (car ele)) 'ENAME) ;entsel Liste (cdr (assoc grp (entget (car ele))))) (T (cdr (assoc grp ele))))) ;entget Liste ;;; zB: (gettyp pline) => "POLYLINE" (defun GETTYP (ele) ;Rückhabe des Typs (getval 0 ele)) ;;; => ENAME ;;; Konvertiert das Element zum Typ ENAME (defun ENTITY (ele) (cond ;akzeptiert: ((= (type ele) 'ENAME) ele) ; ENAME ((not (listp ele)) nil) ; error: keine Liste ((= (type (car ele)) 'ENAME) (car ele)) ; entsel Liste ((cdr (assoc -1 ele))) ; entget Liste oder nil ) ) ;und jetzt lediglich: (defun getval (grp ele) (cdr (assoc grp (entget (entity ele))))) ;;; Ist Element ein ...? ;;; zB: (istypep ele "TEXT") (defun istypep (ele typ) ;prüfe Typ (= (gettyp ele) typ)) ;;; Ist Element eines von ...? ;;; zB: (istypep ele '("TEXT" "ATTDEF")) (defun ISTYPEP (ele typ) ;besser, akzepiert mehrere Typen (cond ((listp typ) (member (gettyp ele) typ)) ((stringp typ) (= (gettyp ele) typ)) ;Typ = großgeschrieben, (T nil))) ; wcmatch wäere zu langsam ;;; zB: (getpt (entsel)) => ( 0.1 10.0 24) (defun GETPT (ele) ;Rückgabe des Startpunktes jedes Elementes (getval 10 ele)) ;Gruppe 10 ;;; zB: (getflag pline) => 1 wenn geschlossen (defun GETFLAG (ele) (getval 70 ele)) ;same with the entity flag ;;; Ist Bitwert val im Flag gesetzt? ;;; zB: (flagsetp 1 pline) => T wenn geschlossen ;;; zB: (flagsetp 16 vertex) => T wenn Spline Kontrolpunkt (defun FLAGSETP (val ele) (bitsetp val (getflag ele))) ;;; zB: (bitsetp 4 12) => T ;Bitwert 4 (=2.Bit) in 12 (=4+8) gesetzt (defun BITSETP (val flag) (= (logand val flag) val)) ;;; Konvertiert Auswahlsatz zu Liste. Langsam, aber einfach zu benutzen. ;;; Beachte: Es ist gut AI_SSGET zu benutzen, wegen Elementen auf ;;; gesperrten Layern. ;;; zB: (sslist (ai_ssget (ssget))) ;;; oder (mapcar 'entupd (sslist (ssget "X" '((8 . "TEMP"))))) ;;; - regeneriert alle Elemente auf Layer TEMP (defun SSLIST (ss / n lst) (if (= 'PICKSET (type ss)) (repeat (setq n (sslength ss)) (setq n (1- n) lst (cons (ssname ss n) lst))))) ;;; 'Mappe' eine Funktion über jedes Element im Auswahlsatz, in umgekehrter ;;; Richtung. Schneller, aber schwerer zu verstehen. Siehe [22.2] ;;; [umbenannt von SSAPPLY zu SSMAP wegen der STDLIB] ;;; zB: (ssmap 'entupd (ssget)) ; regeniere einige Elemente (defun SSMAP (fun ss / n) (if (= 'PICKSET (type ss)) (repeat (setq n (sslength ss)) (apply fun (list (ssname ss (setq n (1- n))))))))


[21] Beispiel Programme:

[21.1] Ersetze Texte global, mehrere Polylinien, Layer Utilities, Datumsstempel

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. Siehe auch [1] and some code at [22], [23], and [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 professional plotstamp routine is here: http://ourworld.compuserve.com/homepages/tonyt/plotstmp.htm

[21.2] Starte den Plotdialog von Lisp aus. DDE oder ActiveX

(initdia)(command "_PLOT")

Der Aufruf der PLOT Dialoges von AutoLISP bevor R14 war nur möglich unter Windows, z.B mit LISPPLOT für R12/13 von Mike Dickason. Das fütterte den Tastaturbuffer mit Tasten. http://www.cadalog.com/cadalog/files/lispd-l/lspplw.zip oder auch ftp://ftp.mcwi.com/pub/mcwi/lisp/winplt.lsp
Oder erzeuge eine Skriptdatei und rufe sie vom Ende des Lispprogrammes aus auf. Das zeigt aber nicht den Dialog.

Xiang Zhu: Man kann "ddelisp" unter Windows verwenden:

;;; [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))) Für R12 nimm "autocad.dde" als Server Name. Dann kann man von Lisp oder vom Skript aus einfach (ddecmd "_plot ") aufrufen. DDECMD gibt NIL bei einem Fehler oder die Zeichenkette zurück.
The string is just like what you type under the command prompt from keyboard, so you need put a space or a return, which is "^13" here, to end the string.

Besides, the function is very useful in the following situation: If within a lisp, you need to call an AutoCAD transparent command like LAYER, normally you will use (command "_layer"), but after using this line, the lisp own will not be transparent. Using the function, you will solve this problem.

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:

;;; 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) ; define window (pts in WCS) (vla-PlotPreview plt 1) ; 0 for partial, 1 for full (vla-PlotToDevice plt "Default System Printer") ; if it exists Mit R14 wurde INITDIA eingeführt, das vor allen Dialogen angewandt werden kann.
(initdia)(command "_PLOT")
Mit A2000 geht nur mehr OLE (die VLA- Methoden), DDE wird von Microsoft nicht mehr unterstützt.

[21.3] (entmod) und (entmake) für Layer, ohne (command "_LAYER"...)

ENTMOD a layer
I try to change a layer property without calling COMMAND function inside a lisp routine.

Under 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")) ;;; 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] Auswahl von mehreren Dateien mit Lisp? (wie zB. in DATEIEN - Entsperren)

At http://xarch.tu-graz.ac.at/autocad/progs/MGETFILD.ZIP is a lisp helper routine to select multiple files with DCL.
You will also need DOSLIB from McNeel to access the dos specific directory functions. http://www.mcneel.com/mcneel/doslib.html

[21.5] Ersetze mehrere Blöcke

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
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/find.htm Keyword "Block Replace"
=> http://www.cadalog.com/cadalog/files/lispr-z/replace.zip (this one is the best)

[21.6] (vports), VIEWPORT Element, Pixel Konversion
Das VIEWPORT Element:
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

[new]: http://www.ez-sys.net/~coopfra/lisp.htm#view has also some tricks.

How to change viewports in AutoLISP?
with (setvar "CVPORT" vport-id) siehe 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")))) [new] Note also the "Pixel Off by One" Errors in AutoCAD, described by Vibrant, here: http://xarch.tu-graz.ac.at/autocad/news/pixel-off-by-one-error.txt

[21.7] Auswahl aller sichtbaren Elemente: ZOOM Koordinaten
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 from the entity 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 [doc fixed] (defun maptrans0-1 (pts)(mapcar '(lambda (pt)(trans pt 0 1)) pts))
[21.8] Wie schreibe ich die XYZ Daten von Elementen in eine Datei?

;;; 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


[22] Block Attribute

[22.1] Zugriffsmethoden zu Block Attributen mit AutoLISP
Prüfe alle Unterobjekte nach dem INSERT objekt bis zum richtigen Attribut. Siehe http://xarch.tu-graz.ac.at/autocad/stdlib/STDENT.LSP ;;; gibt entget Liste des Attributes 's' (STRING) in Element ele (ENAME) zurück ;;; oder nil wenn nicht gefunden (defun ATTELE (ele attname / rslt) (if (and (istypep ele "INSERT") (= (getval 66 ele) 1)) (progn (setq ele (entnext (entity ele))) (while (and ele (istypep ele "ATTRIB")) (if (= (strcase (getval 2 ele)) (strcase attname)) (setq rslt (entget ele) ele nil) ;break the loop (setq ele (entnext ele)) ) ) ) ) rslt ) ;;Beispiel: (attele (entsel) "TEST") ; returns entget-list of ; attribute "TEST" if the block has it BTW: Noch etwas trickreichere Funktionen sind GET und EDLGETENT von 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-verticies-and-bulges (pline-ename) (get '(10 42) (cdr (edlgetent pline-ename)))) verfügbar unter http://members.tripod.com/~vnestr/

[22.2] Wie ÄNDERE ich Block Attribute? DATESTAMP.LSP
Für ein einfache automatische Datum-Stempel Lösung rufe entmod mit der entget-liste des DATUM Attributes in deinem PLANKOPF Block. Verwende dazu (attele) wie unten. ;;; Ändere den Attributwert in Block ele auf 'new'. (defun ATTCHG (ele attname new / b) (if (setq b (attele ele attname)) (entmod (subst (cons 1 new) (getval 1 b) b)))) ;;; Ändere alle DATUM Attribute in allen eingefügten PLANKOPF* Blöcken (defun C:DATESTAMP () (ssmap '(lambda (ele) (attchg ele "DATUM" (heute)) (entupd ele) ) (ssget "X" '((0 . "INSERT")(2 . "PLANKOPF*"))) )) ;;; Rückgabe des aktuellen deutschen Datum-Strings, "31.01.99". ;;; Kann auch mit DIESEL gelöst werden. (defun HEUTE (/ s) (setq s (rtos (getvar "CDATE") 2)) ;julianisches Datum (strcat (substr s 7 2) "." (substr s 5 2)"."(substr s 3 2))) Automatische Datum Updates macht man entweder mit RTEXT (bonus/express tools) oder HPCONFIG mit einem HPGL/2 Plotter. (&lt;a2000i)
[22.3] Wie UPDATE ich Block Attribute?
Es gibt ein SUPPORT\ATTREDEF.LSP um Attributeigenschaften (wie Position, Layer, Texthöhe, ...) auf bereits eingefügte Blöcke zu übertragen.

Bei komplexen Elementen muß man entupd mit dem Hauptelement (INSERT oder POLYLINE) ausführen, um Änderungen am Bildschirm zu sehen. ("Element REGEN"). ;;; Beispiel: (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-entities (if (istypep b '("SEQEND" "ENDBLK")) (getval -2 b) ;complex entity -> header b ;normal entity ) )

[22.4] Wie erzeugt man mit ENTMAKE einen Block?>
Siehe http://xarch.tu-graz.ac.at/autocad/stdlib/ENTMAKE.LSP

Dort gibt es eine Beispiel vom Mehrfachaufrufen von (ENTMAKE) für den Blockdefinitions HEADER, die Elemente, den Abschluss (ENDTAB) und zum Schluß den Block als INSERT mit (ENTMAKE) einzufügen. Für anonyme Blöcke beachte daß (setq bn (entmake '((0 . "ENDBLK")))) gibt den erzeugten Blocknamen für (entmake (list '(0 . "INSERT")'(70 . 1)(cons 2 bn) ...)) zurück.


[23] POLYLINIEN

Seit R14 speichert die neue LWPOLYLINE ("light weight") die Punkte nur mehr in einem Objekt als mehrfache 10'er Gruppen. Es ist kein komplexes Objekt mehr, die (assoc) Methode funktioniert nicht mehr.
[23.1] Wie greift man auf Polylinien Knotenpunkte (VERTEX) zu?
Ein Polylinien VERTEX ist eine Unterelement einer POLYLINE (wie auch ein ATTRIB ein Unterelement eines INSERT Blockes ist, oder ATTDEF eines BLOCK). Also können die selben Funktionen wie in [22.1]-[22.3] benutzt werden. ;;; Rückgabe einiger assoc Gruppenwerte einer Liste (für LWPOLYLINE) (defun group-only (grp lst) (mapcar 'cdr (remove-if-not '(lambda(pair)(= grp (car pair))) lst))) ;;; Rückgabe der Vertex Liste einer Polylinie oder eines bel. anderen Elementes (defun GETPTS (ele / pts) (setq ele (entity ele)) ;=> ENAME typ (cond ((istypep ele "POLYLINE") (while (istypep (setq ele (entnext ele)) "VERTEX") ;; lasse Fit und Spline Punkte aus (konservativer Stil) (if (not (or (flagsetp 1 ele) (flagsetp 8 ele))) ;bugfix! (setq pts (cons (trans (getpt ele) ele 0) pts))) (reverse pts))) ;; Spezialfall: Man muß mappen, assoc finded nur den ersten. ;; Fix für einen LWPOLYLINE Bug in R14: Intern nur 2D, ;; (entget) gibt Fantasie Z Werte zurück. ((istypep ele "LWPOLYLINE") (mapcar '(lambda(pt)(trans (list (car pt)(cadr pt) 0.0) ele 0)) (group-only 10 (entget ele)))) ;; Füge hier andere Elementtypen ein, sowie: ((istypep ele '("TEXT" "CIRCLE")) (list (getpt ele))) ;; Andere (Serge's Stil). Für LWPOLYLINE siehe oben. (T (apply 'append (mapcar '(lambda (n / p) (if (setq p (getval n ele)) (list p))) '(10 11 12 13))) ) ;; oder so (konservativer Stil) ;;(T (foreach n '(10 11 12 13) ;; (if (setq p (getval n ele)) (setq pts (cons p pts)))) ;; pts ;;) ) ) Vorschläge von Vladimir Nesteroswky für eine andere Vertex Struktur: Siehe [22.1] (defun vertices-and-bulges( pline-ename ) (mapcar 'cdr (remove-if-not '(lambda(ele) (bitsetp 9 x)) (get '(70 10 42) (cdr (edlgetent pline-ename)) => Liste von (10 42) Paaren einer Polylinie ;;; kann dann auch so geschrieben werden: (defun flag9p (ele) (flagsetp 9 ele))) ;Wahr für Fit oder Spline Punkte (mapcar '(lambda (ele) (remove-if-not 'flag9p (cdr (edlgetent pline-entname)))) Siehe auch [23.5] für eine andere Kanten Struktur (Segmente) von Polylinien.

[23.2] Wie VERBINDET man mehrere Linien zu Polylinien?
Versuche einfach jedes Element mit allen ausgewählten Elementen zu verbinden, aber beachte daß bereits verbundene Elemente können nicht mehr mit ENTGET gefunden werden weil sie beim Verbinden gelöscht wurden. ;;; Dieses einfache Beispiel konvertiert alle gewählten Elemente zu ;;; Polylinien und versucht so viele möglich zu verbinden. (defun C:JOINPOLY (/ ele ss) (foreach ele (sslist (setq ss (ssget))) ;besser mit einer Liste (if (entget ele) ;nicht bereits verbunden? (cond ;(sonst wäre sie nil) ((istypep ele '("ARC" "LINE")) ;; Sie sollten hier noch dazu die Erhebung (Z) und das BKS beachten! (command "_PEDIT" ele "_y" "_j" ss "" ""); Konvertiere und VERBINDE ) ((and (istypep ele '("POLYLINE" "LWPOLYLINE")) (not (flagsetp 1 ele)) ;offen (< (rem (getflag ele) 128) 8)) ;ignoriere Netze usw. (command "_PEDIT" ele "_j" ss "" "");BKS Prüfung hier ausgelassen ) ) ) ) )
[23.3] Ändere die BREITE von mehreren Polylinien
Mit den obigen Hilfsfunktionen ist es leicht: (defun C:POLYWID (/ wid ele) (initget 5)(setq wid (getdist "Neue Polylinie Breite: ")) ;nicht negativ (foreach ele (sslist (ssget '((0 . "*POLYLINE")))) ;nur PLINE (command "_PEDIT" ele "_W" wid "")))
[23.4] Erzeuge Polylinie oder Spline: mit (ENTMAKE) oder (COMMAND)
  1. Du kannst eine Skriptdatei mit einem LISP Programm erzeugen und dann aufrufen. Das erscheint für Anfänger der einfachste Weg zu sein. Aber I/O (Ein/Ausgabe) Fehler machen das ganze unzuverlässig und kompiliziert. Kommerzielle Programme machen das anders.
  2. Im zweiten Weg erzeugt man die fertige Elementliste und ruft ENTMAKE auf. Vorteil: Schnell, im WKS, unabhängig von Objektfang.
    Siehe http://xarch.tu-graz.ac.at/autocad/stdlib/ENTMAKE.LSP
  3. Die dritte und häufigste Möglichkeit basiert auf COMMAND. Es funktioniert wie bei der Benutzereingabe für Polylinien, Splines oder Linien. Nachteile: BKS, Objektfänge. ;;; Zeichnet eine POLYLINIE aus einer Punktliste (das selbe mit SPLINE, ;;; oder LINIE), im aktuellem BKS, mit der aktuellen Objektfangeinstellung. (defun DRAW-PLINE (pts) (command "_PLINE") (mapcar 'command pts) ;; oder so: (foreach pt pts (command pt)) => braucht weniger Speicher (command "")) (defun DRAW-SPLINE (pts) (command "_SPLINE") (apply 'command pts) ; so geht's auch, pts = Fitpunkte (command "" "" ""))

[23.5] Wie messe ich die LÄNGE von Polylinien?
Es gibt zwei Wege:
  1. Die einfache, mit dem FLÄCHE (_AREA) Befehl, ist mitunter 'laut'. (druckt das Ergebnis), aber funktioniert mit allem, auch Splines. ;;; addiere alle LÄNGEN aller gewählten Objeke, LAUT, ;;; für die Fläche ändere die letzte Zeile auf (getvar "AREA") (defun C:LEN-OF () (command "_AREA" "_A" "_E") ;addiere Objekte (_E für R12+R13 Komp.) (ssapply 'command (ssget)) ;pass all elements to AutoCAD (command "" "") ;two returns (getvar "PERIMETER")) ;this is the length
  2. Mit einiger Mathematik, aber nur für einfache Objekte. Here is best to define some helper functions again. This is also an introduction for the next chapter [24], some bulge trigonometry for curved segments.

    ;;; Berechne Länge eine Polylinie, leise (defun POLY-LENGTH (poly / seg) (apply '+ ; die Summe aller Einzellängen (mapcar '(lambda (seg) ;Länge eines Segments (if (zerop (car seg)) (distance (cadr seg) (caddr seg)) ;Liniensegment oder (abs (arclen seg seg)))) ;gekrümmt: siehe [24] (pline-segs poly)))) ;;; 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)))) ;;; PLINE-SEGS - 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)) (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 polylines, QUIET ;;; To accept also other entities, add those to pline-segs (defun C:POLYLEN () (apply '+ (ssapply 'poly-length (ssget '((0 . "*POLYLINE"))))))
Für die Summe aller Flächen verwende entweder den lauten Befehl AREA (wie oben) oder implementiere Heron's Formel für Polygonflächen (aber nur für einfache geschlossene Polylinien).

[23.6] Wie drehe ich die Richtung von Polylinien um (REVPOLY.LSP)?
Sergei Komarov submitted a REVPOLY.LSP which takes care of bulges and widths too.
http://xarch.tu-graz.ac.at/autocad/news/lisp_pro/revpoly.lsp Eine kurze Stdlib Version wäre das: ;;; Ignoriere jede Breiten 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 "\nDrehe Polylinie um: "))) (std-entmake-pline (entget ele '("*")) ; behalte EED information (poly-reverse (std-pline-segs ele)))))
[23.7] Wie errechnet man das Zentrum einer Polylinie? [neu]
Das Zentroid eines Volumenkörpers oder Region muß mit _MASSPROP extrahiert werden. Man kann das resultat in eine Dateio schreieben und dieses dann analysieren. Das Zentroid einer Polylinie ist verschieden vom "geometrischem Mittelpunkt", Dieser ist einfach. (setq n (float (length pts))) (list (/ (apply '+ (mapcar 'car pts)) n) (/ (apply '+ (mapcar 'cadr pts)) n)) Das echte Zentrum ist aber viel schwieriger. Die stdlib Version ist auf http://xarch.tu-graz.ac.at/autocad/stdlib/STDPOINT.LSP STD-CENTROID-2D
Im stdlib.arx oder unter www.manusoft.com (siehe freebies) sind bessere MASSPROP Lisp funktionen für Solid's. Man nehme also (command "_REGION" ele)(massprop entlast)(command "_UNDO" 1). In VLA gibt es auch eine MASSPROP Objekteigenschaft für Acis Objekte.


[24] Kreis/Bogen Geometrie: BULGE Konversion. Ein bißchen Trigonometrie

[fixed] Was ist BULGE, die "Krümmung" in einer Polylinie?

Die Krümmung ist der Tangens eines Viertels des inkludierten Winkels des gekrümmten Segmentbogens. Eine Krümmung von 0.0 repräsentiert eine gerade Linie. Zusammen mit dem Start und Endpunkt ist das genug Information um schnell alle anderen Werte zu berechnen. Eine negative Krümmung bedeutet Drehung im Uhrzeigersinn ("mathematisch negativ").

  Bogenlänge = radius * winkel
  Krümmung   = +/- tan( winkel/4 )            (CCW: +, CW -)
  Winkel     = 4 * atan( krümmung )
  Krümmung   = +/- ( 2 * höhe ) / stichlänge  (CCW: +, CW -)

Siehe auch http://www.autodesk.com/support/techdocs/fax700/fax797.htm für ein Beispiel oder das Buch "Maximizing AutoLISP" [2]. (Beachte: Das R10/11 Buch -Vol II- beinhaltet eine falsche Bulge Formel.)

(bugfixed, falsche Formel! Dank an Sergei Komarov)

;;; Konvertiert ein gekrümmtes Polyliniensegment (bulge pt1 pt2) ;;; in einen Kreis (ctr rad). Start- und Endpunkte sind bekannt, ;;; also die Winkel auch: (angle ctr pt1)(angle ctr pt2) ;;; Gibt NIL bei gerader Linie zurück. (defun SEG2CIR (seg / bulge p1 p2 cot x y rad dummy) (if (zerop (car seg)) nil (setq bulge (car seg) p1 (cadr seg) p2 (caddr seg) cot (* 0.5 (- (/ 1.0 bf) bf)) 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) ; um PROGN zu vermeiden ) ) ) ;;; Inverse Konvertierung, berechne Segment (bulge p1 p2) eines Bogens ;;; mit gegebenem Kreis (ctr rad), start- und end-winkel (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) ) ;;; Berechnet Krümmung eines Kreisbogens. Gegeben sind die Bogenpunkte ;;; und der Kreis (ctr rad) [fixed von 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))) ;;; Eingeschlossener Bogenwinkel des Segments (bulge p1 p2) (defun bul2ang (seg / ctr) (- (angle (setq ctr (car (seg2cir seg))) (cadr seg)) (angle ctr (caddr seg)))) ;;; Berechnet Bogenwinkel aus der Stichlänge und dem Radius (defun arc2ang (chord rad) (* 2.0 (atan (/ chord 2.0 (sqrt (- (expt rad 2) (expt (/ chord 2.0) 2) ) ) ) ) ) ) ; eine andere Lebensform in der Klammernwelt ;;; ARCLEN - Bogenlänge = radius * winkel ;;; Beachte Vorzeichen! +/- (abs (arclen seg)) ist die reine Länge (defun arclen (seg) (* (cadr (seg2cir seg)) ; radius 4.0 (atan (car seg)))) ; winkel = 4*atan(bulge) (setq *INFINITY* 1.7e308) ; größte double Zahl (defun TAN (z / cosz) (if (zerop (setq cosz (cos z))) *INFINITY* (/ (sin z) cosz))) (defun DTR (ang)(* pi (/ ang 180.0))) ; Grad in Radian (defun RTD (ang)(/ (* ang 180.0) pi)) ; Radian in Grad


[25] DCL: Listboxen mit TABS oder MONOTXT Schriften

Unter Windows ist es schwierig Texte zu layouten ohne "monospaced" Schriften.

Versucher entweder das "tabs" Attribut in der list_box Komponente, so wie:

tabs = "0 20 40"; (set_tile "listbox" "Layer:\t0\tweiss") oder verwende eine monospaced Schrift mit dem "fixed_width_font" Attribut: : list_box { label = "Drawing"; key = "dwglist"; width = 50; fixed_width_font = true; // <- monotext } Beachte auch die DETAB Funktion (TAB -> Leerzeichen) auf http://xarch.tu-graz.ac.at/autocad/news/detab.lsp oder STD-DETAB in http://xarch.tu-graz.ac.at/autocad/stdlib/STDSTR.LSP


[26] EED Extended Entity Data: Zugriff, Auswahl und Speichern

[26.1] Wähle Objekte über EED mit (ssget "X") ;;; Definiert den appname Header und Delimiter (4 Zeichen regapp name ;;; nach AAIG, der Autodesk Application Interoperation Guidelines) (setq appname "HUBU-") ;;; definiert "*" für alle Untertypen (setq allappnames (strcat appname "*")) ;;; zB: HUBU-LIST1, HUBU-LIST2 ;;; Gibt EED Liste eines Elementes zurück (defun GETEED-LST (ele) (cdadr (assoc -3 (entget ele (list allappnames))))) ;;; Gibt alle Elemente eines bestimmten appname Typ zurück ;; (reguläre Ausdrücke erlaubt) (defun ssget-app (typ) (ssget "X" (list (list -3 (list typ)))) ;;; Gibt alle deine privaten "HUBU-*" Elemente zurück (defun ssget-hubu (typ) (ssget "X" (list (list -3 (list (strcat appname typ))))) (ssget-hubu "*") ; will get all your elements
[26.2] Zugriff auf Objekt EED (XDATA)

Prüfe XDATA mit: (entget (car (entsel)) '("*"))

Diese Funktionen extrahieren alle XDATA passend zum regapp Namen oder alle passenden XDATA Werte.

;;; GETXDATA - alle XDATA Listen eines Elementes ;;; zB mit den 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 - alle XDATA als Listen, ohne regapp namen ;;; => ((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


[27] Wie breche ich in Lisp einen Befehl ab?

Auch: "How do I press Break in AutoLISP?"

(command) ohne Argument oder mit nil als Argument funktioniert wie Ctrl-C in R12 oder Esc danach, aber nur in der Befehlszeile, nicht in einem Dialogfeld. Und es funktioniert auch nicht in SKRIPTs. (command nil) ist dasselbe wie (command).

(command) bricht nur den aktuellen Befehl ab, z.B. bei "BEM" in AutoLISP muß man (command) zweimal ausführen.

Das funktioniert aber nicht mit Lispschleifen. Hier gibt es (quit) oder (exit) -äquivalent- um ein Lispprogramm sofort zu beenden.

Beispiel:

(while T ; do ; Endlosschleife (princ "\nEingabe a=") (setq a (getint)) (if (zerop a)(exit)) ; Abbruch aus Lisp ) In diesem Beispiel würde (command) nicht die Schleife beenden. (exit) beendet die Ausführung wie mit Control-C. Es wird "error: quit / exit abort" ausgegeben und der Stack aller aufgerufenen Funktionen wird ausgegeben.
Für einen unsichtbaren Abbruch muß man *error* umdefinieren: (setq olderr *error* *error* my_error) (defun MY_ERROR (s) (if (not (member s ; unsichtbar '("Funktion abgebrochen" "Tastatur-Abbruch" "quit / exit abort"))) (princ (strcat "\nFehler: " s)) ) (setq *error* olderr) )

Für Skripts definiere einfach eine CANCEL Funktion in Lisp, wie:

(defun SCRIPT-CANCEL () (command) (command "resume")) und dann im SCRIPT.SCR: .. [Skript Befehle] (script-cancel) [weitere Skript Befehle] ..


[27.1] Wie überläßt man dem Benutzer eine unbestimmte Anzahl an Eingaben?

[neu] Um den Benutzer die Möglichkeit zu überlassen jeden beliebigen Befehl mit allen möglichen Optionen zu verwenden ohne alles auszuprogrammieren, wiederhole einfach (command PAUSE) bis der Befehl zu Ende ist. zB. bei den schwierigen Befehlen PLINIE oder BOGEN. (command "_ARC") (while (= 1 (logand (getvar "CMDACTIVE") 1)) (command PAUSE))


[28] Wie entschlüssele ich die interne ACIS Geometrie mit Lisp?

Alle ACIS Objekte (3DSOLID) sind dokumentiert von Spatial (SAT Format Description). Die interne Representation mit (ENTGET) ist verschlüsselt, aber das Verschlüsselungsschema wurde geknackt. (XOR 95)

Siehe http://xarch.tu-graz.ac.at/autocad/stdlib/samples/ACIS-REGION.LSP [neu]



[A] Urheberrechtliche Bemerkungen

Wenn Du glaubst nützliche Verbesserungen oder Änderungen für dieses FAQ zu wissen, sende ein E-Mail an Reini Urban <rurban@x-ray.at> aber erwarte keine Antwort.

Dieses AutoLISP FAQ ist urheberrechtlch geschützt © 1996-2000 von Reini Urban. Alle Rechte vorbehalten.
Die Beispielfunktionen sind, wenn nicht anders beschrieben, © 1991-97 von Reini Urban und dürfen frei benützt, kopiert, verändert und verbreitet werden, aber nur ohne Entgelt.
Die Grundfunktionen sind © 1991-97 von Reini Urban und dürfen frei benützt, kopiert, verändert und verbreitet werden.

Dieses FAQ darf frei verbreitet werden, aber nur als vollständiges Dokument ohne Änderungen. Es darf nicht gegen Entgelt verkauft oder in kommerziellen Dokumenten oder Produkten verwendet werden ohne vorheriger schriftlicher Zustimmung des Rechteinhabers (z.B. publiziert auf kommerziellen CD-ROM's, Disketten, Büchern, Zeitschriften, oä.). Die Erlaubnis wird explizit erteilt, dieses Dokument im freien und unbeschränkten elektronischen Datenverkehr (FTP, WWW, ...) zugänglich zu machen und in eine offizielles AutoCAD FAQ inkludiert zu werden.

Wenn dieses Dokument in off-line Form (z.B. CD-ROM, gedruckt) reproduziert wird, muß eine zusätzliche Kopie an den Rechteinhaber Reini Urban, X-RAY, Nibelungeng. 3, 8010 Graz, Austria gesandt werden.

Die Autoren und/oder der Rechteinhaber weisen ausdrücklich alle Haftungsansprüche für etwaige Fehler oder mißverständlich interpretierte Probleme zurück. Wir haftet nicht für Verluste oder Schäden welcher Art auch immer. Einschließlich des Verlusts oder der Zerstörung von Daten, entgangenen Gewinn, Versicherungskosten oder andere spezifische, unvorhergesehene, folge- oder mittelbare Schäden, die sich aus der Benutzung oder der Unmöglichkeit der Benutzung der Software oder der Dokumentation ergeben, ungeachtet der Ursache und des für die Haftung geltend gemachten Rechtsgrundes, sofern sie nicht nach zwingenden gesetzlichen Bestimmungen haftet.

[A.1] FAQ Links

Homepage der HTML Version:
http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp.html
Kommentierte AcadWiki version: [neu]
http://xarch.tu-graz.ac.at/acadwiki/AutoLispFaq
Die geposteten ASCII Versionen (und meist am letzten Stand) sind hier:
http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp.1
http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp.2
Eine Winhelp version (gezippt mit FAQ-CODE.LSP) ist hier:
ftp://xarch.tu-graz.ac.at/pub/autocad/news/faq/autolisp.zip
FAQ Usenet Archiv
http://www.faqs.org/faqs/CAD/autolisp-faq/ oder per ftp ftp://rtfm.mit.edu/pub/usenet-by-hierarchy/comp/cad/autocad/
Alle Lisp Funktionen aus diesem FAQ sind hier:
ftp://xarch.tu-graz.ac.at/pub/autocad/news/faq/FAQ-CODE.LSP
Alte Anfänge eines eigenen, neuen AutoCAD FAQ's sind hier:
http://xarch.tu-graz.ac.at/autocad/news/faq/new-acad
Die französische Übersetzung von Roger Rosec:
http://www.newz.net/acadplus/page5101.htm
Die japanische Übersetzung von MASAMI Chikahiro:
http://www.page.sannet.ne.jp/chestnutsburr/autolisp-j.html
Die russische Übersetzung von Igor Orellana:
http://www.cad.dp.ua/stats/alfaq_ru.htm
Die deutsche Übersetzung von Reini Urban:
http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp.html.de
Die spanische Übersetzung von Eduardo Magdalena: [neu]
www.peletash.com/mecanicad/
Wegen einer griechischen Übersetzung wurde ich kontaktiert.
AutoDesk's FAQ's und TechSupport
http://www.autodesk.com/support/autocad/
Suche nach AutoCAD+FAQ
Support Assistant 2000
AutoDesk Diskussionsforen [geändert]
news:autodesk.autocad.customization, auf Google [neu] oder das neue WebX interface auf Autodesk's web server.


[B] Danksagungen

Dieses FAQ basiert auf große Anstrengungen der gesamten comp.cad.autocad Gemeinschaft, in besonderem:

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 und vielen anderen.


[C] Revisionsliste

3.Mar 2002
Vladimir added a section to [11] S::STARTUP (from the wiki)
18.Jun 2001
fixed deja.com to groups.google.com
23.Apr 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
neu: [23.7] "Wie errechnet man das Zentrum einer Polylinie?"
15.Sep 2000
"Stack Overflow" Kapitel [14] überarbeitet (VL/VLIDE, A2000).
neues englisches Buch [2]
1.Sep 2000
vl-sort Warnung mit doppelten Einträgen [8]
18.Aug 2000
changed Codemagic [6.1] from Freeware to Shareware, thanks to Nir Sullam
1.Aug 2000
Änderung der Autodesk FAQ's auf Search URL
v2.266.Jun 2000
neuer LDATA bug [7], fixed DEFUN-Q [11], entferne die meisten farbigen [neu/geändert] Noten.
v2.25 17.May 2000
neu [27.1], neu C:POLYREV [23.6]
25.Apr 2000
neu Point A [1.1], DDE Beispiel gekürzt [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 ranges [7]: -32766 => -32768
23.Feb 2000
Phil Kenewell updated LispLink 2000 [6.1].
17.Feb 2000
Added the dotsoft biglist url [7].
Mike Tuersley fixed [11] for MNL files.
v2.23 14.Feb 2000
Chris Ehly fixed all broken links.
v2.22 13.Jan 2000
additions to numerical precision. adesk techdocs links are broken again. compiled S::STARTUP hooks
v2.216.Dec 99
adesk faq link, removed peoples urls/emails, minor fixes.
7.Oct 99
wording in [0.1], german translation, link in [28]
v2.2 13.Jul 99
added topics [0.1] What changed with AutoCAD 2000?, [0.2] Why cannot I create ARX anymore?, [5.4] Better ones: Common Lisp and Scheme.
additions to [6.2] Analyzers, Packagers..., [5.3] R15 VLISP info, [4] FAS Security, [21.4], [20.4]: renamed SSAPPLY to SSMAP
13.Apr 99
fixed a link [1]
v2.1 3.Jan 99
fixed and added some links: [22.4], [A.1], [B], [27], [1], [2], [20], [22.1]
21.Dec 98
found a russian translation, bob jones' and masami chikahiro's links are broken
12.Jul 98
changed posting frequency to monthly. Some minor fixes concerning the now available Visual Lisp and other cosmetics. cadsyst url
6.Jun 98
changed Eugene's email
13.May 98
added R14 plotdialog [21.2]
11.May 98
bugfixes by Serge Pashkov <xrs@aha.ru> in [24] arc2bul, [20.1] remove-if-not (but correct in faq-code.lsp), [21.7] doc of maptrans0-1, [24] tan, [21.2] DDECMD and some vlisp beta1 fixes in faq-code.lsp
v2.0 7.May 98
lots of Visual Lisp based changes: [0],[4],[5],[6.1],[7]
[17] new, [2] new books, [21.2] ActiveX sample, [A.1]better official R14 FAQ
27.Feb 98
[0] Visual Lisp available.
24.Feb 98
[6.1] lspedit.exe, [0] Visual Lisp news and [7] entmake vertex
v1.12 12.Feb 98
Eugene Tenenbaum <et119@columbia.edu> send me huge list of corrections, mostly improving the english language. This time only up to [11].
15.Jan 98
[7] HATCH added to entget problem,
[0] more specific now, [22.4] url change [A.1] Japanese translation
12.Jan.98
[2] The R13 lisp manual is in the cust. manual not only on the cd. sorry
8.Jan.98
Vladimir Nesterowsky's new web url
24.Nov.97
fixed some typos
v1.11 15.Nov.97
changed header.
Autodesk AutoCAD FAQ URL's. see [A.1]
LispLink editor. see [6.1]
Zoomer rumors: [0]
23.Oct.97
Roger Rosec provided a french translation of the entire FAQ. see [A.1]
13.Sep 97
Alan Williams detected a stupid error in DATESTAMP in [22.2] but in FAQ-CODE.LSP it was okay.
28.Aug 97
added the (entget) LWPLOYLINE bug to [7],
changed my mail address to rurban@xarch.tu-graz.ac.at to be prepared for the after-student area. :)
v1.10 22.Jul 97
some LWPOLYLINE fixes, R14 Lisp debugger Vital LISP 3.0 shipped, Convert 3.3 update [4.4], fixed cronjob for bi-weekly posting: every 2nd Monday, 11.30 MET
20.Jul 97
Vital LISP 3.0 shipped
12.Jul 97
Convert 3.3 update [4.4], fixed cronjob for bi-weekly posting: every 2nd Monday, 18.00 MET
2.July 97
fixed URL in [10],
30.June 97
fixed (istypep) in [20.4], changed title of [16], light changes in (getpts) in [23.1]
v1.9 26.June 97
[5.2] confirmed Vill3 release date, added DDE sample from Xiang Zhu to [21.2], provided detab.lsp [25]
17.June 97
bugfix in [20.4]: short (getval), [12] R14 ARX autoloading, [23.5] (pline-segs) is now R14-save but still not compatible, new [23.6] revpoly.lsp, [A.1], [5.2] Vill 3 will have reactor support.
9.June 97
new symbol-string trick by Christoph Candido [20.3]
21.May 97
some minor corrections.
v1.8 15.May 97
added [0] Future of AutoLISP?
changed VERTECES to VERTICES, fixed mail address of af.buturovic@berwanger.com,
added SSAPPLY: [20.4], [23.5],
started to R14'ify some code for LWPOLYLINE's [23], not finished yet, (pline-segs) is missing
9.May 97
[2.1] R14 Winhelps, [5.2]: new basis url, Vill Lite [6.1]
added [16]: Lisp over mult. dwg's
added some short comments to [6.1](ntemacs), [14], [21.8]
21.April 97
added [[28] ACIS decryption
v1.7 9.April 97
added [[21.8] C:XYZ,
added [[15] (command "ROTATE3D") does not work! Why?
HTML version chapter numbers match the posted version,
added [27]: (command) as ctrl-c, Sergei Komarov improved [27], Adi Buturovic improved [27] for scripts.
v1.6 13.Feb 97
moved the intro to the very beginning for the curious.
another lisp plot lisp [21.2], a third lisp debugger [3.1], [A.1]: the gd.tuwien uunet mirror is faster than the official ones, fixed cadence FAQ url, applied digest format partially, html will be created automatically soon, wrong (old) chapter numbering from the v1.5 version, [7] 64 in flag 70 in symbol tables,
v1.5 5.Feb 97
added get and edlgetent samples by Vladimir, removed the sort code instead,
changed [11] title and added string funcnames,
bugfix in getpts [23.1], basic funcs should be free [A],
added DATESTAMP to [22.2], added a "s" to [A] title,
added [20] DCL, [21] EED, [21.1-21.7] samples,
Serguei Komarov found a bug in seg2cir,arclen,arc2bul [24],
added arc2ang and (corrected) arclen,
bugfixes in sslist, getval, all predicates with "p" postfix now,
prepared a FAQ-CODE.LSP, Convert supercedes Decrypt [4.4], added scripts and (command) to [23.4], AREA to [23.5],
v1.4 24.Jan 97
important news with Decrypt [4.4],
moved [11] "bugs" to [7] "problems",
added [11] "How do I (sym, list)" instead,
added the "Approved" header for news.answers processing,
added [22]-[24]: some examples for subentities and bulge stuff,
Serge found a bug/feature in acad_strlsort [7],
added number accuracy and ss limitation to [7],
added break code and samples to [3.3],
added a short lisp style guide at [2.2], instead of [6.4]
v1.3 17.Jan 97
added [16] stack overflow (thanks Serge), [4.7] Lisp2C,
updated [8] fastest sort (sample, benches),
received the news.anwsers approval
v1.2 11.Jan 97
added Phoaks to news archive
fixed (break) in [3.3] (Thanks Tony),
added a sorting example to [8], improved (my-princ) in [15]
changed posting frequency from weekly to bi-weekly
v1.1 4.Jan 97
R13 bugs, S::STARTUP code by Owen Wengerd,
homepages instead of e-mail adresses where appropriate, (people get enough junk mail these days)
more links, and some bugfixes
v1.0 22.Dec 96
First version, posted on 28.Dec 96
as a discussion basis