| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-16 16:17:20 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef WIN32
 | 
					
						
							|  |  |  | #include <dirent.h>
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #include "BLI_winstuff.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-02-16 16:17:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | #include <Python.h>
 | 
					
						
							|  |  |  | #include "compile.h"		/* for the PyCodeObject */
 | 
					
						
							|  |  |  | #include "eval.h"		/* for PyEval_EvalCode */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "bpy_compat.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "bpy_rna.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-21 08:53:36 +00:00
										 |  |  | #include "bpy_operator.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | #include "bpy_ui.h"
 | 
					
						
							| 
									
										
										
										
											2009-06-05 16:11:35 +00:00
										 |  |  | #include "bpy_util.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-20 09:17:43 +00:00
										 |  |  | #include "DNA_anim_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | #include "DNA_space_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | #include "DNA_text_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | #include "BLI_util.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | #include "BLI_string.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_context.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-20 09:17:43 +00:00
										 |  |  | #include "BKE_fcurve.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | #include "BKE_text.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5
More cleanup!
- removed old UI font completely, including from uiBeginBlock
- emboss hints for uiBlock only have three types now;
  Regular, Pulldown, or "Nothing" (only icon/text)
- removed old font path from Userdef
- removed all old button theme hinting
- removed old "auto block" to merge buttons in groups
  (was only in use for radiosity buttons)
And went over all warnings. One hooray for make giving clean output :)
Well, we need uniform definitions for warnings, so people at least fix
them... here's the real bad bugs I found:
- in mesh code, a call to editmesh mixed *em and *me
- in armature, ED_util.h was not included, so no warnings for wrong call
  to ED_undo_push()
- The extern Py api .h was not included in the bpy_interface.c, showing
  a several calls using different args.
Further just added the missing includes, and removed unused vars.
											
										 
											2009-04-14 15:59:52 +00:00
										 |  |  | #include "BPY_extern.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-17 20:33:34 +00:00
										 |  |  | #include "../generic/bpy_internal_import.h" // our own imports
 | 
					
						
							| 
									
										
										
										
											2009-07-02 12:11:20 +00:00
										 |  |  | /* external util modules */ | 
					
						
							| 
									
										
										
										
											2009-06-23 13:34:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "../generic/Mathutils.h"
 | 
					
						
							|  |  |  | #include "../generic/Geometry.h"
 | 
					
						
							|  |  |  | #include "../generic/BGL.h"
 | 
					
						
							| 
									
										
										
										
											2009-06-17 20:33:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | void BPY_free_compiled_text( struct Text *text ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if( text->compiled ) { | 
					
						
							|  |  |  | 		Py_DECREF( ( PyObject * ) text->compiled ); | 
					
						
							|  |  |  | 		text->compiled = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | * Description: Creates the bpy module and adds it to sys.modules for importing | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | *****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | static void bpy_init_modules( void ) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-03-13 07:50:07 +00:00
										 |  |  | 	PyObject *mod; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-03-13 07:50:07 +00:00
										 |  |  | 	mod = PyModule_New("bpy"); | 
					
						
							| 
									
										
										
										
											2009-02-16 16:17:20 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-03-13 07:50:07 +00:00
										 |  |  | 	PyModule_AddObject( mod, "data", BPY_rna_module() ); | 
					
						
							|  |  |  | 	/* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */ | 
					
						
							|  |  |  | 	PyModule_AddObject( mod, "types", BPY_rna_types() ); | 
					
						
							| 
									
										
										
										
											2009-06-18 19:51:22 +00:00
										 |  |  | 	PyModule_AddObject( mod, "props", BPY_rna_props() ); | 
					
						
							| 
									
										
										
										
											2009-04-11 05:46:40 +00:00
										 |  |  | 	PyModule_AddObject( mod, "ops", BPY_operator_module() ); | 
					
						
							| 
									
										
										
										
											2009-06-23 13:34:45 +00:00
										 |  |  | 	PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experimental, consider this a test, especially PyCObject is not meant to be permanent
 | 
					
						
							| 
									
										
										
										
											2009-02-16 16:17:20 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | 	/* add the module so we can import it */ | 
					
						
							|  |  |  | 	PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod); | 
					
						
							|  |  |  | 	Py_DECREF(mod); | 
					
						
							| 
									
										
										
										
											2009-06-23 13:34:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* stand alone utility modules not related to blender directly */ | 
					
						
							|  |  |  | 	Geometry_Init("Geometry"); | 
					
						
							|  |  |  | 	Mathutils_Init("Mathutils"); | 
					
						
							|  |  |  | 	BGL_Init("BGL"); | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5
More cleanup!
- removed old UI font completely, including from uiBeginBlock
- emboss hints for uiBlock only have three types now;
  Regular, Pulldown, or "Nothing" (only icon/text)
- removed old font path from Userdef
- removed all old button theme hinting
- removed old "auto block" to merge buttons in groups
  (was only in use for radiosity buttons)
And went over all warnings. One hooray for make giving clean output :)
Well, we need uniform definitions for warnings, so people at least fix
them... here's the real bad bugs I found:
- in mesh code, a call to editmesh mixed *em and *me
- in armature, ED_util.h was not included, so no warnings for wrong call
  to ED_undo_push()
- The extern Py api .h was not included in the bpy_interface.c, showing
  a several calls using different args.
Further just added the missing includes, and removed unused vars.
											
										 
											2009-04-14 15:59:52 +00:00
										 |  |  | #if (PY_VERSION_HEX < 0x02050000)
 | 
					
						
							|  |  |  | PyObject *PyImport_ImportModuleLevel(char *name, void *a, void *b, void *c, int d) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return PyImport_ImportModule(name); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | void BPY_update_modules( void ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); | 
					
						
							|  |  |  | 	PyModule_AddObject( mod, "data", BPY_rna_module() ); | 
					
						
							|  |  |  | 	PyModule_AddObject( mod, "types", BPY_rna_types() ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  | * Description: This function creates a new Python dictionary object. | 
					
						
							|  |  |  | *****************************************************************************/ | 
					
						
							|  |  |  | static PyObject *CreateGlobalDictionary( bContext *C ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *mod; | 
					
						
							|  |  |  | 	PyObject *dict = PyDict_New(  ); | 
					
						
							|  |  |  | 	PyObject *item = PyUnicode_FromString( "__main__" ); | 
					
						
							|  |  |  | 	PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins(  ) ); | 
					
						
							|  |  |  | 	PyDict_SetItemString( dict, "__name__", item ); | 
					
						
							|  |  |  | 	Py_DECREF(item); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-02-16 16:17:20 +00:00
										 |  |  | 	// XXX - evil, need to access context
 | 
					
						
							| 
									
										
										
										
											2009-05-25 13:48:44 +00:00
										 |  |  | 	BPy_SetContext(C); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-03-16 15:54:43 +00:00
										 |  |  | 	// XXX - put somewhere more logical
 | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		PyMethodDef *ml; | 
					
						
							|  |  |  | 		static PyMethodDef bpy_prop_meths[] = { | 
					
						
							| 
									
										
										
										
											2009-03-21 16:03:26 +00:00
										 |  |  | 			{"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""}, | 
					
						
							|  |  |  | 			{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""}, | 
					
						
							|  |  |  | 			{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""}, | 
					
						
							| 
									
										
										
										
											2009-06-18 19:51:22 +00:00
										 |  |  | 			{"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""}, | 
					
						
							| 
									
										
										
										
											2009-03-16 15:54:43 +00:00
										 |  |  | 			{NULL, NULL, 0, NULL} | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2009-03-21 16:03:26 +00:00
										 |  |  | 		for(ml = bpy_prop_meths; ml->ml_name; ml++) { | 
					
						
							| 
									
										
										
										
											2009-03-16 15:54:43 +00:00
										 |  |  | 			PyDict_SetItemString( dict, ml->ml_name, PyCFunction_New(ml, NULL)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | 	/* add bpy to global namespace */ | 
					
						
							|  |  |  | 	mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); | 
					
						
							|  |  |  | 	PyDict_SetItemString( dict, "bpy", mod ); | 
					
						
							|  |  |  | 	Py_DECREF(mod); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 	return dict; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-02 12:11:20 +00:00
										 |  |  | /* Use this so we can include our own python bundle */ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | wchar_t* Py_GetPath(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	static wchar_t py_path[FILE_MAXDIR] = L""; | 
					
						
							|  |  |  | 	char *dirname= BLI_gethome_folder("python"); | 
					
						
							|  |  |  | 	if(dirname) { | 
					
						
							|  |  |  | 		i= mbstowcs(py_path, dirname, FILE_MAXDIR); | 
					
						
							|  |  |  | 		printf("py path %s, %d\n", dirname, i); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return py_path; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-03 04:38:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* must be called before Py_Initialize */ | 
					
						
							|  |  |  | void BPY_start_python_path(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char *py_path_bundle= BLI_gethome_folder("python"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(py_path_bundle==NULL) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* set the environment path */ | 
					
						
							|  |  |  | 	printf("found bundled python: %s\n", py_path_bundle); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if (defined(WIN32) || defined(WIN64))
 | 
					
						
							|  |  |  | #if defined(FREE_WINDOWS)
 | 
					
						
							| 
									
										
										
										
											2009-07-08 21:31:28 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		char py_path[FILE_MAXDIR + 11] = ""; | 
					
						
							|  |  |  | 		sprintf(py_path, "PYTHONPATH=%s", py_path_bundle); | 
					
						
							|  |  |  | 		putenv(py_path); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-07-03 04:38:55 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	_putenv_s("PYTHONPATH", py_path_bundle); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #ifdef __sgi
 | 
					
						
							| 
									
										
										
										
											2009-07-08 21:31:28 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		char py_path[FILE_MAXDIR + 11] = ""; | 
					
						
							|  |  |  | 		sprintf(py_path, "PYTHONPATH=%s", py_path_bundle); | 
					
						
							|  |  |  | 		putenv(py_path); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-07-03 04:38:55 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2009-07-03 11:46:46 +00:00
										 |  |  | 	setenv("PYTHONPATH", py_path_bundle, 1); | 
					
						
							| 
									
										
										
										
											2009-07-03 04:38:55 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												2.5
More cleanup!
- removed old UI font completely, including from uiBeginBlock
- emboss hints for uiBlock only have three types now;
  Regular, Pulldown, or "Nothing" (only icon/text)
- removed old font path from Userdef
- removed all old button theme hinting
- removed old "auto block" to merge buttons in groups
  (was only in use for radiosity buttons)
And went over all warnings. One hooray for make giving clean output :)
Well, we need uniform definitions for warnings, so people at least fix
them... here's the real bad bugs I found:
- in mesh code, a call to editmesh mixed *em and *me
- in armature, ED_util.h was not included, so no warnings for wrong call
  to ED_undo_push()
- The extern Py api .h was not included in the bpy_interface.c, showing
  a several calls using different args.
Further just added the missing includes, and removed unused vars.
											
										 
											2009-04-14 15:59:52 +00:00
										 |  |  | void BPY_start_python( int argc, char **argv ) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	PyThreadState *py_tstate = NULL; | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-07-03 04:38:55 +00:00
										 |  |  | 	BPY_start_python_path(); /* allow to use our own included python */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 	Py_Initialize(  ); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-07-08 09:23:49 +00:00
										 |  |  | #if (PY_VERSION_HEX < 0x03000000)
 | 
					
						
							|  |  |  | 	PySys_SetArgv( argc, argv); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	/* sigh, why do python guys not have a char** version anymore? :( */ | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		int i; | 
					
						
							|  |  |  | 		PyObject *py_argv= PyList_New(argc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (i=0; i<argc; i++) | 
					
						
							|  |  |  | 			PyList_SET_ITEM(py_argv, i, PyUnicode_FromString(argv[i])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		PySys_SetObject("argv", py_argv); | 
					
						
							|  |  |  | 		Py_DECREF(py_argv); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* Initialize thread support (also acquires lock) */ | 
					
						
							|  |  |  | 	PyEval_InitThreads(); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* bpy.* and lets us import it */ | 
					
						
							|  |  |  | 	bpy_init_modules();  | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-17 20:33:34 +00:00
										 |  |  | 	{ /* our own import and reload functions */ | 
					
						
							|  |  |  | 		PyObject *item; | 
					
						
							|  |  |  | 		//PyObject *m = PyImport_AddModule("__builtin__");
 | 
					
						
							|  |  |  | 		//PyObject *d = PyModule_GetDict(m);
 | 
					
						
							|  |  |  | 		PyObject *d = PyEval_GetBuiltins(  ); | 
					
						
							|  |  |  | 		PyDict_SetItemString(d, "reload",		item=PyCFunction_New(bpy_reload_meth, NULL));	Py_DECREF(item); | 
					
						
							|  |  |  | 		PyDict_SetItemString(d, "__import__",	item=PyCFunction_New(bpy_import_meth, NULL));	Py_DECREF(item); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	py_tstate = PyGILState_GetThisThreadState(); | 
					
						
							|  |  |  | 	PyEval_ReleaseThread(py_tstate); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-27 04:55:45 +00:00
										 |  |  | void BPY_end_python( void ) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	PyGILState_Ensure(); /* finalizing, no need to grab the state */ | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	// free other python data.
 | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  | 	//BPY_rna_free_types();
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	Py_Finalize(  ); | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | /* Can run a file or text block */ | 
					
						
							| 
									
										
										
										
											2009-06-14 12:53:47 +00:00
										 |  |  | int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struct ReportList *reports) | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	PyObject *py_dict, *py_result; | 
					
						
							|  |  |  | 	PyGILState_STATE gilstate; | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (fn==NULL && text==NULL) { | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2008-12-27 04:55:45 +00:00
										 |  |  | 	//BPY_start_python();
 | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-16 01:42:53 +00:00
										 |  |  | 	BPY_update_modules(); /* can give really bad results if this isnt here */ | 
					
						
							| 
									
										
										
										
											2009-06-17 20:33:34 +00:00
										 |  |  | 	bpy_import_main_set(CTX_data_main(C)); | 
					
						
							| 
									
										
										
										
											2009-04-16 01:42:53 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2008-12-21 08:53:36 +00:00
										 |  |  | 	py_dict = CreateGlobalDictionary(C); | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (text) { | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if( !text->compiled ) {	/* if it wasn't already compiled, do it now */ | 
					
						
							|  |  |  | 			char *buf = txt_to_buf( text ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			text->compiled = | 
					
						
							|  |  |  | 				Py_CompileString( buf, text->id.name+2, Py_file_input ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			MEM_freeN( buf ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if( PyErr_Occurred(  ) ) { | 
					
						
							| 
									
										
										
										
											2009-06-14 12:53:47 +00:00
										 |  |  | 				BPy_errors_to_report(reports); | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | 				BPY_free_compiled_text( text ); | 
					
						
							| 
									
										
										
										
											2009-03-23 14:39:37 +00:00
										 |  |  | 				PyGILState_Release(gilstate); | 
					
						
							| 
									
										
										
										
											2009-03-11 17:28:37 +00:00
										 |  |  | 				return 0; | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		py_result =  PyEval_EvalCode( text->compiled, py_dict, py_dict ); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		char pystring[512]; | 
					
						
							|  |  |  | 		/* TODO - look into a better way to run a file */ | 
					
						
							|  |  |  | 		sprintf(pystring, "exec(open(r'%s').read())", fn);	 | 
					
						
							|  |  |  | 		py_result = PyRun_String( pystring, Py_file_input, py_dict, py_dict );			 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | 	if (!py_result) { | 
					
						
							| 
									
										
										
										
											2009-06-14 12:53:47 +00:00
										 |  |  | 		BPy_errors_to_report(reports); | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 		Py_DECREF( py_result ); | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-04-23 09:15:42 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	Py_DECREF(py_dict); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 	PyGILState_Release(gilstate); | 
					
						
							| 
									
										
										
										
											2009-06-17 20:33:34 +00:00
										 |  |  | 	bpy_import_main_set(NULL); | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2008-12-27 04:55:45 +00:00
										 |  |  | 	//BPY_end_python();
 | 
					
						
							| 
									
										
										
										
											2009-03-04 13:26:33 +00:00
										 |  |  | 	return py_result ? 1:0; | 
					
						
							| 
									
										
										
										
											2008-11-29 13:36:08 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* TODO - move into bpy_space.c ? */ | 
					
						
							|  |  |  | /* GUI interface routines */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Copied from Draw.c */ | 
					
						
							|  |  |  | static void exit_pydraw( SpaceScript * sc, short err ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Script *script = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if( !sc || !sc->script ) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	script = sc->script; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if( err ) { | 
					
						
							| 
									
										
										
										
											2009-06-14 12:53:47 +00:00
										 |  |  | 		BPy_errors_to_report(NULL); // TODO, reports
 | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | 		script->flags = 0;	/* mark script struct for deletion */ | 
					
						
							|  |  |  | 		SCRIPT_SET_NULL(script); | 
					
						
							|  |  |  | 		script->scriptname[0] = '\0'; | 
					
						
							|  |  |  | 		script->scriptarg[0] = '\0'; | 
					
						
							|  |  |  | // XXX 2.5		error_pyscript();
 | 
					
						
							|  |  |  | // XXX 2.5		scrarea_queue_redraw( sc->area );
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0 // XXX 2.5
 | 
					
						
							|  |  |  | 	BPy_Set_DrawButtonsList(sc->but_refs); | 
					
						
							|  |  |  | 	BPy_Free_DrawButtonsList(); /*clear all temp button references*/ | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sc->but_refs = NULL; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	Py_XDECREF( ( PyObject * ) script->py_draw ); | 
					
						
							|  |  |  | 	Py_XDECREF( ( PyObject * ) script->py_event ); | 
					
						
							|  |  |  | 	Py_XDECREF( ( PyObject * ) script->py_button ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	script->py_draw = script->py_event = script->py_button = NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int bpy_run_script_init(bContext *C, SpaceScript * sc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (sc->script==NULL)  | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (sc->script->py_draw==NULL && sc->script->scriptname[0] != '\0') | 
					
						
							| 
									
										
										
										
											2009-06-14 12:53:47 +00:00
										 |  |  | 		BPY_run_python_script(C, sc->script->scriptname, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 	if (sc->script->py_draw==NULL) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-09 15:40:04 +00:00
										 |  |  | int BPY_run_script_space_draw(const struct bContext *C, SpaceScript * sc) | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-07-09 15:40:04 +00:00
										 |  |  | 	if (bpy_run_script_init( (bContext *)C, sc)) { | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | 		PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							|  |  |  | 		PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL ); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (result==NULL) | 
					
						
							|  |  |  | 			exit_pydraw(sc, 1); | 
					
						
							| 
									
										
										
										
											2009-03-02 20:18:29 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 		PyGILState_Release(gilstate); | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // XXX - not used yet, listeners dont get a context
 | 
					
						
							|  |  |  | int BPY_run_script_space_listener(bContext *C, SpaceScript * sc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (bpy_run_script_init(C, sc)) { | 
					
						
							|  |  |  | 		PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL ); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (result==NULL) | 
					
						
							|  |  |  | 			exit_pydraw(sc, 1); | 
					
						
							| 
									
										
										
										
											2009-03-02 20:18:29 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 		PyGILState_Release(gilstate); | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-01 12:43:07 +00:00
										 |  |  | void BPY_DECREF(void *pyob_ptr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Py_DECREF((PyObject *)pyob_ptr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | /* called from the the scripts window, assume context is ok */ | 
					
						
							|  |  |  | int BPY_run_python_script_space(const char *modulename, const char *func) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *py_dict, *py_result= NULL; | 
					
						
							|  |  |  | 	char pystring[512]; | 
					
						
							|  |  |  | 	PyGILState_STATE gilstate; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* for calling the module function */ | 
					
						
							|  |  |  | 	PyObject *py_func,  | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	gilstate = PyGILState_Ensure(); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	py_dict = CreateGlobalDictionary(C); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	PyObject *module = PyImport_ImportModule(scpt->script.filename); | 
					
						
							|  |  |  | 	if (module==NULL) { | 
					
						
							|  |  |  | 		PyErr_SetFormat(PyExc_SystemError, "could not import '%s'", scpt->script.filename); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		py_func = PyObject_GetAttrString(modulename, func); | 
					
						
							|  |  |  | 		if (py_func==NULL) { | 
					
						
							|  |  |  | 			PyErr_SetFormat(PyExc_SystemError, "module has no function '%s.%s'\n", scpt->script.filename, func); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2009-03-18 22:22:58 +00:00
										 |  |  | 			Py_DECREF(py_func); | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | 			if (!PyCallable_Check(py_func)) { | 
					
						
							|  |  |  | 				PyErr_SetFormat(PyExc_SystemError, "module item is not callable '%s.%s'\n", scpt->script.filename, func); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				py_result= PyObject_CallObject(py_func, NULL); // XXX will need args eventually
 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-04-23 09:15:42 +00:00
										 |  |  | 	if (!py_result) { | 
					
						
							| 
									
										
										
										
											2009-06-14 12:53:47 +00:00
										 |  |  | 		BPy_errors_to_report(NULL); // TODO - reports
 | 
					
						
							| 
									
										
										
										
											2009-04-23 09:15:42 +00:00
										 |  |  | 	} else | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | 		Py_DECREF( py_result ); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	Py_XDECREF(module); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-04-23 09:15:42 +00:00
										 |  |  | 	Py_DECREF(py_dict); | 
					
						
							| 
									
										
										
										
											2009-02-28 13:27:45 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	PyGILState_Release(gilstate); | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | // #define TIME_REGISTRATION
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef TIME_REGISTRATION
 | 
					
						
							|  |  |  | #include "PIL_time.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | /* XXX this is temporary, need a proper script registration system for 2.5 */ | 
					
						
							| 
									
										
										
										
											2009-04-23 06:58:02 +00:00
										 |  |  | void BPY_run_ui_scripts(bContext *C, int reload) | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | #ifdef TIME_REGISTRATION
 | 
					
						
							|  |  |  | 	double time = PIL_check_seconds_timer(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | 	DIR *dir;  | 
					
						
							|  |  |  | 	struct dirent *de; | 
					
						
							|  |  |  | 	char *file_extension; | 
					
						
							| 
									
										
										
										
											2009-06-18 19:51:22 +00:00
										 |  |  | 	char *dirname; | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | 	char path[FILE_MAX]; | 
					
						
							| 
									
										
										
										
											2009-06-18 19:51:22 +00:00
										 |  |  | 	char *dirs[] = {"io", "ui", NULL}; | 
					
						
							| 
									
										
										
										
											2009-07-09 07:35:35 +00:00
										 |  |  | 	int a; | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	PyGILState_STATE gilstate; | 
					
						
							|  |  |  | 	PyObject *mod; | 
					
						
							| 
									
										
										
										
											2009-07-11 13:57:56 +00:00
										 |  |  | 	PyObject *sys_path; | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | 	gilstate = PyGILState_Ensure(); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-05-25 13:48:44 +00:00
										 |  |  | 	// XXX - evil, need to access context
 | 
					
						
							|  |  |  | 	BPy_SetContext(C); | 
					
						
							| 
									
										
										
										
											2009-06-17 20:33:34 +00:00
										 |  |  | 	bpy_import_main_set(CTX_data_main(C)); | 
					
						
							| 
									
										
										
										
											2009-06-18 19:51:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-11 13:57:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	sys_path= PySys_GetObject("path"); /* borrow */ | 
					
						
							|  |  |  | 	PyList_Insert(sys_path, 0, Py_None); /* place holder, resizes the list */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-18 19:51:22 +00:00
										 |  |  | 	for(a=0; dirs[a]; a++) { | 
					
						
							|  |  |  | 		dirname= BLI_gethome_folder(dirs[a]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(!dirname) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		dir = opendir(dirname); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(!dir) | 
					
						
							|  |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2009-07-11 13:57:56 +00:00
										 |  |  | 		/* set the first dir in the sys.path for fast importing of modules */ | 
					
						
							|  |  |  | 		PyList_SetItem(sys_path, 0, PyUnicode_FromString(dirname)); /* steals the ref */ | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2009-06-18 19:51:22 +00:00
										 |  |  | 		while((de = readdir(dir)) != NULL) { | 
					
						
							|  |  |  | 			/* We could stat the file but easier just to let python
 | 
					
						
							|  |  |  | 			 * import it and complain if theres a problem */ | 
					
						
							| 
									
										
										
										
											2009-07-08 21:31:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-18 19:51:22 +00:00
										 |  |  | 			file_extension = strstr(de->d_name, ".py"); | 
					
						
							| 
									
										
										
										
											2009-04-23 06:58:02 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2009-07-09 07:35:35 +00:00
										 |  |  | 			if(file_extension && file_extension[3] == '\0') { | 
					
						
							|  |  |  | 				BLI_strncpy(path, de->d_name, (file_extension - de->d_name) + 1); /* cut off the .py on copy */ | 
					
						
							| 
									
										
										
										
											2009-06-18 19:51:22 +00:00
										 |  |  | 				mod= PyImport_ImportModuleLevel(path, NULL, NULL, NULL, 0); | 
					
						
							|  |  |  | 				if (mod) { | 
					
						
							|  |  |  | 					if (reload) { | 
					
						
							|  |  |  | 						PyObject *mod_orig= mod; | 
					
						
							|  |  |  | 						mod= PyImport_ReloadModule(mod); | 
					
						
							|  |  |  | 						Py_DECREF(mod_orig); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				if(mod) { | 
					
						
							|  |  |  | 					Py_DECREF(mod); /* could be NULL from reloading */ | 
					
						
							|  |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2009-07-09 07:35:35 +00:00
										 |  |  | 					BPy_errors_to_report(NULL); | 
					
						
							| 
									
										
										
										
											2009-06-18 19:51:22 +00:00
										 |  |  | 					fprintf(stderr, "unable to import \"%s\"  %s/%s\n", path, dirname, de->d_name); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-18 19:51:22 +00:00
										 |  |  | 		closedir(dir); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-07-11 13:57:56 +00:00
										 |  |  | 	PyList_SetSlice(sys_path, 0, 1, NULL); /* remove the first item */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-17 20:33:34 +00:00
										 |  |  | 	bpy_import_main_set(NULL); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-04-11 16:17:39 +00:00
										 |  |  | 	PyGILState_Release(gilstate); | 
					
						
							|  |  |  | #ifdef TIME_REGISTRATION
 | 
					
						
							|  |  |  | 	printf("script time %f\n", (PIL_check_seconds_timer()-time)); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-04-11 02:18:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-20 09:17:43 +00:00
										 |  |  | /* ****************************************** */ | 
					
						
							|  |  |  | /* Drivers - PyExpression Evaluation */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* for pydrivers (drivers using one-line Python expressions to express relationships between targets) */ | 
					
						
							|  |  |  | PyObject *bpy_pydriver_Dict = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* For faster execution we keep a special dictionary for pydrivers, with
 | 
					
						
							|  |  |  |  * the needed modules and aliases.  | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int bpy_pydriver_create_dict(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *d, *mod; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* validate namespace for driver evaluation */ | 
					
						
							|  |  |  | 	if (bpy_pydriver_Dict) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	d = PyDict_New(); | 
					
						
							|  |  |  | 	if (d == NULL)  | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		bpy_pydriver_Dict = d; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* import some modules: builtins, bpy, math, (Blender.noise )*/ | 
					
						
							|  |  |  | 	PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mod = PyImport_ImportModule("math"); | 
					
						
							|  |  |  | 	if (mod) { | 
					
						
							|  |  |  | 		PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */ | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/* Only keep for backwards compat! - just import all math into root, they are standard */ | 
					
						
							|  |  |  | 		PyDict_SetItemString(d, "math", mod); | 
					
						
							|  |  |  | 		PyDict_SetItemString(d, "m", mod); | 
					
						
							|  |  |  | 		Py_DECREF(mod); | 
					
						
							|  |  |  | 	}  | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* add bpy to global namespace */ | 
					
						
							|  |  |  | 	mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); | 
					
						
							|  |  |  | 	if (mod) { | 
					
						
							|  |  |  | 		PyDict_SetItemString(bpy_pydriver_Dict, "bpy", mod); | 
					
						
							|  |  |  | 		Py_DECREF(mod); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | #if 0 // non existant yet
 | 
					
						
							|  |  |  | 	mod = PyImport_ImportModule("Blender.Noise"); | 
					
						
							|  |  |  | 	if (mod) { | 
					
						
							|  |  |  | 		PyDict_SetItemString(d, "noise", mod); | 
					
						
							|  |  |  | 		PyDict_SetItemString(d, "n", mod); | 
					
						
							|  |  |  | 		Py_DECREF(mod); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		PyErr_Clear(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* If there's a Blender text called pydrivers.py, import it.
 | 
					
						
							|  |  |  | 	 * Users can add their own functions to this module.  | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (G.f & G_DOSCRIPTLINKS) { | 
					
						
							|  |  |  | 		mod = importText("pydrivers"); /* can also use PyImport_Import() */ | 
					
						
							|  |  |  | 		if (mod) { | 
					
						
							|  |  |  | 			PyDict_SetItemString(d, "pydrivers", mod); | 
					
						
							|  |  |  | 			PyDict_SetItemString(d, "p", mod); | 
					
						
							|  |  |  | 			Py_DECREF(mod); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			PyErr_Clear(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif // non existant yet
 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Update function, it gets rid of pydrivers global dictionary, forcing
 | 
					
						
							|  |  |  |  * BPY_pydriver_eval to recreate it. This function is used to force | 
					
						
							|  |  |  |  * reloading the Blender text module "pydrivers.py", if available, so | 
					
						
							|  |  |  |  * updates in it reach pydriver evaluation.  | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void BPY_pydriver_update(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */ | 
					
						
							|  |  |  | 		PyDict_Clear(bpy_pydriver_Dict); | 
					
						
							|  |  |  | 		Py_DECREF(bpy_pydriver_Dict); | 
					
						
							|  |  |  | 		bpy_pydriver_Dict = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyGILState_Release(gilstate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* error return function for BPY_eval_pydriver */ | 
					
						
							|  |  |  | static float pydriver_error(ChannelDriver *driver)  | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */ | 
					
						
							|  |  |  | 		PyDict_Clear(bpy_pydriver_Dict); | 
					
						
							|  |  |  | 		Py_DECREF(bpy_pydriver_Dict); | 
					
						
							|  |  |  | 		bpy_pydriver_Dict = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	driver->flag |= DRIVER_FLAG_INVALID; /* py expression failed */ | 
					
						
							|  |  |  | 	fprintf(stderr, "\nError in Driver: The following Python expression failed:\n\t'%s'\n\n", driver->expression); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-06-14 12:53:47 +00:00
										 |  |  | 	BPy_errors_to_report(NULL); // TODO - reports
 | 
					
						
							| 
									
										
										
										
											2009-04-20 09:17:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0.0f; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This evals py driver expressions, 'expr' is a Python expression that
 | 
					
						
							|  |  |  |  * should evaluate to a float number, which is returned.  | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | float BPY_pydriver_eval (ChannelDriver *driver) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *driver_vars=NULL; | 
					
						
							|  |  |  | 	PyObject *retval; | 
					
						
							|  |  |  | 	PyGILState_STATE gilstate; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	DriverTarget *dtar; | 
					
						
							|  |  |  | 	float result = 0.0f; /* default return */ | 
					
						
							|  |  |  | 	char *expr = NULL; | 
					
						
							|  |  |  | 	short targets_ok= 1; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* sanity checks - should driver be executed? */ | 
					
						
							|  |  |  | 	if ((driver == NULL) /*|| (G.f & G_DOSCRIPTLINKS)==0*/)  | 
					
						
							|  |  |  | 		return result; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* get the py expression to be evaluated */ | 
					
						
							|  |  |  | 	expr = driver->expression;  | 
					
						
							|  |  |  | 	if ((expr == NULL) || (expr[0]=='\0'))  | 
					
						
							|  |  |  | 		return result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	gilstate = PyGILState_Ensure(); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* init global dictionary for py-driver evaluation settings */ | 
					
						
							|  |  |  | 	if (!bpy_pydriver_Dict) { | 
					
						
							|  |  |  | 		if (bpy_pydriver_create_dict() != 0) { | 
					
						
							|  |  |  | 			fprintf(stderr, "Pydriver error: couldn't create Python dictionary"); | 
					
						
							|  |  |  | 			PyGILState_Release(gilstate); | 
					
						
							|  |  |  | 			return result; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-04-22 10:07:12 +00:00
										 |  |  | 	/* add target values to a dict that will be used as '__locals__' dict */ | 
					
						
							| 
									
										
										
										
											2009-04-20 09:17:43 +00:00
										 |  |  | 	driver_vars = PyDict_New(); // XXX do we need to decref this?
 | 
					
						
							|  |  |  | 	for (dtar= driver->targets.first; dtar; dtar= dtar->next) { | 
					
						
							|  |  |  | 		PyObject *driver_arg = NULL; | 
					
						
							|  |  |  | 		float tval = 0.0f; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/* try to get variable value */ | 
					
						
							|  |  |  | 		tval= driver_get_target_value(driver, dtar); | 
					
						
							|  |  |  | 		driver_arg= PyFloat_FromDouble((double)tval); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/* try to add to dictionary */ | 
					
						
							|  |  |  | 		if (PyDict_SetItemString(driver_vars, dtar->name, driver_arg)) { | 
					
						
							| 
									
										
										
										
											2009-04-22 10:07:12 +00:00
										 |  |  | 			/* this target failed - bad name */ | 
					
						
							| 
									
										
										
										
											2009-04-20 09:17:43 +00:00
										 |  |  | 			if (targets_ok) { | 
					
						
							|  |  |  | 				/* first one - print some extra info for easier identification */ | 
					
						
							|  |  |  | 				fprintf(stderr, "\nBPY_pydriver_eval() - Error while evaluating PyDriver:\n"); | 
					
						
							|  |  |  | 				targets_ok= 0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			fprintf(stderr, "\tBPY_pydriver_eval() - couldn't add variable '%s' to namespace \n", dtar->name); | 
					
						
							| 
									
										
										
										
											2009-06-14 12:53:47 +00:00
										 |  |  | 			BPy_errors_to_report(NULL); // TODO - reports
 | 
					
						
							| 
									
										
										
										
											2009-04-20 09:17:43 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* execute expression to get a value */ | 
					
						
							|  |  |  | 	retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* decref the driver vars first...  */ | 
					
						
							|  |  |  | 	Py_DECREF(driver_vars); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* process the result */ | 
					
						
							|  |  |  | 	if (retval == NULL) { | 
					
						
							|  |  |  | 		result = pydriver_error(driver); | 
					
						
							|  |  |  | 		PyGILState_Release(gilstate); | 
					
						
							|  |  |  | 		return result; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	result = (float)PyFloat_AsDouble(retval); | 
					
						
							|  |  |  | 	Py_DECREF(retval); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if ((result == -1) && PyErr_Occurred()) { | 
					
						
							|  |  |  | 		result = pydriver_error(driver); | 
					
						
							|  |  |  | 		PyGILState_Release(gilstate); | 
					
						
							|  |  |  | 		return result; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* all fine, make sure the "invalid expression" flag is cleared */ | 
					
						
							|  |  |  | 	driver->flag &= ~DRIVER_FLAG_INVALID; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyGILState_Release(gilstate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } |