####### DM2 ####### hirschberg@tugraz.at ####### http://iam.tugraz.at/dm2/w20 - HU7 ####### Domino & Fantastic Stairs Library lib_version = "v1.2 20201212" import rhinoscriptsyntax as rs import random as ran ############################################################################## # domino globals, used as default variables ############################################################################## A = 4.5 # A = Module size (distance between columns) B = A/3 # B = Distance of columns to end of plate f_height = 0.5 # f_height = foundation height f_size = 0.8 # f_size = foundation edge size 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 = 3 # number of floor plates # stair values s_width = 1.2 # 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 ############################################################################## # domino helper functions - variables are defaults ############################################################################## # function to create a box at an insertion point def make_box(insertion = [0,0,0], xsize = 10, ysize=10, zsize=10): """Adds box to the document with insertion point at center of base plane Parameters: insertion (point): center of box x_size (number): size of box in x direction y_size (number): size of box in y direction z_size (number): size of box in z direction Returns: guid: id of the new box object Example: import flipped_classroom_lib as fc box = fc.make_box() box = fc.make_box([10,10,10], 3, 4.5, 0.3) """ 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 a box at an insertion point with line sticking out in x def make_box_wline(insertion = [0,0,0], xsize = 10, ysize=10, zsize=10, line_len=5): """Adds box with line sticking out in x with insertion point at center of base plane Parameters: insertion (point): center of box x_size (number): size of box in x direction y_size (number): size of box in y direction z_size (number): size of box in z direction Returns: list of 2 guid: [0] id of the new box object [1] id of the new line object Example: import flipped_classroom_lib as fc (box, line) = fc.make_box_wline() (box, line) = fc.make_box_wline([10,10,10], 3, 4.5, 0.3, 1) """ 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) line = rs.AddLine([xsize,ysize/2,zsize],[xsize+line_len,ysize/2,zsize]) rs.MoveObjects([box,line], (-xsize/2,-ysize/2,0)) rs.MoveObject([box,line], insertion) return(box, line) # function to create box at cornerpoint def make_podest(insertion=[0,0,0],xsize=10,ysize=10,zsize=10): """Adds box to the document with insertion point at corner of base plane Parameters: insertion (point): center of box x_size (number): size of box in x direction y_size (number): size of box in y direction z_size (number): size of box in z direction Returns: guid: id of the new box object Example: import flipped_classroom_lib as fc box = fc.make_podest() box = fc.make_podest([10,10,10], 3, 4.5, 0.3) """ 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 an equally spaced array of boxes starting at (0,0,0) def make_foundations( A=5.0, f_size=0.8, f_height=0.5, xcol=2, ycol=3 ): """Adds array of equally spaced square boxes starting at (0,0,0) Parameters: A (number): spacing in x and y directions f_size (number): size of boxes in x and y directions f_height (number): height of boxes in z direction xcol (number): number of boxes in x direction ycol (number): number of boxes in y direction Returns: list of guids: ids of the new box objects Example: import flipped_classroom_lib as fc boxes = fc.make_foundations() boxes = fc.make_foundations(4.0, 1.0, 0.5, 4, 8) """ 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 an equally spaced array of columns starting at (0,0,level) def make_columns(A=5.0, level=0.7, thick=0.2, hgt=3.0, xcol=2, ycol=3): """Adds array of equally spaced square boxes starting at (0,0,level) Parameters: A (number): spacing in x and y directions level (number): height above ground in z direction f_size (number): size of boxes in x and y directions f_height (number): height of boxes in z direction xcol (number): number of boxes in x direction ycol (number): number of boxes in y direction Returns: list of guids: ids of the new column objects Example: import flipped_classroom_lib as fc boxes = fc.make_columns() boxes = fc.make_columns(4.5, 5.0, 0.15, 3.0, 4, 8) """ 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 an extruded arc shape def make_arc(insertion, rad, thick, hgt, orientation): """Adds an extruded 180 degree arc shape at insertion Parameters: insertion (point): center of arc rad (number): radius of arc thick (number): wall thickness of arc hgt (number): height of arc orientation (number): angle of rotation around center of arc Returns: guid: id of the new arc object Example: import flipped_classroom_lib as fc arc = fc.make_arc() arc = fc.make_arc([10,5,1], 2.5, 0.2, 3.0, 90) """ 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-thick),0,0],[-rad,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 place arcs on the floor plates def make_arc_array(A=5.0, level=0.7, thick=0.2, hgt=3.0, xcol=2, ycol=3): """Adds array of equally spaced, randomly oriented arcs, starting at (0,0,level) Parameters: A (number): spacing in x and y directions level (number): elevation of plane on which arcs are placed thick (number): thickness of arc walls hgt (number): height of arc extrusion xcol (number): number of arcs in x direction ycol (number): number of arcs in y direction Returns: list of guids: ids of the arc objects Example: import flipped_classroom_lib as fc arcs = fc.make_arc_array() arcs = fc.make_arc_array(4.5, 1.0, 0.2, 2.7, 4, 8) """ cls =[] for i in range(xcol-1): for j in range(ycol-1): ori = ran.randint(0,6) if ori<4: # only create two thirds of arcs orientation = ori*90 # orientation is randomly one of four 90 degree steps cls.append(make_arc([i*A+A/2,j*A+A/2,level], A/2, thick, hgt, orientation)) return(cls) # function to place walls on perimeters of a floor plate def domino_bruestung(A, B, level, thick, hgt, f_size, xcol, ycol): """Adds walls with horizontal openings around the perimeter of a domino model Parameters: A (number): spacing of module in x and y directions B (number): offset of facade from columns in y-direction level (number): elevation of plane on which walls are placed thick (number): thickness of walls hgt (number): height of arc extrusion f_size (number): size of domino foundation (determines offset from columns in x direction) xcol (number): number of modules in x direction (to determine overall floorplate size in x) ycol (number): number of modules in y direction (to determine overall floorplate size in y) Returns: list of guids: ids of the wall objects Example: import flipped_classroom_lib as fc walls = fc.domino_bruestung(fc.A, fc.B, fc.level, fc.thick, fc.hgt, fc.f_size, fc.xcol, fc.ycol) walls = fc.domino_bruestung(4.5, 1.5, 0.7, 0.2, 3.0, 0.8, 2, 3) """ cls =[] cls.append(make_podest([-B,-f_size/2,level],thick,A*(ycol-1)+f_size, 1)) cls.append(make_podest([-B,-f_size/2,level+hgt-.5],thick,A*(ycol-1)+f_size, .5)) cls.append(make_podest([A*(xcol-1)+B-thick,-f_size/2,level],thick,A*(ycol-1)+f_size, 1)) cls.append(make_podest([A*(xcol-1)+B-thick,-f_size/2,level+hgt-.5],thick,A*(ycol-1)+f_size, .5)) cls.append(make_podest([-B,-f_size/2,level],B,thick, hgt)) cls.append(make_podest([A,-f_size/2,level],A*(xcol-2)+B,thick,hgt)) cls.append(make_podest([-B,A*(ycol-1)+f_size/2-thick,level],A*(xcol-1)+2*B,thick, 1)) cls.append(make_podest([-B,A*(ycol-1)+f_size/2-thick,level+hgt-.5],A*(xcol-1)+2*B,thick, .5)) return(cls) ################################################################################ # Stair functions ################################################################################ # stair without landings in straight line (x-axis) def make_stair(start, th, tt, steps, thick, s_width): """Adds stair without landings in straight line (x-axis) Parameters: start (point): starting point th (number): tread height / rise (float) tt (number): tread depth / tiefe (float) steps (number): number of steps (int) thick (number): thickness of stair (below tread) (float) s_width (number): stair width (float) Returns: guid: id of the stair object Example: import flipped_classroom_lib as fc stair = fc.make_stair([0,0,0], fc.th, fc.tt, fc.steps, fc.thick, fc.s_width) stair = fc.make_stair([10,5,1], 0.17, 0.3, 14, 0.2, 1.2) """ 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]]) stair = rs.ExtrudeCurve(s_outline, path) rs.CapPlanarHoles(stair) rs.DeleteObjects([s_outline,path]) return(stair) # stair with landings and up and down changes in straight line (x-axis) def make_podeststair(start=[0,0,0], th=th,tt=tt, steps=48, pod_l=pod_l, thick=thick, s_width=s_width, DC=24, P=8, An=0): """Adds stair with landings and up and down changes in straight line (x-axis) Parameters: start (point): starting point th (number): tread height / rise (float) tt (number): tread depth / tiefe (float) steps (number): number of steps (int) thick (number): thickness of stair (below tread) (float) s_width (number): stair width (float) pod_l (number): podest laenge / depth of landing (float) DC (number): direction change every DC steps (int) P (number): podest / landing every P steps (int) An (number): Antrittpodest / first landing, if 0 no landing is created (float) Returns: guid: id of the stair object Example: import flipped_classroom_lib as fc stair = fc.make_podeststair() stair = fc.make_podeststair([10,10,0], 0.17, 0.3, 24, 1.2, 0.2, 1.2, DC=16, P=8, An=0.3) stair = fc.make_podeststair([10,10,0], -0.17, 0.3, 35, 1.2, 0.2, 1.2, DC=16, P=8, An=0) """ pts = [start] if(th<0 and An==0): An=0.3 steps=steps-1 for i in range(1,steps+1): if(not(i%DC)): ##DC: Direction Change pts.append([pts[-1][0],pts[-1][1],pts[-1][2]+th]) pts.append((pts[-1][0]+tt,pts[-1][1],pts[-1][2])) 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])) th=-th elif(not(i%P)): ##P: Podest pts.append([pts[-1][0],pts[-1][1],pts[-1][2]+th]) pts.append((pts[-1][0]+tt,pts[-1][1],pts[-1][2])) 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 (An>0): ##P: Erstes Podest pts.append([pts[-1][0]+An,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) if (An>0): pts.append([pts[1][0]-tt, pts[1][1], pts[1][2]-thick]) 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])) stair = rs.ExtrudeCurve(s_outline, path) rs.CapPlanarHoles(stair) rs.DeleteObjects([s_outline, path]) return(stair) # ramp in straight line (x-axis) def make_ramp(start, len_c, tothgt, thick=thick, s_width=s_width): """Adds ramp in straight line (x-axis) Parameters: start (point): starting point len_c (number): length of ramp (float) tothgt (number): height difference (float) thick (number): thickness of ramp (float) s_width (number): ramp width (float) Returns: guid: id of the ramp object Example: import flipped_classroom_lib as fc ramp = fc.make_ramp([0,0,0], 50, 3.0) ramp = fc.make_ramp([10,10,0], 50, 3.0, 0.2, 1.2) """ pts = [[0,0,0], [len_c,0,tothgt], [len_c,0,tothgt-thick], [0,0,-thick], [0,0,0]] s_outline = rs.AddPolyline(pts) path=rs.AddLine(start,[start[0],start[1]+s_width,start[2]]) ramp = rs.ExtrudeCurve(s_outline, path) rs.DeleteObjects([s_outline,path]) rs.CapPlanarHoles(ramp) rs.MoveObject(ramp, start) return(ramp) # stair without landings along a curve def make_curved_stair(curve, th=th,tt=tt, steps=240, thick=thick, s_width=s_width): """Adds stair without landings along a curve Parameters: curve (guid): objectID of a curve th (number): tread height / rise (float) tt (number): tread depth / tiefe (float) steps (number): number of steps (int) thick (number): thickness of stair (below tread) (float) s_width (number): stair width (float) Returns: guid: id of the stair object Example: import flipped_classroom_lib as fc stair = fc.make_curved_stair(curve, fc.th, fc.tt, fc.steps, fc.thick, fc.s_width) stair = fc.make_curved_stair(curve, 0.17, 0.3, 14, 0.2, 1.2) """ pts = [[0,0,0]] for i in range(1,steps+1): pts.append([pts[-1][0],pts[-1][1],pts[-1][2]+th]) pts.append([pts[-1][0]+tt,pts[-1][1],pts[-1][2]]) pts.append((pts[-1][0], pts[-1][1], pts[-1][2]-thick)) 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],(pts[-3][0], pts[-3][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) hull = rs.FirstObject() stair = rs.OffsetSurface(hull, s_width/2, both_sides=True, create_solid=True) rs.DeleteObjects([s_surf[0], shadow, path, s_outline]) return(stair) # stair with landings and up and down changes along a curve def make_curved_podeststair(curve, th=th, tt=tt, steps=40, thick=thick, s_width=s_width, pod_l=s_width/2, DC=12, P=12, An=0): """Adds stair with landings and up and down changes along a curve Parameters: curve (guid): objectID of a curve th (number): tread height / rise (float) tt (number): tread depth / tiefe (float) steps (number): number of steps (int) thick (number): thickness of stair (below tread) (float) s_width (number): stair width (float) pod_l (number): podest laenge / depth of landing (float) DC (number): direction change every DC steps (int) P (number): podest / landing every P steps (int) An (number): Antrittpodest / first landing, if 0 no landing is created (float) Returns: guid: id of the stair object Example: import flipped_classroom_lib as fc stair = fc.make_curved_podeststair(curve) stair = fc.make_curved_podeststair(curve, 0.17, 0.3, 24, 1.2, 0.2, 1.2, DC=16, P=8, An=0.3) stair = fc.make_curved_podeststair(curve, -0.17, 0.3, 35, 1.2, 0.2, 1.2, DC=16, P=8, An=0) """ pts = [[0,0,0]] if(th<0 and An==0): An=0.3 steps=steps-1 for i in range(1,steps+1): if(not(i%DC)): ##DC: Direction Change pts.append([pts[-1][0],pts[-1][1],pts[-1][2]+th]) pts.append((pts[-1][0]+tt,pts[-1][1],pts[-1][2])) 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])) th=-th elif(i==1): ##An: Erstes Podest if An>0: pts.append([pts[-1][0]+An,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]]) elif(i==steps): ##An: Letztes Podest pts.append([pts[-1][0],pts[-1][1],pts[-1][2]+th]) pts.append([pts[-1][0]+tt,pts[-1][1],pts[-1][2]]) elif(not(i%P)): ##P: Podest pts.append([pts[-1][0],pts[-1][1],pts[-1][2]+th]) pts.append((pts[-1][0]+tt,pts[-1][1],pts[-1][2])) 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])) 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) if (An>0): pts.append([pts[1][0]-tt, pts[1][1], pts[1][2]-thick]) 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/2, both_sides=True, create_solid=True) rs.DeleteObjects([s_surf[0], shadow, path, s_outline, profile]) return(stair) # ramp along a curve def make_curved_ramp(curve, tothgt, thick=thick, s_width=s_width): """Adds ramp along a curve Parameters: curve (guid): objectID of a flat curve (on xy palne) tothgt (number): height difference (float) thick (number): thickness of ramp (float) s_width (number): ramp width (float) Returns: guid: id of the stair object Example: import flipped_classroom_lib as fc stair = fc.make_curved_ramp(curve, 3.0) stair = fc.make_curved_ramp(curve, 3.0, 0.2, 1.2) """ len_c = rs.CurveLength(curve) pts = [[0,0,0], [len_c,0,tothgt], [len_c,0,tothgt-thick], [0,0,-thick], [0,0,0]] #pts = [[0,0,0], [len_c,0,tothgt], [len_c,0,0], [0,0,0]] s_outline = rs.AddPolyline(pts) path = rs.AddLine(pts[0],[pts[0][0], pts[0][1]+s_width/2, pts[0][2]]) s_surf = rs.AddPlanarSrf(s_outline) shadow = rs.AddLine(pts[0],[pts[1][0], pts[1][1], pts[0][2]]) rs.Command("_Flow selID {} _Enter selID {} selID {} _Enter".format(s_surf[0], shadow, curve), False) profile = rs.FirstObject() ramp = rs.OffsetSurface(profile, s_width/2, both_sides=True, create_solid=True) rs.DeleteObjects([s_surf[0], shadow, s_outline, profile]) return(ramp) # parametric domino house generator 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): """creates a parametric maison Dom-ino at [0,0,0] Parameters: A (number): Module size (distance between columns) B (number): Distance of columns to end of plate thick (number): thickness of all slabs hgt (number): height of room levels (number): number of floor plates f_height (number): foundation height f_size (number): foundation edge size xcol (number): columns in x direction ycol (number): columns in y direction Returns: list of lists: [foundations, columns, plates, stairs] [0]: list with guids of foundations [1]: list with guids of columns [2]: list with guids of plates [3]: list with guids of stairs Example: import flipped_classroom_lib as fc result_list = fc.make_domino() (f_list, c_list, p_list, stair_l) = fc.make_domino(A=fc.A, B=fc.B, thick=fc.thick, hgt=fc.hgt, levels=fc.levels, xcol=fc.xcol, ycol=fc.ycol, f_height=fc.f_height, f_size=fc.f_size) """ f_list = [] # list of foundations c_list = [] # list of columns p_list = [] # list of plates stair_l = [] # list of stair objects # 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) ############################### # build the domino structure ############################### 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)) p_list.append(make_box(center_pt, p_width, p_length, thick)) ############################### # set the stair parameters ############################### th = 0.17 # initial rise value thmax = 0.19 # highest acceptable rise value tt = 0.3 # step size s_width = 1.2 # s_width = stair width pod_l = B # pod_l = depth of landing start = [pod_l,-(s_width*2+f_size/2), f_height+thick] # startpoint of stair ############################## # calculate stair values ############################## steps = int((hgt+thick)/th) if steps%2: steps = steps-1 th = (hgt+thick)/steps if(th>thmax): steps= steps+2 th = (hgt+thick)/steps ############################## # loop to create staircase ############################## for i in range(levels): start[2] = f_height+thick + i*(thick+hgt) # z-wert bei jeder Iteration neu gesetzt if i==levels-1: # letztes podest stair_l.append(make_podest([start[0]-pod_l, start[1]+s_width, start[2]-thick], pod_l, s_width, thick)) # sonderpodest else: stair_l.append(make_podest([start[0]-pod_l, start[1], start[2]-thick], pod_l, 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_l, 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) # same as above: parametric domino house generator, but with outside walls and arcs def make_domino_b(A=A, B=B, thick=thick, hgt=hgt, levels=levels, xcol=xcol, ycol=ycol, f_height=f_height, f_size=f_size): """creates a parametric maison Dom-ino with outside walls at [0,0,0] Parameters: A (number): Module size (distance between columns) B (number): Distance of columns to end of plate thick (number): thickness of all slabs hgt (number): height of room levels (number): number of floor plates f_height (number): foundation height f_size (number): foundation edge size xcol (number): columns in x direction ycol (number): columns in y direction Returns: list of lists: [foundations, columns, plates, stairs] [0]: list with guids of foundations [1]: list with guids of columns [2]: list with guids of plates [3]: list with guids of stairs Example: import flipped_classroom_lib as fc result_list = fc.make_domino_b() (f_list, c_list, p_list, stair_l) = fc.make_domino_b(A=fc.A, B=fc.B, thick=fc.thick, hgt=fc.hgt, levels=fc.levels, xcol=fc.xcol, ycol=fc.ycol, f_height=fc.f_height, f_size=fc.f_size) """ f_list = [] # list of foundations c_list = [] # list of columns p_list = [] # list of plates stair_l = [] # list of stair objects # 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) ############################### # build the domino structure ############################### 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_arc_array(A, level, thick, hgt-thick, xcol, ycol)) if i>1: c_list.extend(domino_bruestung(A, B, level, thick, hgt, f_size, xcol, ycol)) p_list.append(make_box(center_pt, p_width, p_length, thick)) level=f_height + thick +(levels-1)*(hgt+thick) c_list.extend(make_arc_array(A, level, thick, hgt-3*thick, xcol, ycol)) ############################### # set the stair parameters ############################### th = 0.17 # initial rise value thmax = 0.19 # highest acceptable rise value tt = 0.3 # step size s_width = 1.2 # s_width = stair width pod_l = B # pod_l = depth of landing start = [pod_l,-(s_width*2+f_size/2), f_height+thick] # startpoint of stair ############################## # calculate stair values ############################## steps = int((hgt+thick)/th) if steps%2: steps = steps-1 th = (hgt+thick)/steps if(th>thmax): steps= steps+2 th = (hgt+thick)/steps ############################## #loop to create staircase ############################## stair_l = [] # list of stair objects for i in range(levels): start[2] = f_height+thick + i*(thick+hgt) # z-wert bei jeder Iteration neu gesetzt if i==levels-1: # letztes podest stair_l.append(make_podest([start[0]-pod_l, start[1]+s_width, start[2]-thick], pod_l, s_width, thick)) # sonderpodest else: stair_l.append(make_podest([start[0]-pod_l, start[1], start[2]-thick], pod_l, 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_l, 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) # same as above: parametric domino house generator, but without stairs def make_domino_raw(A=A, B=B, thick=thick, hgt=hgt, levels=levels, xcol=xcol, ycol=ycol, f_height=f_height, f_size=f_size): """creates a parametric maison Dom-ino at [0,0,0] without stairs Parameters: A (number): Module size (distance between columns) B (number): Distance of columns to end of plate thick (number): thickness of all slabs hgt (number): height of room levels (number): number of floor plates f_height (number): foundation height f_size (number): foundation edge size xcol (number): columns in x direction ycol (number): columns in y direction Returns: list of lists: [foundations, columns, plates, stairs] [0]: list with guids of foundations [1]: list with guids of columns [2]: list with guids of plates [3]: list with guids of stairs Example: import flipped_classroom_lib as fc result_list = fc.make_domino() (f_list, c_list, p_list) = fc.make_domino(A=fc.A, B=fc.B, thick=fc.thick, hgt=fc.hgt, levels=fc.levels, xcol=fc.xcol, ycol=fc.ycol, f_height=fc.f_height, f_size=fc.f_size) """ f_list = [] # list of foundations c_list = [] # list of columns p_list = [] # list of plates # 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) ############################### # build the domino structure ############################### 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)) p_list.append(make_box(center_pt, p_width, p_length, thick)) return(f_list, c_list, p_list) # makes an array of randomized parametric domino houses def domino_city(x=5, y=2): """creates an array of randomized parametric domino houses starting at [0,0,0] Parameters: x (number): maisons in x direction y (number): maisons in y direction Returns: no return values defined Example: import flipped_classroom_lib as fc fc.domino_city() """ for ip in range(x): for jp in range(y): result=make_domino_b(A=ran.uniform(3,6), B=A/3, hgt=ran.uniform(2.5,4.0),levels=ran.randint(2,5),xcol=ran.randint(2,3),ycol=ran.randint(2,5)) #rotangle = ran.randint(0,6)*15 for i in range(len(result)): #rs.RotateObjects(result[i],(0,0,0), rotangle) rs.MoveObjects(result[i],((ip*20),(jp*30),0)) ################################################################################ # 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): """creates a random 2D curve with a given number of points, sorted in x Parameters: p_num (number): number of curve points range_x (number): randomness range in x range_y (number): randomness range in y degree (number): degree of curve Returns: guid of curve Example: import flipped_classroom_lib as fc make_random_curve(5) make_random_curve(5, 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=2, 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): """creates a random arc polyline with a given number of points, circling around [0,0,0] Parameters: p_num (number): number of curve points min_x (number): minimum radius value max_x (number): maximum radius value mindeg (number): minimum angle degree value maxdeg (number): maximum angle degree value Returns: guid of curve Example: import flipped_classroom_lib as fc make_random_arcline(5) make_random_arcline(5, 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) #blends 2 curves and returns joined curves def blend_curves(curve0, curve1, degree=2): """blends 2 curves and returns joined curves Parameters: curve0 (guid): objectID of first curve curve1 (guid): objectID of second curve degree (number): degree of joined curve Returns: guid: id of joined curve Example: import flipped_classroom_lib as fc curve = fc.blend_curves(curve0, curve1, 2) """ curves = curve0, curve1 domain_crv0 = rs.CurveDomain(curve0) domain_crv1 = rs.CurveDomain(curve1) params = domain_crv0[1], domain_crv1[1] revs = False, False cont = degree,degree curve2 = rs.AddBlendCurve(curves, params, revs, cont) curve = rs.JoinCurves([curve0,curve1,curve2],delete_input=True, tolerance=None)[0] return(curve) #turns curve into flat stairline from same starting point, returns curve and original height difference to last point def curve_to_stairline(curve): """turns curve into flat stairline from same starting point, returns curve and original height difference from first to last point Parameters: curve (guid): objectID of curve degree (number): degree of resulting curve Returns: [0] guid: id of joined curve [1] number: total height difference from first to last point of original curve Example: import flipped_classroom_lib as fc (curve, tothgt) = fc.blend_curves(curve0, curve1, 2) """ pts = rs.CurvePoints(curve) knts = rs.CurveKnots(curve) degree = rs.CurveDegree(curve) #rs.Command("-_ProjectToCPlane selID {} _Enter Yes _Enter".format(curve), False)# project curve to Cplane flat_pts = [] for p in pts: flat_pts.append([p[0], p[1],0]) flatcurve = rs.AddNurbsCurve(flat_pts,knts, degree) if pts[0][2] < pts[-1][2]: rs.MoveObject(flatcurve,[0,0,pts[0][2]]) tothgt = pts[-1][2] - pts[0][2] else: rs.MoveObject(flatcurve,[0,0,pts[-1][2]]) rs.ReverseCurve(flatcurve) tothgt = pts[0][2] - pts[-1][2] return(flatcurve, tothgt) # finds an appropriate number of steps for a height difference def calculate_steps_height(tothgt, th=0.17, thmax=0.19, even=True): steps = abs(int(tothgt/th)) if steps%2 and even: steps = steps-1 th = tothgt/steps if(abs(th)>abs(thmax)): steps= steps+2 th = tothgt/steps return(steps, th) def calculate_podlen(len_c, tt, steps, P, An=0): pod_num = int(steps/P) if not(steps%P): pod_num = pod_num -1 # omit last landing allpod = len_c - (tt*steps+pod_num*tt)- An if allpod < tt*pod_num: print "impossible stair!" return(allpod/pod_num) ################################################################################ # PEF functions # # return Pointlist, Edgelists and Facelist as used in HU9 ################################################################################ # creates Pointlist, Edgelists and Facelist for a single face def PEF_single_face(points = [[0,0,0], [10,0,0], [10,0,12], [0,0,12]]): """creates Pointlist, Edgelists and Facelist for a single face Parameters: points (list): list of 4 points Returns: [0] p_list, Pointlist, contains single points [1] H_edge_list, Horizontal Edgelist, contains lists with two points [2] V_edge_list, Vertical Edgelist, contains lists with two points [3] face_list, Facelist, contains lists with four points (quads) [4] zcol, number of levels of faces [5] xcol, number of faces in one level Example: import flipped_classroom_lib as fc (p_list, H_edge_list, V_edge_list, face_list,zcol, xcol) = PEF_single_face() """ fp_list =[] for p in points: rs.AddPoint(p) fp_list.append(rs.VectorCreate(p, [0,0,0])) face_list = [fp_list] p_list = fp_list H_edge_list = [[fp_list[0], fp_list[1]],[fp_list[3], fp_list[2]]] V_edge_list = [[fp_list[0], fp_list[3]],[fp_list[1], fp_list[2]]] return([p_list, H_edge_list, V_edge_list, face_list, 1, 1]) def PEF_face(xcol, zcol, xmod, zmod, angle): """creates Pointlist, Edgelists and Facelist for an array of faces Parameters: xcol (number): columns of array in x zcol (number): levels of array in z xmod (number): module size in x zmod (number): module size in z angle (number): angle in degreees around origin Returns: [0] p_list, Pointlist, contains single points [1] H_edge_list, Horizontal Edgelist, contains lists with two points [2] V_edge_list, Vertical Edgelist, contains lists with two points [3] face_list, Facelist, contains lists with four points (quads) [4] zcol, number of levels of faces [5] xcol, number of faces in one level Example: import flipped_classroom_lib as fc (p_list, H_edge_list, V_edge_list, face_list,zcol, xcol) = PEF_face() """ p_list = [] for i in range(0, zcol): for j in range(0, xcol): p_list.append(rs.VectorRotate([xmod*j, 0, zmod*i], angle, [0,0,1])) H_edge_list=[] V_edge_list=[] face_list=[] for i, pt in enumerate(p_list): if (i < (zcol-1)*xcol-1): if not((i+1)%xcol == 0): H_edge_list.append([pt,p_list[i+1]]) face_list.append([pt,p_list[i+1], p_list[i+xcol+1],p_list[i+xcol]]) V_edge_list.append([pt,p_list[i+xcol]]) else: V_edge_list.append([pt,p_list[i+xcol]]) else: if not((i+1)%xcol == 0): H_edge_list.append([pt,p_list[i+1]]) elif(i < (zcol-1)*xcol): V_edge_list.append([pt,p_list[i+xcol]]) return([p_list, H_edge_list, V_edge_list, face_list, zcol-1, xcol-1]) def PEF_face_w(xcol, zcol, xmod, zmod, angle, wiggle): """creates Pointlist, Edgelists and Facelist for a wiggly array of faces Parameters: xcol (number): columns of array in x zcol (number): levels of array in z xmod (number): module size in x zmod (number): module size in z angle (number): angle in degreees around origin wiggle (number): randomize factor Returns: [0] p_list, Pointlist, contains single points [1] H_edge_list, Horizontal Edgelist, contains lists with two points [2] V_edge_list, Vertical Edgelist, contains lists with two points [3] face_list, Facelist, contains lists with four points (quads) [4] zcol, number of levels of faces [5] xcol, number of faces in one level Example: import flipped_classroom_lib as fc (p_list, H_edge_list, V_edge_list, face_list,zcol, xcol) = PEF_face_w() """ p_list = [] for i in range(0, zcol): for j in range(0, xcol): rw = ran.uniform(-wiggle, wiggle) p_list.append(rs.VectorRotate([xmod*j, rw, zmod*i], angle, [0,0,1])) H_edge_list=[] V_edge_list=[] face_list=[] for i, pt in enumerate(p_list): if (i < (zcol-1)*xcol-1): if not((i+1)%xcol == 0): H_edge_list.append([pt,p_list[i+1]]) face_list.append([pt,p_list[i+1], p_list[i+xcol+1],p_list[i+xcol]]) V_edge_list.append([pt,p_list[i+xcol]]) else: V_edge_list.append([pt,p_list[i+xcol]]) else: if not((i+1)%xcol == 0): H_edge_list.append([pt,p_list[i+1]]) elif(i < (zcol-1)*xcol): V_edge_list.append([pt,p_list[i+xcol]]) return([p_list, H_edge_list, V_edge_list, face_list, zcol-1, xcol-1]) def PEF_pantheon(radius=21.72, xcol=28): """creates Pointlist, Edgelists and Facelist for a simplified version of the Pantheon cuppola Parameters: radius (number): 21.72 is the radius of the original xcol (number): number of faces going around - 28 is the original Returns: [0] p_list, Pointlist, contains single points [1] H_edge_list, Horizontal Edgelist, contains lists with two points [2] V_edge_list, Vertical Edgelist, contains lists with two points [3] face_list, Facelist, contains lists with four points (quads) [4] zcol, number of levels of faces [5] xcol, number of faces in one level Example: import flipped_classroom_lib as fc (p_list, H_edge_list, V_edge_list, face_list, zcol, xcol) = PEF_pantheon() """ p_list = [] a_list=[0,15.0,27.5,39.5,50.0,59.0,78.0] zcol= len(a_list) for i in range(zcol): for j in range(xcol): pt = rs.VectorRotate([21.72, 0, 0],a_list[i],[0,-1,0]) p_list.append(rs.VectorRotate(pt, (360.0/xcol)*j, [0,0,1])) H_edge_list=[] V_edge_list=[] face_list=[] for i, pt in enumerate(p_list): if (i < (zcol-1)*xcol): if ((i+1)%xcol == 0): H_edge_list.append([pt,p_list[i+1-xcol]]) face_list.append([pt,p_list[i+1-xcol], p_list[i+1],p_list[i+xcol]]) else: H_edge_list.append([pt,p_list[i+1]]) face_list.append([pt,p_list[i+1], p_list[i+xcol+1],p_list[i+xcol]]) V_edge_list.append([pt,p_list[i+xcol]]) elif (i < (zcol*xcol)-1): H_edge_list.append([pt,p_list[i+1]]) else : H_edge_list.append([pt,p_list[i+1-xcol]]) #circle = rs.AddCircle([0,0,0], radius) #path = rs.AddLine([0,0,.1],[0,0,-radius]) #rs.ExtrudeCurve(circle, path) #rs.DeleteObjects([path, circle]) return([p_list, H_edge_list, V_edge_list, face_list, zcol-1, xcol]) print "loaded flipped classroom lib", lib_version