Index: source/blender/python/api2_2x/doc/Particle.py =================================================================== --- source/blender/python/api2_2x/doc/Particle.py (revision 15623) +++ source/blender/python/api2_2x/doc/Particle.py (working copy) @@ -137,7 +137,7 @@ @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) + @return: list of vectors or list of list of vectors (hair mode) or None if system is disabled """ def getRot(all=0,id=0): """ @@ -150,7 +150,7 @@ @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(): @@ -169,7 +169,7 @@ @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): @@ -181,7 +181,7 @@ @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. """ # Blender.Object module and the Object PyType object Index: source/blender/python/api2_2x/Particle.c =================================================================== --- source/blender/python/api2_2x/Particle.c (revision 15623) +++ source/blender/python/api2_2x/Particle.c (working copy) @@ -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" @@ -803,18 +804,20 @@ ParticleSystem *psys = 0L; Object *ob = 0L; PyObject *partlist,*seglist; + ParticleCacheKey **cache,*path; PyObject* loc = 0L; - ParticleCacheKey **cache,*path; ParticleKey state; - float cfra=bsystem_time(ob,(float)CFRA,0.0); + DerivedMesh* dm; + float cfra = bsystem_time(ob,(float)CFRA,0.0); int i,j,k; + float vm[4][4],wm[4][4]; 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" ); + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected two optionals integers as argument" ); psys = self->psys; ob = self->object; @@ -822,49 +825,81 @@ 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_INCREF(Py_None); + return Py_None; + } + if (psys->part->type == PART_HAIR){ + + partlist = PyList_New( 0 ); - if( !partlist ) + + if( !partlist ){ + psys_render_restore(ob,psys); + G.rendering = 0; + Particle_Recalc(self,1); 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); + 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) ){ + 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 = Py_BuildValue("(fff)",(double)path->co[0], (double)path->co[1], (double)path->co[2]); + + if (!loc){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(seglist); + Py_DECREF(partlist); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't build tuple" ); + } + + if ( (PyList_Append(seglist,loc) < 0) ){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(seglist); + Py_DECREF(partlist); + Py_XDECREF(loc); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } + Py_DECREF(loc); /* PyList_Append increfs */ + path++; + } + + if ( PyList_Append(partlist,seglist) < 0 ){ + psys_render_restore(ob,psys); + G.rendering = 0; Py_DECREF(seglist); Py_DECREF(partlist); - Py_XDECREF(loc); + Particle_Recalc(self,1); return EXPP_ReturnPyObjError( PyExc_RuntimeError, - "Couldn't append item to PyList" ); + "Couldn't append item to PyList" ); } - Py_DECREF(loc); /* PyList_Append increfs */ - path++; + Py_DECREF(seglist); /* PyList_Append increfs */ } - - if ( PyList_Append(partlist,seglist) < 0 ){ - Py_DECREF(seglist); - Py_DECREF(partlist); - return EXPP_ReturnPyObjError( PyExc_RuntimeError, - "Couldn't append item to PyList" ); - } - Py_DECREF(seglist); /* PyList_Append increfs */ } cache=psys->childcache; @@ -874,15 +909,23 @@ seglist = PyList_New( 0 ); k = path->steps+1; for( j = 0; j < k ; j++){ - loc = PyTuple_New(3); + loc = Py_BuildValue("(fff)",(double)path->co[0], (double)path->co[1], (double)path->co[2]); - 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 (!loc){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(partlist); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't build tuple" ); + } if ( PyList_Append(seglist,loc) < 0){ + psys_render_restore(ob,psys); + G.rendering = 0; Py_DECREF(partlist); Py_XDECREF(loc); + Particle_Recalc(self,1); return EXPP_ReturnPyObjError( PyExc_RuntimeError, "Couldn't append item to PyList" ); } @@ -891,19 +934,27 @@ } if ( PyList_Append(partlist,seglist) < 0){ + psys_render_restore(ob,psys); + G.rendering = 0; Py_DECREF(partlist); Py_XDECREF(loc); + Particle_Recalc(self,1); return EXPP_ReturnPyObjError( PyExc_RuntimeError, "Couldn't append item to PyList" ); } Py_DECREF(seglist); /* PyList_Append increfs */ } - } else { int init; + partlist = PyList_New( 0 ); - if( !partlist ) + + if( !partlist ){ + psys_render_restore(ob,psys); + G.rendering = 0; + Particle_Recalc(self,1); return EXPP_ReturnPyObjError( PyExc_MemoryError, "PyList() failed" ); + } if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT)) childexists = 1; @@ -919,36 +970,62 @@ 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 (!id){ + loc = Py_BuildValue("(fff)",(double)state.co[0], + (double)state.co[1], (double)state.co[2]); + + if (!loc){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(partlist); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't build tuple" ); + } + }else{ + loc = Py_BuildValue("(fffi)",(double)state.co[0], + (double)state.co[1], (double)state.co[2], i); + + if (!loc){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(partlist); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't build tuple" ); + } + } + if ( PyList_Append(partlist,loc) < 0 ){ + psys_render_restore(ob,psys); + G.rendering = 0; Py_DECREF(partlist); - Py_XDECREF(loc); + Py_DECREF(loc); + Particle_Recalc(self,1); return EXPP_ReturnPyObjError( PyExc_RuntimeError, "Couldn't append item to PyList" ); } - Py_DECREF(loc);/* PyList_Append increfs */ + Py_DECREF(loc); } else { if ( all ){ if ( PyList_Append(partlist,Py_None) < 0 ){ + psys_render_restore(ob,psys); + G.rendering = 0; Py_DECREF(partlist); + Particle_Recalc(self,1); return EXPP_ReturnPyObjError( PyExc_RuntimeError, "Couldn't append item to PyList" ); } - Py_DECREF(Py_None); /* PyList_Append increfs */ } } } } + + psys_render_restore(ob,psys); + G.rendering = 0; + Particle_Recalc(self,1); return partlist; } @@ -958,6 +1035,8 @@ 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; @@ -966,8 +1045,8 @@ 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" ); + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected two optionals integers as argument" ); psys = self->psys; ob = self->object; @@ -975,9 +1054,32 @@ 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_INCREF(Py_None); + return Py_None; + } + + if (psys->part->type != PART_HAIR){ partlist = PyList_New( 0 ); + if( !partlist ){ + psys_render_restore(ob,psys); + G.rendering = 0; + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_MemoryError, "PyList() failed" ); + } + if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT)) childexists = 1; @@ -988,27 +1090,65 @@ 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 */ + if( PyList_Append(partlist,Py_None) < 0){ + psys_render_restore(ob,psys); + G.rendering = 0; + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } 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); + if (!id){ + loc = Py_BuildValue("(ffff)",(double)state.rot[0], (double)state.rot[1], + (double)state.rot[2], (double)state.rot[3]); + + if (!loc){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(partlist); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't build tuple" ); + } + }else{ + loc = Py_BuildValue("(ffffi)",(double)state.rot[0], (double)state.rot[1], + (double)state.rot[2], (double)state.rot[3], i); + + if (!loc){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(partlist); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't build tuple" ); + } + } + if (PyList_Append(partlist,loc) < 0){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(partlist); + Py_XDECREF(loc); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } Py_DECREF(loc); /* PyList_Append increfs */ } + } else { + psys_render_restore(ob,psys); + G.rendering = 0; + Particle_Recalc(self,1); + Py_INCREF(Py_None); + return (Py_None); } + + psys_render_restore(ob,psys); + G.rendering = 0; + Particle_Recalc(self,1); return partlist; } @@ -1019,6 +1159,8 @@ 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; @@ -1029,7 +1171,7 @@ if( !PyArg_ParseTuple( args, "|ii", &all, &id ) ) return EXPP_ReturnPyObjError( PyExc_TypeError, - "expected one optional integer as argument" ); + "expected two optionals integers as argument" ); data = self->psys->particles; @@ -1039,12 +1181,35 @@ 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++){ + dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL); + dm->release(dm); + + if ( !psys_check_enabled(ob,psys) ){ + psys_render_restore(ob,psys); + G.rendering = 0; + Particle_Recalc(self,1); + Py_INCREF(Py_None); + return Py_None; + } + + partlist = PyList_New( 0 ); + + if( !partlist ){ + psys_render_restore(ob,psys); + G.rendering = 0; + Particle_Recalc(self,1); + 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++, data++){ if (psys->part->type != 2){ if (childexists && (i < psys->totpart)) continue; @@ -1061,19 +1226,49 @@ 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); + + tuple = Py_BuildValue("(fi)",(double)size,i); + + if (!tuple){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(partlist); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't build tuple" ); + } + + if (PyList_Append(partlist,tuple) < 0){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(partlist); + Py_XDECREF(tuple); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } Py_DECREF(tuple); } else { siz = PyFloat_FromDouble((double)size); - PyList_Append(partlist,siz); + if(PyList_Append(partlist,siz) < 0){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(partlist); + Py_XDECREF(siz); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } Py_DECREF(siz); } } } + + psys_render_restore(ob,psys); + G.rendering = 0; + Particle_Recalc(self,1); return partlist; } @@ -1085,6 +1280,8 @@ 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; @@ -1095,7 +1292,7 @@ if( !PyArg_ParseTuple( args, "|ii", &all, &id ) ) return EXPP_ReturnPyObjError( PyExc_TypeError, - "expected one optional integer as argument" ); + "expected two optionals integers as argument" ); data = self->psys->particles; @@ -1105,12 +1302,33 @@ 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++){ + dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL); + dm->release(dm); + + if ( !psys_check_enabled(ob,psys) ){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_INCREF(Py_None); + return Py_None; + } + + partlist = PyList_New( 0 ); + if( !partlist ){ + psys_render_restore(ob,psys); + G.rendering = 0; + Particle_Recalc(self,1); + 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++, data++){ if (psys->part->type != 2){ if (childexists && (i < psys->totpart)) @@ -1129,18 +1347,47 @@ 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); + + tuple = Py_BuildValue("(fi)",(double)life,i); + + if (!tuple){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(partlist); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't build tuple" ); + } + + if (PyList_Append(partlist,tuple) < 0){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(partlist); + Py_XDECREF(tuple); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } Py_DECREF(tuple); } else { lif = PyFloat_FromDouble((double)life); - PyList_Append(partlist,lif); + if (PyList_Append(partlist,lif) < 0){ + psys_render_restore(ob,psys); + G.rendering = 0; + Py_DECREF(partlist); + Py_XDECREF(lif); + Particle_Recalc(self,1); + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "Couldn't append item to PyList" ); + } Py_DECREF(lif); } } } + + psys_render_restore(ob,psys); + G.rendering = 0; + Particle_Recalc(self,1); return partlist; } @@ -1546,7 +1793,7 @@ return EXPP_ReturnIntError( PyExc_TypeError, errstr ); } - self->psys->part->from = number; + self->psys->part->from = (short)number; Particle_RecalcPsys_distr(self,1); @@ -1603,7 +1850,7 @@ return EXPP_ReturnIntError( PyExc_TypeError, errstr ); } - self->psys->part->distr = number; + self->psys->part->distr = (short)number; Particle_RecalcPsys_distr(self,1); @@ -1731,7 +1978,7 @@ 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;