OpenMesh: OpenMesh/Core/Utils/PropertyCreator.hh Source File

| OpenMesh

PropertyCreator.hh
1 /* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2020, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openmesh.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenMesh. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 * ========================================================================= */
41
42 #pragma once
43
44 #include <OpenMesh/Core/System/config.h>
45 #include <OpenMesh/Core/Utils/HandleToPropHandle.hh>
46 #include <OpenMesh/Core/Utils/PropertyManager.hh>
47 #include <OpenMesh/Core/Mesh/PolyConnectivity.hh>
48 #include <sstream>
49 #include <stdexcept>
50 #include <string>
51 #include <memory>
52
53 #include <OpenMesh/Core/IO/SR_store.hh>
54
55
56 namespace OpenMesh {
57
58 #define OM_CONCAT_IMPL(a, b) a##b
59 #define OM_CONCAT(a, b) OM_CONCAT_IMPL(a, b)
60
67 class OPENMESHDLLEXPORT PropertyCreator
68 {
69 public:
70
72 virtual std::string type_string() = 0;
73
74 virtual std::string type_id_string() = 0;
75
77 bool can_you_create(const std::string &_type_name);
78
80 virtual void create_vertex_property (BaseKernel& _mesh, const std::string& _property_name) = 0;
81
83 virtual void create_halfedge_property(BaseKernel& _mesh, const std::string& _property_name) = 0;
84
86 virtual void create_edge_property (BaseKernel& _mesh, const std::string& _property_name) = 0;
87
89 virtual void create_face_property (BaseKernel& _mesh, const std::string& _property_name) = 0;
90
92 virtual void create_mesh_property (BaseKernel& _mesh, const std::string& _property_name) = 0;
93
94
96 template <typename HandleT>
97 void create_property(BaseKernel& _mesh, const std::string& _property_name);
98
99 virtual ~PropertyCreator() {}
100
101 protected:
102 PropertyCreator() {}
103
104 };
105
106 template <> inline void PropertyCreator::create_property<VertexHandle> (BaseKernel& _mesh, const std::string& _property_name) { create_vertex_property (_mesh, _property_name); }
107 template <> inline void PropertyCreator::create_property<HalfedgeHandle>(BaseKernel& _mesh, const std::string& _property_name) { create_halfedge_property(_mesh, _property_name); }
108 template <> inline void PropertyCreator::create_property<EdgeHandle> (BaseKernel& _mesh, const std::string& _property_name) { create_edge_property (_mesh, _property_name); }
109 template <> inline void PropertyCreator::create_property<FaceHandle> (BaseKernel& _mesh, const std::string& _property_name) { create_face_property (_mesh, _property_name); }
110 template <> inline void PropertyCreator::create_property<MeshHandle> (BaseKernel& _mesh, const std::string& _property_name) { create_mesh_property (_mesh, _property_name); }
111
114 template <typename PropertyCreatorT>
115 class PropertyCreatorImpl : public PropertyCreator
116 {
117 public:
118 std::string type_id_string() override { return get_type_name<typename PropertyCreatorT::type>(); }
119
120 template <typename HandleT, typename PropT>
121 void create_prop(BaseKernel& _mesh, const std::string& _property_name)
122 {
123 using PHandle = typename PropHandle<HandleT>::template type<PropT>;
124 PHandle prop;
125 if (!_mesh.get_property_handle(prop, _property_name))
126 _mesh.add_property(prop, _property_name);
127 }
128
129 void create_vertex_property (BaseKernel& _mesh, const std::string& _property_name) override { create_prop<VertexHandle , typename PropertyCreatorT::type>(_mesh, _property_name); }
130 void create_halfedge_property(BaseKernel& _mesh, const std::string& _property_name) override { create_prop<HalfedgeHandle, typename PropertyCreatorT::type>(_mesh, _property_name);}
131 void create_edge_property (BaseKernel& _mesh, const std::string& _property_name) override { create_prop<EdgeHandle , typename PropertyCreatorT::type>(_mesh, _property_name);}
132 void create_face_property (BaseKernel& _mesh, const std::string& _property_name) override { create_prop<FaceHandle , typename PropertyCreatorT::type>(_mesh, _property_name);}
133 void create_mesh_property (BaseKernel& _mesh, const std::string& _property_name) override { create_prop<MeshHandle , typename PropertyCreatorT::type>(_mesh, _property_name);}
134
135 ~PropertyCreatorImpl() override {}
136 protected:
137 PropertyCreatorImpl() {}
138 };
139
141 namespace {
142 template <typename T>
143 class PropertyCreatorT : public PropertyCreatorImpl<PropertyCreatorT<T>>
144 {
145 };
146 }
147
149
150 #define OM_REGISTER_PROPERTY_TYPE(ClassName) \
151 namespace OpenMesh { \
152 namespace { /* ensure internal linkage of class */ \
153 template <> \
154 class PropertyCreatorT<ClassName> : public PropertyCreatorImpl<PropertyCreatorT<ClassName>> \
155 { \
156 public: \
157 using type = ClassName; \
158 std::string type_string() override { return OpenMesh::IO::binary<type>::type_identifier(); } \
159 \
160 PropertyCreatorT() \
161 { \
162 PropertyCreationManager::instance().register_property_creator(this); \
163 } \
164 ~PropertyCreatorT() override {} \
165 }; \
166 } \
167 /* static to ensure internal linkage of object */ \
168 static PropertyCreatorT<ClassName> OM_CONCAT(property_creator_registration_object_, __LINE__); \
169 }
170
180 class OPENMESHDLLEXPORT PropertyCreationManager
181 {
182 public:
183
184 static PropertyCreationManager& instance();
185
186 template <typename HandleT>
187 void create_property(BaseKernel& _mesh, const std::string& _type_name, const std::string& _property_name)
188 {
189
190 auto can_create = [_type_name](OpenMesh::PropertyCreator* pc){
191 return pc->can_you_create(_type_name);
192 };
193
194 std::vector<OpenMesh::PropertyCreator*>::iterator pc_iter = std::find_if(property_creators_.begin(),
195 property_creators_.end(), can_create);
196 if (pc_iter != property_creators_.end())
197 {
198 const auto& pc = *pc_iter;
199 pc->create_property<HandleT>(_mesh, _property_name);
200 return;
201 }
202
203 omerr() << "No property creator registered that can create a property of type " << _type_name << std::endl;
204 omerr() << "You need to register your custom type using OM_REGISTER_PROPERTY_TYPE(ClassName) and declare the struct binary<ClassName>.\
205 See documentation for more details." << std::endl;
206 omerr() << "Adding property failed." << std::endl;
207 }
208
209 void register_property_creator(PropertyCreator* _property_creator)
210 {
211 for (auto pc : property_creators_)
212 if (pc->type_string() == _property_creator->type_string())
213 {
214 if (pc->type_id_string() != _property_creator->type_id_string())
215 {
216 omerr() << "And it looks like you are trying to add a different type with an already existing string identification." << std::endl;
217 omerr() << "Type id of existing type is " << pc->type_id_string() << " trying to add for " << _property_creator->type_id_string() << std::endl;
218 }
219 return;
220 }
221 property_creators_.push_back(_property_creator);
222 }
223
224 private:
225
226 PropertyCreationManager() {}
227 ~PropertyCreationManager() {}
228
229 std::vector<PropertyCreator*> property_creators_;
230 };
231
236 template <typename HandleT>
237 void create_property_from_string(BaseKernel& _mesh, const std::string& _type_name, const std::string& _property_name)
238 {
239 PropertyCreationManager::instance().create_property<HandleT>(_mesh, _type_name, _property_name);
240 }
241
242 } /* 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