Index: source/blender/python/api2_2x/Blender.c =================================================================== --- source/blender/python/api2_2x/Blender.c (revision 14514) +++ source/blender/python/api2_2x/Blender.c (working copy) @@ -96,6 +96,7 @@ #include "Window.h" #include "World.h" #include "Types.h" +#include "Particle.h" /**********************************************************/ /* Python API function prototypes for the Blender module. */ @@ -1069,6 +1070,7 @@ PyDict_SetItemString(dict, "Node", Node_Init()); PyDict_SetItemString(dict, "Noise", Noise_Init()); PyDict_SetItemString(dict, "Object", Object_Init()); + PyDict_SetItemString(dict, "Particle", ParticleSYS_Init()); PyDict_SetItemString(dict, "Group", Group_Init()); PyDict_SetItemString(dict, "Registry", Registry_Init()); PyDict_SetItemString(dict, "Scene", Scene_Init()); Index: source/blender/python/api2_2x/doc/Particle.py =================================================================== --- source/blender/python/api2_2x/doc/Particle.py (revision 0) +++ source/blender/python/api2_2x/doc/Particle.py (revision 0) @@ -0,0 +1,182 @@ +# Blender.Object module and the Object PyType object + +""" +The Blender.Particle submodule + + +Particle +======== + +This module provides access to the B{Particle} in Blender. + +@type TYPE: readonly dictionary +@var TYPE: Constant dict used for with L{Particle.TYPE} + - HAIR: set particle system to hair mode. + - REACTOR: set particle system to reactor mode. + - EMITTER: set particle system to emitter mode. +@type DISTRIBUTION: readonly dictionary +@var DISTRIBUTION: Constant dict used for with L{Particle.DISTRIBUTION} + - GRID: set grid distribution. + - RANDOM: set random distribution. + - JITTERED: set jittered distribution. +@type EMITFROM: readonly dictionary +@var EMITFROM: Constant dict used for with L{Particle.EMITFROM} + - VERTS: set particles emit from vertices + - FACES: set particles emit from faces + - VOLUME: set particles emit from volume + - PARTICLE: set particles emit from particles +@type REACTON: readonly dictionary +@var REACTON: Constant dict used for with L{Particle.REACTON} + - NEAR: react on near + - COLLISION: react on collision + - DEATH: react on death +@type DRAWAS: readonly dictionary +@var DRAWAS: Constant dict used for with L{Particle.DRAWAS} + - NONE: Don't draw + - POINT: Draw as point + - CIRCLE: Draw as circles + - CROSS: Draw as crosses + - AXIS: Draw as axis + - LINE: Draw as lines + - PATH: Draw pathes + - OBJECT: Draw object + - GROUP: Draw goup + - BILLBOARD: Draw as billboard +""" + +def Get(name): + """ + Get the particle system of the object "name". + @type name: string + @return: The particle system of the object. + """ +def New(name): + """ + Assign a new particle system to the object "name". + @type name: string + @return: The newly created particle system. + """ + +class Particle: + """ + The Particle object + =================== + This object gives access to paticles data. + + @ivar seed: Set an offset in the random table. + @type seed: int + @ivar type: Type of particle system ( Particle.TYPE[ 'HAIR' | 'REACTOR' | 'EMITTER' ] ). + @type type: int + @ivar resolutionGrid: The resolution of the particle grid. + @type resolutionGrid: int + @ivar startFrame: Frame # to start emitting particles. + @type startFrame: float + @ivar endFrame: Frame # to stop emitting particles. + @type endFrame: float + @ivar editable: Finalize hair to enable editing in particle mode. + @type editable: int + @ivar amount: The total number of particles. + @type amount: int + @ivar multireact: React multiple times ( Paricle.REACTON[ 'NEAR' | 'COLLISION' | 'DEATH' ] ). + @type multireact: int + @ivar reactshape: Power of reaction strength dependence on distance to target. + @type reactshape: float + @ivar hairSegments: Amount of hair segments. + @type hairSegments: int + @ivar lifetime: Specify the life span of the particles. + @type lifetime: float + @ivar randlife: Give the particle life a random variation. + @type randlife: float + @ivar randemission: Give the particle life a random variation + @type randemission: int + @ivar particleDistribution: Where to emit particles from Paricle.EMITFROM[ 'PARTICLE' | 'VOLUME' | 'FACES' | 'VERTS' ] ) + @type particleDistribution: int + @ivar evenDistribution: Use even distribution from faces based on face areas or edge lengths. + @type evenDistribution: int + @ivar distribution: How to distribute particles on selected element Paricle.DISTRIBUTION[ 'GRID' | 'RANDOM' | 'JITTERED' ] ). + @type distribution: int + @ivar jitterAmount: Amount of jitter applied to the sampling. + @type jitterAmount: float + @ivar pf: Emission locations / face (0 = automatic). + @type pf:int + @ivar invert: Invert what is considered object and what is not. + @type invert: int + @ivar targetObject: The object that has the target particle system (empty if same object). + @type targetObject: Blender object + @ivar targetpsys: The target particle system number in the object. + @type targetpsys: int + @ivar 2d: Constrain boids to a surface. + @type 2d: float + @ivar maxvel: Maximum velocity. + @type maxvel: float + @ivar avvel: The usual speed % of max velocity. + @type avvel: float + @ivar latacc: Lateral acceleration % of max velocity + @type latacc: float + @ivar tanacc: Tangential acceleration % of max velocity + @type tanacc: float + @ivar groundz: Default Z value. + @type groundz: float + @ivar object: Constrain boids to object's surface. + @type object: Blender Object + @ivar renderEmitter: Render emitter object. + @type renderEmitter: int + @ivar displayPercentage: Particle display percentage. + @type displayPercentage: int + @ivar hairDisplayStep: How many steps paths are drawn with (power of 2) in visu mode. + @type hairDisplayStep: int + @ivar hairRenderStep: How many steps paths are rendered with (power of 2) in render mode." + @type hairRenderStep: int + @ivar duplicateObject: Get the duplicate object. + @type duplicateObject: Blender Object + @ivar drawAs: Get draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ]). + @type drawAs: int + """ + def freeEdit(): + """ + Free edit mode. + @return: None + """ + + def getLoc(all=0,id=0): + """ + Get the particles locations. + A list of tuple is returned in particle mode. + A list of list of tuple is returned in hair mode. + The tuple is a vector list of 3 floats in world space. + @type all: int + @param all: if not 0 export all particles (uninitialized (unborn or died)particles exported as None). + @type id: int + @param id: add the particle id in the end of the vector tuple + @rtype: list of vectors (tuple of 3 floats and optionnaly the id) or list of list of vectors + @return: list of vectors or list of list of vectors (hair mode) + """ + def getRot(all=0,id=0): + """ + Get the particles rotations as quaternion. + A list of tuple is returned in particle mode. + The tuple is a vector list of 4 floats (quaternion). + @type all: int + @param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None). + @type id: int + @param id: add the particle id in the return tuple + @rtype: list of tuple of 4 or 5 elements (if id is not zero) + @return: list of 4-tuples + """ + def getMat(): + """ + Get the particles material. + @rtype: Blender Material + @return: The marterial assigned to particles + """ + def getSize(all=0,id=0): + """ + Get the particles size. + A list of float. + @type all: int + @param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None). + @type id: int + @param id: add the particle id in the return tuple + @rtype: list of floats + @return: list of floats or list of tuples if id is not zero (size,id). + """ Index: source/blender/python/api2_2x/Particle.c =================================================================== --- source/blender/python/api2_2x/Particle.c (revision 14514) +++ source/blender/python/api2_2x/Particle.c (working copy) @@ -1,6 +1,4 @@ /* - * $Id$ - * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -22,250 +20,501 @@ * * This is a new part of Blender. * - * Contributor(s): Jacques Guignot, Jean-Michel Soler + * Contributor(s): Cedric Paille * * ***** END GPL LICENSE BLOCK ***** */ -#include "Particle.h" /*This must come first */ - -#include "DNA_object_types.h" -#include "BKE_effect.h" +#include "Particle.h" +#include "gen_utils.h" +#include "BKE_object.h" +#include "BKE_main.h" +#include "BKE_particle.h" #include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_object.h" +#include "BKE_depsgraph.h" +#include "BKE_modifier.h" +#include "BKE_material.h" +#include "BKE_utildefines.h" +#include "BKE_pointcache.h" +#include "BIF_editparticle.h" +#include "BIF_space.h" +#include "blendef.h" +#include "DNA_modifier_types.h" +#include "DNA_scene_types.h" +#include "DNA_material_types.h" #include "BLI_blenlib.h" -#include "gen_utils.h" +#include "mydevice.h" +#include "Object.h" +#include "Material.h" +#include "MEM_guardedalloc.h" + + + +/* Type Methods */ +static PyObject *M_ParticleSYS_New( PyObject * self, PyObject * args ); +static PyObject *M_ParticleSYS_Get( PyObject * self, PyObject * args ); + +/* Particle Methods */ +static PyObject *Part_freeEdit( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_GetLoc( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_GetRot( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_GetMat( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_GetSize( BPy_PartSYS * self, PyObject * args ); +static int Part_setSeed( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getSeed( BPy_PartSYS * self ); +static int Part_setType( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getType( BPy_PartSYS * self ); +static int Part_setResol( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getResol( BPy_PartSYS * self ); +static int Part_setStart( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getStart( BPy_PartSYS * self ); +static int Part_setEnd( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getEnd( BPy_PartSYS * self ); +static int Part_setEditable( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getEditable( BPy_PartSYS * self ); +static int Part_setAmount( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getAmount( BPy_PartSYS * self ); +static int Part_setMultiReact( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getMultiReact( BPy_PartSYS * self ); +static int Part_setReactShape( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getReactShape( BPy_PartSYS * self ); +static int Part_setSegments( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getSegments( BPy_PartSYS * self ); +static int Part_setLife( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getLife( BPy_PartSYS * self ); +static int Part_setRandLife( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getRandLife( BPy_PartSYS * self ); +static int Part_set2d( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_get2d( BPy_PartSYS * self ); +static int Part_setMaxVel( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getMaxVel( BPy_PartSYS * self ); +static int Part_setAvVel( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getAvVel( BPy_PartSYS * self ); +static int Part_setLatAcc( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getLatAcc( BPy_PartSYS * self ); +static int Part_setMaxTan( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getMaxTan( BPy_PartSYS * self ); +static int Part_setGroundZ( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getGroundZ( BPy_PartSYS * self ); +static int Part_setOb( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getOb( BPy_PartSYS * self ); +static PyObject *Part_getRandEmission( BPy_PartSYS * self ); +static int Part_setRandEmission( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getRandEmission( BPy_PartSYS * self ); +static int Part_setPaticleDist( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getPaticleDist( BPy_PartSYS * self ); +static int Part_setEvenDist( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getEvenDist( BPy_PartSYS * self ); +static int Part_setDist( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getDist( BPy_PartSYS * self ); +static int Part_setParticleDisp( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getParticleDisp( BPy_PartSYS * self ); +static int Part_setJitterAmount( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getJitterAmount( BPy_PartSYS * self ); +static int Part_setPF( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getPF( BPy_PartSYS * self ); +static int Part_setInvert( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getInvert( BPy_PartSYS * self ); +static int Part_setTargetOb( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getTargetOb( BPy_PartSYS * self ); +static int Part_setTargetPsys( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getTargetPsys( BPy_PartSYS * self ); +static int Part_setRenderObject( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getRenderObject( BPy_PartSYS * self ); +static int Part_setStep( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getStep( BPy_PartSYS * self ); +static int Part_setRenderStep( BPy_PartSYS * self, PyObject * args ); +static PyObject *Part_getRenderStep( BPy_PartSYS * self ); +static PyObject *Part_getDupOb( BPy_PartSYS * self ); +static PyObject *Part_getDrawAs( BPy_PartSYS * self ); +static PyObject *Part_GetAge( BPy_PartSYS * self, PyObject * args ); + /*****************************************************************************/ -/* Python API function prototypes for the Particle module. */ +/* Python Effect_Type callback function prototypes: */ /*****************************************************************************/ -PyObject *M_Particle_New( PyObject * self, PyObject * args ); -PyObject *M_Particle_Get( PyObject * self, PyObject * args ); +static PyObject *ParticleSYS_repr( void ); /*****************************************************************************/ -/* Python BPy_Particle methods declarations: */ +/* The following string definitions are used for documentation strings. */ +/* In Python these will be written to the console when doing a */ +/* Blender.Particle.__doc__ */ /*****************************************************************************/ -PyObject *Effect_getType( BPy_Effect * self ); -PyObject *Effect_setType( BPy_Effect * self, PyObject * args ); -PyObject *Effect_getFlag( BPy_Effect * self ); -PyObject *Effect_setFlag( BPy_Effect * self, PyObject * args ); -PyObject *Particle_getSta( BPy_Particle * self ); -PyObject *Particle_setSta( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getEnd( BPy_Particle * self ); -PyObject *Particle_setEnd( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getLifetime( BPy_Particle * self ); -PyObject *Particle_setLifetime( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getNormfac( BPy_Particle * self ); -PyObject *Particle_setNormfac( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getObfac( BPy_Particle * self ); -PyObject *Particle_setObfac( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getRandfac( BPy_Particle * self ); -PyObject *Particle_setRandfac( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getTexfac( BPy_Particle * self ); -PyObject *Particle_setTexfac( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getRandlife( BPy_Particle * self ); -PyObject *Particle_setRandlife( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getNabla( BPy_Particle * self ); -PyObject *Particle_setNabla( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getVectsize( BPy_Particle * self ); -PyObject *Particle_setVectsize( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getTotpart( BPy_Particle * self ); -PyObject *Particle_setTotpart( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getTotkey( BPy_Particle * self ); -PyObject *Particle_setTotkey( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getSeed( BPy_Particle * self ); -PyObject *Particle_setSeed( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getForce( BPy_Particle * self ); -PyObject *Particle_setForce( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getMult( BPy_Particle * self ); -PyObject *Particle_setMult( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getLife( BPy_Particle * self ); -PyObject *Particle_setLife( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getMat( BPy_Particle * self ); -PyObject *Particle_setMat( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getChild( BPy_Particle * self ); -PyObject *Particle_setChild( BPy_Particle * self, PyObject * a ); -PyObject *Particle_getDefvec( BPy_Particle * self ); -PyObject *Particle_setDefvec( BPy_Particle * self, PyObject * a ); +static char M_ParticleSYS_doc[] = "The Blender Effect module\n\n\ +This module provides access to **Object Data** in Blender.\n\ +Functions :\n\ + Get(name) : retreives particle system (as list) with the given name\n"; +static char M_ParticleSYS_Get_doc[] = "xxx"; +static char M_ParticleSYS_New_doc[] = "xxx"; /*****************************************************************************/ -/* Python Particle_Type callback function prototypes: */ +/* Python BPy_ParticleSYS methods table: */ /*****************************************************************************/ -void ParticleDeAlloc( BPy_Particle * msh ); -//int ParticlePrint (BPy_Particle *msh, FILE *fp, int flags); -int ParticleSetAttr( BPy_Particle * msh, char *name, PyObject * v ); -PyObject *ParticleGetAttr( BPy_Particle * msh, char *name ); -PyObject *ParticleRepr( void ); -PyObject *ParticleCreatePyObject( struct Effect *particle ); -int ParticleCheckPyObject( PyObject * py_obj ); -struct Particle *ParticleFromPyObject( PyObject * py_obj ); - +static PyMethodDef BPy_ParticleSYS_methods[] = { + {"freeEdit", ( PyCFunction ) Part_freeEdit, + METH_NOARGS, "() - Free from edit mode"}, + {"getLoc", ( PyCFunction ) Part_GetLoc, + METH_VARARGS, "() - Get particles location"}, + {"getRot", ( PyCFunction ) Part_GetRot, + METH_VARARGS, "() - Get particles rotations (list of 4 floats quaternion)"}, + {"getMat", ( PyCFunction ) Part_GetMat, + METH_NOARGS, "() - Get particles material"}, + {"getSize", ( PyCFunction ) Part_GetSize, + METH_VARARGS, "() - Get particles size in a list"}, + {"getAge", ( PyCFunction ) Part_GetAge, + METH_VARARGS, "() - Get particles life in a list"}, + {NULL, NULL, 0, NULL} +}; + /*****************************************************************************/ -/* Python BPy_Particle methods table: */ +/* Python BPy_ParticleSYS attributes get/set structure: */ /*****************************************************************************/ -static PyMethodDef BPy_Particle_methods[] = { - {"getType", ( PyCFunction ) Effect_getType, - METH_NOARGS, "() - Return Effect type"}, - {"setType", ( PyCFunction ) Effect_setType, - METH_VARARGS, "() - Set Effect type"}, - {"getFlag", ( PyCFunction ) Effect_getFlag, - METH_NOARGS, "() - Return Effect flag"}, - {"setFlag", ( PyCFunction ) Effect_setFlag, - METH_VARARGS, "() - Set Effect flag"}, - {"getStartTime", ( PyCFunction ) Particle_getSta, - METH_NOARGS, "()-Return particle start time"}, - {"setStartTime", ( PyCFunction ) Particle_setSta, METH_VARARGS, - "()- Sets particle start time"}, - {"getEndTime", ( PyCFunction ) Particle_getEnd, - METH_NOARGS, "()-Return particle end time"}, - {"setEndTime", ( PyCFunction ) Particle_setEnd, METH_VARARGS, - "()- Sets particle end time"}, - {"getLifetime", ( PyCFunction ) Particle_getLifetime, - METH_NOARGS, "()-Return particle life time"}, - {"setLifetime", ( PyCFunction ) Particle_setLifetime, METH_VARARGS, - "()- Sets particle life time "}, - {"getNormfac", ( PyCFunction ) Particle_getNormfac, - METH_NOARGS, "()-Return particle life time"}, - {"setNormfac", ( PyCFunction ) Particle_setNormfac, METH_VARARGS, - "()- Sets particle life time "}, - {"getObfac", ( PyCFunction ) Particle_getObfac, - METH_NOARGS, "()-Return particle life time"}, - {"setObfac", ( PyCFunction ) Particle_setObfac, METH_VARARGS, - "()- Sets particle life time "}, - {"getRandfac", ( PyCFunction ) Particle_getRandfac, - METH_NOARGS, "()-Return particle life time"}, - {"setRandfac", ( PyCFunction ) Particle_setRandfac, METH_VARARGS, - "()- Sets particle life time "}, - {"getTexfac", ( PyCFunction ) Particle_getTexfac, - METH_NOARGS, "()-Return particle life time"}, - {"setTexfac", ( PyCFunction ) Particle_setTexfac, METH_VARARGS, - "()- Sets particle life time "}, - {"getRandlife", ( PyCFunction ) Particle_getRandlife, - METH_NOARGS, "()-Return particle life time"}, - {"setRandlife", ( PyCFunction ) Particle_setRandlife, METH_VARARGS, - "()- Sets particle life time "}, - {"getNabla", ( PyCFunction ) Particle_getNabla, - METH_NOARGS, "()-Return particle life time"}, - {"setNabla", ( PyCFunction ) Particle_setNabla, METH_VARARGS, - "()- Sets particle life time "}, - {"getVectsize", ( PyCFunction ) Particle_getVectsize, - METH_NOARGS, "()-Return particle life time"}, - {"setVectsize", ( PyCFunction ) Particle_setVectsize, METH_VARARGS, - "()- Sets particle life time "}, - {"getTotpart", ( PyCFunction ) Particle_getTotpart, - METH_NOARGS, "()-Return particle life time"}, - {"setTotpart", ( PyCFunction ) Particle_setTotpart, METH_VARARGS, - "()- Sets particle life time "}, - {"getTotkey", ( PyCFunction ) Particle_getTotkey, - METH_NOARGS, "()-Return particle life time"}, - {"setTotkey", ( PyCFunction ) Particle_setTotkey, METH_VARARGS, - "()- Sets particle life time "}, - {"getSeed", ( PyCFunction ) Particle_getSeed, - METH_NOARGS, "()-Return particle life time"}, - {"setSeed", ( PyCFunction ) Particle_setSeed, METH_VARARGS, - "()- Sets particle life time "}, - {"getForce", ( PyCFunction ) Particle_getForce, - METH_NOARGS, "()-Return particle life time"}, - {"setForce", ( PyCFunction ) Particle_setForce, METH_VARARGS, - "()- Sets particle life time "}, - {"getMult", ( PyCFunction ) Particle_getMult, - METH_NOARGS, "()-Return particle life time"}, - {"setMult", ( PyCFunction ) Particle_setMult, METH_VARARGS, - "()- Sets particle life time "}, - {"getLife", ( PyCFunction ) Particle_getLife, - METH_NOARGS, "()-Return particle life time"}, - {"setLife", ( PyCFunction ) Particle_setLife, METH_VARARGS, - "()- Sets particle life time "}, - {"getMat", ( PyCFunction ) Particle_getMat, - METH_NOARGS, "()-Return particle life time"}, - {"setMat", ( PyCFunction ) Particle_setMat, METH_VARARGS, - "()- Sets particle life time "}, - {"getChild", ( PyCFunction ) Particle_getChild, - METH_NOARGS, "()-Return particle life time"}, - {"setChild", ( PyCFunction ) Particle_setChild, METH_VARARGS, - "()- Sets particle life time "}, - {"getDefvec", ( PyCFunction ) Particle_getDefvec, - METH_NOARGS, "()-Return particle life time"}, - {"setDefvec", ( PyCFunction ) Particle_setDefvec, METH_VARARGS, - "()- Sets particle life time "}, - - +static PyGetSetDef BPy_ParticleSYS_getseters[] = { +/* Extras */ + {"seed", + (getter)Part_getSeed, (setter)Part_setSeed, + "Set an offset in the random table", + NULL}, + /* basics */ + {"type", + (getter)Part_getType, (setter)Part_setType, + "Type of particle system ( Particle.TYPE[ 'HAIR' | 'REACTOR' | 'EMITTER' ] )", + NULL}, + {"resolutionGrid", + (getter)Part_getResol, (setter)Part_setResol, + "The resolution of the particle grid", + NULL}, + {"startFrame", + (getter)Part_getStart, (setter)Part_setStart, + "Frame # to start emitting particles", + NULL}, + {"endFrame", + (getter)Part_getEnd, (setter)Part_setEnd, + "Frame # to stop emitting particles", + NULL}, + {"editable", + (getter)Part_getEditable, (setter)Part_setEditable, + "Finalize hair to enable editing in particle mode", + NULL}, + {"amount", + (getter)Part_getAmount, (setter)Part_setAmount, + "The total number of particles", + NULL}, + {"multireact", + (getter)Part_getMultiReact, (setter)Part_setMultiReact, + "React multiple times ( Paricle.REACTON[ 'NEAR' | 'COLLISION' | 'DEATH' ] )", + NULL}, + {"reactshape", + (getter)Part_getReactShape, (setter)Part_setReactShape, + "Power of reaction strength dependence on distance to target", + NULL}, + {"hairSegments", + (getter)Part_getSegments, (setter)Part_setSegments, + "Amount of hair segments", + NULL}, + {"lifetime", + (getter)Part_getLife, (setter)Part_setLife, + "Specify the life span of the particles", + NULL}, + {"randlife", + (getter)Part_getRandLife, (setter)Part_setRandLife, + "Give the particle life a random variation", + NULL}, + {"randemission", + (getter)Part_getRandEmission, (setter)Part_setRandEmission, + "Give the particle life a random variation", + NULL}, + {"particleDistribution", + (getter)Part_getPaticleDist, (setter)Part_setPaticleDist, + "Where to emit particles from Paricle.EMITFROM[ 'PARTICLE' | 'VOLUME' | 'FACES' | 'VERTS' ] )", + NULL}, + {"evenDistribution", + (getter)Part_getEvenDist, (setter)Part_setEvenDist, + "Use even distribution from faces based on face areas or edge lengths", + NULL}, + {"distribution", + (getter)Part_getDist, (setter)Part_setDist, + "How to distribute particles on selected element Paricle.DISTRIBUTION[ 'GRID' | 'RANDOM' | 'JITTERED' ] )", + NULL}, + {"jitterAmount", + (getter)Part_getJitterAmount, (setter)Part_setJitterAmount, + "Amount of jitter applied to the sampling", + NULL}, + {"pf", + (getter)Part_getPF, (setter)Part_setPF, + "Emission locations / face (0 = automatic)", + NULL}, + {"invert", + (getter)Part_getInvert, (setter)Part_setInvert, + "Invert what is considered object and what is not.", + NULL}, + {"targetObject", + (getter)Part_getTargetOb, (setter)Part_setTargetOb, + "The object that has the target particle system (empty if same object)", + NULL}, + {"targetpsys", + (getter)Part_getTargetPsys, (setter)Part_setTargetPsys, + "The target particle system number in the object", + NULL}, +/* Physics */ + {"2d", + (getter)Part_get2d, (setter)Part_set2d, + "Constrain boids to a surface", + NULL}, + {"maxvel", + (getter)Part_getMaxVel, (setter)Part_setMaxVel, + "Maximum velocity", + NULL}, + {"avvel", + (getter)Part_getAvVel, (setter)Part_setAvVel, + "The usual speed % of max velocity", + NULL}, + {"latacc", + (getter)Part_getLatAcc, (setter)Part_setLatAcc, + "Lateral acceleration % of max velocity", + NULL}, + {"tanacc", + (getter)Part_getMaxTan, (setter)Part_setMaxTan, + "Tangential acceleration % of max velocity", + NULL}, + {"groundz", + (getter)Part_getGroundZ, (setter)Part_setGroundZ, + "Default Z value", + NULL}, + {"object", + (getter)Part_getOb, (setter)Part_setOb, + "Constrain boids to object's surface", + NULL}, +/* Visualisation */ + {"renderEmitter", + (getter)Part_getRenderObject, (setter)Part_setRenderObject, + "Render emitter object", + NULL}, + {"displayPercentage", + (getter)Part_getParticleDisp, (setter)Part_setParticleDisp, + "Particle display percentage", + NULL}, + {"hairDisplayStep", + (getter)Part_getStep, (setter)Part_setStep, + "How many steps paths are drawn with (power of 2)", + NULL}, + {"hairRenderStep", + (getter)Part_getRenderStep, (setter)Part_setRenderStep, + "How many steps paths are rendered with (power of 2)", + NULL}, + {"duplicateObject", + (getter)Part_getDupOb, NULL, + "Get the duplicate ob", + NULL}, + {"drawAs", + (getter)Part_getDrawAs, NULL, + "Get draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ] )", + NULL}, + {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ +}; + +/*****************************************************************************/ +/* Python method structure definition for Blender.Particle module: */ +/*****************************************************************************/ +static struct PyMethodDef M_ParticleSYS_methods[] = { + {"New", ( PyCFunction ) M_ParticleSYS_New, METH_VARARGS, M_ParticleSYS_New_doc}, + {"Get", M_ParticleSYS_Get, METH_VARARGS, M_ParticleSYS_Get_doc}, {NULL, NULL, 0, NULL} }; -/**************** prototypes ********************/ -PyObject *Particle_Init( void ); - - /*****************************************************************************/ -/* Python Particle_Type structure definition: */ +/* Python ParticleSYS_Type structure definition: */ /*****************************************************************************/ +PyTypeObject ParticleSYS_Type = { + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ + /* For printing, in format "." */ + "Blender ParticleSYS", /* char *tp_name; */ + sizeof( BPy_PartSYS ), /* int tp_basicsize; */ + 0, /* tp_itemsize; For allocation */ -PyTypeObject Particle_Type = { - PyObject_HEAD_INIT( NULL ) - 0, - "Particle", - sizeof( BPy_Particle ), - 0, + /* Methods to implement standard operations */ - ( destructor ) ParticleDeAlloc, - 0, - ( getattrfunc ) ParticleGetAttr, - ( setattrfunc ) ParticleSetAttr, - 0, - ( reprfunc ) ParticleRepr, - 0, - 0, - 0, - 0, - 0, 0, 0, 0, 0, 0, - 0, - 0, 0, 0, 0, 0, 0, - BPy_Particle_methods, - 0, + NULL, /* destructor tp_dealloc; */ + NULL, /* printfunc tp_print; */ + NULL, /* getattrfunc tp_getattr; */ + NULL, /* setattrfunc tp_setattr; */ + NULL, /* cmpfunc tp_compare; */ + ( reprfunc ) ParticleSYS_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_ParticleSYS_methods, /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + BPy_ParticleSYS_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 }; + /*****************************************************************************/ -/* The following string definitions are used for documentation strings. */ -/* In Python these will be written to the console when doing a */ -/* Blender.Particle.__doc__ */ +/* Function: PARTICLESYS_repr */ +/* Description: This is a callback function for the BPy_Effect type. It */ +/* builds a meaninful string to represent effcte objects. */ /*****************************************************************************/ -char M_Particle_doc[] = "The Blender Particle module\n\n\ -This module provides access to **Object Data** in Blender.\n\ -Functions :\n\ - New(object mesh's name) : creates a new part object and adds it to the given mesh object \n\ - Get(name) : retreives a particle with the given name (mandatory)\n\ - get(name) : same as Get. Kept for compatibility reasons.\n"; -char M_Particle_New_doc[] = "New(name) : creates a new part object and adds it to the given mesh object\n"; -char M_Particle_Get_doc[] = "xxx"; +static PyObject *ParticleSYS_repr( void ) +{ + return PyString_FromString( "ParticleSYS" ); +} /*****************************************************************************/ -/* Python method structure definition for Blender.Particle module: */ +/* Function : P_sys_FromPyObject */ /*****************************************************************************/ -struct PyMethodDef M_Particle_methods[] = { - {"New", ( PyCFunction ) M_Particle_New, METH_VARARGS, M_Particle_New_doc}, - {"Get", M_Particle_Get, METH_VARARGS, M_Particle_Get_doc}, - {"get", M_Particle_Get, METH_VARARGS, M_Particle_Get_doc}, - {NULL, NULL, 0, NULL} -}; +struct ParticleSystem *P_sys_FromPyObject( BPy_PartSYS * py_obj ) +{ + BPy_PartSYS *blen_obj; + blen_obj = ( BPy_PartSYS * ) py_obj; + return ( blen_obj->psys ); +} + /*****************************************************************************/ -/* Function: M_Particle_New */ -/* Python equivalent: Blender.Effect.Particle.New */ -/* Description : Create a particle effect and add a link */ -/* to the given mesh-type Object */ -/* Data : String mesh object name */ -/* Return : pyobject particle */ +/* Function : P_sysCreatePyObject */ /*****************************************************************************/ -PyObject *M_Particle_New( PyObject * self, PyObject * args ) +PyObject *P_sysCreatePyObject( ParticleSystem * psystem, Object *ob ) { - BPy_Effect *pyeffect; - Effect *bleffect = 0; + BPy_PartSYS *blen_object; + + blen_object = + ( BPy_PartSYS * ) PyObject_NEW( BPy_PartSYS, &ParticleSYS_Type ); + + if( blen_object ) + blen_object->psys = (ParticleSystem *)psystem; + + blen_object->object = ob; + + return ( PyObject * ) blen_object; +} + +PyObject *M_ParticleSYS_New( PyObject * self, PyObject * args ){ + ParticleSystem *psys = 0; + ParticleSystem *rpsys = 0; + ModifierData *md; + ParticleSystemModifierData *psmd; + Object *ob = NULL; + char *name = NULL; + ID *id; + int nr; + + if( !PyArg_ParseTuple( args, "s", &name ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected string argument" ); + + 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" ); + + id = (ID *)psys_new_settings("PSys", G.main); + + psys = MEM_callocN(sizeof(ParticleSystem), "particle_system"); + psys->pointcache = BKE_ptcache_add(); + psys->flag |= PSYS_ENABLED; + BLI_addtail(&ob->particlesystem,psys); + + md = modifier_new(eModifierType_ParticleSystem); + sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem)); + psmd = (ParticleSystemModifierData*) md; + psmd->psys=psys; + BLI_addtail(&ob->modifiers, md); + + psys->part=(ParticleSettings*)id; + psys->totpart=0; + psys->flag=PSYS_ENABLED|PSYS_CURRENT; + psys->cfra=bsystem_time(ob,(float)G.scene->r.cfra+1,0.0); + rpsys = psys; + + /* check need for dupliobjects */ + + nr=0; + for(psys=ob->particlesystem.first; psys; psys=psys->next){ + if(ELEM(psys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR)) + nr++; + } + if(nr) + ob->transflag |= OB_DUPLIPARTS; + else + ob->transflag &= ~OB_DUPLIPARTS; + + BIF_undo_push("Browse Particle System"); + + DAG_scene_sort(G.scene); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + + return P_sysCreatePyObject(rpsys,ob); +} + +PyObject *M_ParticleSYS_Get( PyObject * self, PyObject * args ){ + ParticleSystem *blparticlesys = 0; Object *ob; char *name = NULL; + PyObject *partsyslist,*current; if( !PyArg_ParseTuple( args, "s", &name ) ) return EXPP_ReturnPyObjError( PyExc_TypeError, @@ -279,759 +528,1222 @@ return EXPP_ReturnPyObjError( PyExc_AttributeError, "object does not exist" ); - if( ob->type != OB_MESH ) - return EXPP_ReturnPyObjError( PyExc_AttributeError, - "object is not a mesh" ); + blparticlesys = ob->particlesystem.first; - pyeffect = ( BPy_Effect * ) PyObject_NEW( BPy_Effect, &Effect_Type ); - if( !pyeffect ) - return EXPP_ReturnPyObjError( PyExc_MemoryError, - "couldn't create Effect Data object" ); + partsyslist = PyList_New( 0 ); - bleffect = add_effect( EFF_PARTICLE ); - if( !bleffect ) { - Py_DECREF( pyeffect ); - return EXPP_ReturnPyObjError( PyExc_RuntimeError, - "couldn't create Effect Data in Blender" ); + if (!blparticlesys) + return partsyslist; + + current = P_sysCreatePyObject( blparticlesys, ob ); + PyList_Append(partsyslist,current); + + while(blparticlesys = blparticlesys->next){ + current = P_sysCreatePyObject( blparticlesys, ob ); + PyList_Append(partsyslist,current); } - pyeffect->effect = (PartEff *)bleffect; - BLI_addtail( &ob->effect, bleffect ); - - return ( PyObject * ) pyeffect; + return partsyslist; } + /*****************************************************************************/ -/* Function: M_Particle_Get */ -/* Python equivalent: Blender.Effect.Particle.Get */ +/* Function: ParticleSYS_Init */ /*****************************************************************************/ -PyObject *M_Particle_Get( PyObject * self, PyObject * args ) -{ - /*arguments : string object name - int : position of effect in the obj's effect list */ - char *name = 0; - Object *object_iter; - Effect *eff; - BPy_Particle *wanted_eff; - int num, i; - if( !PyArg_ParseTuple( args, "si", &name, &num ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected string int argument" ) ); +/* create the Blender.Particle.Type constant dict */ - object_iter = G.main->object.first; - if( !object_iter ) - return EXPP_ReturnPyObjError( PyExc_AttributeError, - "Scene contains no object" ); +static PyObject *Particle_TypeDict( void ) +{ + PyObject *Types = PyConstant_New( ); - while( object_iter ) { - if( strcmp( name, object_iter->id.name + 2 ) ) { - object_iter = object_iter->id.next; - continue; - } + if( Types ) { + BPy_constant *c = ( BPy_constant * ) Types; - if( object_iter->effect.first != NULL ) { - eff = object_iter->effect.first; - for( i = 0; i < num; i++ ) { - if( eff->type != EFF_PARTICLE ) - continue; - eff = eff->next; - if( !eff ) - return ( EXPP_ReturnPyObjError - ( PyExc_AttributeError, - "Object" ) ); - } - wanted_eff = - ( BPy_Particle * ) PyObject_NEW( BPy_Particle, - &Particle_Type ); - wanted_eff->particle = eff; - return ( PyObject * ) wanted_eff; - } - object_iter = object_iter->id.next; + PyConstant_Insert( c, "HAIR", + PyInt_FromLong( 2 ) ); + PyConstant_Insert( c, "REACTOR", + PyInt_FromLong( 1 ) ); + PyConstant_Insert( c, "EMITTER", + PyInt_FromLong( 0 ) ); } - Py_INCREF( Py_None ); - return Py_None; + return Types; } -/*****************************************************************************/ -/* Function: Particle_Init */ -/*****************************************************************************/ -PyObject *Particle_Init( void ) +/* create the Blender.Particle.Distribution constant dict */ + +static PyObject *Particle_DistrDict( void ) { - PyObject *submodule; - - if( PyType_Ready( &Particle_Type) < 0) - return NULL; - - submodule = - Py_InitModule3( "Blender.Particle", M_Particle_methods, M_Particle_doc ); - return ( submodule ); + PyObject *Distr = PyConstant_New( ); + + if( Distr ) { + BPy_constant *c = ( BPy_constant * ) Distr; + + PyConstant_Insert( c, "GRID", + PyInt_FromLong( 2 ) ); + PyConstant_Insert( c, "RANDOM", + PyInt_FromLong( 1 ) ); + PyConstant_Insert( c, "JITTERED", + PyInt_FromLong( 0 ) ); + } + return Distr; } -/*****************************************************************************/ -/* Python BPy_Particle methods: */ -/*****************************************************************************/ +/* create the Blender.Particle.EmitFrom constant dict */ -PyObject *Particle_getSta( BPy_Particle * self ) +static PyObject *Particle_EmitFrom( void ) { + PyObject *EmitFrom = PyConstant_New( ); - PartEff *ptr = ( PartEff * ) self->particle; - return PyFloat_FromDouble( ptr->sta ); + if( EmitFrom ) { + BPy_constant *c = ( BPy_constant * ) EmitFrom; + + PyConstant_Insert( c, "VERTS", + PyInt_FromLong( 0 ) ); + PyConstant_Insert( c, "FACES", + PyInt_FromLong( 1 ) ); + PyConstant_Insert( c, "VOLUME", + PyInt_FromLong( 2 ) ); + PyConstant_Insert( c, "PARTICLE", + PyInt_FromLong( 3 ) ); + } + return EmitFrom; } +/* create the Blender.Particle.Collision constant dict */ +static PyObject *Particle_ReactOnDict( void ) +{ + PyObject *ReactOn = PyConstant_New( ); -PyObject *Particle_setSta( BPy_Particle * self, PyObject * args ) -{ - PartEff *ptr = ( PartEff * ) self->particle; - float val = 0; - if( !PyArg_ParseTuple( args, "f", &val ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected float argument" ) ); - ptr->sta = val; - Py_INCREF( Py_None ); - return Py_None; + if( ReactOn ) { + BPy_constant *c = ( BPy_constant * ) ReactOn; + + PyConstant_Insert( c, "NEAR", + PyInt_FromLong( 2 ) ); + PyConstant_Insert( c, "COLLISION", + PyInt_FromLong( 1 ) ); + PyConstant_Insert( c, "DEATH", + PyInt_FromLong( 0 ) ); + } + return ReactOn; } -PyObject *Particle_getEnd( BPy_Particle * self ) +static PyObject *Particle_DrawAs( void ) { + PyObject *DrawAs = PyConstant_New( ); - PartEff *ptr = ( PartEff * ) self->particle; - return PyFloat_FromDouble( ptr->end ); + if( DrawAs ) { + BPy_constant *c = ( BPy_constant * ) DrawAs; + + PyConstant_Insert( c, "NONE", + PyInt_FromLong( 0 ) ); + PyConstant_Insert( c, "POINT", + PyInt_FromLong( 1 ) ); + PyConstant_Insert( c, "CIRCLE", + PyInt_FromLong( 2 ) ); + PyConstant_Insert( c, "CROSS", + PyInt_FromLong( 3 ) ); + PyConstant_Insert( c, "AXIS", + PyInt_FromLong( 4 ) ); + PyConstant_Insert( c, "LINE", + PyInt_FromLong( 5 ) ); + PyConstant_Insert( c, "PATH", + PyInt_FromLong( 6 ) ); + PyConstant_Insert( c, "OBJECT", + PyInt_FromLong( 7 ) ); + PyConstant_Insert( c, "GROUP", + PyInt_FromLong( 8 ) ); + PyConstant_Insert( c, "BILLBOARD", + PyInt_FromLong( 9 ) ); + } + return DrawAs; } +void Particle_Recalc(BPy_PartSYS* self,int child){ + psys_flush_settings(self->psys->part,0,child ); +} +void Particle_RecalcPsys_distr(BPy_PartSYS* self,int child){ + psys_flush_settings(self->psys->part,PSYS_DISTR,child); +} -PyObject *Particle_setEnd( BPy_Particle * self, PyObject * args ) -{ - float val = 0; - PartEff *ptr = ( PartEff * ) self->particle; - if( !PyArg_ParseTuple( args, "f", &val ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected float argument" ) ); - ptr->end = val; - Py_INCREF( Py_None ); - return Py_None; +PyObject *ParticleSYS_Init( void ){ + PyObject *submodule; + PyObject *Types; + PyObject *React; + PyObject *EmitFrom; + PyObject *Dist; + PyObject *DrawAs; + + if( PyType_Ready( &ParticleSYS_Type ) < 0) + return NULL; + + Types = Particle_TypeDict (); + React = Particle_ReactOnDict(); + EmitFrom = Particle_EmitFrom(); + DrawAs = Particle_DrawAs(); + Dist = Particle_DistrDict(); + + submodule = Py_InitModule3( "Blender.Particle", M_ParticleSYS_methods, 0 ); + + if( Types ) + PyModule_AddObject( submodule, "TYPE", Types ); + if( React ) + PyModule_AddObject( submodule, "REACTON", React ); + if( EmitFrom ) + PyModule_AddObject( submodule, "EMITFROM", EmitFrom ); + if( Dist ) + PyModule_AddObject( submodule, "DISTRIBUTION", Dist ); + if( DrawAs ) + PyModule_AddObject( submodule, "DRAWAS", DrawAs ); + + return ( submodule ); } -PyObject *Particle_getLifetime( BPy_Particle * self ) -{ +static PyObject *Part_freeEdit( BPy_PartSYS * self, PyObject * args ){ - PartEff *ptr = ( PartEff * ) self->particle; - return PyFloat_FromDouble( ptr->lifetime ); + if(self->psys->flag & PSYS_EDITED){ + if(self->psys->edit) + PE_free_particle_edit(self->psys); + + self->psys->flag &= ~PSYS_EDITED; + self->psys->recalc |= PSYS_RECALC_HAIR; + + DAG_object_flush_update(G.scene, self->object, OB_RECALC_DATA); + } + Py_RETURN_NONE; } +static PyObject *Part_GetLoc( BPy_PartSYS * self, PyObject * args ){ + ParticleSystem *psys = 0L; + Object *ob = 0L; + PyObject *partlist,*seglist; + PyObject* loc; + ParticleCacheKey **cache,*path; + ParticleKey state; + float cfra=bsystem_time(ob,(float)CFRA,0.0); + int i,j,k; + int childexists = 0; + int all = 0; + int id = 0; + if( !PyArg_ParseTuple( args, "|ii", &all,&id ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected one optional integer as argument" ); -PyObject *Particle_setLifetime( BPy_Particle * self, PyObject * args ) -{ - PartEff *ptr = ( PartEff * ) self->particle; - float val = 0; - if( !PyArg_ParseTuple( args, "f", &val ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected float argument" ) ); - ptr->lifetime = val; - Py_INCREF( Py_None ); - return Py_None; + psys = self->psys; + ob = self->object; + + if (!ob || !psys) + Py_RETURN_NONE; + + if (psys->part->type == 2){ + cache=psys->pathcache; + + /* little hack to calculate hair steps in render mode */ + psys->renderdata = (void*)(int)1; + + psys_cache_paths(ob, psys, cfra, 0); + + psys->renderdata = NULL; + + partlist = PyList_New( 0 ); + if( !partlist ) + return EXPP_ReturnPyObjError( PyExc_MemoryError, "PyList() failed" ); + + for(i = 0; i < psys->totpart; i++){ + path=cache[i]; + seglist = PyList_New( 0 ); + k = path->steps+1; + for( j = 0; j < k ; j++){ + loc = PyTuple_New(3); + + PyTuple_SetItem(loc,0,PyFloat_FromDouble((double)path->co[0])); + PyTuple_SetItem(loc,1,PyFloat_FromDouble((double)path->co[1])); + PyTuple_SetItem(loc,2,PyFloat_FromDouble((double)path->co[2])); + + if ( (PyList_Append(seglist,loc) < 0) ){ + Py_DECREF(seglist); + Py_DECREF(partlist); + Py_XDECREF(loc); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } + + path++; + } + + if ( PyList_Append(partlist,seglist) < 0 ){ + Py_DECREF(seglist); + Py_DECREF(partlist); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } + } + + cache=psys->childcache; + + for(i = 0; i < psys->totchild; i++){ + path=cache[i]; + seglist = PyList_New( 0 ); + k = path->steps+1; + for( j = 0; j < k ; j++){ + loc = PyTuple_New(3); + + PyTuple_SetItem(loc,0,PyFloat_FromDouble((double)path->co[0])); + PyTuple_SetItem(loc,1,PyFloat_FromDouble((double)path->co[1])); + PyTuple_SetItem(loc,2,PyFloat_FromDouble((double)path->co[2])); + + if ( PyList_Append(seglist,loc) < 0){ + Py_DECREF(partlist); + Py_XDECREF(loc); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } + + path++; + } + + if ( PyList_Append(partlist,seglist) < 0){ + Py_DECREF(partlist); + Py_XDECREF(loc); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } + } + + } else { + int init; + partlist = PyList_New( 0 ); + if( !partlist ) + return EXPP_ReturnPyObjError( PyExc_MemoryError, "PyList() failed" ); + + if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT)) + childexists = 1; + + for (i = 0; i < psys->totpart + psys->totchild; i++){ + if (childexists && (i < psys->totpart)) + continue; + + state.time = cfra; + if(psys_get_particle_state(ob,psys,i,&state,0)==0) + init = 0; + else + init = 1; + + if (init){ + if (!id) + loc = PyTuple_New(3); + else + loc = PyTuple_New(4); + PyTuple_SetItem(loc,0,PyFloat_FromDouble((double)state.co[0])); + PyTuple_SetItem(loc,1,PyFloat_FromDouble((double)state.co[1])); + PyTuple_SetItem(loc,2,PyFloat_FromDouble((double)state.co[2])); + if (id) + PyTuple_SetItem(loc,3,PyInt_FromLong(i)); + + if ( PyList_Append(partlist,loc) < 0 ){ + Py_DECREF(partlist); + Py_XDECREF(loc); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } + } + else { + if ( all ){ + if ( PyList_Append(partlist,Py_None) < 0 ){ + Py_DECREF(partlist); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } + } + } + } + } + return partlist; } +static PyObject *Part_GetRot( BPy_PartSYS * self, PyObject * args ){ + ParticleSystem *psys = 0L; + Object *ob = 0L; + PyObject *partlist; + PyObject* loc = 0L; + ParticleKey state; + int i; + int childexists = 0; + int all = 0; + int id = 0; -PyObject *Particle_getNormfac( BPy_Particle * self ) -{ + float cfra=bsystem_time(ob,(float)CFRA,0.0); - PartEff *ptr = ( PartEff * ) self->particle; - return PyFloat_FromDouble( ptr->normfac ); + if( !PyArg_ParseTuple( args, "|ii", &all, &id ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected one optional integer as argument" ); + + psys = self->psys; + ob = self->object; + + if (!ob || !psys) + Py_RETURN_NONE; + + if (psys->part->type != 2){ + partlist = PyList_New( 0 ); + + if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT)) + childexists = 1; + + for (i = 0; i < psys->totpart + psys->totchild; i++){ + if (childexists && (i < psys->totpart)) + continue; + + state.time = cfra; + if(psys_get_particle_state(ob,psys,i,&state,0)==0){ + if ( all ){ + PyList_Append(partlist,Py_None); + continue; + } else { + continue; + } + } + if (!id) + loc = PyTuple_New(4); + else + loc = PyTuple_New(5); + PyTuple_SetItem(loc,0,PyFloat_FromDouble((double)state.rot[0])); + PyTuple_SetItem(loc,1,PyFloat_FromDouble((double)state.rot[1])); + PyTuple_SetItem(loc,2,PyFloat_FromDouble((double)state.rot[2])); + PyTuple_SetItem(loc,3,PyFloat_FromDouble((double)state.rot[3])); + if (id) + PyTuple_SetItem(loc,4,PyInt_FromLong(i)); + PyList_Append(partlist,loc); + } + } + return partlist; } +static PyObject *Part_GetSize( BPy_PartSYS * self, PyObject * args ){ + ParticleKey state; + ParticleSystem *psys = 0L; + ParticleData *data; + Object *ob = 0L; + PyObject *partlist,*tuple; + PyObject* siz = 0L; + float size; + int i; + int childexists = 0; + int all = 0; + int id = 0; + float cfra=bsystem_time(ob,(float)CFRA,0.0); -PyObject *Particle_setNormfac( BPy_Particle * self, PyObject * args ) -{ - PartEff *ptr = ( PartEff * ) self->particle; - float val = 0; - if( !PyArg_ParseTuple( args, "f", &val ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected float argument" ) ); - ptr->normfac = val; - Py_INCREF( Py_None ); - return Py_None; + if( !PyArg_ParseTuple( args, "|ii", &all, &id ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected one optional integer as argument" ); + + data = self->psys->particles; + + psys = self->psys; + ob = self->object; + + if (!ob || !psys) + Py_RETURN_NONE; + + partlist = PyList_New( 0 ); + + if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT)) + childexists = 1; + + for (i = 0; i < psys->totpart + psys->totchild; i++, data++){ + if (psys->part->type != 2){ + if (childexists && (i < psys->totpart)) + continue; + + if ( !all ){ + state.time = cfra; + if(psys_get_particle_state(ob,psys,i,&state,0)==0) + continue; + } + + if (i < psys->totpart){ + size = data->size; + } else { + ChildParticle *cpa= &psys->child[i-psys->totpart]; + size = psys_get_child_size(psys,cpa,cfra,0); + } + if (id){ + tuple = PyTuple_New(2); + PyTuple_SetItem(tuple,0,PyFloat_FromDouble((double)size)); + PyTuple_SetItem(tuple,1,PyInt_FromLong(i)); + PyList_Append(partlist,tuple); + } else { + siz = PyFloat_FromDouble((double)size); + PyList_Append(partlist,siz); + } + } + } + return partlist; } +static PyObject *Part_GetAge( BPy_PartSYS * self, PyObject * args ){ + ParticleKey state; + ParticleSystem *psys = 0L; + ParticleData *data; + Object *ob = 0L; + PyObject *partlist,*tuple; + PyObject* lif = 0L; + float life; + int i; + int childexists = 0; + int all = 0; + int id = 0; -PyObject *Particle_getObfac( BPy_Particle * self ) -{ + float cfra=bsystem_time(ob,(float)CFRA,0.0); - PartEff *ptr = ( PartEff * ) self->particle; - return PyFloat_FromDouble( ptr->obfac ); + if( !PyArg_ParseTuple( args, "|ii", &all, &id ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected one optional integer as argument" ); + + data = self->psys->particles; + + psys = self->psys; + ob = self->object; + + if (!ob || !psys) + Py_RETURN_NONE; + + partlist = PyList_New( 0 ); + + if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT)) + childexists = 1; + + for (i = 0; i < psys->totpart + psys->totchild; i++, data++){ + if (psys->part->type != 2){ + + if (childexists && (i < psys->totpart)) + continue; + + if ( !all ){ + state.time = cfra; + if(psys_get_particle_state(ob,psys,i,&state,0)==0) + continue; + } + + if (i < psys->totpart){ + life = (cfra-data->time)/data->lifetime; + } else { + ChildParticle *cpa= &psys->child[i-psys->totpart]; + life = psys_get_child_time(psys,cpa,cfra); + } + if (id){ + tuple = PyTuple_New(2); + PyTuple_SetItem(tuple,0,PyFloat_FromDouble((double)life)); + PyTuple_SetItem(tuple,1,PyInt_FromLong(i)); + PyList_Append(partlist,tuple); + } else { + lif = PyFloat_FromDouble((double)life); + PyList_Append(partlist,lif); + } + } + } + return partlist; } +static PyObject *Part_GetMat( BPy_PartSYS * self, PyObject * args ){ + Material *ma; + PyObject* mat = 0L; + ma = give_current_material(self->object,self->psys->part->omat); + if(!ma) + Py_RETURN_NONE; -PyObject *Particle_setObfac( BPy_Particle * self, PyObject * args ) -{ - float val = 0; - PartEff *ptr = ( PartEff * ) self->particle; - if( !PyArg_ParseTuple( args, "f", &val ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected float argument" ) ); - ptr->obfac = val; - Py_INCREF( Py_None ); - return Py_None; + mat = Material_CreatePyObject(ma); + return mat; } +/*****************************************************************************/ +/* Function: Set/Get Seed */ +/*****************************************************************************/ -PyObject *Particle_getRandfac( BPy_Particle * self ) +static int Part_setSeed( BPy_PartSYS * self, PyObject * args ) { + return EXPP_setIValueRange( args, &self->psys->seed, + 0, 255, 'i' ); +} - PartEff *ptr = ( PartEff * ) self->particle; - return PyFloat_FromDouble( ptr->randfac ); +static PyObject *Part_getSeed( BPy_PartSYS * self ) +{ + return PyInt_FromLong( (long)( self->psys->seed ) ); } +static int Part_setType( BPy_PartSYS * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->type, + 0, 2, 'h' ); + psys_flush_settings( self->psys->part, PSYS_TYPE, 1 ); -PyObject *Particle_setRandfac( BPy_Particle * self, PyObject * args ) + return res; +} + +static PyObject *Part_getType( BPy_PartSYS * self ) { - float val = 0; - PartEff *ptr = ( PartEff * ) self->particle; - if( !PyArg_ParseTuple( args, "f", &val ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected float argument" ) ); - ptr->randfac = val; - Py_INCREF( Py_None ); - return Py_None; + return PyInt_FromLong( (short)( self->psys->part->type ) ); } +static int Part_setResol( BPy_PartSYS * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->grid_res, + 0, 100, 'i' ); + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); -PyObject *Particle_getTexfac( BPy_Particle * self ) + return res; +} + +static PyObject *Part_getResol( BPy_PartSYS * self ) { - - PartEff *ptr = ( PartEff * ) self->particle; - return PyFloat_FromDouble( ptr->texfac ); + return PyInt_FromLong( ((int)( self->psys->part->grid_res )) ); } +static int Part_setStart( BPy_PartSYS * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->sta, + 0.0f, 100000.0f ); + psys_flush_settings(self->psys->part,PSYS_INIT,1); -PyObject *Particle_setTexfac( BPy_Particle * self, PyObject * args ) + return res; +} + +static PyObject *Part_getStart( BPy_PartSYS * self ) { - PartEff *ptr = ( PartEff * ) self->particle; - float val = 0; - if( !PyArg_ParseTuple( args, "f", &val ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected float argument" ) ); - ptr->texfac = val; - Py_INCREF( Py_None ); - return Py_None; + return PyFloat_FromDouble( (float)( self->psys->part->sta ) ); } +static int Part_setEnd( BPy_PartSYS * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->end, + 0.0f, 100000.0f ); + psys_flush_settings(self->psys->part,PSYS_INIT,1); -PyObject *Particle_getRandlife( BPy_Particle * self ) + return res; +} + +static PyObject *Part_getEnd( BPy_PartSYS * self ) { - - PartEff *ptr = ( PartEff * ) self->particle; - return PyFloat_FromDouble( ptr->randlife ); + return PyFloat_FromDouble( (long)( self->psys->part->end ) ); } +static int Part_setEditable( BPy_PartSYS * self, PyObject * args ) +{ + int number; + if( !PyInt_Check( args ) ) { + char errstr[128]; + sprintf ( errstr, "expected int argument" ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); + } -PyObject *Particle_setRandlife( BPy_Particle * self, PyObject * args ) + number = PyInt_AS_LONG( args ); + + if(!number){ + if(self->psys->edit) + PE_free_particle_edit(self->psys); + + self->psys->flag &= ~PSYS_EDITED; + self->psys->recalc |= PSYS_RECALC_HAIR; + + DAG_object_flush_update(G.scene, self->object, OB_RECALC_DATA); + } + else + { + self->psys->flag |= PSYS_EDITED; + if(G.f & G_PARTICLEEDIT) + PE_create_particle_edit(self->object, self->psys); + } + + return 0; +} + +static PyObject *Part_getEditable( BPy_PartSYS * self ) { - PartEff *ptr = ( PartEff * ) self->particle; - float val = 0; - if( !PyArg_ParseTuple( args, "f", &val ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected float argument" ) ); - ptr->randlife = val; - Py_INCREF( Py_None ); - return Py_None; + return PyInt_FromLong( ((long)( self->psys->flag & PSYS_EDITED )) > 0 ); } +static int Part_setAmount( BPy_PartSYS * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->totpart, + 0, 100000, 'i' ); + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); -PyObject *Particle_getNabla( BPy_Particle * self ) + return res; +} + +static PyObject *Part_getAmount( BPy_PartSYS * self ) { - - PartEff *ptr = ( PartEff * ) self->particle; - return PyFloat_FromDouble( ptr->nabla ); + return PyInt_FromLong( ((int)( self->psys->part->totpart )) ); } +static int Part_setMultiReact( BPy_PartSYS * self, PyObject * args ) +{ + int number; + if( !PyInt_Check( args ) ) { + char errstr[128]; + sprintf ( errstr, "expected int argument" ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); + } -PyObject *Particle_setNabla( BPy_Particle * self, PyObject * args ) + number = PyInt_AS_LONG( args ); + + + if (number){ + self->psys->part->flag |= PART_REACT_MULTIPLE; + }else{ + self->psys->part->flag &= ~PART_REACT_MULTIPLE; + } + + Particle_Recalc(self,1); + + return 0; +} + +static PyObject *Part_getMultiReact( BPy_PartSYS * self ) { - PartEff *ptr = ( PartEff * ) self->particle; - float val = 0; - if( !PyArg_ParseTuple( args, "f", &val ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected float argument" ) ); - ptr->nabla = val; - Py_INCREF( Py_None ); - return Py_None; + return PyInt_FromLong( ((long)( self->psys->part->flag & PART_REACT_MULTIPLE )) > 0 ); } +static int Part_setReactShape( BPy_PartSYS * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->reactshape, + 0.0f, 10.0f ); + Particle_Recalc(self,1); -PyObject *Particle_getVectsize( BPy_Particle * self ) + return res; +} + +static PyObject *Part_getReactShape( BPy_PartSYS * self ) { - - PartEff *ptr = ( PartEff * ) self->particle; - return PyFloat_FromDouble( ptr->vectsize ); + return PyFloat_FromDouble( ((double)( self->psys->part->reactshape )) ); } +static int Part_setSegments( BPy_PartSYS * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->hair_step, + 2, 50, 'h' ); + Particle_Recalc(self,1); -PyObject *Particle_setVectsize( BPy_Particle * self, PyObject * args ) + return res; +} + +static PyObject *Part_getSegments( BPy_PartSYS * self ) { - PartEff *ptr = ( PartEff * ) self->particle; - float val = 0; - if( !PyArg_ParseTuple( args, "f", &val ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected float argument" ) ); - ptr->vectsize = val; - Py_INCREF( Py_None ); - return Py_None; + return PyInt_FromLong( ((long)( self->psys->part->hair_step )) ); } - -PyObject *Particle_getTotpart( BPy_Particle * self ) +static int Part_setLife( BPy_PartSYS * self, PyObject * args ) { + int res = EXPP_setFloatRange( args, &self->psys->part->lifetime, + 1.0f, MAXFRAMEF ); - PartEff *ptr = ( PartEff * ) self->particle; - return PyInt_FromLong( ptr->totpart ); + Particle_Recalc(self,1); + + return res; } +static PyObject *Part_getLife( BPy_PartSYS * self ) +{ + return PyFloat_FromDouble( ((double)( self->psys->part->lifetime )) ); +} +static int Part_setRandLife( BPy_PartSYS * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->randlife, + 0.0f, 2.0f ); -PyObject *Particle_setTotpart( BPy_Particle * self, PyObject * args ) + Particle_Recalc(self,1); + + return res; +} + +static PyObject *Part_getRandLife( BPy_PartSYS * self ) { - int val = 0; - PartEff *ptr = ( PartEff * ) self->particle; - if( !PyArg_ParseTuple( args, "i", &val ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected int argument" ) ); - ptr->totpart = val; - Py_INCREF( Py_None ); - return Py_None; + return PyFloat_FromDouble( ((double)( self->psys->part->randlife )) ); } - -PyObject *Particle_getTotkey( BPy_Particle * self ) +static int Part_set2d( BPy_PartSYS * self, PyObject * args ) { + int number; - PartEff *ptr = ( PartEff * ) self->particle; - return PyInt_FromLong( ptr->totkey ); -} + if( !PyInt_Check( args ) ) { + char errstr[128]; + sprintf ( errstr, "expected int argument" ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); + } + number = PyInt_AS_LONG( args ); + if (number){ + self->psys->part->flag |= PART_BOIDS_2D; + }else{ + self->psys->part->flag &= ~PART_BOIDS_2D; + } -PyObject *Particle_setTotkey( BPy_Particle * self, PyObject * args ) + Particle_Recalc(self,1); + + return 0; +} + +static PyObject *Part_get2d( BPy_PartSYS * self ) { - PartEff *ptr = ( PartEff * ) self->particle; - int val = 0; - if( !PyArg_ParseTuple( args, "i", &val ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected int argument" ) ); - ptr->totkey = val; - Py_INCREF( Py_None ); - return Py_None; + return PyInt_FromLong( ((long)( self->psys->part->flag & PART_BOIDS_2D )) > 0 ); } +static int Part_setMaxVel( BPy_PartSYS * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->max_vel, + 0.0f, 200.0f ); + Particle_Recalc(self,1); -PyObject *Particle_getSeed( BPy_Particle * self ) + return res; +} + +static PyObject *Part_getMaxVel( BPy_PartSYS * self ) { - - PartEff *ptr = ( PartEff * ) self->particle; - return PyInt_FromLong( ptr->seed ); + return PyFloat_FromDouble( ((double)( self->psys->part->max_vel )) ); } +static int Part_setAvVel( BPy_PartSYS * self, PyObject * args ) +{ + int res = EXPP_setFloatRange( args, &self->psys->part->average_vel, + 0.0f, 1.0f ); + Particle_Recalc(self,1); -PyObject *Particle_setSeed( BPy_Particle * self, PyObject * args ) + return res; +} + +static PyObject *Part_getAvVel( BPy_PartSYS * self ) { - PartEff *ptr = ( PartEff * ) self->particle; - int val = 0; - if( !PyArg_ParseTuple( args, "i", &val ) ) - return ( EXPP_ReturnPyObjError( PyExc_AttributeError, - "expected int argument" ) ); - ptr->seed = val; - Py_INCREF( Py_None ); - return Py_None; + return PyFloat_FromDouble( ((double)( self->psys->part->average_vel )) ); } -PyObject *Particle_getForce( BPy_Particle * self ) +static int Part_setLatAcc( BPy_PartSYS * self, PyObject * args ) { + int res = EXPP_setFloatRange( args, &self->psys->part->max_lat_acc, + 0.0f, 1.0f ); - PartEff *ptr = ( PartEff * ) self->particle; - return Py_BuildValue( "(f,f,f)", ptr->force[0], ptr->force[1], - ptr->force[2] ); + Particle_Recalc(self,1); + + return res; } - -PyObject *Particle_setForce( BPy_Particle * self, PyObject * args ) +static PyObject *Part_getLatAcc( BPy_PartSYS * self ) { - PartEff *ptr = ( PartEff * ) self->particle; - float val[3]; - if( PyTuple_Size( args ) == 1 ) - args = PyTuple_GetItem( args, 0 ); - val[0] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 0 ) ); - val[1] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 1 ) ); - val[2] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 2 ) ); - /* - if (!PyArg_ParseTuple(args, "fff", val,val+1,val+2 )) - return(EXPP_ReturnPyObjError(PyExc_AttributeError,\ - "expected three float arguments")); - */ - ptr->force[0] = val[0]; - ptr->force[1] = val[1]; - ptr->force[2] = val[2]; - Py_INCREF( Py_None ); - return Py_None; + return PyFloat_FromDouble( ((double)( self->psys->part->max_lat_acc )) ); } -PyObject *Particle_getMult( BPy_Particle * self ) +static int Part_setMaxTan( BPy_PartSYS * self, PyObject * args ) { + int res = EXPP_setFloatRange( args, &self->psys->part->max_tan_acc, + 0.0f, 1.0f ); - PartEff *ptr = ( PartEff * ) self->particle; - return Py_BuildValue( "(f,f,f,f)", - ptr->mult[0], ptr->mult[1], ptr->mult[2], - ptr->mult[3] ); + Particle_Recalc(self,1); + + return res; } +static PyObject *Part_getMaxTan( BPy_PartSYS * self ) +{ + return PyFloat_FromDouble( ((double)( self->psys->part->max_tan_acc )) ); +} -PyObject *Particle_setMult( BPy_Particle * self, PyObject * args ) +static int Part_setGroundZ( BPy_PartSYS * self, PyObject * args ) { - PartEff *ptr = ( PartEff * ) self->particle; - float val[4]; - if( PyTuple_Size( args ) == 1 ) - args = PyTuple_GetItem( args, 0 ); - val[0] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 0 ) ); - val[1] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 1 ) ); - val[2] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 2 ) ); - val[3] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 3 ) ); - ptr->mult[0] = val[0]; - ptr->mult[1] = val[1]; - ptr->mult[2] = val[2]; - ptr->mult[3] = val[3]; - Py_INCREF( Py_None ); - return Py_None; + int res = EXPP_setFloatRange( args, &self->psys->part->groundz, + -100.0f, 100.0f ); + + Particle_Recalc(self,1); + + return res; } +static PyObject *Part_getGroundZ( BPy_PartSYS * self ) +{ + return PyFloat_FromDouble( ((double)( self->psys->part->groundz )) ); +} +static int Part_setOb( BPy_PartSYS * self, PyObject * args ) +{ + Object *obj; + if( !BPy_Object_Check( args ) ) { + char errstr[128]; + sprintf ( errstr, "expected object argument" ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); + } + obj = Object_FromPyObject(args); -PyObject *Particle_getLife( BPy_Particle * self ) + self->psys->keyed_ob = obj; + + return 0; +} + +static PyObject *Part_getOb( BPy_PartSYS * self ) { + Object * obj; + obj = self->psys->keyed_ob; + if (!obj) + Py_RETURN_NONE; - PartEff *ptr = ( PartEff * ) self->particle; - return Py_BuildValue( "(f,f,f,f)", - ptr->life[0], ptr->life[1], ptr->life[2], - ptr->life[3] ); + return Object_CreatePyObject( obj ); } +static int Part_setRandEmission( BPy_PartSYS * self, PyObject * args ) +{ + int number; -PyObject *Particle_setLife( BPy_Particle * self, PyObject * args ) + if( !PyInt_Check( args ) ) { + char errstr[128]; + sprintf ( errstr, "expected int argument" ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); + } + + number = PyInt_AS_LONG( args ); + + if (number){ + self->psys->part->flag |= PART_TRAND; + }else{ + self->psys->part->flag &= ~PART_TRAND; + } + + Particle_RecalcPsys_distr(self,1); + + return 0; +} + +static PyObject *Part_getRandEmission( BPy_PartSYS * self ) { - PartEff *ptr = ( PartEff * ) self->particle; - float val[4]; - if( PyTuple_Size( args ) == 1 ) - args = PyTuple_GetItem( args, 0 ); - val[0] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 0 ) ); - val[1] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 1 ) ); - val[2] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 2 ) ); - val[3] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 3 ) ); - ptr->life[0] = val[0]; - ptr->life[1] = val[1]; - ptr->life[2] = val[2]; - ptr->life[3] = val[3]; - Py_INCREF( Py_None ); - return Py_None; + return PyInt_FromLong( ((long)( self->psys->part->flag & PART_BOIDS_2D )) > 0 ); } +static int Part_setPaticleDist( BPy_PartSYS * self, PyObject * args ) +{ + int number; + char errstr[128]; + if( !PyInt_Check( args ) ) { + sprintf ( errstr, "expected int argument" ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); + } -PyObject *Particle_getChild( BPy_Particle * self ) -{ + number = PyInt_AS_LONG( args ); - PartEff *ptr = ( PartEff * ) self->particle; - return Py_BuildValue( "(f,f,f,f)", - ptr->child[0], ptr->child[1], ptr->child[2], - ptr->child[3] ); + if (number < 0 || number > 3){ + sprintf ( errstr, "expected int argument between 0 - 3" ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); + } + + self->psys->part->from = number; + + Particle_RecalcPsys_distr(self,1); + + return 0; } - -PyObject *Particle_setChild( BPy_Particle * self, PyObject * args ) +static PyObject *Part_getPaticleDist( BPy_PartSYS * self ) { - PartEff *ptr = ( PartEff * ) self->particle; - float val[4]; - if( PyTuple_Size( args ) == 1 ) - args = PyTuple_GetItem( args, 0 ); - val[0] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 0 ) ); - val[1] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 1 ) ); - val[2] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 2 ) ); - val[3] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 3 ) ); - ptr->child[0] = (short)val[0]; - ptr->child[1] = (short)val[1]; - ptr->child[2] = (short)val[2]; - ptr->child[3] = (short)val[3]; - Py_INCREF( Py_None ); - return Py_None; + return PyInt_FromLong( (long)( self->psys->part->from ) ); } +static int Part_setEvenDist( BPy_PartSYS * self, PyObject * args ) +{ + int number; + if( !PyInt_Check( args ) ) { + char errstr[128]; + sprintf ( errstr, "expected int argument" ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); + } -PyObject *Particle_getMat( BPy_Particle * self ) -{ + number = PyInt_AS_LONG( args ); - PartEff *ptr = ( PartEff * ) self->particle; - return Py_BuildValue( "(f,f,f,f)", - ptr->mat[0], ptr->mat[1], ptr->mat[2], - ptr->mat[3] ); + if (number){ + self->psys->part->flag |= PART_EDISTR; + }else{ + self->psys->part->flag &= ~PART_EDISTR; + } + + Particle_RecalcPsys_distr(self,1); + + return 0; } - -PyObject *Particle_setMat( BPy_Particle * self, PyObject * args ) +static PyObject *Part_getEvenDist( BPy_PartSYS * self ) { - PartEff *ptr = ( PartEff * ) self->particle; - float val[4]; - if( PyTuple_Size( args ) == 1 ) - args = PyTuple_GetItem( args, 0 ); - val[0] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 0 ) ); - val[1] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 1 ) ); - val[2] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 2 ) ); - val[3] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 3 ) ); - ptr->mat[0] = (short)val[0]; - ptr->mat[1] = (short)val[1]; - ptr->mat[2] = (short)val[2]; - ptr->mat[3] = (short)val[3]; - Py_INCREF( Py_None ); - return Py_None; + return PyInt_FromLong( ((long)( self->psys->part->flag & PART_EDISTR )) > 0 ); } - -PyObject *Particle_getDefvec( BPy_Particle * self ) +static int Part_setDist( BPy_PartSYS * self, PyObject * args ) { + int number; + char errstr[128]; - PartEff *ptr = ( PartEff * ) self->particle; - return Py_BuildValue( "(f,f,f)", - ptr->defvec[0], ptr->defvec[1], ptr->defvec[2] ); + if( !PyInt_Check( args ) ) { + sprintf ( errstr, "expected int argument" ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); + } + + number = PyInt_AS_LONG( args ); + + if (number < 0 || number > 2){ + sprintf ( errstr, "expected int argument between 0 - 2" ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); + } + + self->psys->part->distr = number; + + Particle_RecalcPsys_distr(self,1); + + return 0; } +static PyObject *Part_getDist( BPy_PartSYS * self ) +{ + return PyInt_FromLong( (long)( self->psys->part->distr ) ); +} -PyObject *Particle_setDefvec( BPy_Particle * self, PyObject * args ) +static int Part_setJitterAmount( BPy_PartSYS * self, PyObject * args ) { - PartEff *ptr = ( PartEff * ) self->particle; - float val[3]; - if( PyTuple_Size( args ) == 1 ) - args = PyTuple_GetItem( args, 0 ); - val[0] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 0 ) ); - val[1] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 1 ) ); - val[2] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 2 ) ); - ptr->defvec[0] = val[0]; - ptr->defvec[1] = val[1]; - ptr->defvec[2] = val[2]; - Py_INCREF( Py_None ); - return Py_None; + int res = EXPP_setFloatRange( args, &self->psys->part->jitfac, + 0.0f, 2.0f ); + + Particle_RecalcPsys_distr(self,1); + + return res; } - -/*****************************************************************************/ -/* Function: ParticleDeAlloc */ -/* Description: This is a callback function for the BPy_Particle type. It is */ -/* the destructor function. */ -/*****************************************************************************/ -void ParticleDeAlloc( BPy_Particle * self ) +static PyObject *Part_getJitterAmount( BPy_PartSYS * self ) { - PartEff *ptr = ( PartEff * ) self; - PyObject_DEL( ptr ); + return PyFloat_FromDouble( ((double)( self->psys->part->jitfac )) ); } -/*****************************************************************************/ -/* Function: ParticleGetAttr */ -/* Description: This is a callback function for the BPy_Particle type. It is */ -/* the function that accesses BPy_Particle "member variables" */ -/* and methods. */ -/*****************************************************************************/ -PyObject *ParticleGetAttr( BPy_Particle * self, char *name ) +static int Part_setPF( BPy_PartSYS * self, PyObject * args ) { + int res = EXPP_setIValueRange( args, &self->psys->part->userjit, + 0, 1000, 'i' ); - if( strcmp( name, "seed" ) == 0 ) - return Particle_getSeed( self ); - else if( strcmp( name, "nabla" ) == 0 ) - return Particle_getNabla( self ); - else if( strcmp( name, "sta" ) == 0 ) - return Particle_getSta( self ); - else if( strcmp( name, "end" ) == 0 ) - return Particle_getEnd( self ); - else if( strcmp( name, "lifetime" ) == 0 ) - return Particle_getLifetime( self ); - else if( strcmp( name, "normfac" ) == 0 ) - return Particle_getNormfac( self ); - else if( strcmp( name, "obfac" ) == 0 ) - return Particle_getObfac( self ); - else if( strcmp( name, "randfac" ) == 0 ) - return Particle_getRandfac( self ); - else if( strcmp( name, "texfac" ) == 0 ) - return Particle_getTexfac( self ); - else if( strcmp( name, "randlife" ) == 0 ) - return Particle_getRandlife( self ); - else if( strcmp( name, "vectsize" ) == 0 ) - return Particle_getVectsize( self ); - else if( strcmp( name, "totpart" ) == 0 ) - return Particle_getTotpart( self ); - else if( strcmp( name, "force" ) == 0 ) - return Particle_getForce( self ); - else if( strcmp( name, "mult" ) == 0 ) - return Particle_getMult( self ); - else if( strcmp( name, "life" ) == 0 ) - return Particle_getLife( self ); - else if( strcmp( name, "child" ) == 0 ) - return Particle_getChild( self ); - else if( strcmp( name, "mat" ) == 0 ) - return Particle_getMat( self ); - else if( strcmp( name, "defvec" ) == 0 ) - return Particle_getDefvec( self ); + Particle_RecalcPsys_distr(self,1); + return res; +} - return Py_FindMethod( BPy_Particle_methods, ( PyObject * ) self, - name ); +static PyObject *Part_getPF( BPy_PartSYS * self ) +{ + return PyInt_FromLong( ((short)( self->psys->part->userjit )) ); } -/*****************************************************************************/ -/* Function: ParticleSetAttr */ -/* Description: This is a callback function for the BPy_Particle type. */ -/* It is the function that sets Particle Data attributes */ -/* (member vars) */ -/*****************************************************************************/ -int ParticleSetAttr( BPy_Particle * self, char *name, PyObject * value ) +static int Part_setInvert( BPy_PartSYS * self, PyObject * args ) { + int number; - PyObject *valtuple; - PyObject *error = NULL; + if( !PyInt_Check( args ) ) { + char errstr[128]; + sprintf ( errstr, "expected int argument" ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); + } - valtuple = Py_BuildValue( "(N)", value ); + number = PyInt_AS_LONG( args ); - if( !valtuple ) - return EXPP_ReturnIntError( PyExc_MemoryError, - "ParticleSetAttr: couldn't create PyTuple" ); + if (number){ + self->psys->part->flag |= PART_GRID_INVERT; + }else{ + self->psys->part->flag &= ~PART_GRID_INVERT; + } - if( strcmp( name, "seed" ) == 0 ) - error = Particle_setSeed( self, valtuple ); - else if( strcmp( name, "nabla" ) == 0 ) - error = Particle_setNabla( self, valtuple ); - else if( strcmp( name, "sta" ) == 0 ) - error = Particle_setSta( self, valtuple ); - else if( strcmp( name, "end" ) == 0 ) - error = Particle_setEnd( self, valtuple ); - else if( strcmp( name, "lifetime" ) == 0 ) - error = Particle_setLifetime( self, valtuple ); - else if( strcmp( name, "normfac" ) == 0 ) - error = Particle_setNormfac( self, valtuple ); - else if( strcmp( name, "obfac" ) == 0 ) - error = Particle_setObfac( self, valtuple ); - else if( strcmp( name, "randfac" ) == 0 ) - error = Particle_setRandfac( self, valtuple ); - else if( strcmp( name, "texfac" ) == 0 ) - error = Particle_setTexfac( self, valtuple ); - else if( strcmp( name, "randlife" ) == 0 ) - error = Particle_setRandlife( self, valtuple ); - else if( strcmp( name, "nabla" ) == 0 ) - error = Particle_setNabla( self, valtuple ); - else if( strcmp( name, "vectsize" ) == 0 ) - error = Particle_setVectsize( self, valtuple ); - else if( strcmp( name, "totpart" ) == 0 ) - error = Particle_setTotpart( self, valtuple ); - else if( strcmp( name, "seed" ) == 0 ) - error = Particle_setSeed( self, valtuple ); - else if( strcmp( name, "force" ) == 0 ) - error = Particle_setForce( self, valtuple ); - else if( strcmp( name, "mult" ) == 0 ) - error = Particle_setMult( self, valtuple ); - else if( strcmp( name, "life" ) == 0 ) - error = Particle_setLife( self, valtuple ); - else if( strcmp( name, "child" ) == 0 ) - error = Particle_setChild( self, valtuple ); - else if( strcmp( name, "mat" ) == 0 ) - error = Particle_setMat( self, valtuple ); - else if( strcmp( name, "defvec" ) == 0 ) - error = Particle_setDefvec( self, valtuple ); + Particle_RecalcPsys_distr(self,1); - else { - Py_DECREF( valtuple ); + return 0; +} - if( ( strcmp( name, "Types" ) == 0 ) || - ( strcmp( name, "Modes" ) == 0 ) ) - return ( EXPP_ReturnIntError( PyExc_AttributeError, - "constant dictionary -- cannot be changed" ) ); +static PyObject *Part_getInvert( BPy_PartSYS * self ) +{ + return PyInt_FromLong( ((long)( self->psys->part->flag & PART_GRID_INVERT )) > 0 ); +} - else - return ( EXPP_ReturnIntError( PyExc_KeyError, - "attribute not found" ) ); +static int Part_setTargetOb( BPy_PartSYS * self, PyObject * args ) +{ + Object *obj; + if( !BPy_Object_Check( args ) ) { + char errstr[128]; + sprintf ( errstr, "expected object argument" ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); } - Py_DECREF(valtuple); - if( error != Py_None ) - return -1; + obj = Object_FromPyObject(args); - Py_DECREF( Py_None ); + self->psys->target_ob = obj; + return 0; } -/*****************************************************************************/ -/* Function: ParticlePrint */ -/* Description: This is a callback function for the BPy_Particle type. It */ -/* particles a meaninful string to 'print' particle objects. */ -/*****************************************************************************/ -/* -int ParticlePrint(BPy_Particle *self, FILE *fp, int flags) -{ - printf("Hi, I'm a particle!"); - return 0; +static PyObject *Part_getTargetOb( BPy_PartSYS * self ) +{ + Object * obj; + obj = self->psys->target_ob; + if (!obj) + Py_RETURN_NONE; + + return Object_CreatePyObject( obj ); } -*/ -/*****************************************************************************/ -/* Function: ParticleRepr */ -/* Description: This is a callback function for the BPy_Particle type. It */ -/* particles a meaninful string to represent particle objects. */ -/*****************************************************************************/ -PyObject *ParticleRepr( void ) + + + +PyObject *Part_getDupOb( BPy_PartSYS * self ) { - return PyString_FromString( "Particle" ); + Object * obj; + obj = self->psys->part->dup_ob; + if (!obj) + Py_RETURN_NONE; + + return Object_CreatePyObject( obj ); } -PyObject *ParticleCreatePyObject( struct Effect * particle ) +static int Part_setTargetPsys( BPy_PartSYS * self, PyObject * args ){ + int tottpsys; + int res; + Object *tob=0; + ParticleSystem *psys = self->psys; + Object *ob; + + ob = self->object; + + if(psys->target_ob) + tob=psys->target_ob; + else + tob=ob; + + tottpsys = BLI_countlist(&tob->particlesystem); + + res = EXPP_setIValueRange( args, &self->psys->target_psys, 0, tottpsys, 'h' ); + + if((psys=psys_get_current(ob))){ + if(psys->keyed_ob==ob || psys->target_ob==ob){ + if(psys->keyed_ob==ob) + psys->keyed_ob=NULL; + else + psys->target_ob=NULL; + } + else{ + DAG_scene_sort(G.scene); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + } + } + + return res; +} + +static PyObject *Part_getTargetPsys( BPy_PartSYS * self ){ + return PyInt_FromLong( (short)( self->psys->target_psys ) ); +} + +static int Part_setRenderObject( BPy_PartSYS * self, PyObject * args ) { - BPy_Particle *blen_object; + int number,nr; + ParticleSystem *psys = 0L; + if( !PyInt_Check( args ) ) { + char errstr[128]; + sprintf ( errstr, "expected int argument" ); + return EXPP_ReturnIntError( PyExc_TypeError, errstr ); + } - blen_object = - ( BPy_Particle * ) PyObject_NEW( BPy_Particle, - &Particle_Type ); + number = PyInt_AS_LONG( args ); - if( blen_object == NULL ) { - return ( NULL ); + if (number){ + self->psys->part->draw |= PART_DRAW_EMITTER; + }else{ + self->psys->part->draw &= ~PART_DRAW_EMITTER; } - blen_object->particle = particle; - return ( ( PyObject * ) blen_object ); + /* check need for dupliobjects */ + nr=0; + for(psys=self->object->particlesystem.first; psys; psys=psys->next){ + if(ELEM(psys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR)) + nr++; + } + if(nr) + self->object->transflag |= OB_DUPLIPARTS; + else + self->object->transflag &= ~OB_DUPLIPARTS; + + return 0; } -int ParticleCheckPyObject( PyObject * py_obj ) +static PyObject *Part_getRenderObject( BPy_PartSYS * self ) { - return ( py_obj->ob_type == &Particle_Type ); + return PyInt_FromLong( ((long)( self->psys->part->draw & PART_DRAW_EMITTER )) > 0 ); } +static int Part_setParticleDisp( BPy_PartSYS * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->disp, + 0, 100, 'i' ); -struct Particle *ParticleFromPyObject( PyObject * py_obj ) + Particle_Recalc(self,0); + + + return res; +} + +static PyObject *Part_getParticleDisp( BPy_PartSYS * self ) { - BPy_Particle *blen_obj; + return PyInt_FromLong( ((short)( self->psys->part->disp )) ); +} - blen_obj = ( BPy_Particle * ) py_obj; - return ( ( struct Particle * ) blen_obj->particle ); +static int Part_setStep( BPy_PartSYS * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->draw_step, + 0, 7, 'i' ); + Particle_Recalc(self,1); + + + return res; } + +static PyObject *Part_getStep( BPy_PartSYS * self ) +{ + return PyInt_FromLong( ((short)( self->psys->part->draw_step )) ); +} + +static int Part_setRenderStep( BPy_PartSYS * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->ren_step, + 0, 7, 'i' ); + + /*Particle_Recalc(self,1);*/ + + + return res; +} + +static PyObject *Part_getRenderStep( BPy_PartSYS * self ) +{ + return PyInt_FromLong( ((short)( self->psys->part->ren_step )) ); +} + +static PyObject *Part_getDrawAs( BPy_PartSYS * self ) +{ + return PyInt_FromLong( (long)( self->psys->part->draw_as ) ); +} Index: source/blender/python/api2_2x/Particle.h =================================================================== --- source/blender/python/api2_2x/Particle.h (revision 14514) +++ source/blender/python/api2_2x/Particle.h (working copy) @@ -1,5 +1,4 @@ -/* - * $Id$ +/* * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -22,43 +21,31 @@ * * This is a new part of Blender. * - * Contributor(s): Jacques Guignot + * Contributor(s): Cedric Paille * * ***** END GPL LICENSE BLOCK ***** - */ +*/ -#ifndef EXPP_PARTICLE_H -#define EXPP_PARTICLE_H +#ifndef EXPP_PARTICLESYS_H +#define EXPP_PARTICLESYS_H #include -#include "DNA_effect_types.h" +#include "DNA_particle_types.h" +#include "DNA_object_types.h" -extern PyTypeObject Particle_Type; +extern PyTypeObject ParticleSYS_Type; -#define BPy_Particle_Check(v) ((v)->ob_type==&Particle_Type) +#define BPy_ParticleSYS_Check(v) \ + ((v)->ob_type == &ParticleSYS_Type) /* for type checking */ -/* Python BPy_Particle structure definition */ +/* Python BPy_Effect structure definition */ typedef struct { PyObject_HEAD /* required py macro */ - Effect * particle; -} BPy_Particle; + ParticleSystem *psys; + Object *object; +} BPy_PartSYS; -#include "Effect.h" +PyObject *ParticleSYS_Init( void ); -/*****************************************************************************/ -/* Python Particle_Type callback function prototypes: */ -/*****************************************************************************/ -#if 0 -void ParticleDeAlloc( BPy_Particle * msh ); -//int ParticlePrint (BPy_Particle *msh, FILE *fp, int flags); -int ParticleSetAttr( BPy_Particle * msh, char *name, PyObject * v ); -PyObject *ParticleGetAttr( BPy_Particle * msh, char *name ); -PyObject *ParticleRepr( void ); -PyObject *ParticleCreatePyObject( struct Effect *particle ); -int ParticleCheckPyObject( PyObject * py_obj ); -struct Particle *ParticleFromPyObject( PyObject * py_obj ); -#endif - - -#endif /* EXPP_PARTICLE_H */ +#endif /* EXPP_EFFECT_H */