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