2006-08-26 03:18:55 +00:00
/*
* * * * * * BEGIN GPL / BL DUAL LICENSE BLOCK * * * * *
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version . The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License . See http : //www.blender.org/BL/ for information
* about this .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*
* The Original Code is Copyright ( C ) 2001 - 2002 by NaN Holding BV .
* All rights reserved .
*
* This is a new part of Blender .
*
* Contributor ( s ) : Campbell Barton
*
* * * * * * END GPL / BL DUAL LICENSE BLOCK * * * * *
*/
2006-08-15 11:24:08 +00:00
# include "MEM_guardedalloc.h"
2006-03-18 14:47:26 +00:00
# include "Group.h" /* This must come first */
# include "DNA_group_types.h"
# include "DNA_scene_types.h" /* for Base */
# include "BKE_mesh.h"
# include "BKE_library.h"
# include "BKE_global.h"
# include "BKE_main.h"
# include "BKE_scene.h"
# include "BKE_group.h"
# include "BLI_blenlib.h"
# include "blendef.h"
# include "Object.h"
2006-03-19 04:45:58 +00:00
# include "gen_utils.h"
2006-03-18 15:23:02 +00:00
2006-09-24 08:30:38 +00:00
/* 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" ) )
2006-03-18 14:47:26 +00:00
/*****************************************************************************/
/* Python API function prototypes for the Blender module. */
/*****************************************************************************/
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 ) ;
2006-09-24 08:30:38 +00:00
/* internal */
static PyObject * GroupObSeq_CreatePyObject ( BPy_Group * self , GroupObject * iter ) ;
2006-03-18 14:47:26 +00:00
/*****************************************************************************/
/* Python method structure definition for Blender.Object module: */
/*****************************************************************************/
struct PyMethodDef M_Group_methods [ ] = {
{ " New " , ( PyCFunction ) M_Group_New , METH_VARARGS ,
2006-08-15 11:24:08 +00:00
" (name) Add a new empty group " } ,
2006-03-18 14:47:26 +00:00
{ " Get " , ( PyCFunction ) M_Group_Get , METH_VARARGS ,
2006-08-15 11:24:08 +00:00
" (name) - return the group with the name 'name', \
returns None if notfound . \ nIf ' name ' is not specified , it returns a list of all groups . " },
2006-03-18 14:47:26 +00:00
{ " Unlink " , ( PyCFunction ) M_Group_Unlink , METH_VARARGS ,
2006-08-15 11:24:08 +00:00
" (group) - Unlink (delete) this group from Blender. " } ,
2006-03-18 14:47:26 +00:00
{ NULL , NULL , 0 , NULL }
} ;
/*****************************************************************************/
/* Python BPy_Group methods table: */
/*****************************************************************************/
2006-08-15 11:24:08 +00:00
static PyObject * BPy_Group_copy ( BPy_Group * self ) ;
2006-03-18 14:47:26 +00:00
static PyMethodDef BPy_Group_methods [ ] = {
/* name, method, flags, doc */
2006-08-15 11:24:08 +00:00
{ " __copy__ " , ( PyCFunction ) BPy_Group_copy , METH_VARARGS ,
" () - Return a copy of the group containing the same objects. " } ,
2006-03-18 14:47:26 +00:00
{ NULL , NULL , 0 , NULL }
} ;
2006-08-15 11:24:08 +00:00
static PyObject * BPy_Group_copy ( BPy_Group * self )
{
2006-09-24 08:30:38 +00:00
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 */
2006-08-15 11:24:08 +00:00
2006-09-24 08:30:38 +00:00
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 ) ;
2006-11-02 23:05:10 +00:00
bl_group - > id . us = 1 ;
2006-09-24 08:30:38 +00:00
/* 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 ;
2006-08-15 11:24:08 +00:00
}
2006-09-24 08:30:38 +00:00
return ( PyObject * ) py_group ;
2006-08-15 11:24:08 +00:00
}
2006-03-18 14:47:26 +00:00
/************************************************************************
*
* Python BPy_Object attributes
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-08-27 16:27:34 +00:00
static PyObject * Group_getObjects ( BPy_Group * self )
2006-03-18 14:47:26 +00:00
{
2006-09-24 08:30:38 +00:00
return GroupObSeq_CreatePyObject ( self , NULL ) ;
2006-03-18 14:47:26 +00:00
}
2006-03-19 04:45:58 +00:00
2006-04-16 15:28:50 +00:00
static void add_to_group_wraper ( Group * group , Object * ob ) {
2006-03-19 04:45:58 +00:00
Base * base ;
add_to_group ( group , ob ) ;
if ( ! ( ob - > flag & OB_FROMGROUP ) ) { /* do this to avoid a listbase lookup */
ob - > flag | = OB_FROMGROUP ;
base = object_in_scene ( ob , G . scene ) ;
if ( base )
base - > flag | = OB_FROMGROUP ;
}
}
2006-03-18 15:23:02 +00:00
/* only for internal use Blender.Group.Get("MyGroup").objects= []*/
2006-08-27 16:27:34 +00:00
static int Group_setObjects ( BPy_Group * self , PyObject * args )
2006-03-18 14:47:26 +00:00
{
2006-03-19 04:45:58 +00:00
int i , list_size ;
2006-03-18 14:47:26 +00:00
Group * group ;
Object * blen_ob ;
2006-03-18 15:23:02 +00:00
group = self - > group ;
2006-09-24 08:30:38 +00:00
GROUP_DEL_CHECK_INT ( self ) ;
2006-03-18 14:47:26 +00:00
if ( PyList_Check ( args ) ) {
if ( EXPP_check_sequence_consistency ( args , & Object_Type ) ! = 1 )
2006-03-19 04:45:58 +00:00
return ( EXPP_ReturnIntError ( PyExc_TypeError ,
" expected a list of objects " ) ) ;
2006-03-18 14:47:26 +00:00
/* remove all from the list and add the new items */
free_group ( group ) ; /* unlink all objects from this group, keep the group */
2006-03-19 04:45:58 +00:00
list_size = PyList_Size ( args ) ;
for ( i = 0 ; i < list_size ; i + + ) {
2006-03-18 14:47:26 +00:00
blen_ob = ( ( BPy_Object * ) PyList_GET_ITEM ( args , i ) ) - > object ;
2006-03-19 04:45:58 +00:00
add_to_group_wraper ( group , blen_ob ) ;
2006-03-18 14:47:26 +00:00
}
2006-03-19 04:45:58 +00:00
} else if ( PyIter_Check ( args ) ) {
PyObject * iterator = PyObject_GetIter ( args ) ;
PyObject * item ;
if ( iterator = = NULL ) {
Py_DECREF ( iterator ) ;
return EXPP_ReturnIntError ( PyExc_TypeError ,
" expected a list of objects, This iterator cannot be used. " ) ;
}
free_group ( group ) ; /* unlink all objects from this group, keep the group */
2006-04-24 15:09:07 +00:00
item = PyIter_Next ( iterator ) ;
while ( item ) {
2006-03-19 04:45:58 +00:00
if ( PyObject_TypeCheck ( item , & Object_Type ) ) {
blen_ob = ( ( BPy_Object * ) item ) - > object ;
add_to_group_wraper ( group , blen_ob ) ;
}
Py_DECREF ( item ) ;
2006-04-24 15:09:07 +00:00
item = PyIter_Next ( iterator ) ;
2006-03-19 04:45:58 +00:00
}
Py_DECREF ( iterator ) ;
if ( PyErr_Occurred ( ) ) {
return EXPP_ReturnIntError ( PyExc_RuntimeError ,
" An unknown error occured while adding iterator objects to the group. \n The group has been modified. " ) ;
}
2006-03-18 14:47:26 +00:00
} else
return EXPP_ReturnIntError ( PyExc_TypeError ,
" expected a list or sequence of objects " ) ;
return 0 ;
}
/*****************************************************************************/
/* PythonTypeObject callback function prototypes */
/*****************************************************************************/
static void Group_dealloc ( BPy_Group * obj ) ;
static PyObject * Group_repr ( BPy_Group * obj ) ;
static int Group_compare ( BPy_Group * a , BPy_Group * b ) ;
/*****************************************************************************/
/* Python BPy_Group methods: */
/*****************************************************************************/
static int Group_setName ( BPy_Group * self , PyObject * value )
{
char * name = NULL ;
2006-09-24 08:30:38 +00:00
GROUP_DEL_CHECK_INT ( self ) ;
2006-03-18 14:47:26 +00:00
name = PyString_AsString ( value ) ;
if ( ! name )
return EXPP_ReturnIntError ( PyExc_TypeError ,
" expected string argument " ) ;
2006-12-27 05:04:20 +00:00
rename_id ( & self - > group - > id , name ) ;
2006-03-18 14:47:26 +00:00
return 0 ;
}
2006-12-26 07:00:32 +00:00
static PyObject * Group_getName ( BPy_Group * self )
2006-03-18 14:47:26 +00:00
{
2006-03-18 15:23:02 +00:00
PyObject * attr ;
2006-09-24 08:30:38 +00:00
GROUP_DEL_CHECK_PY ( self ) ;
2006-03-18 14:47:26 +00:00
2006-03-18 15:23:02 +00:00
attr = PyString_FromString ( self - > group - > id . name + 2 ) ;
2006-03-18 14:47:26 +00:00
if ( attr )
return attr ;
return ( EXPP_ReturnPyObjError ( PyExc_RuntimeError ,
" couldn't get Group.name attribute " ) ) ;
}
static PyObject * Group_getUsers ( BPy_Group * self )
{
2006-12-17 02:16:29 +00:00
GROUP_DEL_CHECK_PY ( self ) ;
2006-03-18 14:47:26 +00:00
return PyInt_FromLong ( self - > group - > id . us ) ;
}
2006-12-17 02:16:29 +00:00
static PyObject * Group_getFakeUser ( BPy_Group * self )
{
GROUP_DEL_CHECK_PY ( self ) ;
if ( self - > group - > id . flag & LIB_FAKEUSER )
Py_RETURN_TRUE ;
else
Py_RETURN_FALSE ;
}
2006-11-16 21:38:08 +00:00
2006-12-17 02:16:29 +00:00
static int Group_setFakeUser ( BPy_Group * self , PyObject * value )
{
2006-12-28 05:00:35 +00:00
GROUP_DEL_CHECK_INT ( self ) ;
2006-12-17 02:16:29 +00:00
return SetIdFakeUser ( & self - > group - > id , value ) ;
}
2006-11-16 21:38:08 +00:00
/*****************************************************************************/
/* Python BPy_Group methods: */
/*****************************************************************************/
static int Group_setLayers ( BPy_Group * self , PyObject * value )
{
unsigned int laymask = 0 ;
GROUP_DEL_CHECK_INT ( self ) ;
if ( ! PyInt_CheckExact ( value ) )
return EXPP_ReturnIntError ( PyExc_TypeError ,
" expected an integer (bitmask) as argument " ) ;
laymask = ( unsigned int ) PyInt_AS_LONG ( value ) ;
if ( laymask < = 0 )
return EXPP_ReturnIntError ( PyExc_ValueError ,
" layer value cannot be zero or below " ) ;
self - > group - > layer = laymask & ( ( 1 < < 20 ) - 1 ) ;
return 0 ;
}
static PyObject * Group_getLayers ( BPy_Group * self )
{
return PyInt_FromLong ( self - > group - > layer ) ;
}
2006-03-18 14:47:26 +00:00
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef BPy_Group_getseters [ ] = {
{ " name " ,
( getter ) Group_getName , ( setter ) Group_setName ,
" Group name " ,
NULL } ,
{ " users " ,
( getter ) Group_getUsers , ( setter ) NULL ,
" Number of group users " ,
NULL } ,
2006-12-17 02:16:29 +00:00
{ " fakeUser " ,
( getter ) Group_getFakeUser , ( setter ) Group_setFakeUser ,
2006-12-26 07:00:32 +00:00
" Groups fake user state " ,
2006-12-17 02:16:29 +00:00
NULL } ,
2006-11-16 21:38:08 +00:00
{ " layers " ,
( getter ) Group_getLayers , ( setter ) Group_setLayers ,
" Number of group users " ,
NULL } ,
2006-03-18 14:47:26 +00:00
{ " objects " ,
2006-08-27 16:27:34 +00:00
( getter ) Group_getObjects , ( setter ) Group_setObjects ,
2006-03-18 14:47:26 +00:00
" objects in this group " ,
NULL } ,
{ NULL , NULL , NULL , NULL , NULL } /* Sentinel */
} ;
/*****************************************************************************/
/* Python TypeGroup structure definition: */
/*****************************************************************************/
PyTypeObject Group_Type = {
PyObject_HEAD_INIT ( NULL ) /* required py macro */
0 , /* ob_size */
/* For printing, in format "<module>.<name>" */
" Blender Group " , /* char *tp_name; */
sizeof ( BPy_Group ) , /* int tp_basicsize; */
0 , /* tp_itemsize; For allocation */
/* Methods to implement standard operations */
( destructor ) Group_dealloc , /* destructor tp_dealloc; */
NULL , /* printfunc tp_print; */
NULL , /* getattrfunc tp_getattr; */
NULL , /* setattrfunc tp_setattr; */
( cmpfunc ) Group_compare , /* cmpfunc tp_compare; */
( reprfunc ) Group_repr , /* reprfunc tp_repr; */
/* Method suites for standard classes */
NULL , /* PyNumberMethods *tp_as_number; */
NULL , /* PySequenceMethods *tp_as_sequence; */
NULL , /* PyMappingMethods *tp_as_mapping; */
/* More standard operations (here for binary compatibility) */
NULL , /* hashfunc tp_hash; */
NULL , /* ternaryfunc tp_call; */
NULL , /* reprfunc tp_str; */
NULL , /* getattrofunc tp_getattro; */
NULL , /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
NULL , /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
Py_TPFLAGS_DEFAULT , /* long tp_flags; */
NULL , /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL , /* traverseproc tp_traverse; */
/* delete references to contained objects */
NULL , /* inquiry tp_clear; */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
NULL , /* richcmpfunc tp_richcompare; */
/*** weak reference enabler ***/
0 , /* long tp_weaklistoffset; */
/*** Added in release 2.2 ***/
/* Iterators */
NULL , /* getiterfunc tp_iter; */
NULL , /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
BPy_Group_methods , /* struct PyMethodDef *tp_methods; */
NULL , /* struct PyMemberDef *tp_members; */
BPy_Group_getseters , /* struct PyGetSetDef *tp_getset; */
NULL , /* struct _typeobject *tp_base; */
NULL , /* PyObject *tp_dict; */
NULL , /* descrgetfunc tp_descr_get; */
NULL , /* descrsetfunc tp_descr_set; */
0 , /* long tp_dictoffset; */
NULL , /* initproc tp_init; */
NULL , /* allocfunc tp_alloc; */
NULL , /* newfunc tp_new; */
/* Low-level free-memory routine */
NULL , /* freefunc tp_free; */
/* For PyObject_IS_GC */
NULL , /* inquiry tp_is_gc; */
NULL , /* PyObject *tp_bases; */
/* method resolution order */
NULL , /* PyObject *tp_mro; */
NULL , /* PyObject *tp_cache; */
NULL , /* PyObject *tp_subclasses; */
NULL , /* PyObject *tp_weaklist; */
NULL
} ;
/*****************************************************************************/
/* Function: M_Group_New */
/* Python equivalent: Blender.Group.New */
/*****************************************************************************/
PyObject * M_Group_New ( PyObject * self , PyObject * args )
{
char * name = " Group " ;
char buf [ 21 ] ;
BPy_Group * py_group ; /* for Group Data object wrapper in Python */
2006-03-18 15:23:02 +00:00
struct Group * bl_group ;
2006-03-18 14:47:26 +00:00
if ( ! PyArg_ParseTuple ( args , " |s " , & name ) )
return EXPP_ReturnPyObjError ( PyExc_TypeError ,
2006-04-20 14:26:24 +00:00
" string expected as argument or nothing " ) ;
2006-03-18 14:47:26 +00:00
2006-03-18 15:23:02 +00:00
bl_group = add_group ( ) ;
2006-03-18 14:47:26 +00:00
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 " ) ) ;
if ( strcmp ( name , " Group " ) ! = 0 ) {
PyOS_snprintf ( buf , sizeof ( buf ) , " %s " , name ) ;
rename_id ( & bl_group - > id , buf ) ;
}
2006-11-02 23:05:10 +00:00
bl_group - > id . us = 1 ;
2006-03-18 14:47:26 +00:00
return ( PyObject * ) py_group ;
}
/*****************************************************************************/
/* Function: M_Group_Get */
/* Python equivalent: Blender.Group.Get */
/*****************************************************************************/
PyObject * M_Group_Get ( PyObject * self , PyObject * args )
{
char * name = NULL ;
Group * group_iter ;
if ( ! PyArg_ParseTuple ( args , " |s " , & name ) )
return ( EXPP_ReturnPyObjError ( PyExc_TypeError ,
" expected string argument (or nothing) " ) ) ;
group_iter = G . main - > group . first ;
if ( name ) { /* (name) - Search group by name */
BPy_Group * wanted_group = NULL ;
while ( ( group_iter ) & & ( wanted_group = = NULL ) ) {
if ( strcmp ( name , group_iter - > id . name + 2 ) = = 0 )
wanted_group =
( BPy_Group * )
Group_CreatePyObject ( group_iter ) ;
group_iter = group_iter - > id . next ;
}
if ( wanted_group = = NULL ) { /* Requested group doesn't exist */
char error_msg [ 64 ] ;
PyOS_snprintf ( error_msg , sizeof ( error_msg ) ,
" Group \" %s \" not found " , name ) ;
return ( EXPP_ReturnPyObjError
( PyExc_NameError , error_msg ) ) ;
}
return ( PyObject * ) wanted_group ;
}
else { /* () - return a list of all groups in the scene */
int index = 0 ;
PyObject * grouplist , * pyobj ;
grouplist = PyList_New ( BLI_countlist ( & ( G . main - > group ) ) ) ;
if ( grouplist = = NULL )
return ( EXPP_ReturnPyObjError ( PyExc_MemoryError ,
2006-03-19 04:45:58 +00:00
" couldn't create group list " ) ) ;
2006-03-18 14:47:26 +00:00
while ( group_iter ) {
pyobj = Group_CreatePyObject ( group_iter ) ;
if ( ! pyobj )
return ( EXPP_ReturnPyObjError
( PyExc_MemoryError ,
2006-03-19 04:45:58 +00:00
" couldn't create Object " ) ) ;
2006-03-18 14:47:26 +00:00
PyList_SET_ITEM ( grouplist , index , pyobj ) ;
group_iter = group_iter - > id . next ;
index + + ;
}
return grouplist ;
}
}
/*****************************************************************************/
/* Function: M_Group_Unlink */
/* Python equivalent: Blender.Group.Unlink */
/*****************************************************************************/
PyObject * M_Group_Unlink ( PyObject * self , PyObject * args )
{
PyObject * pyob = NULL ;
BPy_Group * pygrp = NULL ;
2006-03-18 15:23:02 +00:00
Group * group ;
2006-03-18 14:47:26 +00:00
if ( ! PyArg_ParseTuple ( args , " O! " , & Group_Type , & pyob ) )
return ( EXPP_ReturnPyObjError ( PyExc_TypeError ,
" expected a group " ) ) ;
pygrp = ( BPy_Group * ) pyob ;
2006-09-24 08:30:38 +00:00
GROUP_DEL_CHECK_PY ( pygrp ) ;
group = pygrp - > group ;
2006-03-18 14:47:26 +00:00
pygrp - > group = NULL ;
free_group ( group ) ;
unlink_group ( group ) ;
group - > id . us = 0 ;
free_libblock ( & G . main - > group , group ) ;
2006-10-06 16:48:28 +00:00
Py_RETURN_NONE ;
2006-03-18 14:47:26 +00:00
}
/*****************************************************************************/
/* Function: initObject */
/*****************************************************************************/
PyObject * Group_Init ( void )
{
PyObject * submodule ;
if ( PyType_Ready ( & Group_Type ) < 0 )
return NULL ;
2006-08-27 16:27:34 +00:00
if ( PyType_Ready ( & GroupObSeq_Type ) < 0 )
2006-03-18 14:47:26 +00:00
return NULL ;
submodule = Py_InitModule3 ( " Blender.Group " , M_Group_methods ,
2006-08-15 11:24:08 +00:00
" The Blender Group module \n \n \
This module provides access to * * Group Data * * in Blender . \ n " );
2006-03-18 14:47:26 +00:00
2006-08-15 11:24:08 +00:00
/*Add SUBMODULES to the module*/
/*PyDict_SetItemString(dict, "Constraint", Constraint_Init()); //creates a *new* module*/
2006-03-18 14:47:26 +00:00
return submodule ;
}
/*****************************************************************************/
/* Function: Group_CreatePyObject */
/* Description: This function will create a new BlenObject from an existing */
/* Object structure. */
/*****************************************************************************/
PyObject * Group_CreatePyObject ( struct Group * grp )
{
BPy_Group * pygrp ;
if ( ! grp )
2006-10-06 16:48:28 +00:00
Py_RETURN_NONE ;
2006-03-18 14:47:26 +00:00
pygrp =
( BPy_Group * ) PyObject_NEW ( BPy_Group , & Group_Type ) ;
if ( pygrp = = NULL ) {
return ( NULL ) ;
}
pygrp - > group = grp ;
return ( ( PyObject * ) pygrp ) ;
}
/*****************************************************************************/
/* Function: Group_CheckPyObject */
/* Description: This function returns true when the given PyObject is of the */
/* type Group. Otherwise it will return false. */
/*****************************************************************************/
int Group_CheckPyObject ( PyObject * py_grp )
{
return ( py_grp - > ob_type = = & Group_Type ) ;
}
/*****************************************************************************/
/* Function: Group_FromPyObject */
/* Description: This function returns the Blender group from the given */
/* PyObject. */
/*****************************************************************************/
Group * Group_FromPyObject ( PyObject * py_grp )
{
BPy_Group * blen_grp ;
blen_grp = ( BPy_Group * ) py_grp ;
return ( blen_grp - > group ) ;
}
/*****************************************************************************/
/* 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. */
/*****************************************************************************/
Group * GetGroupByName ( char * name )
{
Group * grp_iter ;
grp_iter = G . main - > group . first ;
while ( grp_iter ) {
if ( StringEqual ( name , GetIdName ( & ( grp_iter - > id ) ) ) ) {
return ( grp_iter ) ;
}
grp_iter = grp_iter - > id . next ;
}
/* There is no object with the given name */
return ( NULL ) ;
}
/*****************************************************************************/
/* Function: Group_dealloc */
/* Description: This is a callback function for the BlenObject type. It is */
/* the destructor function. */
/*****************************************************************************/
static void Group_dealloc ( BPy_Group * grp )
{
PyObject_DEL ( grp ) ;
}
/*****************************************************************************/
/* Function: Group_compare */
/* Description: This is a callback function for the BPy_Group type. It */
/* compares two Group_Type objects. Only the "==" and "!=" */
/* comparisons are meaninful. Returns 0 for equality and -1 if */
/* they don't point to the same Blender Object struct. */
/* In Python it becomes 1 if they are equal, 0 otherwise. */
/*****************************************************************************/
static int Group_compare ( BPy_Group * a , BPy_Group * b )
{
Group * pa = a - > group , * pb = b - > group ;
return ( pa = = pb ) ? 0 : - 1 ;
}
/*****************************************************************************/
/* Function: Group_repr */
/* Description: This is a callback function for the BPy_Group type. It */
/* builds a meaninful string to represent object objects. */
/*****************************************************************************/
static PyObject * Group_repr ( BPy_Group * self )
{
2006-09-24 08:30:38 +00:00
if ( ! self - > group )
return PyString_FromString ( " [Group - Removed] " ) ;
2006-03-18 14:47:26 +00:00
return PyString_FromFormat ( " [Group \" %s \" ] " ,
self - > group - > id . name + 2 ) ;
}
/************************************************************************
*
* GroupOb sequence
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
2006-08-27 16:27:34 +00:00
* create a thin GroupOb object
2006-03-18 14:47:26 +00:00
*/
2006-09-24 08:30:38 +00:00
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 )
2006-03-18 14:47:26 +00:00
{
2006-09-24 08:30:38 +00:00
Group * group = self - > bpygroup - > group ;
2006-03-18 14:47:26 +00:00
int index = 0 ;
PyObject * bpy_obj ;
GroupObject * gob ;
2006-09-24 08:30:38 +00:00
GROUP_DEL_CHECK_PY ( self - > bpygroup ) ;
2006-03-18 14:47:26 +00:00
for ( gob = group - > gobject . first ; gob & & i ! = index ; gob = gob - > next , index + + ) { }
if ( ! ( gob ) )
return EXPP_ReturnPyObjError ( PyExc_IndexError ,
" array index out of range " ) ;
bpy_obj = Object_CreatePyObject ( gob - > ob ) ;
if ( ! bpy_obj )
return EXPP_ReturnPyObjError ( PyExc_RuntimeError ,
" PyObject_New() failed " ) ;
return ( PyObject * ) bpy_obj ;
2006-09-24 08:30:38 +00:00
2006-03-18 14:47:26 +00:00
}
2006-08-27 16:27:34 +00:00
static PySequenceMethods GroupObSeq_as_sequence = {
( inquiry ) GroupObSeq_len , /* sq_length */
2006-03-18 14:47:26 +00:00
( binaryfunc ) 0 , /* sq_concat */
( intargfunc ) 0 , /* sq_repeat */
2006-08-27 16:27:34 +00:00
( intargfunc ) GroupObSeq_item , /* sq_item */
2006-03-18 14:47:26 +00:00
( intintargfunc ) 0 , /* sq_slice */
( intobjargproc ) 0 , /* sq_ass_item */
( intintobjargproc ) 0 , /* sq_ass_slice */
0 , 0 , 0 ,
} ;
/************************************************************************
*
2006-08-27 16:27:34 +00:00
* Python GroupObSeq_Type iterator ( iterates over GroupObjects )
2006-03-18 14:47:26 +00:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Initialize the interator index
*/
2006-08-27 16:27:34 +00:00
static PyObject * GroupObSeq_getIter ( BPy_GroupObSeq * self )
2006-03-18 14:47:26 +00:00
{
2006-09-24 08:30:38 +00:00
GROUP_DEL_CHECK_PY ( self - > bpygroup ) ;
if ( ! self - > iter ) {
self - > iter = self - > bpygroup - > group - > gobject . first ;
return EXPP_incr_ret ( ( PyObject * ) self ) ;
} else {
2006-09-24 09:21:18 +00:00
return GroupObSeq_CreatePyObject ( self - > bpygroup , self - > bpygroup - > group - > gobject . first ) ;
2006-09-24 08:30:38 +00:00
}
2006-03-18 14:47:26 +00:00
}
/*
2006-08-27 16:27:34 +00:00
* Return next GroupOb .
2006-03-18 14:47:26 +00:00
*/
2006-08-27 16:27:34 +00:00
static PyObject * GroupObSeq_nextIter ( BPy_GroupObSeq * self )
2006-03-18 14:47:26 +00:00
{
PyObject * object ;
2006-12-11 03:23:17 +00:00
if ( ! ( self - > iter ) | | ! ( self - > bpygroup - > group ) ) {
self - > iter = NULL ; /* so we can add objects again */
2006-03-18 14:47:26 +00:00
return EXPP_ReturnPyObjError ( PyExc_StopIteration ,
" iterator at end " ) ;
2006-12-11 03:23:17 +00:00
}
2006-03-18 14:47:26 +00:00
object = Object_CreatePyObject ( self - > iter - > ob ) ;
self - > iter = self - > iter - > next ;
return object ;
}
2006-12-11 03:23:17 +00:00
static PyObject * GroupObSeq_link ( BPy_GroupObSeq * self , PyObject * args )
2006-03-18 14:47:26 +00:00
{
PyObject * pyobj ;
Object * blen_ob ;
2006-09-24 08:30:38 +00:00
GROUP_DEL_CHECK_PY ( self - > bpygroup ) ;
2006-03-18 14:47:26 +00:00
if ( ! PyArg_ParseTuple ( args , " O! " , & Object_Type , & pyobj ) )
return ( EXPP_ReturnPyObjError ( PyExc_TypeError ,
" expected a python object as an argument " ) ) ;
2006-12-11 03:23:17 +00:00
/*
if ( self - > iter ! = NULL )
return EXPP_ReturnPyObjError ( PyExc_RuntimeError ,
" Cannot modify group objects while iterating " ) ;
*/
2006-03-18 14:47:26 +00:00
blen_ob = ( ( BPy_Object * ) pyobj ) - > object ;
2006-03-19 04:45:58 +00:00
add_to_group_wraper ( self - > bpygroup - > group , blen_ob ) ; /* this checks so as not to add the object into the group twice*/
2006-03-18 14:47:26 +00:00
2006-10-06 16:48:28 +00:00
Py_RETURN_NONE ;
2006-03-18 14:47:26 +00:00
}
2006-12-28 05:00:35 +00:00
static PyObject * GroupObSeq_append ( BPy_GroupObSeq * self , PyObject * args )
{
printf ( " WARNING: grp.objects.append() has been deprecated, use grp.objects.link() instead. \n Blender releases after 2.43 will not support .append() " ) ;
return GroupObSeq_link ( self , args ) ;
}
2006-03-18 14:47:26 +00:00
2006-12-11 03:23:17 +00:00
static PyObject * GroupObSeq_unlink ( BPy_GroupObSeq * self , PyObject * args )
2006-03-18 14:47:26 +00:00
{
PyObject * pyobj ;
Object * blen_ob ;
Base * base = NULL ;
2006-09-24 08:30:38 +00:00
GROUP_DEL_CHECK_PY ( self - > bpygroup ) ;
2006-03-18 14:47:26 +00:00
if ( ! PyArg_ParseTuple ( args , " O! " , & Object_Type , & pyobj ) )
return ( EXPP_ReturnPyObjError ( PyExc_TypeError ,
" expected a python object as an argument " ) ) ;
blen_ob = ( ( BPy_Object * ) pyobj ) - > object ;
rem_from_group ( self - > bpygroup - > group , blen_ob ) ;
if ( find_group ( blen_ob ) = = NULL ) {
blen_ob - > flag & = ~ OB_FROMGROUP ;
base = object_in_scene ( blen_ob , G . scene ) ;
if ( base )
base - > flag & = ~ OB_FROMGROUP ;
}
2006-10-06 16:48:28 +00:00
Py_RETURN_NONE ;
2006-03-18 14:47:26 +00:00
}
2006-12-28 05:00:35 +00:00
static PyObject * GroupObSeq_remove ( BPy_GroupObSeq * self , PyObject * args )
{
printf ( " WARNING: grp.objects.remove() has been deprecated, use grp.objects.unlink() instead. \n Blender releases after 2.43 will not support .remove() " ) ;
return GroupObSeq_unlink ( self , args ) ;
}
2006-03-18 14:47:26 +00:00
2006-08-27 16:27:34 +00:00
static struct PyMethodDef BPy_GroupObSeq_methods [ ] = {
2006-12-11 03:23:17 +00:00
{ " link " , ( PyCFunction ) GroupObSeq_link , METH_VARARGS ,
" make the object a part of this group " } ,
2006-12-28 05:00:35 +00:00
{ " unlink " , ( PyCFunction ) GroupObSeq_unlink , METH_VARARGS ,
" unlink an object from this group " } ,
/* Deprecated! use the above functions */
{ " append " , ( PyCFunction ) GroupObSeq_append , METH_VARARGS ,
" make the object a part of this group - deprecated, use link " } ,
{ " remove " , ( PyCFunction ) GroupObSeq_remove , METH_VARARGS ,
" remove an object from this group - deprecated, use unlink " } ,
{ NULL , NULL , 0 , NULL }
2006-03-18 14:47:26 +00:00
} ;
/************************************************************************
*
2006-08-27 16:27:34 +00:00
* Python GroupObSeq_Type standard operations
2006-03-18 14:47:26 +00:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-08-27 16:27:34 +00:00
static void GroupObSeq_dealloc ( BPy_GroupObSeq * self )
2006-03-18 14:47:26 +00:00
{
Py_DECREF ( self - > bpygroup ) ;
PyObject_DEL ( self ) ;
}
/*****************************************************************************/
2006-08-27 16:27:34 +00:00
/* Python GroupObSeq_Type structure definition: */
2006-03-18 14:47:26 +00:00
/*****************************************************************************/
2006-08-27 16:27:34 +00:00
PyTypeObject GroupObSeq_Type = {
2006-03-18 14:47:26 +00:00
PyObject_HEAD_INIT ( NULL ) /* required py macro */
0 , /* ob_size */
/* For printing, in format "<module>.<name>" */
2006-08-27 16:27:34 +00:00
" Blender GroupObSeq " , /* char *tp_name; */
sizeof ( BPy_GroupObSeq ) , /* int tp_basicsize; */
2006-03-18 14:47:26 +00:00
0 , /* tp_itemsize; For allocation */
/* Methods to implement standard operations */
2006-08-27 16:27:34 +00:00
( destructor ) GroupObSeq_dealloc , /* destructor tp_dealloc; */
2006-03-18 14:47:26 +00:00
NULL , /* printfunc tp_print; */
NULL , /* getattrfunc tp_getattr; */
NULL , /* setattrfunc tp_setattr; */
NULL , /* cmpfunc tp_compare; */
NULL , /* reprfunc tp_repr; */
/* Method suites for standard classes */
NULL , /* PyNumberMethods *tp_as_number; */
2006-08-27 16:27:34 +00:00
& GroupObSeq_as_sequence , /* PySequenceMethods *tp_as_sequence; */
2006-03-18 14:47:26 +00:00
NULL , /* PyMappingMethods *tp_as_mapping; */
/* More standard operations (here for binary compatibility) */
NULL , /* hashfunc tp_hash; */
NULL , /* ternaryfunc tp_call; */
NULL , /* reprfunc tp_str; */
NULL , /* getattrofunc tp_getattro; */
NULL , /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
NULL , /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
Py_TPFLAGS_DEFAULT , /* long tp_flags; */
NULL , /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL , /* traverseproc tp_traverse; */
/* delete references to contained objects */
NULL , /* inquiry tp_clear; */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
NULL , /* richcmpfunc tp_richcompare; */
/*** weak reference enabler ***/
0 , /* long tp_weaklistoffset; */
/*** Added in release 2.2 ***/
/* Iterators */
2006-08-27 16:27:34 +00:00
( getiterfunc ) GroupObSeq_getIter , /* getiterfunc tp_iter; */
( iternextfunc ) GroupObSeq_nextIter , /* iternextfunc tp_iternext; */
2006-03-18 14:47:26 +00:00
/*** Attribute descriptor and subclassing stuff ***/
2006-08-27 16:27:34 +00:00
BPy_GroupObSeq_methods , /* struct PyMethodDef *tp_methods; */
2006-03-18 14:47:26 +00:00
NULL , /* struct PyMemberDef *tp_members; */
NULL , /* struct PyGetSetDef *tp_getset; */
NULL , /* struct _typeobject *tp_base; */
NULL , /* PyObject *tp_dict; */
NULL , /* descrgetfunc tp_descr_get; */
NULL , /* descrsetfunc tp_descr_set; */
0 , /* long tp_dictoffset; */
NULL , /* initproc tp_init; */
NULL , /* allocfunc tp_alloc; */
NULL , /* newfunc tp_new; */
/* Low-level free-memory routine */
NULL , /* freefunc tp_free; */
/* For PyObject_IS_GC */
NULL , /* inquiry tp_is_gc; */
NULL , /* PyObject *tp_bases; */
/* method resolution order */
NULL , /* PyObject *tp_mro; */
NULL , /* PyObject *tp_cache; */
NULL , /* PyObject *tp_subclasses; */
NULL , /* PyObject *tp_weaklist; */
NULL
} ;