Straight Flight Stair Documentation
Index
1. General Description
The purpose of this library part is to produce an architectural correct, simple straight flight stair with clear GDL scripts and well-designed user interface. We used the Straight Flight Stair of the standard ArchiCAD 8 library and the Stair Maker stair as a starting point, together with information we gathered from our users.
1.1. 2D look

The 2D representation has been fully re-designed. Now it has the united the knowledge of the old RC Straight Flight Stair object and Stairmaker. It can be story sensitve, which means that the stair can be represented differently on different stories. It can be scale sensitive, in which case the drawing elements appear regarding the actual scale of the 2D window.
1.2. 3D look

The 3D model is mainly the same as the RC Straight Flight Stair in the ArchiCAD Library. It provides the same connection types as the Monolith version of the old stair. There is no spinebeam. The handling of nosing has changed, in this version Riser Angle and Tread Cover Nosing are separate values. Tread Cover Edging is added.
1.3. User Interface
The 2D representation of the stair needed to be highly customizable, but we also wanted to keep the number of parameters as low as possible. To achieve this, in many cases we assume, that a value or an attribute will most likely be equal to another one, so there is no need to introduce a new parameter. (E.g. we show the stair on lower stories with the same line attributes as we do on the home story above the breakline, since both represent a structure above my horizontal cut plane.)
We used two kinds of hierarchy among the parameters:
- some are ordered under others in the parameter list to create hierarchy
- some are hidden or grayed out depending on another parameter (grayed out if its value is important, even though it cannot be set)
The user interface tab pages cover only the most important part of the whole parameter set. This makes up nine pages with clearly defined role for each.
We chose the most commonly used parameters, and placed them on the Custom Settings tab pages, in the same structure as they appear in the parameter list. Navigation between these pages is possible by the "Previous" and "Next" buttons and the tabpage chooser at the top of each page. By the latter control, each page has a title. The controls were placed in the same style (alignment, spacing) as they are placed everywhere in the tool settings dialog boxes. Whereever needed, we used graphics and text instead of only text (e.g. connection to other structures...).
2. Parameters
| Parameter Name | Type | Description | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| storyHeight | Length | Story height | ||||||||||||||||||||
| riseCalcMethod | String |
Rise Calculation Method: Number of risers - the user can set the number of risers, the riser height is calculated from the story height Preferred Height - the user can set a desired height of the risers, the actual riser height and the riser number are calculated from the story height |
||||||||||||||||||||
| pth | Length | Preferred riser height | ||||||||||||||||||||
| nRiser | Integer | Number of risers | ||||||||||||||||||||
| th | Length | Riser height | ||||||||||||||||||||
| runCalcMethod | String |
Run Calculation Method: Run Length - the user can set the actual tread depth or the total stair length (nRiser is fix) Calculate by "2 x Rise + Run" - the user can set the target value of the rule, the actual tread depth is calculated (riser height is fix) |
||||||||||||||||||||
| rule1_thd | Length | Target value for the "2 x Rise + Run" rule | ||||||||||||||||||||
| td | Length | Run Length / Tread Depth | ||||||||||||||||||||
| B_full | Length | Total Stair Length | ||||||||||||||||||||
| slabThickness | Length | Stair Slab Thickness: at the slimmest point of the stair structure (without covers) | ||||||||||||||||||||
| width | Length | Flight Width / Width of the stair structure (without covers) | ||||||||||||||||||||
| widthFull | Length | Full WIdth of the stair (with covers) | ||||||||||||||||||||
| gs_2D_representation | Title | 2D Representation | ||||||||||||||||||||
| gs_cont_pen | PenColor | Primary Pen - used for all lines of the 2D drawing | ||||||||||||||||||||
| ltContour | LineType | Primary Line Type - line type of the actual story | ||||||||||||||||||||
| ltRiser | LineType | Riser Line Type - line type of riser lines | ||||||||||||||||||||
| gs_fill_type | FillPattern | Primary Fill Type - fill type of the actual story | ||||||||||||||||||||
| gs_fill_pen | PenColor | Primary Fill Pen - fill pen of the actual story | ||||||||||||||||||||
| gs_back_pen | PenColor | Primary Fill Background Pen - fill pen of the actual story | ||||||||||||||||||||
| bScaleSensitive | Boolean |
Scale Sensitive - if set, the presence of the 2D drawing elements is calcuated from the actual scale
|
||||||||||||||||||||
| shRailing2D | String |
Show Railing: On / Off / In Large Scale Only If "In Large Scale Only" is set, the railing is shown if the scale is greater than 1:200. |
||||||||||||||||||||
| bRailingIn2D | Boolean | Checkbox version of the above parameter for the user interface tabpage | ||||||||||||||||||||
| shTreadLines | Boolean | Show Tread Lines | ||||||||||||||||||||
| shHiddenRiserLines | Boolean | Show Riser Lines | ||||||||||||||||||||
| shWalkingLine | Boolean | Show Walking Line | ||||||||||||||||||||
| penWalkingLine | PenColor | Walking Line Pen | ||||||||||||||||||||
| ltWalkingLine | LineType | Walking Line Type | ||||||||||||||||||||
| walkingDirUPDN | Boolean | Walking Line Direction UP/DN - checkbox version of walkingDir. | ||||||||||||||||||||
| walkingDir | String |
|
||||||||||||||||||||
| bUpDownText | Boolean | Show UP/DN Text at the end of the walking line. It is obligatory set if walkingDir = UP/DN. | ||||||||||||||||||||
| penUpDownText | PenColor | UP/DN Text Pen Color | ||||||||||||||||||||
| upDownFontSize | RealNum | UP/DN Text Size | ||||||||||||||||||||
| shNumbering | Boolean | Show tread numbering | ||||||||||||||||||||
| numOffset | Integer | The number the tread numbering starts from. | ||||||||||||||||||||
| penNumbering | PenColor | Numbering Pen | ||||||||||||||||||||
| numberingFontSize | RealNum | Numbering Font Size | ||||||||||||||||||||
| shText | Boolean |
Show walking line text Text format: "riser num R. @ th = storyHeight m" and "tread num T. @ td = B_full m" |
||||||||||||||||||||
| penText | PenColor | Walking Line Text Pen | ||||||||||||||||||||
| fontsize | RealNum | Walking Line Text Size | ||||||||||||||||||||
| textType | String | Walking Line Text Prefix: R/T or Rise/Run | ||||||||||||||||||||
| bStorySensitive | Boolean | Story Sensitive | ||||||||||||||||||||
| breakHeight | Length | Height of break from the bottom of the stair | ||||||||||||||||||||
| bBreakOnUpper | Boolean | There is break on upper story | ||||||||||||||||||||
| breakLineStyle | String |
Breakline Style
|
||||||||||||||||||||
| ltAboveBreakline / ltBelowBreakline | LineType | Line Type Above / Line Type Below | ||||||||||||||||||||
| bDrawContAB / bDrawContBB | Boolean | Fill Above / Fill Below | ||||||||||||||||||||
| fillTypeAB / fillTypeBB | FillPattern | Fill Type Above / Fill Type Below | ||||||||||||||||||||
| fillPenAB / fillPenBB | PenColor | Fill Pen Above / Fill Pen Below | ||||||||||||||||||||
| fillBackAB / fillBackBB | PenColor | Fill Background Above / Fill Background Below | ||||||||||||||||||||
| bDrawTreadsAB / bDrawTreadsBB | Boolean | Tread Above / Tread Below | ||||||||||||||||||||
| bDrawRisersSecAB / bDrawRisersSecBB | Boolean | Riser Above / Riser Below | ||||||||||||||||||||
| bDrawArrowAB / bDrawArrowBB | Boolean | Walking Line Above / Walking Line Below | ||||||||||||||||||||
| bNumberingAB / bNumberingBB | Boolean | Numbering Above / Numbering Below | ||||||||||||||||||||
| gs_3D_representation | Title | 3D Representation | ||||||||||||||||||||
| resCurve | Integer | Curve resolution | ||||||||||||||||||||
| gs_detlevel_3D | 3D Detail Level: if not Detailed, no cover edging, no non-slip insert will be generated and the curved railing parts will be rectangular. | |||||||||||||||||||||
| ConnectionTitle | Title | Connection to other structures | ||||||||||||||||||||
| firstTreadLevel | String | Level of the first tread: "At Floor Level" or "Above Floor Level" | ||||||||||||||||||||
| botJunctionType | String | Lower junction type - the junction differs if the lower connecting slab is a landing or the groundfloor. The difference is that the groundfloor slab expands below the stair. | ||||||||||||||||||||
| botSlabThick | Length | Thickness of the lower connecting slab | ||||||||||||||||||||
| topTreadLevel | String | Level of the top tread: "At Floor Level" or "Below Floor Level" | ||||||||||||||||||||
| topSlabThick | Length | Thickness of the upper connecting slab | ||||||||||||||||||||
| TreadTitle | Title | Tread Size and Style | ||||||||||||||||||||
| riserAngle | Angle | Riser Angle![]() |
||||||||||||||||||||
| bTreadCover | Boolean | Tread Cover ![]() |
||||||||||||||||||||
| covthick | Length | Tread cover thickness (1) | ||||||||||||||||||||
| covNosing | Length | Tread cover nosing (2) | ||||||||||||||||||||
| covOHLeft, covOHRight | Length | Tread cover left / right overhang | ||||||||||||||||||||
| bRiserCover | Boolean | Riser Cover | ||||||||||||||||||||
| covthicky | Length | Riser cover thickness | ||||||||||||||||||||
| bNonSlip | Boolean | Non-slip tread inserts | ||||||||||||||||||||
| nonSlipLength | Length | Insert length | ||||||||||||||||||||
| coverEdging | String |
Tread Cover Edging
|
||||||||||||||||||||
| bSpecialFirstRiser | Boolean | Starting Step Half Circle - the inserts don't run on the half circles. | ||||||||||||||||||||
| firstRiserLeftR, firstRiserRightR | Length | Radius of the left / right half circle. If 0, no half circle is generated. | ||||||||||||||||||||
| rail | String | Rail: None / Left / Right / Both | ||||||||||||||||||||
| railHeight | Length | Rail height | ||||||||||||||||||||
| handrailShape | String |
Handrail cross-section
|
||||||||||||||||||||
| railWidth | Length | Handrail width | ||||||||||||||||||||
| handrailDepth | Length | Handrail depth | ||||||||||||||||||||
| postNumberingStyle | String |
Post Placement - The post are distributed with equal spaces as possible and they stand on the centerline of a tread.
|
||||||||||||||||||||
| nPost | Integer | Number of Posts (if postNumberingStyle = "By Number") | ||||||||||||||||||||
| postShape | String | Post & bar cross-section: Rectangular or Circular | ||||||||||||||||||||
| postWidth, barWidth | Length | Post / Bar thickness | ||||||||||||||||||||
| rightRailType | String | Type of right rail | ||||||||||||||||||||
| rRailOffset | Length | Offset of the right rail from the stair edge. Positive direction points outside. | ||||||||||||||||||||
| leftRailType | String | Type of left rail | ||||||||||||||||||||
| lRailOffset | Length | Offset of the left rail from the stair edge. Positive direction points outside. | ||||||||||||||||||||
| MaterialTitle | Title | Materials | ||||||||||||||||||||
| matStairSlab, matTreadCover, matRiserCover, matPost, matFrame, matBaluster | Material | Material of the Stair Slab / Tread Cover / Riser Cover / Posts / Handrail / Bars | ||||||||||||||||||||
| StoreyTitle | Title | Stories | ||||||||||||||||||||
| bServiceStoreys | Boolean | There are interstitial stories between real stories. In this case the upper story is 2 stories up. For proper work set the objects "Show On" value to "All Stories". | ||||||||||||||||||||
| sFarestAbove | String | Show on stories (above): 2 stories above Home / 3 stories above Home. Since for proper work you have to set the objects "Show On" value to "All Stories", you have the possibility to specify the farest story above home, the object is shown on. | ||||||||||||||||||||
| sFarestBelow | String | Show on stories (below): 2 stories below Home / 3 stories below Home. Since for proper work you have to set the objects "Show On" value to "All Stories", you have the possibility to specify the farest story below home, the object is shown on. |
3. Development decisions, ideas
3.1. General issues
You can see a common styling code in the scripts of the object. It is advisable to use an obvious style in capitalization, line breaks, tabulation, commenting, in-line spacing and variable names. In this file you find the following:
- capitalization - the keywords are lowercase to match the taste of C/C++/Java developers (which are the most used programming languages in application development nowadays); the complex variable names are lowescase with uppercase letters at the start of each word but the first, f. ex.:
onHomeStorey,iBreakPos. The global variable names are uppercase, f. ex.:WIDO_ORIG_DIST - line breaks - line breaks are the tool for grouping things: group commands with extra line breaks, group parameters by line breaks
- tabulation - the content of a
forcycle or anifbranch is always indented with one tab character. There are no exeptions for that rule! - commenting - there is a two-level comment practice in this object: main parts are separated by longer lines and more linebreaks and shorter comment-lines indicate the start of a smaller code section
- in-line spacing - one space before and one after binary operators (+, -, *, /, %, >, <, =, <>, etc.), one space after each ",". No space after unary operators (-).
- variable names - the complex variable names are lowescase with uppercase letters at the start of each word but the first, f. ex.:
onHomeStorey,iBreakPos. Don't use one or two letter variable names, no one will know what you ment. To achieve higher clarity some type prefixes may be used, f. ex.:bfor boolean [bRailingIn2D],penfor pen color [penMain],ltfor line type [ltBelowBreakline],matfor material [matCover],nandifor integer values (number and index) [nRiser, iBreakPos],xandyfor coordinates [xLeftRailPos, yRailStart]
Values - which are used many times - are calculated directly before the block of use
if the usage can be well localized or at the beginning of the script otherwise.
There is no compromise.
Calculate complex values only once to spare calculation time and store them in variables
(but do not waste variables unnecessary) or in the transformation stack
(add, rot, etc.).
3.2. Script structure
The scripts of the object are of linear structure which makes them clearer. Subroutines are only used when a calculation or model generation segment is needed more than one time. For only one call no subroutine is needed, use comments for clarity. It is an important principle to avoid coding the same thing twice. Redundancy will make the later changes much more difficult. If you make big choice branches, you can't avoid this situation. Try to prepare the data for a calculation or generation command in smaller choices, where you can avoid redundancy easier.
Bad Example
if onHomeStorey then line_type ltContour fill gs_fill_type poly2_b 5, 3, gs_fill_pen, gs_back_pen, left, 0, 1, left, -td, 1, right, -td, 1, right, 0, 0, left, 0, -1 endif if (onUpperStorey or onAboveUpper) and bDrawContBB then line_type ltBelowBreakline fill fillTypeBB poly2_b 5, 3, fillPenBB, fillBackBB, left, 0, 1, left, -td, 1, right, -td, 1, right, 0, 0, left, 0, -1 endif
The definition of geometry is duplicated! It could be even worse if the distance between the identical commands were bigger.
Good Example
if onHomeStorey then line_type ltContour fill gs_fill_type fillPen = gs_fill_pen fillBGPen = gs_back_pen endif if (onUpperStorey or onAboveUpper) and bDrawContBB then line_type ltBelowBreakline fill fillTypeBB fillPen = fillPenBB fillBGPen = fillBackBB endif poly2_b 5, 3, fillPen, fillBGPen, left, 0, 1, left, -td, 1, right, -td, 1, right, 0, 0, left, 0, -1
3.3. Master Script
There may be only common calculations in the Master Script,
which are needed in more than one other script.
In this case, these are some details of the geometry of the stair
(used both in 2D and 3D) and the EPS definition.
This second is very important issue in GDL, because the floating point numbers
need extra care in comparison.
That's why it usually makes no sense comparing two floating point numbers by a = b.
Use the abs (a - b) < EPS expression instead.
3.4. 2D Script
The script begins with the determination of the story and the drawing scale. These will affect the whole 2D look. After the calculation of some generally used values, the 2D model generation begins with the stair block. Significant care was taken to avoid the duplicated definition of geometry. So the elements are put only once. The generation of the unsplit rectangular stair polygon is a good - and simple - exapmle for this.
! --- full rectangular polygon --- bGo = 0 if (not(shBreakLine) and (onHomeStorey or onUpperStorey)) then bGo = 1 fill gs_fill_type fillPen = gs_fill_pen fillBGPen = gs_back_pen endif if onBelowHome and bDrawContAB then bGo = 1 fill fillTypeAB fillPen = fillPenAB fillBGPen = fillBackAB endif if onAboveUpper and bDrawContBB then bGo = 1 fill fillTypeBB fillPen = fillPenBB fillBGPen = fillBackBB endif if bGo then poly2_b 5, 2, fillPen, fillBGPen, left, -nosingPlusCover, contType, right, -nosingPlusCover, contType, right, td * nRiser, contType, left, td * nRiser, contType, left, -nosingPlusCover, -1 endif
The same polygon can appear in four cases where only some parameters differ. This section presents the stair fill for each case, that is the effect of the linear sturcture of the script.
After this, the code sections of 2D elements follow: tread lines, riser lines, walking line, connections, walking line text, tread numbering, railing and editable hotspots.
Care must be taken when using the text2 command,
because the text can be upside down depending on the rotation angle of the stair.
See the tread numbering for example:
REQUEST ("Height_of_style", "textstyle", strHeight) strHeight = strHeight / 1000 * GLOB_SCALE ... if SYMB_ROTANGLE > 90 and SYMB_ROTANGLE < 270 then rot2 180 strWidth = STW(str("%.0", i + numOffset)) / 1000 * GLOB_SCALE add2 -strWidth, strHeight else rot2 0 add2 0, 0 endif text2 0, 0, i + numOffset del 2
3.5. 3D Script
The 3D Script has the same structure as the 2D Script. It is linear and consists of blocks which generate a separate part of the stair.
There is nothing special about this script, let's mention the editable hotspots here. All the editable hotspots have a unique ID, to manage this a counter is used. Even the best GDL programmers forget or mix up the codes of the different types of hotspots sometimes, so simple comments are put.
uid = uid + 1 hotspot left, yTop, zTop, uid, widthFull, 1+256 ! base uid = uid + 1 hotspot left-0.1, yTop, zTop, uid, widthFull, 3 ! reference uid = uid + 1 hotspot right, yTop, zTop, uid, widthFull, 2 ! moving
3.6. Interface Script
The Interface Script has two things to mention. The first issue is the collection of common things in the tab pages. One common thing is the position of the columns of controls:
wEditText = 79 hEditText = 23 xText = 57 xColumn1 = 205 xColumn2 = 365
Another common thing is the header part of the pages. This consists of the same controls, so the creation of them became a subroutine.
!!!!!!!!!!!!!!!!!!!!!!! *** Page 2 *** !!!!!!!!!!!!!!!!!!!! !!! Calculation Methods !!! ui_page 2 ! --- draw the header part of the page --- gosub 1 ui_pict 12, 0, 35 ... ! ======================================================================= ! draw the header part of the page ! ----------------------------------------------------------------------- ! Remark: ! The routine places a page chooser and the Previous and Next buttons ! on the top of the page. ! Other UI items may begin at the Y position of 35. ! ======================================================================= 1: ui_style 2, 1 ui_infield{3} "gs_ui_current_page", 14,3, 210,20, 2, "", 9, 1, cx,cy, px, 35, "", `General Stair Geometry`, 1, "", `Calculation Methods`, 2, "", `Primary 2D Representation`, 3, "", `2D Representation`, 4, "", `Walking Line & Numbering`, 5, "", `Connection to other Structures`, 6, "", `Connection Structure Dimensions`, 7, "", `Tread Size and Style`, 8, "", `Tread Edging`, 9 ui_button ui_prev, `<< Previous`, 250, 3, 90, 20 ui_button ui_next, `Next >>`, 350, 3, 90, 20 ui_separator 0, 30, 444, 30 ui_style 2, 0 return
The second issue is the paging method introduced in ArchiCAD 10. Going this way the first thing to do is adding a parameter named gs_ui_current_page. This parameter is set by the running environment (ArchiCAD or other agent) when the Previous or Next buttons are pushed. The next step is instructing ArchiCAD to display the page appointed by this parameter. This can be done in the beginning of the UI script like this:
ui_current_page gs_ui_current_page
Now you can set the current page index in the parameter script or you can define an infield as a page chooser control. The code section above defines such a control.

