Page 1

...a story about modern architecture


parametric architecture


well...that all looks very nice... ...but how can you value architecture that results out of some computer calculations?


hold on ... is that actually architecture?


I began studying architecture in 2003 at the Technical University in Vienna. My education focused on a very technical and structural part of design. Therefore, moving on with my studies I appropriated myself a quite structural approach towards architecture. On the one hand, it has its positive and “realistic” attitudes, but on the other hand there is always a line that can’t be exceeded. The design can only go as far as my head can imagine its outcome. I have always been fascinated by amazing modern architecture where its perception crosses the line of understanding. Maybe as a result, my opinion towards such concepts has been quite critical. Often I didn’t value these projects; because I thought that architecture, which is designed by a computer, loses its origin.


Is parametric architecture the future of architecture?

You can’t ignore the changes of modern architecture... Therefore I want to challenge myself and start understanding that topic to actually be able to form an opinion about it.


Last year I was chosen to go as an exchange student between RMIT University in Melbourne and Technical University in Vienna. One reason why I wanted to take the opportunity to study at this particular university, was the possibility to explore a new approach towards the design process trough computer scripting.

I am very excited about possible outcomes, in particular, how my thinking regarding modern architecture may change. Maybe if I know this topic a little better, I can start to understand its structure and therefore its value to me changes.


FIRST STEPS


it all started with one little point


Option Explicit 'Script written by <martina hatzenbichler> 'Script copyrighted by <martinsche corperation> 'Script version Saturday, 7 March 2009 3:53:38 PM Call DrawPoint() Sub DrawPoint() Dim arrPoint(2) Dim i,k,j For i=0 To 9 For k=0 To 9 For j=0 To 9 arrPoint(0)=k arrPoint(1)=i arrPoint(2)=j Next Next End Sub

Next

Call Rhino.AddPoint (arrPoint)


Option Explicit 'Script written by <martina hatzenbichler> 'Script copyrighted by < martinsche corperation > 'Script version Saturday, 7 March 2009 3:53:38 PM Call DrawPoint() Sub DrawPoint() Dim arrCenter(2) Dim i,k,j Dim dblRadius For i=0 To 9 For k=0 To 9 arrCenter(0)=k arrCenter(1)=i arrCenter(2)=0 If i<2 Or k<2 Then dblRadius=0.1*i Call Rhino.AddSphere (arrCenter, dblRadius) End If Next End Sub

Next


Option Explicit 'Script written by <martina hatzenbichler> 'Script copyrighted by < martinsche corperation > 'Script version Sunday, 8 March 2009 11:42:20 AM Call Main() Sub Main() Dim arrPoint(2) Dim i,j,k For i=0 To 9 For j=0 To 9 For k=0 To 9 arrPoint(0)=i*j arrPoint(1)=j*k arrPoint(2)=k*i Call Rhino.AddPoint (arrPoint) Next Next Next End Sub


the points become lines ...


the lines form a grid ...


the grid becomes a surface ...

- get user to pick a surface - dublicate and subdivide edgecurves - find the closest point on srf to edgesubdivision and extract isocurves in u-v direction - create new srf with each isocurve - create a sphere in the middle of the new surfaces based on the curvature


- a facade of a building could place windows, its size depending on certain factors (sunlight, weather exposure etc.) - a structure of a facade could break up where less is needed or when curved elements wouldnâ&#x20AC;&#x2122;t be appropriate (material - wood, too expensive, etc)


Inspired by the book “tooling” by Aranda/Lasch


SUBDIVISIONS


- get user to pick an initial closed polyline - split polyline in single curves - divide each line into certain segments - loop trough each line to add new lines by connecting divisionpoints - store them in dynamic array - starting the script again until a certain generation is reached


first subdivision script Option Explicit ‘Script written by <martina hatzenbichler> ‘Script copyrighted by <martinsche corperation> ‘Script version Montag, 13. April 2009 20:33:32 Call Main() Sub Main() Dim arrObject Dim dblGen,dblCurrentGen Dim dblProp If Not (Rhino.IsProcedure(“DynamicArrayProxy”)) Then Rhino.Command “-LoadScript DynamicArray.rvb” End If

dblCurrentGen = 0

‘get user input’

arrObject = Rhino.getObject(“pick a closed polyline”,4) dblProp = Rhino.GetInteger(“get Proportion”) dblGen = Rhino.GetInteger(“choose generation of subdivisions”)

Call Rhino.EnableRedraw(False)

‘call recursive function’

Call RecursiveSubdivison(arrObject,dblGen,dblCurrentGen,dblProp)

Call Rhino.EnableRedraw(True)

End Sub Function RecursiveSubdivison(arrObject,dblGen,dblCurrentGen,dblProp)

Dim Dim Dim Dim Dim Dim

arrCurves arrDivisionPoints() i arrNewCurve arrNewCurveClosed arrNewCurveObject


If dblCurrentGen < dblGen Then

Dim arrSecondCurvePoint Set arrSecondCurvePoint = New DynamicArray

‘explode this polyline into its single curves’ arrCurves= Rhino.ExplodeCurves(arrObject)

‘devide each polyline into 5 pieces’ For i=0 To Ubound(arrCurves)

ReDim Preserve arrDivisionPoints(i)

arrDivisionPoints(i) = Rhino.DivideCurve(arrCurves(i),dblProp)

‘store second point in dynamic array’ arrSecondCurvePoint.push (arrDivisionPoints(i)(1))

Next

‘to close polyline arrSecondCurvePoint.push (arrSecondCurvePoint.Data(0))

‘convert dynamic array to ‘normal’ array arrSecondCurvePoint = arrSecondCurvePoint.DataArray

‘connect those new points with each other to form a new polyline’ If IsArray(arrSecondCurvePoint) Then

arrNewCurve=Rhino.AddPolyline(arrSecondCurvePoint)

Else Call Rhino.MessageBox(“screeeeeam”) End If

‘clean up Call Rhino.DeleteObjects(arrCurves)

Else Exit Function End If

dblCurrentGen = dblCurrentGen+1

Call RecursiveSubdivison(arrNewCurve,dblGen,dblCurrentGen,dblProp)

End Function


changing subdivisions, generations and connecting points


subdivisions create curves


applying created subdivisions to an object


when subdivisons become 3d


pick a closed polyline


subdivide polyline until a certain generation


create surfaces out of subdivisions


add colourrange based on surface-area


move surface based on surface-area


add colourrange

arrSRFarea = Rhino.SurfaceArea (arrNewSrf(0)) dblSRFarea = abs (arrSRFarea(0)/1000) If dblSRFarea >= 255 Then Call Rhino.ObjectColor (arrNewSrf,RGB(1,0,0)) Else Call Rhino.ObjectColor(arrNewSrf, RGB(255-dblSRFarea,0,0)) End If

move surface

Call Rhino.MoveObject (arrNewSrf(0), array(0,0,0),array(0,0,dblSRFarea))


initual curve


top view


perspective 1


perspective 2


a game ...


starts with a polyline ...


....50 generations, 2 divisions


....20 generations, 8 divisions


....100 generations, 50 divisions


back <<<


changing the playrules ...


..to create a constant height and thickness


it then ...


... becomes a staircase


... with some structure


- get surfacevolume centroid of each surface - draw a line from each centroid to c-plane - loop trough the lines and create pipes


subdivisions ‘constant hight’ script Option Explicit 'Script written by <martina hatzenbichler> 'Script copyrighted by <martinsche corporation> 'Script version Tuesday, 14 April 2009 3:47:32 PM Call Main() Sub Main()

Dim Dim Dim Dim Dim Dim Dim

arrObject dblCurrent dblMax dblDiv arrCurves Nr delete

'get user input' arrObject = Rhino.GetObject("pick a closed polyline",4) dblMax = Rhino.GetInteger("choose number of generation") dblDiv = Rhino.GetInteger("choose an equal(2 or 4 or 6 or 8 or 10...) number of division")

'exlode initual curve for subdivisions' arrCurves = Rhino.ExplodeCurves(arrObject) dblCurrent = 0 Nr = 0 If Not (Rhino.IsProcedure("DynamicArrayProxy")) Then Rhino.Command "-LoadScript DynamicArray.rvb"

End If

Call Subdivisionsyeah(arrCurves,dblCurrent,dblMax,dblDiv,Nr)

Call Rhino.EnableRedraw(False)

'clean up' delete = Rhino.ObjectsByType(4) Call Rhino.DeleteObjects(delete) Rhino.EnableRedraw(True)

End Sub


Function Subdivisionsyeah(arrCurves,dblCurrent,dblMax,dblDiv,Nr) ‘if certain generation is reached exit function’ If dblCurrent >= dblMax Then Exit Function End If

Dim arrSubdivision Set arrSubdivision = New DynamicArray

Dim Dim Dim Dim Dim Dim Dim Dim Dim

‘divide all curves into certain number of subdivisions’

arrNewLine arrSrfLines, arrLastSrfLines arrSplitSrfLines, arrSplitLastSrfLines arrNewSrf, arrNewLastSrf i,j arrDivPoints() arrLastLine arrSRFarea dblSRFarea

For i = 0 To Ubound(arrCurves)

ReDim Preserve arrDivPoints(i)

Next

arrDivPoints(i) = Rhino.DivideCurve(arrCurves(i),dblDiv)

‘loop trough each line to create new line’ For j = 0 To (Ubound(arrCurves)-1)

‘firstlines’

‘add colourgradient based on the surface area’

arrNewLine = Rhino.AddLine(arrDivPoints(j)(1),arrDivPoints(j+1)(1)) arrSrfLines = Rhino.AddPolyline(array(arrDivPoints(j)(1),arrDivPoints(j+1)(0),arrDivPoints(j+1)(4),arrDivPoints(j)(1))) arrSplitSrfLines = Rhino.ExplodeCurves(arrSrfLines) arrNewSrf = Rhino.AddPlanarSrf (arrSplitSrfLines) arrSubdivision.Push (arrNewLine)

arrSRFarea = Rhino.SurfaceArea(arrNewSrf(0)) dblSRFarea = abs(arrSRFarea(0)/1000)


If dblSRFarea >=255 Then Call Rhino.ObjectColor(arrNewSrf,RGB(1,0,0)) Else Call Rhino.ObjectColor(arrNewSrf,RGB(255-dblSRFarea,0,0)) End If ‘increase hight and move surface’ Nr=Nr+10 Call Rhino.MoveObject (arrNewSrf(0), array(0,0,0),array(0,0,Nr)) ‘clean up’ Call Rhino.DeleteObjects(arrSplitSrfLines) Next

‘lastline’ arrLastLine = Rhino.AddLine(arrDivPoints(Ubound(arrDivPoints))(1),arrDivPoints(0)(1)) arrLastSrfLines = Rhino.AddPolyline(array(arrDivPoints(Ubound(arrDivPoints))(1),arrDivPoints(Ubound(arrDivPoints))(dblDiv), arrDivPoints(0)(1),arrDivPoints(Ubound(arrDivPoints))(1))) arrSplitLastSrfLines = Rhino.ExplodeCurves(arrLastSrfLines) arrNewLastSrf = Rhino.AddPlanarSrf (arrSplitLastSrfLines)

arrSubdivision.Push (arrLastLine) arrSRFarea = Rhino.SurfaceArea(arrNewLastSrf(0)) dblSRFarea = abs(arrSRFarea(0)/1000) ‘add colourgradient based on the surface area’ If dblSRFarea >=255 Then Call Rhino.ObjectColor(arrNewLastSrf,RGB(1,0,0)) Else Call Rhino.ObjectColor(arrNewLastSrf,RGB(255-dblSRFarea,0,0)) End If


‘move surface’ Call Rhino.MoveObject (arrNewLastSrf(0), array(0,0,0),array(0,0,Nr)) Call Rhino.DeleteObjects(arrSplitLastSrfLines) arrSubdivision = arrSubdivision.DataArray ‘clean up’ Call Rhino.DeleteObjects(arrCurves) dblCurrent = dblCurrent+1 Call Subdivisionsyeah(arrSubdivision,dblCurrent,dblMax,dblDiv,Nr)

End Function


script to create structure for each polysurface Option Explicit 'Script written by <Martina Hatzenbichler> 'Script copyrighted by <martinsche corporation> 'Script version Friday, 29 May 2009 5:21:06 PM Call Main() Sub Main() Dim arrSubdivision Dim i Dim arrCentroid Dim arrStrunctureLine Dim pipeRadius Dim STRLines Set STRLines = New DynamicArray 'get user input' arrSubdivision = Rhino.Getobjects ("get polysurfaces",(16)) pipeRadius = Rhino.GetReal("Enter radius of pipestructure") Call Rhino.EnableRedraw(False) 'loop trough each polysurface' For i=0 To Ubound(arrSubdivision) 'get objects centroid' arrCentroid = Rhino.SurfaceVolumeCentroid (arrSubdivision(i)) 'draw a line from the centroid of each object to groundlevel and store in dynamic array' arrStrunctureLine = Rhino.AddLine(arrCentroid(0), array(arrCentroid(0)(0),arrCentroid(0)(1),(0))) STRLines.Push (arrStrunctureLine) Next STRLines = STRLines.DataArray Call PipeAll(STRLines,pipeRadius) Call Rhino.EnableRedraw(True) End Sub


Function PipeAll(STRLines,pipeRadius) Dim Str Dim i 'loop trough each line and create pipe' For i=0 To Ubound(STRLines)

Rhino.SelectObject STRLines(i)

Str = CStr("Pipe Enter " & pipeRadius & " " & pipeRadius & " Enter")

Rhino.Command Str

Rhino.UnselectAllObjects

Next

End Function


it then becomes a building


... or a pavillion


... or a sculpture


when subdivisons become architecture


pick an outline ...


create a constant height


offset surfaces to create a thickness


add a structure to each created plattform


when subdivisons become a city


basic city grids

New York

London

San Francisco

Copenhagen

Toronto

Rome


subdividing the subdivisions

... to offer the possibility of growth


the subdivisions change their behaviour based on certain attractors


the created subdivisions which are not intersecting with any attractors - stop intersecting


the created subdivisions which are not intersecting with any attractors - stop intersecting - are deleted


pick a cityoutline and attractors mainstreet, important citypoint, rivers, etc


dividing towards attractors until certain srf-area


delete surfaces if not intersecting any attractor


create a â&#x20AC;&#x2DC;towerâ&#x20AC;&#x2122; in the center of each surface depending on srf area

a possible value-based placeholder for later input


from each surface a tower is created

its size is shaped depending on surface-area (towers might intersect with each other)


towers are only created if area stopped intersecting

to avoid towers to intersect with each other


comparison

1

2


pick your own towerbase


user input

arrObject = Rhino.GetObjects(“pick the outline of a city”,4) arrAttractorCrv = Rhino.GetObjects(“pick an attractor curve”) dblMin = Rhino.GetInteger(“choose min surface area”) arrTowerBase=Rhino.GetObjects(“pick an outline for the towerbase”)


‘pick your own tower-base’ function Function towers(towerBases,arrTowerBase) Dim obj Dim arrSplitPolyline Dim arrCentr Dim arrpath Dim arrTower Dim dblLevel Dim arrTowerBaseCentr Dim arrCopyTowerBase Dim arrTowerBaseSrf arrTowerBaseCentr = Rhino.CurveAreaCentroid (arrTowerBase) dblLevel=10 'get info for tower----lots of info' For Each obj In towerBases dblLevel=dblLevel+1 Next End Function

arrCentr=Rhino.CurveAreaCentroid(obj) arrCopyTowerBase = Rhino.CopyObject(arrTowerBase(0),arrTowerBaseCentr(0),arrCentr(0)) 'draw tower based on the slected crv' arrSplitPolyline = Rhino.ExplodeCurves(arrCopyTowerBase) arrTowerBaseSrf= Rhino.AddPlanarSrf (arrSplitPolyline) 'add path to extrude surface to form tower' arrpath = Rhino.AddLine(array(0,0,0),array(0,0,dblLevel)) arrTower = Rhino.ExtrudeSurface (arrTowerBaseSrf(0), arrpath,True) 'clean up ' Call Call Call Call

Rhino.DeleteObjects(arrSplitPolyline) Rhino.DeleteObject(obj) Rhino.DeleteObject(arrpath) Rhino.DeleteObjects(arrTowerBaseSrf)


sections


pick a different ‘tower-base’

..here the script can interact with other scripts


uniform tower height


a city ...


...when subdivisions create parks, courtyards and towers


based on the surface area, the city-divider creates...

...parks

...towers

...courtyard-buildings

arrTowerBase = Rhino.ScaleObject (arrSRF(0), arrC(0),array(0.2,0.2,0.2)) arrTowerBasearea = Rhino.SurfaceArea(arrTowerBase) If arrTowerBasearea(0) > 1000 Or arrTowerBasearea(0) < 100 Then 'if area too big, add a park' If arrTowerBasearea(0) > 1000 Then Rhino.CurrentLayer ("Park") arrpath = Rhino.AddLine(array(0,0,0),array(0,0,10)) arrBaseCourtyard = Rhino.ScaleObject (arrSRF(0), arrC(0), array(4,4,0)) arrBlockCourtyard = Rhino.ExtrudeSurface (arrBaseCourtyard, arrpath,True) 'clean' Call Rhino.DeleteObject(arrpath) Call Rhino.DeleteObject(arrBaseCourtyard) End If 'if area too small, add a tower' If arrTowerBasearea(0) < 100 Then Rhino.CurrentLayer ("Tower") arrpath = Rhino.AddLine(array(0,0,0),array(0,0,sqr(dblLevel)*10)) arrBaseCourtyard = Rhino.ScaleObject (arrSRF(0), arrC(0), array(4,4,0)) arrBlockCourtyard = Rhino.ExtrudeSurface (arrBaseCourtyard, arrpath,True) 'clean' Call Rhino.DeleteObject(arrpath) Call Rhino.DeleteObject(arrBaseCourtyard) End If 'else add a courtyard kind of building' Else Rhino.CurrentLayer ("Courtyard") arrpath = Rhino.AddLine(array(0,0,0),array(0,0,sqr(dblLevel)*8)) arrTower = Rhino.ExtrudeSurface (arrTowerBase, arrpath,True) 'draw courtyard block based on srf area arrBaseCourtyard = Rhino.ScaleObject (arrSRF(0), arrC(0), array(4,4,0)) arrBlockCourtyard = Rhino.ExtrudeSurface (arrBaseCourtyard, arrpath,True) ' cut out towerbase from courtyardblock to form courtyard...and therefore street, towerblock and each courtyard' arrCourtyard = Rhino.BooleanDifference (array(arrBlockCourtyard), array(arrTower),True) End If


pick a city outline


get attractor curves


subdivide until certain srf-area


created towers


created courtyard-buildings


created parks


resulting city-structure


‘city-divider’ The ‘city-divider’-script offers the possibility to create various cities with different densities. The script is built up on certain user inputs.

The user is asked to pick a city outline and then some attractors - curves which are intersecting with the cityoutline. The attractor-curves can represent mainroad systems, rivers or important areas in the city such as city centers, buisness districts, housing areas etc. The user decides on a minimum surface area at which the script stops intersecting.

Now, the script starts to create certain building typologies based on the respective surface areas. it loops through each polyline and; If the area is too big, it creates a park, with minimal constant height, If the area is too small, it creates a tower, with height increasing the closer to an attractor, Otherwise, creates typical city buildings with a courtyard, with less variance within height differences.

This values can be changed easily in the script to create different values within a city. Trough changing the heights of each buildingtype or the value that creates them, the ‘city-divider’ can create - greener cities or denser cities - city centers with office towers or family based housing districts etc.


‘city-divider’ script Option Explicit 'Script written by <martina hatzenbichler> 'Script copyrighted by <martinsche corporation> 'Script version Samstag, 16. Mai 2009 10:58:56 Call Main() Sub Main()

Dim Dim Dim Dim

arrObject dblCurrent dblMin arrAttractorCrv

'get user input' arrObject = Rhino.GetObjects("pick the outline of a city",4) arrAttractorCrv = Rhino.GetObjects("pick an attractor curve") dblMin = Rhino.GetInteger("choose min surface area") dblCurrent = 0

If Not (Rhino.IsProcedure("DynamicArrayProxy")) Then Rhino.Command "-LoadScript DynamicArray.rvb"

End If

Rhino.EnableRedraw(True)

Rhino.EnableRedraw(False) Call subdivisioncitymap(arrObject,dblMin,arrAttractorCrv)

End Sub Function subdivisioncitymap(arrObject,dblMin,arrAttractorCrv) Dim arrCentroid Dim arrCurves Dim arrCurveMidPoint() Dim arrPolyline Dim i, obj Dim arrCurvePts Dim arrPolylines Dim dblCurrent Dim arrCheckIntersection Dim dblIntersections Dim LayerJames


Dim bla Set bla = New DynamicArray Dim towerBases Set towerBases = New DynamicArray If Not IsNull(arrObject) Then ‘looping trough all attractors and check for any intersecting’ For Each obj In arrObject dblIntersections=0 For i=0 To Ubound(arrAttractorCrv) arrCheckIntersection= Rhino.CurveCurveIntersection (obj,(arrAttractorCrv(i))) If Not IsNull(arrCheckIntersection) Then dblIntersections=dblIntersections+1 End If Next If Not dblIntersections=0 Then ‘ thats the important bit i turned off or on’ ‘Call Rhino.DeleteObject(obj) bla.Push (obj) Else towerBases.Push (obj) End If Next ‘looping trough each subdivision which “pass” the test of area and intersection’ arrObject=bla.DataArray bla.flush For Each obj In arrObject ‘get the midpoint of the closed polyline citything’ arrCentroid = Rhino.CurveAreaCentroid (obj) ‘get the endpoints the curves is made out of’ arrCurvePts =Rhino.CurveEditPoints (obj)


‘take your curve and split it into its lines’ arrCurves = Rhino.ExplodeCurves(obj) ‘get the midpoint of each line’ For i=0 To (Ubound(arrCurves)) ReDim Preserve arrCurveMidPoint(i) arrCurveMidPoint(i) = Rhino.CurveMidPoint(arrCurves(i)) Next ‘connect each midpoint of each line with the center’ For i=0 To (Ubound(arrCurves)-1) arrPolyline = Rhino.AddPolyline(array(arrCurveMidPoint(i),arrCurvePts(i+1),arrCurveMidPoint(i+1),arrCentroid(0), arrCurveMidPoint(i))) dblCurrent = Rhino.CurveArea(arrPolyLine) ‘check if the area is too small If dblCurrent(0) < dblMin Then Call Rhino.DeleteObject(arrPolyLine) Else bla.Push (arrPolyline) End If Next ‘last polyline’ arrPolyline = Rhino.AddPolyline(array(arrCurveMidPoint(Ubound(arrCurveMidPoint)),arrCurvePts(0),arrCurveMidPoint(0), arrCentroid(0),arrCurveMidPoint(Ubound(arrCurveMidPoint)))) ‘check if the area is too small If dblCurrent(0) < dblMin Then Call Rhino.DeleteObject(arrPolyLine) Else bla.Push (arrPolyline) End If Next ‘cleaning’ Call Rhino.DeleteObjects(arrCurves) arrPolylines=bla.DataArray ‘this is veeeery important...either to turn it off or on->subdiv the subs or not’ ‘bla.flush


End If End Function

Call subdivisioncitymap(arrPolylines,dblMin,arrAttractorCrv) Rhino.AddLayer (“Layer_James Layer”) Rhino.CurrentLayer(“Layer_James Layer”) towerBases=towerBases.DataArray Call towers(towerBases)

Function towers (towerBases)

creates towers, buildings with courtyards and parks based on surfaces area. This part is changed easely and therefore different city patterns are created


...when subdivisions create city districts


pick city district outlines


get attractor curves

attractor area (places of interest) attractor curve (water way, road)


subdivide until certain srf-area


create city based on certain rules


SCRIPTING BESIDE CITIES


i canâ&#x20AC;&#x2122;t believe that i am actually having fun with writing scripts for computers ...


...scripting brithday presents


...created subdivisions become a facade-structure


ideas of scripting architecture


toolbar for emergent urbanism TOOLING EMERGENT URBANISM

BUILDING HIGHT

or `tenging’

FACADE SUN LOUVRES STREET WIDTH

or `shading’

or `width of the street ‘

CONNECTED FACILITIES

or `salt and pepper’


TOOL

DESCRIPTION


My approach towards architecture and modern technology has changed a lot since I have immersed myself in the topic. It has made me understand that there is a lot more behind it then just letting the computer design for you. Without the process of the architects consideration and manual intervention it just remains a computer program without any use. The basic idea, how the system developes and what possible outcomes it might provide, still has to come from the designer themselves. Itâ&#x20AC;&#x2122;s a new language that is, at the beginning, quite hard to learn, but once you understand the basic rules, it becomes a very interessting and useful design tool that offers a much broader approach towards architecture.


written by Martina Hatzenbichler Studentnr. 3242104 Strange Procedures Tim Schork, Paul Minifie

the big pot of generating things  

first steps in computer scripting