import rhinoscriptsyntax as rs import math import sys sys.path.append("C:/Users/frede/Desktop/dm2/lib/") import OSM_lib as osm import DM_lib as dm # REMAP FUNCTION def remap(value, init_min, init_max, remap_min, remap_max, limit=False, type='linear', exp_power=2, sigmoid_k=1, sigmoid_center=0): """ Takes value that lies within the [init_min, init_max] and changes it to fit the boundaries of [remap_min, remap_max]. If limit == True and the value escapes boundaries [remap_min, remap_max], then the vlue will be set to remap_min(valueremap_max). Types: linear, logarithmic, exponential, sigmoid """ remap_size = remap_max - remap_min init_size = init_max - init_min if remap_size == 0 or init_size == 0: return remap_min floored_value = value - init_min if type == 'linear': init_fraction = floored_value / init_size elif type == 'logarithmic': if floored_value == 0: init_fraction = 0 else: sign = floored_value / abs(floored_value) * init_size / abs(init_size) if floored_value != 0 else init_size/init_size init_fraction = math.log( sign*(floored_value / (init_size+1)))*sign elif type == 'exponential': sign = floored_value / abs(floored_value) * init_size / abs(init_size) if floored_value != 0 else init_size/init_size # if init_size*floored_value < 0: # print init_size, floored_value, sign init_fraction = (sign*floored_value / init_size)**exp_power*sign elif type == 'sigmoid': init_fraction = 1/(1+math.e**(-sigmoid_k*(value-sigmoid_center))) remap_value = remap_min + remap_size * init_fraction if limit == True: if remap_value < remap_min: remap_value = remap_min elif remap_value > remap_max: remap_value = remap_max return remap_value def plot_plane(x, y, z): """ Takes three arrays and adds points (x[i], y[i], z[i]) to the Rhino. The color of the point is determined by mapping x, y, z to Red, Green, Blue on the scale of [minXYZ; maxXYZ] to [0; 255] """ points_quantity = len(x) min_x = min(x) max_x = max(x) min_y = min(y) max_y = max(y) min_z = min(z) max_z = max(z) for i in range(points_quantity): point = [x[i], y[i], z[i]] point_added = rs.AddPoint(point) x_color = remap(x[i], min_x, max_x, 0, 255, True, type="exponential", exp_power=0.5) y_color = remap(y[i], min_y, max_y, 0, 255, True, type="exponential", exp_power=0.5) z_color = remap(z[i], min_z, max_z, 0, 255, True, type="exponential", exp_power=0.5) rs.ObjectColor(point_added, [z_color, z_color, z_color]) def distance_from_point_to_line(line_vector, line_point, point_a): vector = rs.VectorCreate(point_a, line_point) return rs.VectorLength(rs.VectorCrossProduct(vector, line_vector))/rs.VectorLength(line_vector) # PROJECT VECTOR ON VECTOR FUNCTION def project_vector_onto_another_vector(vector_to_project, vector_projected_on): dot_product = rs.VectorDotProduct(vector_to_project, vector_projected_on) vec_projected_on_length = rs.VectorLength(vector_projected_on) # Rescale value of a projected_on_vector rescale_value = dot_product/(vec_projected_on_length)**2 projected_vector = rs.VectorScale(vector_projected_on, rescale_value) return projected_vector # PROJECT VECTOR/POINT ON A PLANE FUNCTION def project_point_on_a_plane(normal_vector, plane_point, point_to_project): # rs.AddTextDot("project", point_to_project) # Step 1: Find a vector (vec_between_points) from the plane_point to point_to_project vec_between_points = rs.VectorSubtract(point_to_project, plane_point) # Step 2: project this vector onto normal vector rescaled_normal_vector = project_vector_onto_another_vector(vec_between_points, normal_vector) # Step 3: subtract point from this projected vector projected_point = rs.VectorSubtract(point_to_project, rescaled_normal_vector) return projected_point # IS POINT IN POLYGON FUNCTION def is_point_in_polygon(point, polygon): num_vertices = len(polygon) x0, y0 = point is_inside = False # Store the first point in the polygon and initialize the second point p1 = polygon[0] # Loop through each edge in the polygon for i in range(1, num_vertices + 1): # Get the next point in the polygon p2 = polygon[i % num_vertices] # Check if the point is above the minimum y coordinate of the edge if y0 > min(p1[1], p2[1]): # Check if the point is below the maximum y coordinate of the edge if y0 <= max(p1[1], p2[1]): # Check if the point is to the left of the maximum x coordinate of the edge if x0 <= max(p1[0], p2[0]): # Calculate the x-intersection of the line connecting the point to the edge x_intersection = (y0 - p1[1]) * (p2[0] - p1[0]) / (p2[1] - p1[1]) + p1[0] # Check if the point is on the same line as the edge or to the left of the x-intersection if p1[0] == p2[0] or x0 <= x_intersection: # Flip the inside flag is_inside = not is_inside # Store the current point as the first point for the next iteration p1 = p2 # Return the value of the inside flag return is_inside def get_angle_bisector(vector1, vector2): # Use formula u * ||v|| + v * ||u|| # rs.AddTextDot("vec1", vector1) # rs.AddTextDot("vec2", vector2) vector1_length = rs.VectorLength(vector1) vector2_length = rs.VectorLength(vector2) vector1_scaled = rs.VectorScale(vector1, vector2_length) vector2_scaled = rs.VectorScale(vector2, vector1_length) vector_angle_bisector = rs.VectorAdd(vector1_scaled, vector2_scaled) vector_angle_bisector_normalized = rs.VectorUnitize(vector_angle_bisector) # rs.AddTextDot("res", vector_angle_bisector) return vector_angle_bisector_normalized def generate_parabola_points(vertex, height, focus_distance, direction=[1, 0], num_points=100): """ Generate points of a parabola. Parameters: vertex (list): The vertex of the parabola (x, y). height (float): The vertical height of the parabola from the vertex to its edge. focus_distance (float): The distance from the vertex to the focus of the parabola. num_points (int): Number of points to generate along the parabola. direction (list): A unit vector indicating the direction the parabola opens. Default is (1, 0) for opening rightward. Returns: list of tuples: A list of (x, y) points along the parabola. """ # Extract the vertex coordinates x0, y0 = vertex # Normalize the direction vector direction_length = math.sqrt(direction[0]**2 + direction[1]**2) dir_x, dir_y = direction[0] / direction_length, direction[1] / direction_length # Compute a perpendicular vector to the direction perp_x, perp_y = -dir_y, dir_x # Rotate direction vector by 90 degrees # Parabola constant based on focus distance a = 1 / (4 * focus_distance) # Generate parabola points in local coordinates points = [] x_span = height # Extent of the parabola in the perpendicular direction for i in range(-num_points // 2, num_points // 2 + 1): # Compute x' (perpendicular offset) in the local coordinate system x_perp = i * (x_span / num_points) # Compute y' (parallel offset) using the parabola equation y_parallel = a * x_perp**2 # Convert to global coordinates x_global = x0 + x_perp * perp_x + y_parallel * dir_x y_global = y0 + x_perp * perp_y + y_parallel * dir_y points.append([x_global, y_global]) return points def point_in_between_2d(point1, point2): result_point = [] for i in range(2): result_point.append((point1[i]+point2[i])/2) return result_point def get_parabola_height_focus_distance_direction(parabola_vertex, vertex1, vertex2): # Calcualte direction of a fold (bisector of the corner) vector1 = rs.VectorSubtract(vertex1, parabola_vertex) vector2 = rs.VectorSubtract(vertex2, parabola_vertex) parabola_direction = get_angle_bisector(vector1, vector2) # Calculate height of the parabola distance_between_neighbours= rs.Distance(vertex1, vertex2) corner_angle = rs.VectorAngle(vector1, vector2) scale_factor = 1.25 # constant parabola_height = scale_factor*distance_between_neighbours*(360-corner_angle)/360 # Calculate the focus distance focus_distance = (parabola_height**2)/(2*distance_between_neighbours) return parabola_height, focus_distance, parabola_direction def bend_plane_parabola(plane_points, plane_params, parabola_vertex_xy, directional_vector, pull_force, parabola_height, focus_distance, parabola_direction): # Generate parabola polygon around axis (vector) # Check whether the point lies within the boundaries # If so, pull it in the direction with remapped force (where parabola_vertex is max) # Step 1: Calculate fractions of perpendicular and parallel pull A, B, C, D = plane_params normal_vector = [A, B, C] normal_vector = rs.VectorUnitize(normal_vector) directional_vector = rs.VectorUnitize(directional_vector) # Find bending center's z value parabola_vertex_z = (-1) * (A * parabola_vertex_xy[0] + B * parabola_vertex_xy[1] + D) / C if C != 0 else 0 parabola_vertex_xyz = parabola_vertex_xy + [parabola_vertex_z] # directional_vector_from_plane = rs.VectorSubtract(directional_vector, parabola_vertex_xyz) # Calculate fraction of parallel and perpendicular pull directional_vector_length = rs.VectorLength(directional_vector) if directional_vector_length == 0: return plane_points # No directional vector, no pull directional_vector_projected_normal = project_vector_onto_another_vector(directional_vector, normal_vector) directional_vector_projected_length = rs.VectorLength(directional_vector_projected_normal) perpendicular_pull_fraction = directional_vector_projected_length / directional_vector_length parallel_pull_fraction = 1 - perpendicular_pull_fraction # Step 2: Move each point that lies within the parabolic influence area parabola_boundaries = generate_parabola_points( vertex = parabola_vertex_xy, height = parabola_height, focus_distance = focus_distance, direction = parabola_direction) rs.ObjectColor(rs.AddCurve(parabola_boundaries), [255,255,255]) pull_force_arr = [] parabola_width = rs.VectorLength(rs.VectorCreate(parabola_boundaries[0], parabola_boundaries[-1])) point_between = point_in_between_2d(parabola_boundaries[0], parabola_boundaries[-1]) # rs.AddTextDot('one', parabola_boundaries[0]) # rs.AddTextDot('two', parabola_boundaries[-1]) w = parabola_width / 2 point_between.append(0) parabola_vertex_xy.append(0) h = rs.VectorLength(rs.VectorCreate(point_between, parabola_vertex_xy)) # print "h=", h max_value = 1 # max_value = parabola_width*parabola_height for i, point in enumerate(plane_points): x = point[0] y = point[1] point_distance_to_vertex = rs.VectorLength(rs.VectorSubtract(parabola_vertex_xyz, point)) point_distance_to_parabola_axis = distance_from_point_to_line(parabola_direction, parabola_vertex_xyz, point) h0 = (point_distance_to_vertex**2 - point_distance_to_parabola_axis**2)**0.5 w0 = point_distance_to_parabola_axis point_value = (h-h0)/h - w0/(10*w)+0.1 # point_value = 10*point_distance_to_vertex - point_distance_to_parabola_axis # point_value = point_distance_to_vertex * (parabola_width-point_distance_to_parabola_axis) if is_point_in_polygon([x, y], parabola_boundaries): # Check if the point is within the area pull_force_remaped = remap(point_value, 0, max_value, 0, pull_force, limit=True, type='exponential', exp_power=5) pull_force_arr.append(pull_force_remaped) parallel_pull_force = pull_force_remaped*parallel_pull_fraction perpendicular_pull_force = pull_force_remaped*perpendicular_pull_fraction normal_vector_scaled = rs.VectorScale(directional_vector_projected_normal, perpendicular_pull_force) directional_vector_scaled = rs.VectorScale(directional_vector, parallel_pull_force) point = rs.VectorAdd(point, normal_vector_scaled) point = rs.VectorAdd(point, directional_vector_scaled) plane_points[i] = point # print "pull force", pull_force # if len(pull_force_arr) != 0: # print "min", min(pull_force_arr) # print "max", max(pull_force_arr) return plane_points # BEND PLANE AREA CIRCLE FUNCTION def bend_plane_circle(plane_points, plane_params, bending_center_xy, directional_vector, pull_force, radius): # Step 1: Calculate fraction of perpendicular and parallel pull # Normalize both vectors A,B,C,D = plane_params normal_vector = [A, B, C] normal_vector = rs.VectorUnitize(normal_vector) directional_vector = rs.VectorUnitize(directional_vector) # Find bending center's z value bending_center_z = (-1)*(A*bending_center_xy[0] + B*bending_center_xy[1] + D)/C if C != 0 else 0 bending_center_xyz = bending_center_xy[0:] + [bending_center_z] # Find a fraction directional_vector_length = rs.VectorLength(directional_vector) if directional_vector_length == 0: return plane_points directional_vector_projected = project_vector_onto_another_vector(directional_vector, normal_vector) directional_vector_projected_length = rs.VectorLength(directional_vector_projected) perpendicular_pull_fraction = directional_vector_projected_length / directional_vector_length parallel_pull_fraction = 1 - perpendicular_pull_fraction # Step 2: Move each point that lies within the boundaries of a circle pull_force_arr = [] center_x = bending_center_xy[0] center_y = bending_center_xy[1] radius_sq = radius**2 for i, point in enumerate(plane_points): x = point[0] y = point[1] point_radius_sq = (x-center_x)**2 + (y-center_y)**2 if radius_sq >= point_radius_sq: pull_force_remaped= remap(point_radius_sq, radius_sq, 0, 0, pull_force, type="exponential", exp_power=2) pull_force_arr.append(pull_force_remaped) parallel_pull_force = pull_force_remaped*parallel_pull_fraction perpendicular_pull_force = pull_force_remaped*perpendicular_pull_fraction normal_vector_scaled = rs.VectorScale(directional_vector, perpendicular_pull_force) directional_vector_scaled = rs.VectorScale(directional_vector, parallel_pull_force) point = rs.VectorAdd(point, normal_vector_scaled) point = rs.VectorAdd(point, directional_vector_scaled) plane_points[i] = point # if len(pull_force_arr) != 0: # print pull_force_arr # print "min", min(pull_force_arr) # print "max", max(pull_force_arr) # print sum(pull_force_arr)/len(pull_force_arr) return plane_points # GENERATE POINTS OF A PLANE DEFINED BY 3 OR MORE POINTS def generate_plane(vertices, three_main_vertices_ids, density_rate = 5, move_non_main_vertices = False): """ Creates a plane out of main points (triangular). Uses additional vertices to complete the shape (square). Then uses more points to bend the plane and make it more interesting. """ # Step 1: find a plane's equation p1 = vertices[three_main_vertices_ids[0]] # Point 1 p2 = vertices[three_main_vertices_ids[1]] # Point 2 p3 = vertices[three_main_vertices_ids[2]] # Point 3 # rs.AddTextDot('p1', p1) # rs.AddTextDot('p2', p2) # rs.AddTextDot('p3', p3) # Calculate vectors v1 = rs.VectorCreate(p2, p1) v2 = rs.VectorCreate(p3, p1) # Calculate the normal vector of the plane normal = rs.VectorCrossProduct(v1, v2) # Normalize the normal vector normal = rs.VectorUnitize(normal) # Make normal vector always point in the direction of z+ if normal[2] < 0: for coord in normal: coord = coord*(-1) # Plane equation: Ax + By + Cz + D = 0 A, B, C = normal D = (A * p1[0] + B * p1[1] + C * p1[2])*(-1) # Step 2: generate X and Y values for the plane # Find the borders of the plane (min and max values of X and Y) # for vertex in vertices: # x = str(vertex[0]) # y = str(vertex[1]) # z = str(vertex[2]) # rs.AddTextDot(x+';'+y+';'+z, vertex) # every_x_of_the_plane = [] every_y_of_the_plane = [] for vertex in vertices: every_x_of_the_plane.append(vertex[0]) every_y_of_the_plane.append(vertex[1]) min_x = int(math.floor(min(every_x_of_the_plane))) max_x = int(math.ceil(max(every_x_of_the_plane))) min_y = int(math.floor(min(every_y_of_the_plane))) max_y = int(math.ceil(max(every_y_of_the_plane))) # Generate x and y coordinates for points x_range = [i / density_rate for i in range(int((min_x)*density_rate)-1, int((max_x)*density_rate)+1)] # X values y_range = [i / density_rate for i in range(int((min_y)*density_rate)-1, int((max_y)*density_rate)+1)] # Y values # Step 3: delete points that are out of border # Generate all 2d points points_2d_in_range = [] for x in x_range: for y in y_range: points_2d_in_range.append([x, y]) # Delete points out of border points_2d_in_border = [] for point in points_2d_in_range: if is_point_in_polygon(point, vertices): points_2d_in_border.append(point) # Step 4: Generate points of the plane points_3d = [] for point_2d in points_2d_in_border: x = point_2d[0] y = point_2d[1] # Calculate z using the plane equation z = (-A * x - B * y - D) / C if C != 0 else 0 # Avoid division by zero # points.append(Rhino.Geometry.Point3d(x, y, z)) points_3d.append([x,y,z]) plane_paremeters = [A, B, C, D] # Step 5: Move additional_vertices in their corresponding place if move_non_main_vertices: vertex_quantity = len(vertices) non_main_vertices_ids = [i for i in range(vertex_quantity) if i not in three_main_vertices_ids] for i in non_main_vertices_ids: vertex = vertices[i%vertex_quantity] print vertex projected_vertex = project_point_on_a_plane(normal, p1, vertex) vertex_distance_to_plane = rs.VectorLength(rs.VectorSubtract(vertex, projected_vertex)) directional_vector = rs.VectorSubtract(vertex, projected_vertex) print vertex print "vdtp", vertex_distance_to_plane if directional_vector != rs.CreateVector([0,0,0]): # points_3d = bend_plane_circle(points_3d, plane_paremeters, vertex[0:2], directional_vector, vertex_distance_to_plane, vertex_distance_to_plane*10 ) # plane_points, plane_params, bending_center_xy, directional_vector, pull_force, radius previous_vertex = vertices[(i-1)%vertex_quantity] next_vertex = vertices[(i+1)%vertex_quantity] # Calcualte direction of a fold (bisector of the corner) vector1 = rs.VectorSubtract(previous_vertex, vertex) vector2 = rs.VectorSubtract(next_vertex, vertex) parabola_direction = get_angle_bisector(vector1, vector2) # Calculate height of the parabola distance_between_neighbours= rs.Distance(previous_vertex, next_vertex) corner_angle = rs.VectorAngle(vector1, vector2) scale_factor = 1.25 # constant parabola_height = scale_factor*distance_between_neighbours*(360-corner_angle)/360 # Calculate the focus distance focus_distance = (parabola_height**2)/(2*distance_between_neighbours) points_3d = bend_plane_parabola( plane_points = points_3d, plane_params = plane_paremeters, parabola_vertex_xy = vertex[0:2], directional_vector = directional_vector, pull_force = vertex_distance_to_plane, parabola_height = parabola_height, focus_distance = focus_distance, parabola_direction = parabola_direction) return points_3d, plane_paremeters # BEND PLANE AROUND MULTIPLE POINTS def bend_plane_multiple_points(plane_points, plane_params, points_to_bend, directional_vector, pull_force, radius): bend_points_quantity = len(points_to_bend) for i in range(bend_points_quantity): x = points_to_bend[i][0] y = points_to_bend[i][1] plane_points = bend_plane_circle(plane_points, plane_params, [x,y] , directional_vector, pull_force, radius) # plane_points, plane_params, bending_center_xy, directional_vector, pull_force, radius return plane_points # MOVE POINT TO NEW ORIGIN def move_points_to_new_origin(points, origin): for i, point in enumerate(points): points[i] = [point[j]+origin[j] for j in range(3)] return points def polygon(origin): dict = { "vertices": [ [83.0, 254.0, 20.0], [260.0, 243.0, 20.0], [322.0, 55.0, 20.0], [188.0, -95.0, 0.0], [23.0, -205.0, 0.0], [-148.0, -280.0, 0.0], [-285.0, -233.0, 0.0], [-334.0, -74.0, 0], [-259.0, 66.0, 9.5]], "three_main_vertices_ids": [0,1,2], "density_rate": 0.5, "move_non_main_vertices": True } dict["vertices"] = move_points_to_new_origin(dict["vertices"], origin) points, params = generate_plane( vertices= dict["vertices"], three_main_vertices_ids = dict["three_main_vertices_ids"], density_rate = dict["density_rate"], move_non_main_vertices = dict["move_non_main_vertices"]) vertices = dict['vertices'] for i in range(3): vertex = vertices[i] previous_vertex = vertices[(i-1)] next_vertex = vertices[i+1] parabola_height, focus_distance, parabola_direction = get_parabola_height_focus_distance_direction(vertex,previous_vertex, next_vertex) points = bend_plane_parabola( plane_points = points, plane_params = params, parabola_vertex_xy = vertex[0:2], directional_vector = [0,0,-1], pull_force = vertex[2], parabola_height = parabola_height, focus_distance = focus_distance, parabola_direction = parabola_direction) points = bend_plane_circle( plane_points=points, plane_params=params, bending_center_xy = move_points_to_new_origin([[-140,-80,0]], origin)[0][0:2], directional_vector = [0,1,1], pull_force = 75, radius = 150) points = bend_plane_circle( plane_points=points, plane_params=params, bending_center_xy = move_points_to_new_origin([[140,80,0]], origin)[0][0:2], directional_vector = [0,-1,1], pull_force = 75, radius = 150) line_points = move_points_to_new_origin([[-100, 167, 0], [100, -167, 0]], origin) curve = rs.AddCurve(line_points) curve_points = rs.DivideCurve(curve, 20) # Every even point in direction [1,0,1] points = bend_plane_multiple_points( plane_points=points, plane_params=params, points_to_bend=curve_points[1::2], directional_vector=[0.5,0.5,1], pull_force=20, radius=10) # Every odd point in direction [-1,0,1] points = bend_plane_multiple_points( plane_points=points, plane_params=params, points_to_bend=curve_points[0::2], directional_vector=[-0.5,-0.5,1], pull_force=20, radius=10) return points def curved_roof(origin): # Move curve building curve_building = rs.ObjectsByName("Wcrv_330570500") rs.ExtrudeCurve(curve_building, rs.AddLine([0,0,0], [0,0,80])) # Build roof roof_vertices = [ [-336.707, -60.151, 80.0], [-326.275, -38.0, 80.0], [-319.665, -23.2, 80.0], [-276.42, 10.2, 80.0], [-190.9, 69.89, 80.0], [-190.0, 71.092, 80.0], [-154.175, 96.749, 80.0], [-150.928, 99.554, 80.0],[-122.19, 117.633, 80.0], [-24.655, 187.381, 80.0], [20.363, 214.347, 80.0] ] # length = 11 dict = { "vertices": roof_vertices[0:] + [ # [-350, -11, 80], # [214, 329, 80], [161, -95, 7.7], [-236.5, -337, 10] ], "three_main_vertices_ids": [0,-3,-2], "density_rate": 0.1, "move_non_main_vertices": True } dict["vertices"] = move_points_to_new_origin(dict["vertices"], origin) points, params = generate_plane( vertices= dict["vertices"], three_main_vertices_ids = dict["three_main_vertices_ids"], density_rate = dict["density_rate"], move_non_main_vertices = dict["move_non_main_vertices"]) vertices = dict['vertices'][0:] line_points = move_points_to_new_origin([[-272, -238, 0], [0,0,0], [293, 207, 0]], origin) curve = rs.AddCurve(line_points, 3) curve_points = rs.DivideCurve(curve, 100) points = bend_plane_multiple_points( plane_points=points, plane_params=params, points_to_bend=curve_points, directional_vector=params[0:3], pull_force=1, radius=200) # bend_corners_ids = [] for i in bend_corners_ids: vertex = vertices[i] previous_vertex = vertices[(i-1)] next_vertex = vertices[i+1] parabola_height, focus_distance, parabola_direction = get_parabola_height_focus_distance_direction(vertex,previous_vertex, next_vertex) points = bend_plane_parabola( plane_points = points, plane_params = params, parabola_vertex_xy = vertex[0:2], # directional_vector = params[0:3], directional_vector = [0,0,-1], pull_force = vertex[2]-12, parabola_height = parabola_height*2, focus_distance = focus_distance, parabola_direction = parabola_direction) return points # bend_corners_ids = [-3] for i in bend_corners_ids: vertex = vertices[i] previous_vertex = vertices[(i-1)] next_vertex = vertices[i+1] parabola_height, focus_distance, parabola_direction = get_parabola_height_focus_distance_direction(vertex,previous_vertex, next_vertex) points = bend_plane_parabola( plane_points = points, plane_params = params, parabola_vertex_xy = vertex[0:2], # directional_vector = params[0:3], directional_vector = [0,0,-1], pull_force = vertex[2]-12, parabola_height = parabola_height*2, focus_distance = focus_distance, parabola_direction = parabola_direction) return points def build_roof(name): origin = [-64841, 21717, 0] move_camera(move_points_to_new_origin([[0,0,0]], origin)[0], origin) points = [] if name == "polygon": points = polygon(origin) elif name == "curved_roof": points = curved_roof(origin) x = [] y = [] z = [] for point in points: x.append(point[0]) y.append(point[1]) z.append(point[2]) plot_plane(x,y,z) rs.AddCurve(points, 1) def move_camera(camera_position=[10, 10, 10] , target_point=[0, 0, 0]): # Get the name of the active view (or specify a specific view name) active_view = rs.CurrentView() # Set the camera and target for the view rs.ViewCamera(active_view, camera_position) rs.ViewTarget(active_view, target_point) # MAIN: rs.ShowGrid(view=None, show=True) rs.ViewDisplayMode(rs.CurrentView(), "wireframe") # clear_rhino_data() rs.EnableRedraw(1) dm.newEmptyLayer("Default") if 1: OSMpath = "C:/Users/frede/Desktop/dm2/lib/" # CHANGE OSMfile = "loisville.osm" osm.OSMi(OSMfile, OSMpath, trimBounds=0, do3D=1, minHeight=1.0, heightFac=1.0, randomize=[5.0, 10.0], doAllCurves=1, move2Guinea = 1, verbose=0) if 1: # rs.AddLayer("Roof") dm.newEmptyLayer("Roof") build_roof('curved_roof') # polygon or curved_roof #rs.DeleteObjects( rs.ObjectsByType(1))