Skip to content

Commit

Permalink
Refactor code for simplicity
Browse files Browse the repository at this point in the history
  • Loading branch information
artem-ogre committed Jan 29, 2025
1 parent ee85196 commit cc04653
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 179 deletions.
2 changes: 1 addition & 1 deletion CDT/extras/InitializeWithGrid.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void generateGridVertices(
TXCoordIter xiter = xfirst;
for(std::size_t ix = 0; xiter != xlast; ++xiter, ++ix)
{
*outVertsFirst++ = V2d<T>::make(*xiter, *yiter);
*outVertsFirst++ = V2d<T>(*xiter, *yiter);
const std::size_t i = iy * xres + ix;
TriIndVec vTris;
vTris.reserve(6);
Expand Down
2 changes: 1 addition & 1 deletion CDT/include/CDT.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ DuplicatesInfo FindDuplicates(
typename PosToIndex::const_iterator it;
bool isUnique;
tie(it, isUnique) = uniqueVerts.insert(
std::make_pair(V2d<T>::make(getX(*first), getY(*first)), iOut));
std::make_pair(V2d<T>(getX(*first), getY(*first)), iOut));
if(isUnique)
{
di.mapping[iIn] = iOut++;
Expand Down
151 changes: 87 additions & 64 deletions CDT/include/CDTUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,21 @@ std::string to_string(const T& value)
namespace CDT
{

namespace detail
{
/// Needed for c++03 compatibility (no uniform initialization available)
template <typename T>
array<T, 3> arr3(const T& v0, const T& v1, const T& v2)
{
const array<T, 3> out = {v0, v1, v2};
return out;
}
} // namespace detail

/// Needed for c++03 compatibility (no uniform initialization available)
template <typename T>
array<T, 3> arr3(const T& v)
{
const array<T, 3> out = {v, v, v};
return out;
}

/// 2D vector
template <typename T>
Expand All @@ -118,8 +123,17 @@ struct CDT_EXPORT V2d
T x; ///< X-coordinate
T y; ///< Y-coordinate

/// Create vector from X and Y coordinates
static V2d make(T x, T y);
/// Vertex with zero coordinates
V2d()
: x(T(0))
, y(T(0))
{}

/// Vertex with given coordinates
V2d(const T x, const T y)
: x(x)
, y(y)
{}
};

/// X- coordinate getter for V2d
Expand Down Expand Up @@ -187,6 +201,12 @@ struct CDT_EXPORT Box2d
V2d<T> min; ///< min box corner
V2d<T> max; ///< max box corner

/// Box that doesn't contain any point
Box2d()
: min(std::numeric_limits<T>::max(), std::numeric_limits<T>::max())
, max(-std::numeric_limits<T>::max(), -std::numeric_limits<T>::max())
{}

/// Envelop box around a point
void envelopPoint(const V2d<T>& p)
{
Expand All @@ -201,54 +221,71 @@ struct CDT_EXPORT Box2d
min.y = std::min(y, min.y);
max.y = std::max(y, max.y);
}
};

/// Bounding box of a collection of custom 2D points given coordinate getters
template <
typename T,
typename TVertexIter,
typename TGetVertexCoordX,
typename TGetVertexCoordY>
Box2d<T> envelopBox(
TVertexIter first,
TVertexIter last,
TGetVertexCoordX getX,
TGetVertexCoordY getY)
{
const T max = std::numeric_limits<T>::max();
Box2d<T> box = {{max, max}, {-max, -max}};
for(; first != last; ++first)
/// Envelop box around a collection of custom points
template <
typename TVertexIter,
typename TGetVertexCoordX,
typename TGetVertexCoordY>
void envelopPoints(
TVertexIter first,
TVertexIter last,
TGetVertexCoordX getX,
TGetVertexCoordY getY)
{
box.envelopPoint(getX(*first), getY(*first));
for(; first != last; ++first)
{
envelopPoint(getX(*first), getY(*first));
}
}
return box;
}

/// Bounding box of a collection of 2D points
template <typename T>
CDT_EXPORT Box2d<T> envelopBox(const std::vector<V2d<T> >& vertices);
/// Envelop box around a collection of points
void envelopPoints(const std::vector<V2d<T> >& vertices)
{
envelopPoints(
vertices.begin(), vertices.end(), getX_V2d<T>, getY_V2d<T>);
}
};

/// Edge connecting two vertices: vertex with smaller index is always first
/// @note: hash Edge is specialized at the bottom
struct CDT_EXPORT Edge
{
/// Constructor
Edge(VertInd iV1, VertInd iV2);
Edge(const VertInd iV1, const VertInd iV2)
: m_vertices(
iV1 < iV2 ? std::make_pair(iV1, iV2) : std::make_pair(iV2, iV1))
{}

/// Equals operator
bool operator==(const Edge& other) const;
bool operator==(const Edge& other) const
{
return m_vertices == other.m_vertices;
}

/// Not-equals operator
bool operator!=(const Edge& other) const;
bool operator!=(const Edge& other) const
{
return !(this->operator==(other));
}

/// V1 getter
VertInd v1() const;
VertInd v1() const
{
return m_vertices.first;
}

/// V2 getter
VertInd v2() const;
VertInd v2() const
{
return m_vertices.second;
}

/// Edges' vertices
const std::pair<VertInd, VertInd>& verts() const;
const std::pair<VertInd, VertInd>& verts() const
{
return m_vertices;
}

private:
std::pair<VertInd, VertInd> m_vertices;
Expand Down Expand Up @@ -290,30 +327,17 @@ struct CDT_EXPORT Triangle
VerticesArr3 vertices; ///< triangle's three vertices
NeighborsArr3 neighbors; ///< triangle's three neighbors

/**
* Factory method
* @note needed for c++03 compatibility (no uniform initialization
* available)
*/
static Triangle
make(const array<VertInd, 3>& vertices, const array<TriInd, 3>& neighbors)
{
const Triangle t = {vertices, neighbors};
return t;
}
/// Triangle with no vertices and no neighbors
Triangle()
: vertices(arr3(noVertex))
, neighbors(arr3(noNeighbor))
{}

/**
* Factory method for creating uninitialized triangle
* @note needed for c++03 compatibility (no uniform initialization
* available)
*/
static Triangle uninitialized()
{
const Triangle t = {
detail::arr3(noVertex, noVertex, noVertex),
detail::arr3(noNeighbor, noNeighbor, noNeighbor)};
return t;
}
/// Triangle with given vertices and neighbors
Triangle(const VerticesArr3& vertices, const NeighborsArr3& neighbors)
: vertices(vertices)
, neighbors(neighbors)
{}

/// Next triangle adjacent to a vertex (clockwise)
/// @returns pair of next triangle and the other vertex of a common edge
Expand Down Expand Up @@ -343,6 +367,7 @@ struct CDT_EXPORT Triangle
return std::make_pair(neighbors[1], vertices[1]);
}

/// Check if triangle contains a vertex
bool containsVertex(const VertInd i) const
{
return std::find(vertices.begin(), vertices.end(), i) != vertices.end();
Expand Down Expand Up @@ -487,6 +512,7 @@ namespace std
namespace boost
#endif
{

#ifdef CDT_USE_STRONG_TYPING

/// Vertex index hasher
Expand Down Expand Up @@ -536,16 +562,13 @@ struct hash<CDT::Edge>

static std::size_t hashEdge(const CDT::Edge& e)
{
const std::pair<CDT::VertInd, CDT::VertInd>& vv = e.verts();
std::size_t seed1(0);
hashCombine(seed1, vv.first);
hashCombine(seed1, vv.second);
std::size_t seed2(0);
hashCombine(seed2, vv.second);
hashCombine(seed2, vv.first);
return std::min(seed1, seed2);
std::size_t seed(0);
hashCombine(seed, e.v1());
hashCombine(seed, e.v2());
return seed;
}
};

} // namespace std/boost

#endif // header guard
56 changes: 0 additions & 56 deletions CDT/include/CDTUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,62 +16,6 @@
namespace CDT
{

//*****************************************************************************
// V2d
//*****************************************************************************
template <typename T>
V2d<T> V2d<T>::make(const T x, const T y)
{
V2d<T> out = {x, y};
return out;
}

//*****************************************************************************
// Box2d
//*****************************************************************************
template <typename T>
Box2d<T> envelopBox(const std::vector<V2d<T> >& vertices)
{
return envelopBox<T>(
vertices.begin(), vertices.end(), getX_V2d<T>, getY_V2d<T>);
}

//*****************************************************************************
// Edge
//*****************************************************************************
CDT_INLINE_IF_HEADER_ONLY Edge::Edge(VertInd iV1, VertInd iV2)
: m_vertices(
iV1 < iV2 ? std::make_pair(iV1, iV2) : std::make_pair(iV2, iV1))
{}

CDT_INLINE_IF_HEADER_ONLY bool Edge::operator==(const Edge& other) const
{
return m_vertices == other.m_vertices;
}

CDT_INLINE_IF_HEADER_ONLY bool Edge::operator!=(const Edge& other) const
{
return !(this->operator==(other));
}

CDT_INLINE_IF_HEADER_ONLY VertInd Edge::v1() const
{
return m_vertices.first;
}

CDT_INLINE_IF_HEADER_ONLY VertInd Edge::v2() const
{
return m_vertices.second;
}

CDT_INLINE_IF_HEADER_ONLY const std::pair<VertInd, VertInd>& Edge::verts() const
{
return m_vertices;
}

//*****************************************************************************
// Utility functions
//*****************************************************************************
CDT_INLINE_IF_HEADER_ONLY Index ccw(Index i)
{
return Index((i + 1) % 3);
Expand Down
10 changes: 4 additions & 6 deletions CDT/include/KDTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ class KDTree
/// Default constructor
KDTree()
: m_rootDir(NodeSplitDirection::X)
, m_min(point_type::make(
, m_min(point_type(
-std::numeric_limits<coord_type>::max(),
-std::numeric_limits<coord_type>::max()))
, m_max(point_type::make(
, m_max(point_type(
std::numeric_limits<coord_type>::max(),
std::numeric_limits<coord_type>::max()))
, m_size(0)
Expand Down Expand Up @@ -349,10 +349,8 @@ class KDTree
for(pd_cit it = data.begin(); it != data.end(); ++it)
{
const point_type& p = points[*it];
m_min = point_type::make(
std::min(m_min.x, p.x), std::min(m_min.y, p.y));
m_max = point_type::make(
std::max(m_max.x, p.x), std::max(m_max.y, p.y));
m_min = point_type(std::min(m_min.x, p.x), std::min(m_min.y, p.y));
m_max = point_type(std::max(m_max.x, p.x), std::max(m_max.y, p.y));
}
// Make sure bounding box does not have a zero size by adding padding:
// zero-size bounding box cannot be extended properly
Expand Down
4 changes: 2 additions & 2 deletions CDT/include/LocatorKDTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class LocatorKDTree
typedef typename std::vector<V2d_t>::const_iterator Cit;
for(Cit it = points.begin(); it != points.end(); ++it)
{
min = V2d_t::make(std::min(min.x, it->x), std::min(min.y, it->y));
max = V2d_t::make(std::max(max.x, it->x), std::max(max.y, it->y));
min = V2d_t(std::min(min.x, it->x), std::min(min.y, it->y));
max = V2d_t(std::max(max.x, it->x), std::max(max.y, it->y));
}
m_kdTree = KDTree_t(min, max);
for(VertInd i(0); i < points.size(); ++i)
Expand Down
14 changes: 5 additions & 9 deletions CDT/include/Triangulation.h
Original file line number Diff line number Diff line change
Expand Up @@ -746,10 +746,7 @@ class CDT_EXPORT Triangulation

void insertVertices_AsProvided(VertInd superGeomVertCount);
void insertVertices_Randomized(VertInd superGeomVertCount);
void insertVertices_KDTreeBFS(
VertInd superGeomVertCount,
V2d<T> boxMin,
V2d<T> boxMax);
void insertVertices_KDTreeBFS(VertInd superGeomVertCount, Box2d<T> box);
std::pair<TriInd, TriInd> edgeTriangles(VertInd a, VertInd b) const;
bool hasEdge(VertInd a, VertInd b) const;
void setAdjacentTriangle(const VertInd v, const TriInd t);
Expand Down Expand Up @@ -872,26 +869,25 @@ void Triangulation<T, TNearPointLocator>::insertVertices(
vertices.reserve(capacityVertices);
m_vertTris.reserve(capacityVertices);

const T max = std::numeric_limits<T>::max();
Box2d<T> box = {{max, max}, {-max, -max}};
Box2d<T> box;
if(isFirstTime)
{
box = envelopBox<T>(first, last, getX, getY);
box.envelopPoints(first, last, getX, getY);
addSuperTriangle(box);
}
tryInitNearestPointLocator();
const VertInd nExistingVerts = static_cast<VertInd>(vertices.size());

for(TVertexIter it = first; it != last; ++it)
addNewVertex(V2d<T>::make(getX(*it), getY(*it)), noNeighbor);
addNewVertex(V2d<T>(getX(*it), getY(*it)), noNeighbor);

switch(m_vertexInsertionOrder)
{
case VertexInsertionOrder::AsProvided:
insertVertices_AsProvided(nExistingVerts);
break;
case VertexInsertionOrder::Auto:
isFirstTime ? insertVertices_KDTreeBFS(nExistingVerts, box.min, box.max)
isFirstTime ? insertVertices_KDTreeBFS(nExistingVerts, box)
: insertVertices_Randomized(nExistingVerts);
break;
}
Expand Down
Loading

0 comments on commit cc04653

Please sign in to comment.