VCRA-SZCZERBACKI-PointBasedRendering/Mesh.cpp

00001 #include "Mesh.h"
00002 #include <set>
00003 #include <deque>
00004 
00005 //=======================================================================
00006 //=======================================================================
00007 
00008 UINT8 *Mesh::m_fileptr = NULL;
00009 UINT8 *Mesh::m_nextchunkptr = NULL;
00010 UINT8 *Mesh::m_nextsubchunkptr = NULL;
00011 UINT8 *Mesh::m_fileend = NULL;
00012 UINT8 *Mesh::m_readptr = NULL;
00013 
00014 //=======================================================================
00015 //=======================================================================
00016 
00017 Mesh::Mesh()
00018 {
00019         m_ambiguousNeighbours = 0;
00020         m_adjacencyCalculated = false;
00021         m_filename = "";
00022 }
00023 
00024 //=======================================================================
00025 //=======================================================================
00026 
00027 Mesh::Mesh( int vertices, int triangles )
00028 {
00029         SS_ASSERT(vertices > 0);
00030         SS_ASSERT(triangles > 0);
00031 
00032         m_ambiguousNeighbours = 0;
00033         m_adjacencyCalculated = false;
00034         m_filename = "";
00035         m_vertices.resize(vertices);
00036         m_triangles.resize(triangles);
00037 }
00038 
00039 //=======================================================================
00040 //=======================================================================
00041 
00042 Mesh::Mesh( const char *fileName )
00043 {
00044         load( fileName );
00045 }
00046 
00047 //=======================================================================
00048 //=======================================================================
00049 
00050 Mesh::Mesh( const Mesh &m )
00051 {
00052         m_vertices = m.m_vertices;
00053         m_triangles = m.m_triangles;
00054         m_edges = m.m_edges;
00055         m_surfaces = m.m_surfaces;
00056         m_filename = m.m_filename;
00057 
00058         m_boundingBoxMin = m.m_boundingBoxMin;
00059         m_boundingBoxMax = m.m_boundingBoxMax;
00060         m_boundingRadius = m.m_boundingRadius;
00061         m_ambiguousNeighbours = m.m_ambiguousNeighbours;
00062         m_adjacencyCalculated = m.m_adjacencyCalculated;
00063 }
00064 
00065 //=======================================================================
00066 //=======================================================================
00067 
00068 Mesh::~Mesh()
00069 {
00070 }
00071 
00072 //=======================================================================
00073 //=======================================================================
00074 
00075 void Mesh::load( const char *fileName )
00076 {
00077         svPrint("loading %s\n",fileName);
00078 
00079         m_vertices.clear();
00080         m_triangles.clear();
00081         m_edges.clear();
00082         m_surfaces.clear();
00083 
00084         m_ambiguousNeighbours = 0;
00085         m_adjacencyCalculated = false;
00086 
00087         m_filename = fileName;
00088 
00089         FILE    *pF;
00090         if( (pF = fopen( fileName, "rb" )) != NULL )
00091         {
00092                 fseek( pF, 0L, SEEK_END );
00093                 UINT32 l = ftell( pF );
00094                 fseek( pF, 0L, SEEK_SET );
00095 
00096                 m_fileptr = new UINT8[l];
00097 
00098                 if( (fread( m_fileptr, sizeof(char), l, pF )) != l)
00099                 {
00100                         svError( STR("error while reading file '%s'",fileName) );
00101                 }
00102                 fclose( pF );
00103         }
00104         else
00105         {
00106                 svError( STR("couldn't open file '%s'",fileName) );
00107         }
00108         m_readptr = m_fileptr;
00109 
00110         if(readID4() != 'FORM')
00111         {
00112                 svError("not a valid IFF file");
00113         }
00114 
00115         m_fileend = m_fileptr + readU4();
00116 
00117         UINT32 i = readID4();
00118         if(i == 'LWOB') loadLW5();
00119         else if(i == 'LWO2') loadLW6();
00120         else svError("not a LWO file");
00121 
00122         delete[] m_fileptr;
00123 
00124         svPrint("polys %d vertices %d surfaces %d\n",m_triangles.size(),m_vertices.size(),m_surfaces.size());
00125 }
00126 
00127 //=======================================================================
00128 //=======================================================================
00129 
00130 void Mesh::calculateAdjacency()
00131 {
00132         if( m_adjacencyCalculated ) return;
00133 
00134         svPrint("calculating polygon adjacency\n");
00135 
00136         std::set<Edge> edgeset;
00137 
00138         m_edges.clear();
00139 
00140         //create a set of edges + calculate neighbourhood information
00141         //O(T log E)
00142         m_ambiguousNeighbours = 0;
00143         for(int i=0;i<m_triangles.size();++i)
00144         {
00145                 for(int j=0;j<3;j++)
00146                 {
00147                         m_triangles[i].m_n[j] = -1;
00148 
00149                         int k = (j+1)%3;
00150                         Edge edge;
00151                         edge.m_v[0] = min2(m_triangles[i].m_v[j],m_triangles[i].m_v[k]);
00152                         edge.m_v[1] = max2(m_triangles[i].m_v[j],m_triangles[i].m_v[k]);
00153                         edge.m_t[0] = i;
00154                         edge.m_t[1] = -1;
00155                         std::pair<std::set<Edge>::iterator,bool> ret = edgeset.insert( edge );  //O(log E)
00156                         if( !ret.second )
00157                         {       //already exists, check if it already has 2 triangles
00158                                 if( (*ret.first).m_t[1] != -1 ) ++m_ambiguousNeighbours;
00159                                 else
00160                                 {       //neighbour found, update information
00161                                         (*ret.first).m_t[1] = i;
00162                                         int n = (*ret.first).m_t[0];
00163                                         int ne;
00164                                         if( edge.m_v[0] == m_triangles[n].m_v[0] )
00165                                         {
00166                                                 if( edge.m_v[1] == m_triangles[n].m_v[1] ) ne = 0;
00167                                                 else if( edge.m_v[1] == m_triangles[n].m_v[2] ) ne = 2;
00168                                         }
00169                                         else if( edge.m_v[0] == m_triangles[n].m_v[1] )
00170                                         {
00171                                                 if( edge.m_v[1] == m_triangles[n].m_v[0] ) ne = 0;
00172                                                 else if( edge.m_v[1] == m_triangles[n].m_v[2] ) ne = 1;
00173                                         }
00174                                         else if( edge.m_v[0] == m_triangles[n].m_v[2] )
00175                                         {
00176                                                 if( edge.m_v[1] == m_triangles[n].m_v[0] ) ne = 2;
00177                                                 else if( edge.m_v[1] == m_triangles[n].m_v[1] ) ne = 1;
00178                                         }
00179                                         m_triangles[i].m_n[j] = n;
00180                                         m_triangles[i].m_nedge[j] = ne;
00181                                         m_triangles[n].m_n[ne] = i;
00182                                         m_triangles[n].m_nedge[ne] = j;
00183                                 }
00184                         }
00185                 }
00186         }
00187 
00188         //copy edges to vector
00189         //O( E )
00190         int i=0;
00191         int interior = 0,boundary = 0;
00192         m_edges.resize( edgeset.size() );
00193         std::set<Edge>::iterator it = edgeset.begin();
00194         while( it != edgeset.end() )
00195         {
00196                 m_edges[i] = (*it);
00197                 if( m_edges[i].m_t[1] == -1 ) ++boundary;
00198                 else ++interior;
00199                 ++it;
00200                 ++i;
00201         }
00202 
00203         svPrint("edges %d interior edges %d boundary edges %d\n",m_edges.size(),interior,boundary);
00204         svPrint("edges shared by more than 2 triangles: %d\n",m_ambiguousNeighbours);
00205         m_adjacencyCalculated = true;
00206 }
00207 
00208 //=======================================================================
00209 //=======================================================================
00210 
00211 void Mesh::setParametrization()
00212 {
00213         for(int t=0;t<m_triangles.size();t++)
00214         {
00215                 m_triangles[t].m_uv[0].set(0,0);
00216                 m_triangles[t].m_uv[1].set(1,0);
00217                 m_triangles[t].m_uv[2].set(0,1);
00218                 m_triangles[t].m_baseTriangle = t;
00219         }
00220 }
00221 
00222 //=======================================================================
00223 //=======================================================================
00224 
00225 void Mesh::calculateNormals()
00226 {
00227         //recalculate triangle and vertex normals
00228         for(int i=0;i<m_vertices.size();i++)
00229                 m_vertices[i].m_normal.set(0,0,0);
00230         float area;
00231         for(int t=0;t<m_triangles.size();t++)
00232         {
00233                 Vector3 n,e1,e2;
00234                 e1 = m_vertices[m_triangles[t].m_v[1]].m_position;
00235                 e1 -= m_vertices[m_triangles[t].m_v[0]].m_position;
00236                 e2 = m_vertices[m_triangles[t].m_v[2]].m_position;
00237                 e2 -= m_vertices[m_triangles[t].m_v[0]].m_position;
00238                 n = cross(e1, e2);
00239                 area = n.length();
00240                 m_triangles[t].m_area = 0.5f * area;
00241                 n /= area;
00242                 m_triangles[t].m_normal = n;
00243 
00244                 m_vertices[m_triangles[t].m_v[0]].m_normal += n;
00245                 m_vertices[m_triangles[t].m_v[1]].m_normal += n;
00246                 m_vertices[m_triangles[t].m_v[2]].m_normal += n;
00247         }
00248         for(int i=0;i<m_vertices.size();i++)
00249                 m_vertices[i].m_normal.normalize();
00250 }
00251 
00252 //=======================================================================
00253 //=======================================================================
00254 
00255 void Mesh::setTriangleUsing()
00256 {
00257         for(int i=0;i<m_vertices.size();i++)
00258         {
00259                 m_vertices[i].m_triangleUsing = -1;
00260         }
00261         for(int i=0;i<m_triangles.size();++i)
00262         {
00263                 m_vertices[m_triangles[i].m_v[0]].m_triangleUsing = (i<<2) | 0;
00264                 m_vertices[m_triangles[i].m_v[1]].m_triangleUsing = (i<<2) | 1;
00265                 m_vertices[m_triangles[i].m_v[2]].m_triangleUsing = (i<<2) | 2;
00266         }
00267 }
00268 
00269 //=======================================================================
00270 //=======================================================================
00271 
00272 void Mesh::subdivide( int n )
00273 {
00274         if( n == 0 ) return;
00275         SS_ASSERT(n > 0);
00276 
00277         setTriangleUsing();
00278         calculateAdjacency();
00279         if( m_ambiguousNeighbours ) svError("can't subdivide: '%s' contains %d edges which are shared by more than 2 polygons",m_filename.c_str(),m_ambiguousNeighbours);
00280 
00281         std::vector<Vertex>             vertices2;
00282         std::vector<Triangle>   triangles2;
00283         std::vector<Edge>               edges2;
00284         std::vector<Vertex>             *vIn,*vOut;
00285         std::vector<Triangle>   *tIn,*tOut;
00286         std::vector<Edge>               *eIn,*eOut;
00287 
00288         vIn = &m_vertices;
00289         tIn = &m_triangles;
00290         eIn = &m_edges;
00291         vOut = &vertices2;
00292         tOut = &triangles2;
00293         eOut = &edges2;
00294 
00295 //t(n+1) = t(n) * 4
00296 //e(n+1) = e(n) * 2 + t(n) * 3
00297 //v(n+1) = v(n) + e(n)
00298 
00299 //t(n) = t(0) * 2^2n   , n>=0
00300 //e(n) = e(0) * 2^n + t(0) * 3 * 2^(n-1) * (2^n - 1)   , n>=0
00301 //v(n) = v(0) + e(0) * (2^n - 1) + t(0) * 3 * (2^2n / 6 - 2^(n-1) + 1)  , n > 0
00302 
00303         int ct=m_triangles.size(),cv=m_vertices.size(),ce=m_edges.size();
00304         cv += ce * ((1<<n)-1);
00305         if(n > 1) cv += ct * 3 * ((1<<(2*n)) / 6 + 1 - (1<<(n-1)));
00306         ce *= (1<<n);
00307         ce += ct * 3 * (1<<(n-1)) * ((1<<n) - 1);
00308         ct *= (1<<(2*n));
00309         //TODO reserve (other array (n-1), other n)
00310 //      svPrint("subdivision reserve      v:%d t:%d e:%d\n",cv,ct,ce);
00311 
00312         svPrint("subdivision before       v:%d t:%d e:%d\n",m_vertices.size(),m_triangles.size(),m_edges.size());
00313 
00314         for(int step=0;step<n;step++)
00315         {
00316                 Edge en;
00317 
00318                 *vOut = *vIn;
00319                 tOut->clear();
00320                 eOut->clear();
00321 
00322                 for(int t=0;t<tIn->size();t++)
00323                 {
00324                         //calculate edge midpoints
00325                         int nv[3];
00326                         for(int e=0;e<3;e++)
00327                         {
00328                                 int i1,i2,i3,a3,nbour,nedge;
00329                                 Vertex vn;
00330 
00331                                 i1 = (*tIn)[t].m_v[ (e+0)%3 ];
00332                                 i2 = (*tIn)[t].m_v[ (e+1)%3 ];
00333                                 i3 = (*tIn)[t].m_v[ (e+2)%3 ];
00334 
00335                                 nv[e] = vOut->size();
00336                                 vn.m_triangleUsing = ((t * 4 + e) << 2) | ((e+1)%3);
00337                                 vn.reset();
00338 
00339                                 nbour = (*tIn)[t].m_n[e];
00340                                 if( nbour != -1 )
00341                                 {
00342                                         nedge = (*tIn)[t].m_nedge[e];
00343                                         if( nbour < t )
00344                                         {
00345                                                 //edge is split already
00346                                                 nv[e] = (*tOut)[ nbour * 4 + nedge ].m_v[ (nedge+1)%3 ];
00347                                         }
00348                                         else
00349                                         {
00350                                                 //new vertex
00351                                                 a3 = (*tIn)[ nbour ].m_v[ (nedge+2)%3 ];
00352 
00353                                                 vn.mad( (*vIn)[i1], 0.375f );
00354                                                 vn.mad( (*vIn)[i2], 0.375f );
00355                                                 vn.mad( (*vIn)[i3], 0.125f );
00356                                                 vn.mad( (*vIn)[a3], 0.125f );
00357                                                 vn.normalize();
00358                                                 vOut->push_back( vn );
00359 
00360                                                 en.m_t[0] = t * 4 + e;
00361                                                 en.m_t[1] = nbour * 4 + ((nedge + 1) % 3);
00362                                                 en.m_v[0] = i1;
00363                                                 en.m_v[1] = nv[e];
00364                                                 eOut->push_back( en );
00365 
00366                                                 en.m_t[0] = t * 4 + ((e + 1) % 3);
00367                                                 en.m_t[1] = nbour * 4 + nedge;
00368                                                 en.m_v[0] = nv[e];
00369                                                 en.m_v[1] = i2;
00370                                                 eOut->push_back( en );
00371                                         }
00372                                 }
00373                                 else //boundary
00374                                 {
00375                                         vn.mad( (*vIn)[i1], 0.5f );
00376                                         vn.mad( (*vIn)[i2], 0.5f );
00377                                         vn.normalize();
00378                                         vOut->push_back( vn );
00379 
00380                                         en.m_t[0] = t * 4 + e;
00381                                         en.m_t[1] = -1;
00382                                         en.m_v[0] = i1;
00383                                         en.m_v[1] = nv[e];
00384                                         eOut->push_back( en );
00385 
00386                                         en.m_t[0] = t * 4 + ((e + 1) % 3);
00387                                         en.m_t[1] = -1;
00388                                         en.m_v[0] = nv[e];
00389                                         en.m_v[1] = i2;
00390                                         eOut->push_back( en );
00391                                 }
00392                         }
00393 
00394                         //make new triangles
00395                         Triangle tn;
00396                         int ct = tOut->size();
00397                         tn.m_surface = (*tIn)[t].m_surface;
00398                         tn.m_baseTriangle = (*tIn)[t].m_baseTriangle;
00399 
00400                         tn.m_v[0] = (*tIn)[t].m_v[0];
00401                         tn.m_v[1] = nv[0];
00402                         tn.m_v[2] = nv[2];
00403                         tn.m_n[0] = (*tIn)[t].m_n[0] != -1 ? (*tIn)[t].m_n[0] * 4 + ((*tIn)[t].m_nedge[0] + 1) % 3 : -1;
00404                         tn.m_n[1] = ct + 3;
00405                         tn.m_n[2] = (*tIn)[t].m_n[2] != -1 ? (*tIn)[t].m_n[2] * 4 + (*tIn)[t].m_nedge[2]: -1;
00406                         tn.m_uv[0] = (*tIn)[t].m_uv[0];
00407                         tn.m_uv[1] = 0.5f * ((*tIn)[t].m_uv[1] + (*tIn)[t].m_uv[0]);
00408                         tn.m_uv[2] = 0.5f * ((*tIn)[t].m_uv[2] + (*tIn)[t].m_uv[0]);
00409                         tn.m_nedge[0] = (*tIn)[t].m_nedge[0];
00410                         tn.m_nedge[1] = 0;
00411                         tn.m_nedge[2] = (*tIn)[t].m_nedge[2];
00412                         tOut->push_back( tn );
00413 
00414                         tn.m_v[0] = nv[0];
00415                         tn.m_v[1] = (*tIn)[t].m_v[1];
00416                         tn.m_v[2] = nv[1];
00417                         tn.m_n[0] = (*tIn)[t].m_n[0] != -1 ? (*tIn)[t].m_n[0] * 4 + (*tIn)[t].m_nedge[0]: -1;
00418                         tn.m_n[1] = (*tIn)[t].m_n[1] != -1 ? (*tIn)[t].m_n[1] * 4 + ((*tIn)[t].m_nedge[1] + 1) % 3 : -1;
00419                         tn.m_n[2] = ct + 3;
00420                         tn.m_uv[0] = 0.5f * ((*tIn)[t].m_uv[0] + (*tIn)[t].m_uv[1]);
00421                         tn.m_uv[1] = (*tIn)[t].m_uv[1];
00422                         tn.m_uv[2] = 0.5f * ((*tIn)[t].m_uv[2] + (*tIn)[t].m_uv[1]);
00423                         tn.m_nedge[0] = (*tIn)[t].m_nedge[0];
00424                         tn.m_nedge[1] = (*tIn)[t].m_nedge[1];
00425                         tn.m_nedge[2] = 1;
00426                         tOut->push_back( tn );
00427 
00428                         tn.m_v[0] = nv[2];
00429                         tn.m_v[1] = nv[1];
00430                         tn.m_v[2] = (*tIn)[t].m_v[2];
00431                         tn.m_n[0] = ct + 3;
00432                         tn.m_n[1] = (*tIn)[t].m_n[1] != -1 ? (*tIn)[t].m_n[1] * 4 + (*tIn)[t].m_nedge[1]: -1;
00433                         tn.m_n[2] = (*tIn)[t].m_n[2] != -1 ? (*tIn)[t].m_n[2] * 4 + ((*tIn)[t].m_nedge[2] + 1) % 3 : -1;
00434                         tn.m_uv[0] = 0.5f * ((*tIn)[t].m_uv[0] + (*tIn)[t].m_uv[2]);
00435                         tn.m_uv[1] = 0.5f * ((*tIn)[t].m_uv[1] + (*tIn)[t].m_uv[2]);
00436                         tn.m_uv[2] = (*tIn)[t].m_uv[2];
00437                         tn.m_nedge[0] = 2;
00438                         tn.m_nedge[1] = (*tIn)[t].m_nedge[1];
00439                         tn.m_nedge[2] = (*tIn)[t].m_nedge[2];
00440                         tOut->push_back( tn );
00441 
00442                         tn.m_v[0] = nv[2];
00443                         tn.m_v[1] = nv[0];
00444                         tn.m_v[2] = nv[1];
00445                         tn.m_n[0] = ct;
00446                         tn.m_n[1] = ct + 1;
00447                         tn.m_n[2] = ct + 2;
00448                         tn.m_uv[0] = 0.5f * ((*tIn)[t].m_uv[2] + (*tIn)[t].m_uv[0]);
00449                         tn.m_uv[1] = 0.5f * ((*tIn)[t].m_uv[0] + (*tIn)[t].m_uv[1]);
00450                         tn.m_uv[2] = 0.5f * ((*tIn)[t].m_uv[2] + (*tIn)[t].m_uv[1]);
00451                         tn.m_nedge[0] = 1;
00452                         tn.m_nedge[1] = 2;
00453                         tn.m_nedge[2] = 0;
00454                         tOut->push_back( tn );
00455 
00456                         en.m_t[0] = ct;
00457                         en.m_t[1] = ct + 3;
00458                         en.m_v[0] = nv[0];
00459                         en.m_v[1] = nv[2];
00460                         eOut->push_back( en );
00461 
00462                         en.m_t[0] = ct + 1;
00463                         en.m_t[1] = ct + 3;
00464                         en.m_v[0] = nv[1];
00465                         en.m_v[1] = nv[0];
00466                         eOut->push_back( en );
00467 
00468                         en.m_t[0] = ct + 2;
00469                         en.m_t[1] = ct + 3;
00470                         en.m_v[0] = nv[2];
00471                         en.m_v[1] = nv[1];
00472                         eOut->push_back( en );
00473                 }
00474 
00475                 //move even vertices
00476                 for(int v=0;v<vIn->size();v++)
00477                 {
00478                         if( (*vIn)[v].m_triangleUsing == -1 ) continue; //not used
00479 
00480                         Vertex sum;
00481                         int spoly = (*vIn)[v].m_triangleUsing >> 2,cpoly,npoly,lB,rB;
00482                         int sedge = (*vIn)[v].m_triangleUsing & 3,cedge,nedge,cv;
00483                         SS_ASSERT( sedge >= 0 && sedge < 3 );
00484                         SS_ASSERT( spoly >= 0 && spoly < tIn->size() );
00485                         int valence = 0;
00486                         bool boundary = false;
00487 
00488                         sum.reset();
00489 
00490                         //loop right
00491                         npoly = spoly;
00492                         nedge = sedge;
00493                         do
00494                         {
00495                                 cpoly = npoly;
00496                                 cedge = nedge;
00497 
00498                                 //loop code
00499                                 valence++;
00500                                 cv = (*tIn)[cpoly].m_v[(cedge+1) % 3];
00501                                 sum.add( (*vIn)[cv] );
00502 
00503                                 npoly = (*tIn)[cpoly].m_n[cedge];
00504                                 if( npoly == -1 )
00505                                 {
00506                                         boundary = true;
00507                                         rB = cv;
00508                                         break;
00509                                 }
00510                                 nedge = ((*tIn)[cpoly].m_nedge[cedge] + 1) % 3;
00511                         } while( npoly != spoly );
00512                         if( boundary )
00513                         {
00514                                 npoly = spoly;
00515                                 nedge = (sedge + 2)%3;
00516                                 //loop left
00517                                 do
00518                                 {
00519                                         cpoly = npoly;
00520                                         cedge = nedge;
00521 
00522                                         //loop code
00523                                         valence++;
00524                                         cv = (*tIn)[cpoly].m_v[cedge];
00525                                         sum.add( (*vIn)[cv] );
00526 
00527                                         npoly = (*tIn)[cpoly].m_n[cedge];
00528                                         if( npoly == -1 )
00529                                         {
00530                                                 lB = cv;
00531                                                 break;
00532                                         }
00533                                         nedge = ((*tIn)[cpoly].m_nedge[cedge] + 2) % 3;
00534                                 } while( npoly != spoly );
00535 
00536 
00537                                 (*vOut)[v].reset();
00538                                 (*vOut)[v].mad( (*vIn)[v], 0.75f );
00539                                 (*vOut)[v].mad( (*vIn)[lB], 0.125f );
00540                                 (*vOut)[v].mad( (*vIn)[rB], 0.125f );
00541                                 (*vOut)[v].normalize();
00542                                 (*vOut)[v].m_triangleUsing = ((spoly * 4 + sedge) << 2) | sedge;
00543                         }
00544                         else    //no boundary
00545                         {
00546                                 float beta;
00547                                 if( valence == 3 )
00548                                         beta = 3.0f / 16.0f;
00549                                 else
00550                                         beta = 3.0f / (float(valence) * 8.0f);
00551 
00552                                 (*vOut)[v].reset();
00553                                 (*vOut)[v].mad( (*vIn)[v], (1.0f - float(valence) * beta) );
00554                                 (*vOut)[v].mad( sum, beta );
00555                                 (*vOut)[v].normalize();
00556                                 (*vOut)[v].m_triangleUsing = ((spoly * 4 + sedge) << 2) | sedge;
00557                         }
00558                 }
00559 
00560     std::swap(vIn,vOut);
00561                 std::swap(tIn,tOut);
00562                 std::swap(eIn,eOut);
00563 
00564                 svPrint("subdivision after step %d v:%d t:%d e:%d\n",(step+1),vIn->size(),tIn->size(),eIn->size());
00565         }
00566 
00567         if(vIn != &m_vertices)
00568         {
00569                 m_vertices = *vIn;
00570                 m_triangles = *tIn;
00571                 m_edges = *eIn;
00572         }
00573 
00574         calculateNormals();
00575 }
00576 
00577 //=======================================================================
00578 //=======================================================================
00579 
00580 const std::vector<Mesh::ventry> &Mesh::get1Neighbourhood( int ver, int &valence, bool &boundary, int &left, int &right )
00581 {
00582         static std::vector<ventry> vertexlist;
00583         valence = 0;
00584         boundary = false;
00585         vertexlist.clear();
00586         if( m_vertices[ver].m_triangleUsing == -1 ) return vertexlist;  //not used
00587         if( m_ambiguousNeighbours ) svError("can't traverse neighbourhood: '%s' contains %d edges which are shared by more than 2 polygons",m_filename.c_str(),m_ambiguousNeighbours);
00588 
00589         int spoly = m_vertices[ver].m_triangleUsing >> 2,cpoly,npoly;
00590         int sedge = m_vertices[ver].m_triangleUsing & 3,cedge,nedge;
00591         SS_ASSERT( sedge >= 0 && sedge < 3 );
00592         SS_ASSERT( spoly >= 0 && spoly < m_triangles.size() );
00593         int i;
00594         ventry ve;
00595 
00596         //these loops count on that there are no neighbour ambiguities (edges with >2 polygons)
00597         // if this condition doesn't hold, these may loop infinitely
00598         //loop right
00599         npoly = spoly;
00600         nedge = sedge;
00601         i = 0;
00602         do
00603         {
00604                 cpoly = npoly;
00605                 cedge = nedge;
00606 
00607                 valence++;
00608                 ve.m_vertex = m_triangles[cpoly].m_v[(cedge+1) % 3];
00609                 ve.m_i = i;
00610                 vertexlist.push_back( ve );
00611                 i++;
00612 
00613                 npoly = m_triangles[cpoly].m_n[cedge];
00614                 if( npoly == -1 )
00615                 {
00616                         boundary = true;
00617                         right = ve.m_vertex;
00618                         break;
00619                 }
00620                 nedge = (m_triangles[cpoly].m_nedge[cedge] + 1) % 3;
00621         } while( npoly != spoly );
00622         if( boundary )
00623         {
00624                 i = -1;
00625                 npoly = spoly;
00626                 nedge = (sedge + 2)%3;
00627                 //loop left
00628                 do
00629                 {
00630                         cpoly = npoly;
00631                         cedge = nedge;
00632 
00633                         valence++;
00634                         ve.m_vertex = m_triangles[cpoly].m_v[cedge];
00635                         ve.m_i = i;
00636                         vertexlist.push_back( ve );
00637                         i--;
00638 
00639                         npoly = m_triangles[cpoly].m_n[cedge];
00640                         if( npoly == -1 )
00641                         {
00642                                 left = ve.m_vertex;
00643                                 break;
00644                         }
00645                         nedge = (m_triangles[cpoly].m_nedge[cedge] + 2) % 3;
00646                 } while( npoly != spoly );
00647         }
00648         return vertexlist;
00649 }
00650 
00651 //=======================================================================
00652 //=======================================================================
00653 
00654 void Mesh::calculateBoundingBox()
00655 {
00656         m_boundingBoxMin.set(FLT_MAX,FLT_MAX,FLT_MAX);
00657         m_boundingBoxMax.set(-FLT_MAX,-FLT_MAX,-FLT_MAX);
00658         m_boundingRadius = 0.0f;
00659         for(int i=0;i<m_vertices.size();i++)
00660         {
00661                 Vector3 v = m_vertices[i].m_position;
00662                 if( v.x > m_boundingBoxMax.x ) m_boundingBoxMax.x = v.x;
00663                 if( v.y > m_boundingBoxMax.y ) m_boundingBoxMax.y = v.y;
00664                 if( v.z > m_boundingBoxMax.z ) m_boundingBoxMax.z = v.z;
00665                 if( v.x < m_boundingBoxMin.x ) m_boundingBoxMin.x = v.x;
00666                 if( v.y < m_boundingBoxMin.y ) m_boundingBoxMin.y = v.y;
00667                 if( v.z < m_boundingBoxMin.z ) m_boundingBoxMin.z = v.z;
00668 
00669                 if( dot(v,v) > m_boundingRadius ) m_boundingRadius = dot(v,v);
00670         }
00671         m_boundingRadius = sqrt(m_boundingRadius);
00672 }
00673 
00674 //=======================================================================
00675 //=======================================================================

Generated on Thu Feb 15 09:09:20 2007 for Surface Splating by  doxygen 1.5.1-p1