Hi, there is one such routine in SAGE (http://www.sagemath.org/)

see here:
http://www.sagemath.org/doc/reference/sage/graphs/generic_graph.html#sage.graphs.generic_graph.GenericGraph.trace_faces

```
def trace_faces(self, comb_emb):
"""
A helper function for finding the genus of a graph. Given a graph
and a combinatorial embedding (rot_sys), this function will
compute the faces (returned as a list of lists of edges (tuples) of
the particular embedding.
Note - rot_sys is an ordered list based on the hash order of the
vertices of graph. To avoid confusion, it might be best to set the
rot_sys based on a 'nice_copy' of the graph.
INPUT:
- ``comb_emb`` - a combinatorial embedding
dictionary. Format: v1:[v2,v3], v2:[v1], v3:[v1] (clockwise
ordering of neighbors at each vertex.)
EXAMPLES::
sage: T = graphs.TetrahedralGraph()
sage: T.trace_faces({0: [1, 3, 2], 1: [0, 2, 3], 2: [0, 3, 1], 3: [0, 1, 2]})
[[(0, 1), (1, 2), (2, 0)],
[(3, 2), (2, 1), (1, 3)],
[(2, 3), (3, 0), (0, 2)],
[(0, 3), (3, 1), (1, 0)]]
"""
from sage.sets.set import Set
# Establish set of possible edges
edgeset = Set([])
for edge in self.to_undirected().edges():
edgeset = edgeset.union( Set([(edge[0],edge[1]),(edge[1],edge[0])]))
# Storage for face paths
faces = []
path = []
for edge in edgeset:
path.append(edge)
edgeset -= Set([edge])
break # (Only one iteration)
# Trace faces
while (len(edgeset) > 0):
neighbors = comb_emb[path[-1][-1]]
next_node = neighbors[(neighbors.index(path[-1][-2])+1)%(len(neighbors))]
tup = (path[-1][-1],next_node)
if tup == path[0]:
faces.append(path)
path = []
for edge in edgeset:
path.append(edge)
edgeset -= Set([edge])
break # (Only one iteration)
else:
path.append(tup)
edgeset -= Set([tup])
if (len(path) != 0): faces.append(path)
return faces
```

I also have my own implementation which is an adaptation from the SAGE lib:

```
def Faces(edges,embedding)
"""
edges: is an undirected graph as a set of undirected edges
embedding: is a combinatorial embedding dictionary. Format: v1:[v2,v3], v2:[v1], v3:[v1] clockwise ordering of neighbors at each vertex.)
"""
# Establish set of possible edges
edgeset = set()
for edge in edges: # edges is an undirected graph as a set of undirected edges
edge = list(edge)
edgeset |= set([(edge[0],edge[1]),(edge[1],edge[0])])
# Storage for face paths
faces = []
path = []
for edge in edgeset:
path.append(edge)
edgeset -= set([edge])
break # (Only one iteration)
# Trace faces
while (len(edgeset) > 0):
neighbors = self.embedding[path[-1][-1]]
next_node = neighbors[(neighbors.index(path[-1][-2])+1)%(len(neighbors))]
tup = (path[-1][-1],next_node)
if tup == path[0]:
faces.append(path)
path = []
for edge in edgeset:
path.append(edge)
edgeset -= set([edge])
break # (Only one iteration)
else:
path.append(tup)
edgeset -= set([tup])
if (len(path) != 0): faces.append(path)
return iter(faces)
```