def __init__(self, elements=None, attributes=None, default_element_attributes=None, default_connection_attributes=None): self.network = Network() self.network.attributes.update({'name': 'Assembly'}) if attributes is not None: self.network.attributes.update(attributes) self.network.default_node_attributes.update({ 'is_planned': False, 'is_placed': False }) if default_element_attributes is not None: self.network.default_node_attributes.update( default_element_attributes) if default_connection_attributes is not None: self.network.default_edge_attributes.update( default_connection_attributes) if elements: for element in elements: self.add_element(element)
def surface_discrete_mapping(srf_guid, discretisation, minimum_discretisation = 5, crv_guids = [], pt_guids = []): """Map the boundaries of a Rhino NURBS surface to planar poylines dicretised within some discretisation using the surface UV parameterisation. Curve and point feautres on the surface can be included. Parameters ---------- srf_guid : guid A surface guid. crv_guids : list List of guids of curves on the surface. pt_guids : list List of guids of points on the surface. discretisation : float The discretisation of the surface boundaries. minimum_discretisation : int The minimum discretisation of the surface boundaries. Returns ------- tuple Tuple of the mapped objects: outer boundary, inner boundaries, polyline_features, point_features. """ srf = RhinoSurface.from_guid(srf_guid) # a boundary may be made of multiple boundary components and therefore checking for closeness and joining are necessary mapped_borders = [] for i in [1, 2]: mapped_border = [] for border_guid in srf.borders(type = i): points = [list(srf.point_xyz_to_uv(pt)) + [0.0] for pt in rs.DivideCurve(border_guid, max(int(rs.CurveLength(border_guid) / discretisation) + 1, minimum_discretisation))] if rs.IsCurveClosed(border_guid): points.append(points[0]) mapped_border.append(points) rs.DeleteObject(border_guid) mapped_borders.append(mapped_border) outer_boundaries, inner_boundaries = [network_polylines(Network.from_lines([(u, v) for border in mapped_borders[i] for u, v in pairwise(border)])) for i in [0, 1]] # mapping of the curve features on the surface mapped_curves = [] for crv_guid in crv_guids: curve = RhinoCurve.from_guid(crv_guid) points = [list(srf.point_xyz_to_uv(pt)) + [0.0] for pt in curve.divide(max(int(curve.length() / discretisation) + 1, minimum_discretisation))] if curve.is_closed(): points.append(points[0]) mapped_curves.append(points) polyline_features = network_polylines(Network.from_lines([(u, v) for curve in mapped_curves for u, v in pairwise(curve)])) # mapping of the point features onthe surface point_features = [list(srf.point_xyz_to_uv(rs.PointCoordinates(pt_guid))) + [0.0] for pt_guid in pt_guids] return outer_boundaries[0], inner_boundaries, polyline_features, point_features
def test_astar_shortest_path(): n = Network() a = n.add_node(x=1, y=2, z=0) b = n.add_node(x=3, y=1, z=0) n.add_edge(a, b) path = astar_shortest_path(n, a, b) assert path == [a, b]
def __init__(self, layers=None, attributes=None, default_layer_attribute=None, default_connection_attributes=None): self.network = Network() self.network.attributes.update({'name': 'AMModel'}) if attributes is not None: self.network.attributes.update(attributes) self.network.default_node_attributes.update({ 'is_planned': False, 'is_placed': False }) if default_layer_attribute is not None: self.network.default_node_attributes.update( default_layer_attribute) if default_connection_attributes is not None: self.network.default_edge_attributes.update( default_connection_attributes) if layers: for layer in layers: self.add_layer(layer)
def __init__(self, nodes=None, attributes=None, edges=None): self.network = Network() self.network.attributes.update({'name': 'Layer', 'is_constructed': False}) self.is_constructed = False if attributes is not None: self.network.attributes.update(attributes) if nodes: for node in nodes: self.add_node(node) self.trajectory = None
def test_json_network(): before = Network() a = before.add_node() b = before.add_node() before.add_edge(a, b) after = compas.json_loads(compas.json_dumps(before)) assert before.dtype == after.dtype assert before.attributes == after.attributes assert all(before.has_node(node) for node in after.nodes()) assert all(after.has_node(node) for node in before.nodes()) assert all(before.has_edge(*edge) for edge in after.edges()) assert all(after.has_edge(*edge) for edge in before.edges())
def dr_numpy_xfunc(network): from compas.datastructures import Network network = Network.from_data(network) vertices = network.get_vertices_attributes(('x', 'y', 'z')) edges = list(network.edges()) fixed = network.vertices_where({'is_fixed': True}) loads = network.get_vertices_attributes(('px', 'py', 'pz')) qpre = network.get_edges_attribute('qpre') fpre = network.get_edges_attribute('fpre') lpre = network.get_edges_attribute('lpre') linit = network.get_edges_attribute('linit') E = network.get_edges_attribute('E') radius = network.get_edges_attribute('radius') x, q, f, l, r = dr_numpy(vertices, edges, fixed, loads, qpre, fpre, lpre, linit, E, radius) for key, attr in network.vertices(True): attr['x'] = x[key, 0] attr['y'] = x[key, 1] attr['z'] = x[key, 2] attr['rx'] = r[key, 0] attr['ry'] = r[key, 1] attr['rz'] = r[key, 2] for index, (u, v, attr) in enumerate(network.edges(True)): attr['q'] = f[index, 0] attr['f'] = f[index, 0] attr['l'] = l[index, 0] return network.to_data()
def from_lines(cls, lines, delete_boundary_face=False, precision=None): """Construct a mesh object from a list of lines described by start and end point coordinates. Parameters ---------- lines : list A list of pairs of point coordinates. delete_boundary_face : bool, optional The algorithm that finds the faces formed by the connected lines first finds the face *on the outside*. In most cases this face is not expected to be there. Therefore, there is the option to have it automatically deleted. precision: str, optional The precision of the geometric map that is used to connect the lines. Returns ------- Mesh A mesh object. Examples -------- >>> """ from compas.datastructures import Network from compas.datastructures import network_find_cycles network = Network.from_lines(lines, precision=precision) vertices = network.to_points() faces = network_find_cycles(network) mesh = cls.from_vertices_and_faces(vertices, faces) if delete_boundary_face: mesh.delete_face(0) mesh.cull_vertices() return mesh
def kagome_polyedge_colouring(kagome): polyedges = kagome.polyedge_data edge_to_polyedge_index = {vkey: {} for vkey in kagome.vertices()} for i, polyedge in enumerate(polyedges): for u, v in pairwise(polyedge): edge_to_polyedge_index[u][v] = i edge_to_polyedge_index[v][u] = i vertices = [ centroid_points([kagome.vertex_coordinates(vkey) for vkey in polyedge]) for polyedge in polyedges ] edges = [] for idx, polyedge in enumerate(polyedges): for vkey in polyedge: for vkey_2 in kagome.vertex_neighbors(vkey): idx_2 = edge_to_polyedge_index[vkey][vkey_2] if idx_2 != idx and idx < idx_2 and (idx, idx_2) not in edges: edges.append((idx, idx_2)) polyedge_network = Network.from_nodes_and_edges(vertices, edges) key_to_colour = vertex_coloring(polyedge_network.adjacency) return [key_to_colour[key] for key in sorted(key_to_colour.keys())]
def from_lines(cls, lines, delete_boundary_face=True, precision=None): """Construct a FormDiagram from a list of lines described by start and end point coordinates. Parameters ---------- lines : list A list of pairs of point coordinates. precision: str, optional The precision of the geometric map that is used to connect the lines. Returns ------- FormDiagram A Formdiagram object. Examples -------- .. code-block:: python from compas_tna.diagrams import FormDiagram form = FormDiagram.from_lines(lines) """ from compas.topology import network_find_faces from compas.datastructures import Network network = Network.from_lines(lines, precision=precision) mesh = cls() for key, attr in network.vertices(True): mesh.add_vertex(key, x=attr['x'], y=attr['y'], z=0.0) mesh.halfedge = network.halfedge network_find_faces(mesh) if delete_boundary_face: mesh.delete_face(0) return mesh
def create_networks(): networks = {} descendent_tree = {} for u in joints: global_local = {} lines = [] nbrs = network_global.neighbors(u) start_pt = network_global.node_coordinates(u) for v in nbrs: end_pt = network_global.edge_point(u, v, t=joint_length) lines.append([start_pt, end_pt]) network_local = Network.from_lines(lines) key_local = list( set(list(network_local.nodes())) - set(network_local.leaves()))[0] global_local.update({u: key_local}) gkeys_global_network = [geometric_key(line[1]) for line in lines] gkeys_local_network = [ geometric_key(network_local.node_coordinates(key)) for key in network_local.leaves() ] for i, key_global in enumerate(nbrs): gkey_global = gkeys_global_network[i] index_local = gkeys_local_network.index(gkey_global) key_local = network_local.leaves()[index_local] global_local.update({key_global: key_local}) descendent_tree.update({u: global_local}) networks.update({u: network_local}) return networks, descendent_tree
def test_gen_grasp_planes(points_library, test_file_name, save_dir): b_struct_data, o_struct_data, _ = parse_saved_structure_data( os.path.join(save_dir, test_file_name)) o_struct = Network.from_data(o_struct_data) b_struct = Network.from_data(b_struct_data) o_struct.struct_bar = b_struct offset_d1, offset_d2 = 5, 5 nb_rot, nb_trans = 4, 4 seq = [v for v in b_struct.vertex] for v in b_struct.vertex: calculate_gripping_plane(b_struct, v, b_struct.vertex[v]["mean_point"], nb_rot=nb_rot, nb_trans=nb_trans) calculate_offset(o_struct, b_struct, v, offset_d1, offset_d2, seq)
def gh_from_rhino_lines(mesh, max): from compas.datastructures import Network from compas.datastructures import network_find_cycles network = Network.from_lines(lines, precision=precision) vertices = network.to_points() faces = [face_vertices for face_vertices in network_find_cycles(network) if len(face_vertices) <=4] mesh = CoarsePseudoQuadMesh.from_vertices_and_faces(vertices, faces) if delete_boundary_face: mesh.delete_face(0) mesh.cull_vertices() return mesh
def get_initial_mesh(precision): crvs = rs.GetObjects("Select boundary curves", 4, group=True, preselect=False, select=False, objects=None, minimum_count=3, maximum_count=0) lines = get_line_coordinates(crvs) geo_lines = [(geometric_key(pt_u, precision), geometric_key(pt_v, precision)) for pt_u, pt_v in lines] network = Network.from_lines(lines, precision) if network.leaves(): return None adjacency = { key: network.vertex_neighbors(key) for key in network.vertices() } root = network.get_any_vertex() ordering, predecessors, paths = depth_first_tree(adjacency, root) if len(ordering) != network.number_of_vertices(): return None mesh = Mesh.from_lines(lines, delete_boundary_face=True, precision=precision) for u, v, attr in mesh.edges(True): pt_u, pt_v = mesh.edge_coordinates(u, v) geo_u, geo_v = geometric_key(pt_u, precision), geometric_key( pt_v, precision) for i, geo_l_uv in enumerate(geo_lines): geo_l_u, geo_l_v = geo_l_uv[0], geo_l_uv[1] if (geo_l_u == geo_u) and (geo_l_v == geo_v): attr['dir'] = True elif (geo_l_u == geo_v) and (geo_l_v == geo_u): attr['dir'] = False else: continue attr['guid'] = str(crvs[i]) attr['length'] = rs.CurveLength(crvs[i]) # initiate flag for corners for fkey, attr in mesh.faces(True): mesh.set_face_attribute(fkey, 'corner', 0) mesh.set_face_attribute(fkey, 'opening', 0) return mesh
def data(self, data): for _vkey, vdata in data['data']['node'].items(): vdata['node'] = Node.from_data(vdata['node']) if 'is_constructed' in data: self.is_constructed = _deserialize_from_data(data['data']['attributes']['is_constructed']) if 'trajectory' in data: self.trajectory = _deserialize_from_data(data['data']['attributes']['trajectory']) if 'path' in data: self.path = [Frame.from_data(d) for d in data['data']['attributes']['path']] self.network = Network.from_data(data)
def from_lines(cls, lines, delete_boundary_face=True, precision=None, **kwargs): """Construct a FormDiagram from a list of lines described by start and end point coordinates. Parameters ---------- lines : list A list of pairs of point coordinates. delete_boundary_face : bool, optional Set ``True`` to delete the face on the outside of the boundary, ``False`` to keep it. Default is ``True``. precision: str, optional The precision of the geometric map that is used to connect the lines. If not specified, the global precision stored in ``compas.PRECISION`` will be used. Returns ------- FormDiagram A FormDiagram object. Examples -------- .. code-block:: python import compas from compas.files import OBJ from compas_tna.diagrams import FormDiagram obj = OBJ(compas.get('lines.obj')) vertices = obj.parser.vertices edges = obj.parser.lines lines = [(vertices[u], vertices[v]) for u, v in edges] form = FormDiagram.from_lines(lines) """ from compas.datastructures import network_find_faces from compas.datastructures import Network network = Network.from_lines(lines, precision=precision) mesh = cls() for key, attr in network.vertices(True): mesh.add_vertex(key, x=attr['x'], y=attr['y'], z=0.0) mesh.halfedge = network.halfedge network_find_faces(mesh) if delete_boundary_face: mesh.delete_face(0) if 'name' in kwargs: mesh.name = kwargs['name'] return mesh
def test_astar_shortest_path_disconnected(): n = Network() a = n.add_node(x=1, y=0, z=0) b = n.add_node(x=2, y=0, z=0) c = n.add_node(x=3, y=0, z=0) n.add_edge(a, b) path = astar_shortest_path(n, a, c) assert path is None
def network_from_bmesh(bmesh): """ Create a Network datastructure from a Blender mesh. Parameters: bmesh (obj): Blender mesh object. Returns: obj: Network object. """ blendermesh = BlenderMesh(bmesh) vertices = blendermesh.get_vertex_coordinates() edges = blendermesh.get_edge_vertex_indices() network = Network.from_vertices_and_edges(vertices=vertices, edges=edges) return network
def from_lines(cls, lines, delete_boundary_face=True, precision=None, **kwargs): """Construct a FormDiagram from a list of lines described by start and end point coordinates. Parameters ---------- lines : list A list of pairs of point coordinates. delete_boundary_face : bool, optional Set ``True`` to delete the face on the outside of the boundary, ``False`` to keep it. Default is ``True``. precision: str, optional The precision of the geometric map that is used to connect the lines. If not specified, the global precision stored in ``compas.PRECISION`` will be used. Returns ------- FormDiagram A FormDiagram object. Examples -------- >>> import compas >>> from compas.files import OBJ >>> from compas_tna.diagrams import FormDiagram >>> obj = OBJ(compas.get('lines.obj')) >>> vertices = obj.parser.vertices >>> edges = obj.parser.lines >>> lines = [(vertices[u], vertices[v]) for u, v in edges] >>> form = FormDiagram.from_lines(lines) """ network = Network.from_lines(lines, precision=precision) points = network.to_points() cycles = network_find_cycles(network, breakpoints=network.leaves()) form = cls.from_vertices_and_faces(points, cycles) if delete_boundary_face: form.delete_face(0) if 'name' in kwargs: form.name = kwargs['name'] return form
def from_lines(cls, lines, boundary_face=False, precision='3f'): """""" from compas.datastructures import network_find_faces # from compas.datastructures import FaceNetwork from compas.datastructures import Network # network = FaceNetwork.from_lines(lines) network = Network.from_lines(lines) network_find_faces(network, breakpoints=network.leaves()) key_index = network.key_index() vertices = [network.vertex_coordinates(key) for key in network.vertices()] faces = [[key_index[key] for key in network.face_vertices(fkey)] for fkey in network.faces()] mesh = cls.from_vertices_and_faces(vertices, faces) if not boundary_face: mesh.delete_face(0) return mesh
def network_from_lines(guids=[], layer=None): """ Creates a Network datastructure object from a list of curve guids. Parameters ---------- guids : list guids of the Rhino curves to be made into a Network. layer : str Layer to grab line guids from. Returns ------- obj Network datastructure object. """ if layer: guids = rs.ObjectsByLayer(layer) lines = [[rs.CurveStartPoint(guid), rs.CurveEndPoint(guid)] for guid in guids] return Network.from_lines(lines)
from compas.datastructures import Network from compas.numerical import drx_numpy from compas_plotters import NetworkPlotter L = 2.5 n = 100 EI = 0.2 vertices = [[i, 1 - abs(i), 0] for i in list(linspace(-1, 1, n))] for i in range(n): if vertices[i][1] < 0.5: vertices[i][0] = sign(vertices[i][0]) * vertices[i][1] edges = [[i, i + 1] for i in range(n - 1)] structure = Network.from_vertices_and_edges(vertices=vertices, edges=edges) structure.update_default_vertex_attributes({ 'is_fixed': False, 'EIx': EI, 'EIy': EI }) structure.update_default_edge_attributes({'E': 50, 'A': 1, 'l0': L / n}) structure.get_vertices_attributes(['B', 'is_fixed'], [[0, 0, 0], True], structure.leaves()) structure.attributes['beams'] = {'beam': {'nodes': list(range(n))}} lines = [] for u, v in structure.edges(): lines.append({ 'start': structure.vertex_coordinates(u, 'xy'), 'end': structure.vertex_coordinates(v, 'xy'),
# self.draw_edges( # color={(u, v): '#ff0000' for u, v in edges}, # width={(u, v): 5.0 for u, v in edges} # ) # ============================================================================== # Main # ============================================================================== if __name__ == "__main__": import compas from compas.datastructures import Network network = Network.from_obj(compas.get('grid_irregular.obj')) plotter = NetworkPlotter(network, figsize=(10, 8)) plotter.draw_nodes(radius=0.1, picker=10) plotter.draw_edges() default = [plotter.defaults['node.facecolor'] for key in network.nodes()] highlight = '#ff0000' def on_pick(event): index = event.ind[0] colors = default[:] colors[index] = highlight
from itertools import combinations from compas.datastructures import Network from compas.utilities import linspace, meshgrid from compas_rhino.artists import NetworkArtist X, Y = meshgrid(linspace(0, 10, 10), linspace(0, 5, 5)) points = [] for z in linspace(0, 3, 3): for xs, ys in zip(X, Y): for x, y in zip(xs, ys): points.append([x, y, z]) network = Network() for point in points: network.add_node(x=point[0], y=point[1], z=point[2]) for a, b in combinations(network.nodes(), 2): if network.node_attribute(a, 'z') != network.node_attribute(b, 'z'): network.add_edge(a, b) artist = NetworkArtist(network, layer="ITA20::Network") artist.clear_layer() artist.draw_nodes() artist.draw_edges()
def get_initial_mesh(precision): crvs = rs.GetObjects("Select boundary curves", 4, group=True, preselect=False, select=False, objects=None, minimum_count=3, maximum_count=0) lines = get_line_coordinates(crvs) geo_lines = [(geometric_key(pt_u, precision), geometric_key(pt_v, precision)) for pt_u, pt_v in lines] network = Network.from_lines(lines, precision) if network.leaves(): return None adjacency = { key: network.vertex_neighbours(key) for key in network.vertices() } root = network.get_any_vertex() ordering, predecessors, paths = depth_first_tree(adjacency, root) if len(ordering) != network.number_of_vertices(): return None mesh = Mesh.from_lines(lines, delete_boundary_face=True, precision=precision) rs.EnableRedraw(False) dots = {} for fkey in mesh.faces(): cent = mesh.face_centroid(fkey) dot = rs.AddTextDot('', cent) rs.TextDotHeight(dot, 6) dots[str(dot)] = fkey rs.EnableRedraw(True) if not dots: return None dot_ids = dots.keys() data = rs.GetObjectsEx(message="Select face for openings", filter=0, preselect=False, select=False, objects=dot_ids) rs.DeleteObjects(dot_ids) if data: for datum in data: dot = datum[0] fkey = dots[str(dot)] mesh.delete_face(fkey) geo_edges = [] for u, v, attr in mesh.edges(True): pt_u, pt_v = mesh.edge_coordinates(u, v) geo_u, geo_v = geometric_key(pt_u, precision), geometric_key( pt_v, precision) for i, geo_l_uv in enumerate(geo_lines): geo_l_u, geo_l_v = geo_l_uv[0], geo_l_uv[1] if (geo_l_u == geo_u) and (geo_l_v == geo_v): attr['dir'] = True elif (geo_l_u == geo_v) and (geo_l_v == geo_u): attr['dir'] = False else: continue attr['guid'] = str(crvs[i]) attr['length'] = rs.CurveLength(crvs[i]) # initiate flag for corners for fkey, attr in mesh.faces(True): mesh.set_face_attribute(fkey, 'corner', 0) return mesh, crvs
vertices = list(set(flatten(faces))) i_index = {i: index for index, i in enumerate(vertices)} vertices = [points[index] for index in vertices] faces = [[i_index[i] for i in face] for face in faces] faces = unify_cycles(vertices, faces) mesh = Mesh.from_vertices_and_faces(vertices, faces) return mesh guids = compas_rhino.select_lines() lines = compas_rhino.get_line_coordinates(guids) network = Network.from_lines(lines) leafs = [] joints = [] for key in network.node: if network.is_leaf(key): leafs.append(key) else: joints.append(key) pt_center = network.node_coordinates(joints[0]) pts = [network.node_coordinates(key) for key in leafs] joint_width = 15 leaf_width = 7 convex_hull_mesh = get_convex_hull_mesh(pts)
import os from compas.datastructures import Network from compas.utilities import i_to_rgb from compas_rhino.artists import NetworkArtist HERE = os.path.dirname(__file__) FILE = os.path.join(HERE, 'clusters.json') network = Network.from_json(FILE) artist = NetworkArtist(network, layer="ITA20::Network") artist.clear_layer() nodecolor = { node: i_to_rgb(network.node_attribute(node, 'cluster') / 9) for node in network.nodes() } edgecolor = { edge: i_to_rgb(network.node_attribute(edge[0], 'cluster') / 9) for edge in network.edges() } artist.draw_nodes(color=nodecolor) artist.draw_edges(color=edgecolor)
tol = 0.01 du = 0.02 deg = pi / 180 dr = 15 * deg # Target curve = get_objects(layer=1)[0] blendercurve = BlenderCurve(object=curve) Xt = array(blendercurve.divide(number_of_segments=mi)) # Network vertices = [list(Xi) for Xi in list(Xt[:mi:div, :])] edges = [[i, i + 1] for i in range(m)] network = Network.from_vertices_and_edges(vertices=vertices, edges=edges) network.update_default_vertex_attributes({'EIx': E*I, 'EIy': E*I}) network.update_default_edge_attributes({'E': E, 'A': A, 'l0': ds}) network.set_vertices_attributes([0, 1, m - 1, m], {'B': [0, 0, 0]}) network.beams = {'beam': {'nodes': list(range(network.number_of_vertices()))}} # Manual #dofs = 0, 0, 45 * deg, 0.6, 0, 155 * deg #Xs = update(dofs=dofs, network=network, tol=tol, plot=True, Xt=Xt, ds=ds) # Optimise generations = 30 xa, za = Xt[+0, [0, 2]]
def __init__(self, data, dtype='f'): m = len(data) rows = range(m) super(SparseDiagonal, self).__init__((rows, rows, data), (m, m), dtype) # ============================================================================== # Main # ============================================================================== if __name__ == "__main__": import compas from compas.datastructures import Network network = Network.from_obj(compas.get('lines.obj')) e = network.number_of_edges() v = network.number_of_vertices() vertices = network.vertices_attributes('xyz') edges = list(network.edges()) xyz = Array(vertices, (v, 3)) shape = e, v rows, cols, data = [], [], [] for i, (u, v) in enumerate(edges): rows.append(i)
# define a callback function # for plotting the intermediate configurations of the DR process def callback(k, xyz, crits, args): print(k) plotter.update_vertices() plotter.update_edges() plotter.update(pause=0.001) for key, attr in network.vertices(True): attr['x'] = xyz[key][0] attr['y'] = xyz[key][1] attr['z'] = xyz[key][2] # make a network network = Network.from_obj(FILE) # identify the fixed vertices network.set_vertices_attribute('is_fixed', True, keys=network.vertices_where( {'vertex_degree': 1})) # assign random prescribed force densities to the edges for uv in network.edges(): network.set_edge_attribute(uv, 'qpre', 1.0 * random.randint(1, 7)) # make a plotter for (dynamic) visualization plotter = NetworkPlotter(network, figsize=(10, 7)) # plot the starting configuration