Freestyle: Code cleanup, prepare for strict C++ flags
[blender.git] / source / blender / freestyle / intern / python / Interface0D / CurvePoint / BPy_StrokeVertex.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/CurvePoint/BPy_StrokeVertex.cpp
22  *  \ingroup freestyle
23  */
24
25 #include "BPy_StrokeVertex.h"
26
27 #include "../../BPy_Freestyle.h"
28 #include "../../BPy_Convert.h"
29 #include "../../BPy_StrokeAttribute.h"
30 #include "../../Interface0D/BPy_SVertex.h"
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 ///////////////////////////////////////////////////////////////////////////////////////////
37
38 //------------------------INSTANCE METHODS ----------------------------------
39
40 PyDoc_STRVAR(StrokeVertex_doc,
41 "Class hierarchy: :class:`Interface0D` > :class:`CurvePoint` > :class:`StrokeVertex`\n"
42 "\n"
43 "Class to define a stroke vertex.\n"
44 "\n"
45 ".. method:: __init__()\n"
46 "\n"
47 "   Default constructor.\n"
48 "\n"
49 ".. method:: __init__(brother)\n"
50 "\n"
51 "   Copy constructor.\n"
52 "\n"
53 "   :arg brother: A StrokeVertex object.\n"
54 "   :type brother: :class:`StrokeVertex`\n"
55 "\n"
56 ".. method:: __init__(first_vertex, second_vertex, t3d)\n"
57 "\n"
58 "   Build a stroke vertex from 2 stroke vertices and an interpolation\n"
59 "   parameter.\n"
60 "\n"
61 "   :arg first_vertex: The first StrokeVertex.\n"
62 "   :type first_vertex: :class:`StrokeVertex`\n"
63 "   :arg second_vertex: The second StrokeVertex.\n"
64 "   :type second_vertex: :class:`StrokeVertex`\n"
65 "   :arg t3d: An interpolation parameter.\n"
66 "   :type t3d: float\n"
67 "\n"
68 ".. method:: __init__(point)\n"
69 "\n"
70 "   Build a stroke vertex from a CurvePoint\n"
71 "\n"
72 "   :arg point: A CurvePoint object.\n"
73 "   :type point: :class:`CurvePoint`\n"
74 "\n"
75 ".. method:: __init__(svertex)\n"
76 "\n"
77 "   Build a stroke vertex from a SVertex\n"
78 "\n"
79 "   :arg svertex: An SVertex object.\n"
80 "   :type svertex: :class:`SVertex`\n"
81 "\n"
82 ".. method:: __init__(svertex, attribute)\n"
83 "\n"
84 "   Build a stroke vertex from an SVertex and a StrokeAttribute object.\n"
85 "\n"
86 "   :arg svertex: An SVertex object.\n"
87 "   :type svertex: :class:`SVertex`\n"
88 "   :arg attribute: A StrokeAttribute object.\n"
89 "   :type attribute: :class:`StrokeAttribute`");
90
91 static int StrokeVertex_init(BPy_StrokeVertex *self, PyObject *args, PyObject *kwds)
92 {
93         static const char *kwlist_1[] = {"brother", NULL};
94         static const char *kwlist_2[] = {"first_vertex", "second_vertex", "t3d", NULL};
95         static const char *kwlist_3[] = {"point", NULL};
96         static const char *kwlist_4[] = {"svertex", "attribute", NULL};
97         PyObject *obj1 = 0, *obj2 = 0;
98         float t3d;
99
100         if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &StrokeVertex_Type, &obj1)) {
101                 if (!obj1) {
102                         self->sv = new StrokeVertex();
103                 }
104                 else {
105                         if (!((BPy_StrokeVertex *)obj1)->sv) {
106                                 PyErr_SetString(PyExc_TypeError, "argument 1 is an invalid StrokeVertex object");
107                                 return -1;
108                         }
109                         self->sv = new StrokeVertex(*(((BPy_StrokeVertex *)obj1)->sv));
110                 }
111         }
112         else if (PyErr_Clear(),
113                  PyArg_ParseTupleAndKeywords(args, kwds, "O!O!f", (char **)kwlist_2,
114                                              &StrokeVertex_Type, &obj1, &StrokeVertex_Type, &obj2, &t3d))
115         {
116                 StrokeVertex *sv1 = ((BPy_StrokeVertex *)obj1)->sv;
117                 StrokeVertex *sv2 = ((BPy_StrokeVertex *)obj2)->sv;
118                 if (!sv1 || (sv1->A() == 0 && sv1->B() == 0)) {
119                         PyErr_SetString(PyExc_TypeError, "argument 1 is an invalid StrokeVertex object");
120                         return -1;
121                 }
122                 if (!sv2 || (sv2->A() == 0 && sv2->B() == 0)) {
123                         PyErr_SetString(PyExc_TypeError, "argument 2 is an invalid StrokeVertex object");
124                         return -1;
125                 }
126                 self->sv = new StrokeVertex(sv1, sv2, t3d);
127         }
128         else if (PyErr_Clear(),
129                  PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_3, &CurvePoint_Type, &obj1))
130         {
131                 CurvePoint *cp = ((BPy_CurvePoint *)obj1)->cp;
132                 if (!cp || cp->A() == 0 || cp->B() == 0) {
133                         PyErr_SetString(PyExc_TypeError, "argument 1 is an invalid CurvePoint object");
134                         return -1;
135                 }
136                 self->sv = new StrokeVertex(cp);
137         }
138         else if (PyErr_Clear(), (obj2 = 0),
139                  PyArg_ParseTupleAndKeywords(args, kwds, "O!|O!", (char **)kwlist_4,
140                                              &SVertex_Type, &obj1, &StrokeAttribute_Type, &obj2))
141         {
142                 if (!obj2)
143                         self->sv = new StrokeVertex(((BPy_SVertex *)obj1)->sv);
144                 else
145                         self->sv = new StrokeVertex(((BPy_SVertex *)obj1)->sv, *(((BPy_StrokeAttribute *)obj2)->sa));
146         }
147         else {
148                 PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
149                 return -1;
150         }
151         self->py_cp.cp = self->sv;
152         self->py_cp.py_if0D.if0D = self->sv;
153         self->py_cp.py_if0D.borrowed = false;
154         return 0;
155 }
156
157 // real         operator[] (const int i) const
158 // real &       operator[] (const int i)
159
160 /*----------------------mathutils callbacks ----------------------------*/
161
162 static int StrokeVertex_mathutils_check(BaseMathObject *bmo)
163 {
164         if (!BPy_StrokeVertex_Check(bmo->cb_user))
165                 return -1;
166         return 0;
167 }
168
169 static int StrokeVertex_mathutils_get(BaseMathObject *bmo, int /*subtype*/)
170 {
171         BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
172         bmo->data[0] = (float)self->sv->x();
173         bmo->data[1] = (float)self->sv->y();
174         return 0;
175 }
176
177 static int StrokeVertex_mathutils_set(BaseMathObject *bmo, int /*subtype*/)
178 {
179         BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
180         self->sv->setX((real)bmo->data[0]);
181         self->sv->setY((real)bmo->data[1]);
182         return 0;
183 }
184
185 static int StrokeVertex_mathutils_get_index(BaseMathObject *bmo, int /*subtype*/, int index)
186 {
187         BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
188         switch (index) {
189         case 0: bmo->data[0] = (float)self->sv->x(); break;
190         case 1: bmo->data[1] = (float)self->sv->y(); break;
191         default:
192                 return -1;
193         }
194         return 0;
195 }
196
197 static int StrokeVertex_mathutils_set_index(BaseMathObject *bmo, int /*subtype*/, int index)
198 {
199         BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
200         switch (index) {
201         case 0: self->sv->setX((real)bmo->data[0]); break;
202         case 1: self->sv->setY((real)bmo->data[1]); break;
203         default:
204                 return -1;
205         }
206         return 0;
207 }
208
209 static Mathutils_Callback StrokeVertex_mathutils_cb = {
210         StrokeVertex_mathutils_check,
211         StrokeVertex_mathutils_get,
212         StrokeVertex_mathutils_set,
213         StrokeVertex_mathutils_get_index,
214         StrokeVertex_mathutils_set_index
215 };
216
217 static unsigned char StrokeVertex_mathutils_cb_index = -1;
218
219 void StrokeVertex_mathutils_register_callback()
220 {
221         StrokeVertex_mathutils_cb_index = Mathutils_RegisterCallback(&StrokeVertex_mathutils_cb);
222 }
223
224 /*----------------------StrokeVertex get/setters ----------------------------*/
225
226 PyDoc_STRVAR(StrokeVertex_attribute_doc,
227 "StrokeAttribute for this StrokeVertex.\n"
228 "\n"
229 ":type: :class:`StrokeAttribute`");
230
231 static PyObject *StrokeVertex_attribute_get(BPy_StrokeVertex *self, void *UNUSED(closure))
232 {
233         return BPy_StrokeAttribute_from_StrokeAttribute(self->sv->attribute());
234 }
235
236 static int StrokeVertex_attribute_set(BPy_StrokeVertex *self, PyObject *value, void *UNUSED(closure))
237 {
238         if (!BPy_StrokeAttribute_Check(value)) {
239                 PyErr_SetString(PyExc_TypeError, "value must be a StrokeAttribute object");
240                 return -1;
241         }
242         self->sv->setAttribute(*(((BPy_StrokeAttribute *)value)->sa));
243         return 0;
244 }
245
246 PyDoc_STRVAR(StrokeVertex_curvilinear_abscissa_doc,
247 "Curvilinear abscissa of this StrokeVertex in the Stroke.\n"
248 "\n"
249 ":type: float");
250
251 static PyObject *StrokeVertex_curvilinear_abscissa_get(BPy_StrokeVertex *self, void *UNUSED(closure))
252 {
253         return PyFloat_FromDouble(self->sv->curvilinearAbscissa());
254 }
255
256 static int StrokeVertex_curvilinear_abscissa_set(BPy_StrokeVertex *self, PyObject *value, void *UNUSED(closure))
257 {
258         float scalar;
259         if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
260                 PyErr_SetString(PyExc_TypeError, "value must be a number");
261                 return -1;
262         }
263         self->sv->setCurvilinearAbscissa(scalar);
264         return 0;
265 }
266
267 PyDoc_STRVAR(StrokeVertex_point_doc,
268 "2D point coordinates.\n"
269 "\n"
270 ":type: :class:`mathutils.Vector`");
271
272 static PyObject *StrokeVertex_point_get(BPy_StrokeVertex *self, void *UNUSED(closure))
273 {
274         return Vector_CreatePyObject_cb((PyObject *)self, 2, StrokeVertex_mathutils_cb_index, 0);
275 }
276
277 static int StrokeVertex_point_set(BPy_StrokeVertex *self, PyObject *value, void *UNUSED(closure))
278 {
279         float v[2];
280         if (mathutils_array_parse(v, 2, 2, value,
281                                   "value must be a 2-dimensional vector") == -1)
282         {
283                 return -1;
284         }
285         self->sv->setX(v[0]);
286         self->sv->setY(v[1]);
287         return 0;
288 }
289
290 PyDoc_STRVAR(StrokeVertex_stroke_length_doc,
291 "Stroke length (it is only a value retained by the StrokeVertex,\n"
292 "and it won't change the real stroke length).\n"
293 "\n"
294 ":type: float");
295
296 static PyObject *StrokeVertex_stroke_length_get(BPy_StrokeVertex *self, void *UNUSED(closure))
297 {
298         return PyFloat_FromDouble(self->sv->strokeLength());
299 }
300
301 static int StrokeVertex_stroke_length_set(BPy_StrokeVertex *self, PyObject *value, void *UNUSED(closure))
302 {
303         float scalar;
304         if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
305                 PyErr_SetString(PyExc_TypeError, "value must be a number");
306                 return -1;
307         }
308         self->sv->setStrokeLength(scalar);
309         return 0;
310 }
311
312 PyDoc_STRVAR(StrokeVertex_u_doc,
313 "Curvilinear abscissa of this StrokeVertex in the Stroke.\n"
314 "\n"
315 ":type: float");
316
317 static PyObject *StrokeVertex_u_get(BPy_StrokeVertex *self, void *UNUSED(closure))
318 {
319         return PyFloat_FromDouble(self->sv->u());
320 }
321
322 static PyGetSetDef BPy_StrokeVertex_getseters[] = {
323         {(char *)"attribute", (getter)StrokeVertex_attribute_get, (setter)StrokeVertex_attribute_set,
324                               (char *)StrokeVertex_attribute_doc, NULL},
325         {(char *)"curvilinear_abscissa", (getter)StrokeVertex_curvilinear_abscissa_get,
326                                          (setter)StrokeVertex_curvilinear_abscissa_set,
327                                          (char *)StrokeVertex_curvilinear_abscissa_doc, NULL},
328         {(char *)"point", (getter)StrokeVertex_point_get, (setter)StrokeVertex_point_set,
329                           (char *)StrokeVertex_point_doc, NULL},
330         {(char *)"stroke_length", (getter)StrokeVertex_stroke_length_get, (setter)StrokeVertex_stroke_length_set,
331                                   (char *)StrokeVertex_stroke_length_doc, NULL},
332         {(char *)"u", (getter)StrokeVertex_u_get, (setter)NULL, (char *)StrokeVertex_u_doc, NULL},
333         {NULL, NULL, NULL, NULL, NULL}  /* Sentinel */
334 };
335
336 /*-----------------------BPy_StrokeVertex type definition ------------------------------*/
337 PyTypeObject StrokeVertex_Type = {
338         PyVarObject_HEAD_INIT(NULL, 0)
339         "StrokeVertex",                 /* tp_name */
340         sizeof(BPy_StrokeVertex),       /* tp_basicsize */
341         0,                              /* tp_itemsize */
342         0,                              /* tp_dealloc */
343         0,                              /* tp_print */
344         0,                              /* tp_getattr */
345         0,                              /* tp_setattr */
346         0,                              /* tp_reserved */
347         0,                              /* tp_repr */
348         0,                              /* tp_as_number */
349         0,                              /* tp_as_sequence */
350         0,                              /* tp_as_mapping */
351         0,                              /* tp_hash  */
352         0,                              /* tp_call */
353         0,                              /* tp_str */
354         0,                              /* tp_getattro */
355         0,                              /* tp_setattro */
356         0,                              /* tp_as_buffer */
357         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
358         StrokeVertex_doc,               /* tp_doc */
359         0,                              /* tp_traverse */
360         0,                              /* tp_clear */
361         0,                              /* tp_richcompare */
362         0,                              /* tp_weaklistoffset */
363         0,                              /* tp_iter */
364         0,                              /* tp_iternext */
365         0,                              /* tp_methods */
366         0,                              /* tp_members */
367         BPy_StrokeVertex_getseters,     /* tp_getset */
368         &CurvePoint_Type,               /* tp_base */
369         0,                              /* tp_dict */
370         0,                              /* tp_descr_get */
371         0,                              /* tp_descr_set */
372         0,                              /* tp_dictoffset */
373         (initproc)StrokeVertex_init,    /* tp_init */
374         0,                              /* tp_alloc */
375         0,                              /* tp_new */
376 };
377
378 ///////////////////////////////////////////////////////////////////////////////////////////
379
380 #ifdef __cplusplus
381 }
382 #endif