gen_utils.c (GetObjectByName).
* Blender.link, Blender.bylink and Blender.event should work. Somehow the
only event coming through now is only REDRAW.
* Added include path to /intern/guardedalloc
Michel
#include <Python.h>
#include <stdio.h>
+#include <MEM_guardedalloc.h>
+
#include <BKE_text.h>
#include <DNA_ID.h>
#include <DNA_scriptlink_types.h>
#include <BPY_extern.h>
#include "api2_2x/interface.h"
+/* unfortunately the following #include is needed because of some missing */
+/* functionality in BKE/DNA */
+/* #include "api2_2x/gen_utils.h" */
/*****************************************************************************/
/* Structure definitions */
/*****************************************************************************/
PyObject * RunPython(Text *text, PyObject *globaldict);
char * GetName(Text *text);
+PyObject * CreateGlobalDictionary (void);
+void ReleaseGlobalDictionary (PyObject * dict);
/*****************************************************************************/
/* Description: This function will initialise Python and all the implemented */
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
- * Notes: The call to BLO_findstruct_offset needs to be removed.
- * Somehow the object triggered by the event has to be retrieved.
- */
+/*****************************************************************************/
+/* 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)
{
- int obj_id;
- char structname[10];
- int offset;
- ScriptLink * scriptlink;
+ ScriptLink * scriptlink;
+ int index;
+ PyObject * dict;
printf ("In BPY_do_pyscript(id=%s, event=%d)\n",id->name, event);
- /* First get the object type that the script is linked to. */
- obj_id = MAKE_ID2(id->name[0], id->name[1]);
- switch (obj_id)
- {
- case ID_OB:
- sprintf (structname, "Object");
- break;
- case ID_LA:
- sprintf (structname, "Lamp");
- break;
- case ID_CA:
- sprintf (structname, "Camera");
- break;
- case ID_MA:
- sprintf (structname, "Material");
- break;
- case ID_WO:
- sprintf (structname, "World");
- break;
- case ID_SCE:
- sprintf (structname, "Scene");
- break;
- default:
- /* TODO: Do we need to generate a nice error message here? */
- return;
- }
+ scriptlink = setScriptLinks (id, event);
-/* TODO: Replace the following piece of code. See the Notes for info. */
- /* Check if a script is provided */
- offset = BLO_findstruct_offset (structname, "scriptlink");
- if (offset < 0)
+ if (scriptlink == NULL)
{
- printf ("Internal error, unable to find script link\n");
return;
}
- scriptlink = (ScriptLink*) (((char*)id) + offset);
- if (!scriptlink->totscript)
+ for (index=0 ; index<scriptlink->totscript ; index++)
{
- /* no script provided */
- return;
+ 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);
+ }
}
-
- /* Get all links from blender and set them in the Python environment */
- setScriptLinks (id, event);
+
return;
}
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. */
+}
+
module = Py_InitModule3("Blender", Blender_methods, NULL);
dict = PyModule_GetDict (module);
+ g_blenderdict = dict;
PyDict_SetItemString (dict, "Object", initObject());
}
{
char * name;
PyObject * arg;
- struct Object * obj_iter;
+ struct Object * object;
BlenObject * blen_object;
printf ("In Object_Get()\n");
return (PythonReturnErrorObject (PyExc_AttributeError,
"expected string argument"));
}
- name = PyString_AsString (arg);
-
- /* Use the name to search for the object requested. */
- /* Should this lookup be a new function in blenkernel/intern/object.c? */
- blen_object = NULL;
- obj_iter = G.main->object.first;
- while ((obj_iter) && (blen_object == NULL))
- {
- if (StringEqual (name, GetIdName (&(obj_iter->id))))
- {
- blen_object = (BlenObject*)PyObject_NEW
- (BlenObject,
- &object_type);
- blen_object->object = obj_iter;
- }
- obj_iter = obj_iter->id.next;
- }
+ name = PyString_AsString (arg);
+ object = GetObjectByName (name);
- if (blen_object == NULL)
+ if (object == NULL)
{
/* No object exists with the name specified in the argument name. */
return (PythonReturnErrorObject (PyExc_AttributeError,
- "expected string argument"));
+ "Unknown object specified."));
}
+ blen_object = (BlenObject*)PyObject_NEW (BlenObject, &object_type);
+ blen_object->object = object;
return ((PyObject*)blen_object);
}
#include <string.h>
#include <Python.h>
+#include <BKE_global.h>
+#include <BKE_main.h>
#include <DNA_ID.h>
+#include <DNA_object_types.h>
#include <DNA_scriptlink_types.h>
+/*****************************************************************************/
+/* Description: This function returns true if both given strings are equal, */
+/* otherwise it returns false. */
+/*****************************************************************************/
int StringEqual (char * string1, char * string2)
{
return (strcmp(string1, string2)==0);
}
+/*****************************************************************************/
+/* Description: This function returns the name of the given ID struct */
+/* without the Object type identifying characters prepended. */
+/*****************************************************************************/
char * GetIdName (ID *id)
{
return ((id->name)+2);
}
+/*****************************************************************************/
+/* Description: This function sets an internal string with the given type */
+/* and error_msg arguments. */
+/*****************************************************************************/
PyObject * PythonReturnErrorObject (PyObject * type, char * error_msg)
{
PyErr_SetString (type, error_msg);
return (NULL);
}
+/*****************************************************************************/
+/* Description: This function increments the reference count of the given */
+/* Python object. */
+/*****************************************************************************/
PyObject * PythonIncRef (PyObject *object)
{
Py_INCREF (object);
return (object);
}
+/*****************************************************************************/
+/* Description: This function maps the event identifier to a string. */
+/*****************************************************************************/
char * event_to_name(short event)
{
switch (event)
}
}
+/*****************************************************************************/
+/* Description: Returns the object with the name specified by the argument */
+/* name. Note that the calling function has to remove the first */
+/* two characters of the object name. These two characters */
+/* specify the type of the object (OB, ME, WO, ...) */
+/* The function will return NULL when no object with the given */
+/* name is found. */
+/*****************************************************************************/
+struct Object * GetObjectByName (char * name)
+{
+ Object * obj_iter;
+
+ obj_iter = G.main->object.first;
+ while (obj_iter)
+ {
+ if (StringEqual (name, GetIdName (&(obj_iter->id))))
+ {
+ return (obj_iter);
+ }
+ obj_iter = obj_iter->id.next;
+ }
+
+ /* There is no object with the given name */
+ return (NULL);
+}
+
PyObject * PythonIncRef (PyObject *object);
char * event_to_name(short event);
+/* The following functions may need to be moved to the respective BKE or */
+/* DNA modules. */
+
+struct Object * GetObjectByName (char * name);
+
#include <stdio.h>
+#include <Python.h>
+
#include <BKE_global.h>
#include <BKE_main.h>
#include <DNA_ID.h>
#include <DNA_material_types.h>
#include <DNA_object_types.h>
#include <DNA_scene_types.h>
+#include <DNA_scriptlink_types.h>
#include <DNA_world_types.h>
-#include "datablock.h"
#include "gen_utils.h"
#include "modules.h"
void initBlenderApi2_2x (void)
{
printf ("initBlenderApi2_2x\n");
+ g_blenderdict = NULL;
initBlender ();
}
-void setScriptLinks(ID *id, short event)
+ScriptLink * setScriptLinks(ID *id, short event)
{
- PyObject *link;
- int obj_id;
-
- printf ("In setScriptLinks (id=?, event=%d)\n", event);
- if (!g_blenderdict)
- {
- /* Not initialized yet. This can happen at first file load. */
- return;
- }
+ ScriptLink * scriptlink;
+ PyObject * link;
+ Object * object;
+ int obj_id;
obj_id = MAKE_ID2 (id->name[0], id->name[1]);
- if (obj_id == ID_SCE)
- {
- Py_INCREF(Py_None);
- link = Py_None;
- }
- else
+ printf ("In setScriptLinks (id=%s, event=%d)\n",id->name, event);
+
+ switch (obj_id)
{
- link = Py_None;
- switch (obj_id)
- {
- case ID_OB:
- /* Create a new datablock of type: Object */
- /*
- link = ObjectCreatePyObject (G.main->object);
- */
- break;
- case ID_ME:
- /* Create a new datablock of type: Mesh */
- break;
- case ID_LA:
- /* Create a new datablock of type: Lamp */
- break;
- case ID_CA:
- /* Create a new datablock of type: Camera */
- break;
- case ID_MA:
- /* Create a new datablock of type: Material */
- break;
- case ID_WO:
- /* Create a new datablock of type: World */
- break;
- case ID_IP:
- /* Create a new datablock of type: Ipo */
- break;
- case ID_IM:
- /* Create a new datablock of type: Image */
- break;
- case ID_TXT:
- /* Create a new datablock of type: Text */
- break;
- default:
- PythonReturnErrorObject (PyExc_SystemError,
- "Unable to create block for data");
- return;
- }
- /* link = DataBlockFromID(id); */
+ case ID_OB:
+ object = GetObjectByName (GetIdName (id));
+ if (object == NULL)
+ {
+ return NULL;
+ }
+ link = ObjectCreatePyObject (object);
+ scriptlink = &(object->scriptlink);
+ break;
+ case ID_LA:
+ scriptlink = NULL;
+ Py_INCREF(Py_None);
+ link = Py_None;
+ break;
+ case ID_CA:
+ scriptlink = NULL;
+ Py_INCREF(Py_None);
+ link = Py_None;
+ break;
+ case ID_MA:
+ scriptlink = NULL;
+ Py_INCREF(Py_None);
+ link = Py_None;
+ break;
+ case ID_WO:
+ scriptlink = NULL;
+ Py_INCREF(Py_None);
+ link = Py_None;
+ break;
+ case ID_SCE:
+ scriptlink = NULL;
+ Py_INCREF(Py_None);
+ link = Py_None;
+ break;
+ default:
+ Py_INCREF(Py_None);
+ link = Py_None;
+ return NULL;
}
- if (!link)
+ if (scriptlink == NULL)
{
+ /* This is probably not an internal error anymore :)
+TODO: Check this
printf ("Internal error, unable to create PyBlock for script link\n");
- printf ("This is a bug; please report to bugs@blender.nl");
+ */
Py_INCREF(Py_False);
PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
- return;
- } else {
+ return NULL;
+ }
+ else
+ {
Py_INCREF(Py_True);
PyDict_SetItemString(g_blenderdict, "bylink", Py_True);
}
PyDict_SetItemString(g_blenderdict, "link", link);
PyDict_SetItemString(g_blenderdict, "event",
Py_BuildValue("s", event_to_name(event)));
+
+ return (scriptlink);
}
#include <DNA_ID.h>
void initBlenderApi2_2x (void);
-void setScriptLinks(ID *id, short event);
+ScriptLink * setScriptLinks(ID *id, short event);