/*===========================================================================*\ * * * OpenMesh * * Copyright (c) 2001-2015, RWTH-Aachen University * * Department for Computer Graphics and Multimedia * * All rights reserved. * * www.openmesh.org * * * *---------------------------------------------------------------------------* * This file is part of OpenMesh. * *---------------------------------------------------------------------------* * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted provided that the following conditions * * are met: * * * * 1. Redistributions of source code must retain the above copyright notice, * * this list of conditions and the following disclaimer. * * * * 2. Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * * * 3. Neither the name of the copyright holder nor the names of its * * contributors may be used to endorse or promote products derived from * * this software without specific prior written permission. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * /*===========================================================================*\ /*===========================================================================*\ * * * $Revision$ * * $Date$ * * * \*===========================================================================*/ #ifndef OPENMESH_ATTRIBKERNEL_HH #define OPENMESH_ATTRIBKERNEL_HH //== INCLUDES ================================================================= #include #include #include #include #include //== NAMESPACES =============================================================== namespace OpenMesh { //== CLASS DEFINITION ========================================================= /** \class AttribKernelT AttribKernelT.hh The attribute kernel adds all standard properties to the kernel. Therefore the functions/types defined here provide a subset of the kernel interface as described in Concepts::KernelT. \see Concepts::KernelT */ template class AttribKernelT : public Connectivity { public: //---------------------------------------------------------------- item types typedef MeshItems MeshItemsT; typedef Connectivity ConnectivityT; typedef typename Connectivity::Vertex Vertex; typedef typename Connectivity::Halfedge Halfedge; typedef typename Connectivity::Edge Edge; typedef typename Connectivity::Face Face; typedef typename MeshItems::Point Point; typedef typename MeshItems::Normal Normal; typedef typename MeshItems::Color Color; typedef typename MeshItems::TexCoord1D TexCoord1D; typedef typename MeshItems::TexCoord2D TexCoord2D; typedef typename MeshItems::TexCoord3D TexCoord3D; typedef typename MeshItems::Scalar Scalar; typedef typename MeshItems::TextureIndex TextureIndex; typedef typename MeshItems::VertexData VertexData; typedef typename MeshItems::HalfedgeData HalfedgeData; typedef typename MeshItems::EdgeData EdgeData; typedef typename MeshItems::FaceData FaceData; typedef AttribKernelT AttribKernel; enum Attribs { VAttribs = MeshItems::VAttribs, HAttribs = MeshItems::HAttribs, EAttribs = MeshItems::EAttribs, FAttribs = MeshItems::FAttribs }; typedef VPropHandleT DataVPropHandle; typedef HPropHandleT DataHPropHandle; typedef EPropHandleT DataEPropHandle; typedef FPropHandleT DataFPropHandle; public: //-------------------------------------------------- constructor / destructor AttribKernelT() : refcount_vnormals_(0), refcount_vcolors_(0), refcount_vtexcoords1D_(0), refcount_vtexcoords2D_(0), refcount_vtexcoords3D_(0), refcount_htexcoords1D_(0), refcount_htexcoords2D_(0), refcount_htexcoords3D_(0), refcount_henormals_(0), refcount_hecolors_(0), refcount_ecolors_(0), refcount_fnormals_(0), refcount_fcolors_(0), refcount_ftextureIndex_(0) { this->add_property( points_, "v:points" ); if (VAttribs & Attributes::Normal) request_vertex_normals(); if (VAttribs & Attributes::Color) request_vertex_colors(); if (VAttribs & Attributes::TexCoord1D) request_vertex_texcoords1D(); if (VAttribs & Attributes::TexCoord2D) request_vertex_texcoords2D(); if (VAttribs & Attributes::TexCoord3D) request_vertex_texcoords3D(); if (HAttribs & Attributes::TexCoord1D) request_halfedge_texcoords1D(); if (HAttribs & Attributes::TexCoord2D) request_halfedge_texcoords2D(); if (HAttribs & Attributes::TexCoord3D) request_halfedge_texcoords3D(); if (HAttribs & Attributes::Color) request_halfedge_colors(); if (VAttribs & Attributes::Status) Connectivity::request_vertex_status(); if (HAttribs & Attributes::Status) Connectivity::request_halfedge_status(); if (HAttribs & Attributes::Normal) request_halfedge_normals(); if (EAttribs & Attributes::Status) Connectivity::request_edge_status(); if (EAttribs & Attributes::Color) request_edge_colors(); if (FAttribs & Attributes::Normal) request_face_normals(); if (FAttribs & Attributes::Color) request_face_colors(); if (FAttribs & Attributes::Status) Connectivity::request_face_status(); if (FAttribs & Attributes::TextureIndex) request_face_texture_index(); //FIXME: data properties might actually cost storage even //if there are no data traits?? this->add_property(data_vpph_); this->add_property(data_fpph_); this->add_property(data_hpph_); this->add_property(data_epph_); } virtual ~AttribKernelT() { // should remove properties, but this will be done in // BaseKernel's destructor anyway... } /** Assignment from another mesh of \em another type. \note All that's copied is connectivity and vertex positions. All other information (like e.g. attributes or additional elements from traits classes) is not copied. \note If you want to copy all information, including *custom* properties, use PolyMeshT::operator=() instead. TODO: version which copies standard properties specified by the user */ template void assign(const _AttribKernel& _other) { this->assign_connectivity(_other); for (typename Connectivity::VertexIter v_it = Connectivity::vertices_begin(); v_it != Connectivity::vertices_end(); ++v_it) {//assumes Point constructor supports cast from _AttribKernel::Point set_point(*v_it, (Point)_other.point(*v_it)); } } //-------------------------------------------------------------------- points const Point* points() const { return this->property(points_).data(); } const Point& point(VertexHandle _vh) const { return this->property(points_, _vh); } Point& point(VertexHandle _vh) { return this->property(points_, _vh); } void set_point(VertexHandle _vh, const Point& _p) { this->property(points_, _vh) = _p; } //------------------------------------------------------------ vertex normals const Normal* vertex_normals() const { return this->property(vertex_normals_).data(); } const Normal& normal(VertexHandle _vh) const { return this->property(vertex_normals_, _vh); } void set_normal(VertexHandle _vh, const Normal& _n) { this->property(vertex_normals_, _vh) = _n; } //------------------------------------------------------------- vertex colors const Color* vertex_colors() const { return this->property(vertex_colors_).data(); } const Color& color(VertexHandle _vh) const { return this->property(vertex_colors_, _vh); } void set_color(VertexHandle _vh, const Color& _c) { this->property(vertex_colors_, _vh) = _c; } //------------------------------------------------------- vertex 1D texcoords const TexCoord1D* texcoords1D() const { return this->property(vertex_texcoords1D_).data(); } const TexCoord1D& texcoord1D(VertexHandle _vh) const { return this->property(vertex_texcoords1D_, _vh); } void set_texcoord1D(VertexHandle _vh, const TexCoord1D& _t) { this->property(vertex_texcoords1D_, _vh) = _t; } //------------------------------------------------------- vertex 2D texcoords const TexCoord2D* texcoords2D() const { return this->property(vertex_texcoords2D_).data(); } const TexCoord2D& texcoord2D(VertexHandle _vh) const { return this->property(vertex_texcoords2D_, _vh); } void set_texcoord2D(VertexHandle _vh, const TexCoord2D& _t) { this->property(vertex_texcoords2D_, _vh) = _t; } //------------------------------------------------------- vertex 3D texcoords const TexCoord3D* texcoords3D() const { return this->property(vertex_texcoords3D_).data(); } const TexCoord3D& texcoord3D(VertexHandle _vh) const { return this->property(vertex_texcoords3D_, _vh); } void set_texcoord3D(VertexHandle _vh, const TexCoord3D& _t) { this->property(vertex_texcoords3D_, _vh) = _t; } //.------------------------------------------------------ halfedge 1D texcoords const TexCoord1D* htexcoords1D() const { return this->property(halfedge_texcoords1D_).data(); } const TexCoord1D& texcoord1D(HalfedgeHandle _heh) const { return this->property(halfedge_texcoords1D_, _heh); } void set_texcoord1D(HalfedgeHandle _heh, const TexCoord1D& _t) { this->property(halfedge_texcoords1D_, _heh) = _t; } //------------------------------------------------------- halfedge 2D texcoords const TexCoord2D* htexcoords2D() const { return this->property(halfedge_texcoords2D_).data(); } const TexCoord2D& texcoord2D(HalfedgeHandle _heh) const { return this->property(halfedge_texcoords2D_, _heh); } void set_texcoord2D(HalfedgeHandle _heh, const TexCoord2D& _t) { this->property(halfedge_texcoords2D_, _heh) = _t; } //------------------------------------------------------- halfedge 3D texcoords const TexCoord3D* htexcoords3D() const { return this->property(halfedge_texcoords3D_).data(); } const TexCoord3D& texcoord3D(HalfedgeHandle _heh) const { return this->property(halfedge_texcoords3D_, _heh); } void set_texcoord3D(HalfedgeHandle _heh, const TexCoord3D& _t) { this->property(halfedge_texcoords3D_, _heh) = _t; } //------------------------------------------------------------- edge colors const Color* edge_colors() const { return this->property(edge_colors_).data(); } const Color& color(EdgeHandle _eh) const { return this->property(edge_colors_, _eh); } void set_color(EdgeHandle _eh, const Color& _c) { this->property(edge_colors_, _eh) = _c; } //------------------------------------------------------------- halfedge normals const Normal& normal(HalfedgeHandle _heh) const { return this->property(halfedge_normals_, _heh); } void set_normal(HalfedgeHandle _heh, const Normal& _n) { this->property(halfedge_normals_, _heh) = _n; } //------------------------------------------------------------- halfedge colors const Color* halfedge_colors() const { return this->property(halfedge_colors_).data(); } const Color& color(HalfedgeHandle _heh) const { return this->property(halfedge_colors_, _heh); } void set_color(HalfedgeHandle _heh, const Color& _c) { this->property(halfedge_colors_, _heh) = _c; } //-------------------------------------------------------------- face normals const Normal& normal(FaceHandle _fh) const { return this->property(face_normals_, _fh); } void set_normal(FaceHandle _fh, const Normal& _n) { this->property(face_normals_, _fh) = _n; } //-------------------------------------------------------------- per Face Texture index const TextureIndex& texture_index(FaceHandle _fh) const { return this->property(face_texture_index_, _fh); } void set_texture_index(FaceHandle _fh, const TextureIndex& _t) { this->property(face_texture_index_, _fh) = _t; } //--------------------------------------------------------------- face colors const Color& color(FaceHandle _fh) const { return this->property(face_colors_, _fh); } void set_color(FaceHandle _fh, const Color& _c) { this->property(face_colors_, _fh) = _c; } //------------------------------------------------ request / alloc properties void request_vertex_normals() { if (!refcount_vnormals_++) this->add_property( vertex_normals_, "v:normals" ); } void request_vertex_colors() { if (!refcount_vcolors_++) this->add_property( vertex_colors_, "v:colors" ); } void request_vertex_texcoords1D() { if (!refcount_vtexcoords1D_++) this->add_property( vertex_texcoords1D_, "v:texcoords1D" ); } void request_vertex_texcoords2D() { if (!refcount_vtexcoords2D_++) this->add_property( vertex_texcoords2D_, "v:texcoords2D" ); } void request_vertex_texcoords3D() { if (!refcount_vtexcoords3D_++) this->add_property( vertex_texcoords3D_, "v:texcoords3D" ); } void request_halfedge_texcoords1D() { if (!refcount_htexcoords1D_++) this->add_property( halfedge_texcoords1D_, "h:texcoords1D" ); } void request_halfedge_texcoords2D() { if (!refcount_htexcoords2D_++) this->add_property( halfedge_texcoords2D_, "h:texcoords2D" ); } void request_halfedge_texcoords3D() { if (!refcount_htexcoords3D_++) this->add_property( halfedge_texcoords3D_, "h:texcoords3D" ); } void request_edge_colors() { if (!refcount_ecolors_++) this->add_property( edge_colors_, "e:colors" ); } void request_halfedge_normals() { if (!refcount_henormals_++) this->add_property( halfedge_normals_, "h:normals" ); } void request_halfedge_colors() { if (!refcount_hecolors_++) this->add_property( halfedge_colors_, "h:colors" ); } void request_face_normals() { if (!refcount_fnormals_++) this->add_property( face_normals_, "f:normals" ); } void request_face_colors() { if (!refcount_fcolors_++) this->add_property( face_colors_, "f:colors" ); } void request_face_texture_index() { if (!refcount_ftextureIndex_++) this->add_property( face_texture_index_, "f:textureindex" ); } //------------------------------------------------- release / free properties void release_vertex_normals() { if ((refcount_vnormals_ > 0) && (! --refcount_vnormals_)) this->remove_property(vertex_normals_); } void release_vertex_colors() { if ((refcount_vcolors_ > 0) && (! --refcount_vcolors_)) this->remove_property(vertex_colors_); } void release_vertex_texcoords1D() { if ((refcount_vtexcoords1D_ > 0) && (! --refcount_vtexcoords1D_)) this->remove_property(vertex_texcoords1D_); } void release_vertex_texcoords2D() { if ((refcount_vtexcoords2D_ > 0) && (! --refcount_vtexcoords2D_)) this->remove_property(vertex_texcoords2D_); } void release_vertex_texcoords3D() { if ((refcount_vtexcoords3D_ > 0) && (! --refcount_vtexcoords3D_)) this->remove_property(vertex_texcoords3D_); } void release_halfedge_texcoords1D() { if ((refcount_htexcoords1D_ > 0) && (! --refcount_htexcoords1D_)) this->remove_property(halfedge_texcoords1D_); } void release_halfedge_texcoords2D() { if ((refcount_htexcoords2D_ > 0) && (! --refcount_htexcoords2D_)) this->remove_property(halfedge_texcoords2D_); } void release_halfedge_texcoords3D() { if ((refcount_htexcoords3D_ > 0) && (! --refcount_htexcoords3D_)) this->remove_property(halfedge_texcoords3D_); } void release_edge_colors() { if ((refcount_ecolors_ > 0) && (! --refcount_ecolors_)) this->remove_property(edge_colors_); } void release_halfedge_normals() { if ((refcount_henormals_ > 0) && (! --refcount_henormals_)) this->remove_property(halfedge_normals_); } void release_halfedge_colors() { if ((refcount_hecolors_ > 0) && (! --refcount_hecolors_)) this->remove_property(halfedge_colors_); } void release_face_normals() { if ((refcount_fnormals_ > 0) && (! --refcount_fnormals_)) this->remove_property(face_normals_); } void release_face_colors() { if ((refcount_fcolors_ > 0) && (! --refcount_fcolors_)) this->remove_property(face_colors_); } void release_face_texture_index() { if ((refcount_ftextureIndex_ > 0) && (! --refcount_ftextureIndex_)) this->remove_property(face_texture_index_); } //---------------------------------------------- dynamic check for properties bool has_vertex_normals() const { return vertex_normals_.is_valid(); } bool has_vertex_colors() const { return vertex_colors_.is_valid(); } bool has_vertex_texcoords1D() const { return vertex_texcoords1D_.is_valid(); } bool has_vertex_texcoords2D() const { return vertex_texcoords2D_.is_valid(); } bool has_vertex_texcoords3D() const { return vertex_texcoords3D_.is_valid(); } bool has_halfedge_texcoords1D() const { return halfedge_texcoords1D_.is_valid();} bool has_halfedge_texcoords2D() const { return halfedge_texcoords2D_.is_valid();} bool has_halfedge_texcoords3D() const { return halfedge_texcoords3D_.is_valid();} bool has_edge_colors() const { return edge_colors_.is_valid(); } bool has_halfedge_normals() const { return halfedge_normals_.is_valid(); } bool has_halfedge_colors() const { return halfedge_colors_.is_valid(); } bool has_face_normals() const { return face_normals_.is_valid(); } bool has_face_colors() const { return face_colors_.is_valid(); } bool has_face_texture_index() const { return face_texture_index_.is_valid(); } public: typedef VPropHandleT PointsPropertyHandle; typedef VPropHandleT VertexNormalsPropertyHandle; typedef VPropHandleT VertexColorsPropertyHandle; typedef VPropHandleT VertexTexCoords1DPropertyHandle; typedef VPropHandleT VertexTexCoords2DPropertyHandle; typedef VPropHandleT VertexTexCoords3DPropertyHandle; typedef HPropHandleT HalfedgeTexCoords1DPropertyHandle; typedef HPropHandleT HalfedgeTexCoords2DPropertyHandle; typedef HPropHandleT HalfedgeTexCoords3DPropertyHandle; typedef EPropHandleT EdgeColorsPropertyHandle; typedef HPropHandleT HalfedgeNormalsPropertyHandle; typedef HPropHandleT HalfedgeColorsPropertyHandle; typedef FPropHandleT FaceNormalsPropertyHandle; typedef FPropHandleT FaceColorsPropertyHandle; typedef FPropHandleT FaceTextureIndexPropertyHandle; public: //standard vertex properties PointsPropertyHandle points_pph() const { return points_; } VertexNormalsPropertyHandle vertex_normals_pph() const { return vertex_normals_; } VertexColorsPropertyHandle vertex_colors_pph() const { return vertex_colors_; } VertexTexCoords1DPropertyHandle vertex_texcoords1D_pph() const { return vertex_texcoords1D_; } VertexTexCoords2DPropertyHandle vertex_texcoords2D_pph() const { return vertex_texcoords2D_; } VertexTexCoords3DPropertyHandle vertex_texcoords3D_pph() const { return vertex_texcoords3D_; } //standard halfedge properties HalfedgeTexCoords1DPropertyHandle halfedge_texcoords1D_pph() const { return halfedge_texcoords1D_; } HalfedgeTexCoords2DPropertyHandle halfedge_texcoords2D_pph() const { return halfedge_texcoords2D_; } HalfedgeTexCoords3DPropertyHandle halfedge_texcoords3D_pph() const { return halfedge_texcoords3D_; } // standard edge properties HalfedgeNormalsPropertyHandle halfedge_normals_pph() const { return halfedge_normals_; } // standard edge properties HalfedgeColorsPropertyHandle halfedge_colors_pph() const { return halfedge_colors_; } // standard edge properties EdgeColorsPropertyHandle edge_colors_pph() const { return edge_colors_; } //standard face properties FaceNormalsPropertyHandle face_normals_pph() const { return face_normals_; } FaceColorsPropertyHandle face_colors_pph() const { return face_colors_; } FaceTextureIndexPropertyHandle face_texture_index_pph() const { return face_texture_index_; } VertexData& data(VertexHandle _vh) { return this->property(data_vpph_, _vh); } const VertexData& data(VertexHandle _vh) const { return this->property(data_vpph_, _vh); } FaceData& data(FaceHandle _fh) { return this->property(data_fpph_, _fh); } const FaceData& data(FaceHandle _fh) const { return this->property(data_fpph_, _fh); } EdgeData& data(EdgeHandle _eh) { return this->property(data_epph_, _eh); } const EdgeData& data(EdgeHandle _eh) const { return this->property(data_epph_, _eh); } HalfedgeData& data(HalfedgeHandle _heh) { return this->property(data_hpph_, _heh); } const HalfedgeData& data(HalfedgeHandle _heh) const { return this->property(data_hpph_, _heh); } private: //standard vertex properties PointsPropertyHandle points_; VertexNormalsPropertyHandle vertex_normals_; VertexColorsPropertyHandle vertex_colors_; VertexTexCoords1DPropertyHandle vertex_texcoords1D_; VertexTexCoords2DPropertyHandle vertex_texcoords2D_; VertexTexCoords3DPropertyHandle vertex_texcoords3D_; //standard halfedge properties HalfedgeTexCoords1DPropertyHandle halfedge_texcoords1D_; HalfedgeTexCoords2DPropertyHandle halfedge_texcoords2D_; HalfedgeTexCoords3DPropertyHandle halfedge_texcoords3D_; HalfedgeNormalsPropertyHandle halfedge_normals_; HalfedgeColorsPropertyHandle halfedge_colors_; // standard edge properties EdgeColorsPropertyHandle edge_colors_; //standard face properties FaceNormalsPropertyHandle face_normals_; FaceColorsPropertyHandle face_colors_; FaceTextureIndexPropertyHandle face_texture_index_; //data properties handles DataVPropHandle data_vpph_; DataHPropHandle data_hpph_; DataEPropHandle data_epph_; DataFPropHandle data_fpph_; unsigned int refcount_vnormals_; unsigned int refcount_vcolors_; unsigned int refcount_vtexcoords1D_; unsigned int refcount_vtexcoords2D_; unsigned int refcount_vtexcoords3D_; unsigned int refcount_htexcoords1D_; unsigned int refcount_htexcoords2D_; unsigned int refcount_htexcoords3D_; unsigned int refcount_henormals_; unsigned int refcount_hecolors_; unsigned int refcount_ecolors_; unsigned int refcount_fnormals_; unsigned int refcount_fcolors_; unsigned int refcount_ftextureIndex_; }; //============================================================================= } // namespace OpenMesh //============================================================================= #endif // OPENMESH_ATTRIBKERNEL_HH defined //=============================================================================