Squashed memory leaks.

This commit is contained in:
Maciej Suminski 2014-03-05 14:57:14 +01:00
parent 505b38416d
commit c557e52dab
3 changed files with 102 additions and 88 deletions

View File

@ -45,6 +45,8 @@
#include <algorithm>
#include <fstream>
#include <limits>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
using namespace hed;
@ -115,28 +117,27 @@ EdgePtr Triangulation::initTwoEnclosingTriangles(NodesContainer::iterator first,
double dx = (xmax-xmin)/fac;
double dy = (ymax-ymin)/fac;
NodePtr n1(new Node(xmin-dx,ymin-dy));
NodePtr n2(new Node(xmax+dx,ymin-dy));
NodePtr n3(new Node(xmax+dx,ymax+dy));
NodePtr n4(new Node(xmin-dx,ymax+dy));
NodePtr n1 = boost::make_shared<Node>(xmin-dx, ymin-dy);
NodePtr n2 = boost::make_shared<Node>(xmax+dx, ymin-dy);
NodePtr n3 = boost::make_shared<Node>(xmax+dx, ymax+dy);
NodePtr n4 = boost::make_shared<Node>(xmin-dx, ymax+dy);
// diagonal
EdgePtr e1d(new Edge); // lower
EdgePtr e2d(new Edge); // upper, the twin edge
EdgePtr e1d = boost::make_shared<Edge>();
EdgePtr e2d = boost::make_shared<Edge>();
// lower triangle
EdgePtr e11(new Edge);
EdgePtr e12(new Edge);
EdgePtr e11 = boost::make_shared<Edge>();
EdgePtr e12 = boost::make_shared<Edge>();
// upper triangle
EdgePtr e21(new Edge); // upper upper
EdgePtr e22(new Edge);
EdgePtr e21 = boost::make_shared<Edge>();
EdgePtr e22 = boost::make_shared<Edge>();
// lower triangle
e1d->setSourceNode(n3);
e1d->setNextEdgeInFace(e11);
e1d->setTwinEdge(e2d);
e1d->setAsLeadingEdge();
addLeadingEdge(e1d);
e11->setSourceNode(n1);
@ -149,7 +150,6 @@ EdgePtr Triangulation::initTwoEnclosingTriangles(NodesContainer::iterator first,
e2d->setSourceNode(n1);
e2d->setNextEdgeInFace(e21);
e2d->setTwinEdge(e1d);
e2d->setAsLeadingEdge();
addLeadingEdge(e2d);
e21->setSourceNode(n3);
@ -226,12 +226,9 @@ void Triangulation::removeTriangle(EdgePtr& edge) {
EdgePtr e2(e1->getNextEdgeInFace());
EdgePtr e3(e2->getNextEdgeInFace());
if (e1->getTwinEdge())
e1->getTwinEdge()->setTwinEdge(EdgePtr());
if (e2->getTwinEdge())
e2->getTwinEdge()->setTwinEdge(EdgePtr());
if (e3->getTwinEdge())
e3->getTwinEdge()->setTwinEdge(EdgePtr());
e1->clear();
e2->clear();
e3->clear();
}
@ -268,6 +265,19 @@ void Triangulation::reverse_splitTriangle(EdgePtr& edge) {
// from the triangulation, but the arcs have not been deleted.
// Next delete the 6 half edges radiating from the node
// The node is maintained by handle and need not be deleted explicitly
EdgePtr estar = edge;
EdgePtr enext = estar->getTwinEdge()->getNextEdgeInFace();
estar->getTwinEdge()->clear();
estar->clear();
estar = enext;
enext = estar->getTwinEdge()->getNextEdgeInFace();
estar->getTwinEdge()->clear();
estar->clear();
enext->getTwinEdge()->clear();
enext->clear();
// Create the new triangle
e1->setNextEdgeInFace(e2);
@ -277,25 +287,6 @@ void Triangulation::reverse_splitTriangle(EdgePtr& edge) {
}
//--------------------------------------------------------------------------------------------------
// This is a "template" for iterating the boundary
/*
static void iterateBoundary(const Dart& dart) {
cout << "Iterate boundary 2" << endl;
// input is a dart at the boundary
Dart dart_iter = dart;
do {
if (helper->isBoundaryEdge(dart_iter))
dart_iter.alpha0().alpha1();
else
dart_iter.alpha2().alpha1();
} while(dart_iter != dart);
}
*/
//--------------------------------------------------------------------------------------------------
Dart Triangulation::createDart() {
@ -332,18 +323,19 @@ bool Triangulation::removeLeadingEdgeFromList(EdgePtr& leadingEdge) {
//--------------------------------------------------------------------------------------------------
void Triangulation::cleanAll() {
leadingEdges_.clear();
BOOST_FOREACH(EdgePtr& edge, leadingEdges_)
edge->setNextEdgeInFace(EdgePtr());
}
//--------------------------------------------------------------------------------------------------
void Triangulation::swapEdge(Dart& dart) {
if (!dart.getEdge()->isConstrained()) swapEdge(dart.getEdge());
swapEdge(dart.getEdge());
}
//--------------------------------------------------------------------------------------------------
void Triangulation::splitTriangle(Dart& dart, NodePtr point) {
void Triangulation::splitTriangle(Dart& dart, const NodePtr& point) {
EdgePtr edge = splitTriangle(dart.getEdge(), point);
dart.init(edge);
}
@ -429,7 +421,7 @@ list<EdgePtr>* Triangulation::getEdges(bool skip_boundary_edges) const {
//--------------------------------------------------------------------------------------------------
EdgePtr Triangulation::splitTriangle(EdgePtr& edge, NodePtr& point) {
EdgePtr Triangulation::splitTriangle(EdgePtr& edge, const NodePtr& point) {
// Add a node by just splitting a triangle into three triangles
// Assumes the half edge is located in the triangle
@ -457,12 +449,12 @@ EdgePtr Triangulation::splitTriangle(EdgePtr& edge, NodePtr& point) {
EdgePtr e3(e2->getNextEdgeInFace());
NodePtr n3(e3->getSourceNode());
EdgePtr e1_n(new Edge);
EdgePtr e11_n(new Edge);
EdgePtr e2_n(new Edge);
EdgePtr e22_n(new Edge);
EdgePtr e3_n(new Edge);
EdgePtr e33_n(new Edge);
EdgePtr e1_n = boost::make_shared<Edge>();
EdgePtr e11_n = boost::make_shared<Edge>();
EdgePtr e2_n = boost::make_shared<Edge>();
EdgePtr e22_n = boost::make_shared<Edge>();
EdgePtr e3_n = boost::make_shared<Edge>();
EdgePtr e33_n = boost::make_shared<Edge>();
e1_n->setSourceNode(n1);
e11_n->setSourceNode(point);
@ -503,7 +495,7 @@ EdgePtr Triangulation::splitTriangle(EdgePtr& edge, NodePtr& point) {
else if(e3->isLeadingEdge())
removeLeadingEdgeFromList(e3);
else
return EdgePtr();
assert( false ); // one of the edges should be leading
addLeadingEdge(e1_n);
addLeadingEdge(e2_n);
@ -640,7 +632,7 @@ void Triangulation::optimizeDelaunay() {
Dart dart(edge);
// Constrained edges should not be swapped
if (!edge->isConstrained() && helper->swapTestDelaunay<TTLtraits>(dart, cycling_check)) {
if (helper->swapTestDelaunay<TTLtraits>(dart, cycling_check)) {
optimal = false;
swapEdge(edge);
}

View File

@ -53,6 +53,7 @@
#include <fstream>
#include <ttl/ttl_util.h>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
namespace ttl {
class TriangulationHelper;
@ -68,6 +69,7 @@ namespace hed {
class Edge;
typedef boost::shared_ptr<Node> NodePtr;
typedef boost::shared_ptr<Edge> EdgePtr;
typedef boost::weak_ptr<Edge> EdgeWeakPtr;
typedef std::vector<NodePtr> NodesContainer;
//------------------------------------------------------------------------------------------------
@ -154,8 +156,7 @@ public:
class Edge {
public:
/// Constructor
Edge() : weight_(0)
{ flags_.isLeadingEdge_ = false; flags_.isConstrained_ = false; }
Edge() : weight_(0), isLeadingEdge_(false) {}
/// Destructor
virtual ~Edge() {}
@ -170,49 +171,52 @@ public:
void setTwinEdge(const EdgePtr& edge) { twinEdge_ = edge; }
/// Sets the edge as a leading edge
void setAsLeadingEdge(bool val=true) { flags_.isLeadingEdge_ = val; }
void setAsLeadingEdge(bool val=true) { isLeadingEdge_ = val; }
/// Checks if an edge is a leading edge
bool isLeadingEdge() const { return flags_.isLeadingEdge_; }
/// Sets the edge as a constrained edge
void setConstrained(bool val=true) { flags_.isConstrained_ = val;
if (twinEdge_) twinEdge_->flags_.isConstrained_ = val; }
/// Checks if an edge is constrained
bool isConstrained() const { return flags_.isConstrained_; }
bool isLeadingEdge() const { return isLeadingEdge_; }
/// Returns the twin edge
const EdgePtr& getTwinEdge() const { return twinEdge_; };
EdgePtr getTwinEdge() const { return twinEdge_.lock(); };
void clearTwinEdge() { twinEdge_.reset(); }
/// Returns the next edge in face
const EdgePtr& getNextEdgeInFace() const { return nextEdgeInFace_; }
/// Retuns the source node
virtual const NodePtr& getSourceNode() const { return sourceNode_; }
const NodePtr& getSourceNode() const { return sourceNode_; }
/// Returns the target node
virtual const NodePtr& getTargetNode() const { return getNextEdgeInFace()->getSourceNode(); }
virtual const NodePtr& getTargetNode() const { return nextEdgeInFace_->getSourceNode(); }
void setWeight( unsigned int weight ) { weight_ = weight; }
unsigned int getWeight() const { return weight_; }
void clear()
{
sourceNode_.reset();
nextEdgeInFace_.reset();
if( !twinEdge_.expired() )
{
twinEdge_.lock()->clearTwinEdge();
twinEdge_.reset();
}
}
protected:
NodePtr sourceNode_;
EdgePtr twinEdge_;
EdgeWeakPtr twinEdge_;
EdgePtr nextEdgeInFace_;
unsigned int weight_;
struct {
bool isLeadingEdge_;
bool isConstrained_;
} flags_;
bool isLeadingEdge_;
}; // End of class Edge
/** \class EdgeMST
* \brief \b %Specialization of Edge class to be used for Minimum Spanning Tree algorithm.
* \brief \b Specialization of %Edge class to be used for Minimum Spanning Tree algorithm.
*/
class EdgeMST : public Edge
{
@ -224,10 +228,17 @@ public:
target_(target)
{ sourceNode_ = source; weight_ = weight; }
EdgeMST( const Edge& edge )
{
sourceNode_ = edge.getSourceNode();
target_ = edge.getTargetNode();
weight_ = edge.getWeight();
}
~EdgeMST() {};
/// @copydoc Edge::setSourceNode()
const NodePtr& getTargetNode() const { return target_; }
virtual const NodePtr& getTargetNode() const { return target_; }
};
@ -288,7 +299,7 @@ public:
* \param dart
* Output: A CCW dart incident with the new node; see the figure.
*/
void splitTriangle(Dart& dart, NodePtr point);
void splitTriangle(Dart& dart, const NodePtr& point);
/** The reverse operation of TTLtraits::splitTriangle.
* This function is only required for functions that involve
@ -332,7 +343,7 @@ public:
void swapEdge(EdgePtr& diagonal);
/// Splits the triangle associated with edge into three new triangles joining at point
EdgePtr splitTriangle(EdgePtr& edge, NodePtr& point);
EdgePtr splitTriangle(EdgePtr& edge, const NodePtr& point);
// Functions required by TTL for removing nodes in a Delaunay triangulation
@ -350,7 +361,7 @@ public:
const std::list<EdgePtr>& getLeadingEdges() const { return leadingEdges_; }
/// Returns the number of triangles
int noTriangles() const { return (int)leadingEdges_.size(); }
int noTriangles() const { return (int)leadingEdges_.size(); }
/// Returns a list of half-edges (one half-edge for each arc)
std::list<EdgePtr>* getEdges(bool skip_boundary_edges = false) const;

View File

@ -40,6 +40,7 @@
#include <class_zone.h>
#include <boost/range/adaptor/map.hpp>
#include <boost/pointer_cast.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/bind.hpp>
@ -140,10 +141,18 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
cycles[srcTag].splice( cycles[srcTag].end(), cycles[trgTag] );
if( dt->getWeight() == 0 ) // Skip already existing connections (weight == 0)
{
mstExpectedSize--;
}
else
{
mst->push_back( dt );
// Do a copy of edge, but make it RN_EDGE_MST. In contrary to RN_EDGE,
// RN_EDGE_MST saves both source and target node and does not require any other
// edges to exist for getting source/target nodes
RN_EDGE_MST_PTR newEdge = boost::make_shared<RN_EDGE_MST>( dt->getSourceNode(),
dt->getTargetNode(),
dt->getWeight() );
mst->push_back( newEdge );
++mstSize;
}
}
@ -414,7 +423,7 @@ void RN_NET::AddItem( const ZONE_CONTAINER* aZone )
// Origin and end of bounding box for a polygon
VECTOR2I origin( polyPoints[0].x, polyPoints[0].y );
VECTOR2I end( polyPoints[0].x, polyPoints[0].y );
int idxStart = 0;
unsigned int idxStart = 0;
// Extract polygons from zones
for( unsigned int i = 0; i < polyPoints.size(); ++i )
@ -440,10 +449,14 @@ void RN_NET::AddItem( const ZONE_CONTAINER* aZone )
m_links, BOX2I( origin, end - origin ) ) );
idxStart = i + 1;
origin.x = polyPoints[idxStart].x;
origin.y = polyPoints[idxStart].y;
end.x = polyPoints[idxStart].x;
end.y = polyPoints[idxStart].y;
if( idxStart < polyPoints.size() )
{
origin.x = polyPoints[idxStart].x;
origin.y = polyPoints[idxStart].y;
end.x = polyPoints[idxStart].x;
end.y = polyPoints[idxStart].y;
}
}
}
@ -968,25 +981,23 @@ void RN_DATA::Recalculate( int aNet )
{
if( aNet < 0 ) // Recompute everything
{
unsigned int tid, i, chunk, netCount;
unsigned int i, netCount;
netCount = m_board->GetNetCount();
chunk = 1;
#ifdef USE_OPENMP
#pragma omp parallel shared(chunk, netCount) private(i, tid)
#pragma omp parallel shared(netCount) private(i)
{
tid = omp_get_thread_num();
#pragma omp for schedule(guided, chunk)
#pragma omp for schedule(guided, 1)
#else /* USE_OPENMP */
{
#endif
// Start with net number 1, as 0 stand for not connected
// Start with net number 1, as 0 stands for not connected
for( i = 1; i < netCount; ++i )
{
if( m_nets[i].IsDirty() )
updateNet( i );
}
} /* end of parallel section */
} /* end of parallel section */
}
else if( aNet > 0 ) // Recompute only specific net
{