* Implemented BPY_end_python function. * Implemented error handling. This results in rerunning a script after an error has occurred. No need to restart blender anymore. * Camera module supports dir() * variable assignment now calls the Python equivalent function - this has type checking and should be safer now. * Implemented the Lamp module. Used the Camera module as a template. * Implemented the Image module. * Added EXPP_ClampFloat and EXPP_intError functions to gen_utils.[ch] * Implemented 'constant' object.
		
			
				
	
	
		
			382 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			382 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* 
 | |
|  *
 | |
|  * ***** 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.
 | |
|  *
 | |
|  * Contributor(s): Michel Selten, Willian P. Germano
 | |
|  *
 | |
|  * ***** END GPL/BL DUAL LICENSE BLOCK *****
 | |
| */
 | |
| #ifdef HAVE_CONFIG_H
 | |
| #include <config.h>
 | |
| #endif
 | |
| #include <Python.h>
 | |
| #include <stdio.h>
 | |
| 
 | |
| #include <MEM_guardedalloc.h>
 | |
| 
 | |
| #include <BKE_global.h>
 | |
| #include <BKE_main.h>
 | |
| #include <BKE_text.h>
 | |
| #include <DNA_camera_types.h>
 | |
| #include <DNA_ID.h>
 | |
| #include <DNA_lamp_types.h>
 | |
| #include <DNA_material_types.h>
 | |
| #include <DNA_object_types.h>
 | |
| #include <DNA_scene_types.h>
 | |
| #include <DNA_scriptlink_types.h>
 | |
| #include <DNA_space_types.h>
 | |
| #include <DNA_text_types.h>
 | |
| #include <DNA_world_types.h>
 | |
| 
 | |
| #include "BPY_extern.h"
 | |
| 
 | |
| #include "api2_2x/interface.h"
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Structure definitions                                                     */
 | |
| /*****************************************************************************/
 | |
| #define FILENAME_LENGTH 24
 | |
| typedef struct _ScriptError {
 | |
| 	char filename[FILENAME_LENGTH];
 | |
| 	int lineno;
 | |
| } ScriptError;
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Global variables                                                          */
 | |
| /*****************************************************************************/
 | |
| ScriptError g_script_error;
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Function prototypes                                                       */
 | |
| /*****************************************************************************/
 | |
| PyObject * RunPython(Text *text, PyObject *globaldict);
 | |
| char *     GetName(Text *text);
 | |
| PyObject * CreateGlobalDictionary (void);
 | |
| void       ReleaseGlobalDictionary (PyObject * dict);
 | |
| void       DoAllScriptsFromList (ListBase * list, short event);
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description: This function will initialise Python and all the implemented */
 | |
| /*              api variations.                                              */
 | |
| /* Notes:       Currently only the api for 2.2x will be initialised.         */
 | |
| /*****************************************************************************/
 | |
| void BPY_start_python(void)
 | |
| {
 | |
| 	printf ("In BPY_start_python\n");
 | |
| /* TODO: Shouldn't "blender" be replaced by PACKAGE ?? (config.h) */
 | |
| 	Py_SetProgramName("blender");
 | |
| 
 | |
| 	Py_Initialize ();
 | |
| 
 | |
| 	initBlenderApi2_2x ();
 | |
| 
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description: This function will terminate the Python interpreter          */
 | |
| /*****************************************************************************/
 | |
| void BPY_end_python(void)
 | |
| {
 | |
| 	printf ("In BPY_end_python\n");
 | |
| 	Py_Finalize();
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description: This function will return the linenumber on which an error   */
 | |
| /*              has occurred in the Python script.                           */
 | |
| /*****************************************************************************/
 | |
| int BPY_Err_getLinenumber(void)
 | |
| {
 | |
| 	printf ("In BPY_Err_getLinenumber\n");
 | |
| 	return g_script_error.lineno;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description: This function will return the filename of the python script. */
 | |
| /*****************************************************************************/
 | |
| const char *BPY_Err_getFilename(void)
 | |
| {
 | |
| 	printf ("In BPY_Err_getFilename\n");
 | |
| 	return g_script_error.filename;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description: This function executes the script passed by st.              */
 | |
| /* Notes:       Currently, the script is compiled each time it is executed,  */
 | |
| /*              This should be optimized to store the compiled bytecode as   */
 | |
| /*              has been done by the previous implementation.                */
 | |
| /*****************************************************************************/
 | |
| struct _object *BPY_txt_do_python(struct SpaceText* st)
 | |
| {
 | |
| 	PyObject *	dict;
 | |
| 	PyObject *	ret;
 | |
| 	printf ("In BPY_txt_do_python\n");
 | |
| 
 | |
| 	if (!st->text)
 | |
| 	{
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| 	dict = PyModule_GetDict(PyImport_AddModule("__main__"));
 | |
| 	/* dict = newGlobalDictionary(); */
 | |
| 	ret = RunPython (st->text, dict);
 | |
| 
 | |
| 	/* If errors have occurred, set the error filename to the name of the
 | |
| 	   script.
 | |
| 	*/
 | |
| 	if (!ret)
 | |
| 	{
 | |
| 		sprintf(g_script_error.filename, "%s", st->text->id.name+2);
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| 	return dict;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description:                                                              */
 | |
| /* Notes:       Not implemented yet                                          */
 | |
| /*****************************************************************************/
 | |
| void BPY_free_compiled_text(struct Text* text)
 | |
| {
 | |
| 	printf ("In BPY_free_compiled_text\n");
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description:                                                              */
 | |
| /* Notes:       Not implemented yet                                          */
 | |
| /*****************************************************************************/
 | |
| void BPY_clear_bad_scriptlinks(struct Text *byebye)
 | |
| {
 | |
| 	printf ("In BPY_clear_bad_scriptlinks\n");
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* 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).                                           */
 | |
| /*****************************************************************************/
 | |
| void BPY_do_all_scripts(short event)
 | |
| {
 | |
| 	printf ("In BPY_do_all_scripts(event=%d)\n",event);
 | |
| 
 | |
| 	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);
 | |
| 
 | |
| 	BPY_do_pyscript (&(G.scene->id), event);
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* 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.                                                       */
 | |
| /*****************************************************************************/
 | |
| void BPY_do_pyscript(struct ID *id, short event)
 | |
| {
 | |
| 	ScriptLink     * scriptlink;
 | |
| 	int              index;
 | |
| 	PyObject       * dict;
 | |
| 
 | |
| 	printf ("In BPY_do_pyscript(id=%s, event=%d)\n",id->name, event);
 | |
| 
 | |
| 	scriptlink = setScriptLinks (id, event);
 | |
| 
 | |
| 	if (scriptlink == NULL)
 | |
| 	{
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	for (index=0 ; index<scriptlink->totscript ; index++)
 | |
| 	{
 | |
| 		printf ("scriptnr: %d\tevent=%d, flag[index]=%d\n", index,
 | |
| 				event, scriptlink->flag[index]);
 | |
| 		if ((scriptlink->flag[index] == event) &&
 | |
| 		    (scriptlink->scripts[index]!=NULL))
 | |
| 		{
 | |
| 			dict = CreateGlobalDictionary();
 | |
| 			RunPython ((Text*) scriptlink->scripts[index], dict);
 | |
| 			ReleaseGlobalDictionary (dict);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description:                                                              */
 | |
| /* Notes:       Not implemented yet                                          */
 | |
| /*****************************************************************************/
 | |
| void BPY_free_scriptlink(struct ScriptLink *slink)
 | |
| {
 | |
| 	printf ("In BPY_free_scriptlink\n");
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description:                                                              */
 | |
| /* Notes:       Not implemented yet                                          */
 | |
| /*****************************************************************************/
 | |
| void BPY_copy_scriptlink(struct ScriptLink *scriptlink)
 | |
| {
 | |
| 	printf ("In BPY_copy_scriptlink\n");
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description:                                                              */
 | |
| /* Notes:       Not implemented yet                                          */
 | |
| /*****************************************************************************/
 | |
| int BPY_call_importloader(char *name)
 | |
| {
 | |
| 	printf ("In BPY_call_importloader(name=%s)\n",name);
 | |
| 	return (0);
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description:                                                              */
 | |
| /* Notes:       Not implemented yet                                          */
 | |
| /*****************************************************************************/
 | |
| int BPY_spacetext_is_pywin(struct SpaceText *st)
 | |
| {
 | |
| 	/* No printf is done here because it is called with every mouse move */
 | |
| 	return (0);
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description:                                                              */
 | |
| /* Notes:       Not implemented yet                                          */
 | |
| /*****************************************************************************/
 | |
| void BPY_spacetext_do_pywin_draw(struct SpaceText *st)
 | |
| {
 | |
| 	printf ("In BPY_spacetext_do_pywin_draw\n");
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description:                                                              */
 | |
| /* Notes:       Not implemented yet                                          */
 | |
| /*****************************************************************************/
 | |
| void BPY_spacetext_do_pywin_event(struct SpaceText *st,
 | |
|                                   unsigned short event,
 | |
|                                   short val)
 | |
| {
 | |
| 	printf ("In BPY_spacetext_do_pywin_event(st=?, event=%d, val=%d)\n",
 | |
| 	        event, val);
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Private functions                                                         */
 | |
| /*****************************************************************************/
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description: This function executes the python script passed by text.     */
 | |
| /*              The Python dictionary containing global variables needs to   */
 | |
| /*              be passed in globaldict.                                     */
 | |
| /*****************************************************************************/
 | |
| PyObject * RunPython(Text *text, PyObject *globaldict)
 | |
| {
 | |
| 	PyObject * ret;
 | |
| 	char     * buf;
 | |
| 
 | |
| 	printf("Run Python script \"%s\" ...\n", GetName(text));
 | |
| 	buf = txt_to_buf(text);
 | |
| 	ret = PyRun_String (buf, Py_file_input, globaldict, globaldict);
 | |
| 
 | |
| 	if (!ret)
 | |
| 	{
 | |
| 		/* an exception was raised, handle it here */
 | |
| 		PyErr_Print(); /* this function also clears the error
 | |
| 				  indicator */
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		PyErr_Clear(); /* seems necessary, at least now */
 | |
| 	}
 | |
| 
 | |
| 	MEM_freeN (buf);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description: This function returns the value of the name field of the     */
 | |
| /*              given Text struct.                                           */
 | |
| /*****************************************************************************/
 | |
| char * GetName(Text *text)
 | |
| {
 | |
| 	return (text->id.name+2);
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description: This function creates a new Python dictionary object.        */
 | |
| /*****************************************************************************/
 | |
| PyObject * CreateGlobalDictionary (void)
 | |
| {
 | |
| 	PyObject *dict = PyDict_New();
 | |
| 	PyDict_SetItemString (dict, "__builtins__", PyEval_GetBuiltins());
 | |
| 	PyDict_SetItemString (dict, "__name__", PyString_FromString("__main__"));
 | |
| 
 | |
| 	return (dict);
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Description: This function deletes a given Python dictionary object.      */
 | |
| /*****************************************************************************/
 | |
| void ReleaseGlobalDictionary (PyObject * dict)
 | |
| {
 | |
| 	PyDict_Clear (dict);
 | |
| 	Py_DECREF (dict);		/* Release dictionary. */
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* 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.                     */
 | |
| /*****************************************************************************/
 | |
| void DoAllScriptsFromList (ListBase * list, short event)
 | |
| {
 | |
| 	ID       * id;
 | |
| 
 | |
| 	id = list->first;
 | |
| 
 | |
| 	while (id != NULL)
 | |
| 	{
 | |
| 		BPY_do_pyscript (id, event);
 | |
| 		id = id->next;
 | |
| 	}
 | |
| }
 | |
| 
 |