I am writing a simple command line program in Python 3.3 which reads a text file of xyz-coordinates and outputs a the equivalent triangle faces in between. The export format are Wavefront obj-files (https://en.wikipedia.org/wiki/Wavefront_.obj_file). The algorthm is solely intended to work with regular spaced points from high resolution satellite scans of the earth. Actually, I am using a set of about 340000 points and creating 2 triangles in between a vertex quadrupel. The outer iteration goes in x-direction while the inner iteration is over the y-direction. So, pairs of triangle faces are creates for every vertex in y-direction until it moves on in x-direction and repeats the process. I will show you the principle pattern (the lines are the face edges):
v1--v5--v9
| \ | / |
v2--v6--v10
| / | \ |
v3--v7--v11
| \ | / |
v4--v8--v12
The code seems to work in way as importing the file in Blender or MeshLab gives reasonable results, except for one thing: All stripes of face pairs seem to be not connected with their neighbors along the x-axis. A rendered picture which demonstrates the problem: unconnected stripes.
Normally, there shouldn't be an vertical offset between different face-stripes because they share the same vertices along their interior border(-line). Tests with less vertices and more common low coordinate values succeeded. The method was working perfectly fine. Maybe the problem lies not within my mesh generator but within the coordinate limitations of Blender, MeshLab, etcetera.
Here is the function which generates the faces and stitches everythin together in an return-string:
def simpleTriangMesh(verts):
printAll("--creating simple triangulated mesh", "\n")
maxCoords = [max(verts[0]), max(verts[1]), max(verts[2])]
minCoords = [min(verts[0]), min(verts[1]), min(verts[2])]
printAll("max. coordinates (xyz): \n", maxCoords, "\n")
printAll("min. coordinates (xyz): \n", minCoords, "\n")
xVerts = 0 # amount of vertices in x-direction
yVerts = 0 # amount of vertices in y-direction
faceAmount = 0 # amount of required faces to skin grid
i = 0
temp = verts[0][0]
while(i < len(verts[0])):
if(temp < verts[0][i]):
yVerts = int(i)
break
temp = verts[0][i]
i += 1
xVerts = int(len(verts[0]) / float(yVerts))
faceAmount = ((xVerts - 1) * (yVerts - 1)) * 2
printAll("vertices in x direction: ", xVerts, "\n")
printAll("vertices in y direction: ", yVerts, "\n")
printAll("estimated amount of triangle faces: ",
faceAmount, "\n")
printAll("----generating vertex triangles representing the faces", "\n")
# list of vertex-index quadrupels representing the faces
faceList = [[0 for line in range(0, 3)] for face in range(0, int(faceAmount))]
f = 0
v = 0
# rather to draw hypotenuse of the triangles from topleft to bottomright
# or perpendicular to that (topright to bottomleft)
tl = True # the one that changes in y-direction
tl_rem = False # to remember the hypotenuse direction of the last topmost faces
while(f < len(faceList)):
# prevent creation of faces at the bottom line
# + guarantees that v = 1 when creating the first face
if(( v % yVerts ) == 0):
v += 1
tl = not tl_rem
tl_rem = tl
if(tl):
faceList[f][0] = v
faceList[f][1] = v + yVerts
faceList[f][2] = v + yVerts + 1
f += 1
faceList[f][0] = v
faceList[f][1] = v + yVerts + 1
faceList[f][2] = v + 1
else:
faceList[f][0] = v
faceList[f][1] = v + yVerts
faceList[f][2] = v + 1
f += 1
faceList[f][0] = v + 1
faceList[f][1] = v + yVerts
faceList[f][2] = v + yVerts + 1
f += 1
v += 1
tl = not tl
printAll("----preparing obj-file-content for export", "\n")
rectMesh_Obj = "" # string containing the mesh in obj-format (ascii)
tempVerts = ""
tempFaces = ""
row = 0
while(row < len(verts[0])):
# temp = ("v" + " " + str(verts[0][row]) + " " + str(verts[1][row])
# + " " + str(verts[2][row]) + "\n")
temp = ("v" + " " + str(verts[0][row]) + " " + str(verts[2][row])
+ " " + str(verts[1][row]) + "\n")
tempVerts += temp
row += 1
row = 0
while(row < len(faceList)):
temp = ("f"
+ " " + str(int(faceList[row][0]))
+ " " + str(int(faceList[row][1]))
+ " " + str(int(faceList[row][2]))
# + " " + str(int(faceList[row][3]))
+ "\n")
tempFaces += temp
row += 1
rectMesh_Obj += tempVerts + tempFaces
return(rectMesh_Obj)
The verts-variable which is inputted into the function has the form of a 2-dimensional list, similar to:
# x y z
vertsExample = [[3334, 3333, 3332], [2555, 2554, 2553], [10.2, 5.2, 6.7]]
I hope some of you can help me out of the misery. If something requires more explanation, please let me know and I will add it to the first post.
I finally solved the issue. The problem wasn't in my mesh generator program. Blender and MeshLab (and most likely other 3D-Programs as well) do some weird things when the coordinates of vertices are too big. If am reducing the real world geographically projected coordinates to smaller relative coordinates everything works just fine.
My guess: The Wavefront obj-format has too limited byte-sizes for its numbers. or to be more correct: Common 3D-Programs do not expect the numbers to be so big like the real world ones. This way they interpret what they get in a confusing manner.
I hope this solution helps somebody in the future !