FreeCAD

Форк
0
/
LinkViewPyImp.cpp 
397 строк · 13.7 Кб
1
/****************************************************************************
2
 *   Copyright (c) 2017 Zheng Lei (realthunder) <realthunder.dev@gmail.com> *
3
 *                                                                          *
4
 *   This file is part of the FreeCAD CAx development system.               *
5
 *                                                                          *
6
 *   This library is free software; you can redistribute it and/or          *
7
 *   modify it under the terms of the GNU Library General Public            *
8
 *   License as published by the Free Software Foundation; either           *
9
 *   version 2 of the License, or (at your option) any later version.       *
10
 *                                                                          *
11
 *   This library  is distributed in the hope that it will be useful,       *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
14
 *   GNU Library General Public License for more details.                   *
15
 *                                                                          *
16
 *   You should have received a copy of the GNU Library General Public      *
17
 *   License along with this library; see the file COPYING.LIB. If not,     *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,          *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                 *
20
 *                                                                          *
21
 ****************************************************************************/
22

23
#include "PreCompiled.h"
24

25
#include <Base/BoundBoxPy.h>
26
#include <Base/MatrixPy.h>
27
#include <App/DocumentObjectPy.h>
28
#include <App/MaterialPy.h>
29

30
#include "LinkViewPy.h"
31
#include "LinkViewPy.cpp"
32
#include "ViewProviderDocumentObjectPy.h"
33

34

35
using namespace Gui;
36

37
PyObject *LinkViewPy::PyMake(struct _typeobject *, PyObject *, PyObject *)  // Python wrapper
38
{
39
    return new LinkViewPy(new LinkView);
40
}
41

42
int LinkViewPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
43
{
44
    return 0;
45
}
46

47

48
// returns a string which represent the object e.g. when printed in python
49
std::string LinkViewPy::representation() const
50
{
51
    return "<Link view>";
52
}
53

54
PyObject* LinkViewPy::reset(PyObject *args) {
55
    if (!PyArg_ParseTuple(args, ""))
56
        return nullptr;
57

58
    PY_TRY {
59
        auto lv = getLinkViewPtr();
60
        lv->setSize(0);
61
        lv->setLink(nullptr);
62
        Py_Return;
63
    } PY_CATCH;
64
}
65

66
PyObject* LinkViewPy::setMaterial(PyObject *args) {
67
    PyObject *pyObj;
68
    if (!PyArg_ParseTuple(args, "O", &pyObj))
69
        return nullptr;
70

71
    PY_TRY {
72
        auto lv = getLinkViewPtr();
73
        if(pyObj == Py_None) {
74
            lv->setMaterial(-1,nullptr);
75
            Py_Return;
76
        }
77
        if(PyObject_TypeCheck(pyObj,&App::MaterialPy::Type)) {
78
            lv->setMaterial(-1,static_cast<App::MaterialPy*>(pyObj)->getMaterialPtr());
79
            Py_Return;
80
        }
81
        if(PyDict_Check(pyObj)) {
82
            PyObject *key, *value;
83
            Py_ssize_t pos = 0;
84
            std::map<int,App::Material*> materials;
85
            while(PyDict_Next(pyObj, &pos, &key, &value)) {
86
                Py::Int idx(key);
87
                if(value == Py_None)
88
                    materials[(int)idx] = nullptr;
89
                else if(!PyObject_TypeCheck(value,&App::MaterialPy::Type)) {
90
                    PyErr_SetString(PyExc_TypeError, "exepcting a type of material");
91
                    return nullptr;
92
                }else
93
                    materials[(int)idx] = static_cast<App::MaterialPy*>(value)->getMaterialPtr();
94
            }
95
            for(auto &v : materials)
96
                lv->setMaterial(v.first,v.second);
97
            Py_Return;
98
        }
99
        if(PySequence_Check(pyObj)) {
100
            Py::Sequence seq(pyObj);
101
            std::vector<App::Material*> materials;
102
            materials.resize(seq.size(),nullptr);
103
            for(Py_ssize_t i=0;i<seq.size();++i) {
104
                PyObject* item = seq[i].ptr();
105
                if(item == Py_None) continue;
106
                if(!PyObject_TypeCheck(item,&App::MaterialPy::Type)) {
107
                    PyErr_SetString(PyExc_TypeError, "exepcting a type of material");
108
                    return nullptr;
109
                }
110
                materials[i] = static_cast<App::MaterialPy*>(item)->getMaterialPtr();
111
            }
112
            for(size_t i=0;i<materials.size();++i)
113
                lv->setMaterial(i,materials[i]);
114
            Py_Return;
115
        }
116

117
        PyErr_SetString(PyExc_TypeError, "exepcting a type of Material, [Material,...] or {Int:Material,}");
118
        return nullptr;
119
    } PY_CATCH;
120
}
121

122
PyObject* LinkViewPy::setTransform(PyObject *args) {
123
    PyObject *pyObj;
124
    if (!PyArg_ParseTuple(args, "O", &pyObj))
125
        return nullptr;
126

127
    PY_TRY {
128
        auto lv = getLinkViewPtr();
129
        if(PyObject_TypeCheck(pyObj,&Base::MatrixPy::Type)) {
130
            lv->setTransform(-1,*static_cast<Base::MatrixPy*>(pyObj)->getMatrixPtr());
131
            Py_Return;
132
        }
133
        if(PyDict_Check(pyObj)) {
134
            PyObject *key, *value;
135
            Py_ssize_t pos = 0;
136
            std::map<int,Base::Matrix4D*> mat;
137
            while(PyDict_Next(pyObj, &pos, &key, &value)) {
138
                Py::Int idx(key);
139
                if(!PyObject_TypeCheck(value,&Base::MatrixPy::Type)) {
140
                    PyErr_SetString(PyExc_TypeError, "exepcting a type of Matrix");
141
                    return nullptr;
142
                }else
143
                    mat[(int)idx] = static_cast<Base::MatrixPy*>(value)->getMatrixPtr();
144
            }
145
            for(auto &v : mat)
146
                lv->setTransform(v.first,*v.second);
147
            Py_Return;
148
        }
149
        if(PySequence_Check(pyObj)) {
150
            Py::Sequence seq(pyObj);
151
            std::vector<Base::Matrix4D*> mat;
152
            mat.resize(seq.size(),nullptr);
153
            for(Py_ssize_t i=0;i<seq.size();++i) {
154
                PyObject* item = seq[i].ptr();
155
                if(!PyObject_TypeCheck(item,&Base::MatrixPy::Type)) {
156
                    PyErr_SetString(PyExc_TypeError, "exepcting a type of Matrix");
157
                    return nullptr;
158
                }
159
                mat[i] = static_cast<Base::MatrixPy*>(item)->getMatrixPtr();
160
            }
161
            for(size_t i=0;i<mat.size();++i)
162
                lv->setTransform(i,*mat[i]);
163
            Py_Return;
164
        }
165

166
        PyErr_SetString(PyExc_TypeError, "exepcting a type of Matrix, [Matrix,...] or {Int:Matrix,...}");
167
        return nullptr;
168
    } PY_CATCH;
169
}
170

171
PyObject* LinkViewPy::setType(PyObject *args) {
172
    short type;
173
    PyObject *sublink = Py_True;
174
    if (!PyArg_ParseTuple(args, "h|O!", &type, &PyBool_Type, &sublink))
175
        return nullptr;
176

177
    PY_TRY{
178
        getLinkViewPtr()->setNodeType((LinkView::SnapshotType)type, Base::asBoolean(sublink));
179
        Py_Return;
180
    } PY_CATCH;
181
}
182

183
PyObject*  LinkViewPy::setChildren(PyObject *args) {
184
    PyObject *pyObj;
185
    PyObject *pyVis = Py_None;
186
    short type=0;
187
    if (!PyArg_ParseTuple(args, "O|Os",&pyObj,&pyVis,&type))
188
        return nullptr;
189

190
    PY_TRY{
191
        App::PropertyBoolList vis;
192
        App::PropertyLinkList links;
193
        if(pyObj!=Py_None)
194
            links.setPyObject(pyObj);
195
        if(pyVis!=Py_None)
196
            vis.setPyObject(pyVis);
197
        getLinkViewPtr()->setChildren(links.getValue(),vis.getValue(),static_cast<LinkView::SnapshotType>(type));
198
        Py_Return;
199
    } PY_CATCH;
200
}
201

202
PyObject*  LinkViewPy::setLink(PyObject *args)
203
{
204
    PyObject *pyObj;
205
    PyObject *pySubName = Py_None;
206
    if (!PyArg_ParseTuple(args, "O|O",&pyObj,&pySubName))
207
        return nullptr;
208

209
    PY_TRY {
210
        ViewProviderDocumentObject *vpd = nullptr;
211
        App::DocumentObject *obj = nullptr;
212
        if(pyObj!=Py_None) {
213
            if(PyObject_TypeCheck(pyObj,&App::DocumentObjectPy::Type))
214
                obj = static_cast<App::DocumentObjectPy*>(pyObj)->getDocumentObjectPtr();
215
            else if(PyObject_TypeCheck(pyObj,&ViewProviderDocumentObjectPy::Type))
216
                vpd = static_cast<ViewProviderDocumentObjectPy*>(pyObj)->getViewProviderDocumentObjectPtr();
217
            else {
218
                PyErr_SetString(PyExc_TypeError,
219
                        "exepcting a type of DocumentObject or ViewProviderDocumentObject");
220
                return nullptr;
221
            }
222
        }
223

224
        // Too lazy to parse the argument...
225
        App::PropertyStringList prop;
226
        if(pySubName!=Py_None)
227
            prop.setPyObject(pySubName);
228

229
        if(obj)
230
            getLinkViewPtr()->setLink(obj,prop.getValue());
231
        else
232
            getLinkViewPtr()->setLinkViewObject(vpd,prop.getValue());
233
        Py_Return;
234
    } PY_CATCH;
235
}
236

237
Py::Object LinkViewPy::getOwner() const {
238
    auto owner = getLinkViewPtr()->getOwner();
239
    if(!owner)
240
        return Py::Object();
241
    return Py::Object(owner->getPyObject(),true);
242
}
243

244
void LinkViewPy::setOwner(Py::Object owner) {
245
    ViewProviderDocumentObject *vp = nullptr;
246
    if(!owner.isNone()) {
247
        if(!PyObject_TypeCheck(owner.ptr(),&ViewProviderDocumentObjectPy::Type))
248
            throw Py::TypeError("exepcting the owner to be of ViewProviderDocumentObject");
249
        vp = static_cast<ViewProviderDocumentObjectPy*>(
250
                owner.ptr())->getViewProviderDocumentObjectPtr();
251
    }
252
    getLinkViewPtr()->setOwner(vp);
253
}
254

255
Py::Object LinkViewPy::getLinkedView() const {
256
    auto linked = getLinkViewPtr()->getLinkedView();
257
    if(!linked)
258
        return Py::Object();
259
    return Py::Object(linked->getPyObject(),true);
260
}
261

262
Py::Object LinkViewPy::getSubNames() const {
263
    const auto &subs = getLinkViewPtr()->getSubNames();
264
    if(subs.empty())
265
        return Py::Object();
266
    Py::Tuple ret(subs.size());
267
    int i=0;
268
    for(auto &s : subs)
269
        ret.setItem(i++,Py::String(s.c_str()));
270
    return ret;
271
}
272

273
PyObject* LinkViewPy::getElementPicked(PyObject* args)
274
{
275
    PyObject *obj;
276
    if (!PyArg_ParseTuple(args, "O",&obj))
277
        return nullptr;
278
    void *ptr = nullptr;
279
    Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoPickedPoint *", obj, &ptr, 0);
280
    auto pp = static_cast<SoPickedPoint*>(ptr);
281
    if(!pp)
282
        throw Py::TypeError("type must be of coin.SoPickedPoint");
283
    PY_TRY{
284
        std::string name;
285
        if(!getLinkViewPtr()->linkGetElementPicked(pp,name))
286
            Py_Return;
287
        return Py::new_reference_to(Py::String(name));
288
    }PY_CATCH
289
}
290

291
PyObject* LinkViewPy::getDetailPath(PyObject* args)
292
{
293
    const char *sub;
294
    PyObject *path;
295
    if (!PyArg_ParseTuple(args, "sO",&sub,&path))
296
        return nullptr;
297
    void *ptr = nullptr;
298
    Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoPath *", path, &ptr, 0);
299
    auto pPath = static_cast<SoPath*>(ptr);
300
    if(!pPath)
301
        throw Py::TypeError("type must be of coin.SoPath");
302
    PY_TRY{
303
        SoDetail *det = nullptr;
304
        getLinkViewPtr()->linkGetDetailPath(sub,static_cast<SoFullPath*>(pPath),det);
305
        if(!det)
306
            Py_Return;
307
        return Base::Interpreter().createSWIGPointerObj("pivy.coin", "SoDetail *", static_cast<void*>(det), 0);
308
    }PY_CATCH
309
}
310

311
PyObject* LinkViewPy::getBoundBox(PyObject* args)
312
{
313
    PyObject *vobj = Py_None;
314
    if (!PyArg_ParseTuple(args, "O",&vobj))
315
        return nullptr;
316

317
    PY_TRY {
318
        Base::PyTypeCheck(&vobj, &ViewProviderDocumentObjectPy::Type);
319
        ViewProviderDocumentObject *vpd = nullptr;
320
        if (vobj)
321
            vpd = static_cast<ViewProviderDocumentObjectPy*>(vobj)->getViewProviderDocumentObjectPtr();
322

323
        auto bbox = getLinkViewPtr()->getBoundBox(vpd);
324
        Py::Object ret(new Base::BoundBoxPy(new Base::BoundBox3d(bbox)));
325
        return Py::new_reference_to(ret);
326
    }
327
    PY_CATCH
328
}
329

330
PyObject *LinkViewPy::getCustomAttributes(const char*) const
331
{
332
    return nullptr;
333
}
334

335
int LinkViewPy::setCustomAttributes(const char*, PyObject*)
336
{
337
    return 0;
338
}
339

340
Py::Object LinkViewPy::getRootNode() const
341
{
342
    try {
343
        SoNode* node = getLinkViewPtr()->getLinkRoot();
344
        PyObject* Ptr = Base::Interpreter().createSWIGPointerObj("pivy.coin","SoSeparator *", node, 1);
345
        node->ref();
346
        return Py::Object(Ptr, true);
347
    }
348
    catch (const Base::Exception& e) {
349
        throw Py::RuntimeError(e.what());
350
    }
351
}
352

353
Py::Object LinkViewPy::getVisibilities() const {
354
    auto linked = getLinkViewPtr();
355
    if(!linked->getSize())
356
        return Py::Object();
357
    Py::Tuple ret(linked->getSize());
358
    for(int i=0;i<linked->getSize();++i)
359
        ret.setItem(i,Py::Boolean(linked->isElementVisible(i)));
360
    return ret;
361
}
362

363
void LinkViewPy::setVisibilities(Py::Object value) {
364
    App::PropertyBoolList v;
365
    if(!value.isNone())
366
        v.setPyObject(value.ptr());
367

368
    auto linked = getLinkViewPtr();
369
    const auto &vis = v.getValue();
370
    for(int i=0;i<linked->getSize();++i)
371
        linked->setElementVisible(i,i>=(int)vis.size()||vis[i]);
372
}
373

374
PyObject* LinkViewPy::getChildren(PyObject *args) {
375
    if (!PyArg_ParseTuple(args, ""))
376
        return nullptr;
377
    auto children = getLinkViewPtr()->getChildren();
378
    if(children.empty())
379
        Py_Return;
380
    Py::Tuple ret(children.size());
381
    int i=0;
382
    for(auto vp : children)
383
        ret.setItem(i++,Py::Object(vp->getPyObject(),true));
384
    return Py::new_reference_to(ret);
385
}
386

387
Py::Int LinkViewPy::getCount() const {
388
    return Py::Int(getLinkViewPtr()->getSize());
389
}
390

391
void LinkViewPy::setCount(Py::Int count) {
392
    try {
393
        getLinkViewPtr()->setSize((int)count);
394
    } catch (const Base::Exception& e) {
395
        throw Py::RuntimeError(e.what());
396
    }
397
}
398

399

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.