Made the Freestyle Python API compatible with Python 3.
[blender.git] / source / blender / freestyle / intern / python / BPy_Operators.cpp
1 #include "BPy_Operators.h"
2
3 #include "BPy_BinaryPredicate1D.h"
4 #include "BPy_UnaryPredicate0D.h"
5 #include "BPy_UnaryPredicate1D.h"
6 #include "UnaryFunction0D/BPy_UnaryFunction0DDouble.h"
7 #include "UnaryFunction1D/BPy_UnaryFunction1DVoid.h"
8 #include "Iterator/BPy_ViewEdgeIterator.h"
9 #include "Iterator/BPy_ChainingIterator.h"
10 #include "BPy_StrokeShader.h"
11
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15
16 ///////////////////////////////////////////////////////////////////////////////////////////
17
18 /*---------------  Python API function prototypes for Operators instance  -----------*/
19 static void Operators___dealloc__(BPy_Operators *self);
20
21 static PyObject * Operators_select(BPy_Operators* self, PyObject *args);
22 static PyObject * Operators_chain(BPy_Operators* self, PyObject *args);
23 static PyObject * Operators_bidirectionalChain(BPy_Operators* self, PyObject *args);
24 static PyObject * Operators_sequentialSplit(BPy_Operators* self, PyObject *args);
25 static PyObject * Operators_recursiveSplit(BPy_Operators* self, PyObject *args);
26 static PyObject * Operators_sort(BPy_Operators* self, PyObject *args);
27 static PyObject * Operators_create(BPy_Operators* self, PyObject *args);
28 static PyObject * Operators_getViewEdgesSize( BPy_Operators* self);
29 static PyObject * Operators_getChainsSize( BPy_Operators* self);
30 static PyObject * Operators_getStrokesSize( BPy_Operators* self);
31
32 /*----------------------Operators instance definitions ----------------------------*/
33 static PyMethodDef BPy_Operators_methods[] = {
34         {"select", ( PyCFunction ) Operators_select, METH_VARARGS | METH_STATIC, 
35         "select operator"},
36         {"chain", ( PyCFunction ) Operators_chain, METH_VARARGS | METH_STATIC,
37          "chain operator"},
38         {"bidirectionalChain", ( PyCFunction ) Operators_bidirectionalChain, METH_VARARGS | METH_STATIC,
39          "bidirectionalChain operator"},
40         {"sequentialSplit", ( PyCFunction ) Operators_sequentialSplit, METH_VARARGS | METH_STATIC,
41          "sequentialSplit operator"},
42         {"recursiveSplit", ( PyCFunction ) Operators_recursiveSplit, METH_VARARGS | METH_STATIC, 
43         "recursiveSplit operator"},
44         {"sort", ( PyCFunction ) Operators_sort, METH_VARARGS | METH_STATIC, 
45         "sort operator"},
46         {"create", ( PyCFunction ) Operators_create, METH_VARARGS | METH_STATIC, 
47         "create operator"},
48         {"getViewEdgesSize", ( PyCFunction ) Operators_getViewEdgesSize, METH_NOARGS | METH_STATIC, ""},
49         {"getChainsSize", ( PyCFunction ) Operators_getChainsSize, METH_NOARGS | METH_STATIC, ""},
50         {"getStrokesSize", ( PyCFunction ) Operators_getStrokesSize, METH_NOARGS | METH_STATIC, ""},
51         {NULL, NULL, 0, NULL}
52 };
53
54 /*-----------------------BPy_Operators type definition ------------------------------*/
55
56 PyTypeObject Operators_Type = {
57         PyVarObject_HEAD_INIT(NULL, 0)
58         "Operators",                    /* tp_name */
59         sizeof(BPy_Operators),          /* tp_basicsize */
60         0,                              /* tp_itemsize */
61         (destructor)Operators___dealloc__, /* tp_dealloc */
62         0,                              /* tp_print */
63         0,                              /* tp_getattr */
64         0,                              /* tp_setattr */
65         0,                              /* tp_reserved */
66         0,                              /* tp_repr */
67         0,                              /* tp_as_number */
68         0,                              /* tp_as_sequence */
69         0,                              /* tp_as_mapping */
70         0,                              /* tp_hash  */
71         0,                              /* tp_call */
72         0,                              /* tp_str */
73         0,                              /* tp_getattro */
74         0,                              /* tp_setattro */
75         0,                              /* tp_as_buffer */
76         Py_TPFLAGS_DEFAULT,             /* tp_flags */
77         "Operators objects",            /* tp_doc */
78         0,                              /* tp_traverse */
79         0,                              /* tp_clear */
80         0,                              /* tp_richcompare */
81         0,                              /* tp_weaklistoffset */
82         0,                              /* tp_iter */
83         0,                              /* tp_iternext */
84         BPy_Operators_methods,          /* tp_methods */
85         0,                              /* tp_members */
86         0,                              /* tp_getset */
87         0,                              /* tp_base */
88         0,                              /* tp_dict */
89         0,                              /* tp_descr_get */
90         0,                              /* tp_descr_set */
91         0,                              /* tp_dictoffset */
92         0,                              /* tp_init */
93         0,                              /* tp_alloc */
94         PyType_GenericNew,              /* tp_new */
95 };
96
97 //-------------------MODULE INITIALIZATION--------------------------------
98 int Operators_Init( PyObject *module )
99 {       
100         if( module == NULL )
101                 return -1;
102
103         if( PyType_Ready( &Operators_Type ) < 0 )
104                 return -1;
105
106         Py_INCREF( &Operators_Type );
107         PyModule_AddObject(module, "Operators", (PyObject *)&Operators_Type);   
108         return 0;
109 }
110
111 //------------------------INSTANCE METHODS ----------------------------------
112
113 void Operators___dealloc__(BPy_Operators* self)
114 {
115     Py_TYPE(self)->tp_free((PyObject*)self);
116 }
117
118 PyObject * Operators_select(BPy_Operators* self, PyObject *args)
119 {
120         PyObject *obj = 0;
121
122         if ( !PyArg_ParseTuple(args, "O!", &UnaryPredicate1D_Type, &obj) )
123                 return NULL;
124         if ( !((BPy_UnaryPredicate1D *) obj)->up1D ) {
125                 PyErr_SetString(PyExc_TypeError, "Operators.select(): 1st argument: invalid UnaryPredicate1D object");
126                 return NULL;
127         }
128
129         if (Operators::select(*( ((BPy_UnaryPredicate1D *) obj)->up1D )) < 0) {
130                 if (!PyErr_Occurred())
131                         PyErr_SetString(PyExc_RuntimeError, "Operators.select() failed");
132                 return NULL;
133         }
134
135         Py_RETURN_NONE;
136 }
137
138 // CHANGE: first parameter is a chaining iterator, not just a view
139
140 PyObject * Operators_chain(BPy_Operators* self, PyObject *args)
141 {
142         PyObject *obj1 = 0, *obj2 = 0, *obj3 = 0;
143
144         if ( !PyArg_ParseTuple(args, "O!O!|O!", &ChainingIterator_Type, &obj1,
145                                                                                     &UnaryPredicate1D_Type, &obj2,
146                                                                                     &UnaryFunction1DVoid_Type, &obj3) )
147                 return NULL;
148         if ( !((BPy_ChainingIterator *) obj1)->c_it ) {
149                 PyErr_SetString(PyExc_TypeError, "Operators.chain(): 1st argument: invalid ChainingIterator object");
150                 return NULL;
151         }
152         if ( !((BPy_UnaryPredicate1D *) obj2)->up1D ) {
153                 PyErr_SetString(PyExc_TypeError, "Operators.chain(): 2nd argument: invalid UnaryPredicate1D object");
154                 return NULL;
155         }
156
157         if( !obj3 ) {
158                 
159                 if (Operators::chain(   *( ((BPy_ChainingIterator *) obj1)->c_it ),
160                                                                 *( ((BPy_UnaryPredicate1D *) obj2)->up1D )  ) < 0) {
161                         if (!PyErr_Occurred())
162                                 PyErr_SetString(PyExc_RuntimeError, "Operators.chain() failed");
163                         return NULL;
164                 }
165                                                         
166         } else {
167                 
168                 if ( !((BPy_UnaryFunction1DVoid *) obj3)->uf1D_void ) {
169                         PyErr_SetString(PyExc_TypeError, "Operators.chain(): 3rd argument: invalid UnaryFunction1DVoid object");
170                         return NULL;
171                 }
172                 if (Operators::chain(   *( ((BPy_ChainingIterator *) obj1)->c_it ),
173                                                                 *( ((BPy_UnaryPredicate1D *) obj2)->up1D ),
174                                                                 *( ((BPy_UnaryFunction1DVoid *) obj3)->uf1D_void )  ) < 0) {
175                         if (!PyErr_Occurred())
176                                 PyErr_SetString(PyExc_RuntimeError, "Operators.chain() failed");
177                         return NULL;
178                 }
179                 
180         }
181         
182         Py_RETURN_NONE;
183 }
184
185 PyObject * Operators_bidirectionalChain(BPy_Operators* self, PyObject *args)
186 {
187         PyObject *obj1 = 0, *obj2 = 0;
188
189         if( !PyArg_ParseTuple(args, "O!|O!", &ChainingIterator_Type, &obj1, &UnaryPredicate1D_Type, &obj2) )
190                 return NULL;
191         if ( !((BPy_ChainingIterator *) obj1)->c_it ) {
192                 PyErr_SetString(PyExc_TypeError, "Operators.bidirectionalChain(): 1st argument: invalid ChainingIterator object");
193                 return NULL;
194         }
195
196         if( !obj2 ) {
197
198                 if (Operators::bidirectionalChain(      *( ((BPy_ChainingIterator *) obj1)->c_it ) ) < 0) {
199                         if (!PyErr_Occurred())
200                                 PyErr_SetString(PyExc_RuntimeError, "Operators.bidirectionalChain() failed");
201                         return NULL;
202                 }
203                                                         
204         } else {
205
206                 if ( !((BPy_UnaryPredicate1D *) obj2)->up1D ) {
207                         PyErr_SetString(PyExc_TypeError, "Operators.bidirectionalChain(): 2nd argument: invalid UnaryPredicate1D object");
208                         return NULL;
209                 }
210                 if (Operators::bidirectionalChain(      *( ((BPy_ChainingIterator *) obj1)->c_it ),
211                                                                                         *( ((BPy_UnaryPredicate1D *) obj2)->up1D ) ) < 0) {
212                         if (!PyErr_Occurred())
213                                 PyErr_SetString(PyExc_RuntimeError, "Operators.bidirectionalChain() failed");
214                         return NULL;
215                 }
216                 
217         }
218         
219         Py_RETURN_NONE;
220 }
221
222 PyObject * Operators_sequentialSplit(BPy_Operators* self, PyObject *args)
223 {
224         PyObject *obj1 = 0, *obj2 = 0;
225         float f = 0.0;
226
227         if( !PyArg_ParseTuple(args, "O!|Of", &UnaryPredicate0D_Type, &obj1, &obj2, &f) )
228                 return NULL;
229         if ( !((BPy_UnaryPredicate0D *) obj1)->up0D ) {
230                 PyErr_SetString(PyExc_TypeError, "Operators.sequentialSplit(): 1st argument: invalid UnaryPredicate0D object");
231                 return NULL;
232         }
233
234         if( obj2 && BPy_UnaryPredicate0D_Check(obj2) ) {
235                 
236                 if ( !((BPy_UnaryPredicate0D *) obj2)->up0D ) {
237                         PyErr_SetString(PyExc_TypeError, "Operators.sequentialSplit(): 2nd argument: invalid UnaryPredicate0D object");
238                         return NULL;
239                 }
240                 if (Operators::sequentialSplit( *( ((BPy_UnaryPredicate0D *) obj1)->up0D ),
241                                                                                 *( ((BPy_UnaryPredicate0D *) obj2)->up0D ),
242                                                                                 f ) < 0) {
243                         if (!PyErr_Occurred())
244                                 PyErr_SetString(PyExc_RuntimeError, "Operators.sequentialSplit() failed");
245                         return NULL;
246                 }
247
248         } else {
249                 
250                 if ( obj2 ) {
251                         if ( !PyFloat_Check(obj2) ) {
252                                 PyErr_SetString(PyExc_TypeError, "Operators.sequentialSplit(): invalid 2nd argument");
253                                 return NULL;
254                         }
255                         f = PyFloat_AsDouble(obj2);
256                 }
257                 if (Operators::sequentialSplit( *( ((BPy_UnaryPredicate0D *) obj1)->up0D ), f ) < 0) {
258                         if (!PyErr_Occurred())
259                                 PyErr_SetString(PyExc_RuntimeError, "Operators.sequentialSplit() failed");
260                         return NULL;
261                 }
262                 
263         }
264         
265         Py_RETURN_NONE;
266 }
267
268 PyObject * Operators_recursiveSplit(BPy_Operators* self, PyObject *args)
269 {
270         PyObject *obj1 = 0, *obj2 = 0, *obj3 = 0;
271         float f = 0.0;
272
273         if ( !PyArg_ParseTuple(args, "O!O|Of", &UnaryFunction0DDouble_Type, &obj1, &obj2, &obj3, &f) )
274                 return NULL;
275         if ( !((BPy_UnaryFunction0DDouble *) obj1)->uf0D_double ) {
276                 PyErr_SetString(PyExc_TypeError, "Operators.recursiveSplit(): 1st argument: invalid UnaryFunction0DDouble object");
277                 return NULL;
278         }
279         
280         if ( BPy_UnaryPredicate1D_Check(obj2) ) {
281
282                 if ( !((BPy_UnaryPredicate1D *) obj2)->up1D ) {
283                         PyErr_SetString(PyExc_TypeError, "Operators.recursiveSplit(): 2nd argument: invalid UnaryPredicate1D object");
284                         return NULL;
285                 }
286                 if ( obj3 ) {
287                         if ( !PyFloat_Check(obj3) ) {
288                                 PyErr_SetString(PyExc_TypeError, "Operators.recursiveSplit(): invalid 3rd argument");
289                                 return NULL;
290                         }
291                         f = PyFloat_AsDouble(obj3);
292                 }
293                 if (Operators::recursiveSplit(  *( ((BPy_UnaryFunction0DDouble *) obj1)->uf0D_double ),
294                                                                                 *( ((BPy_UnaryPredicate1D *) obj2)->up1D ),
295                                                                                 f ) < 0) {
296                         if (!PyErr_Occurred())
297                                 PyErr_SetString(PyExc_RuntimeError, "Operators.recursiveSplit() failed");
298                         return NULL;
299                 }
300         
301         } else {
302
303                 if ( !BPy_UnaryPredicate0D_Check(obj2) || !((BPy_UnaryPredicate0D *) obj2)->up0D ) {
304                         PyErr_SetString(PyExc_TypeError, "Operators.recursiveSplit(): invalid 2nd argument");
305                         return NULL;
306                 }
307                 if ( !BPy_UnaryPredicate1D_Check(obj3) || !((BPy_UnaryPredicate1D *) obj3)->up1D ) {
308                         PyErr_SetString(PyExc_TypeError, "Operators.recursiveSplit(): invalid 3rd argument");
309                         return NULL;
310                 }
311                 if (Operators::recursiveSplit(  *( ((BPy_UnaryFunction0DDouble *) obj1)->uf0D_double ),
312                                                                                 *( ((BPy_UnaryPredicate0D *) obj2)->up0D ),
313                                                                                 *( ((BPy_UnaryPredicate1D *) obj3)->up1D ),
314                                                                                 f ) < 0) {
315                         if (!PyErr_Occurred())
316                                 PyErr_SetString(PyExc_RuntimeError, "Operators.recursiveSplit() failed");
317                         return NULL;
318                 }
319
320         }
321         
322         Py_RETURN_NONE;
323 }
324
325 PyObject * Operators_sort(BPy_Operators* self, PyObject *args)
326 {
327         PyObject *obj = 0;
328
329         if ( !PyArg_ParseTuple(args, "O!", &BinaryPredicate1D_Type, &obj) )
330                 return NULL;
331         if ( !((BPy_BinaryPredicate1D *) obj)->bp1D ) {
332                 PyErr_SetString(PyExc_TypeError, "Operators.sort(): 1st argument: invalid BinaryPredicate1D object");
333                 return NULL;
334         }
335
336         if (Operators::sort(*( ((BPy_BinaryPredicate1D *) obj)->bp1D )) < 0) {
337                 if (!PyErr_Occurred())
338                         PyErr_SetString(PyExc_RuntimeError, "Operators.sort() failed");
339                 return NULL;
340         }
341         Py_RETURN_NONE;
342 }
343
344 PyObject * Operators_create(BPy_Operators* self, PyObject *args)
345 {
346         PyObject *obj1 = 0, *obj2 = 0;
347
348         if ( !PyArg_ParseTuple(args, "O!O!", &UnaryPredicate1D_Type, &obj1, &PyList_Type, &obj2) )
349                 return NULL;
350         if ( !((BPy_UnaryPredicate1D *) obj1)->up1D ) {
351                 PyErr_SetString(PyExc_TypeError, "Operators.create(): 1st argument: invalid UnaryPredicate1D object");
352                 return NULL;
353         }
354
355         vector<StrokeShader *> shaders;
356         for( int i = 0; i < PyList_Size(obj2); i++) {
357                 PyObject *py_ss = PyList_GetItem(obj2,i);
358                 
359                 if ( !BPy_StrokeShader_Check(py_ss) ) {
360                         PyErr_SetString(PyExc_TypeError, "Operators.create() 2nd argument must be a list of StrokeShader objects");
361                         return NULL;
362                 }
363                 shaders.push_back( ((BPy_StrokeShader *) py_ss)->ss );
364         }
365         
366         if (Operators::create( *( ((BPy_UnaryPredicate1D *) obj1)->up1D ), shaders) < 0) {
367                 if (!PyErr_Occurred())
368                         PyErr_SetString(PyExc_RuntimeError, "Operators.create() failed");
369                 return NULL;
370         }
371
372         Py_RETURN_NONE;
373 }
374
375 PyObject * Operators_getViewEdgesSize( BPy_Operators* self) {
376         return PyLong_FromLong( Operators::getViewEdgesSize() );
377 }
378
379 PyObject * Operators_getChainsSize( BPy_Operators* self ) {
380         return PyLong_FromLong( Operators::getChainsSize() );
381 }
382
383 PyObject * Operators_getStrokesSize( BPy_Operators* self) {
384         return PyLong_FromLong( Operators::getStrokesSize() );
385 }
386
387
388 ///////////////////////////////////////////////////////////////////////////////////////////
389
390 #ifdef __cplusplus
391 }
392 #endif
393
394