Objects vs. Arrays August 16, 2011
Posted by PythonGuy in Advanced Python.trackback
I’m playing around with some 3D data. I think this is a good learning experience for those who want to understand the flexibility Python allows.
I started with the simplest case. I had three Numpy arrays. One was an array of vertices, another an array of normals, and the third an array of triangles which referenced three vertices and three normals.
Rendering the surface in OpenGL is trivial. Just glBegin(GL_TRIANGLES), then go through each triangle, calling glNormal3dv() and glVertex3dv() for each normal and vertex in the triangle.
Thinking of this in the computer science sense, it’s apparent that the list of vertices and the list of normals are not truly independent. If a vertex or normal isn’t mentioned as part of a triangle, there’s no reason to hold on to it in memory.
In a sense, the arrays of vertices and normals is an artificial data structure, created for convenience, not correctness. If I manipulated the surface so that triangles would change or disappear, there’s a good chance that the arrays of vertices and normals would be incorrect, holding information that is no longer needed.
I started down the OO path, creating a Triangle class, then a Vertex and Normal class. I realized, part way through this process, that I was moving away from the way things work in OpenGL land. Ultimately, I would load the vertices and normals into a buffer of some sort, and then I would issue render commands against the buffer of vertices. I haven’t quite seen how to do this yet, but it’s apparent that the array is the proper way to store these things, not as separate objects spread out all over creation.
The second problem was one of elegance. In the system I had devised earlier, it is quite natural that many triangles would share the same vertex, and these relationships are all but obvious. If I moved the vertex, then all of the connected triangles would likewise move, whether or not they were aware of the change. While I can implement a system where the same Vertex object is shared among many Triangle objects, I doubt it would be as elegant as the first solution I derived. Finding which triangles share the same vertex is not trivial in the OO approach, but in the indexed approach it is a simple filter for triangles that have the same index to the vertex.
I haven’t exactly resolved this dilemma in my mind. I suppose that I can create an object that uses invisible indexing into a massive array, and manages the memory within the array not unlike you’d have to do in C. I’m not convinced that such a solution is elegant or even beneficial.
In the long run, I think having a highly optimized set of data structures, each with their own unique access and modification rules, is probably the right way to go. I can “protect” these within a class, and then provide accessors and mutators to view and modify specific segments as needed. Perhaps having the elements defined as low as individual Triangles and Vertexes is simply too much detail.
Disclaimer: I know jack squat about OpenGL or NumPy arrays.
Perhaps you might try an Object which represents all three arrays together and have properties on it which represent the individual arrays. This might allow you to add behavior to add or remove vertex/normal/triangle data together conveniently.
That’s along the lines of my thinking right now.
Plus, if ever I have to rewrite it in C, it will be pretty straightforward since I won’t have to rely on advanced features of Python that C doesn’t have.