Loading...
Searching...
No Matches
PropertyCreator.hh
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2020, RWTH-Aachen University *
* Department of 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. *
* *
* ========================================================================= */
#pragma once
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/HandleToPropHandle.hh>
#include <OpenMesh/Core/Utils/PropertyManager.hh>
#include <OpenMesh/Core/Mesh/PolyConnectivity.hh>
#include <sstream>
#include <stdexcept>
#include <string>
#include <memory>
#include <OpenMesh/Core/IO/SR_store.hh>
namespace OpenMesh {
#define OM_CONCAT_IMPL(a, b) a##b
#define OM_CONCAT(a, b) OM_CONCAT_IMPL(a, b)
class OPENMESHDLLEXPORT PropertyCreator
{
public:
virtual std::string type_string() = 0;
virtual std::string type_id_string() = 0;
bool can_you_create(const std::string &_type_name);
virtual void create_vertex_property (BaseKernel& _mesh, const std::string& _property_name) = 0;
virtual void create_halfedge_property(BaseKernel& _mesh, const std::string& _property_name) = 0;
virtual void create_edge_property (BaseKernel& _mesh, const std::string& _property_name) = 0;
virtual void create_face_property (BaseKernel& _mesh, const std::string& _property_name) = 0;
virtual void create_mesh_property (BaseKernel& _mesh, const std::string& _property_name) = 0;
template <typename HandleT>
void create_property(BaseKernel& _mesh, const std::string& _property_name);
virtual ~PropertyCreator() {}
protected:
PropertyCreator() {}
};
template <> inline void PropertyCreator::create_property<VertexHandle> (BaseKernel& _mesh, const std::string& _property_name) { create_vertex_property (_mesh, _property_name); }
template <> inline void PropertyCreator::create_property<HalfedgeHandle>(BaseKernel& _mesh, const std::string& _property_name) { create_halfedge_property(_mesh, _property_name); }
template <> inline void PropertyCreator::create_property<EdgeHandle> (BaseKernel& _mesh, const std::string& _property_name) { create_edge_property (_mesh, _property_name); }
template <> inline void PropertyCreator::create_property<FaceHandle> (BaseKernel& _mesh, const std::string& _property_name) { create_face_property (_mesh, _property_name); }
template <> inline void PropertyCreator::create_property<MeshHandle> (BaseKernel& _mesh, const std::string& _property_name) { create_mesh_property (_mesh, _property_name); }
template <typename PropertyCreatorT>
class PropertyCreatorImpl : public PropertyCreator
{
public:
std::string type_id_string() override { return get_type_name<typename PropertyCreatorT::type>(); }
template <typename HandleT, typename PropT>
void create_prop(BaseKernel& _mesh, const std::string& _property_name)
{
using PHandle = typename PropHandle<HandleT>::template type<PropT>;
PHandle prop;
if (!_mesh.get_property_handle(prop, _property_name))
_mesh.add_property(prop, _property_name);
}
void create_vertex_property (BaseKernel& _mesh, const std::string& _property_name) override { create_prop<VertexHandle , typename PropertyCreatorT::type>(_mesh, _property_name); }
void create_halfedge_property(BaseKernel& _mesh, const std::string& _property_name) override { create_prop<HalfedgeHandle, typename PropertyCreatorT::type>(_mesh, _property_name);}
void create_edge_property (BaseKernel& _mesh, const std::string& _property_name) override { create_prop<EdgeHandle , typename PropertyCreatorT::type>(_mesh, _property_name);}
void create_face_property (BaseKernel& _mesh, const std::string& _property_name) override { create_prop<FaceHandle , typename PropertyCreatorT::type>(_mesh, _property_name);}
void create_mesh_property (BaseKernel& _mesh, const std::string& _property_name) override { create_prop<MeshHandle , typename PropertyCreatorT::type>(_mesh, _property_name);}
~PropertyCreatorImpl() override {}
protected:
PropertyCreatorImpl() {}
};
namespace {
template <typename T>
class PropertyCreatorT : public PropertyCreatorImpl<PropertyCreatorT<T>>
{
};
}
#define OM_REGISTER_PROPERTY_TYPE(ClassName) \
namespace OpenMesh { \
namespace { /* ensure internal linkage of class */ \
template <> \
class PropertyCreatorT<ClassName> : public PropertyCreatorImpl<PropertyCreatorT<ClassName>> \
{ \
public: \
using type = ClassName; \
std::string type_string() override { return OpenMesh::IO::binary<type>::type_identifier(); } \
\
PropertyCreatorT() \
{ \
PropertyCreationManager::instance().register_property_creator(this); \
} \
~PropertyCreatorT() override {} \
}; \
} \
/* static to ensure internal linkage of object */ \
static PropertyCreatorT<ClassName> OM_CONCAT(property_creator_registration_object_, __LINE__); \
}
class OPENMESHDLLEXPORT PropertyCreationManager
{
public:
static PropertyCreationManager& instance();
template <typename HandleT>
void create_property(BaseKernel& _mesh, const std::string& _type_name, const std::string& _property_name)
{
auto can_create = [_type_name](OpenMesh::PropertyCreator* pc){
return pc->can_you_create(_type_name);
};
std::vector<OpenMesh::PropertyCreator*>::iterator pc_iter = std::find_if(property_creators_.begin(),
property_creators_.end(), can_create);
if (pc_iter != property_creators_.end())
{
const auto& pc = *pc_iter;
pc->create_property<HandleT>(_mesh, _property_name);
return;
}
omerr() << "No property creator registered that can create a property of type " << _type_name << std::endl;
omerr() << "You need to register your custom type using OM_REGISTER_PROPERTY_TYPE(ClassName) and declare the struct binary<ClassName>.\
See documentation for more details." << std::endl;
omerr() << "Adding property failed." << std::endl;
}
void register_property_creator(PropertyCreator* _property_creator)
{
for (auto pc : property_creators_)
if (pc->type_string() == _property_creator->type_string())
{
if (pc->type_id_string() != _property_creator->type_id_string())
{
omerr() << "And it looks like you are trying to add a different type with an already existing string identification." << std::endl;
omerr() << "Type id of existing type is " << pc->type_id_string() << " trying to add for " << _property_creator->type_id_string() << std::endl;
}
return;
}
property_creators_.push_back(_property_creator);
}
private:
PropertyCreationManager() {}
~PropertyCreationManager() {}
std::vector<PropertyCreator*> property_creators_;
};
template <typename HandleT>
void create_property_from_string(BaseKernel& _mesh, const std::string& _type_name, const std::string& _property_name)
{
PropertyCreationManager::instance().create_property<HandleT>(_mesh, _type_name, _property_name);
}
} /* namespace OpenMesh */
OpenMesh
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition MeshItems.hh:59
OpenMesh::create_property_from_string
void create_property_from_string(BaseKernel &_mesh, const std::string &_type_name, const std::string &_property_name)
Create a property with type corresponding to _type_name on _mesh with name _property_name.
Definition PropertyCreator.hh:237
OpenMesh::BaseKernel
This class provides low-level property management like adding/removing properties and access to prope...
Definition BaseKernel.hh:98
OpenMesh::BaseKernel::add_property
void add_property(VPropHandleT< T > &_ph, const std::string &_name="<vprop>")
You should not use this function directly.
Definition BaseKernel.hh:141
OpenMesh::BaseKernel::get_property_handle
bool get_property_handle(VPropHandleT< T > &_ph, const std::string &_name) const
You should not use this function directly.
Definition BaseKernel.hh:254
OpenMesh::PropHandle
Definition Property.hh:487
OpenMesh::PropertyCreator
Base class for property creators.
Definition PropertyCreator.hh:68
OpenMesh::PropertyCreator::create_face_property
virtual void create_face_property(BaseKernel &_mesh, const std::string &_property_name)=0
Create a face property on _mesh with name _property_name.
OpenMesh::PropertyCreator::type_string
virtual std::string type_string()=0
The string that corresponds to the type this property creator can create.
OpenMesh::PropertyCreator::create_halfedge_property
virtual void create_halfedge_property(BaseKernel &_mesh, const std::string &_property_name)=0
Create a halfedge property on _mesh with name _property_name.
OpenMesh::PropertyCreator::create_property
void create_property(BaseKernel &_mesh, const std::string &_property_name)
Create a property for the element of type HandleT on _mesh with name _property_name.
OpenMesh::PropertyCreator::create_mesh_property
virtual void create_mesh_property(BaseKernel &_mesh, const std::string &_property_name)=0
Create a mesh property on _mesh with name _property_name.
OpenMesh::PropertyCreator::create_vertex_property
virtual void create_vertex_property(BaseKernel &_mesh, const std::string &_property_name)=0
Create a vertex property on _mesh with name _property_name.
OpenMesh::PropertyCreator::create_edge_property
virtual void create_edge_property(BaseKernel &_mesh, const std::string &_property_name)=0
Create an edge property on _mesh with name _property_name.
OpenMesh::PropertyCreatorImpl
Helper class that contains the implementation of the create_<HandleT>_property methods.
Definition PropertyCreator.hh:116
OpenMesh::PropertyCreatorImpl::create_edge_property
void create_edge_property(BaseKernel &_mesh, const std::string &_property_name) override
Create an edge property on _mesh with name _property_name.
Definition PropertyCreator.hh:131
OpenMesh::PropertyCreatorImpl::create_face_property
void create_face_property(BaseKernel &_mesh, const std::string &_property_name) override
Create a face property on _mesh with name _property_name.
Definition PropertyCreator.hh:132
OpenMesh::PropertyCreatorImpl::create_vertex_property
void create_vertex_property(BaseKernel &_mesh, const std::string &_property_name) override
Create a vertex property on _mesh with name _property_name.
Definition PropertyCreator.hh:129
OpenMesh::PropertyCreatorImpl::create_mesh_property
void create_mesh_property(BaseKernel &_mesh, const std::string &_property_name) override
Create a mesh property on _mesh with name _property_name.
Definition PropertyCreator.hh:133
OpenMesh::PropertyCreatorImpl::create_halfedge_property
void create_halfedge_property(BaseKernel &_mesh, const std::string &_property_name) override
Create a halfedge property on _mesh with name _property_name.
Definition PropertyCreator.hh:130
OpenMesh::PropertyCreationManager
Class for adding properties based on strings.
Definition PropertyCreator.hh:181