diff --git a/libs/cg/include/psemek/cg/dcel.hpp b/libs/cg/include/psemek/cg/dcel.hpp index 825ac312..d987a78d 100644 --- a/libs/cg/include/psemek/cg/dcel.hpp +++ b/libs/cg/include/psemek/cg/dcel.hpp @@ -107,13 +107,14 @@ namespace psemek::cg std::vector edges; std::vector faces; - // TODO: const handles - // TODO: iteration over handles struct point_handle; + struct point_handle_const; struct edge_handle; + struct edge_handle_const; struct face_handle; + struct face_handle_const; struct point_handle : detail::handle_base { @@ -123,7 +124,7 @@ namespace psemek::cg edge_handle edge() const; - void edge(edge_handle h); + void edge(edge_handle h) const; protected: point_rec & get() const @@ -134,6 +135,23 @@ namespace psemek::cg } }; + struct point_handle_const : detail::handle_base + { + using detail::handle_base::handle_base; + + Point const & data() const; + + edge_handle_const edge() const; + + protected: + point_rec const & get() const + { + assert(this->owner_ != nullptr); + assert(this->i_ < this->owner_->points.size()); + return this->owner_->points[this->i_]; + } + }; + struct edge_handle : detail::handle_base { using detail::handle_base::handle_base; @@ -145,10 +163,10 @@ namespace psemek::cg edge_handle twin() const; face_handle face() const; - void origin(point_handle h); - void next(edge_handle h); - void twin(edge_handle h); - void face(face_handle h); + void origin(point_handle h) const; + void next(edge_handle h) const; + void twin(edge_handle h) const; + void face(face_handle h) const; protected: edge_rec & get() const @@ -159,6 +177,26 @@ namespace psemek::cg } }; + struct edge_handle_const : detail::handle_base + { + using detail::handle_base::handle_base; + + Edge const & data() const; + + point_handle_const origin() const; + edge_handle_const next() const; + edge_handle_const twin() const; + face_handle_const face() const; + + protected: + edge_rec const & get() const + { + assert(this->owner_ != nullptr); + assert(this->i_ < this->owner_->edges.size()); + return this->owner_->edges[this->i_]; + } + }; + struct face_handle : detail::handle_base { using detail::handle_base::handle_base; @@ -167,7 +205,7 @@ namespace psemek::cg edge_handle edge() const; - void edge(edge_handle h); + void edge(edge_handle h) const; protected: face_rec & get() const @@ -178,6 +216,23 @@ namespace psemek::cg } }; + struct face_handle_const : detail::handle_base + { + using detail::handle_base::handle_base; + + Face const & data() const; + + edge_handle_const edge() const; + + protected: + face_rec const & get() const + { + assert(this->owner_ != nullptr); + assert(this->i_ < this->owner_->faces.size()); + return this->owner_->faces[this->i_]; + } + }; + point_handle point(Index i) { return {this, i}; @@ -193,6 +248,21 @@ namespace psemek::cg return {this, i}; } + point_handle_const point(Index i) const + { + return {this, i}; + } + + edge_handle_const edge(Index i) const + { + return {this, i}; + } + + face_handle_const face(Index i) const + { + return {this, i}; + } + point_handle push_point(Point data = {}) { auto i = static_cast(points.size()); @@ -315,11 +385,23 @@ namespace psemek::cg } template - void dcel::point_handle::edge(edge_handle h) + void dcel::point_handle::edge(edge_handle h) const { get().edge = h.index(); } + template + Point const & dcel::point_handle_const::data() const + { + return get().data(); + } + + template + typename dcel::edge_handle_const dcel::point_handle_const::edge() const + { + return edge_handle_const{this->owner_, get().edge}; + } + template Edge & dcel::edge_handle::data() const { @@ -351,29 +433,59 @@ namespace psemek::cg } template - void dcel::edge_handle::origin(point_handle h) + void dcel::edge_handle::origin(point_handle h) const { get().origin = h.index(); } template - void dcel::edge_handle::next(edge_handle h) + void dcel::edge_handle::next(edge_handle h) const { get().next = h.index(); } template - void dcel::edge_handle::twin(edge_handle h) + void dcel::edge_handle::twin(edge_handle h) const { get().twin = h.index(); } template - void dcel::edge_handle::face(face_handle h) + void dcel::edge_handle::face(face_handle h) const { get().face = h.index(); } + template + Edge const & dcel::edge_handle_const::data() const + { + return get().data(); + } + + template + typename dcel::point_handle_const dcel::edge_handle_const::origin() const + { + return point_handle_const{this->owner_, get().origin}; + } + + template + typename dcel::edge_handle_const dcel::edge_handle_const::next() const + { + return edge_handle_const{this->owner_, get().next}; + } + + template + typename dcel::edge_handle_const dcel::edge_handle_const::twin() const + { + return edge_handle_const{this->owner_, get().twin}; + } + + template + typename dcel::face_handle_const dcel::edge_handle_const::face() const + { + return face_handle_const{this->owner_, get().face}; + } + template Face & dcel::face_handle::data() const { @@ -387,11 +499,23 @@ namespace psemek::cg } template - void dcel::face_handle::edge(edge_handle h) + void dcel::face_handle::edge(edge_handle h) const { get().edge = h.index(); } + template + Face const & dcel::face_handle_const::data() const + { + return get().data(); + } + + template + typename dcel::edge_handle_const dcel::face_handle_const::edge() const + { + return edge_handle_const{this->owner_, get().edge}; + } + template < typename Point2, typename Edge2 = util::empty, typename Face2 = util::empty, typename Index2 = std::size_t, typename Point, typename Edge, typename Face, typename Index,