def super_triangle(coords): centpt = centroid_points(coords) bbpts = bounding_box(coords) dis = distance_point_point(bbpts[0], bbpts[2]) dis = dis * 300 v1 = (0 * dis, 2 * dis, 0) v2 = (1.73205 * dis, -1.0000000000001 * dis, 0) # due to numerical issues v3 = (-1.73205 * dis, -1 * dis, 0) pt1 = add_vectors(centpt, v1) pt2 = add_vectors(centpt, v2) pt3 = add_vectors(centpt, v3) return pt1, pt2, pt3
def bounding_box(self): xyz = self.nodes_attributes('xyz', keys=list(self.nodes())) # x_sorted = sorted(xyz, key=lambda k: k[0]) # y_sorted = sorted(xyz, key=lambda k: k[1]) # z_sorted = sorted(xyz, key=lambda k: k[2]) # x = abs(x_sorted[0][0] - x_sorted[-1][0]) # y = abs(y_sorted[0][1] - y_sorted[-1][1]) # z = abs(z_sorted[0][2] - z_sorted[-1][2]) return bounding_box(xyz)
def volmesh_bounding_box(volmesh): """Compute the (axis aligned) bounding box of a volmesh. Parameters ---------- volmesh : :class:`compas.datastructures.VolMesh` The volmesh data structure. Returns ------- list[[float, float, float]] The 8 corner points of the bounding box. """ xyz = volmesh.vertices_attributes('xyz', vertices=list(volmesh.vertices())) return bounding_box(xyz)
def draw_graph(graph, group=None, key_to_colour=None): """Draw a graph in Rhino as grouped points and lines with optional node colouring. Parameters ---------- graph : Network A graph. group : string Optional name of the group. key_to_colour : dict An optional dictonary point node keys no RGB colours. Returns ------- group The name of the drawn group. """ box = bounding_box( [graph.vertex_coordinates(vkey) for vkey in graph.vertices()]) scale = distance_point_point(box[0], box[6]) colours = [[255, 0, 0], [0, 0, 255], [0, 255, 0], [255, 255, 0], [0, 255, 255], [255, 0, 255], [0, 0, 0]] if key_to_colour is None: key_to_colour = {key: -1 for key in graph.vertices()} circles = [] for key in graph.vertices(): circle = rs.AddCircle(graph.vertex_coordinates(key), .01 * scale) circles.append(circle) colour = colours[key_to_colour[key]] rs.ObjectColor(circle, colour) lines = [ rs.AddLine(graph.vertex_coordinates(u), graph.vertex_coordinates(v)) for u, v in graph.edges() ] group = rs.AddGroup(group) rs.AddObjectsToGroup(circles + lines, group) return group
def volmesh_bounding_box(volmesh): """Compute the (axis aligned) bounding box of a volmesh. Parameters ---------- volmesh : compas.datastructures.VolMesh The mesh data structure. Returns ------- float The x dimension of the bounding box. float The y dimension of the bounding box. float The z dimensino of the bounding box. """ xyz = volmesh.vertices_attributes('xyz', keys=list(volmesh.vertices())) return bounding_box(xyz)
def mesh_bounding_box(mesh): """Compute the (axis aligned) bounding box of a mesh. Parameters ---------- mesh : compas.datastructures.Mesh The mesh data structure. Returns ------- list of point The 8 corners of the bounding box of the mesh. Examples -------- >>> mesh_bounding_box(mesh) [[0.0, 0.0, 0.0], [10.0, 0.0, 0.0], [10.0, 10.0, 0.0], [0.0, 10.0, 0.0], [0.0, 0.0, 0.0], [10.0, 0.0, 0.0], [10.0, 10.0, 0.0], [0.0, 10.0, 0.0]] """ xyz = mesh.get_vertices_attributes('xyz') return bounding_box(xyz)
def mesh_bounding_box(mesh): """Compute the (axis aligned) bounding box of a mesh. Parameters ---------- mesh : compas.datastructures.Mesh The mesh data structure. Returns ------- box The bounding box of the mesh. Examples -------- .. code-block:: python pass """ xyz = mesh.get_vertices_attributes('xyz') return bounding_box(xyz)
def mesh_bounding_box(mesh): """Compute the (axis aligned) bounding box of a mesh. Parameters ---------- mesh : compas.datastructures.Mesh The mesh data structure. Returns ------- list of point The 8 corners of the bounding box of the mesh. Examples -------- >>> from compas.datastructures import Mesh >>> mesh = Mesh.from_obj(compas.get('faces.obj')) >>> mesh_bounding_box(mesh) [[0.0, 0.0, 0.0], [10.0, 0.0, 0.0], [10.0, 10.0, 0.0], [0.0, 10.0, 0.0], [0.0, 0.0, 0.0], [10.0, 0.0, 0.0], [10.0, 10.0, 0.0], [0.0, 10.0, 0.0]] """ xyz = mesh.vertices_attributes('xyz', keys=list(mesh.vertices())) return bounding_box(xyz)
}, { 'start': origin, 'end': zaxis, 'color': (0, 0, 255), 'arrow': 'end' }] compas_rhino.draw_points(points, layer=layer, clear=False) compas_rhino.draw_lines(lines, layer=layer, clear=False) # ============================================================================== # Algorithm # ============================================================================== cloud1 = pointcloud(30, (0, 10), (0, 3), (0, 5)) bbox1 = bounding_box(cloud1) Rz = Rotation.from_axis_and_angle([0.0, 0.0, 1.0], radians(60)) Ry = Rotation.from_axis_and_angle([0.0, 1.0, 0.0], radians(20)) Rx = Rotation.from_axis_and_angle([1.0, 0.0, 0.0], radians(10)) T = Translation([2.0, 5.0, 8.0]) R = T * Rz * Ry * Rx cloud2 = transform_points(cloud1, R) bbox2 = transform_points(bbox1, R) mean, vectors, values = numerical.pca_numpy(cloud2) origin = mean
'color': (255, 0, 0) }, { 'start': origin, 'end': yaxis, 'color': (0, 255, 0) }, { 'start': origin, 'end': zaxis, 'color': (0, 0, 255) }] compas_rhino.draw_points(points, layer=layer, clear=True) compas_rhino.draw_lines(lines, layer=layer, clear=False) cloud1 = pointcloud(30, (0, 10), (0, 3), (0, 5)) bbox1 = bounding_box(cloud1) Rz = Rotation.from_axis_and_angle([ 0., 0., 1., ], radians(30)) Ry = Rotation.from_axis_and_angle([ 0., 1., 0., ], radians(20)) Rx = Rotation.from_axis_and_angle([ 1., 0., 0.,
if __name__ == '__main__': # define min/max shell thickness thickness_max = 0.4 thickness_min = 0.1 new_z_delta = thickness_max - thickness_min # select tessellation edge_crvs = rs.GetObjects("Select edges", 4) lines = get_line_coordinates(edge_crvs) mesh = Mesh.from_lines(lines, delete_boundary_face=True) # find z-max and z-min of the tessellation geomerty bb = bounding_box(mesh.get_vertices_attributes(('x', 'y', 'z'))) z_max = bb[0][2] z_min = bb[4][2] z_delta = z_max - z_min # compute offset points top (a) vertices_list = [] key_index_a = {} for i, key in enumerate(mesh.vertices()): pt = mesh.vertex_coordinates(key) normal = mesh.vertex_normal(key) thickness = (((pt[2] - z_min) * new_z_delta) / z_delta) + thickness_min vertices_list.append(add_vectors(pt, scale_vector(normal, thickness * .5))) # create key_index map top (a) key_index_a[key] = i
def set_scales(self): mesh = self.mesh box = bounding_box( [mesh.vertex_coordinates(vkey) for vkey in mesh.vertices()]) self.dx = box[2][0] - box[0][0] self.dy = box[2][1] - box[0][1]
def bounding_box(self): return bounding_box(self.points)
rhinopoints = [] for key in keys: a = shell.vertex_coordinates(key) r = shell.get_vertex_attributes(key, ['rx', 'ry', 'rz']) b = add_vectors(a, r) line = a, b x = intersection_line_plane(line, plane) points.append(x) rhinopoints.append({ 'pos' : x, 'color' : (0, 0, 255), 'name' : "{}.{}.anchor".format(shell.name, key) }) box = bounding_box(points) lines = [] for i, j in [(0, 1), (1, 5), (5, 4), (4, 0)]: a = box[i] b = box[j] d = distance_point_point(a, b) if d < 0.01: continue lines.append({ 'start' : a, 'end' : b, 'color' : (0, 255, 255), 'name' : "box" })
def test_bounding_box(coords, expected): assert expected == bounding_box(coords)
source = [Point(*xyz) for xyz in pointcloud(30, (0, 10), (0, 5), (0, 3))] R = Rotation.from_axis_and_angle(Vector.Zaxis(), radians(30)) observations = Point.transformed_collection(source, R) noise = [] for i in range(5): point = random.choice(observations) T = Translation([random.random(), random.random(), random.random()]) noise.append(point.transformed(T)) outliers = [Point(*xyz) for xyz in pointcloud(3, (10, 15), (0, 5), (0, 3))] Point.transform_collection(outliers, R) target = observations + noise + outliers A, X = icp_numpy(source, target) source_new = [Point(*point) for point in A] bbox = bounding_box(source + target + source_new) plotter = Plotter2(view=[(bbox[0][0], bbox[2][0]), (bbox[0][1], bbox[2][1])]) [plotter.add(point, facecolor=(1.0, 1.0, 1.0)) for point in source] [plotter.add(point, facecolor=(0.0, 0.0, 0.0)) for point in target] [plotter.add(point, facecolor=(1.0, 0.0, 0.0)) for point in source_new] plotter.show()
# Make a box and a sphere # ============================================================================== box = Box.from_width_height_depth(2, 2, 2) box = Mesh.from_shape(box) box.quads_to_triangles() A = box.to_vertices_and_faces() sphere = Sphere(Point(1, 1, 1), 1) sphere = Mesh.from_shape(sphere, u=30, v=30) sphere.quads_to_triangles() B = sphere.to_vertices_and_faces() bbox = bounding_box(box.vertices_attributes('xyz') + sphere.vertices_attributes('xyz')) bbox = Box.from_bounding_box(bbox) width = bbox.xsize # ============================================================================== # Remesh the sphere # ============================================================================== B = remesh(B, 0.3, 10) # ============================================================================== # Compute the boolean union # ============================================================================== V, F = boolean_union(A, B)
def start(): # -2. layer structure layers = ['shape_and_features', 'delaunay_mesh', 'initial_coarse_quad_mesh', 'edited_coarse_quad_mesh', 'quad_mesh', 'pattern_topology', 'pattern_geometry'] colours = [[255,0,0], [255, 255, 255], [0,0,0], [0,0,0], [200,200,200], [100,100,100], [0,0,0]] for layer, colour in zip(layers, colours): rs.AddLayer(layer) rs.LayerColor(layer, colour) objects = rs.ObjectsByLayer(layer) rs.DeleteObjects(objects) # -1. template coarse_quad_mesh = None if rs.GetString('use template?', defaultString = 'False', strings = ['True', 'False']) == 'True': vertices, faces = templating() coarse_quad_mesh = PseudoQuadMesh.from_vertices_and_faces(vertices, faces) if len(mesh_boundaries(coarse_quad_mesh)) == 0: coarse_quad_mesh_guid = draw_mesh(coarse_quad_mesh) rs.ObjectLayer(coarse_quad_mesh_guid, layer = 'initial_coarse_quad_mesh') rs.LayerVisible('initial_coarse_quad_mesh', visible = True) return # 0. input surface_guid = rs.GetObject('select surface', filter = 8) if surface_guid is None: box = bounding_box([coarse_quad_mesh.vertex_coordinates(vkey) for vkey in coarse_quad_mesh.vertices()]) points = box[:4] surface_guid = rs.AddSrfPt(points) rs.ObjectColor(surface_guid, [255,0,0]) surface_guid = rs.CopyObject(surface_guid) rs.ObjectLayer(surface_guid, 'shape_and_features') curve_features_guids = rs.GetObjects('select curve features', filter = 4) if curve_features_guids is None: curve_features_guids = [] rs.ObjectColor(curve_features_guids, [255,0,0]) curve_features_guids = rs.CopyObjects(curve_features_guids) rs.ObjectLayer(curve_features_guids, 'shape_and_features') point_features_guids = rs.GetObjects('select point features', filter = 1) if point_features_guids is None: point_features_guids = [] rs.ObjectColor(point_features_guids, [255,0,0]) point_features_guids = rs.CopyObjects(point_features_guids) rs.ObjectLayer(point_features_guids, 'shape_and_features') if coarse_quad_mesh is None: # 1. mapping discretisation = rs.GetReal('NURBS element discretisation', number = 1) rs.EnableRedraw(False) planar_boundary_polyline, planar_hole_polylines, planar_polyline_features, planar_point_features = mapping(discretisation, surface_guid, curve_features_guids = curve_features_guids, point_features_guids = point_features_guids) # 2. triangulation delaunay_mesh = triangulation(planar_boundary_polyline, holes = planar_hole_polylines, polyline_features = planar_polyline_features, point_features = planar_point_features) delaunay_mesh_remapped = delaunay_mesh.copy() remapping(delaunay_mesh_remapped, surface_guid) delaunay_mesh_guid = draw_mesh(delaunay_mesh_remapped) rs.ObjectLayer(delaunay_mesh_guid, layer = 'delaunay_mesh') rs.LayerVisible('delaunay_mesh', visible = True) # 3. decomposition medial_branches, boundary_polylines = decomposition(delaunay_mesh) # 4. extraction vertices, faces, edges_to_polyline = extraction(boundary_polylines, medial_branches) patch_decomposition = PseudoQuadMesh.from_vertices_and_faces(vertices, faces) # 5. conforming coarse_quad_mesh = conforming(patch_decomposition, delaunay_mesh, medial_branches, boundary_polylines, edges_to_polyline, planar_point_features, planar_polyline_features) # 6. remapping remapping(coarse_quad_mesh, surface_guid) rs.LayerVisible('delaunay_mesh', visible = False) coarse_quad_mesh_guid = draw_mesh(coarse_quad_mesh) rs.ObjectLayer(coarse_quad_mesh_guid, layer = 'initial_coarse_quad_mesh') rs.LayerVisible('initial_coarse_quad_mesh', visible = True) # 7. editing rs.EnableRedraw(False) rs.LayerVisible('initial_coarse_quad_mesh', visible = False) editing(coarse_quad_mesh) rs.EnableRedraw(True) thickening = rs.GetString('thicken?', defaultString = 'False', strings = ['True', 'False']) if thickening == 'True': thickness = rs.GetReal(message = 'thickness', number = 1, minimum = .0001, maximum = 1000) coarse_quad_mesh = mesh_thickening(coarse_quad_mesh, thickness = thickness) #closed_mesh_guid = draw_mesh(closed_mesh.to_mesh()) #rs.ObjectLayer(closed_mesh_guid, layer = 'edited_coarse_quad_mesh') #rs.LayerVisible('edited_coarse_quad_mesh', visible = True) #return coarse_quad_mesh_guid = draw_mesh(coarse_quad_mesh.to_mesh()) rs.ObjectLayer(coarse_quad_mesh_guid, layer = 'edited_coarse_quad_mesh') rs.LayerVisible('edited_coarse_quad_mesh', visible = True) # 8. densification rs.EnableRedraw(True) target_length = rs.GetReal('target length for densification', number = 1) quad_mesh = densification(coarse_quad_mesh, target_length) quad_mesh = quad_mesh.to_mesh() quad_mesh_guid = draw_mesh(quad_mesh) rs.ObjectLayer(quad_mesh_guid, layer = 'quad_mesh') rs.LayerVisible('edited_coarse_quad_mesh', visible = False) rs.LayerVisible('quad_mesh', visible = True) # 9. patterning rs.EnableRedraw(True) operators = ['dual', 'join', 'ambo', 'kis', 'needle', 'gyro'] patterning_operator = rs.GetString('patterning operator', strings = operators) rs.EnableRedraw(False) pattern_topology = patterning(quad_mesh, patterning_operator) pattern_topology_guid = draw_mesh(pattern_topology) rs.ObjectLayer(pattern_topology_guid, layer = 'pattern_topology') rs.LayerVisible('quad_mesh', visible = False) rs.LayerVisible('pattern_topology', visible = True) # 10. smoothing pattern_geometry = pattern_topology.copy() pattern_geometry.cull_vertices() rs.EnableRedraw(True) smoothing_iterations = rs.GetInteger('number of iterations for smoothing', number = 20) if smoothing_iterations == 0: pattern_geometry_guid = draw_mesh(pattern_geometry) rs.ObjectLayer(pattern_geometry_guid, layer = 'pattern_geometry') rs.LayerVisible('pattern_topology', visible = False) rs.LayerVisible('pattern_geometry', visible = True) return damping_value = rs.GetReal('damping value for smoothing', number = .5) rs.EnableRedraw(False) constraints, surface_boundaries = define_constraints(pattern_geometry, surface_guid, curve_constraints = curve_features_guids, point_constraints = point_features_guids) fixed_vertices = [vkey for vkey, constraint in constraints.items() if constraint[0] == 'point'] mesh_smooth_area(pattern_geometry, fixed = fixed_vertices, kmax = smoothing_iterations, damping = damping_value, callback = apply_constraints, callback_args = [pattern_geometry, constraints]) #vertex_keys = pattern_geometry.vertices() #vertices = [pattern_geometry.vertex_coordinates(vkey) for vkey in vertex_keys] #adjacency = [[vertex_keys.index(nbr) for nbr in pattern_geometry.vertex_neighbours(vkey)] for vkey in vertex_keys] #smooth_centroid_cpp(vertices, adjacency, fixed_vertices, kmax = smoothing_iterations, callback = apply_constraints, callback_args = [pattern_geometry, constraints]) rs.DeleteObjects(surface_boundaries) pattern_geometry_guid = draw_mesh(pattern_geometry) rs.ObjectLayer(pattern_geometry_guid, layer = 'pattern_geometry') rs.LayerVisible('pattern_topology', visible = False) rs.LayerVisible('pattern_geometry', visible = True) print_metrics(pattern_geometry)