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