diff --git a/common/geometry/hetriang.cpp b/common/geometry/hetriang.cpp index b69255cdbf..eb5e59ecf7 100644 --- a/common/geometry/hetriang.cpp +++ b/common/geometry/hetriang.cpp @@ -45,6 +45,8 @@ #include #include #include +#include +#include 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(xmin-dx, ymin-dy); + NodePtr n2 = boost::make_shared(xmax+dx, ymin-dy); + NodePtr n3 = boost::make_shared(xmax+dx, ymax+dy); + NodePtr n4 = boost::make_shared(xmin-dx, ymax+dy); // diagonal - EdgePtr e1d(new Edge); // lower - EdgePtr e2d(new Edge); // upper, the twin edge + EdgePtr e1d = boost::make_shared(); + EdgePtr e2d = boost::make_shared(); // lower triangle - EdgePtr e11(new Edge); - EdgePtr e12(new Edge); + EdgePtr e11 = boost::make_shared(); + EdgePtr e12 = boost::make_shared(); // upper triangle - EdgePtr e21(new Edge); // upper upper - EdgePtr e22(new Edge); + EdgePtr e21 = boost::make_shared(); + EdgePtr e22 = boost::make_shared(); // 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); @@ -225,13 +225,10 @@ void Triangulation::removeTriangle(EdgePtr& edge) { // Remove the triangle 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* 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(); + EdgePtr e11_n = boost::make_shared(); + EdgePtr e2_n = boost::make_shared(); + EdgePtr e22_n = boost::make_shared(); + EdgePtr e3_n = boost::make_shared(); + EdgePtr e33_n = boost::make_shared(); 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(dart, cycling_check)) { + if (helper->swapTestDelaunay(dart, cycling_check)) { optimal = false; swapEdge(edge); } diff --git a/include/ttl/halfedge/hetriang.h b/include/ttl/halfedge/hetriang.h index c8326a417d..2c5380864e 100644 --- a/include/ttl/halfedge/hetriang.h +++ b/include/ttl/halfedge/hetriang.h @@ -53,6 +53,7 @@ #include #include #include +#include namespace ttl { class TriangulationHelper; @@ -68,6 +69,7 @@ namespace hed { class Edge; typedef boost::shared_ptr NodePtr; typedef boost::shared_ptr EdgePtr; + typedef boost::weak_ptr EdgeWeakPtr; typedef std::vector 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& 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* getEdges(bool skip_boundary_edges = false) const; diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 201f6b6041..234326c132 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -140,10 +141,18 @@ std::vector* 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( 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 {