Draws a 2d wireframe+surface in 3d: generalization of :any:`plot_wireframe` and :any:`plot_surface`.

    :param x: {x2d}
    :param y: {y2d}
    :param z: {z2d}
    :param color: {color2d}
    :param bool wireframe: draw lines between the vertices
    :param bool surface: draw faces/triangles between the vertices
    :param bool wrapx: when True, the x direction is assumed to wrap, and polygons are drawn between the begin and end points
    :param boool wrapy: idem for y
    :param u: {u}
    :param v: {v}
    :param texture: {texture}
    :return: :any:`Mesh`

def plot_mesh(
    x, y, z, color=default_color, wireframe=True, surface=True, wrapx=False, wrapy=False, u=None, v=None, texture=None
):
    """Draws a 2d wireframe+surface in 3d: generalization of :any:`plot_wireframe` and :any:`plot_surface`.

    :param x: {x2d}
    :param y: {y2d}
    :param z: {z2d}
    :param color: {color2d}
    :param bool wireframe: draw lines between the vertices
    :param bool surface: draw faces/triangles between the vertices
    :param bool wrapx: when True, the x direction is assumed to wrap, and polygons are drawn between the begin and end points
    :param boool wrapy: idem for y
    :param u: {u}
    :param v: {v}
    :param texture: {texture}
    :return: :any:`Mesh`
    """
    fig = gcf()

    # assert len(x.shape) == 2
    # assert len(y.shape) == 2
    # assert len(z.shape) == 2
    # if isinstance(color, np.ndarray):
    # 	assert len(color.shape) == 3
    # 	assert color.shape[:2] == x.shape
    # 	color = color.reshape(-1)

    def dim(x):
        d = 0
        el = x
        while True:
            try:
                el = el[0]
                d += 1
            except:
                break
        return d

    if dim(x) == 2:
        nx, ny = x.shape
    else:
        nx, ny = x[0].shape

    # assert len(x.shape) == 2, "Array x must be 2 dimensional."
    # assert len(y.shape) == 2, "Array y must be 2 dimensional."
    # assert len(z.shape) == 2, "Array z must be 2 dimensional."
    # assert x.shape == y.shape, "Arrays x and y must have same shape."
    # assert y.shape == z.shape, "Arrays y and z must have same shape."
    # convert x, y, z from shape (nx, ny) to (nx * ny) or
    # (frame, nx, ny) to (frame, nx*ny)
    def reshape(ar):
        if dim(ar) == 3:
            return [k.reshape(-1) for k in ar]
        else:
            return ar.reshape(-1)

    x = reshape(x)
    y = reshape(y)
    z = reshape(z)
    # similar for texture coordinates
    if u is not None:
        u = reshape(u)
    if v is not None:
        v = reshape(v)

    # convert color from shape (nx, ny, {3,4}) to (nx * ny, {3, 4}) or
    # (frame, nx, ny, {3,4}) to (frame, nx*ny, {3,4})
    def reshape_color(ar):
        if dim(ar) == 4:
            return [k.reshape(-1, k.shape[-1]) for k in ar]
        else:
            return ar.reshape(-1, ar.shape[-1])

    if isinstance(color, np.ndarray):
        color = reshape_color(color)

    _grow_limits(np.array(x).reshape(-1), np.array(y).reshape(-1), np.array(z).reshape(-1))
    triangles, lines = _make_triangles_lines((nx, ny), wrapx, wrapy)
    mesh = ipv.Mesh(
        x=x,
        y=y,
        z=z,
        triangles=triangles if surface else None,
        color=color,
        lines=lines if wireframe else None,
        u=u,
        v=v,
        texture=texture,
    )
    fig.meshes = fig.meshes + [mesh]
    return mesh