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