Lost ofMesh faces when using append

hello OF folks

I have a collection of ofPolylines that I am extruding and stacking to form a mesh model. To begin with I do this as a whole vector of individual ofMesh objects, and then draw them. This all looks great.

However, I also want to add all the separate ofMesh objects into one single ofMesh (i.e. not as a vector) for export as a .ply model. When I do this by the append method, I loose a whole load of mesh faces (the vertical edges of the extruded shapes).

Can someone tell me how to fix this/what I am doing wrong?

Below is two screen grabs, first of the shapes rendered one by one from the vector and then second as one single ofMesh after appending them all together.

I’m pretty sure there must be some kind of clash (in winding mode? or normals? - but I don’t know much about these) between the two types of meshes. So, when I append them into one single mesh, the verticals get garbled?

I’m making the horizontal shape meshes by just tessellating from ofPath objects, then changing their vertical position and adding normals:

                    ofVboMesh front = minko[j].getTessellation();
                    glm::vec3* v = front.getVerticesPointer();
                    for(int k = 0; k<front.getNumVertices(); k++){
                        v[k].z = total_depth;
                        front.addColor(frontCol);
                        front.addNormal(glm::vec3(0,0,1));
                    }

And I’m making the edge ribbon meshes by using the edge outline polylines as follows:

                   ofVboMesh ribbon;
                    vector<ofPolyline>polys = minko[j].getOutline();
                    //should only be a single polyline ever
                    for(int k = 0; k<polys.size(); k++){
                        //get all the points in the edge overall
                        vector<glm::vec3>points = polys[k].getVertices();
                        for(int l = 0; l<points.size(); l++){
                            //get the next segment of the edge to work with
                            int m = l+1;
                            if(m == points.size()) m = 0;
                            glm::vec3 p1 = points[l];
                            glm::vec3 p2 = points[m];
                            glm::vec3 p3 = glm::vec3(p1.x, p1.y, total_depth);
                            
                            //calculate the normal for these triangles
                            glm::vec3 e1 = p1 - p2;
                            glm::vec3 e2 = p3 - p2;
                            glm::vec3 norm = glm::cross(e1, e2);
                            
                            //add the two triangles for this edge part
                            ribbon.addVertex(glm::vec3(p1.x, p1.y, total_depth));
                            ribbon.addColor(sideCol);
                            ribbon.addNormal(norm);
                            ribbon.addVertex(glm::vec3(p2.x, p2.y, total_depth));
                            ribbon.addColor(sideCol);
                            ribbon.addNormal(norm);
                            ribbon.addVertex(glm::vec3(p1.x, p1.y, total_depth+gap));
                            ribbon.addColor(sideCol);
                            ribbon.addNormal(norm);
                            
                            ribbon.addVertex(glm::vec3(p2.x, p2.y, total_depth+gap));
                            ribbon.addColor(sideCol);
                            ribbon.addNormal(norm);
                            ribbon.addVertex(glm::vec3(p1.x, p1.y, total_depth+gap));
                            ribbon.addColor(sideCol);
                            ribbon.addNormal(norm);
                            ribbon.addVertex(glm::vec3(p2.x, p2.y, total_depth));
                            ribbon.addColor(sideCol);
                            ribbon.addNormal(norm);
                        }}

Then later I append them together by:

ofVboMesh minkoFinal;
minkoFinal.clear();
minkoFinal.append(front);
minkoFinal.append(ribbon);
//etc

But the final mesh shows the ribbon edges missing.
Am I doing something wrong? Can anyone help??

Looking at the 2 pictures, it seems that the problem is the normal calculation or the winding. Do you have the same numbers of vertices and normals, in the vector of meshes and in the merged mesh? They should be the same. Once you have tested this, I would probably make a smaller mesh, maybe with just a couple of triangles, and I would check the values of the normal and the winding.

thanks for the reply. I’ll check the counts… how would I check the winding?

edit: yes, the number of vertices in the vector and the number in the ofVboMesh minkoFinal are a match. So it isn’t that vertices and normals are being left out, just that they are subsequently being overlooked?

To check the winding you could draw the wireframe of your mesh, writing the number of your indices positioned where the vertices are. You can even do it “mentally”, you draw just a square and you ofLog() the value of the indices and the vertices.
In your mesh creation, you are not adding indexes. Have a look at this chapter of the book https://github.com/mikewesthad/ofSite/blob/master/_tutorials/03_graphics/generativemesh.markdown, and at the addIndex

whoop, you nailed it

The issue was (I fink) because I wasn’t adding indices in the ribbon mesh - but they probably are added in the ofPath meshes. Soooo append was garbling the relations because of inconsistent indices additions.

Tweaking the ribbon construction to the following results in a nice clean single final ofMesh after the append section:

                    for(int l = 0; l<points.size(); l++){
                            int m = l+1;
                            if(m == points.size()) m = 0;
                            glm::vec3 p1 = points[l];
                            glm::vec3 p2 = points[m];
                            glm::vec3 p3 = glm::vec3(p1.x, p1.y, total_depth);
                            
                            glm::vec3 e1 = p1 - p2;
                            glm::vec3 e2 = p3 - p2;
                            glm::vec3 norm = glm::cross(e1, e2);
                            
                            int newV = ribbon.getNumVertices();
                            
                            ribbon.addVertex(glm::vec3(p1.x, p1.y, total_depth));
                            ribbon.addColor(sideCol);
                            ribbon.addNormal(norm);
                            ribbon.addVertex(glm::vec3(p2.x, p2.y, total_depth));
                            ribbon.addColor(sideCol);
                            ribbon.addNormal(norm);
                            ribbon.addVertex(glm::vec3(p1.x, p1.y, total_depth+gap));
                            ribbon.addColor(sideCol);
                            ribbon.addNormal(norm);

                            ribbon.addVertex(glm::vec3(p1.x, p1.y, total_depth+gap));
                            ribbon.addColor(sideCol);
                            ribbon.addNormal(norm);
                            ribbon.addVertex(glm::vec3(p2.x, p2.y, total_depth+gap));
                            ribbon.addColor(sideCol);
                            ribbon.addNormal(norm);
                            ribbon.addVertex(glm::vec3(p2.x, p2.y, total_depth));
                            ribbon.addColor(sideCol);
                            ribbon.addNormal(norm);
                            
                            ribbon.addIndex(newV); //connect the first vertex we made, v0
                            ribbon.addIndex(newV+1); //to v1
                            ribbon.addIndex(newV+2); //to v2 to complete the face
                            ribbon.addIndex(newV+3); //now start a new face beginning with v1
                            ribbon.addIndex(newV+4); //that is connected to v2
                            ribbon.addIndex(newV+5);
                    }}

Thanks so much!!

1 Like