FreeCAD

Форк
0
/
PlacementPyImp.cpp 
564 строки · 18.3 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2008 Werner Mayer <wmayer[at]users.sourceforge.net>     *
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

24
#include "PreCompiled.h"
25

26
#include "GeometryPyCXX.h"
27
#include <Base/PyWrapParseTupleAndKeywords.h>
28

29
// inclusion of the generated files (generated out of PlacementPy.xml)
30
#include "PlacementPy.h"
31
#include "PlacementPy.cpp"
32
#include "Matrix.h"
33
#include "MatrixPy.h"
34
#include "RotationPy.h"
35
#include "VectorPy.h"
36
#include "Tools.h"
37

38
using namespace Base;
39

40
// returns a string which represents the object e.g. when printed in python
41
std::string PlacementPy::representation() const
42
{
43
    double yaw {};
44
    double pitch {};
45
    double roll {};
46
    PlacementPy::PointerType ptr = getPlacementPtr();
47
    std::stringstream str;
48
    ptr->getRotation().getYawPitchRoll(yaw, pitch, roll);
49

50
    str << "Placement [Pos=(";
51
    str << ptr->getPosition().x << "," << ptr->getPosition().y << "," << ptr->getPosition().z;
52
    str << "), Yaw-Pitch-Roll=(" << yaw << "," << pitch << "," << roll << ")]";
53

54
    return str.str();
55
}
56

57
PyObject* PlacementPy::PyMake(PyTypeObject* /*unused*/, PyObject* /*unused*/, PyObject* /*unused*/)
58
{
59
    // create a new instance of PlacementPy and the Twin object
60
    return new PlacementPy(new Placement);
61
}
62

63
// clang-format off
64
// constructor method
65
int PlacementPy::PyInit(PyObject* args, PyObject* /*kwd*/)
66
{
67
    PyObject* o {};
68
    if (PyArg_ParseTuple(args, "")) {
69
        return 0;
70
    }
71

72
    PyErr_Clear();
73
    if (PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type), &o)) {
74
        try {
75
            Base::Matrix4D mat = static_cast<Base::MatrixPy*>(o)->value();
76
            getPlacementPtr()->fromMatrix(mat);
77
            return 0;
78
        }
79
        catch (const Base::Exception& e) {
80
            PyErr_SetString(e.getPyExceptionType(), e.what());
81
            return -1;
82
        }
83
    }
84

85
    PyErr_Clear();
86
    if (PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type), &o)) {
87
        Base::Placement* plm = static_cast<Base::PlacementPy*>(o)->getPlacementPtr();
88
        *(getPlacementPtr()) = *plm;
89
        return 0;
90
    }
91

92
    PyErr_Clear();
93
    PyObject* d {};
94
    double angle {};
95
    if (PyArg_ParseTuple(args,
96
                         "O!O!d",
97
                         &(Base::VectorPy::Type), &o,
98
                         &(Base::VectorPy::Type), &d,
99
                         &angle)) {
100
        // NOTE: The first parameter defines the translation, the second the rotation axis
101
        // and the last parameter defines the rotation angle in degree.
102
        Base::Rotation rot(static_cast<Base::VectorPy*>(d)->value(), angle / 180.0 * D_PI);
103
        *getPlacementPtr() = Base::Placement(static_cast<Base::VectorPy*>(o)->value(), rot);
104
        return 0;
105
    }
106

107
    PyErr_Clear();
108
    if (PyArg_ParseTuple(args,
109
                         "O!O!",
110
                         &(Base::VectorPy::Type), &o,
111
                         &(Base::RotationPy::Type), &d)) {
112
        Base::Vector3d* pos = static_cast<Base::VectorPy*>(o)->getVectorPtr();
113
        getPlacementPtr()->setPosition(*pos);
114
        Base::Rotation* rot = static_cast<Base::RotationPy*>(d)->getRotationPtr();
115
        getPlacementPtr()->setRotation(*rot);
116
        return 0;
117
    }
118

119
    PyErr_Clear();
120
    PyObject* c {};
121
    if (PyArg_ParseTuple(args,
122
                         "O!O!O!",
123
                         &(Base::VectorPy::Type), &o,
124
                         &(Base::RotationPy::Type), &d,
125
                         &(Base::VectorPy::Type), &c)) {
126
        Base::Vector3d* pos = static_cast<Base::VectorPy*>(o)->getVectorPtr();
127
        Base::Rotation* rot = static_cast<Base::RotationPy*>(d)->getRotationPtr();
128
        Base::Vector3d* cnt = static_cast<Base::VectorPy*>(c)->getVectorPtr();
129
        Base::Placement p(*pos, *rot, *cnt);
130
        getPlacementPtr()->operator=(p);
131
        return 0;
132
    }
133

134
    PyErr_SetString(PyExc_TypeError, "empty parameter list, matrix or placement expected");
135
    return -1;
136
}
137
// clang-format on
138

139
PyObject* PlacementPy::richCompare(PyObject* v, PyObject* w, int op)
140
{
141
    if (PyObject_TypeCheck(v, &(PlacementPy::Type))
142
        && PyObject_TypeCheck(w, &(PlacementPy::Type))) {
143
        Base::Placement p1 = *static_cast<PlacementPy*>(v)->getPlacementPtr();
144
        Base::Placement p2 = *static_cast<PlacementPy*>(w)->getPlacementPtr();
145

146
        PyObject* res = nullptr;
147
        if (op != Py_EQ && op != Py_NE) {
148
            PyErr_SetString(PyExc_TypeError, "no ordering relation is defined for Placement");
149
            return nullptr;
150
        }
151
        if (op == Py_EQ) {
152
            res = (p1 == p2) ? Py_True : Py_False;
153
            Py_INCREF(res);
154
            return res;
155
        }
156
        res = (p1 != p2) ? Py_True : Py_False;
157
        Py_INCREF(res);
158
        return res;
159
    }
160
    // This always returns False
161
    Py_INCREF(Py_NotImplemented);
162
    return Py_NotImplemented;
163
}
164

165
PyObject* PlacementPy::move(PyObject* args)
166
{
167
    PyObject* vec {};
168
    if (!PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &vec)) {
169
        return nullptr;
170
    }
171
    getPlacementPtr()->move(static_cast<VectorPy*>(vec)->value());
172
    Py_Return;
173
}
174

175
PyObject* PlacementPy::translate(PyObject* args)
176
{
177
    return move(args);
178
}
179

180
// clang-format off
181
PyObject* PlacementPy::rotate(PyObject* args, PyObject* kwds)
182
{
183
    double angle {};
184
    static const std::array<const char*, 6> kwlist {"center", "axis", "angle", "comp", nullptr};
185
    Vector3d center;
186
    Vector3d axis;
187
    PyObject* pyComp = Py_False;  // NOLINT
188

189
    if (!Base::Wrapped_ParseTupleAndKeywords(args,
190
                                             kwds,
191
                                             "(ddd)(ddd)d|O!",
192
                                             kwlist,
193
                                             &center.x, &center.y, &center.z,
194
                                             &axis.x, &axis.y, &axis.z,
195
                                             &angle, &PyBool_Type, &pyComp)) {
196
        return nullptr;
197
    }
198

199
    try {
200
        /*
201
         * if comp is False, we retain the original behaviour that - contrary to the (old)
202
         * documentation - generates Placements different from TopoShape.rotate() to ensure
203
         * compatibility for existing code
204
         */
205
        bool comp = Base::asBoolean(pyComp);
206

207
        if (!comp) {
208
            getPlacementPtr()->multRight(
209
                Placement(Vector3d(), Rotation(axis, toRadians<double>(angle)), center));
210
        }
211
        else {
212
            // multiply new Placement the same way TopoShape.rotate() does
213
            getPlacementPtr()->multLeft(
214
                Placement(Vector3d(), Rotation(axis, toRadians<double>(angle)), center));
215
        }
216

217
        Py_Return;
218
    }
219
    catch (const Py::Exception&) {
220
        return nullptr;
221
    }
222
}
223
// clang-format on
224

225
PyObject* PlacementPy::multiply(PyObject* args)
226
{
227
    PyObject* plm {};
228
    if (!PyArg_ParseTuple(args, "O!", &(PlacementPy::Type), &plm)) {
229
        return nullptr;
230
    }
231
    Placement mult = (*getPlacementPtr()) * (*static_cast<PlacementPy*>(plm)->getPlacementPtr());
232
    return new PlacementPy(new Placement(mult));
233
}
234

235
PyObject* PlacementPy::multVec(PyObject* args)
236
{
237
    PyObject* vec {};
238
    if (!PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &vec)) {
239
        return nullptr;
240
    }
241
    Base::Vector3d pnt(static_cast<VectorPy*>(vec)->value());
242
    getPlacementPtr()->multVec(pnt, pnt);
243
    return new VectorPy(new Vector3d(pnt));
244
}
245

246
PyObject* PlacementPy::copy(PyObject* args)
247
{
248
    if (!PyArg_ParseTuple(args, "")) {
249
        return nullptr;
250
    }
251
    return new PlacementPy(new Placement(*getPlacementPtr()));
252
}
253

254
PyObject* PlacementPy::toMatrix(PyObject* args)
255
{
256
    if (!PyArg_ParseTuple(args, "")) {
257
        return nullptr;
258
    }
259
    Base::Matrix4D mat = getPlacementPtr()->toMatrix();
260
    return new MatrixPy(new Matrix4D(mat));
261
}
262

263
PyObject* PlacementPy::inverse(PyObject* args)
264
{
265
    if (!PyArg_ParseTuple(args, "")) {
266
        return nullptr;
267
    }
268
    Base::Placement p = getPlacementPtr()->inverse();
269
    return new PlacementPy(new Placement(p));
270
}
271

272
PyObject* PlacementPy::pow(PyObject* args)
273
{
274
    double t {};
275
    PyObject* shorten = Py_True;
276
    if (!PyArg_ParseTuple(args, "d|O!", &t, &(PyBool_Type), &shorten)) {
277
        return nullptr;
278
    }
279
    Base::Placement ret = getPlacementPtr()->pow(t, Base::asBoolean(shorten));
280
    return new PlacementPy(new Placement(ret));
281
}
282

283

284
PyObject* PlacementPy::sclerp(PyObject* args)
285
{
286
    PyObject* pyplm2 {};
287
    double t {};
288
    PyObject* shorten = Py_True;
289
    if (!PyArg_ParseTuple(args,
290
                          "O!d|O!",
291
                          &(PlacementPy::Type),
292
                          &pyplm2,
293
                          &t,
294
                          &(PyBool_Type),
295
                          &shorten)) {
296
        return nullptr;
297
    }
298
    Base::Placement plm2 = static_cast<Base::PlacementPy*>(pyplm2)->value();
299
    Base::Placement ret =
300
        Base::Placement::sclerp(*getPlacementPtr(), plm2, t, Base::asBoolean(shorten));
301
    return new PlacementPy(new Placement(ret));
302
}
303

304
PyObject* PlacementPy::slerp(PyObject* args)
305
{
306
    PyObject* pyplm2 {};
307
    double t {};
308
    if (!PyArg_ParseTuple(args, "O!d", &(PlacementPy::Type), &pyplm2, &t)) {
309
        return nullptr;
310
    }
311
    Base::Placement plm2 = static_cast<Base::PlacementPy*>(pyplm2)->value();
312
    Base::Placement ret = Base::Placement::slerp(*getPlacementPtr(), plm2, t);
313
    return new PlacementPy(new Placement(ret));
314
}
315

316
PyObject* PlacementPy::isIdentity(PyObject* args)
317
{
318
    double tol = 0.0;
319
    if (!PyArg_ParseTuple(args, "|d", &tol)) {
320
        return nullptr;
321
    }
322
    bool none = tol > 0 ? getPlacementPtr()->isIdentity(tol) : getPlacementPtr()->isIdentity();
323
    return Py_BuildValue("O", (none ? Py_True : Py_False));
324
}
325

326
PyObject* PlacementPy::isSame(PyObject* args)
327
{
328
    PyObject* plm {};
329
    double tol = 0.0;
330
    if (!PyArg_ParseTuple(args, "O!|d", &PlacementPy::Type, &plm, &tol)) {
331
        return nullptr;
332
    }
333

334
    Base::Placement plm1 = *getPlacementPtr();
335
    Base::Placement plm2 = *static_cast<PlacementPy*>(plm)->getPlacementPtr();
336
    bool same = tol > 0.0 ? plm1.isSame(plm2, tol) : plm1.isSame(plm2);
337
    return Py_BuildValue("O", (same ? Py_True : Py_False));
338
}
339

340
Py::Object PlacementPy::getBase() const
341
{
342
    return Py::Vector(getPlacementPtr()->getPosition());  // NOLINT
343
}
344

345
void PlacementPy::setBase(Py::Object arg)
346
{
347
    getPlacementPtr()->setPosition(Py::Vector(arg).toVector());
348
}
349

350
Py::Object PlacementPy::getRotation() const
351
{
352
    return Py::Rotation(getPlacementPtr()->getRotation());
353
}
354

355
void PlacementPy::setRotation(Py::Object arg)
356
{
357
    Py::Rotation rot;
358
    if (rot.accepts(arg.ptr())) {
359
        getPlacementPtr()->setRotation(static_cast<Base::Rotation>(Py::Rotation(arg)));
360
        return;
361
    }
362
    Py::Tuple tuple;
363
    if (tuple.accepts(arg.ptr())) {
364
        tuple = arg;
365
        getPlacementPtr()->setRotation(Base::Rotation(static_cast<double>(Py::Float(tuple[0])),
366
                                                      static_cast<double>(Py::Float(tuple[1])),
367
                                                      static_cast<double>(Py::Float(tuple[2])),
368
                                                      static_cast<double>(Py::Float(tuple[3]))));
369
        return;
370
    }
371

372
    throw Py::TypeError("either Rotation or tuple of four floats expected");
373
}
374

375
Py::Object PlacementPy::getMatrix() const
376
{
377
    return Py::Matrix(getPlacementPtr()->toMatrix());
378
}
379

380
void PlacementPy::setMatrix(Py::Object arg)
381
{
382
    Py::Matrix mat;
383
    if (!mat.accepts(arg.ptr())) {
384
        throw Py::TypeError("Expect type Matrix");
385
    }
386
    try {
387
        mat = arg;
388
        getPlacementPtr()->fromMatrix(mat);
389
    }
390
    catch (const Base::ValueError& e) {
391
        throw Py::ValueError(e.what());
392
    }
393
}
394

395
PyObject* PlacementPy::getCustomAttributes(const char* attr) const
396
{
397
    // for backward compatibility
398
    if (strcmp(attr, "isNull") == 0) {
399
        PyObject* w {};
400
        PyObject* res {};
401
        w = PyUnicode_InternFromString("isIdentity");
402
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
403
        res = PyObject_GenericGetAttr(const_cast<PlacementPy*>(this), w);
404
        Py_XDECREF(w);
405
        return res;
406
    }
407
    return nullptr;
408
}
409

410
int PlacementPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
411
{
412
    return 0;
413
}
414

415
PyObject* PlacementPy::number_multiply_handler(PyObject* self, PyObject* other)
416
{
417
    if (PyObject_TypeCheck(self, &(PlacementPy::Type))) {
418
        Base::Placement a = static_cast<PlacementPy*>(self)->value();
419

420
        if (PyObject_TypeCheck(other, &(VectorPy::Type))) {
421
            Vector3d res;
422
            a.multVec(static_cast<VectorPy*>(other)->value(), res);
423
            return new VectorPy(res);
424
        }
425

426
        if (PyObject_TypeCheck(other, &(RotationPy::Type))) {
427
            Placement b(Vector3d(), static_cast<RotationPy*>(other)->value());
428
            return new PlacementPy(a * b);
429
        }
430

431
        if (PyObject_TypeCheck(other, &(PlacementPy::Type))) {
432
            const auto& b = static_cast<PlacementPy*>(other)->value();
433
            return new PlacementPy(a * b);
434
        }
435

436
        if (PyObject_TypeCheck(other, &(MatrixPy::Type))) {
437
            const auto& b = static_cast<MatrixPy*>(other)->value();
438
            return new MatrixPy(a.toMatrix() * b);
439
        }
440
    }
441

442
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
443
    return nullptr;
444
}
445

446
PyObject* PlacementPy::number_power_handler(PyObject* self, PyObject* other, PyObject* arg)
447
{
448
    Py::Object pw(other);
449
    Py::Tuple tup(1);
450
    tup[0] = pw;
451

452
    double pw_v {};
453
    if (!PyArg_ParseTuple(tup.ptr(), "d", &pw_v)) {
454
        return nullptr;
455
    }
456
    if (!PyObject_TypeCheck(self, &(PlacementPy::Type)) || arg != Py_None) {
457
        PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
458
        return nullptr;
459
    }
460

461
    Placement a = static_cast<PlacementPy*>(self)->value();
462
    return new PlacementPy(a.pow(pw_v));
463
}
464

465
PyObject* PlacementPy::number_add_handler(PyObject* /*self*/, PyObject* /*other*/)
466
{
467
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
468
    return nullptr;
469
}
470

471
PyObject* PlacementPy::number_subtract_handler(PyObject* /*self*/, PyObject* /*other*/)
472
{
473
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
474
    return nullptr;
475
}
476

477
PyObject* PlacementPy::number_divide_handler(PyObject* /*self*/, PyObject* /*other*/)
478
{
479
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
480
    return nullptr;
481
}
482

483
PyObject* PlacementPy::number_remainder_handler(PyObject* /*self*/, PyObject* /*other*/)
484
{
485
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
486
    return nullptr;
487
}
488

489
PyObject* PlacementPy::number_divmod_handler(PyObject* /*self*/, PyObject* /*other*/)
490
{
491
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
492
    return nullptr;
493
}
494

495
PyObject* PlacementPy::number_negative_handler(PyObject* /*self*/)
496
{
497
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
498
    return nullptr;
499
}
500

501
PyObject* PlacementPy::number_positive_handler(PyObject* /*self*/)
502
{
503
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
504
    return nullptr;
505
}
506

507
PyObject* PlacementPy::number_absolute_handler(PyObject* /*self*/)
508
{
509
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
510
    return nullptr;
511
}
512

513
int PlacementPy::number_nonzero_handler(PyObject* /*self*/)
514
{
515
    return 1;
516
}
517

518
PyObject* PlacementPy::number_invert_handler(PyObject* /*self*/)
519
{
520
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
521
    return nullptr;
522
}
523

524
PyObject* PlacementPy::number_lshift_handler(PyObject* /*self*/, PyObject* /*other*/)
525
{
526
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
527
    return nullptr;
528
}
529

530
PyObject* PlacementPy::number_rshift_handler(PyObject* /*self*/, PyObject* /*other*/)
531
{
532
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
533
    return nullptr;
534
}
535

536
PyObject* PlacementPy::number_and_handler(PyObject* /*self*/, PyObject* /*other*/)
537
{
538
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
539
    return nullptr;
540
}
541

542
PyObject* PlacementPy::number_xor_handler(PyObject* /*self*/, PyObject* /*other*/)
543
{
544
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
545
    return nullptr;
546
}
547

548
PyObject* PlacementPy::number_or_handler(PyObject* /*self*/, PyObject* /*other*/)
549
{
550
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
551
    return nullptr;
552
}
553

554
PyObject* PlacementPy::number_int_handler(PyObject* /*self*/)
555
{
556
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
557
    return nullptr;
558
}
559

560
PyObject* PlacementPy::number_float_handler(PyObject* /*self*/)
561
{
562
    PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
563
    return nullptr;
564
}
565

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

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

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

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