Updated class now has 2 different types with 2 different heights. The small units also rotate to give various terrace locations/orientation. Assembled with previous core/stair classes, and booleaned off with larger, terrace/voids.
import rhinoscriptsyntax as rs
from random import choice
import random
from System.Drawing import Color
Xnumber = 8
Ynumber = 8
Znumber = 8
#################################################################
# 1. CELL (Condition/Rules)
class Cell():
def __init__(self, x, y, z):
self.X = x
self.Y = y
self.Z = z
self.Pos = [x,y,z]
self.Visibility = False # Cell’s visibility(True means On/Alive, False means Off/Dead)
self.N = 0 # Number of Neighboring Cells
def getVisibility(self):
return self.Visibility
def setVisibility(self, v): # v will be True or False
self.Visibility = v
def getN(self):
return self.N
def setN(self, n): # n is the number of neighbors
self.N = n
def getX(self):
return self.X
def getY(self):
return self.Y
def getZ(self):
return self.Z
def getPos(self):
return self.Pos
def updateVisibility(self):
if (self.Visibility == True): # ALIVE cell = apply rule1_visibility
self.rule1_Visibility()
else: #(self.Visibility == False) # DEAD cell = apply rule2_visibility
self.rule2_Population()
def rule1_Visibility(self):
if (self.N < 10):
self.setVisibility(False)
elif (self.N < 15):
self.setVisibility(True)
else:
self.setVisibility(False)
def rule2_Population(self):
if (self.N == 0 or self.N == 5 or self.N == 10):
self.setVisibility(True)
elif (self.N < 5):
self.setVisibility(False)
elif (self.N < 15):
self.setVisibility(True)
else:
pass
#################################################################
# 2. SET OF CELLS
class SetOfCells():
def __init__(self):
self.ListCells = [] # list containing all cell classes
self.generateCells() # these two functions automatically run when the class is initiated.
self.setSeeds()
def generateCells(self):
xCellList = [] # this is the outer list of nested list(ListCells)
for x in range(Xnumber):
yCellList = [] # this is the inner list of a nested list(ListCells)
for y in range(Ynumber):
zCellList = []
for z in range(Znumber):
c = Cell(x,y,z)
zCellList.append(c)
yCellList.append(zCellList)
xCellList.append(yCellList)
self.ListCells = xCellList # returns the nested list into self.ListCells
def setSeeds(self): # this function defines initial states of cells
for x in range(Xnumber):
for y in range(Ynumber):
for z in range(Znumber):
cell = self.ListCells[x][y][z]
if (x > 0 and x < 8 and y > 0 and y < 8 and z > 0 and z < 8): # initial condition
cell.setVisibility(True)
else:
cell.setVisibility(False)
def getCells(self): # getter for self.ListCells
return self.ListCells
#################################################################
# 3. AUTOMATA CONTROLLER
class AutomataController():
def __init__(self):
self.ListCells = []
self.SC = SetOfCells() # generate cells and contain them in a list
self.M = AutomataModel() # initiates AutomataModel
def initiateModel(self):
self.ListCells = self.SC.getCells() # gets the generated cells
self.M.setListCells(self.ListCells) # passes the list of cells into AutomataModel
self.M.repeatProcesses() # calls repeating processes
#################################################################
# 4. AUTOMATA MODEL
class AutomataModel():
def __init__(self):
self.ListCells = [] # will be passed by AutomataConroller
self.V = AutomataView() # initiates View class
def setListCells(self, lc): # s etter
self.ListCells = lc
def repeatProcesses(self): # repeats the two processes and make geometries
iterationNumber = 5
for i in range(iterationNumber):
self.checkNeighboringCells()
self.updateCellVisibility()
self.V.setListCells(self.ListCells) # passes self.ListCells into View
points = self.V.getCoordinates() # makes Geometries
center = self.V.getCenter ()
self.V.makeBoxes (points, center)
self.V.moveGeometries() # deletes geometries for the next iteration
def checkNeighboringCells(self): # the “1)” process
for i in range(1,Xnumber-1):
for j in range(1,Ynumber-1):
for k in range(1,Znumber-1):
cell = self.ListCells[i][j][k] # gets each cell information
x = cell.getX()
y = cell.getY()
z = cell.getZ()
n = self.calculateNumberOfNeighboringCells(x,y,z)
cell.setN(n)
def calculateNumberOfNeighboringCells(self, x, y, z):
cell0 = self.ListCells[x-1][y-1][z-1]
cell1 = self.ListCells[x][y-1][z-1]
cell2 = self.ListCells[x+1][y-1][z-1]
cell3 = self.ListCells[x-1][y][z-1]
cell4 = self.ListCells[x][y][z-1]
cell5 = self.ListCells[x+1][y][z-1]
cell6 = self.ListCells[x-1][y+1][z-1]
cell7 = self.ListCells[x][y+1][z-1]
cell8 = self.ListCells[x+1][y+1][z-1]
cell9 = self.ListCells[x-1][y-1][z]
cell10 = self.ListCells[x][y-1][z]
cell11 = self.ListCells[x+1][y-1][z]
cell12 = self.ListCells[x-1][y][z]
cell13 = self.ListCells[x+1][y][z]
cell14 = self.ListCells[x-1][y+1][z]
cell15 = self.ListCells[x][y+1][z]
cell16 = self.ListCells[x+1][y+1][z]
cell17 = self.ListCells[x-1][y-1][z+1]
cell18 = self.ListCells[x][y-1][z+1]
cell19 = self.ListCells[x+1][y-1][z+1]
cell20 = self.ListCells[x-1][y][z+1]
cell21 = self.ListCells[x][y][z+1]
cell22 = self.ListCells[x+1][y][z+1]
cell23 = self.ListCells[x-1][y+1][z+1]
cell24 = self.ListCells[x][y+1][z+1]
cell25 = self.ListCells[x+1][y+1][z+1]
v0 = cell0.getVisibility()
v1 = cell1.getVisibility()
v2 = cell2.getVisibility()
v3 = cell3.getVisibility()
v4 = cell4.getVisibility()
v5 = cell5.getVisibility()
v6 = cell6.getVisibility()
v7 = cell7.getVisibility()
v8 = cell8.getVisibility()
v9 = cell9.getVisibility()
v10 = cell10.getVisibility()
v11 = cell11.getVisibility()
v12 = cell12.getVisibility()
v13 = cell13.getVisibility()
v14 = cell14.getVisibility()
v15 = cell15.getVisibility()
v16 = cell16.getVisibility()
v17 = cell17.getVisibility()
v18 = cell18.getVisibility()
v19 = cell19.getVisibility()
v20 = cell20.getVisibility()
v21 = cell21.getVisibility()
v22 = cell22.getVisibility()
v23 = cell23.getVisibility()
v24 = cell24.getVisibility()
v25 = cell25.getVisibility()
sum = v0+v1+v2+v3+v4+v5+v6+v7+v8+v9+v10+v11+v12+v13+v14+v15+v16+v17+v18+v19+v20+v21+v22+v23+v24+v25
return sum
def updateCellVisibility(self): # the “2)” process
for x in range(1,Xnumber-1):
for y in range(1,Ynumber-1):
for z in range(1,Znumber-1):
cell = self.ListCells[x][y][z]
cell.updateVisibility()
#################################################################
# 5. AUTOMATA VIEW
class AutomataView():
def __init__(self):
self.ListCells = [] # will be passed by AutomataModel
def setListCells(self, lc):
self.ListCells = lc
def getCoordinates(self):
ptlist = []
for x in range(Xnumber):
for y in range(Ynumber):
for z in range(Znumber):
cell = self.ListCells[x][y][z]
visibility = cell.getVisibility()
if visibility == True:
pos = cell.getPos()
ptlist.append (pos)
length = len (ptlist)
return ptlist
def getCenter(self):
ptlist = []
for x in range(Xnumber):
for y in range(Ynumber):
for z in range(Znumber):
cell = self.ListCells[x][y][z]
visibility = cell.getVisibility()
if visibility == True:
pos = cell.getPos()
shift = 0.5
center = [pos[0]+shift, pos[1]+shift, pos[2]]
ptlist.append (center)
print ptlist
return ptlist
def makeBoxes (self, points, center):
length = len (points)
print “point list =”, points
print “point list length =”, length #prints # of POINTS
percent = 0.8 * length # set PERECNTAGE
minority = int(percent) # count of input percentage of all POINTS
print “minority # =”, minority
majority = length – minority # count of remaining percentage of all POINTS
########################################################################
#for minority units
minorityrandomlist = []
for i in range(minority):
randomvalues = random.randint (0, length-1)
minorityrandomlist.append (randomvalues)
minorityrandomlist = list (set(minorityrandomlist)) #removes duplicate numbders
minorityrandomlist.sort() #sorts the list in ascending order
print “minority random list =”, minorityrandomlist
for r in minorityrandomlist :
rs.AddLayer(“Small Unit”, Color.Red)
rs.CurrentLayer(“Small Unit”)
rectangle = rs.AddRectangle(points[r], 0.5, 1)
path = rs.AddLine([0,0,0], [0,0,0.5]) # Height
extrusion = rs.ExtrudeCurve (rectangle, path)
rs.CapPlanarHoles(extrusion)
rotation = [0, 90, 180, 270]
angle = choice(rotation)
rs.RotateObjects(extrusion, center[r], angle)
rs.DeleteObject(path)
rs.DeleteObject (rectangle)
########################################################################
#for majority units
majorityrandomlist = []
for i in range (length):
majorityrandomlist.append (i)
print “majority random list =”, majorityrandomlist
for x in minorityrandomlist:
majorityrandomlist.remove (x)
for r in majorityrandomlist: #Makes Large Unit
rs.AddLayer(“Large Unit”, Color.Blue)
rs.CurrentLayer(“Large Unit”)
rectangle = rs.AddRectangle(points[r], 1, 1)
path = rs.AddLine([0,0,0], [0,0,1]) # Height
extrusion = rs.ExtrudeCurve (rectangle, path)
rs.CapPlanarHoles(extrusion)
rs.DeleteObject(path)
def moveGeometries(self):
#rs.Sleep(1000)
allObjIDs = rs.AllObjects()
trans = [20,0,0]
rs.MoveObjects(allObjIDs, trans)
#################################################################
# 6. RUN AUTOMATA CONTORLLER
ac = AutomataController()
ac.initiateModel()