www.pudn.com > View3D.zip > HE_mesh.cpp
#include "HE_mesh.h" #include "SA_stralgo.h" #include#include #include #include using namespace std; int HE_Mesh::LoadWaveFrontObj(char * filename) { ifstream infile; infile.open(filename); if(infile.fail()) cout<<"open file "< vposlist; char line[256]; memset(line,0,256); int i; float px,py,pz; int v1,v2,v3; char temp[32]; string linestr; int pos1,pos2; vector segment; while(!infile.eof()){ memset(line,0,256); infile.getline(line,256); // cout< co[0] = px; V->co[1] = py; V->co[2] = pz; V->index = verts.size; verts.append(V); vpos = verts.end; vposlist.push_back(vpos); } else if(line[0] == 'f' && line[1] == ' '){ HE_Face *F = new HE_Face; HE_HalfEdge *E1,*E2,*E3; E1 = new HE_HalfEdge; E2 = new HE_HalfEdge; E3 = new HE_HalfEdge; HE_Face *f; linestr = line; segment = StringAlgo::split(linestr); int nverts = segment.size()-1; vector vv; vv.clear(); for(i=0;i start = vpos; E1->index = edges.size; vpos->outedge = E1; edges.prepend(E1); vpos = vposlist[v2]; E2->start = vpos; E2->index = edges.size; vpos->outedge = E2; edges.prepend(E2); vpos = vposlist[v3]; E3->start = vpos; E3->index = edges.size; vpos->outedge = E3; edges.prepend(E3); F->edge = E1; F->index = faces.size; faces.prepend(F); E1->nextedge = E2; E2->nextedge = E3; E3->nextedge = E1; E1->face = F; E2->face = F; E3->face = F; }else{} } cout<<"Vertex : "< co[0]; float xmax = xmin; float ymin = vpos->co[1]; float ymax = ymin; float zmin = vpos->co[2]; float zmax = zmin; for(vpos=verts.begin;vpos;vpos=vpos->next){ xmin = MIN(xmin,vpos->co[0]); xmax = MAX(xmax,vpos->co[0]); ymin = MIN(ymin,vpos->co[1]); ymax = MAX(ymax,vpos->co[1]); zmin = MIN(zmin,vpos->co[2]); zmax = MAX(zmax,vpos->co[2]); } center[0] = (xmin+xmax)/2.0; center[1] = (ymin+ymax)/2.0; center[2] = (zmin+zmax)/2.0; for(vpos=verts.begin;vpos;vpos=vpos->next){ vpos->co[0] -= center[0]; vpos->co[1] -= center[1]; vpos->co[2] -= center[2]; } return 1; } int HE_Mesh::GetReverseEdge() { HE_HalfEdge *e1,*e2; for(e1=edges.begin;e1;e1=e1->next){ if(e1->reverse!=NULL) continue; for(e2=e1;e2;e2=e2->next){ if((e1->start == e2->nextedge->start) && (e2->start == e1->nextedge->start)){ e1->reverse = e2; e2->reverse = e1; break; } } if(e1->reverse == NULL){ e1->flag = EDGE_NO_REVERSE; } } return 1; } vector HE_Mesh::VSurroundVertices(HE_Vert * vpos) { HE_HalfEdge * ep = vpos->outedge->nextedge; HE_Vert * vp = ep->start; assert(ep!=NULL); assert(vp!=NULL); vector sv; sv.push_back(vp); while(true){ ep = ep->nextedge->reverse->nextedge; assert(ep!=NULL); assert(ep->start!=NULL); if(ep->start == sv[0]) break; sv.push_back(ep->start); } return sv; } vector HE_Mesh::VSurroundEdges(HE_Vert * vpos) { HE_HalfEdge * ep = vpos->outedge; vector se; se.push_back(ep); while(true){ ep = ep->nextedge->nextedge->reverse; if(ep==se[0]) break; se.push_back(ep); } return se; } int HE_Mesh::CalcEdgeLength(HE_HalfEdge * epos) { HE_Vert *vp1,*vp2; vp1 = epos->start; vp2 = epos->nextedge->start; epos->length = GeometryAlgo::Distance(vp1->co,vp2->co); return 1; } int HE_Mesh::CalcAllEdgeLength() { HE_HalfEdge * epos; for(epos=edges.begin;epos;epos=epos->next){ CalcEdgeLength(epos); } return 1; } int HE_Mesh::Gauss_Curvature(HE_Vert* vpos) { vector sv = VSurroundVertices(vpos); if(sv.size()==0) return 0; int i; float theta = 0.0; for(i=0;i co,vpos->co,sv[i+1]->co); } i = sv.size()-1; theta += GeometryAlgo::CalcAngle3P(sv[i]->co,vpos->co,sv[0]->co); vpos->gauss_cur = 2*PI-theta; return 1; } int HE_Mesh::Gauss_CurvatureAll() { HE_Vert * vpos; for(vpos=verts.begin;vpos;vpos=vpos->next){ Gauss_Curvature(vpos); } cout<<"Calculate All Vertices' Gauss Curvature Finished!"< next){ if(PM_CanCollapse(epos)==1){ vp1 = epos->start; vp2 = epos->nextedge->start; weight = epos->length+ABS(vp1->gauss_cur)+ABS(vp2->gauss_cur); if(minweight > weight){ minweight = weight; eret = epos; } } } return eret; } int HE_Mesh::PM_CanCollapse(HE_HalfEdge * epos) { assert(epos!=NULL); HE_HalfEdge *e1,*e2,*e3,*e4,*e5,*e6; e1 = epos; assert(e1!=NULL); e2 = e1->nextedge; assert(e2!=NULL); e3 = e2->nextedge; assert(e3!=NULL); e4 = e1->reverse; assert(e4!=NULL); e5 = e4->nextedge; assert(e5!=NULL); e6 = e5->nextedge; assert(e6!=NULL); assert(e6->nextedge == e4); assert(e3->nextedge == e1); if(e3->reverse->nextedge->reverse == e6->reverse->nextedge) return 0; int t = 0; HE_Vert *vp1,*vp2; vp1 = epos->start; vp2 = epos->nextedge->start; assert(e4->start == vp2); assert(e1->start == vp1); vector sv1,sv2; sv1 = VSurroundVertices(vp1); sv2 = VSurroundVertices(vp2); int i,j; t = 0; for(i=0;i nextedge; assert(e2!=NULL); e3 = e2->nextedge; assert(e3!=NULL); e4 = e1->reverse; assert(e4!=NULL); e5 = e4->nextedge; assert(e5!=NULL); e6 = e5->nextedge; assert(e6!=NULL); assert(e6->nextedge == e4); assert(e3->nextedge == e1); assert(e1->face == e2->face); assert(e2->face == e3->face); assert(e4->face == e5->face); assert(e5->face == e6->face); HE_Vert *vp1,*vp2; vp1 = epos->start; vp2 = epos->nextedge->start; assert(vp2==epos->reverse->start); vector se2 = VSurroundEdges(vp2); for(i=0;i start = vp1; } assert(e6->reverse->start == vp1); vp1->outedge = e6->reverse; e3->start->outedge = e2->reverse; e6->start->outedge = e5->reverse; e5->reverse->reverse = e6->reverse; e6->reverse->reverse = e5->reverse; e2->reverse->reverse = e3->reverse; e3->reverse->reverse = e2->reverse; faces.erase(e1->face); faces.erase(e4->face); e1->face = NULL; e4->face = NULL; edges.erase(e1); edges.erase(e2); edges.erase(e3); edges.erase(e4); edges.erase(e5); edges.erase(e6); verts.erase(vp2); vp2 = NULL; e1 = NULL; e2 = NULL; e3 = NULL; e4 = NULL; e5 = NULL; e6 = NULL; vector se = VSurroundEdges(vp1); Gauss_Curvature(vp1); for(i=0;i nextedge->start); CalcEdgeLength(se[i]); } return 1; } vector HE_Mesh::FSurroundVertices(HE_Face * fpos) { HE_HalfEdge* epos; vector ret; epos = fpos->edge; ret.push_back(epos->start); while(true){ epos = epos->nextedge; if(epos->start == ret[0]){ break; } ret.push_back(epos->start); } return ret; } int HE_Mesh::FCalculateNormFace(HE_Face * fpos) { assert(fpos!=NULL); vector sv = FSurroundVertices(fpos); GeometryAlgo::CalcNormFloat(sv[0]->co,sv[1]->co,sv[2]->co,fpos->no); return 1; } int HE_Mesh::FCalculateNormAllFace() { int i; HE_Face * fpos; for(fpos = faces.begin;fpos;fpos=fpos->next){ vector sv = FSurroundVertices(fpos); if(sv.size()<3) return 0; GeometryAlgo::CalcNormFloat(sv[0]->co,sv[1]->co,sv[2]->co,fpos->no); for(i=0;i no[0] += fpos->no[0]; sv[i]->no[1] += fpos->no[1]; sv[i]->no[2] += fpos->no[2]; } } HE_Vert * vpos; for(vpos=verts.begin; vpos;vpos=vpos->next){ GAMath::Normalise(vpos->no); } return 1; }