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 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 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 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 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 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 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 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 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)
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 create_sk3_quad(lines, joint_width=1, leaf_width=1, joint_length=0.4): def get_convex_hull_mesh(points): faces = convex_hull(points) 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 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 create_sk3_branch(u, v): def find_vertices(u, v): sk3_joint_u = sk3_joints[u] # inside of network_u, find vertices on the verge leaf_u = descendent_tree[u][ v] # this is network local key, not convexhull mesh leaf_u = sk3_joint_u.network_convexhull[leaf_u] nbrs = sk3_joint_u.convexhull_mesh.vertex_neighbors(leaf_u, ordered=True) keys = [ sk3_joint_u.descendent_tree[leaf_u][nbr]['lp'] for nbr in nbrs ] points = [sk3_joint_u.vertex_coordinates(key) for key in keys] return points if u in joints and v in joints: # its an internal edge points_u = find_vertices(u, v) points_v = find_vertices(v, u) if len(points_u) != len(points_v): mesh = get_convex_hull_mesh(points_u + points_v) else: points_v = points_v[::-1] index = closest_point_in_cloud(points_u[0], points_v)[2] points_v = points_v[index:] + points_v[:index] vertices = points_u + points_v faces = [] n = len(points_u) for i in range(n): faces.append([i, (i + 1) % n, (i + 1) % n + n, i + n]) mesh = Mesh.from_vertices_and_faces(vertices, faces) else: if u in leafs: leaf, joint = u, v elif v in leafs: leaf, joint = v, u points_joint = find_vertices(joint, leaf) network = networks[joint] u_local = descendent_tree[joint][joint] v_local = descendent_tree[joint][leaf] vec = [ i * (1 - joint_length) for i in network_global.edge_vector(joint, leaf) ] points_leaf = [add_vectors(pt, vec) for pt in points_joint] vertices = points_joint + points_leaf faces = [] n = len(points_joint) for i in range(n): faces.append([i, (i + 1) % n, (i + 1) % n + n, i + n]) mesh = Mesh.from_vertices_and_faces(vertices, faces) return mesh def create_sk3_branches(): return [create_sk3_branch(u, v) for u, v in network_global.edges()] def create_sk3_joints(networks): sk3_joints = {} for u in networks: network = networks[u] sk3_joint = Skeleton3D_Node.from_network(network) sk3_joint.joint_width = joint_width sk3_joint.leaf_width = leaf_width sk3_joint.update_vertices_location() sk3_joints.update({u: sk3_joint}) return sk3_joints def draw_mesh_faces(mesh): fkeys_nodraw = [ fkey for fkey in mesh.faces() if mesh.face_area(fkey) <= 0 ] fkeys = list(set(list(mesh.faces())) - set(fkeys_nodraw)) artist = MeshArtist(mesh) artist.layer = '3GS::Skeleton' artist.draw_faces(faces=fkeys, join_faces=True) network_global = Network.from_lines(lines) joints = [] leafs = [] for key in network_global.node: if network_global.is_leaf(key): leafs.append(key) else: joints.append(key) networks, descendent_tree = create_networks() sk3_joints = create_sk3_joints(networks) sk3_branches = create_sk3_branches() mesh = meshes_join(sk3_joints.values() + sk3_branches) draw_mesh_faces(mesh) return mesh
from compas.visualization import NetworkPlotter # make a network from a sample file with open('data.json', 'r') as f: lines = json.load(f) pointList = [] for k, v in lines.items(): subList = [] subList.append(v["pt0"]) subList.append(v["pt1"]) pointList.append(subList) network = Network.from_lines(pointList) adjacency = {key: network.vertex_neighbours(key) for key in network.vertices()} weight = {(u, v): network.edge_length(u, v) for u, v in network.edges()} weight.update({(v, u): weight[(u, v)] for u, v in network.edges()}) # gkey_key = {geometric_key(network.vertex_coordinates(key),'3f'): key for key in network.ver} # make a few edges heavier # for example to simulate traffic problems # heavy = [(7, 17), (9, 19)] # for u, v in heavy: # weight[(u, v)] = 1000.0
def from_skeleton_lines(cls, lines=[]): skeleton_vol = cls() network = Network.from_lines(lines) convex_hull_mesh = get_convex_hull_mesh(points)
class SkeletonVol(Mesh): """ SkeletonVol is typologically constructed low poly mesh. It construct a branch like volumetric mesh from input lines. """ def __init__(self): super(SkeletonVol, self).__init__() @classmethod def from_skeleton_lines(cls, lines=[]): skeleton_vol = cls() network = Network.from_lines(lines) convex_hull_mesh = get_convex_hull_mesh(points) def get_convex_hull_mesh(points): faces = convex_hull(points) 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] convex_hull_mesh = get_convex_hull_mesh(pts) mesh = Mesh() # for key in convex_hull_mesh.vertices(): # mesh.add_vertex(key) # mesh.vertex[key].update(convex_hull_mesh.vertex[key]) descdent_tree = copy.deepcopy(convex_hull_mesh.halfedge) for u, v in convex_hull_mesh.edges(): descdent_tree[u][v] = {'jp': None, 'lp': None} descdent_tree[v][u] = {'jp': None, 'lp': None} # current_key = convex_hull_mesh.number_of_vertices() current_key = 0 for fkey in convex_hull_mesh.faces(): f_centroid = convex_hull_mesh.face_centroid(fkey) vec = Vector.from_start_end(pt_center, f_centroid) # if the branches has a 'convex' corner, # flip the vec to the corresponding face. f_normal = convex_hull_mesh.face_normal(fkey) angle = angle_vectors(f_normal, vec, False) if angle > math.pi * 0.5: pln = Plane(pt_center, f_normal) pt_mirror = mirror_point_plane(f_centroid, pln) vec = Vector.from_start_end(pt_center, pt_mirror) vec.unitize() vec.scale(joint_width) pt = add_vectors(pt_center, vec) face = convex_hull_mesh.face[fkey] v_keys = face + [face[0]] for u, v in pairwise(v_keys): descdent_tree[u][v].update({'jp': current_key}) mesh.add_vertex(current_key) mesh.vertex[current_key].update({'x': pt[0], 'y': pt[1], 'z': pt[2]}) current_key += 1 for key in convex_hull_mesh.vertices(): nbrs = convex_hull_mesh.vertex_neighbors(key) for nbr in nbrs: halfedge = (key, nbr) pt_joint_descendent = mesh.vertex_coordinates( descdent_tree[key][nbr]['jp']) vec_edge = Vector.from_start_end( pt_center, convex_hull_mesh.vertex_coordinates(key)) pln_end = Plane(convex_hull_mesh.vertex_coordinates(key), vec_edge) pt = project_point_plane(pt_joint_descendent, pln_end) vec_leaf = Vector.from_start_end( convex_hull_mesh.vertex_coordinates(key), pt) vec_leaf.unitize() vec_leaf.scale(leaf_width) pt = add_vectors(convex_hull_mesh.vertex_coordinates(key), vec_leaf) descdent_tree[key][nbr].update({'lp': current_key}) mesh.add_vertex(current_key) mesh.vertex[current_key].update({ 'x': pt[0], 'y': pt[1], 'z': pt[2] }) current_key += 1 for key in convex_hull_mesh.vertices(): nbrs = convex_hull_mesh.vertex_neighbors(key, ordered=True) v_keys = nbrs + [nbrs[0]] for a, b in pairwise(v_keys): face = [ descdent_tree[key][a]['lp'], descdent_tree[key][a]['jp'], descdent_tree[key][b]['jp'], descdent_tree[key][b]['lp'] ] mesh.add_face(face) fixed = list(mesh.vertices_where({'vertex_degree': 3})) fixed = list(mesh.vertices()) mesh = mesh_subdivide_catmullclark(mesh, k=1, fixed=fixed) # mesh = mesh_subdivide_quad(mesh, k=1) mesh_smooth_centroid(mesh, fixed=fixed) artist = MeshArtist(mesh) artist.draw_mesh()
def trimesh_skeleton(cls, lines, radius=1): network = Network.from_lines(lines) tube_extremities = {} nodes = [] for vkey in network.nodes(): if len(network.adjacency[vkey]) > 1: points = { nbr: network.edge_point(vkey, nbr, t=float(radius) / network.edge_length(vkey, nbr)) for nbr in network.adjacency[vkey] } idx_to_key = { i: key for i, key in enumerate(network.adjacency[vkey]) } faces = convex_hull(list(points.values())) faces = [[idx_to_key[idx] for idx in face] for face in faces] mesh = cls.from_vertices_and_faces(points, faces) nodes.append(mesh) meshes = [] for fkey in mesh.faces(): vertices = [ mesh.edge_midpoint(u, v) for u, v in mesh.face_halfedges(fkey) ] faces = [[0, 1, 2]] meshes.append(cls.from_vertices_and_faces(vertices, faces)) for vkey_2 in mesh.vertices(): tops = [] bottoms = [] n = normalize_vector( subtract_vectors(mesh.vertex_coordinates(vkey_2), network.node_coordinates(vkey))) for i in range(len(mesh.vertex_neighbors(vkey_2))): pt_0 = mesh.edge_midpoint( vkey_2, mesh.vertex_neighbors(vkey_2, ordered=True)[i - 1]) bottoms.append(pt_0) pt_1 = mesh.edge_midpoint( vkey_2, mesh.vertex_neighbors(vkey_2, ordered=True)[i]) pt_2 = midpoint_line([pt_0, pt_1]) pt_2 = add_vectors( scale_vector(n, distance_point_point(pt_0, pt_1)), pt_2) tops.append(pt_2) vertices = [pt_0, pt_2, pt_1] faces = [[0, 1, 2]] meshes.append(cls.from_vertices_and_faces(vertices, faces)) for i in range(len(tops)): vertices = [tops[i - 1], tops[i], bottoms[i]] faces = [[0, 1, 2]] meshes.append(cls.from_vertices_and_faces(vertices, faces)) tube_extremities[(vkey, vkey_2)] = tops mesh = meshes_join_and_weld(meshes) nodes.append(mesh) all_nodes = meshes_join_and_weld(nodes) # leaf node ring for u in network.nodes(): if len(network.adjacency[u]) == 1: v = next(iter(network.adjacency[u].keys())) ring_v = tube_extremities[(v, u)] ring_u = [ add_vectors(pt, network.edge_vector(v, u)) for pt in ring_v[::-1] ] tube_extremities[(u, v)] = ring_u beams = [] for u, v in network.edges(): geom_key_map = { geometric_key(all_nodes.vertex_coordinates(vkey)): vkey for vkey in all_nodes.vertices() } if len(tube_extremities[(u, v)]) != len(tube_extremities[(v, u)]): if len(tube_extremities[(u, v)]) < len(tube_extremities[(v, u)]): a, b = u, v else: a, b = v, u n = len(tube_extremities[(b, a)]) - len(tube_extremities[(a, b)]) for i in range(n): bdry_vkey = geom_key_map[geometric_key( tube_extremities[(a, b)][0])] nbr_vkey = None for nbr in all_nodes.vertex_neighbors(bdry_vkey): if not all_nodes.is_edge_on_boundary(bdry_vkey, nbr): nbr_vkey = nbr k = tube_extremities[(a, b)].index( all_nodes.vertex_coordinates(bdry_vkey)) new_vkey = insert_triface_on_boundary(all_nodes, bdry_vkey, nbr_vkey) tube_extremities[(a, b)].insert( k + 1 - len(tube_extremities[(a, b)]), all_nodes.vertex_coordinates(new_vkey)) if len(tube_extremities[(u, v)]) == len(tube_extremities[(v, u)]): n = len(tube_extremities[(u, v)]) l = network.edge_length(u, v) - 2 * radius m = (floor(l / radius) + 1) * 2 pt_uv = tube_extremities[(u, v)] pt_vu = list(reversed(tube_extremities[(v, u)])) dmin = -1 imin = None for i in range(n): distance = sum([ distance_point_point(pt_uv[j], pt_vu[i + j - len(pt_vu)]) for j in range(n) ]) if dmin < 0 or distance < dmin: dmin = distance imin = i pt_vu = [pt_vu[imin + j - len(pt_vu)] for j in range(n)] # ab = pt_uv# + pt_uv[0:] # dc = pt_vu# + pt_vu[0:] # line = Polyline([ab[0], dc[0]]) # ad = [line.point(i / (m - 1)) for i in range(m)] # bc = ad # vertices, faces = discrete_coons_patch(ab, bc, dc, ad) # tri_faces = [] # for (a, b, c, d) in faces: # tri_faces += [[a, b, c], [a, c, d]] # reverse? # beams.append(Mesh.from_vertices_and_faces(vertices, tri_faces)) array = [pt_uv] for i in range(int(m)): polygon = [] for j in range(int(n)): u = pt_uv[j] v = pt_vu[j] polygon.append( add_vectors( scale_vector(u, (float(m) - 1 - float(i)) / float(m - 1)), scale_vector(v, float(i) / float(m - 1)))) array.append(polygon) array.append(pt_vu) for i in range(1, int(m + 2)): for j in range(int(n)): vertices = [ array[i - 1][j - 1], array[i - 1][j], array[i][j - 1], array[i][j] ] # create staggered pattern? faces = [[3, 1, 0], [2, 3, 0]] beams.append(cls.from_vertices_and_faces(vertices, faces)) # return all_nodes # #return meshes_join_and_weld(beams) return meshes_join_and_weld([all_nodes] + beams)
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)
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
if faces[0][0] == faces[-1][-1]: faces[:] = [faces[-1] + faces[0][1:]] + faces[1:-1] if len(faces) == 1: broken.append(faces[0]) continue for vertices in faces: broken.append(vertices) return broken # ============================================================================== # Main # ============================================================================== if __name__ == '__main__': import compas from compas.datastructures import Network network = Network.from_obj(compas.get('lines.obj')) network = Network.from_lines(network.to_lines()) network.summary() cycles = network_find_cycles(network, network.leaves()) for cycle in cycles: print(cycle)