[Bf-blender-cvs] [89c74df] particles_refactor: Custom get/set methods for the "Particle" type. This supports particle attributes directly as python properties in the particle wrapper type. If a particle identifier has no corresponding data in the state yet it will be automatically created when writing.
Lukas Tönne
noreply at git.blender.org
Tue Apr 22 12:06:18 CEST 2014
Commit: 89c74dfcf11f520610c273339f74c56677b02f73
Author: Lukas Tönne
Date: Fri Dec 20 15:36:20 2013 +0100
https://developer.blender.org/rB89c74dfcf11f520610c273339f74c56677b02f73
Custom get/set methods for the "Particle" type. This supports particle
attributes directly as python properties in the particle wrapper type.
If a particle identifier has no corresponding data in the state yet it
will be automatically created when writing.
===================================================================
M source/blender/blenkernel/BKE_nparticle.h
M source/blender/blenkernel/intern/nparticle.c
M source/blender/python/bparticles/bparticles_py_types.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_nparticle.h b/source/blender/blenkernel/BKE_nparticle.h
index 9648b10..a9978b8 100644
--- a/source/blender/blenkernel/BKE_nparticle.h
+++ b/source/blender/blenkernel/BKE_nparticle.h
@@ -65,6 +65,8 @@ struct NParticleAttributeState *BKE_nparticle_state_get_attribute_by_index(struc
int BKE_nparticle_state_num_particles(struct NParticleState *state);
+void *BKE_nparticle_attribute_state_data(struct NParticleAttributeState *attrstate, int index);
+
typedef struct NParticleAttributeStateIterator {
/* XXX for now is simply a pointer, using ListBase next/prev.
* Eventually this will become a hash table iterator.
@@ -89,10 +91,12 @@ typedef struct NParticleIterator {
} NParticleIterator;
void BKE_nparticle_iter_init(struct NParticleState *state, struct NParticleIterator *it);
-void BKE_nparticle_iter_find_id(struct NParticleState *state, struct NParticleIterator *it, NParticleID id);
+void BKE_nparticle_iter_from_id(struct NParticleState *state, struct NParticleIterator *it, NParticleID id);
+void BKE_nparticle_iter_from_index(struct NParticleState *state, struct NParticleIterator *it, int index);
void BKE_nparticle_iter_next(struct NParticleIterator *it);
bool BKE_nparticle_iter_valid(struct NParticleIterator *it);
+/*void *BKE_nparticle_iter_get_data(struct NParticleIterator *it, const char *attr);*/
int BKE_nparticle_iter_get_int(struct NParticleIterator *it, const char *attr);
void BKE_nparticle_iter_set_int(struct NParticleIterator *it, const char *attr, int value);
float BKE_nparticle_iter_get_float(struct NParticleIterator *it, const char *attr);
diff --git a/source/blender/blenkernel/intern/nparticle.c b/source/blender/blenkernel/intern/nparticle.c
index a7ec704..d3e33f7 100644
--- a/source/blender/blenkernel/intern/nparticle.c
+++ b/source/blender/blenkernel/intern/nparticle.c
@@ -380,6 +380,11 @@ int BKE_nparticle_state_num_particles(NParticleState *state)
return attrstate ? attrstate->data.totelem : 0;
}
+void *BKE_nparticle_attribute_state_data(NParticleAttributeState *attrstate, int index)
+{
+ return BLI_pbuf_get(&attrstate->data, index);
+}
+
int BKE_nparticle_find_index(NParticleState *state, NParticleID id)
{
@@ -447,12 +452,22 @@ void BKE_nparticle_iter_init(NParticleState *state, NParticleIterator *it)
it->index = 0;
}
-void BKE_nparticle_iter_find_id(NParticleState *state, NParticleIterator *it, NParticleID id)
+void BKE_nparticle_iter_from_id(NParticleState *state, NParticleIterator *it, NParticleID id)
{
it->state = state;
it->index = BKE_nparticle_find_index(state, id);
}
+void BKE_nparticle_iter_from_index(NParticleState *state, NParticleIterator *it, int index)
+{
+ NParticleAttributeState *attrstate = nparticle_state_find_attribute_id(state);
+ it->state = state;
+ if (index >= 0 && attrstate && index < attrstate->data.totelem)
+ it->index = index;
+ else
+ it->index = -1;
+}
+
void BKE_nparticle_iter_next(NParticleIterator *it)
{
++it->index;
@@ -486,6 +501,13 @@ BLI_INLINE bool nparticle_check_attribute_type(NParticleState *state, const char
return !attrstate || attrstate->desc.datatype == datatype;
}
+#if 0 /* unused */
+void *BKE_nparticle_iter_get_data(struct NParticleIterator *it, const char *attr)
+{
+ return nparticle_data_ptr(it->state, attr, it->index);
+}
+#endif
+
int BKE_nparticle_iter_get_int(NParticleIterator *it, const char *attr)
{
int *data = nparticle_data_ptr(it->state, attr, it->index);
diff --git a/source/blender/python/bparticles/bparticles_py_types.c b/source/blender/python/bparticles/bparticles_py_types.c
index 0cf4e4d..7a3a54e 100644
--- a/source/blender/python/bparticles/bparticles_py_types.c
+++ b/source/blender/python/bparticles/bparticles_py_types.c
@@ -30,11 +30,14 @@
#include <Python.h>
#include "BLI_math.h"
+#include "BLI_string.h"
#include "DNA_nparticle_types.h"
#include "BKE_nparticle.h"
+#include "../mathutils/mathutils.h"
+
#include "../generic/py_capi_utils.h"
#include "bparticles_py_types.h" /* own include */
@@ -144,10 +147,6 @@ static struct PyMethodDef bpy_bpar_attrstate_methods[] = {
{NULL, NULL, 0, NULL}
};
-static PyGetSetDef bpy_bpar_particle_getseters[] = {
- {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
-};
-
static Py_hash_t bpy_bpar_state_hash(PyObject *self)
{
return _Py_HashPointer(((BPy_NParticleState *)self)->state);
@@ -316,7 +315,7 @@ static PyObject *bpy_bpar_particleseq_subscript_int(BPy_NParticleAttributeStateS
NParticleIterator iter;
NParticleID id = (NParticleID)keynum;
- BKE_nparticle_iter_find_id(self->state, &iter, id);
+ BKE_nparticle_iter_from_id(self->state, &iter, id);
if (BKE_nparticle_iter_valid(&iter))
return BPy_NParticleParticle_CreatePyObject(self->state, id, iter);
@@ -418,6 +417,166 @@ static PyObject *bpy_bpar_particleiter_next(BPy_NParticleParticleIter *self)
}
}
+/* Get/Set Functions
+ * ================= */
+
+static PyObject *bpy_bpar_particle_data_read(NParticleAttributeDescription *desc, void *data)
+{
+ switch (desc->datatype) {
+ case PAR_ATTR_DATATYPE_FLOAT:
+ return PyFloat_FromDouble(*(float*)data);
+ case PAR_ATTR_DATATYPE_INT:
+ return PyLong_FromLong(*(int*)data);
+ case PAR_ATTR_DATATYPE_BOOL:
+ return PyBool_FromLong(*(bool*)data);
+ case PAR_ATTR_DATATYPE_VECTOR:
+ case PAR_ATTR_DATATYPE_POINT:
+ case PAR_ATTR_DATATYPE_NORMAL:
+ return Vector_CreatePyObject((float*)data, 3, Py_WRAP, NULL);
+ case PAR_ATTR_DATATYPE_COLOR:
+ return Color_CreatePyObject((float*)data, Py_WRAP, NULL);
+ case PAR_ATTR_DATATYPE_MATRIX:
+ return Matrix_CreatePyObject((float*)data, 4, 4, Py_WRAP, NULL);
+
+ default:
+ return NULL;
+ }
+}
+
+static int bpy_bpar_particle_data_write(NParticleAttributeDescription *desc, void *data, PyObject *value)
+{
+ /* XXX do we accept this sort of overhead just for error prints?
+ * only needs to happen for actual errors, but mathutils_array_parse needs string in advance.
+ */
+// char error_prefix[128];
+// BLI_snprintf(error_prefix, sizeof(error_prefix), "NParticleParticle.%.200s", desc->name);
+
+ switch (desc->datatype) {
+ case PAR_ATTR_DATATYPE_FLOAT:
+ if (PyFloat_Check(value))
+ *(float*)data = (float)PyFloat_AsDouble(value);
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "NParticleParticle.%.200s expects float, not %.200s",
+ desc->name, Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ break;
+ case PAR_ATTR_DATATYPE_INT:
+ if (PyLong_Check(value))
+ *(int*)data = (int)PyLong_AsLong(value);
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "NParticleParticle.%.200s expects int, not %.200s",
+ desc->name, Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ break;
+ case PAR_ATTR_DATATYPE_BOOL:
+ if (PyBool_Check(value))
+ *(bool*)data = (bool)PyLong_AsLong(value);
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "NParticleParticle.%.200s expects bool, not %.200s",
+ desc->name, Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ break;
+ case PAR_ATTR_DATATYPE_VECTOR:
+ case PAR_ATTR_DATATYPE_POINT:
+ case PAR_ATTR_DATATYPE_NORMAL: {
+ if (mathutils_array_parse((float*)data, 3, 3, value, "NParticleParticle") == -1)
+ return -1;
+ break;
+ }
+ case PAR_ATTR_DATATYPE_COLOR: {
+ if (mathutils_array_parse((float*)data, 3, 3, value, "NParticleParticle") == -1)
+ return -1;
+ break;
+ }
+ case PAR_ATTR_DATATYPE_MATRIX: {
+ if (mathutils_array_parse((float*)data, 16, 16, value, "NParticleParticle") == -1)
+ return -1;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static PyObject *bpy_bpar_particle_getattro(BPy_NParticleParticle *self, PyObject *pyname)
+{
+ const char *name = _PyUnicode_AsString(pyname);
+ PyObject *ret;
+
+// PYRNA_STRUCT_CHECK_OBJ(self);
+
+ if (!BKE_nparticle_iter_valid(&self->iter)) {
+ ret = NULL;
+ }
+ else if (name == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "NParticleParticle: __getattr__ must be a string");
+ ret = NULL;
+ }
+ else {
+ NParticleAttributeState *attrstate = BKE_nparticle_state_find_attribute(self->state, name);
+ void *data;
+
+ if (!attrstate) {
+ PyErr_Format(PyExc_AttributeError, "NParticleParticle.%.200s not found", name);
+ ret = NULL;
+ }
+ else {
+ data = BKE_nparticle_attribute_state_data(attrstate, self->iter.index);
+ if (!data) {
+ ret = NULL;
+ }
+ else {
+ ret = bpy_bpar_particle_data_read(&attrstate->desc, data);
+ }
+ }
+ }
+
+ return ret;
+}
+
+static int bpy_bpar_particle_setattro(BPy_NParticleParticle *self, PyObject *pyname, PyObject *value)
+{
+ const char *name = _PyUnicode_AsString(pyname);
+
+// PYRNA_STRUCT_CHECK_INT(self);
+
+ if (name == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "NParticleParticle: __setattr__ must be a string");
+ return -1;
+ }
+ else {
+ NParticleAttributeState *attrstate = BKE_nparticle_state_find_attribute(self->state, name);
+ void *data;
+
+ if (!attrstate) {
+ PyErr_Format(PyExc_AttributeError, "NParticleParticle.%.200s not found", name);
+ return -1;
+ }
+
+ if (!BKE_nparticle_iter_valid(&self->iter)) {
+ int index = BKE_nparticle_add(self->state, self->id);
+ BKE_nparticle_iter_from_index(self->state, &self->iter, index);
+ }
+
+ data = BKE_nparticle_attribute_state_data(attrstate, self->iter.index);
+ if (!data) {
+ return -1;
+ }
+
+ if (bpy_bpar_particle_data_write(&attrstate->desc, data, value) == -1) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
/* Dealloc Functions
* ================= */
@@ -514,10 +673,12 @@ void BPy_BPAR_init_types(void)
BPy_NParticleAttributeState_Type.tp_getset = bpy_bpar_attrstate_getseters;
BPy_NParticleAttributeStateSeq_Type.tp_getset = NULL;
BPy_NParticleAttributeStateIter_Type.tp_getset = NULL;
- BPy_NParticleParticle_Type.tp_getset = bpy_bpar_particle_getseters;
BPy_NParticleParticleSeq_Type.tp_getset = NULL;
BPy_NParticleParticleIter_Type.tp_getset = NULL;
+ BPy_NParticleParticle_Type.tp_getattro = (getattrofunc)bpy_bpar_particle_getattro;
+ BPy_NParticleParticle_Type.tp_setattro = (setattrofunc)bpy_bpar_particle_setat
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list