Merged ratsnest_threadsafe branch.
This commit is contained in:
commit
468e14f003
|
@ -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" )
|
||||
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 )
|
||||
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" )
|
||||
|
||||
|
|
|
@ -51,8 +51,6 @@ using namespace hed;
|
|||
using namespace std;
|
||||
|
||||
|
||||
Triangulation* TTLtraits::triang_ = NULL;
|
||||
|
||||
#ifdef TTL_USE_NODE_ID
|
||||
int Node::id_count = 0;
|
||||
#endif
|
||||
|
@ -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,
|
||||
NodesContainer::iterator last) {
|
||||
|
||||
TTLtraits::triang_ = this;
|
||||
cleanAll();
|
||||
|
||||
EdgePtr bedge = initTwoEnclosingTriangles(first, last);
|
||||
|
@ -178,7 +195,7 @@ void Triangulation::createDelaunay(NodesContainer::iterator first,
|
|||
|
||||
NodesContainer::iterator 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
|
||||
|
@ -189,7 +206,7 @@ void Triangulation::createDelaunay(NodesContainer::iterator first,
|
|||
// triangle "outside" the triangulation.)
|
||||
|
||||
// Assumes rectangular domain
|
||||
ttl::removeRectangularBoundary<TTLtraits>(dc);
|
||||
helper->removeRectangularBoundary<TTLtraits>(dc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -269,7 +286,7 @@ cout << "Iterate boundary 2" << endl;
|
|||
|
||||
Dart dart_iter = dart;
|
||||
do {
|
||||
if (ttl::isBoundaryEdge(dart_iter))
|
||||
if (helper->isBoundaryEdge(dart_iter))
|
||||
dart_iter.alpha0().alpha1();
|
||||
else
|
||||
dart_iter.alpha2().alpha1();
|
||||
|
@ -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
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// This is a "template" for accessing all nodes (but multiple tests)
|
||||
|
@ -486,7 +528,7 @@ void Triangulation::swapEdge(EdgePtr& diagonal) {
|
|||
|
||||
// Note that diagonal is both input and output and it is always
|
||||
// kept in counterclockwise direction (this is not required by all
|
||||
// finctions in ttl:: now)
|
||||
// functions in TriangulationHelper now)
|
||||
|
||||
// Swap by rotating counterclockwise
|
||||
// Use the same objects - no deletion or new objects
|
||||
|
@ -567,7 +609,7 @@ bool Triangulation::checkDelaunay() const {
|
|||
// only one of the half-edges
|
||||
if (!twinedge || (size_t)edge.get() > (size_t)twinedge.get()) {
|
||||
Dart dart(edge);
|
||||
if (ttl::swapTestDelaunay<TTLtraits>(dart)) {
|
||||
if (helper->swapTestDelaunay<TTLtraits>(dart)) {
|
||||
noNotDelaunay++;
|
||||
|
||||
//printEdge(dart,os); os << "\n";
|
||||
|
@ -610,7 +652,7 @@ void Triangulation::optimizeDelaunay() {
|
|||
|
||||
Dart dart(edge);
|
||||
// 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;
|
||||
swapEdge(edge);
|
||||
}
|
||||
|
@ -632,7 +674,7 @@ EdgePtr Triangulation::getInteriorNode() const {
|
|||
for (int i = 0; i < 3; ++i) {
|
||||
if (edge->getTwinEdge()) {
|
||||
|
||||
if (!ttl::isBoundaryNode(Dart(edge)))
|
||||
if (!helper->isBoundaryNode(Dart(edge)))
|
||||
return edge;
|
||||
}
|
||||
edge = edge->getNextEdgeInFace();
|
||||
|
@ -643,18 +685,18 @@ EdgePtr Triangulation::getInteriorNode() const {
|
|||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static EdgePtr getBoundaryEdgeInTriangle(const EdgePtr& e) {
|
||||
EdgePtr Triangulation::getBoundaryEdgeInTriangle(const EdgePtr& e) const {
|
||||
EdgePtr edge = e;
|
||||
|
||||
if (ttl::isBoundaryEdge(Dart(edge)))
|
||||
if (helper->isBoundaryEdge(Dart(edge)))
|
||||
return edge;
|
||||
|
||||
edge = edge->getNextEdgeInFace();
|
||||
if (ttl::isBoundaryEdge(Dart(edge)))
|
||||
if (helper->isBoundaryEdge(Dart(edge)))
|
||||
return edge;
|
||||
|
||||
edge = edge->getNextEdgeInFace();
|
||||
if (ttl::isBoundaryEdge(Dart(edge)))
|
||||
if (helper->isBoundaryEdge(Dart(edge)))
|
||||
return edge;
|
||||
|
||||
return EdgePtr();
|
||||
|
|
|
@ -69,9 +69,6 @@ namespace hed {
|
|||
|
||||
struct TTLtraits {
|
||||
|
||||
// The actual triangulation object
|
||||
static Triangulation* triang_;
|
||||
|
||||
/** The floating point type used in calculations
|
||||
* involving scalar products and cross products.
|
||||
*/
|
||||
|
@ -172,127 +169,6 @@ namespace hed {
|
|||
}
|
||||
|
||||
//@} // 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
|
||||
|
|
|
@ -51,10 +51,13 @@
|
|||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <ttl/ttl.h>
|
||||
#include <ttl/ttl_util.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace ttl {
|
||||
class TriangulationHelper;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// The half-edge data structure
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -242,26 +245,75 @@ public:
|
|||
class Triangulation {
|
||||
|
||||
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) {
|
||||
edge->setAsLeadingEdge();
|
||||
leadingEdges_.push_front( edge );
|
||||
}
|
||||
|
||||
bool removeLeadingEdgeFromList(EdgePtr& leadingEdge);
|
||||
|
||||
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:
|
||||
/// Default constructor
|
||||
Triangulation() {}
|
||||
Triangulation();
|
||||
|
||||
/// Copy constructor
|
||||
Triangulation(const Triangulation& tr) {
|
||||
std::cout << "Triangulation: Copy constructor not present - EXIT.";
|
||||
exit(-1);
|
||||
}
|
||||
Triangulation(const Triangulation& tr);
|
||||
|
||||
/// Destructor
|
||||
~Triangulation() { cleanAll(); }
|
||||
~Triangulation();
|
||||
|
||||
/// Creates a Delaunay triangulation from a set of points
|
||||
void createDelaunay(NodesContainer::iterator first,
|
||||
|
@ -295,20 +347,20 @@ public:
|
|||
Dart createDart();
|
||||
|
||||
/// 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
|
||||
int noTriangles() const { return (int)leadingEdges_.size(); }
|
||||
|
||||
/// 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
|
||||
/// Sets flag in all the nodes
|
||||
void flagNodes(bool flag) const;
|
||||
|
||||
/// 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
|
||||
|
||||
/// Swaps edges until the triangulation is Delaunay (constrained edges are not swapped)
|
||||
|
@ -320,12 +372,16 @@ public:
|
|||
/// Returns an arbitrary interior node (as the source node of the returned edge)
|
||||
EdgePtr getInteriorNode() const;
|
||||
|
||||
EdgePtr getBoundaryEdgeInTriangle(const EdgePtr& e) const;
|
||||
|
||||
/// Returns an arbitrary boundary edge
|
||||
EdgePtr getBoundaryEdge() const;
|
||||
|
||||
/// Print edges for plotting with, e.g., gnuplot
|
||||
void printEdges(std::ofstream& os) const;
|
||||
|
||||
friend class ttl::TriangulationHelper;
|
||||
|
||||
}; // End of class Triangulation
|
||||
|
||||
|
||||
|
|
|
@ -52,8 +52,6 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
using std::list;
|
||||
|
||||
|
||||
// Next on TOPOLOGY:
|
||||
// - get triangle strips
|
||||
|
@ -102,7 +100,7 @@
|
|||
* - \e CW - clockwise
|
||||
* - \e 0_orbit, \e 1_orbit and \e 2_orbit: A sequence of darts around
|
||||
* a node, around an edge and in a triangle respectively;
|
||||
* see ttl::get_0_orbit_interior and ttl::get_0_orbit_boundary
|
||||
* see get_0_orbit_interior and get_0_orbit_boundary
|
||||
* - \e arc - In a triangulation an arc is equivalent with an edge
|
||||
*
|
||||
* \see
|
||||
|
@ -115,14 +113,14 @@
|
|||
|
||||
namespace ttl {
|
||||
|
||||
|
||||
class TriangulationHelper
|
||||
{
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// ----------------------------------- Forward declarations -------------------------------------
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
#if ((_MSC_VER > 0) && (_MSC_VER < 1300))
|
||||
#else
|
||||
public:
|
||||
TriangulationHelper(hed::Triangulation& triang) : triangulation(triang)
|
||||
{
|
||||
}
|
||||
|
||||
// Delaunay Triangulation
|
||||
// ----------------------
|
||||
|
@ -145,55 +143,55 @@ namespace ttl {
|
|||
// Topological and Geometric Queries
|
||||
// ---------------------------------
|
||||
template<class TraitsType, class PointType, class DartType>
|
||||
bool locateFaceSimplest(const PointType& point, DartType& dart);
|
||||
static bool locateFaceSimplest(const PointType& point, DartType& dart);
|
||||
|
||||
template<class TraitsType, class PointType, class DartType>
|
||||
bool locateTriangle(const PointType& point, DartType& dart);
|
||||
static bool locateTriangle(const PointType& point, DartType& dart);
|
||||
|
||||
template<class TraitsType, class PointType, class DartType>
|
||||
bool inTriangleSimplest(const PointType& point, const DartType& dart);
|
||||
static bool inTriangleSimplest(const PointType& point, const DartType& dart);
|
||||
|
||||
template<class TraitsType, class PointType, class DartType>
|
||||
bool inTriangle(const PointType& point, const DartType& dart);
|
||||
static bool inTriangle(const PointType& point, const DartType& dart);
|
||||
|
||||
template<class DartType, class DartListType>
|
||||
void getBoundary(const DartType& dart, DartListType& boundary);
|
||||
static void getBoundary(const DartType& dart, DartListType& boundary);
|
||||
|
||||
template<class DartType>
|
||||
bool isBoundaryEdge(const DartType& dart);
|
||||
static bool isBoundaryEdge(const DartType& dart);
|
||||
|
||||
template<class DartType>
|
||||
bool isBoundaryFace(const DartType& dart);
|
||||
static bool isBoundaryFace(const DartType& dart);
|
||||
|
||||
template<class DartType>
|
||||
bool isBoundaryNode(const DartType& dart);
|
||||
static bool isBoundaryNode(const DartType& dart);
|
||||
|
||||
template<class DartType>
|
||||
int getDegreeOfNode(const DartType& dart);
|
||||
static int getDegreeOfNode(const DartType& dart);
|
||||
|
||||
template<class DartType, class DartListType>
|
||||
void get_0_orbit_interior(const DartType& dart, DartListType& orbit);
|
||||
static void get_0_orbit_interior(const DartType& dart, DartListType& orbit);
|
||||
|
||||
template<class DartType, class DartListType>
|
||||
void get_0_orbit_boundary(const DartType& dart, DartListType& orbit);
|
||||
static void get_0_orbit_boundary(const DartType& dart, DartListType& orbit);
|
||||
|
||||
template<class DartType>
|
||||
bool same_0_orbit(const DartType& d1, const DartType& d2);
|
||||
static bool same_0_orbit(const DartType& d1, const DartType& d2);
|
||||
|
||||
template<class DartType>
|
||||
bool same_1_orbit(const DartType& d1, const DartType& d2);
|
||||
static bool same_1_orbit(const DartType& d1, const DartType& d2);
|
||||
|
||||
template<class DartType>
|
||||
bool same_2_orbit(const DartType& d1, const DartType& d2);
|
||||
static bool same_2_orbit(const DartType& d1, const DartType& d2);
|
||||
|
||||
template <class TraitsType, class DartType>
|
||||
bool swappableEdge(const DartType& dart, bool allowDegeneracy = false);
|
||||
static bool swappableEdge(const DartType& dart, bool allowDegeneracy = false);
|
||||
|
||||
template<class DartType>
|
||||
void positionAtNextBoundaryEdge(DartType& dart);
|
||||
static void positionAtNextBoundaryEdge(DartType& dart);
|
||||
|
||||
template<class TraitsType, class DartType>
|
||||
bool convexBoundary(const DartType& dart);
|
||||
static bool convexBoundary(const DartType& dart);
|
||||
|
||||
|
||||
// Utilities for Delaunay Triangulation
|
||||
|
@ -205,7 +203,7 @@ namespace ttl {
|
|||
void optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end);
|
||||
|
||||
template<class TraitsType, class DartType>
|
||||
bool swapTestDelaunay(const DartType& dart, bool cycling_check = false);
|
||||
bool swapTestDelaunay(const DartType& dart, bool cycling_check = false) const;
|
||||
|
||||
template<class TraitsType, class DartType>
|
||||
void recSwapDelaunay(DartType& diagonal);
|
||||
|
@ -223,9 +221,29 @@ namespace ttl {
|
|||
// Constrained Triangulation
|
||||
// -------------------------
|
||||
template<class TraitsType, class DartType>
|
||||
DartType insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay);
|
||||
static DartType insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay);
|
||||
|
||||
#endif
|
||||
private:
|
||||
hed::Triangulation& triangulation;
|
||||
|
||||
template <class TraitsType, class ForwardIterator, class DartType>
|
||||
void insertNodes(ForwardIterator first, ForwardIterator last, DartType& dart);
|
||||
|
||||
template <class TopologyElementType, class DartType>
|
||||
static bool isMemberOfFace(const TopologyElementType& topologyElement, const DartType& dart);
|
||||
|
||||
template <class TraitsType, class NodeType, class DartType>
|
||||
static bool locateFaceWithNode(const NodeType& node, DartType& dart_iter);
|
||||
|
||||
template <class DartType>
|
||||
static void getAdjacentTriangles(const DartType& dart, DartType& t1, DartType& t2, DartType& t3);
|
||||
|
||||
template <class DartType>
|
||||
static void getNeighborNodes(const DartType& dart, std::list<DartType>& node_list, bool& boundary);
|
||||
|
||||
template <class TraitsType, class DartType>
|
||||
static bool degenerateTriangle(const DartType& dart);
|
||||
};
|
||||
|
||||
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
|
@ -245,7 +263,7 @@ namespace ttl {
|
|||
* can be created as two triangles forming a rectangle that contains
|
||||
* all the points.
|
||||
* After \c insertNode has been called repeatedly with all the points,
|
||||
* ttl::removeRectangularBoundary can be called to remove triangles
|
||||
* removeRectangularBoundary can be called to remove triangles
|
||||
* at the boundary of the triangulation so that the boundary
|
||||
* form the convex hull of the points.
|
||||
*
|
||||
|
@ -268,19 +286,19 @@ namespace ttl {
|
|||
* - \ref hed::TTLtraits::splitTriangle "TraitsType::splitTriangle" (DartType&, const PointType&)
|
||||
*
|
||||
* \using
|
||||
* - ttl::locateTriangle
|
||||
* - ttl::recSwapDelaunay
|
||||
* - locateTriangle
|
||||
* - recSwapDelaunay
|
||||
*
|
||||
* \note
|
||||
* - For efficiency reasons \e dart should be close to the insertion \e point.
|
||||
*
|
||||
* \see
|
||||
* ttl::removeRectangularBoundary
|
||||
* removeRectangularBoundary
|
||||
*/
|
||||
template <class TraitsType, class DartType, class PointType>
|
||||
bool insertNode(DartType& dart, PointType& point) {
|
||||
bool TriangulationHelper::insertNode(DartType& dart, PointType& point) {
|
||||
|
||||
bool found = ttl::locateTriangle<TraitsType>(point, dart);
|
||||
bool found = locateTriangle<TraitsType>(point, dart);
|
||||
if (!found) {
|
||||
#ifdef DEBUG_TTL
|
||||
cout << "ERROR: Triangulation::insertNode: NO triangle found. /n";
|
||||
|
@ -289,7 +307,7 @@ namespace ttl {
|
|||
}
|
||||
|
||||
// ??? can we hide the dart? this is not possible if one triangle only
|
||||
TraitsType::splitTriangle(dart, point);
|
||||
triangulation.splitTriangle(dart, point);
|
||||
|
||||
DartType d1 = dart;
|
||||
d1.alpha2().alpha1().alpha2().alpha0().alpha1();
|
||||
|
@ -304,14 +322,14 @@ namespace ttl {
|
|||
//DartType dsav = d3;
|
||||
d3.alpha0().alpha1();
|
||||
|
||||
//if (!TraitsType::fixedEdge(d1) && !ttl::isBoundaryEdge(d1)) {
|
||||
if (!ttl::isBoundaryEdge(d1)) {
|
||||
//if (!TraitsType::fixedEdge(d1) && !isBoundaryEdge(d1)) {
|
||||
if (!isBoundaryEdge(d1)) {
|
||||
d1.alpha2();
|
||||
recSwapDelaunay<TraitsType>(d1);
|
||||
}
|
||||
|
||||
//if (!TraitsType::fixedEdge(d2) && !ttl::isBoundaryEdge(d2)) {
|
||||
if (!ttl::isBoundaryEdge(d2)) {
|
||||
//if (!TraitsType::fixedEdge(d2) && !isBoundaryEdge(d2)) {
|
||||
if (!isBoundaryEdge(d2)) {
|
||||
d2.alpha2();
|
||||
recSwapDelaunay<TraitsType>(d2);
|
||||
}
|
||||
|
@ -319,8 +337,8 @@ namespace ttl {
|
|||
// Preserve the incoming dart as output incident to the node and CCW
|
||||
//d = dsav.alpha2();
|
||||
dart.alpha2();
|
||||
//if (!TraitsType::fixedEdge(d3) && !ttl::isBoundaryEdge(d3)) {
|
||||
if (!ttl::isBoundaryEdge(d3)) {
|
||||
//if (!TraitsType::fixedEdge(d3) && !isBoundaryEdge(d3)) {
|
||||
if (!isBoundaryEdge(d3)) {
|
||||
d3.alpha2();
|
||||
recSwapDelaunay<TraitsType>(d3);
|
||||
}
|
||||
|
@ -332,7 +350,7 @@ namespace ttl {
|
|||
//------------------------------------------------------------------------------------------------
|
||||
// Private/Hidden function (might change later)
|
||||
template <class TraitsType, class ForwardIterator, class DartType>
|
||||
void insertNodes(ForwardIterator first, ForwardIterator last, DartType& dart) {
|
||||
void TriangulationHelper::insertNodes(ForwardIterator first, ForwardIterator last, DartType& dart) {
|
||||
|
||||
// Assumes that the dereferenced point objects are pointers.
|
||||
// References to the point objects are then passed to TTL.
|
||||
|
@ -355,14 +373,14 @@ namespace ttl {
|
|||
* Output: A CCW dart at the new boundary
|
||||
*
|
||||
* \using
|
||||
* - ttl::removeBoundaryNode
|
||||
* - removeBoundaryNode
|
||||
*
|
||||
* \note
|
||||
* - This function requires that the boundary of the triangulation is
|
||||
* a rectangle with four nodes (one in each corner).
|
||||
*/
|
||||
template <class TraitsType, class DartType>
|
||||
void removeRectangularBoundary(DartType& dart) {
|
||||
void TriangulationHelper::removeRectangularBoundary(DartType& dart) {
|
||||
|
||||
DartType d_next = dart;
|
||||
DartType d_iter;
|
||||
|
@ -370,8 +388,8 @@ namespace ttl {
|
|||
for (int i = 0; i < 4; i++) {
|
||||
d_iter = d_next;
|
||||
d_next.alpha0();
|
||||
ttl::positionAtNextBoundaryEdge(d_next);
|
||||
ttl::removeBoundaryNode<TraitsType>(d_iter);
|
||||
positionAtNextBoundaryEdge(d_next);
|
||||
removeBoundaryNode<TraitsType>(d_iter);
|
||||
}
|
||||
|
||||
dart = d_next; // Return a dart at the new boundary
|
||||
|
@ -383,20 +401,20 @@ namespace ttl {
|
|||
* updates the triangulation to be Delaunay.
|
||||
*
|
||||
* \using
|
||||
* - ttl::removeBoundaryNode if \e dart represents a node at the boundary
|
||||
* - ttl::removeInteriorNode if \e dart represents an interior node
|
||||
* - removeBoundaryNode if \e dart represents a node at the boundary
|
||||
* - removeInteriorNode if \e dart represents an interior node
|
||||
*
|
||||
* \note
|
||||
* - The node cannot belong to a fixed (constrained) edge that is not
|
||||
* swappable. (An endless loop is likely to occur in this case).
|
||||
*/
|
||||
template <class TraitsType, class DartType>
|
||||
void removeNode(DartType& dart) {
|
||||
void TriangulationHelper::removeNode(DartType& dart) {
|
||||
|
||||
if (ttl::isBoundaryNode(dart))
|
||||
ttl::removeBoundaryNode<TraitsType>(dart);
|
||||
if (isBoundaryNode(dart))
|
||||
removeBoundaryNode<TraitsType>(dart);
|
||||
else
|
||||
ttl::removeInteriorNode<TraitsType>(dart);
|
||||
removeInteriorNode<TraitsType>(dart);
|
||||
}
|
||||
|
||||
|
||||
|
@ -405,14 +423,14 @@ namespace ttl {
|
|||
* updates the triangulation to be Delaunay.
|
||||
*
|
||||
* \using
|
||||
* - ttl::swapEdgesAwayFromBoundaryNode
|
||||
* - ttl::optimizeDelaunay
|
||||
* - swapEdgesAwayFromBoundaryNode
|
||||
* - optimizeDelaunay
|
||||
*
|
||||
* \require
|
||||
* - \ref hed::TTLtraits::removeBoundaryTriangle "TraitsType::removeBoundaryTriangle" (Dart&)
|
||||
*/
|
||||
template <class TraitsType, class DartType>
|
||||
void removeBoundaryNode(DartType& dart) {
|
||||
void TriangulationHelper::removeBoundaryNode(DartType& dart) {
|
||||
|
||||
// ... and update Delaunay
|
||||
// - CCW dart must be given (for remove)
|
||||
|
@ -420,13 +438,13 @@ namespace ttl {
|
|||
// we assume that there is not only one triangle left in the triangulation.
|
||||
|
||||
// Position at boundary edge and CCW
|
||||
if (!ttl::isBoundaryEdge(dart)) {
|
||||
if (!isBoundaryEdge(dart)) {
|
||||
dart.alpha1(); // ensures that next function delivers back a CCW dart (if the given dart is CCW)
|
||||
ttl::positionAtNextBoundaryEdge(dart);
|
||||
positionAtNextBoundaryEdge(dart);
|
||||
}
|
||||
|
||||
list<DartType> swapped_edges;
|
||||
ttl::swapEdgesAwayFromBoundaryNode<TraitsType>(dart, swapped_edges);
|
||||
std::list<DartType> swapped_edges;
|
||||
swapEdgesAwayFromBoundaryNode<TraitsType>(dart, swapped_edges);
|
||||
|
||||
// Remove boundary triangles and remove the new boundary from the list
|
||||
// of swapped edges, see below.
|
||||
|
@ -435,7 +453,7 @@ namespace ttl {
|
|||
bool bend = false;
|
||||
while (bend == false) {
|
||||
dnext.alpha1().alpha2();
|
||||
if (ttl::isBoundaryEdge(dnext))
|
||||
if (isBoundaryEdge(dnext))
|
||||
bend = true; // Stop when boundary
|
||||
|
||||
// Generic: Also remove the new boundary from the list of swapped edges
|
||||
|
@ -443,20 +461,20 @@ namespace ttl {
|
|||
n_bedge.alpha1().alpha0().alpha1().alpha2(); // new boundary edge
|
||||
|
||||
// ??? can we avoid find if we do this in swap away?
|
||||
typename list<DartType>::iterator it;
|
||||
typename std::list<DartType>::iterator it;
|
||||
it = find(swapped_edges.begin(), swapped_edges.end(), n_bedge);
|
||||
|
||||
if (it != swapped_edges.end())
|
||||
swapped_edges.erase(it);
|
||||
|
||||
// Remove the boundary triangle
|
||||
TraitsType::removeBoundaryTriangle(d_iter);
|
||||
triangulation.removeBoundaryTriangle(d_iter);
|
||||
d_iter = dnext;
|
||||
}
|
||||
|
||||
// Optimize Delaunay
|
||||
typedef list<DartType> DartListType;
|
||||
ttl::optimizeDelaunay<TraitsType, DartType, DartListType>(swapped_edges);
|
||||
typedef std::list<DartType> DartListType;
|
||||
optimizeDelaunay<TraitsType, DartType, DartListType>(swapped_edges);
|
||||
}
|
||||
|
||||
|
||||
|
@ -465,8 +483,8 @@ namespace ttl {
|
|||
* updates the triangulation to be Delaunay.
|
||||
*
|
||||
* \using
|
||||
* - ttl::swapEdgesAwayFromInteriorNode
|
||||
* - ttl::optimizeDelaunay
|
||||
* - swapEdgesAwayFromInteriorNode
|
||||
* - optimizeDelaunay
|
||||
*
|
||||
* \require
|
||||
* - \ref hed::TTLtraits::reverse_splitTriangle "TraitsType::reverse_splitTriangle" (Dart&)
|
||||
|
@ -476,7 +494,7 @@ namespace ttl {
|
|||
* swappable. (An endless loop is likely to occur in this case).
|
||||
*/
|
||||
template <class TraitsType, class DartType>
|
||||
void removeInteriorNode(DartType& dart) {
|
||||
void TriangulationHelper::removeInteriorNode(DartType& dart) {
|
||||
|
||||
// ... and update to Delaunay.
|
||||
// Must allow degeneracy temporarily, see comments in swap edges away
|
||||
|
@ -492,13 +510,13 @@ namespace ttl {
|
|||
|
||||
// Assumes dart is counterclockwise
|
||||
|
||||
list<DartType> swapped_edges;
|
||||
ttl::swapEdgesAwayFromInteriorNode<TraitsType>(dart, swapped_edges);
|
||||
std::list<DartType> swapped_edges;
|
||||
swapEdgesAwayFromInteriorNode<TraitsType>(dart, swapped_edges);
|
||||
|
||||
// The reverse operation of split triangle:
|
||||
// Make one triangle of the three triangles at the node associated with dart
|
||||
// TraitsType::
|
||||
TraitsType::reverse_splitTriangle(dart);
|
||||
triangulation.reverse_splitTriangle(dart);
|
||||
|
||||
// ???? Not generic yet if we are very strict:
|
||||
// When calling unsplit triangle, darts at the three opposite sides may
|
||||
|
@ -511,7 +529,7 @@ namespace ttl {
|
|||
// Note the theoretical result: if there are no edges in the list,
|
||||
// the triangulation is Delaunay already
|
||||
|
||||
ttl::optimizeDelaunay<TraitsType, DartType>(swapped_edges);
|
||||
optimizeDelaunay<TraitsType, DartType>(swapped_edges);
|
||||
}
|
||||
|
||||
//@} // End of Delaunay Triangulation Group
|
||||
|
@ -527,7 +545,7 @@ namespace ttl {
|
|||
//------------------------------------------------------------------------------------------------
|
||||
// Private/Hidden function (might change later)
|
||||
template <class TopologyElementType, class DartType>
|
||||
bool isMemberOfFace(const TopologyElementType& topologyElement, const DartType& dart) {
|
||||
bool TriangulationHelper::isMemberOfFace(const TopologyElementType& topologyElement, const DartType& dart) {
|
||||
|
||||
// Check if the given topology element (node, edge or face) is a member of the face
|
||||
// Assumes:
|
||||
|
@ -547,7 +565,7 @@ namespace ttl {
|
|||
//------------------------------------------------------------------------------------------------
|
||||
// Private/Hidden function (might change later)
|
||||
template <class TraitsType, class NodeType, class DartType>
|
||||
bool locateFaceWithNode(const NodeType& node, DartType& dart_iter) {
|
||||
bool TriangulationHelper::locateFaceWithNode(const NodeType& node, DartType& dart_iter) {
|
||||
// Locate a face in the topology structure with the given node as a member
|
||||
// Assumes:
|
||||
// - TraitsType::orient2d(DartType, DartType, NodeType)
|
||||
|
@ -594,10 +612,10 @@ namespace ttl {
|
|||
* \e regular as explained above.
|
||||
*
|
||||
* \see
|
||||
* ttl::locateTriangle
|
||||
* locateTriangle
|
||||
*/
|
||||
template <class TraitsType, class PointType, class DartType>
|
||||
bool locateFaceSimplest(const PointType& point, DartType& dart) {
|
||||
bool TriangulationHelper::locateFaceSimplest(const PointType& point, DartType& dart) {
|
||||
// Not degenerate triangles if point is on the extension of the edges
|
||||
// But inTriangle may be called in case of true (may update to inFace2)
|
||||
// Convex boundary
|
||||
|
@ -660,11 +678,11 @@ namespace ttl {
|
|||
* then the edge associated with \e dart will be at the boundary of the triangulation.
|
||||
*
|
||||
* \using
|
||||
* - ttl::locateFaceSimplest
|
||||
* - ttl::inTriangle
|
||||
* - locateFaceSimplest
|
||||
* - inTriangle
|
||||
*/
|
||||
template <class TraitsType, class PointType, class DartType>
|
||||
bool locateTriangle(const PointType& point, DartType& dart) {
|
||||
bool TriangulationHelper::locateTriangle(const PointType& point, DartType& dart) {
|
||||
// The purpose is to have a fast and stable procedure that
|
||||
// i) avoids concluding that a point is inside a triangle if it is not inside
|
||||
// ii) avoids infinite loops
|
||||
|
@ -713,10 +731,10 @@ namespace ttl {
|
|||
* - \ref hed::TTLtraits::orient2d "TraitsType::orient2d" (DartType&, DartType&, PointType&)
|
||||
*
|
||||
* \see
|
||||
* ttl::inTriangle for a more robust function
|
||||
* inTriangle for a more robust function
|
||||
*/
|
||||
template <class TraitsType, class PointType, class DartType>
|
||||
bool inTriangleSimplest(const PointType& point, const DartType& dart) {
|
||||
bool TriangulationHelper::inTriangleSimplest(const PointType& point, const DartType& dart) {
|
||||
|
||||
// Fast and simple: Do not deal with degenerate faces, i.e., if there is
|
||||
// degeneracy, true will be returned if the point is on the extension of the
|
||||
|
@ -757,10 +775,10 @@ namespace ttl {
|
|||
* - \ref hed::TTLtraits::scalarProduct2d "TraitsType::scalarProduct2d" (DartType&, PointType&)
|
||||
*
|
||||
* \see
|
||||
* ttl::inTriangleSimplest
|
||||
* inTriangleSimplest
|
||||
*/
|
||||
template <class TraitsType, class PointType, class DartType>
|
||||
bool inTriangle(const PointType& point, const DartType& dart) {
|
||||
bool TriangulationHelper::inTriangle(const PointType& point, const DartType& dart) {
|
||||
|
||||
// SHOULD WE INCLUDE A STRATEGY WITH EDGE X e_1 ETC? TO GUARANTEE THAT
|
||||
// ONLY ON ONE EDGE? BUT THIS DOES NOT SOLVE PROBLEMS WITH
|
||||
|
@ -841,7 +859,7 @@ namespace ttl {
|
|||
//------------------------------------------------------------------------------------------------
|
||||
// Private/Hidden function (might change later)
|
||||
template <class DartType>
|
||||
void getAdjacentTriangles(const DartType& dart, DartType& t1, DartType& t2, DartType& t3) {
|
||||
void TriangulationHelper::getAdjacentTriangles(const DartType& dart, DartType& t1, DartType& t2, DartType& t3) {
|
||||
|
||||
DartType dart_iter = dart;
|
||||
|
||||
|
@ -886,7 +904,7 @@ namespace ttl {
|
|||
* - DartListType::push_back (DartType&)
|
||||
*/
|
||||
template <class DartType, class DartListType>
|
||||
void getBoundary(const DartType& dart, DartListType& boundary) {
|
||||
void TriangulationHelper::getBoundary(const DartType& dart, DartListType& boundary) {
|
||||
// assumes the given dart is at the boundary (by edge)
|
||||
|
||||
DartType dart_iter(dart);
|
||||
|
@ -932,7 +950,7 @@ namespace ttl {
|
|||
* \endcode
|
||||
*/
|
||||
template <class DartType>
|
||||
bool isBoundaryEdge(const DartType& dart) {
|
||||
bool TriangulationHelper::isBoundaryEdge(const DartType& dart) {
|
||||
|
||||
DartType dart_iter = dart;
|
||||
if (dart_iter.alpha2() == dart)
|
||||
|
@ -947,7 +965,7 @@ namespace ttl {
|
|||
* the boundary of the triangulation.
|
||||
*/
|
||||
template <class DartType>
|
||||
bool isBoundaryFace(const DartType& dart) {
|
||||
bool TriangulationHelper::isBoundaryFace(const DartType& dart) {
|
||||
|
||||
// Strategy: boundary if alpha2(d)=d
|
||||
|
||||
|
@ -976,7 +994,7 @@ namespace ttl {
|
|||
* the boundary of the triangulation.
|
||||
*/
|
||||
template <class DartType>
|
||||
bool isBoundaryNode(const DartType& dart) {
|
||||
bool TriangulationHelper::isBoundaryNode(const DartType& dart) {
|
||||
|
||||
// Strategy: boundary if alpha2(d)=d
|
||||
|
||||
|
@ -1009,7 +1027,7 @@ namespace ttl {
|
|||
* the number of edges joining \e V with another node in the triangulation.
|
||||
*/
|
||||
template <class DartType>
|
||||
int getDegreeOfNode(const DartType& dart) {
|
||||
int TriangulationHelper::getDegreeOfNode(const DartType& dart) {
|
||||
|
||||
DartType dart_iter(dart);
|
||||
DartType dart_prev;
|
||||
|
@ -1069,7 +1087,8 @@ namespace ttl {
|
|||
|
||||
// Private/Hidden function
|
||||
template <class DartType>
|
||||
void getNeighborNodes(const DartType& dart, std::list<DartType>& node_list, bool& boundary) {
|
||||
void TriangulationHelper::getNeighborNodes(const DartType& dart,
|
||||
std::list<DartType>& node_list, bool& boundary) {
|
||||
|
||||
DartType dart_iter(dart);
|
||||
|
||||
|
@ -1131,10 +1150,10 @@ namespace ttl {
|
|||
* - DartListType::push_back (DartType&)
|
||||
*
|
||||
* \see
|
||||
* ttl::get_0_orbit_boundary
|
||||
* get_0_orbit_boundary
|
||||
*/
|
||||
template <class DartType, class DartListType>
|
||||
void get_0_orbit_interior(const DartType& dart, DartListType& orbit) {
|
||||
void TriangulationHelper::get_0_orbit_interior(const DartType& dart, DartListType& orbit) {
|
||||
|
||||
DartType d_iter = dart;
|
||||
orbit.push_back(d_iter);
|
||||
|
@ -1165,10 +1184,10 @@ namespace ttl {
|
|||
* - The last dart in the sequence have opposite orientation compared to the others!
|
||||
*
|
||||
* \see
|
||||
* ttl::get_0_orbit_interior
|
||||
* get_0_orbit_interior
|
||||
*/
|
||||
template <class DartType, class DartListType>
|
||||
void get_0_orbit_boundary(const DartType& dart, DartListType& orbit) {
|
||||
void TriangulationHelper::get_0_orbit_boundary(const DartType& dart, DartListType& orbit) {
|
||||
|
||||
DartType dart_prev;
|
||||
DartType d_iter = dart;
|
||||
|
@ -1195,17 +1214,17 @@ namespace ttl {
|
|||
* own version.)
|
||||
*/
|
||||
template <class DartType>
|
||||
bool same_0_orbit(const DartType& d1, const DartType& d2) {
|
||||
bool TriangulationHelper::same_0_orbit(const DartType& d1, const DartType& d2) {
|
||||
|
||||
// Two copies of the same dart
|
||||
DartType d_iter = d2;
|
||||
DartType d_end = d2;
|
||||
|
||||
if (ttl::isBoundaryNode(d_iter)) {
|
||||
if (isBoundaryNode(d_iter)) {
|
||||
// position at both boundary edges
|
||||
ttl::positionAtNextBoundaryEdge(d_iter);
|
||||
positionAtNextBoundaryEdge(d_iter);
|
||||
d_end.alpha1();
|
||||
ttl::positionAtNextBoundaryEdge(d_end);
|
||||
positionAtNextBoundaryEdge(d_end);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
|
@ -1229,7 +1248,7 @@ namespace ttl {
|
|||
* \e d1 and/or \e d2 can be CCW or CW.
|
||||
*/
|
||||
template <class DartType>
|
||||
bool same_1_orbit(const DartType& d1, const DartType& d2) {
|
||||
bool TriangulationHelper::same_1_orbit(const DartType& d1, const DartType& d2) {
|
||||
|
||||
DartType d_iter = d2;
|
||||
// (Also works at the boundary)
|
||||
|
@ -1245,7 +1264,7 @@ namespace ttl {
|
|||
* \e d1 and/or \e d2 can be CCW or CW
|
||||
*/
|
||||
template <class DartType>
|
||||
bool same_2_orbit(const DartType& d1, const DartType& d2) {
|
||||
bool TriangulationHelper::same_2_orbit(const DartType& d1, const DartType& d2) {
|
||||
|
||||
DartType d_iter = d2;
|
||||
if (d_iter == d1 || d_iter.alpha0() == d1 ||
|
||||
|
@ -1259,7 +1278,7 @@ namespace ttl {
|
|||
//------------------------------------------------------------------------------------------------
|
||||
// Private/Hidden function
|
||||
template <class TraitsType, class DartType>
|
||||
bool degenerateTriangle(const DartType& dart) {
|
||||
bool TriangulationHelper::degenerateTriangle(const DartType& dart) {
|
||||
|
||||
// Check if triangle is degenerate
|
||||
// Assumes CCW dart
|
||||
|
@ -1287,7 +1306,7 @@ namespace ttl {
|
|||
* - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (Dart&, Dart&)
|
||||
*/
|
||||
template <class TraitsType, class DartType>
|
||||
bool swappableEdge(const DartType& dart, bool allowDegeneracy) {
|
||||
bool TriangulationHelper::swappableEdge(const DartType& dart, bool allowDegeneracy) {
|
||||
|
||||
// How "safe" is it?
|
||||
|
||||
|
@ -1340,7 +1359,7 @@ namespace ttl {
|
|||
* infinit loop occurs.
|
||||
*/
|
||||
template <class DartType>
|
||||
void positionAtNextBoundaryEdge(DartType& dart) {
|
||||
void TriangulationHelper::positionAtNextBoundaryEdge(DartType& dart) {
|
||||
|
||||
DartType dart_prev;
|
||||
|
||||
|
@ -1365,14 +1384,14 @@ namespace ttl {
|
|||
* - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (const Dart&, const Dart&)
|
||||
*/
|
||||
template <class TraitsType, class DartType>
|
||||
bool convexBoundary(const DartType& dart) {
|
||||
bool TriangulationHelper::convexBoundary(const DartType& dart) {
|
||||
|
||||
list<DartType> blist;
|
||||
ttl::getBoundary(dart, blist);
|
||||
std::list<DartType> blist;
|
||||
getBoundary(dart, blist);
|
||||
|
||||
int no;
|
||||
no = (int)blist.size();
|
||||
typename list<DartType>::const_iterator bit = blist.begin();
|
||||
typename std::list<DartType>::const_iterator bit = blist.begin();
|
||||
DartType d1 = *bit;
|
||||
++bit;
|
||||
DartType d2;
|
||||
|
@ -1428,17 +1447,17 @@ namespace ttl {
|
|||
* seen if it was glued to the edge when swapping (rotating) the edge CCW
|
||||
*
|
||||
* \using
|
||||
* - ttl::swapTestDelaunay
|
||||
* - swapTestDelaunay
|
||||
*/
|
||||
template <class TraitsType, class DartType, class DartListType>
|
||||
void optimizeDelaunay(DartListType& elist) {
|
||||
void TriangulationHelper::optimizeDelaunay(DartListType& elist) {
|
||||
optimizeDelaunay<TraitsType, DartType, DartListType>(elist, elist.end());
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
template <class TraitsType, class DartType, class DartListType>
|
||||
void optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end) {
|
||||
void TriangulationHelper::optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end) {
|
||||
|
||||
// CCW darts
|
||||
// Optimize here means Delaunay, but could be any criterion by
|
||||
|
@ -1481,14 +1500,14 @@ namespace ttl {
|
|||
while(!optimal) {
|
||||
optimal = true;
|
||||
for (it = elist.begin(); it != end_opt; ++it) {
|
||||
if (ttl::swapTestDelaunay<TraitsType>(*it, cycling_check)) {
|
||||
if (swapTestDelaunay<TraitsType>(*it, cycling_check)) {
|
||||
|
||||
// Preserve darts. Potential darts in the list are:
|
||||
// - The current dart
|
||||
// - the four CCW darts on the boundary of the quadrilateral
|
||||
// (the current arc has only one dart)
|
||||
|
||||
ttl::swapEdgeInList<TraitsType, DartType>(it, elist);
|
||||
swapEdgeInList<TraitsType, DartType>(it, elist);
|
||||
|
||||
optimal = false;
|
||||
} // end if should swap
|
||||
|
@ -1513,9 +1532,9 @@ namespace ttl {
|
|||
*/
|
||||
template <class TraitsType, class DartType>
|
||||
#if ((_MSC_VER > 0) && (_MSC_VER < 1300))//#ifdef _MSC_VER
|
||||
bool swapTestDelaunay(const DartType& dart, bool cycling_check = false) {
|
||||
bool TriangulationHelper::swapTestDelaunay(const DartType& dart, bool cycling_check = false) const {
|
||||
#else
|
||||
bool swapTestDelaunay(const DartType& dart, bool cycling_check) {
|
||||
bool TriangulationHelper::swapTestDelaunay(const DartType& dart, bool cycling_check) const {
|
||||
#endif
|
||||
|
||||
// The general strategy is taken from Cline & Renka. They claim that
|
||||
|
@ -1627,17 +1646,17 @@ namespace ttl {
|
|||
* - Calls itself recursively
|
||||
*/
|
||||
template <class TraitsType, class DartType>
|
||||
void recSwapDelaunay(DartType& diagonal) {
|
||||
void TriangulationHelper::recSwapDelaunay(DartType& diagonal) {
|
||||
|
||||
if (!ttl::swapTestDelaunay<TraitsType>(diagonal))
|
||||
// ??? ttl::swapTestDelaunay also checks if boundary, so this can be optimized
|
||||
if (!swapTestDelaunay<TraitsType>(diagonal))
|
||||
// ??? swapTestDelaunay also checks if boundary, so this can be optimized
|
||||
return;
|
||||
|
||||
// Get the other "edges" of the current triangle; see illustration above.
|
||||
DartType oppEdge1 = diagonal;
|
||||
oppEdge1.alpha1();
|
||||
bool b1;
|
||||
if (ttl::isBoundaryEdge(oppEdge1))
|
||||
if (isBoundaryEdge(oppEdge1))
|
||||
b1 = true;
|
||||
else {
|
||||
b1 = false;
|
||||
|
@ -1648,7 +1667,7 @@ namespace ttl {
|
|||
DartType oppEdge2 = diagonal;
|
||||
oppEdge2.alpha0().alpha1().alpha0();
|
||||
bool b2;
|
||||
if (ttl::isBoundaryEdge(oppEdge2))
|
||||
if (isBoundaryEdge(oppEdge2))
|
||||
b2 = true;
|
||||
else {
|
||||
b2 = false;
|
||||
|
@ -1656,7 +1675,7 @@ namespace ttl {
|
|||
}
|
||||
|
||||
// Swap the given diagonal
|
||||
TraitsType::swapEdge(diagonal);
|
||||
triangulation.swapEdge(diagonal);
|
||||
|
||||
if (!b1)
|
||||
recSwapDelaunay<TraitsType>(oppEdge1);
|
||||
|
@ -1669,7 +1688,7 @@ namespace ttl {
|
|||
/** Swaps edges away from the (interior) node associated with
|
||||
* \e dart such that that exactly three edges remain incident
|
||||
* with the node.
|
||||
* This function is used as a first step in ttl::removeInteriorNode
|
||||
* This function is used as a first step in removeInteriorNode
|
||||
*
|
||||
* \retval dart
|
||||
* A CCW dart incident with the node
|
||||
|
@ -1689,10 +1708,10 @@ namespace ttl {
|
|||
* at the node that is given as input.
|
||||
*
|
||||
* \see
|
||||
* ttl::swapEdgesAwayFromBoundaryNode
|
||||
* swapEdgesAwayFromBoundaryNode
|
||||
*/
|
||||
template <class TraitsType, class DartType, class ListType>
|
||||
void swapEdgesAwayFromInteriorNode(DartType& dart, ListType& swapped_edges) {
|
||||
void TriangulationHelper::swapEdgesAwayFromInteriorNode(DartType& dart, ListType& swapped_edges) {
|
||||
|
||||
// Same iteration as in fixEdgesAtCorner, but not boundary
|
||||
DartType dnext = dart;
|
||||
|
@ -1706,14 +1725,14 @@ namespace ttl {
|
|||
// infinite loop with degree > 3.
|
||||
bool allowDegeneracy = true;
|
||||
|
||||
int degree = ttl::getDegreeOfNode(dart);
|
||||
int degree = getDegreeOfNode(dart);
|
||||
DartType d_iter;
|
||||
while (degree > 3) {
|
||||
d_iter = dnext;
|
||||
dnext.alpha1().alpha2();
|
||||
|
||||
if (ttl::swappableEdge<TraitsType>(d_iter, allowDegeneracy)) {
|
||||
TraitsType::swapEdge(d_iter); // swap the edge away
|
||||
if (swappableEdge<TraitsType>(d_iter, allowDegeneracy)) {
|
||||
triangulation.swapEdge(d_iter); // swap the edge away
|
||||
// Collect swapped edges in the list
|
||||
// "Hide" the dart on the other side of the edge to avoid it being changed for
|
||||
// other swaps
|
||||
|
@ -1733,7 +1752,7 @@ namespace ttl {
|
|||
/** Swaps edges away from the (boundary) node associated with
|
||||
* \e dart in such a way that when removing the edges that remain incident
|
||||
* with the node, the boundary of the triangulation will be convex.
|
||||
* This function is used as a first step in ttl::removeBoundaryNode
|
||||
* This function is used as a first step in removeBoundaryNode
|
||||
*
|
||||
* \retval dart
|
||||
* A CCW dart incident with the node
|
||||
|
@ -1747,10 +1766,10 @@ namespace ttl {
|
|||
* - The node associated with \e dart is at the boundary of the triangulation.
|
||||
*
|
||||
* \see
|
||||
* ttl::swapEdgesAwayFromInteriorNode
|
||||
* swapEdgesAwayFromInteriorNode
|
||||
*/
|
||||
template <class TraitsType, class DartType, class ListType>
|
||||
void swapEdgesAwayFromBoundaryNode(DartType& dart, ListType& swapped_edges) {
|
||||
void TriangulationHelper::swapEdgesAwayFromBoundaryNode(DartType& dart, ListType& swapped_edges) {
|
||||
|
||||
// All darts that are swappable.
|
||||
// To treat collinear nodes at an existing boundary, we must allow degeneracy
|
||||
|
@ -1762,7 +1781,7 @@ namespace ttl {
|
|||
// - A dart on the swapped edge is delivered back in a position as
|
||||
// seen if it was glued to the edge when swapping (rotating) the edge CCW
|
||||
|
||||
//int degree = ttl::getDegreeOfNode(dart);
|
||||
//int degree = getDegreeOfNode(dart);
|
||||
|
||||
passes:
|
||||
|
||||
|
@ -1780,7 +1799,7 @@ passes:
|
|||
while (!bend) {
|
||||
|
||||
d_next.alpha1().alpha2();
|
||||
if (ttl::isBoundaryEdge(d_next))
|
||||
if (isBoundaryEdge(d_next))
|
||||
bend = true; // then it is CW since alpha2
|
||||
|
||||
// To allow removing among collinear nodes at the boundary,
|
||||
|
@ -1789,13 +1808,13 @@ passes:
|
|||
tmp1 = d_iter; tmp1.alpha1();
|
||||
tmp2 = d_iter; tmp2.alpha2().alpha1(); // don't bother with boundary (checked later)
|
||||
|
||||
if (ttl::isBoundaryEdge(tmp1) && ttl::isBoundaryEdge(tmp2))
|
||||
if (isBoundaryEdge(tmp1) && isBoundaryEdge(tmp2))
|
||||
allowDegeneracy = true;
|
||||
else
|
||||
allowDegeneracy = false;
|
||||
|
||||
if (ttl::swappableEdge<TraitsType>(d_iter, allowDegeneracy)) {
|
||||
TraitsType::swapEdge(d_iter);
|
||||
if (swappableEdge<TraitsType>(d_iter, allowDegeneracy)) {
|
||||
triangulation.swapEdge(d_iter);
|
||||
|
||||
// Collect swapped edges in the list
|
||||
// "Hide" the dart on the other side of the edge to avoid it being changed for
|
||||
|
@ -1821,7 +1840,7 @@ passes:
|
|||
else {
|
||||
d_iter.alpha1(); // CW and see below
|
||||
}
|
||||
ttl::positionAtNextBoundaryEdge(d_iter); // CCW
|
||||
positionAtNextBoundaryEdge(d_iter); // CCW
|
||||
|
||||
dart = d_iter; // for next pass or output
|
||||
|
||||
|
@ -1839,7 +1858,7 @@ passes:
|
|||
* keep them in \e elist.
|
||||
*/
|
||||
template <class TraitsType, class DartType, class DartListType>
|
||||
void swapEdgeInList(const typename DartListType::iterator& it, DartListType& elist) {
|
||||
void TriangulationHelper::swapEdgeInList(const typename DartListType::iterator& it, DartListType& elist) {
|
||||
|
||||
typename DartListType::iterator it1, it2, it3, it4;
|
||||
DartType dart(*it);
|
||||
|
@ -1867,7 +1886,7 @@ passes:
|
|||
it3 = find(elist.begin(), elist.end(), d3);
|
||||
it4 = find(elist.begin(), elist.end(), d4);
|
||||
|
||||
TraitsType::swapEdge(dart);
|
||||
triangulation.swapEdge(dart);
|
||||
// Update the current dart which may have changed
|
||||
*it = dart;
|
||||
|
||||
|
|
|
@ -51,9 +51,6 @@
|
|||
static ofstream ofile_constr("qweCons.dat");
|
||||
#endif
|
||||
|
||||
|
||||
//using namespace std;
|
||||
|
||||
/** \brief Constrained Delaunay triangulation
|
||||
*
|
||||
* Basic generic algorithms in TTL for inserting a constrained edge between two existing nodes.\n
|
||||
|
@ -61,7 +58,7 @@
|
|||
* See documentation for the namespace ttl for general requirements and assumptions.
|
||||
*
|
||||
* \author
|
||||
* Øyvind Hjelle, oyvindhj@ifi.uio.no
|
||||
* <EFBFBD>yvind Hjelle, oyvindhj@ifi.uio.no
|
||||
*/
|
||||
|
||||
namespace ttl_constr {
|
||||
|
@ -73,6 +70,9 @@ namespace ttl_constr {
|
|||
#endif
|
||||
|
||||
|
||||
class ConstrainedTriangulation
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------------------------
|
||||
/* Checks if \e dart has start and end points in \e dstart and \e dend.
|
||||
*
|
||||
|
@ -89,14 +89,14 @@ namespace ttl_constr {
|
|||
* A bool confirming that it's the constraint or not
|
||||
*
|
||||
* \using
|
||||
* ttl::same_0_orbit
|
||||
* same_0_orbit
|
||||
*/
|
||||
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;
|
||||
d0.alpha0(); // CW
|
||||
if ((ttl::same_0_orbit(dstart, dart) && ttl::same_0_orbit(dend, d0)) ||
|
||||
(ttl::same_0_orbit(dstart, d0) && ttl::same_0_orbit(dend, dart))) {
|
||||
if ((ttl::TriangulationHelper::same_0_orbit(dstart, dart) && ttl::TriangulationHelper::same_0_orbit(dend, d0)) ||
|
||||
(ttl::TriangulationHelper::same_0_orbit(dstart, d0) && ttl::TriangulationHelper::same_0_orbit(dend, dart))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -123,7 +123,7 @@ namespace ttl_constr {
|
|||
* TraitsType::orient2d
|
||||
*/
|
||||
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_2 = TraitsType::orient2d(dstart,d2,dend);
|
||||
|
@ -156,12 +156,12 @@ namespace ttl_constr {
|
|||
* The dart \e d making the smallest positive (or == 0) angle
|
||||
*
|
||||
* \using
|
||||
* ttl::isBoundaryNode
|
||||
* ttl::positionAtNextBoundaryEdge
|
||||
* isBoundaryNode
|
||||
* positionAtNextBoundaryEdge
|
||||
* TraitsType::orient2d
|
||||
*/
|
||||
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???
|
||||
// - Handle the case where the constraint is already present???
|
||||
|
@ -169,9 +169,9 @@ namespace ttl_constr {
|
|||
// (dstart and dend may define a boundary edge)
|
||||
|
||||
DartType d_iter = dstart;
|
||||
if (ttl::isBoundaryNode(d_iter)) {
|
||||
if (ttl::TriangulationHelper::isBoundaryNode(d_iter)) {
|
||||
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
|
||||
|
@ -273,7 +273,7 @@ namespace ttl_constr {
|
|||
* Returns the next "collinear" starting node such that dend is returned when done.
|
||||
*/
|
||||
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);
|
||||
DartType my_end = getAtSmallestAngle<TraitsType>(dend, dstart);
|
||||
|
@ -387,15 +387,16 @@ namespace ttl_constr {
|
|||
* A list containing all the edges crossing the spesified constraint
|
||||
*
|
||||
* \using
|
||||
* ttl::swappableEdge
|
||||
* ttl::swapEdgeInList
|
||||
* ttl::crossesConstraint
|
||||
* ttl::isTheConstraint
|
||||
* swappableEdge
|
||||
* swapEdgeInList
|
||||
* crossesConstraint
|
||||
* isTheConstraint
|
||||
*/
|
||||
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.
|
||||
// (The general rule is that darts inside the actual quadrilateral can be changed,
|
||||
|
@ -423,7 +424,7 @@ namespace ttl_constr {
|
|||
if (counter > dartsInList)
|
||||
break;
|
||||
|
||||
if (ttl::swappableEdge<TraitsType, DartType>(*it, true)) {
|
||||
if (ttl::TriangulationHelper::swappableEdge<TraitsType, DartType>(*it, true)) {
|
||||
// Dyn & Goren & Rippa 's notation:
|
||||
// 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.
|
||||
|
@ -456,7 +457,7 @@ namespace ttl_constr {
|
|||
end = true;
|
||||
|
||||
// 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,
|
||||
// we update them.
|
||||
|
@ -512,6 +513,8 @@ namespace ttl_constr {
|
|||
|
||||
}
|
||||
|
||||
}; // End of ConstrainedTriangulation class
|
||||
|
||||
}; // End of ttl_constr namespace scope
|
||||
|
||||
|
||||
|
@ -546,14 +549,14 @@ namespace ttl { // (extension)
|
|||
* - \ref hed::TTLtraits::swapEdge "TraitsType::swapEdge" (DartType&)
|
||||
*
|
||||
* \using
|
||||
* - ttl::optimizeDelaunay if \e optimize_delaunay is set to \c true
|
||||
* - optimizeDelaunay if \e optimize_delaunay is set to \c true
|
||||
*
|
||||
* \par Assumes:
|
||||
* - The constrained edge must be inside the existing triangulation (and it cannot
|
||||
* cross the boundary of the triangulation).
|
||||
*/
|
||||
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:
|
||||
// - It is the users responsibility to avoid crossing constraints
|
||||
|
@ -567,8 +570,8 @@ namespace ttl { // (extension)
|
|||
// calls itself recursively.
|
||||
|
||||
// RECURSION
|
||||
list<DartType> elist;
|
||||
DartType next_start = ttl_constr::findCrossingEdges<TraitsType>(dstart, dend, elist);
|
||||
std::list<DartType> 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
|
||||
// is an existing edge.
|
||||
|
@ -583,7 +586,7 @@ namespace ttl { // (extension)
|
|||
// findCrossingEdges stops if it finds a node lying on the constraint.
|
||||
// A dart with this node as start node is returned
|
||||
// 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
|
||||
cout << "RECURSION due to collinearity along constraint" << endl;
|
||||
|
@ -594,7 +597,7 @@ namespace ttl { // (extension)
|
|||
|
||||
// Swap edges such that the constraint edge is present in the transformed triangulation.
|
||||
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
|
||||
cout << "size of elist = " << elist.size() << endl;
|
||||
|
@ -607,13 +610,13 @@ namespace ttl { // (extension)
|
|||
#endif
|
||||
|
||||
// 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) {
|
||||
|
||||
// Indicate that the constrained edge, which is the last element in the list,
|
||||
// should not be swapped
|
||||
--end_opt;
|
||||
ttl::optimizeDelaunay<TraitsType, DartType>(elist, end_opt);
|
||||
optimizeDelaunay<TraitsType, DartType>(elist, end_opt);
|
||||
}
|
||||
|
||||
if(elist.size() == 0) // by Thomas Sevaldrud
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
* @brief Class that computes missing connections on a PCB.
|
||||
*/
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#include <omp.h>
|
||||
#endif /* USE_OPENMP */
|
||||
|
||||
#include <ratsnest_data.h>
|
||||
|
||||
#include <class_board.h>
|
||||
|
@ -964,13 +968,25 @@ void RN_DATA::Recalculate( int aNet )
|
|||
{
|
||||
if( aNet < 0 ) // Recompute everything
|
||||
{
|
||||
// Start with net number 1, as 0 stands for not connected
|
||||
for( unsigned int i = 1; i < m_nets.size(); ++i )
|
||||
unsigned int tid, i, chunk, netCount;
|
||||
netCount = m_board->GetNetCount();
|
||||
chunk = 1;
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#pragma omp parallel shared(chunk, netCount) private(i, tid)
|
||||
{
|
||||
tid = omp_get_thread_num();
|
||||
#pragma omp for schedule(guided, chunk)
|
||||
#else /* USE_OPENMP */
|
||||
{
|
||||
#endif
|
||||
// Start with net number 1, as 0 stand for not connected
|
||||
for( i = 1; i < netCount; ++i )
|
||||
{
|
||||
// Recompute only nets that require it
|
||||
if( m_nets[i].IsDirty() )
|
||||
updateNet( i );
|
||||
}
|
||||
} /* end of parallel section */
|
||||
}
|
||||
else if( aNet > 0 ) // Recompute only specific net
|
||||
{
|
||||
|
@ -982,6 +998,7 @@ void RN_DATA::Recalculate( int aNet )
|
|||
void RN_DATA::updateNet( int aNetCode )
|
||||
{
|
||||
assert( aNetCode < (int) m_nets.size() );
|
||||
|
||||
if( aNetCode < 1 )
|
||||
return;
|
||||
|
||||
|
|
Loading…
Reference in New Issue