Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
a10d918c
Commit
a10d918c
authored
Jan 27, 2014
by
Maciej Suminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Thread-safe version of Delaunay triangulation.
parent
fe97521b
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
317 additions
and
321 deletions
+317
-321
hetriang.cpp
common/geometry/hetriang.cpp
+57
-15
hetraits.h
include/ttl/halfedge/hetraits.h
+0
-124
hetriang.h
include/ttl/halfedge/hetriang.h
+67
-11
ttl.h
include/ttl/ttl.h
+158
-139
ttl_constr.h
include/ttl/ttl_constr.h
+34
-31
ratsnest_data.cpp
pcbnew/ratsnest_data.cpp
+1
-1
No files found.
common/geometry/hetriang.cpp
View file @
a10d918c
...
@@ -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
// f
inctions in ttl::
now)
// f
unctions 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
();
...
...
include/ttl/halfedge/hetraits.h
View file @
a10d918c
...
@@ -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
...
...
include/ttl/halfedge/hetriang.h
View file @
a10d918c
...
@@ -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
...
...
include/ttl/ttl.h
View file @
a10d918c
...
@@ -52,8 +52,6 @@
...
@@ -52,8 +52,6 @@
}
}
#endif
#endif
using
std
::
list
;
// Next on TOPOLOGY:
// Next on TOPOLOGY:
// - get triangle strips
// - get triangle strips
...
@@ -102,7 +100,7 @@
...
@@ -102,7 +100,7 @@
* - \e CW - clockwise
* - \e CW - clockwise
* - \e 0_orbit, \e 1_orbit and \e 2_orbit: A sequence of darts around
* - \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;
* 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
* - \e arc - In a triangulation an arc is equivalent with an edge
*
*
* \see
* \see
...
@@ -115,15 +113,15 @@
...
@@ -115,15 +113,15 @@
namespace
ttl
{
namespace
ttl
{
class
TriangulationHelper
{
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifndef DOXYGEN_SHOULD_SKIP_THIS
//------------------------------------------------------------------------------------------------
// ----------------------------------- Forward declarations -------------------------------------
//------------------------------------------------------------------------------------------------
#if ((_MSC_VER > 0) && (_MSC_VER < 1300))
public
:
#else
TriangulationHelper
(
hed
::
Triangulation
&
triang
)
:
triangulation
(
triang
)
{
}
// Delaunay Triangulation
// Delaunay Triangulation
// ----------------------
// ----------------------
template
<
class
TraitsType
,
class
DartType
,
class
PointType
>
template
<
class
TraitsType
,
class
DartType
,
class
PointType
>
...
@@ -145,55 +143,55 @@ namespace ttl {
...
@@ -145,55 +143,55 @@ namespace ttl {
// Topological and Geometric Queries
// Topological and Geometric Queries
// ---------------------------------
// ---------------------------------
template
<
class
TraitsType
,
class
PointType
,
class
DartType
>
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
>
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
>
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
>
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
>
template
<
class
DartType
,
class
DartListType
>
void
getBoundary
(
const
DartType
&
dart
,
DartListType
&
boundary
);
static
void
getBoundary
(
const
DartType
&
dart
,
DartListType
&
boundary
);
template
<
class
DartType
>
template
<
class
DartType
>
bool
isBoundaryEdge
(
const
DartType
&
dart
);
static
bool
isBoundaryEdge
(
const
DartType
&
dart
);
template
<
class
DartType
>
template
<
class
DartType
>
bool
isBoundaryFace
(
const
DartType
&
dart
);
static
bool
isBoundaryFace
(
const
DartType
&
dart
);
template
<
class
DartType
>
template
<
class
DartType
>
bool
isBoundaryNode
(
const
DartType
&
dart
);
static
bool
isBoundaryNode
(
const
DartType
&
dart
);
template
<
class
DartType
>
template
<
class
DartType
>
int
getDegreeOfNode
(
const
DartType
&
dart
);
static
int
getDegreeOfNode
(
const
DartType
&
dart
);
template
<
class
DartType
,
class
DartListType
>
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
>
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
>
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
>
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
>
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
>
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
>
template
<
class
DartType
>
void
positionAtNextBoundaryEdge
(
DartType
&
dart
);
static
void
positionAtNextBoundaryEdge
(
DartType
&
dart
);
template
<
class
TraitsType
,
class
DartType
>
template
<
class
TraitsType
,
class
DartType
>
bool
convexBoundary
(
const
DartType
&
dart
);
static
bool
convexBoundary
(
const
DartType
&
dart
);
// Utilities for Delaunay Triangulation
// Utilities for Delaunay Triangulation
...
@@ -205,7 +203,7 @@ namespace ttl {
...
@@ -205,7 +203,7 @@ namespace ttl {
void
optimizeDelaunay
(
DartListType
&
elist
,
const
typename
DartListType
::
iterator
end
);
void
optimizeDelaunay
(
DartListType
&
elist
,
const
typename
DartListType
::
iterator
end
);
template
<
class
TraitsType
,
class
DartType
>
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
>
template
<
class
TraitsType
,
class
DartType
>
void
recSwapDelaunay
(
DartType
&
diagonal
);
void
recSwapDelaunay
(
DartType
&
diagonal
);
...
@@ -223,9 +221,29 @@ namespace ttl {
...
@@ -223,9 +221,29 @@ namespace ttl {
// Constrained Triangulation
// Constrained Triangulation
// -------------------------
// -------------------------
template
<
class
TraitsType
,
class
DartType
>
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
#endif // DOXYGEN_SHOULD_SKIP_THIS
...
@@ -245,7 +263,7 @@ namespace ttl {
...
@@ -245,7 +263,7 @@ namespace ttl {
* can be created as two triangles forming a rectangle that contains
* can be created as two triangles forming a rectangle that contains
* all the points.
* all the points.
* After \c insertNode has been called repeatedly with 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
* at the boundary of the triangulation so that the boundary
* form the convex hull of the points.
* form the convex hull of the points.
*
*
...
@@ -268,19 +286,19 @@ namespace ttl {
...
@@ -268,19 +286,19 @@ namespace ttl {
* - \ref hed::TTLtraits::splitTriangle "TraitsType::splitTriangle" (DartType&, const PointType&)
* - \ref hed::TTLtraits::splitTriangle "TraitsType::splitTriangle" (DartType&, const PointType&)
*
*
* \using
* \using
* -
ttl::
locateTriangle
* - locateTriangle
* -
ttl::
recSwapDelaunay
* - recSwapDelaunay
*
*
* \note
* \note
* - For efficiency reasons \e dart should be close to the insertion \e point.
* - For efficiency reasons \e dart should be close to the insertion \e point.
*
*
* \see
* \see
*
ttl::
removeRectangularBoundary
* removeRectangularBoundary
*/
*/
template
<
class
TraitsType
,
class
DartType
,
class
PointType
>
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
)
{
if
(
!
found
)
{
#ifdef DEBUG_TTL
#ifdef DEBUG_TTL
cout
<<
"ERROR: Triangulation::insertNode: NO triangle found. /n"
;
cout
<<
"ERROR: Triangulation::insertNode: NO triangle found. /n"
;
...
@@ -289,7 +307,7 @@ namespace ttl {
...
@@ -289,7 +307,7 @@ namespace ttl {
}
}
// ??? can we hide the dart? this is not possible if one triangle only
// ??? can we hide the dart? this is not possible if one triangle only
TraitsType
::
splitTriangle
(
dart
,
point
);
triangulation
.
splitTriangle
(
dart
,
point
);
DartType
d1
=
dart
;
DartType
d1
=
dart
;
d1
.
alpha2
().
alpha1
().
alpha2
().
alpha0
().
alpha1
();
d1
.
alpha2
().
alpha1
().
alpha2
().
alpha0
().
alpha1
();
...
@@ -304,14 +322,14 @@ namespace ttl {
...
@@ -304,14 +322,14 @@ namespace ttl {
//DartType dsav = d3;
//DartType dsav = d3;
d3
.
alpha0
().
alpha1
();
d3
.
alpha0
().
alpha1
();
//if (!TraitsType::fixedEdge(d1) && !
ttl::
isBoundaryEdge(d1)) {
//if (!TraitsType::fixedEdge(d1) && !isBoundaryEdge(d1)) {
if
(
!
ttl
::
isBoundaryEdge
(
d1
))
{
if
(
!
isBoundaryEdge
(
d1
))
{
d1
.
alpha2
();
d1
.
alpha2
();
recSwapDelaunay
<
TraitsType
>
(
d1
);
recSwapDelaunay
<
TraitsType
>
(
d1
);
}
}
//if (!TraitsType::fixedEdge(d2) && !
ttl::
isBoundaryEdge(d2)) {
//if (!TraitsType::fixedEdge(d2) && !isBoundaryEdge(d2)) {
if
(
!
ttl
::
isBoundaryEdge
(
d2
))
{
if
(
!
isBoundaryEdge
(
d2
))
{
d2
.
alpha2
();
d2
.
alpha2
();
recSwapDelaunay
<
TraitsType
>
(
d2
);
recSwapDelaunay
<
TraitsType
>
(
d2
);
}
}
...
@@ -319,8 +337,8 @@ namespace ttl {
...
@@ -319,8 +337,8 @@ namespace ttl {
// Preserve the incoming dart as output incident to the node and CCW
// Preserve the incoming dart as output incident to the node and CCW
//d = dsav.alpha2();
//d = dsav.alpha2();
dart
.
alpha2
();
dart
.
alpha2
();
//if (!TraitsType::fixedEdge(d3) && !
ttl::
isBoundaryEdge(d3)) {
//if (!TraitsType::fixedEdge(d3) && !isBoundaryEdge(d3)) {
if
(
!
ttl
::
isBoundaryEdge
(
d3
))
{
if
(
!
isBoundaryEdge
(
d3
))
{
d3
.
alpha2
();
d3
.
alpha2
();
recSwapDelaunay
<
TraitsType
>
(
d3
);
recSwapDelaunay
<
TraitsType
>
(
d3
);
}
}
...
@@ -332,7 +350,7 @@ namespace ttl {
...
@@ -332,7 +350,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
// Private/Hidden function (might change later)
// Private/Hidden function (might change later)
template
<
class
TraitsType
,
class
ForwardIterator
,
class
DartType
>
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.
// Assumes that the dereferenced point objects are pointers.
// References to the point objects are then passed to TTL.
// References to the point objects are then passed to TTL.
...
@@ -355,14 +373,14 @@ namespace ttl {
...
@@ -355,14 +373,14 @@ namespace ttl {
* Output: A CCW dart at the new boundary
* Output: A CCW dart at the new boundary
*
*
* \using
* \using
* -
ttl::
removeBoundaryNode
* - removeBoundaryNode
*
*
* \note
* \note
* - This function requires that the boundary of the triangulation is
* - This function requires that the boundary of the triangulation is
* a rectangle with four nodes (one in each corner).
* a rectangle with four nodes (one in each corner).
*/
*/
template
<
class
TraitsType
,
class
DartType
>
template
<
class
TraitsType
,
class
DartType
>
void
removeRectangularBoundary
(
DartType
&
dart
)
{
void
TriangulationHelper
::
removeRectangularBoundary
(
DartType
&
dart
)
{
DartType
d_next
=
dart
;
DartType
d_next
=
dart
;
DartType
d_iter
;
DartType
d_iter
;
...
@@ -370,8 +388,8 @@ namespace ttl {
...
@@ -370,8 +388,8 @@ namespace ttl {
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
d_iter
=
d_next
;
d_iter
=
d_next
;
d_next
.
alpha0
();
d_next
.
alpha0
();
ttl
::
positionAtNextBoundaryEdge
(
d_next
);
positionAtNextBoundaryEdge
(
d_next
);
ttl
::
removeBoundaryNode
<
TraitsType
>
(
d_iter
);
removeBoundaryNode
<
TraitsType
>
(
d_iter
);
}
}
dart
=
d_next
;
// Return a dart at the new boundary
dart
=
d_next
;
// Return a dart at the new boundary
...
@@ -383,20 +401,20 @@ namespace ttl {
...
@@ -383,20 +401,20 @@ namespace ttl {
* updates the triangulation to be Delaunay.
* updates the triangulation to be Delaunay.
*
*
* \using
* \using
* -
ttl::
removeBoundaryNode if \e dart represents a node at the boundary
* - removeBoundaryNode if \e dart represents a node at the boundary
* -
ttl::
removeInteriorNode if \e dart represents an interior node
* - removeInteriorNode if \e dart represents an interior node
*
*
* \note
* \note
* - The node cannot belong to a fixed (constrained) edge that is not
* - The node cannot belong to a fixed (constrained) edge that is not
* swappable. (An endless loop is likely to occur in this case).
* swappable. (An endless loop is likely to occur in this case).
*/
*/
template
<
class
TraitsType
,
class
DartType
>
template
<
class
TraitsType
,
class
DartType
>
void
removeNode
(
DartType
&
dart
)
{
void
TriangulationHelper
::
removeNode
(
DartType
&
dart
)
{
if
(
ttl
::
isBoundaryNode
(
dart
))
if
(
isBoundaryNode
(
dart
))
ttl
::
removeBoundaryNode
<
TraitsType
>
(
dart
);
removeBoundaryNode
<
TraitsType
>
(
dart
);
else
else
ttl
::
removeInteriorNode
<
TraitsType
>
(
dart
);
removeInteriorNode
<
TraitsType
>
(
dart
);
}
}
...
@@ -405,14 +423,14 @@ namespace ttl {
...
@@ -405,14 +423,14 @@ namespace ttl {
* updates the triangulation to be Delaunay.
* updates the triangulation to be Delaunay.
*
*
* \using
* \using
* -
ttl::
swapEdgesAwayFromBoundaryNode
* - swapEdgesAwayFromBoundaryNode
* -
ttl::
optimizeDelaunay
* - optimizeDelaunay
*
*
* \require
* \require
* - \ref hed::TTLtraits::removeBoundaryTriangle "TraitsType::removeBoundaryTriangle" (Dart&)
* - \ref hed::TTLtraits::removeBoundaryTriangle "TraitsType::removeBoundaryTriangle" (Dart&)
*/
*/
template
<
class
TraitsType
,
class
DartType
>
template
<
class
TraitsType
,
class
DartType
>
void
removeBoundaryNode
(
DartType
&
dart
)
{
void
TriangulationHelper
::
removeBoundaryNode
(
DartType
&
dart
)
{
// ... and update Delaunay
// ... and update Delaunay
// - CCW dart must be given (for remove)
// - CCW dart must be given (for remove)
...
@@ -420,13 +438,13 @@ namespace ttl {
...
@@ -420,13 +438,13 @@ namespace ttl {
// we assume that there is not only one triangle left in the triangulation.
// we assume that there is not only one triangle left in the triangulation.
// Position at boundary edge and CCW
// 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)
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
;
std
::
list
<
DartType
>
swapped_edges
;
ttl
::
swapEdgesAwayFromBoundaryNode
<
TraitsType
>
(
dart
,
swapped_edges
);
swapEdgesAwayFromBoundaryNode
<
TraitsType
>
(
dart
,
swapped_edges
);
// Remove boundary triangles and remove the new boundary from the list
// Remove boundary triangles and remove the new boundary from the list
// of swapped edges, see below.
// of swapped edges, see below.
...
@@ -435,7 +453,7 @@ namespace ttl {
...
@@ -435,7 +453,7 @@ namespace ttl {
bool
bend
=
false
;
bool
bend
=
false
;
while
(
bend
==
false
)
{
while
(
bend
==
false
)
{
dnext
.
alpha1
().
alpha2
();
dnext
.
alpha1
().
alpha2
();
if
(
ttl
::
isBoundaryEdge
(
dnext
))
if
(
isBoundaryEdge
(
dnext
))
bend
=
true
;
// Stop when boundary
bend
=
true
;
// Stop when boundary
// Generic: Also remove the new boundary from the list of swapped edges
// Generic: Also remove the new boundary from the list of swapped edges
...
@@ -443,20 +461,20 @@ namespace ttl {
...
@@ -443,20 +461,20 @@ namespace ttl {
n_bedge
.
alpha1
().
alpha0
().
alpha1
().
alpha2
();
// new boundary edge
n_bedge
.
alpha1
().
alpha0
().
alpha1
().
alpha2
();
// new boundary edge
// ??? can we avoid find if we do this in swap away?
// ??? 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
);
it
=
find
(
swapped_edges
.
begin
(),
swapped_edges
.
end
(),
n_bedge
);
if
(
it
!=
swapped_edges
.
end
())
if
(
it
!=
swapped_edges
.
end
())
swapped_edges
.
erase
(
it
);
swapped_edges
.
erase
(
it
);
// Remove the boundary triangle
// Remove the boundary triangle
TraitsType
::
removeBoundaryTriangle
(
d_iter
);
triangulation
.
removeBoundaryTriangle
(
d_iter
);
d_iter
=
dnext
;
d_iter
=
dnext
;
}
}
// Optimize Delaunay
// Optimize Delaunay
typedef
list
<
DartType
>
DartListType
;
typedef
std
::
list
<
DartType
>
DartListType
;
ttl
::
optimizeDelaunay
<
TraitsType
,
DartType
,
DartListType
>
(
swapped_edges
);
optimizeDelaunay
<
TraitsType
,
DartType
,
DartListType
>
(
swapped_edges
);
}
}
...
@@ -465,8 +483,8 @@ namespace ttl {
...
@@ -465,8 +483,8 @@ namespace ttl {
* updates the triangulation to be Delaunay.
* updates the triangulation to be Delaunay.
*
*
* \using
* \using
* -
ttl::
swapEdgesAwayFromInteriorNode
* - swapEdgesAwayFromInteriorNode
* -
ttl::optimizeDelaunay
* -
optimizeDelaunay
*
*
* \require
* \require
* - \ref hed::TTLtraits::reverse_splitTriangle "TraitsType::reverse_splitTriangle" (Dart&)
* - \ref hed::TTLtraits::reverse_splitTriangle "TraitsType::reverse_splitTriangle" (Dart&)
...
@@ -476,7 +494,7 @@ namespace ttl {
...
@@ -476,7 +494,7 @@ namespace ttl {
* swappable. (An endless loop is likely to occur in this case).
* swappable. (An endless loop is likely to occur in this case).
*/
*/
template
<
class
TraitsType
,
class
DartType
>
template
<
class
TraitsType
,
class
DartType
>
void
removeInteriorNode
(
DartType
&
dart
)
{
void
TriangulationHelper
::
removeInteriorNode
(
DartType
&
dart
)
{
// ... and update to Delaunay.
// ... and update to Delaunay.
// Must allow degeneracy temporarily, see comments in swap edges away
// Must allow degeneracy temporarily, see comments in swap edges away
...
@@ -492,13 +510,13 @@ namespace ttl {
...
@@ -492,13 +510,13 @@ namespace ttl {
// Assumes dart is counterclockwise
// Assumes dart is counterclockwise
list
<
DartType
>
swapped_edges
;
std
::
list
<
DartType
>
swapped_edges
;
ttl
::
swapEdgesAwayFromInteriorNode
<
TraitsType
>
(
dart
,
swapped_edges
);
swapEdgesAwayFromInteriorNode
<
TraitsType
>
(
dart
,
swapped_edges
);
// The reverse operation of split triangle:
// The reverse operation of split triangle:
// Make one triangle of the three triangles at the node associated with dart
// Make one triangle of the three triangles at the node associated with dart
// TraitsType::
// TraitsType::
TraitsType
::
reverse_splitTriangle
(
dart
);
triangulation
.
reverse_splitTriangle
(
dart
);
// ???? Not generic yet if we are very strict:
// ???? Not generic yet if we are very strict:
// When calling unsplit triangle, darts at the three opposite sides may
// When calling unsplit triangle, darts at the three opposite sides may
...
@@ -511,7 +529,7 @@ namespace ttl {
...
@@ -511,7 +529,7 @@ namespace ttl {
// Note the theoretical result: if there are no edges in the list,
// Note the theoretical result: if there are no edges in the list,
// the triangulation is Delaunay already
// the triangulation is Delaunay already
ttl
::
optimizeDelaunay
<
TraitsType
,
DartType
>
(
swapped_edges
);
optimizeDelaunay
<
TraitsType
,
DartType
>
(
swapped_edges
);
}
}
//@} // End of Delaunay Triangulation Group
//@} // End of Delaunay Triangulation Group
...
@@ -527,7 +545,7 @@ namespace ttl {
...
@@ -527,7 +545,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
// Private/Hidden function (might change later)
// Private/Hidden function (might change later)
template
<
class
TopologyElementType
,
class
DartType
>
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
// Check if the given topology element (node, edge or face) is a member of the face
// Assumes:
// Assumes:
...
@@ -547,7 +565,7 @@ namespace ttl {
...
@@ -547,7 +565,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
// Private/Hidden function (might change later)
// Private/Hidden function (might change later)
template
<
class
TraitsType
,
class
NodeType
,
class
DartType
>
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
// Locate a face in the topology structure with the given node as a member
// Assumes:
// Assumes:
// - TraitsType::orient2d(DartType, DartType, NodeType)
// - TraitsType::orient2d(DartType, DartType, NodeType)
...
@@ -594,10 +612,10 @@ namespace ttl {
...
@@ -594,10 +612,10 @@ namespace ttl {
* \e regular as explained above.
* \e regular as explained above.
*
*
* \see
* \see
*
ttl::
locateTriangle
* locateTriangle
*/
*/
template
<
class
TraitsType
,
class
PointType
,
class
DartType
>
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
// 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)
// But inTriangle may be called in case of true (may update to inFace2)
// Convex boundary
// Convex boundary
...
@@ -660,11 +678,11 @@ namespace ttl {
...
@@ -660,11 +678,11 @@ namespace ttl {
* then the edge associated with \e dart will be at the boundary of the triangulation.
* then the edge associated with \e dart will be at the boundary of the triangulation.
*
*
* \using
* \using
* -
ttl::
locateFaceSimplest
* - locateFaceSimplest
* -
ttl::
inTriangle
* - inTriangle
*/
*/
template
<
class
TraitsType
,
class
PointType
,
class
DartType
>
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
// 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
// i) avoids concluding that a point is inside a triangle if it is not inside
// ii) avoids infinite loops
// ii) avoids infinite loops
...
@@ -713,10 +731,10 @@ namespace ttl {
...
@@ -713,10 +731,10 @@ namespace ttl {
* - \ref hed::TTLtraits::orient2d "TraitsType::orient2d" (DartType&, DartType&, PointType&)
* - \ref hed::TTLtraits::orient2d "TraitsType::orient2d" (DartType&, DartType&, PointType&)
*
*
* \see
* \see
*
ttl::
inTriangle for a more robust function
* inTriangle for a more robust function
*/
*/
template
<
class
TraitsType
,
class
PointType
,
class
DartType
>
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
// 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
// degeneracy, true will be returned if the point is on the extension of the
...
@@ -757,10 +775,10 @@ namespace ttl {
...
@@ -757,10 +775,10 @@ namespace ttl {
* - \ref hed::TTLtraits::scalarProduct2d "TraitsType::scalarProduct2d" (DartType&, PointType&)
* - \ref hed::TTLtraits::scalarProduct2d "TraitsType::scalarProduct2d" (DartType&, PointType&)
*
*
* \see
* \see
*
ttl::
inTriangleSimplest
* inTriangleSimplest
*/
*/
template
<
class
TraitsType
,
class
PointType
,
class
DartType
>
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
// 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
// ONLY ON ONE EDGE? BUT THIS DOES NOT SOLVE PROBLEMS WITH
...
@@ -841,7 +859,7 @@ namespace ttl {
...
@@ -841,7 +859,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
// Private/Hidden function (might change later)
// Private/Hidden function (might change later)
template
<
class
DartType
>
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
;
DartType
dart_iter
=
dart
;
...
@@ -886,7 +904,7 @@ namespace ttl {
...
@@ -886,7 +904,7 @@ namespace ttl {
* - DartListType::push_back (DartType&)
* - DartListType::push_back (DartType&)
*/
*/
template
<
class
DartType
,
class
DartListType
>
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)
// assumes the given dart is at the boundary (by edge)
DartType
dart_iter
(
dart
);
DartType
dart_iter
(
dart
);
...
@@ -932,7 +950,7 @@ namespace ttl {
...
@@ -932,7 +950,7 @@ namespace ttl {
* \endcode
* \endcode
*/
*/
template
<
class
DartType
>
template
<
class
DartType
>
bool
isBoundaryEdge
(
const
DartType
&
dart
)
{
bool
TriangulationHelper
::
isBoundaryEdge
(
const
DartType
&
dart
)
{
DartType
dart_iter
=
dart
;
DartType
dart_iter
=
dart
;
if
(
dart_iter
.
alpha2
()
==
dart
)
if
(
dart_iter
.
alpha2
()
==
dart
)
...
@@ -947,7 +965,7 @@ namespace ttl {
...
@@ -947,7 +965,7 @@ namespace ttl {
* the boundary of the triangulation.
* the boundary of the triangulation.
*/
*/
template
<
class
DartType
>
template
<
class
DartType
>
bool
isBoundaryFace
(
const
DartType
&
dart
)
{
bool
TriangulationHelper
::
isBoundaryFace
(
const
DartType
&
dart
)
{
// Strategy: boundary if alpha2(d)=d
// Strategy: boundary if alpha2(d)=d
...
@@ -976,7 +994,7 @@ namespace ttl {
...
@@ -976,7 +994,7 @@ namespace ttl {
* the boundary of the triangulation.
* the boundary of the triangulation.
*/
*/
template
<
class
DartType
>
template
<
class
DartType
>
bool
isBoundaryNode
(
const
DartType
&
dart
)
{
bool
TriangulationHelper
::
isBoundaryNode
(
const
DartType
&
dart
)
{
// Strategy: boundary if alpha2(d)=d
// Strategy: boundary if alpha2(d)=d
...
@@ -1009,7 +1027,7 @@ namespace ttl {
...
@@ -1009,7 +1027,7 @@ namespace ttl {
* the number of edges joining \e V with another node in the triangulation.
* the number of edges joining \e V with another node in the triangulation.
*/
*/
template
<
class
DartType
>
template
<
class
DartType
>
int
getDegreeOfNode
(
const
DartType
&
dart
)
{
int
TriangulationHelper
::
getDegreeOfNode
(
const
DartType
&
dart
)
{
DartType
dart_iter
(
dart
);
DartType
dart_iter
(
dart
);
DartType
dart_prev
;
DartType
dart_prev
;
...
@@ -1069,7 +1087,8 @@ namespace ttl {
...
@@ -1069,7 +1087,8 @@ namespace ttl {
// Private/Hidden function
// Private/Hidden function
template
<
class
DartType
>
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
);
DartType
dart_iter
(
dart
);
...
@@ -1131,10 +1150,10 @@ namespace ttl {
...
@@ -1131,10 +1150,10 @@ namespace ttl {
* - DartListType::push_back (DartType&)
* - DartListType::push_back (DartType&)
*
*
* \see
* \see
*
ttl::
get_0_orbit_boundary
* get_0_orbit_boundary
*/
*/
template
<
class
DartType
,
class
DartListType
>
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
;
DartType
d_iter
=
dart
;
orbit
.
push_back
(
d_iter
);
orbit
.
push_back
(
d_iter
);
...
@@ -1165,10 +1184,10 @@ namespace ttl {
...
@@ -1165,10 +1184,10 @@ namespace ttl {
* - The last dart in the sequence have opposite orientation compared to the others!
* - The last dart in the sequence have opposite orientation compared to the others!
*
*
* \see
* \see
*
ttl::
get_0_orbit_interior
* get_0_orbit_interior
*/
*/
template
<
class
DartType
,
class
DartListType
>
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
dart_prev
;
DartType
d_iter
=
dart
;
DartType
d_iter
=
dart
;
...
@@ -1195,17 +1214,17 @@ namespace ttl {
...
@@ -1195,17 +1214,17 @@ namespace ttl {
* own version.)
* own version.)
*/
*/
template
<
class
DartType
>
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
// Two copies of the same dart
DartType
d_iter
=
d2
;
DartType
d_iter
=
d2
;
DartType
d_end
=
d2
;
DartType
d_end
=
d2
;
if
(
ttl
::
isBoundaryNode
(
d_iter
))
{
if
(
isBoundaryNode
(
d_iter
))
{
// position at both boundary edges
// position at both boundary edges
ttl
::
positionAtNextBoundaryEdge
(
d_iter
);
positionAtNextBoundaryEdge
(
d_iter
);
d_end
.
alpha1
();
d_end
.
alpha1
();
ttl
::
positionAtNextBoundaryEdge
(
d_end
);
positionAtNextBoundaryEdge
(
d_end
);
}
}
for
(;;)
{
for
(;;)
{
...
@@ -1229,7 +1248,7 @@ namespace ttl {
...
@@ -1229,7 +1248,7 @@ namespace ttl {
* \e d1 and/or \e d2 can be CCW or CW.
* \e d1 and/or \e d2 can be CCW or CW.
*/
*/
template
<
class
DartType
>
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
;
DartType
d_iter
=
d2
;
// (Also works at the boundary)
// (Also works at the boundary)
...
@@ -1245,7 +1264,7 @@ namespace ttl {
...
@@ -1245,7 +1264,7 @@ namespace ttl {
* \e d1 and/or \e d2 can be CCW or CW
* \e d1 and/or \e d2 can be CCW or CW
*/
*/
template
<
class
DartType
>
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
;
DartType
d_iter
=
d2
;
if
(
d_iter
==
d1
||
d_iter
.
alpha0
()
==
d1
||
if
(
d_iter
==
d1
||
d_iter
.
alpha0
()
==
d1
||
...
@@ -1259,7 +1278,7 @@ namespace ttl {
...
@@ -1259,7 +1278,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
// Private/Hidden function
// Private/Hidden function
template
<
class
TraitsType
,
class
DartType
>
template
<
class
TraitsType
,
class
DartType
>
bool
degenerateTriangle
(
const
DartType
&
dart
)
{
bool
TriangulationHelper
::
degenerateTriangle
(
const
DartType
&
dart
)
{
// Check if triangle is degenerate
// Check if triangle is degenerate
// Assumes CCW dart
// Assumes CCW dart
...
@@ -1287,7 +1306,7 @@ namespace ttl {
...
@@ -1287,7 +1306,7 @@ namespace ttl {
* - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (Dart&, Dart&)
* - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (Dart&, Dart&)
*/
*/
template
<
class
TraitsType
,
class
DartType
>
template
<
class
TraitsType
,
class
DartType
>
bool
swappableEdge
(
const
DartType
&
dart
,
bool
allowDegeneracy
)
{
bool
TriangulationHelper
::
swappableEdge
(
const
DartType
&
dart
,
bool
allowDegeneracy
)
{
// How "safe" is it?
// How "safe" is it?
...
@@ -1340,7 +1359,7 @@ namespace ttl {
...
@@ -1340,7 +1359,7 @@ namespace ttl {
* infinit loop occurs.
* infinit loop occurs.
*/
*/
template
<
class
DartType
>
template
<
class
DartType
>
void
positionAtNextBoundaryEdge
(
DartType
&
dart
)
{
void
TriangulationHelper
::
positionAtNextBoundaryEdge
(
DartType
&
dart
)
{
DartType
dart_prev
;
DartType
dart_prev
;
...
@@ -1365,14 +1384,14 @@ namespace ttl {
...
@@ -1365,14 +1384,14 @@ namespace ttl {
* - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (const Dart&, const Dart&)
* - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (const Dart&, const Dart&)
*/
*/
template
<
class
TraitsType
,
class
DartType
>
template
<
class
TraitsType
,
class
DartType
>
bool
convexBoundary
(
const
DartType
&
dart
)
{
bool
TriangulationHelper
::
convexBoundary
(
const
DartType
&
dart
)
{
list
<
DartType
>
blist
;
std
::
list
<
DartType
>
blist
;
ttl
::
getBoundary
(
dart
,
blist
);
getBoundary
(
dart
,
blist
);
int
no
;
int
no
;
no
=
(
int
)
blist
.
size
();
no
=
(
int
)
blist
.
size
();
typename
list
<
DartType
>::
const_iterator
bit
=
blist
.
begin
();
typename
std
::
list
<
DartType
>::
const_iterator
bit
=
blist
.
begin
();
DartType
d1
=
*
bit
;
DartType
d1
=
*
bit
;
++
bit
;
++
bit
;
DartType
d2
;
DartType
d2
;
...
@@ -1428,17 +1447,17 @@ namespace ttl {
...
@@ -1428,17 +1447,17 @@ namespace ttl {
* seen if it was glued to the edge when swapping (rotating) the edge CCW
* seen if it was glued to the edge when swapping (rotating) the edge CCW
*
*
* \using
* \using
* -
ttl::
swapTestDelaunay
* - swapTestDelaunay
*/
*/
template
<
class
TraitsType
,
class
DartType
,
class
DartListType
>
template
<
class
TraitsType
,
class
DartType
,
class
DartListType
>
void
optimizeDelaunay
(
DartListType
&
elist
)
{
void
TriangulationHelper
::
optimizeDelaunay
(
DartListType
&
elist
)
{
optimizeDelaunay
<
TraitsType
,
DartType
,
DartListType
>
(
elist
,
elist
.
end
());
optimizeDelaunay
<
TraitsType
,
DartType
,
DartListType
>
(
elist
,
elist
.
end
());
}
}
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
template
<
class
TraitsType
,
class
DartType
,
class
DartListType
>
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
// CCW darts
// Optimize here means Delaunay, but could be any criterion by
// Optimize here means Delaunay, but could be any criterion by
...
@@ -1481,14 +1500,14 @@ namespace ttl {
...
@@ -1481,14 +1500,14 @@ namespace ttl {
while
(
!
optimal
)
{
while
(
!
optimal
)
{
optimal
=
true
;
optimal
=
true
;
for
(
it
=
elist
.
begin
();
it
!=
end_opt
;
++
it
)
{
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:
// Preserve darts. Potential darts in the list are:
// - The current dart
// - The current dart
// - the four CCW darts on the boundary of the quadrilateral
// - the four CCW darts on the boundary of the quadrilateral
// (the current arc has only one dart)
// (the current arc has only one dart)
ttl
::
swapEdgeInList
<
TraitsType
,
DartType
>
(
it
,
elist
);
swapEdgeInList
<
TraitsType
,
DartType
>
(
it
,
elist
);
optimal
=
false
;
optimal
=
false
;
}
// end if should swap
}
// end if should swap
...
@@ -1513,9 +1532,9 @@ namespace ttl {
...
@@ -1513,9 +1532,9 @@ namespace ttl {
*/
*/
template
<
class
TraitsType
,
class
DartType
>
template
<
class
TraitsType
,
class
DartType
>
#if ((_MSC_VER > 0) && (_MSC_VER < 1300))//#ifdef _MSC_VER
#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
#else
bool
swapTestDelaunay
(
const
DartType
&
dart
,
bool
cycling_check
)
{
bool
TriangulationHelper
::
swapTestDelaunay
(
const
DartType
&
dart
,
bool
cycling_check
)
const
{
#endif
#endif
// The general strategy is taken from Cline & Renka. They claim that
// The general strategy is taken from Cline & Renka. They claim that
...
@@ -1627,17 +1646,17 @@ namespace ttl {
...
@@ -1627,17 +1646,17 @@ namespace ttl {
* - Calls itself recursively
* - Calls itself recursively
*/
*/
template
<
class
TraitsType
,
class
DartType
>
template
<
class
TraitsType
,
class
DartType
>
void
recSwapDelaunay
(
DartType
&
diagonal
)
{
void
TriangulationHelper
::
recSwapDelaunay
(
DartType
&
diagonal
)
{
if
(
!
ttl
::
swapTestDelaunay
<
TraitsType
>
(
diagonal
))
if
(
!
swapTestDelaunay
<
TraitsType
>
(
diagonal
))
// ???
ttl::
swapTestDelaunay also checks if boundary, so this can be optimized
// ??? swapTestDelaunay also checks if boundary, so this can be optimized
return
;
return
;
// Get the other "edges" of the current triangle; see illustration above.
// Get the other "edges" of the current triangle; see illustration above.
DartType
oppEdge1
=
diagonal
;
DartType
oppEdge1
=
diagonal
;
oppEdge1
.
alpha1
();
oppEdge1
.
alpha1
();
bool
b1
;
bool
b1
;
if
(
ttl
::
isBoundaryEdge
(
oppEdge1
))
if
(
isBoundaryEdge
(
oppEdge1
))
b1
=
true
;
b1
=
true
;
else
{
else
{
b1
=
false
;
b1
=
false
;
...
@@ -1648,7 +1667,7 @@ namespace ttl {
...
@@ -1648,7 +1667,7 @@ namespace ttl {
DartType
oppEdge2
=
diagonal
;
DartType
oppEdge2
=
diagonal
;
oppEdge2
.
alpha0
().
alpha1
().
alpha0
();
oppEdge2
.
alpha0
().
alpha1
().
alpha0
();
bool
b2
;
bool
b2
;
if
(
ttl
::
isBoundaryEdge
(
oppEdge2
))
if
(
isBoundaryEdge
(
oppEdge2
))
b2
=
true
;
b2
=
true
;
else
{
else
{
b2
=
false
;
b2
=
false
;
...
@@ -1656,7 +1675,7 @@ namespace ttl {
...
@@ -1656,7 +1675,7 @@ namespace ttl {
}
}
// Swap the given diagonal
// Swap the given diagonal
TraitsType
::
swapEdge
(
diagonal
);
triangulation
.
swapEdge
(
diagonal
);
if
(
!
b1
)
if
(
!
b1
)
recSwapDelaunay
<
TraitsType
>
(
oppEdge1
);
recSwapDelaunay
<
TraitsType
>
(
oppEdge1
);
...
@@ -1669,7 +1688,7 @@ namespace ttl {
...
@@ -1669,7 +1688,7 @@ namespace ttl {
/** Swaps edges away from the (interior) node associated with
/** Swaps edges away from the (interior) node associated with
* \e dart such that that exactly three edges remain incident
* \e dart such that that exactly three edges remain incident
* with the node.
* 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
* \retval dart
* A CCW dart incident with the node
* A CCW dart incident with the node
...
@@ -1689,10 +1708,10 @@ namespace ttl {
...
@@ -1689,10 +1708,10 @@ namespace ttl {
* at the node that is given as input.
* at the node that is given as input.
*
*
* \see
* \see
*
ttl::
swapEdgesAwayFromBoundaryNode
* swapEdgesAwayFromBoundaryNode
*/
*/
template
<
class
TraitsType
,
class
DartType
,
class
ListType
>
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
// Same iteration as in fixEdgesAtCorner, but not boundary
DartType
dnext
=
dart
;
DartType
dnext
=
dart
;
...
@@ -1706,14 +1725,14 @@ namespace ttl {
...
@@ -1706,14 +1725,14 @@ namespace ttl {
// infinite loop with degree > 3.
// infinite loop with degree > 3.
bool
allowDegeneracy
=
true
;
bool
allowDegeneracy
=
true
;
int
degree
=
ttl
::
getDegreeOfNode
(
dart
);
int
degree
=
getDegreeOfNode
(
dart
);
DartType
d_iter
;
DartType
d_iter
;
while
(
degree
>
3
)
{
while
(
degree
>
3
)
{
d_iter
=
dnext
;
d_iter
=
dnext
;
dnext
.
alpha1
().
alpha2
();
dnext
.
alpha1
().
alpha2
();
if
(
ttl
::
swappableEdge
<
TraitsType
>
(
d_iter
,
allowDegeneracy
))
{
if
(
swappableEdge
<
TraitsType
>
(
d_iter
,
allowDegeneracy
))
{
TraitsType
::
swapEdge
(
d_iter
);
// swap the edge away
triangulation
.
swapEdge
(
d_iter
);
// swap the edge away
// Collect swapped edges in the list
// Collect swapped edges in the list
// "Hide" the dart on the other side of the edge to avoid it being changed for
// "Hide" the dart on the other side of the edge to avoid it being changed for
// other swaps
// other swaps
...
@@ -1733,7 +1752,7 @@ namespace ttl {
...
@@ -1733,7 +1752,7 @@ namespace ttl {
/** Swaps edges away from the (boundary) node associated with
/** Swaps edges away from the (boundary) node associated with
* \e dart in such a way that when removing the edges that remain incident
* \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.
* 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
* \retval dart
* A CCW dart incident with the node
* A CCW dart incident with the node
...
@@ -1747,10 +1766,10 @@ namespace ttl {
...
@@ -1747,10 +1766,10 @@ namespace ttl {
* - The node associated with \e dart is at the boundary of the triangulation.
* - The node associated with \e dart is at the boundary of the triangulation.
*
*
* \see
* \see
*
ttl::
swapEdgesAwayFromInteriorNode
* swapEdgesAwayFromInteriorNode
*/
*/
template
<
class
TraitsType
,
class
DartType
,
class
ListType
>
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.
// All darts that are swappable.
// To treat collinear nodes at an existing boundary, we must allow degeneracy
// To treat collinear nodes at an existing boundary, we must allow degeneracy
...
@@ -1762,7 +1781,7 @@ namespace ttl {
...
@@ -1762,7 +1781,7 @@ namespace ttl {
// - A dart on the swapped edge is delivered back in a position as
// - 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
// seen if it was glued to the edge when swapping (rotating) the edge CCW
//int degree =
ttl::
getDegreeOfNode(dart);
//int degree = getDegreeOfNode(dart);
passes
:
passes
:
...
@@ -1780,7 +1799,7 @@ passes:
...
@@ -1780,7 +1799,7 @@ passes:
while
(
!
bend
)
{
while
(
!
bend
)
{
d_next
.
alpha1
().
alpha2
();
d_next
.
alpha1
().
alpha2
();
if
(
ttl
::
isBoundaryEdge
(
d_next
))
if
(
isBoundaryEdge
(
d_next
))
bend
=
true
;
// then it is CW since alpha2
bend
=
true
;
// then it is CW since alpha2
// To allow removing among collinear nodes at the boundary,
// To allow removing among collinear nodes at the boundary,
...
@@ -1789,13 +1808,13 @@ passes:
...
@@ -1789,13 +1808,13 @@ passes:
tmp1
=
d_iter
;
tmp1
.
alpha1
();
tmp1
=
d_iter
;
tmp1
.
alpha1
();
tmp2
=
d_iter
;
tmp2
.
alpha2
().
alpha1
();
// don't bother with boundary (checked later)
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
;
allowDegeneracy
=
true
;
else
else
allowDegeneracy
=
false
;
allowDegeneracy
=
false
;
if
(
ttl
::
swappableEdge
<
TraitsType
>
(
d_iter
,
allowDegeneracy
))
{
if
(
swappableEdge
<
TraitsType
>
(
d_iter
,
allowDegeneracy
))
{
TraitsType
::
swapEdge
(
d_iter
);
triangulation
.
swapEdge
(
d_iter
);
// Collect swapped edges in the list
// Collect swapped edges in the list
// "Hide" the dart on the other side of the edge to avoid it being changed for
// "Hide" the dart on the other side of the edge to avoid it being changed for
...
@@ -1821,7 +1840,7 @@ passes:
...
@@ -1821,7 +1840,7 @@ passes:
else
{
else
{
d_iter
.
alpha1
();
// CW and see below
d_iter
.
alpha1
();
// CW and see below
}
}
ttl
::
positionAtNextBoundaryEdge
(
d_iter
);
// CCW
positionAtNextBoundaryEdge
(
d_iter
);
// CCW
dart
=
d_iter
;
// for next pass or output
dart
=
d_iter
;
// for next pass or output
...
@@ -1839,7 +1858,7 @@ passes:
...
@@ -1839,7 +1858,7 @@ passes:
* keep them in \e elist.
* keep them in \e elist.
*/
*/
template
<
class
TraitsType
,
class
DartType
,
class
DartListType
>
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
;
typename
DartListType
::
iterator
it1
,
it2
,
it3
,
it4
;
DartType
dart
(
*
it
);
DartType
dart
(
*
it
);
...
@@ -1867,7 +1886,7 @@ passes:
...
@@ -1867,7 +1886,7 @@ passes:
it3
=
find
(
elist
.
begin
(),
elist
.
end
(),
d3
);
it3
=
find
(
elist
.
begin
(),
elist
.
end
(),
d3
);
it4
=
find
(
elist
.
begin
(),
elist
.
end
(),
d4
);
it4
=
find
(
elist
.
begin
(),
elist
.
end
(),
d4
);
TraitsType
::
swapEdge
(
dart
);
triangulation
.
swapEdge
(
dart
);
// Update the current dart which may have changed
// Update the current dart which may have changed
*
it
=
dart
;
*
it
=
dart
;
...
...
include/ttl/ttl_constr.h
View file @
a10d918c
...
@@ -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
...
...
pcbnew/ratsnest_data.cpp
View file @
a10d918c
...
@@ -240,7 +240,7 @@ void RN_NET::compute()
...
@@ -240,7 +240,7 @@ void RN_NET::compute()
return
;
return
;
}
}
else
if
(
boardNodes
.
size
()
=
=
1
)
// This case is even simpler
else
if
(
boardNodes
.
size
()
<
=
1
)
// This case is even simpler
{
{
m_rnEdges
.
reset
(
new
std
::
vector
<
RN_EDGE_PTR
>
(
0
)
);
m_rnEdges
.
reset
(
new
std
::
vector
<
RN_EDGE_PTR
>
(
0
)
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment