Skip to content
Snippets Groups Projects
Commit 964b0340 authored by Emilie Marchandise's avatar Emilie Marchandise
Browse files

Create Topology much faster

parent 544b8771
No related branches found
No related tags found
No related merge requests found
...@@ -38,6 +38,66 @@ ...@@ -38,6 +38,66 @@
std::vector<GModel*> GModel::list; std::vector<GModel*> GModel::list;
int GModel::_current = -1; int GModel::_current = -1;
static void recur_connect(MVertex *v,
std::multimap<MVertex*,MEdge> &v2e,
std::set<MEdge,Less_Edge> &group,
std::set<MVertex*> &touched)
{
if (touched.find(v) != touched.end())return;
touched.insert(v);
for (std::multimap <MVertex*,MEdge>::iterator it = v2e.lower_bound(v);
it != v2e.upper_bound(v) ; ++it){
group.insert(it->second);
for (int i=0;i<it->second.getNumVertices();++i){
recur_connect (it->second.getVertex(i),v2e,group,touched);
}
}
}
// starting form a list of elements, returns
// lists of lists that are all simply connected
static void recur_connect_e (const MEdge &e,
std::multimap<MEdge,MElement*,Less_Edge> &e2e,
std::set<MElement*> &group,
std::set<MEdge,Less_Edge> &touched){
if (touched.find(e) != touched.end())return;
touched.insert(e);
for (std::multimap <MEdge,MElement*,Less_Edge>::iterator it = e2e.lower_bound(e);
it != e2e.upper_bound(e) ; ++it){
group.insert(it->second);
for (int i=0;i<it->second->getNumEdges();++i){
recur_connect_e (it->second->getEdge(i),e2e,group,touched);
}
}
}
static int connected_bounds (std::set<MEdge, Less_Edge> &edges, std::vector<std::vector<MEdge> > &boundaries)
{
std::multimap<MVertex*,MEdge> v2e;
for(std::set<MEdge, Less_Edge>::iterator it = edges.begin(); it != edges.end(); it++){
for (int j=0;j<it->getNumVertices();j++){
v2e.insert(std::make_pair(it->getVertex(j),*it));
}
}
while (!v2e.empty()){
std::set<MEdge, Less_Edge> group;
std::set<MVertex*> touched;
recur_connect (v2e.begin()->first,v2e,group,touched);
std::vector<MEdge> temp;
temp.insert(temp.begin(), group.begin(), group.end());
boundaries.push_back(temp);
for (std::set<MVertex*>::iterator it = touched.begin() ; it != touched.end();++it)
v2e.erase(*it);
}
return boundaries.size();
}
GModel::GModel(std::string name) GModel::GModel(std::string name)
: _name(name), _visible(1), _octree(0), : _name(name), _visible(1), _octree(0),
_geo_internals(0), _occ_internals(0), _fm_internals(0), _geo_internals(0), _occ_internals(0), _fm_internals(0),
...@@ -1138,39 +1198,35 @@ void GModel::createTopologyFromFaces(std::vector<discreteFace*> &discFaces) ...@@ -1138,39 +1198,35 @@ void GModel::createTopologyFromFaces(std::vector<discreteFace*> &discFaces)
std::map<int, std::vector<int> > face2Edges; std::map<int, std::vector<int> > face2Edges;
while (!map_edges.empty()){ while (!map_edges.empty()){
std::set<MEdge, Less_Edge> myEdges;
std::vector<MEdge> myEdges; myEdges.clear();
std::vector<int> tagFaces = map_edges.begin()->second; std::vector<int> tagFaces = map_edges.begin()->second;
myEdges.push_back(map_edges.begin()->first); myEdges.insert(map_edges.begin()->first);
map_edges.erase(map_edges.begin()); map_edges.erase(map_edges.begin());
std::map<MEdge, std::vector<int>, Less_Edge >::iterator itmap = map_edges.begin(); std::map<MEdge, std::vector<int>, Less_Edge >::iterator itmap = map_edges.begin();
while (itmap != map_edges.end()){ while (itmap != map_edges.end()){
std::vector<int> tagFaces2 = itmap->second; std::vector<int> tagFaces2 = itmap->second;
if (tagFaces2 == tagFaces){ if (tagFaces2 == tagFaces){
myEdges.push_back(itmap->first); myEdges.insert(itmap->first);
map_edges.erase(itmap++); map_edges.erase(itmap++);
} }
else else
itmap++; itmap++;
} }
//printf("*** %d Edges that bound \n", myEdges.size());
//for(std::vector<int>::iterator itFace = tagFaces.begin(); itFace != tagFaces.end(); itFace++)
// printf("face %d \n", *itFace);
// if the loaded mesh already contains discrete Edges, check if // if the loaded mesh already contains discrete Edges, check if
// the candidate discrete Edge does contain any of those; if not, // the candidate discrete Edge does contain any of those; if not,
// create discreteEdges and create a map face2Edges that associate // create discreteEdges and create a map face2Edges that associate
// for each face the boundary discrete Edges // for each face the boundary discrete Edges
for (std::vector<discreteEdge*>::iterator itE = discEdges.begin(); for (std::vector<discreteEdge*>::iterator itE = discEdges.begin(); itE != discEdges.end(); itE++){
itE != discEdges.end(); itE++){
bool candidate = true; bool candidate = true;
for (unsigned int i = 0; i < (*itE)->getNumMeshElements(); i++){ for (unsigned int i = 0; i < (*itE)->getNumMeshElements(); i++){
MEdge me = (*itE)->getMeshElement(i)->getEdge(0); MEdge me = (*itE)->getMeshElement(i)->getEdge(0);
if (std::find(myEdges.begin(), myEdges.end(), me) == myEdges.end()){ std::set<MEdge, Less_Edge >::iterator itset = myEdges.find(me);
if (itset == myEdges.end()){
candidate = false; candidate = false;
break; break;
} }
...@@ -1180,11 +1236,10 @@ void GModel::createTopologyFromFaces(std::vector<discreteFace*> &discFaces) ...@@ -1180,11 +1236,10 @@ void GModel::createTopologyFromFaces(std::vector<discreteFace*> &discFaces)
std::vector<int> tagEdges; std::vector<int> tagEdges;
tagEdges.push_back((*itE)->tag()); tagEdges.push_back((*itE)->tag());
//printf("Push back edge %d\n", (*itE)->tag());
for (unsigned int i = 0; i < (*itE)->getNumMeshElements(); i++){ for (unsigned int i = 0; i < (*itE)->getNumMeshElements(); i++){
MEdge me = (*itE)->getMeshElement(i)->getEdge(0); MEdge me = (*itE)->getMeshElement(i)->getEdge(0);
std::vector<MEdge>::iterator itME = std::find(myEdges.begin(), myEdges.end(), me); std::set<MEdge, Less_Edge >::iterator itset = myEdges.find(me);
myEdges.erase(itME); myEdges.erase(itset);
} }
for (std::vector<int>::iterator itFace = tagFaces.begin(); for (std::vector<int>::iterator itFace = tagFaces.begin();
...@@ -1202,43 +1257,11 @@ void GModel::createTopologyFromFaces(std::vector<discreteFace*> &discFaces) ...@@ -1202,43 +1257,11 @@ void GModel::createTopologyFromFaces(std::vector<discreteFace*> &discFaces)
} }
while (!myEdges.empty()) { std::vector<std::vector<MEdge> > boundaries;
std::vector<MEdge> myLines; double nbBounds = connected_bounds(myEdges, boundaries);
myLines.clear();
std::vector<MEdge>::iterator it = myEdges.begin();
MVertex *vB = (*it).getVertex(0); for (int ib = 0; ib < nbBounds; ib++){
MVertex *vE = (*it).getVertex(1); std::vector<MEdge> myLines = boundaries[ib];
myLines.push_back(*it);
myEdges.erase(it);
it++;
for (int i = 0; i < 2; i++) {
std::vector<MEdge>::iterator it= myEdges.begin();
while (it != myEdges.end()){
MVertex *v1 = (*it).getVertex(0);
MVertex *v2 = (*it).getVertex(1);
std::vector<MEdge>::iterator itp;
if (v1 == vE){
myLines.push_back(*it);
myEdges.erase(it);
vE = v2;
i = -1;
}
else if (v2 == vE){
myLines.push_back(*it);
myEdges.erase(it);
vE = v1;
i = -1;
}
else it++;
}
if (vB == vE) break;
if (myEdges.empty()) break;
MVertex *temp = vB;
vB = vE;
vE = temp;
}
int numE = maxEdgeNum()+1; int numE = maxEdgeNum()+1;
discreteEdge *e = new discreteEdge(this, numE, 0, 0); discreteEdge *e = new discreteEdge(this, numE, 0, 0);
...@@ -1259,13 +1282,11 @@ void GModel::createTopologyFromFaces(std::vector<discreteFace*> &discFaces) ...@@ -1259,13 +1282,11 @@ void GModel::createTopologyFromFaces(std::vector<discreteFace*> &discFaces)
} }
e->mesh_vertices.insert(e->mesh_vertices.begin(), allV.begin(),allV.end()); e->mesh_vertices.insert(e->mesh_vertices.begin(), allV.begin(),allV.end());
for (std::vector<int>::iterator itFace = tagFaces.begin(); for (std::vector<int>::iterator itFace = tagFaces.begin(); itFace != tagFaces.end(); itFace++) {
itFace != tagFaces.end(); itFace++) {
//delete new mesh vertices of edge from adjacent faces //delete new mesh vertices of edge from adjacent faces
GFace *dFace = getFaceByTag(*itFace); GFace *dFace = getFaceByTag(*itFace);
for (std::vector<MVertex*>::iterator itv = allV.begin(); for (std::vector<MVertex*>::iterator itv = allV.begin();itv != allV.end(); itv++) {
itv != allV.end(); itv++) {
std::vector<MVertex*>::iterator itve = std::vector<MVertex*>::iterator itve =
std::find(dFace->mesh_vertices.begin(), dFace->mesh_vertices.end(), *itv); std::find(dFace->mesh_vertices.begin(), dFace->mesh_vertices.end(), *itv);
if (itve != dFace->mesh_vertices.end()) dFace->mesh_vertices.erase(itve); if (itve != dFace->mesh_vertices.end()) dFace->mesh_vertices.erase(itve);
...@@ -1287,25 +1308,94 @@ void GModel::createTopologyFromFaces(std::vector<discreteFace*> &discFaces) ...@@ -1287,25 +1308,94 @@ void GModel::createTopologyFromFaces(std::vector<discreteFace*> &discFaces)
} }
} }
if (map_edges.empty()) break;
} }
// set boundary edges for each face // set boundary edges for each face
for (std::vector<discreteFace*>::iterator it = discFaces.begin(); for (std::vector<discreteFace*>::iterator it = discFaces.begin(); it != discFaces.end(); it++){
it != discFaces.end(); it++){
//printf("set boundary edge for face =%d \n", (*it)->tag()); //printf("set boundary edge for face =%d \n", (*it)->tag());
std::map<int, std::vector<int> >::iterator ite = face2Edges.find((*it)->tag()); std::map<int, std::vector<int> >::iterator ite = face2Edges.find((*it)->tag());
if (ite != face2Edges.end()){ if (ite != face2Edges.end()){
std::vector<int> myEdges = ite->second; std::vector<int> bcEdges = ite->second;
(*it)->setBoundEdges(myEdges); (*it)->setBoundEdges(bcEdges);
} }
} }
// for each discreteEdge, create Topology // for each discreteEdge, create Topology
for (std::vector<discreteEdge*>::iterator it = discEdges.begin(); std::map<MVertex*, MVertex*, std::less<MVertex*> > old2new;
it != discEdges.end(); it++){ for (std::vector<discreteEdge*>::iterator it = discEdges.begin(); it != discEdges.end(); it++){
double t1 = Cpu();
(*it)->createTopo(); (*it)->createTopo();
(*it)->parametrize(); double t2 = Cpu();
(*it)->parametrize(old2new);
double t3 = Cpu();
}
//we need to recreate lines, triangles and tets
//that contain those new MEdgeVertices
double t5 = Cpu();
for (std::vector<discreteFace*>::iterator iFace = discFaces.begin(); iFace != discFaces.end(); iFace++){
std::vector<MTriangle*> newTriangles;
std::vector<MQuadrangle*> newQuadrangles;
for (unsigned int i = 0; i < (*iFace)->getNumMeshElements(); ++i){
MElement *e = (*iFace)->getMeshElement(i);
int N = e->getNumVertices();
std::vector<MVertex *> v(N);
for(int j = 0; j < N; j++) v[j] = e->getVertex(j);
for (int j = 0; j < N; j++){
std::map<MVertex*, MVertex*, std::less<MVertex*> >::iterator itmap = old2new.find(v[j]);
if (itmap != old2new.end()) {
MVertex *vNEW;
vNEW = itmap->second;
v[j]=vNEW;
}
}
if (N == 3) newTriangles.push_back(new MTriangle(v[0], v[1], v[2]));
else if ( N == 4) newQuadrangles.push_back(new MQuadrangle(v[0], v[1], v[2], v[3]));
}
(*iFace)->deleteVertexArrays();
(*iFace)->triangles.clear();
(*iFace)->triangles = newTriangles;
(*iFace)->quadrangles.clear();
(*iFace)->quadrangles = newQuadrangles;
}
for(GModel::riter iRegion = firstRegion(); iRegion != lastRegion(); iRegion++){
std::vector<MTetrahedron*> newTetrahedra;
std::vector<MHexahedron*> newHexahedra;
std::vector<MPrism*> newPrisms;
std::vector<MPyramid*> newPyramids;
for (unsigned int i = 0; i < (*iRegion)->getNumMeshElements(); ++i){
MElement *e = (*iRegion)->getMeshElement(i);
int N = e->getNumVertices();
std::vector<MVertex *> v(N);
for(int j = 0; j < N; j++) v[j] = e->getVertex(j);
for (int j = 0; j < N; j++){
std::map<MVertex*, MVertex*, std::less<MVertex*> >::iterator itmap = old2new.find(v[j]);
MVertex *vNEW;
if (itmap != old2new.end()) {
vNEW = itmap->second;
v[j]=vNEW;
}
}
if (N == 4) newTetrahedra.push_back(new MTetrahedron(v[0], v[1], v[2], v[3]));
else if (N == 5) newPyramids.push_back(new MPyramid(v[0], v[1], v[2], v[3], v[4]));
else if (N == 6) newPrisms.push_back(new MPrism(v[0], v[1], v[2], v[3], v[4], v[5]));
else if (N == 8) newHexahedra.push_back(new MHexahedron(v[0], v[1], v[2], v[3],
v[4], v[5], v[6], v[7]));
}
(*iRegion)->deleteVertexArrays();
(*iRegion)->tetrahedra.clear();
(*iRegion)->tetrahedra = newTetrahedra;
(*iRegion)->pyramids.clear();
(*iRegion)->pyramids = newPyramids;
(*iRegion)->prisms.clear();
(*iRegion)->prisms = newPrisms;
(*iRegion)->hexahedra.clear();
(*iRegion)->hexahedra = newHexahedra;
} }
} }
GModel *GModel::buildCutGModel(gLevelset *ls, bool cutElem) GModel *GModel::buildCutGModel(gLevelset *ls, bool cutElem)
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "MHexahedron.h" #include "MHexahedron.h"
#include "MPyramid.h" #include "MPyramid.h"
#include "Geo.h" #include "Geo.h"
#include "OS.h"
discreteEdge::discreteEdge(GModel *model, int num, GVertex *_v0, GVertex *_v1) discreteEdge::discreteEdge(GModel *model, int num, GVertex *_v0, GVertex *_v1)
: GEdge(model, num, _v0, _v1) : GEdge(model, num, _v0, _v1)
...@@ -242,20 +243,19 @@ void discreteEdge::setBoundVertices() ...@@ -242,20 +243,19 @@ void discreteEdge::setBoundVertices()
+---------------+--------------+----------- ... ----------+ +---------------+--------------+----------- ... ----------+
_pars[0]=0 _pars[1]=1 _pars[2]=2 _pars[N+1]=N+1 _pars[0]=0 _pars[1]=1 _pars[2]=2 _pars[N+1]=N+1
*/ */
void discreteEdge::parametrize() void discreteEdge::parametrize(std::map<MVertex*, MVertex*, std::less<MVertex*> > &old2new)
{ {
for (unsigned int i = 0; i < lines.size() + 1; i++){ for (unsigned int i = 0; i < lines.size() + 1; i++){
_pars.push_back(i); _pars.push_back(i);
} }
//Replace MVertex by MedgeVertex //Replace MVertex by MedgeVertex
//we need to recreate lines, triangles and tets
//that contain those new MEdgeVertices
std::map<MVertex*, MVertex*> old2new;
std::vector<MVertex* > newVertices; std::vector<MVertex* > newVertices;
std::vector<MLine*> newLines; std::vector<MLine*> newLines;
double t1 = Cpu();
MVertex *vL = getBeginVertex()->mesh_vertices[0]; MVertex *vL = getBeginVertex()->mesh_vertices[0];
int i = 0; int i = 0;
for(i = 0; i < (int)lines.size() - 1; i++){ for(i = 0; i < (int)lines.size() - 1; i++){
...@@ -282,98 +282,35 @@ void discreteEdge::parametrize() ...@@ -282,98 +282,35 @@ void discreteEdge::parametrize()
lines.clear(); lines.clear();
lines = newLines; lines = newLines;
for(std::list<GFace*>::iterator iFace = l_faces.begin(); iFace != l_faces.end(); ++iFace){
std::vector<MTriangle*> newTriangles;
std::vector<MQuadrangle*> newQuadrangles;
for (unsigned int i = 0; i < (*iFace)->getNumMeshElements(); ++i){
MElement *e = (*iFace)->getMeshElement(i);
int N = e->getNumVertices();
std::vector<MVertex *> v(N);
for(int j = 0; j < N; j++){
v[j] = e->getVertex(j);
}
for (int j = 0; j < N; j++){
std::map<MVertex*, MVertex*>::iterator itmap = old2new.find(v[j]);
MVertex *vNEW;
if (itmap != old2new.end()) {
vNEW = itmap->second;
v[j]=vNEW;
}
}
if (N == 3) newTriangles.push_back(new MTriangle(v[0], v[1], v[2]));
else if ( N == 4) newQuadrangles.push_back(new MQuadrangle(v[0], v[1], v[2], v[3]));
}
(*iFace)->deleteVertexArrays();
(*iFace)->triangles.clear();
(*iFace)->triangles = newTriangles;
(*iFace)->quadrangles.clear();
(*iFace)->quadrangles = newQuadrangles;
}
for(GModel::riter iRegion = model()->firstRegion();
iRegion != model()->lastRegion(); iRegion++){
std::vector<MTetrahedron*> newTetrahedra;
std::vector<MHexahedron*> newHexahedra;
std::vector<MPrism*> newPrisms;
std::vector<MPyramid*> newPyramids;
for (unsigned int i = 0; i < (*iRegion)->getNumMeshElements(); ++i){
MElement *e = (*iRegion)->getMeshElement(i);
int N = e->getNumVertices();
std::vector<MVertex *> v(N);
for(int j = 0; j < N; j++){
v[j] = e->getVertex(j);
}
for (int j = 0; j < N; j++){
std::map<MVertex*, MVertex*>::iterator itmap = old2new.find(v[j]);
MVertex *vNEW;
if (itmap != old2new.end()) {
vNEW = itmap->second;
v[j]=vNEW;
}
}
if (N == 4) newTetrahedra.push_back(new MTetrahedron(v[0], v[1], v[2], v[3]));
else if (N == 5) newPyramids.push_back(new MPyramid(v[0], v[1], v[2], v[3], v[4]));
else if (N == 6) newPrisms.push_back(new MPrism(v[0], v[1], v[2], v[3], v[4], v[5]));
else if (N == 8) newHexahedra.push_back(new MHexahedron(v[0], v[1], v[2], v[3],
v[4], v[5], v[6], v[7]));
}
(*iRegion)->deleteVertexArrays();
(*iRegion)->tetrahedra.clear();
(*iRegion)->tetrahedra = newTetrahedra;
(*iRegion)->pyramids.clear();
(*iRegion)->pyramids = newPyramids;
(*iRegion)->prisms.clear();
(*iRegion)->prisms = newPrisms;
(*iRegion)->hexahedra.clear();
(*iRegion)->hexahedra = newHexahedra;
}
computeNormals(); computeNormals();
} }
void discreteEdge::computeNormals () const void discreteEdge::computeNormals () const
{ {
_normals.clear(); _normals.clear();
for (int i= 0; i < mesh_vertices.size(); i++) _normals[mesh_vertices[i]] = SVector3(0.0,0.0,0.0);
_normals[getBeginVertex()->mesh_vertices[0]] = SVector3(0.0,0.0,0.0);
_normals[getBeginVertex()->mesh_vertices[0]] = SVector3(0.0,0.0,0.0);
double J[3][3]; double J[3][3];
for(std::list<GFace*>::const_iterator iFace = l_faces.begin(); for(std::list<GFace*>::const_iterator iFace = l_faces.begin();
iFace != l_faces.end(); ++iFace){ iFace != l_faces.end(); ++iFace){
for (unsigned int i = 0; i < (*iFace)->triangles.size(); ++i){ for (unsigned int i = 0; i < (*iFace)->triangles.size(); ++i){
MTriangle *t = (*iFace)->triangles[i]; MTriangle *t = (*iFace)->triangles[i];
for (int j = 0; j < 3; j++){
std::map<MVertex*, SVector3, std::less<MVertex*> >::iterator itn = _normals.find(t->getVertex(j));
if (itn != _normals.end()){
t->getJacobian(0, 0, 0, J); t->getJacobian(0, 0, 0, J);
SVector3 d1(J[0][0], J[0][1], J[0][2]); SVector3 d1(J[0][0], J[0][1], J[0][2]);
SVector3 d2(J[1][0], J[1][1], J[1][2]); SVector3 d2(J[1][0], J[1][1], J[1][2]);
SVector3 n = crossprod(d1, d2); SVector3 n = crossprod(d1, d2);
n.normalize(); n.normalize();
for (int j = 0; j < 3; j++){ _normals[t->getVertex(j)] += n;
std::map<MVertex*, SVector3>::iterator itn = _normals.find(t->getVertex(j)); }
if (itn == _normals.end())_normals[t->getVertex(j)] = n;
else itn->second += n;
} }
} }
} }
std::map<MVertex*,SVector3>::iterator itn = _normals.begin(); std::map<MVertex*,SVector3, std::less<MVertex*> >::iterator itn = _normals.begin();
for ( ; itn != _normals.end(); ++itn){ for ( ; itn != _normals.end(); ++itn){
itn->second.normalize(); itn->second.normalize();
} }
......
...@@ -15,7 +15,7 @@ class discreteEdge : public GEdge { ...@@ -15,7 +15,7 @@ class discreteEdge : public GEdge {
std::vector<double> _pars; std::vector<double> _pars;
std::vector<int> _orientation; std::vector<int> _orientation;
std::map<MVertex*,MLine*> boundv; std::map<MVertex*,MLine*> boundv;
mutable std::map<MVertex*,SVector3> _normals; mutable std::map<MVertex*,SVector3, std::less<MVertex*> > _normals;
bool createdTopo; bool createdTopo;
public: public:
discreteEdge(GModel *model, int num, GVertex *_v0, GVertex *_v1); discreteEdge(GModel *model, int num, GVertex *_v0, GVertex *_v1);
...@@ -25,7 +25,7 @@ class discreteEdge : public GEdge { ...@@ -25,7 +25,7 @@ class discreteEdge : public GEdge {
virtual GPoint point(double p) const; virtual GPoint point(double p) const;
virtual SVector3 firstDer(double par) const; virtual SVector3 firstDer(double par) const;
virtual Range<double> parBounds(int) const; virtual Range<double> parBounds(int) const;
void parametrize(); void parametrize(std::map<MVertex*, MVertex*, std::less<MVertex*> > &old2new);
void orderMLines(); void orderMLines();
void setBoundVertices(); void setBoundVertices();
void createTopo(); void createTopo();
......
...@@ -4,7 +4,7 @@ Mesh.Algorithm3D = 4; //Frontal (4) Delaunay(1) ...@@ -4,7 +4,7 @@ Mesh.Algorithm3D = 4; //Frontal (4) Delaunay(1)
Merge "pelvis.stl"; Merge "pelvis.stl";
Compound Surface(200)={1}; Compound Surface(200)={1} Conformal;
Surface Loop(300)={200}; Surface Loop(300)={200};
Volume(301)={300}; Volume(301)={300};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment