Oft geht es nicht darum, Geometrie zu erzeugen, sondern
vorhandene Zeichnungselemente zu verändern. Dafür gibt es
im Repertoire der AutoLisp-Funktionen natürlich auch eine
geeignete zu finden:
(entmod ...). Diese Funktion
bekommt eine Geometriedatenliste, die aber von der, die
von
(entmake ...) erwartet wird, in zwei Punkten
abweicht. Zum Einen muss sie den Entity-Namen des zu
modifizierenden Elements enthalten, zum Anderen genügt es
aber, wenn sie diejenigen Paarungen aus Gruppencodes und
Werten enthält, die geändert werden sollen. Sie muss also
in keiner Weise vollständig sein, kann es aber sein.
Oft wird nur ein einziger Wert in der von
(entget ...)
erhaltenen Datenliste mit
(subst ...) geändert. Die
unveränderten Daten werden von
(entmod) ignoriert.
In anderen Fällen wird (neben dem Entitynamen) nur ein
einziges Paar mitgeschickt - es geht genauso. Um das zu
verdeutlichen, nehmen wir noch einmal einen Kreis, den wir
zuvor mit
(entmake) erzeugen. Anschliessend
ändern wir dann noch einmal seine Farbe in rot:
(entmake
(list
'(0 . "CIRCLE")
'(40 . 10)
'(10 0 0 0)
)
)
(entmod
(cons '(62 . 1)(entget(entlast)))
)
=> ((62 . 1) (-1 . <Objektname: 400a0d70>)
(0 . "CIRCLE") (330 . <Objektname: 400a0cf8>)
(5 . "2E") (100 . "AcDbEntity") (67 . 0)
(410 . "Model") (8 . "0") (100 . "AcDbCircle")
(10 0.0 0.0 0.0) (40 . 10.0) (210 0.0 0.0 1.0))
So funktioniert das allerdings nur, wenn in AutoCAD die Farbe
'Vonlayer' eingestellt ist - das bedeutet, dass der Kreis selbst
gar keinen Eintrag für die Farbe bekommt. Nur unter diesen
Umständen können wir den Gruppencode 62 so einfach mit
(cons) in die Liste einfügen. Wäre dieser Code schon in
den Geometriedaten vorhanden, würde das zu widersprüchlichen
Informationen führen. In diesem Fall ist also das andere
angesprochene Verfahren sicherer, nur den Entity-Namen
mit der neuen Farbeinstellung zu kombinieren. Wir machen den
Kreis auf diese Weise jetzt gelb:
(entmod
(list
'(62 . 2)
(assoc -1(entget(entlast)))
)
)
=> ((62 . 2) (-1 . <Objektname: 400a0d70>))
Etwas anspruchsvoller könnte dann schon die Aufgabe sein,
einem Kreis, der bisher eine Farbe hat, diese wieder wegzunehmen,
um dem Kreis wieder die Farbe "Vonlayer" zu verpassen. Da, wie
wir gesehen haben, das Weglassen eines Gruppencodes diesen auch
nicht verändert, wäre es eigentlich unmöglich... Aber da haben
die AutoCAD-Programmierer vorgesorgt.
(entmod) akzeptiert
die 257. Farbe (da ab 0 gezählt wird, hat sie natürlich die
Nummer 256):
(entmod
(list
'(62 . 256)
(assoc -1(entget(entlast)))
)
)
=> ((62 . 256) (-1 . <Objektname: 400a0d70>))
(entget(entlast))
=> ((-1 . <Objektname: 400a0d70>) (0 . "CIRCLE")
(330 . <Objektname: 400a0cf8>) (5 . "2E")
(100 . "AcDbEntity") (67 . 0) (410 . "Model")
(8 . "0") (100 . "AcDbCircle") (10 0.0 0.0 0.0)
(40 . 10.0) (210 0.0 0.0 1.0))
Wie wir sehen, ist der Gruppencode 62 wieder verschwunden!
Und nun noch ein kleines Beispiel für die Arbeitsweise von
(entmod) und den Gruppencode 62:
(defun kleine-spielerei( / farbe)
(setq farbe 0)
(while 'T
(entmod
(list
(cons 62(+ farbe 10))
(assoc -1(entget(entlast)))
)
)
(command "_redraw")
(setq farbe(rem(1+ farbe)239))
)
)
Zum Einen ist dieses kleine 'Programm' eine Demonstration der
Arbeitsweise von
(entmod), zum Anderen aber auch der
Beweis, dass manche
(command)-Aufrufe unumgänglich sind:
Der Aufruf von
redraw sorgt dafür, dass der Bildschirm
nach jeder Farbänderung aktualisiert wird - man würde sonst
nichts davon sehen! Solche
(command)-Aufrufe kann man
nicht durch
(entmake) ersetzen!
Aber nun zu etwas Anderem: Auf die Dauer wird es sicher auch
einmal notwendig sein, ein anderes Element als das zuletzt
gezeichnete zu ändern. Eine der Möglichkeiten ist die, den
Benutzer aufzufordern, ein Element seiner Wahl mit der Maus
anzupicken. Die Funktion dazu heisst
(entsel), und man
kann sie entweder ohne Argument oder aber mit einer Zeichenkette
aufrufen, die dem Benutzer mitteilt, was zu tun ist. Ohne
diese Zeichenkette erscheint die Standard-Aufforderung 'Objekt
wählen: '. Beispiele:
(entsel)
(entsel "Bitte wählen Sie einen Kreis: ")
Die Rückgabe von
(entsel) ist eine Liste, die als erstes
Element den Entitynamen und als zweites Element die Koordinaten
des Auswahlpunktes enthält. Dieser Punkt wird nur manchmal im
Programm benötigt, meistens bleibt er unverarbeitet. Die gängige
Standardformel lautet also
(entget(car(entsel))). Das
nächste Beispiel zeigt, wie man einen angewählten Kreis um 10%
vergrößert:
(defun beispiel1( / data)
(setq data(entget(car(entsel "Kreis wählen: "))))
(entmod
(list
(assoc -1 data)
(cons 40(* 1.1(cdr(assoc 40 data))))
)
)
)
Man kann alle Eigenschaften eines Objekts ändern, für alles stehen
entsprechende Gruppencodes zur Verfügung, die man in der Online-Hilfe
von AutoCAD nachschlagen kann. Was man allerdings (natürlich) nicht
ändern kann, ist der Typ des Entity: Man kann aus einem Kreis keine
Linie machen - und man einer Linie auch nicht den Gruppencode 40
hinzufügen:
(defun schlechtes-beispiel( / data)
(setq data(entget(car(entsel "Linie wählen: "))))
(entmod
(list
(assoc -1 data)
'(40 . 1.0)
)
)
) => nil (wenn Linie gewählt wurde)
Ein Programm muss immer so ausgelegt sein, dass es eventuelle
Fehler des Anwenders auffängt. Daher modifizieren wir unser
erstes Beispiel noch einmal:
(defun beispiel1( / data)
(setq data(entget(car(entsel "Kreis wählen: "))))
(if(="CIRCLE"(cdr(assoc 0 data)))
(entmod
(list
(assoc -1 data)
(cons 40(* 1.1(cdr(assoc 40 data))))
)
)
(princ "Kein Kreis gewählt!\n")
)
)
Übungsaufgaben
-
-
-
-
-
-
-
-
-
-
Lösungen