Generates a NURBS surface object from a mesh file.

    :param file_name: input mesh file
    :type file_name: str
    :return: a NURBS surface
    :rtype: NURBS.Surface

def import_surf_mesh(file_name):
    """ Generates a NURBS surface object from a mesh file.

    :param file_name: input mesh file
    :type file_name: str
    :return: a NURBS surface
    :rtype: NURBS.Surface
    """
    raw_content = read_file(file_name)
    raw_content = raw_content.split("\n")
    content = []
    for rc in raw_content:
        temp = rc.strip().split()
        content.append(temp)

    # 1st line defines the dimension and it must be 3
    if int(content[0][0]) != 3:
        raise TypeError("Input mesh '" + str(file_name) + "' must be 3-dimensional")

    # Create a NURBS surface instance and fill with the data read from mesh file
    surf = shortcuts.generate_surface(rational=True)

    # 2nd line is the degrees
    surf.degree_u = int(content[1][0])
    surf.degree_v = int(content[1][1])

    # 3rd line is the number of weighted control points in u and v directions
    dim_u = int(content[2][0])
    dim_v = int(content[2][1])

    # Starting from 6th line, we have the weighted control points
    ctrlpts_end = 5 + (dim_u * dim_v)
    ctrlpts_mesh = content[5:ctrlpts_end]

    # mesh files have the control points in u-row order format
    ctrlpts = compatibility.flip_ctrlpts_u(ctrlpts_mesh, dim_u, dim_v)

    # mesh files store control points in format (x, y, z, w)
    ctrlptsw = compatibility.generate_ctrlptsw(ctrlpts)

    # Set control points
    surf.set_ctrlpts(ctrlptsw, dim_u, dim_v)

    # 4th and 5th lines are knot vectors
    surf.knotvector_u = [float(u) for u in content[3]]
    surf.knotvector_v = [float(v) for v in content[4]]

    # Return the surface instance
    return surf