GDL
GDL, die Geometric Description Language, ist eine BASIC-ähliche Programmiersprache und wird in Archicad verwendet um die Elemente der Bibliothek zu erstellen.
Die wichtigsten Ressourcen für das Erlernen und den Umgang sind SelfGDL und Graphisofts GDL center. Unter Hilfe > Handbücher befindet sich auch das GDL Referenzhandbuch als PDF für die jeweilige Archicadversion.
Ein Klassiker der GDL Literatur ist David Nichelson-Coles GDL Cookbook und Object Making with ArchiCAD – GDL for Beginners, welche beide jedoch schon älteren Datums sind. Die meisten Grundlagen haben sich allerdings nicht geändert; daher sind diese Bücher immer noch empfehlenswert. Neueren Datums ist das GDL Handbook – A Comprehensive Guide von Andrew Watson (ursprünglich zu beziehen bei Cadimage, mittlerweile in Central Innovation, der Reseller in Australien/Neuseeland, aufgegangen).
Da das Programmieren im GDL Editor selbst recht mühsam ist, und moderne Annehmlichkeiten vermissen lässt, haben sich Alternativen etabliert:
Ausgewähle Tricks
Schnelle Ergebnisse
Wenn das Überlegen und händische Scripten einer Form zu anstrengend und langwierig ist, und besonders, wenn keine Parametrik vonnöten ist, so ist folgendes eine geeignete Alternative: Dabei wird die Form mithilfe einer Polylinie am oder um den Ursprung gezeichnet, und dann als Objekt abgespeichert. (Es ist auch möglich Elemente aus dem Grundriss/3D-Fenster in das jeweilige Skriptfenster zu ziehen. Dazu müssen die Tabs aber abgedockt werden.)
Dadurch schreibt uns Archicad automatisch ein poly2_b{5}
. Das ist von der Logik in den meisten Fällen gar nicht vonnöten – der Autor selbst wandelt die Kommando noch in ein normales poly2_b
um. Wichtig sind ohnehin die Koordinaten, und diese lassen sich sehr einfach auch für die gängigen prism
Befehle im 3D nutzen! Zu beachten ist dort dann jedoch noch das Setzen der richtigen Flags.
Relevantes Geschoss korrekt
Um eine korrekte Anzeige bei In relevanten Geschossen anzeigen zu erhalten, müssen die Parameter ac_bottomlevel
und ac_toplevel
logisch belegt sein (Das obere Level kann nicht unter dem unteren liegen).
! parameter script
bottom = GLOB_HSTORY_ELEV + GLOB_ELEVATION
parameters ac_bottomlevel = bottom
parameters ac_toplevel = bottom + ZZYZX
Schriftartauswahl
Für eine automatische Auswahlliste aller auf dem System installieren Schriftarten in den Objekt-Einstellungen. Dabei ist in diesem Beispiel ein Textparameter namens myFontFace
anzulegen (kann beliebig benannt werden).
! param script
dim fontNames[]
n = request("FONTNAMES_LIST", "", fontNames)
values "myFontFace" fontNames, CUSTOM
Relative Abhängigkeit von Parametern
Manchmal kommt es vor, dass man Parameter in Relation zueinander setzen muss: Wenn Basis
doppelt so groß ist, soll Rel_Param
auch doppelt so groß sein (Beispiel). Dazu braucht es lediglich einen neuen Parameter Basis_alt
, der den vorherigen Wert von Basis
speichert. Das kann über GLOB_MODPAR_NAME
realisiert werden.
!'--- param script ---'!
if GLOB_MODPAR_NAME = "Basis" then
rr = Basis / Basis_alt
Rel_Param = Rel_Param * rr
Basis_alt = Basis
endif
parameters Rel_Param = Rel_Param,
Basis_alt = Basis_alt
Präzision
Aufgrund der Natur von Floating Point Berechnungen kann es passieren, dass der Vergleich von 2 reellen Zahlen nicht das Ergebnis gibt, was man erwartet hätte. Sobald man folgendes im GDL versucht if reell_a = reell_b …
, bekommt man eine scharfe Mahnung zurückgeliefert.
Das dient allerdings lediglich als Hinweis, dass man sich mit so einem Konstrukt auf dünnem Eis bewegt. Um Fehler zu vermeiden, sollte man stattdessen die zu vergleichenden Zahlen von einander subtrahieren und dann prüfen, ob dieses Ergebnis größer ist, als ein zuvor definiertes Epsilon, quasi eine Toleranz.
Das Epsilon findet sich häufig als eps = 0.0001
im GDL Code, z.B. von den mitgelieferten Objekten.
Ein besonders detailliertes Konstrukt wäre z.B.:
dict EPS
EPS.length = 0.0001 !' 1/10 mm
EPS.square = EPS.length**2
EPS.scalar = EPS.square
EPS.angle = acs(1 - EPS.scalar) !' 0.0081°
! Ein Vergleich wäre dann:
if abs(real_a - real_b) < EPS.length then [...]
Werte aus einem Array löschen
Es gibt leider keine Möglichkeit nativ Werte zu pop
en, aber mit einem bisschen Geschiebe ist auch das möglich:
dim arr[]
!' init w/ some values
arr[1] = 0.1
arr[2] = 0.2
arr[3] = 0.3
!' the item index you want to delete
todelete = 2
dim new_arr[]
check = 0
for i = 1 to vardim1(arr)-1
if i = todelete then check = 1
new_arr[i] = arr[i+check]
next i
arr = new_arr
print arr !' prints: 0.1 0.3
if not(LABEL_HAS_POINTER) then
add2 LABEL_POSITION [2][1] + LABEL_POSITION [3][1],
LABEL_POSITION [2][2] + LABEL_POSITION [3][2]
endif
Text in Umfassungsbox
Natürlich ließe sich dafür richtext2
verwenden, aber hiermit kommt man auch zum Ziel:
! Bounding-Box
line2 0, 0, 0, B
line2 0, 0, A, 0
line2 A, B, 0, B
line2 A, 0, A, B
mst = 1/1000 * GLOB_SCALE ! Zeichnungsmaßstab
font_size = 5
font = "Arial"
txt_display = "Ein bisschen Text"
gosub "getStyle" ! definiert einen passenden Textstil
text2 a/2, b/2, txt_display
END !--- END --- END --- END --- END --- END ---!
!-----------------------------------------------!
"getStyle":
! Dummystil definieren
define style "dummy" font, A*mst, font_size, 0
style "dummy"
width_A = stw(txt_display) ! Textbreite mit Dummystil ermitteln
ratio_A = A/width_A ! Verhältnis von Dummy-Textbreite zu A
define style "dummyA" font, A*ratio_A, font_size, 0
style "dummyA"
r = request("Height_of_style", "dummyA", text_height)
text_height = text_height * mst
if text_height > B then
ratio_B = text_height / B
define style "dummyB" font, A*ratio_A/ratio_B, font_size, 0
style "dummyB"
endif
return
Strichlinien in 3D
Zwar kann man auch Linien im 3D zeichnen, allerdings stehen dafür keine verschiedenen Linienarten wie im 2D zur Verfügung.
! 3D script
!convert paper lengths to model
dashLen = dashLen * GLOB_SCALE
gapLen = gapLen * GLOB_SCALE
dashStart = 0 ! where the first dash starts
dashQ = 0 ! counter for dashes
flag = 0 ! stopper for while loop
! count dashes
while flag = 0 do
! add a dash to the count
dashQ = dashQ + 1
! advance to the next dash start
dashStart = dashStart + dashLen + gapLen
! if that's beyond the end, stop
if dashStart > lineLen then flag = 1
endwhile
! start of final dash
dashStart = dashStart - dashLen - gapLen
! is the last dash trimmed by the end of the object
if dashStart + dashLen > lineLen then
bTrimDash = 1
trimLen = lineLen - dashStart ! special length for last dash
else
bTrimDash = 0 ! object ends with gap, no special dash
endif
! normal dashes, omit last if trimmed
for k = 1 to dashQ - bTrimDash
lin_ 0, 0, 0, dashLen, 0, 0
addx dashLen + gapLen
next k
! special trimmed last dash if needed
if bTrimDash then lin_ 0, 0, 0, trimLen, 0, 0
del dashQ - bTrimDash
Built-in Parameter
Um z.B. den Umbaustatus eines Objekts zu erfragen, verwendet man n = APPLICATION_QUERY ("OwnCustomParameters", "GetParameter(Renovation.RenovationStatus)", parValue)
.
parValue
hält nun den Status als lokalisierten (!) String.
Alle eingebauten Parameter: (Ausgabe im 2D)
DIM folderNamesArray[]
n = APPLICATION_QUERY ("OwnCustomParameters", "GetParameterFolderNames()", folderNamesArray)
for i = 1 to vardim1(folderNamesArray) step 3
DIM parNamesArray[]
querystring = "GetParameterNames(" + folderNamesArray[i] + ")"
n = APPLICATION_QUERY ("OwnCustomParameters", querystring, parNamesArray)
text2 0, 0, querystring
add2 1, -1
_nLines = 1
for j = 1 to vardim1(parNamesArray) step 3
parValue = ""
querystring = "GetParameter(" + parNamesArray[j] + ")"
n = APPLICATION_QUERY ("OwnCustomParameters", querystring, parValue)
text2 0, 0, querystring + ": " + parValue
add2 0, -1
_nLines = _nLines + 1
next j
del _nLines
add2 0, -_nLines
next i