/**************************************************************************** * Copyright (c) 2017 Zheng Lei (realthunder) * * * * 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., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ****************************************************************************/ #include "PreCompiled.h" #include #include #include #include #include "LinkViewPy.h" #include "LinkViewPy.cpp" #include "ViewProviderDocumentObjectPy.h" using namespace Gui; PyObject *LinkViewPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper { return new LinkViewPy(new LinkView); } int LinkViewPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/) { return 0; } // returns a string which represent the object e.g. when printed in python std::string LinkViewPy::representation() const { return ""; } PyObject* LinkViewPy::reset(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return nullptr; PY_TRY { auto lv = getLinkViewPtr(); lv->setSize(0); lv->setLink(nullptr); Py_Return; } PY_CATCH; } PyObject* LinkViewPy::setMaterial(PyObject *args) { PyObject *pyObj; if (!PyArg_ParseTuple(args, "O", &pyObj)) return nullptr; PY_TRY { auto lv = getLinkViewPtr(); if(pyObj == Py_None) { lv->setMaterial(-1,nullptr); Py_Return; } if(PyObject_TypeCheck(pyObj,&App::MaterialPy::Type)) { lv->setMaterial(-1,static_cast(pyObj)->getMaterialPtr()); Py_Return; } if(PyDict_Check(pyObj)) { PyObject *key, *value; Py_ssize_t pos = 0; std::map materials; while(PyDict_Next(pyObj, &pos, &key, &value)) { Py::Int idx(key); if(value == Py_None) materials[(int)idx] = nullptr; else if(!PyObject_TypeCheck(value,&App::MaterialPy::Type)) { PyErr_SetString(PyExc_TypeError, "exepcting a type of material"); return nullptr; }else materials[(int)idx] = static_cast(value)->getMaterialPtr(); } for(auto &v : materials) lv->setMaterial(v.first,v.second); Py_Return; } if(PySequence_Check(pyObj)) { Py::Sequence seq(pyObj); std::vector materials; materials.resize(seq.size(),nullptr); for(Py_ssize_t i=0;i(item)->getMaterialPtr(); } for(size_t i=0;isetMaterial(i,materials[i]); Py_Return; } PyErr_SetString(PyExc_TypeError, "exepcting a type of Material, [Material,...] or {Int:Material,}"); return nullptr; } PY_CATCH; } PyObject* LinkViewPy::setTransform(PyObject *args) { PyObject *pyObj; if (!PyArg_ParseTuple(args, "O", &pyObj)) return nullptr; PY_TRY { auto lv = getLinkViewPtr(); if(PyObject_TypeCheck(pyObj,&Base::MatrixPy::Type)) { lv->setTransform(-1,*static_cast(pyObj)->getMatrixPtr()); Py_Return; } if(PyDict_Check(pyObj)) { PyObject *key, *value; Py_ssize_t pos = 0; std::map mat; while(PyDict_Next(pyObj, &pos, &key, &value)) { Py::Int idx(key); if(!PyObject_TypeCheck(value,&Base::MatrixPy::Type)) { PyErr_SetString(PyExc_TypeError, "exepcting a type of Matrix"); return nullptr; }else mat[(int)idx] = static_cast(value)->getMatrixPtr(); } for(auto &v : mat) lv->setTransform(v.first,*v.second); Py_Return; } if(PySequence_Check(pyObj)) { Py::Sequence seq(pyObj); std::vector mat; mat.resize(seq.size(),nullptr); for(Py_ssize_t i=0;i(item)->getMatrixPtr(); } for(size_t i=0;isetTransform(i,*mat[i]); Py_Return; } PyErr_SetString(PyExc_TypeError, "exepcting a type of Matrix, [Matrix,...] or {Int:Matrix,...}"); return nullptr; } PY_CATCH; } PyObject* LinkViewPy::setType(PyObject *args) { short type; PyObject *sublink = Py_True; if (!PyArg_ParseTuple(args, "h|O!", &type, &PyBool_Type, &sublink)) return nullptr; PY_TRY{ getLinkViewPtr()->setNodeType((LinkView::SnapshotType)type, Base::asBoolean(sublink)); Py_Return; } PY_CATCH; } PyObject* LinkViewPy::setChildren(PyObject *args) { PyObject *pyObj; PyObject *pyVis = Py_None; short type=0; if (!PyArg_ParseTuple(args, "O|Os",&pyObj,&pyVis,&type)) return nullptr; PY_TRY{ App::PropertyBoolList vis; App::PropertyLinkList links; if(pyObj!=Py_None) links.setPyObject(pyObj); if(pyVis!=Py_None) vis.setPyObject(pyVis); getLinkViewPtr()->setChildren(links.getValue(),vis.getValue(),static_cast(type)); Py_Return; } PY_CATCH; } PyObject* LinkViewPy::setLink(PyObject *args) { PyObject *pyObj; PyObject *pySubName = Py_None; if (!PyArg_ParseTuple(args, "O|O",&pyObj,&pySubName)) return nullptr; PY_TRY { ViewProviderDocumentObject *vpd = nullptr; App::DocumentObject *obj = nullptr; if(pyObj!=Py_None) { if(PyObject_TypeCheck(pyObj,&App::DocumentObjectPy::Type)) obj = static_cast(pyObj)->getDocumentObjectPtr(); else if(PyObject_TypeCheck(pyObj,&ViewProviderDocumentObjectPy::Type)) vpd = static_cast(pyObj)->getViewProviderDocumentObjectPtr(); else { PyErr_SetString(PyExc_TypeError, "exepcting a type of DocumentObject or ViewProviderDocumentObject"); return nullptr; } } // Too lazy to parse the argument... App::PropertyStringList prop; if(pySubName!=Py_None) prop.setPyObject(pySubName); if(obj) getLinkViewPtr()->setLink(obj,prop.getValue()); else getLinkViewPtr()->setLinkViewObject(vpd,prop.getValue()); Py_Return; } PY_CATCH; } Py::Object LinkViewPy::getOwner() const { auto owner = getLinkViewPtr()->getOwner(); if(!owner) return Py::Object(); return Py::Object(owner->getPyObject(),true); } void LinkViewPy::setOwner(Py::Object owner) { ViewProviderDocumentObject *vp = nullptr; if(!owner.isNone()) { if(!PyObject_TypeCheck(owner.ptr(),&ViewProviderDocumentObjectPy::Type)) throw Py::TypeError("exepcting the owner to be of ViewProviderDocumentObject"); vp = static_cast( owner.ptr())->getViewProviderDocumentObjectPtr(); } getLinkViewPtr()->setOwner(vp); } Py::Object LinkViewPy::getLinkedView() const { auto linked = getLinkViewPtr()->getLinkedView(); if(!linked) return Py::Object(); return Py::Object(linked->getPyObject(),true); } Py::Object LinkViewPy::getSubNames() const { const auto &subs = getLinkViewPtr()->getSubNames(); if(subs.empty()) return Py::Object(); Py::Tuple ret(subs.size()); int i=0; for(auto &s : subs) ret.setItem(i++,Py::String(s.c_str())); return ret; } PyObject* LinkViewPy::getElementPicked(PyObject* args) { PyObject *obj; if (!PyArg_ParseTuple(args, "O",&obj)) return nullptr; void *ptr = nullptr; Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoPickedPoint *", obj, &ptr, 0); auto pp = static_cast(ptr); if(!pp) throw Py::TypeError("type must be of coin.SoPickedPoint"); PY_TRY{ std::string name; if(!getLinkViewPtr()->linkGetElementPicked(pp,name)) Py_Return; return Py::new_reference_to(Py::String(name)); }PY_CATCH } PyObject* LinkViewPy::getDetailPath(PyObject* args) { const char *sub; PyObject *path; if (!PyArg_ParseTuple(args, "sO",&sub,&path)) return nullptr; void *ptr = nullptr; Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoPath *", path, &ptr, 0); auto pPath = static_cast(ptr); if(!pPath) throw Py::TypeError("type must be of coin.SoPath"); PY_TRY{ SoDetail *det = nullptr; getLinkViewPtr()->linkGetDetailPath(sub,static_cast(pPath),det); if(!det) Py_Return; return Base::Interpreter().createSWIGPointerObj("pivy.coin", "SoDetail *", static_cast(det), 0); }PY_CATCH } PyObject* LinkViewPy::getBoundBox(PyObject* args) { PyObject *vobj = Py_None; if (!PyArg_ParseTuple(args, "O",&vobj)) return nullptr; PY_TRY { Base::PyTypeCheck(&vobj, &ViewProviderDocumentObjectPy::Type); ViewProviderDocumentObject *vpd = nullptr; if (vobj) vpd = static_cast(vobj)->getViewProviderDocumentObjectPtr(); auto bbox = getLinkViewPtr()->getBoundBox(vpd); Py::Object ret(new Base::BoundBoxPy(new Base::BoundBox3d(bbox))); return Py::new_reference_to(ret); } PY_CATCH } PyObject *LinkViewPy::getCustomAttributes(const char*) const { return nullptr; } int LinkViewPy::setCustomAttributes(const char*, PyObject*) { return 0; } Py::Object LinkViewPy::getRootNode() const { try { SoNode* node = getLinkViewPtr()->getLinkRoot(); PyObject* Ptr = Base::Interpreter().createSWIGPointerObj("pivy.coin","SoSeparator *", node, 1); node->ref(); return Py::Object(Ptr, true); } catch (const Base::Exception& e) { throw Py::RuntimeError(e.what()); } } Py::Object LinkViewPy::getVisibilities() const { auto linked = getLinkViewPtr(); if(!linked->getSize()) return Py::Object(); Py::Tuple ret(linked->getSize()); for(int i=0;igetSize();++i) ret.setItem(i,Py::Boolean(linked->isElementVisible(i))); return ret; } void LinkViewPy::setVisibilities(Py::Object value) { App::PropertyBoolList v; if(!value.isNone()) v.setPyObject(value.ptr()); auto linked = getLinkViewPtr(); const auto &vis = v.getValue(); for(int i=0;igetSize();++i) linked->setElementVisible(i,i>=(int)vis.size()||vis[i]); } PyObject* LinkViewPy::getChildren(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return nullptr; auto children = getLinkViewPtr()->getChildren(); if(children.empty()) Py_Return; Py::Tuple ret(children.size()); int i=0; for(auto vp : children) ret.setItem(i++,Py::Object(vp->getPyObject(),true)); return Py::new_reference_to(ret); } Py::Int LinkViewPy::getCount() const { return Py::Int(getLinkViewPtr()->getSize()); } void LinkViewPy::setCount(Py::Int count) { try { getLinkViewPtr()->setSize((int)count); } catch (const Base::Exception& e) { throw Py::RuntimeError(e.what()); } }