From b9f6d66328b8b96d4f1fe29f761a99fbe531c4de Mon Sep 17 00:00:00 2001 From: Willian Padovani Germano Date: Tue, 13 May 2003 01:54:28 +0000 Subject: * Added 3 missing functions, 2 of them called by blender/src/drawtext.c: Callbacks registered with Draw.Register in Python are called now. That should fix submodule Blender.Draw. * Added a few other missing functions to BPY_interface.c * Finished implementing Get() function for Camera, Lamp, Image and Text: Both the .Get(name) and .Get() cases are handled now. * Added function Blender.ReleaseGlobalDict(): This function should give script writers control over whether the global Python Interpreter Dict should be cleared after the script is run (default is to clear). This is a test. --- source/blender/python/BPY_extern.h | 10 +- source/blender/python/BPY_interface.c | 447 ++++++++++++++++++++++---------- source/blender/python/api2_2x/BGL.c | 17 +- source/blender/python/api2_2x/BGL.h | 5 +- source/blender/python/api2_2x/Blender.c | 27 +- source/blender/python/api2_2x/Blender.h | 16 +- source/blender/python/api2_2x/Camera.c | 93 ++++--- source/blender/python/api2_2x/Camera.h | 1 + source/blender/python/api2_2x/Draw.c | 140 ++++++---- source/blender/python/api2_2x/Draw.h | 12 +- source/blender/python/api2_2x/Image.c | 106 +++++--- source/blender/python/api2_2x/Image.h | 1 + source/blender/python/api2_2x/Lamp.c | 162 +++++++----- source/blender/python/api2_2x/Lamp.h | 3 + source/blender/python/api2_2x/Object.c | 2 +- source/blender/python/api2_2x/Text.c | 98 ++++--- source/blender/python/api2_2x/Text.h | 1 + 17 files changed, 752 insertions(+), 389 deletions(-) (limited to 'source/blender/python') diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index b2747ef0ce6..2af7edc835e 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -25,11 +25,15 @@ * * The Original Code is: source/blender/bpyton/include/BPY_extern.h * - * Contributor(s): Michel Selten + * Contributor(s): Michel Selten, Willian P. Germano * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ +/* Global to control whether the global dictionary should be preserved or not + * each time a script is executed by the Python Interpreter: */ +extern short EXPP_releaseGlobalDict; /* defaults to TRUE */ + struct Text; /* defined in DNA_text_types.h */ struct ID; /* defined in DNA_ID.h */ struct ScriptLink; /* defined in DNA_scriptlink_types.h */ @@ -57,7 +61,9 @@ void BPY_copy_scriptlink(struct ScriptLink *scriptlink); /* format importer hook */ int BPY_call_importloader(char *name); +/* XXX The 3 functions below are implemented in Draw.c */ +/* int BPY_spacetext_is_pywin(struct SpaceText *st); void BPY_spacetext_do_pywin_draw(struct SpaceText *st); void BPY_spacetext_do_pywin_event(struct SpaceText *st, unsigned short event, short val); - +*/ diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index 76fc47dfe1a..6cec2ed5ee5 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -31,7 +31,11 @@ #ifdef HAVE_CONFIG_H #include #endif + #include +#include "compile.h" /* for the PyCodeObject */ +#include "eval.h" /* for PyEval_EvalCode */ + #include #include @@ -51,31 +55,32 @@ #include #include "BPY_extern.h" - #include "api2_2x/EXPP_interface.h" + /*****************************************************************************/ /* Structure definitions */ /*****************************************************************************/ #define FILENAME_LENGTH 24 typedef struct _ScriptError { - char filename[FILENAME_LENGTH]; - int lineno; + char filename[FILENAME_LENGTH]; + int lineno; } ScriptError; /*****************************************************************************/ /* Global variables */ /*****************************************************************************/ ScriptError g_script_error; +short EXPP_releaseGlobalDict = 1; /*****************************************************************************/ /* 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); +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 */ @@ -84,15 +89,15 @@ void DoAllScriptsFromList (ListBase * list, short event); /*****************************************************************************/ void BPY_start_python(void) { - printf ("In BPY_start_python\n"); + printf ("In BPY_start_python\n"); /* TODO: Shouldn't "blender" be replaced by PACKAGE ?? (config.h) */ - Py_SetProgramName("blender"); + Py_SetProgramName("blender"); - Py_Initialize (); + Py_Initialize (); - initBlenderApi2_2x (); + initBlenderApi2_2x (); - return; + return; /* We could take away all these return; ... */ } /*****************************************************************************/ @@ -100,9 +105,9 @@ void BPY_start_python(void) /*****************************************************************************/ void BPY_end_python(void) { - printf ("In BPY_end_python\n"); - Py_Finalize(); - return; + printf ("In BPY_end_python\n"); + Py_Finalize(); + return; } /*****************************************************************************/ @@ -111,8 +116,8 @@ void BPY_end_python(void) /*****************************************************************************/ int BPY_Err_getLinenumber(void) { - printf ("In BPY_Err_getLinenumber\n"); - return g_script_error.lineno; + printf ("In BPY_Err_getLinenumber\n"); + return g_script_error.lineno; } /*****************************************************************************/ @@ -120,60 +125,190 @@ int BPY_Err_getLinenumber(void) /*****************************************************************************/ const char *BPY_Err_getFilename(void) { - printf ("In BPY_Err_getFilename\n"); - return g_script_error.filename; + printf ("In BPY_Err_getFilename\n"); + 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); + return; + } else { + PyErr_NormalizeException(&exception, &err, &tb); + PyErr_Restore(exception, err, tb); // takes away reference! + PyErr_Print(); + tb = PySys_GetObject("last_traceback"); + Py_INCREF(tb); + +/* 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."' */ + + while (1) { + v = PyObject_GetAttrString(tb, "tb_next"); + + if (v == Py_None || + strcmp(PyString_AsString(traceback_getFilename(v)), GetName(text))) + break; + Py_DECREF(tb); + tb = v; + } + + 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); + } + + return; } /*****************************************************************************/ /* 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. */ +/* Notes: It is called by blender/src/drawtext.c when a Blender user */ +/* presses ALT+PKEY in the script's text window. */ /*****************************************************************************/ 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; + PyObject *dict, *ret; + + printf ("In BPY_txt_do_python\n"); + + 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 + * call Blender.releaseGlobalDict(bool), with bool != 0, in the script */ + + if (EXPP_releaseGlobalDict) { + printf("Using a clean Global Dictionary.\n"); + st->flags |= ST_CLEAR_NAMESPACE; + dict = CreateGlobalDictionary(); + } + else + dict = PyModule_GetDict(PyImport_AddModule("__main__")); + + ret = RunPython (st->text, dict); /* Run the script */ + + if (!ret) { /* Failed execution of the script */ + + if (EXPP_releaseGlobalDict) ReleaseGlobalDictionary(dict); + + BPY_Err_Handle(st->text); + BPY_end_python(); + BPY_start_python(); + + return NULL; + } + + else Py_DECREF (ret); + +/* From the old BPY_main.c: + * 'The following lines clear the global name space of the python + * interpreter. This is desired to release objects after execution + * of a script (remember that each wrapper object increments the refcount + * of the Blender Object. + * Exception: 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.' + * See api2_2x/Draw.c: Method_Register() */ + + if (EXPP_releaseGlobalDict) { + if (st->flags & ST_CLEAR_NAMESPACE) { + ReleaseGlobalDictionary(dict); + /*garbage_collect(&G.main); Unfinished in the previous implementation */ + } + } + +/* 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; } /*****************************************************************************/ /* Description: */ -/* Notes: Not implemented yet */ +/* Notes: */ /*****************************************************************************/ void BPY_free_compiled_text(struct Text* text) { - printf ("In BPY_free_compiled_text\n"); + printf ("In BPY_free_compiled_text\n"); + if (!text->compiled) return; + Py_DECREF((PyObject*) text->compiled); + text->compiled = NULL; + return; } +/*****************************************************************************/ +/* ScriptLinks */ +/*****************************************************************************/ + /*****************************************************************************/ /* Description: */ /* Notes: Not implemented yet */ /*****************************************************************************/ void BPY_clear_bad_scriptlinks(struct Text *byebye) { - printf ("In BPY_clear_bad_scriptlinks\n"); + printf ("In BPY_clear_bad_scriptlinks\n"); +/* + 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); +*/ return; } @@ -185,15 +320,16 @@ void BPY_clear_bad_scriptlinks(struct Text *byebye) /*****************************************************************************/ void BPY_do_all_scripts(short event) { - printf ("In BPY_do_all_scripts(event=%d)\n",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); - 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); - BPY_do_pyscript (&(G.scene->id), event); return; } @@ -206,52 +342,71 @@ void BPY_do_all_scripts(short event) /*****************************************************************************/ 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 ; indextotscript ; 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); - } - } + 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 */ +/* Notes: */ /*****************************************************************************/ void BPY_free_scriptlink(struct ScriptLink *slink) { - printf ("In BPY_free_scriptlink\n"); + printf ("In BPY_free_scriptlink\n"); + + if (slink->totscript) { + if(slink->flag) MEM_freeN(slink->flag); + if(slink->scripts) MEM_freeN(slink->scripts); + } + return; } /*****************************************************************************/ /* Description: */ -/* Notes: Not implemented yet */ +/* Notes: */ /*****************************************************************************/ void BPY_copy_scriptlink(struct ScriptLink *scriptlink) { - printf ("In BPY_copy_scriptlink\n"); + void *tmp; + + printf ("In BPY_copy_scriptlink\n"); + + 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); + } + return; } @@ -260,43 +415,45 @@ void BPY_copy_scriptlink(struct ScriptLink *scriptlink) /* Notes: Not implemented yet */ /*****************************************************************************/ int BPY_call_importloader(char *name) -{ - printf ("In BPY_call_importloader(name=%s)\n",name); - return (0); +{ /* XXX Should this function go away from Blender? */ + printf ("In BPY_call_importloader(name=%s)\n",name); + return (0); } +/* XXX THE 3 FUNCTIONS BELOW ARE IMPLEMENTED IN DRAW.C */ + /*****************************************************************************/ /* 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); -} +//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; -} +//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; -} +//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 */ @@ -309,26 +466,30 @@ void BPY_spacetext_do_pywin_event(struct SpaceText *st, /*****************************************************************************/ 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; + char *buf = NULL; + + printf("Run Python script \"%s\" ...\n", GetName(text)); + +/* 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 */ + buf = txt_to_buf(text); + + text->compiled = Py_CompileString(buf, GetName(text), Py_file_input); + + MEM_freeN(buf); + + if (PyErr_Occurred()) { + BPY_free_compiled_text(text); + PyErr_SetString (PyExc_RuntimeError, + "couldn't compile script to Python bytecode"); + return NULL; + } + + } + + return PyEval_EvalCode(text->compiled, globaldict, globaldict); } /*****************************************************************************/ @@ -337,7 +498,7 @@ PyObject * RunPython(Text *text, PyObject *globaldict) /*****************************************************************************/ char * GetName(Text *text) { - return (text->id.name+2); + return (text->id.name+2); } /*****************************************************************************/ @@ -345,11 +506,12 @@ char * GetName(Text *text) /*****************************************************************************/ PyObject * CreateGlobalDictionary (void) { - PyObject *dict = PyDict_New(); - PyDict_SetItemString (dict, "__builtins__", PyEval_GetBuiltins()); - PyDict_SetItemString (dict, "__name__", PyString_FromString("__main__")); + PyObject *dict = PyDict_New(); + + PyDict_SetItemString (dict, "__builtins__", PyEval_GetBuiltins()); + PyDict_SetItemString (dict, "__name__", PyString_FromString("__main__")); - return (dict); + return dict; } /*****************************************************************************/ @@ -357,8 +519,10 @@ PyObject * CreateGlobalDictionary (void) /*****************************************************************************/ void ReleaseGlobalDictionary (PyObject * dict) { - PyDict_Clear (dict); - Py_DECREF (dict); /* Release dictionary. */ + PyDict_Clear (dict); + Py_DECREF (dict); /* Release dictionary. */ + + return; } /*****************************************************************************/ @@ -366,16 +530,17 @@ void ReleaseGlobalDictionary (PyObject * dict) /* list argument. The event by which the function has been */ /* called, is passed in the event argument. */ /*****************************************************************************/ -void DoAllScriptsFromList (ListBase * list, short event) +void DoAllScriptsFromList (ListBase *list, short event) { - ID * id; + ID *id; - id = list->first; + id = list->first; - while (id != NULL) - { - BPY_do_pyscript (id, event); - id = id->next; - } + while (id != NULL) { + BPY_do_pyscript (id, event); + id = id->next; + } + + return; } diff --git a/source/blender/python/api2_2x/BGL.c b/source/blender/python/api2_2x/BGL.c index 858b343bfe8..0e9d8938146 100644 --- a/source/blender/python/api2_2x/BGL.c +++ b/source/blender/python/api2_2x/BGL.c @@ -337,7 +337,10 @@ static PyObject *Buffer_repr(PyObject *self) } /* BGL_Wrap defined in BGL.h */ -#ifndef __APPLE__ + +/* Let's try to take away this ifndef: */ +/* #ifndef __APPLE__ */ + BGL_Wrap(2, Accum, void, (GLenum, GLfloat)) BGL_Wrap(2, AlphaFunc, void, (GLenum, GLclampf)) BGL_Wrap(3, AreTexturesResident, GLboolean, (GLsizei, GLuintP, GLbooleanP)) @@ -663,7 +666,8 @@ BGL_Wrap(1, Vertex4iv, void, (GLintP)) BGL_Wrap(4, Vertex4s, void, (GLshort, GLshort, GLshort, GLshort)) BGL_Wrap(1, Vertex4sv, void, (GLshortP)) BGL_Wrap(4, Viewport, void, (GLint, GLint, GLsizei, GLsizei)) -#endif + +/* #endif */ #undef MethodDef #define MethodDef(func) {"gl"#func, Method_##func, METH_VARARGS} @@ -673,8 +677,10 @@ BGL_Wrap(4, Viewport, void, (GLint, GLint, GLsizei, GLsizei)) static struct PyMethodDef BGL_methods[] = { {"Buffer", Method_Buffer, METH_VARARGS, Method_Buffer_doc}, -#ifndef __APPLE__ - MethodDef( Accum), + +/* #ifndef __APPLE__ */ + + MethodDef( Accum), MethodDef( AlphaFunc), MethodDef( AreTexturesResident), MethodDef( Begin), @@ -987,7 +993,8 @@ static struct PyMethodDef BGL_methods[] = { MethodDef( Vertex4s), MethodDef( Vertex4sv), MethodDef( Viewport), -#endif + +/* #endif */ {NULL, NULL} }; diff --git a/source/blender/python/api2_2x/BGL.h b/source/blender/python/api2_2x/BGL.h index 2da80b4555c..c63cacb2ec0 100644 --- a/source/blender/python/api2_2x/BGL.h +++ b/source/blender/python/api2_2x/BGL.h @@ -151,7 +151,8 @@ PyTypeObject Buffer_Type = { &Buffer_SeqMethods, /*tp_as_sequence*/ }; -#ifndef __APPLE__ +/* #ifndef __APPLE__ */ + /*@ By golly George! It looks like fancy pants macro time!!! */ /* @@ -419,6 +420,6 @@ static PyObject *Method_##funcname (PyObject *self, PyObject *args) {\ ret_ret_##ret; \ } -#endif +/* #endif */ PyObject *M_BGL_Init(void); diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c index d7a685d131e..c0530c91aa1 100644 --- a/source/blender/python/api2_2x/Blender.c +++ b/source/blender/python/api2_2x/Blender.c @@ -24,7 +24,7 @@ * * This is a new part of Blender. * - * Contributor(s): Michel Selten + * Contributor(s): Michel Selten, Willian P. Germano * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -173,6 +173,31 @@ PyObject *Blender_Redraw(PyObject *self, PyObject *args) return M_Window_Redraw(self, Py_BuildValue("(i)", wintype)); } +/*****************************************************************************/ +/* Function: Blender_ReleaseGlobalDict */ +/* Python equivalent: Blender.ReleaseGlobalDict */ +/* Description: Receives an int (treated as boolean) to define */ +/* whether the global Python dictionary should be */ +/* cleared after the script is run or not. Default */ +/* is to clear (to release). To change this, call */ +/* Blender.ReleaseGlobalDict with a non-zero int */ +/* argument. If called with an empty arg list, it */ +/* doesn't change anything. */ +/* Returns the current behavior. */ +/*****************************************************************************/ +PyObject *Blender_ReleaseGlobalDict(PyObject *self, PyObject *args) +{ + printf ("In Blender_ReleaseGlobalDict()\n"); + + if (!PyArg_ParseTuple (args, "|i", &EXPP_releaseGlobalDict)) + { + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected int argument (or nothing)"); + } + + return Py_BuildValue("i", (EXPP_releaseGlobalDict?1:0)); +} + /*****************************************************************************/ /* Function: initBlender */ /*****************************************************************************/ diff --git a/source/blender/python/api2_2x/Blender.h b/source/blender/python/api2_2x/Blender.h index 50afa1053f7..19e3d686630 100644 --- a/source/blender/python/api2_2x/Blender.h +++ b/source/blender/python/api2_2x/Blender.h @@ -24,7 +24,7 @@ * * This is a new part of Blender. * - * Contributor(s): Michel Selten + * Contributor(s): Michel Selten, Willian P. Germano * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -50,12 +50,18 @@ /* From Window.h, used here by Blender_Redraw */ PyObject *M_Window_Redraw(PyObject *self, PyObject *args); +/* This global variable controls whether the global Interpreter dictionary + * should be cleared after a script is run. Default is to clear it. + * See Blender.ReleaseGlobalDict(bool) */ +extern short EXPP_releaseGlobalDict; + /*****************************************************************************/ /* Python API function prototypes for the Blender module. */ /*****************************************************************************/ PyObject *Blender_Set (PyObject *self, PyObject *args); PyObject *Blender_Get (PyObject *self, PyObject *args); PyObject *Blender_Redraw(PyObject *self, PyObject *args); +PyObject *Blender_ReleaseGlobalDict(PyObject *self, PyObject *args); /*****************************************************************************/ /* The following string definitions are used for documentation strings. */ @@ -81,6 +87,12 @@ char Blender_Get_doc[] = char Blender_Redraw_doc[] = "() - Redraw all 3D windows"; +char Blender_ReleaseGlobalDict_doc[] = +"(int) - Define whether the global Python Interpreter dictionary\n\ + should be cleared after the script is run. Default is\n\ + to clear (non-zero int).\n\ +() - Return the current behavior as a bool value (0 is false, 1 is true)\n"; + /*****************************************************************************/ /* Python method structure definition. */ /*****************************************************************************/ @@ -88,6 +100,8 @@ struct PyMethodDef Blender_methods[] = { {"Set", &Blender_Set, METH_VARARGS, Blender_Set_doc}, {"Get", &Blender_Get, METH_VARARGS, Blender_Get_doc}, {"Redraw", &Blender_Redraw, METH_VARARGS, Blender_Redraw_doc}, + {"ReleaseGlobalDict", &Blender_ReleaseGlobalDict, + METH_VARARGS, Blender_ReleaseGlobalDict_doc}, {NULL, NULL} }; diff --git a/source/blender/python/api2_2x/Camera.c b/source/blender/python/api2_2x/Camera.c index 81646cae727..97c57ee9a5b 100644 --- a/source/blender/python/api2_2x/Camera.c +++ b/source/blender/python/api2_2x/Camera.c @@ -87,40 +87,69 @@ static PyObject *M_Camera_New(PyObject *self, PyObject *args, PyObject *keywords /*****************************************************************************/ /* Function: M_Camera_Get */ /* Python equivalent: Blender.Camera.Get */ +/* Description: Receives a string and returns the camera data obj */ +/* whose name matches the string. If no argument is */ +/* passed in, a list of all camera data names in the */ +/* current scene is returned. */ /*****************************************************************************/ static PyObject *M_Camera_Get(PyObject *self, PyObject *args) { - char *name; - Camera *cam_iter; - C_Camera *wanted_cam; + char *name = NULL; + Camera *cam_iter; - printf ("In Camera_Get()\n"); - if (!PyArg_ParseTuple(args, "s", &name)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected string argument")); + if (!PyArg_ParseTuple(args, "|s", &name)) + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string argument (or nothing)")); - /* Use the name to search for the camera requested */ - wanted_cam = NULL; cam_iter = G.main->camera.first; - while ((cam_iter) && (wanted_cam == NULL)) { + if (name) { /* (name) - Search camera by name */ + + C_Camera *wanted_cam = NULL; - if (strcmp (name, cam_iter->id.name+2) == 0) { - wanted_cam = (C_Camera *)PyObject_NEW(C_Camera, &Camera_Type); - if (wanted_cam) wanted_cam->camera = cam_iter; + while ((cam_iter) && (wanted_cam == NULL)) { + if (strcmp (name, cam_iter->id.name+2) == 0) { + wanted_cam = (C_Camera *)PyObject_NEW(C_Camera, &Camera_Type); + if (wanted_cam) wanted_cam->camera = cam_iter; + } + cam_iter = cam_iter->id.next; } - cam_iter = cam_iter->id.next; - } + if (wanted_cam == NULL) { /* Requested camera doesn't exist */ + char error_msg[64]; + PyOS_snprintf(error_msg, sizeof(error_msg), + "Camera \"%s\" not found", name); + return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg)); + } - if (wanted_cam == NULL) { /* Requested camera doesn't exist */ - char error_msg[64]; - PyOS_snprintf(error_msg, sizeof(error_msg), - "Camera \"%s\" not found", name); - return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg)); - } + return (PyObject *)wanted_cam; + } + + else { /* () - return a list of all cameras in the scene */ + int index = 0; + PyObject *camlist, *pystr; + + camlist = PyList_New (BLI_countlist (&(G.main->camera))); + + if (camlist == NULL) + return (PythonReturnErrorObject (PyExc_MemoryError, + "couldn't create PyList")); + + while (cam_iter) { + pystr = PyString_FromString (cam_iter->id.name+2); + + if (!pystr) + return (PythonReturnErrorObject (PyExc_MemoryError, + "couldn't create PyString")); + + PyList_SET_ITEM (camlist, index, pystr); - return (PyObject*)wanted_cam; + cam_iter = cam_iter->id.next; + index++; + } + + return (camlist); + } } /*****************************************************************************/ @@ -216,7 +245,7 @@ static PyObject *Camera_rename(C_Camera *self, PyObject *args) char buf[21]; if (!PyArg_ParseTuple(args, "s", &name)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected string argument")); PyOS_snprintf(buf, sizeof(buf), "%s", name); @@ -232,7 +261,7 @@ static PyObject *Camera_setType(C_Camera *self, PyObject *args) char *type; if (!PyArg_ParseTuple(args, "s", &type)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected string argument")); if (strcmp (type, "persp") == 0) @@ -257,13 +286,13 @@ static PyObject *Camera_setIntType(C_Camera *self, PyObject *args) short value; if (!PyArg_ParseTuple(args, "h", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected int argument: 0 or 1")); if (value == 0 || value == 1) self->camera->type = value; else - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_ValueError, "expected int argument: 0 or 1")); Py_INCREF(Py_None); @@ -312,13 +341,13 @@ static PyObject *Camera_setIntMode(C_Camera *self, PyObject *args) short value; if (!PyArg_ParseTuple(args, "h", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected int argument in [0,3]")); if (value >= 0 && value <= 3) self->camera->flag = value; else - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_ValueError, "expected int argument in [0,3]")); Py_INCREF(Py_None); @@ -330,7 +359,7 @@ static PyObject *Camera_setLens(C_Camera *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected float argument")); self->camera->lens = EXPP_ClampFloat (value, @@ -345,7 +374,7 @@ static PyObject *Camera_setClipStart(C_Camera *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected float argument")); self->camera->clipsta = EXPP_ClampFloat (value, @@ -360,7 +389,7 @@ static PyObject *Camera_setClipEnd(C_Camera *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected float argument")); self->camera->clipend = EXPP_ClampFloat (value, @@ -375,7 +404,7 @@ static PyObject *Camera_setDrawSize(C_Camera *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected a float number as argument")); self->camera->drawsize = EXPP_ClampFloat (value, diff --git a/source/blender/python/api2_2x/Camera.h b/source/blender/python/api2_2x/Camera.h index dd5b087924a..38e988d793b 100644 --- a/source/blender/python/api2_2x/Camera.h +++ b/source/blender/python/api2_2x/Camera.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "constant.h" diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c index 04b26bf20be..f9feaf398de 100644 --- a/source/blender/python/api2_2x/Draw.c +++ b/source/blender/python/api2_2x/Draw.c @@ -114,20 +114,26 @@ static void exit_pydraw(SpaceText *st) static void exec_callback(SpaceText *st, PyObject *callback, PyObject *args) { - PyObject *result= PyEval_CallObject(callback, args); - + PyObject *result = PyObject_CallObject (callback, args); + printf ("In exec_callback\n"); if (result==NULL) { + printf("In exec_callback, result == NULL\n"); st->text->compiled= NULL; PyErr_Print(); exit_pydraw(st); } + printf ("In exec_callback 2\n"); Py_XDECREF(result); Py_DECREF(args); } -/*@ the handler for drawing routines (see Register method) */ +/* BPY_spacetext_do_pywin_draw, the static spacetext_do_pywin_buttons and + * BPY_spacetext_do_pywin_event are the three functions responsible for + * calling the draw, buttons and event callbacks registered with Draw.Register + * (see Method_Register below). They are called (only the two BPY_ ones) + * from blender/src/drawtext.c */ -void EXPP_spacetext_do_pywin_draw(SpaceText *st) +void BPY_spacetext_do_pywin_draw(SpaceText *st) { uiBlock *block; char butblock[20]; @@ -150,8 +156,6 @@ void EXPP_spacetext_do_pywin_draw(SpaceText *st) curarea->win_swap= WIN_BACK_OK; } -/*@ the handler for button event routines (see Register method) */ - static void spacetext_do_pywin_buttons(SpaceText *st, unsigned short event) { if (st->py_button) { @@ -159,9 +163,7 @@ static void spacetext_do_pywin_buttons(SpaceText *st, unsigned short event) } } -/*@ calls the generic event handling methods registered with Register */ - -void EXPP_spacetext_do_pywin_event(SpaceText *st, unsigned short event, short val) +void BPY_spacetext_do_pywin_event(SpaceText *st, unsigned short event, short val) { if (event==QKEY && G.qual & (LR_ALTKEY|LR_CTRLKEY|LR_SHIFTKEY)) { exit_pydraw(st); @@ -171,23 +173,22 @@ void EXPP_spacetext_do_pywin_event(SpaceText *st, unsigned short event, short va if (val) { if (uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; - if (event==UI_BUT_EVENT) { + if (event==UI_BUT_EVENT) spacetext_do_pywin_buttons(st, val); - } } - if (st->py_event) { + if (st->py_event) exec_callback(st, st->py_event, Py_BuildValue("(ii)", event, val)); - } } -int EXPP_spacetext_is_pywin(SpaceText *st) +int BPY_spacetext_is_pywin(SpaceText *st) { return (st->py_draw || st->py_event || st->py_button); } -#define EXPP_TRY(x) if((!(x))) \ - return EXPP_ReturnPyObjError(PyExc_AttributeError, "in module Blender.Draw") +/* the define CLEAR_NAMESPACE is currently ignored. It should be + * substituted by a better method, that was also the intention of the + * programmer(s) who put it there. */ static PyObject *Method_Exit (PyObject *self, PyObject *args) { @@ -195,8 +196,10 @@ static PyObject *Method_Exit (PyObject *self, PyObject *args) #ifdef CLEAR_NAMESPACE PyObject *d; #endif - EXPP_TRY(PyArg_ParseTuple(args, "")); - + if (!PyArg_ParseTuple(args, "")) + return EXPP_ReturnPyObjError (PyExc_AttributeError, + "expected empty argument list"); + exit_pydraw(st); #ifdef CLEAR_NAMESPACE d = st->py_globaldict; /* The current window's global namespace dictionary */ @@ -206,7 +209,7 @@ static PyObject *Method_Exit (PyObject *self, PyObject *args) } #endif - return EXPP_incr_ret(Py_None); + return EXPP_incr_ret (Py_None); } static PyObject *Method_Register (PyObject *self, PyObject *args) @@ -214,8 +217,10 @@ static PyObject *Method_Register (PyObject *self, PyObject *args) PyObject *newdrawc= NULL, *neweventc= NULL, *newbuttonc= NULL; SpaceText *st= curarea->spacedata.first; - EXPP_TRY(PyArg_ParseTuple(args, "O|OO", &newdrawc, - &neweventc, &newbuttonc)); + if (!PyArg_ParseTuple(args, "O|OO", &newdrawc, + &neweventc, &newbuttonc)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected one or three PyObjects"); /*@This is a hack again: * Every python script should actually do a global variable cleanup at @@ -235,33 +240,35 @@ static PyObject *Method_Register (PyObject *self, PyObject *args) st->flags &= ~ST_CLEAR_NAMESPACE; - if (!PyCallable_Check(newdrawc)) newdrawc= NULL; - if (!PyCallable_Check(neweventc)) neweventc= NULL; - if (!PyCallable_Check(newbuttonc)) newbuttonc= NULL; + if (!PyCallable_Check(newdrawc)) newdrawc = NULL; + if (!PyCallable_Check(neweventc)) neweventc = NULL; + if (!PyCallable_Check(newbuttonc)) newbuttonc = NULL; if (!(newdrawc || neweventc || newbuttonc)) return EXPP_incr_ret(Py_None); - + exit_pydraw(st); Py_XINCREF(newdrawc); Py_XINCREF(neweventc); Py_XINCREF(newbuttonc); - + st->py_draw= newdrawc; st->py_event= neweventc; st->py_button= newbuttonc; scrarea_queue_redraw(st->area); - return EXPP_incr_ret(Py_None); + return EXPP_incr_ret (Py_None); } static PyObject *Method_Redraw (PyObject *self, PyObject *args) { int after= 0; - EXPP_TRY(PyArg_ParseTuple(args, "|i", &after)); + if (!PyArg_ParseTuple(args, "|i", &after)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected int argument (or nothing)"); if (after) addafterqueue(curarea->win, REDRAW, 1); else scrarea_queue_winredraw(curarea); @@ -273,17 +280,20 @@ static PyObject *Method_Draw (PyObject *self, PyObject *args) { /*@ If forced drawing is disable queue a redraw event instead */ if (EXPP_disable_force_draw) { + printf ("\nEXPP_disable_force_draw\n"); scrarea_queue_winredraw(curarea); - return EXPP_incr_ret(Py_None); + return EXPP_incr_ret (Py_None); } - - EXPP_TRY(PyArg_ParseTuple(args, "")); + + if (!PyArg_ParseTuple(args, "")) + return EXPP_ReturnPyObjError (PyExc_AttributeError, + "expected empty argument list"); scrarea_do_windraw(curarea); screen_swapbuffers(); - - return EXPP_incr_ret(Py_None); + + return EXPP_incr_ret (Py_None); } static PyObject *Method_Create (PyObject *self, PyObject *args) @@ -291,7 +301,9 @@ static PyObject *Method_Create (PyObject *self, PyObject *args) Button *but; PyObject *in; - EXPP_TRY(PyArg_ParseTuple(args, "O", &in)); + if (!PyArg_ParseTuple(args, "O", &in)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected PyObject argument"); but= newbutton(); if(PyFloat_Check(in)) { @@ -329,8 +341,10 @@ static PyObject *Method_Button (PyObject *self, PyObject *args) int event; int x, y, w, h; - EXPP_TRY(PyArg_ParseTuple(args, "siiiii|s", &name, &event, - &x, &y, &w, &h, &tip)); + if (!PyArg_ParseTuple(args, "siiiii|s", &name, &event, + &x, &y, &w, &h, &tip)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected a string, five ints and optionally another string as arguments"); block= Get_uiBlock(); @@ -348,9 +362,11 @@ static PyObject *Method_Menu (PyObject *self, PyObject *args) int x, y, w, h; Button *but; - EXPP_TRY(PyArg_ParseTuple(args, "siiiiii|s", &name, &event, - &x, &y, &w, &h, &def, &tip)); - + if (!PyArg_ParseTuple(args, "siiiiii|s", &name, &event, + &x, &y, &w, &h, &def, &tip)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected a string, six ints and optionally another string as arguments"); + but= newbutton(); but->type= 1; but->val.asint= def; @@ -370,9 +386,11 @@ static PyObject *Method_Toggle (PyObject *self, PyObject *args) int x, y, w, h, def; Button *but; - EXPP_TRY(PyArg_ParseTuple(args, "siiiiii|s", &name, &event, - &x, &y, &w, &h, &def, &tip)); - + if (!PyArg_ParseTuple(args, "siiiiii|s", &name, &event, + &x, &y, &w, &h, &def, &tip)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected a string, six ints and optionally another string as arguments"); + but= newbutton(); but->type= 1; but->val.asint= def; @@ -425,10 +443,12 @@ static PyObject *Method_Slider (PyObject *self, PyObject *args) Button *but; PyObject *mino, *maxo, *inio; - EXPP_TRY(PyArg_ParseTuple(args, "siiiiiOOO|is", &name, &event, - &x, &y, &w, &h, &inio, &mino, &maxo, &realtime, &tip)); + if (!PyArg_ParseTuple(args, "siiiiiOOO|is", &name, &event, + &x, &y, &w, &h, &inio, &mino, &maxo, &realtime, &tip)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected a string, five ints, three PyObjects\n\ + and optionally another int and string as arguments"); - but= newbutton(); if (PyFloat_Check(inio)) { float ini, min, max; @@ -479,8 +499,12 @@ static PyObject *Method_Scrollbar (PyObject *self, PyObject *args) PyObject *mino, *maxo, *inio; float ini, min, max; - EXPP_TRY(PyArg_ParseTuple(args, "iiiiiOOO|is", &event, &x, &y, &w, &h, &inio, &mino, &maxo, &realtime, &tip)); - + if (!PyArg_ParseTuple(args, "iiiiiOOO|is", &event, &x, &y, &w, &h, + &inio, &mino, &maxo, &realtime, &tip)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected five ints, three PyObjects and optionally\n\ + another int and string as arguments"); + if (!PyNumber_Check(inio) || !PyNumber_Check(inio) || !PyNumber_Check(inio)) return EXPP_ReturnPyObjError (PyExc_AttributeError, "expected numbers for initial, min, and max"); @@ -526,9 +550,12 @@ static PyObject *Method_Number (PyObject *self, PyObject *args) Button *but; PyObject *mino, *maxo, *inio; - EXPP_TRY(PyArg_ParseTuple(args, "siiiiiOOO|s", &name, &event, - &x, &y, &w, &h, &inio, &mino, &maxo, &tip)); - + if (!PyArg_ParseTuple(args, "siiiiiOOO|s", &name, &event, + &x, &y, &w, &h, &inio, &mino, &maxo, &tip)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected a string, five ints, three PyObjects and\n\ + optionally another string as arguments"); + but= newbutton(); if (PyFloat_Check(inio)) { @@ -570,8 +597,11 @@ static PyObject *Method_String (PyObject *self, PyObject *args) int x, y, w, h, len; Button *but; - EXPP_TRY(PyArg_ParseTuple(args, "siiiiisi|s", &name, &event, - &x, &y, &w, &h, &newstr, &len, &tip)); + if (!PyArg_ParseTuple(args, "siiiiisi|s", &name, &event, + &x, &y, &w, &h, &newstr, &len, &tip)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected a string, five ints, a string, an int and\n\ + optionally another string as arguments"); but= newbutton(); but->type= 3; @@ -592,8 +622,10 @@ static PyObject *Method_Text (PyObject *self, PyObject *args) { char *text; - EXPP_TRY(PyArg_ParseTuple(args, "s", &text)); - + if (!PyArg_ParseTuple(args, "s", &text)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string argument"); + BMF_DrawString(G.font, text); return EXPP_incr_ret(Py_None); diff --git a/source/blender/python/api2_2x/Draw.h b/source/blender/python/api2_2x/Draw.h index 4b69807da57..1d3cfe0c1cb 100644 --- a/source/blender/python/api2_2x/Draw.h +++ b/source/blender/python/api2_2x/Draw.h @@ -121,10 +121,10 @@ static Button *newbutton (void); static void exit_pydraw(SpaceText *st); static void exec_callback(SpaceText *st, PyObject *callback, PyObject *args); -void EXPP_spacetext_do_pywin_draw(SpaceText *st); +void BPY_spacetext_do_pywin_draw(SpaceText *st); static void spacetext_do_pywin_buttons(SpaceText *st, unsigned short event); -void EXPP_spacetext_do_pywin_event(SpaceText *st, unsigned short event, short val); -int EXPP_spacetext_is_pywin(SpaceText *st); +void BPY_spacetext_do_pywin_event(SpaceText *st, unsigned short event, short val); +int BPY_spacetext_is_pywin(SpaceText *st); static char Method_Exit_doc[] = "() - Exit the windowing interface"; @@ -160,10 +160,8 @@ exactly once for everytime this function is called."; static PyObject *Method_Draw (PyObject *self, PyObject *args); static char Method_Create_doc[] = -"(value) - Create a default Button object\n\ -\n\ -(value) - The value to store in the button\n\ -\n\ +"(value) - Create a default Button object\n\n\ +(value) - The value to store in the button\n\n\ Valid values are ints, floats, and strings"; static PyObject *Method_Create (PyObject *self, PyObject *args); diff --git a/source/blender/python/api2_2x/Image.c b/source/blender/python/api2_2x/Image.c index 2449de31750..99e1f61945a 100644 --- a/source/blender/python/api2_2x/Image.c +++ b/source/blender/python/api2_2x/Image.c @@ -44,57 +44,89 @@ static PyObject *M_Image_New(PyObject *self, PyObject *args, PyObject *keywords) } /*****************************************************************************/ -/* Function: M_Image_Get */ -/* Python equivalent: Blender.Image.Get */ +/* Function: M_Image_Get */ +/* Python equivalent: Blender.Image.Get */ +/* Description: Receives a string and returns the image object */ +/* whose name matches the string. If no argument is */ +/* passed in, a list of all image names in the */ +/* current scene is returned. */ /*****************************************************************************/ static PyObject *M_Image_Get(PyObject *self, PyObject *args) { - char *name; - Image *img_iter; - C_Image *wanted_img; + char *name = NULL; + Image *img_iter; - printf ("In Image_Get()\n"); - if (!PyArg_ParseTuple(args, "s", &name)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected string argument")); + if (!PyArg_ParseTuple(args, "|s", &name)) + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string argument (or nothing)")); - /* Use the name to search for the image requested. */ - wanted_img = NULL; img_iter = G.main->image.first; - while ((img_iter) && (wanted_img == NULL)) { + if (name) { /* (name) - Search image by name */ + + C_Image *wanted_image = NULL; - if (strcmp (name, img_iter->id.name+2) == 0) { - wanted_img = (C_Image *)PyObject_NEW(C_Image, &Image_Type); - if (wanted_img) wanted_img->image = img_iter; + while ((img_iter) && (wanted_image == NULL)) { + if (strcmp (name, img_iter->id.name+2) == 0) { + wanted_image = (C_Image *)PyObject_NEW(C_Image, &Image_Type); + if (wanted_image) wanted_image->image = img_iter; + } + img_iter = img_iter->id.next; } - img_iter = img_iter->id.next; - } + if (wanted_image == NULL) { /* Requested image doesn't exist */ + char error_msg[64]; + PyOS_snprintf(error_msg, sizeof(error_msg), + "Image \"%s\" not found", name); + return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg)); + } - if (wanted_img == NULL) { - /* No image exists with the name specified in the argument name. */ - char error_msg[64]; - PyOS_snprintf(error_msg, sizeof(error_msg), - "Image \"%s\" not found", name); - return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg)); - } + return (PyObject *)wanted_image; + } + + else { /* () - return a list of all images in the scene */ + int index = 0; + PyObject *img_list, *pystr; + + img_list = PyList_New (BLI_countlist (&(G.main->image))); + + if (img_list == NULL) + return (PythonReturnErrorObject (PyExc_MemoryError, + "couldn't create PyList")); + + while (img_iter) { + pystr = PyString_FromString (img_iter->id.name+2); - return (PyObject*)wanted_img; + if (!pystr) + return (PythonReturnErrorObject (PyExc_MemoryError, + "couldn't create PyString")); + + PyList_SET_ITEM (img_list, index, pystr); + + img_iter = img_iter->id.next; + index++; + } + + return (img_list); + } } +/*****************************************************************************/ +/* Function: M_Image_Load */ +/* Python equivalent: Blender.Image.Load */ +/* Description: Receives a string and returns the image object */ +/* whose filename matches the string. */ +/*****************************************************************************/ static PyObject *M_Image_Load(PyObject *self, PyObject *args) { - char *fname; - Image *img_ptr; + char *fname; + Image *img_ptr; C_Image *img; - printf ("In Image_Load()\n"); - if (!PyArg_ParseTuple(args, "s", &fname)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected string argument")); - + img = (C_Image *)PyObject_NEW(C_Image, &Image_Type); if (!img) @@ -118,8 +150,6 @@ PyObject *M_Image_Init (void) { PyObject *submodule; - printf ("In M_Image_Init()\n"); - submodule = Py_InitModule3("Blender.Image", M_Image_methods, M_Image_doc); return (submodule); @@ -154,7 +184,7 @@ static PyObject *Image_rename(C_Image *self, PyObject *args) char buf[21]; if (!PyArg_ParseTuple(args, "s", &name)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected string argument")); PyOS_snprintf(buf, sizeof(buf), "%s", name); @@ -170,13 +200,13 @@ static PyObject *Image_setXRep(C_Image *self, PyObject *args) short value; if (!PyArg_ParseTuple(args, "h", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected int argument in [1,16]")); if (value >= EXPP_IMAGE_REP_MIN || value <= EXPP_IMAGE_REP_MAX) self->image->xrep = value; else - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_ValueError, "expected int argument in [1,16]")); Py_INCREF(Py_None); @@ -188,13 +218,13 @@ static PyObject *Image_setYRep(C_Image *self, PyObject *args) short value; if (!PyArg_ParseTuple(args, "h", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected int argument in [1,16]")); if (value >= EXPP_IMAGE_REP_MIN || value <= EXPP_IMAGE_REP_MAX) self->image->yrep = value; else - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_ValueError, "expected int argument in [1,16]")); Py_INCREF(Py_None); diff --git a/source/blender/python/api2_2x/Image.h b/source/blender/python/api2_2x/Image.h index 4ddffe01356..8373b3f82bb 100644 --- a/source/blender/python/api2_2x/Image.h +++ b/source/blender/python/api2_2x/Image.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "gen_utils.h" diff --git a/source/blender/python/api2_2x/Lamp.c b/source/blender/python/api2_2x/Lamp.c index a1d305692ec..da104852fdc 100644 --- a/source/blender/python/api2_2x/Lamp.c +++ b/source/blender/python/api2_2x/Lamp.c @@ -89,42 +89,69 @@ static PyObject *M_Lamp_New(PyObject *self, PyObject *args, PyObject *keywords) /*****************************************************************************/ /* Function: M_Lamp_Get */ /* Python equivalent: Blender.Lamp.Get */ +/* Description: Receives a string and returns the lamp data obj */ +/* whose name matches the string. If no argument is */ +/* passed in, a list of all lamp data names in the */ +/* current scene is returned. */ /*****************************************************************************/ static PyObject *M_Lamp_Get(PyObject *self, PyObject *args) { - char *name; - Lamp *lamp_iter; - C_Lamp *wanted_lamp; + char *name = NULL; + Lamp *lamp_iter; - printf ("In Lamp_Get()\n"); - if (!PyArg_ParseTuple(args, "s", &name)) - { - return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected string argument")); - } + if (!PyArg_ParseTuple(args, "|s", &name)) + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string argument (or nothing)")); - /* Use the name to search for the lamp requested. */ - wanted_lamp = NULL; lamp_iter = G.main->lamp.first; - while ((lamp_iter) && (wanted_lamp == NULL)) { + if (name) { /* (name) - Search lamp by name */ - if (strcmp (name, lamp_iter->id.name+2) == 0) { - wanted_lamp = (C_Lamp *)PyObject_NEW(C_Lamp, &Lamp_Type); - if (wanted_lamp) wanted_lamp->lamp = lamp_iter; + C_Lamp *wanted_lamp = NULL; + + while ((lamp_iter) && (wanted_lamp == NULL)) { + if (strcmp (name, lamp_iter->id.name+2) == 0) { + wanted_lamp = (C_Lamp *)PyObject_NEW(C_Lamp, &Lamp_Type); + if (wanted_lamp) wanted_lamp->lamp = lamp_iter; + } + lamp_iter = lamp_iter->id.next; } - lamp_iter = lamp_iter->id.next; - } + if (wanted_lamp == NULL) { /* Requested lamp doesn't exist */ + char error_msg[64]; + PyOS_snprintf(error_msg, sizeof(error_msg), + "Lamp \"%s\" not found", name); + return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg)); + } - if (wanted_lamp == NULL) {/* Requested Lamp doesn't exist */ - char error_msg[64]; - PyOS_snprintf(error_msg, sizeof(error_msg), - "Lamp \"%s\" not found", name); - return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg)); - } + return (PyObject *)wanted_lamp; + } + + else { /* () - return a list of all lamps in the scene */ + int index = 0; + PyObject *lamplist, *pystr; + + lamplist = PyList_New (BLI_countlist (&(G.main->lamp))); + + if (lamplist == NULL) + return (PythonReturnErrorObject (PyExc_MemoryError, + "couldn't create PyList")); + + while (lamp_iter) { + pystr = PyString_FromString (lamp_iter->id.name+2); + + if (!pystr) + return (PythonReturnErrorObject (PyExc_MemoryError, + "couldn't create PyString")); - return (PyObject*)wanted_lamp; + PyList_SET_ITEM (lamplist, index, pystr); + + lamp_iter = lamp_iter->id.next; + index++; + } + + return (lamplist); + } } /*****************************************************************************/ @@ -320,7 +347,7 @@ static PyObject *Lamp_rename(C_Lamp *self, PyObject *args) char buf[21]; if (!PyArg_ParseTuple(args, "s", &name)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected string argument")); PyOS_snprintf(buf, sizeof(buf), "%s", name); @@ -336,7 +363,7 @@ static PyObject *Lamp_setType(C_Lamp *self, PyObject *args) char *type; if (!PyArg_ParseTuple(args, "s", &type)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected string argument")); if (strcmp (type, "Lamp") == 0) @@ -365,13 +392,13 @@ static PyObject *Lamp_setIntType(C_Lamp *self, PyObject *args) short value; if (!PyArg_ParseTuple(args, "h", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected int argument in [0,3]")); if (value >= 0 && value <= 3) self->lamp->type = value; else - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_ValueError, "expected int argument in [0,3]")); Py_INCREF(Py_None); @@ -386,7 +413,7 @@ static PyObject *Lamp_setMode(C_Lamp *self, PyObject *args) if (!PyArg_ParseTuple(args, "|ssssssss", &m[0], &m[1], &m[2], &m[3], &m[4], &m[5], &m[6], &m[7])) return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected string argument(s)")); + "expected from none to eight string argument(s)")); for (i = 0; i < 8; i++) { if (m[i] == NULL) break; @@ -424,7 +451,7 @@ static PyObject *Lamp_setIntMode(C_Lamp *self, PyObject *args) short value; if (!PyArg_ParseTuple(args, "h", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected int argument")); /* well, with so many flag bits, we just accept any short int, no checking */ @@ -439,14 +466,14 @@ static PyObject *Lamp_setSamples(C_Lamp *self, PyObject *args) short value; if (!PyArg_ParseTuple(args, "h", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected int argument in [1,16]")); if (value >= EXPP_LAMP_SAMPLES_MIN && value <= EXPP_LAMP_SAMPLES_MAX) self->lamp->samp = value; else - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_ValueError, "expected int argument in [1,16]")); Py_INCREF(Py_None); @@ -458,21 +485,15 @@ static PyObject *Lamp_setBufferSize(C_Lamp *self, PyObject *args) short value; if (!PyArg_ParseTuple(args, "h", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected int argument, any of [512, 768, 1024, 1536, 2560]")); - - switch (value) { - case 512: - case 768: - case 1024: - case 1536: - case 2560: - self->lamp->bufsize = value; - break; - default: - return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected int argument, any of [512, 768, 1024, 1536, 2560]")); - } + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected int argument in [512, 5120]")); + + if (value >= EXPP_LAMP_BUFFERSIZE_MIN && + value <= EXPP_LAMP_BUFFERSIZE_MAX) + self->lamp->bufsize = value; + else + return (EXPP_ReturnPyObjError (PyExc_ValueError, + "expected int argument in [512, 5120]")); Py_INCREF(Py_None); return Py_None; @@ -483,16 +504,16 @@ static PyObject *Lamp_setHaloStep(C_Lamp *self, PyObject *args) short value; if (!PyArg_ParseTuple(args, "h", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected int argument in [0,12]")); if (value >= EXPP_LAMP_HALOSTEP_MIN && value <= EXPP_LAMP_HALOSTEP_MAX) self->lamp->shadhalostep = value; else - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_ValueError, "expected int argument in [0,12]")); - + Py_INCREF(Py_None); return Py_None; } @@ -502,7 +523,7 @@ static PyObject *Lamp_setColorComponent(C_Lamp *self, char *key, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected float argument in [0.0, 1.0]")); value = EXPP_ClampFloat (value, 0.0, 1.0); @@ -523,7 +544,7 @@ static PyObject *Lamp_setEnergy(C_Lamp *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected float argument")); value = EXPP_ClampFloat (value, EXPP_LAMP_ENERGY_MIN, EXPP_LAMP_ENERGY_MAX); @@ -538,7 +559,7 @@ static PyObject *Lamp_setDist(C_Lamp *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected float argument")); value = EXPP_ClampFloat (value, EXPP_LAMP_DIST_MIN, EXPP_LAMP_DIST_MAX); @@ -553,10 +574,11 @@ static PyObject *Lamp_setSpotSize(C_Lamp *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected float argument")); - value = EXPP_ClampFloat (value, EXPP_LAMP_SPOTSIZE_MIN, EXPP_LAMP_SPOTSIZE_MAX); + value = EXPP_ClampFloat (value, EXPP_LAMP_SPOTSIZE_MIN, + EXPP_LAMP_SPOTSIZE_MAX); self->lamp->spotsize = value; Py_INCREF(Py_None); @@ -568,7 +590,7 @@ static PyObject *Lamp_setSpotBlend(C_Lamp *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected float argument")); value = EXPP_ClampFloat (value, EXPP_LAMP_SPOTBLEND_MIN, @@ -584,8 +606,8 @@ static PyObject *Lamp_setClipStart(C_Lamp *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected a float number as argument")); + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected float argument")); value = EXPP_ClampFloat (value, EXPP_LAMP_CLIPSTART_MIN, EXPP_LAMP_CLIPSTART_MAX); @@ -600,8 +622,8 @@ static PyObject *Lamp_setClipEnd(C_Lamp *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected a float number as argument")); + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected float argument")); value = EXPP_ClampFloat (value, EXPP_LAMP_CLIPEND_MIN, EXPP_LAMP_CLIPEND_MAX); @@ -616,8 +638,8 @@ static PyObject *Lamp_setBias(C_Lamp *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected a float number as argument")); + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected float argument")); value = EXPP_ClampFloat (value, EXPP_LAMP_BIAS_MIN, EXPP_LAMP_BIAS_MAX); self->lamp->bias = value; @@ -631,8 +653,8 @@ static PyObject *Lamp_setSoftness(C_Lamp *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected a float number as argument")); + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected float argument")); value = EXPP_ClampFloat (value, EXPP_LAMP_SOFTNESS_MIN, EXPP_LAMP_SOFTNESS_MAX); @@ -647,8 +669,8 @@ static PyObject *Lamp_setHaloInt(C_Lamp *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected a float number as argument")); + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected float argument")); value = EXPP_ClampFloat (value, EXPP_LAMP_HALOINT_MIN, EXPP_LAMP_HALOINT_MAX); @@ -663,8 +685,8 @@ static PyObject *Lamp_setQuad1(C_Lamp *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected a float number as argument")); + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected float argument")); value = EXPP_ClampFloat (value, EXPP_LAMP_QUAD1_MIN, EXPP_LAMP_QUAD1_MAX); @@ -679,8 +701,8 @@ static PyObject *Lamp_setQuad2(C_Lamp *self, PyObject *args) float value; if (!PyArg_ParseTuple(args, "f", &value)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected a float number as argument")); + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected float argument")); value = EXPP_ClampFloat (value, EXPP_LAMP_QUAD2_MIN, EXPP_LAMP_QUAD2_MAX); diff --git a/source/blender/python/api2_2x/Lamp.h b/source/blender/python/api2_2x/Lamp.h index 1e5913ece44..8c1ab134411 100644 --- a/source/blender/python/api2_2x/Lamp.h +++ b/source/blender/python/api2_2x/Lamp.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "constant.h" @@ -79,6 +80,8 @@ #define EXPP_LAMP_SAMPLES_MIN 1 #define EXPP_LAMP_SAMPLES_MAX 16 #define EXPP_LAMP_BUFFERSIZE 512 +#define EXPP_LAMP_BUFFERSIZE_MIN 512 +#define EXPP_LAMP_BUFFERSIZE_MAX 5120 #define EXPP_LAMP_ENERGY 1.0 #define EXPP_LAMP_ENERGY_MIN 0.0 #define EXPP_LAMP_ENERGY_MAX 10.0 diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index 50a65f05f0c..dcf9e9a2e95 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -183,7 +183,7 @@ PyObject *M_Object_New(PyObject *self, PyObject *args) PyObject *M_Object_Get(PyObject *self, PyObject *args) { struct Object * object; - char * name; + char * name = NULL; printf ("In Object_Get()\n"); diff --git a/source/blender/python/api2_2x/Text.c b/source/blender/python/api2_2x/Text.c index 216572390ff..20ab6b10cd7 100644 --- a/source/blender/python/api2_2x/Text.c +++ b/source/blender/python/api2_2x/Text.c @@ -43,10 +43,8 @@ static PyObject *M_Text_New(PyObject *self, PyObject *args, PyObject *keywords) Text *bl_text; /* blender text object */ C_Text *py_text; /* python wrapper */ - printf ("In Text_New()\n"); - if (!PyArg_ParseTuple(args, "|si", &name, &follow)) - return EXPP_ReturnPyObjError (PyExc_TypeError, + return EXPP_ReturnPyObjError (PyExc_AttributeError, "expected string and int arguments (or nothing)"); bl_text = add_empty_text(); @@ -73,55 +71,87 @@ static PyObject *M_Text_New(PyObject *self, PyObject *args, PyObject *keywords) } /*****************************************************************************/ -/* Function: M_Text_Get */ -/* Python equivalent: Blender.Text.Get */ +/* Function: M_Text_Get */ +/* Python equivalent: Blender.Text.Get */ +/* Description: Receives a string and returns the text object */ +/* whose name matches the string. If no argument is */ +/* passed in, a list of all text names in the current */ +/* scene is returned. */ /*****************************************************************************/ static PyObject *M_Text_Get(PyObject *self, PyObject *args) { - char *name; - Text *txt_iter; - C_Text *wanted_txt; + char *name = NULL; + Text *txt_iter; - printf ("In Text_Get()\n"); - if (!PyArg_ParseTuple(args, "s", &name)) - return EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected string argument"); + if (!PyArg_ParseTuple(args, "|s", &name)) + return (EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string argument (or nothing)")); - /* Use the name to search for the text requested. */ - wanted_txt = NULL; txt_iter = G.main->text.first; - while ((txt_iter) && (wanted_txt == NULL)) { + if (name) { /* (name) - Search text by name */ - if (strcmp (name, txt_iter->id.name+2) == 0) { - wanted_txt = (C_Text *)PyObject_NEW(C_Text, &Text_Type); - if (wanted_txt) wanted_txt->text = txt_iter; + C_Text *wanted_txt = NULL; + + while ((txt_iter) && (wanted_txt == NULL)) { + if (strcmp (name, txt_iter->id.name+2) == 0) { + wanted_txt = (C_Text *)PyObject_NEW(C_Text, &Text_Type); + if (wanted_txt) wanted_txt->text = txt_iter; + } + txt_iter = txt_iter->id.next; } - txt_iter = txt_iter->id.next; - } + if (wanted_txt == NULL) { /* Requested text doesn't exist */ + char error_msg[64]; + PyOS_snprintf(error_msg, sizeof(error_msg), + "Text \"%s\" not found", name); + return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg)); + } - if (wanted_txt == NULL) { - /* No text exists with the name specified in the argument name. */ - char error_msg[64]; - PyOS_snprintf(error_msg, sizeof(error_msg), - "Text \"%s\" not found", name); - return EXPP_ReturnPyObjError (PyExc_NameError, error_msg); - } + return (PyObject *)wanted_txt; + } + + else { /* () - return a list of all texts in the scene */ + int index = 0; + PyObject *txtlist, *pystr; + + txtlist = PyList_New (BLI_countlist (&(G.main->text))); - return (PyObject*)wanted_txt; + if (txtlist == NULL) + return (PythonReturnErrorObject (PyExc_MemoryError, + "couldn't create PyList")); + + while (txt_iter) { + pystr = PyString_FromString (txt_iter->id.name+2); + + if (!pystr) + return (PythonReturnErrorObject (PyExc_MemoryError, + "couldn't create PyString")); + + PyList_SET_ITEM (txtlist, index, pystr); + + txt_iter = txt_iter->id.next; + index++; + } + + return (txtlist); + } } +/*****************************************************************************/ +/* Function: M_Text_Get */ +/* Python equivalent: Blender.Text.Load */ +/* Description: Receives a filename and returns the text object */ +/* created from the corresponding file. */ +/*****************************************************************************/ static PyObject *M_Text_Load(PyObject *self, PyObject *args) { char *fname; Text *txt_ptr; C_Text *txt; - printf ("In Text_Load()\n"); - if (!PyArg_ParseTuple(args, "s", &fname)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected string argument")); txt = (C_Text *)PyObject_NEW(C_Text, &Text_Type); @@ -177,8 +207,6 @@ PyObject *M_Text_Init (void) { PyObject *submodule; - printf ("In M_Text_Init()\n"); - submodule = Py_InitModule3("Blender.Text", M_Text_methods, M_Text_doc); return (submodule); @@ -236,7 +264,7 @@ static PyObject *Text_rename(C_Text *self, PyObject *args) char buf[21]; if (!PyArg_ParseTuple(args, "s", &name)) - return (EXPP_ReturnPyObjError (PyExc_AttributeError, + return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected string argument")); PyOS_snprintf(buf, sizeof(buf), "%s", name); @@ -296,7 +324,7 @@ static PyObject *Text_write(C_Text *self, PyObject *args) if (!PyArg_ParseTuple(args, "s", &str)) return EXPP_ReturnPyObjError (PyExc_TypeError, - "expected a string argument"); + "expected string argument"); oldstate = txt_get_undostate(); txt_insert_buf(self->text, str); diff --git a/source/blender/python/api2_2x/Text.h b/source/blender/python/api2_2x/Text.h index 5b5d5b149e2..ff67b28cc94 100644 --- a/source/blender/python/api2_2x/Text.h +++ b/source/blender/python/api2_2x/Text.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include "gen_utils.h" -- cgit v1.2.3