Hallo,
es gibt eine neue neue CADCAL Beta Version, sie hängt diesem Beitrag als CADCAL.ZIP an, kann aber auch von www.archtools.de/CADCAL.zip herunter geladen werden.
Es hat sich seit der letzten Betaversion sehr viel verändert, und deshalb sind die alten CALSCRIPT Objektinstanzen nicht mehr verwendbar. Die Demodateien liegen aber in aktualisierter Version im ./demo Unterordner des ZIP bei. Installation ist simpel: einfach die ZIP in ein Verzeichnis der Wahl entpacken, und, falls noch nicht geschehen, dieses Verzeichnis in den Suchpfad für Supportdateien von AutoCAD oder BricsCAD aufnehmen.
Wichtigste funktionale Neuerung ist die nun realisierte Objektkommunikation. Man kann mit dem Befehl CC-CONNECT Objektinstanzen miteinander verbinden. Die Kommunikation verläuft dabei von einem Master zu beliebig vielen Slaves. Ein Slave kann nur einen Master haben, aber ein Slave kann auch Master für andere Slaves sein. Man kann damit also beliebig lange Kommunikationsketten aufbauen, und damit dynamische Modelle simulieren.
Ob die Kommunikation überhaupt Einfluss auf die Erscheinung eines Slaves hat, wird natürlich im Slave selbst festgelegt, also in der Skript-Datei. Ein extrem einfaches Beispiel ist diese Skript für eine Lampe, das nur in der in der ZIP vorhandenen ./demo/switch-and-lamp.dwg lauffähig ist, weil nur dort die benötigten Blockdefinitionen verwendet werden:
Code:
(setq self.name "LAMP")
;;
cc-import power,0
cc-overwrite power
;;
(if (zerop power) (setq bn "lamp-off")(setq bn "lamp-on"))
(if master.origin (command "._line" origin master.origin ""))
._INSERT !bn !ORIGIN 1 1 0
Die Deklaration eines Objektnamens durch "(setq self.name "LAMP")" ist optional. Falls sie vorhanden ist, dann erhält die Objektinstanz einen XDATA-Marker mit dem Namen als Appname, so dass Programmierer die Objektinstanzen leicht ansprechen können.
Mit "cc-import power,0" werden die Argumente der automatsich aus dem Skript erzeugten Lisp-Funktion zzusammen mit dem Vorgabewert deklariert. Dabei stehen Argumentname und Defaultwert immer durch Komma getrennt, und diese Paare ebenfalls durch Komma getrennt. Im ./demo/nickshouse.scr steht da beispielsweise "width,100,height,100". Alternativ kann man die Deklaration statt mit diesem Script-Command auch mit der CAL Anweisung "CAL import(width,100,height,100) vornehmen.
Die Deklaration "cc-overwrite power" hat nur Relevanz, wenn dieses Objekt als Sklave einem Master zugeordnet ist. Damit werden die entsprechenden Eigenschaften des Masters im Sklaven bernommen. Mit "cc-overwrite power,layer" würde auch der Layer übernommen. Diese Deklaration der Überschreibung der eigenen Werte durch die Master-werte kann alternativ auch so vorgenommen werden: "(if master.power (setq power master.power self.power master.power)".
Nur bei den durch die Import-Deklaration definierten Variablen muss auf jeden Fall auch der pure Variablenname (hier "power" gesetzt werden, denn das Objekt hat zu diesem Zeitpunkt ja noch gar keine SELF.* Werte, die erst nach der Objekterzeugung existieren. Die Berechnungen laufen ja auch mit "POWER" statt "SELF.POWER". Erst, wenn eine vorhandene Objektinstanz modifiziert werden soll, sind die SELF.* Werte vorhanden, aber sie zeigen die Werte VOR der Veränderung. Bei Objektkommunikation existieren die MASTER.* Werte aber allesamt, weil die Instanz des Masters ja zwingend vorhanden sein muss.
Deshalb kann mit "(if master.origin (command "._line" origin master.origin ""))" eine Linie von der Objektinstanz zum Master gezogen werden. Nur bei vorhandener Kommunikation gibt es den master.origin (Einfügepunkt der Master Instanz). Mit "(if (zerop power) (setq bn "lamp-off")(setq bn "lamp-on"))" wird dann nur noch in Abhängigkeit von der Import-Variablen POWER der Blockname festgelegt, bevor mit einem einfachen Skript-Command das Insert erzeugt wird.
Man kann mit (setq myvar (c:calscript->lisp)) ein Skript in eine ausführbare Lisp-Funktion übersetzen. Aus der Liste der lokalen Variablen darin kann man ablesen, welche Werte man aus sich selbst oder dem Master auslesen und setzen kann. Steht z.B. diese Deklaration im Skript: "(setq self.layer "MeinLayer")", dann wird die Objektinstanz auf diesem Layer erzeugt, bzw die zu ändernde bereits vorhandene dortin versetzt. Im Skript ./demo/nickshouse.scr kann man sehen, wie das gemacht wird, ohne die lokalen Import-Werte zu ändern. Dieses Objekt setzt sich automatisch immer an den rechten unteren Eckpunkt des Masters. In der Datei ./demo/nickshouse-comm.dwg kann man die Wirkung sehen, wenn man mit CC-MODIFY die Breite einer Objektinstanz einer Reihe ändert: da werden dann automatisch alle in der Kommunikationskette abhängigen Instanzen passend zur Seite gerückt. In der ./demo/switch-and-lamp.dwg kann man mit dem Schalter die damit verbundenen Lampen ein- und ausschalten (ein=1, 0=aus).
Code:
(LAMBDA (POWER SELF
/ SELF.ENAME SELF.DATA
SELF.ORIGIN SELF.ANGLE SELF.SCALE
SELF.XSCALE SELF.YSCALE SELF.ZSCALE
SELF.LAYER SELF.OCS SELF.COLOR
SELF.LINETYPE SELF.LINEWEIGHT SELF.PROPERTIES
SELF.NAME SELF.WIDTH SELF.HEIGHT
MASTER.DATA MASTER.ORIGIN MASTER.ANGLE
MASTER.SCALE MASTER.XSCALE MASTER.YSCALE
MASTER.ZSCALE MASTER.LAYER MASTER.OCS
MASTER.COLOR MASTER.LINETYPE MASTER.LINEWEIGHT
MASTER.PROPERTIES MASTER.NAME
MASTER.ENAME
...
))
Die Lamda-Funktion hat sich ebenfalls geändert, sie hat jetzt immer ein zu den Import-Argumenten zusätzliches SELF Argument. Dieses kann entweder NIL sein (dann wird eine neue Objektinstanz auf '(0 0 0) mit Winkel 0 erzeugt), oder der Ename einer zu verändernden Objektinstanz sein (dann wird keine neue Objektinstanz erzeugt, sondern das mitgegebene verändert), oder eine Liste aus Einfügepunkt und Winkel (im Bogenmaß), dann wird eine neue Objektinstanz am Einfügepunkt im Winkel erzeugt.
Ein einfache Test zeigt das vermutlich anschaulicher. In der ./demo/nickshouse-comm.dwg kann man mit (setq en (car (entsel))) ein der Objektinstanzen auswählen, und mit (setq myfun (c:calsript->lisp)) die Datei ./demo(nickshouse.scr in eine ausführbare Lisp-Funktion übersetzen lassen. Diese Funktion kann dann mit (apply myfun (list 40 80 en)) auf die vorher gewählte Objektinstanz angewednet werden. Dieses wird dann die Werte WIDTH=40 und HEIGHT=80 annehmen.
Durch die Anwendung dieser Funktion wird die Objektinstanz absichtlich noch nicht angestoßen. Diese löst man erst mit (cc-redraw en) aus.
In der Datei ./demo/nickshouse.lsp sieht man beispielhaft, wie man mit den automatisch erzeugten Lisp Funktionen eigene Appliktaionen basteln kann. Hier wurde lediglich das "LAMBDA" am Beginn der Funktion durch "DEFUN NICKSHOUSE" ersetzt. Damit Anwender auch einen Befehl dafür zur Verfügung haben, wurde auch die C:NICKSHOUSE Funktion angehängt. Diese fragt nur nach Einfügepunkt, Drehwinkel, und den Werten für WIDTH und HEIGHT, und ruft damit dann die NICKSHOUSE Funktion auf.
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP