FreeCAD

Форк
0
/
BoundBoxPyImp.cpp 
631 строка · 18.6 Кб
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
// inclusion of the generated files (generated out of BoundBoxPy.xml)
27
#include "MatrixPy.h"
28
#include "VectorPy.h"
29
#include "GeometryPyCXX.h"
30
#include "BoundBoxPy.h"
31
#include "BoundBoxPy.cpp"
32

33
using namespace Base;
34

35
// returns a string which represent the object e.g. when printed in python
36
std::string BoundBoxPy::representation() const
37
{
38
    std::stringstream str;
39
    str << "BoundBox (";
40
    str << getBoundBoxPtr()->MinX << ", " << getBoundBoxPtr()->MinY << ", "
41
        << getBoundBoxPtr()->MinZ << ", " << getBoundBoxPtr()->MaxX << ", "
42
        << getBoundBoxPtr()->MaxY << ", " << getBoundBoxPtr()->MaxZ;
43
    str << ")";
44

45
    return str.str();
46
}
47

48
PyObject* BoundBoxPy::PyMake(PyTypeObject* /*unused*/, PyObject* /*unused*/, PyObject* /*unused*/)
49
{
50
    // create a new instance of BoundBoxPy and the Twin object
51
    return new BoundBoxPy(new BoundBox3d);
52
}
53

54
// constructor method
55
int BoundBoxPy::PyInit(PyObject* args, PyObject* /*kwd*/)
56
{
57
    if (PyArg_ParseTuple(args, "")) {
58
        return 0;
59
    }
60
    PyErr_Clear();  // set by PyArg_ParseTuple()
61

62
    double xMin = 0.0;
63
    double yMin = 0.0;
64
    double zMin = 0.0;
65
    double xMax = 0.0;
66
    double yMax = 0.0;
67
    double zMax = 0.0;
68
    PyObject* object1 {};
69
    PyObject* object2 {};
70
    BoundBoxPy::PointerType ptr = getBoundBoxPtr();
71
    if (PyArg_ParseTuple(args, "d|ddddd", &xMin, &yMin, &zMin, &xMax, &yMax, &zMax)) {
72
        ptr->MaxX = xMax;
73
        ptr->MaxY = yMax;
74
        ptr->MaxZ = zMax;
75
        ptr->MinX = xMin;
76
        ptr->MinY = yMin;
77
        ptr->MinZ = zMin;
78
        return 0;
79
    }
80
    PyErr_Clear();  // set by PyArg_ParseTuple()
81
    if (PyArg_ParseTuple(args, "O!O!", &PyTuple_Type, &object1, &PyTuple_Type, &object2)) {
82
        try {
83
            Vector3d v1 = getVectorFromTuple<double>(object1);
84
            Vector3d v2 = getVectorFromTuple<double>(object2);
85
            ptr->Add(v1);
86
            ptr->Add(v2);
87
            return 0;
88
        }
89
        catch (const Py::Exception&) {
90
            return -1;
91
        }
92
    }
93
    PyErr_Clear();  // set by PyArg_ParseTuple()
94
    if (PyArg_ParseTuple(args,
95
                         "O!O!",
96
                         &(Base::VectorPy::Type),
97
                         &object1,
98
                         &(Base::VectorPy::Type),
99
                         &object2)) {
100
        ptr->Add(*(static_cast<Base::VectorPy*>(object1)->getVectorPtr()));
101
        ptr->Add(*(static_cast<Base::VectorPy*>(object2)->getVectorPtr()));
102
        return 0;
103
    }
104
    PyErr_Clear();  // set by PyArg_ParseTuple()
105
    if (PyArg_ParseTuple(args, "O!", &(Base::BoundBoxPy::Type), &object1)) {
106
        *ptr = *(static_cast<Base::BoundBoxPy*>(object1)->getBoundBoxPtr());
107
        return 0;
108
    }
109

110
    PyErr_SetString(PyExc_TypeError,
111
                    "Either six floats, two instances of "
112
                    "Vector/Tuple or instance of BoundBox expected");
113
    return -1;
114
}
115

116
PyObject* BoundBoxPy::setVoid(PyObject* args)
117
{
118
    if (!PyArg_ParseTuple(args, "")) {
119
        return nullptr;
120
    }
121

122
    getBoundBoxPtr()->SetVoid();
123
    Py_Return;
124
}
125

126
PyObject* BoundBoxPy::isValid(PyObject* args)
127
{
128
    if (!PyArg_ParseTuple(args, "")) {
129
        return nullptr;
130
    }
131

132
    return PyBool_FromLong(getBoundBoxPtr()->IsValid() ? 1 : 0);
133
}
134

135
PyObject* BoundBoxPy::add(PyObject* args)
136
{
137
    double x {};
138
    double y {};
139
    double z {};
140
    PyObject* object {};
141
    if (PyArg_ParseTuple(args, "ddd", &x, &y, &z)) {
142
        getBoundBoxPtr()->Add(Vector3d(x, y, z));
143
        Py_Return;
144
    }
145

146
    PyErr_Clear();
147
    if (PyArg_ParseTuple(args, "O!", &PyTuple_Type, &object)) {
148
        getBoundBoxPtr()->Add(getVectorFromTuple<double>(object));
149
        Py_Return;
150
    }
151

152
    PyErr_Clear();
153
    if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &object)) {
154
        getBoundBoxPtr()->Add(*(static_cast<Base::VectorPy*>(object)->getVectorPtr()));
155
        Py_Return;
156
    }
157

158
    PyErr_Clear();
159
    if (PyArg_ParseTuple(args,
160
                         "O!;Need a Vector, BoundBox or three floats as argument",
161
                         &(Base::BoundBoxPy::Type),
162
                         &object)) {
163
        getBoundBoxPtr()->Add(*(static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()));
164
        Py_Return;
165
    }
166

167
    PyErr_SetString(PyExc_TypeError,
168
                    "Either three floats, instance of Vector or instance of BoundBox expected");
169
    return nullptr;
170
}
171

172
PyObject* BoundBoxPy::getPoint(PyObject* args)
173
{
174
    unsigned short index {};
175
    if (!PyArg_ParseTuple(args, "H", &index)) {
176
        return nullptr;
177
    }
178

179
    if (index > 7) {
180
        PyErr_SetString(PyExc_IndexError, "Invalid point index");
181
        return nullptr;
182
    }
183

184
    Base::Vector3d pnt = getBoundBoxPtr()->CalcPoint(index);
185
    return new Base::VectorPy(new Base::Vector3d(pnt));
186
}
187

188
PyObject* BoundBoxPy::getEdge(PyObject* args)
189
{
190
    unsigned short index {};
191
    if (!PyArg_ParseTuple(args, "H", &index)) {
192
        return nullptr;
193
    }
194

195
    if (index > 11) {
196
        PyErr_SetString(PyExc_IndexError, "Invalid edge index");
197
        return nullptr;
198
    }
199

200
    Base::Vector3d pnt1;
201
    Base::Vector3d pnt2;
202
    getBoundBoxPtr()->CalcEdge(index, pnt1, pnt2);
203
    Py::Tuple tuple(2);
204
    tuple.setItem(0, Py::Vector(pnt1));
205
    tuple.setItem(1, Py::Vector(pnt2));
206
    return Py::new_reference_to(tuple);
207
}
208

209
PyObject* BoundBoxPy::closestPoint(PyObject* args)
210
{
211
    double x {};
212
    double y {};
213
    double z {};
214
    PyObject* object {};
215

216
    Base::Vector3d vec;
217

218
    do {
219
        if (PyArg_ParseTuple(args, "ddd", &x, &y, &z)) {
220
            vec = Vector3d(x, y, z);
221
            break;
222
        }
223

224
        PyErr_Clear();
225
        if (PyArg_ParseTuple(args, "O!", &PyTuple_Type, &object)) {
226
            vec = getVectorFromTuple<double>(object);
227
            break;
228
        }
229

230
        PyErr_Clear();
231
        if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &object)) {
232
            vec = *(static_cast<Base::VectorPy*>(object)->getVectorPtr());
233
            break;
234
        }
235

236
        PyErr_SetString(PyExc_TypeError, "Either three floats or vector expected");
237
        return nullptr;
238
    } while (false);
239

240
    Base::Vector3d point = getBoundBoxPtr()->ClosestPoint(vec);
241
    return new Base::VectorPy(new Base::Vector3d(point));
242
}
243

244
PyObject* BoundBoxPy::intersect(PyObject* args)
245
{
246
    PyObject* object1 {};
247
    PyObject* object2 {};
248
    Py::Boolean retVal;
249

250
    if (!getBoundBoxPtr()->IsValid()) {
251
        PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box");
252
        return nullptr;
253
    }
254

255
    do {
256
        if (PyArg_ParseTuple(args,
257
                             "O!O!",
258
                             &(Base::VectorPy::Type),
259
                             &object1,
260
                             &(Base::VectorPy::Type),
261
                             &object2)) {
262
            retVal = getBoundBoxPtr()->IsCutLine(
263
                *(static_cast<Base::VectorPy*>(object1)->getVectorPtr()),
264
                *(static_cast<Base::VectorPy*>(object2)->getVectorPtr()));
265
            break;
266
        }
267

268
        PyErr_Clear();
269
        if (PyArg_ParseTuple(args, "O!", &(Base::BoundBoxPy::Type), &object1)) {
270
            if (!static_cast<Base::BoundBoxPy*>(object1)->getBoundBoxPtr()->IsValid()) {
271
                PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box argument");
272
                return nullptr;
273
            }
274
            retVal = getBoundBoxPtr()->Intersect(
275
                *(static_cast<Base::BoundBoxPy*>(object1)->getBoundBoxPtr()));
276
            break;
277
        }
278

279
        PyErr_SetString(PyExc_TypeError, "Either BoundBox or two Vectors expected");
280
        return nullptr;
281
    } while (false);
282

283
    return Py::new_reference_to(retVal);
284
}
285

286
PyObject* BoundBoxPy::intersected(PyObject* args)
287
{
288
    if (!getBoundBoxPtr()->IsValid()) {
289
        PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box");
290
        return nullptr;
291
    }
292

293
    PyObject* object {};
294
    if (!PyArg_ParseTuple(args, "O!", &(Base::BoundBoxPy::Type), &object)) {
295
        return nullptr;
296
    }
297
    if (!static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()->IsValid()) {
298
        PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box argument");
299
        return nullptr;
300
    }
301

302
    Base::BoundBox3d bbox =
303
        getBoundBoxPtr()->Intersected(*static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr());
304
    return new Base::BoundBoxPy(new Base::BoundBox3d(bbox));
305
}
306

307
PyObject* BoundBoxPy::united(PyObject* args)
308
{
309
    if (!getBoundBoxPtr()->IsValid()) {
310
        PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box");
311
        return nullptr;
312
    }
313

314
    PyObject* object {};
315
    if (!PyArg_ParseTuple(args, "O!", &(Base::BoundBoxPy::Type), &object)) {
316
        return nullptr;
317
    }
318
    if (!static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()->IsValid()) {
319
        PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box argument");
320
        return nullptr;
321
    }
322

323
    Base::BoundBox3d bbox =
324
        getBoundBoxPtr()->United(*static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr());
325
    return new Base::BoundBoxPy(new Base::BoundBox3d(bbox));
326
}
327

328
PyObject* BoundBoxPy::enlarge(PyObject* args)
329
{
330
    double s {};
331
    if (!PyArg_ParseTuple(args, "d;Need float parameter to enlarge", &s)) {
332
        return nullptr;
333
    }
334
    getBoundBoxPtr()->Enlarge(s);
335
    Py_Return;
336
}
337

338
PyObject* BoundBoxPy::getIntersectionPoint(PyObject* args)
339
{
340
    PyObject* object1 {};
341
    PyObject* object2 {};
342
    double epsilon = 0.0001;
343
    if (!PyArg_ParseTuple(args,
344
                          "O!O!|d;Need base and direction vector",
345
                          &(Base::VectorPy::Type),
346
                          &object1,
347
                          &(Base::VectorPy::Type),
348
                          &object2,
349
                          &epsilon)) {
350
        return nullptr;
351
    }
352

353
    Base::Vector3d point;
354
    bool ok = getBoundBoxPtr()->IntersectionPoint(
355
        *(static_cast<Base::VectorPy*>(object1)->getVectorPtr()),
356
        *(static_cast<Base::VectorPy*>(object2)->getVectorPtr()),
357
        point,
358
        epsilon);
359
    if (ok) {
360
        return new VectorPy(point);
361
    }
362

363
    PyErr_SetString(Base::PyExc_FC_GeneralError, "No intersection");
364
    return nullptr;
365
}
366

367
PyObject* BoundBoxPy::move(PyObject* args)
368
{
369
    double x {};
370
    double y {};
371
    double z {};
372
    PyObject* object {};
373

374
    Base::Vector3d vec;
375

376
    do {
377
        if (PyArg_ParseTuple(args, "ddd", &x, &y, &z)) {
378
            vec = Vector3d(x, y, z);
379
            break;
380
        }
381

382
        PyErr_Clear();
383
        if (PyArg_ParseTuple(args, "O!", &PyTuple_Type, &object)) {
384
            vec = getVectorFromTuple<double>(object);
385
            break;
386
        }
387

388
        PyErr_Clear();
389
        if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &object)) {
390
            vec = *(static_cast<Base::VectorPy*>(object)->getVectorPtr());
391
            break;
392
        }
393

394
        PyErr_SetString(PyExc_TypeError, "Either three floats or vector expected");
395
        return nullptr;
396
    } while (false);
397

398
    getBoundBoxPtr()->MoveX(vec.x);
399
    getBoundBoxPtr()->MoveY(vec.y);
400
    getBoundBoxPtr()->MoveZ(vec.z);
401

402
    Py_Return;
403
}
404

405
PyObject* BoundBoxPy::scale(PyObject* args)
406
{
407
    double x {};
408
    double y {};
409
    double z {};
410
    PyObject* object {};
411

412
    Base::Vector3d vec;
413

414
    do {
415
        if (PyArg_ParseTuple(args, "ddd", &x, &y, &z)) {
416
            vec = Vector3d(x, y, z);
417
            break;
418
        }
419

420
        PyErr_Clear();
421
        if (PyArg_ParseTuple(args, "O!", &PyTuple_Type, &object)) {
422
            vec = getVectorFromTuple<double>(object);
423
            break;
424
        }
425

426
        PyErr_Clear();
427
        if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &object)) {
428
            vec = *(static_cast<Base::VectorPy*>(object)->getVectorPtr());
429
            break;
430
        }
431

432
        PyErr_SetString(PyExc_TypeError, "Either three floats or vector expected");
433
        return nullptr;
434
    } while (false);
435

436
    getBoundBoxPtr()->ScaleX(vec.x);
437
    getBoundBoxPtr()->ScaleY(vec.y);
438
    getBoundBoxPtr()->ScaleZ(vec.z);
439

440
    Py_Return;
441
}
442

443
PyObject* BoundBoxPy::transformed(PyObject* args)
444
{
445
    PyObject* mat {};
446

447
    if (!PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type), &mat)) {
448
        return nullptr;
449
    }
450

451
    if (!getBoundBoxPtr()->IsValid()) {
452
        throw Py::FloatingPointError("Cannot transform invalid bounding box");
453
    }
454
    Base::BoundBox3d bbox =
455
        getBoundBoxPtr()->Transformed(*static_cast<Base::MatrixPy*>(mat)->getMatrixPtr());
456
    return new Base::BoundBoxPy(new Base::BoundBox3d(bbox));
457
}
458

459
PyObject* BoundBoxPy::isCutPlane(PyObject* args)
460
{
461
    PyObject* object {};
462
    PyObject* object2 {};
463
    Py::Boolean retVal;
464

465
    if (!getBoundBoxPtr()->IsValid()) {
466
        PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box");
467
        return nullptr;
468
    }
469

470
    if (!PyArg_ParseTuple(args,
471
                          "O!O!;Need base and normal vector of a plane",
472
                          &(Base::VectorPy::Type),
473
                          &object,
474
                          &(Base::VectorPy::Type),
475
                          &object2)) {
476
        return nullptr;
477
    }
478

479
    retVal = getBoundBoxPtr()->IsCutPlane(*(static_cast<Base::VectorPy*>(object)->getVectorPtr()),
480
                                          *(static_cast<Base::VectorPy*>(object2)->getVectorPtr()));
481

482
    return Py::new_reference_to(retVal);
483
}
484

485
PyObject* BoundBoxPy::isInside(PyObject* args)
486
{
487
    double x {};
488
    double y {};
489
    double z {};
490
    PyObject* object {};
491
    Py::Boolean retVal;
492

493
    if (!getBoundBoxPtr()->IsValid()) {
494
        PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box");
495
        return nullptr;
496
    }
497

498
    do {
499
        if (PyArg_ParseTuple(args, "ddd", &x, &y, &z)) {
500
            retVal = getBoundBoxPtr()->IsInBox(Vector3d(x, y, z));
501
            break;
502
        }
503

504
        PyErr_Clear();
505
        if (PyArg_ParseTuple(args, "O!", &PyTuple_Type, &object)) {
506
            retVal = getBoundBoxPtr()->IsInBox(getVectorFromTuple<double>(object));
507
            break;
508
        }
509

510
        PyErr_Clear();
511
        if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &object)) {
512
            retVal =
513
                getBoundBoxPtr()->IsInBox(*(static_cast<Base::VectorPy*>(object)->getVectorPtr()));
514
            break;
515
        }
516

517
        PyErr_Clear();
518
        if (PyArg_ParseTuple(args, "O!", &(Base::BoundBoxPy::Type), &object)) {
519
            if (!static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()->IsValid()) {
520
                PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box argument");
521
                return nullptr;
522
            }
523
            retVal = getBoundBoxPtr()->IsInBox(
524
                *(static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()));
525
            break;
526
        }
527

528
        PyErr_SetString(PyExc_TypeError, "Either three floats, Vector(s) or BoundBox expected");
529
        return nullptr;
530
    } while (false);
531

532
    return Py::new_reference_to(retVal);
533
}
534

535
Py::Object BoundBoxPy::getCenter() const
536
{
537
    return Py::Vector(getBoundBoxPtr()->GetCenter());  // NOLINT
538
}
539

540
Py::Float BoundBoxPy::getXMax() const
541
{
542
    return Py::Float(getBoundBoxPtr()->MaxX);
543
}
544

545
void BoundBoxPy::setXMax(Py::Float arg)
546
{
547
    getBoundBoxPtr()->MaxX = arg;
548
}
549

550
Py::Float BoundBoxPy::getYMax() const
551
{
552
    return Py::Float(getBoundBoxPtr()->MaxY);
553
}
554

555
void BoundBoxPy::setYMax(Py::Float arg)
556
{
557
    getBoundBoxPtr()->MaxY = arg;
558
}
559

560
Py::Float BoundBoxPy::getZMax() const
561
{
562
    return Py::Float(getBoundBoxPtr()->MaxZ);
563
}
564

565
void BoundBoxPy::setZMax(Py::Float arg)
566
{
567
    getBoundBoxPtr()->MaxZ = arg;
568
}
569

570
Py::Float BoundBoxPy::getXMin() const
571
{
572
    return Py::Float(getBoundBoxPtr()->MinX);
573
}
574

575
void BoundBoxPy::setXMin(Py::Float arg)
576
{
577
    getBoundBoxPtr()->MinX = arg;
578
}
579

580
Py::Float BoundBoxPy::getYMin() const
581
{
582
    return Py::Float(getBoundBoxPtr()->MinY);
583
}
584

585
void BoundBoxPy::setYMin(Py::Float arg)
586
{
587
    getBoundBoxPtr()->MinY = arg;
588
}
589

590
Py::Float BoundBoxPy::getZMin() const
591
{
592
    return Py::Float(getBoundBoxPtr()->MinZ);
593
}
594

595
void BoundBoxPy::setZMin(Py::Float arg)
596
{
597
    getBoundBoxPtr()->MinZ = arg;
598
}
599

600
Py::Float BoundBoxPy::getXLength() const
601
{
602
    return Py::Float(getBoundBoxPtr()->LengthX());
603
}
604

605
Py::Float BoundBoxPy::getYLength() const
606
{
607
    return Py::Float(getBoundBoxPtr()->LengthY());
608
}
609

610
Py::Float BoundBoxPy::getZLength() const
611
{
612
    return Py::Float(getBoundBoxPtr()->LengthZ());
613
}
614

615
Py::Float BoundBoxPy::getDiagonalLength() const
616
{
617
    if (!getBoundBoxPtr()->IsValid()) {
618
        throw Py::FloatingPointError("Cannot determine diagonal length of invalid bounding box");
619
    }
620
    return Py::Float(getBoundBoxPtr()->CalcDiagonalLength());
621
}
622

623
PyObject* BoundBoxPy::getCustomAttributes(const char* /*attr*/) const
624
{
625
    return nullptr;
626
}
627

628
int BoundBoxPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
629
{
630
    return 0;
631
}
632

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

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

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

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