Freestyle: Code cleanup, prepare for strict C++ flags
[blender.git] / source / blender / freestyle / intern / python / BPy_Freestyle.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/BPy_Freestyle.cpp
22  *  \ingroup freestyle
23  */
24
25 #include "BPy_Freestyle.h"
26
27 #include "BPy_BBox.h"
28 #include "BPy_BinaryPredicate0D.h"
29 #include "BPy_BinaryPredicate1D.h"
30 #include "BPy_ContextFunctions.h"
31 #include "BPy_Convert.h"
32 #include "BPy_FrsMaterial.h"
33 #include "BPy_FrsNoise.h"
34 #include "BPy_Id.h"
35 #include "BPy_IntegrationType.h"
36 #include "BPy_Interface0D.h"
37 #include "BPy_Interface1D.h"
38 #include "BPy_Iterator.h"
39 #include "BPy_MediumType.h"
40 #include "BPy_Nature.h"
41 #include "BPy_Operators.h"
42 #include "BPy_SShape.h"
43 #include "BPy_StrokeAttribute.h"
44 #include "BPy_StrokeShader.h"
45 #include "BPy_UnaryFunction0D.h"
46 #include "BPy_UnaryFunction1D.h"
47 #include "BPy_UnaryPredicate0D.h"
48 #include "BPy_UnaryPredicate1D.h"
49 #include "BPy_ViewMap.h"
50 #include "BPy_ViewShape.h"
51
52
53 #ifdef __cplusplus
54 extern "C" {
55 #endif
56
57 ///////////////////////////////////////////////////////////////////////////////////////////
58
59 //------------------------ MODULE FUNCTIONS ----------------------------------
60
61 #include "FRS_freestyle.h"
62 #include "RNA_access.h"
63 #include "BKE_appdir.h"
64 #include "DNA_scene_types.h"
65 #include "bpy_rna.h" /* pyrna_struct_CreatePyObject() */
66
67 static char Freestyle_getCurrentScene___doc__[] =
68 ".. function:: getCurrentScene()\n"
69 "\n"
70 "   Returns the current scene.\n"
71 "\n"
72 "   :return: The current scene.\n"
73 "   :rtype: :class:`bpy.types.Scene`\n";
74
75 static PyObject *Freestyle_getCurrentScene(PyObject * /*self*/)
76 {
77         if (!freestyle_scene) {
78                 PyErr_SetString(PyExc_TypeError, "current scene not available");
79                 return NULL;
80         }
81         PointerRNA ptr_scene;
82         RNA_pointer_create(&freestyle_scene->id, &RNA_Scene, freestyle_scene, &ptr_scene);
83         return pyrna_struct_CreatePyObject(&ptr_scene);
84 }
85
86 #include "DNA_material_types.h"
87
88 static int ramp_blend_type(const char *type)
89 {
90         if (STREQ(type, "MIX"))           return MA_RAMP_BLEND;
91         if (STREQ(type, "ADD"))           return MA_RAMP_ADD;
92         if (STREQ(type, "MULTIPLY"))      return MA_RAMP_MULT;
93         if (STREQ(type, "SUBTRACT"))      return MA_RAMP_SUB;
94         if (STREQ(type, "SCREEN"))        return MA_RAMP_SCREEN;
95         if (STREQ(type, "DIVIDE"))        return MA_RAMP_DIV;
96         if (STREQ(type, "DIFFERENCE"))    return MA_RAMP_DIFF;
97         if (STREQ(type, "DARKEN"))        return MA_RAMP_DARK;
98         if (STREQ(type, "LIGHTEN"))       return MA_RAMP_LIGHT;
99         if (STREQ(type, "OVERLAY"))       return MA_RAMP_OVERLAY;
100         if (STREQ(type, "DODGE"))         return MA_RAMP_DODGE;
101         if (STREQ(type, "BURN"))          return MA_RAMP_BURN;
102         if (STREQ(type, "HUE"))           return MA_RAMP_HUE;
103         if (STREQ(type, "SATURATION"))    return MA_RAMP_SAT;
104         if (STREQ(type, "VALUE"))         return MA_RAMP_VAL;
105         if (STREQ(type, "COLOR"))         return MA_RAMP_COLOR;
106         if (STREQ(type, "SOFT_LIGHT"))    return MA_RAMP_SOFT;
107         if (STREQ(type, "LINEAR_LIGHT"))  return MA_RAMP_LINEAR;
108         return -1;
109 }
110
111 #include "BKE_material.h" /* ramp_blend() */
112
113 static char Freestyle_blendRamp___doc__[] =
114 ".. function:: blendRamp(type, color1, fac, color2)\n"
115 "\n"
116 "   Blend two colors according to a ramp blend type.\n"
117 "\n"
118 "   :arg type: Ramp blend type.\n"
119 "   :type type: int\n"
120 "   :arg color1: 1st color.\n"
121 "   :type color1: :class:`mathutils.Vector`, list or tuple of 3 real numbers\n"
122 "   :arg fac: Blend factor.\n"
123 "   :type fac: float\n"
124 "   :arg color2: 1st color.\n"
125 "   :type color2: :class:`mathutils.Vector`, list or tuple of 3 real numbers\n"
126 "   :return: Blended color in RGB format.\n"
127 "   :rtype: :class:`mathutils.Vector`\n";
128
129 static PyObject *Freestyle_blendRamp(PyObject * /*self*/, PyObject *args)
130 {
131         PyObject *obj1, *obj2;
132         char *s;
133         int type;
134         float a[3], fac, b[3];
135
136         if (!PyArg_ParseTuple(args, "sOfO", &s, &obj1, &fac, &obj2))
137                 return NULL;
138         type = ramp_blend_type(s);
139         if (type < 0) {
140                 PyErr_SetString(PyExc_TypeError, "argument 1 is an unknown ramp blend type");
141                 return NULL;
142         }
143         if (mathutils_array_parse(a, 3, 3, obj1,
144                                   "argument 2 must be a 3D vector "
145                                   "(either a tuple/list of 3 elements or Vector)") == -1)
146         {
147                 return NULL;
148         }
149         if (mathutils_array_parse(b, 3, 3, obj2,
150                                   "argument 4 must be a 3D vector "
151                                   "(either a tuple/list of 3 elements or Vector)") == -1)
152         {
153                 return NULL;
154         }
155         ramp_blend(type, a, fac, b);
156         return Vector_CreatePyObject(a, 3, NULL);
157 }
158
159 #include "BKE_texture.h" /* do_colorband() */
160
161 static char Freestyle_evaluateColorRamp___doc__[] =
162 ".. function:: evaluateColorRamp(ramp, in)\n"
163 "\n"
164 "   Evaluate a color ramp at a point in the interval 0 to 1.\n"
165 "\n"
166 "   :arg ramp: Color ramp object.\n"
167 "   :type ramp: :class:`bpy.types.ColorRamp`\n"
168 "   :arg in: Value in the interval 0 to 1.\n"
169 "   :type in: float\n"
170 "   :return: color in RGBA format.\n"
171 "   :rtype: :class:`mathutils.Vector`\n";
172
173 static PyObject *Freestyle_evaluateColorRamp(PyObject * /*self*/, PyObject *args)
174 {
175         BPy_StructRNA *py_srna;
176         ColorBand *coba;
177         float in, out[4];
178
179         if (!(PyArg_ParseTuple(args, "O!f", &pyrna_struct_Type, &py_srna, &in)))
180                 return NULL;
181         if (!RNA_struct_is_a(py_srna->ptr.type, &RNA_ColorRamp)) {
182                 PyErr_SetString(PyExc_TypeError, "1st argument is not a ColorRamp object");
183                 return NULL;
184         }
185         coba = (ColorBand *)py_srna->ptr.data;
186         if (!do_colorband(coba, in, out)) {
187                 PyErr_SetString(PyExc_ValueError, "failed to evaluate the color ramp");
188                 return NULL;
189         }
190         return Vector_CreatePyObject(out, 4, NULL);
191 }
192
193 #include "DNA_color_types.h"
194 #include "BKE_colortools.h" /* curvemapping_evaluateF() */
195
196 static char Freestyle_evaluateCurveMappingF___doc__[] =
197 ".. function:: evaluateCurveMappingF(cumap, cur, value)\n"
198 "\n"
199 "   Evaluate a curve mapping at a point in the interval 0 to 1.\n"
200 "\n"
201 "   :arg cumap: Curve mapping object.\n"
202 "   :type cumap: :class:`bpy.types.CurveMapping`\n"
203 "   :arg cur: Index of the curve to be used (0 <= cur <= 3).\n"
204 "   :type cur: int\n"
205 "   :arg value: Input value in the interval 0 to 1.\n"
206 "   :type value: float\n"
207 "   :return: Mapped output value.\n"
208 "   :rtype: float\n";
209
210 static PyObject *Freestyle_evaluateCurveMappingF(PyObject * /*self*/, PyObject *args)
211 {
212         BPy_StructRNA *py_srna;
213         CurveMapping *cumap;
214         int cur;
215         float value;
216
217         if (!(PyArg_ParseTuple(args, "O!if", &pyrna_struct_Type, &py_srna, &cur, &value)))
218                 return NULL;
219         if (!RNA_struct_is_a(py_srna->ptr.type, &RNA_CurveMapping)) {
220                 PyErr_SetString(PyExc_TypeError, "1st argument is not a CurveMapping object");
221                 return NULL;
222         }
223         if (cur < 0 || cur > 3) {
224                 PyErr_SetString(PyExc_ValueError, "2nd argument is out of range");
225                 return NULL;
226         }
227         cumap = (CurveMapping *)py_srna->ptr.data;
228         curvemapping_initialize(cumap);
229         /* disable extrapolation if enabled */
230         if ((cumap->cm[cur].flag & CUMA_EXTEND_EXTRAPOLATE)) {
231                 cumap->cm[cur].flag &= ~(CUMA_EXTEND_EXTRAPOLATE);
232                 curvemapping_changed(cumap, 0);
233         }
234         return PyFloat_FromDouble(curvemapping_evaluateF(cumap, cur, value));
235 }
236
237 /*-----------------------Freestyle module docstring----------------------------*/
238
239 static char module_docstring[] =
240 "This module provides classes for defining line drawing rules (such as\n"
241 "predicates, functions, chaining iterators, and stroke shaders), as well\n"
242 "as helper functions for style module writing.\n"
243 "\n"
244 "Class hierarchy:\n"
245 "\n"
246 "- :class:`BBox`\n"
247 "- :class:`BinaryPredicate0D`\n"
248 "- :class:`BinaryPredicate1D`\n"
249 "\n"
250 "  - :class:`FalseBP1D`\n"
251 "  - :class:`Length2DBP1D`\n"
252 "  - :class:`SameShapeIdBP1D`\n"
253 "  - :class:`TrueBP1D`\n"
254 "  - :class:`ViewMapGradientNormBP1D`\n"
255 "\n"
256 "- :class:`Id`\n"
257 "- :class:`Interface0D`\n"
258 "\n"
259 "  - :class:`CurvePoint`\n"
260 "\n"
261 "    - :class:`StrokeVertex`\n"
262 "\n"
263 "  - :class:`SVertex`\n"
264 "  - :class:`ViewVertex`\n"
265 "\n"
266 "    - :class:`NonTVertex`\n"
267 "    - :class:`TVertex`\n"
268 "\n"
269 "- :class:`Interface1D`\n"
270 "\n"
271 "  - :class:`Curve`\n"
272 "\n"
273 "    - :class:`Chain`\n"
274 "\n"
275 "  - :class:`FEdge`\n"
276 "\n"
277 "    - :class:`FEdgeSharp`\n"
278 "    - :class:`FEdgeSmooth`\n"
279 "\n"
280 "  - :class:`Stroke`\n"
281 "  - :class:`ViewEdge`\n"
282 "\n"
283 "- :class:`Iterator`\n"
284 "\n"
285 "  - :class:`AdjacencyIterator`\n"
286 "  - :class:`CurvePointIterator`\n"
287 "  - :class:`Interface0DIterator`\n"
288 "  - :class:`SVertexIterator`\n"
289 "  - :class:`StrokeVertexIterator`\n"
290 "  - :class:`ViewEdgeIterator`\n"
291 "\n"
292 "    - :class:`ChainingIterator`\n"
293 "\n"
294 "      - :class:`ChainPredicateIterator`\n"
295 "      - :class:`ChainSilhouetteIterator`\n"
296 "\n"
297 "  - :class:`orientedViewEdgeIterator`\n"
298 "\n"
299 "- :class:`Material`\n"
300 "- :class:`Noise`\n"
301 "- :class:`Operators`\n"
302 "- :class:`SShape`\n"
303 "- :class:`StrokeAttribute`\n"
304 "- :class:`StrokeShader`\n"
305 "\n"
306 "  - :class:`BackboneStretcherShader`\n"
307 "  - :class:`BezierCurveShader`\n"
308 "  - :class:`BlenderTextureShader`\n"
309 "  - :class:`CalligraphicShader`\n"
310 "  - :class:`ColorNoiseShader`\n"
311 "  - :class:`ColorVariationPatternShader`\n"
312 "  - :class:`ConstantColorShader`\n"
313 "  - :class:`ConstantThicknessShader`\n"
314 "  - :class:`ConstrainedIncreasingThicknessShader`\n"
315 "  - :class:`GuidingLinesShader`\n"
316 "  - :class:`IncreasingColorShader`\n"
317 "  - :class:`IncreasingThicknessShader`\n"
318 "  - :class:`PolygonalizationShader`\n"
319 "  - :class:`SamplingShader`\n"
320 "  - :class:`SmoothingShader`\n"
321 "  - :class:`SpatialNoiseShader`\n"
322 "  - :class:`StrokeTextureShader`\n"
323 "  - :class:`StrokeTextureStepShader`\n"
324 "  - :class:`TextureAssignerShader`\n"
325 "  - :class:`ThicknessNoiseShader`\n"
326 "  - :class:`ThicknessVariationPatternShader`\n"
327 "  - :class:`TipRemoverShader`\n"
328 "  - :class:`fstreamShader`\n"
329 "  - :class:`streamShader`\n"
330 "\n"
331 "- :class:`UnaryFunction0D`\n"
332 "\n"
333 "  - :class:`UnaryFunction0DDouble`\n"
334 "\n"
335 "    - :class:`Curvature2DAngleF0D`\n"
336 "    - :class:`DensityF0D`\n"
337 "    - :class:`GetProjectedXF0D`\n"
338 "    - :class:`GetProjectedYF0D`\n"
339 "    - :class:`GetProjectedZF0D`\n"
340 "    - :class:`GetXF0D`\n"
341 "    - :class:`GetYF0D`\n"
342 "    - :class:`GetZF0D`\n"
343 "    - :class:`LocalAverageDepthF0D`\n"
344 "    - :class:`ZDiscontinuityF0D`\n"
345 "\n"
346 "  - :class:`UnaryFunction0DEdgeNature`\n"
347 "\n"
348 "    - :class:`CurveNatureF0D`\n"
349 "\n"
350 "  - :class:`UnaryFunction0DFloat`\n"
351 "\n"
352 "    - :class:`GetCurvilinearAbscissaF0D`\n"
353 "    - :class:`GetParameterF0D`\n"
354 "    - :class:`GetViewMapGradientNormF0D`\n"
355 "    - :class:`ReadCompleteViewMapPixelF0D`\n"
356 "    - :class:`ReadMapPixelF0D`\n"
357 "    - :class:`ReadSteerableViewMapPixelF0D`\n"
358 "\n"
359 "  - :class:`UnaryFunction0DId`\n"
360 "\n"
361 "    - :class:`ShapeIdF0D`\n"
362 "\n"
363 "  - :class:`UnaryFunction0DMaterial`\n"
364 "\n"
365 "    - :class:`MaterialF0D`\n"
366 "\n"
367 "  - :class:`UnaryFunction0DUnsigned`\n"
368 "\n"
369 "    - :class:`QuantitativeInvisibilityF0D`\n"
370 "\n"
371 "  - :class:`UnaryFunction0DVec2f`\n"
372 "\n"
373 "    - :class:`Normal2DF0D`\n"
374 "    - :class:`VertexOrientation2DF0D`\n"
375 "\n"
376 "  - :class:`UnaryFunction0DVec3f`\n"
377 "\n"
378 "    - :class:`VertexOrientation3DF0D`\n"
379 "\n"
380 "  - :class:`UnaryFunction0DVectorViewShape`\n"
381 "\n"
382 "    - :class:`GetOccludersF0D`\n"
383 "\n"
384 "  - :class:`UnaryFunction0DViewShape`\n"
385 "\n"
386 "    - :class:`GetOccludeeF0D`\n"
387 "    - :class:`GetShapeF0D`\n"
388 "\n"
389 "- :class:`UnaryFunction1D`\n"
390 "\n"
391 "  - :class:`UnaryFunction1DDouble`\n"
392 "\n"
393 "    - :class:`Curvature2DAngleF1D`\n"
394 "    - :class:`DensityF1D`\n"
395 "    - :class:`GetCompleteViewMapDensityF1D`\n"
396 "    - :class:`GetDirectionalViewMapDensityF1D`\n"
397 "    - :class:`GetProjectedXF1D`\n"
398 "    - :class:`GetProjectedYF1D`\n"
399 "    - :class:`GetProjectedZF1D`\n"
400 "    - :class:`GetSteerableViewMapDensityF1D`\n"
401 "    - :class:`GetViewMapGradientNormF1D`\n"
402 "    - :class:`GetXF1D`\n"
403 "    - :class:`GetYF1D`\n"
404 "    - :class:`GetZF1D`\n"
405 "    - :class:`LocalAverageDepthF1D`\n"
406 "    - :class:`ZDiscontinuityF1D`\n"
407 "\n"
408 "  - :class:`UnaryFunction1DEdgeNature`\n"
409 "\n"
410 "    - :class:`CurveNatureF1D`\n"
411 "\n"
412 "  - :class:`UnaryFunction1DFloat`\n"
413 "  - :class:`UnaryFunction1DUnsigned`\n"
414 "\n"
415 "    - :class:`QuantitativeInvisibilityF1D`\n"
416 "\n"
417 "  - :class:`UnaryFunction1DVec2f`\n"
418 "\n"
419 "    - :class:`Normal2DF1D`\n"
420 "    - :class:`Orientation2DF1D`\n"
421 "\n"
422 "  - :class:`UnaryFunction1DVec3f`\n"
423 "\n"
424 "    - :class:`Orientation3DF1D`\n"
425 "\n"
426 "  - :class:`UnaryFunction1DVectorViewShape`\n"
427 "\n"
428 "    - :class:`GetOccludeeF1D`\n"
429 "    - :class:`GetOccludersF1D`\n"
430 "    - :class:`GetShapeF1D`\n"
431 "\n"
432 "  - :class:`UnaryFunction1DVoid`\n"
433 "\n"
434 "    - :class:`ChainingTimeStampF1D`\n"
435 "    - :class:`IncrementChainingTimeStampF1D`\n"
436 "    - :class:`TimeStampF1D`\n"
437 "\n"
438 "- :class:`UnaryPredicate0D`\n"
439 "\n"
440 "  - :class:`FalseUP0D`\n"
441 "  - :class:`TrueUP0D`\n"
442 "\n"
443 "- :class:`UnaryPredicate1D`\n"
444 "\n"
445 "  - :class:`ContourUP1D`\n"
446 "  - :class:`DensityLowerThanUP1D`\n"
447 "  - :class:`EqualToChainingTimeStampUP1D`\n"
448 "  - :class:`EqualToTimeStampUP1D`\n"
449 "  - :class:`ExternalContourUP1D`\n"
450 "  - :class:`FalseUP1D`\n"
451 "  - :class:`QuantitativeInvisibilityUP1D`\n"
452 "  - :class:`ShapeUP1D`\n"
453 "  - :class:`TrueUP1D`\n"
454 "  - :class:`WithinImageBoundaryUP1D`\n"
455 "\n"
456 "- :class:`ViewMap`\n"
457 "- :class:`ViewShape`\n"
458 "- :class:`IntegrationType`\n"
459 "- :class:`MediumType`\n"
460 "- :class:`Nature`\n"
461 "\n";
462
463 /*-----------------------Freestyle module method def---------------------------*/
464
465 static PyMethodDef module_functions[] = {
466         {"getCurrentScene", (PyCFunction) Freestyle_getCurrentScene, METH_NOARGS, Freestyle_getCurrentScene___doc__},
467         {"blendRamp", (PyCFunction) Freestyle_blendRamp, METH_VARARGS, Freestyle_blendRamp___doc__},
468         {"evaluateColorRamp", (PyCFunction) Freestyle_evaluateColorRamp, METH_VARARGS, Freestyle_evaluateColorRamp___doc__},
469         {"evaluateCurveMappingF", (PyCFunction) Freestyle_evaluateCurveMappingF, METH_VARARGS,
470                                   Freestyle_evaluateCurveMappingF___doc__},
471         {NULL, NULL, 0, NULL}
472 };
473
474 /*-----------------------Freestyle module definition---------------------------*/
475
476 static PyModuleDef module_definition = {
477     PyModuleDef_HEAD_INIT,
478     "_freestyle",
479     module_docstring,
480     -1,
481     module_functions
482 };
483
484 //-------------------MODULE INITIALIZATION--------------------------------
485 PyObject *Freestyle_Init(void)
486 {
487         PyObject *module;
488         
489         // initialize modules
490         module = PyModule_Create(&module_definition);
491         if (!module)
492                 return NULL;
493         PyDict_SetItemString(PySys_GetObject("modules"), module_definition.m_name, module);
494
495         // update 'sys.path' for Freestyle Python API modules
496         const char * const path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, "freestyle");
497         if (path) {
498                 char modpath[FILE_MAX];
499                 BLI_join_dirfile(modpath, sizeof(modpath), path, "modules");
500                 PyObject *sys_path = PySys_GetObject("path"); /* borrow */
501                 PyObject *py_modpath = PyUnicode_FromString(modpath);
502                 PyList_Append(sys_path, py_modpath);
503                 Py_DECREF(py_modpath);
504 #if 0
505                 printf("Adding Python path: %s\n", modpath);
506 #endif
507         }
508         else {
509                 printf("Freestyle: couldn't find 'scripts/freestyle/modules', Freestyle won't work properly.\n");
510         }
511         
512         // attach its classes (adding the object types to the module)
513         
514         // those classes have to be initialized before the others
515         MediumType_Init(module);
516         Nature_Init(module);
517
518         BBox_Init(module);
519         BinaryPredicate0D_Init(module);
520         BinaryPredicate1D_Init(module);
521         ContextFunctions_Init(module);
522         FrsMaterial_Init(module);
523         FrsNoise_Init(module);
524         Id_Init(module);
525         IntegrationType_Init(module);
526         Interface0D_Init(module);
527         Interface1D_Init(module);
528         Iterator_Init(module);
529         Operators_Init(module);
530         SShape_Init(module);
531         StrokeAttribute_Init(module);
532         StrokeShader_Init(module);
533         UnaryFunction0D_Init(module);
534         UnaryFunction1D_Init(module);
535         UnaryPredicate0D_Init(module);
536         UnaryPredicate1D_Init(module);
537         ViewMap_Init(module);
538         ViewShape_Init(module);
539
540         return module;
541 }
542
543 ///////////////////////////////////////////////////////////////////////////////////////////
544
545 #ifdef __cplusplus
546 }
547 #endif