diff options
author | Campbell Barton <ideasman42@gmail.com> | 2006-08-09 05:37:17 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2006-08-09 05:37:17 +0400 |
commit | 49e778ed7fc7b7b0cb5163ad75fcb3152cfa184e (patch) | |
tree | b5108e0577c6c72c9f2b78c33b65aedc96e7696d /source | |
parent | 27925d1bf0ec3f4d0bc64c3096a90bb54a91fffe (diff) |
Commiting JMS's patch for particles with modifications.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/python/api2_2x/Effect.c | 186 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Effect.py | 111 |
2 files changed, 237 insertions, 60 deletions
diff --git a/source/blender/python/api2_2x/Effect.c b/source/blender/python/api2_2x/Effect.c index 975770f2d3a..1cd2ab03b23 100644 --- a/source/blender/python/api2_2x/Effect.c +++ b/source/blender/python/api2_2x/Effect.c @@ -32,15 +32,19 @@ #include "Effect.h" /*This must come first */ #include "DNA_object_types.h" +#include "DNA_scene_types.h" /* for G.scene->r.cfra */ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_effect.h" #include "BKE_object.h" #include "BKE_deform.h" +#include "BKE_scene.h" /* for G.scene->r.cfra */ +#include "BKE_ipo.h" /* frame_to_float() */ #include "BLI_blenlib.h" #include "gen_utils.h" #include "blendef.h" - +#include "vector.h" + #define EXPP_EFFECT_STA_MIN -250.0f #define EXPP_EFFECT_END_MIN 1.0f #define EXPP_EFFECT_LIFETIME_MIN 1.0f @@ -104,6 +108,8 @@ static PyObject *M_Effect_Get( PyObject * self, PyObject * args ); /*****************************************************************************/ static PyObject *Effect_getType( BPy_Effect * self ); static int Effect_setType( void ); +static PyObject *Effect_getStype( BPy_Effect * self ); +static int Effect_setStype( BPy_Effect * self, PyObject * args ); static PyObject *Effect_getFlag( BPy_Effect * self ); static int Effect_setFlag( BPy_Effect * self, PyObject * args ); static PyObject *Effect_getSta( BPy_Effect * self ); @@ -160,9 +166,10 @@ static PyObject *Effect_getVertGroup( BPy_Effect * self ); static int Effect_setVertGroup( BPy_Effect * self, PyObject * a ); static PyObject *Effect_getSpeedVertGroup( BPy_Effect * self ); static int Effect_setSpeedVertGroup( BPy_Effect * self, PyObject * a ); -static PyObject *Effect_getParticlesLoc( BPy_Effect * self, PyObject * a ); +static PyObject *Effect_getParticlesLoc( BPy_Effect * self ); static PyObject *Effect_oldsetType( void ); +static PyObject *Effect_oldsetStype( BPy_Effect * self, PyObject * args ); static PyObject *Effect_oldsetFlag( BPy_Effect * self, PyObject * args ); static PyObject *Effect_oldsetSta( BPy_Effect * self, PyObject * a ); static PyObject *Effect_oldsetEnd( BPy_Effect * self, PyObject * a ); @@ -222,6 +229,10 @@ static PyMethodDef BPy_Effect_methods[] = { METH_NOARGS, "() - Return Effect type"}, {"setType", ( PyCFunction ) Effect_oldsetType, METH_VARARGS, "() - Set Effect type"}, + {"getStype", ( PyCFunction ) Effect_getStype, + METH_NOARGS, "() - Return Effect stype"}, + {"setStype", ( PyCFunction ) Effect_oldsetStype, + METH_VARARGS, "() - Set Effect stype"}, {"getFlag", ( PyCFunction ) Effect_getFlag, METH_NOARGS, "() - Return Effect flag"}, {"setFlag", ( PyCFunction ) Effect_oldsetFlag, @@ -302,7 +313,7 @@ static PyMethodDef BPy_Effect_methods[] = { METH_NOARGS, "()-Return particle life time"}, {"setDefvec", ( PyCFunction ) Effect_oldsetDefvec, METH_VARARGS, "()- Sets particle life time "}, - {"getParticlesLoc", ( PyCFunction ) Effect_getParticlesLoc, METH_VARARGS, + {"getParticlesLoc", ( PyCFunction ) Effect_getParticlesLoc, METH_NOARGS, "()- Sets particle life time "}, {NULL, NULL, 0, NULL} }; @@ -315,6 +326,10 @@ static PyGetSetDef BPy_Effect_getseters[] = { (getter)Effect_getFlag, (setter)Effect_setFlag, "The particle flag bitfield", NULL}, + {"stype", + (getter)Effect_getStype, (setter)Effect_setStype, + "The particle stype bitfield", + NULL}, {"type", (getter)Effect_getType, (setter)Effect_setType, "The effect's type (deprecated)", @@ -758,6 +773,27 @@ static int Effect_setType( void ) return 0; } +static int Effect_setStype( BPy_Effect * self, PyObject * args ) +{ + short param; + if( !PyArg_Parse( args, "h", ¶m ) ) + return EXPP_ReturnIntError( PyExc_TypeError, + "expected an int as argument" ); + self->effect->stype |= 1-param; + return 0; +} + +static PyObject *Effect_getStype( BPy_Effect * self ) +{ + PyObject *attr; + long stype = (long)( self->effect->stype ); + + attr = PyInt_FromLong( stype ); + if( attr ) return attr; + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "couldn't get Effect.stype attribute" ); +} + static PyObject *Effect_getFlag( BPy_Effect * self ) { PyObject *attr; @@ -1383,53 +1419,132 @@ static int Effect_setSpeedVertGroup( BPy_Effect * self, PyObject * value ) /* Method: getParticlesLoc */ /* Python equivalent: effect.getParticlesLoc */ /* Description: Get the current location of each particle */ -/* and return a list of 3D coords */ -/* Data: float currentframe */ -/* Return: One python list of python lists of 3D coords */ +/* and return a list of 3D vectors */ +/* or a list of ists of two 3D vectors */ +/* if effect.vect has any sense */ +/* Data: notihng get the current time from G.scene */ +/* Return: One python list of 3D vector */ /*****************************************************************************/ -static PyObject *Effect_getParticlesLoc( BPy_Effect * self, PyObject * args ) +static PyObject *Effect_getParticlesLoc( BPy_Effect * self ) { Object *ob; + Effect *eff; PartEff *paf; - Particle *pa; + Particle *pa=0; + PyObject *list, *strand_list; + float p_time, c_time, vec[3], vec1[3], cfra, m_time, s_time; int a; - PyObject *list; - float p_time, c_time, vec[3], cfra; - - if( !PyArg_ParseTuple( args, "f", &cfra) ) - return EXPP_ReturnPyObjError( PyExc_TypeError, - "expected float argument" ); + short disp=100 ; + + cfra=frame_to_float( G.scene->r.cfra ); + + /* as we need to update the particles system we try to retrieve + the object to which the effect is connected */ + eff =(Effect *) self->effect; + + ob= self->object; + if(!ob) + return ( EXPP_ReturnPyObjError (PyExc_AttributeError, + "Effect has no object" ) ); + /*get the particles data */ + paf= (PartEff *)eff; + + /* particles->disp reduce the display number of particles */ + /* as we want the complete list ... we backup the disp value and restore later */ + if (paf->disp<100) + disp= paf->disp; paf->disp=100; + + + build_particle_system(ob); + pa= paf->keys; - ob = self->object; - paf = (PartEff *)self->effect; + if(!pa) + return ( EXPP_ReturnPyObjError (PyExc_AttributeError, + "Particles Location : no Keys" ) ); - pa = paf->keys; - if( !pa ) - return EXPP_ReturnPyObjError( PyExc_AttributeError, - "Particles location: no keys" ); - + /* if object is in motion */ 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; a<paf->totpart; 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 append item to PyList" ); + + c_time= bsystem_time( ob, 0, cfra, p_time ); + + for( a=0; a < paf->totpart; a++, pa += paf->totkey ) { + + if(paf->flag & PAF_STATIC ) { + strand_list = PyList_New( 0 ); + m_time= pa->time+pa->lifetime+paf->staticstep-1; + for(c_time= pa->time; c_time<m_time; c_time+=paf->staticstep) { + where_is_particle(paf, pa, c_time, vec); + MTC_Mat4MulVecfl(ob->obmat, vec); /* make worldspace like the others */ + if( PyList_Append( strand_list, newVectorObject(vec, 3, Py_NEW)) < 0 ) { + Py_DECREF( list ); + Py_DECREF( strand_list ); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } + } + + if( PyList_Append( list, strand_list) < 0 ) { + Py_DECREF( list ); + Py_DECREF( strand_list ); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } + + } else { + if(c_time > pa->time && c_time < pa->time+pa->lifetime ) { + /* vector particles are a tuple of 2 vectors */ + if( paf->stype==PAF_VECT ) { + s_time= c_time; + p_time= c_time+1.0f; + if(c_time < pa->time) { + if(paf->flag & PAF_UNBORN) + p_time= pa->time+1.0f; + else + continue; + } + if(c_time > pa->time+pa->lifetime) { + if(paf->flag & PAF_DIED) + s_time= pa->time+pa->lifetime-1.0f; + else + continue; + } + where_is_particle(paf, pa, s_time, vec); + where_is_particle(paf, pa, p_time, vec1); + if( PyList_Append( list, + Py_BuildValue("[OO]", + newVectorObject(vec, 3, Py_NEW), + newVectorObject(vec1, 3, Py_NEW))) < 0 ) + { + Py_DECREF( list ); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } + } else { /* not a vector */ + where_is_particle(paf, pa, c_time, vec); + if( PyList_Append( list, + newVectorObject(vec, 3, Py_NEW)) < 0 ) { + Py_DECREF( list ); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } + } } } } - + + /* restore the real disp value */ + if (disp<100){ + paf->disp=disp; + build_particle_system(ob); + } + return list; } @@ -1584,6 +1699,11 @@ static PyObject *Effect_oldsetFlag( BPy_Effect * self, PyObject * args ) return EXPP_setterWrapper( (void *)self, args, (setter)Effect_setFlag ); } +static PyObject *Effect_oldsetStype( BPy_Effect * self, PyObject * args ) +{ + return EXPP_setterWrapper( (void *)self, args, (setter)Effect_setStype ); +} + static PyObject *Effect_oldsetType( void ) { return EXPP_incr_ret( Py_None ); diff --git a/source/blender/python/api2_2x/doc/Effect.py b/source/blender/python/api2_2x/doc/Effect.py index c8ff87385d7..14f05203212 100644 --- a/source/blender/python/api2_2x/doc/Effect.py +++ b/source/blender/python/api2_2x/doc/Effect.py @@ -23,12 +23,12 @@ were implemented. Example:: import Blender - listffects = Blender.Effect.Get() - print listeffects - eff = listeffects[0] - #we suppose the first effect is a build effect - print eff.getLen() - eff.setLen(500) + listffects = Blender.Effect.Get() + print listeffects + eff = listeffects[0] + #we suppose the first effect is a build effect + print eff.getLen() + eff.setLen(500) @type Flags: read-only dictionary @var Flags: The particle effect flags. Values can be ORed. @@ -227,7 +227,6 @@ class Effect: @return: the end time of the effect. """ - def setEnd(newendrt): """ Sets the end time of an particle effect object @@ -236,7 +235,7 @@ class Effect: @rtype: None @return: None """ - + def getLifetime(): """ Retrieves the lifetime of a particle effect object @@ -261,7 +260,6 @@ class Effect: @return: normal strength of the particles (relatively to mesh). """ - def setNormfac(newnormfac): """ Sets the normal strength of the particles (relatively to mesh). @@ -270,7 +268,7 @@ class Effect: @rtype: None @return: None """ - + def getObfac(): """ Retrieves the initial strength of the particles relatively to objects. @@ -278,7 +276,6 @@ class Effect: @return: initial strength of the particles (relatively to mesh). """ - def setObfac(newobfac): """ Sets the initial strength of the particles relatively to objects. @@ -295,7 +292,6 @@ class Effect: @return: random strength applied to the particles. """ - def setRandfac(newrandfac): """ Sets the random strength applied to the particles. @@ -304,6 +300,22 @@ class Effect: @rtype: None @return: None """ + + def getStype(): + """ + Retrieves the vect state of an effect object. + @rtype: int + @return: the Stype (Vect) of an effect object : 0 , Vect is not enabled, 1, Vect is enabled + (particle effect) + """ + + def setStype(int): + """ + @type int : int + @param int : state of the Stype : 0 not enabled, 1 enabled. + @rtype: None + @return: None + """ def getTexfac(): """ @@ -312,7 +324,6 @@ class Effect: @return: strength applied to the particles from the texture of the object. """ - def setTexfac(newtexfac): """ Sets the strength applied to the particles from the texture of the object. @@ -329,7 +340,6 @@ class Effect: @return: variability of the life of the particles. """ - def setRandlife(newrandlife): """ Sets the variability of the life of the particles. @@ -453,14 +463,14 @@ class Effect: @rtype: None @return: None """ - + def getLife(): """ Retrieves the average life of the particles (4 generations) @rtype: tuple of 4 floats @return: average life of the particles (4 generations) """ - + def setLife(newlife): """ Sets the average life of the particles (4 generations). @@ -469,14 +479,14 @@ class Effect: @rtype: None @return: None """ - + def getChild(): """ Retrieves the average number of children of the particles (4 generations). @rtype: tuple of 4 ints @return: average number of children of the particles (4 generations). """ - + def setChild(newchild): """ Sets the average number of children of the particles (4 generations). @@ -492,7 +502,7 @@ class Effect: @rtype: tuple of 4 ints @return: indexes of the materials associated to the particles (4 generations). """ - + def setMat(newmat): """ Sets the indexes of the materials associated to the particles (4 generations). @@ -508,7 +518,7 @@ class Effect: @rtype: tuple of 3 floats @return: x, y and z components of the force defined by the texture. """ - + def setDefvec(newdefvec): """ Sets the x, y and z components of the force defined by the texture. @@ -519,11 +529,58 @@ class Effect: @return: None """ - def getParticlesLoc ( time ): - """ - Get the location of each particle at a given time. - @type time: int - @param time: The desired time during the particle effect. - @rtype: List of x,y,z coordinates - @return: The coordinates of each particle at the requested time. + def getParticlesLoc(): + """ + Gets the location of each particle at the current time in worldspace. + @rtype: A list of vector or a list of vector lists. + @return: The coordinates of each particle at the current time. + If the "Vect" option is enabled a list Vector pairs will be returned with a start and end point for each particle. + When static particles are enabled, a list of lists will be returned, each item a strand of particles. + + Example:: + + import Blender + from Blender import Effect, Object + scn= Blender.Scene.GetCurrent() + ob= scn.getActiveObject() + effect= ob.effects[0] + particles= effect.getParticlesLoc() + + # Check that particles are points only (not static and not vectors) + if not effect.getFlag() & Effect.Flags.STATIC or not effect.getStype(): + for pt in particles: + ob_empty= Object.New('Empty') + ob_empty.setLocation(pt) + scn.link(ob_empty) + + else: # Particles will be a list + for pt in particles: + for pt_item in pt: + ob_empty= Object.New('Empty') + ob_empty.setLocation(pt_item) + scn.link(ob_empty) + + Example:: + # Converts particles into a mesh with edges for strands + from Blender import Scene, Mathutils, Effect, Mesh, Object + scn= Scene.GetCurrent() + ob= scn.getActiveObject() + me= Mesh.New() + + effects= Effect.Get() + for eff in effects: + for p in ee.getParticlesLoc(): + # p is either a vector or a list of vectors + print p + me.verts.extend(p) + + if type(p)==list: # Are we a strand or a pair, then add edges. + if len(p)>1: + edges= [(i, i+1) for i in range(len(me.verts)-len(p), len(me.verts)-1)] + me.edges.extend( edges ) + + print len(me.verts) + ob= Object.New('Mesh') + ob.link(me) + scn.link(ob) """ |