Created
August 9, 2012 06:46
-
-
Save atduskgreg/3301755 to your computer and use it in GitHub Desktop.
Calculate DAG of vertex connectivity for ofMesh, use that DAG to perform a Laplacian smooth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef map<ofIndexType, vector<ofIndexType> > VertexGraph; | |
// build a DAG representing the connectivity | |
// between vertices in a mesh | |
// assumes vertices are inserted as triangles | |
// i.e. each triplet of vertices is treated as the corners | |
// of a single triangle | |
VertexGraph testApp::buildGraph(ofMesh &m){ | |
typedef VertexGraph::iterator I; | |
VertexGraph result; | |
// iterate through the indices in sets of three | |
// adding the neighbor relationships for the | |
// indices in each triangle | |
for(int tri = 0; tri < m.getIndices().size(); tri+=3){ | |
ofIndexType v1 = m.getIndices()[tri]; | |
vector<ofIndexType> n1; | |
// 0->1 | |
// 0->2 | |
n1.push_back(m.getIndices()[tri+1]); | |
n1.push_back(m.getIndices()[tri+2]); | |
std::pair<I,bool> const& r=result.insert(VertexGraph::value_type(v1, n1)); | |
// we already have neighbors for this index | |
// so append these new ones | |
if(!r.second){ | |
vector<ofIndexType> toInsert = r.first->second; | |
toInsert.push_back(n1.at(0)); | |
toInsert.push_back(n1.at(1)); | |
result.insert(VertexGraph::value_type(v1, toInsert)); | |
} | |
// 1->0 | |
// 1->2 | |
ofIndexType v2= m.getIndices()[tri+1]; | |
vector<ofIndexType> n2; | |
n2.push_back(m.getIndices()[tri+0]); | |
n2.push_back(m.getIndices()[tri+2]); | |
std::pair<I,bool> const& r2=result.insert(VertexGraph::value_type(v2, n2)); | |
if(!r2.second){ | |
vector<ofIndexType> toInsert = r.first->second; | |
toInsert.push_back(n2.at(0)); | |
toInsert.push_back(n2.at(1)); | |
result.insert(VertexGraph::value_type(v2, toInsert)); | |
} | |
// 2->0 | |
// 2->1 | |
ofIndexType v3= m.getIndices()[tri+2]; | |
vector<ofIndexType> n3; | |
n3.push_back(m.getIndices()[tri+0]); | |
n3.push_back(m.getIndices()[tri+1]); | |
std::pair<I,bool> const& r3=result.insert(VertexGraph::value_type(v3, n3)); | |
// we already have neighbors for this index | |
if(!r3.second){ | |
vector<ofIndexType> toInsert = r.first->second; | |
toInsert.push_back(n3.at(0)); | |
toInsert.push_back(n3.at(1)); | |
result.insert(VertexGraph::value_type(v3, toInsert)); | |
} | |
} | |
return result; | |
} | |
// laplacian smooth for vertices of an ofMesh with indices | |
// algorithm adapted from here: http://accu.org/index.php/journals/1526 | |
ofMesh testApp::performSmooth(ofMesh &m, float relaxationFactor){ | |
ofMesh result; | |
for(int i = 0; i < m.getVertices().size(); i++){ | |
ofVec3f vert = m.getVertices().at(i); | |
// get adjacent vertices | |
vector<ofIndexType> neighbors = connectivityGraph[i]; | |
for(int n = 0; n < neighbors.size(); n++ ){ | |
ofIndexType neighborIndex = neighbors.at(n); | |
ofVec3f offset = m.getVertices().at(neighborIndex) - m.getVertices().at(i); | |
offset *= relaxationFactor / neighbors.size(); | |
vert += offset; | |
} | |
result.addVertex(vert); | |
} | |
return result; | |
} | |
void testApp::smoothMesh(ofMesh & m, int iterations){ | |
vector<ofIndexType> originalIndices = m.getIndices(); | |
for(int i = 0; i < iterations; i++){ | |
cout << "performing iteration " << i << endl; | |
m = performSmooth(m, 0.5); | |
} | |
m.addIndices(originalIndices); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I am having a look at this, which looks awesome, but I am not sure what is connectivityGraph[i]?