Python API

----------

Particle patch from Cédric Paille: bugfixes and child-particles export improvements for .getLoc(), part.getRot() part.getSize(), part.getAge() methods.

Also fix a bug with part.randemission getter (was using PART_BOIDS_2D instead of PART_TRAND), plus typos and duplications in API documentation.
This commit is contained in:
Ken Hughes
2008-07-21 20:42:11 +00:00
parent 78ce90b752
commit 4c086bf4ae
2 changed files with 344 additions and 353 deletions

View File

@@ -40,6 +40,7 @@
#include "BKE_material.h"
#include "BKE_utildefines.h"
#include "BKE_pointcache.h"
#include "BKE_DerivedMesh.h"
#include "BIF_editparticle.h"
#include "BIF_space.h"
#include "blendef.h"
@@ -799,22 +800,27 @@ static PyObject *Part_freeEdit( BPy_PartSys * self, PyObject * args ){
Py_RETURN_NONE;
}
static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){
static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args )
{
ParticleSystem *psys = 0L;
Object *ob = 0L;
PyObject *partlist,*seglist;
PyObject* loc = 0L;
ParticleCacheKey **cache,*path;
PyObject* loc = 0L;
ParticleKey state;
float cfra=bsystem_time(ob,(float)CFRA,0.0);
DerivedMesh* dm;
float cfra;
int i,j,k;
float vm[4][4],wm[4][4];
int childexists = 0;
int all = 0;
int id = 0;
cfra = bsystem_time(ob,(float)CFRA,0.0);
if( !PyArg_ParseTuple( args, "|ii", &all,&id ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected one optional integer as argument" );
"expected two optional integers as arguments" );
psys = self->psys;
ob = self->object;
@@ -822,88 +828,118 @@ static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){
if (!ob || !psys)
Py_RETURN_NONE;
if (psys->part->type == 2){
cache=psys->pathcache;
G.rendering = 1;
/* little hack to calculate hair steps in render mode */
psys->renderdata = (void*)(int)1;
/* Just to create a valid rendering context */
psys_render_set(ob,psys,vm,wm,0,0,0);
psys_cache_paths(ob, psys, cfra, 1);
dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
dm->release(dm);
psys->renderdata = NULL;
if ( !psys_check_enabled(ob,psys) ){
G.rendering = 0;
psys_render_restore(ob,psys);
Particle_Recalc(self,1);
Py_RETURN_NONE;
}
partlist = PyList_New( 0 );
if( !partlist )
return EXPP_ReturnPyObjError( PyExc_MemoryError, "PyList() failed" );
partlist = PyList_New( 0 );
if( !partlist ){
PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
goto error;
}
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);
if (psys->part->type == PART_HAIR){
cache = psys->pathcache;
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 ( ((self->psys->part->draw & PART_DRAW_PARENT) && (self->psys->part->childtype != 0)) || (self->psys->part->childtype == 0) ){
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" );
for(i = 0; i < psys->totpart; i++){
seglist = PyList_New( 0 );
if (!seglist){
PyErr_SetString( PyExc_MemoryError,
"PyList_New() failed" );
goto error;
}
Py_DECREF(loc); /* PyList_Append increfs */
path++;
}
if ( PyList_Append(partlist,seglist) < 0 ){
Py_DECREF(seglist);
Py_DECREF(partlist);
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Couldn't append item to PyList" );
path=cache[i];
k = path->steps+1;
for( j = 0; j < k ; j++, path++){
loc = Py_BuildValue("(fff)",(double)path->co[0],
(double)path->co[1], (double)path->co[2]);
if (!loc){
PyErr_SetString( PyExc_RuntimeError,
"Couldn't build tuple" );
goto error;
}
if ( (PyList_Append(seglist,loc) < 0) ){
PyErr_SetString( PyExc_RuntimeError,
"Couldn't append item to PyList" );
goto error;
}
Py_DECREF(loc); /* PyList_Append increfs */
loc = NULL;
}
if ( PyList_Append(partlist,seglist) < 0 ){
PyErr_SetString( PyExc_RuntimeError,
"Couldn't append item to PyList" );
goto error;
}
Py_DECREF(seglist); /* PyList_Append increfs */
seglist = NULL;
}
Py_DECREF(seglist); /* PyList_Append increfs */
}
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);
if (!seglist){
PyErr_SetString( PyExc_MemoryError,
"PyList_New() failed" );
goto error;
}
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]));
path=cache[i];
k = path->steps+1;
for( j = 0; j < k ; j++, path++ ){
loc = Py_BuildValue("(fff)",(double)path->co[0],
(double)path->co[1], (double)path->co[2]);
if (!loc){
PyErr_SetString( PyExc_RuntimeError,
"Couldn't build tuple" );
goto error;
}
if ( PyList_Append(seglist,loc) < 0){
Py_DECREF(partlist);
Py_XDECREF(loc);
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
PyErr_SetString( PyExc_RuntimeError,
"Couldn't append item to PyList" );
goto error;
}
Py_DECREF(loc);/* PyList_Append increfs */
path++;
loc = NULL;
}
if ( PyList_Append(partlist,seglist) < 0){
Py_DECREF(partlist);
Py_XDECREF(loc);
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
PyErr_SetString( PyExc_RuntimeError,
"Couldn't append item to PyList" );
goto error;
}
Py_DECREF(seglist); /* PyList_Append increfs */
seglist = NULL;
}
} else {
int init;
partlist = PyList_New( 0 );
if( !partlist )
return EXPP_ReturnPyObjError( PyExc_MemoryError, "PyList() failed" );
char *fmt = NULL;
if(id)
fmt = "(fffi)";
else
fmt = "(fff)";
if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
childexists = 1;
@@ -919,55 +955,67 @@ static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){
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));
loc = Py_BuildValue(fmt,(double)state.co[0],
(double)state.co[1], (double)state.co[2],i);
if (!loc){
PyErr_SetString( PyExc_RuntimeError,
"Couldn't build tuple" );
goto error;
}
if ( PyList_Append(partlist,loc) < 0 ){
Py_DECREF(partlist);
Py_XDECREF(loc);
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Couldn't append item to PyList" );
PyErr_SetString( PyExc_RuntimeError,
"Couldn't append item to PyList" );
goto error;
}
Py_DECREF(loc);/* PyList_Append increfs */
}
else {
if ( all ){
if ( PyList_Append(partlist,Py_None) < 0 ){
Py_DECREF(partlist);
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Couldn't append item to PyList" );
}
Py_DECREF(Py_None); /* PyList_Append increfs */
Py_DECREF(loc);
loc = NULL;
} else {
if ( all && PyList_Append(partlist,Py_None) < 0 ){
PyErr_SetString( PyExc_RuntimeError,
"Couldn't append item to PyList" );
goto error;
}
}
}
}
psys_render_restore(ob,psys);
G.rendering = 0;
Particle_Recalc(self,1);
return partlist;
error:
Py_XDECREF(partlist);
Py_XDECREF(seglist);
Py_XDECREF(loc);
psys_render_restore(ob,psys);
G.rendering = 0;
Particle_Recalc(self,1);
return NULL;
}
static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args ){
static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args )
{
ParticleSystem *psys = 0L;
Object *ob = 0L;
PyObject *partlist = 0L;
PyObject* loc = 0L;
ParticleKey state;
DerivedMesh* dm;
float vm[4][4],wm[4][4];
int i;
int childexists = 0;
int all = 0;
int id = 0;
char *fmt = NULL;
float cfra=bsystem_time(ob,(float)CFRA,0.0);
if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected one optional integer as argument" );
"expected two optional integers as arguments" );
psys = self->psys;
ob = self->object;
@@ -975,63 +1023,105 @@ static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args ){
if (!ob || !psys)
Py_RETURN_NONE;
if (psys->part->type != 2){
G.rendering = 1;
/* Just to create a valid rendering context */
psys_render_set(ob,psys,vm,wm,0,0,0);
dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
dm->release(dm);
if ( !psys_check_enabled(ob,psys) ){
G.rendering = 0;
psys_render_restore(ob,psys);
Particle_Recalc(self,1);
Py_RETURN_NONE;
}
if (psys->part->type != PART_HAIR){
partlist = PyList_New( 0 );
if( !partlist ){
PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
goto error;
}
if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
childexists = 1;
if(id)
fmt = "(ffffi)";
else
fmt = "(ffff)";
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);
Py_DECREF(Py_None); /* PyList_Append increfs */
continue;
} else {
continue;
if ( all && PyList_Append(partlist,Py_None) < 0){
PyErr_SetString( PyExc_RuntimeError,
"Couldn't append item to PyList" );
goto error;
}
} else {
loc = Py_BuildValue(fmt,(double)state.rot[0], (double)state.rot[1],
(double)state.rot[2], (double)state.rot[3], i);
if (!loc){
PyErr_SetString( PyExc_RuntimeError,
"Couldn't build tuple" );
goto error;
}
if (PyList_Append(partlist,loc) < 0){
PyErr_SetString ( PyExc_RuntimeError,
"Couldn't append item to PyList" );
goto error;
}
Py_DECREF(loc); /* PyList_Append increfs */
loc = NULL;
}
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);
Py_DECREF(loc); /* PyList_Append increfs */
}
} else {
partlist = EXPP_incr_ret( Py_None );
}
psys_render_restore(ob,psys);
G.rendering = 0;
Particle_Recalc(self,1);
return partlist;
error:
Py_XDECREF(partlist);
Py_XDECREF(loc);
psys_render_restore(ob,psys);
G.rendering = 0;
Particle_Recalc(self,1);
return NULL;
}
static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args ){
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;
DerivedMesh* dm;
float vm[4][4],wm[4][4];
float size;
int i;
int childexists = 0;
int all = 0;
int id = 0;
char *fmt = NULL;
float cfra=bsystem_time(ob,(float)CFRA,0.0);
if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected one optional integer as argument" );
data = self->psys->particles;
"expected two optional integers as arguments" );
psys = self->psys;
ob = self->object;
@@ -1039,13 +1129,39 @@ static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args ){
if (!ob || !psys)
Py_RETURN_NONE;
partlist = PyList_New( 0 );
G.rendering = 1;
if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
childexists = 1;
/* Just to create a valid rendering context */
psys_render_set(ob,psys,vm,wm,0,0,0);
for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
if (psys->part->type != 2){
dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
dm->release(dm);
data = self->psys->particles;
if ( !psys_check_enabled(ob,psys) ){
psys_render_restore(ob,psys);
G.rendering = 0;
Particle_Recalc(self,1);
Py_RETURN_NONE;
}
partlist = PyList_New( 0 );
if( !partlist ){
PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
goto error;
}
if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
childexists = 1;
if(id)
fmt = "(fi)";
else
fmt = "f";
for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
if (psys->part->type != PART_HAIR){
if (childexists && (i < psys->totpart))
continue;
@@ -1061,43 +1177,61 @@ static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args ){
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);
Py_DECREF(tuple);
} else {
siz = PyFloat_FromDouble((double)size);
PyList_Append(partlist,siz);
Py_DECREF(siz);
tuple = Py_BuildValue(fmt,(double)size,i);
if (!tuple){
PyErr_SetString( PyExc_RuntimeError,
"Couldn't build tuple" );
goto error;
}
if (PyList_Append(partlist,tuple) < 0){
PyErr_SetString( PyExc_RuntimeError,
"Couldn't append item to PyList" );
goto error;
}
Py_DECREF(tuple);
tuple = NULL;
}
}
psys_render_restore(ob,psys);
G.rendering = 0;
Particle_Recalc(self,1);
return partlist;
error:
Py_XDECREF(partlist);
Py_XDECREF(tuple);
psys_render_restore(ob,psys);
G.rendering = 0;
Particle_Recalc(self,1);
return NULL;
}
static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args ){
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;
DerivedMesh* dm;
float vm[4][4],wm[4][4];
float life;
int i;
int childexists = 0;
int all = 0;
int id = 0;
char *fmt = NULL;
float cfra=bsystem_time(ob,(float)CFRA,0.0);
if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected one optional integer as argument" );
data = self->psys->particles;
"expected two optional integers as arguments" );
psys = self->psys;
ob = self->object;
@@ -1105,13 +1239,37 @@ static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args ){
if (!ob || !psys)
Py_RETURN_NONE;
partlist = PyList_New( 0 );
G.rendering = 1;
if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
childexists = 1;
/* Just to create a valid rendering context */
psys_render_set(ob,psys,vm,wm,0,0,0);
for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
if (psys->part->type != 2){
dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
dm->release(dm);
data = self->psys->particles;
if ( !psys_check_enabled(ob,psys) ){
psys_render_restore(ob,psys);
G.rendering = 0;
Py_RETURN_NONE;
}
partlist = PyList_New( 0 );
if( !partlist ){
PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
goto error;
}
if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
childexists = 1;
if(id)
fmt = "(fi)";
else
fmt = "f";
for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
if (psys->part->type != PART_HAIR){
if (childexists && (i < psys->totpart))
continue;
@@ -1128,20 +1286,37 @@ static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args ){
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);
Py_DECREF(tuple);
} else {
lif = PyFloat_FromDouble((double)life);
PyList_Append(partlist,lif);
Py_DECREF(lif);
tuple = Py_BuildValue(fmt,(double)life,i);
if (!tuple){
PyErr_SetString( PyExc_RuntimeError,
"Couldn't build tuple" );
goto error;
}
if (PyList_Append(partlist,tuple) < 0){
PyErr_SetString( PyExc_RuntimeError,
"Couldn't append item to PyList" );
goto error;
}
Py_DECREF(tuple);
tuple = NULL;
}
}
psys_render_restore(ob,psys);
G.rendering = 0;
Particle_Recalc(self,1);
return partlist;
error:
Py_XDECREF(partlist);
Py_XDECREF(tuple);
psys_render_restore(ob,psys);
G.rendering = 0;
Particle_Recalc(self,1);
return NULL;
}
@@ -1376,11 +1551,8 @@ static int Part_set2d( 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 );
}
if( !PyInt_Check( args ) )
return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
number = PyInt_AS_LONG( args );
@@ -1526,7 +1698,7 @@ static int Part_setRandEmission( BPy_PartSys * self, PyObject * args )
static PyObject *Part_getRandEmission( BPy_PartSys * self )
{
return PyInt_FromLong( ((long)( self->psys->part->flag & PART_BOIDS_2D )) > 0 );
return PyInt_FromLong( ((long)( self->psys->part->flag & PART_TRAND )) > 0 );
}
static int Part_setParticleDist( BPy_PartSys * self, PyObject * args )
@@ -1546,7 +1718,7 @@ static int Part_setParticleDist( BPy_PartSys * self, PyObject * args )
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
}
self->psys->part->from = number;
self->psys->part->from = (short)number;
Particle_RecalcPsys_distr(self,1);
@@ -1603,7 +1775,7 @@ static int Part_setDist( BPy_PartSys * self, PyObject * args )
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
}
self->psys->part->distr = number;
self->psys->part->distr = (short)number;
Particle_RecalcPsys_distr(self,1);
@@ -1731,7 +1903,7 @@ static int Part_setTargetPsys( BPy_PartSys * self, PyObject * args ){
res = EXPP_setIValueRange( args, &self->psys->target_psys, 0, tottpsys, 'h' );
if((psys=psys_get_current(ob))){
if( ( psys = psys_get_current(ob) ) ){
if(psys->keyed_ob==ob || psys->target_ob==ob){
if(psys->keyed_ob==ob)
psys->keyed_ob=NULL;

View File

@@ -56,17 +56,17 @@ class Particle:
@type type: int
@ivar resolutionGrid: The resolution of the particle grid.
@type resolutionGrid: int
@ivar startFrame: Frame # to start emitting particles.
@ivar startFrame: Frame number to start emitting particles.
@type startFrame: float
@ivar endFrame: Frame # to stop emitting particles.
@ivar endFrame: Frame number 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' ] ).
@ivar multireact: React multiple times ( Particle.REACTON[ 'NEAR' | 'COLLISION' | 'DEATH' ] ).
@type multireact: int
@ivar reactshape: Power of reaction strength dependence on distance to target.
@ivar reactshape: Power of reaction strength, dependent on distance to target.
@type reactshape: float
@ivar hairSegments: Amount of hair segments.
@type hairSegments: int
@@ -74,13 +74,13 @@ class Particle:
@type lifetime: float
@ivar randlife: Give the particle life a random variation.
@type randlife: float
@ivar randemission: Give the particle life a random variation
@ivar randemission: Emit particles in random order.
@type randemission: int
@ivar particleDistribution: Where to emit particles from Paricle.EMITFROM[ 'PARTICLE' | 'VOLUME' | 'FACES' | 'VERTS' ] )
@ivar particleDistribution: Where to emit particles from ( Particle.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' ] ).
@ivar distribution: How to distribute particles on selected element ( Particle.DISTRIBUTION[ 'GRID' | 'RANDOM' | 'JITTERED' ] ).
@type distribution: int
@ivar jitterAmount: Amount of jitter applied to the sampling.
@type jitterAmount: float
@@ -131,237 +131,56 @@ class Particle:
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 or 4 floats in world space (x,y,z, optionnaly the particle's id).
The tuple is a vector of 3 or 4 floats in world space (x,y,z,
optionally the particle's id).
@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)
@rtype: list of vectors (tuple of 3 floats and optionally the id) or list of list of vectors
@return: list of vectors or list of list of vectors (hair mode) or None if system is disabled
"""
def getRot(all=0,id=0):
"""
Get the particles rotations as quaternion.
Get the particles' rotations as quaternion.
A list of tuple is returned in particle mode.
The tuple is a vector list of 4 or 5 floats (x,y,z,w, optionnaly the id of the particle).
The tuple is vector of 4 or 5 floats (x,y,z,w, optionally the id of the particle).
@type all: int
@param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None).
@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
@return: list of 4-tuples or None if system is disabled
"""
def getMat():
"""
Get the particles material.
Get the particles' material.
@rtype: Blender Material
@return: The marterial assigned to particles
@return: The material assigned to particles
"""
def getSize(all=0,id=0):
"""
Get the particles size.
Get the particles' size.
A list of float or list of tuple (particle's size,particle's id).
@type all: int
@param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None).
@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).
@return: list of floats or list of tuples if id is not zero (size,id) or None if system is disabled.
"""
def getAge(all=0,id=0):
"""
Get the particles age.
A list of float or list of tuple (particle's age,particle's id).
Get the particles' age.
A list of float or list of tuple (particle's age, particle's id).
@type all: int
@param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None).
@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).
"""
# 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).
@return: list of floats or list of tuples if id is not zero (size,id) or None if system is disabled.
"""