b654525ea1655ea1b1284b5e1799af0464988454
[blender.git] / source / blender / freestyle / intern / python / BPy_Nature.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  * The Original Code is Copyright (C) 2010 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file source/blender/freestyle/intern/python/BPy_Nature.cpp
29  *  \ingroup freestyle
30  */
31
32 #include "BPy_Nature.h"
33
34 #include "BPy_Convert.h"
35
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39
40 ///////////////////////////////////////////////////////////////////////////////////////////
41
42 static PyObject *BPy_Nature_and(PyObject *a, PyObject *b);
43 static PyObject *BPy_Nature_xor(PyObject *a, PyObject *b);
44 static PyObject *BPy_Nature_or(PyObject *a, PyObject *b);
45 static int BPy_Nature_bool(PyObject *v);
46
47 /*-----------------------BPy_Nature number method definitions --------------------*/
48
49 PyNumberMethods nature_as_number = {
50         0,                              /* binaryfunc nb_add */
51         0,                              /* binaryfunc nb_subtract */
52         0,                              /* binaryfunc nb_multiply */
53         0,                              /* binaryfunc nb_remainder */
54         0,                              /* binaryfunc nb_divmod */
55         0,                              /* ternaryfunc nb_power */
56         0,                              /* unaryfunc nb_negative */
57         0,                              /* unaryfunc nb_positive */
58         0,                              /* unaryfunc nb_absolute */
59         (inquiry)BPy_Nature_bool,       /* inquiry nb_bool */
60         0,                              /* unaryfunc nb_invert */
61         0,                              /* binaryfunc nb_lshift */
62         0,                              /* binaryfunc nb_rshift */
63         (binaryfunc)BPy_Nature_and,     /* binaryfunc nb_and */
64         (binaryfunc)BPy_Nature_xor,     /* binaryfunc nb_xor */
65         (binaryfunc)BPy_Nature_or,      /* binaryfunc nb_or */
66         0,                              /* unaryfunc nb_int */
67         0,                              /* void *nb_reserved */
68         0,                              /* unaryfunc nb_float */
69         0,                              /* binaryfunc nb_inplace_add */
70         0,                              /* binaryfunc nb_inplace_subtract */
71         0,                              /* binaryfunc nb_inplace_multiply */
72         0,                              /* binaryfunc nb_inplace_remainder */
73         0,                              /* ternaryfunc nb_inplace_power */
74         0,                              /* binaryfunc nb_inplace_lshift */
75         0,                              /* binaryfunc nb_inplace_rshift */
76         0,                              /* binaryfunc nb_inplace_and */
77         0,                              /* binaryfunc nb_inplace_xor */
78         0,                              /* binaryfunc nb_inplace_or */
79         0,                              /* binaryfunc nb_floor_divide */
80         0,                              /* binaryfunc nb_true_divide */
81         0,                              /* binaryfunc nb_inplace_floor_divide */
82         0,                              /* binaryfunc nb_inplace_true_divide */
83         0,                              /* unaryfunc nb_index */
84 };
85
86 /*-----------------------BPy_Nature docstring ------------------------------------*/
87
88 PyDoc_STRVAR(Nature_doc,
89 "Class hierarchy: int > :class:`Nature`\n"
90 "\n"
91 "Different possible natures of 0D and 1D elements of the ViewMap.\n"
92 "\n"
93 "Vertex natures:\n"
94 "\n"
95 "* Nature.POINT: True for any 0D element.\n"
96 "* Nature.S_VERTEX: True for SVertex.\n"
97 "* Nature.VIEW_VERTEX: True for ViewVertex.\n"
98 "* Nature.NON_T_VERTEX: True for NonTVertex.\n"
99 "* Nature.T_VERTEX: True for TVertex.\n"
100 "* Nature.CUSP: True for CUSP.\n"
101 "\n"
102 "Edge natures:\n"
103 "\n"
104 "* Nature.NO_FEATURE: True for non feature edges (always false for 1D\n"
105 "  elements of the ViewMap).\n"
106 "* Nature.SILHOUETTE: True for silhouettes.\n"
107 "* Nature.BORDER: True for borders.\n"
108 "* Nature.CREASE: True for creases.\n"
109 "* Nature.RIDGE: True for ridges.\n"
110 "* Nature.VALLEY: True for valleys.\n"
111 "* Nature.SUGGESTIVE_CONTOUR: True for suggestive contours.\n"
112 "* Nature.MATERIAL_BOUNDARY: True for edges at material boundaries.\n"
113 "* Nature.EDGE_MARK: True for edges having user-defined edge marks.");
114
115 /*-----------------------BPy_Nature type definition ------------------------------*/
116
117 PyTypeObject Nature_Type = {
118         PyVarObject_HEAD_INIT(NULL, 0)
119         "Nature",                       /* tp_name */
120         sizeof(PyLongObject),           /* tp_basicsize */
121         0,                              /* tp_itemsize */
122         0,                              /* tp_dealloc */
123         0,                              /* tp_print */
124         0,                              /* tp_getattr */
125         0,                              /* tp_setattr */
126         0,                              /* tp_reserved */
127         0,                              /* tp_repr */
128         &nature_as_number,              /* tp_as_number */
129         0,                              /* tp_as_sequence */
130         0,                              /* tp_as_mapping */
131         0,                              /* tp_hash  */
132         0,                              /* tp_call */
133         0,                              /* tp_str */
134         0,                              /* tp_getattro */
135         0,                              /* tp_setattro */
136         0,                              /* tp_as_buffer */
137         Py_TPFLAGS_DEFAULT,             /* tp_flags */
138         Nature_doc,                     /* tp_doc */
139         0,                              /* tp_traverse */
140         0,                              /* tp_clear */
141         0,                              /* tp_richcompare */
142         0,                              /* tp_weaklistoffset */
143         0,                              /* tp_iter */
144         0,                              /* tp_iternext */
145         0,                              /* tp_methods */
146         0,                              /* tp_members */
147         0,                              /* tp_getset */
148         &PyLong_Type,                   /* tp_base */
149         0,                              /* tp_dict */
150         0,                              /* tp_descr_get */
151         0,                              /* tp_descr_set */
152         0,                              /* tp_dictoffset */
153         0,                              /* tp_init */
154         0,                              /* tp_alloc */
155         0,                              /* tp_new */
156 };
157
158 /*-----------------------BPy_Nature instance definitions ----------------------------------*/
159
160 static PyLongObject _Nature_POINT = {
161         PyVarObject_HEAD_INIT(&Nature_Type, 1)
162         { Nature::POINT }
163 };
164 static PyLongObject _Nature_S_VERTEX = {
165         PyVarObject_HEAD_INIT(&Nature_Type, 1)
166         { Nature::S_VERTEX }
167 };
168 static PyLongObject _Nature_VIEW_VERTEX = {
169         PyVarObject_HEAD_INIT(&Nature_Type, 1)
170         { Nature::VIEW_VERTEX }
171 };
172 static PyLongObject _Nature_NON_T_VERTEX = {
173         PyVarObject_HEAD_INIT(&Nature_Type, 1)
174         { Nature::NON_T_VERTEX }
175 };
176 static PyLongObject _Nature_T_VERTEX = {
177         PyVarObject_HEAD_INIT(&Nature_Type, 1)
178         { Nature::T_VERTEX }
179 };
180 static PyLongObject _Nature_CUSP = {
181         PyVarObject_HEAD_INIT(&Nature_Type, 1)
182         { Nature::CUSP }
183 };
184 static PyLongObject _Nature_NO_FEATURE = {
185         PyVarObject_HEAD_INIT(&Nature_Type, 1)
186         { Nature::NO_FEATURE }
187 };
188 static PyLongObject _Nature_SILHOUETTE = {
189         PyVarObject_HEAD_INIT(&Nature_Type, 1)
190         { Nature::SILHOUETTE }
191 };
192 static PyLongObject _Nature_BORDER = {
193         PyVarObject_HEAD_INIT(&Nature_Type, 1)
194         { Nature::BORDER }
195 };
196 static PyLongObject _Nature_CREASE = {
197         PyVarObject_HEAD_INIT(&Nature_Type, 1)
198         { Nature::CREASE }
199 };
200 static PyLongObject _Nature_RIDGE = {
201         PyVarObject_HEAD_INIT(&Nature_Type, 1)
202         { Nature::RIDGE }
203 };
204 static PyLongObject _Nature_VALLEY = {
205         PyVarObject_HEAD_INIT(&Nature_Type, 1)
206         { Nature::VALLEY }
207 };
208 static PyLongObject _Nature_SUGGESTIVE_CONTOUR = {
209         PyVarObject_HEAD_INIT(&Nature_Type, 1)
210         { Nature::SUGGESTIVE_CONTOUR }
211 };
212 static PyLongObject _Nature_MATERIAL_BOUNDARY = {
213         PyVarObject_HEAD_INIT(&Nature_Type, 1)
214         { Nature::MATERIAL_BOUNDARY }
215 };
216 static PyLongObject _Nature_EDGE_MARK = {
217         PyVarObject_HEAD_INIT(&Nature_Type, 1)
218         { Nature::EDGE_MARK }
219 };
220
221 #define BPy_Nature_POINT               ((PyObject *)&_Nature_POINT)
222 #define BPy_Nature_S_VERTEX            ((PyObject *)&_Nature_S_VERTEX)
223 #define BPy_Nature_VIEW_VERTEX         ((PyObject *)&_Nature_VIEW_VERTEX)
224 #define BPy_Nature_NON_T_VERTEX        ((PyObject *)&_Nature_NON_T_VERTEX)
225 #define BPy_Nature_T_VERTEX            ((PyObject *)&_Nature_T_VERTEX)
226 #define BPy_Nature_CUSP                ((PyObject *)&_Nature_CUSP)
227 #define BPy_Nature_NO_FEATURE          ((PyObject *)&_Nature_NO_FEATURE)
228 #define BPy_Nature_SILHOUETTE          ((PyObject *)&_Nature_SILHOUETTE)
229 #define BPy_Nature_BORDER              ((PyObject *)&_Nature_BORDER)
230 #define BPy_Nature_CREASE              ((PyObject *)&_Nature_CREASE)
231 #define BPy_Nature_RIDGE               ((PyObject *)&_Nature_RIDGE)
232 #define BPy_Nature_VALLEY              ((PyObject *)&_Nature_VALLEY)
233 #define BPy_Nature_SUGGESTIVE_CONTOUR  ((PyObject *)&_Nature_SUGGESTIVE_CONTOUR)
234 #define BPy_Nature_MATERIAL_BOUNDARY   ((PyObject *)&_Nature_MATERIAL_BOUNDARY)
235 #define BPy_Nature_EDGE_MARK           ((PyObject *)&_Nature_EDGE_MARK)
236
237 //-------------------MODULE INITIALIZATION--------------------------------
238 int Nature_Init(PyObject *module)
239 {
240         if (module == NULL)
241                 return -1;
242
243         if (PyType_Ready(&Nature_Type) < 0)
244                 return -1;
245         Py_INCREF(&Nature_Type);
246         PyModule_AddObject(module, "Nature", (PyObject *)&Nature_Type);
247
248         // VertexNature
249         PyDict_SetItemString(Nature_Type.tp_dict, "POINT", BPy_Nature_POINT);
250         PyDict_SetItemString(Nature_Type.tp_dict, "S_VERTEX", BPy_Nature_S_VERTEX);
251         PyDict_SetItemString(Nature_Type.tp_dict, "VIEW_VERTEX", BPy_Nature_VIEW_VERTEX);
252         PyDict_SetItemString(Nature_Type.tp_dict, "NON_T_VERTEX", BPy_Nature_NON_T_VERTEX);
253         PyDict_SetItemString(Nature_Type.tp_dict, "T_VERTEX", BPy_Nature_T_VERTEX);
254         PyDict_SetItemString(Nature_Type.tp_dict, "CUSP", BPy_Nature_CUSP);
255
256         // EdgeNature
257         PyDict_SetItemString(Nature_Type.tp_dict, "NO_FEATURE", BPy_Nature_NO_FEATURE);
258         PyDict_SetItemString(Nature_Type.tp_dict, "SILHOUETTE", BPy_Nature_SILHOUETTE);
259         PyDict_SetItemString(Nature_Type.tp_dict, "BORDER", BPy_Nature_BORDER);
260         PyDict_SetItemString(Nature_Type.tp_dict, "CREASE", BPy_Nature_CREASE);
261         PyDict_SetItemString(Nature_Type.tp_dict, "RIDGE", BPy_Nature_RIDGE);
262         PyDict_SetItemString(Nature_Type.tp_dict, "VALLEY", BPy_Nature_VALLEY);
263         PyDict_SetItemString(Nature_Type.tp_dict, "SUGGESTIVE_CONTOUR", BPy_Nature_SUGGESTIVE_CONTOUR);
264         PyDict_SetItemString(Nature_Type.tp_dict, "MATERIAL_BOUNDARY", BPy_Nature_MATERIAL_BOUNDARY);
265         PyDict_SetItemString(Nature_Type.tp_dict, "EDGE_MARK", BPy_Nature_EDGE_MARK);
266
267         return 0;
268 }
269
270 static PyObject *BPy_Nature_bitwise(PyObject *a, int op, PyObject *b)
271 {
272         BPy_Nature *result;
273
274         if (!BPy_Nature_Check(a) || !BPy_Nature_Check(b)) {
275                 PyErr_SetString(PyExc_TypeError, "operands must be a Nature object");
276                 return NULL;
277         }
278         if (Py_SIZE(a) != 1) {
279                 stringstream msg;
280                 msg << "operand 1: unexpected Nature byte length: " << Py_SIZE(a);
281                 PyErr_SetString(PyExc_TypeError, msg.str().c_str());
282                 return NULL;
283         }
284         if (Py_SIZE(b) != 1) {
285                 stringstream msg;
286                 msg << "operand 2: unexpected Nature byte length: " << Py_SIZE(b);
287                 PyErr_SetString(PyExc_TypeError, msg.str().c_str());
288                 return NULL;
289         }
290         result = PyObject_NewVar(BPy_Nature, &Nature_Type, 1);
291         if (!result)
292                 return NULL;
293         if (Py_SIZE(result) != 1) {
294                 stringstream msg;
295                 msg << "unexpected Nature byte length: " << Py_SIZE(result);
296                 PyErr_SetString(PyExc_TypeError, msg.str().c_str());
297                 return NULL;
298         }
299         switch (op) {
300         case '&':
301                 result->i.ob_digit[0] = (((PyLongObject *)a)->ob_digit[0]) & (((PyLongObject *)b)->ob_digit)[0];
302                 break;
303         case '^':
304                 result->i.ob_digit[0] = (((PyLongObject *)a)->ob_digit[0]) ^ (((PyLongObject *)b)->ob_digit)[0];
305                 break;
306         case '|':
307                 result->i.ob_digit[0] = (((PyLongObject *)a)->ob_digit[0]) | (((PyLongObject *)b)->ob_digit)[0];
308                 break;
309         }
310         return (PyObject *)result;
311 }
312
313 static PyObject *BPy_Nature_and(PyObject *a, PyObject *b)
314 {
315         return BPy_Nature_bitwise(a, '&', b);
316 }
317
318 static PyObject *BPy_Nature_xor(PyObject *a, PyObject *b)
319 {
320         return BPy_Nature_bitwise(a, '^', b);
321 }
322
323 static PyObject *BPy_Nature_or(PyObject *a, PyObject *b)
324 {
325         return BPy_Nature_bitwise(a, '|', b);
326 }
327
328 static int BPy_Nature_bool(PyObject *v)
329 {
330         return ((PyLongObject *)v)->ob_digit[0] != 0;
331 }
332
333 ///////////////////////////////////////////////////////////////////////////////////////////
334
335 #ifdef __cplusplus
336 }
337 #endif