/*===========================================================================*\ * * * OpenMesh * * Copyright (C) 2001-2003 by Computer Graphics Group, RWTH Aachen * * www.openmesh.org * * * *---------------------------------------------------------------------------* * * * License * * * * This library is free software; you can redistribute it and/or modify it * * under the terms of the GNU Lesser General Public License as published * * by the Free Software Foundation, version 2.1. * * * * This library is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * \*===========================================================================*/ #ifndef OPENMESH_KERNEL_OSG_ATTRIBKERNEL_HH #define OPENMESH_KENREL_OSG_ATTRIBKERNEL_HH //== INCLUDES ================================================================= #include #include // -------------------- #include #include // -------------------- #include //== NAMESPACES =============================================================== namespace OpenMesh { namespace Kernel_OSG { //== CLASS DEFINITION ========================================================= /// This class adds the standard properties to the mesh type. template class AttribKernelT : public PropertyKernel< typename MeshItems::Face::IsTriangle > { protected: typedef typename MeshItems::Face::IsTriangle IsTriMesh; typedef PropertyKernel< IsTriMesh > Base; typedef typename Base::FPTypesHandle FPTypesHandle; typedef typename Base::FPLengthsHandle FPLengthsHandle; typedef typename Base::FIndicesHandle FIndicesHandle; public: //---------------------------------------------------------------- item types typedef typename MeshItems::Vertex Vertex; typedef typename MeshItems::Halfedge Halfedge; typedef typename MeshItems::Edge Edge; typedef typename MeshItems::Face Face; typedef typename MeshItems::Point Point; typedef typename MeshItems::Normal Normal; typedef typename MeshItems::Color Color; typedef typename MeshItems::TexCoord TexCoord; typedef typename MeshItems::Scalar Scalar; typedef Attributes::StatusInfo StatusInfo; enum Attribs { VAttribs = MeshItems::VAttribs, HAttribs = MeshItems::HAttribs, EAttribs = MeshItems::EAttribs, FAttribs = MeshItems::FAttribs, }; typedef GenProg::Bool2Type<(bool)(HAttribs & Attributes::PrevHalfedge)> HasPrevHalfedge; // typedef typename _t2vp< Point >::prop GeoPositions; typedef typename _t2vn< Normal >::prop GeoNormals; typedef typename _t2vc< Color >::prop GeoColors; typedef typename _t2vtc< TexCoord >::prop GeoTexCoords; // typedef typename Base::GeoPTypes GeoPTypes; // typedef typename Base::GeoPLengths GeoPLengths; // typedef typename Base::GeoIndices GeoIndices; //-------------------------------------------------- constructor / destructor AttribKernelT() : refcount_vnormals_(0), refcount_vcolors_(0), refcount_vtexcoords_(0), refcount_vstatus_(0), refcount_estatus_(0), refcount_hstatus_(0), refcount_fnormals_(0), refcount_fcolors_(0), refcount_fstatus_(0) { points_ = add_vpositions( Point(), "v:points" ); face_types_ = add_fptypes(); face_lengths_ = add_fplengths(); face_indices_ = add_findices( face_types_, face_lengths_); if (VAttribs & Attributes::Normal) request_vertex_normals(); if (VAttribs & Attributes::Color) request_vertex_colors(); if (VAttribs & Attributes::TexCoord) request_vertex_texcoords(); if (VAttribs & Attributes::Status) request_vertex_status(); if (EAttribs & Attributes::Status) request_edge_status(); if (FAttribs & Attributes::Normal) request_face_normals(); if (FAttribs & Attributes::Color) request_face_colors(); if (FAttribs & Attributes::Status) request_face_status(); } ~AttribKernelT() { // should remove properties, but this will be done in // BaseKernel's destructor anyway... } // ------------------------------------------------------- copy & assignement AttribKernelT( const AttribKernelT& _rhs ) : Base( _rhs ) { operator=(_rhs); } AttribKernelT& operator = ( const AttribKernelT& _rhs ) { // remove old properties remove_property(points_); remove_property(vertex_normals_); remove_property(vertex_colors_); remove_property(vertex_texcoords_); remove_property(vertex_status_); remove_property(halfedge_status_); remove_property(edge_status_); remove_property(face_normals_); remove_property(face_colors_); remove_property(face_status_); // parent deep-copies properties BaseKernel::operator=(_rhs); // copy property handles points_ = _rhs.points_; vertex_normals_ = _rhs.vertex_normals_; vertex_colors_ = _rhs.vertex_colors_; vertex_texcoords_ = _rhs.vertex_texcoords_; vertex_status_ = _rhs.vertex_status_; halfedge_status_ = _rhs.halfedge_status_; edge_status_ = _rhs.edge_status_; face_normals_ = _rhs.face_normals_; face_colors_ = _rhs.face_colors_; face_status_ = _rhs.face_status_; // copy ref-counts refcount_vnormals_ = _rhs.refcount_vnormals_; refcount_vcolors_ = _rhs.refcount_vcolors_; refcount_vtexcoords_ = _rhs.refcount_vtexcoords_; refcount_vstatus_ = _rhs.refcount_vstatus_; refcount_hstatus_ = _rhs.refcount_hstatus_; refcount_estatus_ = _rhs.refcount_estatus_; refcount_fnormals_ = _rhs.refcount_fnormals_; refcount_fcolors_ = _rhs.refcount_fcolors_; refcount_fstatus_ = _rhs.refcount_fstatus_; return *this; } //------------------------------------------------------------ osg properties //------------------------------ vertex property typename GeoPositions::property_ptr_t osg_vpositions() { return vpositions(points_).osg_ptr(); } typename GeoNormals::property_ptr_t osg_vnormals() { return vnormals(vertex_normals_).osg_ptr(); } typename GeoColors::property_ptr_t osg_vcolors() { return vcolors(vertex_colors_).osg_ptr(); } typename GeoTexCoords::property_ptr_t osg_vtexcoords() { return vtexcoords(vertex_texcoords_).osg_ptr(); } //------------------------------ face property GeoPTypes::property_ptr_t osg_ptypes() { return fptypes( face_types_ ).osg_ptr(); } GeoPLengths::property_ptr_t osg_plengths() { return fplengths( face_lengths_ ).osg_ptr(); } typename GeoIndices::property_ptr_t osg_indices() { return findices( face_indices_ ).osg_ptr(); } //---------------------------------------- set osg geo property //------------------------------ face property void set_face_types( FaceHandle _fh, GeoPTypes::value_type _t) { fptypes( face_types_, _fh ) = _t; } void set_face_lengths( FaceHandle _fh, GeoPLengths::value_type _l) { fplengths( face_lengths_, _fh ) = _l; } void set_face_indices( FaceHandle _fh, typename GeoIndices::value_type _i) { findices( face_indices_, _fh ) = _i; } //--------------------------------------------------------- set/get properties //---------------------------------------- points const Point* points() const { return vpositions( points_ ).data(); } const Point& point(VertexHandle _vh) const { return vpositions( points_, _vh); } void set_point(VertexHandle _vh, const Point& _p) { vpositions( points_, _vh ) = _p; } //---------------------------------------- vertex normals const Normal* vertex_normals() const { return vnormals(vertex_normals_).data(); } const Normal& normal(VertexHandle _vh) const { return vnormals(vertex_normals_, _vh); } void set_normal(VertexHandle _vh, const Normal& _n) { vnormals(vertex_normals_, _vh) = _n; } //---------------------------------------- vertex colors const Color* vertex_colors() const { return vcolors(vertex_colors_).data(); } const Color& color(VertexHandle _vh) const { return vcolors(vertex_colors_, _vh); } void set_color(VertexHandle _vh, const Color& _c) { vcolors(vertex_colors_, _vh) = _c; } //---------------------------------------- vertex texcoords const TexCoord* texcoords() const { return vtexcoords(vertex_texcoords_).data(); } const TexCoord& texcoord(VertexHandle _vh) const { return vtexcoords(vertex_texcoords_, _vh); } void set_texcoord(VertexHandle _vh, const TexCoord& _t) { vtexcoords(vertex_texcoords_, _vh) = _t; } //---------------------------------------- vertex status const StatusInfo& status(VertexHandle _vh) const { return property(vertex_status_, _vh); } StatusInfo& status(VertexHandle _vh) { return property(vertex_status_, _vh); } //---------------------------------------- edge status const StatusInfo& status(HalfedgeHandle _eh) const { return property(halfedge_status_, _eh); } StatusInfo& status(HalfedgeHandle _eh) { return property(halfedge_status_, _eh); } //---------------------------------------- edge status const StatusInfo& status(EdgeHandle _eh) const { return property(edge_status_, _eh); } StatusInfo& status(EdgeHandle _eh) { return property(edge_status_, _eh); } //---------------------------------------- face status const StatusInfo& status(FaceHandle _fh) const { return property(face_status_, _fh); } StatusInfo& status(FaceHandle _fh) { return property(face_status_, _fh); } //---------------------------------------- face normals const Normal& normal(FaceHandle _fh) const { return property(face_normals_, _fh); } void set_normal(FaceHandle _fh, const Normal& _n) { property(face_normals_, _fh) = _n; } //---------------------------------------- face colors const Color& color(FaceHandle _fh) const { return property(face_colors_, _fh); } void set_color(FaceHandle _fh, const Color& _c) { property(face_colors_, _fh) = _c; } //------------------------------------------------ request / alloc properties void request_vertex_normals() { if (!refcount_vnormals_++) vertex_normals_ = add_vnormals( Normal(), "v:normals" ); } void request_vertex_colors() { if (!refcount_vcolors_++) vertex_colors_ = add_vcolors( Color(), "v:colors" ); } void request_vertex_texcoords() { if (!refcount_vtexcoords_++) vertex_texcoords_ = add_vtexcoords( TexCoord(), "v:texcoords" ); } void request_vertex_status() { if (!refcount_vstatus_++) add_property( vertex_status_, "v:status" ); } void request_halfedge_status() { if (!refcount_hstatus_++) add_property( halfedge_status_, "h:status" ); } void request_edge_status() { if (!refcount_estatus_++) add_property( edge_status_, "e:status" ); } void request_face_normals() { if (!refcount_fnormals_++) add_property( face_normals_, "f:normals" ); } void request_face_colors() { if (!refcount_fcolors_++) add_property( face_colors_, "f:colors" ); } void request_face_status() { if (!refcount_fstatus_++) add_property( face_status_, "f:status" ); } //------------------------------------------------- release / free properties void release_vertex_normals() { if ((refcount_vnormals_ > 0) && (! --refcount_vnormals_)) remove_property(vertex_normals_); } void release_vertex_colors() { if ((refcount_vcolors_ > 0) && (! --refcount_vcolors_)) remove_property(vertex_colors_); } void release_vertex_texcoords() { if ((refcount_vtexcoords_ > 0) && (! --refcount_vtexcoords_)) remove_property(vertex_texcoords_); } void release_vertex_status() { if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_)) remove_property(vertex_status_); } void release_halfedge_status() { if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_)) remove_property(halfedge_status_); } void release_edge_status() { if ((refcount_estatus_ > 0) && (! --refcount_estatus_)) remove_property(edge_status_); } void release_face_normals() { if ((refcount_fnormals_ > 0) && (! --refcount_fnormals_)) remove_property(face_normals_); } void release_face_colors() { if ((refcount_fcolors_ > 0) && (! --refcount_fcolors_)) remove_property(face_colors_); } void release_face_status() { if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_)) remove_property(face_status_); } //----------------------------------------------- static check for properties typedef GenProg::Bool2Type<(bool)(VAttribs & Attributes::Normal)> HasVertexNormals; typedef GenProg::Bool2Type<(bool)(VAttribs & Attributes::Color)> HasVertexColors; typedef GenProg::Bool2Type<(bool)(VAttribs & Attributes::TexCoord)> HasVertexTexCoords; typedef GenProg::Bool2Type<(bool)(VAttribs & Attributes::Status)> HasVertexStatus; typedef GenProg::Bool2Type<(bool)(HAttribs & Attributes::PrevHalfedge)> HasPrevHalfedge; typedef GenProg::Bool2Type<(bool)(HAttribs & Attributes::Status)> HasHalfedgeStatus; typedef GenProg::Bool2Type<(bool)(EAttribs & Attributes::Status)> HasEdgeStatus; typedef GenProg::Bool2Type<(bool)(FAttribs & Attributes::Normal)> HasFaceNormals; typedef GenProg::Bool2Type<(bool)(FAttribs & Attributes::Color)> HasFaceColors; typedef GenProg::Bool2Type<(bool)(FAttribs & Attributes::Status)> HasFaceStatus; //---------------------------------------------- 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_texcoords() const { return vertex_texcoords_.is_valid(); } bool has_vertex_status() const { return vertex_status_.is_valid(); } bool has_edge_status() const { return edge_status_.is_valid(); } bool has_halfedge_status() const { return halfedge_status_.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_status() const { return face_status_.is_valid(); } static bool has_prev_halfedge() { return (HAttribs & Attributes::PrevHalfedge); } public: osg::GeometryPtr createGeometryPtr() { using namespace osg; GeometryPtr geo=Geometry::create(); return bind(geo) ? geo : NullFC; } // create new geometry core from mesh bool bind( osg::GeometryPtr& _geo ) { using namespace osg; int Mask = Geometry::TypesFieldMask | Geometry::LengthsFieldMask | Geometry::IndicesFieldMask | Geometry::PositionsFieldMask; if ( has_vertex_colors() ) Mask |= Geometry::ColorsFieldMask; if ( has_vertex_normals() ) Mask |= Geometry::NormalsFieldMask; if ( has_vertex_texcoords() ) Mask |= Geometry::TexCoordsFieldMask; // std::clog << "#ptypes : " << osg_ptypes()->getSize() << std::endl; // std::clog << "#plengths : " << osg_plengths()->getSize() << std::endl; // std::clog << "#indices : " << osg_indices()->getSize() << std::endl; // std::clog << "#points : " << osg_vpositions()->getSize() << std::endl; beginEditCP( _geo, Mask ); { addRefCP( osg_ptypes() ); _geo->setTypes ( osg_ptypes() ); addRefCP( osg_plengths() ); _geo->setLengths ( osg_plengths() ); addRefCP( osg_indices() ); _geo->setIndices ( osg_indices() ); addRefCP( osg_vpositions() ); _geo->setPositions( osg_vpositions() ); if ( has_vertex_colors() ) { addRefCP( osg_vcolors() ); _geo->setColors ( osg_vcolors() ); } if ( has_vertex_normals() ) { addRefCP( osg_vnormals() ); _geo->setNormals ( osg_vnormals() ); } if ( has_vertex_texcoords() ) { addRefCP( osg_vtexcoords() ); _geo->setTexCoords( osg_vtexcoords() ); } } endEditCP (_geo, Mask); return true; } private: VPropHandleT points_; VPropHandleT vertex_normals_; VPropHandleT vertex_colors_; VPropHandleT vertex_texcoords_; VPropHandleT vertex_status_; FPTypesHandle face_types_; FPLengthsHandle face_lengths_; FIndicesHandle face_indices_; EPropHandleT edge_status_; HPropHandleT halfedge_status_; FPropHandleT face_normals_; FPropHandleT face_colors_; FPropHandleT face_status_; unsigned int refcount_vnormals_; unsigned int refcount_vcolors_; unsigned int refcount_vtexcoords_; unsigned int refcount_vstatus_; unsigned int refcount_estatus_; unsigned int refcount_hstatus_; unsigned int refcount_fnormals_; unsigned int refcount_fcolors_; unsigned int refcount_fstatus_; }; //============================================================================= } // namespace Kernel_OSG } // namespace OpenMesh //============================================================================= #endif // OPENMESH_KERNEL_OSG_ATTRIBKERNEL_HH defined //=============================================================================