#pragma once #include #include #include namespace cgv { namespace media { namespace mesh { /** pure abstract interface to handle callbacks of a streaming mesh */ struct streaming_mesh_callback_handler { /// called when a new vertex is generated virtual void new_vertex(unsigned int vertex_index) = 0; /// announces a new polygon defines by the vertex indices stored in the given vector virtual void new_polygon(const std::vector& vertex_indices) = 0; /// drop the currently first vertex that has the given global vertex index virtual void before_drop_vertex(unsigned int vertex_index) = 0; }; /// class used to perform the marching cubes algorithm template class streaming_mesh { public: /// type of vertex locations typedef cgv::math::fvec pnt_type; /// type of vertex normals typedef cgv::math::fvec vec_type; protected: /// offset used to address vertices in deque int idx_off; /// count the number of faces unsigned int nr_faces; /// store currently used points in deque std::deque pnts; /// store currently used normals in deque std::deque nmls; /// store a pointer to the callback handler streaming_mesh_callback_handler* smcbh; public: /// construct from callback handler streaming_mesh(streaming_mesh_callback_handler* _smcbh = 0) : smcbh(_smcbh), nr_faces(0), idx_off(0) { } /// set a new callback handler void set_callback_handler(streaming_mesh_callback_handler* _smcbh) { smcbh = _smcbh; } /// return the number of vertices dropped from the front, what is used as index offset into a deque unsigned int get_nr_dropped_vertices() const { return idx_off; } /// return the number of vertices unsigned int get_nr_vertices() const { return (unsigned int) pnts.size()+idx_off; } /// return the number of faces unsigned int get_nr_faces() const { return nr_faces; } /// drop the front most vertex from the deque void drop_vertex() { if (pnts.empty()) return; if (smcbh) smcbh->before_drop_vertex(idx_off); pnts.pop_front(); nmls.pop_front(); ++idx_off; } /// drop n vertices from the front of the deque void drop_vertices(unsigned int n) { for (unsigned int i=0; inew_vertex(vi); return vi; } /// construct a new triangle by calling the new polygon method of the callback handler void new_triangle(unsigned int vi, unsigned int vj, unsigned int vk) { static std::vector vis(3); vis[0] = vi; vis[1] = vj; vis[2] = vk; ++nr_faces; if (smcbh) smcbh->new_polygon(vis); } /// construct a new quad by calling the new polygon method of the callback handler void new_quad(unsigned int vi, unsigned int vj, unsigned int vk, unsigned int vl) { static std::vector vis(4); vis[0] = vi; vis[1] = vj; vis[2] = vk; vis[3] = vl; ++nr_faces; if (smcbh) smcbh->new_polygon(vis); } /// construct a new polygon by calling the new polygon method of the callback handler void new_polygon(const std::vector& vertex_indices) { ++nr_faces; if (smcbh) smcbh->new_polygon(vertex_indices); } }; } } }