用Qt实现,具体算法内容可自行百度。算法只对原始边进行了收缩,其后,新增边的处理存在bug,导致模型出现空洞,若有大佬知晓原因,望告知。
void MeshSimplifying(){
//网格简化操作
if(minHeap.empty())
return();
else{
Vertex *one=minHeap.top()->first;
Vertex *two=minHeap.top()->second;
Vertex *fine=minHeap.top()->final;
pair st=minHeap.top()->match;
if(one->IsSimplified||two->IsSimplified){
minHeap.pop();
return;
}
one->IsSimplified=true;
two->IsSimplified=true;
Face *face1;
Face *face2;
if(mesh->MAPedge.count(make_pair(st.first,st.second))!=0)
face1=mesh->MAPedge[make_pair(st.first,st.second)]->IncFace;
else return;
if(mesh->MAPedge.count(make_pair(st.second,st.first))!=0)
face2=mesh->MAPedge[make_pair(st.second,st.first)]->IncFace;
else return;
face1->live=false;
face2->live=false;
int number=fine->ID;
halfEdge* it;
for(set::iterator pp=one->neighbors.begin() ;pp!=one->neighbors.end();pp++){
if(mesh->MAPedge.count(make_pair(st.first,*pp))!=0){
it=mesh->MAPedge[make_pair(st.first,*pp)];
if(it->IncFace->live){
if(it!=NULL){
mesh->MAPedge.insert(map,halfEdge*>::value_type(make_pair(number,*pp),it));
it->origin=fine;
fine->edge=it;
fine->neighbors.insert(*pp);
if(*ppnverts){
mesh->verts[*pp].neighbors.insert(number);
if(mesh->verts[*pp].neighbors.count(st.first)!=0)
mesh->verts[*pp].neighbors.erase(st.first);
}else{
addVertices[*pp].neighbors.insert(number);
if(addVertices[*pp].neighbors.count(st.first)!=0)
addVertices[*pp].neighbors.erase(st.first);
}
VertexPairs* a=computePosition(make_pair(number,*pp),it);
twiceHeap.push(a);
//该面的法向量计算
Face& face=*it->IncFace;
for(int index=0;indexnverts){
v1 = &mesh->verts[face.record[i]];
}else{
v1=&addVertices[face.record[i]];
}
if(face.record[(i+1)%face.nverts]nverts){
v2 = &mesh->verts[face.record[(i+1)%face.nverts]];
}else{
v2=&addVertices[face.record[(i+1)%face.nverts]];
}
face.normal[0] += (v1->y - v2->y) * (v1->z + v2->z);
face.normal[1] += (v1->z - v2->z) * (v1->x + v2->x);
face.normal[2] += (v1->x - v2->x) * (v1->y + v2->y);
}
// Normalize normal for face
float squared_normal_length = 0.0;
squared_normal_length += face.normal[0]*face.normal[0];
squared_normal_length += face.normal[1]*face.normal[1];
squared_normal_length += face.normal[2]*face.normal[2];
float normal_length = sqrt(squared_normal_length);
if (normal_length > 1.0E-6) {
face.normal[0] /= normal_length;
face.normal[1] /= normal_length;
face.normal[2] /= normal_length;
}
mesh->MAPedge.erase(make_pair(st.first,*pp));
}
}
}
if(mesh->MAPedge.count(make_pair(*pp,st.first))!=0){
it=mesh->MAPedge[make_pair(*pp,st.first)];
if(it->IncFace->live){
if(it!=NULL){
if(it->IncFace->live){
Face &face=*it->IncFace;
for(int index=0;indexMAPedge.insert(map,halfEdge*>::value_type(make_pair(*pp,number),it));
//if(*pp!=st.second)
mesh->MAPedge.erase(make_pair(*pp,st.first));
}
}
}
}
for(set::iterator pp=two->neighbors.begin() ;pp!=two->neighbors.end();pp++){
if(mesh->MAPedge.count(make_pair(st.second,*pp))!=0){
it=mesh->MAPedge[make_pair(st.second,*pp)];
if(it->IncFace->live){
if(it!=NULL){
mesh->MAPedge.insert(map,halfEdge*>::value_type(make_pair(number,*pp),it));
it->origin=fine;
fine->neighbors.insert(*pp);
if(*ppnverts){
mesh->verts[*pp].neighbors.insert(number);
if(mesh->verts[*pp].neighbors.count(st.second)!=0)
mesh->verts[*pp].neighbors.erase(st.second);
}else{
addVertices[*pp].neighbors.insert(number);
if(addVertices[*pp].neighbors.count(st.second)!=0)
addVertices[*pp].neighbors.erase(st.second);
}
VertexPairs* a=computePosition(make_pair(number,*pp),it);
twiceHeap.push(a);
//计算该面的法向量
Face &face=*it->IncFace;
face=*it->IncFace;
for(int index=0;indexnverts){
v1 = &mesh->verts[face.record[i]];
}else{
v1=&addVertices[face.record[i]];
}
if(face.record[(i+1)%face.nverts]nverts){
v2 = &mesh->verts[face.record[(i+1)%face.nverts]];
}else{
v2=&addVertices[face.record[(i+1)%face.nverts]];
}
face.normal[0] += (v1->y - v2->y) * (v1->z + v2->z);
face.normal[1] += (v1->z - v2->z) * (v1->x + v2->x);
face.normal[2] += (v1->x - v2->x) * (v1->y + v2->y);
}
// Normalize normal for face
float squared_normal_length = 0.0;
squared_normal_length += face.normal[0]*face.normal[0];
squared_normal_length += face.normal[1]*face.normal[1];
squared_normal_length += face.normal[2]*face.normal[2];
float normal_length = sqrt(squared_normal_length);
if (normal_length > 1.0E-6) {
face.normal[0] /= normal_length;
face.normal[1] /= normal_length;
face.normal[2] /= normal_length;
}
mesh->MAPedge.erase(make_pair(st.second,*pp));
}
}
}
if(mesh->MAPedge.count(make_pair(*pp,st.second))!=0){
it=mesh->MAPedge[make_pair(*pp,st.second)];
if(it!=NULL){
if(it->IncFace->live){
Face& face=*it->IncFace;
for(int index=0;indexMAPedge.insert(map,halfEdge*>::value_type(make_pair(*pp,number),it));
mesh->MAPedge.erase(make_pair(*pp,st.second));
}
}
}
}
minHeap.pop();
}
}
原模型:
:处理后的模型