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