Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Poirier <theeth@yahoo.com>2008-08-05 06:27:09 +0400
committerMartin Poirier <theeth@yahoo.com>2008-08-05 06:27:09 +0400
commite2380665259eb0f74376ffda2ab791ba8e1bb9ef (patch)
treeac5134d6f03956f51e4498e828143482d36287fa /source/blender/python/api2_2x
parentd4b646103a6cae433d58bf7e2f4953f81358835b (diff)
parent07bc1e56fec864748c160af02659e3fcff317be9 (diff)
Merging with trunk
15568 - 15963
Diffstat (limited to 'source/blender/python/api2_2x')
-rw-r--r--source/blender/python/api2_2x/Armature.c2
-rw-r--r--source/blender/python/api2_2x/Blender.c2
-rw-r--r--source/blender/python/api2_2x/Bone.c10
-rw-r--r--source/blender/python/api2_2x/IDProp.c57
-rw-r--r--source/blender/python/api2_2x/Library.c69
-rw-r--r--source/blender/python/api2_2x/Material.c12
-rw-r--r--source/blender/python/api2_2x/Particle.c472
-rw-r--r--source/blender/python/api2_2x/doc/Armature.py3
-rw-r--r--source/blender/python/api2_2x/doc/IDProp.py4
-rw-r--r--source/blender/python/api2_2x/doc/Ipo.py4
-rw-r--r--source/blender/python/api2_2x/doc/LibData.py42
-rw-r--r--source/blender/python/api2_2x/doc/Particle.py229
-rw-r--r--source/blender/python/api2_2x/doc/Render.py4
-rw-r--r--source/blender/python/api2_2x/sceneRender.c40
14 files changed, 555 insertions, 395 deletions
diff --git a/source/blender/python/api2_2x/Armature.c b/source/blender/python/api2_2x/Armature.c
index e9dff098773..0db87c00dd2 100644
--- a/source/blender/python/api2_2x/Armature.c
+++ b/source/blender/python/api2_2x/Armature.c
@@ -1469,6 +1469,8 @@ PyObject *Armature_Init(void)
PyConstant_NewInt("BONE_SELECTED", BONE_SELECTED));
PyModule_AddObject(module, "TIP_SELECTED",
PyConstant_NewInt("TIP_SELECTED", BONE_TIPSEL));
+ PyModule_AddObject(module, "LOCKED_EDIT",
+ PyConstant_NewInt("LOCKED_EDIT", BONE_EDITMODE_LOCKED));
PyModule_AddObject(module, "OCTAHEDRON",
PyConstant_NewInt("OCTAHEDRON", ARM_OCTA));
diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c
index d8385c1d660..420d292cdce 100644
--- a/source/blender/python/api2_2x/Blender.c
+++ b/source/blender/python/api2_2x/Blender.c
@@ -708,7 +708,7 @@ static PyObject *Blender_Save( PyObject * self, PyObject * args )
"expected filename and optional int (overwrite flag) as arguments" );
for( li = G.main->library.first; li; li = li->id.next ) {
- if( BLI_streq( li->name, fname ) ) {
+ if( li->parent==NULL && BLI_streq( li->name, fname ) ) {
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"cannot overwrite used library" );
}
diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c
index 84faf416c5f..948eb007803 100644
--- a/source/blender/python/api2_2x/Bone.c
+++ b/source/blender/python/api2_2x/Bone.c
@@ -368,6 +368,10 @@ static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
goto RuntimeError;
+ if(self->editbone->flag & BONE_EDITMODE_LOCKED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "LOCKED_EDIT")) == -1)
+ goto RuntimeError;
}else{
if(self->flag & BONE_CONNECTED)
if (PyList_Append(list,
@@ -401,6 +405,10 @@ static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
goto RuntimeError;
+ if(self->flag & BONE_EDITMODE_LOCKED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "LOCKED_EDIT")) == -1)
+ goto RuntimeError;
}
return list;
@@ -422,7 +430,7 @@ static int EditBone_CheckValidConstant(PyObject *constant)
return 0;
if (!STREQ3(PyString_AsString(name), "CONNECTED", "HINGE", "NO_DEFORM") &&
!STREQ3(PyString_AsString(name), "ROOT_SELECTED", "BONE_SELECTED", "TIP_SELECTED") &&
- !STREQ2(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT"))
+ !STREQ3(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT", "LOCKED_EDIT"))
return 0;
else
return 1;
diff --git a/source/blender/python/api2_2x/IDProp.c b/source/blender/python/api2_2x/IDProp.c
index f60ebf8dee1..4a51619aec4 100644
--- a/source/blender/python/api2_2x/IDProp.c
+++ b/source/blender/python/api2_2x/IDProp.c
@@ -60,6 +60,8 @@ PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop )
return PyInt_FromLong( (long)prop->data.val );
case IDP_FLOAT:
return PyFloat_FromDouble( (double)(*(float*)(&prop->data.val)) );
+ case IDP_DOUBLE:
+ return PyFloat_FromDouble( (*(double*)(&prop->data.val)) );
case IDP_GROUP:
/*blegh*/
{
@@ -128,7 +130,19 @@ int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject *value)
Py_XDECREF(value);
break;
}
-
+ case IDP_DOUBLE:
+ {
+ double dvalue;
+ if (!PyNumber_Check(value))
+ return EXPP_ReturnIntError(PyExc_TypeError, "expected a float!");
+ value = PyNumber_Float(value);
+ if (!value)
+ return EXPP_ReturnIntError(PyExc_TypeError, "expected a float!");
+ dvalue = (float) PyFloat_AsDouble(value);
+ *(double*)&self->prop->data.val = dvalue;
+ Py_XDECREF(value);
+ break;
+ }
default:
return EXPP_ReturnIntError(PyExc_AttributeError, "attempt to set read-only attribute!");
}
@@ -204,8 +218,8 @@ char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObje
IDPropertyTemplate val = {0};
if (PyFloat_Check(ob)) {
- val.f = (float) PyFloat_AsDouble(ob);
- prop = IDP_New(IDP_FLOAT, val, name);
+ val.d = PyFloat_AsDouble(ob);
+ prop = IDP_New(IDP_DOUBLE, val, name);
} else if (PyInt_Check(ob)) {
val.i = (int) PyInt_AsLong(ob);
prop = IDP_New(IDP_INT, val, name);
@@ -223,7 +237,7 @@ char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObje
val.array.len = PySequence_Length(ob);
for (i=0; i<val.array.len; i++) {
item = PySequence_GetItem(ob, i);
- if (PyFloat_Check(item)) val.array.type = IDP_FLOAT;
+ if (PyFloat_Check(item)) val.array.type = IDP_DOUBLE;
else if (!PyInt_Check(item)) return "only floats and ints are allowed in ID property arrays";
Py_XDECREF(item);
}
@@ -236,7 +250,7 @@ char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObje
((int*)prop->data.pointer)[i] = (int)PyInt_AsLong(item);
} else {
item = PyNumber_Float(item);
- ((float*)prop->data.pointer)[i] = (float)PyFloat_AsDouble(item);
+ ((double*)prop->data.pointer)[i] = (float)PyFloat_AsDouble(item);
}
Py_XDECREF(item);
}
@@ -334,6 +348,9 @@ PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
case IDP_FLOAT:
return PyFloat_FromDouble(*((float*)&prop->data.val));
break;
+ case IDP_DOUBLE:
+ return PyFloat_FromDouble(*((double*)&prop->data.val));
+ break;
case IDP_INT:
return PyInt_FromLong( (long)prop->data.val );
break;
@@ -347,12 +364,15 @@ PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
"PyList_New() failed" );
for (i=0; i<prop->len; i++) {
- if (prop->subtype == IDP_FLOAT)
+ if (prop->subtype == IDP_FLOAT) {
PyList_SetItem(seq, i,
PyFloat_FromDouble(((float*)prop->data.pointer)[i]));
-
- else PyList_SetItem(seq, i,
- PyInt_FromLong(((int*)prop->data.pointer)[i]));
+ } else if (prop->subtype == IDP_DOUBLE) {
+ PyList_SetItem(seq, i,
+ PyFloat_FromDouble(((double*)prop->data.pointer)[i]));
+ } else { PyList_SetItem(seq, i,
+ PyInt_FromLong(((int*)prop->data.pointer)[i]));
+ }
}
return seq;
}
@@ -451,7 +471,7 @@ PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self)
/*set correct group length*/
self->prop->len = i;
- /*free the old list*/
+ /*free the list*/
Py_DECREF(seq);
/*call self again*/
@@ -688,6 +708,9 @@ PyObject *BPy_IDArray_GetItem(BPy_IDArray *self, int index)
case IDP_FLOAT:
return PyFloat_FromDouble( (double)(((float*)self->prop->data.pointer)[index]));
break;
+ case IDP_DOUBLE:
+ return PyFloat_FromDouble( (((double*)self->prop->data.pointer)[index]));
+ break;
case IDP_INT:
return PyInt_FromLong( (long)((int*)self->prop->data.pointer)[index] );
break;
@@ -700,7 +723,8 @@ int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *val)
{
int i;
float f;
-
+ double d;
+
if (index < 0 || index >= self->prop->len)
return EXPP_ReturnIntError( PyExc_RuntimeError,
"index out of range!");
@@ -717,6 +741,17 @@ int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *val)
((float*)self->prop->data.pointer)[index] = f;
Py_XDECREF(val);
break;
+ case IDP_DOUBLE:
+ if (!PyNumber_Check(val)) return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected a float");
+ val = PyNumber_Float(val);
+ if (!val) return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected a float");
+
+ d = (double) PyFloat_AsDouble(val);
+ ((double*)self->prop->data.pointer)[index] = d;
+ Py_XDECREF(val);
+ break;
case IDP_INT:
if (!PyNumber_Check(val)) return EXPP_ReturnIntError( PyExc_TypeError,
"expected an int");
diff --git a/source/blender/python/api2_2x/Library.c b/source/blender/python/api2_2x/Library.c
index 799735c2062..468263c4208 100644
--- a/source/blender/python/api2_2x/Library.c
+++ b/source/blender/python/api2_2x/Library.c
@@ -1135,9 +1135,78 @@ static PyObject *M_Library_Load(PyObject *self, PyObject * args)
return (PyObject *)lib;
}
+static PyObject *M_Library_GetPaths(PyObject *self, PyObject * args)
+{
+ PyObject *list;
+ PyObject *name;
+ int type=0;
+ Library *lib;
+
+ if( !PyArg_ParseTuple( args, "|i", &type ) || type < 0 || type > 2 ) {
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected an int between 0 and 2." );
+ }
+
+ list = PyList_New(0);
+
+ for(lib= G.main->library.first; lib; lib= lib->id.next) {
+ if (type==0) {
+ /* any type is ok */
+ } else if (type==1 && lib->parent == 0) {
+ /* only direct linked */
+ } else if (type==2 && lib->parent != 0) {
+ /* only indirect */
+ } else {
+ continue; /* incompatible type */
+ }
+
+ name = PyString_FromString(lib->name);
+ PyList_Append(list, name);
+ Py_DECREF(name);
+ }
+ return list;
+}
+
+static PyObject *M_Library_ReplacePath(PyObject *self, PyObject * args)
+{
+ char *name_from, *name_to;
+ Library *lib;
+
+ if( !PyArg_ParseTuple( args, "ss", &name_from, &name_to )) {
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected the name of a library path" );
+ }
+
+ for(lib= G.main->library.first; lib; lib= lib->id.next) {
+ if (strcmp(lib->name, name_from)==0) {
+ if (lib->parent) {
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "path is indirectly linked, cannot be changed." );
+ }
+
+ if (strlen(name_to) > sizeof(lib->name)) {
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "string length too long, cannot set path." );
+ }
+
+ strcpy(lib->name, name_to);
+ Py_RETURN_NONE;
+ }
+ }
+
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "path given does not exist as a library" );
+}
+
+
+
static struct PyMethodDef M_Library_methods[] = {
{"load", (PyCFunction)M_Library_Load, METH_VARARGS,
"(string) - declare a .blend file for use as a library"},
+ {"paths", (PyCFunction)M_Library_GetPaths, METH_VARARGS,
+ "(type) - return a list of library paths, type 0 for all, 1 only direct links, 2 only indirect links"},
+ {"replace", (PyCFunction)M_Library_ReplacePath, METH_VARARGS,
+ "(from, to) - replace the path of an existing, directly linked library."},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/api2_2x/Material.c b/source/blender/python/api2_2x/Material.c
index c36213950b0..ccd24a437b5 100644
--- a/source/blender/python/api2_2x/Material.c
+++ b/source/blender/python/api2_2x/Material.c
@@ -131,11 +131,11 @@
#define EXPP_MAT_RAYMIRRGLOSS_MIN 0.0
#define EXPP_MAT_RAYMIRRGLOSS_MAX 1.0
#define EXPP_MAT_RAYMIRRGLOSSSAMPLES_MIN 0
-#define EXPP_MAT_RAYMIRRGLOSSSAMPLES_MAX 255
+#define EXPP_MAT_RAYMIRRGLOSSSAMPLES_MAX 1024
#define EXPP_MAT_RAYTRANSPGLOSS_MIN 0.0
#define EXPP_MAT_RAYTRANSPGLOSS_MAX 1.0
#define EXPP_MAT_RAYTRANSPGLOSSSAMPLES_MIN 0
-#define EXPP_MAT_RAYTRANSPGLOSSSAMPLES_MAX 255
+#define EXPP_MAT_RAYTRANSPGLOSSSAMPLES_MAX 1024
#define EXPP_MAT_FILTER_MIN 0.0
#define EXPP_MAT_FILTER_MAX 1.0
#define EXPP_MAT_TRANSLUCENCY_MIN 0.0
@@ -738,8 +738,10 @@ static PyMethodDef BPy_Material_methods[] = {
"() - Return fresnel power for refractions factor"},
{"getRayTransGloss", ( PyCFunction ) Material_getGlossTrans, METH_NOARGS,
"() - Return amount refraction glossiness"},
+ {"getRayTransGlossSamples", ( PyCFunction ) Material_getGlossTransSamples, METH_NOARGS,
+ "() - Return number of sampels for transparent glossiness"},
{"getRayMirrGlossSamples", ( PyCFunction ) Material_getGlossMirrSamples, METH_NOARGS,
- "() - Return amount mirror glossiness"},
+ "() - Return number of sampels for mirror glossiness"},
{"getFilter", ( PyCFunction ) Material_getFilter, METH_NOARGS,
"() - Return the amount of filtering when transparent raytrace is enabled"},
{"getTranslucency", ( PyCFunction ) Material_getTranslucency, METH_NOARGS,
@@ -847,8 +849,10 @@ static PyMethodDef BPy_Material_methods[] = {
"(f) - Set blend fac for mirror fresnel - [1.0, 5.0]"},
{"setRayTransGloss", ( PyCFunction ) Material_setGlossTrans, METH_VARARGS,
"(f) - Set amount refraction glossiness - [0.0, 1.0]"},
+ {"setRayTransGlossSamples", ( PyCFunction ) Material_setGlossTransSamples, METH_VARARGS,
+ "(i) - Set number transparent gloss samples - [1, 1024]"},
{"setRayMirrGlossSamples", ( PyCFunction ) Material_setGlossMirrSamples, METH_VARARGS,
- "(f) - Set amount mirror glossiness - [0.0, 1.0]"},
+ "(i) - Set number mirror gloss samples - [1, 1024]"},
{"setFilter", ( PyCFunction ) Matr_oldsetFilter, METH_VARARGS,
"(f) - Set the amount of filtering when transparent raytrace is enabled"},
{"setTranslucency", ( PyCFunction ) Matr_oldsetTranslucency, METH_VARARGS,
diff --git a/source/blender/python/api2_2x/Particle.c b/source/blender/python/api2_2x/Particle.c
index 95de9757b87..2c2e724129e 100644
--- a/source/blender/python/api2_2x/Particle.c
+++ b/source/blender/python/api2_2x/Particle.c
@@ -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);
-
- 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" );
+ if (psys->part->type == PART_HAIR){
+ cache = psys->pathcache;
+
+ if ( ((self->psys->part->draw & PART_DRAW_PARENT) && (self->psys->part->childtype != 0)) || (self->psys->part->childtype == 0) ){
+
+ for(i = 0; i < psys->totpart; i++){
+ seglist = PyList_New( 0 );
+ if (!seglist){
+ PyErr_SetString( PyExc_MemoryError,
+ "PyList_New() failed" );
+ goto error;
+ }
+
+ 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;
}
- 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" );
+ 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);
+
+ 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 != 2){
+ 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);
+
+ 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 != 2){
+ 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;
diff --git a/source/blender/python/api2_2x/doc/Armature.py b/source/blender/python/api2_2x/doc/Armature.py
index 68916af6166..9aceb0105e3 100644
--- a/source/blender/python/api2_2x/doc/Armature.py
+++ b/source/blender/python/api2_2x/doc/Armature.py
@@ -89,6 +89,8 @@ Example::
@type BONE_SELECTED: Constant
@var TIP_SELECTED: Tip of the Bone is selected
@type TIP_SELECTED: Constant
+@var LOCKED_EDIT: Prevents the bone from being transformed in editmode
+@type LOCKED_EDIT: Constant
@var OCTAHEDRON: Bones drawn as octahedrons
@type OCTAHEDRON: Constant
@var STICK: Bones drawn as a line
@@ -286,6 +288,7 @@ class Bone:
- Armature.ROOT_SELECTED: Selection of root ball of bone
- Armature.BONE_SELECTED: Selection of bone
- Armature.TIP_SELECTED: Selection of tip ball of bone
+ - Armature.LOCKED_EDIT: Prevents the bone from being transformed in editmode
@type options: List of Constants
@ivar subdivision: The number of bone subdivisions.
@type subdivision: Int
diff --git a/source/blender/python/api2_2x/doc/IDProp.py b/source/blender/python/api2_2x/doc/IDProp.py
index 0a0df335fa3..01d5136cd70 100644
--- a/source/blender/python/api2_2x/doc/IDProp.py
+++ b/source/blender/python/api2_2x/doc/IDProp.py
@@ -18,7 +18,9 @@ class IDGroup:
Note that for arrays, the array type defaults to int unless a float is found
while scanning the template list; if any floats are found, then the whole
- array is float.
+ array is float. Note that double-precision floating point numbers are used for
+ python-created float ID properties and arrays (though the internal C api does
+ support single-precision floats, and the python code will read them).
You can also delete properties with the del operator. For example:
diff --git a/source/blender/python/api2_2x/doc/Ipo.py b/source/blender/python/api2_2x/doc/Ipo.py
index c479926ccf3..d1c72f8cb86 100644
--- a/source/blender/python/api2_2x/doc/Ipo.py
+++ b/source/blender/python/api2_2x/doc/Ipo.py
@@ -250,7 +250,7 @@ class Ipo:
OfsZ, SizeX, SizeY, SizeZ, texR, texG, texB, DefVar, Col, Nor, Var,
Disp.
3. Object Ipo: LocX, LocY, LocZ, dLocX, dLocY, dLocZ, RotX, RotY, RotZ,
- dRotX, dRotY, dRotZ, SizeX, SizeY, SizeZ, dSizeX, dSizeY, dSizeZ,
+ dRotX, dRotY, dRotZ, ScaleX, ScaleY, ScaleZ, dScaleX, dScaleY, dScaleZ,
Layer, Time, ColR, ColG, ColB, ColA, FStreng, FFall, Damping,
RDamp, Perm.
4. Lamp Ipo: Energ, R, G, B, Dist, SpoSi, SpoBl, Quad1, Quad2, HaInt.
@@ -289,7 +289,7 @@ class Ipo:
OfsZ, SizeX, SizeY, SizeZ, texR, texG, texB, DefVar, Col, Nor, Var,
Disp.
3. Object Ipo: LocX, LocY, LocZ, dLocX, dLocY, dLocZ, RotX, RotY, RotZ,
- dRotX, dRotY, dRotZ, SizeX, SizeY, SizeZ, dSizeX, dSizeY, dSizeZ,
+ dRotX, dRotY, dRotZ, ScaleX, ScaleY, ScaleZ, dScaleX, dScaleY, dScaleZ,
Layer, Time, ColR, ColG, ColB, ColA, FStreng, FFall, Damping,
RDamp, Perm.
4. Lamp Ipo: Energ, R, G, B, Dist, SpoSi, SpoBl, Quad1, Quad2, HaInt.
diff --git a/source/blender/python/api2_2x/doc/LibData.py b/source/blender/python/api2_2x/doc/LibData.py
index 47bd7fdb763..daa6a186531 100644
--- a/source/blender/python/api2_2x/doc/LibData.py
+++ b/source/blender/python/api2_2x/doc/LibData.py
@@ -27,17 +27,37 @@ Example::
"""
def load(filename,relative=False):
- """
- Select an existing .blend file for use as a library. Unlike the
- Library module, multiple libraries can be defined at the same time.
-
- @type filename: string
- @param filename: The filename of a Blender file. Filenames starting with "//" will be loaded relative to the blend file's location.
- @type relative: boolean
- @param relative: Convert relative paths to absolute paths (default). Setting this parameter to True will leave paths relative.
- @rtype: Library
- @return: return a L{Library} object.
- """
+ """
+ Select an existing .blend file for use as a library. Unlike the
+ Library module, multiple libraries can be defined at the same time.
+
+ @type filename: string
+ @param filename: The filename of a Blender file. Filenames starting with "//" will be loaded relative to the blend file's location.
+ @type relative: boolean
+ @param relative: Convert relative paths to absolute paths (default). Setting this parameter to True will leave paths relative.
+ @rtype: Library
+ @return: return a L{Library} object.
+ """
+
+def paths(link=0):
+ """
+ Returns a list of paths used in the current blend file.
+
+ @type link: int
+ @param link: 0 (default if no args given) for all library paths, 1 for directly linked library paths only, 2 for indirectly linked library paths only.
+ @rtype: List
+ @return: return a list of path strings.
+ """
+
+def replace(pathFrom, pathTo):
+ """
+ Replaces an existing directly linked path.
+
+ @type pathFrom: string
+ @param pathFrom: An existing library path.
+ @type pathTo: string
+ @param pathTo: A new library path.
+ """
class Libraries:
"""
diff --git a/source/blender/python/api2_2x/doc/Particle.py b/source/blender/python/api2_2x/doc/Particle.py
index 192ecd5355b..511ad81b45f 100644
--- a/source/blender/python/api2_2x/doc/Particle.py
+++ b/source/blender/python/api2_2x/doc/Particle.py
@@ -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.
"""
diff --git a/source/blender/python/api2_2x/doc/Render.py b/source/blender/python/api2_2x/doc/Render.py
index 475a4fc5b10..d4dc83e84a0 100644
--- a/source/blender/python/api2_2x/doc/Render.py
+++ b/source/blender/python/api2_2x/doc/Render.py
@@ -833,9 +833,7 @@ class RenderData:
def enableCropping(toggle):
"""
- Enable/disable exclusion of border rendering from total image.
- @type toggle: int
- @param toggle: pass 1 for on / 0 for off
+ Deprecated: see the L{crop} attribute.
"""
def setImageType(type):
diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c
index b446af7efd4..22e165cbe9f 100644
--- a/source/blender/python/api2_2x/sceneRender.c
+++ b/source/blender/python/api2_2x/sceneRender.c
@@ -56,6 +56,7 @@ struct View3D; /* keep me up here */
#include "gen_utils.h"
#include "gen_library.h"
+#include "../BPY_extern.h" /* for BPY_do_all_scripts() */
#include "Scene.h"
#include "Group.h"
@@ -469,19 +470,20 @@ PyObject *M_Render_EnableDispWin( PyObject * self )
PyObject *RenderData_Render( BPy_RenderData * self )
{
Scene *oldsce;
+ /* unlock to prevent a deadlock when there are pynodes: */
+ PyThreadState *tstate = NULL;
if (!G.background) {
oldsce = G.scene;
set_scene( self->scene );
+ tstate = PyEval_SaveThread();
BIF_do_render( 0 );
set_scene( oldsce );
}
-
else { /* background mode (blender -b file.blend -P script) */
+ int slink_flag = 0;
Render *re= RE_NewRender(G.scene->id.name);
-
-
int end_frame = G.scene->r.efra;
if (G.scene != self->scene)
@@ -490,11 +492,25 @@ PyObject *RenderData_Render( BPy_RenderData * self )
G.scene->r.efra = G.scene->r.sfra;
+ if (G.f & G_DOSCRIPTLINKS) {
+ BPY_do_all_scripts(SCRIPT_RENDER);
+ G.f &= ~G_DOSCRIPTLINKS; /* avoid FRAMECHANGED events*/
+ slink_flag = 1;
+ }
+
+ tstate = PyEval_SaveThread();
+
RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra);
+ if (slink_flag) {
+ G.f |= G_DOSCRIPTLINKS;
+ BPY_do_all_scripts(SCRIPT_POSTRENDER);
+ }
+
G.scene->r.efra = end_frame;
}
+ PyEval_RestoreThread(tstate);
Py_RETURN_NONE;
}
@@ -565,10 +581,13 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args )
PyObject *RenderData_RenderAnim( BPy_RenderData * self )
{
Scene *oldsce;
-
+ /* unlock to prevent a deadlock when there are pynodes: */
+ PyThreadState *tstate = NULL;
+
if (!G.background) {
oldsce = G.scene;
set_scene( self->scene );
+ tstate = PyEval_SaveThread();
BIF_do_render( 1 );
set_scene( oldsce );
}
@@ -582,9 +601,18 @@ PyObject *RenderData_RenderAnim( BPy_RenderData * self )
if (G.scene->r.sfra > G.scene->r.efra)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"start frame must be less or equal to end frame");
-
+
+ if (G.f & G_DOSCRIPTLINKS)
+ BPY_do_all_scripts(SCRIPT_RENDER);
+
+ tstate = PyEval_SaveThread();
RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra);
+
+ if (G.f & G_DOSCRIPTLINKS)
+ BPY_do_all_scripts(SCRIPT_POSTRENDER);
}
+
+ PyEval_RestoreThread(tstate);
Py_RETURN_NONE;
}
@@ -985,7 +1013,7 @@ PyObject *RenderData_EnableCropping( void )
/* return M_Render_BitToggleInt( args, R_MOVIECROP,
&self->renderContext->mode );
*/
- printf("cropping option is now default, obsolete\n");
+ printf("obsolete: movie cropping option is now default\n");
Py_RETURN_NONE;
}