#include "inmost.h" #include #if defined(USE_MESH) namespace INMOST { ElementType GetNextType(ElementType current, ElementType types) { ElementType ret = MESH << 1; for(ElementType i = current << 1; i <= MESH; i = i << 1) if( types & i ) { ret = i; break; } if( ret > MESH ) ret = NONE; return ret; } ElementType GetPrevType(ElementType current, ElementType types) { ElementType ret = MESH << 1; for(ElementType i = current >> 1; i > NONE; i = i >> 1) if( types & i ) { ret = i; break; } if( ret > MESH ) ret = NONE; return ret; } HandleType Mesh::NextHandle(HandleType h) const { integer num = GetHandleElementNum(h), id = GetHandleID(h); ++id; while( num < 5 ) { while(id < static_cast(links[num].size()) && links[num][id] == -1) ++id; if( id == static_cast(links[num].size()) ) { id = 0; ++num; } else break; } if( num == 5 && id > 0 ) id = 1; return ComposeHandleNum(num,id); } HandleType Mesh::PrevHandle(HandleType h) const { integer num = GetHandleElementNum(h), id = GetHandleID(h); --id; if( num == 5 ) { if( id < 0 ) num = 4; else return ComposeHandleNum(ElementNum(MESH),0); } while( num >= 0 ) { while(id >= 0 && links[num][id] == -1) --id; if( id == -1 ) { --num; if( num > 0 ) id = static_cast(links[num].size())-1; } else break; } if( num < 0 ) return InvalidHandle(); return ComposeHandleNum(num,id); } HandleType Mesh::NextHandle(HandleType h, ElementType etype) const { integer num = GetHandleElementNum(h), id = GetHandleID(h); ++id; while( num < 5 ) { while(id < static_cast(links[num].size()) && links[num][id] == -1) ++id; if( id == static_cast(links[num].size()) ) { bool stop = true; for(integer q = num+1; q < 5; q++) { if( etype & (1 << q) ) { id = 0; num = q; stop = false; break; } } if( stop ) break; } else break; } if( num == 5 && id > 0 ) id = 1; return ComposeHandleNum(num,id); } HandleType Mesh::PrevHandle(HandleType h, ElementType etype) const { integer num = GetHandleElementNum(h), id = GetHandleID(h); --id; if( num == 5 ) { if( id < 0 ) { bool stop = true; for(integer q = 4; q >= 0; q--) { if( etype & (1 << q) ) { num = q; id = static_cast(links[num].size())-1; stop = false; break; } } if( stop ) return InvalidHandle(); } else return ComposeHandleNum(ElementNum(MESH),0); } while( num >= 0 ) { while(id >= 0 && links[num][id] == -1) --id; if( id == -1 ) { bool stop = true; for(integer q = num-1; q >= 0; q--) { if( etype & (1 << q) ) { num = q; id = static_cast(links[num].size())-1; stop = false; break; } } if( stop ) return InvalidHandle(); } else break; } if( num < 0 ) return InvalidHandle(); return ComposeHandleNum(num,id); } Storage::integer Mesh::FirstLocalID(ElementType etype) const { assert(OneType(etype)); integer ret = 0, n = ElementNum(etype); if(n == 5) return 0; while(ret < static_cast(links[n].size()) && links[n][ret] == -1) ++ret; return ret; } Storage::integer Mesh::NumberOf(ElementType t) const { integer ret = 0; for(int m = 0; m < 5; m++) if( (1 << m) & t ) ret += static_cast(links[m].size() - empty_links[m].size()); if( t & MESH ) ret++; return ret; } template Mesh::base_iterator & Mesh::base_iterator::operator ++() { while( etype != NONE ) { lid = m->NextLocalID(etype,lid); if( lid == m->LastLocalID(etype) ) { etype = GetNextType(etype,types); lid = -1; if( !etype ) break; } else break; } return *this; } template Mesh::base_iterator & Mesh::base_iterator::operator --() { while( etype != NONE ) { lid = m->PrevLocalID(etype,lid); if( lid == -1 ) { etype = GetPrevType(etype,types); if( etype ) lid = m->LastLocalID(etype); else { lid = -1; break; } } else break; } return *this; } template Mesh::base_iterator::base_iterator(ElementType T, Mesh * _m, bool last) { m = _m; types = T; etype = NONE; lid = -1; if( last ) { for(ElementType i = MESH; i >= NODE; i = i >> 1) if( types & i ) {etype = i; break;} lid = m->LastLocalID(etype); operator--(); } else { for(ElementType i = NODE; i <= MESH; i = i << 1) if( types & i ) {etype = i; break;} lid = -1; operator++(); } } template void Mesh::base_iterator::Print() { printf("Number: %10d CurrentType %x types %x\n",lid,etype,types); } Mesh::iteratorStorage Mesh::Begin(ElementType Types) {return base_iterator(Types,this,false);} Mesh::iteratorStorage Mesh::End() {return base_iterator(this);} Mesh::iteratorElement Mesh::BeginElement(ElementType Types) {return base_iterator(Types & (NODE | EDGE | FACE | CELL | ESET),this,false);} Mesh::iteratorElement Mesh::EndElement() {return base_iterator(this);} Mesh::iteratorSet Mesh::BeginSet() {return base_iterator(ESET,this,false);} Mesh::iteratorSet Mesh::EndSet() {return base_iterator(this);} Mesh::iteratorCell Mesh::BeginCell() {return base_iterator(CELL,this,false);} Mesh::iteratorCell Mesh::EndCell() {return base_iterator(this);} Mesh::iteratorFace Mesh::BeginFace() {return base_iterator(FACE,this,false);} Mesh::iteratorFace Mesh::EndFace() {return base_iterator(this);} Mesh::iteratorEdge Mesh::BeginEdge() {return base_iterator(EDGE,this,false);} Mesh::iteratorEdge Mesh::EndEdge() {return base_iterator(this);} Mesh::iteratorNode Mesh::BeginNode() {return base_iterator(NODE,this,false);} Mesh::iteratorNode Mesh::EndNode() {return base_iterator(this);} //all possible templates template class Mesh::base_iterator; template class Mesh::base_iterator; template class Mesh::base_iterator; template class Mesh::base_iterator; template class Mesh::base_iterator; template class Mesh::base_iterator; template class Mesh::base_iterator; } #endif