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