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>
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 
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 */
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 .