diff --git a/src/App/ComplexGeoDataPy.xml b/src/App/ComplexGeoDataPy.xml
index c60f905826..7b094cb3dd 100644
--- a/src/App/ComplexGeoDataPy.xml
+++ b/src/App/ComplexGeoDataPy.xml
@@ -64,6 +64,37 @@
Apply a transformation to the underlying geometry
+
+
+
+ setElementName(element,name=None,postfix=None,overwrite=False,sid=None), Set an element name
+
+ element : the original element name, e.g. Edge1, Vertex2
+ name : the new name for the element, None to remove the mapping
+ postfix : postfix of the name that will not be hashed
+ overwrite: if true, it will overwrite exiting name
+ sid : to hash the name any way you want, provide your own string id(s) in this parameter
+
+ An element can have multiple mapped names. However, a name can only be mapped
+ to one element
+
+
+
+
+
+ getElementName(name,direction=0) - Return a mapped element name or reverse
+
+
+
+
+ getElementIndexedName(name) - Return the indexed element name
+
+
+
+
+ getElementMappedName(name) - Return the mapped element name
+
+
Get the bounding box (BoundBox) of the complex geometric data.
@@ -88,5 +119,35 @@
+
+
+ Get/Set the string hasher of this object
+
+
+
+
+
+ Get the current element map size
+
+
+
+
+
+ Get/Set a dict of element mapping
+
+
+
+
+
+ Get a dict of element reverse mapping
+
+
+
+
+
+ Element map version
+
+
+
diff --git a/src/App/ComplexGeoDataPyImp.cpp b/src/App/ComplexGeoDataPyImp.cpp
index e6c9fe69a5..b3469ddc1a 100644
--- a/src/App/ComplexGeoDataPyImp.cpp
+++ b/src/App/ComplexGeoDataPyImp.cpp
@@ -27,10 +27,13 @@
#endif
#include "ComplexGeoData.h"
+#include "StringHasher.h"
// inclusion of the generated files (generated out of ComplexGeoDataPy.xml)
#include
#include
+#include
+#include
#include
#include
#include
@@ -292,6 +295,184 @@ PyObject* ComplexGeoDataPy::transformGeometry(PyObject *args)
}
}
+PyObject* ComplexGeoDataPy::getElementName(PyObject *args)
+{
+ char* input;
+ int direction = 0;
+ if (!PyArg_ParseTuple(args, "s|i", &input,&direction))
+ return NULL;
+
+ Data::MappedElement res = getComplexGeoDataPtr()->getElementName(input);
+ std::string s;
+ if (direction == 1)
+ return Py::new_reference_to(Py::String(res.name.appendToBuffer(s)));
+ else if (direction == 0)
+ return Py::new_reference_to(Py::String(res.index.appendToStringBuffer(s)));
+ else if (Data::IndexedName(input))
+ return Py::new_reference_to(Py::String(res.name.appendToBuffer(s)));
+ else
+ return Py::new_reference_to(Py::String(res.index.appendToStringBuffer(s)));
+}
+
+PyObject* ComplexGeoDataPy::getElementIndexedName(PyObject *args)
+{
+ char* input;
+ PyObject *returnID = Py_False;
+ if (!PyArg_ParseTuple(args, "s|O", &input,&returnID))
+ return NULL;
+
+ ElementIDRefs ids;
+ Data::MappedElement res = getComplexGeoDataPtr()->getElementName(
+ input, PyObject_IsTrue(returnID)?&ids:nullptr);
+ std::string s;
+ Py::String name(res.index.appendToStringBuffer(s));
+ if (!PyObject_IsTrue(returnID))
+ return Py::new_reference_to(name);
+
+ Py::List list;
+ for (auto &id : ids)
+ list.append(Py::Long(id.value()));
+ return Py::new_reference_to(Py::TupleN(name, list));
+}
+
+PyObject* ComplexGeoDataPy::getElementMappedName(PyObject *args)
+{
+ char* input;
+ PyObject *returnID = Py_False;
+ if (!PyArg_ParseTuple(args, "s|O", &input,&returnID))
+ return NULL;
+
+ ElementIDRefs ids;
+ Data::MappedElement res = getComplexGeoDataPtr()->getElementName(
+ input, PyObject_IsTrue(returnID)?&ids:nullptr);
+ std::string s;
+ Py::String name(res.name.appendToBuffer(s));
+ if (!PyObject_IsTrue(returnID))
+ return Py::new_reference_to(name);
+
+ Py::List list;
+ for (auto &id : ids)
+ list.append(Py::Long(id.value()));
+ return Py::new_reference_to(Py::TupleN(name, list));
+}
+
+PyObject *ComplexGeoDataPy::setElementName(PyObject *args, PyObject *kwds) {
+ const char *element;
+ const char *name = 0;
+ const char *postfix = 0;
+ int tag = 0;
+ PyObject *pySid = Py_None;
+ PyObject *overwrite = Py_False;
+
+ static char *kwlist[] = {"element", "name", "postfix", "overwrite", "sid", "tag", NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|sssOOi", kwlist,
+ &element,&name,&postfix,&overwrite,&pySid,&tag))
+ return NULL;
+ ElementIDRefs sids;
+ if(pySid != Py_None) {
+ if(PyObject_TypeCheck(pySid,&App::StringIDPy::Type))
+ sids.push_back(static_cast(pySid)->getStringIDPtr());
+ else if(PySequence_Check(pySid)) {
+ Py::Sequence seq(pySid);
+ for(auto it=seq.begin();it!=seq.end();++it) {
+ auto ptr = (*it).ptr();
+ if(PyObject_TypeCheck(ptr,&App::StringIDPy::Type))
+ sids.push_back(static_cast(ptr)->getStringIDPtr());
+ else
+ throw Py::TypeError("expect StringID in sid sequence");
+ }
+ } else
+ throw Py::TypeError("expect sid to contain either StringID or sequence of StringID");
+ }
+ PY_TRY {
+ Data::IndexedName index(element, getComplexGeoDataPtr()->getElementTypes());
+ Data::MappedName mapped = Data::MappedName::fromRawData(name);
+ std::ostringstream ss;
+ ElementMapPtr map = getComplexGeoDataPtr()->resetElementMap();
+ map->encodeElementName(getComplexGeoDataPtr()->elementType(index),
+ mapped, ss, &sids, tag, postfix, tag);
+ Data::MappedName res = map->setElementName(
+ index, mapped, tag, &sids, PyObject_IsTrue(overwrite));
+ return Py::new_reference_to(Py::String(res.toString(0)));
+ }PY_CATCH
+}
+
+Py::Object ComplexGeoDataPy::getHasher() const {
+ auto self = getComplexGeoDataPtr();
+ if(!self->Hasher)
+ return Py::None();
+ return Py::Object(self->Hasher->getPyObject(),true);
+}
+
+Py::Dict ComplexGeoDataPy::getElementMap() const {
+ Py::Dict ret;
+ std::string s;
+ for(auto &v : getComplexGeoDataPtr()->getElementMap()) {
+ s.clear();
+ ret.setItem(v.name.toString(0), Py::String(v.index.appendToStringBuffer(s)));
+ }
+ return ret;
+}
+
+void ComplexGeoDataPy::setElementMap(Py::Dict dict) {
+ std::vector map;
+ const auto & types = getComplexGeoDataPtr()->getElementTypes();
+ for(auto it=dict.begin();it!=dict.end();++it) {
+ const auto &value = *it;
+ if(!value.first.isString() || !value.second.isString())
+ throw Py::TypeError("expect only strings in the dict");
+ map.emplace_back(Data::MappedName(value.first.as_string().c_str()),
+ Data::IndexedName(Py::Object(value.second).as_string().c_str(), types));
+ }
+ getComplexGeoDataPtr()->setElementMap(map);
+}
+
+Py::Dict ComplexGeoDataPy::getElementReverseMap() const {
+ Py::Dict ret;
+ std::string s;
+ for(auto &v : getComplexGeoDataPtr()->getElementMap()) {
+ s.clear();
+ auto value = ret[Py::String(v.index.appendToStringBuffer(s))];
+ Py::Object item(value);
+ if(item.isNone()) {
+ s.clear();
+ value = Py::String(v.name.appendToBuffer(s));
+ } else if(item.isList()) {
+ Py::List list(item);
+ s.clear();
+ list.append(Py::String(v.name.appendToBuffer(s)));
+ } else {
+ Py::List list;
+ list.append(item);
+ s.clear();
+ list.append(Py::String(v.name.appendToBuffer(s)));
+ value = list;
+ }
+ }
+ return ret;
+}
+
+Py::Int ComplexGeoDataPy::getElementMapSize() const {
+ return Py::Int((long)getComplexGeoDataPtr()->getElementMapSize());
+}
+
+void ComplexGeoDataPy::setHasher(Py::Object obj) {
+ auto self = getComplexGeoDataPtr();
+ if(obj.isNone()) {
+ if(self->Hasher) {
+ self->Hasher = App::StringHasherRef();
+ self->resetElementMap();
+ }
+ }else if(PyObject_TypeCheck(obj.ptr(),&App::StringHasherPy::Type)) {
+ App::StringHasherRef ref(static_cast(obj.ptr())->getStringHasherPtr());
+ if(self->Hasher != ref) {
+ self->Hasher = ref;
+ self->resetElementMap();
+ }
+ }else
+ throw Py::TypeError("invalid type");
+}
+
Py::Object ComplexGeoDataPy::getBoundBox() const
{
return Py::BoundingBox(getComplexGeoDataPtr()->getBoundBox());
@@ -324,6 +505,12 @@ void ComplexGeoDataPy::setPlacement(Py::Object arg)
}
}
+Py::String ComplexGeoDataPy::getElementMapVersion() const
+{
+ return Py::String(getComplexGeoDataPtr()->getElementMapVersion());
+}
+
+
Py::Int ComplexGeoDataPy::getTag() const
{
return Py::Int(getComplexGeoDataPtr()->Tag);