| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | /* 
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. The Blender | 
					
						
							|  |  |  |  * Foundation also sells licenses for use in proprietary software under | 
					
						
							|  |  |  |  * the Blender License.  See http://www.blender.org/BL/ for information
 | 
					
						
							|  |  |  |  * about this. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This is a new part of Blender. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2003-09-18 00:54:43 +00:00
										 |  |  |  * Contributor(s): Michel Selten, Willian P. Germano, Stephen Swaney | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL/BL DUAL LICENSE BLOCK ***** | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | #ifdef HAVE_CONFIG_H
 | 
					
						
							|  |  |  | #include <config.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | #include <Python.h>
 | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | #include "compile.h" /* for the PyCodeObject */
 | 
					
						
							|  |  |  | #include "eval.h" /* for PyEval_EvalCode */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-18 20:21:26 +00:00
										 |  |  | #include <MEM_guardedalloc.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | #include <BLI_blenlib.h> /* for BLI_last_slash() */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-19 18:57:23 +00:00
										 |  |  | #include <BKE_global.h>
 | 
					
						
							|  |  |  | #include <BKE_main.h>
 | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | #include <BKE_text.h>
 | 
					
						
							| 
									
										
										
										
											2003-03-19 18:57:23 +00:00
										 |  |  | #include <DNA_camera_types.h>
 | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | #include <DNA_ID.h>
 | 
					
						
							| 
									
										
										
										
											2003-03-19 18:57:23 +00:00
										 |  |  | #include <DNA_lamp_types.h>
 | 
					
						
							|  |  |  | #include <DNA_material_types.h>
 | 
					
						
							|  |  |  | #include <DNA_object_types.h>
 | 
					
						
							|  |  |  | #include <DNA_scene_types.h>
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | #include <DNA_scriptlink_types.h>
 | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | #include <DNA_space_types.h>
 | 
					
						
							|  |  |  | #include <DNA_text_types.h>
 | 
					
						
							| 
									
										
										
										
											2003-03-19 18:57:23 +00:00
										 |  |  | #include <DNA_world_types.h>
 | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | #include <DNA_userdef_types.h> /* for U.pythondir */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-19 18:57:23 +00:00
										 |  |  | #include "BPY_extern.h"
 | 
					
						
							| 
									
										
										
										
											2003-05-08 03:13:17 +00:00
										 |  |  | #include "api2_2x/EXPP_interface.h"
 | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-09-03 04:13:08 +00:00
										 |  |  | /* bpy_registryDict is declared in api2_2x/Registry.h and defined
 | 
					
						
							|  |  |  |  * here.  This Python dictionary will be used to store data that scripts | 
					
						
							|  |  |  |  * choose to preserve after they are executed, so user changes can be | 
					
						
							|  |  |  |  * restored next time the script is used.  Check the Blender.Registry module. */ | 
					
						
							|  |  |  | extern PyObject *bpy_registryDict; | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Structure definitions                                                     */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | #define FILENAME_LENGTH 24
 | 
					
						
							|  |  |  | typedef struct _ScriptError { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   char filename[FILENAME_LENGTH]; | 
					
						
							|  |  |  |   int lineno; | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } ScriptError; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Global variables                                                          */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | ScriptError g_script_error; | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | short EXPP_releaseGlobalDict = 1; | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Function prototypes                                                       */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | PyObject *RunPython(Text *text, PyObject *globaldict); | 
					
						
							|  |  |  | char     *GetName(Text *text); | 
					
						
							|  |  |  | PyObject *CreateGlobalDictionary (void); | 
					
						
							|  |  |  | void      ReleaseGlobalDictionary (PyObject * dict); | 
					
						
							|  |  |  | void      DoAllScriptsFromList (ListBase * list, short event); | 
					
						
							| 
									
										
										
										
											2003-07-03 01:42:00 +00:00
										 |  |  | PyObject *importText(char *name); | 
					
						
							|  |  |  | void init_ourImport(void); | 
					
						
							|  |  |  | PyObject *blender_import(PyObject *self, PyObject *args); | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description: This function will initialise Python and all the implemented */ | 
					
						
							|  |  |  | /*              api variations.                                              */ | 
					
						
							|  |  |  | /* Notes:       Currently only the api for 2.2x will be initialised.         */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | void BPY_start_python(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-09-03 04:13:08 +00:00
										 |  |  |   bpy_registryDict = PyDict_New(); /* check comment at start of this file */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!bpy_registryDict) | 
					
						
							|  |  |  |     printf("Error: Couldn't create the Registry Python Dictionary!"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | /* TODO: Shouldn't "blender" be replaced by PACKAGE ?? (config.h) */ | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   Py_SetProgramName("blender"); | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   Py_Initialize (); | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   init_ourImport (); | 
					
						
							| 
									
										
										
										
											2003-07-03 01:42:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   initBlenderApi2_2x (); | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   init_syspath(); | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   return; | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-04-08 19:54:14 +00:00
										 |  |  | /* Description: This function will terminate the Python interpreter          */ | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | void BPY_end_python(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-09-03 04:13:08 +00:00
										 |  |  |   if (bpy_registryDict) { | 
					
						
							|  |  |  |     Py_DECREF (bpy_registryDict); | 
					
						
							|  |  |  |     bpy_registryDict = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   Py_Finalize(); | 
					
						
							|  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | void syspath_append(PyObject *dir) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PyObject *mod_sys, *dict, *path; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyErr_Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   mod_sys = PyImport_ImportModule("sys"); /* new ref */ | 
					
						
							|  |  |  |   dict = PyModule_GetDict(mod_sys);       /* borrowed ref */ | 
					
						
							|  |  |  |   path = PyDict_GetItemString(dict, "path"); /* borrowed ref */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!PyList_Check(path)) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyList_Append(path, dir); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (PyErr_Occurred()) Py_FatalError("could not build sys.path"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_DECREF(mod_sys); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void init_syspath(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   PyObject *path; | 
					
						
							|  |  |  |   PyObject *mod, *d; | 
					
						
							|  |  |  |   PyObject *p; | 
					
						
							|  |  |  |   char *c, *progname; | 
					
						
							|  |  |  |   char execdir[FILE_MAXDIR + FILE_MAXFILE];/*defines from DNA_space_types.h*/ | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   int n; | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   path = Py_BuildValue("s", bprogname); | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   mod = PyImport_ImportModule("Blender.sys"); | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (mod) { | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |     d = PyModule_GetDict(mod); | 
					
						
							|  |  |  |     PyDict_SetItemString(d, "progname", path); | 
					
						
							|  |  |  |     Py_DECREF(mod); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  |   else | 
					
						
							|  |  |  |     printf("Warning: could not set Blender.sys.progname\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   progname = BLI_last_slash(bprogname); /* looks for the last dir separator */ | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   c = Py_GetPath(); /* get python system path */ | 
					
						
							|  |  |  |   PySys_SetPath(c); /* initialize */ | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   n = progname - bprogname; | 
					
						
							|  |  |  |   if (n > 0) { | 
					
						
							|  |  |  |     strncpy(execdir, bprogname, n); | 
					
						
							|  |  |  |     if (execdir[n-1] == '.') n--; /*fix for when run as ./blender */ | 
					
						
							|  |  |  |     execdir[n] = '\0'; | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |     p = Py_BuildValue("s", execdir); | 
					
						
							|  |  |  |     syspath_append(p);  /* append to module search path */ | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |     /* set Blender.sys.progname */ | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  |   else | 
					
						
							|  |  |  |     printf ("Warning: could not determine argv[0] path\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   if (U.pythondir) { | 
					
						
							|  |  |  |     p = Py_BuildValue("s", U.pythondir); | 
					
						
							|  |  |  |     syspath_append(p);  /* append to module search path */ | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-09-18 00:54:43 +00:00
										 |  |  |   /* sds */ | 
					
						
							|  |  |  |   /* bring in the site module so we can add site-package dirs to sys.path */ | 
					
						
							|  |  |  |   mod = PyImport_ImportModule("site"); /* new ref */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (mod) { | 
					
						
							|  |  |  |     PyObject* item; | 
					
						
							|  |  |  |     int size, index; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* get the value of 'sitedirs' from the module */ | 
					
						
							|  |  |  |     d = PyModule_GetDict (mod); /* borrowed ref */ | 
					
						
							|  |  |  |     p = PyDict_GetItemString (d, "sitedirs");  /* borrowed ref */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* append each item in sitedirs list to path */ | 
					
						
							|  |  |  |     size = PyList_Size (p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (index = 0; index < size; index++) { | 
					
						
							|  |  |  |       item  = PySequence_GetItem (p, index);  /* new ref */ | 
					
						
							|  |  |  |       syspath_append (item); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(mod); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else PyErr_Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   /* set sys.executable to the Blender exe */ | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  |   mod = PyImport_ImportModule("sys"); /* new ref */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   if (mod) { | 
					
						
							|  |  |  |     d = PyModule_GetDict(mod); /* borrowed ref */ | 
					
						
							|  |  |  |     PyDict_SetItemString(d, "executable", Py_BuildValue("s", bprogname)); | 
					
						
							| 
									
										
										
										
											2003-08-10 23:18:00 +00:00
										 |  |  |     /* in the future this can be extended to have more argv's if needed: */ | 
					
						
							|  |  |  |     PyDict_SetItemString(d, "argv", Py_BuildValue("[s]", bprogname)); | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |     Py_DECREF(mod); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-06-28 07:38:21 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-28 10:35:14 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description: This function adds the user defined folder for Python        */ | 
					
						
							|  |  |  | /*              scripts to sys.path.  This is done in init_syspath, too, but */ | 
					
						
							|  |  |  | /*              when Blender's main() runs BPY_start_python(), U.pythondir   */ | 
					
						
							|  |  |  | /*              isn't set yet, so we provide this function to be executed    */ | 
					
						
							|  |  |  | /*              after U.pythondir is defined.                                */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | void BPY_syspath_append_pythondir(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   syspath_append(Py_BuildValue("s", U.pythondir)); | 
					
						
							| 
									
										
										
										
											2003-06-28 10:35:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description: This function will return the linenumber on which an error   */ | 
					
						
							|  |  |  | /*              has occurred in the Python script.                           */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | int BPY_Err_getLinenumber(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   return g_script_error.lineno; | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description: This function will return the filename of the python script. */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | const char *BPY_Err_getFilename(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   return g_script_error.filename; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description: Return PyString filename from a traceback object             */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | PyObject *traceback_getFilename(PyObject *tb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PyObject *v; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* co_filename is in f_code, which is in tb_frame, which is in tb */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   v = PyObject_GetAttrString(tb, "tb_frame"); Py_XDECREF(v); | 
					
						
							|  |  |  |   v = PyObject_GetAttrString(v, "f_code"); Py_XDECREF(v); | 
					
						
							|  |  |  |   v = PyObject_GetAttrString(v, "co_filename"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return v; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description: Blender Python error handler. This catches the error and     */ | 
					
						
							|  |  |  | /* stores filename and line number in a global                               */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | void BPY_Err_Handle(Text *text) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PyObject *exception, *err, *tb, *v; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyErr_Fetch(&exception, &err, &tb); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!exception && !tb) { | 
					
						
							|  |  |  |     printf("FATAL: spurious exception\n"); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   strcpy(g_script_error.filename, GetName(text)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) { | 
					
						
							|  |  |  |     /* no traceback available when SyntaxError */ | 
					
						
							|  |  |  |     PyErr_Restore(exception, err, tb); /* takes away reference! */ | 
					
						
							|  |  |  |     PyErr_Print(); | 
					
						
							|  |  |  |     v = PyObject_GetAttrString(err, "lineno"); | 
					
						
							|  |  |  |     g_script_error.lineno = PyInt_AsLong(v); | 
					
						
							|  |  |  |     Py_XDECREF(v); | 
					
						
							| 
									
										
										
										
											2003-09-18 00:54:43 +00:00
										 |  |  |     /* this avoids an abort in Python 2.3's garbage collecting: */ | 
					
						
							|  |  |  |     PyErr_Clear();  | 
					
						
							|  |  |  |     return; | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     PyErr_NormalizeException(&exception, &err, &tb); | 
					
						
							|  |  |  |     PyErr_Restore(exception, err, tb); // takes away reference!
 | 
					
						
							|  |  |  |     PyErr_Print(); | 
					
						
							|  |  |  |     tb = PySys_GetObject("last_traceback"); | 
					
						
							| 
									
										
										
										
											2003-06-07 03:49:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |     if (!tb) { | 
					
						
							|  |  |  |       printf("\nCan't get traceback\n"); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-06-07 03:49:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Py_INCREF(tb); | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* From old bpython BPY_main.c:
 | 
					
						
							|  |  |  |  * 'check traceback objects and look for last traceback in the | 
					
						
							|  |  |  |  *  same text file. This is used to jump to the line of where the | 
					
						
							|  |  |  |  *  error occured. "If the error occured in another text file or module, | 
					
						
							|  |  |  |  *  the last frame in the current file is adressed."' */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-23 04:37:33 +00:00
										 |  |  |     while (1) {  | 
					
						
							|  |  |  |       v = PyObject_GetAttrString(tb, "tb_next"); | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-23 04:37:33 +00:00
										 |  |  |       if (v == Py_None || strcmp(PyString_AsString(traceback_getFilename(v)), | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |                               GetName(text))) { | 
					
						
							| 
									
										
										
										
											2003-05-23 04:37:33 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2003-05-23 04:37:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Py_DECREF(tb); | 
					
						
							|  |  |  |       tb = v; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     v = PyObject_GetAttrString(tb, "tb_lineno"); | 
					
						
							|  |  |  |     g_script_error.lineno = PyInt_AsLong(v); | 
					
						
							|  |  |  |     Py_XDECREF(v); | 
					
						
							|  |  |  |     v = traceback_getFilename(tb); | 
					
						
							|  |  |  |     strncpy(g_script_error.filename, PyString_AsString(v), FILENAME_LENGTH); | 
					
						
							|  |  |  |     Py_XDECREF(v); | 
					
						
							|  |  |  |     Py_DECREF(tb); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |   return; | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description: This function executes the script passed by st.              */ | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | /* Notes:       It is called by blender/src/drawtext.c when a Blender user   */ | 
					
						
							|  |  |  | /*              presses ALT+PKEY in the script's text window.                */ | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | struct _object *BPY_txt_do_python(struct SpaceText* st) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   PyObject *dict, *ret; | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   PyObject *main_dict = PyModule_GetDict(PyImport_AddModule("__main__")); | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!st->text) return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* The EXPP_releaseGlobalDict global variable controls whether we should run
 | 
					
						
							|  |  |  |  * the script with a clean global dictionary or should keep the current one, | 
					
						
							|  |  |  |  * possibly already "polluted" by other calls to the Python Interpreter. | 
					
						
							|  |  |  |  * The default is to use a clean one.  To change this the script writer must | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |  * call Blender.ReleaseGlobalDict(bool), with bool == 0, in the script. */ | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (EXPP_releaseGlobalDict) { | 
					
						
							|  |  |  |     printf("Using a clean Global Dictionary.\n"); | 
					
						
							|  |  |  |     st->flags |= ST_CLEAR_NAMESPACE; | 
					
						
							|  |  |  |     dict = CreateGlobalDictionary(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |     dict = main_dict; /* must be careful not to free the main_dict */ | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-22 18:34:36 +00:00
										 |  |  |   clearScriptLinks (); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   ret = RunPython (st->text, dict); /* Run the script */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!ret) { /* Failed execution of the script */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |     if (EXPP_releaseGlobalDict && (dict != main_dict)) | 
					
						
							|  |  |  |       ReleaseGlobalDictionary(dict); | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     BPY_Err_Handle(st->text); | 
					
						
							|  |  |  |     BPY_end_python(); | 
					
						
							|  |  |  |     BPY_start_python(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   else Py_DECREF (ret); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  | /* Scripts that use the GUI rely on the persistent global namespace, so
 | 
					
						
							|  |  |  |  * they need a workaround: The namespace is released when the GUI is exit.' | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |  * See api2_2x/Draw.c: Method_Register() */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  | /* Block below: The global dict should only be released if:
 | 
					
						
							|  |  |  |  * - a script didn't defined it to be persistent and | 
					
						
							|  |  |  |  * - Draw.Register() is not in use (no GUI) and | 
					
						
							|  |  |  |  * - it is not the real __main__ dict (if it is, restart to clean it) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (EXPP_releaseGlobalDict) { | 
					
						
							|  |  |  |     if (st->flags & ST_CLEAR_NAMESPACE) { /* False if the GUI is in use */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (dict != main_dict) ReleaseGlobalDictionary(dict); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         BPY_end_python(); /* restart to get a fresh __main__ dict */ | 
					
						
							|  |  |  |         BPY_start_python(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   else if (dict != main_dict) PyDict_Update (main_dict, dict); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Line above: if it should be kept and it's not already the __main__ dict,
 | 
					
						
							|  |  |  |  * merge it into the __main__ one.  This happens when to release is the | 
					
						
							|  |  |  |  * current behavior and the script changes that with | 
					
						
							|  |  |  |  * Blender.ReleaseGlobalDict(0). */ | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Edited from old BPY_main.c:
 | 
					
						
							|  |  |  |  * 'The return value is the global namespace dictionary of the script | 
					
						
							|  |  |  |  *  context.  This may be stored in the SpaceText instance to give control | 
					
						
							|  |  |  |  *  over namespace persistence.  Remember that the same script may be | 
					
						
							|  |  |  |  *  executed in several windows ...  Namespace persistence is desired for | 
					
						
							|  |  |  |  *  scripts that use the GUI and store callbacks to the current script.' */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return dict; | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description:                                                              */ | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | /* Notes:                                                                    */ | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | void BPY_free_compiled_text(struct Text* text) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   if (!text->compiled) return; | 
					
						
							|  |  |  |   Py_DECREF((PyObject*) text->compiled); | 
					
						
							|  |  |  |   text->compiled = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |   return; | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* ScriptLinks                                                               */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description:                                                              */ | 
					
						
							|  |  |  | /* Notes:       Not implemented yet                                          */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | void BPY_clear_bad_scriptlinks(struct Text *byebye) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |   BPY_clear_bad_scriptlist(getObjectList(), byebye); | 
					
						
							|  |  |  |   BPY_clear_bad_scriptlist(getLampList(), byebye); | 
					
						
							|  |  |  |   BPY_clear_bad_scriptlist(getCameraList(), byebye); | 
					
						
							|  |  |  |   BPY_clear_bad_scriptlist(getMaterialList(), byebye); | 
					
						
							|  |  |  |   BPY_clear_bad_scriptlist(getWorldList(),  byebye); | 
					
						
							|  |  |  |   BPY_clear_bad_scriptlink(&scene_getCurrent()->id, byebye); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   allqueue(REDRAWBUTSSCRIPT, 0); | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |   return; | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-03-19 18:57:23 +00:00
										 |  |  | /* Description: Loop through all scripts of a list of object types, and      */ | 
					
						
							|  |  |  | /*              execute these scripts.                                       */ | 
					
						
							|  |  |  | /*              For the scene, only the current active scene the scripts are */ | 
					
						
							|  |  |  | /*              executed (if any).                                           */ | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | void BPY_do_all_scripts(short event) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   DoAllScriptsFromList (&(G.main->object), event); | 
					
						
							|  |  |  |   DoAllScriptsFromList (&(G.main->lamp), event); | 
					
						
							|  |  |  |   DoAllScriptsFromList (&(G.main->camera), event); | 
					
						
							|  |  |  |   DoAllScriptsFromList (&(G.main->mat), event); | 
					
						
							|  |  |  |   DoAllScriptsFromList (&(G.main->world), event); | 
					
						
							| 
									
										
										
										
											2003-03-19 18:57:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   BPY_do_pyscript (&(G.scene->id), event); | 
					
						
							| 
									
										
										
										
											2003-03-19 18:57:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |   return; | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-18 20:21:26 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description: Execute a Python script when an event occurs. The following  */ | 
					
						
							|  |  |  | /*              events are possible: frame changed, load script and redraw.  */ | 
					
						
							|  |  |  | /*              Only events happening to one of the following object types   */ | 
					
						
							|  |  |  | /*              are handled: Object, Lamp, Camera, Material, World and       */ | 
					
						
							|  |  |  | /*              Scene.                                                       */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | void BPY_do_pyscript(struct ID *id, short event) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   ScriptLink  * scriptlink; | 
					
						
							|  |  |  |   int           index; | 
					
						
							|  |  |  |   PyObject    * dict; | 
					
						
							| 
									
										
										
										
											2003-06-22 18:34:36 +00:00
										 |  |  |   PyObject    * ret; | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   scriptlink = setScriptLinks (id, event); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (scriptlink == NULL) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (index = 0; index < scriptlink->totscript; index++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if ((scriptlink->flag[index] == event) && | 
					
						
							|  |  |  |         (scriptlink->scripts[index] != NULL)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       dict = CreateGlobalDictionary(); | 
					
						
							| 
									
										
										
										
											2003-06-22 18:34:36 +00:00
										 |  |  |       ret = RunPython ((Text*) scriptlink->scripts[index], dict); | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |       ReleaseGlobalDictionary (dict); | 
					
						
							| 
									
										
										
										
											2003-06-22 18:34:36 +00:00
										 |  |  |       if (!ret) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |           /* Failed execution of the script */ | 
					
						
							|  |  |  |           BPY_Err_Handle ((Text*) scriptlink->scripts[index]); | 
					
						
							|  |  |  |           BPY_end_python (); | 
					
						
							|  |  |  |           BPY_start_python (); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |           Py_DECREF (ret); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-03-18 20:21:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |   return; | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description:                                                              */ | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | /* Notes:                                                                    */ | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | void BPY_free_scriptlink(struct ScriptLink *slink) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   if (slink->totscript) { | 
					
						
							|  |  |  |     if(slink->flag) MEM_freeN(slink->flag); | 
					
						
							|  |  |  |     if(slink->scripts) MEM_freeN(slink->scripts);  | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |   return; | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description:                                                              */ | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | /* Notes:                                                                    */ | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | void BPY_copy_scriptlink(struct ScriptLink *scriptlink) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   void *tmp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (scriptlink->totscript) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tmp = scriptlink->scripts; | 
					
						
							|  |  |  |     scriptlink->scripts = | 
					
						
							|  |  |  |       MEM_mallocN(sizeof(ID*)*scriptlink->totscript, "scriptlistL"); | 
					
						
							|  |  |  |     memcpy(scriptlink->scripts, tmp, sizeof(ID*)*scriptlink->totscript); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tmp = scriptlink->flag; | 
					
						
							|  |  |  |     scriptlink->flag = | 
					
						
							|  |  |  |       MEM_mallocN(sizeof(short)*scriptlink->totscript, "scriptlistF"); | 
					
						
							|  |  |  |     memcpy(scriptlink->flag, tmp, sizeof(short)*scriptlink->totscript); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |   return; | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description:                                                              */ | 
					
						
							|  |  |  | /* Notes:       Not implemented yet                                          */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | int BPY_call_importloader(char *name) | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | { /* XXX Should this function go away from Blender? */ | 
					
						
							|  |  |  |   printf ("In BPY_call_importloader(name=%s)\n",name); | 
					
						
							|  |  |  |   return (0); | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Private functions                                                         */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description: This function executes the python script passed by text.     */ | 
					
						
							|  |  |  | /*              The Python dictionary containing global variables needs to   */ | 
					
						
							|  |  |  | /*              be passed in globaldict.                                     */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | PyObject * RunPython(Text *text, PyObject *globaldict) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   char *buf = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* The script text is compiled to Python bytecode and saved at text->compiled
 | 
					
						
							|  |  |  |  * to speed-up execution if the user executes the script multiple times */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!text->compiled) { /* if it wasn't already compiled, do it now */ | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |     buf = txt_to_buf(text); | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     text->compiled = Py_CompileString(buf, GetName(text), Py_file_input); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     MEM_freeN(buf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (PyErr_Occurred()) { | 
					
						
							|  |  |  |       BPY_free_compiled_text(text); | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   return PyEval_EvalCode(text->compiled, globaldict, globaldict); | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-08 18:10:20 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description: This function returns the value of the name field of the     */ | 
					
						
							|  |  |  | /*              given Text struct.                                           */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | char * GetName(Text *text) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   return (text->id.name+2); | 
					
						
							| 
									
										
										
										
											2003-02-26 19:22:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-18 20:21:26 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description: This function creates a new Python dictionary object.        */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | PyObject * CreateGlobalDictionary (void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   PyObject *dict = PyDict_New(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyDict_SetItemString (dict, "__builtins__", PyEval_GetBuiltins()); | 
					
						
							|  |  |  |   PyDict_SetItemString (dict, "__name__", PyString_FromString("__main__")); | 
					
						
							| 
									
										
										
										
											2003-03-18 20:21:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   return dict; | 
					
						
							| 
									
										
										
										
											2003-03-18 20:21:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description: This function deletes a given Python dictionary object.      */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | void ReleaseGlobalDictionary (PyObject * dict) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   PyDict_Clear (dict); | 
					
						
							|  |  |  |   Py_DECREF (dict);   /* Release dictionary. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |   return; | 
					
						
							| 
									
										
										
										
											2003-03-18 20:21:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-19 18:57:23 +00:00
										 |  |  | /*****************************************************************************/ | 
					
						
							|  |  |  | /* Description: This function runs all scripts (if any) present in the       */ | 
					
						
							|  |  |  | /*              list argument. The event by which the function has been      */ | 
					
						
							|  |  |  | /*              called, is passed in the event argument.                     */ | 
					
						
							|  |  |  | /*****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  | void DoAllScriptsFromList (ListBase *list, short event) | 
					
						
							| 
									
										
										
										
											2003-03-19 18:57:23 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   ID *id; | 
					
						
							| 
									
										
										
										
											2003-03-19 18:57:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   id = list->first; | 
					
						
							| 
									
										
										
										
											2003-03-19 18:57:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-13 01:54:28 +00:00
										 |  |  |   while (id != NULL) { | 
					
						
							|  |  |  |     BPY_do_pyscript (id, event); | 
					
						
							|  |  |  |     id = id->next; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-09 20:07:43 +00:00
										 |  |  |   return; | 
					
						
							| 
									
										
										
										
											2003-03-19 18:57:23 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2003-07-03 01:42:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | PyObject *importText(char *name) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   Text *text; | 
					
						
							|  |  |  |   char *txtname; | 
					
						
							|  |  |  |   char *buf = NULL; | 
					
						
							|  |  |  |   int namelen = strlen(name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   txtname = malloc(namelen+3+1); | 
					
						
							|  |  |  |   if (!txtname) return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   memcpy(txtname, name, namelen); | 
					
						
							|  |  |  |   memcpy(&txtname[namelen], ".py", 4); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   text = (Text*) &(G.main->text.first); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while(text) { | 
					
						
							|  |  |  |     if (!strcmp (txtname, GetName(text))) | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     text = text->id.next; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!text) { | 
					
						
							|  |  |  |     free(txtname); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!text->compiled) { | 
					
						
							|  |  |  |     buf = txt_to_buf(text); | 
					
						
							|  |  |  |     text->compiled = Py_CompileString(buf, GetName(text), Py_file_input); | 
					
						
							|  |  |  |     MEM_freeN(buf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (PyErr_Occurred()) { | 
					
						
							|  |  |  |       PyErr_Print(); | 
					
						
							|  |  |  |       BPY_free_compiled_text(text); | 
					
						
							|  |  |  |       free(txtname); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   free(txtname); | 
					
						
							|  |  |  |   return PyImport_ExecCodeModule(name, text->compiled); | 
					
						
							| 
									
										
										
										
											2003-07-03 01:42:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyMethodDef bimport[] = { | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   { "blimport", blender_import, METH_VARARGS, "our own import"} | 
					
						
							| 
									
										
										
										
											2003-07-03 01:42:00 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *blender_import(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   PyObject *exception, *err, *tb; | 
					
						
							|  |  |  |   char *name; | 
					
						
							|  |  |  |   PyObject *globals = NULL, *locals = NULL, *fromlist = NULL; | 
					
						
							|  |  |  |   PyObject *m; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!PyArg_ParseTuple(args, "s|OOO:bimport", | 
					
						
							|  |  |  |           &name, &globals, &locals, &fromlist)) | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m = PyImport_ImportModuleEx(name, globals, locals, fromlist); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (m)  | 
					
						
							|  |  |  |     return m; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     PyErr_Fetch(&exception, &err, &tb); /*restore for probable later use*/ | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   m = importText(name); | 
					
						
							|  |  |  |   if (m) { /* found module, ignore above exception*/ | 
					
						
							|  |  |  |     PyErr_Clear(); | 
					
						
							|  |  |  |     Py_XDECREF(exception); Py_XDECREF(err); Py_XDECREF(tb); | 
					
						
							|  |  |  |     printf("imported from text buffer...\n"); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     PyErr_Restore(exception, err, tb); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return m; | 
					
						
							| 
									
										
										
										
											2003-07-03 01:42:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void init_ourImport(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   PyObject *m, *d; | 
					
						
							|  |  |  |   PyObject *import = PyCFunction_New(bimport, NULL); | 
					
						
							| 
									
										
										
										
											2003-07-03 01:42:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-04 02:56:07 +00:00
										 |  |  |   m = PyImport_AddModule("__builtin__"); | 
					
						
							|  |  |  |   d = PyModule_GetDict(m); | 
					
						
							|  |  |  |   PyDict_SetItemString(d, "__import__", import); | 
					
						
							| 
									
										
										
										
											2003-07-03 01:42:00 +00:00
										 |  |  | } |