import rhinoscriptsyntax as rs import random as ran import math # Delete everything and start from scratch allobjs = rs.AllObjects() rs.DeleteObjects(allobjs) rs.EnableRedraw(False) #------------------------------------------------------------------------------- # dom-ino variables: #------------------------------------------------------------------------------- A = 5 # A = Module size (distance between columns) B = A/3 # B = Distance of columns to end of plate thick = 0.2 # thickness of all slabs hgt = 2.7 # height of room xcol = 2 # columns in x direction ycol = 3 # columns in y direction levels = 5 # number of floor plates f_height= 0.5 # f_height = foundation height f_size = 0.8 # f_size = foundation edge size w_pts = 360 # number of Facade Elements w_height= hgt*(levels-f_size) # w_height = hight of the facade w_size = 0.02 # w_size = facade edge size frequency = 0.5 # distance of the wave #insertion = [A*(xcol-1)/2,A*(ycol-1)/2, f_height] #------------------------------------------------------------------------------- # stair values #------------------------------------------------------------------------------- s_width = 2.4 # s_width = stair total width pod_l = 1.8 # pod_l = depth of landing tt = 0.3 # length of steps th = 0.17 # initial rise setting thmax = 0.19 # maximum acceptable rise #------------------------------------------------------------------------------- # derived values: #------------------------------------------------------------------------------- center_pt = [A*(xcol-1)/2,A*(ycol-1)/2, f_height] # insertion point of floor plate p_width = A*(xcol-1) + 2*B # width of floor plate (x) p_length = A*(ycol-1) + f_size # length of floor plate (y) # function to make box def make_box(insertion=[0,0,0],xsize=10,ysize=10,zsize=10): # Define the corners of the box corners = [[0, 0, 0], [xsize, 0, 0], [xsize, ysize, 0], [0, ysize, 0], [0, 0, zsize], [xsize, 0, zsize], [xsize, ysize, zsize], [0, ysize, zsize]] box=rs.AddBox(corners) rs.MoveObject(box, (-xsize/2,-ysize/2,0)) rs.MoveObject(box, insertion) return(box) #function to create podest def make_podest(insertion=[0,0,0],xsize=10,ysize=10,zsize=10): corners = [[0,0,0], [xsize,0,0], [xsize,ysize,0], [0,ysize,0], [0,0,zsize],[xsize,0,zsize],[xsize,ysize,zsize],[0,ysize,zsize]] box=rs.AddBox(corners) rs.MoveObject(box, insertion) return(box) #function to create curved podest def make_curved_podeststair(curve, th=th, tt=tt, steps=40, thick=thick, s_width=s_width, pod_l=s_width/2, DC=48, P=12, A=0): pts = [[0,0,0]] for i in range(1,steps): #switch=ran.randint(0,9) if(not(i%DC)): ##DC: Direction Change th=-th pts.append([pts[-1][0]+pod_l,pts[-1][1],pts[-1][2]]) pts.append(pts[-1]) pts.append((pts[-1][0]+tt,pts[-1][1],pts[-1][2])) elif(not(i%P)): ##P: Podest pts.append((pts[-1][0]+pod_l,pts[-1][1],pts[-1][2])) pts.append((pts[-1][0]+tt,pts[-1][1],pts[-1][2])) elif(i==1) and (A>0): ##P: Erstes Podest pts.append([pts[-1][0]+A,pts[-1][1],pts[-1][2]]) pts.append([pts[-1][0],pts[-1][1],pts[-1][2]+th]) pts.append([pts[-1][0]+tt,pts[-1][1],pts[-1][2]]) else: ##Regular steps pts.append([pts[-1][0],pts[-1][1],pts[-1][2]+th]) pts.append([pts[-1][0]+tt,pts[-1][1],pts[-1][2]]) if th<0: ## stair ends going down: add a lower edgepoint pts.append([pts[-1][0],pts[-1][1],pts[-1][2]+th]) return_list = [] for i in range(-1,-len(pts),-2): return_list.append((pts[i][0], pts[i][1], pts[i][2]-thick)) pts.extend(return_list) pts.append([pts[0][0], pts[0][1], pts[0][2]-thick]) pts.append(pts[0]) s_outline = rs.AddPolyline(pts) path = rs.AddLine(pts[0],[pts[0][0], pts[0][1]+s_width/2, pts[0][2]]) shadow = rs.AddLine(pts[0],[return_list[0][0], return_list[0][1], pts[0][2]]) s_surf = rs.AddPlanarSrf(s_outline) rs.Command("_Flow _selID {} _Enter _selID {} _selID {} _Enter".format(s_surf[0], shadow, curve), False) profile = rs.FirstObject() stair = rs.OffsetSurface(profile, s_width/4, both_sides=True, create_solid=True) rs.DeleteObjects([s_surf[0], shadow, curve, path, s_outline, profile]) return(stair) # function to create a field of foundations def make_foundations(A=5.0, f_size=0.8, f_height=0.5, xcol=2, ycol=3): fns = [] for i in range(xcol): for j in range(ycol): fns.append(make_box([i*A,j*A,0], f_size, f_size, f_height)) return(fns) # function to create a field of columns def make_columns(A=5.0, level=0.7, thick=0.2, hgt=3.0, xcol=2, ycol=3): cls =[] for i in range(xcol): for j in range(ycol): cls.append(make_box([i*A,j*A,level], thick, thick, hgt)) return(cls) # Function to create a facade with height adapting to the building height def make_facade(insertion=[0, 0, 0], p_width=p_width, p_length=p_length, w_size=w_size, building_height=10, frequency=frequency): fcd = [] plane = rs.WorldXYPlane() plane = rs.RotatePlane(plane, 0, [0, 0, 0]) rec = rs.AddRectangle(plane, p_width, p_length) move_vector = rs.VectorCreate( [center_pt[0] - p_width / 2, center_pt[1] - p_length / 2, center_pt[2] + thick], [0, 0, 0] ) rs.MoveObject(rec, move_vector) fcd.append(rec) pts = rs.DivideCurve(rec, w_pts, False, True) # Create the "facade" layer if it doesnt exist if not rs.IsLayer("facade"): rs.AddLayer("facade") rs.LayerColor("facade", (139, 69, 19)) # Brown color for facade for i, p in enumerate(pts): # Adjust height of each facade element based on sine function and building height random_factor = ran.uniform(0.6, 1) element_height = max(thick, building_height * math.sin(math.radians(frequency * i)) * random_factor) random_size = w_size * ran.uniform(0.8, 1.5) # Create facade element with some random rotation for variety w_box = make_box(insertion, xsize=random_size, ysize=random_size, zsize=-element_height) rs.MoveObject(w_box, p) angle = ran.uniform(-10, 10) # Random rotation angle rs.RotateObject(w_box, p, angle) # Set alternating colors for the facade elements if i % 2 == 0: rs.ObjectColor(w_box, (139, 69, 19)) else: rs.ObjectColor(w_box, (205, 133, 63)) # Assign facade elements to "facade" layer rs.ObjectLayer(w_box, "facade") fcd.append(w_box) rs.DeleteObjects(rec) return fcd, pts # Function to create a Arc def make_arc(insertion, rad, thick, hgt, orientation): segs=[] segs.append(rs.AddArc([0,0,0], rad, 180)) segs.append(rs.AddArc([0,0,0], rad-thick, 180)) segs.append(rs.AddLine([rad,0,0],[rad-thick,0,0])) segs.append(rs.AddLine([-rad,0,0],[-(rad-thick),0,0])) crv=rs.JoinCurves(segs, delete_input=True) path=rs.AddLine([0,0,0],[0,0,hgt]) arc=rs.ExtrudeCurve(crv, path) rs.CapPlanarHoles(arc) rs.DeleteObject(crv) rs.DeleteObject(path) rs.RotateObject(arc, [0,0,0], orientation) rs.MoveObject(arc, insertion) return(arc) # Function to create a terrace def make_terrace(A=5.0, level=0.7, thick=0.2, hgt=3.0, xcol=2, ycol=3): cls =[] for i in range(xcol-1): for j in range(ycol-1): ori = ran.randint(0, 6) if ori<4: orientation = ori*90 cls.append(make_arc([i*A+A/2,j*A+A/2,level], A/2, thick, hgt, orientation)) return(cls) #function to create stair def make_stair(start, th, tt, steps, thick, s_width): pointlist=[start] for i in range(steps): pointlist.append([pointlist[-1][0],pointlist[-1][1],pointlist[-1][2]+th]) pointlist.append([pointlist[-1][0]+tt,pointlist[-1][1],pointlist[-1][2]]) pointlist.append([pointlist[-1][0],pointlist[-1][1],pointlist[-1][2]-thick]) pointlist.append([pointlist[0][0],pointlist[0][1],pointlist[0][2]-thick]) pointlist.append([pointlist[0][0],pointlist[0][1],pointlist[0][2]]) s_outline=rs.AddPolyline(pointlist) path = rs.AddLine(start,[start[0],start[1]+s_width,start[2]]) hull = rs.ExtrudeCurve(s_outline, path) rs.CapPlanarHoles(hull) rs.DeleteObjects((s_outline,path)) return(hull) # Function to create dom-ino def make_domino(A=A, B=B, thick=thick, hgt=hgt, levels=levels, xcol=xcol, ycol=ycol, f_height=f_height, f_size=f_size): f_list = [] # list of foundations c_list = [] # list of columns p_list = [] # list of plates facade_elements = [] # list of facade elements building_height = f_height + (levels-1) * (hgt + thick) # Calculate building height for i in range(levels): center_pt[2] = f_height + i * (thick + hgt) level = f_height + thick + (i - 1) * (hgt + thick) if i == 0: f_list = make_foundations(A, f_size, f_height, xcol, ycol) else: c_list.extend(make_columns(A, level, thick, hgt, xcol, ycol)) if i % 2: c_list.extend(make_terrace(A, level, thick, hgt, xcol, ycol)) p_list.append(make_box(center_pt, p_width, p_length, thick)) # Pass building_height to make_facade facade_elements, _ = make_facade(building_height=building_height) level = f_height + thick + (levels - 1) * (hgt + thick) #--------------------------------------------------------------------------- # Staircase parameters #--------------------------------------------------------------------------- steps = int((hgt + thick) / 0.17) steps = steps - 1 if steps % 2 else steps th = (hgt + thick) / steps steps += 2 if th > 0.19 else 0 th = (hgt + thick) / steps tt = 0.28 s_width = 1.2 pod_w = B start = [0, -(s_width * 2 + f_size / 2), f_height + thick] # Create staircase for each level stair_l = [] for i in range(levels): start[2] = f_height + thick + i * (thick + hgt) if i == levels - 1: stair_l.append(make_podest([start[0] - pod_w, start[1] + s_width, start[2] - thick], pod_w, s_width, thick)) else: stair_l.append(make_podest([start[0] - pod_w, start[1], start[2] - thick], pod_w, s_width * 2, thick)) stair_l.append(make_stair(start, th, tt, int(steps / 2), thick, s_width)) stair_l.append(make_podest([start[0] + (steps / 2) * tt, start[1], start[2] + (steps / 2) * th - thick], pod_w, s_width * 2, thick)) stair_l.append(make_stair([start[0] + (steps / 2) * tt, start[1] + s_width, start[2] + (steps / 2) * th], th, -tt, int(steps / 2), thick, s_width)) return f_list, c_list, p_list, stair_l, facade_elements #------------------------------------------------------------------------------- # Curve functions # various ways of creating randomized or "patternized" 2D curves #------------------------------------------------------------------------------- def make_random_curve(p_num, range_x=10, range_y=10, degree=3): c_points =[] for i in range(p_num): c_points.append([ran.uniform(0,range_x), ran.uniform(0,range_y), 0]) c_points.sort() curve = rs.AddCurve(c_points, degree) return(curve) def make_random_spiral(p_num, min_x=1, max_x=3, mindeg=45, maxdeg=135): c_points =[] cur_angle=ran.uniform(mindeg, 315) for i in range(p_num): radius = ran.uniform(min_x, max_x) angle= ran.uniform(mindeg, maxdeg) cur_angle=angle+cur_angle nextpoint = rs.VectorRotate([radius,0,0],cur_angle, [0,0,1]) c_points.append(nextpoint) curve = rs.AddCurve(c_points, 2) return(curve) def make_random_arcline(p_num, min_x=3, max_x=4, mindeg=15, maxdeg=45): c_points =[] #cur_angle=ran.uniform(mindeg, 315) cur_angle=0 for i in range(p_num): radius = ran.uniform(min_x, max_x) angle= ran.uniform(mindeg, maxdeg) nextpoint = rs.VectorRotate([radius,0,0],cur_angle, [0,0,1]) cur_angle=angle+cur_angle c_points.append(nextpoint) cmd ="-_Polyline _Mode=Arc" for i in range(len(c_points)): cmd += " {},{},{}".format(c_points[i][0], c_points[i][1],c_points[i][2]) cmd +=" _Enter" rs.Command(cmd, False) curve=rs.FirstObject(False) return(curve) #clover pattern: polyline made up of arcs will result in interesting patterns based on angle def make_clover(p_num, radius=3, angle=45, translation=[0,0,0]): c_points =[] cur_angle=0 for i in range(p_num): cur_angle=angle+cur_angle nextpoint = rs.VectorRotate([radius,0,0],cur_angle, [0,0,1]) c_points.append(nextpoint) cmd ="-_Polyline" for i in range(len(c_points)): cmd += " {},{},{} _Mode=Arc".format(c_points[i][0], c_points[i][1],c_points[i][2]) cmd +=" _Enter" rs.Command(cmd, False) curve=rs.FirstObject(False) rs.MoveObject(curve, translation) return(curve) #clover pattern2: polyline made up of arcs will result in interesting patterns based on angle def make_clover2(p_num, radius=3, angle=45, translation=[0,0,0]): c_points =[] cur_angle=0 for i in range(p_num): nextpoint = rs.VectorRotate([radius,0,0],cur_angle, [0,0,1]) cur_angle=angle+cur_angle c_points.append(nextpoint) cmd ="-_Polyline" for i in range(len(c_points)): cmd += " {},{},{} _Mode=Arc".format(c_points[i][0], c_points[i][1],c_points[i][2]) cmd +=" _Enter" rs.Command(cmd, False) curve=rs.FirstObject(False) rs.MoveObject(curve, translation) return(curve) #clover pattern with hack to prevent short-circuiting "nsc = no short-circuiting" def make_clover_nsc(p_num, radius=3, angle=45, translation=[0,0,0]): c_points =[] cur_angle=0 for i in range(p_num): cur_angle=angle+cur_angle nextpoint = rs.VectorRotate([radius,0,0],cur_angle, [0,0,1]) c_points.append(nextpoint) cmd ="-_Polyline" for i in range(len(c_points)): cmd += " {},{},{} _Mode=Arc".format(c_points[i][0], c_points[i][1],c_points[i][2]+i*0.0000001) cmd +=" _Enter" rs.Command(cmd, False) curve=rs.FirstObject(False) rs.Command("-_ProjectToCPlane _selID {} _Enter _Yes _Enter".format(curve), False)# project curve to Cplane rs.MoveObject(curve, translation) return(curve) #clover pattern2 with hack to prevent short-circuiting "nsc = no short-circuiting" def make_clover2_nsc(p_num, radius=3, angle=45, translation=[0,0,0]): c_points =[] cur_angle=0 for i in range(p_num): nextpoint = rs.VectorRotate([radius,0,0],cur_angle, [0,0,1]) cur_angle=angle+cur_angle c_points.append(nextpoint) cmd ="-_Polyline" for i in range(len(c_points)): cmd += " {},{},{} _Mode=Arc".format(c_points[i][0], c_points[i][1],c_points[i][2]+i*0.0000001)# hack to prevent short-circuiting cmd +=" _Enter" rs.Command(cmd, False) curve=rs.FirstObject(False) rs.Command("-_ProjectToCPlane _selID {} _Enter _Yes _Enter".format(curve), False)# project curve to Cplane rs.MoveObject(curve, translation) return(curve) # Ensure that the necessary layers exist def setup_layers(): layers = { "foundation": (100, 40, 19), "columns": (160, 90, 90), "plates": (139, 110, 60), "stairs": (139, 69, 19), } for layer, color in layers.items(): if not rs.IsLayer(layer): rs.AddLayer(layer) rs.LayerColor(layer, color) # Set up layers setup_layers() """ # Create buildings and assign layers at the end for i in range(10): xran = ran.randint(0, 150) yran = ran.randint(0, 150) levels = ran.randint(2, 15) # Create the building f_list, c_list, p_list, stair_l, facade_elements = make_domino(levels=levels) # Move the entire building rs.MoveObjects(f_list + c_list + p_list + stair_l + facade_elements, (xran, yran, 0)) # Assign layers at the end rs.ObjectLayer(f_list, "foundation") rs.ObjectLayer(c_list, "columns") rs.ObjectLayer(p_list, "plates") rs.ObjectLayer(stair_l, "stairs") """ #------------------------------------------------------------------------------- # Stair functions #------------------------------------------------------------------------------- if 0: stair = make_stair([0, 0, 0], th=th, tt=tt * 1.5, steps=15, thick=thick, s_width=s_width * 1.5) #rs.SelectObject(stair) if 0: stair = make_podeststair([0, 0, 0], th=th, tt=tt * 1.5, steps=50, pod_l=pod_l * 1.5, thick=thick, s_width=s_width * 1.5, DC=48, P=12, A=2.0) #rs.SelectObject(stair) #------------------------------------------------------------------------------- # Curved Stair functions #------------------------------------------------------------------------------- if 1: # Adding a larger and more dynamic Clover curve with less density and more open spaces curve = make_clover(36, 8, 15) # Very large spacing and open curves stair = make_curved_podeststair(curve, th=th * 1.5, tt=tt * 1.5, steps=100, pod_l=pod_l * 2, thick=thick * 1.5, s_width=s_width * 1.5, DC=48, P=12, A=2.5) # Bigger steps, larger gaps if 0: # Clover variations with even more air make_clover2(36, 3, 90, (0, -100, 0)) make_clover(36, 3, 90, (20, -100, 0)) make_clover2(90, 3, 80, (0, -60, 0)) make_clover(90, 3, 80, (20, -60, 0)) make_clover2_nsc(24, 3, 80, (0, -20, 0)) make_clover(24, 3, 80, (20, -20, 0)) make_clover2(36, 3, 75, (0, 0, 0)) make_clover(36, 3, 75, (20, 0, 0)) make_clover2(36, 3, 60, (0, 40, 0)) make_clover(36, 3, 60, (20, 40, 0)) if 1: # Dramatic spiral with dynamic changes in radius and height, providing more height and air curve = rs.AddSpiral([0, 0, 0], [0, 0, 1], 0, turns=35, radius0=8, radius1=3) stair = make_curved_podeststair(curve, th=th * 1.8, tt=tt * 1.5, steps=70, thick=thick * 1.5, s_width=s_width * 1.5, pod_l=s_width / 2, DC=341, P=341, A=1.0) # More dynamic and higher spacing if 1: # Creating a higher, more dynamic, and open spiral curve with increased air and dramatic spacing curve = make_clover2_nsc(24, 8, 90, (0, 0, 0)) # Larger spacing, more dramatic turns stair = make_curved_podeststair(curve, th=th * 1.8, tt=tt * 1.5, steps=150, pod_l=s_width / 3, thick=thick * 1.5, s_width=s_width * 1.5, DC=80, P=20, A=1.2) if 1: # High and open clover spiral with exaggerated dynamic features curve = make_clover2_nsc(36, 8, 70, (0, 0, 0)) # Increased spacing and larger curve stair = make_curved_podeststair(curve, th=th * 2.0, tt=tt * 1.5, steps=200, thick=thick * 1.8, s_width=s_width * 1.8, pod_l=s_width / 2, DC=80, P=20, A=2.0) if 1: # Adding a very dynamic and high random spiral with great variations curve = make_random_spiral(10, min_x=8, max_x=12, mindeg=30, maxdeg=60) # More variation, large gaps stair = make_curved_podeststair(curve, th=th * 2.0, tt=tt * 1.6, steps=50, thick=thick * 2, s_width=s_width * 1.5, pod_l=s_width / 2, DC=75, P=20, A=1.2) if 0: # Linear staircase with dramatic waves and varying heights curve = rs.AddLine([0, 0, 0], [100, 0, 0]) stair = make_curved_podeststair(curve, th=th * 1.5, tt=tt * 1.3, steps=15, pod_l=s_width / 3, thick=thick * 1.5, s_width=s_width * 1.5, DC=15, P=7) if 0: stair = make_podeststair([0, 0, 0], th=th * 2, tt=tt * 1.5, steps=60, pod_l=pod_l * 2, thick=thick * 2, s_width=s_width * 1.5, DC=48, P=12, A=5.0) #rs.SelectObject(stair)