* Moved the code to retrieve an object by name to a seperate function in

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
This commit is contained in:
2003-03-18 20:21:26 +00:00
parent 465229e4d6
commit 3a0725d4aa
7 changed files with 176 additions and 134 deletions

View File

@@ -34,6 +34,8 @@
#include <Python.h> #include <Python.h>
#include <stdio.h> #include <stdio.h>
#include <MEM_guardedalloc.h>
#include <BKE_text.h> #include <BKE_text.h>
#include <DNA_ID.h> #include <DNA_ID.h>
#include <DNA_scriptlink_types.h> #include <DNA_scriptlink_types.h>
@@ -43,6 +45,9 @@
#include <BPY_extern.h> #include <BPY_extern.h>
#include "api2_2x/interface.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 */ /* Structure definitions */
@@ -63,6 +68,8 @@ ScriptError g_script_error;
/*****************************************************************************/ /*****************************************************************************/
PyObject * RunPython(Text *text, PyObject *globaldict); PyObject * RunPython(Text *text, PyObject *globaldict);
char * GetName(Text *text); char * GetName(Text *text);
PyObject * CreateGlobalDictionary (void);
void ReleaseGlobalDictionary (PyObject * dict);
/*****************************************************************************/ /*****************************************************************************/
/* Description: This function will initialise Python and all the implemented */ /* Description: This function will initialise Python and all the implemented */
@@ -165,68 +172,41 @@ void BPY_do_all_scripts(short event)
return; return;
} }
/* /*****************************************************************************/
* Description: Execute a Python script when an event occurs. The following /* Description: Execute a Python script when an event occurs. The following */
* events are possible: frame changed, load script and redraw. /* events are possible: frame changed, load script and redraw. */
* Only events happening to one of the following object types are /* Only events happening to one of the following object types */
* handled: Object, Lamp, Camera, Material, World and Scene /* are handled: Object, Lamp, Camera, Material, World and */
* Notes: The call to BLO_findstruct_offset needs to be removed. /* Scene. */
* Somehow the object triggered by the event has to be retrieved. /*****************************************************************************/
*/
void BPY_do_pyscript(struct ID *id, short event) void BPY_do_pyscript(struct ID *id, short event)
{ {
int obj_id; ScriptLink * scriptlink;
char structname[10]; int index;
int offset; PyObject * dict;
ScriptLink * scriptlink;
printf ("In BPY_do_pyscript(id=%s, event=%d)\n",id->name, event); printf ("In BPY_do_pyscript(id=%s, event=%d)\n",id->name, event);
/* First get the object type that the script is linked to. */ scriptlink = setScriptLinks (id, event);
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;
}
/* TODO: Replace the following piece of code. See the Notes for info. */ if (scriptlink == NULL)
/* Check if a script is provided */
offset = BLO_findstruct_offset (structname, "scriptlink");
if (offset < 0)
{ {
printf ("Internal error, unable to find script link\n");
return; return;
} }
scriptlink = (ScriptLink*) (((char*)id) + offset);
if (!scriptlink->totscript) for (index=0 ; index<scriptlink->totscript ; index++)
{ {
/* no script provided */ printf ("scriptnr: %d\tevent=%d, flag[index]=%d\n", index,
return; 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;
} }
@@ -324,3 +304,24 @@ char * GetName(Text *text)
return (text->id.name+2); 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. */
}

View File

@@ -239,6 +239,7 @@ void initBlender (void)
module = Py_InitModule3("Blender", Blender_methods, NULL); module = Py_InitModule3("Blender", Blender_methods, NULL);
dict = PyModule_GetDict (module); dict = PyModule_GetDict (module);
g_blenderdict = dict;
PyDict_SetItemString (dict, "Object", initObject()); PyDict_SetItemString (dict, "Object", initObject());
} }

View File

@@ -131,7 +131,7 @@ PyObject *Object_Get(PyObject *self, PyObject *args)
{ {
char * name; char * name;
PyObject * arg; PyObject * arg;
struct Object * obj_iter; struct Object * object;
BlenObject * blen_object; BlenObject * blen_object;
printf ("In Object_Get()\n"); printf ("In Object_Get()\n");
@@ -148,31 +148,18 @@ PyObject *Object_Get(PyObject *self, PyObject *args)
return (PythonReturnErrorObject (PyExc_AttributeError, return (PythonReturnErrorObject (PyExc_AttributeError,
"expected string argument")); "expected string argument"));
} }
name = PyString_AsString (arg); name = PyString_AsString (arg);
object = GetObjectByName (name);
/* Use the name to search for the object requested. */ if (object == NULL)
/* 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;
}
if (blen_object == NULL)
{ {
/* No object exists with the name specified in the argument name. */ /* No object exists with the name specified in the argument name. */
return (PythonReturnErrorObject (PyExc_AttributeError, 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); return ((PyObject*)blen_object);
} }

View File

@@ -33,31 +33,53 @@
#include <string.h> #include <string.h>
#include <Python.h> #include <Python.h>
#include <BKE_global.h>
#include <BKE_main.h>
#include <DNA_ID.h> #include <DNA_ID.h>
#include <DNA_object_types.h>
#include <DNA_scriptlink_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) int StringEqual (char * string1, char * string2)
{ {
return (strcmp(string1, string2)==0); 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) char * GetIdName (ID *id)
{ {
return ((id->name)+2); 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) PyObject * PythonReturnErrorObject (PyObject * type, char * error_msg)
{ {
PyErr_SetString (type, error_msg); PyErr_SetString (type, error_msg);
return (NULL); return (NULL);
} }
/*****************************************************************************/
/* Description: This function increments the reference count of the given */
/* Python object. */
/*****************************************************************************/
PyObject * PythonIncRef (PyObject *object) PyObject * PythonIncRef (PyObject *object)
{ {
Py_INCREF (object); Py_INCREF (object);
return (object); return (object);
} }
/*****************************************************************************/
/* Description: This function maps the event identifier to a string. */
/*****************************************************************************/
char * event_to_name(short event) char * event_to_name(short event)
{ {
switch (event) switch (event)
@@ -73,3 +95,29 @@ char * event_to_name(short 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);
}

View File

@@ -39,3 +39,8 @@ PyObject * PythonReturnErrorObject (PyObject * type, char * error_msg);
PyObject * PythonIncRef (PyObject *object); PyObject * PythonIncRef (PyObject *object);
char * event_to_name(short event); 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);

View File

@@ -31,6 +31,8 @@
#include <stdio.h> #include <stdio.h>
#include <Python.h>
#include <BKE_global.h> #include <BKE_global.h>
#include <BKE_main.h> #include <BKE_main.h>
#include <DNA_ID.h> #include <DNA_ID.h>
@@ -39,87 +41,83 @@
#include <DNA_material_types.h> #include <DNA_material_types.h>
#include <DNA_object_types.h> #include <DNA_object_types.h>
#include <DNA_scene_types.h> #include <DNA_scene_types.h>
#include <DNA_scriptlink_types.h>
#include <DNA_world_types.h> #include <DNA_world_types.h>
#include "datablock.h"
#include "gen_utils.h" #include "gen_utils.h"
#include "modules.h" #include "modules.h"
void initBlenderApi2_2x (void) void initBlenderApi2_2x (void)
{ {
printf ("initBlenderApi2_2x\n"); printf ("initBlenderApi2_2x\n");
g_blenderdict = NULL;
initBlender (); initBlender ();
} }
void setScriptLinks(ID *id, short event) ScriptLink * setScriptLinks(ID *id, short event)
{ {
PyObject *link; ScriptLink * scriptlink;
int obj_id; PyObject * link;
Object * object;
printf ("In setScriptLinks (id=?, event=%d)\n", event); int obj_id;
if (!g_blenderdict)
{
/* Not initialized yet. This can happen at first file load. */
return;
}
obj_id = MAKE_ID2 (id->name[0], id->name[1]); obj_id = MAKE_ID2 (id->name[0], id->name[1]);
if (obj_id == ID_SCE) printf ("In setScriptLinks (id=%s, event=%d)\n",id->name, event);
switch (obj_id)
{ {
Py_INCREF(Py_None); case ID_OB:
link = Py_None; 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 (scriptlink == NULL)
{
/* This is probably not an internal error anymore :)
TODO: Check this
printf ("Internal error, unable to create PyBlock for script link\n");
*/
Py_INCREF(Py_False);
PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
return NULL;
} }
else else
{ {
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); */
}
if (!link)
{
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 {
Py_INCREF(Py_True); Py_INCREF(Py_True);
PyDict_SetItemString(g_blenderdict, "bylink", Py_True); PyDict_SetItemString(g_blenderdict, "bylink", Py_True);
} }
@@ -127,4 +125,6 @@ void setScriptLinks(ID *id, short event)
PyDict_SetItemString(g_blenderdict, "link", link); PyDict_SetItemString(g_blenderdict, "link", link);
PyDict_SetItemString(g_blenderdict, "event", PyDict_SetItemString(g_blenderdict, "event",
Py_BuildValue("s", event_to_name(event))); Py_BuildValue("s", event_to_name(event)));
return (scriptlink);
} }

View File

@@ -32,4 +32,4 @@
#include <DNA_ID.h> #include <DNA_ID.h>
void initBlenderApi2_2x (void); void initBlenderApi2_2x (void);
void setScriptLinks(ID *id, short event); ScriptLink * setScriptLinks(ID *id, short event);