/* * $Id$ * * ***** 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): Jacques Guignot, Jean-Michel Soler * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ #include "Effect.h" /*This must come first */ #include "DNA_object_types.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_effect.h" #include "BKE_object.h" #include "Particle.h" #include "gen_utils.h" PyObject *M_Particle_New( PyObject * self, PyObject * args ); int ParticleSetAttr( BPy_Particle * msh, char *name, PyObject * v ); PyObject *ParticleGetAttr( BPy_Particle * msh, char *name ); PyObject *M_Effect_GetParticlesLoc( PyObject * self, PyObject * args ); /*****************************************************************************/ /* Python BPy_Effect methods table: */ /*****************************************************************************/ static PyMethodDef BPy_Effect_methods[] = { {NULL, NULL, 0, NULL} }; /*****************************************************************************/ /* Python Effect_Type structure definition: */ /*****************************************************************************/ PyTypeObject Effect_Type = { PyObject_HEAD_INIT( NULL ) 0, /* ob_size */ "Effect", /* tp_name */ sizeof( BPy_Effect ), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ ( destructor ) EffectDeAlloc, /* tp_dealloc */ 0, /* tp_print */ ( getattrfunc ) EffectGetAttr, /* tp_getattr */ ( setattrfunc ) EffectSetAttr, /* tp_setattr */ 0, /* tp_compare */ ( reprfunc ) EffectRepr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_as_hash */ 0, 0, 0, 0, 0, 0, 0, /* tp_doc */ 0, 0, 0, 0, 0, 0, BPy_Effect_methods, /* tp_methods */ 0, /* tp_members */ }; static char M_Effect_GetParticlesLoc_doc[] = "GetParticlesLoc(name,effect num, curframe) : current particles locations"; /*****************************************************************************/ /* Python method structure definition for Blender.Effect module: */ /*****************************************************************************/ struct PyMethodDef M_Effect_methods[] = { {"New", ( PyCFunction ) M_Effect_New, METH_VARARGS, NULL}, {"Get", M_Effect_Get, METH_VARARGS, NULL}, {"get", M_Effect_Get, METH_VARARGS, NULL}, {"GetParticlesLoc", M_Effect_GetParticlesLoc, METH_VARARGS, M_Effect_GetParticlesLoc_doc}, {NULL, NULL, 0, NULL} }; /*****************************************************************************/ /* Function: M_Effect_New */ /* Python equivalent: Blender.Effect.New */ /*****************************************************************************/ PyObject *M_Effect_New( PyObject * self, PyObject * args ) { return M_Particle_New( self, args ); } /*****************************************************************************/ /* Function: M_Effect_Get */ /* Python equivalent: Blender.Effect.Get */ /*****************************************************************************/ PyObject *M_Effect_Get( PyObject * self, PyObject * args ) { /*arguments : string object name int : position of effect in the obj's effect list */ char *name = NULL; Object *object_iter; Effect *eff; BPy_Effect *wanted_eff; int num = -1, i; if( !PyArg_ParseTuple( args, "|si", &name, &num ) ) return ( EXPP_ReturnPyObjError( PyExc_AttributeError, "expected string int argument" ) ); object_iter = G.main->object.first; if( !object_iter ) return ( EXPP_ReturnPyObjError( PyExc_AttributeError, "Scene contains no object" ) ); if( name ) { /* (name, num = -1) - try to find the given object */ while( object_iter ) { if( !strcmp( name, object_iter->id.name + 2 ) ) { eff = object_iter->effect.first; /*can be NULL: None will be returned*/ if (num >= 0) { /* return effect in given num position if available */ for( i = 0; i < num; i++ ) { if (!eff) break; eff = eff->next; } if (eff) { wanted_eff = (BPy_Effect *)PyObject_NEW(BPy_Effect, &Effect_Type); wanted_eff->effect = eff; return ( PyObject * ) wanted_eff; } else { /* didn't find any effect in the given position */ Py_INCREF(Py_None); return Py_None; } } else {/*return a list with all effects linked to the given object*/ /* this was pointed by Stephen Swaney */ PyObject *effectlist = PyList_New( 0 ); while (eff) { BPy_Effect *found_eff = (BPy_Effect *)PyObject_NEW(BPy_Effect, &Effect_Type); found_eff->effect = eff; PyList_Append( effectlist, ( PyObject * ) found_eff ); Py_DECREF((PyObject *)found_eff); /* PyList_Append incref'ed it */ eff = eff->next; } return effectlist; } } object_iter = object_iter->id.next; } if (!object_iter) return EXPP_ReturnPyObjError (PyExc_AttributeError, "no such object"); } else { /* () - return a list with all effects currently in Blender */ PyObject *effectlist = PyList_New( 0 ); while( object_iter ) { if( object_iter->effect.first != NULL ) { eff = object_iter->effect.first; while( eff ) { BPy_Effect *found_eff = ( BPy_Effect * ) PyObject_NEW( BPy_Effect, &Effect_Type ); found_eff->effect = eff; PyList_Append( effectlist, ( PyObject * ) found_eff ); Py_DECREF((PyObject *)found_eff); eff = eff->next; } } object_iter = object_iter->id.next; } return effectlist; } Py_INCREF( Py_None ); return Py_None; } /*****************************************************************************/ /* Function: GetParticlesLoc */ /* Python equivalent: Blender.Effect.GetParticlesLoc */ /* Description: Get the current location of each particle */ /* and return a list of 3D coords */ /* Data: String object name, int particle effect number, */ /* float currentframe */ /* Return: One python list of python lists of 3D coords */ /*****************************************************************************/ PyObject *M_Effect_GetParticlesLoc( PyObject * self, PyObject * args ) { char *name; Object *ob; Effect *eff; PartEff *paf; Particle *pa=0; int num, i, a; PyObject *list; float p_time, c_time, vec[3],cfra; if( !PyArg_ParseTuple( args, "sif", &name, &num , &cfra) ) return ( EXPP_ReturnPyObjError( PyExc_TypeError, "expected string, int, float arguments" ) ); for( ob = G.main->object.first; ob; ob = ob->id.next ) if( !strcmp( name, ob->id.name + 2 ) ) break; if( !ob ) return EXPP_ReturnPyObjError( PyExc_AttributeError, "object does not exist" ); if( ob->type != OB_MESH ) return EXPP_ReturnPyObjError( PyExc_AttributeError, "object is not a mesh" ); eff = ob->effect.first; for( i = 0; i < num && eff; i++ ) eff = eff->next; if( num < 0 || !eff ) return EXPP_ReturnPyObjError( PyExc_IndexError, "effect index out of range" ); if( eff->type != EFF_PARTICLE ) return EXPP_ReturnPyObjError( PyExc_RuntimeError, "unknown effect type" ); paf = (PartEff *)eff; pa = paf->keys; if( !pa ) return EXPP_ReturnPyObjError( PyExc_AttributeError, "Particles location: no keys" ); if( ob->ipoflag & OB_OFFS_PARTICLE ) p_time= ob->sf; else p_time= 0.0; c_time= bsystem_time( ob, 0, cfra, p_time ); list = PyList_New( 0 ); if( !list ) return EXPP_ReturnPyObjError( PyExc_MemoryError, "PyList() failed" ); for( a=0; atotpart; a++, pa += paf->totkey ) { if( c_time > pa->time && c_time < pa->time+pa->lifetime ) { where_is_particle(paf, pa, c_time, vec); if( PyList_Append( list, Py_BuildValue("[fff]", vec[0], vec[1], vec[2]) ) < 0 ) { Py_DECREF( list ); return EXPP_ReturnPyObjError( PyExc_RuntimeError, "Couldn't add item to list" ); } } } return list; } /*****************************************************************************/ /* Function: Effect_Init */ /*****************************************************************************/ PyObject *Particle_Init( void ); PyObject *Effect_Init( void ) { PyObject *submodule, *dict; Effect_Type.ob_type = &PyType_Type; submodule = Py_InitModule3( "Blender.Effect", M_Effect_methods, 0 ); dict = PyModule_GetDict( submodule ); PyDict_SetItemString( dict, "Particle", Particle_Init( ) ); return ( submodule ); } /*****************************************************************************/ /* Python BPy_Effect methods: */ /*****************************************************************************/ PyObject *Effect_getType( BPy_Effect * self ) { PyObject *attr = PyInt_FromLong( ( long ) self->effect->type ); if( attr ) return attr; return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, "couldn't get mode attribute" ) ); } /* does nothing since there is only one type of effect */ PyObject *Effect_setType( BPy_Effect * self ) { Py_INCREF( Py_None ); return Py_None; } PyObject *Effect_getFlag( BPy_Effect * self ) { PyObject *attr = PyInt_FromLong( ( long ) self->effect->flag ); if( attr ) return attr; return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, "couldn't get mode attribute" ) ); } PyObject *Effect_setFlag( BPy_Effect * self, PyObject * args ) { int value; if( !PyArg_ParseTuple( args, "i", &value ) ) return ( EXPP_ReturnPyObjError( PyExc_TypeError, "expected an int as argument" ) ); self->effect->flag = (short)value; Py_INCREF( Py_None ); return Py_None; } /*****************************************************************************/ /* Function: EffectDeAlloc */ /* Description: This is a callback function for the BPy_Effect type. It is */ /* the destructor function. */ /*****************************************************************************/ void EffectDeAlloc( BPy_Effect * self ) { PyObject_DEL( self ); } /*****************************************************************************/ /* Function: EffectGetAttr */ /* Description: This is a callback function for the BPy_Effect type. It is */ /* the function that accesses BPy_Effect "member variables" and */ /* methods. */ /*****************************************************************************/ PyObject *EffectGetAttr( BPy_Effect * self, char *name ) { switch ( self->effect->type ) { case EFF_PARTICLE: return ParticleGetAttr( ( BPy_Particle * ) self, name ); } return Py_FindMethod( BPy_Effect_methods, ( PyObject * ) self, name ); } /*****************************************************************************/ /* Function: EffectSetAttr */ /* Description: This is a callback function for the BPy_Effect type. It */ /* sets Effect Data attributes (member variables). */ /*****************************************************************************/ int EffectSetAttr( BPy_Effect * self, char *name, PyObject * value ) { switch ( self->effect->type ) { case EFF_PARTICLE: return ParticleSetAttr( ( BPy_Particle * ) self, name, value ); } return 0; /* normal exit */ } /*****************************************************************************/ /* Function: EffectPrint */ /* Description: This is a callback function for the BPy_Effect type. It */ /* builds a meaninful string to 'print' effcte objects. */ /*****************************************************************************/ /* int EffectPrint(BPy_Effect *self, FILE *fp, int flags) { if (self->effect->type == EFF_PARTICLE)puts("Effect Particle"); return 0; } */ /*****************************************************************************/ /* Function: EffectRepr */ /* Description: This is a callback function for the BPy_Effect type. It */ /* builds a meaninful string to represent effcte objects. */ /*****************************************************************************/ PyObject *EffectRepr( BPy_Effect * self ) { char *str = ""; if( self->effect->type == EFF_PARTICLE ) str = "Effect Particle"; return PyString_FromString( str ); } PyObject *EffectCreatePyObject( struct Effect * effect ) { BPy_Effect *blen_object; blen_object = ( BPy_Effect * ) PyObject_NEW( BPy_Effect, &Effect_Type ); if( blen_object == NULL ) { return ( NULL ); } blen_object->effect = effect; return ( ( PyObject * ) blen_object ); } int EffectCheckPyObject( PyObject * py_obj ) { return ( py_obj->ob_type == &Effect_Type ); } struct Effect *EffectFromPyObject( PyObject * py_obj ) { BPy_Effect *blen_obj; blen_obj = ( BPy_Effect * ) py_obj; return ( ( Effect * ) blen_obj->effect ); }