Skip to content
Snippets Groups Projects
Commit daa84d6f authored by Alexander Dielen's avatar Alexander Dielen
Browse files

remove property maps (thanks to Matthias Möller for the patch)

parent daa46106
No related branches found
No related tags found
No related merge requests found
Pipeline #8971 passed
......@@ -57,17 +57,15 @@ public:
template <class Handle>
bool py_has_property(const std::string& _name) {
auto& prop_map = py_prop_map(Handle());
return prop_map.count(_name);
HandleToPropHandle<Handle> dummy;
return py_get_property_handle<Handle>(dummy, _name);
}
template <class Handle>
void py_remove_property(const std::string& _name) {
auto& prop_map = py_prop_map(Handle());
if (prop_map.count(_name) != 0) {
Mesh::remove_property(prop_map.at(_name));
prop_map.erase(_name);
}
HandleToPropHandle<Handle> h;
Mesh::get_property_handle(h, _name);
Mesh::remove_property(h);
}
template <class Handle, class PropHandle>
......@@ -222,35 +220,97 @@ private:
template <class Handle>
void py_deepcopy_prop(MeshWrapperT *_copy, py::object _copyfunc, py::dict _memo) {
for (const auto& item : py_prop_map(Handle())) {
const auto prop = item.second;
for (size_t i = 0; i < py_n_items(Handle()); ++i) {
const Handle h(i);
_copy->property(prop, h) = _copyfunc(this->property(prop, h), _memo);
using PropHandle = HandleToPropHandle<Handle>;
const auto enditer = this->end(Handle());
for (auto iter = this->begin(Handle()); iter != enditer; ++iter){
// only select properties owned by python (all properties with type "py::none")
const OpenMesh::BaseProperty* baseProp = *iter;
const auto* srcProp = dynamic_cast< const OpenMesh::PropertyT<py::none>* >(baseProp);
if (!srcProp)
continue; //not a python prop -> dont copy
const PropHandle targetProp = _copy->py_prop_on_demand<Handle, PropHandle>(srcProp->name());
for (size_t i = 0; i < srcProp->n_elements(); ++i) {
_copy->property(targetProp, Handle(i)) = _copyfunc((*srcProp)[i], _memo);
}
}
}
template <class Handle, class PropHandle>
PropHandle py_prop_on_demand(const std::string& _name) {
auto& prop_map = py_prop_map(Handle());
if (prop_map.count(_name) == 0) {
PropHandle prop;
Mesh::add_property(prop, _name);
prop_map[_name] = prop;
bool py_get_property_handle(PropHandle &_out, const std::string& _name) {
#ifdef OM_FORCE_STATIC_CAST
// Enable type checking for OpenMesh Properties.
// In OpenMesh it is disabled due to a problem with the shared linkage using libc++
// We link the static library and therefore, OpenMesh-Python is not affected by this
// This function enables type checking, if it is disabled in OpenMesh (per default, in Relase mode)
// Use normal OpenMesh property_handle function, when type checking is not disabled (debug more or hopefully in the future)
int idx = -1;
const auto it = std::find_if(this->begin(Handle()), this->end(Handle()), [&_name, &idx](OpenMesh::BaseProperty* p)
{
++idx;
return ((p != nullptr) && (p->name() == _name) && (dynamic_cast<OpenMesh::PropertyT<py::none>*>(p) != nullptr));
});
if (it == this->end(Handle()))
{
_out = PropHandle();
return false;
}
else
{
_out = PropHandle(idx);
return true;
}
#else
return Mesh::get_property_handle(_out, _name);
#endif
}
return prop_map.at(_name);
template <class Handle, class PropHandle>
PropHandle py_prop_on_demand(const std::string& _name) {
PropHandle result;
if (!py_get_property_handle<Handle>(result, _name))
Mesh::add_property(result, _name);
return result;
}
std::map<std::string, VPropHandle>& py_prop_map(OpenMesh::VertexHandle) { return vprop_map; }
std::map<std::string, HPropHandle>& py_prop_map(OpenMesh::HalfedgeHandle) { return hprop_map; }
std::map<std::string, EPropHandle>& py_prop_map(OpenMesh::EdgeHandle) { return eprop_map; }
std::map<std::string, FPropHandle>& py_prop_map(OpenMesh::FaceHandle) { return fprop_map; }
typename Mesh::prop_iterator begin(OpenMesh::VertexHandle) { return this->vprops_begin(); }
typename Mesh::prop_iterator end(OpenMesh::VertexHandle) { return this->vprops_end(); }
typename Mesh::prop_iterator begin(OpenMesh::HalfedgeHandle) { return this->hprops_begin(); }
typename Mesh::prop_iterator end(OpenMesh::HalfedgeHandle) { return this->hprops_end(); }
typename Mesh::prop_iterator begin(OpenMesh::EdgeHandle) { return this->eprops_begin(); }
typename Mesh::prop_iterator end(OpenMesh::EdgeHandle) { return this->eprops_end(); }
typename Mesh::prop_iterator begin(OpenMesh::FaceHandle) { return this->fprops_begin(); }
typename Mesh::prop_iterator end(OpenMesh::FaceHandle) { return this->fprops_end(); }
template<typename Handle, typename Dummy>
struct HandleToPropHandle_D
{};
template<typename Dummy>
struct HandleToPropHandle_D<OpenMesh::VertexHandle, Dummy>
{
using type = VPropHandle;
};
template<typename Dummy>
struct HandleToPropHandle_D<OpenMesh::HalfedgeHandle, Dummy>
{
using type = HPropHandle;
};
template<typename Dummy>
struct HandleToPropHandle_D<OpenMesh::EdgeHandle, Dummy>
{
using type = EPropHandle;
};
template<typename Dummy>
struct HandleToPropHandle_D<OpenMesh::FaceHandle, Dummy>
{
using type = FPropHandle;
};
template<typename Handle>
using HandleToPropHandle = typename HandleToPropHandle_D<Handle,Handle>::type;
std::map<std::string, VPropHandle> vprop_map;
std::map<std::string, HPropHandle> hprop_map;
std::map<std::string, EPropHandle> eprop_map;
std::map<std::string, FPropHandle> fprop_map;
};
......
......@@ -325,6 +325,15 @@ class Property(unittest.TestCase):
self.assertFalse(self.mesh.has_edge_property('test'))
self.assertFalse(self.mesh.has_face_property('test'))
def test_access_wrong_property_type(self):
self.assertFalse(self.mesh.has_vertex_property("v:points"))
self.vhandle.append(self.mesh.add_vertex(np.array([0, 0, 0])))
vh = openmesh.VertexHandle(0)
self.mesh.set_vertex_property("v:points", vh, [99,99,99])
self.assertNotEqual(self.mesh.point(vh)[0], 99)
self.assertNotEqual(self.mesh.point(vh)[1], 99)
self.assertNotEqual(self.mesh.point(vh)[2], 99)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(Property)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment