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;istart = 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;ico,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;inextedge;    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;istart = 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;inextedge->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;ino[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;
}