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
Expand all
Show 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
This diff is collapsed.
Click to expand it.
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