Monday, May 20, 2013

Leaf Srf

DayTwo_Leaf Paneling

The Leaf Surface investigates the python scripting possibilities to accommodate a fairly simple paneling principle. Panels are bent in the diagonal axis according to their distance parameters to the point of attraction. A surface, populated with these customized elements can create and interesting structure with smooth transitions between closed and open /bent/ quads.

CODE:

import rhinoscriptsyntax as rs

#obtain surface from rhino
srf = rs.GetObject("Pick the reference surface",8)
attractor = rs.GetObject("Please pick a Point of attraction",1)
attractorCoord = rs.PointCoordinates(attractor)

#surface domain
uDomain = rs.SurfaceDomain(srf, 0)
vDomain = rs.SurfaceDomain(srf, 1)

#print uDomain,vDomain
uLength = uDomain[1] - uDomain[0]
vLength = vDomain[1] - vDomain[0]

subdivU = 20
subdivV = 20

stepU = uLength/subdivU
stepV = vLength/subdivV

#surface sampling

#main list which will contain sub-list/rows
mainList = []
mainListNormals = []
listDistances = []

rs.EnableRedraw(False)

for i in rs.frange(uDomain[0],uDomain[1]+0.01,stepU):
for j in rs.frange(vDomain[0],vDomain[1]+0.01,stepV):
ptCoord = rs.EvaluateSurface(srf,i,j)
Pt = rs.AddPoint(ptCoord)
distance = rs.Distance(attractor,Pt)
rs.DeleteObject(Pt)
listDistances.append(distance)

listDistances.sort()
distMin = listDistances[0]
distMax = listDistances[len(listDistances)-1]

if distMin > distMax:
distMax = listDistances[0]
distMin = listDistances[len(listDistances)-1]

treshold = (distMax-distMin)*0.5

print distMin
print distMax

for i in rs.frange(uDomain[0],uDomain[1]+0.01,stepU):
#sub-list containing pts
subList = []
subListNormals = []
for j in rs.frange(vDomain[0],vDomain[1]+0.01,stepV):
ptCoord = rs.EvaluateSurface(srf,i,j) #3d coordinates Pt
NormalCoord = rs.SurfaceNormal(srf,[i,j])#3d coordinates Pt offset

PtN = rs.AddPoint(NormalCoord)
Pt = rs.AddPoint(ptCoord) #3d point ID

PtN = rs.VectorUnitize(PtN)
distance = rs.Distance(attractor,Pt)
if (distMax-distance)<treshold:
PtNormal = Pt
else:
PtN = rs.VectorScale(PtN,(distMax-distance-treshold)**2/250)
PtNormal = rs.VectorAdd(Pt,PtN)

subList.append(Pt)
subListNormals.append(PtNormal)
mainListNormals.append(subListNormals)
mainList.append(subList)
#-----------------------------------------------------------------------------
#Paneling

filletRad = 0.5

for i in range(0,len(mainList)-1):
for j in range(0,len(mainList[i])-1):
Pt00 = mainList[i][j]
# Pt01 = mainList[i+1][j]
Pt02 = mainList[i+1][j+1]
# Pt03 = mainList[i][j+1]
# Pts = [Pt00,Pt01,Pt02,Pt03,Pt00]
# rs.AddCurve(Pts,1)

# Pt00N = mainListNormals[i][j]
Pt01N = mainListNormals[i+1][j]
# Pt02N = mainListNormals[i+1][j+1]
Pt03N = mainListNormals[i][j+1]
# PtsN = [Pt00N,Pt01N,Pt02N,Pt03N,Pt00N]
Pts001 = [Pt00,Pt01N]
Pts002 = [Pt01N,Pt02]
Pts011 = [Pt02,Pt03N]
Pts012 = [Pt03N,Pt00]

crv01 = rs.AddCurve(Pts001,2)
crv02 = rs.AddCurve(Pts002,2)

crv11 = rs.AddCurve(Pts011,2)
crv12 = rs.AddCurve(Pts012,2)

#add fillets
strFilletCrv00 = rs.AddFilletCurve(crv12,crv01,filletRad)
strFilletCrv10 = rs.AddFilletCurve(crv11,crv02,filletRad)

#evaluate fillets for points
dblFilletCrvDomain00 = rs.CurveDomain(strFilletCrv00)
FilletPt00 = rs.EvaluateCurve(strFilletCrv00,dblFilletCrvDomain00[0])
FilletPt01 = rs.EvaluateCurve(strFilletCrv00,dblFilletCrvDomain00[1])

dblFilletCrvDomain10 = rs.CurveDomain(strFilletCrv10)
FilletPt10 = rs.EvaluateCurve(strFilletCrv10,dblFilletCrvDomain10[0])
FilletPt11 = rs.EvaluateCurve(strFilletCrv10,dblFilletCrvDomain10[1])

#add new lines inbetween the quad corners and the fillet ends
crv01 = rs.AddCurve([Pt03N,FilletPt00],3)
crv02 = rs.AddCurve([Pt01N,FilletPt01],3)

crv11 = rs.AddCurve([Pt03N,FilletPt10],3)
crv12 = rs.AddCurve([Pt01N,FilletPt11],3)

#join the fillets and curves and loft them to a surface
joinedCrv01 = rs.JoinCurves([crv01,strFilletCrv00,crv02],True)
joinedCrv02 = rs.JoinCurves([crv11,strFilletCrv10,crv12],True)

# print joinedCrv01[0]

rs.RebuildCurve(joinedCrv01[0],3,30)
rs.RebuildCurve(joinedCrv02[0],3,30)

rs.AddLoftSrf([joinedCrv01[0],joinedCrv02[0]])

rs.EnableRedraw(True)

Saturday, May 18, 2013

branching algorithm on a surface

DayThree_Branching Algorithm

The Branching Algorithm has been done as a individual assignment, to practice the scripting skills on a project which can be developed also after the workshop.
This algorithm consists of three main logical steps :


01.   generating Points in the boundary between 4 corners of a subSurface


02.   generating a branch by finding the nearest Point from the last nearest Pt found /starting at corners

03.   repeating the branching process to a subdivided Surface, generating a unique branching pattern each time the process is run on a subSurface of a Surface

The next steps in further development will be to adapt the branch lengths and threshold value for finding the nearest point individually for each subSurface by applying a surface attractor.

CODE:


import rhinoscriptsyntax as rs
import random as rnd

#definition for finding a random point between two points
def randomPtbetweenTwoPoints (strPt00,strPt01):
vec01 = rs.VectorCreate(strPt01,strPt00)
vec01 = rs.VectorScale(vec01,rnd.random())
vecPt01 = rs.VectorAdd(strPt00,vec01)
return vecPt01


#------------------------------------------------------------------------------
#SURFACE EVALUATION#

strSrf = rs.GetObject("Pick a surface",8)
#strAttractor = rs.GetObject("Pick an attractor",1)

#get srf domains
listDomainU = rs.SurfaceDomain(strSrf,0)
listDomainV = rs.SurfaceDomain(strSrf,1)

#getdomain lengths
Udivision = 10
Vdivision = 10

domainULength = listDomainU[1]-listDomainU[0]
domainVLength = listDomainV[1]-listDomainV[0]

#get domain Tstep
uStep = domainULength/Udivision
vStep = domainVLength/Vdivision

#declaring empty Main and Sub Lists
mainListPt = []
mainListNormal = []

rs.EnableRedraw(False)

#starting to evaluate with loop
for i in rs.frange(listDomainU[0],listDomainU[1]+0.01,uStep):
subListNormal = []
subListPt = []
for j in rs.frange(listDomainV[0],listDomainV[1]+0.01,vStep):

#evaluate surface for Ptcoordinates
PtCoord = rs.EvaluateSurface(strSrf,i,j)
Pt = rs.AddPoint(PtCoord)

#evaluate surface for normals
normal = rs.SurfaceNormal(strSrf,[i,j])
normal = rs.VectorUnitize(normal)
 
#append the Pts to the subList and the subList to the mainList
subListPt.append(Pt)
mainListPt.append(subListPt)
#------------------------------------------------------------------------------


intIterations = 80
listPtsRandom = []
gen = 16

# running a loop to find the strating corners of each subSurface quad and generating branches
for k in range(0,Udivision):
for l in range (0,Vdivision):

#corners of the quad
strPt00 = mainListPt[k][l]
strPt01 = mainListPt[k+1][l]
strPt02 = mainListPt[k+1][l+1]
strPt03 = mainListPt[k][l+1]

#generating Pts inbetween the four corner of each quad
for i in range(0,intIterations):
PtA = randomPtbetweenTwoPoints(strPt00,strPt01)
PtB = randomPtbetweenTwoPoints(strPt03,strPt02)

ptRandom = randomPtbetweenTwoPoints(PtA,PtB)

listPtsRandom.append(ptRandom)
rs.AddPoints(listPtsRandom)

#generating the branches from each quad corner
listLines = []

ClosestPt = strPt00

ClosestPts = [strPt00,strPt01,strPt02,strPt03]

for i in range(0,gen):
newClosestPts = []
# print "gen", i
for j in range (0,len(ClosestPts)):
# print "point", j
newIndexPt = rs.PointArrayClosestPoint(listPtsRandom,ClosestPts[j])
newClosestPt = listPtsRandom.pop(newIndexPt)
strLine = rs.AddLine(ClosestPts[j],newClosestPt)
listLines.append(strLine)
newClosestPts.append(newClosestPt)
ClosestPts = newClosestPts

strPolyline = rs.JoinCurves(listLines,True)

rs.EnableRedraw(True)

Thursday, May 16, 2013

Tower Script

DayOne_TowerScript

The python script uses a simple rhinoscript functions like rotate, scale, copy object functions to create a loft surface based on the curve input. Script also utilizes math functions like sin() for distribution of the curve profiles along Z axis.

CODE:

import rhinoscriptsyntax as rs
import math

strFloor = rs.GetObject("Pick a closed curve representing the floor slab.", 4)
strCenterPt = rs.CurveAreaCentroid(strFloor)
listFloors = []
maxFloors = 50
strFloorCopy = rs.CopyObject(strFloor)

for i in range(0,maxFloors):
print math.sin(i)+1
strFloorCopy = rs.CopyObject(strFloorCopy,[0,0,(math.sin(i)+1)])
strCenterPt = rs.CurveAreaCentroid(strFloorCopy)
strFloorRotate = rs.RotateObject(strFloorCopy,strCenterPt[0],i*(360/maxFloors))
strFloorScale = rs.ScaleObject(strFloorRotate,strCenterPt[0],[0.98,0.98,0])

listFloors.append(strFloorScale)

rs.AddLoftSrf(listFloors)


Scripted Tower


Tuesday, May 7, 2013


Computational Design: Responsive Surfaces












NUMINUS

Numinous is a rain shelter, inspired by water collection methods of plants and japanese garden fixtures. It can change between different porous states in dry and wet weather. Numinus was developed as a research group project at the Architectural Association (2012) between: Guy Austern, Marie Boltenstern, Javier A Cardos, &  Marina Konstantatou

The overall shape of a module is determined by a recursive algorithm (written in Python, in the Grasshopper plug-in for Rhinoceros) that manipulates parameters, such as the spacing and angles between the different components. These modules are then articulated into different types of aggregations that conform to the chosen site’s conditions.

Monday, May 6, 2013

Computational Design: BRIDGE+








BRIDGE+

BRIDGE+ is an application of digital computational tools to urban and architectural design.
The project has been originally conceived as a design proposal for the Europan 11 Competition and then developed as a Master Thesis at the AA EmTech (Emergent Technologies and Design Programme, Architectural Association School of Architecture, London, 2011) by Pierluigi D’Acunto, Norman Hack and Camila Rock de Luigi. BRIDGE+ answers the question of how an infrastructure can act as a seed for new urban development in the suggested sites of Skien and Porsgrunn, located in the Grenland District (Norway). In particular, the project proposes a series of inhabitable pedestrian footbridges to be placed along the river that flow through the Grenland District. In addition, the bridges are intended to be directly connected to the public transport network.

Within the framework of Evolutionary Compu­tation, a set of four genetic algo­rithms (EVO+00, EVO+01, EVO+02, EVO+03) has been developed as the main generative tool of BRIDGE+. The algorithms work in a hierarchical way. Starting from the urban scale and moving to the architectural scale and eventually to the material system, the output of each of them represents the input for the next one. The algorithms are based on customized code written in Python and they take advantage of the 3D digital design platform McNeel Rhinoceros and Grasshopper.

Preparing the lectures

Some sneak-peeks of the lecture's slides we are preparing!



Thursday, May 2, 2013


Computational design, or more specifically the use of digital generative and evaluative tools for architectural design, has been heralded as the new paradigm in architecture for the last decade. Digital design techniques coupled with rapid prototyping have permeated architectural education and practice at all levels. But, besides the endless rhetoric and baseless forms, what can these methods actually contribute to the field? What is the scope of their use? The workshop sought to answer these questions by investigating surfaces, surface mathematics and manipulations, and using this investigation to design small (and beautiful) artefacts to be fabricated.


Schedule:
Day 01 – Introduction
•        Introduction: course description and objectives, introduction to scripting and parametric design
•        Preliminary settings: installation of the Python plugin and introduction to the environment
•        Variables and flow
•        Data types (Integers, doubles, strings)
•        Mathematical operations and logical operators
•        Computational geometry: vector and points (xyz coordinates)
•        Introduction to lists
•        Defining a problem, individual / group assignments
Day 02 
•        Computational geometry: curves (t parameter)
•        Geometry analysis and manipulation: rhinoscript syntax
•        Conditional statements
•        Loops
•        Nested lists
•        Solving a problem, individual / group assignments
Day 03
•        Scripted / not scripted
•        Computational geometry:  surfaces (u,v parameters)
•        Theory of tessellation
•        Simple to complex tessellations
•        Mesh vs. nurbs (vs. solid)
•        Fabrication processes and issues
•        Finalizing a design, individual / group assignments

24HRS Python Workshop

Computational design, or more specifically the use of digital generative and evaluative tools for architectural design, has been heralded as the new paradigm in architecture for the last decade. Digital design techniques coupled with rapid prototyping have permeated architectural education and practice at all levels. But, besides the endless rhetoric and baseless forms, what can these methods actually contribute to the field? What is the scope of their use? This workshop seeks to answer these questions by investigating surfaces, surface mathematics and manipulations, and using this investigation to introduce students to the issues of design and fabrication of artifacts. The workshop will thus introduce participants to the basic concepts for design utilizing scripting techniques, through the exploration of the Python language for Rhinoceros. Together with the study of syntax, data types and scripting techniques the focus will be put on the understanding of the digital tools in relation with the common practice and the ways to approach problems a designer might encounter while using them.