FreeCAD

Форк
0
/
GeometryPyCXX.cpp 
409 строк · 10.9 Кб
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
#ifndef _PreComp_
26
#include <sstream>
27
#endif
28

29
#include "GeometryPyCXX.h"
30
#include "VectorPy.h"
31

32

33
// NOLINTBEGIN(readability-identifier-length)
34
int Py::Vector::Vector_TypeCheck(PyObject* obj)
35
{
36
    return PyObject_TypeCheck(obj, &(Base::VectorPy::Type));
37
}
38

39
bool Py::Vector::accepts(PyObject* obj) const
40
{
41
    if (obj && Vector_TypeCheck(obj)) {
42
        return true;
43
    }
44
    if (obj && PySequence_Check(obj)) {
45
        return (PySequence_Size(obj) == 3);
46
    }
47

48
    return false;
49
}
50

51
Py::Vector::Vector(const Base::Vector3d& vec)
52
{
53
    set(new Base::VectorPy(vec), true);
54
    validate();
55
}
56

57
Py::Vector::Vector(const Base::Vector3f& vec)
58
{
59
    set(new Base::VectorPy(vec), true);
60
    validate();
61
}
62

63
Py::Vector& Py::Vector::operator=(PyObject* rhsp)
64
{
65
    if (ptr() == rhsp) {
66
        return *this;
67
    }
68
    set(rhsp, false);
69
    return *this;
70
}
71

72
Py::Vector& Py::Vector::operator=(const Base::Vector3d& vec)
73
{
74
    set(new Base::VectorPy(vec), true);
75
    return *this;
76
}
77

78
Py::Vector& Py::Vector::operator=(const Base::Vector3f& vec)
79
{
80
    set(new Base::VectorPy(vec), true);
81
    return *this;
82
}
83

84
Base::Vector3d Py::Vector::toVector() const
85
{
86
    if (Vector_TypeCheck(ptr())) {
87
        return static_cast<Base::VectorPy*>(ptr())->value();
88
    }
89

90
    return Base::getVectorFromTuple<double>(ptr());
91
}
92

93
namespace Base
94
{
95

96
Py::PythonType& Vector2dPy::behaviors()
97
{
98
    return Py::PythonClass<Vector2dPy>::behaviors();
99
}
100

101
PyTypeObject* Vector2dPy::type_object()
102
{
103
    return Py::PythonClass<Vector2dPy>::type_object();
104
}
105

106
bool Vector2dPy::check(PyObject* py)
107
{
108
    return Py::PythonClass<Vector2dPy>::check(py);
109
}
110

111
Py::PythonClassObject<Vector2dPy> Vector2dPy::create(const Vector2d& vec)
112
{
113
    return create(vec.x, vec.y);
114
}
115

116
Py::PythonClassObject<Vector2dPy> Vector2dPy::create(double vx, double vy)
117
{
118
    Py::Callable class_type(type());
119
    Py::Tuple arg(2);
120
    arg.setItem(0, Py::Float(vx));
121
    arg.setItem(1, Py::Float(vy));
122
    Py::PythonClassObject<Vector2dPy> py =
123
        Py::PythonClassObject<Vector2dPy>(class_type.apply(arg, Py::Dict()));
124
    return py;
125
}
126

127
Vector2dPy::Vector2dPy(Py::PythonClassInstance* self, Py::Tuple& args, Py::Dict& kwds)
128
    : Py::PythonClass<Vector2dPy>::PythonClass(self, args, kwds)
129
{
130
    double vx = 0;
131
    double vy = 0;
132
    if (!PyArg_ParseTuple(args.ptr(), "|dd", &vx, &vy)) {
133
        throw Py::Exception();
134
    }
135

136
    v.x = vx;
137
    v.y = vy;
138
}
139

140
Vector2dPy::~Vector2dPy() = default;
141

142
Py::Object Vector2dPy::repr()
143
{
144
    Py::Float vx(v.x);
145
    Py::Float vy(v.y);
146
    std::stringstream str;
147
    str << "Vector2 (";
148
    str << static_cast<std::string>(vx.repr()) << ", " << static_cast<std::string>(vy.repr());
149
    str << ")";
150

151
    return Py::String(str.str());  // NOLINT
152
}
153

154
Py::Object Vector2dPy::getattro(const Py::String& name_)
155
{
156
    // For Py3 either handle __dict__ or implement __dir__ as shown here:
157
    // https://stackoverflow.com/questions/48609111/how-is-dir-implemented-exactly-and-how-should-i-know-it
158
    //
159
    std::string name(name_.as_std_string("utf-8"));
160

161
    if (name == "__dict__") {
162
        Py::Dict attr;
163
        attr.setItem(Py::String("x"), Py::Float(v.x));
164
        attr.setItem(Py::String("y"), Py::Float(v.y));
165
        return attr;  // NOLINT
166
    }
167
    if (name == "x") {
168
        return Py::Float(v.x);  // NOLINT
169
    }
170
    if (name == "y") {
171
        return Py::Float(v.y);  // NOLINT
172
    }
173

174
    return genericGetAttro(name_);
175
}
176

177
int Vector2dPy::setattro(const Py::String& name_, const Py::Object& value)
178
{
179
    std::string name(name_.as_std_string("utf-8"));
180

181
    if (name == "x" && !value.isNull()) {
182
        v.x = static_cast<double>(Py::Float(value));
183
        return 0;
184
    }
185
    if (name == "y" && !value.isNull()) {
186
        v.y = static_cast<double>(Py::Float(value));
187
        return 0;
188
    }
189

190
    return genericSetAttro(name_, value);
191
}
192

193
Py::Object Vector2dPy::number_negative()
194
{
195
    return create(-v.x, -v.y);  // NOLINT
196
}
197

198
Py::Object Vector2dPy::number_positive()
199
{
200
    return create(v.x, v.y);  // NOLINT
201
}
202

203
Py::Object Vector2dPy::number_absolute()
204
{
205
    return create(fabs(v.x), fabs(v.y));  // NOLINT
206
}
207

208
Py::Object Vector2dPy::number_invert()
209
{
210
    throw Py::TypeError("Not defined");
211
}
212

213
Py::Object Vector2dPy::number_int()
214
{
215
    throw Py::TypeError("Not defined");
216
}
217

218
Py::Object Vector2dPy::number_float()
219
{
220
    throw Py::TypeError("Not defined");
221
}
222

223
Py::Object Vector2dPy::number_add(const Py::Object& py)
224
{
225
    Vector2d vec(Py::toVector2d(py));
226
    vec = v + vec;
227
    return create(vec);  // NOLINT
228
}
229

230
Py::Object Vector2dPy::number_subtract(const Py::Object& py)
231
{
232
    Vector2d vec(Py::toVector2d(py));
233
    vec = v - vec;
234
    return create(vec);  // NOLINT
235
}
236

237
Py::Object Vector2dPy::number_multiply(const Py::Object& py)
238
{
239
    if (PyObject_TypeCheck(py.ptr(), Vector2dPy::type_object())) {
240
        Vector2d vec(Py::toVector2d(py));
241
        double scalar = v * vec;
242
        return Py::Float(scalar);  // NOLINT
243
    }
244
    if (py.isNumeric()) {
245
        double scale = static_cast<double>(Py::Float(py));
246
        return create(v * scale);  // NOLINT
247
    }
248

249
    throw Py::TypeError("Argument must be Vector2d or Float");
250
}
251

252
Py::Object Vector2dPy::number_remainder(const Py::Object&)
253
{
254
    throw Py::TypeError("Not defined");
255
}
256

257
Py::Object Vector2dPy::number_divmod(const Py::Object&)
258
{
259
    throw Py::TypeError("Not defined");
260
}
261

262
Py::Object Vector2dPy::number_lshift(const Py::Object&)
263
{
264
    throw Py::TypeError("Not defined");
265
}
266

267
Py::Object Vector2dPy::number_rshift(const Py::Object&)
268
{
269
    throw Py::TypeError("Not defined");
270
}
271

272
Py::Object Vector2dPy::number_and(const Py::Object&)
273
{
274
    throw Py::TypeError("Not defined");
275
}
276

277
Py::Object Vector2dPy::number_xor(const Py::Object&)
278
{
279
    throw Py::TypeError("Not defined");
280
}
281

282
Py::Object Vector2dPy::number_or(const Py::Object&)
283
{
284
    throw Py::TypeError("Not defined");
285
}
286

287
Py::Object Vector2dPy::number_power(const Py::Object&, const Py::Object&)
288
{
289
    throw Py::TypeError("Not defined");
290
}
291

292
Py::Object Vector2dPy::isNull(const Py::Tuple& args)
293
{
294
    double tol = 0.0;
295
    if (args.size() > 0) {
296
        tol = static_cast<double>(Py::Float(args[0]));
297
    }
298
    return Py::Boolean(v.IsNull(tol));  // NOLINT
299
}
300
PYCXX_VARARGS_METHOD_DECL(Vector2dPy, isNull)
301

302
Py::Object Vector2dPy::length(const Py::Tuple&)
303
{
304
    return Py::Float(v.Length());  // NOLINT
305
}
306
PYCXX_VARARGS_METHOD_DECL(Vector2dPy, length)
307

308
Py::Object Vector2dPy::atan2(const Py::Tuple&)
309
{
310
    return Py::Float(v.Angle());  // NOLINT
311
}
312
PYCXX_VARARGS_METHOD_DECL(Vector2dPy, atan2)
313

314
Py::Object Vector2dPy::square(const Py::Tuple&)
315
{
316
    return Py::Float(v.Sqr());  // NOLINT
317
}
318
PYCXX_VARARGS_METHOD_DECL(Vector2dPy, square)
319

320
Py::Object Vector2dPy::scale(const Py::Tuple& args)
321
{
322
    double value = static_cast<double>(Py::Float(args[0]));
323
    v.Scale(value);
324
    return Py::None();
325
}
326
PYCXX_VARARGS_METHOD_DECL(Vector2dPy, scale)
327

328
Py::Object Vector2dPy::rotate(const Py::Tuple& args)
329
{
330
    double value = static_cast<double>(Py::Float(args[0]));
331
    v.Rotate(value);
332
    return Py::None();
333
}
334
PYCXX_VARARGS_METHOD_DECL(Vector2dPy, rotate)
335

336
Py::Object Vector2dPy::normalize(const Py::Tuple&)
337
{
338
    v.Normalize();
339
    return Py::None();
340
}
341
PYCXX_VARARGS_METHOD_DECL(Vector2dPy, normalize)
342

343
Py::Object Vector2dPy::perpendicular(const Py::Tuple& args)
344
{
345
    bool value = static_cast<bool>(Py::Boolean(args[0]));
346
    Base::Vector2d pnt = v.Perpendicular(value);
347
    return create(pnt);  // NOLINT
348
}
349
PYCXX_VARARGS_METHOD_DECL(Vector2dPy, perpendicular)
350

351
Py::Object Vector2dPy::distance(const Py::Tuple& args)
352
{
353
    Base::Vector2d pnt = Py::toVector2d(args[0]);
354
    return Py::Float(pnt.Distance(v));  // NOLINT
355
}
356
PYCXX_VARARGS_METHOD_DECL(Vector2dPy, distance)
357

358
Py::Object Vector2dPy::isEqual(const Py::Tuple& args)
359
{
360
    Base::Vector2d pnt = Py::toVector2d(args[0]);
361
    double tol = static_cast<double>(Py::Float(args[1]));
362
    return Py::Boolean(v.IsEqual(pnt, tol));  // NOLINT
363
}
364
PYCXX_VARARGS_METHOD_DECL(Vector2dPy, isEqual)
365

366
Py::Object Vector2dPy::getAngle(const Py::Tuple& args)
367
{
368
    Base::Vector2d vec = Py::toVector2d(args[0]);
369
    return Py::Float(v.GetAngle(vec));  // NOLINT
370
}
371
PYCXX_VARARGS_METHOD_DECL(Vector2dPy, getAngle)
372

373
Py::Object Vector2dPy::projectToLine(const Py::Tuple& args)
374
{
375
    Base::Vector2d pnt1 = Py::toVector2d(args[0]);
376
    Base::Vector2d pnt2 = Py::toVector2d(args[1]);
377
    v.ProjectToLine(pnt1, pnt2);
378
    return Py::None();
379
}
380
PYCXX_VARARGS_METHOD_DECL(Vector2dPy, projectToLine)
381
// NOLINTEND(readability-identifier-length)
382

383
void Vector2dPy::init_type()
384
{
385
    behaviors().name("Vector2d");
386
    behaviors().doc("Vector2d class");
387
    behaviors().supportGetattro();
388
    behaviors().supportSetattro();
389
    behaviors().supportRepr();
390
    behaviors().supportNumberType();
391

392
    PYCXX_ADD_VARARGS_METHOD(isNull, isNull, "isNull()");
393
    PYCXX_ADD_VARARGS_METHOD(length, length, "length()");
394
    PYCXX_ADD_VARARGS_METHOD(atan2, atan2, "atan2()");
395
    PYCXX_ADD_VARARGS_METHOD(square, square, "square()");
396
    PYCXX_ADD_VARARGS_METHOD(scale, scale, "scale()");
397
    PYCXX_ADD_VARARGS_METHOD(rotate, rotate, "rotate()");
398
    PYCXX_ADD_VARARGS_METHOD(normalize, normalize, "normalize()");
399
    PYCXX_ADD_VARARGS_METHOD(perpendicular, perpendicular, "perpendicular()");
400
    PYCXX_ADD_VARARGS_METHOD(distance, distance, "distance()");
401
    PYCXX_ADD_VARARGS_METHOD(isEqual, isEqual, "isEqual()");
402
    PYCXX_ADD_VARARGS_METHOD(getAngle, getAngle, "getAngle()");
403
    PYCXX_ADD_VARARGS_METHOD(projectToLine, projectToLine, "projectToLine()");
404

405
    // Call to make the type ready for use
406
    behaviors().readyType();
407
}
408

409
}  // namespace Base
410

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

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

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

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