OpenMesh
PropertyCreator.hh
1/* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2023, 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
56namespace OpenMesh {
57
58#define OM_CONCAT_IMPL(a, b) a##b
59#define OM_CONCAT(a, b) OM_CONCAT_IMPL(a, b)
60
67class OPENMESHDLLEXPORT PropertyCreator
68{
69public:
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
101protected:
102 PropertyCreator() {}
103
104};
105
106template <> inline void PropertyCreator::create_property<VertexHandle> (BaseKernel& _mesh, const std::string& _property_name) { create_vertex_property (_mesh, _property_name); }
107template <> inline void PropertyCreator::create_property<HalfedgeHandle>(BaseKernel& _mesh, const std::string& _property_name) { create_halfedge_property(_mesh, _property_name); }
108template <> inline void PropertyCreator::create_property<EdgeHandle> (BaseKernel& _mesh, const std::string& _property_name) { create_edge_property (_mesh, _property_name); }
109template <> inline void PropertyCreator::create_property<FaceHandle> (BaseKernel& _mesh, const std::string& _property_name) { create_face_property (_mesh, _property_name); }
110template <> inline void PropertyCreator::create_property<MeshHandle> (BaseKernel& _mesh, const std::string& _property_name) { create_mesh_property (_mesh, _property_name); }
111
114template <typename PropertyCreatorT>
116{
117public:
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 {}
136protected:
137 PropertyCreatorImpl() {}
138};
139
141namespace {
142template <typename T>
143class PropertyCreatorT : public PropertyCreatorImpl<PropertyCreatorT<T>>
144{
145};
146}
147
149
150#define OM_REGISTER_PROPERTY_TYPE(ClassName) \
151namespace OpenMesh { \
152namespace { /* ensure internal linkage of class */ \
153template <> \
154class PropertyCreatorT<ClassName> : public PropertyCreatorImpl<PropertyCreatorT<ClassName>> \
155{ \
156public: \
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 */ \
168static PropertyCreatorT<ClassName> OM_CONCAT(property_creator_registration_object_, __LINE__); \
169}
170
180class OPENMESHDLLEXPORT PropertyCreationManager
181{
182public:
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
224private:
225
228
229 std::vector<PropertyCreator*> property_creators_;
230};
231
236template <typename HandleT>
237void 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 */
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:59
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
This class provides low-level property management like adding/removing properties and access to prope...
Definition: BaseKernel.hh:98
void add_property(VPropHandleT< T > &_ph, const std::string &_name="<vprop>")
You should not use this function directly.
Definition: BaseKernel.hh:141
bool get_property_handle(VPropHandleT< T > &_ph, const std::string &_name) const
You should not use this function directly.
Definition: BaseKernel.hh:254
Definition: Property.hh:487
Base class for property creators.
Definition: PropertyCreator.hh:68
virtual void create_face_property(BaseKernel &_mesh, const std::string &_property_name)=0
Create a face property on _mesh with name _property_name.
virtual std::string type_string()=0
The string that corresponds to the type this property creator can create.
virtual void create_halfedge_property(BaseKernel &_mesh, const std::string &_property_name)=0
Create a halfedge property on _mesh with name _property_name.
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.
virtual void create_mesh_property(BaseKernel &_mesh, const std::string &_property_name)=0
Create a mesh property on _mesh with name _property_name.
virtual void create_vertex_property(BaseKernel &_mesh, const std::string &_property_name)=0
Create a vertex property on _mesh with name _property_name.
virtual void create_edge_property(BaseKernel &_mesh, const std::string &_property_name)=0
Create an edge property on _mesh with name _property_name.
Helper class that contains the implementation of the create_<HandleT>_property methods.
Definition: PropertyCreator.hh:116
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
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
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
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
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
Class for adding properties based on strings.
Definition: PropertyCreator.hh:181

Project OpenMesh, ©  Visual Computing Institute, RWTH Aachen. Documentation generated using doxygen .