Commit e821d220 authored by Christophe Geuzaine's avatar Christophe Geuzaine

fix memory leaks in 3d mesher

parent c718c7e8
Pipeline #3036 passed with stage
in 15 minutes and 1 second
......@@ -1317,6 +1317,7 @@ void delaunayTrgl(const unsigned int numThreads,
for(unsigned int i = 0; i < bnd[K].size(); i++)
if(bnd[K][i].t) bnd[K][i].t->unset(myThread, K);
}
}
if(invalidCavities[0]) Msg::Error("%d invalid cavities", invalidCavities[0]);
......@@ -1409,7 +1410,6 @@ void delaunayTriangulation(const int numThreads, const int nptsatonce,
}
int nbBlocks = nptsatonce * numThreads;
// int blockSize = (nbBlocks * (N / nbBlocks))/nbBlocks;
std::vector<Vert *> assignTo0[1];
std::vector<std::vector<Vert *> > assignTo(nbBlocks);
......@@ -1418,28 +1418,17 @@ void delaunayTriangulation(const int numThreads, const int nptsatonce,
int start = indices[i - 1];
int end = indices[i];
int sizePerBlock = (nbBlocks * ((end - start) / nbBlocks)) / nbBlocks;
// printf("sizePerBlock[%3d] = %8d\n",i,sizePerBlock);
int currentBlock = 0;
int localCounter = 0;
// FIXME : something's wrong here !!!
if(i < 1) {
for(int jPt = start; jPt < end; jPt++) {
assignTo0[0].push_back(S[jPt]);
S[jPt]->_thread = numThreads * (jPt - start) / (end - start);
}
}
else {
for(int jPt = start; jPt < end; jPt++) {
if(localCounter++ >= sizePerBlock && currentBlock != nbBlocks - 1) {
localCounter = 0;
currentBlock++;
}
assignTo[currentBlock].push_back(S[jPt]);
for(int jPt = start; jPt < end; jPt++) {
if(localCounter++ >= sizePerBlock && currentBlock != nbBlocks - 1) {
localCounter = 0;
currentBlock++;
}
assignTo[currentBlock].push_back(S[jPt]);
}
}
S.clear();
delaunayTrgl(1, 1, assignTo0[0].size(), assignTo0, allocator);
delaunayTrgl(numThreads, nptsatonce, N, &assignTo[0], allocator);
// __print("finalTetrahedrization.pos",0, allocator);
......@@ -1462,17 +1451,13 @@ void delaunayTriangulation(const int numThreads, const int nptsatonce,
}
double d = 1 * sqrt(maxx * maxx + maxy * maxy + maxz * maxz);
tetContainer allocator(1, S.size() * 10);
tetContainer allocator(numThreads, S.size() * 10);
for(unsigned int i = 0; i < N; i++) {
MVertex *mv = S[i];
// FIXME : should be zero !!!!
double dx =
d * CTX::instance()->mesh.randFactor3d * (double)rand() / RAND_MAX;
double dy =
d * CTX::instance()->mesh.randFactor3d * (double)rand() / RAND_MAX;
double dz =
d * CTX::instance()->mesh.randFactor3d * (double)rand() / RAND_MAX;
double dx = d * CTX::instance()->mesh.randFactor3d * (double)rand() / RAND_MAX;
double dy = d * CTX::instance()->mesh.randFactor3d * (double)rand() / RAND_MAX;
double dz = d * CTX::instance()->mesh.randFactor3d * (double)rand() / RAND_MAX;
mv->x() += dx;
mv->y() += dy;
mv->z() += dz;
......@@ -1483,19 +1468,16 @@ void delaunayTriangulation(const int numThreads, const int nptsatonce,
robustPredicates::exactinit(1, maxx, maxy, maxz);
// FIXME numThreads
Vert *box[8];
delaunayTriangulation(numThreads, nptsatonce, _vertices, box, allocator);
//__print("finalTetrahedrization.pos",0, allocator);
MVertex *VV[8];
for(int i = 0; i < 8; i++) {
Vert *v = box[i];
v->setNum(N + i + 1);
VV[i] = new MVertex(v->x(), v->y(), v->z(), NULL, N + (i + 1));
_temp[v->getNum()] = VV[i];
S.push_back(VV[i]);
MVertex *mv = new MVertex(v->x(), v->y(), v->z(), NULL, N + (i + 1));
_temp[v->getNum()] = mv;
S.push_back(mv);
}
for(int myThread = 0; myThread < numThreads; myThread++) {
......@@ -1518,5 +1500,6 @@ void delaunayTriangulation(const int numThreads, const int nptsatonce,
}
}
for(int i = 0; i < 8; i++) delete box[i];
for(unsigned int i = 0; i < _vertices.size(); i++) delete _vertices[i];
}
......@@ -9,6 +9,8 @@
class MVertex;
class MTetrahedron;
// tetrahedralize the vertices given in S; adds 8 new vertices at the end of S (the
// corners of an enclosing box)
void delaunayTriangulation(const int numThreads, const int nptsatonce,
std::vector<MVertex *> &S,
std::vector<MTetrahedron *> &T);
......
......@@ -6,14 +6,11 @@
#ifndef _DELAUNAY3D_PRIVATE_H_
#define _DELAUNAY3D_PRIVATE_H_
#include <stdio.h>
#include <vector>
#include "SPoint3.h"
#include <cmath>
#include "SPoint3.h"
#include "robustPredicates.h"
#include <stdio.h>
#if defined(_OPENMP)
#include <omp.h>
#endif
#ifndef MAX_NUM_THREADS_
#define MAX_NUM_THREADS_ 8
......@@ -242,14 +239,13 @@ struct Tet {
Vert *V[4];
CHECKTYPE _bitset[MAX_NUM_THREADS_];
bool _modified;
// static int in_sphere_counter;
Tet() : _modified(true)
{
V[0] = V[1] = V[2] = V[3] = NULL;
T[0] = T[1] = T[2] = T[3] = NULL;
setAllDeleted();
}
// inline bool isFace () const {return V[3]==NULL;}
int setVerticesNoTest(Vert *v0, Vert *v1, Vert *v2, Vert *v3)
{
_modified = true;
......@@ -259,7 +255,6 @@ struct Tet {
V[3] = v3;
for(int i = 0; i < 4; i++)
if(V[i]) V[i]->setT(this);
// for (int i=0;i<4;i++)_copy[i] = *V[i];
return 1;
}
int setVertices(Vert *v0, Vert *v1, Vert *v2, Vert *v3)
......@@ -274,20 +269,16 @@ struct Tet {
for(int i = 0; i < 4; i++)
if(V[i]) V[i]->setT(this);
if(val > 0) {
// for (int i=0;i<4;i++)_copy[i] = *V[i];
return 1;
}
else if(val < 0) {
// throw;
V[0] = v1;
V[1] = v0;
V[2] = v2;
V[3] = v3;
// for (int i=0;i<4;i++)_copy[i] = *V[i];
return -1;
}
else {
// throw;
return 0;
}
}
......@@ -329,7 +320,6 @@ struct Tet {
}
bool inSphere(Vert *vd, int thread)
{
// in_sphere_counter++;
return inSphereTest_s(V[0], V[1], V[2], V[3], vd);
}
};
......@@ -357,7 +347,6 @@ public:
{
const unsigned int _array = i / _nbAlloc;
const unsigned int _offset = i % _nbAlloc;
// printf("%d %d %d\n",i,_array,_offset);
return _all[_array] + _offset;
}
......@@ -377,7 +366,6 @@ public:
{
if(_current == _nbAlloc) {
_all.push_back(new T[_nbAlloc]);
// printf("REALLOCATION %d\n",_all.size());
_current = 0;
}
_current++;
......@@ -400,23 +388,17 @@ public:
tetContainer(int nbThreads, int preallocSizePerThread)
{
// FIXME !!!
// if (nbThreads != 1) throw;
_perThread.resize(nbThreads);
#if defined(_OPENMP)
#pragma omp parallel num_threads(nbThreads)
#endif
{
#if defined(_OPENMP)
int myThread = omp_get_thread_num();
#else
int myThread = 0;
#endif
_perThread[myThread] = new aBunchOfStuff<Tet>(preallocSizePerThread);
for(unsigned int i = 0; i < _perThread.size(); i++){
_perThread[i] = new aBunchOfStuff<Tet>(preallocSizePerThread);
}
}
Tet *newTet(int thread) { return _perThread[thread]->newStuff(); }
~tetContainer() { delete _perThread[0]; }
~tetContainer()
{
for(unsigned int i = 0; i < _perThread.size(); i++)
delete _perThread[i];
}
};
typedef std::vector<Tet *> cavityContainer;
......
......@@ -125,8 +125,6 @@ namespace tetgenBR {
GRegion *_gr = ((brdata *)p)->gr;
splitQuadRecovery *_sqr = ((brdata *)p)->sqr;
in = new tetgenio();
b = new tetgenbehavior();
char opts[128];
sprintf(opts, "YpeQT%gp/%g", CTX::instance()->mesh.toleranceInitialDelaunay,
CTX::instance()->mesh.angleToleranceFacetOverlap);
......@@ -206,7 +204,7 @@ namespace tetgenBR {
std::vector<MTetrahedron *> tets;
delaunayMeshIn3D(_vertices, tets, false);
delaunayMeshIn3D(_vertices, tets); // will add 8 MVertices at the end of _vertices
if(Msg::GetErrorCount()) return false;
Msg::Debug("Points have been tetrahedralized");
......@@ -434,6 +432,7 @@ namespace tetgenBR {
hullsize = tetrahedrons->items - hullsize;
delete[] ver2tetarray;
for(unsigned int i = 0; i < tets.size(); i++) delete tets[i];
tets.clear(); // Release all memory in this vector.
}
......@@ -972,6 +971,10 @@ namespace tetgenBR {
vIter->first->setXYZ(coordinates.x(), coordinates.y(), coordinates.z());
}
// delete 8 new enclosing box vertices added in delaunayMeshIn3d
for(unsigned int i = _vertices.size() - 8; i < _vertices.size(); i++)
delete _vertices[i];
return true;
}
......@@ -1184,8 +1187,12 @@ bool meshGRegionBoundaryRecovery(GRegion *gr, splitQuadRecovery *sqr)
bool ret = false;
try {
tetgenBR::tetgenmesh *m = new tetgenBR::tetgenmesh();
m->in = new tetgenBR::tetgenio();
m->b = new tetgenBR::tetgenbehavior();
tetgenBR::brdata data = {gr, sqr};
ret = m->reconstructmesh((void *)&data);
delete m->in;
delete m->b;
delete m;
} catch(int err) {
if(err == 1) {
......
......@@ -1622,7 +1622,7 @@ void insertVerticesInRegion(GRegion *gr, int maxVert, bool _classify,
// do a 3D delaunay mesh assuming a set of vertices
void delaunayMeshIn3D(std::vector<MVertex *> &v,
std::vector<MTetrahedron *> &result, bool removeBox)
std::vector<MTetrahedron *> &result)
{
double t1 = Cpu();
delaunayTriangulation(1, 1, v, result);
......
......@@ -217,8 +217,7 @@ public:
void connectTets(std::list<MTet4 *> &, const std::set<MFace, Less_Face> * = 0);
void connectTets(std::vector<MTet4 *> &, const std::set<MFace, Less_Face> * = 0);
void delaunayMeshIn3D(std::vector<MVertex *> &, std::vector<MTetrahedron *> &,
bool removeBox = true);
void delaunayMeshIn3D(std::vector<MVertex *> &, std::vector<MTetrahedron *> &);
void insertVerticesInRegion(GRegion *gr, int maxVert = 2000000000,
bool _classify = true, splitQuadRecovery *sqr = 0);
void bowyerWatsonFrontalLayers(GRegion *gr, bool hex);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment