示例#1
0
def add_handle_artist(mesh):
    """Select two mesh faces and add handle.

	Parameters
	----------
	mesh : Mesh
		The mesh.

	Returns
	-------
	fkeys
		The new face keys from the handle.

	"""

    artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
    artist.clear_layer()

    artist.draw_facelabels()
    artist.redraw()
    fkey_1 = rhino_helper.mesh_select_face(mesh, message='fkey_1')
    if fkey_1 is not None:
        fkey_2 = rhino_helper.mesh_select_face(mesh, message='fkey_2')
        if fkey_2 is not None:
            fkeys = add_handle(mesh, fkey_1, fkey_2)

        else:
            fkeys = []
    else:
        fkeys = []

    artist.clear()
    rs.DeleteLayer('mesh_artist')

    return fkeys
from compas.datastructures import Mesh

from compas_rhino.artists.meshartist import MeshArtist
from compas_rhino.helpers import mesh_select_face

if __name__ == '__main__':

    # get mesh from json
    mesh = Mesh.from_json('tessellation_mesh.json')

    # draw tessellation mesh
    artist = MeshArtist(mesh, layer='tessellation_mesh')
    artist.draw_edges()
    artist.draw_facelabels()
    artist.redraw()

    # select a face
    fkey = mesh_select_face(mesh, message='Select face.')

    artist.clear_facelabels()

    # find neighboring faces
    fkeys = list(mesh.face_neighbors(fkey)) + [fkey]
    for fkey in fkeys:
        # get voussoir meshes stored as face attribute
        data = mesh.get_face_attribute(fkey, 'voussoir')
        voussoir_mesh = Mesh.from_data(data)
        # draw neighboring voussoir mesh
        artist = MeshArtist(voussoir_mesh, layer='voussoir_meshes')
        artist.draw_faces(join_faces=True)
示例#3
0
# ------------------------------------------------------------------------------
#   1. make cell from rhino polysurfaces
# ------------------------------------------------------------------------------
layer = 'cell'

guid = rs.GetObject("select a closed polysurface", filter=rs.filter.polysurface)
rs.HideObjects(guid)

cell = mesh_from_surface(Cell, guid)
cell.draw()

# ------------------------------------------------------------------------------
#   2. Target area
# ------------------------------------------------------------------------------
fkey   = mesh_select_face(cell)

area   = cell.face_area(fkey)
center = cell.face_centroid(fkey)
normal = cell.face_normal(fkey)

target_area = rs.GetReal("Enter target area", number=area)


# ------------------------------------------------------------------------------
#   3. Arearise cell face
# ------------------------------------------------------------------------------

# conduit
conduit = MeshConduit(cell)
示例#4
0
def rhino_cell_face_pull(cell):

    # --------------------------------------------------------------------------
    #  1. pick face
    # --------------------------------------------------------------------------
    cell.draw()
    face = mesh_select_face(cell)
    cell_split_indet_face_vertices(cell, face)
    cell.clear()

    # --------------------------------------------------------------------------
    #  2. face data
    # --------------------------------------------------------------------------
    f_normal = cell.face_normal(face)
    f_center = cell.face_center(face)
    f_area = cell.face_area(face)
    f_vkeys = cell.face_vertices(face)

    # --------------------------------------------------------------------------
    #  3. get neighbor edges and vertex coordinates
    # --------------------------------------------------------------------------
    edges = {}
    for u in f_vkeys:
        u_nbrs = cell.vertex_neighbors(u)
        for v in u_nbrs:
            if v not in f_vkeys:
                edges[u] = v

    xyz_dict = {}
    for vkey in cell.vertex:
        if vkey not in f_vkeys:
            xyz_dict[vkey] = cell.vertex_coordinates(vkey)

    # --------------------------------------------------------------------------
    #  4. dynamic draw
    # --------------------------------------------------------------------------
    rs.EnableRedraw(True)

    def OnDynamicDraw(sender, e):

        cp = e.CurrentPoint
        plane = (cp, f_normal)
        new_pt_list = []

        for u in f_vkeys:
            v = edges[u]
            u_xyz = cell.vertex_coordinates(u)
            v_xyz = cell.vertex_coordinates(v)
            line = (u_xyz, v_xyz)
            it = intersection_line_plane(line, plane)
            xyz_dict[u] = it
            new_pt_list.append(it)

            e.Display.DrawDottedLine(Point3d(*u_xyz), Point3d(*it), black)

        for vkey in cell.vertex:
            xyz = cell.vertex_coordinates(vkey)
            e.Display.DrawPoint(Point3d(*xyz), 0, 5, black)

        # old normal and area --------------------------------------------------
        e.Display.DrawDot(Point3d(*f_center), str(round(f_area, 3)), gray,
                          white)

        # draw original face ---------------------------------------------------
        for i in range(-1, len(f_vkeys) - 1):
            vkey1 = f_vkeys[i]
            vkey2 = f_vkeys[i + 1]
            sp = Point3d(*cell.vertex_coordinates(vkey1))
            np = Point3d(*cell.vertex_coordinates(vkey2))

            e.Display.DrawDottedLine(sp, np, black)

        # get current face info ------------------------------------------------
        areas = {}
        normals = {}
        for fkey in cell.faces():
            face_coordinates = [
                xyz_dict[vkey] for vkey in cell.face_vertices(fkey)
            ]
            areas[fkey] = polygon_area_oriented(face_coordinates)
            normals[fkey] = polygon_normal_oriented(face_coordinates)

        # draw new face areas / vectors ----------------------------------------
        for fkey in cell.faces():
            area = areas[fkey]
            normal = normals[fkey]
            value = area / max(areas.values())
            color = i_to_rgb(value)
            color = FromArgb(*color)

            # draw vectors -----------------------------------------------------
            scale = 0.25
            center = datastructure_centroid(cell)
            sp = Point3d(*center)
            vector = scale_vector(normal, area * scale)
            ep = Point3d(*add_vectors(center, vector))

            e.Display.DrawArrow(Line(sp, ep), color, 20, 0)

            # draw face --------------------------------------------------------
            face_coordinates = [
                xyz_dict[vkey] for vkey in cell.face_vertices(fkey)
            ]
            face_coordinates.append(face_coordinates[0])
            polygon_xyz = [Point3d(*xyz) for xyz in face_coordinates]

            e.Display.DrawPolyline(polygon_xyz, black, 2)

            if fkey == face:
                e.Display.DrawPolyline(polygon_xyz, black, 4)
                e.Display.DrawPolygon(polygon_xyz, color, filled=True)

            # display force magnitudes -----------------------------------------
            vector = add_vectors(vector,
                                 scale_vector(normalize_vector(normal), 0.75))
            xyz = add_vectors(center, vector)
            if fkey == face:
                color = black

            e.Display.DrawDot(Point3d(*xyz), str(round(area, 2)), color, white)

    # --------------------------------------------------------------------------
    #  5. input point
    # --------------------------------------------------------------------------
    ip = Point3d(*f_center)
    line = Rhino.Geometry.Line(ip, ip + Vector3d(*f_normal))
    gp = get_target_point(line, OnDynamicDraw)

    # --------------------------------------------------------------------------
    #  6. update cell coordinates
    # --------------------------------------------------------------------------
    cell_relocate_face(cell, face, gp, f_normal)

    cell.draw()
def apply_rule(mesh, rule):

    if rule == 'face_pole':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        face_pole(mesh, fkey)

    elif rule == 'edge_pole':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        artist.draw_edgelabels(text={(u, v): "{}-{}".format(u, v)
                                     for u, v in mesh.face_halfedges(fkey)})
        artist.redraw()
        edge = rhino_helper.mesh_select_edge(mesh, message='edge')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        edge_pole(mesh, fkey, edge)

    elif rule == 'vertex_pole':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        artist.draw_vertexlabels(
            text={key: str(key)
                  for key in mesh.face_vertices(fkey)})
        artist.redraw()
        pole = rhino_helper.mesh_select_vertex(mesh, message='pole')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        vertex_pole(mesh, fkey, pole)

    elif rule == 'add_opening':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        face_opening(mesh, fkey)

    elif rule == 'close_opening':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        boundaries = mesh_boundaries(mesh)
        artist.draw_vertexlabels(
            text={
                key: str(key)
                for key in
                [vkey for boundary in boundaries for vkey in boundary]
            })
        artist.redraw()
        vkey = rhino_helper.mesh_select_vertex(
            mesh, message='vertex on the opening to close')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        for boundary in boundaries:
            if vkey in boundary:
                vkeys = boundary
                break

        close_opening(mesh, vkeys)

    elif rule == 'flat_corner_2':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        artist.draw_vertexlabels(
            text={key: str(key)
                  for key in mesh.face_vertices(fkey)})
        artist.redraw()
        corner = rhino_helper.mesh_select_vertex(mesh, message='corner')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        flat_corner_2(mesh, fkey, corner)

    elif rule == 'flat_corner_3':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        artist.draw_vertexlabels(
            text={key: str(key)
                  for key in mesh.face_vertices(fkey)})
        artist.redraw()
        corner = rhino_helper.mesh_select_vertex(mesh, message='corner')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        flat_corner_3(mesh, fkey, corner)

    elif rule == 'flat_corner_33':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        artist.draw_vertexlabels(
            text={key: str(key)
                  for key in mesh.face_vertices(fkey)})
        artist.redraw()
        corner = rhino_helper.mesh_select_vertex(mesh, message='corner')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        flat_corner_33(mesh, fkey, corner)

    elif rule == 'split_35':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        artist.draw_edgelabels(text={(u, v): "{}-{}".format(u, v)
                                     for u, v in mesh.face_halfedges(fkey)})
        artist.redraw()
        edge = rhino_helper.mesh_select_edge(mesh, message='edge')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        split_35(mesh, fkey, edge)

    elif rule == 'split_35_diag':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        artist.draw_vertexlabels(
            text={key: str(key)
                  for key in mesh.face_vertices(fkey)})
        artist.redraw()
        corner = rhino_helper.mesh_select_vertex(mesh, message='corner')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        split_35_diag(mesh, fkey, corner)

    elif rule == 'split_26':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        artist.draw_edgelabels(text={(u, v): "{}-{}".format(u, v)
                                     for u, v in mesh.face_halfedges(fkey)})
        artist.redraw()
        edge = rhino_helper.mesh_select_edge(mesh, message='edge')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        split_26(mesh, fkey, edge)

    elif rule == 'simple_split':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        artist.draw_edgelabels(text={(u, v): "{}-{}".format(u, v)
                                     for u, v in mesh.face_halfedges(fkey)})
        artist.redraw()
        edge = rhino_helper.mesh_select_edge(mesh, message='edge')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        simple_split(mesh, fkey, edge)

    elif rule == 'double_split':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        double_split(mesh, fkey)

    elif rule == 'insert_pole':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        artist.draw_vertexlabels(
            text={key: str(key)
                  for key in mesh.face_vertices(fkey)})
        artist.redraw()
        pole = rhino_helper.mesh_select_vertex(mesh, message='pole')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        insert_pole(mesh, fkey, pole)

    elif rule == 'insert_partial_pole':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        artist.draw_vertexlabels(
            text={key: str(key)
                  for key in mesh.face_vertices(fkey)})
        artist.redraw()
        pole = rhino_helper.mesh_select_vertex(mesh, message='pole')
        artist.clear_layer()
        artist.redraw()

        artist.draw_edgelabels({(u, v): "{}-{}".format(u, v)
                                for u, v in mesh.face_halfedges(fkey)
                                if u != pole and v != pole})
        artist.redraw()
        edge = rhino_helper.mesh_select_edge(mesh, message='edge')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        insert_partial_pole(mesh, fkey, pole, edge)

    elif rule == 'singular_boundary_1':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_edgelabels(text={(u, v): "{}-{}".format(u, v)
                                     for u, v in mesh.edges()})
        artist.redraw()
        edge = rhino_helper.mesh_select_edge(mesh, message='edge')
        artist.clear_layer()
        artist.redraw()

        artist.draw_vertexlabels(text={key: str(key) for key in edge})
        artist.redraw()
        vkey = rhino_helper.mesh_select_vertex(mesh, message='vkey')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        singular_boundary_1(mesh, edge, vkey)

    elif rule == 'singular_boundary_2':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_edgelabels(text={(u, v): "{}-{}".format(u, v)
                                     for u, v in mesh.edges()})
        artist.redraw()
        edge = rhino_helper.mesh_select_edge(mesh, message='edge')
        artist.clear_layer()
        artist.redraw()

        artist.draw_vertexlabels(text={key: str(key) for key in edge})
        artist.redraw()
        vkey = rhino_helper.mesh_select_vertex(mesh, message='vkey')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        singular_boundary_2(mesh, edge, vkey)

    elif rule == 'singular_boundary_minus_1':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey = rhino_helper.mesh_select_face(mesh, message='fkey')
        artist.clear_layer()
        artist.redraw()

        artist.draw_vertexlabels(
            text={key: str(key)
                  for key in mesh.face_vertices(fkey)})
        artist.redraw()
        vkey = rhino_helper.mesh_select_vertex(mesh, message='vkey')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        singular_boundary_minus_1(mesh, fkey, vkey)

    elif rule == 'face_strip_collapse':
        edge_groups, max_group = dual_edge_polylines(mesh)

        groups = {}

        for edge, group in edge_groups.items():
            u, v = edge
            if group in groups:
                if (v, u) not in groups[group]:
                    groups[group].append((u, v))
            else:
                groups[group] = [(u, v)]

        rs.EnableRedraw(False)
        dots = {}
        for group, edges in groups.items():
            k = float(group) / float(max_group) * 255
            RGB = [k] * 3
            rs.AddGroup(group)
            for u, v in edges:
                dot = rs.AddTextDot(group, mesh.edge_midpoint(u, v))
                dots[dot] = (u, v)
                rs.ObjectColor(dot, RGB)
                rs.AddObjectToGroup(dot, group)
        rs.EnableRedraw(True)

        dot = rs.GetObject('dual polyedge to collapse', filter=8192)
        u, v = dots[dot]
        rs.DeleteObjects(dots)

        face_strip_collapse(PseudoQuadMesh, mesh, u, v)

    elif rule == 'face_strip_insert':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        count = mesh.number_of_vertices() * 1.5
        artist.draw_vertexlabels(
            text={key: str(key)
                  for key in mesh.vertices_on_boundary()})
        artist.redraw()
        vertex_path = [rhino_helper.mesh_select_vertex(mesh, message='vertex')]
        artist.clear_layer()
        count = mesh.number_of_vertices() * 1.5
        while count > 0:
            count -= 1
            artist.draw_vertexlabels(text={
                key: str(key)
                for key in mesh.vertex_neighbors(vertex_path[-1])
            })
            artist.redraw()
            vkey = rhino_helper.mesh_select_vertex(mesh, message='vertex')
            artist.clear_layer()
            artist.redraw()
            if vkey is None:
                break
            else:
                vertex_path.append(vkey)

        rs.DeleteLayer('mesh_artist')

        #start_pole = rs.GetInteger(message='pole at the start?', number=0, minimum=0, maximum=1)
        #end_pole = rs.GetInteger(message='pole at the end?', number=0, minimum=0, maximum=1)
        start_pole = 0
        end_pole = 0

        mesh = face_strip_insert(PseudoQuadMesh,
                                 mesh,
                                 vertex_path,
                                 pole_extremities=[start_pole, end_pole])

    elif rule == 'rotate_vertex':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_vertexlabels(
            text={key: str(key)
                  for key in mesh.vertices()})
        artist.redraw()
        vkey = rhino_helper.mesh_select_vertex(mesh, message='vkey')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        rotate_vertex(mesh, vkey)

    elif rule == 'clear_faces':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkeys = rhino_helper.mesh_select_faces(mesh, message='fkeys')
        artist.clear_layer()
        artist.redraw()

        vertices = [mesh.vertex_coordinates(vkey) for vkey in mesh.vertices()]
        face_vertices = [mesh.face_vertices(fkey) for fkey in fkeys]

        faces_mesh = PseudoQuadMesh.from_vertices_and_faces(
            vertices, face_vertices)
        faces_boundary_vertices = mesh_boundaries(faces_mesh)[0]

        artist.draw_vertexlabels(
            text={key: str(key)
                  for key in faces_boundary_vertices})
        artist.redraw()
        vkeys = rhino_helper.mesh_select_vertices(mesh, message='vkeys')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        clear_faces(mesh, fkeys, vkeys)

    elif rule == 'add_handle':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey_1 = rhino_helper.mesh_select_face(mesh, message='fkey_1')
        artist.clear_layer()
        artist.redraw()

        artist.draw_facelabels()
        artist.redraw()
        fkey_2 = rhino_helper.mesh_select_face(mesh, message='fkey_2')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        add_handle(mesh, fkey_1, fkey_2)

    elif rule == 'close_handle':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_facelabels()
        artist.redraw()
        fkey_1 = rhino_helper.mesh_select_face(mesh, message='fkey_1')
        artist.clear_layer()
        artist.redraw()

        artist.draw_facelabels(
            text={key: str(key)
                  for key in mesh.face_neighbors(fkey_1)})
        artist.redraw()
        fkey_2 = rhino_helper.mesh_select_face(mesh, message='fkey_2')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        count = mesh.number_of_faces()
        fkeys = [fkey_1, fkey_2]
        while count > 0:
            count -= 1
            u, v = mesh.face_adjacency_halfedge(fkeys[-2], fkeys[-1])
            w = mesh.face_vertex_ancestor(fkeys[-1], v)
            x = mesh.face_vertex_ancestor(fkeys[-1], w)
            if x in mesh.halfedge[w] and mesh.halfedge[w][x] is not None:
                fkey_3 = mesh.halfedge[w][x]
                fkeys.append(fkey_3)
                if fkeys[-1] == fkeys[0]:
                    break

        close_handle(mesh, fkeys)

    elif rule == 'close_handle_2':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        edge_paths = []
        for i in range(2):

            vertex_path = []

            artist.draw_vertexlabels(
                text={key: str(key)
                      for key in mesh.vertices()})
            artist.redraw()
            vertex_path.append(
                rhino_helper.mesh_select_vertex(mesh, message='vertex'))
            artist.clear_layer()
            artist.redraw()

            count = mesh.number_of_vertices()
            while count > 0:
                count -= 1
                artist.draw_vertexlabels(
                    text={
                        key: str(key)
                        for key in mesh.vertex_neighbors(vertex_path[-1])
                    })
                artist.redraw()
                vkey = rhino_helper.mesh_select_vertex(mesh, message='vertex')
                if vkey is None:
                    break
                artist.clear_layer()
                artist.redraw()
                if vkey in list(mesh.vertices()):
                    vertex_path.append(vkey)
                else:
                    break
                if vkey == vertex_path[0]:
                    break
            del vertex_path[-1]
            edge_paths.append([[vertex_path[i - 1], vertex_path[i]]
                               for i in range(len(vertex_path))])

        rs.DeleteLayer('mesh_artist')

        edge_path_1, edge_path_2 = edge_paths

        mesh = close_handle_2(mesh, edge_path_1, edge_path_2)

    elif rule == 'move_vertices':
        artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
        artist.clear_layer()

        artist.draw_vertexlabels(
            text={key: str(key)
                  for key in mesh.vertices()})
        artist.redraw()
        vkeys = rhino_helper.mesh_select_vertices(mesh, message='vkeys')
        artist.clear_layer()
        artist.redraw()

        rs.DeleteLayer('mesh_artist')

        x1, y1, z1 = rs.GetPoint(message='from...')
        x2, y2, z2 = rs.GetPoint(message='...to')

        for vkey in vkeys:
            attr = mesh.vertex[vkey]
            attr['x'] += x2 - x1
            attr['y'] += y2 - y1
            attr['z'] += z2 - z1

    elif rule == 'project_on_surface':
        srf = rs.GetObject('surface for projection', filter=8)
        for vkey in mesh.vertices():
            u, v = rs.SurfaceClosestPoint(srf, mesh.vertex_coordinates(vkey))
            x, y, z = rs.EvaluateSurface(srf, u, v)
            attr = mesh.vertex[vkey]
            attr['x'] = x
            attr['y'] = y
            attr['z'] = z

    return 0