Пример #1
0
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
Пример #2
0
    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
Пример #3
0
    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
Пример #4
0
    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
Пример #5
0
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
Пример #6
0
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
Пример #7
0
    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
Пример #8
0
    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
Пример #9
0
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)
Пример #10
0
    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
Пример #11
0
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
Пример #12
0
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
Пример #13
0
    def from_skeleton_lines(cls, lines=[]):
        skeleton_vol = cls()

        network = Network.from_lines(lines)
        convex_hull_mesh = get_convex_hull_mesh(points)
Пример #14
0
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()
Пример #15
0
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)
Пример #16
0
    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)
Пример #17
0
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
Пример #18
0
            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)