76fc47dfe1ac06b81e47d3345983fa23fc99013d
[blender-staging.git] / source / blender / python / BPY_interface.c
1 /* 
2  *
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * This is a new part of Blender.
26  *
27  * Contributor(s): Michel Selten, Willian P. Germano
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30 */
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34 #include <Python.h>
35 #include <stdio.h>
36
37 #include <MEM_guardedalloc.h>
38
39 #include <BKE_global.h>
40 #include <BKE_main.h>
41 #include <BKE_text.h>
42 #include <DNA_camera_types.h>
43 #include <DNA_ID.h>
44 #include <DNA_lamp_types.h>
45 #include <DNA_material_types.h>
46 #include <DNA_object_types.h>
47 #include <DNA_scene_types.h>
48 #include <DNA_scriptlink_types.h>
49 #include <DNA_space_types.h>
50 #include <DNA_text_types.h>
51 #include <DNA_world_types.h>
52
53 #include "BPY_extern.h"
54
55 #include "api2_2x/EXPP_interface.h"
56
57 /*****************************************************************************/
58 /* Structure definitions                                                     */
59 /*****************************************************************************/
60 #define FILENAME_LENGTH 24
61 typedef struct _ScriptError {
62         char filename[FILENAME_LENGTH];
63         int lineno;
64 } ScriptError;
65
66 /*****************************************************************************/
67 /* Global variables                                                          */
68 /*****************************************************************************/
69 ScriptError g_script_error;
70
71 /*****************************************************************************/
72 /* Function prototypes                                                       */
73 /*****************************************************************************/
74 PyObject * RunPython(Text *text, PyObject *globaldict);
75 char *     GetName(Text *text);
76 PyObject * CreateGlobalDictionary (void);
77 void       ReleaseGlobalDictionary (PyObject * dict);
78 void       DoAllScriptsFromList (ListBase * list, short event);
79
80 /*****************************************************************************/
81 /* Description: This function will initialise Python and all the implemented */
82 /*              api variations.                                              */
83 /* Notes:       Currently only the api for 2.2x will be initialised.         */
84 /*****************************************************************************/
85 void BPY_start_python(void)
86 {
87         printf ("In BPY_start_python\n");
88 /* TODO: Shouldn't "blender" be replaced by PACKAGE ?? (config.h) */
89         Py_SetProgramName("blender");
90
91         Py_Initialize ();
92
93         initBlenderApi2_2x ();
94
95         return;
96 }
97
98 /*****************************************************************************/
99 /* Description: This function will terminate the Python interpreter          */
100 /*****************************************************************************/
101 void BPY_end_python(void)
102 {
103         printf ("In BPY_end_python\n");
104         Py_Finalize();
105         return;
106 }
107
108 /*****************************************************************************/
109 /* Description: This function will return the linenumber on which an error   */
110 /*              has occurred in the Python script.                           */
111 /*****************************************************************************/
112 int BPY_Err_getLinenumber(void)
113 {
114         printf ("In BPY_Err_getLinenumber\n");
115         return g_script_error.lineno;
116 }
117
118 /*****************************************************************************/
119 /* Description: This function will return the filename of the python script. */
120 /*****************************************************************************/
121 const char *BPY_Err_getFilename(void)
122 {
123         printf ("In BPY_Err_getFilename\n");
124         return g_script_error.filename;
125 }
126
127 /*****************************************************************************/
128 /* Description: This function executes the script passed by st.              */
129 /* Notes:       Currently, the script is compiled each time it is executed,  */
130 /*              This should be optimized to store the compiled bytecode as   */
131 /*              has been done by the previous implementation.                */
132 /*****************************************************************************/
133 struct _object *BPY_txt_do_python(struct SpaceText* st)
134 {
135         PyObject *      dict;
136         PyObject *      ret;
137         printf ("In BPY_txt_do_python\n");
138
139         if (!st->text)
140         {
141                 return NULL;
142         }
143
144         dict = PyModule_GetDict(PyImport_AddModule("__main__"));
145         /* dict = newGlobalDictionary(); */
146         ret = RunPython (st->text, dict);
147
148         /* If errors have occurred, set the error filename to the name of the
149            script.
150         */
151         if (!ret)
152         {
153                 sprintf(g_script_error.filename, "%s", st->text->id.name+2);
154                 return NULL;
155         }
156
157         return dict;
158 }
159
160 /*****************************************************************************/
161 /* Description:                                                              */
162 /* Notes:       Not implemented yet                                          */
163 /*****************************************************************************/
164 void BPY_free_compiled_text(struct Text* text)
165 {
166         printf ("In BPY_free_compiled_text\n");
167         return;
168 }
169
170 /*****************************************************************************/
171 /* Description:                                                              */
172 /* Notes:       Not implemented yet                                          */
173 /*****************************************************************************/
174 void BPY_clear_bad_scriptlinks(struct Text *byebye)
175 {
176         printf ("In BPY_clear_bad_scriptlinks\n");
177         return;
178 }
179
180 /*****************************************************************************/
181 /* Description: Loop through all scripts of a list of object types, and      */
182 /*              execute these scripts.                                       */
183 /*              For the scene, only the current active scene the scripts are */
184 /*              executed (if any).                                           */
185 /*****************************************************************************/
186 void BPY_do_all_scripts(short event)
187 {
188         printf ("In BPY_do_all_scripts(event=%d)\n",event);
189
190         DoAllScriptsFromList (&(G.main->object), event);
191         DoAllScriptsFromList (&(G.main->lamp), event);
192         DoAllScriptsFromList (&(G.main->camera), event);
193         DoAllScriptsFromList (&(G.main->mat), event);
194         DoAllScriptsFromList (&(G.main->world), event);
195
196         BPY_do_pyscript (&(G.scene->id), event);
197         return;
198 }
199
200 /*****************************************************************************/
201 /* Description: Execute a Python script when an event occurs. The following  */
202 /*              events are possible: frame changed, load script and redraw.  */
203 /*              Only events happening to one of the following object types   */
204 /*              are handled: Object, Lamp, Camera, Material, World and       */
205 /*              Scene.                                                       */
206 /*****************************************************************************/
207 void BPY_do_pyscript(struct ID *id, short event)
208 {
209         ScriptLink     * scriptlink;
210         int              index;
211         PyObject       * dict;
212
213         printf ("In BPY_do_pyscript(id=%s, event=%d)\n",id->name, event);
214
215         scriptlink = setScriptLinks (id, event);
216
217         if (scriptlink == NULL)
218         {
219                 return;
220         }
221
222         for (index=0 ; index<scriptlink->totscript ; index++)
223         {
224                 printf ("scriptnr: %d\tevent=%d, flag[index]=%d\n", index,
225                                 event, scriptlink->flag[index]);
226                 if ((scriptlink->flag[index] == event) &&
227                     (scriptlink->scripts[index]!=NULL))
228                 {
229                         dict = CreateGlobalDictionary();
230                         RunPython ((Text*) scriptlink->scripts[index], dict);
231                         ReleaseGlobalDictionary (dict);
232                 }
233         }
234
235         return;
236 }
237
238 /*****************************************************************************/
239 /* Description:                                                              */
240 /* Notes:       Not implemented yet                                          */
241 /*****************************************************************************/
242 void BPY_free_scriptlink(struct ScriptLink *slink)
243 {
244         printf ("In BPY_free_scriptlink\n");
245         return;
246 }
247
248 /*****************************************************************************/
249 /* Description:                                                              */
250 /* Notes:       Not implemented yet                                          */
251 /*****************************************************************************/
252 void BPY_copy_scriptlink(struct ScriptLink *scriptlink)
253 {
254         printf ("In BPY_copy_scriptlink\n");
255         return;
256 }
257
258 /*****************************************************************************/
259 /* Description:                                                              */
260 /* Notes:       Not implemented yet                                          */
261 /*****************************************************************************/
262 int BPY_call_importloader(char *name)
263 {
264         printf ("In BPY_call_importloader(name=%s)\n",name);
265         return (0);
266 }
267
268 /*****************************************************************************/
269 /* Description:                                                              */
270 /* Notes:       Not implemented yet                                          */
271 /*****************************************************************************/
272 int BPY_spacetext_is_pywin(struct SpaceText *st)
273 {
274         /* No printf is done here because it is called with every mouse move */
275         return (0);
276 }
277
278 /*****************************************************************************/
279 /* Description:                                                              */
280 /* Notes:       Not implemented yet                                          */
281 /*****************************************************************************/
282 void BPY_spacetext_do_pywin_draw(struct SpaceText *st)
283 {
284         printf ("In BPY_spacetext_do_pywin_draw\n");
285         return;
286 }
287
288 /*****************************************************************************/
289 /* Description:                                                              */
290 /* Notes:       Not implemented yet                                          */
291 /*****************************************************************************/
292 void BPY_spacetext_do_pywin_event(struct SpaceText *st,
293                                   unsigned short event,
294                                   short val)
295 {
296         printf ("In BPY_spacetext_do_pywin_event(st=?, event=%d, val=%d)\n",
297                 event, val);
298         return;
299 }
300
301 /*****************************************************************************/
302 /* Private functions                                                         */
303 /*****************************************************************************/
304
305 /*****************************************************************************/
306 /* Description: This function executes the python script passed by text.     */
307 /*              The Python dictionary containing global variables needs to   */
308 /*              be passed in globaldict.                                     */
309 /*****************************************************************************/
310 PyObject * RunPython(Text *text, PyObject *globaldict)
311 {
312         PyObject * ret;
313         char     * buf;
314
315         printf("Run Python script \"%s\" ...\n", GetName(text));
316         buf = txt_to_buf(text);
317         ret = PyRun_String (buf, Py_file_input, globaldict, globaldict);
318
319         if (!ret)
320         {
321                 /* an exception was raised, handle it here */
322                 PyErr_Print(); /* this function also clears the error
323                                   indicator */
324         }
325         else
326         {
327                 PyErr_Clear(); /* seems necessary, at least now */
328         }
329
330         MEM_freeN (buf);
331         return ret;
332 }
333
334 /*****************************************************************************/
335 /* Description: This function returns the value of the name field of the     */
336 /*              given Text struct.                                           */
337 /*****************************************************************************/
338 char * GetName(Text *text)
339 {
340         return (text->id.name+2);
341 }
342
343 /*****************************************************************************/
344 /* Description: This function creates a new Python dictionary object.        */
345 /*****************************************************************************/
346 PyObject * CreateGlobalDictionary (void)
347 {
348         PyObject *dict = PyDict_New();
349         PyDict_SetItemString (dict, "__builtins__", PyEval_GetBuiltins());
350         PyDict_SetItemString (dict, "__name__", PyString_FromString("__main__"));
351
352         return (dict);
353 }
354
355 /*****************************************************************************/
356 /* Description: This function deletes a given Python dictionary object.      */
357 /*****************************************************************************/
358 void ReleaseGlobalDictionary (PyObject * dict)
359 {
360         PyDict_Clear (dict);
361         Py_DECREF (dict);               /* Release dictionary. */
362 }
363
364 /*****************************************************************************/
365 /* Description: This function runs all scripts (if any) present in the       */
366 /*              list argument. The event by which the function has been      */
367 /*              called, is passed in the event argument.                     */
368 /*****************************************************************************/
369 void DoAllScriptsFromList (ListBase * list, short event)
370 {
371         ID       * id;
372
373         id = list->first;
374
375         while (id != NULL)
376         {
377                 BPY_do_pyscript (id, event);
378                 id = id->next;
379         }
380 }
381