I have an algorithm for you that works in the 2D case. It is tricky, but do-able to generalize it to 3D space. The basic idea is to start with a minimum-surface (triangle in 2D or tetrahedron in 3D), and split each edge (face) as you traverse the array of points.
2D algorithm (python. FULL SOURCE/DEMO HERE: http://pastebin.com/jmwUt3ES)
edit: this demo is fun to watch: http://pastebin.com/K0WpMyA3
def surface(pts):
center = pt_center(pts)
tx = -center[0]
ty = -center[1]
pts = translate_pts(pts, (tx, ty))
# tricky part: initialization
# initialize edges such that you have a triangle with the origin inside of it
# in 3D, this will be a tetrahedron.
ptA, ptB, ptC = get_center_triangle(pts)
print ptA, ptB, ptC
# tracking edges we've already included (triangles in 3D)
edges = [(ptA, ptB), (ptB, ptC), (ptC, ptA)]
# loop over all other points
pts.remove(ptA)
pts.remove(ptB)
pts.remove(ptC)
for pt in pts:
ptA = (0,0)
ptB = (0,0)
# find the edge that this point will be splitting
for (ptA, ptB) in edges:
if crossz(ptA, pt) > 0 and crossz(pt, ptB) > 0:
break
edges.remove((ptA, ptB))
edges.append((ptA, pt))
edges.append((pt, ptB))
# translate everything back
edges = [((ptA[0] - tx, ptA[1] - ty), (ptB[0] - tx, ptB[1] - ty)) for (ptA, ptB) in edges]
return edges
RESULT:

Generalizing to 3D
- instead of edges, you have triangles.
- initialization is a tetrahedron around the origin
- finding the splitting face involves projecting a triangle, and checking if the pt is interior to that triangle
- splitting involves adding 3 new faces whereas 2D was 2 new edges
- need to be careful about orientation of the face (in my 2D code, I was easily able to guarantee A->B would be CCW orientation)
Depending on the size of your point cloud and speed requirements, you may need to be more clever about data structures for faster add/remove.