def to_mesh(obj):
if   is_mesh(obj): return obj<EOL>elif pimms.is_vector(obj) and len(obj) == <NUM_LIT:2>:<EOL><INDENT>(a,b) = obj<EOL>if   pimms.is_matrix(a, '<STR_LIT:int>') and pimms.is_matrix(b, '<STR_LIT>'): return mesh(a, b)<EOL>elif pimms.is_matrix(b, '<STR_LIT:int>') and pimms.is_matrix(a, '<STR_LIT>'): return mesh(b, a)<EOL>elif is_mesh(a) and (b is None or pimms.is_str(b)): return a<EOL>elif is_mesh(a) and is_mesh(b): return b<EOL>elif is_topo(a):<EOL><INDENT>from neuropythy import is_cortex<EOL>if   is_mesh(b):          return b<EOL>elif not pimms.is_str(b): raise ValueError('<STR_LIT>' % (b,))<EOL>(b0, lb) = (b, b.lower())<EOL>s = b[<NUM_LIT:4>:] if lb.startswith('<STR_LIT>') else b[<NUM_LIT:5>:] if lb.startswith('<STR_LIT>') else b<EOL>ls = s.lower()<EOL>if ls.endswith('<STR_LIT>'): b = ('<STR_LIT>' + s[:-<NUM_LIT:7>])<EOL>elif ls == '<STR_LIT>': b = '<STR_LIT>'<EOL>lb = b.lower()<EOL>if is_cortex(a) and not lb.startswith('<STR_LIT>'):<EOL><INDENT>(s,ls) = (b[<NUM_LIT:5>:],lb[<NUM_LIT:5>:]) if lb.startswith('<STR_LIT>') else (b,lb)<EOL>if   s  in a.surfaces: return a.surfaces[s]<EOL>elif ls in a.surfaces: return a.surfaces[ls]<EOL><DEDENT>if not lb.startswith('<STR_LIT>'):<EOL><INDENT>(s,ls) = (b[<NUM_LIT:4>:],lb[<NUM_LIT:4>:]) if lb.startswith('<STR_LIT>') else (b,lb)<EOL>if   s  in a.registrations: return a.registrations[s]<EOL>elif ls in a.registrations: return a.registrations[ls]<EOL><DEDENT>raise ValueError('<STR_LIT>' % (b0, a))<EOL><DEDENT>else: raise ValueError('<STR_LIT>' % (obj,))<EOL><DEDENT>else: raise ValueError('<STR_LIT>')<EOL>
to_mesh(obj) yields a Mesh object that is equivalent to obj or identical to obj if obj is itself
  a mesh object.

The following objects can be converted into meshes:
  * a mesh object
  * a tuple (coords, faces) where coords is a coordinate matrix and faces is a matrix of
    coordinate indices that make-up the triangles
  * a tuple (faces, coords) where faces is a triangle matrix and coords is a coordinate matrix;
    note that if neither matrix is of integer type, then the latter ordering (which is the same
    as that accepted by the mesh() function) is assumed.
  * a tuple (topo, regname) specifying the registration name to use (note that regname may
    optionally start with 'reg:' which is ignored).
  * a tuple (cortex, surfname) specifying the surface name to use. Note that surfname may
    optionally start with 'surf:' or 'reg:', both of which are used only to determine whether
    to lookup a registration or a surface. If no 'surf:' or 'reg:' is given as a prefix, then
    a surface is tried first followed by a registration. The surface name 'sphere' is
    automatically translated to 'reg:native' and any surface name of the form '<name>_sphere' is
    automatically translated to 'reg:<name>'.
  * a tuple (topo/cortex, mesh) results in the mesh being returned.
  * a tuple (mesh, string) or (mesh, None) results in mesh with the second argument ignored.
  * a tuple (mesh1, mesh2) results in mesh2 with mesh1 ignored.

Note that some of the behavior described above is desirable because of a common use case of the
to_mesh function. When another function f accepts as arguments both a hemi/topology object as
well as an optional surface argument, the purpose is often to obtain a specific mesh from the
topology but to allow the user to specify which or to pass their own mesh.