"Professional CMake" book suggest the following: "Targets should build successfully with or without compiler support for precompiled headers. It should be considered an optimization, not a requirement. In particular, do not explicitly include a precompile header (e.g. stdafx.h) in the source code, let CMake force-include an automatically generated precompile header on the compiler command line instead. This is more portable across the major compilers and is likely to be easier to maintain. It will also avoid warnings being generated from certain code checking tools like iwyu (include what you use)." Therefore, removed the "#include <PreCompiled.h>" from sources, also there is no need for the "#ifdef _PreComp_" anymore
398 lines
14 KiB
C++
398 lines
14 KiB
C++
/****************************************************************************
|
|
* Copyright (c) 2017 Zheng Lei (realthunder) <realthunder.dev@gmail.com> *
|
|
* *
|
|
* 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 <Base/BoundBoxPy.h>
|
|
#include <Base/MatrixPy.h>
|
|
#include <App/DocumentObjectPy.h>
|
|
#include <App/MaterialPy.h>
|
|
|
|
#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 "<Link view>";
|
|
}
|
|
|
|
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<App::MaterialPy*>(pyObj)->getMaterialPtr());
|
|
Py_Return;
|
|
}
|
|
if(PyDict_Check(pyObj)) {
|
|
PyObject *key, *value;
|
|
Py_ssize_t pos = 0;
|
|
std::map<int,App::Material*> materials;
|
|
while(PyDict_Next(pyObj, &pos, &key, &value)) {
|
|
Py::Long 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<App::MaterialPy*>(value)->getMaterialPtr();
|
|
}
|
|
for(auto &v : materials)
|
|
lv->setMaterial(v.first,v.second);
|
|
Py_Return;
|
|
}
|
|
if(PySequence_Check(pyObj)) {
|
|
Py::Sequence seq(pyObj);
|
|
std::vector<App::Material*> materials;
|
|
materials.resize(seq.size(),nullptr);
|
|
for(Py_ssize_t i=0;i<seq.size();++i) {
|
|
PyObject* item = seq[i].ptr();
|
|
if(item == Py_None) continue;
|
|
if(!PyObject_TypeCheck(item,&App::MaterialPy::Type)) {
|
|
PyErr_SetString(PyExc_TypeError, "exepcting a type of material");
|
|
return nullptr;
|
|
}
|
|
materials[i] = static_cast<App::MaterialPy*>(item)->getMaterialPtr();
|
|
}
|
|
for(size_t i=0;i<materials.size();++i)
|
|
lv->setMaterial(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<Base::MatrixPy*>(pyObj)->getMatrixPtr());
|
|
Py_Return;
|
|
}
|
|
if(PyDict_Check(pyObj)) {
|
|
PyObject *key, *value;
|
|
Py_ssize_t pos = 0;
|
|
std::map<int,Base::Matrix4D*> mat;
|
|
while(PyDict_Next(pyObj, &pos, &key, &value)) {
|
|
Py::Long 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<Base::MatrixPy*>(value)->getMatrixPtr();
|
|
}
|
|
for(auto &v : mat)
|
|
lv->setTransform(v.first,*v.second);
|
|
Py_Return;
|
|
}
|
|
if(PySequence_Check(pyObj)) {
|
|
Py::Sequence seq(pyObj);
|
|
std::vector<Base::Matrix4D*> mat;
|
|
mat.resize(seq.size(),nullptr);
|
|
for(Py_ssize_t i=0;i<seq.size();++i) {
|
|
PyObject* item = seq[i].ptr();
|
|
if(!PyObject_TypeCheck(item,&Base::MatrixPy::Type)) {
|
|
PyErr_SetString(PyExc_TypeError, "exepcting a type of Matrix");
|
|
return nullptr;
|
|
}
|
|
mat[i] = static_cast<Base::MatrixPy*>(item)->getMatrixPtr();
|
|
}
|
|
for(size_t i=0;i<mat.size();++i)
|
|
lv->setTransform(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<LinkView::SnapshotType>(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<App::DocumentObjectPy*>(pyObj)->getDocumentObjectPtr();
|
|
else if(PyObject_TypeCheck(pyObj,&ViewProviderDocumentObjectPy::Type))
|
|
vpd = static_cast<ViewProviderDocumentObjectPy*>(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<ViewProviderDocumentObjectPy*>(
|
|
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<SoPickedPoint*>(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<SoPath*>(ptr);
|
|
if(!pPath)
|
|
throw Py::TypeError("type must be of coin.SoPath");
|
|
PY_TRY{
|
|
SoDetail *det = nullptr;
|
|
getLinkViewPtr()->linkGetDetailPath(sub,static_cast<SoFullPath*>(pPath),det);
|
|
if(!det)
|
|
Py_Return;
|
|
return Base::Interpreter().createSWIGPointerObj("pivy.coin", "SoDetail *", static_cast<void*>(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<ViewProviderDocumentObjectPy*>(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;i<linked->getSize();++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;i<linked->getSize();++i)
|
|
linked->setElementVisible(i,i>=(int)vis.size()||vis[i]);
|
|
}
|
|
|
|
PyObject* LinkViewPy::getChildren(PyObject *args) const {
|
|
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::Long LinkViewPy::getCount() const {
|
|
return Py::Long(getLinkViewPtr()->getSize());
|
|
}
|
|
|
|
void LinkViewPy::setCount(Py::Long count) {
|
|
try {
|
|
getLinkViewPtr()->setSize((int)count);
|
|
} catch (const Base::Exception& e) {
|
|
throw Py::RuntimeError(e.what());
|
|
}
|
|
}
|