####### DM2 ####### hirschberg@tugraz.at ####### http://iamweb01.tugraz.at/dm2/w23 - HU6 ####### Domino & Fantastic Stairs import rhinoscriptsyntax as rs import random as ran # delete everything and start from scratch rs.DeleteObjects(rs.AllObjects()) ############################################################################## # domino variables ############################################################################## A = 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.18 # 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 = 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 ############################################################################## # domino 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): 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 box at cornerpoint 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 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): 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): 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 twisted arc-like shape def create_twisted_arc(base_point, radius, thickness, height, twist_angle, orientation): # List to store curve segments curve_segments = [] # Create outer and inner arcs outer_arc = rs.AddArc([0, 0, 0], radius, 150) inner_arc = rs.AddArc([0, 0, 0], radius - thickness, 150) # Add lines to close the arc line1 = rs.AddLine([radius, 0, 0], [radius - thickness, 0, 0]) line2 = rs.AddLine([-(radius - thickness), 0, 0], [-radius, 0, 0]) # Append all segments to the list curve_segments.extend([outer_arc, inner_arc, line1, line2]) # Join the segments into a closed curve closed_curve = rs.JoinCurves(curve_segments, delete_input=True) # Create the extrusion path extrusion_path = rs.AddLine([0, 0, 0], [0, 0, height]) # Extrude the curve to create a surface extruded_arc = rs.ExtrudeCurve(closed_curve, extrusion_path) # Cap the surface to create a solid rs.CapPlanarHoles(extruded_arc) # Apply a twist along the height of the shape rs.Command("_Twist _selID {} _StartPoint 0,0,0 _EndPoint 0,0,{} _Angle {}".format( extruded_arc, height, twist_angle), echo=False) # Clean up temporary geometry rs.DeleteObject(closed_curve) rs.DeleteObject(extrusion_path) # Rotate the object based on the specified orientation rs.RotateObject(extruded_arc, [0, 0, 0], orientation) # Move the object to the specified base point rs.MoveObject(extruded_arc, base_point) # Return the resulting twisted arc-like shape return extruded_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): 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 place walls on perimeters of a floor plate def domino_bruestung(A, B, level, thick, hgt, f_size,xcol, ycol): 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) ################################################################################ # make_stair(start, th, tt, steps, thick, s_width) # # stair without landings in straight line (x-axis) ################################################################################ # Arguments / Variables: # start = starting point # th = tritt hoehe / rise (float) # tt = tritt tiefe / tread depth (float) # steps = anzahl stufen / steps of steps (int) # thick = thickness of stair (below tread) (float) # s_width = breite der stufen / stair width (float) ################################################################################ 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([path, s_outline]) return(hull) ################################################################################ # make_curved_podeststair(curve, th, tt, steps, thick, s_width, pod_l, DC, P, A) # # stair with landings and up and down changes along a curve ################################################################################ # Arguments / Variables: # start = starting point # th = tritt hoehe / rise (float) # tt = tritt tiefe / tread depth (float) # steps = anzahl stufen / number of steps (int) # thick = thickness of stair (below tread) (float) # s_width = breite der stufen / stair width (float) # pod_l = podest laenge / depth of landing (float) # DC = direction change every DC steps (int) # P = podest / landing every P steps (int) # A = Antrittpodest / first landing, if 0 no landing is created (float) ################################################################################ def make_podeststair(start, th=th,tt=tt, steps=9, pod_l=pod_l, thick=thick, s_width=s_width, DC=48, P=12, A=0): pts = [start] for i in range(1,steps): 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])) hull = rs.ExtrudeCurve(s_outline, path) rs.CapPlanarHoles(hull) rs.DeleteObjects([path, s_outline]) return(hull) ################################################################################ # create_curved_stair(curve, rise, tread_depth, num_steps, thickness, stair_width) # # Generate a stair along a curve without intermediate landings ################################################################################ # Parameters / Variables: # curve = objectID of the guiding curve # rise = height of each step (float) # tread_depth = depth of each tread (float) # num_steps = total number of steps (int) # thickness = thickness of the stair structure below the tread (float) # stair_width = overall width of the staircase (float) ################################################################################ def create_curved_stair(curve, rise=th, tread_depth=tt, num_steps=240, thickness=thick, stair_width=s_width): points = [[0, 0, 0]] # Initial point at the base of the staircase for step in range(1, num_steps): # Add points for the rise and tread of each step points.append([points[-1][0], points[-1][1], points[-1][2] + rise]) points.append([points[-1][0] + tread_depth, points[-1][1], points[-1][2]]) # Add points to close the stair geometry points.append((points[-1][0], points[-1][1], points[-1][2] - thickness)) points.append((points[0][0], points[0][1], points[0][2] - thickness)) points.append(points[0]) # Close the loop # Create the stair outline as a polyline stair_outline = rs.AddPolyline(points) # Create auxiliary paths for flow operation path_line = rs.AddLine(points[0], (points[0][0], points[0][1] + stair_width / 2, points[0][2])) shadow_line = rs.AddLine(points[0], (points[-3][0], points[-3][1], points[0][2])) # Generate a planar surface for the stair outline stair_surface = rs.AddPlanarSrf(stair_outline) # Flow the planar surface along the curve rs.Command("_Flow _selID {} _Enter _selID {} _selID {} _Enter".format(stair_surface[0], shadow_line, curve), False) # Offset the resulting surface to create a solid stair structure stair_hull = rs.FirstObject() final_stair = rs.OffsetSurface(stair_hull, 0.5, both_sides=True, create_solid=True) # Cleanup: Delete intermediate objects rs.DeleteObjects([stair_surface[0], shadow_line, path_line, stair_outline]) return final_stair ################################################################################ # make_curved_podeststair(curve, th, tt, steps, thick, s_width, pod_l, DC, P, A) # # stair with landings and up and down changes along a curve ################################################################################ # Arguments / Variables: # curve = objectID of a curve # th = tritt hoehe / rise (float) # tt = tritt tiefe / tread depth (float) # steps = anzahl stufen / number of steps (int) # thick = thickness of stair (below tread) (float) # s_width = breite der stufen / stair width (float) # pod_l = podest laenge / depth of landing (float) # DC = direction change every DC steps (int) # P = podest / landing every P steps (int) # A = Antrittpodest / first landing, if 0 no landing is created (float) ################################################################################ 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) ################################################################################ # make_domino(A, B, thick, hgt, levels, xcol, ycol, f_height, f_size) # # parametric domino house generator ################################################################################ # Arguments / Variables: # A = Module size (distance between columns) # B = Distance of columns to end of plate # thick = thickness of all slabs # hgt = height of room # levels = number of floor plates # f_height = foundation height # f_size = foundation edge size # xcol = columns in x direction # ycol = columns in y direction # # returns list of lists: foundations, columns, plates, stairs (f_list, c_list, p_list, stair_l) ################################################################################ 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 ############################################################################## # 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, 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, xcol, ycol)) ############################### # set the stair parameters ############################### th = 0.17 # initial rise value thmax = 0.30 # highest acceptable rise value tt = 0.6 # step size s_width = 1.5 # 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) ################################################################################ # make_domino_b(A, B, thick, hgt, levels, xcol, ycol, f_height, f_size) # # same as above, but with parametric domino house generator with outside walls ################################################################################ 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): 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)) if(i%2): c_list.extend(make_arc_array(A, level, thick, hgt, 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, 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) ################################################################################ # domino_city(x, y) # # makes an array of randomized parametric domino houses ################################################################################ def domino_city(x=5, y=2): 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)*30 for i in range(len(result)): #rs.RotateObjects(result[i],(0,0,0), rotangle) rs.MoveObjects(result[i],((ip*20),(jp*30),0)) ################################################################################ # domino_cityblock(xcol, ycol) # # arranges 4 parametric domino houses around a courtyard ################################################################################ def domino_cityblock(xcol=5, ycol=3): p_width = A*(xcol-1)+2*B # width of floor plate (x) p_length = A*(ycol-1) + f_size # length of floor plate (y) for i in range(4): result=make_domino(A=A, B=A/3, hgt=hgt,levels=ran.randint(6,18),xcol=xcol,ycol=ycol) rotangle = i*90 for j in range(len(result)): rs.RotateObjects(result[j],((p_width+p_length)/2,-(p_width)/2,0), rotangle) ################################################################################ # 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, 520) 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, 520) 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) rs.EnableRedraw(False) ################################################################################# # Domino functions ################################################################################# if 0: #(f_list, c_list, p_list, stair_l) = make_domino() (f_list, c_list, p_list, stair_l) = make_domino_b() # version mit Bruestungen rs.AddLayer("foundation") rs.LayerColor("foundation", (220,60,60)) rs.ObjectLayer(f_list,"foundation") rs.AddLayer("columns") rs.LayerColor("columns", (60,220,60)) rs.ObjectLayer(c_list,"columns") rs.AddLayer("plates") rs.LayerColor("plates", (60,60,220)) rs.ObjectLayer(p_list,"plates") rs.AddLayer("stair") rs.LayerColor("stair", (220,220,60)) rs.ObjectLayer(stair_l,"stair") if 0: domino_cityblock() import math # Import math module for trigonometric calculations # Curved Stair functions ################################################################################# if 1: # Parameters for the spherical spiral shape steps = 430 # Number of steps in the spherical staircase radius = 6 # Initial radius of the spherical spiral height = 11 # Total height to be covered by the staircase turns = 6 # Number of full rotations the staircase will make thickness = 0.1 # Thickness of the staircase steps step_width = 2 # Width of each step # Ensure steps is a positive integer and not zero if steps <= 0: print("Error: Steps must be a positive integer.") else: # Initialize an empty list for the curve points curve_points = [] # Generate the points for the spherical spiral for i in range(steps): # Ensure turns is a valid positive number if turns <= 0: print("Error: Turns must be a positive number.") break # Exit if turns is invalid # Angle for this step angle = 2 * math.pi * (i / steps) * turns # Spiral angle formula # Radius will stay constant for a uniform spherical shape r = radius # Vertical height for this step z = (i / steps) * height # Proportional height for each step # Calculate the x, y, z coordinates based on polar coordinates x = r * math.cos(angle) # Horizontal position in X y = r * math.sin(angle) # Horizontal position in Y # Add the point to the list curve_points.append([x, y, z]) # Create a polyline from the list of points curve = rs.AddPolyline(curve_points) # Create the spherical staircase based on the generated curve stair = make_curved_podeststair(curve, th=0.22, tt=0.25, steps=steps, pod_l=1.0, thick=thickness, s_width=step_width, DC=28, P=52, A=1.0) # Further parts of your script remain unchanged... rs.EnableRedraw(True) """ def make_box(insertion=[0, 0, 0], xd=10, yd=10, zd=10): corners = [(0, 0, 0), (xd, 0, 0), (xd, yd, 0), (0, yd, 0), (0, 0, zd), (xd, 0, zd), (xd, yd, zd), (0, yd, zd)] box = rs.AddBox(corners) rs.MoveObject(box, (-xd / 2, -yd / 2, 0)) rs.MoveObject(box, insertion) return box p_num= 20 #crv = rs.AddLine([0,0,0], [100,0,50]) #crv = rs.AddPolyLine([0,0,0], [50,0,50], [70, 40, 20], [100, 0, 0]) crv = rs.AddCurve([[0,0,0], [50,0,50], [70, 40, 20], [100, 0, 0]], 3) #rs.RebuildCurve(crv, 3, p_num) c_len = rs.CurveLength(crv) seg_len = c_len / p_num print seg_len pts = rs.DivideCurveEquidistant(crv, seg_len, create_points=True, return_points=True) print c_len #pts = rs.CurvePoints(crv) for p in pts: rs.AddCircle(p, seg_len) param = rs.CurveClosestPoint(crv, p) normal = rs.CurveTangent(crv, param) t_angle = rs.Angle([0,0,0], normal)[0] box = make_box(p,xd=seg_len, yd=4*seg_len, zd=seg_len/4) rs.RotateObject(box, p, t_angle[0], [0,0,1]) """