Commit 5e041bc3 authored by Kirill Terekhov's avatar Kirill Terekhov

some updates

Retrieval of elements by markers;
Introduced options for loading of files;
Fixed issues saving vtk format when not all topological tests are
active;
Introduced Connect / Disconnect functions for manipulations with mesh;
DrawGrid example can now visualize array of entered cells/faces for
debug purposes;
OldDrawGrid example demonstrates fast interactive mesh slicing and
onscreen element picking.
parent b8d47cc5
......@@ -54,19 +54,19 @@ namespace INMOST
}
adjacent<Node> Cell::getNodes(MIDType mask)
adjacent<Node> Cell::getNodes(MIDType mask, bool invert)
{
adjacent<Node> aret;
if( !GetMeshLink()->HideMarker() )
{
for(adj_iterator it = high_conn.begin(); it != high_conn.end(); ++it)
if( (*it)->GetMarker(mask) ) aret.push_back((*it));
if( invert ^ (*it)->GetMarker(mask) ) aret.push_back((*it));
}
else
{
MIDType hm = GetMeshLink()->HideMarker();
for(adj_iterator it = high_conn.begin(); it != high_conn.end(); ++it)
if( (*it)->GetMarker(mask) && !(*it)->GetMarker(hm) ) aret.push_back((*it));
if( (invert ^ (*it)->GetMarker(mask)) && !(*it)->GetMarker(hm) ) aret.push_back((*it));
}
return aret;
}
......@@ -169,7 +169,7 @@ namespace INMOST
}
adjacent<Edge> Cell::getEdges(MIDType mask)
adjacent<Edge> Cell::getEdges(MIDType mask, bool invert)
{
adjacent<Edge> aret;
if( !GetMeshLink()->HideMarker() )
......@@ -179,8 +179,8 @@ namespace INMOST
aret.reserve(low_conn.size());
Element * last, * first;
Element * q = low_conn[0]; //edge 0
if( q->low_conn[0]->GetMarker(mask) ) aret.push_back(q->low_conn[0]); //node 0
if( q->low_conn[1]->GetMarker(mask) ) aret.push_back(q->low_conn[1]); //node 1
if( invert ^ q->low_conn[0]->GetMarker(mask) ) aret.push_back(q->low_conn[0]); //node 0
if( invert ^ q->low_conn[1]->GetMarker(mask) ) aret.push_back(q->low_conn[1]); //node 1
first = q->low_conn[0];
last = q->low_conn[1];
Element * r = low_conn[1]; //edge 1
......@@ -200,12 +200,12 @@ namespace INMOST
if( last == (*it)->low_conn[0] )
{
last = (*it)->low_conn[1];
if( last->GetMarker(mask) ) aret.push_back(last);
if( invert ^ last->GetMarker(mask) ) aret.push_back(last);
}
else
{
last = (*it)->low_conn[0];
if( last->GetMarker(mask) ) aret.push_back(last);
if( invert ^ last->GetMarker(mask) ) aret.push_back(last);
}
++it;
}
......@@ -216,7 +216,7 @@ namespace INMOST
MIDType mrk = m->CreateMarker();
for(Element::adj_iterator it = low_conn.begin(); it != low_conn.end(); it++) //faces
for(Element::adj_iterator jt = (*it)->low_conn.begin(); jt != (*it)->low_conn.end(); jt++) //edges
if( (*jt)->GetMarker(mask) && !(*jt)->GetMarker(mrk))
if( (invert ^ (*jt)->GetMarker(mask)) && !(*jt)->GetMarker(mrk))
{
aret.push_back(*jt);
(*jt)->SetMarker(mrk);
......@@ -239,10 +239,10 @@ namespace INMOST
i = Mesh::getNext(&low_conn[0],low_conn.size(),i,hm);
Element * q = low_conn[i]; //edge 0
k = Mesh::getNext(&q->low_conn[0],q->low_conn.size(),k,hm);
if( q->low_conn[k]->GetMarker(mask) ) aret.push_back(q->low_conn[k]); //node 0
if( invert ^ q->low_conn[k]->GetMarker(mask) ) aret.push_back(q->low_conn[k]); //node 0
first = q->low_conn[k];
k = Mesh::getNext(&q->low_conn[0],q->low_conn.size(),k,hm);
if( q->low_conn[k]->GetMarker(mask) ) aret.push_back(q->low_conn[k]); //node 1
if( invert ^ q->low_conn[k]->GetMarker(mask) ) aret.push_back(q->low_conn[k]); //node 1
last = q->low_conn[k];
i = Mesh::getNext(&low_conn[0],low_conn.size(),i,hm);
Element * r = low_conn[i]; //edge 1
......@@ -267,12 +267,12 @@ namespace INMOST
if( last == (*it)->low_conn[k1] )
{
last = (*it)->low_conn[k2];
if( last->GetMarker(mask) ) aret.push_back(last);
if( invert ^ last->GetMarker(mask) ) aret.push_back(last);
}
else
{
last = (*it)->low_conn[k1];
if( last->GetMarker(mask) ) aret.push_back(last);
if( invert ^ last->GetMarker(mask) ) aret.push_back(last);
}
++it;
}
......@@ -283,7 +283,7 @@ namespace INMOST
MIDType mrk = m->CreateMarker();
for(Element::adj_iterator it = low_conn.begin(); it != low_conn.end(); it++) if( !(*it)->GetMarker(hm) ) //faces
for(Element::adj_iterator jt = (*it)->low_conn.begin(); jt != (*it)->low_conn.end(); jt++) if( !(*jt)->GetMarker(hm) )//edges
if( (*jt)->GetMarker(mask) && !(*jt)->GetMarker(mrk))
if( (invert ^ (*jt)->GetMarker(mask)) && !(*jt)->GetMarker(mrk))
{
aret.push_back(*jt);
(*jt)->SetMarker(mrk);
......@@ -311,19 +311,19 @@ namespace INMOST
}
adjacent<Face> Cell::getFaces(MIDType mask)
adjacent<Face> Cell::getFaces(MIDType mask, bool invert)
{
adjacent<Face> aret;
if( !GetMeshLink()->HideMarker() )
{
for(adj_iterator it = low_conn.begin(); it != low_conn.end(); ++it)
if( (*it)->GetMarker(mask) ) aret.push_back((*it));
if( invert ^ (*it)->GetMarker(mask) ) aret.push_back((*it));
}
else
{
MIDType hm = GetMeshLink()->HideMarker();
for(adj_iterator it = low_conn.begin(); it != low_conn.end(); ++it)
if( (*it)->GetMarker(mask) && !(*it)->GetMarker(hm) ) aret.push_back((*it));
if( (invert ^ (*it)->GetMarker(mask)) && !(*it)->GetMarker(hm) ) aret.push_back((*it));
}
return aret;
}
......
......@@ -1833,6 +1833,8 @@ namespace INMOST
}
}
public:
element * data() {return pbegin;}
const element * data() const {return pbegin;}
void report_addr()
{
std::cout << "stack: " << &stack << std::endl;
......
......@@ -84,19 +84,19 @@ namespace INMOST
}
}
adjacent<Node> Edge::getNodes(MIDType mask)
adjacent<Node> Edge::getNodes(MIDType mask, bool invert)
{
adjacent<Node> aret;
if( !GetMeshLink()->HideMarker() )
{
for(adj_iterator it = low_conn.begin(); it != low_conn.end(); ++it)
if( (*it)->GetMarker(mask) ) aret.push_back((*it));
if( invert ^ (*it)->GetMarker(mask) ) aret.push_back((*it));
}
else
{
MIDType hm = GetMeshLink()->HideMarker();
for(adj_iterator it = low_conn.begin(); it != low_conn.end(); ++it)
if( (*it)->GetMarker(mask) && !(*it)->GetMarker(hm) ) aret.push_back((*it));
if( (invert ^ (*it)->GetMarker(mask)) && !(*it)->GetMarker(hm) ) aret.push_back((*it));
}
return aret;
}
......@@ -116,19 +116,19 @@ namespace INMOST
}
adjacent<Face> Edge::getFaces(MIDType mask)
adjacent<Face> Edge::getFaces(MIDType mask, bool invert)
{
adjacent<Face> aret;
if( !GetMeshLink()->HideMarker() )
{
for(adj_iterator it = high_conn.begin(); it != high_conn.end(); ++it)
if( (*it)->GetMarker(mask) ) aret.push_back((*it));
if( (invert ^ (*it)->GetMarker(mask)) ) aret.push_back((*it));
}
else
{
MIDType hm = GetMeshLink()->HideMarker();
for(adj_iterator it = high_conn.begin(); it != high_conn.end(); ++it)
if( (*it)->GetMarker(mask) && !(*it)->GetMarker(hm) ) aret.push_back((*it));
if( (invert ^ (*it)->GetMarker(mask)) && !(*it)->GetMarker(hm) ) aret.push_back((*it));
}
return aret;
}
......@@ -165,7 +165,7 @@ namespace INMOST
return aret;
}
adjacent<Cell> Edge::getCells(MIDType mask)
adjacent<Cell> Edge::getCells(MIDType mask, bool invert)
{
adjacent<Cell> aret;
Mesh * m = GetMeshLink();
......@@ -174,7 +174,7 @@ namespace INMOST
{
for(Element::adj_iterator it = high_conn.begin(); it != high_conn.end(); it++) //faces
for(Element::adj_iterator jt = (*it)->high_conn.begin(); jt != (*it)->high_conn.end(); jt++) //cels
if( (*jt)->GetMarker(mask) && !(*jt)->GetMarker(mrk) )
if( (invert ^ (*jt)->GetMarker(mask)) && !(*jt)->GetMarker(mrk) )
{
aret.push_back(*jt);
(*jt)->SetMarker(mrk);
......@@ -185,7 +185,7 @@ namespace INMOST
MIDType hm = GetMeshLink()->HideMarker();
for(Element::adj_iterator it = high_conn.begin(); it != high_conn.end(); it++) if( !(*it)->GetMarker(hm) ) //faces
for(Element::adj_iterator jt = (*it)->high_conn.begin(); jt != (*it)->high_conn.end(); jt++) if( !(*jt)->GetMarker(hm) ) //cels
if( (*jt)->GetMarker(mask) && !(*jt)->GetMarker(mrk) )
if( (invert ^ (*jt)->GetMarker(mask)) && !(*jt)->GetMarker(mrk) )
{
aret.push_back(*jt);
(*jt)->SetMarker(mrk);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -17,6 +17,7 @@
#include "my_glut.h"
#include "rotate.h"
#include "math.h"
#include <vector>
struct quaternion
{
......@@ -35,7 +36,7 @@ double mx,my;
extern int width, height;
extern int interactive;
//
std::vector<quaternion> storage;
void clickmotion(int nmx, int nmy) // Mouse
{
......@@ -119,6 +120,19 @@ void quatinit()
q.w = 1.0;
}
void quatpush()
{
storage.push_back(q);
}
void quatpop()
{
if( !storage.empty() )
{
q = storage.back();
storage.pop_back();
}
}
void rotatevector(double * vec)
{
......@@ -154,6 +168,78 @@ void rotatevector(double * vec)
vec[2] = ret[2]/ret[3];
}
void revrotatevector(double * vec)
{
int i;
double rot[16];
double temp[4] = {vec[0],vec[1],vec[2],1.0};
double ret[4];
q.w = -q.w;
rot[ 0] = (q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z);
rot[ 1] = 2.*(q.x*q.y - q.w*q.z);
rot[ 2] = 2.*(q.x*q.z + q.w*q.y);
rot[ 3] = 0.0;
rot[ 4] = 2.*(q.x*q.y + q.w*q.z);
rot[ 5] = (q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z);
rot[ 6] = 2.*(q.y*q.z - q.w*q.x);
rot[ 7] = 0.0;
rot[ 8] = 2.*(q.x*q.z - q.w*q.y);
rot[ 9] = 2.*(q.y*q.z + q.w*q.x);
rot[10] = (q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z);
rot[11] = 0.0;
rot[12] = 0.0;
rot[13] = 0.0;
rot[14] = 0.0;
rot[15] = (q.w*q.w + q.x*q.x + q.y*q.y + q.z*q.z);
for(i=0; i < 4; i++)
{
ret[i] = temp[0] * rot[i*4];
ret[i] += temp[1] * rot[i*4+1];
ret[i] += temp[2] * rot[i*4+2];
ret[i] += temp[3] * rot[i*4+3];
}
vec[0] = ret[0]/ret[3];
vec[1] = ret[1]/ret[3];
vec[2] = ret[2]/ret[3];
q.w = -q.w;
}
void rotatevector_from_stack(double * vec)
{
int i;
struct quaternion q = storage.back();
double rot[16];
double temp[4] = {vec[0],vec[1],vec[2],1.0};
double ret[4];
rot[ 0] = (q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z);
rot[ 1] = 2.*(q.x*q.y - q.w*q.z);
rot[ 2] = 2.*(q.x*q.z + q.w*q.y);
rot[ 3] = 0.0;
rot[ 4] = 2.*(q.x*q.y + q.w*q.z);
rot[ 5] = (q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z);
rot[ 6] = 2.*(q.y*q.z - q.w*q.x);
rot[ 7] = 0.0;
rot[ 8] = 2.*(q.x*q.z - q.w*q.y);
rot[ 9] = 2.*(q.y*q.z + q.w*q.x);
rot[10] = (q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z);
rot[11] = 0.0;
rot[12] = 0.0;
rot[13] = 0.0;
rot[14] = 0.0;
rot[15] = (q.w*q.w + q.x*q.x + q.y*q.y + q.z*q.z);
for(i=0; i < 4; i++)
{
ret[i] = temp[0] * rot[i*4];
ret[i] += temp[1] * rot[i*4+1];
ret[i] += temp[2] * rot[i*4+2];
ret[i] += temp[3] * rot[i*4+3];
}
vec[0] = ret[0]/ret[3];
vec[1] = ret[1]/ret[3];
vec[2] = ret[2]/ret[3];
}
void rotate()
{
double rot[16];
......@@ -176,3 +262,27 @@ void rotate()
glMultMatrixd(rot);
}
void rotate_from_stack()
{
double rot[16];
struct quaternion q = storage.back();
rot[ 0] = (q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z);
rot[ 1] = 2.*(q.x*q.y - q.w*q.z);
rot[ 2] = 2.*(q.x*q.z + q.w*q.y);
rot[ 3] = 0.0;
rot[ 4] = 2.*(q.x*q.y + q.w*q.z);
rot[ 5] = (q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z);
rot[ 6] = 2.*(q.y*q.z - q.w*q.x);
rot[ 7] = 0.0;
rot[ 8] = 2.*(q.x*q.z - q.w*q.y);
rot[ 9] = 2.*(q.y*q.z + q.w*q.x);
rot[10] = (q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z);
rot[11] = 0.0;
rot[12] = 0.0;
rot[13] = 0.0;
rot[14] = 0.0;
rot[15] = (q.w*q.w + q.x*q.x + q.y*q.y + q.z*q.z);
glMultMatrixd(rot);
}
......@@ -21,7 +21,12 @@ void clickmotion(int nmx, int nmy);
void motion(int nmx, int nmy);
void click(int b, int s, int nmx, int nmy);
void quatinit();
void quatpush();
void quatpop();
void rotate();
void rotate_from_stack();
void rotatevector(double * vec);
void revrotatevector(double * vec);
void rotatevector_from_stack(double * vec);
#endif
......@@ -238,7 +238,7 @@ namespace INMOST
}
adjacent<Node> Face::getNodes(MIDType mask)
adjacent<Node> Face::getNodes(MIDType mask, bool invert)
{
adjacent<Node> aret;
if( !GetMeshLink()->HideMarker() )
......@@ -247,15 +247,15 @@ namespace INMOST
{
aret.reserve(low_conn.size());
for(Element::adj_iterator it = low_conn.begin(); it != low_conn.end(); it++) //iterate over edges that are of type Vertex
if( (*it)->low_conn.front()->GetMarker(mask) )
if( invert ^ (*it)->low_conn.front()->GetMarker(mask) )
aret.push_back((*it)->low_conn.front());
}
else
{
aret.reserve(low_conn.size());
Element * q = low_conn[0], * first = q->low_conn[0], * last = q->low_conn[1]; //edge 0
if( q->low_conn[0]->GetMarker(mask) ) aret.push_back(q->low_conn[0]); //node 0
if( q->low_conn[1]->GetMarker(mask) ) aret.push_back(q->low_conn[1]); //node 1
if( invert ^ q->low_conn[0]->GetMarker(mask) ) aret.push_back(q->low_conn[0]); //node 0
if( invert ^ q->low_conn[1]->GetMarker(mask) ) aret.push_back(q->low_conn[1]); //node 1
Element * r = low_conn[1]; //edge 1
if( first == r->low_conn[0] || first == r->low_conn[1] )
{
......@@ -272,13 +272,13 @@ namespace INMOST
{
if( last == (*it)->low_conn[0] )
{
if( (*it)->low_conn[1]->GetMarker(mask) )
if( invert ^ (*it)->low_conn[1]->GetMarker(mask) )
aret.push_back((*it)->low_conn[1]);
last = (*it)->low_conn[1];
}
else
{
if( (*it)->low_conn[0]->GetMarker(mask) )
if( invert ^ (*it)->low_conn[0]->GetMarker(mask) )
aret.push_back((*it)->low_conn[0]);
last = (*it)->low_conn[0];
}
......@@ -297,7 +297,7 @@ namespace INMOST
{
INMOST_DATA_ENUM_TYPE i = static_cast<INMOST_DATA_ENUM_TYPE>(-1);
i = Mesh::getNext(&(*it)->low_conn[0],low_conn.size(),i,hm);
if( i < (*it)->low_conn.size() && (*it)->low_conn[i]->GetMarker(mask) ) aret.push_back((*it)->low_conn[i]);
if( i < (*it)->low_conn.size() && (invert ^ (*it)->low_conn[i]->GetMarker(mask)) ) aret.push_back((*it)->low_conn[i]);
}
}
else
......@@ -309,10 +309,10 @@ namespace INMOST
i = Mesh::getNext(&low_conn[0],low_conn.size(),i,hm);
Element * q = low_conn[i], * first, * last; //edge 0
k = Mesh::getNext(&q->low_conn[0],q->low_conn.size(),k,hm);
if( q->low_conn[k]->GetMarker(mask) ) aret.push_back(q->low_conn[k]); //node 0
if( invert ^ q->low_conn[k]->GetMarker(mask) ) aret.push_back(q->low_conn[k]); //node 0
first = q->low_conn[k];
k = Mesh::getNext(&q->low_conn[0],q->low_conn.size(),k,hm);
if( q->low_conn[k]->GetMarker(mask) ) aret.push_back(q->low_conn[k]); //node 1
if( invert ^ q->low_conn[k]->GetMarker(mask) ) aret.push_back(q->low_conn[k]); //node 1
last = q->low_conn[k];
i = Mesh::getNext(&low_conn[0],low_conn.size(),i,hm);
Element * r = low_conn[i]; //edge 1
......@@ -336,12 +336,12 @@ namespace INMOST
k2 = Mesh::getNext(&(*it)->low_conn[0],(*it)->low_conn.size(),k1,hm);
if( last == (*it)->low_conn[k1] )
{
if( (*it)->low_conn[k2]->GetMarker(mask) ) aret.push_back((*it)->low_conn[k2]);
if( invert ^ (*it)->low_conn[k2]->GetMarker(mask) ) aret.push_back((*it)->low_conn[k2]);
last = (*it)->low_conn[k2];
}
else
{
if( (*it)->low_conn[k1]->GetMarker(mask) ) aret.push_back((*it)->low_conn[k1]);
if( invert ^ (*it)->low_conn[k1]->GetMarker(mask) ) aret.push_back((*it)->low_conn[k1]);
last = (*it)->low_conn[k1];
}
++it;
......@@ -366,19 +366,19 @@ namespace INMOST
}
}
adjacent<Edge> Face::getEdges(MIDType mask)
adjacent<Edge> Face::getEdges(MIDType mask, bool invert)
{
adjacent<Edge> aret;
if( !GetMeshLink()->HideMarker() )
{
for(adj_iterator it = low_conn.begin(); it != low_conn.end(); ++it)
if( (*it)->GetMarker(mask) ) aret.push_back((*it));
if( invert ^ (*it)->GetMarker(mask) ) aret.push_back((*it));
}
else
{
MIDType hm = GetMeshLink()->HideMarker();
for(adj_iterator it = low_conn.begin(); it != low_conn.end(); ++it)
if( (*it)->GetMarker(mask) && !(*it)->GetMarker(hm) ) aret.push_back((*it));
if( (invert ^ (*it)->GetMarker(mask)) && !(*it)->GetMarker(hm) ) aret.push_back((*it));
}
return aret;
}
......@@ -397,19 +397,19 @@ namespace INMOST
}
}
adjacent<Cell> Face::getCells(MIDType mask)
adjacent<Cell> Face::getCells(MIDType mask, bool invert)
{
adjacent<Cell> aret;
if( !GetMeshLink()->HideMarker() )
{
for(adj_iterator it = high_conn.begin(); it != high_conn.end(); ++it)
if( (*it)->GetMarker(mask) ) aret.push_back((*it));
if( invert ^ (*it)->GetMarker(mask)) aret.push_back((*it));
}
else
{
MIDType hm = GetMeshLink()->HideMarker();
for(adj_iterator it = high_conn.begin(); it != high_conn.end(); ++it)
if( (*it)->GetMarker(mask) && !(*it)->GetMarker(hm) ) aret.push_back((*it));
if( (invert ^ (*it)->GetMarker(mask)) && !(*it)->GetMarker(hm) ) aret.push_back((*it));
}
return aret;
}
......
......@@ -220,7 +220,7 @@ namespace INMOST
case CELL:
if( lc[0]->GetElementDimension() == 1 )
{
if( TestClosure(lc,s) )
if( !GetTopologyCheck(NEED_TEST_CLOSURE) || TestClosure(lc,s) )
{
if( s == 3 )
ret = Element::Tri;
......@@ -267,7 +267,8 @@ namespace INMOST
{
m_type = Unset;
adjacent<Element> lc = getAdjElements(GetElementType() >> 1);
m_type = GetMeshLink()->ComputeGeometricType(GetElementType(),lc.data(),lc.size());
if( !lc.empty() )
m_type = GetMeshLink()->ComputeGeometricType(GetElementType(),lc.data(),lc.size());
/*
if( lc.size() == 0 && etypenum != 0) return;
switch(etypenum)
......@@ -471,8 +472,11 @@ namespace INMOST
if( (mask & etype) && !HaveGeometricData(CENTROID,etype))
{
centroid_tag = CreateTag("GEOM_UTIL_CENTROID",DATA_REAL,etype,NONE,GetDimensions());
for(Mesh::iteratorElement e = BeginElement(etype); e != EndElement(); ++e)
GetGeometricData(&*e,CENTROID,&e->RealDF(centroid_tag));
for(INMOST_DATA_INTEGER_TYPE k = 0; k < MaxLocalID(etype); ++k)
{
Element * e = ElementByLocalID(etype,k);
if( e != NULL ) GetGeometricData(e,CENTROID,&e->RealDF(centroid_tag));
}
ShowGeometricData(CENTROID,etype);
}
}
......
......@@ -549,7 +549,7 @@ namespace INMOST
void clear() {container.clear();}
void reserve(size_t n) {container.reserve(n);}
size_t size() const { return container.size(); }
AdjacentType ** data() {return reinterpret_cast<AdjacentType **>(&container[0]);}
AdjacentType ** data() {return reinterpret_cast<AdjacentType **>(container.data());}
void unite(const adjacent<AdjacentType> & other);
void substract(const adjacent<AdjacentType> & other);
void intersect(const adjacent<AdjacentType> & other);
......@@ -597,21 +597,21 @@ namespace INMOST
virtual ~Element();
INMOST_DATA_ENUM_TYPE nbAdjElements(ElementType _etype) const;
adjacent<Element> getAdjElements(ElementType _etype) const; //unordered
INMOST_DATA_ENUM_TYPE nbAdjElements(ElementType _etype, MIDType mask) const;
adjacent<Element> getAdjElements(ElementType _etype, MIDType mask) const; //unordered
adjacent<Element> BridgeAdjacencies(ElementType Bridge, ElementType Dest, MIDType mask = 0);
adjacent<Node> BridgeAdjacencies2Node(ElementType Bridge, MIDType mask = 0);
adjacent<Edge> BridgeAdjacencies2Edge(ElementType Bridge, MIDType mask = 0);
adjacent<Face> BridgeAdjacencies2Face(ElementType Bridge, MIDType mask = 0);
adjacent<Cell> BridgeAdjacencies2Cell(ElementType Bridge, MIDType mask = 0);
INMOST_DATA_ENUM_TYPE nbAdjElements(ElementType _etype, MIDType mask, bool invert_mask = false) const;
adjacent<Element> getAdjElements(ElementType _etype, MIDType mask, bool invert_mask = false) const; //unordered
adjacent<Element> BridgeAdjacencies(ElementType Bridge, ElementType Dest, MIDType mask = 0, bool invert_mask = false);
adjacent<Node> BridgeAdjacencies2Node(ElementType Bridge, MIDType mask = 0, bool invert_mask = false);
adjacent<Edge> BridgeAdjacencies2Edge(ElementType Bridge, MIDType mask = 0, bool invert_mask = false);
adjacent<Face> BridgeAdjacencies2Face(ElementType Bridge, MIDType mask = 0, bool invert_mask = false);
adjacent<Cell> BridgeAdjacencies2Cell(ElementType Bridge, MIDType mask = 0, bool invert_mask = false);
virtual adjacent<Node> getNodes(); //unordered
virtual adjacent<Edge> getEdges(); //unordered
virtual adjacent<Face> getFaces(); //unordered
virtual adjacent<Cell> getCells(); //unordered
virtual adjacent<Node> getNodes(MIDType mask); //unordered
virtual adjacent<Edge> getEdges(MIDType mask); //unordered
virtual adjacent<Face> getFaces(MIDType mask); //unordered
virtual adjacent<Cell> getCells(MIDType mask); //unordered
virtual adjacent<Node> getNodes(MIDType mask,bool invert_mask = false); //unordered
virtual adjacent<Edge> getEdges(MIDType mask,bool invert_mask = false); //unordered
virtual adjacent<Face> getFaces(MIDType mask,bool invert_mask = false); //unordered
virtual adjacent<Cell> getCells(MIDType mask,bool invert_mask = false); //unordered
Node * getAsNode(); //does dynamic conversation for you, if not a node returns NULL
Edge * getAsEdge(); //does dynamic conversation for you, if not an edge returns NULL
Face * getAsFace(); //does dynamic conversation for you, if not a face returns NULL
......@@ -638,9 +638,18 @@ namespace INMOST
bool Hidden();
bool New();
void Disconnect(bool delete_upper_adjacent); //disconnect all elements, delete upper dependent
void Disconnect(Element ** adjacent, INMOST_DATA_ENUM_TYPE num); //disconnect upper or lower adjacent elements from current element, geometric data is updated automatically
void Connect(Element ** adjacent, INMOST_DATA_ENUM_TYPE num); //connect lower adjacent elements to current element, geometric data is updated automatically
void UpdateGeometricData(); //update geometric data for element, calls RecomputeGeometricData from Mesh
/// Disconnects nodes from this edge, edges from this face, faces from this cell, cannot disconnect cells from this node;
/// Disconnects edges from this node, faces from this edge, cells from this face, cannot disconnect nodes from this cell;
/// Updates geometric data and cell nodes automatically.
void Disconnect(Element ** adjacent, INMOST_DATA_ENUM_TYPE num);
/// Connects lower adjacencies to current element,
/// geometric data and cell nodes are updated automatically.
/// TODO:
/// 1. asserts in this function should be replaced by Topography checks;
/// 2. this function should be used for creation of elements instead of current implementation.
void Connect(Element ** adjacent, INMOST_DATA_ENUM_TYPE num);
/// Update geometric data for element, calls RecomputeGeometricData from Mesh.
void UpdateGeometricData();
};
class Node : public Element //implemented in node.cpp
......@@ -657,9 +666,9 @@ namespace INMOST
adjacent<Face> getFaces(); //unordered
adjacent<Cell> getCells(); //unordered
adjacent<Edge> getEdges(MIDType mask); //unordered
adjacent<Face> getFaces(MIDType mask); //unordered
adjacent<Cell> getCells(MIDType mask); //unordered
adjacent<Edge> getEdges(MIDType mask,bool invert_mask = false); //unordered
adjacent<Face> getFaces(MIDType mask,bool invert_mask = false); //unordered
adjacent<Cell> getCells(MIDType mask,bool invert_mask = false); //unordered
Storage::real_array Coords();
friend class Mesh;
......@@ -679,9 +688,9 @@ namespace INMOST
adjacent<Face> getFaces(); //unordered
adjacent<Cell> getCells(); //unordered
adjacent<Node> getNodes(MIDType mask); //ordered
adjacent<Face> getFaces(MIDType mask); //unordered
adjacent<Cell> getCells(MIDType mask); //unordered
adjacent<Node> getNodes(MIDType mask,bool invert_mask = false); //ordered
adjacent<Face> getFaces(MIDType mask,bool invert_mask = false); //unordered
adjacent<Cell> getCells(MIDType mask,bool invert_mask = false); //unordered
Node * getBeg() const;
Node * getEnd() const;
......@@ -709,9 +718,9 @@ namespace INMOST
adjacent<Edge> getEdges(); //ordered
adjacent<Cell> getCells(); //unordered
adjacent<Node> getNodes(MIDType mask); //ordered
adjacent<Edge> getEdges(MIDType mask); //ordered
adjacent<Cell> getCells(MIDType mask); //unordered
adjacent<Node> getNodes(MIDType mask,bool invert_mask = false); //ordered
adjacent<Edge> getEdges(MIDType mask,bool invert_mask = false); //ordered
adjacent<Cell> getCells(MIDType mask,bool invert_mask = false); //unordered
//this is for 2d case when the face is represented by segment
Node * getBeg() const;
......@@ -755,9 +764,9 @@ namespace INMOST
adjacent<Edge> getEdges(); //unordered
adjacent<Face> getFaces(); //ordered (keeps order it was created in)
adjacent<Node> getNodes(MIDType mask); //ordered (for known geometric types only)
adjacent<Edge> getEdges(MIDType mask); //unordered
adjacent<Face> getFaces(MIDType mask); //ordered (keeps order it was created in)
adjacent<Node> getNodes(MIDType mask,bool invert_mask = false); //ordered (for known geometric types only)
adjacent<Edge> getEdges(MIDType mask,bool invert_mask = false); //unordered
adjacent<Face> getFaces(MIDType mask,bool invert_mask = false); //ordered (keeps order it was created in)
bool CheckEdgeOrder(); //not implemented//2D only, returns true if edges of face form an ordered closed loop
......@@ -1174,8 +1183,13 @@ namespace INMOST
public:
/// Current availible file options:
/// "VTK_GRID_DIMS" - set "2" for two-dimensional vtk grids, "3" for three-dimensional vtk grids
void SetFileOptions(std::vector< std::pair<std::string,std::string> > options);
/// "VERBOSITY" - set "2" for progress messages, "1" for reports, "0" for silence
void SetFileOption(std::string,std::string);
std::string GetFileOption(std::string);
void Load(std::string File); // .vtk, .pvtk, .pmf
/// Remeber: .pmf stores all references to elements. If reference are broken due to mesh modification,
/// saving or loading such a mesh may lead to seagfault. To automatically maintain correct
/// references modify mesh using BeginModification, ApplyModification, EndModification
void Save(std::string File); // .vtk, .pvtk, .gmv, .pmf
bool isParallelFileFormat(std::string File);
public:
......
......@@ -1514,124 +1514,135 @@ namespace INMOST
void Mesh::UntieElement(Storage * e)
{
INMOST_DATA_ENUM_TYPE pos = e->LocalID();
switch(e->GetElementType())
#if defined(USE_OMP)
#pragma omp critical [storage_interraction]
#endif
{
case ESET:
if( pos >= sets.size() || sets[pos] != e ) return;
empty_sets.push_back(pos);
sets[pos] = NULL;
break;
case CELL:
if( pos >= cells.size() || cells[pos] != e ) return;
empty_cells.push_back(pos);
cells[pos] = NULL;
break;
case FACE:
if( pos >= faces.size() ||