Commit 795268ed authored by Kirill Terekhov's avatar Kirill Terekhov

Functions to remove and restore upper/lower adjacency connections; use...

Functions to remove and restore upper/lower adjacency connections; use RestoreCellNodes for vtk/vtu output only; change RestoreCellNodes algorithm to not require upper adjacencies for nodes
parent aa464182
......@@ -881,9 +881,9 @@ namespace INMOST
__INLINE bool Tag::isDefinedMask(ElementType mask) const
{
assert(mem!=NULL);
bool ret = false;
bool ret = true;
for(ElementType etype = NODE; etype <= MESH; etype = NextElementType(etype))
if( etype & mask ) ret |= isDefined(etype&mask);
if( etype & mask ) ret &= isDefined(etype&mask);
return ret;
}
__INLINE bool Tag::isSparse(ElementType type) const
......
......@@ -2068,6 +2068,18 @@ namespace INMOST
/// @see Face::FixNormalOrientation
/// @see Mesh::LowConn
Element::adj_type & HighConn (HandleType h) {return *static_cast<inner_reference_array*>(MGetDenseLink(h,HighConnTag()));}
/// Check that upper adjacencies are stored
ElementType HaveUpperAdjacencies() const;
/// Delete all upper adjacencies, access to HighConn should fire assertion and retrival of upper adjacencies is no longer valid
void RemoveUpperAdjacencies(ElementType mask = (NODE|EDGE|FACE));
/// Restore all upper adjacencies
void RestoreUpperAdjacencies(ElementType mask = (NODE|EDGE|FACE));
/// Check that upper adjacencies are stored
ElementType HaveLowerAdjacencies() const;
/// Delete all upper adjacencies, access to HighConn should fire assertion and retrival of upper adjacencies is no longer valid
void RemoveLowerAdjacencies(ElementType mask = (EDGE|FACE|CELL));
/// Restore all upper adjacencies
void RestoreLowerAdjacencies(ElementType mask = (EDGE|FACE|CELL));
/// Access directly higher order adjacencies of current element without right of modification.
Element::adj_type const& HighConn (HandleType h) const {return *static_cast<const inner_reference_array*>(MGetDenseLink(h,HighConnTag()));}
/// Access directly lower order adjacencies of current element with right of modification.
......
......@@ -227,7 +227,8 @@ namespace INMOST
case Element::Pyramid:
case Element::Prism:
{
ElementArray<Node> nodes = it->getNodes();
ElementArray<Node> nodes(this);// = it->getNodes();
RestoreCellNodes(*it,nodes);
if( nodes.size() != VtkElementNodes(it->GetGeometricType()) ) goto safe_output;
values.push_back(static_cast<integer>(nodes.size()));
for(ElementArray<Node>::iterator jt = nodes.begin(); jt != nodes.end(); jt++)
......@@ -243,50 +244,6 @@ namespace INMOST
values.push_back(jt->IntegerDF(set_id));
break;
}
/*
case Element::Prism:
{
ElementArray<Node> nodes = it->getNodes();
if( nodes.size() != 6 ) goto safe_output;
values.push_back(static_cast<integer>(nodes.size()));
values.push_back(nodes[0].IntegerDF(set_id));
values.push_back(nodes[2].IntegerDF(set_id));
values.push_back(nodes[1].IntegerDF(set_id));
values.push_back(nodes[3].IntegerDF(set_id));
values.push_back(nodes[5].IntegerDF(set_id));
values.push_back(nodes[4].IntegerDF(set_id));
break;
}
*/
/*
case Element::Hex:
{
ElementArray<Node> nodes = it->getNodes();
if( nodes.size() != 8 ) goto safe_output;
values.push_back(static_cast<integer>(nodes.size()));
values.push_back(nodes[0].IntegerDF(set_id));
values.push_back(nodes[3].IntegerDF(set_id));
values.push_back(nodes[2].IntegerDF(set_id));
values.push_back(nodes[1].IntegerDF(set_id));
values.push_back(nodes[4].IntegerDF(set_id));
values.push_back(nodes[7].IntegerDF(set_id));
values.push_back(nodes[6].IntegerDF(set_id));
values.push_back(nodes[5].IntegerDF(set_id));
break;
}
case Element::Pyramid:
{
ElementArray<Node> nodes = it->getNodes();
if( nodes.size() != 5 ) goto safe_output;
values.push_back(static_cast<integer>(nodes.size()));
values.push_back(nodes[0].IntegerDF(set_id));
values.push_back(nodes[3].IntegerDF(set_id));
values.push_back(nodes[2].IntegerDF(set_id));
values.push_back(nodes[1].IntegerDF(set_id));
values.push_back(nodes[4].IntegerDF(set_id));
break;
}
*/
case Element::Polyhedron:
case Element::MultiPolygon:
{
......
......@@ -344,7 +344,9 @@ namespace INMOST
f << "\t\t\t\t<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\">" << std::endl;
for(Mesh::iteratorCell jt = BeginCell(); jt != EndCell(); ++jt)
{
ElementArray<Node> nodes = jt->getNodes();
ElementArray<Node> nodes(this); //= jt->getNodes();
RestoreCellNodes(*jt,nodes);
assert(nodes.size() == jt->nbAdjElements(NODE));
for(ElementArray<Node>::iterator kt = nodes.begin(); kt != nodes.end(); ++kt)
f << nid[*kt] << " ";
f << std::endl;
......@@ -355,8 +357,9 @@ namespace INMOST
size_t offset = 0;
for(Mesh::iteratorCell jt = BeginCell(); jt != EndCell(); ++jt)
{
ElementArray<Node> nodes = jt->getNodes();
offset += nodes.size();
//ElementArray<Node> nodes = jt->getNodes();
//offset += nodes.size();
offset += jt->nbAdjElements(NODE);
f << offset << std::endl;
}
}
......@@ -383,6 +386,7 @@ namespace INMOST
for(ElementArray<Face>::iterator kt = faces.begin(); kt != faces.end(); ++kt)
{
ElementArray<Node> nodes = kt->getNodes();
assert(nodes.size() == kt->nbAdjElements(NODE));
f << nodes.size() << " ";
for(ElementArray<Node>::iterator qt = nodes.begin(); qt != nodes.end(); ++qt)
f << nid[*qt] << " ";
......@@ -405,7 +409,8 @@ namespace INMOST
for(ElementArray<Face>::iterator kt = faces.begin(); kt != faces.end(); ++kt)
{
offset++; //number of nodes in face
offset+= kt->getNodes().size(); //node ids
//offset+= kt->getNodes().size(); //node ids
offset += kt->nbAdjElements(NODE);
}
f << offset << std::endl;
}
......
......@@ -289,7 +289,7 @@ namespace INMOST
return false;
}
}
return false;
return true;
}
ElementArray<Node> Cell::getNodes() const
......@@ -297,7 +297,51 @@ namespace INMOST
assert(GetHandleElementType(GetHandle())==CELL);
Mesh * m = GetMeshLink();
ElementArray<Node> ret(m);
m->RestoreCellNodes(GetHandle(),ret);
MarkerType mrk = m->CreatePrivateMarker();
HandleType hc = GetHandle();
if( !m->HideMarker() )
{
Element::adj_type & lc = m->LowConn(hc);
for(Element::adj_type::size_type i = 0; i < lc.size(); i++) //iterate over faces
{
Element::adj_type & ilc = m->LowConn(lc[i]);
for(Element::adj_type::size_type j = 0; j < ilc.size(); j++) //iterate over face edges
{
Element::adj_type & jlc = m->LowConn(ilc[j]);
for(Element::adj_type::size_type k = 0; k < jlc.size(); k++) //iterator over edge nodes
{
if( !m->GetPrivateMarker(jlc[k],mrk) )
{
m->SetPrivateMarker(jlc[k],mrk);
ret.push_back(jlc[k]);
}
}
}
}
}
else
{
MarkerType hm = m->HideMarker();
Element::adj_type & lc = m->LowConn(hc);
for(Element::adj_type::size_type i = 0; i < lc.size(); i++) if( !m->GetMarker(lc[i],hm) ) //iterate over faces
{
Element::adj_type & ilc = m->LowConn(lc[i]);
for(Element::adj_type::size_type j = 0; j < ilc.size(); j++) if( !m->GetMarker(ilc[j],hm) ) //iterate over face edges
{
Element::adj_type & jlc = m->LowConn(ilc[j]);
for(Element::adj_type::size_type k = 0; k < jlc.size(); k++) if( !m->GetMarker(jlc[k],hm) ) //iterator over edge nodes
{
if( !m->GetPrivateMarker(jlc[k], mrk) )
{
m->SetPrivateMarker(jlc[k],mrk);
ret.push_back(jlc[k]);
}
}
}
}
}
ret.RemPrivateMarker(mrk);
m->ReleasePrivateMarker(mrk);
return ret;
}
......@@ -306,21 +350,100 @@ namespace INMOST
{
assert(GetHandleElementType(GetHandle())==CELL);
Mesh * m = GetMeshLink();
ElementArray<Node> aret(m), ret(m);
m->RestoreCellNodes(GetHandle(),ret);
ElementArray<Node> ret(m);
MarkerType mrk = m->CreatePrivateMarker();
HandleType hc = GetHandle();
if( isPrivate(mask) )
{
for(ElementArray<Node>::iterator it = ret.begin(); it != ret.end(); ++it)
if( invert ^ m->GetPrivateMarker(*it,mask) )
aret.push_back(*it);
if( !m->HideMarker() )
{
Element::adj_type & lc = m->LowConn(hc);
for(Element::adj_type::size_type i = 0; i < lc.size(); i++) //iterate over faces
{
Element::adj_type & ilc = m->LowConn(lc[i]);
for(Element::adj_type::size_type j = 0; j < ilc.size(); j++) //iterate over face edges
{
Element::adj_type & jlc = m->LowConn(ilc[j]);
for(Element::adj_type::size_type k = 0; k < jlc.size(); k++) //iterator over edge nodes
{
if( (invert ^ m->GetPrivateMarker(jlc[k],mask)) && !m->GetPrivateMarker(jlc[k],mrk) )
{
m->SetPrivateMarker(jlc[k],mrk);
ret.push_back(jlc[k]);
}
}
}
}
}
else
{
MarkerType hm = m->HideMarker();
Element::adj_type & lc = m->LowConn(hc);
for(Element::adj_type::size_type i = 0; i < lc.size(); i++) if( !m->GetMarker(lc[i],hm) ) //iterate over faces
{
Element::adj_type & ilc = m->LowConn(lc[i]);
for(Element::adj_type::size_type j = 0; j < ilc.size(); j++) if( !m->GetMarker(ilc[j],hm) ) //iterate over face edges
{
Element::adj_type & jlc = m->LowConn(ilc[j]);
for(Element::adj_type::size_type k = 0; k < jlc.size(); k++) if( !m->GetMarker(jlc[k],hm) ) //iterator over edge nodes
{
if( (invert ^ m->GetPrivateMarker(jlc[k],mask)) && !m->GetPrivateMarker(jlc[k], mrk) )
{
m->SetPrivateMarker(jlc[k],mrk);
ret.push_back(jlc[k]);
}
}
}
}
}
}
else
{
for(ElementArray<Node>::iterator it = ret.begin(); it != ret.end(); ++it)
if( invert ^ m->GetMarker(*it,mask) )
aret.push_back(*it);
if( !m->HideMarker() )
{
Element::adj_type & lc = m->LowConn(hc);
for(Element::adj_type::size_type i = 0; i < lc.size(); i++) //iterate over faces
{
Element::adj_type & ilc = m->LowConn(lc[i]);
for(Element::adj_type::size_type j = 0; j < ilc.size(); j++) //iterate over face edges
{
Element::adj_type & jlc = m->LowConn(ilc[j]);
for(Element::adj_type::size_type k = 0; k < jlc.size(); k++) //iterator over edge nodes
{
if( (invert ^ m->GetMarker(jlc[k],mask)) && !m->GetPrivateMarker(jlc[k],mrk) )
{
m->SetPrivateMarker(jlc[k],mrk);
ret.push_back(jlc[k]);
}
}
}
}
}
else
{
MarkerType hm = m->HideMarker();
Element::adj_type & lc = m->LowConn(hc);
for(Element::adj_type::size_type i = 0; i < lc.size(); i++) if( !m->GetMarker(lc[i],hm) ) //iterate over faces
{
Element::adj_type & ilc = m->LowConn(lc[i]);
for(Element::adj_type::size_type j = 0; j < ilc.size(); j++) if( !m->GetMarker(ilc[j],hm) ) //iterate over face edges
{
Element::adj_type & jlc = m->LowConn(ilc[j]);
for(Element::adj_type::size_type k = 0; k < jlc.size(); k++) if( !m->GetMarker(jlc[k],hm) ) //iterator over edge nodes
{
if( (invert ^ m->GetMarker(jlc[k],mask)) && !m->GetPrivateMarker(jlc[k], mrk) )
{
m->SetPrivateMarker(jlc[k],mrk);
ret.push_back(jlc[k]);
}
}
}
}
}
}
return aret;
ret.RemPrivateMarker(mrk);
m->ReleasePrivateMarker(mrk);
return ret;
}
ElementArray<Edge> Cell::getEdges() const
......
......@@ -1460,39 +1460,49 @@ namespace INMOST
*/
case Element::Hex:
{
MarkerType cemrk = CreatePrivateMarker();
MarkerType femrk = CreatePrivateMarker();
ElementArray<Face> faces = c->getFaces();
MarkerType mrk = CreatePrivateMarker();
const ElementArray<Face> faces = c->getFaces();
Face face = faces[0];
ret.reserve(8);
ElementArray<Node> verts = face->getNodes();
if( face->BackCell() == c )
ret.insert(ret.end(),verts.rbegin(),verts.rend());
else
ret.insert(ret.end(),verts.begin(),verts.end());
ElementArray<Edge> c_edges = c->getEdges();
ElementArray<Edge> f_edges = face->getEdges();
c_edges.SetPrivateMarker(cemrk);
f_edges.SetPrivateMarker(femrk);
for(unsigned int k = 0; k < 4; k++)
{
ElementArray<Edge> v_edges = ret[k]->getEdges(cemrk);
for(ElementArray<Edge>::iterator it = v_edges.begin(); it != v_edges.end(); it++)
const ElementArray<Node> verts = face->getNodes();
if( face->FaceOrientedOutside(c) )
ret.insert(ret.end(),verts.rbegin(),verts.rend());
else
ret.insert(ret.end(),verts.begin(),verts.end());
}
ret.SetPrivateMarker(mrk);
ret.resize(8);
for(ElementArray<Face>::size_type k = 1; k < faces.size(); ++k)
{
if( faces[k].nbAdjElements(NODE,mrk) == 2 )
{
if( !it->GetPrivateMarker(femrk) )
{
if( it->getBeg() == ret[k] )
ret.push_back(it->getEnd());
else
ret.push_back(it->getBeg());
break;
}
int inspos[2] = {-1,-1}, r = 0;
const ElementArray<Node> verts = faces[k].getNodes();
for(ElementArray<Node>::size_type q = 0; q < verts.size(); ++q)
if( verts[q].GetPrivateMarker(mrk) )
{
for(int l = 0; l < 4; ++l) if( ret[l] == verts[q] )
{
inspos[r] = l+4;
break;
}
assert(inspos[r] != -1);
ElementArray<Node>::size_type nxt = (q+1)%verts.size();
ElementArray<Node>::size_type prv = (q-1+verts.size())%verts.size();
if( verts[nxt].GetPrivateMarker(mrk) )
ret[inspos[r]] = verts[prv];
else if( verts[prv].GetPrivateMarker(mrk) )
ret[inspos[r]] = verts[nxt];
else assert(false); //this should not happen
r++;
}
ret[inspos[0]].SetPrivateMarker(mrk);
ret[inspos[1]].SetPrivateMarker(mrk);
}
}
c_edges.RemPrivateMarker(cemrk);
f_edges.RemPrivateMarker(femrk);
ReleasePrivateMarker(cemrk);
ReleasePrivateMarker(femrk);
ret.RemPrivateMarker(mrk);
ReleasePrivateMarker(mrk);
break;
}
/*
......@@ -1503,43 +1513,53 @@ namespace INMOST
*/
case Element::Prism:
{
MarkerType cemrk = CreatePrivateMarker();
MarkerType femrk = CreatePrivateMarker();
MarkerType mrk = CreatePrivateMarker();
ret.reserve(6);
Face face;
ElementArray<Face> faces = c->getFaces();
const ElementArray<Face> faces = c->getFaces();
for(ElementArray<Face>::size_type i = 0; i < faces.size(); i++) //iterate over faces
if( faces[i].nbAdjElements(EDGE) == 3 ) //number of edges in i-th face
{
face = faces[i];
break;
}
ElementArray<Node> verts = face->getNodes();
if( face->BackCell() == c )
ret.insert(ret.end(),verts.rbegin(),verts.rend());
else
ret.insert(ret.end(),verts.begin(),verts.end());
ElementArray<Edge> c_edges = c->getEdges();
ElementArray<Edge> f_edges = face->getEdges();
c_edges.SetPrivateMarker(cemrk);
f_edges.SetPrivateMarker(femrk);
for(ElementArray<Cell>::size_type k = 0; k < 3; k++)
{
ElementArray<Edge> v_edges = ret[k]->getEdges(cemrk);
for(ElementArray<Edge>::iterator it = v_edges.begin(); it != v_edges.end(); it++)
if( !it->GetPrivateMarker(femrk) )
{
if( it->getBeg() == ret[k] )
ret.push_back(it->getEnd());
else
ret.push_back(it->getBeg());
break;
}
const ElementArray<Node> verts = face->getNodes();
if( face->FaceOrientedOutside(c) )
ret.insert(ret.end(),verts.rbegin(),verts.rend());
else
ret.insert(ret.end(),verts.begin(),verts.end());
}
c_edges.RemPrivateMarker(cemrk);
f_edges.RemPrivateMarker(femrk);
ReleasePrivateMarker(cemrk);
ReleasePrivateMarker(femrk);
ret.SetPrivateMarker(mrk);
ret.resize(6);
for(ElementArray<Face>::size_type k = 0; k < faces.size(); ++k)
{
if( faces[k].nbAdjElements(NODE,mrk) == 2 )
{
int inspos[2] = {-1,-1}, r = 0;
const ElementArray<Node> verts = faces[k].getNodes();
for(ElementArray<Node>::size_type q = 0; q < verts.size(); ++q)
if( verts[q].GetPrivateMarker(mrk) )
{
for(int l = 0; l < 3; ++l) if( ret[l] == verts[q] )
{
inspos[r] = l+3;
break;
}
assert(inspos[r] != -1);
ElementArray<Node>::size_type nxt = (q+1)%verts.size();
ElementArray<Node>::size_type prv = (q-1+verts.size())%verts.size();
if( verts[nxt].GetPrivateMarker(mrk) )
ret[inspos[r]] = verts[prv];
else if( verts[prv].GetPrivateMarker(mrk) )
ret[inspos[r]] = verts[nxt];
else assert(false); //this should not happen
r++;
}
}
}
ret.RemPrivateMarker(mrk);
ReleasePrivateMarker(mrk);
break;
}
/*
......@@ -1550,49 +1570,31 @@ namespace INMOST
case Element::Pyramid:
{
ret.reserve(5);
Face quad, triangle;
Face face;
MarkerType mrk = CreatePrivateMarker();
ElementArray<Face> faces = c->getFaces();
const ElementArray<Face> faces = c->getFaces();
for(ElementArray<Face>::size_type i = 0; i < faces.size(); i++) //go over faces
{
if( faces[i].nbAdjElements(EDGE) == 4 ) //check if number of edges = 4
{
quad = faces[i];
face = faces[i];
break;
}
}
for(ElementArray<Face>::size_type i = 0; i < faces.size(); i++) //go over faces
{
if( faces[i].nbAdjElements(EDGE) == 3 ) //check if number of edges = 3
{
triangle = faces[i];
break;
}
const ElementArray<Node> verts = face->getNodes();
if( face->FaceOrientedOutside(c) )
ret.insert(ret.begin(),verts.rbegin(),verts.rend());
else
ret.insert(ret.begin(),verts.begin(),verts.end());
}
ElementArray<Node> base_nodes = quad->getNodes();
if( quad->BackCell() == c )
for(ElementArray<Node>::reverse_iterator it = base_nodes.rbegin(); it != base_nodes.rend(); it++)
{
ret.push_back(*it);
it->SetPrivateMarker(mrk);
}
else
for(ElementArray<Node>::iterator it = base_nodes.begin(); it != base_nodes.end(); it++)
{
ret.push_back(*it);
it->SetPrivateMarker(mrk);
}
ElementArray<Node> tri_nodes = triangle->getNodes();
for(ElementArray<Node>::iterator it = tri_nodes.begin(); it != tri_nodes.end(); it++)
{
if( !it->GetPrivateMarker(mrk) )
ret.SetPrivateMarker(mrk);
for(ElementArray<Face>::size_type i = 0; i < faces.size(); i++) //go over faces
if( faces[i].nbAdjElements(NODE) == 3 )
{
ret.push_back(*it);
ret.Unite(faces[i]->getNodes(mrk,true));
assert(ret.size() == 5);
break;
}
}
for(ElementArray<Node>::iterator it = ret.begin(); it != ret.end(); it++)
it->RemPrivateMarker(mrk);
ret.RemPrivateMarker(mrk);
ReleasePrivateMarker(mrk);
break;
}
......@@ -1605,31 +1607,18 @@ namespace INMOST
{
ret.reserve(4);
MarkerType mrk = CreatePrivateMarker();
ElementArray<Face> faces = c->getFaces();
ElementArray<Node> base_nodes = faces[0]->getNodes();
if( faces[0]->BackCell() == c )
for(ElementArray<Node>::reverse_iterator it = base_nodes.rbegin(); it != base_nodes.rend(); it++)
{
ret.push_back(*it);
it->SetPrivateMarker(mrk);
}
else
for(ElementArray<Node>::iterator it = base_nodes.begin(); it != base_nodes.end(); it++)
{
ret.push_back(*it);
it->SetPrivateMarker(mrk);
}
ElementArray<Node> tri_nodes = faces[1]->getNodes();
for(ElementArray<Node>::iterator it = tri_nodes.begin(); it != tri_nodes.end(); it++)
const ElementArray<Face> faces = c->getFaces();
{
if( !it->GetPrivateMarker(mrk) )
{
ret.push_back(*it);
break;
}
const ElementArray<Node> verts = faces[0]->getNodes();
if( faces[0]->FaceOrientedOutside(c) )
ret.insert(ret.begin(),verts.rbegin(),verts.rend());
else
ret.insert(ret.begin(),verts.begin(),verts.end());
ret.SetPrivateMarker(mrk);
}
for(ElementArray<Node>::iterator it = ret.begin(); it != ret.end(); it++)
it->RemPrivateMarker(mrk);
ret.Unite(faces[1]->getNodes(mrk,true));
assert(ret.size() == 4);
ret.RemPrivateMarker(mrk);
ReleasePrivateMarker(mrk);
break;
}
......@@ -1681,7 +1670,117 @@ namespace INMOST
break;
}
}
}
ElementType Mesh::HaveUpperAdjacencies() const
{
ElementType ret = NONE;
if( tag_high_conn.isValid() )
{
for(ElementType etype = NODE; etype <= CELL; etype = NextElementType(etype) )
if( tag_high_conn.isDefined(etype) )
ret |= etype;
return ret;
}
else return NONE;
}
ElementType Mesh::HaveLowerAdjacencies() const
{
ElementType ret = NONE;
if( tag_low_conn.isValid() )
{
for(ElementType etype = NODE; etype <= CELL; etype = NextElementType(etype) )
if( tag_low_conn.isDefined(etype) )
ret |= etype;
return ret;
}
else return NONE;
}
void Mesh::RemoveUpperAdjacencies(ElementType mask)
{
if( (HaveUpperAdjacencies() & mask) != NONE )
tag_high_conn = DeleteTag(tag_high_conn,(NODE|EDGE|FACE) & mask);
else
{
std::cout << __FILE__ << ":" << __LINE__ << " Upper adjacencies were already removed for";
for(ElementType etype = NODE; etype <= CELL; etype = NextElementType(etype)) if( etype & mask )
std::cout << " " << ElementTypeName(etype);
std::cout << std::endl;
}
}
void Mesh::RemoveLowerAdjacencies(ElementType mask)
{
if( (HaveLowerAdjacencies() & mask) != NONE )
tag_low_conn = DeleteTag(tag_low_conn,(EDGE|FACE|CELL) & mask);
else
{
std::cout << __FILE__ << ":" << __LINE__ << " Lower adjacencies were already removed for";
for(ElementType etype = NODE; etype <= CELL; etype = NextElementType(etype)) if( etype & mask )
std::cout << " " << ElementTypeName(etype);
std::cout << std::endl;
}
}
void Mesh::RestoreUpperAdjacencies(ElementType mask)
{
ElementType had = HaveUpperAdjacencies();
if( (had & mask) == mask )
{
std::cout << __FILE__ << ":" << __LINE__ << " Upper adjacencies already exist for";
for(ElementType etype = NODE; etype <= CELL; etype = NextElementType(etype)) if( etype & mask )
std::cout << " " << ElementTypeName(etype);
std::cout << std::endl;
}
else
{
tag_high_conn = CreateTag("PROTECTED_HIGH_CONN",DATA_REFERENCE,(FACE|EDGE|NODE) & mask,NONE);
for(ElementType etype = CELL; etype > NODE; etype = PrevElementType(etype)) if( (PrevElementType(etype) & mask) && !(PrevElementType(etype) & had) )
for(integer it = 0; it < LastLocalID(etype); ++it) if( isValidElement(etype,it) )
{
HandleType me = ComposeHandle(etype,it);
const Element::adj_type & lc = LowConn(me);
for(Element::adj_type::const_iterator it = lc.begin(); it != lc.end(); ++it)
HighConn(*it).push_back(me);
}
if( (mask & FACE) && !(had & FACE) && HaveGeometricData(ORIENTATION,FACE) )
for(integer it = 0; it < FaceLastLocalID(); ++it) if( isValidFace(it) )
FaceByLocalID(it).FixNormalOrientation(true);
}
}
void Mesh::RestoreLowerAdjacencies(ElementType mask)
{
ElementType had = HaveLowerAdjacencies();
if( (had & mask) == mask )
{
std::cout << __FILE__ << ":" << __LINE__ << " Lower adjacencies already exist for";
for(ElementType etype = NODE; etype <= CELL; etype = NextElementType(etype)) if( etype & mask )
std::cout << " " << ElementTypeName(etype);
std::cout << std::endl;
}
else
{
tag_low_conn = CreateTag("PROTECTED_LOW_CONN",DATA_REFERENCE,(CELL|FACE|EDGE) & mask,NONE);
for(ElementType etype = NODE; etype < CELL; etype = NextElementType(etype)) if( (NextElementType(etype) & mask) && !(NextElementType(etype) & had) )
for(integer it = 0; it < LastLocalID(etype); ++it) if( isValidElement(etype,it) )
{
HandleType me = ComposeHandle(etype,it);
const Element::adj_type & hc = HighConn(me);
for(Element::adj_type::const_iterator it = hc.begin(); it != hc.end(); ++it)
LowConn(*it).push_back(me);
}
if( (mask & FACE) && !(had & FACE) ) //fix edge order
for(integer it = 0; it < FaceLastLocalID(); ++it) if( isValidFace(it) )