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

View File

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

View File

@ -40,6 +40,7 @@
#include <class_zone.h> #include <class_zone.h>
#include <boost/range/adaptor/map.hpp> #include <boost/range/adaptor/map.hpp>
#include <boost/pointer_cast.hpp>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
#include <boost/bind.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] ); cycles[srcTag].splice( cycles[srcTag].end(), cycles[trgTag] );
if( dt->getWeight() == 0 ) // Skip already existing connections (weight == 0) if( dt->getWeight() == 0 ) // Skip already existing connections (weight == 0)
{
mstExpectedSize--; mstExpectedSize--;
}
else 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; ++mstSize;
} }
} }
@ -414,7 +423,7 @@ void RN_NET::AddItem( const ZONE_CONTAINER* aZone )
// Origin and end of bounding box for a polygon // Origin and end of bounding box for a polygon
VECTOR2I origin( polyPoints[0].x, polyPoints[0].y ); VECTOR2I origin( polyPoints[0].x, polyPoints[0].y );
VECTOR2I end( 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 // Extract polygons from zones
for( unsigned int i = 0; i < polyPoints.size(); ++i ) 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 ) ) ); m_links, BOX2I( origin, end - origin ) ) );
idxStart = i + 1; idxStart = i + 1;
origin.x = polyPoints[idxStart].x;
origin.y = polyPoints[idxStart].y; if( idxStart < polyPoints.size() )
end.x = polyPoints[idxStart].x; {
end.y = polyPoints[idxStart].y; 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 if( aNet < 0 ) // Recompute everything
{ {
unsigned int tid, i, chunk, netCount; unsigned int i, netCount;
netCount = m_board->GetNetCount(); netCount = m_board->GetNetCount();
chunk = 1;
#ifdef USE_OPENMP #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, 1)
#pragma omp for schedule(guided, chunk)
#else /* USE_OPENMP */ #else /* USE_OPENMP */
{ {
#endif #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 ) for( i = 1; i < netCount; ++i )
{ {
if( m_nets[i].IsDirty() ) if( m_nets[i].IsDirty() )
updateNet( i ); updateNet( i );
} }
} /* end of parallel section */ } /* end of parallel section */
} }
else if( aNet > 0 ) // Recompute only specific net else if( aNet > 0 ) // Recompute only specific net
{ {