Skip to content

Commit

Permalink
[#27] QHull DOD refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
ilia-glushchenko committed Nov 24, 2018
1 parent 640b830 commit f079a26
Show file tree
Hide file tree
Showing 9 changed files with 670 additions and 211 deletions.
1 change: 0 additions & 1 deletion Epona/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ set(EPONA_SOURCES
sources/Analysis.cpp
sources/HalfEdgeDataStructure.cpp
sources/HyperPlane.cpp
sources/JacobiEigenvalue.cpp
)

if (MSVC)
Expand Down
14 changes: 14 additions & 0 deletions Epona/include/Epona/Analysis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#ifndef EPONA_HPP
#define EPONA_HPP

#include <Epona/FloatingPoint.hpp>
#include <Epona/HyperPlane.hpp>

#define GLM_ENABLE_EXPERIMENTAL
Expand Down Expand Up @@ -373,6 +374,19 @@ float LineSegmentPointDistance(
* @return barycentric coordinates
*/
glm::vec3 CalculateBarycentricCoordinates(glm::vec3 p, glm::vec3 a, glm::vec3 b, glm::vec3 c);

/*
* @brief Calculate area of the triangle and returns true if area is equal to zero
*
* @param a triangle's point
* @param b triangle's point
* @param c triangle's point
* @return if points are on the same line
*/
inline bool OneLine(glm::vec3 a, glm::vec3 b, glm::vec3 c)
{
return epona::fp::IsZero((a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y)) / 2.f);
}
} // namespace epona

#endif // EPONA_HPP
151 changes: 117 additions & 34 deletions Epona/include/Epona/HalfEdgeDataStructure.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/*
* Copyright (C) 2017 by Godlike
* Copyright (C) 2018 by Godlike
* This code is licensed under the MIT license (MIT)
* (http://opensource.org/licenses/MIT)
*/
#ifndef EPONA_HEDS_HPP
#define EPONA_HEDS_HPP

#include <Epona/HyperPlane.hpp>
#include <iterator>
#include <unordered_map>
#include <list>
Expand All @@ -21,10 +22,38 @@ class HalfEdgeDataStructure
struct HalfEdge;
class Face;

using Faces = std::list<Face>;
using HalfEdges = std::list<HalfEdge>;
using face_iterator = Faces::iterator;
using const_face_iterator = Faces::const_iterator;
using face_iterator = std::list<Face>::iterator;
using const_face_iterator = std::list<Face>::const_iterator;

HalfEdgeDataStructure() = default;

HalfEdgeDataStructure(HalfEdgeDataStructure const&) = delete;

HalfEdgeDataStructure& operator=(HalfEdgeDataStructure const& heds) = delete;

HalfEdgeDataStructure(HalfEdgeDataStructure&& heds)
{
m_halfEdgeList = std::move(heds.m_halfEdgeList);
m_halfEdgePointerIteratorMap = std::move(heds.m_halfEdgePointerIteratorMap);
m_halfEdgeVerticesIteratorMap = std::move(heds.m_halfEdgeVerticesIteratorMap);

m_facesList = std::move(heds.m_facesList);
m_faceIteratorMap = std::move(heds.m_faceIteratorMap);
m_faceVerticesIteratorMap = std::move(heds.m_faceVerticesIteratorMap);
}

HalfEdgeDataStructure& operator=(HalfEdgeDataStructure&& heds)
{
m_halfEdgeList = std::move(heds.m_halfEdgeList);
m_halfEdgePointerIteratorMap = std::move(heds.m_halfEdgePointerIteratorMap);
m_halfEdgeVerticesIteratorMap = std::move(heds.m_halfEdgeVerticesIteratorMap);

m_facesList = std::move(heds.m_facesList);
m_faceIteratorMap = std::move(heds.m_faceIteratorMap);
m_faceVerticesIteratorMap = std::move(heds.m_faceVerticesIteratorMap);

return *this;
}

/**
* @brief HEDS Face data container
Expand All @@ -51,7 +80,7 @@ class HalfEdgeDataStructure
* Under the hood iterates along the inner half-edges of the face.
* @tparam HalfEdgeType half-edge type
*/
template <typename HalfEdgeType>
template < typename HalfEdgeType = HalfEdge >
class HalfEdgeCirculator : public std::iterator<std::bidirectional_iterator_tag, HalfEdgeType>
{
public:
Expand All @@ -60,7 +89,7 @@ class HalfEdgeDataStructure
* @param halfEdge
*/
explicit HalfEdgeCirculator(HalfEdgeType& halfEdge)
: m_current(&halfEdge)
: m_currentHalfEdge(&halfEdge)
{
}

Expand All @@ -70,7 +99,7 @@ class HalfEdgeDataStructure
*/
HalfEdgeType& operator*() const
{
return *m_current;
return *m_currentHalfEdge;
}

/**
Expand All @@ -79,7 +108,7 @@ class HalfEdgeDataStructure
*/
HalfEdgeType* operator->() const
{
return m_current;
return m_currentHalfEdge;
}

/**
Expand All @@ -88,7 +117,7 @@ class HalfEdgeDataStructure
*/
HalfEdgeCirculator& operator++()
{
m_current = m_current->next;
m_currentHalfEdge = m_currentHalfEdge->next;
return *this;
}

Expand All @@ -109,7 +138,7 @@ class HalfEdgeDataStructure
*/
HalfEdgeCirculator& operator--()
{
m_current = m_current->prev;
m_currentHalfEdge = m_currentHalfEdge->prev;
return *this;
}

Expand All @@ -131,7 +160,7 @@ class HalfEdgeDataStructure
*/
bool operator==(HalfEdgeCirculator const& other) const
{
return m_current == other.m_current;
return m_currentHalfEdge == other.m_currentHalfEdge;
}

/**
Expand All @@ -151,7 +180,7 @@ class HalfEdgeDataStructure
*/
friend void swap(HalfEdgeCirculator& lhs, HalfEdgeCirculator& rhs) noexcept
{
std::swap(lhs.m_current, rhs.m_current);
std::swap(lhs.m_currentHalfEdge, rhs.m_currentHalfEdge);
}

/**
Expand All @@ -163,7 +192,7 @@ class HalfEdgeDataStructure
}

private:
HalfEdgeType* m_current;
HalfEdgeType* m_currentHalfEdge;
};

/**
Expand All @@ -176,7 +205,7 @@ class HalfEdgeDataStructure
* Access to adjacent faces is performed via twin half-edge.
* @tparam FaceType face type
*/
template <typename FaceType>
template < typename FaceType = Face>
class AdjacentFaceCirculator : public std::iterator<std::bidirectional_iterator_tag, FaceType>
{
public:
Expand All @@ -185,7 +214,7 @@ class HalfEdgeDataStructure
* @param[in] halfEdge a half-edge object
*/
explicit AdjacentFaceCirculator(HalfEdge& halfEdge)
: m_current(&halfEdge)
: m_currentHalfEdge(&halfEdge)
{
}

Expand All @@ -195,7 +224,7 @@ class HalfEdgeDataStructure
*/
FaceType& operator*() const
{
return *m_current->twin->face;
return *m_currentHalfEdge->twin->face;
}

/**
Expand All @@ -204,7 +233,7 @@ class HalfEdgeDataStructure
*/
FaceType* operator->() const
{
return m_current->twin->face;
return m_currentHalfEdge->twin->face;
}

/**
Expand All @@ -213,7 +242,7 @@ class HalfEdgeDataStructure
*/
AdjacentFaceCirculator& operator++()
{
m_current = m_current->next;
m_currentHalfEdge = m_currentHalfEdge->next;
return *this;
}

Expand All @@ -234,7 +263,7 @@ class HalfEdgeDataStructure
*/
AdjacentFaceCirculator& operator--()
{
m_current = m_current->prev;
m_currentHalfEdge = m_currentHalfEdge->prev;
return *this;
}

Expand All @@ -256,7 +285,7 @@ class HalfEdgeDataStructure
*/
bool operator==(AdjacentFaceCirculator const& other) const
{
return m_current == other.m_current;
return m_currentHalfEdge == other.m_currentHalfEdge;
}

/**
Expand All @@ -276,7 +305,7 @@ class HalfEdgeDataStructure
*/
friend void swap(AdjacentFaceCirculator& lhs, AdjacentFaceCirculator& rhs) noexcept
{
std::swap(lhs.m_current, lhs.m_current);
std::swap(lhs.m_currentHalfEdge, lhs.m_currentHalfEdge);
}

/**
Expand All @@ -286,9 +315,14 @@ class HalfEdgeDataStructure
{
return AdjacentFaceCirculator<FaceType const>(*this);
}

operator HalfEdge*() const
{
return m_currentHalfEdge;
}

private:
HalfEdge* m_current;
HalfEdge* m_currentHalfEdge;
};

/**
Expand Down Expand Up @@ -321,6 +355,12 @@ class HalfEdgeDataStructure
*/
const_face_iterator GetAdjacentFaceIterator() const;

//! Stores face hyperplane
HyperPlane hyperPlane;

//! Stores face index
uint32_t index;

private:
HalfEdge* m_halfEdge;
};
Expand Down Expand Up @@ -360,13 +400,48 @@ class HalfEdgeDataStructure
uint64_t vertexIndex;
};

/**
* @brief Inserts face into the current data structure
* @param[in] a vertex index
* @param[in] b vertex index
* @param[in] c vertex index
*/
void MakeFace(uint64_t a, uint64_t b, uint64_t c)
{
MakeFace(a, b, c, {}, 0);
}

/**
* @brief Inserts face into the current data structure
* @param[in] a vertex index
* @param[in] b vertex index
* @param[in] c vertex index
* @param a vertex index
* @param b vertex index
* @param c vertex index
* @param hp hyperplane containing input vertices
* @param index outside face index
*/
void MakeFace(uint64_t a, uint64_t b, uint64_t c);
void MakeFace(uint64_t a, uint64_t b, uint64_t c, HyperPlane hp, uint32_t index);

/**
* @brief Inserts face into the current data structure
* @type T array-like type with overaloded operator[]
* @param index face indices array of size 3
*/
template < typename T >
decltype(auto) GetFace(T index)
{
return GetFace(index[0], index[1], index[2]);
}

/**
* @brief Inserts face into the current data structure
* @type T array-like type with overaloded operator[]
* @param index face indices array of size 3
*/
template < typename T >
decltype(auto) GetFace(T index) const
{
return GetFace(index[0], index[1], index[2]);
}

/**
* @brief Returns a face iterator
Expand Down Expand Up @@ -429,20 +504,20 @@ class HalfEdgeDataStructure
bool operator==(HalfEdgeVertices const& other) const;
};

HalfEdges m_halfEdgeList;
std::list<HalfEdge> m_halfEdgeList;
std::unordered_map<
HalfEdge const*, HalfEdges::iterator
HalfEdge const*, std::list<HalfEdge>::iterator
> m_halfEdgePointerIteratorMap;
std::unordered_map<
HalfEdgeVertices, HalfEdges::iterator, HalfEdgeVertices::Hasher
HalfEdgeVertices, std::list<HalfEdge>::iterator, HalfEdgeVertices::Hasher
> m_halfEdgeVerticesIteratorMap;

Faces m_facesList;
std::list<Face> m_facesList;
std::unordered_map<
Face const*, Faces::iterator
Face const*, std::list<Face>::iterator
> m_faceIteratorMap;
std::unordered_map<
FaceVertices, Faces::iterator, FaceVertices::Hasher
FaceVertices, std::list<Face>::iterator, FaceVertices::Hasher
> m_faceVerticesIteratorMap;

/**
Expand All @@ -455,12 +530,20 @@ class HalfEdgeDataStructure
* @param[in] vertexIndexTo end edge vertex index
*/
void IntializeHalfEdge(
HalfEdges::iterator he,
std::list<HalfEdge>::iterator he,
HalfEdge* next, HalfEdge* prev,
Face* face,
uint64_t vertexIndexFrom,
uint64_t vertexIndexTo
);
};

template < typename T >
std::tuple<uint64_t, uint64_t> GetRidge(HalfEdgeDataStructure::face_iterator it)
{


return {};
}
} // namespace epona
#endif // EPONA_HEDS_HPP
Loading

0 comments on commit f079a26

Please sign in to comment.