Blender V4.5
BPy_SVertex.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BPy_SVertex.h"
10
11#include "../BPy_Convert.h"
12#include "../BPy_Id.h"
14
15#include "BLI_sys_types.h"
16
17using namespace Freestyle;
18
20
21/*----------------------SVertex methods ----------------------------*/
22
24 /* Wrap. */
25 SVertex_doc,
26 "Class hierarchy: :class:`Interface0D` > :class:`SVertex`\n"
27 "\n"
28 "Class to define a vertex of the embedding.\n"
29 "\n"
30 ".. method:: __init__()\n"
31 " __init__(brother)\n"
32 " __init__(point_3d, id)\n"
33 "\n"
34 " Builds a :class:`SVertex` using the default constructor,\n"
35 " copy constructor or the overloaded constructor which builds"
36 " a :class:`SVertex` from 3D coordinates and an Id.\n"
37 "\n"
38 " :arg brother: A SVertex object.\n"
39 " :type brother: :class:`SVertex`\n"
40 " :arg point_3d: A three-dimensional vector.\n"
41 " :type point_3d: :class:`mathutils.Vector`\n"
42 " :arg id: An Id object.\n"
43 " :type id: :class:`Id`");
44
45static int SVertex_init(BPy_SVertex *self, PyObject *args, PyObject *kwds)
46{
47 static const char *kwlist_1[] = {"brother", nullptr};
48 static const char *kwlist_2[] = {"point_3d", "id", nullptr};
49 PyObject *obj = nullptr;
50 float v[3];
51
52 if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &SVertex_Type, &obj)) {
53 if (!obj) {
54 self->sv = new SVertex();
55 }
56 else {
57 self->sv = new SVertex(*(((BPy_SVertex *)obj)->sv));
58 }
59 }
60 else if ((void)PyErr_Clear(),
61 PyArg_ParseTupleAndKeywords(
62 args, kwds, "O&O!", (char **)kwlist_2, convert_v3, v, &Id_Type, &obj))
63 {
64 Vec3r point_3d(v[0], v[1], v[2]);
65 self->sv = new SVertex(point_3d, *(((BPy_Id *)obj)->id));
66 }
67 else {
68 PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
69 return -1;
70 }
71 self->py_if0D.if0D = self->sv;
72 self->py_if0D.borrowed = false;
73 return 0;
74}
75
77 /* Wrap. */
78 SVertex_add_normal_doc,
79 ".. method:: add_normal(normal)\n"
80 "\n"
81 " Adds a normal to the SVertex's set of normals. If the same normal\n"
82 " is already in the set, nothing changes.\n"
83 "\n"
84 " :arg normal: A three-dimensional vector.\n"
85 " :type normal: :class:`mathutils.Vector` | tuple[float, float, float] | list[float]");
86
87static PyObject *SVertex_add_normal(BPy_SVertex *self, PyObject *args, PyObject *kwds)
88{
89 static const char *kwlist[] = {"normal", nullptr};
90 PyObject *py_normal;
91 Vec3r n;
92
93 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", (char **)kwlist, &py_normal)) {
94 return nullptr;
95 }
96 if (!Vec3r_ptr_from_PyObject(py_normal, n)) {
97 PyErr_SetString(PyExc_TypeError,
98 "argument 1 must be a 3D vector (either a list of 3 elements or Vector)");
99 return nullptr;
100 }
101 self->sv->AddNormal(n);
102 Py_RETURN_NONE;
103}
104
106 /* Wrap. */
107 SVertex_add_fedge_doc,
108 ".. method:: add_fedge(fedge)\n"
109 "\n"
110 " Add an FEdge to the list of edges emanating from this SVertex.\n"
111 "\n"
112 " :arg fedge: An FEdge.\n"
113 " :type fedge: :class:`FEdge`");
114
115static PyObject *SVertex_add_fedge(BPy_SVertex *self, PyObject *args, PyObject *kwds)
116{
117 static const char *kwlist[] = {"fedge", nullptr};
118 PyObject *py_fe;
119
120 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist, &FEdge_Type, &py_fe)) {
121 return nullptr;
122 }
123 self->sv->AddFEdge(((BPy_FEdge *)py_fe)->fe);
124 Py_RETURN_NONE;
125}
126
127// virtual bool operator== (const SVertex &brother)
128
129#ifdef __GNUC__
130# ifdef __clang__
131# pragma clang diagnostic push
132# pragma clang diagnostic ignored "-Wcast-function-type"
133# else
134# pragma GCC diagnostic push
135# pragma GCC diagnostic ignored "-Wcast-function-type"
136# endif
137#endif
138
139static PyMethodDef BPy_SVertex_methods[] = {
140 {"add_normal",
141 (PyCFunction)SVertex_add_normal,
142 METH_VARARGS | METH_KEYWORDS,
143 SVertex_add_normal_doc},
144 {"add_fedge",
145 (PyCFunction)SVertex_add_fedge,
146 METH_VARARGS | METH_KEYWORDS,
147 SVertex_add_fedge_doc},
148 {nullptr, nullptr, 0, nullptr},
149};
150
151#ifdef __GNUC__
152# ifdef __clang__
153# pragma clang diagnostic pop
154# else
155# pragma GCC diagnostic pop
156# endif
157#endif
158
159/*----------------------mathutils callbacks ----------------------------*/
160
161/* subtype */
162#define MATHUTILS_SUBTYPE_POINT3D 1
163#define MATHUTILS_SUBTYPE_POINT2D 2
164
166{
167 if (!BPy_SVertex_Check(bmo->cb_user)) {
168 return -1;
169 }
170 return 0;
171}
172
173static int SVertex_mathutils_get(BaseMathObject *bmo, int subtype)
174{
175 BPy_SVertex *self = (BPy_SVertex *)bmo->cb_user;
176 switch (subtype) {
178 bmo->data[0] = self->sv->getX();
179 bmo->data[1] = self->sv->getY();
180 bmo->data[2] = self->sv->getZ();
181 break;
183 bmo->data[0] = self->sv->getProjectedX();
184 bmo->data[1] = self->sv->getProjectedY();
185 bmo->data[2] = self->sv->getProjectedZ();
186 break;
187 default:
188 return -1;
189 }
190 return 0;
191}
192
193static int SVertex_mathutils_set(BaseMathObject *bmo, int subtype)
194{
195 BPy_SVertex *self = (BPy_SVertex *)bmo->cb_user;
196 switch (subtype) {
198 Vec3r p(bmo->data[0], bmo->data[1], bmo->data[2]);
199 self->sv->setPoint3D(p);
200 break;
201 }
203 Vec3r p(bmo->data[0], bmo->data[1], bmo->data[2]);
204 self->sv->setPoint2D(p);
205 break;
206 }
207 default:
208 return -1;
209 }
210 return 0;
211}
212
213static int SVertex_mathutils_get_index(BaseMathObject *bmo, int subtype, int index)
214{
215 BPy_SVertex *self = (BPy_SVertex *)bmo->cb_user;
216 switch (subtype) {
218 switch (index) {
219 case 0:
220 bmo->data[0] = self->sv->getX();
221 break;
222 case 1:
223 bmo->data[1] = self->sv->getY();
224 break;
225 case 2:
226 bmo->data[2] = self->sv->getZ();
227 break;
228 default:
229 return -1;
230 }
231 break;
233 switch (index) {
234 case 0:
235 bmo->data[0] = self->sv->getProjectedX();
236 break;
237 case 1:
238 bmo->data[1] = self->sv->getProjectedY();
239 break;
240 case 2:
241 bmo->data[2] = self->sv->getProjectedZ();
242 break;
243 default:
244 return -1;
245 }
246 break;
247 default:
248 return -1;
249 }
250 return 0;
251}
252
253static int SVertex_mathutils_set_index(BaseMathObject *bmo, int subtype, int index)
254{
255 BPy_SVertex *self = (BPy_SVertex *)bmo->cb_user;
256 switch (subtype) {
258 Vec3r p(self->sv->point3D());
259 p[index] = bmo->data[index];
260 self->sv->setPoint3D(p);
261 break;
262 }
264 Vec3r p(self->sv->point2D());
265 p[index] = bmo->data[index];
266 self->sv->setPoint2D(p);
267 break;
268 }
269 default:
270 return -1;
271 }
272 return 0;
273}
274
282
284
289
290/*----------------------SVertex get/setters ----------------------------*/
291
293 /* Wrap. */
294 SVertex_point_3d_doc,
295 "The 3D coordinates of the SVertex.\n"
296 "\n"
297 ":type: :class:`mathutils.Vector`");
298
299static PyObject *SVertex_point_3d_get(BPy_SVertex *self, void * /*closure*/)
300{
303}
304
305static int SVertex_point_3d_set(BPy_SVertex *self, PyObject *value, void * /*closure*/)
306{
307 float v[3];
308 if (mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1) {
309 return -1;
310 }
311 Vec3r p(v[0], v[1], v[2]);
312 self->sv->setPoint3D(p);
313 return 0;
314}
315
317 /* Wrap. */
318 SVertex_point_2d_doc,
319 "The projected 3D coordinates of the SVertex.\n"
320 "\n"
321 ":type: :class:`mathutils.Vector`");
322
323static PyObject *SVertex_point_2d_get(BPy_SVertex *self, void * /*closure*/)
324{
327}
328
329static int SVertex_point_2d_set(BPy_SVertex *self, PyObject *value, void * /*closure*/)
330{
331 float v[3];
332 if (mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1) {
333 return -1;
334 }
335 Vec3r p(v[0], v[1], v[2]);
336 self->sv->setPoint2D(p);
337 return 0;
338}
339
341 /* Wrap. */
342 SVertex_id_doc,
343 "The Id of this SVertex.\n"
344 "\n"
345 ":type: :class:`Id`");
346
347static PyObject *SVertex_id_get(BPy_SVertex *self, void * /*closure*/)
348{
349 Id id(self->sv->getId());
350 return BPy_Id_from_Id(id); // return a copy
351}
352
353static int SVertex_id_set(BPy_SVertex *self, PyObject *value, void * /*closure*/)
354{
355 if (!BPy_Id_Check(value)) {
356 PyErr_SetString(PyExc_TypeError, "value must be an Id");
357 return -1;
358 }
359 self->sv->setId(*(((BPy_Id *)value)->id));
360 return 0;
361}
362
364 /* Wrap. */
365 SVertex_normals_doc,
366 "The normals for this Vertex as a list. In a sharp surface, an SVertex\n"
367 "has exactly one normal. In a smooth surface, an SVertex can have any\n"
368 "number of normals.\n"
369 "\n"
370 ":type: list of :class:`mathutils.Vector`");
371
372static PyObject *SVertex_normals_get(BPy_SVertex *self, void * /*closure*/)
373{
374 PyObject *py_normals;
375 set<Vec3r> normals = self->sv->normals();
376 set<Vec3r>::iterator it;
377 py_normals = PyList_New(normals.size());
378 uint i = 0;
379
380 for (it = normals.begin(); it != normals.end(); it++) {
381 Vec3r v(*it);
382 PyList_SET_ITEM(py_normals, i++, Vector_from_Vec3r(v));
383 }
384 return py_normals;
385}
386
388 /* Wrap. */
389 SVertex_normals_size_doc,
390 "The number of different normals for this SVertex.\n"
391 "\n"
392 ":type: int");
393
394static PyObject *SVertex_normals_size_get(BPy_SVertex *self, void * /*closure*/)
395{
396 return PyLong_FromLong(self->sv->normalsSize());
397}
398
400 /* Wrap. */
401 SVertex_viewvertex_doc,
402 "If this SVertex is also a ViewVertex, this property refers to the\n"
403 "ViewVertex, and None otherwise.\n"
404 "\n"
405 ":type: :class:`ViewVertex`");
406
407static PyObject *SVertex_viewvertex_get(BPy_SVertex *self, void * /*closure*/)
408{
409 ViewVertex *vv = self->sv->viewvertex();
410 if (vv) {
412 }
413 Py_RETURN_NONE;
414}
415
417 /* Wrap. */
418 SVertex_curvatures_doc,
419 "Curvature information expressed in the form of a seven-element tuple\n"
420 "(K1, e1, K2, e2, Kr, er, dKr), where K1 and K2 are scalar values\n"
421 "representing the first (maximum) and second (minimum) principal\n"
422 "curvatures at this SVertex, respectively; e1 and e2 are\n"
423 "three-dimensional vectors representing the first and second principal\n"
424 "directions, i.e. the directions of the normal plane where the\n"
425 "curvature takes its maximum and minimum values, respectively; and Kr,\n"
426 "er and dKr are the radial curvature, radial direction, and the\n"
427 "derivative of the radial curvature at this SVertex, respectively.\n"
428 "\n"
429 ":type: tuple");
430
431static PyObject *SVertex_curvatures_get(BPy_SVertex *self, void * /*closure*/)
432{
433 const CurvatureInfo *info = self->sv->getCurvatureInfo();
434 if (!info) {
435 Py_RETURN_NONE;
436 }
437 Vec3r e1(info->e1.x(), info->e1.y(), info->e1.z());
438 Vec3r e2(info->e2.x(), info->e2.y(), info->e2.z());
439 Vec3r er(info->er.x(), info->er.y(), info->er.z());
440 PyObject *retval = PyTuple_New(7);
441 PyTuple_SET_ITEMS(retval,
442 PyFloat_FromDouble(info->K1),
443 PyFloat_FromDouble(info->K2),
446 PyFloat_FromDouble(info->Kr),
448 PyFloat_FromDouble(info->dKr));
449 return retval;
450}
451
452static PyGetSetDef BPy_SVertex_getseters[] = {
453 {"point_3d",
454 (getter)SVertex_point_3d_get,
455 (setter)SVertex_point_3d_set,
456 SVertex_point_3d_doc,
457 nullptr},
458 {"point_2d",
459 (getter)SVertex_point_2d_get,
460 (setter)SVertex_point_2d_set,
461 SVertex_point_2d_doc,
462 nullptr},
463 {"id", (getter)SVertex_id_get, (setter)SVertex_id_set, SVertex_id_doc, nullptr},
464 {"normals", (getter)SVertex_normals_get, (setter) nullptr, SVertex_normals_doc, nullptr},
465 {"normals_size",
467 (setter) nullptr,
468 SVertex_normals_size_doc,
469 nullptr},
470 {"viewvertex",
472 (setter) nullptr,
473 SVertex_viewvertex_doc,
474 nullptr},
475 {"curvatures",
477 (setter) nullptr,
478 SVertex_curvatures_doc,
479 nullptr},
480 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
481};
482
483/*-----------------------BPy_SVertex type definition ------------------------------*/
484
485PyTypeObject SVertex_Type = {
486 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
487 /*tp_name*/ "SVertex",
488 /*tp_basicsize*/ sizeof(BPy_SVertex),
489 /*tp_itemsize*/ 0,
490 /*tp_dealloc*/ nullptr,
491 /*tp_vectorcall_offset*/ 0,
492 /*tp_getattr*/ nullptr,
493 /*tp_setattr*/ nullptr,
494 /*tp_as_async*/ nullptr,
495 /*tp_repr*/ nullptr,
496 /*tp_as_number*/ nullptr,
497 /*tp_as_sequence*/ nullptr,
498 /*tp_as_mapping*/ nullptr,
499 /*tp_hash*/ nullptr,
500 /*tp_call*/ nullptr,
501 /*tp_str*/ nullptr,
502 /*tp_getattro*/ nullptr,
503 /*tp_setattro*/ nullptr,
504 /*tp_as_buffer*/ nullptr,
505 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
506 /*tp_doc*/ SVertex_doc,
507 /*tp_traverse*/ nullptr,
508 /*tp_clear*/ nullptr,
509 /*tp_richcompare*/ nullptr,
510 /*tp_weaklistoffset*/ 0,
511 /*tp_iter*/ nullptr,
512 /*tp_iternext*/ nullptr,
513 /*tp_methods*/ BPy_SVertex_methods,
514 /*tp_members*/ nullptr,
515 /*tp_getset*/ BPy_SVertex_getseters,
516 /*tp_base*/ &Interface0D_Type,
517 /*tp_dict*/ nullptr,
518 /*tp_descr_get*/ nullptr,
519 /*tp_descr_set*/ nullptr,
520 /*tp_dictoffset*/ 0,
521 /*tp_init*/ (initproc)SVertex_init,
522 /*tp_alloc*/ nullptr,
523 /*tp_new*/ nullptr,
524};
525
unsigned char uchar
unsigned int uint
PyObject * Vector_from_Vec3r(Vec3r &vec)
PyObject * BPy_Id_from_Id(Id &id)
PyObject * Any_BPy_ViewVertex_from_ViewVertex(ViewVertex &vv)
int convert_v3(PyObject *obj, void *v)
bool Vec3r_ptr_from_PyObject(PyObject *obj, Vec3r &vec)
PyTypeObject FEdge_Type
PyTypeObject Id_Type
Definition BPy_Id.cpp:160
#define BPy_Id_Check(v)
Definition BPy_Id.h:23
PyTypeObject Interface0D_Type
static PyObject * SVertex_point_3d_get(BPy_SVertex *self, void *)
static int SVertex_point_3d_set(BPy_SVertex *self, PyObject *value, void *)
static int SVertex_point_2d_set(BPy_SVertex *self, PyObject *value, void *)
static PyObject * SVertex_add_normal(BPy_SVertex *self, PyObject *args, PyObject *kwds)
#define MATHUTILS_SUBTYPE_POINT3D
#define MATHUTILS_SUBTYPE_POINT2D
void SVertex_mathutils_register_callback()
static PyObject * SVertex_viewvertex_get(BPy_SVertex *self, void *)
static PyObject * SVertex_point_2d_get(BPy_SVertex *self, void *)
static uchar SVertex_mathutils_cb_index
PyTypeObject SVertex_Type
static int SVertex_mathutils_set_index(BaseMathObject *bmo, int subtype, int index)
static PyMethodDef BPy_SVertex_methods[]
static int SVertex_init(BPy_SVertex *self, PyObject *args, PyObject *kwds)
static PyObject * SVertex_curvatures_get(BPy_SVertex *self, void *)
static PyObject * SVertex_normals_size_get(BPy_SVertex *self, void *)
static Mathutils_Callback SVertex_mathutils_cb
static PyObject * SVertex_normals_get(BPy_SVertex *self, void *)
static int SVertex_mathutils_get(BaseMathObject *bmo, int subtype)
static PyObject * SVertex_add_fedge(BPy_SVertex *self, PyObject *args, PyObject *kwds)
PyDoc_STRVAR(SVertex_doc, "Class hierarchy: :class:`Interface0D` > :class:`SVertex`\n" "\n" "Class to define a vertex of the embedding.\n" "\n" ".. method:: __init__()\n" " __init__(brother)\n" " __init__(point_3d, id)\n" "\n" " Builds a :class:`SVertex` using the default constructor,\n" " copy constructor or the overloaded constructor which builds" " a :class:`SVertex` from 3D coordinates and an Id.\n" "\n" " :arg brother: A SVertex object.\n" " :type brother: :class:`SVertex`\n" " :arg point_3d: A three-dimensional vector.\n" " :type point_3d: :class:`mathutils.Vector`\n" " :arg id: An Id object.\n" " :type id: :class:`Id`")
static int SVertex_mathutils_set(BaseMathObject *bmo, int subtype)
static int SVertex_id_set(BPy_SVertex *self, PyObject *value, void *)
static PyObject * SVertex_id_get(BPy_SVertex *self, void *)
static int SVertex_mathutils_get_index(BaseMathObject *bmo, int subtype, int index)
static int SVertex_mathutils_check(BaseMathObject *bmo)
static PyGetSetDef BPy_SVertex_getseters[]
#define BPy_SVertex_Check(v)
Definition BPy_SVertex.h:19
ATTR_WARN_UNUSED_RESULT const BMVert * v
PyObject * self
value_type x() const
Definition VecMat.h:489
value_type z() const
Definition VecMat.h:509
value_type y() const
Definition VecMat.h:499
static float normals[][3]
int mathutils_array_parse(float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
Definition mathutils.cc:96
uchar Mathutils_RegisterCallback(Mathutils_Callback *cb)
Definition mathutils.cc:521
PyObject * Vector_CreatePyObject_cb(PyObject *cb_user, int vec_num, uchar cb_type, uchar cb_subtype)
VecMat::Vec3< real > Vec3r
Definition Geom.h:30
inherits from class Rep
Definition AppCanvas.cpp:20
#define PyTuple_SET_ITEMS(op_arg,...)
i
Definition text_draw.cc:230