// file: examples/HalfedgeDS/hds_prog_compact.C #include #include #include #include // Define a new halfedge class. We assume that the Halfedge_handle can // be created from a pointer (e.g. the HalfedgeDS is based here on the // In_place_list or a std::vector with such property) and that halfedges // are allocated in pairs. We encode the opposite pointer in a single bit, // which is stored in the lower bit of the next-pointer. We use the // static member function HDS::halfedge_handle to translate pointer to // handles. template class My_halfedge { public: typedef Refs HDS; typedef My_halfedge Base_base; typedef My_halfedge Base; typedef My_halfedge Self; typedef CGAL::Tag_false Supports_halfedge_prev; typedef CGAL::Tag_true Supports_halfedge_vertex; typedef CGAL::Tag_true Supports_halfedge_face; typedef typename Refs::Vertex_handle Vertex_handle; typedef typename Refs::Vertex_const_handle Vertex_const_handle; typedef typename Refs::Halfedge Halfedge; typedef typename Refs::Halfedge_handle Halfedge_handle; typedef typename Refs::Halfedge_const_handle Halfedge_const_handle; typedef typename Refs::Face_handle Face_handle; typedef typename Refs::Face_const_handle Face_const_handle; private: std::ptrdiff_t nxt; public: My_halfedge() : nxt(0), f( Face_handle()) {} Halfedge_handle opposite() { // Halfedge could be different from My_halfedge (e.g. pointer for // linked list). Get proper handle from 'this' pointer first, do // pointer arithmetic, then convert pointer back to handle again. Halfedge_handle h = HDS::halfedge_handle(this); // proper handle if ( nxt & 1) return HDS::halfedge_handle( &* h + 1); return HDS::halfedge_handle( &* h - 1); } Halfedge_const_handle opposite() const { // same as above Halfedge_const_handle h = HDS::halfedge_handle(this); // proper handle if ( nxt & 1) return HDS::halfedge_handle( &* h + 1); return HDS::halfedge_handle( &* h - 1); } Halfedge_handle next() { return HDS::halfedge_handle((Halfedge*)(nxt & (~ std::ptrdiff_t(1)))); } Halfedge_const_handle next() const { return HDS::halfedge_handle((const Halfedge*) (nxt & (~ std::ptrdiff_t(1)))); } void set_opposite( Halfedge_handle h) { CGAL_precondition(( &* h - 1 == &* HDS::halfedge_handle(this)) || ( &* h + 1 == &* HDS::halfedge_handle(this))); if ( &* h - 1 == &* HDS::halfedge_handle(this)) nxt |= 1; else nxt &= (~ std::ptrdiff_t(1)); } void set_next( Halfedge_handle h) { CGAL_precondition( ((std::ptrdiff_t)(&*h) & 1) == 0); nxt = ((std::ptrdiff_t)(&*h)) | (nxt & 1); } private: // Support for the Vertex_handle. Vertex_handle v; public: // the incident vertex. Vertex_handle vertex() { return v; } Vertex_const_handle vertex() const { return v; } void set_vertex( Vertex_handle w) { v = w; } private: Face_handle f; public: Face_handle face() { return f; } Face_const_handle face() const { return f; } void set_face( Face_handle g) { f = g; } bool is_border() const { return f == Face_handle(); } }; // Replace halfedge in the default items type. struct My_items : public CGAL::HalfedgeDS_items_2 { template struct Halfedge_wrapper { typedef My_halfedge Halfedge; }; }; struct Traits { typedef int Point_2; }; #ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM typedef CGAL::HalfedgeDS_vector HDS; #else typedef CGAL::HalfedgeDS_vector::HDS HDS; #endif typedef CGAL::HalfedgeDS_decorator Decorator; int main() { HDS hds(1,2,2); Decorator decorator(hds); decorator.create_loop(); CGAL_assertion( decorator.is_valid()); return 0; }