void setup() { vid.initGrabber(w, h); mesh.setMode(OF_PRIMITIVE_POINTS); mesh.addVertices(vector<ofVec3f>(n)); mesh.addColors(vector<ofFloatColor>(n)); }
void MeshHelper::fuseNeighbours( ofMesh& outputMesh, const ofMesh& sourceMesh, float fuseDistance ) { //@todo tex coords, normals assert( sourceMesh.getMode() == OF_PRIMITIVE_TRIANGLES ); if ( fuseDistance < 0 ) { // fuse close-enough vertices // first define 'close enough' as 1/10000 of smallest dimension of the bounding box width/height/depth ofVec3f tlb, brf; // top left back, bottom right front calculateAABoundingBox( sourceMesh, tlb, brf ); float minDimension = min(brf.x-tlb.x,min(brf.y-tlb.y, brf.z-tlb.z)); fuseDistance = minDimension * 0.00001f; } // now fuse map<int,int> fused; vector<ofVec3f> vertices; for ( int i=0; i<sourceMesh.getNumVertices(); i++ ) { const ofVec3f& vertex = sourceMesh.getVertex(i); //vertex.rotate(10, 10, 10); bool didFuse = false; for ( int j=0; j<vertices.size(); j++ ) { if ( (vertex-vertices[j]).length()<fuseDistance ) { // fuse i to j fused[i] = j; didFuse = true; break; } } if ( !didFuse ) { vertices.push_back( vertex ); fused[i] = vertices.size()-1; } } // build the output mesh outputMesh.clear(); outputMesh.addVertices(vertices); if ( sourceMesh.getNumIndices() > 0 ) { // walk through indices to build up the new mesh const vector<ofIndexType>& indices = sourceMesh.getIndices(); for ( int i=0; i<indices.size(); i+=3 ) { assert( fused.find( indices[i] ) != fused.end() ); assert( fused.find( indices[i+1] ) != fused.end() ); assert( fused.find( indices[i+2] ) != fused.end() ); outputMesh.addTriangle( fused[indices[i]], fused[indices[i+1]], fused[indices[i+2]] ); } } else { // triangles are just triples of vertices for ( int i=0; i<sourceMesh.getNumVertices(); i+=3 ) { outputMesh.addTriangle( fused[i], fused[i+1], fused[i+2] ); } } ofLogNotice("MeshHelper") << "fuseNeighbours: input " << sourceMesh.getNumVertices() << " vertices/" << sourceMesh.getNumIndices() << " indices, output " << outputMesh.getNumVertices() << " vertices/" << outputMesh.getNumIndices() << " indices"; }
void MeshHelper::appendMesh( ofMesh& targetMesh, const ofMesh& toAppend, bool fuse ) { ofIndexType indexOffset = targetMesh.getNumVertices(); targetMesh.addVertices( toAppend.getVertices() ); // append indices const vector<ofIndexType>& indices = toAppend.getIndices(); for ( int i=0; i<indices.size(); i++ ) { targetMesh.addIndex( indices[i]+indexOffset ); } if ( fuse ) fuseNeighbours(targetMesh); }
//---------------------------------------------------------- void ofTessellator::performTessellation(ofPolyWindingMode polyWindingMode, ofMesh& dstmesh, bool bIs2D ) { if (!tessTesselate(cacheTess, polyWindingMode, TESS_POLYGONS, 3, 3, 0)){ ofLogError("ofTessellator") << "performTessellation(): mesh polygon tessellation failed, winding mode " << polyWindingMode; return; } int numVertices = tessGetVertexCount( cacheTess ); int numIndices = tessGetElementCount( cacheTess )*3; dstmesh.clear(); dstmesh.addVertices((ofDefaultVertexType*)tessGetVertices(cacheTess),numVertices); dstmesh.addIndices((ofIndexType*)tessGetElements(cacheTess),numIndices); /*ofIndexType * tessElements = (ofIndexType *)tessGetElements(cacheTess); for(int i=0;i<numIndices;i++){ if(tessElements[i]!=TESS_UNDEF) dstmesh.addIndex(tessElements[i]); }*/ dstmesh.setMode(OF_PRIMITIVE_TRIANGLES); }
void CloudsVisualSystem3DModelLoader::facetMesh( ofMesh& smoothedMesh, ofMesh& targetMesh ) { //get our vertex, uv and face info vector<ofVec3f>& v = smoothedMesh.getVertices(); vector<ofVec2f>& uv = smoothedMesh.getTexCoords(); vector<ofIndexType>& indices = smoothedMesh.getIndices(); bool hasTC = smoothedMesh.getNumTexCoords(); //use these to store our new mesh info vector<ofVec3f> facetedVertices( indices.size() ); vector<ofVec3f> facetedNormals( indices.size() ); vector<ofVec2f> facetedTexCoords; if(hasTC){ facetedTexCoords.resize( indices.size() ); } vector<ofIndexType> facetedIndices( indices.size() ); //store vertex and uv data for (int i=0; i < indices.size(); i++) { facetedIndices[i] = i; facetedVertices[i] = v[indices[i]]; if(hasTC) facetedTexCoords[i] = uv[indices[i]]; } //calculate our face normals ofVec3f n; for (int i=0; i < facetedIndices.size(); i+=3) { n = normalFrom3Points( facetedVertices[i], facetedVertices[i+1], facetedVertices[i+2]); facetedNormals[i] = n; facetedNormals[i+1] = n; facetedNormals[i+2] = n; } //setup our faceted mesh. this should still work if our targetMesh is our smoothMesh targetMesh.clear(); targetMesh.addVertices( facetedVertices ); targetMesh.addNormals( facetedNormals ); if(hasTC) targetMesh.addTexCoords( facetedTexCoords ); targetMesh.addIndices( facetedIndices ); }
void getCellMesh(voro::voronoicell &_c, ofPoint _pos, ofMesh& mesh ){ if( _c.p ) { ofPoint centroid = getCellCentroid(_c,_pos); int i,j,k,l,m,n; // Vertex // double *ptsp=_c.pts; vector<ofPoint> vertices; vector<ofPoint> normals; for(i = 0; i < _c.p; i++, ptsp+=3){ ofPoint newPoint; newPoint.x = _pos.x + ptsp[0]*0.5; newPoint.y = _pos.y + ptsp[1]*0.5; newPoint.z = _pos.z + ptsp[2]*0.5; vertices.push_back(newPoint); ofPoint newNormal; newNormal = _pos - newPoint;//centroid ; newNormal = newNormal.normalize(); normals.push_back(newNormal); } // ofMesh mesh; mesh.setMode(OF_PRIMITIVE_TRIANGLES ); mesh.addVertices(vertices); mesh.addNormals(normals); // Index // for(i = 1; i < _c.p; i++){ for(j = 0; j < _c.nu[i]; j++) { k = _c.ed[i][j]; if( k >= 0 ) { _c.ed[i][j]=-1-k; l = _c.cycle_up( _c.ed[i][ _c.nu[i]+j], k); m = _c.ed[k][l]; _c.ed[k][l]=-1-m; while(m!=i) { n = _c.cycle_up( _c.ed[k][ _c.nu[k]+l],m); mesh.addTriangle(i, k, m); k=m; l=n; m=_c.ed[k][l]; _c.ed[k][l]=-1-m; } } } } // return mesh; } // return ofMesh(); };
void CloudsVisualSystem3DModelLoader::smoothMesh( ofMesh& facetedMesh, ofMesh& targetMesh, int precision) { cout << "smoothing mesh" << endl; //get our vertex, uv and face info vector<ofVec3f>& v = facetedMesh.getVertices(); vector<ofVec2f>& uv = facetedMesh.getTexCoords(); vector<ofIndexType>& indices = facetedMesh.getIndices(); bool hasTC = facetedMesh.getNumTexCoords(); //use these to store our new mesh info map<string, unsigned int> mergeMap; vector<ofVec3f> smoothVertices; vector<ofVec3f> smoothNormals; vector<ofVec2f> smoothTexCoords; vector<ofIndexType> smoothIndices; //merge our vertices by pointing near by vertices to the same index for (int i=0; i<v.size(); i++) { mergeMap[ vec3ToString( v[i], precision ) ] = i; } //fill our smoothed vertex array with merged vertices & tex coords smoothVertices.resize( mergeMap.size() ); if(hasTC) smoothTexCoords.resize( mergeMap.size() ); int smoothVertexCount = 0; for (map<string, unsigned int>::iterator it = mergeMap.begin(); it != mergeMap.end(); it++) { smoothVertices[smoothVertexCount] = v[it->second]; if(hasTC) smoothTexCoords[smoothVertexCount] = uv[it->second]; it->second = smoothVertexCount;//store our new vertex index smoothVertexCount++; } //reconstruct our faces by reassigning their indices to the merged vertices smoothIndices.resize( indices.size() ); for (int i=0; i<indices.size(); i++) { //use our old vertex poisition to retrieve our new index smoothIndices[i] = mergeMap[ vec3ToString( v[ indices[i] ], precision ) ]; } //calculate our normals smoothNormals.resize( smoothVertices.size() ); ofVec3f n; for (int i=0; i<smoothIndices.size(); i+=3) { n = normalFrom3Points( smoothVertices[smoothIndices[i]], smoothVertices[smoothIndices[i+1]], smoothVertices[smoothIndices[i+2]] ); smoothNormals[smoothIndices[i]] += n; smoothNormals[smoothIndices[i+1]] += n; smoothNormals[smoothIndices[i+2]] += n; } for (int i=0; i<smoothNormals.size(); i++) { smoothNormals[i].normalize(); } //setup our smoothed mesh. this should still work if our targetMesh is our facetedMesh targetMesh.clear(); targetMesh.addVertices( smoothVertices ); targetMesh.addNormals( smoothNormals ); if(hasTC) targetMesh.addTexCoords( smoothTexCoords ); targetMesh.addIndices( smoothIndices ); }