import rhinoscriptsyntax as rs import Rhino.Geometry as rg import random, time, sys, math ### #sys.path.append("P:/") ### sys.path.append("C:\Users\Sven\OneDrive\Tu Graz\DM2")### import DM_lib as dm #Supp def lockLayer(): layers = rs.LayerNames() print("Vorhandene Layer:") for layer in layers: print(layer) rs.LayerLocked(layer, True) def determineCurve(layer_name): if rs.IsLayer(layer_name): all_objects = rs.AllObjects() if all_objects: curve_ids = [] for obj in all_objects: if rs.IsCurve(obj) and rs.ObjectLayer(obj) == layer_name: curve_ids.append(obj) # Fuege die Objekt-ID zur Liste hinzu if curve_ids: return curve_ids[0] #Unterste Z Ebene des Crater else: return else: return def clear_all(): rs.DeleteObjects(rs.AllObjects()) def makeDodekaeder( rad=10.0, pos=[0,0,0], makeCrv=1, makeSrf=1, verbose=1): ### https://de.wikipedia.org/wiki/Dodekaeder#/media/Datei:Dodekaeder-w.svg ''' return: allCoords = 12 coordLists ''' r = rad c = (5**0.5+1)*0.5*r a = rs.Distance([r,0,0], rs.VectorRotate( [r,0,0], 72, [0,0,1] )) if verbose: print "*** dodecahedron | pentagondodekaeder" print "*** radius\t\t r", r print "*** kantePentagon\t a", a print "*** kante Cubus\t c", c print "*** allCoords = [ rs.VectorAdd(pos, rs.VectorRotate(cor, 72.0*i, [0,0,1])) for cor in [[r,0,0], [c, 0, r], rs.VectorRotate([c,0,c], 36.0, [0,0,1] ), [c*.5,a*.5,r+c]] for i in range(5) ]" allCoords = [ rs.VectorAdd(pos, rs.VectorRotate(cor, 72.0*i, [0,0,1])) for cor in [[r,0,0], [c, 0, r], rs.VectorRotate([c,0,c], 36.0, [0,0,1] ), [c*.5,a*.5,r+c]] for i in range(5) ] indices=[[x+(i*5) for x in [0,1,2,3,4]] for i in range(0,4)] pentaIndices = [[0,1,2,3,4,0]] pentaIndices.extend( [[indices[0][0+i], indices[0][1+i], indices[1][1+i], indices[2][0+i], indices[1][0+i],indices[0][0+i]] for i in range(4)] ) pentaIndices.append( [4,0,5,14,9,4] ) pentaIndices.append( [6,11,16,15,10,6] ) pentaIndices.extend( [[pentaIndices[6][0]+i, pentaIndices[6][1]+i, pentaIndices[6][2]+i, pentaIndices[6][3]+i, pentaIndices[6][4]+i, pentaIndices[6][5]+i] for i in range(1,4)] ) pentaIndices.append( [5,10,15,19,14,5] ) pentaIndices.extend( [range(15,20)] ) pentaIndices[-1].append(15) pentaIndices[0].reverse() allCoords = [[allCoords[i] for i in indlist] for indlist in pentaIndices ] if makeCrv: i = 0 for coords in allCoords: i= i+1 crv=rs.AddCurve( coords, 1 ) if makeSrf: rs.AddPlanarSrf(crv) if i == 1: rs.ObjectColor(crv, [0, 222, 0] ) return allCoords def makeStabilizer(baseplate, crv, rad=1, segments=20): if crv: param = rs.CurveClosestPoint(crv , baseplate[0]) if param is not None: closest_point = rs.EvaluateCurve(crv, param) if 0: rs.AddPoint( closest_point) for coords in baseplate: basePoint= coords groundPoint=[coords[0],coords[1],closest_point[2]] if 0: rs.ObjectColor(rs.AddPoint(groundPoint), (0, 200, 200)) rs.AddCircle( basePoint, rad ) rs.AddCircle( groundPoint, rad ) groundCircle_out = rs.AddCircle( groundPoint, rad*2 ) groundCircle_geom = rs.coercecurve(groundCircle_out) groundCircle_plane = groundCircle_geom.TryGetPlane()[1] groundVector_normal = groundCircle_plane.Normal groundCoords_out = rs.DivideCurve( groundCircle_out, 2, create_points=0) groundVector = rs.VectorCreate(groundCoords_out[0], groundPoint) unitVector = rs.VectorUnitize(groundVector) groundPoint_out = rs.VectorScale(unitVector, rad*2) groundPoint_in = rs.VectorScale(unitVector, rad) basePoint_in = rs.VectorScale(unitVector, rad) groundCoords_out = [] groundCoords_in = [] baseCoords_in=[] for i in range (segments): groundCoords_out.append(rs.VectorAdd(groundPoint, groundPoint_out)) groundCoords_in.append(rs.VectorAdd(groundPoint, groundPoint_in)) baseCoords_in.append(rs.VectorAdd(basePoint, basePoint_in)) groundPoint_out = rs.VectorRotate(groundPoint_out, 360/segments, groundVector_normal) groundPoint_in = rs.VectorRotate(groundPoint_in, 360/segments, groundVector_normal) basePoint_in = rs.VectorRotate(basePoint_in, 360/segments, groundVector_normal) if 0: rs.ObjectColor(rs.AddPoints(groundCoords_out), (10,10,200)) rs.ObjectColor(rs.AddPoints(groundCoords_in), (10,10,200)) rs.ObjectColor(rs.AddPoints(baseCoords_in), (10,10,200)) for i in range(segments): gP_out = groundCoords_out[(i + 2) % segments] gP_in = groundCoords_in[i] bP_in = baseCoords_in[(i + 2) % segments] ggLine = rs.AddLine( gP_out, gP_in ) gbLine = rs.AddLine( gP_in, bP_in ) rs.ObjectColor(ggLine, (10,10,200) ) rs.ObjectColor(gbLine, (10,10,200) ) def find_center(points): if not points: return None num_points = len(points) sum_x = sum(p[0] for p in points) sum_y = sum(p[1] for p in points) sum_z = sum(p[2] for p in points) return [sum_x / num_points, sum_y / num_points, sum_z / num_points] def makeMidPointDodekaeder(dodekaeder, crv): midPoints=[] if crv: baseplate = dodekaeder[0] param = rs.CurveClosestPoint(crv , baseplate[0]) if param is not None: closest_point = rs.EvaluateCurve(crv, param) center_point = find_center(dodekaeder[0][0:5] +dodekaeder[1][0:5] +dodekaeder[2][0:5] +dodekaeder[3][0:5] +dodekaeder[4][0:5] +dodekaeder[5][0:5] +dodekaeder[5][0:5] +dodekaeder[6][0:5] +dodekaeder[7][0:5] +dodekaeder[8][0:5] +dodekaeder[9][0:5] +dodekaeder[10][0:5] +dodekaeder[11][0:5] ) for plate in dodekaeder: plate_center_point = find_center(plate[0:5]) midPoints.append([plate_center_point[0],plate_center_point[1],plate_center_point[2]]) #mid plate midPoints.append([center_point[0],center_point[1],center_point[2]]) #mid object midPoints.append([center_point[0],center_point[1],closest_point[2]]) #mid bottom if 0: for midPoint in midPoints: rs.ObjectColor(rs.AddPoint(midPoint), (100,255,200)) return midPoints def makeTubeV1(dodekaedersMidPoints, rad=5, countCircle=10, countCirclePts=10): topMidPoints=[] groundMidPoints=[] allMidPoints=[] if dodekaedersMidPoints: for midPoint in dodekaedersMidPoints: midPoint_object=midPoint[12] midPoint_base=midPoint[0] midPoint_ground=midPoint[13] midPointVector = rs.VectorCreate(midPoint_object, midPoint_ground) unitVector = rs.VectorUnitize(midPointVector) vector_out = rs.VectorScale( unitVector, -20) midPoint_top=rs.VectorAdd(midPoint[0], vector_out) topMidPoints.append([midPoint_top.X,midPoint_top.Y, midPoint_top.Z]) groundMidPoints.append([midPoint_ground[0],midPoint_ground[1], midPoint_ground[2]]) if 0: rs.ObjectColor(rs.AddLine(midPoint_object, midPoint_base), (10,20,255)) rs.ObjectColor(rs.AddLine(midPoint_base, midPoint_top), (10,20,255)) rs.ObjectColor(rs.AddLine(midPoint_top, midPoint_ground), (10,20,255)) rs.ObjectColor(rs.AddPoint(midPoint_base), (200, 200, 200)) rs.ObjectColor(rs.AddPoint(midPoint_top), (150, 150, 200)) rs.ObjectColor(rs.AddPoint(midPoint_ground), (200, 150, 150)) for i in range(len(dodekaedersMidPoints)): if i < 2: if i%2==0: allMidPoints.append(topMidPoints[i]) allMidPoints.append(groundMidPoints[i]) else: allMidPoints.append(groundMidPoints[i]) allMidPoints.append(topMidPoints[i]) else: allMidPoints.append(topMidPoints[i-1]) allMidPoints.append(groundMidPoints[i-1]) allMidPoints.append(groundMidPoints[i]) allMidPoints.append(topMidPoints[i]) if 0: for i in range(len(allMidPoints)): rs.ObjectColor( dm.textDots([allMidPoints[i]], str(i)) , [255,255,0] ) if 0: countCircle = countCircle*len(dodekaedersMidPoints) makeTubePanel(allMidPoints, rad, countCircle, countCirclePts) if 1: for i in range(0, len(allMidPoints), 4): twoObjectMidPoints=[] if (i + 3) < len(allMidPoints): twoObjectMidPoints.append(allMidPoints[i]) twoObjectMidPoints.append(allMidPoints[i+1]) twoObjectMidPoints.append(allMidPoints[i+2]) twoObjectMidPoints.append(allMidPoints[i+3]) makeTubePanel(twoObjectMidPoints, rad, countCircle, countCirclePts) def makeTubePanel(midPoints, rad=5, countCircle=10, countCirclePts=10): if midPoints: #draw line between MidPoints crv = rs.AddCurve( midPoints, 2 ) #calculate coords for countCircle coords = rs.DivideCurve( crv, countCircle, create_points=0) circleCoordsLists = [] #####Circles for cor in coords: pass paraX = rs.CurveClosestPoint( crv, cor ) planeX = rs.CurvePerpFrame(crv, paraX) circle = rs.AddCircle( planeX, rad ) circleCoords = rs.DivideCurve( circle, countCirclePts, 0) circleCoordsLists.append( circleCoords ) rs.DeleteObject(circle) ####CicleLine for i in range( int(countCirclePts*1) ): coords = [] for coordList in circleCoordsLists: coords.append( coordList[i] ) rs.ObjectColor(rs.AddInterpCurve(coords, degree=3, knotstyle=3 ),(10,10,200)) def makeTubeV2(dodekaedersMidPoints, rad=5, countCircle=10, countCirclePts=10): if dodekaedersMidPoints: topMidPoints=[] groundMidPoints=[] allMidPoints=[] it = iter(dodekaedersMidPoints) for obj_1, obj_2 in zip(it, it): groundMidP=[] topMidP =[] groundMidP, topMidP = distance_to_objects(obj_1, obj_2) groundMidPoints.extend(groundMidP) topMidPoints.extend(topMidP) if len(dodekaedersMidPoints) % 2 != 0: groundMidP=[] topMidP =[] groundMidP, topMidP = distance_to_objects(dodekaedersMidPoints[len(dodekaedersMidPoints)-2], dodekaedersMidPoints[len(dodekaedersMidPoints)-1]) groundMidPoints.extend(groundMidP) topMidPoints.extend(topMidP) #make array allMidPoints for i in range(len(groundMidPoints)): if i < 2: if i%2==0: allMidPoints.append(topMidPoints[i]) allMidPoints.append(groundMidPoints[i]) else: allMidPoints.append(groundMidPoints[i]) allMidPoints.append(topMidPoints[i]) else: allMidPoints.append(topMidPoints[i-1]) allMidPoints.append(groundMidPoints[i-1]) allMidPoints.append(groundMidPoints[i]) allMidPoints.append(topMidPoints[i]) if 0: for i in range(len(allMidPoints)): rs.ObjectColor( dm.textDots([allMidPoints[i]], str(i)) , [255,255,0] ) for i in range(0, len(allMidPoints), 4): twoObjectMidPoints=[] if (i + 3) < len(allMidPoints): twoObjectMidPoints.append(allMidPoints[i]) twoObjectMidPoints.append(allMidPoints[i+1]) twoObjectMidPoints.append(allMidPoints[i+2]) twoObjectMidPoints.append(allMidPoints[i+3]) makeTubePanel(twoObjectMidPoints, rad, countCircle, countCirclePts) return def distance_to_objects(obj_1, obj_2): topMidPoints=[] groundMidPoints=[] object_1MidPoints=[] object_2MidPoints=[] groundMidPoints.append(obj_1[13]) groundMidPoints.append(obj_2[13]) indices_to_remove = [0,6,7,8,9,10,12,13] object_1MidPoints = [item for j, item in enumerate(obj_1) if j not in indices_to_remove] object_2MidPoints = [item for j, item in enumerate(obj_2) if j not in indices_to_remove] min_distance = float("inf") index1, index2 = -1, -1 for x, p1 in enumerate(object_1MidPoints): for y, p2 in enumerate(object_2MidPoints): distance = distance_to_point(p1, p2) if distance < min_distance: min_distance = distance index1, index2 = x, y topMidPoints.append(object_1MidPoints[index1]) topMidPoints.append(object_2MidPoints[index2]) return groundMidPoints, topMidPoints def distance_to_point(point, ref_point): return rs.Distance(point, ref_point) def makePanelV1(plate, midPoint, rad=10.0, segments=10, distance=10): if midPoint: midPoint_in = midPoint if 0: rs.ObjectColor(rs.AddPoint(midPoint), (200,100,200)) rad_in = rad/3 rad_out = rad/4 vector_normal = dm.normVec3pnts(plate[0],plate[1],plate[2]) vector_out = rs.VectorScale( vector_normal, distance) midPoint_out = rs.VectorAdd(midPoint_in, vector_out) if 0: if midPoint_out: rs.ObjectColor(rs.AddPoint(midPoint_out), (100,100,200)) midVector = rs.VectorCreate(plate[0], midPoint_in) unitVector = rs.VectorUnitize(midVector) point_out = rs.VectorScale(unitVector, rad_out) point_in = rs.VectorScale(unitVector, rad_in) coords_in = [] coords_out = [] for i in range (segments): coords_out.append(rs.VectorAdd(midPoint_out, point_out)) coords_in.append(rs.VectorAdd(midPoint_in, point_in)) point_out = rs.VectorRotate(point_out, 360/segments, vector_out) point_in = rs.VectorRotate(point_in, 360/segments, vector_normal) if 0: rs.ObjectColor(rs.AddPoints(coords_in), (10,10,200)) rs.ObjectColor(rs.AddPoints(coords_out), (10,10,200)) for i in range(segments): pB = coords_in[(i + 10) % segments] pF = coords_out[i] lin = rs.AddLine( pB, pF ) rs.ObjectColor(lin, (10,10,200) ) def makePanelV2(plate, midPoint, distance=10): if midPoint: rs.ObjectColor(rs.AddPoint(midPoint), (200,100,200)) midPoint_in = midPoint vector_normal = dm.normVec3pnts(plate[0],plate[1],plate[2]) vector_out = rs.VectorScale( vector_normal, distance) midPoint_out = rs.VectorAdd(midPoint_in, vector_out) if 0: if midPoint_out: rs.ObjectColor(rs.AddPoint(midPoint_out), (100,100,200)) faces = [rs.AddSrfPt([plate[i], plate[(i+1) % len(plate)], midPoint_out]) for i in range(len(plate))] if faces: for face in faces: if face and rs.IsSurface(face): edges = rs.DuplicateEdgeCurves(face) if edges: for edge in edges: rs.AddPipe(edge, 0, 0.2) def makePlatform(distance=10.0, pos=[0,0,0]): points = [ rs.AddPoint(pos[0], pos[1], pos[2]), rs.AddPoint(pos[0]+distance, pos[1], pos[2]), rs.AddPoint(pos[0]+distance, pos[1]+distance, pos[2]), rs.AddPoint(pos[0], pos[1]+distance, pos[2]), rs.AddPoint(pos[0], pos[1], pos[2]+distance/10), rs.AddPoint(pos[0]+distance, pos[1], pos[2]+distance/10), rs.AddPoint(pos[0]+distance, pos[1]+distance, pos[2]+distance/10), rs.AddPoint(pos[0], pos[1]+distance, pos[2]+distance/10) ] coord=[] for i, point in enumerate(points): coord.append(rs.PointCoordinates(point)) rs.DeleteObject(point) if 0: for i, point in enumerate(coord): rs.ObjectColor(rs.AddPoints([coord[i][0], coord[i][1], coord[i][2]]), (10,10,200)) rs.ObjectColor( dm.textDots([coord[i]], str(i)) , [255,255,0] ) box = rs.AddBox(coord) if 1: if box: edges = rs.DuplicateEdgeCurves(box) if edges: for edge in edges: rs.AddPipe(edge, 0, 0.2) return coord #Main def main(): lockLayer() crv = determineCurve("CRATER::crater_contours") clear_all() dodekaeders=[] dodekaedersMidPoints=[] dodekaedersRadius=[] dodekaedersPosition=[] dodekaedersCounts=4 for i in range (dodekaedersCounts): dodekaedersRadius.append(random.uniform(30,100)) dodekaedersPosition.append([random.uniform(3000,4000), random.uniform(3000,4000),random.uniform(-30,00)]) #make Dodekaeder coords = makeDodekaeder(rad=dodekaedersRadius[i], pos=dodekaedersPosition[i], makeCrv=1, makeSrf=1, verbose=0) #determine mid points midPoint = makeMidPointDodekaeder(coords, crv) #make Stabilizers makeStabilizer(coords[0], crv, rad=1, segments=20) #make side panels for y, plate in enumerate(coords[1:11], start=1): if 1: makePanelV1(plate, midPoint[y], rad=dodekaedersRadius[i], segments=100, distance=4) #make base panel if 1: makePanelV1(coords[0], midPoint[0], rad=dodekaedersRadius[i], segments=100, distance=20) #make top panel if 1: makePanelV2(coords[11], midPoint[11],distance=30) #rs.ObjectColor( dm.textDots([midPoint[0]], str(i)) , [255,255,0] ) dodekaeders.append(coords) dodekaedersMidPoints.append(midPoint) #makePlatform coordsBox = makePlatform(distance=350.0, pos=(random.uniform(3500,4500), random.uniform(3500,4500),random.uniform(-30,0))) makeStabilizer(coordsBox, crv, rad=3, segments=20) boxMidPoint= dm.pntCentroid(coordsBox[4:7]) rad=random.uniform(50,100) #make Dodekaeder on platform coords = makeDodekaeder(rad=rad, pos=boxMidPoint, makeCrv=1, makeSrf=1, verbose=0) #determine mid points midPoint = makeMidPointDodekaeder(coords, crv) #make side panels for y, plate in enumerate(coords[1:11], start=1): if 1: makePanelV1(plate, midPoint[y], rad=rad, segments=100, distance=4) #make base panel if 1: makePanelV1(coords[0], midPoint[0], rad=rad, segments=100, distance=20) #make top panel if 1: makePanelV2(coords[11], midPoint[11],distance=30) # add coords if tube with platform dodekaeder if 1: dodekaeders.append(coords) dodekaedersMidPoints.append(midPoint) #circle tube if 1: if dodekaedersCounts>2: dodekaedersMidPoints.append(dodekaedersMidPoints[0]) #make Tube if 0: makeTubeV1(dodekaedersMidPoints, rad=5, countCircle=80, countCirclePts=20) if 1: makeTubeV2(dodekaedersMidPoints, rad=5, countCircle=20, countCirclePts=60) main()