Commit 468e14f0 authored by Maciej Suminski's avatar Maciej Suminski

Merged ratsnest_threadsafe branch.

parents 3a15f5ad 1490099d
...@@ -125,6 +125,13 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) ...@@ -125,6 +125,13 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden" ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden" )
endif() endif()
find_package( OpenMP QUIET )
if( OPENMP_FOUND )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}" )
add_definitions( -DUSE_OPENMP )
endif()
if( MINGW ) if( MINGW )
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" ) set( CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" )
......
...@@ -51,8 +51,6 @@ using namespace hed; ...@@ -51,8 +51,6 @@ using namespace hed;
using namespace std; using namespace std;
Triangulation* TTLtraits::triang_ = NULL;
#ifdef TTL_USE_NODE_ID #ifdef TTL_USE_NODE_ID
int Node::id_count = 0; int Node::id_count = 0;
#endif #endif
...@@ -164,11 +162,30 @@ EdgePtr Triangulation::initTwoEnclosingTriangles(NodesContainer::iterator first, ...@@ -164,11 +162,30 @@ EdgePtr Triangulation::initTwoEnclosingTriangles(NodesContainer::iterator first,
} }
//--------------------------------------------------------------------------------------------------
Triangulation::Triangulation() {
helper = new ttl::TriangulationHelper( *this );
}
//--------------------------------------------------------------------------------------------------
Triangulation::Triangulation(const Triangulation& tr) {
std::cout << "Triangulation: Copy constructor not present - EXIT.";
exit(-1);
}
//--------------------------------------------------------------------------------------------------
Triangulation::~Triangulation() {
cleanAll();
delete helper;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void Triangulation::createDelaunay(NodesContainer::iterator first, void Triangulation::createDelaunay(NodesContainer::iterator first,
NodesContainer::iterator last) { NodesContainer::iterator last) {
TTLtraits::triang_ = this;
cleanAll(); cleanAll();
EdgePtr bedge = initTwoEnclosingTriangles(first, last); EdgePtr bedge = initTwoEnclosingTriangles(first, last);
...@@ -178,7 +195,7 @@ void Triangulation::createDelaunay(NodesContainer::iterator first, ...@@ -178,7 +195,7 @@ void Triangulation::createDelaunay(NodesContainer::iterator first,
NodesContainer::iterator it; NodesContainer::iterator it;
for (it = first; it != last; ++it) { for (it = first; it != last; ++it) {
ttl::insertNode<TTLtraits>(d_iter, *it); helper->insertNode<TTLtraits>(d_iter, *it);
} }
// In general (e.g. for the triangle based data structure), the initial dart // In general (e.g. for the triangle based data structure), the initial dart
...@@ -189,7 +206,7 @@ void Triangulation::createDelaunay(NodesContainer::iterator first, ...@@ -189,7 +206,7 @@ void Triangulation::createDelaunay(NodesContainer::iterator first,
// triangle "outside" the triangulation.) // triangle "outside" the triangulation.)
// Assumes rectangular domain // Assumes rectangular domain
ttl::removeRectangularBoundary<TTLtraits>(dc); helper->removeRectangularBoundary<TTLtraits>(dc);
} }
...@@ -269,7 +286,7 @@ cout << "Iterate boundary 2" << endl; ...@@ -269,7 +286,7 @@ cout << "Iterate boundary 2" << endl;
Dart dart_iter = dart; Dart dart_iter = dart;
do { do {
if (ttl::isBoundaryEdge(dart_iter)) if (helper->isBoundaryEdge(dart_iter))
dart_iter.alpha0().alpha1(); dart_iter.alpha0().alpha1();
else else
dart_iter.alpha2().alpha1(); dart_iter.alpha2().alpha1();
...@@ -322,6 +339,31 @@ void Triangulation::cleanAll() { ...@@ -322,6 +339,31 @@ void Triangulation::cleanAll() {
} }
//--------------------------------------------------------------------------------------------------
void Triangulation::swapEdge(Dart& dart) {
if (!dart.getEdge()->isConstrained()) swapEdge(dart.getEdge());
}
//--------------------------------------------------------------------------------------------------
void Triangulation::splitTriangle(Dart& dart, NodePtr point) {
EdgePtr edge = splitTriangle(dart.getEdge(), point);
dart.init(edge);
}
//--------------------------------------------------------------------------------------------------
void Triangulation::reverse_splitTriangle(Dart& dart) {
reverse_splitTriangle(dart.getEdge());
}
//--------------------------------------------------------------------------------------------------
void Triangulation::removeBoundaryTriangle(Dart& d) {
removeTriangle(d.getEdge());
}
#ifdef TTL_USE_NODE_FLAG #ifdef TTL_USE_NODE_FLAG
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// This is a "template" for accessing all nodes (but multiple tests) // This is a "template" for accessing all nodes (but multiple tests)
...@@ -486,7 +528,7 @@ void Triangulation::swapEdge(EdgePtr& diagonal) { ...@@ -486,7 +528,7 @@ void Triangulation::swapEdge(EdgePtr& diagonal) {
// Note that diagonal is both input and output and it is always // Note that diagonal is both input and output and it is always
// kept in counterclockwise direction (this is not required by all // kept in counterclockwise direction (this is not required by all
// finctions in ttl:: now) // functions in TriangulationHelper now)
// Swap by rotating counterclockwise // Swap by rotating counterclockwise
// Use the same objects - no deletion or new objects // Use the same objects - no deletion or new objects
...@@ -567,7 +609,7 @@ bool Triangulation::checkDelaunay() const { ...@@ -567,7 +609,7 @@ bool Triangulation::checkDelaunay() const {
// only one of the half-edges // only one of the half-edges
if (!twinedge || (size_t)edge.get() > (size_t)twinedge.get()) { if (!twinedge || (size_t)edge.get() > (size_t)twinedge.get()) {
Dart dart(edge); Dart dart(edge);
if (ttl::swapTestDelaunay<TTLtraits>(dart)) { if (helper->swapTestDelaunay<TTLtraits>(dart)) {
noNotDelaunay++; noNotDelaunay++;
//printEdge(dart,os); os << "\n"; //printEdge(dart,os); os << "\n";
...@@ -610,7 +652,7 @@ void Triangulation::optimizeDelaunay() { ...@@ -610,7 +652,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() && ttl::swapTestDelaunay<TTLtraits>(dart, cycling_check)) { if (!edge->isConstrained() && helper->swapTestDelaunay<TTLtraits>(dart, cycling_check)) {
optimal = false; optimal = false;
swapEdge(edge); swapEdge(edge);
} }
...@@ -632,7 +674,7 @@ EdgePtr Triangulation::getInteriorNode() const { ...@@ -632,7 +674,7 @@ EdgePtr Triangulation::getInteriorNode() const {
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
if (edge->getTwinEdge()) { if (edge->getTwinEdge()) {
if (!ttl::isBoundaryNode(Dart(edge))) if (!helper->isBoundaryNode(Dart(edge)))
return edge; return edge;
} }
edge = edge->getNextEdgeInFace(); edge = edge->getNextEdgeInFace();
...@@ -643,18 +685,18 @@ EdgePtr Triangulation::getInteriorNode() const { ...@@ -643,18 +685,18 @@ EdgePtr Triangulation::getInteriorNode() const {
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
static EdgePtr getBoundaryEdgeInTriangle(const EdgePtr& e) { EdgePtr Triangulation::getBoundaryEdgeInTriangle(const EdgePtr& e) const {
EdgePtr edge = e; EdgePtr edge = e;
if (ttl::isBoundaryEdge(Dart(edge))) if (helper->isBoundaryEdge(Dart(edge)))
return edge; return edge;
edge = edge->getNextEdgeInFace(); edge = edge->getNextEdgeInFace();
if (ttl::isBoundaryEdge(Dart(edge))) if (helper->isBoundaryEdge(Dart(edge)))
return edge; return edge;
edge = edge->getNextEdgeInFace(); edge = edge->getNextEdgeInFace();
if (ttl::isBoundaryEdge(Dart(edge))) if (helper->isBoundaryEdge(Dart(edge)))
return edge; return edge;
return EdgePtr(); return EdgePtr();
......
...@@ -69,9 +69,6 @@ namespace hed { ...@@ -69,9 +69,6 @@ namespace hed {
struct TTLtraits { struct TTLtraits {
// The actual triangulation object
static Triangulation* triang_;
/** The floating point type used in calculations /** The floating point type used in calculations
* involving scalar products and cross products. * involving scalar products and cross products.
*/ */
...@@ -172,127 +169,6 @@ namespace hed { ...@@ -172,127 +169,6 @@ namespace hed {
} }
//@} // End of Geometric Predicates Group //@} // End of Geometric Predicates Group
// A rationale for directing these functions to traits is:
// e.g., constraints
//----------------------------------------------------------------------------------------------
/* Checks if the edge associated with \e dart should be swapped
* according to the Delaunay criterion.<br>
*
* \note
* This function is also present in the TTL as ttl::swapTestDelaunay.<br>
* Thus, the function can be implemented simply as:
* \code
* { return ttl::swapTestDelaunay<TTLtraits>(dart); }
* \endcode
*/
//static bool swapTestDelaunay(const Dart& dart) {
// return ttl::swapTestDelaunay<TTLtraits>(dart);
//}
//----------------------------------------------------------------------------------------------
/* Checks if the edge associated with \e dart can be swapped, i.e.,
* if the edge is a diagonal in a (strictly) convex quadrilateral.
* This function is also present as ttl::swappableEdge.
*/
//static bool swappableEdge(const Dart& dart) {
// return ttl::swappableEdge<TTLtraits>(dart);
//}
//----------------------------------------------------------------------------------------------
/* Checks if the edge associated with \e dart should be \e fixed, meaning
* that it should never be swapped. ??? Use when constraints.
*/
//static bool fixedEdge(const Dart& dart) {
// return dart.getEdge()->isConstrained();
//}
//----------------------------------------------------------------------------------------------
// ----------------------- Functions for Delaunay Triangulation Group -------------------------
//----------------------------------------------------------------------------------------------
/** @name Functions for Delaunay Triangulation */
//@{
//----------------------------------------------------------------------------------------------
/** Swaps the edge associated with \e dart in the actual data structure.
*
* <center>
* \image html swapEdge.gif
* </center>
*
* \param dart
* Some of the functions require a dart as output.
* If this is required by the actual function, the dart should be delivered
* back in a position as seen if it was glued to the edge when swapping (rotating)
* the edge CCW; see the figure.
*
* \note
* - If the edge is \e constrained, or if it should not be swapped for
* some other reason, this function need not do the actual swap of the edge.
* - Some functions in TTL require that \c swapEdge is implemented such that
* darts outside the quadrilateral are not affected by the swap.
*/
static void swapEdge(Dart& dart) {
if (!dart.getEdge()->isConstrained()) triang_->swapEdge(dart.getEdge());
}
//----------------------------------------------------------------------------------------------
/** Splits the triangle associated with \e dart in the actual data structure into
* three new triangles joining at \e point.
*
* <center>
* \image html splitTriangle.gif
* </center>
*
* \param dart
* Output: A CCW dart incident with the new node; see the figure.
*/
static void splitTriangle(Dart& dart, NodePtr point) {
EdgePtr edge = triang_->splitTriangle(dart.getEdge(), point);
dart.init(edge);
}
//@} // End of Functions for Delaunay Triangulation group
//----------------------------------------------------------------------------------------------
// --------------------------- Functions for removing nodes Group -----------------------------
//----------------------------------------------------------------------------------------------
/** @name Functions for removing nodes */
//@{
//----------------------------------------------------------------------------------------------
/** The reverse operation of TTLtraits::splitTriangle.
* This function is only required for functions that involve
* removal of interior nodes; see for example ttl::removeInteriorNode.
*
* <center>
* \image html reverse_splitTriangle.gif
* </center>
*/
static void reverse_splitTriangle(Dart& dart) {
triang_->reverse_splitTriangle(dart.getEdge());
}
//----------------------------------------------------------------------------------------------
/** Removes a triangle with an edge at the boundary of the triangulation
* in the actual data structure
*/
static void removeBoundaryTriangle(Dart& d) {
triang_->removeTriangle(d.getEdge());
}
//@} // End of Functions for removing nodes Group
}; };
}; // End of hed namespace }; // End of hed namespace
......
...@@ -51,10 +51,13 @@ ...@@ -51,10 +51,13 @@
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <ttl/ttl.h>
#include <ttl/ttl_util.h> #include <ttl/ttl_util.h>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
namespace ttl {
class TriangulationHelper;
};
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// The half-edge data structure // The half-edge data structure
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
...@@ -242,26 +245,75 @@ public: ...@@ -242,26 +245,75 @@ public:
class Triangulation { class Triangulation {
protected: protected:
list<EdgePtr> leadingEdges_; // one half-edge for each arc std::list<EdgePtr> leadingEdges_; // one half-edge for each arc
ttl::TriangulationHelper* helper;
void addLeadingEdge(EdgePtr& edge) { void addLeadingEdge(EdgePtr& edge) {
edge->setAsLeadingEdge(); edge->setAsLeadingEdge();
leadingEdges_.push_front( edge ); leadingEdges_.push_front( edge );
} }
bool removeLeadingEdgeFromList(EdgePtr& leadingEdge); bool removeLeadingEdgeFromList(EdgePtr& leadingEdge);
void cleanAll(); void cleanAll();
/** Swaps the edge associated with \e dart in the actual data structure.
*
* <center>
* \image html swapEdge.gif
* </center>
*
* \param dart
* Some of the functions require a dart as output.
* If this is required by the actual function, the dart should be delivered
* back in a position as seen if it was glued to the edge when swapping (rotating)
* the edge CCW; see the figure.
*
* \note
* - If the edge is \e constrained, or if it should not be swapped for
* some other reason, this function need not do the actual swap of the edge.
* - Some functions in TTL require that \c swapEdge is implemented such that
* darts outside the quadrilateral are not affected by the swap.
*/
void swapEdge(Dart& dart);
/** Splits the triangle associated with \e dart in the actual data structure into
* three new triangles joining at \e point.
*
* <center>
* \image html splitTriangle.gif
* </center>
*
* \param dart
* Output: A CCW dart incident with the new node; see the figure.
*/
void splitTriangle(Dart& dart, NodePtr point);
/** The reverse operation of TTLtraits::splitTriangle.
* This function is only required for functions that involve
* removal of interior nodes; see for example TrinagulationHelper::removeInteriorNode.
*
* <center>
* \image html reverse_splitTriangle.gif
* </center>
*/
void reverse_splitTriangle(Dart& dart);
/** Removes a triangle with an edge at the boundary of the triangulation
* in the actual data structure
*/
void removeBoundaryTriangle(Dart& d);
public: public:
/// Default constructor /// Default constructor
Triangulation() {} Triangulation();
/// Copy constructor /// Copy constructor
Triangulation(const Triangulation& tr) { Triangulation(const Triangulation& tr);
std::cout << "Triangulation: Copy constructor not present - EXIT.";
exit(-1);
}
/// Destructor /// Destructor
~Triangulation() { cleanAll(); } ~Triangulation();
/// Creates a Delaunay triangulation from a set of points /// Creates a Delaunay triangulation from a set of points
void createDelaunay(NodesContainer::iterator first, void createDelaunay(NodesContainer::iterator first,
...@@ -295,20 +347,20 @@ public: ...@@ -295,20 +347,20 @@ public:
Dart createDart(); Dart createDart();
/// Returns a list of "triangles" (one leading half-edge for each triangle) /// Returns a list of "triangles" (one leading half-edge for each triangle)
const 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)
list<EdgePtr>* getEdges(bool skip_boundary_edges = false) const; std::list<EdgePtr>* getEdges(bool skip_boundary_edges = false) const;
#ifdef TTL_USE_NODE_FLAG #ifdef TTL_USE_NODE_FLAG
/// Sets flag in all the nodes /// Sets flag in all the nodes
void flagNodes(bool flag) const; void flagNodes(bool flag) const;
/// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node. /// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node.
list<NodePtr>* getNodes() const; std::list<NodePtr>* getNodes() const;
#endif #endif
/// Swaps edges until the triangulation is Delaunay (constrained edges are not swapped) /// Swaps edges until the triangulation is Delaunay (constrained edges are not swapped)
...@@ -320,12 +372,16 @@ public: ...@@ -320,12 +372,16 @@ public:
/// Returns an arbitrary interior node (as the source node of the returned edge) /// Returns an arbitrary interior node (as the source node of the returned edge)
EdgePtr getInteriorNode() const; EdgePtr getInteriorNode() const;
EdgePtr getBoundaryEdgeInTriangle(const EdgePtr& e) const;
/// Returns an arbitrary boundary edge /// Returns an arbitrary boundary edge
EdgePtr getBoundaryEdge() const; EdgePtr getBoundaryEdge() const;
/// Print edges for plotting with, e.g., gnuplot /// Print edges for plotting with, e.g., gnuplot
void printEdges(std::ofstream& os) const; void printEdges(std::ofstream& os) const;
friend class ttl::TriangulationHelper;
}; // End of class Triangulation }; // End of class Triangulation
......
This diff is collapsed.
...@@ -51,9 +51,6 @@ ...@@ -51,9 +51,6 @@
static ofstream ofile_constr("qweCons.dat"); static ofstream ofile_constr("qweCons.dat");
#endif #endif
//using namespace std;
/** \brief Constrained Delaunay triangulation /** \brief Constrained Delaunay triangulation
* *
* Basic generic algorithms in TTL for inserting a constrained edge between two existing nodes.\n * Basic generic algorithms in TTL for inserting a constrained edge between two existing nodes.\n
...@@ -61,7 +58,7 @@ ...@@ -61,7 +58,7 @@
* See documentation for the namespace ttl for general requirements and assumptions. * See documentation for the namespace ttl for general requirements and assumptions.
* *
* \author * \author
* Øyvind Hjelle, oyvindhj@ifi.uio.no * yvind Hjelle, oyvindhj@ifi.uio.no
*/ */
namespace ttl_constr { namespace ttl_constr {
...@@ -73,6 +70,9 @@ namespace ttl_constr { ...@@ -73,6 +70,9 @@ namespace ttl_constr {
#endif #endif
class ConstrainedTriangulation
{
public:
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
/* Checks if \e dart has start and end points in \e dstart and \e dend. /* Checks if \e dart has start and end points in \e dstart and \e dend.
* *
...@@ -89,14 +89,14 @@ namespace ttl_constr { ...@@ -89,14 +89,14 @@ namespace ttl_constr {
* A bool confirming that it's the constraint or not * A bool confirming that it's the constraint or not
* *
* \using * \using
* ttl::same_0_orbit * same_0_orbit
*/ */
template <class DartType> template <class DartType>
bool isTheConstraint(const DartType& dart, const DartType& dstart, const DartType& dend) { static bool isTheConstraint(const DartType& dart, const DartType& dstart, const DartType& dend) {
DartType d0 = dart; DartType d0 = dart;
d0.alpha0(); // CW d0.alpha0(); // CW
if ((ttl::same_0_orbit(dstart, dart) && ttl::same_0_orbit(dend, d0)) || if ((ttl::TriangulationHelper::same_0_orbit(dstart, dart) && ttl::TriangulationHelper::same_0_orbit(dend, d0)) ||
(ttl::same_0_orbit(dstart, d0) && ttl::same_0_orbit(dend, dart))) { (ttl::TriangulationHelper::same_0_orbit(dstart, d0) && ttl::TriangulationHelper::same_0_orbit(dend, dart))) {
return true; return true;
} }
return false; return false;
...@@ -123,7 +123,7 @@ namespace ttl_constr { ...@@ -123,7 +123,7 @@ namespace ttl_constr {
* TraitsType::orient2d * TraitsType::orient2d
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
bool crossesConstraint(DartType& dstart, DartType& dend, DartType& d1, DartType& d2) { static bool crossesConstraint(DartType& dstart, DartType& dend, DartType& d1, DartType& d2) {
typename TraitsType::real_type orient_1 = TraitsType::orient2d(dstart,d1,dend); typename TraitsType::real_type orient_1 = TraitsType::orient2d(dstart,d1,dend);
typename TraitsType::real_type orient_2 = TraitsType::orient2d(dstart,d2,dend); typename TraitsType::real_type orient_2 = TraitsType::orient2d(dstart,d2,dend);
...@@ -156,12 +156,12 @@ namespace ttl_constr { ...@@ -156,12 +156,12 @@ namespace ttl_constr {
* The dart \e d making the smallest positive (or == 0) angle * The dart \e d making the smallest positive (or == 0) angle
* *
* \using * \using
* ttl::isBoundaryNode * isBoundaryNode
* ttl::positionAtNextBoundaryEdge * positionAtNextBoundaryEdge
* TraitsType::orient2d * TraitsType::orient2d
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
DartType getAtSmallestAngle(const DartType& dstart, const DartType& dend) { static DartType getAtSmallestAngle(const DartType& dstart, const DartType& dend) {
// - Must boundary be convex??? // - Must boundary be convex???
// - Handle the case where the constraint is already present??? // - Handle the case where the constraint is already present???
...@@ -169,9 +169,9 @@ namespace ttl_constr { ...@@ -169,9 +169,9 @@ namespace ttl_constr {
// (dstart and dend may define a boundary edge) // (dstart and dend may define a boundary edge)
DartType d_iter = dstart; DartType d_iter = dstart;
if (ttl::isBoundaryNode(d_iter)) { if (ttl::TriangulationHelper::isBoundaryNode(d_iter)) {
d_iter.alpha1(); // CW d_iter.alpha1(); // CW
ttl::positionAtNextBoundaryEdge(d_iter); // CCW (was rotated CW to the boundary) ttl::TriangulationHelper::positionAtNextBoundaryEdge(d_iter); // CCW (was rotated CW to the boundary)
} }
// assume convex boundary; see comments // assume convex boundary; see comments
...@@ -273,7 +273,7 @@ namespace ttl_constr { ...@@ -273,7 +273,7 @@ namespace ttl_constr {
* Returns the next "collinear" starting node such that dend is returned when done. * Returns the next "collinear" starting node such that dend is returned when done.
*/ */
template <class TraitsType, class DartType, class ListType> template <class TraitsType, class DartType, class ListType>
DartType findCrossingEdges(const DartType& dstart, const DartType& dend, ListType& elist) { static DartType findCrossingEdges(const DartType& dstart, const DartType& dend, ListType& elist) {
const DartType my_start = getAtSmallestAngle<TraitsType>(dstart, dend); const DartType my_start = getAtSmallestAngle<TraitsType>(dstart, dend);
DartType my_end = getAtSmallestAngle<TraitsType>(dend, dstart); DartType my_end = getAtSmallestAngle<TraitsType>(dend, dstart);
...@@ -387,15 +387,16 @@ namespace ttl_constr { ...@@ -387,15 +387,16 @@ namespace ttl_constr {
* A list containing all the edges crossing the spesified constraint * A list containing all the edges crossing the spesified constraint
* *
* \using * \using
* ttl::swappableEdge * swappableEdge
* ttl::swapEdgeInList * swapEdgeInList
* ttl::crossesConstraint * crossesConstraint
* ttl::isTheConstraint * isTheConstraint
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
void transformToConstraint(DartType& dstart, DartType& dend, std::list<DartType>& elist) { void transformToConstraint(ttl::TriangulationHelper helper, DartType& dstart, DartType& dend,
std::list<DartType>& elist) const {
typename list<DartType>::iterator it, used; typename std::list<DartType>::iterator it, used;
// We may enter in a situation where dstart and dend are altered because of a swap. // We may enter in a situation where dstart and dend are altered because of a swap.
// (The general rule is that darts inside the actual quadrilateral can be changed, // (The general rule is that darts inside the actual quadrilateral can be changed,
...@@ -423,7 +424,7 @@ namespace ttl_constr { ...@@ -423,7 +424,7 @@ namespace ttl_constr {
if (counter > dartsInList) if (counter > dartsInList)
break; break;
if (ttl::swappableEdge<TraitsType, DartType>(*it, true)) { if (ttl::TriangulationHelper::swappableEdge<TraitsType, DartType>(*it, true)) {
// Dyn & Goren & Rippa 's notation: // Dyn & Goren & Rippa 's notation:
// The node assosiated with dart *it is denoted u_m. u_m has edges crossing the constraint // The node assosiated with dart *it is denoted u_m. u_m has edges crossing the constraint
// named w_1, ... , w_r . The other node to the edge assosiated with dart *it is w_s. // named w_1, ... , w_r . The other node to the edge assosiated with dart *it is w_s.
...@@ -456,7 +457,7 @@ namespace ttl_constr { ...@@ -456,7 +457,7 @@ namespace ttl_constr {
end = true; end = true;
// This is the only place swapping is called when inserting a constraint // This is the only place swapping is called when inserting a constraint
ttl::swapEdgeInList<TraitsType, DartType>(it,elist); helper.swapEdgeInList<TraitsType, DartType>(it,elist);
// If we, during look-ahead, found that dstart and/or dend were in the quadrilateral, // If we, during look-ahead, found that dstart and/or dend were in the quadrilateral,
// we update them. // we update them.
...@@ -512,6 +513,8 @@ namespace ttl_constr { ...@@ -512,6 +513,8 @@ namespace ttl_constr {
} }
}; // End of ConstrainedTriangulation class
}; // End of ttl_constr namespace scope }; // End of ttl_constr namespace scope
...@@ -546,14 +549,14 @@ namespace ttl { // (extension) ...@@ -546,14 +549,14 @@ namespace ttl { // (extension)
* - \ref hed::TTLtraits::swapEdge "TraitsType::swapEdge" (DartType&) * - \ref hed::TTLtraits::swapEdge "TraitsType::swapEdge" (DartType&)
* *
* \using * \using
* - ttl::optimizeDelaunay if \e optimize_delaunay is set to \c true * - optimizeDelaunay if \e optimize_delaunay is set to \c true
* *
* \par Assumes: * \par Assumes:
* - The constrained edge must be inside the existing triangulation (and it cannot * - The constrained edge must be inside the existing triangulation (and it cannot
* cross the boundary of the triangulation). * cross the boundary of the triangulation).
*/ */
template <class TraitsType, class DartType> template <class TraitsType, class DartType>
DartType insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay) { DartType TriangulationHelper::insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay) {
// Assumes: // Assumes:
// - It is the users responsibility to avoid crossing constraints // - It is the users responsibility to avoid crossing constraints
...@@ -567,8 +570,8 @@ namespace ttl { // (extension) ...@@ -567,8 +570,8 @@ namespace ttl { // (extension)
// calls itself recursively. // calls itself recursively.
// RECURSION // RECURSION
list<DartType> elist; std::list<DartType> elist;
DartType next_start = ttl_constr::findCrossingEdges<TraitsType>(dstart, dend, elist); DartType next_start = ttl_constr::ConstrainedTriangulation::findCrossingEdges<TraitsType>(dstart, dend, elist);
// If there are no crossing edges (elist is empty), we assume that the constraint // If there are no crossing edges (elist is empty), we assume that the constraint
// is an existing edge. // is an existing edge.
...@@ -583,7 +586,7 @@ namespace ttl { // (extension) ...@@ -583,7 +586,7 @@ namespace ttl { // (extension)
// findCrossingEdges stops if it finds a node lying on the constraint. // findCrossingEdges stops if it finds a node lying on the constraint.
// A dart with this node as start node is returned // A dart with this node as start node is returned
// We call insertConstraint recursivly until the received dart is dend // We call insertConstraint recursivly until the received dart is dend
if (!ttl::same_0_orbit(next_start, dend)) { if (!same_0_orbit(next_start, dend)) {
#ifdef DEBUG_TTL_CONSTR_PLOT #ifdef DEBUG_TTL_CONSTR_PLOT
cout << "RECURSION due to collinearity along constraint" << endl; cout << "RECURSION due to collinearity along constraint" << endl;
...@@ -594,7 +597,7 @@ namespace ttl { // (extension) ...@@ -594,7 +597,7 @@ namespace ttl { // (extension)
// Swap edges such that the constraint edge is present in the transformed triangulation. // Swap edges such that the constraint edge is present in the transformed triangulation.
if (elist.size() > 0) // by Thomas Sevaldrud if (elist.size() > 0) // by Thomas Sevaldrud
ttl_constr::transformToConstraint<TraitsType>(dstart, next_start, elist); ttl_constr::ConstrainedTriangulation::transformToConstraint<TraitsType>(dstart, next_start, elist);
#ifdef DEBUG_TTL_CONSTR_PLOT #ifdef DEBUG_TTL_CONSTR_PLOT
cout << "size of elist = " << elist.size() << endl; cout << "size of elist = " << elist.size() << endl;
...@@ -607,13 +610,13 @@ namespace ttl { // (extension) ...@@ -607,13 +610,13 @@ namespace ttl { // (extension)
#endif #endif
// Optimize to constrained Delaunay triangulation if required. // Optimize to constrained Delaunay triangulation if required.
typename list<DartType>::iterator end_opt = elist.end(); typename std::list<DartType>::iterator end_opt = elist.end();
if (optimize_delaunay) { if (optimize_delaunay) {
// Indicate that the constrained edge, which is the last element in the list, // Indicate that the constrained edge, which is the last element in the list,
// should not be swapped // should not be swapped
--end_opt; --end_opt;
ttl::optimizeDelaunay<TraitsType, DartType>(elist, end_opt); optimizeDelaunay<TraitsType, DartType>(elist, end_opt);
} }
if(elist.size() == 0) // by Thomas Sevaldrud if(elist.size() == 0) // by Thomas Sevaldrud
......
...@@ -27,6 +27,10 @@ ...@@ -27,6 +27,10 @@
* @brief Class that computes missing connections on a PCB. * @brief Class that computes missing connections on a PCB.
*/ */
#ifdef USE_OPENMP
#include <omp.h>
#endif /* USE_OPENMP */
#include <ratsnest_data.h> #include <ratsnest_data.h>
#include <class_board.h> #include <class_board.h>
...@@ -964,13 +968,25 @@ void RN_DATA::Recalculate( int aNet ) ...@@ -964,13 +968,25 @@ void RN_DATA::Recalculate( int aNet )
{ {
if( aNet < 0 ) // Recompute everything if( aNet < 0 ) // Recompute everything
{ {
// Start with net number 1, as 0 stands for not connected unsigned int tid, i, chunk, netCount;
for( unsigned int i = 1; i < m_nets.size(); ++i ) netCount = m_board->GetNetCount();
chunk = 1;
#ifdef USE_OPENMP
#pragma omp parallel shared(chunk, netCount) private(i, tid)
{ {
// Recompute only nets that require it tid = omp_get_thread_num();
if( m_nets[i].IsDirty() ) #pragma omp for schedule(guided, chunk)
updateNet( i ); #else /* USE_OPENMP */
} {
#endif
// Start with net number 1, as 0 stand for not connected
for( i = 1; i < netCount; ++i )
{
if( m_nets[i].IsDirty() )
updateNet( i );
}
} /* end of parallel section */
} }
else if( aNet > 0 ) // Recompute only specific net else if( aNet > 0 ) // Recompute only specific net
{ {
...@@ -982,6 +998,7 @@ void RN_DATA::Recalculate( int aNet ) ...@@ -982,6 +998,7 @@ void RN_DATA::Recalculate( int aNet )
void RN_DATA::updateNet( int aNetCode ) void RN_DATA::updateNet( int aNetCode )
{ {
assert( aNetCode < (int) m_nets.size() ); assert( aNetCode < (int) m_nets.size() );
if( aNetCode < 1 ) if( aNetCode < 1 )
return; return;
......
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