Python 3.3 – Create 3D-mesh as Wavefront obj-file from regular spaced vertices

Question:

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.

Asked By: Florian R. Klein

||

Answers:

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 (https://dl.dropboxusercontent.com/u/13547611/meshGenWorking001.png).

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 !

Answered By: Florian R. Klein

@Florian R. Klein Can you contact with me? I have some question about 3d mesh face.
I work with some method gnn and I need some database. But I can’t find it.
So I think that I can generate database. As I understand you make it here.
How can we contact (email?)?

Answered By: programsprojects1
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.