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