############################## import rhinoscriptsyntax as rs import sys, math, random sys.path.append("P:\WWW\halil2003\DM2") import DM_lib as dm #reload (osm) import OSM_lib as osm #reload (osm) rs.UnitSystem(4) # meters = 4 rs.ShowGrid(None, 0) rs.ShowGridAxes(None, 1) rs.EnableRedraw(0) currentMode = rs.ViewDisplayMode(rs.CurrentView()) rs.ViewDisplayMode(rs.CurrentView(), "wireframe") rs.Redraw() dm.newEmptyLayer("XXX", [100,100,250]) rs.ShowObjects(rs.AllObjects()) def create_spehere(center, radius): coords = [] scalVec = [radius, 0, 0] for i in range(1001): scalVec = rs.VectorRotate(scalVec, random.uniform(-90,90), [random.uniform(-1,1) for i in range(3)]) coords.append( rs.VectorAdd(center, scalVec) ) pts_id = rs.AddPoints(coords) rs.ObjectColor(pts_id, [255, 0, 0]) def connect_2_speheres(first_center, first_radius, second_center, second_radius): vec = rs.VectorCreate(first_center, second_center) unit_vec = rs.VectorUnitize(vec) unit_vec = rs.VectorReverse(unit_vec) radius_vec = rs.VectorScale(unit_vec, first_radius) first_spehere_intersection_pt = rs.VectorAdd(first_center, radius_vec) unit_vec = rs.VectorReverse(unit_vec) radius_vec = rs.VectorScale(unit_vec, second_radius) second_spehere_intersection_pt = rs.VectorAdd(second_center, radius_vec) line_id = rs.AddLine(first_spehere_intersection_pt, second_spehere_intersection_pt) rs.ObjectColor(line_id, [255, 0, 0]) bldgNames = ["_bldg3D_higBy_flo_136691386", "_bldg3D_higBy_flo_60739635", "_bldg3D_higBy_flo_904678014", "_bldg3D_higBy_flo_116806281"] bldgIDs = [ rs.ObjectsByName(namX)[0] for namX in bldgNames ] bldgCenters = [] bldgAboveCenters = [] secondary_spheres = [] for bldg in bldgIDs: coords = dm.getSurfacePoints(bldg) center = dm.pntCentroid(coords) bldgCenters.append(center) centerAbove = rs.VectorAdd(center, [0,0,25]) bldgAboveCenters.append(centerAbove) rs.AddLine(center, centerAbove) main_center = dm.pntCentroid(bldgAboveCenters) larger_radius = 5 small_radius = 4 create_spehere(main_center, small_radius) def create_ring(ring_center, ring_height, distance_to_sphere_center, sphere_radius, number_of_pts = 1000): z_offsets = [-ring_height, ring_height] color = [166, 189, 219] for idx in range(2): temp_vector = [0, 0, z_offsets[idx]] temp_center = rs.VectorAdd(ring_center, temp_vector) circle_inner = rs.AddCircle(temp_center, distance_to_sphere_center - sphere_radius / 2) coords_inner_initial = rs.DivideCurve(circle_inner, number_of_pts, 0) rs.DeleteObject(circle_inner) coords_inner_final = [] for pt in coords_inner_initial: skip = False for secondary_sphere in secondary_spheres: if calculate_distance(pt, secondary_sphere) < small_radius: skip = True break if not skip: coords_inner_final.append(pt) for pt in coords_inner_final: pt_id = rs.AddPoint(pt) rs.ObjectColor(pt_id, color) circle_outer = rs.AddCircle(temp_center, distance_to_sphere_center + sphere_radius / 2) coords_outer_initial = rs.DivideCurve(circle_outer, number_of_pts, 0) rs.DeleteObject(circle_outer) coords_outer_final = [] for pt in coords_outer_initial: skip = False for secondary_sphere in secondary_spheres: if calculate_distance(pt, secondary_sphere) < small_radius: skip = True break if not skip: coords_outer_final.append(pt) for pt in coords_outer_final: pt_id = rs.AddPoint(pt) rs.ObjectColor(pt_id, color) def calculate_distance(first, second): temp_vector = rs.VectorCreate(first, second) return rs.VectorLength(temp_vector) def create_secondary_spheres(): lower_z = 9999999999999 upper_z = -1 distance_to_the_sphere_center = -1 d = 20 x_offsets = [-d, -d, d, d, -d, -d, d, d] # left - right y_offsets = [-d, d, -d, d, -d, d, -d, d] # further - closer z_offsets = [-d, -d, -d, -d, d, d, d, d] # up - down for idx in range(8): temp_vector = [x_offsets[idx], y_offsets[idx], z_offsets[idx]] new_center = rs.VectorAdd(main_center, temp_vector) secondary_spheres.append(new_center) upper_z = max(upper_z, new_center[2]) lower_z = min(lower_z, new_center[2]) temp_center = [main_center[0], main_center[1], main_center[2] + z_offsets[idx]] temp_vector = rs.VectorCreate(temp_center, new_center) distance_to_the_sphere_center = rs.VectorLength(temp_vector) create_spehere(new_center, small_radius) connect_2_speheres(main_center, small_radius, new_center, small_radius) distance = upper_z - lower_z + 1 number_of_rings = 5 step = distance / (number_of_rings - 1) for z in range(int(lower_z), int(upper_z + 1), int(step)): ring_center = [main_center[0], main_center[1], z] create_ring(ring_center, step / 6, distance_to_the_sphere_center, small_radius) create_secondary_spheres() def create_highest_and_lowest_spheres(): upper_z = -1 for secondary_sphere in secondary_spheres: upper_z = max(upper_z, secondary_sphere[2]) top_secondary_spheres = [] bottom_secondary_spheres = [] for secondary_sphere in secondary_spheres: if secondary_sphere[2] == upper_z: top_secondary_spheres.append(secondary_sphere) else: bottom_secondary_spheres.append(secondary_sphere) # 2 spheres - the heighest and lowest one z_offsets = [-30, 30] # up - down spheres = [bottom_secondary_spheres, top_secondary_spheres] for idx in range(2): temp_vector = [0, 0, z_offsets[idx]] new_center = rs.VectorAdd(main_center, temp_vector) create_spehere(new_center, small_radius) for secondary_sphere in spheres[idx]: connect_2_speheres(secondary_sphere, small_radius, new_center, small_radius) create_highest_and_lowest_spheres() def create_spheres_on_the_top_of_the_buildings(): upper_z = -1 for secondary_sphere in secondary_spheres: upper_z = max(upper_z, secondary_sphere[2]) for center in bldgAboveCenters: create_spehere(center, larger_radius) closest_sphere = [0, 0, 0] min_distance = 99999999999999999 for secondary_sphere in secondary_spheres: if secondary_sphere[2] != upper_z: # if it's not one of the top sphere then do not connect to it! continue distance = calculate_distance(secondary_sphere, center) if distance < min_distance: min_distance = distance closest_sphere = secondary_sphere connect_2_speheres(closest_sphere, small_radius, center, larger_radius) create_spheres_on_the_top_of_the_buildings() #################################### rs.CurrentLayer("Default") rs.ViewDisplayMode(None, "ghosted")