mirror of https://github.com/CGAL/cgal
106 lines
4.2 KiB
C++
106 lines
4.2 KiB
C++
#include <CGAL/HalfedgeDS_items_2.h>
|
|
#include <CGAL/HalfedgeDS_vector.h>
|
|
#include <CGAL/HalfedgeDS_decorator.h>
|
|
#include <cstddef>
|
|
#include <cassert>
|
|
|
|
// 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 Refs>
|
|
class My_halfedge {
|
|
public:
|
|
typedef Refs HDS;
|
|
typedef My_halfedge<Refs> Base_base;
|
|
typedef My_halfedge<Refs> Base;
|
|
typedef My_halfedge<Refs> 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) {
|
|
assert(( &* 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) {
|
|
assert( ((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 <class Refs, class Traits>
|
|
struct Halfedge_wrapper {
|
|
typedef My_halfedge<Refs> Halfedge;
|
|
};
|
|
};
|
|
|
|
struct Traits { typedef int Point_2; };
|
|
typedef CGAL::HalfedgeDS_vector<Traits, My_items> HDS;
|
|
typedef CGAL::HalfedgeDS_decorator<HDS> Decorator;
|
|
|
|
int main() {
|
|
HDS hds(1,2,2);
|
|
Decorator decorator(hds);
|
|
decorator.create_loop();
|
|
assert( decorator.is_valid());
|
|
return 0;
|
|
}
|