From 4c0bb37f4d8ddd33d87453ed36f6772c3bdd0dec Mon Sep 17 00:00:00 2001 From: wandererfan Date: Mon, 11 Nov 2019 14:41:10 -0500 Subject: [PATCH 1/4] [TD]Add getEdges Py functions --- src/Mod/TechDraw/App/DrawViewPartPy.xml | 10 ++++++ src/Mod/TechDraw/App/DrawViewPartPyImp.cpp | 38 ++++++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawViewPartPy.xml b/src/Mod/TechDraw/App/DrawViewPartPy.xml index f6921ae78a..3abc3c44f4 100644 --- a/src/Mod/TechDraw/App/DrawViewPartPy.xml +++ b/src/Mod/TechDraw/App/DrawViewPartPy.xml @@ -13,6 +13,16 @@ Feature for creating and manipulating Technical Drawing Part Views + + + getVisibleEdges() - get the visible edges in the View as Part::TopoShapeEdges + + + + + getHiddenEdges() - get the hidden edges in the View as Part::TopoShapeEdges + + makeCosmeticVertex(p1) - add a CosmeticVertex at p1 (View coordinates). Returns index of created vertex. diff --git a/src/Mod/TechDraw/App/DrawViewPartPyImp.cpp b/src/Mod/TechDraw/App/DrawViewPartPyImp.cpp index 403fd0fbfe..0f35ba67d6 100644 --- a/src/Mod/TechDraw/App/DrawViewPartPyImp.cpp +++ b/src/Mod/TechDraw/App/DrawViewPartPyImp.cpp @@ -70,6 +70,38 @@ std::string DrawViewPartPy::representation(void) const } //TODO: gets & sets for geometry +PyObject* DrawViewPartPy::getVisibleEdges(PyObject *args) +{ + (void) args; + DrawViewPart* dvp = getDrawViewPartPtr(); + PyObject* pEdgeList = PyList_New(0); + std::vector geoms = dvp->getEdgeGeometry(); + for (auto& g: geoms) { + if (g->hlrVisible) { + PyObject* pEdge = new Part::TopoShapeEdgePy(new Part::TopoShape(g->occEdge)); + PyList_Append(pEdgeList, pEdge); + } + } + + return pEdgeList; +} + +PyObject* DrawViewPartPy::getHiddenEdges(PyObject *args) +{ + (void) args; + DrawViewPart* dvp = getDrawViewPartPtr(); + PyObject* pEdgeList = PyList_New(0); + std::vector geoms = dvp->getEdgeGeometry(); + for (auto& g: geoms) { + if (!g->hlrVisible) { + PyObject* pEdge = new Part::TopoShapeEdgePy(new Part::TopoShape(g->occEdge)); + PyList_Append(pEdgeList, pEdge); + } + } + + return pEdgeList; +} + PyObject* DrawViewPartPy::clearCosmeticVertices(PyObject *args) { (void) args; @@ -238,7 +270,7 @@ PyObject* DrawViewPartPy::makeCosmeticCircleArc(PyObject *args) // right result, but ugly: // Qt angles are cw, OCC angles are CCW // Qt -y is up, OCC -y is down - + TopoDS_Edge edge = aMakeEdge.Edge(); int idx = dvp->addCosmeticEdge(edge); TechDraw::CosmeticEdge* ce = dvp->getCosmeticEdgeByIndex(idx); @@ -314,7 +346,7 @@ PyObject* DrawViewPartPy::getCosmeticEdgeByGeom(PyObject *args) throw Py::TypeError("expected (index)"); } DrawViewPart* dvp = getDrawViewPartPtr(); - + TechDraw::BaseGeom* bg = dvp->getGeomByIndex(idx); if (bg == nullptr) { Base::Console().Error("DVPPI::getCEbyGeom - geom: %d not found\n",idx); @@ -502,7 +534,7 @@ PyObject* DrawViewPartPy::formatGeometricEdge(PyObject *args) visible); TechDraw::GeomFormat* newGF = new TechDraw::GeomFormat(idx, fmt); -// int idx = +// int idx = dvp->addGeomFormat(newGF); } return Py_None; From 76f76f02dd22955c3a2c788861d9ee302e40b471 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 12 Nov 2019 23:24:42 +0100 Subject: [PATCH 2/4] add support of static and class methods in Python wrappers --- .../generateBase/generateMetaModel_Module.xsd | 3 + .../generateBase/generateModel_Module.py | 73 ++++++++++++++++++- .../templateClassPyExport.py | 31 +++++++- 3 files changed, 103 insertions(+), 4 deletions(-) diff --git a/src/Tools/generateBase/generateMetaModel_Module.xsd b/src/Tools/generateBase/generateMetaModel_Module.xsd index ec142e78c5..eb641cfbb5 100644 --- a/src/Tools/generateBase/generateMetaModel_Module.xsd +++ b/src/Tools/generateBase/generateMetaModel_Module.xsd @@ -18,6 +18,8 @@ + + @@ -46,6 +48,7 @@ + diff --git a/src/Tools/generateBase/generateModel_Module.py b/src/Tools/generateBase/generateModel_Module.py index 643499cb90..e03e45f930 100644 --- a/src/Tools/generateBase/generateModel_Module.py +++ b/src/Tools/generateBase/generateModel_Module.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -# Generated Mon Aug 21 13:00:21 2017 by generateDS.py. +# Generated Tue Nov 12 21:18:34 2019 by generateDS.py. # Update it with: python generateDS.py -o generateModel_Module.py generateMetaModel_Module.xsd # # WARNING! All changes made in this file will be lost! @@ -221,7 +221,7 @@ class GenerateModel: class PythonExport: subclass = None - def __init__(self, FatherNamespace='', DisableNotify=0, RichCompare=0, Name='', Reference=0, FatherInclude='', Namespace='', Initialization=0, Father='', PythonName='', Twin='', Constructor=0, TwinPointer='', Include='', NumberProtocol=0, Delete=0, Documentation=None, Methode=None, Attribute=None, Sequence=None, CustomAttributes='', ClassDeclarations=''): + def __init__(self, FatherNamespace='', DisableNotify=0, RichCompare=0, Name='', Reference=0, FatherInclude='', Namespace='', Initialization=0, Father='', PythonName='', Twin='', Constructor=0, TwinPointer='', Include='', NumberProtocol=0, Delete=0, Documentation=None, Methode=None, Attribute=None, Sequence=None, CustomAttributes='', ClassDeclarations='', ForwardDeclarations=''): self.FatherNamespace = FatherNamespace self.DisableNotify = DisableNotify self.RichCompare = RichCompare @@ -250,6 +250,7 @@ class PythonExport: self.Sequence = Sequence self.CustomAttributes = CustomAttributes self.ClassDeclarations = ClassDeclarations + self.ForwardDeclarations = ForwardDeclarations def factory(*args_, **kwargs_): if PythonExport.subclass: return PythonExport.subclass(*args_, **kwargs_) @@ -272,6 +273,8 @@ class PythonExport: def setCustomattributes(self, CustomAttributes): self.CustomAttributes = CustomAttributes def getClassdeclarations(self): return self.ClassDeclarations def setClassdeclarations(self, ClassDeclarations): self.ClassDeclarations = ClassDeclarations + def getForwarddeclarations(self): return self.ForwardDeclarations + def setForwarddeclarations(self, ForwardDeclarations): self.ForwardDeclarations = ForwardDeclarations def getFathernamespace(self): return self.FatherNamespace def setFathernamespace(self, FatherNamespace): self.FatherNamespace = FatherNamespace def getDisablenotify(self): return self.DisableNotify @@ -350,6 +353,8 @@ class PythonExport: outfile.write('%s\n' % quote_xml(self.getCustomattributes())) showIndent(outfile, level) outfile.write('%s\n' % quote_xml(self.getClassdeclarations())) + showIndent(outfile, level) + outfile.write('%s\n' % quote_xml(self.getForwarddeclarations())) def exportLiteral(self, outfile, level, name_='PythonExport'): level += 1 self.exportLiteralAttributes(outfile, level, name_) @@ -428,6 +433,8 @@ class PythonExport: outfile.write('CustomAttributes=%s,\n' % quote_python(self.getCustomattributes())) showIndent(outfile, level) outfile.write('ClassDeclarations=%s,\n' % quote_python(self.getClassdeclarations())) + showIndent(outfile, level) + outfile.write('ForwardDeclarations=%s,\n' % quote_python(self.getForwarddeclarations())) def build(self, node_): attrs = node_.attributes self.buildAttributes(attrs) @@ -535,15 +542,23 @@ class PythonExport: for text__content_ in child_.childNodes: ClassDeclarations_ += text__content_.nodeValue self.ClassDeclarations = ClassDeclarations_ + elif child_.nodeType == Node.ELEMENT_NODE and \ + nodeName_ == 'ForwardDeclarations': + ForwardDeclarations_ = '' + for text__content_ in child_.childNodes: + ForwardDeclarations_ += text__content_.nodeValue + self.ForwardDeclarations = ForwardDeclarations_ # end class PythonExport class Methode: subclass = None - def __init__(self, Const=0, Name='', Keyword=0, Documentation=None, Parameter=None): + def __init__(self, Static=0, Const=0, Name='', Keyword=0, Class=0, Documentation=None, Parameter=None): + self.Static = Static self.Const = Const self.Name = Name self.Keyword = Keyword + self.Class = Class self.Documentation = Documentation if Parameter is None: self.Parameter = [] @@ -561,12 +576,16 @@ class Methode: def setParameter(self, Parameter): self.Parameter = Parameter def addParameter(self, value): self.Parameter.append(value) def insertParameter(self, index, value): self.Parameter[index] = value + def getStatic(self): return self.Static + def setStatic(self, Static): self.Static = Static def getConst(self): return self.Const def setConst(self, Const): self.Const = Const def getName(self): return self.Name def setName(self, Name): self.Name = Name def getKeyword(self): return self.Keyword def setKeyword(self, Keyword): self.Keyword = Keyword + def getClass(self): return self.Class + def setClass(self, Class): self.Class = Class def export(self, outfile, level, name_='Methode'): showIndent(outfile, level) outfile.write('<%s' % (name_, )) @@ -576,11 +595,15 @@ class Methode: showIndent(outfile, level) outfile.write('\n' % name_) def exportAttributes(self, outfile, level, name_='Methode'): + if self.getStatic() is not None: + outfile.write(' Static="%s"' % (self.getStatic(), )) if self.getConst() is not None: outfile.write(' Const="%s"' % (self.getConst(), )) outfile.write(' Name="%s"' % (self.getName(), )) if self.getKeyword() is not None: outfile.write(' Keyword="%s"' % (self.getKeyword(), )) + if self.getClass() is not None: + outfile.write(' Class="%s"' % (self.getClass(), )) def exportChildren(self, outfile, level, name_='Methode'): if self.Documentation: self.Documentation.export(outfile, level) @@ -591,12 +614,16 @@ class Methode: self.exportLiteralAttributes(outfile, level, name_) self.exportLiteralChildren(outfile, level, name_) def exportLiteralAttributes(self, outfile, level, name_): + showIndent(outfile, level) + outfile.write('Static = "%s",\n' % (self.getStatic(),)) showIndent(outfile, level) outfile.write('Const = "%s",\n' % (self.getConst(),)) showIndent(outfile, level) outfile.write('Name = "%s",\n' % (self.getName(),)) showIndent(outfile, level) outfile.write('Keyword = "%s",\n' % (self.getKeyword(),)) + showIndent(outfile, level) + outfile.write('Class = "%s",\n' % (self.getClass(),)) def exportLiteralChildren(self, outfile, level, name_): if self.Documentation: showIndent(outfile, level) @@ -623,6 +650,13 @@ class Methode: nodeName_ = child_.nodeName.split(':')[-1] self.buildChildren(child_, nodeName_) def buildAttributes(self, attrs): + if attrs.get('Static'): + if attrs.get('Static').value in ('true', '1'): + self.Static = 1 + elif attrs.get('Static').value in ('false', '0'): + self.Static = 0 + else: + raise ValueError('Bad boolean attribute (Static)') if attrs.get('Const'): if attrs.get('Const').value in ('true', '1'): self.Const = 1 @@ -639,6 +673,13 @@ class Methode: self.Keyword = 0 else: raise ValueError('Bad boolean attribute (Keyword)') + if attrs.get('Class'): + if attrs.get('Class').value in ('true', '1'): + self.Class = 1 + elif attrs.get('Class').value in ('false', '0'): + self.Class = 0 + else: + raise ValueError('Bad boolean attribute (Class)') def buildChildren(self, child_, nodeName_): if child_.nodeType == Node.ELEMENT_NODE and \ nodeName_ == 'Documentation': @@ -1920,6 +1961,14 @@ class SaxGeneratemodelHandler(handler.ContentHandler): done = 1 elif name == 'Methode': obj = Methode.factory() + val = attrs.get('Static', None) + if val is not None: + if val in ('true', '1'): + obj.setStatic(1) + elif val in ('false', '0'): + obj.setStatic(0) + else: + self.reportError('"Static" attribute must be boolean ("true", "1", "false", "0")') val = attrs.get('Const', None) if val is not None: if val in ('true', '1'): @@ -1939,6 +1988,14 @@ class SaxGeneratemodelHandler(handler.ContentHandler): obj.setKeyword(0) else: self.reportError('"Keyword" attribute must be boolean ("true", "1", "false", "0")') + val = attrs.get('Class', None) + if val is not None: + if val in ('true', '1'): + obj.setClass(1) + elif val in ('false', '0'): + obj.setClass(0) + else: + self.reportError('"Class" attribute must be boolean ("true", "1", "false", "0")') stackObj = SaxStackElement('Methode', obj) self.stack.append(stackObj) done = 1 @@ -2062,6 +2119,10 @@ class SaxGeneratemodelHandler(handler.ContentHandler): stackObj = SaxStackElement('ClassDeclarations', None) self.stack.append(stackObj) done = 1 + elif name == 'ForwardDeclarations': + stackObj = SaxStackElement('ForwardDeclarations', None) + self.stack.append(stackObj) + done = 1 elif name == 'Dependencies': obj = Dependencies.factory() stackObj = SaxStackElement('Dependencies', obj) @@ -2185,6 +2246,12 @@ class SaxGeneratemodelHandler(handler.ContentHandler): self.stack[-2].obj.setClassdeclarations(content) self.stack.pop() done = 1 + elif name == 'ForwardDeclarations': + if len(self.stack) >= 2: + content = self.stack[-1].content + self.stack[-2].obj.setForwarddeclarations(content) + self.stack.pop() + done = 1 elif name == 'Dependencies': if len(self.stack) >= 2: self.stack[-2].obj.setDependencies(self.stack[-1].obj) diff --git a/src/Tools/generateTemplates/templateClassPyExport.py b/src/Tools/generateTemplates/templateClassPyExport.py index 95f5409017..81a575e661 100644 --- a/src/Tools/generateTemplates/templateClassPyExport.py +++ b/src/Tools/generateTemplates/templateClassPyExport.py @@ -45,6 +45,11 @@ class TemplateClassPyExport (template.ModelTemplate): #include <@self.export.Include@> #include ++ if(self.export.ForwardDeclarations != ""): +// Forward declarations +@self.export.ForwardDeclarations@ +- + namespace @self.export.Namespace@ { @@ -96,14 +101,18 @@ public: + if i.Keyword: /// callback for the @i.Name@() method static PyObject * staticCallback_@i.Name@ (PyObject *self, PyObject *args, PyObject *kwd); ++ if not i.Static and not i.Class: /// implementer for the @i.Name@() method PyObject* @i.Name@(PyObject *args, PyObject *kwd); +- = else: /// callback for the @i.Name@() method static PyObject * staticCallback_@i.Name@ (PyObject *self, PyObject *args); ++ if not i.Static and not i.Class: /// implementer for the @i.Name@() method PyObject* @i.Name@(PyObject *args); - +- - //@} @@ -231,7 +240,7 @@ public: /// getter for the object handled by this class @self.export.TwinPointer@ *get@self.export.Twin@Ptr(void) const; -+ if(self.export.ClassDeclarations != None): ++ if(self.export.ClassDeclarations != ""): /** @name additional declarations and methods for the wrapper class */ //@{ @self.export.ClassDeclarations@ @@ -352,8 +361,22 @@ PyMethodDef @self.export.Name@::Methods[] = { + for i in self.export.Methode: {"@i.Name@", + if i.Keyword: ++ if i.Class: + reinterpret_cast(reinterpret_cast( staticCallback_@i.Name@ )), + METH_VARARGS|METH_KEYWORDS|METH_CLASS, += elif i.Static: + reinterpret_cast(reinterpret_cast( staticCallback_@i.Name@ )), + METH_VARARGS|METH_KEYWORDS|METH_STATIC, += else: reinterpret_cast(reinterpret_cast( staticCallback_@i.Name@ )), METH_VARARGS|METH_KEYWORDS, +- += elif i.Class: + reinterpret_cast(reinterpret_cast( staticCallback_@i.Name@ )), + METH_VARARGS|METH_CLASS, += elif i.Static: + reinterpret_cast(reinterpret_cast( staticCallback_@i.Name@ )), + METH_VARARGS|METH_STATIC, = else: reinterpret_cast( staticCallback_@i.Name@ ), METH_VARARGS, @@ -510,6 +533,7 @@ PyGetSetDef @self.export.Name@::GetterSetter[] = { // @i.Name@() callback and implementer // PyObject* @self.export.Name@::@i.Name@(PyObject *args){}; // has to be implemented in @self.export.Name@Imp.cpp ++ if not i.Static and not i.Class: + if i.Keyword: PyObject * @self.export.Name@::staticCallback_@i.Name@ (PyObject *self, PyObject *args, PyObject * kwd) = else: @@ -587,6 +611,7 @@ PyObject * @self.export.Name@::staticCallback_@i.Name@ (PyObject *self, PyObject #endif } +- - + for i in self.export.Attribute: // @i.Name@() callback and implementer @@ -869,6 +894,7 @@ std::string @self.export.Name@::representation(void) const } + for i in self.export.Methode: ++ if not i.Static and not i.Class: + if i.Keyword: PyObject* @self.export.Name@::@i.Name@(PyObject *args, PyObject *kwds) = else: @@ -879,6 +905,7 @@ PyObject* @self.export.Name@::@i.Name@(PyObject *args) return 0; } - +- + if (self.export.NumberProtocol): PyObject* @self.export.Name@::number_add_handler(PyObject* /*self*/, PyObject* /*other*/) @@ -1186,6 +1213,7 @@ int @self.export.Name@::finalization() + for i in self.export.Methode: ++ if not i.Static and not i.Class: + if i.Keyword: PyObject* @self.export.Name@::@i.Name@(PyObject * /*args*/, PyObject * /*kwds*/) = else: @@ -1196,6 +1224,7 @@ PyObject* @self.export.Name@::@i.Name@(PyObject * /*args*/) return 0; } - +- + if (self.export.NumberProtocol): PyObject* @self.export.Name@::number_add_handler(PyObject *self, PyObject *other) From 79ef4be9de47a7f9b38f11bee6a39a53cabf1710 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 13 Nov 2019 00:43:23 +0100 Subject: [PATCH 3/4] export typeid system to Python --- src/App/Application.cpp | 2 + src/Base/CMakeLists.txt | 3 + src/Base/TypePy.xml | 81 +++++++++++++++++++++ src/Base/TypePyImp.cpp | 151 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 237 insertions(+) create mode 100644 src/Base/TypePy.xml create mode 100644 src/Base/TypePyImp.cpp diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 46b81602df..3fdf30eecd 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -81,6 +81,7 @@ #include #include #include +#include #include "GeoFeature.h" #include "FeatureTest.h" @@ -303,6 +304,7 @@ Application::Application(std::map &mConfig) Base::Interpreter().addType(&Base::RotationPy ::Type,pBaseModule,"Rotation"); Base::Interpreter().addType(&Base::AxisPy ::Type,pBaseModule,"Axis"); Base::Interpreter().addType(&Base::CoordinateSystemPy::Type,pBaseModule,"CoordinateSystem"); + Base::Interpreter().addType(&Base::TypePy ::Type,pBaseModule,"TypeId"); Base::Interpreter().addType(&App::MaterialPy::Type, pAppModule, "Material"); diff --git a/src/Base/CMakeLists.txt b/src/Base/CMakeLists.txt index be5bbc4944..0654f581de 100644 --- a/src/Base/CMakeLists.txt +++ b/src/Base/CMakeLists.txt @@ -78,6 +78,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") list(APPEND FreeCADBase_LIBS -lutil -ldl) endif() +generate_from_xml(TypePy) generate_from_xml(BaseClassPy) generate_from_xml(BoundBoxPy) generate_from_xml(CoordinateSystemPy) @@ -173,6 +174,7 @@ SET(FreeCADBase_XML_SRCS RotationPy.xml VectorPy.xml QuantityPy.xml + TypePy.xml UnitPy.xml ) SOURCE_GROUP("XML" FILES ${FreeCADBase_XML_SRCS}) @@ -276,6 +278,7 @@ SET(FreeCADBase_CPP_SRCS Tools2D.cpp Translate.cpp Type.cpp + TypePyImp.cpp Uuid.cpp Vector3D.cpp VectorPyImp.cpp diff --git a/src/Base/TypePy.xml b/src/Base/TypePy.xml new file mode 100644 index 0000000000..b1408e2e6d --- /dev/null +++ b/src/Base/TypePy.xml @@ -0,0 +1,81 @@ + + + + +namespace Base { + typedef Type BaseType; +} + + + This is the Type class + This is the Type class + + + + Returns a type object by name + + + + + Returns a type object by key + + + + + Returns the number of type ids + + + + + Returns an invalid type id + + + + + Returns the parent type id + + + + + Checks if the type id is invalid + + + + + Returns true if given type is a father + + + + + Returns all descendants + + + + + The name of the type id + + + + + + The key of the type id + + + + + + Module in which this class is defined + + + + + diff --git a/src/Base/TypePyImp.cpp b/src/Base/TypePyImp.cpp new file mode 100644 index 0000000000..af9b2b2a77 --- /dev/null +++ b/src/Base/TypePyImp.cpp @@ -0,0 +1,151 @@ +/*************************************************************************** + * Copyright (c) 2019 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 51 Franklin Street, * + * Fifth Floor, Boston, MA 02110-1301, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#include "Type.h" +#include "TypePy.h" +#include "TypePy.cpp" + +using namespace Base; + +// returns a string which represent the object e.g. when printed in python +std::string TypePy::representation(void) const +{ + std::stringstream str; + str << "getName() << "'>"; + return str.str(); +} + +PyObject* TypePy::staticCallback_fromName (PyObject * /*self*/, PyObject *args) +{ + const char *name; + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + Base::Type type = Base::Type::fromName(name); + return new TypePy(new Base::Type(type)); +} + +PyObject* TypePy::staticCallback_fromKey (PyObject * /*self*/, PyObject *args) +{ + unsigned int index; + if (!PyArg_ParseTuple(args, "I", &index)) + return NULL; + + Base::Type type = Base::Type::fromKey(index); + return new TypePy(new Base::Type(type)); +} + +PyObject* TypePy::staticCallback_getNumTypes (PyObject * /*self*/, PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; + + int num = Base::Type::getNumTypes(); + return PyLong_FromLong(num); +} + +PyObject* TypePy::staticCallback_getBadType (PyObject * /*self*/, PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; + + Base::Type type = Base::Type::badType(); + return new TypePy(new Base::Type(type)); +} + +PyObject* TypePy::getParent(PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; + + Base::Type type = getBaseTypePtr()->getParent(); + return new TypePy(new Base::Type(type)); +} + +PyObject* TypePy::isBad(PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; + + bool v = getBaseTypePtr()->isBad(); + return PyBool_FromLong(v ? 1 : 0); +} + +PyObject* TypePy::isDerivedFrom(PyObject *args) +{ + char *name; + if (!PyArg_ParseTuple(args, "s", &name)) // convert args: Python->C + return NULL; // NULL triggers exception + + Base::Type type = Base::Type::fromName(name); + bool v = (type != Base::Type::badType() && getBaseTypePtr()->isDerivedFrom(type)); + return PyBool_FromLong(v ? 1 : 0); +} + +PyObject* TypePy::getAllDerivedFrom(PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) // convert args: Python->C + return NULL; // NULL triggers exception + + std::vector ary; + Base::Type::getAllDerivedFrom(*getBaseTypePtr(), ary); + Py::List res; + for (std::vector::iterator it = ary.begin(); it != ary.end(); ++it) + res.append(Py::String(it->getName())); + return Py::new_reference_to(res); +} + +Py::String TypePy::getName(void) const +{ + return Py::String(std::string(getBaseTypePtr()->getName())); +} + +Py::Long TypePy::getKey(void) const +{ + return Py::Long(static_cast(getBaseTypePtr()->getKey())); +} + +Py::String TypePy::getModule(void) const +{ + std::string module(getBaseTypePtr()->getName()); + std::string::size_type pos = module.find_first_of("::"); + + if (pos != std::string::npos) + module = std::string(module, 0, pos); + else + module.clear(); + + return Py::String(module); +} + +PyObject *TypePy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int TypePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} From d953a44eaf0105d137f5c918262582a564668885 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 13 Nov 2019 00:57:21 +0100 Subject: [PATCH 4/4] declare getAllDerivedFrom as static method --- src/Base/TypePy.xml | 2 +- src/Base/TypePyImp.cpp | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Base/TypePy.xml b/src/Base/TypePy.xml index b1408e2e6d..ce5c6efa3b 100644 --- a/src/Base/TypePy.xml +++ b/src/Base/TypePy.xml @@ -54,7 +54,7 @@ namespace Base { Returns true if given type is a father - + Returns all descendants diff --git a/src/Base/TypePyImp.cpp b/src/Base/TypePyImp.cpp index af9b2b2a77..c6f6e065ed 100644 --- a/src/Base/TypePyImp.cpp +++ b/src/Base/TypePyImp.cpp @@ -95,22 +95,24 @@ PyObject* TypePy::isBad(PyObject *args) PyObject* TypePy::isDerivedFrom(PyObject *args) { - char *name; - if (!PyArg_ParseTuple(args, "s", &name)) // convert args: Python->C - return NULL; // NULL triggers exception + const char *name; + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; Base::Type type = Base::Type::fromName(name); bool v = (type != Base::Type::badType() && getBaseTypePtr()->isDerivedFrom(type)); return PyBool_FromLong(v ? 1 : 0); } -PyObject* TypePy::getAllDerivedFrom(PyObject *args) +PyObject* TypePy::staticCallback_getAllDerivedFrom(PyObject* /*self*/, PyObject *args) { - if (!PyArg_ParseTuple(args, "")) // convert args: Python->C - return NULL; // NULL triggers exception - + const char *name; + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + Base::Type type = Base::Type::fromName(name); std::vector ary; - Base::Type::getAllDerivedFrom(*getBaseTypePtr(), ary); + Base::Type::getAllDerivedFrom(type, ary); Py::List res; for (std::vector::iterator it = ary.begin(); it != ary.end(); ++it) res.append(Py::String(it->getName()));