00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043
00044 #include "OSGConfig.h"
00045
00046 OSG_BEGIN_NAMESPACE
00047
00048
00049
00050 inline
00051 void HalfEdgeGraph::HalfEdge::setVertex(HalfEdgeGraph::IndexT startVertexIndex,
00052 HalfEdgeGraph::IndexT
00053 OSG_CHECK_ARG(endVertexIndex))
00054 {
00055 _vertexIndex = startVertexIndex;
00056 }
00057
00058 inline
00059 HalfEdgeGraph::IndexT HalfEdgeGraph::HalfEdge::vertexStart(void)
00060 {
00061 return _vertexIndex;
00062 }
00063
00064 inline
00065 HalfEdgeGraph::IndexT HalfEdgeGraph::HalfEdge::vertexEnd(void)
00066 {
00067 return next->_vertexIndex;
00068 }
00069
00070
00071
00072 inline
00073 void HalfEdgeGraph::Triangle::init(void)
00074 {
00075 state = DEGREE_0;
00076 next = prev = 0;
00077 halfEdgeVec[0].next = &(halfEdgeVec[1]);
00078 halfEdgeVec[0].triangle = this;
00079 halfEdgeVec[1].next = &(halfEdgeVec[2]);
00080 halfEdgeVec[1].triangle = this;
00081 halfEdgeVec[2].next = &(halfEdgeVec[0]);
00082 halfEdgeVec[2].triangle = this;
00083 }
00084
00085 inline
00086 bool HalfEdgeGraph::Triangle::valid (void)
00087 {
00088 return (state >= DEGREE_0) ? true : false;
00089 }
00090
00091 inline
00092 void HalfEdgeGraph::Triangle::resetDegreeState(const Int32 type)
00093 {
00094 state = (halfEdgeVec[0].twin &&
00095 (halfEdgeVec[0].twin->triangle->state >= type) ? 1 : 0) +
00096 (halfEdgeVec[1].twin &&
00097 (halfEdgeVec[1].twin->triangle->state >= type) ? 1 : 0) +
00098 (halfEdgeVec[2].twin &&
00099 (halfEdgeVec[2].twin->triangle->state >= type) ? 1 : 0);
00100 }
00101
00102 inline
00103 void HalfEdgeGraph::Triangle::drop(void)
00104 {
00105 if(halfEdgeVec[0].twin && (halfEdgeVec[0].twin->triangle->state > 0))
00106 halfEdgeVec[0].twin->triangle->state--;
00107 if(halfEdgeVec[1].twin && (halfEdgeVec[1].twin->triangle->state > 0))
00108 halfEdgeVec[1].twin->triangle->state--;
00109 if(halfEdgeVec[2].twin && (halfEdgeVec[2].twin->triangle->state > 0))
00110 halfEdgeVec[2].twin->triangle->state--;
00111 }
00112
00113
00114
00115 inline
00116 HalfEdgeGraph::TriangleList::TriangleList(void)
00117 : first(0), last(0)
00118 {
00119 }
00120
00121 inline
00122 void HalfEdgeGraph::TriangleList::reset(void)
00123 {
00124 first = 0; last = 0;
00125 }
00126
00127 inline
00128 bool HalfEdgeGraph::TriangleList::empty(void)
00129 {
00130 return first ? false : true;
00131 }
00132
00133 inline
00134 UInt32 HalfEdgeGraph::TriangleList::countElem(void)
00135 {
00136 UInt32 count = 0;
00137 for(Triangle *f = first; f; f = f->next)
00138 ++count;
00139 return count;
00140 }
00141
00142 inline
00143 void HalfEdgeGraph::TriangleList::release(Triangle &node)
00144 {
00145 if(node.next)
00146 {
00147 if(node.prev)
00148 {
00149 node.next->prev = node.prev;
00150 node.prev->next = node.next;
00151 }
00152 else
00153 {
00154 node.next->prev = 0;
00155 this->first = node.next;
00156 }
00157 }
00158 else
00159 {
00160 if(node.prev)
00161 {
00162 node.prev->next = 0;
00163 this->last = node.prev;
00164 }
00165 else
00166 {
00167 this->first = 0;
00168 this->last = 0;
00169 }
00170 }
00171 node.next = node.prev = 0;
00172 }
00173
00174 inline
00175 void HalfEdgeGraph::TriangleList::add(Triangle &triangle)
00176 {
00177 if(last)
00178 {
00179 last->next = ▵
00180 triangle.prev = last;
00181 last = ▵
00182 }
00183 else
00184 {
00185 last = ▵
00186 first = ▵
00187 }
00188 }
00189
00190 inline
00191 void HalfEdgeGraph::TriangleList::paste(TriangleList &list)
00192 {
00193 if(&list != this)
00194 {
00195 if(empty())
00196 {
00197 first = list.first;
00198 last = list.last;
00199 }
00200 else
00201 {
00202 if(list.first)
00203 {
00204 last->next = list.first;
00205 list.first->prev = last;
00206 last = list.last;
00207 }
00208 }
00209 list.first = 0;
00210 list.last = 0;
00211 }
00212 }
00213
00214
00215
00216 inline
00217 HalfEdgeGraph::TrianglePool::Chunk::Chunk(const UInt32 size)
00218 : _size(size), _freeElem(size), _next(0)
00219 {
00220 _data = new Triangle[size];
00221 }
00222
00223 inline
00224 HalfEdgeGraph::TrianglePool::Chunk::~Chunk(void)
00225 {
00226 delete [] _data;
00227 delete _next;
00228 }
00229
00230 inline
00231 UInt32 HalfEdgeGraph::TrianglePool::Chunk::countElem(void)
00232 {
00233 return ((_size - _freeElem) + (_next ? _next->countElem() : 0));
00234 }
00235
00236
00237
00238 inline
00239 HalfEdgeGraph::TrianglePool::TrianglePool(UInt32 chunkSize)
00240 : _defaultChunkSize(chunkSize), _first(0), _last(0)
00241 {
00242 }
00243
00244 inline
00245 HalfEdgeGraph::TrianglePool::~TrianglePool(void)
00246 {
00247 clear();
00248 }
00249
00250 inline
00251 HalfEdgeGraph::Triangle *HalfEdgeGraph::TrianglePool::createTriangle(void)
00252 {
00253 if(!_first)
00254 {
00255 _first = _last = new Chunk(_defaultChunkSize);
00256 }
00257 else
00258 {
00259 if(_last->_freeElem == 0)
00260 _last = _last->_next = new Chunk(_defaultChunkSize);
00261 }
00262 return &(_last->_data[_last->_size - _last->_freeElem--]);
00263 }
00264
00265 inline
00266 void HalfEdgeGraph::TrianglePool::clear(void)
00267 {
00268 delete _first;
00269 _first = _last = 0;
00270 }
00271
00272 inline
00273 UInt32 HalfEdgeGraph::TrianglePool::countElem(void)
00274 {
00275 return (_first ? _first->countElem() : 0);
00276 }
00277
00278 inline
00279 void HalfEdgeGraph::TrianglePool::setChunkSize(UInt32 chunkSize)
00280 {
00281 _defaultChunkSize = chunkSize;
00282 }
00283
00284
00285
00286 inline
00287 void HalfEdgeGraph::dropOutTriangle(Triangle &triangle,
00288 TriangleList *degreeBag)
00289 {
00290 HalfEdge *twin;
00291 degreeBag[triangle.state].release(triangle);
00292 triangle.state = STRIP_PART;
00293
00294 if((twin = triangle.halfEdgeVec[0].twin) && (twin->triangle->state > 0))
00295 {
00296 degreeBag[twin->triangle->state--].release(*twin->triangle);
00297 degreeBag[twin->triangle->state].add(*twin->triangle);
00298 }
00299
00300 if((twin = triangle.halfEdgeVec[1].twin) && (twin->triangle->state > 0))
00301 {
00302 degreeBag[twin->triangle->state--].release(*twin->triangle);
00303 degreeBag[twin->triangle->state].add(*twin->triangle);
00304 }
00305
00306 if((twin = triangle.halfEdgeVec[2].twin) && (twin->triangle->state > 0))
00307 {
00308 degreeBag[twin->triangle->state--].release(*twin->triangle);
00309 degreeBag[twin->triangle->state].add(*twin->triangle);
00310 }
00311 }
00312
00313 inline
00314 HalfEdgeGraph::HalfEdge *HalfEdgeGraph::getHalfEdge(UInt32 startVertexIndex,
00315 UInt32 endVertexIndex)
00316 {
00317 UInt32 i, n = _edgeLinkVec.size();
00318 const HalfEdgeLink *edgeLink((startVertexIndex < n) ?
00319 &_edgeLinkVec[startVertexIndex] : 0);
00320
00321 HalfEdge *halfEdge = 0;
00322
00323 if (edgeLink && (n = edgeLink->size()))
00324 {
00325 for (i = 0; i < n; ++i)
00326 {
00327 if ((*edgeLink)[i].first == endVertexIndex)
00328 {
00329 halfEdge = (*edgeLink)[i].second;
00330 break;
00331 }
00332 }
00333 }
00334
00335 return halfEdge;
00336 }
00337
00338 inline
00339 void HalfEdgeGraph::addHalfEdge(HalfEdge &halfEdge, UInt32 startVertexIndex,
00340 UInt32 endVertexIndex)
00341 {
00342 UInt32 n(_edgeLinkVec.size());
00343 bool validIndex(startVertexIndex < n);
00344 HalfEdge *twin(validIndex ?
00345 getHalfEdge(endVertexIndex, startVertexIndex) : 0);
00346
00347 halfEdge.setVertex(startVertexIndex,endVertexIndex);
00348
00349 if(validIndex == false)
00350 _edgeLinkVec.resize(startVertexIndex * 2);
00351
00352 _edgeLinkVec[startVertexIndex].
00353 push_back(std::pair<HalfEdgeGraph::IndexT,HalfEdge*>(endVertexIndex,
00354 &halfEdge));
00355
00356 if((halfEdge.twin = twin))
00357 {
00358 twin->twin = &halfEdge;
00359 halfEdge.triangle->state++;
00360 twin->triangle->state++;
00361 }
00362 }
00363
00364 inline
00365 HalfEdgeGraph::HalfEdge *HalfEdgeGraph::findGateEdge(Triangle *triangleOut,
00366 Triangle *triangleIn)
00367 {
00368 HalfEdgeGraph::HalfEdge *halfEdge = 0;
00369
00370 if(triangleOut && triangleIn)
00371 if(!(halfEdge = triangleOut->halfEdgeVec[0].twin) ||
00372 (halfEdge->triangle != triangleIn))
00373 if(!(halfEdge = triangleOut->halfEdgeVec[1].twin) ||
00374 (halfEdge->triangle != triangleIn))
00375 if(!(halfEdge = triangleOut->halfEdgeVec[2].twin) ||
00376 (halfEdge->triangle != triangleIn))
00377 halfEdge = 0;
00378
00379 return halfEdge ? halfEdge->twin : 0;
00380 }
00381
00382 inline
00383 bool HalfEdgeGraph::addTriangle(HalfEdgeGraph::IndexT v0,
00384 HalfEdgeGraph::IndexT v1,
00385 HalfEdgeGraph::IndexT v2)
00386 {
00387 Triangle *triangle = 0;
00388
00389 if ((v0 != v1) && (v0 != v2) && (v2 != v1))
00390 {
00391
00392 triangle = _trianglePool.createTriangle();
00393 triangle->init();
00394
00395
00396 if (!getHalfEdge(v0,v1) && !getHalfEdge(v1,v2) && !getHalfEdge(v2,v0))
00397 {
00398 addHalfEdge(triangle->halfEdgeVec[0],v0,v1);
00399 addHalfEdge(triangle->halfEdgeVec[1],v1,v2);
00400 addHalfEdge(triangle->halfEdgeVec[2],v2,v0);
00401 _validTriangleBag.add(*triangle);
00402 return true;
00403 }
00404 else
00405 {
00406 triangle->halfEdgeVec[0].setVertex(v0,v1);
00407 triangle->halfEdgeVec[1].setVertex(v1,v2);
00408 triangle->halfEdgeVec[2].setVertex(v2,v0);
00409 triangle->state = INVALID;
00410 _invalidTriangleBag.add(*triangle);
00411 return false;
00412 }
00413 }
00414 return false;
00415 }
00416
00417 inline
00418 UInt32 HalfEdgeGraph::triangleCount(void)
00419 {
00420 return _trianglePool.countElem();
00421 }
00422
00423 inline
00424 UInt32 HalfEdgeGraph::primitiveCount(void)
00425 {
00426 return (_stripBag.size() + _fanBag.size() + _triBag.size());
00427 }
00428
00429 OSG_END_NAMESPACE