ofMesh: accessing the vertex vector


#1

A couple of questions about accessing the vertex vector in ofMesh.

My starting point is a rectangular mesh of vertices representing a height field or terrain map: z(x,y). I build the initial field then calculate differential heights which can be fed back into the structure to imitate, for example, ripples on a liquid surface. I did one version of this in Processing using Java and accessed the field as a 2D array z[rows][cols]. Very convenient since the differential accesses the rows above and below the z-cell in question as well as left and right positions.

In openFrameworks, the mesh vertex vector is linear but we know the number of columns so I can think in terms of rows and columns by indexing with (columnIndex + rowIndex*numberOfColumns).

Question 1: Is there a C++ “cast” operation or other technique where I can sort of convert, say, the pointer to the vertex vector into a 2D reference of known number of columns and rows? (This would make conversion of old Java code simpler.)

Question 2: In browsing the Forum I ran across a mesh vertex access written like this, as best I recall:

mesh.getVertices().at(i).z

This looks like it would be useful. I can find documentation for getVertices() but where the heck is the extension “at()”?

Question 3: Got any references to help me understand the documentation of ofMesh in terms of templates and the .inf file?

Thanks for your thoughts.


#2

the vector in ofMesh is just a vector<glm::vec3> similar to an array. to access it you can use at(i) as you mention or just mesh.getVertices()[i]

there’s no reference for that in the documentation cause a vector is a standard c++ class, search for std::vector and you’ll get all the documentation about it.

to access it as a rows/columns structure you just need to do the operation you point out: columnIndex + rowIndex*numberOfColumns and use the result as an index into the vector.

The mesh is templated as a way to provide compatibility with the old vector math library for old projects but in most cases you just need to use it as a mesh of glm::vec3 for vertices and normals, glm::vec2 for texture coordinates and ofFloatColor for colors


#3

Hello,

Some thoughts then :slight_smile:

Templates was (and still is) a difficulty for me who came from other languages which doesn’t afford that. But it is a great tool.

I made some tries to mimic the [col][row] vertices access. The first is to write an inlined method:

    inline size_t idx( size_t column, size_t row ){
       return column + row * numColumns;
    }

which allow to write

mesh.getVertices()[ idx( col, row ) ]

Others convenient methods in your case can be:

	inline glm::vec3 vertex( size_t column, size_t row ) const {
		return mesh.getVertices()[ column + row * numColumns ];
	}

	inline glm::vec3 & vertex( size_t column, size_t row ){
		return mesh.getVertices()[ column + row * numColumns ];
	}

The first allow a read only access to one vertex:

glm::vec3 aVertex = vertex( col, row );

The second allow a read-write access to one vertex:

vertex( col, row ).z = someValue;

I see no cast operation to do what you want, but I tried to write a class GridMesh which can be interesting. It allow to do:

GridMesh mesh;
mesh.setup( numColumns, numRows, cellWidth, cellHeight );
glm::vec3 aVertex = mesh( col, row );
mesh( col, row ).z = someValue;

Here it is:

class GridMesh
{
public:

	void setup( size_t numColumns, size_t numRows, float cellWidth, float cellHeight ){
		ofPlanePrimitive plane;
		plane.set( numColumns * cellWidth, numRows * cellHeight, int(numColumns), int(numRows) );
		mesh = plane.getMesh();
	}

	// Get the original ofMesh.
	// For example, this allow to do things like myMesh().draw() or
	// myMesh().drawWireFrame() for an instance named myMesh.
	ofMesh & operator()(){ return mesh; }
	
	// Get a mesh vertex. This is const, and modify the returned vertex won't modify the mesh
	glm::vec3 operator()(  size_t column, size_t row ) const { return mesh.getVertices()[ column + row * numColumns ]; }

	// Get a reference to a mesh vertex. Modify this vertex will modify the mesh.
	glm::vec3 & operator()(  size_t column, size_t row ) { return mesh.getVertices()[ column + row * numColumns ]; }
	
protected:
	ofMesh mesh;
	size_t numColumns;
	size_t numRows;
};

If you’re interested see the full comments in the sources:
src.zip (2,4 Ko)


#4

arturo: As usual, thanks for your thoughtful reply – a big help.


#5

lilive: Thanks a ton for all your information. I will study it in detail.


#6

I forgot to say that there is an example app in the attached sources in my previous message.