Extra generic errors for Scene, Groups and Metaballs to raise errors when trying to do anything with a python objects thats had its data removed in Blender.
Added to existing scn.objects scn.objects.active (get/set the active object for the scene) scn.objects.selected - an iterator that only uses selected objects scn.objects.context - an iterator on objects in the user context (visible in the current 3d views layer and selected) These are the same type as scn.objects but .add() .remove() .new() .active etc raise errors. so scn.objects.selected.add() will raise an error. Made nested loops possible with scn.objects, metaball.elements and ob.modifiers, by initializing the iter value as NULL and creating copys of the pyobject when _getIter() is called if ->iter is not NULL. This is how pythons xrange() works.
This commit is contained in:
@@ -48,6 +48,9 @@
|
||||
#include "Object.h"
|
||||
#include "gen_utils.h"
|
||||
|
||||
/* checks for the group being removed */
|
||||
#define GROUP_DEL_CHECK_PY(bpy_group) if (!(bpy_group->group)) return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, "Group has been removed" ) )
|
||||
#define GROUP_DEL_CHECK_INT(bpy_group) if (!(bpy_group->group)) return ( EXPP_ReturnIntError( PyExc_RuntimeError, "Group has been removed" ) )
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python API function prototypes for the Blender module. */
|
||||
@@ -56,6 +59,8 @@ static PyObject *M_Group_New( PyObject * self, PyObject * args );
|
||||
PyObject *M_Group_Get( PyObject * self, PyObject * args );
|
||||
PyObject *M_Group_Unlink( PyObject * self, PyObject * args );
|
||||
|
||||
/* internal */
|
||||
static PyObject *GroupObSeq_CreatePyObject( BPy_Group *self, GroupObject *iter );
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python method structure definition for Blender.Object module: */
|
||||
@@ -86,41 +91,38 @@ static PyMethodDef BPy_Group_methods[] = {
|
||||
|
||||
static PyObject *BPy_Group_copy( BPy_Group * self )
|
||||
{
|
||||
BPy_Group *py_group; /* for Group Data object wrapper in Python */
|
||||
struct Group *bl_group;
|
||||
GroupObject *group_ob, *group_ob_new; /* Group object, copied and added to the groups */
|
||||
|
||||
if( !(self->group) ) {
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Group was deleted!" );
|
||||
} else {
|
||||
BPy_Group *py_group; /* for Group Data object wrapper in Python */
|
||||
struct Group *bl_group;
|
||||
GroupObject *group_ob, *group_ob_new; /* Group object, copied and added to the groups */
|
||||
|
||||
bl_group= add_group();
|
||||
|
||||
if( bl_group ) /* now create the wrapper grp in Python */
|
||||
py_group = ( BPy_Group * ) Group_CreatePyObject( bl_group );
|
||||
else
|
||||
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"couldn't create Group Data in Blender" ) );
|
||||
|
||||
rename_id( &bl_group->id, self->group->id.name + 2 );
|
||||
|
||||
|
||||
/* user count be incremented in Group_CreatePyObject */
|
||||
bl_group->id.us = 0;
|
||||
|
||||
/* Now add the objects to the group */
|
||||
group_ob= self->group->gobject.first;
|
||||
while(group_ob) {
|
||||
/* save time by not using */
|
||||
group_ob_new= MEM_callocN(sizeof(GroupObject), "groupobject");
|
||||
group_ob_new->ob= group_ob->ob;
|
||||
BLI_addtail( &bl_group->gobject, group_ob_new);
|
||||
group_ob= group_ob->next;
|
||||
}
|
||||
|
||||
return ( PyObject * ) py_group;
|
||||
GROUP_DEL_CHECK_PY(self);
|
||||
|
||||
bl_group= add_group();
|
||||
|
||||
if( bl_group ) /* now create the wrapper grp in Python */
|
||||
py_group = ( BPy_Group * ) Group_CreatePyObject( bl_group );
|
||||
else
|
||||
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"couldn't create Group Data in Blender" ) );
|
||||
|
||||
rename_id( &bl_group->id, self->group->id.name + 2 );
|
||||
|
||||
|
||||
/* user count be incremented in Group_CreatePyObject */
|
||||
bl_group->id.us = 0;
|
||||
|
||||
/* Now add the objects to the group */
|
||||
group_ob= self->group->gobject.first;
|
||||
while(group_ob) {
|
||||
/* save time by not using */
|
||||
group_ob_new= MEM_callocN(sizeof(GroupObject), "groupobject");
|
||||
group_ob_new->ob= group_ob->ob;
|
||||
BLI_addtail( &bl_group->gobject, group_ob_new);
|
||||
group_ob= group_ob->next;
|
||||
}
|
||||
|
||||
return ( PyObject * ) py_group;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -131,9 +133,7 @@ static PyObject *BPy_Group_copy( BPy_Group * self )
|
||||
************************************************************************/
|
||||
static PyObject *Group_getObjects( BPy_Group * self )
|
||||
{
|
||||
BPy_GroupObSeq *seq = PyObject_NEW( BPy_GroupObSeq, &GroupObSeq_Type);
|
||||
seq->bpygroup = self; Py_INCREF(self);
|
||||
return (PyObject *)seq;
|
||||
return GroupObSeq_CreatePyObject(self, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +158,8 @@ static int Group_setObjects( BPy_Group * self, PyObject * args )
|
||||
Object *blen_ob;
|
||||
group= self->group;
|
||||
|
||||
GROUP_DEL_CHECK_INT(self);
|
||||
|
||||
if( PyList_Check( args ) ) {
|
||||
if( EXPP_check_sequence_consistency( args, &Object_Type ) != 1)
|
||||
return ( EXPP_ReturnIntError( PyExc_TypeError,
|
||||
@@ -170,11 +172,6 @@ static int Group_setObjects( BPy_Group * self, PyObject * args )
|
||||
blen_ob= ((BPy_Object *)PyList_GET_ITEM( args, i ))->object;
|
||||
add_to_group_wraper(group, blen_ob);
|
||||
}
|
||||
/*
|
||||
} else if( args->ob_type == &GroupObSeq_Type ) {
|
||||
*/
|
||||
/* todo, handle sequences here */
|
||||
|
||||
} else if (PyIter_Check(args)) {
|
||||
PyObject *iterator = PyObject_GetIter(args);
|
||||
PyObject *item;
|
||||
@@ -224,9 +221,7 @@ static int Group_setName( BPy_Group * self, PyObject * value )
|
||||
char *name = NULL;
|
||||
char buf[21];
|
||||
|
||||
if( !(self->group) )
|
||||
return EXPP_ReturnIntError( PyExc_RuntimeError,
|
||||
"Blender Group was deleted!" );
|
||||
GROUP_DEL_CHECK_INT(self);
|
||||
|
||||
name = PyString_AsString ( value );
|
||||
if( !name )
|
||||
@@ -244,9 +239,7 @@ static int Group_setName( BPy_Group * self, PyObject * value )
|
||||
static PyObject *Group_getName( BPy_Group * self, PyObject * args )
|
||||
{
|
||||
PyObject *attr;
|
||||
if( !(self->group) )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Group was deleted!" ) );
|
||||
GROUP_DEL_CHECK_PY(self);
|
||||
|
||||
attr = PyString_FromString( self->group->id.name + 2 );
|
||||
|
||||
@@ -488,11 +481,10 @@ PyObject *M_Group_Unlink( PyObject * self, PyObject * args )
|
||||
"expected a group" ) );
|
||||
|
||||
pygrp= (BPy_Group *)pyob;
|
||||
group= pygrp->group;
|
||||
|
||||
if( !group )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Group was deleted!" ) );
|
||||
GROUP_DEL_CHECK_PY(pygrp);
|
||||
|
||||
group= pygrp->group;
|
||||
|
||||
pygrp->group= NULL;
|
||||
free_group(group);
|
||||
@@ -625,6 +617,9 @@ static int Group_compare( BPy_Group * a, BPy_Group * b )
|
||||
/*****************************************************************************/
|
||||
static PyObject *Group_repr( BPy_Group * self )
|
||||
{
|
||||
if (!self->group)
|
||||
return PyString_FromString( "[Group - Removed]" );
|
||||
|
||||
return PyString_FromFormat( "[Group \"%s\"]",
|
||||
self->group->id.name + 2 );
|
||||
}
|
||||
@@ -639,12 +634,34 @@ static PyObject *Group_repr( BPy_Group * self )
|
||||
* create a thin GroupOb object
|
||||
*/
|
||||
|
||||
static PyObject *GroupObSeq_CreatePyObject( Group *group, int i )
|
||||
static PyObject *GroupObSeq_CreatePyObject( BPy_Group *self, GroupObject *iter )
|
||||
{
|
||||
BPy_GroupObSeq *seq = PyObject_NEW( BPy_GroupObSeq, &GroupObSeq_Type);
|
||||
seq->bpygroup = self; Py_INCREF(self);
|
||||
seq->iter= iter;
|
||||
return (PyObject *)seq;
|
||||
}
|
||||
|
||||
|
||||
static int GroupObSeq_len( BPy_GroupObSeq * self )
|
||||
{
|
||||
GROUP_DEL_CHECK_INT(self->bpygroup);
|
||||
return BLI_countlist( &( self->bpygroup->group->gobject ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* retrive a single GroupOb from somewhere in the GroupObex list
|
||||
*/
|
||||
|
||||
static PyObject *GroupObSeq_item( BPy_GroupObSeq * self, int i )
|
||||
{
|
||||
Group *group= self->bpygroup->group;
|
||||
int index=0;
|
||||
PyObject *bpy_obj;
|
||||
GroupObject *gob;
|
||||
|
||||
GROUP_DEL_CHECK_PY(self->bpygroup);
|
||||
|
||||
for (gob= group->gobject.first; gob && i!=index; gob= gob->next, index++) {}
|
||||
|
||||
if (!(gob))
|
||||
@@ -658,21 +675,7 @@ static PyObject *GroupObSeq_CreatePyObject( Group *group, int i )
|
||||
"PyObject_New() failed" );
|
||||
|
||||
return (PyObject *)bpy_obj;
|
||||
}
|
||||
|
||||
|
||||
static int GroupObSeq_len( BPy_GroupObSeq * self )
|
||||
{
|
||||
return BLI_countlist( &( self->bpygroup->group->gobject ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* retrive a single GroupOb from somewhere in the GroupObex list
|
||||
*/
|
||||
|
||||
static PyObject *GroupObSeq_item( BPy_GroupObSeq * self, int i )
|
||||
{
|
||||
return GroupObSeq_CreatePyObject( self->bpygroup->group, i );
|
||||
|
||||
}
|
||||
|
||||
static PySequenceMethods GroupObSeq_as_sequence = {
|
||||
@@ -698,8 +701,14 @@ static PySequenceMethods GroupObSeq_as_sequence = {
|
||||
|
||||
static PyObject *GroupObSeq_getIter( BPy_GroupObSeq * self )
|
||||
{
|
||||
self->iter = self->bpygroup->group->gobject.first;
|
||||
return EXPP_incr_ret ( (PyObject *) self );
|
||||
GROUP_DEL_CHECK_PY(self->bpygroup);
|
||||
|
||||
if (!self->iter) {
|
||||
self->iter = self->bpygroup->group->gobject.first;
|
||||
return EXPP_incr_ret ( (PyObject *) self );
|
||||
} else {
|
||||
return GroupObSeq_CreatePyObject(self->bpygroup->group, self->bpygroup->group->gobject.first);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -724,6 +733,9 @@ static PyObject *GroupObSeq_add( BPy_GroupObSeq * self, PyObject *args )
|
||||
PyObject *pyobj;
|
||||
Object *blen_ob;
|
||||
Base *base= NULL;
|
||||
|
||||
GROUP_DEL_CHECK_PY(self->bpygroup);
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!", &Object_Type, &pyobj ) )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"expected a python object as an argument" ) );
|
||||
@@ -745,9 +757,7 @@ static PyObject *GroupObSeq_remove( BPy_GroupObSeq * self, PyObject *args )
|
||||
Object *blen_ob;
|
||||
Base *base= NULL;
|
||||
|
||||
if( !(self->bpygroup->group) )
|
||||
return (EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Group was deleted!" ));
|
||||
GROUP_DEL_CHECK_PY(self->bpygroup);
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!", &Object_Type, &pyobj ) )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
|
||||
@@ -726,14 +726,21 @@ static PyObject *Metaball_copy( BPy_Metaball * self )
|
||||
return ( PyObject * ) pymball;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *MetaElemSeq_CreatePyObject(PyObject *self, MetaElem *iter)
|
||||
{
|
||||
BPy_MetaElemSeq *seq = PyObject_NEW( BPy_MetaElemSeq, &MetaElemSeq_Type);
|
||||
seq->bpymetaball = self; Py_INCREF(self);
|
||||
seq->iter= iter;
|
||||
return (PyObject *)seq;
|
||||
}
|
||||
|
||||
/*
|
||||
* Element, get an instance of the iterator.
|
||||
*/
|
||||
static PyObject *Metaball_getElements( BPy_Metaball * self )
|
||||
{
|
||||
BPy_MetaElemSeq *seq = PyObject_NEW( BPy_MetaElemSeq, &MetaElemSeq_Type);
|
||||
seq->bpymetaball = self; Py_INCREF(self);
|
||||
return (PyObject *)seq;
|
||||
return MetaElemSeq_CreatePyObject(self, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1016,8 +1023,11 @@ static PySequenceMethods MetaElemSeq_as_sequence = {
|
||||
|
||||
static PyObject *MetaElemSeq_getIter( BPy_MetaElemSeq * self )
|
||||
{
|
||||
self->iter = self->bpymetaball->metaball->elems.first;
|
||||
return EXPP_incr_ret ( (PyObject *) self );
|
||||
if (!self->iter) { /* not alredy looping on this data, */
|
||||
self->iter = self->bpymetaball->metaball->elems.first;
|
||||
return EXPP_incr_ret ( (PyObject *) self );
|
||||
} else
|
||||
return MetaElemSeq_CreatePyObject(self->bpymetaball, self->bpymetaball->metaball->elems.first);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1027,9 +1037,11 @@ static PyObject *MetaElemSeq_getIter( BPy_MetaElemSeq * self )
|
||||
static PyObject *MetaElemSeq_nextIter( BPy_MetaElemSeq * self )
|
||||
{
|
||||
PyObject *object;
|
||||
if( !(self->iter) || !(self->bpymetaball->metaball) )
|
||||
if( !(self->iter) || !(self->bpymetaball->metaball) ) {
|
||||
self->iter= NULL;
|
||||
return EXPP_ReturnPyObjError( PyExc_StopIteration,
|
||||
"iterator at end" );
|
||||
}
|
||||
|
||||
object= MetaElem_CreatePyObject( self->iter );
|
||||
self->iter= self->iter->next;
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/* TODO, accessing a modifier sequence of a deleted object will crash blender at the moment, not sure how to fix this. */
|
||||
|
||||
|
||||
#include "Modifier.h" /*This must come first*/
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
@@ -48,6 +51,10 @@
|
||||
#include "Mathutils.h"
|
||||
#include "gen_utils.h"
|
||||
|
||||
/* checks for the scene being removed */
|
||||
#define MODIFIER_DEL_CHECK_PY(bpy_modifier) if (!(bpy_modifier->md)) return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, "Modifier has been removed" ) )
|
||||
#define MODIFIER_DEL_CHECK_INT(bpy_modifier) if (!(bpy_modifier->md)) return ( EXPP_ReturnIntError( PyExc_RuntimeError, "Modifier has been removed" ) )
|
||||
|
||||
enum mod_constants {
|
||||
/*Apply to all modifiers*/
|
||||
EXPP_MOD_RENDER = 0,
|
||||
@@ -252,10 +259,7 @@ PyTypeObject Modifier_Type = {
|
||||
|
||||
static PyObject *Modifier_getName( BPy_Modifier * self )
|
||||
{
|
||||
if (self->md==NULL)
|
||||
return (EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"This modifier has been removed!" ));
|
||||
|
||||
MODIFIER_DEL_CHECK_PY(self);
|
||||
return PyString_FromString( self->md->name );
|
||||
}
|
||||
|
||||
@@ -269,9 +273,7 @@ static int Modifier_setName( BPy_Modifier * self, PyObject * attr )
|
||||
if( !name )
|
||||
return EXPP_ReturnIntError( PyExc_TypeError, "expected string arg" );
|
||||
|
||||
if (self->md==NULL)
|
||||
return (EXPP_ReturnIntError( PyExc_RuntimeError,
|
||||
"This modifier has been removed!" ));
|
||||
MODIFIER_DEL_CHECK_INT(self);
|
||||
|
||||
BLI_strncpy( self->md->name, name, sizeof( self->md->name ) );
|
||||
|
||||
@@ -284,9 +286,7 @@ static int Modifier_setName( BPy_Modifier * self, PyObject * attr )
|
||||
|
||||
static PyObject *Modifier_getType( BPy_Modifier * self )
|
||||
{
|
||||
if (self->md==NULL )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"This modifier has been removed!" );
|
||||
MODIFIER_DEL_CHECK_PY(self);
|
||||
|
||||
return PyInt_FromLong( self->md->type );
|
||||
}
|
||||
@@ -729,9 +729,7 @@ static PyObject *Modifier_getData( BPy_Modifier * self, PyObject * key )
|
||||
return EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"expected an int arg as stored in Blender.Modifier.Settings" );
|
||||
|
||||
if (self->md==NULL )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"This modifier has been removed!" );
|
||||
MODIFIER_DEL_CHECK_PY(self);
|
||||
|
||||
setting = PyInt_AsLong( key );
|
||||
switch( setting ) {
|
||||
@@ -784,9 +782,7 @@ static int Modifier_setData( BPy_Modifier * self, PyObject * key,
|
||||
return EXPP_ReturnIntError( PyExc_TypeError,
|
||||
"expected an int arg as stored in Blender.Modifier.Settings" );
|
||||
|
||||
if (self->md==NULL )
|
||||
return EXPP_ReturnIntError( PyExc_RuntimeError,
|
||||
"This modifier has been removed!" );
|
||||
MODIFIER_DEL_CHECK_INT(self);
|
||||
|
||||
key_int = PyInt_AsLong( key );
|
||||
|
||||
@@ -910,8 +906,12 @@ ModifierData *Modifier_FromPyObject( PyObject * pyobj )
|
||||
|
||||
static PyObject *Modifiers_getIter( BPy_Modifiers * self )
|
||||
{
|
||||
self->iter = (ModifierData *)self->obj->modifiers.first;
|
||||
return EXPP_incr_ret ( (PyObject *) self );
|
||||
if (!self->iter) {
|
||||
self->iter = (ModifierData *)self->obj->modifiers.first;
|
||||
return EXPP_incr_ret ( (PyObject *) self );
|
||||
} else {
|
||||
return ModSeq_CreatePyObject(self->obj, (ModifierData *)self->obj->modifiers.first);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -920,12 +920,13 @@ static PyObject *Modifiers_getIter( BPy_Modifiers * self )
|
||||
|
||||
static PyObject *Modifiers_nextIter( BPy_Modifiers * self )
|
||||
{
|
||||
ModifierData *this = self->iter;
|
||||
if( this ) {
|
||||
self->iter = this->next;
|
||||
return Modifier_CreatePyObject( self->obj, this );
|
||||
ModifierData *iter = self->iter;
|
||||
if( iter ) {
|
||||
self->iter = iter->next;
|
||||
return Modifier_CreatePyObject( self->obj, iter );
|
||||
}
|
||||
|
||||
|
||||
self->iter= NULL; /* mark as not iterating */
|
||||
return EXPP_ReturnPyObjError( PyExc_StopIteration,
|
||||
"iterator at end" );
|
||||
}
|
||||
@@ -1195,7 +1196,7 @@ PyTypeObject Modifiers_Type = {
|
||||
/* Description: This function will create a new BPy_Modifiers from an */
|
||||
/* existing ListBase structure. */
|
||||
/*****************************************************************************/
|
||||
PyObject *ModSeq_CreatePyObject( Object *obj )
|
||||
PyObject *ModSeq_CreatePyObject( Object *obj, ModifierData *iter )
|
||||
{
|
||||
BPy_Modifiers *pymod;
|
||||
pymod = ( BPy_Modifiers * ) PyObject_NEW( BPy_Modifiers, &Modifiers_Type );
|
||||
@@ -1203,6 +1204,7 @@ PyObject *ModSeq_CreatePyObject( Object *obj )
|
||||
return EXPP_ReturnPyObjError( PyExc_MemoryError,
|
||||
"couldn't create BPy_Modifiers object" );
|
||||
pymod->obj = obj;
|
||||
pymod->iter = iter;
|
||||
return ( PyObject * ) pymod;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,6 @@ typedef struct {
|
||||
ModifierData *iter;
|
||||
} BPy_Modifiers;
|
||||
|
||||
PyObject *ModSeq_CreatePyObject( Object *obj );
|
||||
PyObject *ModSeq_CreatePyObject( Object *obj, ModifierData *iter );
|
||||
|
||||
#endif /* EXPP_MODIFIER_H */
|
||||
|
||||
@@ -2945,7 +2945,7 @@ static PyObject *Object_getConstraints( BPy_Object * self )
|
||||
|
||||
static PyObject *Object_getModifiers( BPy_Object * self )
|
||||
{
|
||||
return ModSeq_CreatePyObject( self->object );
|
||||
return ModSeq_CreatePyObject( self->object, NULL );
|
||||
}
|
||||
|
||||
static PyObject *Object_insertShapeKey(BPy_Object * self)
|
||||
|
||||
@@ -80,6 +80,11 @@ PyObject *M_Object_Get( PyObject * self, PyObject * args ); /* from Object.c */
|
||||
#define EXPP_SCENE_FRAME_MAX 30000
|
||||
#define EXPP_SCENE_RENDER_WINRESOLUTION_MIN 4
|
||||
#define EXPP_SCENE_RENDER_WINRESOLUTION_MAX 10000
|
||||
|
||||
/* checks for the scene being removed */
|
||||
#define SCENE_DEL_CHECK_PY(bpy_scene) if (!(bpy_scene->scene)) return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, "Scene has been removed" ) )
|
||||
#define SCENE_DEL_CHECK_INT(bpy_scene) if (!(bpy_scene->scene)) return ( EXPP_ReturnIntError( PyExc_RuntimeError, "Scene has been removed" ) )
|
||||
|
||||
/*-----------------------Python API function prototypes for the Scene module--*/
|
||||
static PyObject *M_Scene_New( PyObject * self, PyObject * args,
|
||||
PyObject * keywords );
|
||||
@@ -141,6 +146,10 @@ static int Scene_setAttr( BPy_Scene * self, char *name, PyObject * v );
|
||||
static int Scene_compare( BPy_Scene * a, BPy_Scene * b );
|
||||
static PyObject *Scene_getAttr( BPy_Scene * self, char *name );
|
||||
static PyObject *Scene_repr( BPy_Scene * self );
|
||||
|
||||
/*object seq*/
|
||||
static PyObject *SceneObSeq_CreatePyObject( BPy_Scene *self, Base *iter, int mode);
|
||||
|
||||
/*-----------------------BPy_Scene method def------------------------------*/
|
||||
static PyMethodDef BPy_Scene_methods[] = {
|
||||
/* name, method, flags, doc */
|
||||
@@ -270,10 +279,7 @@ static void Scene_dealloc( BPy_Scene * self )
|
||||
static PyObject *Scene_getAttr( BPy_Scene * self, char *name )
|
||||
{
|
||||
PyObject *attr = Py_None;
|
||||
|
||||
if( !(self->scene) )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
if( strcmp( name, "name" ) == 0 )
|
||||
attr = PyString_FromString( self->scene->id.name + 2 );
|
||||
@@ -306,10 +312,7 @@ static int Scene_setAttr( BPy_Scene * self, char *name, PyObject * value )
|
||||
PyObject *valtuple;
|
||||
PyObject *error = NULL;
|
||||
|
||||
if( !(self->scene) )
|
||||
return EXPP_ReturnIntError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
|
||||
SCENE_DEL_CHECK_INT(self);
|
||||
|
||||
/* We're playing a trick on the Python API users here. Even if they use
|
||||
* Scene.member = val instead of Scene.setMember(val), we end up using the
|
||||
@@ -361,7 +364,7 @@ static int Scene_compare( BPy_Scene * a, BPy_Scene * b )
|
||||
static PyObject *Scene_repr( BPy_Scene * self )
|
||||
{
|
||||
if( !(self->scene) )
|
||||
return PyString_FromString( "[Scene Unlinked]");
|
||||
return PyString_FromString( "[Scene - Removed]");
|
||||
else
|
||||
return PyString_FromFormat( "[Scene \"%s\"]",
|
||||
self->scene->id.name + 2 );
|
||||
@@ -537,9 +540,7 @@ static PyObject *M_Scene_Unlink( PyObject * self, PyObject * args )
|
||||
pyscn = (BPy_Scene *)pyobj;
|
||||
scene = pyscn->scene;
|
||||
|
||||
if (!(scene))
|
||||
return EXPP_ReturnPyObjError( PyExc_SystemError,
|
||||
"scene has alredy been removed!" );
|
||||
SCENE_DEL_CHECK_PY(pyscn);
|
||||
|
||||
if( scene == G.scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_SystemError,
|
||||
@@ -547,16 +548,19 @@ static PyObject *M_Scene_Unlink( PyObject * self, PyObject * args )
|
||||
|
||||
free_libblock( &G.main->scene, scene );
|
||||
|
||||
pyscn->scene=NULL;
|
||||
Py_INCREF( Py_None );
|
||||
return Py_None;
|
||||
pyscn->scene= NULL;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*-----------------------BPy_Scene function defintions-------------------*/
|
||||
/*-----------------------Scene.getName()---------------------------------*/
|
||||
static PyObject *Scene_getName( BPy_Scene * self )
|
||||
{
|
||||
PyObject *attr = PyString_FromString( self->scene->id.name + 2 );
|
||||
PyObject *attr;
|
||||
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
attr= PyString_FromString( self->scene->id.name + 2 );
|
||||
|
||||
if( attr )
|
||||
return attr;
|
||||
@@ -570,17 +574,18 @@ static PyObject *Scene_setName( BPy_Scene * self, PyObject * args )
|
||||
{
|
||||
char *name;
|
||||
char buf[21];
|
||||
|
||||
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
if( !PyArg_ParseTuple( args, "s", &name ) )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"expected string argument" ) );
|
||||
|
||||
|
||||
PyOS_snprintf( buf, sizeof( buf ), "%s", name );
|
||||
|
||||
rename_id( &self->scene->id, buf );
|
||||
|
||||
Py_INCREF( Py_None );
|
||||
return Py_None;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*-----------------------Scene.getLayers()---------------------------------*/
|
||||
@@ -588,7 +593,9 @@ static PyObject *Scene_getLayers( BPy_Scene * self )
|
||||
{
|
||||
PyObject *laylist = PyList_New( 0 ), *item;
|
||||
int layers, bit = 0, val = 0;
|
||||
|
||||
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
if( !laylist )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
|
||||
"couldn't create pylist!" ) );
|
||||
@@ -612,7 +619,9 @@ static PyObject *Scene_setLayers( BPy_Scene * self, PyObject * args )
|
||||
{
|
||||
PyObject *list = NULL, *item = NULL;
|
||||
int layers = 0, val, i, len_list;
|
||||
|
||||
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!", &PyList_Type, &list ) )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"expected a list of integers in the range [1, 20]" ) );
|
||||
@@ -654,14 +663,16 @@ static PyObject *Scene_setLayers( BPy_Scene * self, PyObject * args )
|
||||
}
|
||||
}
|
||||
|
||||
return EXPP_incr_ret(Py_None);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/* only used by setAttr */
|
||||
static PyObject *Scene_setLayersMask(BPy_Scene *self, PyObject *args)
|
||||
{
|
||||
int laymask = 0;
|
||||
|
||||
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
if (!PyArg_ParseTuple(args , "i", &laymask)) {
|
||||
return EXPP_ReturnPyObjError( PyExc_AttributeError,
|
||||
"expected an integer (bitmask) as argument" );
|
||||
@@ -688,7 +699,7 @@ static PyObject *Scene_setLayersMask(BPy_Scene *self, PyObject *args)
|
||||
}
|
||||
}
|
||||
|
||||
return EXPP_incr_ret(Py_None);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*-----------------------Scene.copy()------------------------------------*/
|
||||
@@ -697,9 +708,7 @@ static PyObject *Scene_copy( BPy_Scene * self, PyObject * args )
|
||||
short dup_objs = 1;
|
||||
Scene *scene = self->scene;
|
||||
|
||||
if( !scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
if( !PyArg_ParseTuple( args, "|h", &dup_objs ) )
|
||||
return EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
@@ -712,14 +721,15 @@ static PyObject *Scene_copy( BPy_Scene * self, PyObject * args )
|
||||
static PyObject *Scene_makeCurrent( BPy_Scene * self )
|
||||
{
|
||||
Scene *scene = self->scene;
|
||||
|
||||
if( scene ) {
|
||||
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
if( scene && scene != G.scene) {
|
||||
set_scene( scene );
|
||||
scene_update_for_newframe(scene, scene->lay);
|
||||
}
|
||||
|
||||
Py_INCREF( Py_None );
|
||||
return Py_None;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*-----------------------Scene.update()----------------------------------*/
|
||||
@@ -727,10 +737,8 @@ static PyObject *Scene_update( BPy_Scene * self, PyObject * args )
|
||||
{
|
||||
Scene *scene = self->scene;
|
||||
int full = 0;
|
||||
|
||||
if( !scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
if( !PyArg_ParseTuple( args, "|i", &full ) )
|
||||
return EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
@@ -752,8 +760,7 @@ static PyObject *Scene_update( BPy_Scene * self, PyObject * args )
|
||||
"0: to only sort scene elements (old behavior); or\n"
|
||||
"1: for a full update (regroups, does ipos, keys, etc.)" );
|
||||
|
||||
Py_INCREF( Py_None );
|
||||
return Py_None;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*-----------------------Scene.link()------------------------------------*/
|
||||
@@ -763,9 +770,7 @@ static PyObject *Scene_link( BPy_Scene * self, PyObject * args )
|
||||
BPy_Object *bpy_obj;
|
||||
Object *object = NULL;
|
||||
|
||||
if( !scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!", &Object_Type, &bpy_obj ) )
|
||||
return EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
@@ -817,8 +822,7 @@ static PyObject *Scene_link( BPy_Scene * self, PyObject * args )
|
||||
BLI_addhead( &scene->base, base ); /* finally, link new base to scene */
|
||||
}
|
||||
|
||||
Py_INCREF( Py_None );
|
||||
return Py_None;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*-----------------------Scene.unlink()----------------------------------*/
|
||||
@@ -828,9 +832,7 @@ static PyObject *Scene_unlink( BPy_Scene * self, PyObject * args )
|
||||
Scene *scene = self->scene;
|
||||
Base *base;
|
||||
|
||||
if( !scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender scene was deleted!" );
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!", &Object_Type, &bpy_obj ) )
|
||||
return EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
@@ -857,9 +859,7 @@ static PyObject *Scene_getChildren( BPy_Scene * self )
|
||||
Object *object;
|
||||
Base *base;
|
||||
|
||||
if( !scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
base = scene->base.first;
|
||||
|
||||
@@ -888,9 +888,7 @@ static PyObject *Scene_getActiveObject(BPy_Scene *self)
|
||||
PyObject *pyob;
|
||||
Object *ob;
|
||||
|
||||
if (!scene)
|
||||
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!");
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
ob = ((scene->basact) ? (scene->basact->object) : 0);
|
||||
|
||||
@@ -904,7 +902,7 @@ static PyObject *Scene_getActiveObject(BPy_Scene *self)
|
||||
return pyob;
|
||||
}
|
||||
|
||||
return EXPP_incr_ret(Py_None); /* no active object */
|
||||
Py_RETURN_NONE; /* no active object */
|
||||
}
|
||||
|
||||
/*-----------------------Scene.getCurrentCamera()------------------------*/
|
||||
@@ -914,9 +912,7 @@ static PyObject *Scene_getCurrentCamera( BPy_Scene * self )
|
||||
PyObject *pyob;
|
||||
Scene *scene = self->scene;
|
||||
|
||||
if( !scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
cam_obj = scene->camera;
|
||||
|
||||
@@ -928,8 +924,7 @@ static PyObject *Scene_getCurrentCamera( BPy_Scene * self )
|
||||
return pyob;
|
||||
}
|
||||
|
||||
Py_INCREF( Py_None ); /* none found */
|
||||
return Py_None;
|
||||
Py_RETURN_NONE; /* none found */
|
||||
}
|
||||
|
||||
/*-----------------------Scene.setCurrentCamera()------------------------*/
|
||||
@@ -939,9 +934,7 @@ static PyObject *Scene_setCurrentCamera( BPy_Scene * self, PyObject * args )
|
||||
BPy_Object *cam_obj;
|
||||
Scene *scene = self->scene;
|
||||
|
||||
if( !scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!", &Object_Type, &cam_obj ) )
|
||||
return EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
@@ -961,26 +954,19 @@ static PyObject *Scene_setCurrentCamera( BPy_Scene * self, PyObject * args )
|
||||
/* XXX copy_view3d_lock(REDRAW) prints "bad call to addqueue: 0 (18, 1)".
|
||||
* The same happens in bpython. */
|
||||
|
||||
Py_INCREF( Py_None );
|
||||
return Py_None;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*-----------------------Scene.getRenderingContext()---------------------*/
|
||||
static PyObject *Scene_getRenderingContext( BPy_Scene * self )
|
||||
{
|
||||
if( !self->scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
return RenderData_CreatePyObject( self->scene );
|
||||
}
|
||||
|
||||
static PyObject *Scene_getRadiosityContext( BPy_Scene * self )
|
||||
{
|
||||
if( !self->scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
return Radio_CreatePyObject( self->scene );
|
||||
}
|
||||
|
||||
@@ -990,9 +976,7 @@ static PyObject *Scene_addScriptLink( BPy_Scene * self, PyObject * args )
|
||||
Scene *scene = self->scene;
|
||||
ScriptLink *slink = NULL;
|
||||
|
||||
if( !scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
slink = &( scene )->scriptlink;
|
||||
|
||||
@@ -1005,9 +989,7 @@ static PyObject *Scene_clearScriptLinks( BPy_Scene * self, PyObject * args )
|
||||
Scene *scene = self->scene;
|
||||
ScriptLink *slink = NULL;
|
||||
|
||||
if( !scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
slink = &( scene )->scriptlink;
|
||||
|
||||
@@ -1021,9 +1003,7 @@ static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * args )
|
||||
ScriptLink *slink = NULL;
|
||||
PyObject *ret = NULL;
|
||||
|
||||
if( !scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
slink = &( scene )->scriptlink;
|
||||
|
||||
@@ -1037,14 +1017,11 @@ static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * args )
|
||||
|
||||
static PyObject *Scene_play( BPy_Scene * self, PyObject * args )
|
||||
{
|
||||
Scene *scene = self->scene;
|
||||
int mode = 0, win = SPACE_VIEW3D;
|
||||
PyObject *ret = NULL;
|
||||
ScrArea *sa = NULL, *oldsa = curarea;
|
||||
|
||||
if( !scene )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" );
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
if( !PyArg_ParseTuple( args, "|ii", &mode, &win ) )
|
||||
return EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
@@ -1098,10 +1075,7 @@ static PyObject *Scene_getTimeLine( BPy_Scene *self )
|
||||
{
|
||||
BPy_TimeLine *tm;
|
||||
|
||||
if( !(self->scene) )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender scene was deleted!" );
|
||||
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
|
||||
tm= (BPy_TimeLine *) PyObject_NEW (BPy_TimeLine, &TimeLine_Type);
|
||||
if (!tm)
|
||||
@@ -1113,13 +1087,11 @@ static PyObject *Scene_getTimeLine( BPy_Scene *self )
|
||||
|
||||
return (PyObject *)tm;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *Scene_getObjects( BPy_Scene *self )
|
||||
/* accessed from scn.objects */
|
||||
static PyObject *Scene_getObjects( BPy_Scene *self)
|
||||
{
|
||||
BPy_SceneObSeq *seq = PyObject_NEW( BPy_SceneObSeq, &SceneObSeq_Type);
|
||||
seq->bpyscene = self; Py_INCREF(self);
|
||||
return (PyObject *)seq;
|
||||
SCENE_DEL_CHECK_PY(self);
|
||||
return SceneObSeq_CreatePyObject(self, NULL, 0);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
@@ -1131,13 +1103,83 @@ static PyObject *Scene_getObjects( BPy_Scene *self )
|
||||
* create a thin wrapper for the scenes objects
|
||||
*/
|
||||
|
||||
static PyObject *SceneObSeq_CreatePyObject( Scene *scene, int i )
|
||||
/* accessed from scn.objects.selected or scn.objects.context */
|
||||
static PyObject *SceneObSeq_getObjects( BPy_SceneObSeq *self, void *mode)
|
||||
{
|
||||
SCENE_DEL_CHECK_PY(self->bpyscene);
|
||||
return SceneObSeq_CreatePyObject(self->bpyscene, NULL, (int)((long)mode));
|
||||
}
|
||||
|
||||
|
||||
static PyObject *SceneObSeq_CreatePyObject( BPy_Scene *self, Base *iter, int mode )
|
||||
{
|
||||
BPy_SceneObSeq *seq = PyObject_NEW( BPy_SceneObSeq, &SceneObSeq_Type);
|
||||
seq->bpyscene = self; Py_INCREF(self);
|
||||
seq->iter = iter;
|
||||
seq->mode = mode;
|
||||
return (PyObject *)seq;
|
||||
}
|
||||
|
||||
static int SceneObSeq_len( BPy_SceneObSeq * self )
|
||||
{
|
||||
Scene *scene= self->bpyscene->scene;
|
||||
SCENE_DEL_CHECK_PY(self->bpyscene);
|
||||
|
||||
if (self->mode == 0) /* all obejcts */
|
||||
return BLI_countlist( &( scene->base ) );
|
||||
else if (self->mode == 1) { /* selected obejcts */
|
||||
int len=0;
|
||||
Base *base;
|
||||
for (base= scene->base.first; base; base= base->next) {
|
||||
if (base->flag & SELECT) {
|
||||
len++;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
} else if (self->mode == 2) { /* user context */
|
||||
int len=0;
|
||||
Base *base;
|
||||
|
||||
if( G.vd == NULL ) /* No 3d view has been initialized yet, simply return an empty list */
|
||||
return 0;
|
||||
|
||||
for (base= scene->base.first; base; base= base->next) {
|
||||
if ((base->flag & SELECT) && (base->lay & G.vd->lay)) {
|
||||
len++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*should never run this */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* retrive a single Object from somewhere in the Object list
|
||||
*/
|
||||
|
||||
static PyObject *SceneObSeq_item( BPy_SceneObSeq * self, int i )
|
||||
{
|
||||
int index=0;
|
||||
PyObject *bpy_obj;
|
||||
Base *base;
|
||||
Base *base= NULL;
|
||||
Scene *scene= self->bpyscene->scene;
|
||||
|
||||
for (base= scene->base.first; base&& i!=index; base= base->next, index++) {}
|
||||
SCENE_DEL_CHECK_PY(self->bpyscene);
|
||||
|
||||
/* objects */
|
||||
if (self->mode==0)
|
||||
for (base= scene->base.first; base && i!=index; base= base->next, index++) {}
|
||||
/* selected */
|
||||
else if (self->mode==1)
|
||||
for (base= scene->base.first; base && i!=index; base= base->next)
|
||||
if (base->flag & SELECT)
|
||||
index++;
|
||||
/* context */
|
||||
else if (self->mode==2)
|
||||
if (G.vd)
|
||||
for (base= scene->base.first; base && i!=index; base= base->next)
|
||||
if ((base->flag & SELECT) && (base->lay & G.vd->lay))
|
||||
index++;
|
||||
|
||||
if (!(base))
|
||||
return EXPP_ReturnPyObjError( PyExc_IndexError,
|
||||
@@ -1152,20 +1194,6 @@ static PyObject *SceneObSeq_CreatePyObject( Scene *scene, int i )
|
||||
return (PyObject *)bpy_obj;
|
||||
}
|
||||
|
||||
static int SceneObSeq_len( BPy_SceneObSeq * self )
|
||||
{
|
||||
return BLI_countlist( &( self->bpyscene->scene->base ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* retrive a single MGroupOb from somewhere in the GroupObex list
|
||||
*/
|
||||
|
||||
static PyObject *SceneObSeq_item( BPy_SceneObSeq * self, int i )
|
||||
{
|
||||
return SceneObSeq_CreatePyObject( self->bpyscene->scene, i );
|
||||
}
|
||||
|
||||
static PySequenceMethods SceneObSeq_as_sequence = {
|
||||
( inquiry ) SceneObSeq_len, /* sq_length */
|
||||
( binaryfunc ) 0, /* sq_concat */
|
||||
@@ -1190,8 +1218,29 @@ static PySequenceMethods SceneObSeq_as_sequence = {
|
||||
|
||||
static PyObject *SceneObSeq_getIter( BPy_SceneObSeq * self )
|
||||
{
|
||||
self->iter = self->bpyscene->scene->base.first;
|
||||
return EXPP_incr_ret ( (PyObject *) self );
|
||||
/* we need to get the first base, but for selected context we may need to advance
|
||||
to the first selected or first conext base */
|
||||
Base *base= self->bpyscene->scene->base.first;
|
||||
|
||||
SCENE_DEL_CHECK_PY(self->bpyscene);
|
||||
|
||||
if (self->mode==1) /* selected */
|
||||
while (base && !(base->flag & SELECT))
|
||||
base= base->next;
|
||||
else if (self->mode==2) { /* context */
|
||||
if (!G.vd)
|
||||
base= NULL; /* will never iterate if we have no */
|
||||
else
|
||||
while (base && !((base->flag & SELECT) && (base->lay & G.vd->lay)))
|
||||
base= base->next;
|
||||
}
|
||||
/* create a new iterator if were alredy using this one */
|
||||
if (self->iter==NULL) {
|
||||
self->iter = base;
|
||||
return EXPP_incr_ret ( (PyObject *) self );
|
||||
} else {
|
||||
return SceneObSeq_CreatePyObject(self->bpyscene, base, self->mode);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1201,23 +1250,41 @@ static PyObject *SceneObSeq_getIter( BPy_SceneObSeq * self )
|
||||
static PyObject *SceneObSeq_nextIter( BPy_SceneObSeq * self )
|
||||
{
|
||||
PyObject *object;
|
||||
if( !(self->iter) || !(self->bpyscene->scene) )
|
||||
Base *base;
|
||||
if( !(self->iter) || !(self->bpyscene->scene) ) {
|
||||
self->iter= NULL;
|
||||
return EXPP_ReturnPyObjError( PyExc_StopIteration,
|
||||
"iterator at end" );
|
||||
}
|
||||
|
||||
object= Object_CreatePyObject( self->iter->object );
|
||||
self->iter= self->iter->next;
|
||||
base= self->iter->next;
|
||||
|
||||
if (self->mode==1) /* selected */
|
||||
while (base && !(base->flag & SELECT))
|
||||
base= base->next;
|
||||
else if (self->mode==2) { /* context */
|
||||
if (!G.vd)
|
||||
base= NULL; /* will never iterate if we have no */
|
||||
else
|
||||
while (base && !((base->flag & SELECT) && (base->lay & G.vd->lay)))
|
||||
base= base->next;
|
||||
}
|
||||
self->iter= base;
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *SceneObSeq_add( BPy_SceneObSeq * self, PyObject *pyobj )
|
||||
{
|
||||
if( !(self->bpyscene->scene) )
|
||||
return (EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" ));
|
||||
{
|
||||
SCENE_DEL_CHECK_PY(self->bpyscene);
|
||||
|
||||
/* this shold eventually replace Scene_link */
|
||||
if (self->mode != 0)
|
||||
return (EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"Cannot add to objects.selection or objects.context!" ));
|
||||
|
||||
return Scene_link(self->bpyscene, pyobj);
|
||||
}
|
||||
|
||||
@@ -1232,9 +1299,11 @@ static PyObject *SceneObSeq_new( BPy_SceneObSeq * self, PyObject *args )
|
||||
PyObject *py_data;
|
||||
Scene *scene= self->bpyscene->scene;
|
||||
|
||||
if( !(scene) )
|
||||
return (EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" ));
|
||||
SCENE_DEL_CHECK_PY(self->bpyscene);
|
||||
|
||||
if (self->mode != 0)
|
||||
return (EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"Cannot add new to objects.selection or objects.context!" ));
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O", &py_data ) )
|
||||
return EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
@@ -1368,9 +1437,11 @@ static PyObject *SceneObSeq_remove( BPy_SceneObSeq * self, PyObject *args )
|
||||
Object *blen_ob;
|
||||
Base *base= NULL;
|
||||
|
||||
if( !(self->bpyscene->scene) )
|
||||
return (EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"Blender Scene was deleted!" ));
|
||||
SCENE_DEL_CHECK_PY(self->bpyscene);
|
||||
|
||||
if (self->mode != 0)
|
||||
return (EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"Cannot add new to objects.selection or objects.context!" ));
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!", &Object_Type, &pyobj ) )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
@@ -1394,10 +1465,65 @@ static PyObject *SceneObSeq_remove( BPy_SceneObSeq * self, PyObject *args )
|
||||
MEM_freeN( base );
|
||||
self->bpyscene->scene->basact = 0; /* in case the object was selected */
|
||||
}
|
||||
return EXPP_incr_ret( Py_None );
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
PyObject *SceneObSeq_getActive(BPy_SceneObSeq *self)
|
||||
{
|
||||
PyObject *pyob;
|
||||
Base *base;
|
||||
|
||||
SCENE_DEL_CHECK_PY(self->bpyscene);
|
||||
|
||||
if (self->mode!=0)
|
||||
return (EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"cannot get active from objects.selected or objects.context" ));
|
||||
|
||||
base= self->bpyscene->scene->basact;
|
||||
if (!base)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
pyob = Object_CreatePyObject( base->object );
|
||||
|
||||
if (!pyob)
|
||||
return EXPP_ReturnPyObjError(PyExc_MemoryError,
|
||||
"couldn't create new object wrapper!");
|
||||
|
||||
return pyob;
|
||||
}
|
||||
|
||||
static int SceneObSeq_setActive(BPy_SceneObSeq *self, PyObject *value)
|
||||
{
|
||||
Base *base;
|
||||
|
||||
SCENE_DEL_CHECK_INT(self->bpyscene);
|
||||
|
||||
if (self->mode!=0)
|
||||
return (EXPP_ReturnIntError( PyExc_TypeError,
|
||||
"cannot set active from objects.selected or objects.context" ));
|
||||
|
||||
if (value==Py_None) {
|
||||
self->bpyscene->scene->basact= NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!BPy_Object_Check(value))
|
||||
return (EXPP_ReturnIntError( PyExc_ValueError,
|
||||
"Object or None types can only be assigned to active!" ));
|
||||
|
||||
base = object_in_scene( ((BPy_Object *)value)->object, self->bpyscene->scene );
|
||||
|
||||
if (!base)
|
||||
return (EXPP_ReturnIntError( PyExc_ValueError,
|
||||
"cannot assign an active object outside the scene." ));
|
||||
|
||||
self->bpyscene->scene->basact= base;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct PyMethodDef BPy_SceneObSeq_methods[] = {
|
||||
{"add", (PyCFunction)SceneObSeq_add, METH_VARARGS,
|
||||
"add object to the scene"},
|
||||
@@ -1420,6 +1546,48 @@ static void SceneObSeq_dealloc( BPy_SceneObSeq * self )
|
||||
PyObject_DEL( self );
|
||||
}
|
||||
|
||||
static int SceneObSeq_compare( BPy_SceneObSeq * a, BPy_SceneObSeq * b )
|
||||
{
|
||||
Scene *pa = a->bpyscene->scene, *pb = b->bpyscene->scene;
|
||||
return ( pa == pb && a->mode == b->mode) ? 0 : -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* repr function
|
||||
* callback functions building meaninful string to representations
|
||||
*/
|
||||
static PyObject *SceneObSeq_repr( BPy_SceneObSeq * self )
|
||||
{
|
||||
if( !(self->bpyscene->scene) )
|
||||
return PyString_FromFormat( "[Scene ObjectSeq Removed]" );
|
||||
else if (self->mode==1)
|
||||
return PyString_FromFormat( "[Scene ObjectSeq Selected \"%s\"]",
|
||||
self->bpyscene->scene->id.name + 2 );
|
||||
else if (self->mode==2)
|
||||
return PyString_FromFormat( "[Scene ObjectSeq Context \"%s\"]",
|
||||
self->bpyscene->scene->id.name + 2 );
|
||||
|
||||
/*self->mode==0*/
|
||||
return PyString_FromFormat( "[Scene ObjectSeq \"%s\"]",
|
||||
self->bpyscene->scene->id.name + 2 );
|
||||
}
|
||||
|
||||
static PyGetSetDef SceneObSeq_getseters[] = {
|
||||
{"selected",
|
||||
(getter)SceneObSeq_getObjects, (setter)NULL,
|
||||
"sequence of selected objects",
|
||||
(void *)1},
|
||||
{"context",
|
||||
(getter)SceneObSeq_getObjects, (setter)NULL,
|
||||
"sequence of user context objects",
|
||||
(void *)2},
|
||||
{"active",
|
||||
(getter)SceneObSeq_getActive, (setter)SceneObSeq_setActive,
|
||||
"active object",
|
||||
NULL},
|
||||
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python SceneObSeq_Type structure definition: */
|
||||
/*****************************************************************************/
|
||||
@@ -1437,8 +1605,8 @@ PyTypeObject SceneObSeq_Type = {
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
NULL, /* cmpfunc tp_compare; */
|
||||
NULL, /* reprfunc tp_repr; */
|
||||
( cmpfunc ) SceneObSeq_compare, /* cmpfunc tp_compare; */
|
||||
( reprfunc ) SceneObSeq_repr, /* reprfunc tp_repr; */
|
||||
|
||||
/* Method suites for standard classes */
|
||||
|
||||
@@ -1483,7 +1651,7 @@ PyTypeObject SceneObSeq_Type = {
|
||||
/*** Attribute descriptor and subclassing stuff ***/
|
||||
BPy_SceneObSeq_methods, /* struct PyMethodDef *tp_methods; */
|
||||
NULL, /* struct PyMemberDef *tp_members; */
|
||||
NULL, /* struct PyGetSetDef *tp_getset; */
|
||||
SceneObSeq_getseters, /* struct PyGetSetDef *tp_getset; */
|
||||
NULL, /* struct _typeobject *tp_base; */
|
||||
NULL, /* PyObject *tp_dict; */
|
||||
NULL, /* descrgetfunc tp_descr_get; */
|
||||
|
||||
@@ -57,6 +57,7 @@ typedef struct {
|
||||
PyObject_VAR_HEAD /* required python macro */
|
||||
BPy_Scene *bpyscene; /* link to the python scene so we can know if its been removed */
|
||||
Base *iter; /* so we can iterate over the objects */
|
||||
int mode; /*0:all objects, 1:selected objects, 2:user context*/
|
||||
} BPy_SceneObSeq;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user