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:
-rw-r--r--source/blender/blenkernel/BKE_group.h4
-rw-r--r--source/blender/blenkernel/intern/group.c51
-rw-r--r--source/blender/blenkernel/intern/object.c2
-rw-r--r--source/blender/blenloader/intern/readfile.c2
-rw-r--r--source/blender/editors/object/object_add.c3
-rw-r--r--source/blender/editors/object/object_group.c43
-rw-r--r--source/blender/makesrna/RNA_access.h3
-rw-r--r--source/blender/makesrna/intern/rna_access.c25
-rw-r--r--source/blender/makesrna/intern/rna_group.c52
-rw-r--r--source/blender/python/intern/bpy_rna.c194
-rw-r--r--source/blender/python/intern/bpy_rna.h8
11 files changed, 253 insertions, 134 deletions
diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h
index b66ddf13527..877e09b037f 100644
--- a/source/blender/blenkernel/BKE_group.h
+++ b/source/blender/blenkernel/BKE_group.h
@@ -42,8 +42,8 @@ void free_group(struct Group *group);
void unlink_group(struct Group *group);
struct Group *add_group(char *name);
struct Group *copy_group(struct Group *group);
-void add_to_group(struct Group *group, struct Object *ob);
-int rem_from_group(struct Group *group, struct Object *ob);
+int add_to_group(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
+int rem_from_group(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
struct Group *find_group(struct Object *ob, struct Group *group);
int object_in_group(struct Object *ob, struct Group *group);
int group_is_animated(struct Object *parent, struct Group *group);
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 6bb47bc0f0f..77bf5859385 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -95,7 +95,7 @@ void unlink_group(Group *group)
/* ensure objects are not in this group */
for(; base; base= base->next) {
- if(rem_from_group(group, base->object) && find_group(base->object, NULL)==NULL) {
+ if(rem_from_group(group, base->object, sce, base) && find_group(base->object, NULL)==NULL) {
base->object->flag &= ~OB_FROMGROUP;
base->flag &= ~OB_FROMGROUP;
}
@@ -153,15 +153,15 @@ Group *copy_group(Group *group)
}
/* external */
-void add_to_group(Group *group, Object *ob)
+static int add_to_group_internal(Group *group, Object *ob)
{
GroupObject *go;
- if(group==NULL || ob==NULL) return;
+ if(group==NULL || ob==NULL) return 0;
/* check if the object has been added already */
for(go= group->gobject.first; go; go= go->next) {
- if(go->ob==ob) return;
+ if(go->ob==ob) return 0;
}
go= MEM_callocN(sizeof(GroupObject), "groupobject");
@@ -169,10 +169,31 @@ void add_to_group(Group *group, Object *ob)
go->ob= ob;
+ return 1;
+}
+
+int add_to_group(Group *group, Object *object, Scene *scene, Base *base)
+{
+ if(add_to_group_internal(group, object)) {
+ if((object->flag & OB_FROMGROUP)==0) {
+
+ if(scene && base==NULL)
+ base= object_in_scene(object, scene);
+
+ object->flag |= OB_FROMGROUP;
+
+ if(base)
+ base->flag |= OB_FROMGROUP;
+ }
+ return 1;
+ }
+ else {
+ return 0;
+ }
}
/* also used for ob==NULL */
-int rem_from_group(Group *group, Object *ob)
+static int rem_from_group_internal(Group *group, Object *ob)
{
GroupObject *go, *gon;
int removed = 0;
@@ -192,6 +213,26 @@ int rem_from_group(Group *group, Object *ob)
return removed;
}
+int rem_from_group(Group *group, Object *object, Scene *scene, Base *base)
+{
+ if(rem_from_group_internal(group, object)) {
+
+ if(find_group(object, NULL) == NULL) {
+ if(scene && base==NULL)
+ base= object_in_scene(object, scene);
+
+ object->flag &= ~OB_FROMGROUP;
+
+ if(base)
+ base->flag &= ~OB_FROMGROUP;
+ }
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
int object_in_group(Object *ob, Group *group)
{
GroupObject *go;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index f363b7d9a0a..078ff9d6eeb 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -622,7 +622,7 @@ void unlink_object(Scene *scene, Object *ob)
/* groups */
group= G.main->group.first;
while(group) {
- rem_from_group(group, ob);
+ rem_from_group(group, ob, NULL, NULL);
group= group->id.next;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 4f63fdf0737..83899473cb4 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5261,7 +5261,7 @@ static void lib_link_group(FileData *fd, Main *main)
go= go->next;
}
if(add_us) group->id.us++;
- rem_from_group(group, NULL); /* removes NULL entries */
+ rem_from_group(group, NULL, NULL, NULL); /* removes NULL entries */
}
group= group->id.next;
}
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 61377d76c56..e58170ebab6 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1262,9 +1262,8 @@ static Base *object_add_duplicate_internal(Scene *scene, Base *base, int dupflag
Group *group;
for(group= G.main->group.first; group; group= group->id.next) {
if(object_in_group(ob, group))
- add_to_group(group, obn);
+ add_to_group(group, obn, scene, basen);
}
- obn->flag |= OB_FROMGROUP; /* this flag is unset with copy_object() */
}
/* duplicates using userflags */
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index ec8409e9aa1..1e5b93aa6dc 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -60,7 +60,7 @@
static int objects_add_active_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
- Object *ob= OBACT, *obt;
+ Object *ob= OBACT;
Group *group;
int ok = 0;
@@ -73,11 +73,7 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
if(object_in_group(ob, group)) {
/* Assign groups to selected objects */
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
- obt= base->object;
- add_to_group(group, obt);
- obt->flag |= OB_FROMGROUP;
- base->flag |= OB_FROMGROUP;
- base->object->recalc= OB_RECALC_OB;
+ add_to_group(group, base->object, scene, base);
ok = 1;
}
CTX_DATA_END;
@@ -110,7 +106,7 @@ void GROUP_OT_objects_add_active(wmOperatorType *ot)
static int objects_remove_active_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
- Object *ob= OBACT, *obt;
+ Object *ob= OBACT;
Group *group;
int ok = 0;
@@ -123,11 +119,7 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
if(object_in_group(ob, group)) {
/* Assign groups to selected objects */
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
- obt= base->object;
- rem_from_group(group, obt);
- obt->flag &= ~OB_FROMGROUP;
- base->flag &= ~OB_FROMGROUP;
- base->object->recalc= OB_RECALC_OB;
+ rem_from_group(group, base->object, scene, base);
ok = 1;
}
CTX_DATA_END;
@@ -165,11 +157,7 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
group = NULL;
while((group = find_group(base->object, group)))
- rem_from_group(group, base->object);
-
- base->object->flag &= ~OB_FROMGROUP;
- base->flag &= ~OB_FROMGROUP;
- base->object->recalc= OB_RECALC_OB;
+ rem_from_group(group, base->object, scene, base);
}
CTX_DATA_END;
@@ -205,10 +193,7 @@ static int group_create_exec(bContext *C, wmOperator *op)
group= add_group(name);
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
- add_to_group(group, base->object);
- base->object->flag |= OB_FROMGROUP;
- base->flag |= OB_FROMGROUP;
- base->object->recalc= OB_RECALC_OB;
+ add_to_group(group, base->object, scene, base);
}
CTX_DATA_END;
@@ -259,9 +244,7 @@ static int group_add_exec(bContext *C, wmOperator *op)
group= BLI_findlink(&bmain->group, value);
if(group) {
- add_to_group(group, ob);
- ob->flag |= OB_FROMGROUP;
- base->flag |= OB_FROMGROUP;
+ add_to_group(group, ob, scene, NULL); /* base will be used if found */
}
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
@@ -323,21 +306,11 @@ static int group_remove_exec(bContext *C, wmOperator *op)
Scene *scene= CTX_data_scene(C);
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
Group *group= CTX_data_pointer_get_type(C, "group", &RNA_Group).data;
- Base *base;
if(!ob || !group)
return OPERATOR_CANCELLED;
- base= object_in_scene(ob, scene);
- if(!base)
- return OPERATOR_CANCELLED;
-
- rem_from_group(group, ob);
-
- if(find_group(ob, NULL) == NULL) {
- ob->flag &= ~OB_FROMGROUP;
- base->flag &= ~OB_FROMGROUP;
- }
+ rem_from_group(group, ob, scene, NULL); /* base will be used if found */
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 8d3c3168e00..6a1ef195d1d 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -683,7 +683,10 @@ int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop);
int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *t_ptr);
int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr);
int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr);
+
PropertyRNA *RNA_property_collection_active(PropertyRNA *prop);
+FunctionRNA *RNA_property_collection_add_func(PropertyRNA *prop);
+FunctionRNA *RNA_property_collection_remove_func(PropertyRNA *prop);
/* efficient functions to set properties for arrays */
int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array);
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 93e83492efa..dea593c78a5 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -1567,7 +1567,7 @@ int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
{
IDProperty *idprop;
- CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
+// CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
if((idprop=rna_idproperty_check(&prop, ptr))) {
IDPropertyTemplate val = {0};
@@ -1593,6 +1593,9 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA
MEM_freeN(item);
}
}
+
+ /* py api calls directly */
+#if 0
else if(cprop->add){
if(!(cprop->add->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
ParameterList params;
@@ -1603,6 +1606,7 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA
}
/*else
printf("RNA_property_collection_add %s.%s: not implemented for this property.\n", ptr->type->identifier, prop->identifier);*/
+#endif
if(r_ptr) {
if(idprop) {
@@ -1620,7 +1624,7 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA
int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
{
IDProperty *idprop;
- CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
+// CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
if((idprop=rna_idproperty_check(&prop, ptr))) {
IDProperty tmp, *array;
@@ -1644,6 +1648,9 @@ int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
}
else if(prop->flag & PROP_IDPROPERTY)
return 1;
+
+ /* py api calls directly */
+#if 0
else if(cprop->remove){
if(!(cprop->remove->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
ParameterList params;
@@ -1656,7 +1663,7 @@ int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
}
/*else
printf("RNA_property_collection_remove %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);*/
-
+#endif
return 0;
}
@@ -1767,6 +1774,18 @@ PropertyRNA *RNA_property_collection_active(PropertyRNA *prop)
return cprop->active;
}
+FunctionRNA *RNA_property_collection_add_func(PropertyRNA *prop)
+{
+ CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
+ return cprop->add;
+}
+
+FunctionRNA *RNA_property_collection_remove_func(PropertyRNA *prop)
+{
+ CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
+ return cprop->remove;
+}
+
int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array)
{
CollectionPropertyIterator iter;
diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c
index dddc2062f07..8f6a5f1005c 100644
--- a/source/blender/makesrna/intern/rna_group.c
+++ b/source/blender/makesrna/intern/rna_group.c
@@ -33,6 +33,11 @@
#ifdef RNA_RUNTIME
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_group.h"
+
static PointerRNA rna_Group_objects_get(CollectionPropertyIterator *iter)
{
ListBaseIterator *internal= iter->internal;
@@ -41,6 +46,16 @@ static PointerRNA rna_Group_objects_get(CollectionPropertyIterator *iter)
return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((GroupObject*)internal->link)->ob);
}
+static int rna_Group_objects_add(Group *group, bContext *C, Object *object)
+{
+ return add_to_group(group, object, CTX_data_scene(C), NULL);
+}
+
+static int rna_Group_objects_remove(Group *group, bContext *C, Object *object)
+{
+ return rem_from_group(group, object, CTX_data_scene(C), NULL);
+}
+
#else
void RNA_def_group(BlenderRNA *brna)
@@ -57,16 +72,41 @@ void RNA_def_group(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Dupli Offset", "Offset from the center to use when instancing as DupliGroup.");
RNA_def_property_ui_range(prop, -10000.0, 10000.0, 10, 4);
+ prop= RNA_def_property(srna, "layer", PROP_BOOLEAN, PROP_LAYER);
+ RNA_def_property_boolean_sdna(prop, NULL, "layer", 1);
+ RNA_def_property_array(prop, 20);
+ RNA_def_property_ui_text(prop, "Dupli Layers", "Layers visible when this groups is instanced as a dupli.");
+
+
+ /* add object */
+ FunctionRNA *func;
+ PropertyRNA *parm;
+ func= RNA_def_function(srna, "add_object", "rna_Group_objects_add");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ RNA_def_function_ui_description(func, "Add this object to a group");
+ /* return type */
+ parm= RNA_def_boolean(func, "success", 0, "Success", "Newly created Group Target.");
+ RNA_def_function_return(func, parm);
+ /* object to add */
+ parm= RNA_def_pointer(func, "object", "Object", "", "Object to add.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ /* remove object */
+ func= RNA_def_function(srna, "remove_object", "rna_Group_objects_remove");
+ RNA_def_function_ui_description(func, "Remove this object to a group");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ /* return type */
+ parm= RNA_def_boolean(func, "success", 0, "Success", "Newly created Group Target.");
+ RNA_def_function_return(func, parm);
+ /* object to remove */
+ parm= RNA_def_pointer(func, "object", "Object", "", "Object to remove.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
prop= RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "gobject", NULL);
RNA_def_property_struct_type(prop, "Object");
RNA_def_property_ui_text(prop, "Objects", "A collection of this groups objects.");
- RNA_def_property_collection_funcs(prop, 0, 0, 0, "rna_Group_objects_get", 0, 0, 0, 0, 0);
-
- prop= RNA_def_property(srna, "layer", PROP_BOOLEAN, PROP_LAYER);
- RNA_def_property_boolean_sdna(prop, NULL, "layer", 1);
- RNA_def_property_array(prop, 20);
- RNA_def_property_ui_text(prop, "Dupli Layers", "Layers visible when this groups is instanced as a dupli.");
+ RNA_def_property_collection_funcs(prop, 0, 0, 0, "rna_Group_objects_get", 0, 0, 0, "add_object", "remove_object");
}
#endif
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index d490debdce6..b47214bdded 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -519,7 +519,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw);
-PyObject *pyrna_func_to_py(BPy_StructRNA *pyrna, FunctionRNA *func)
+PyObject *pyrna_func_to_py(BPy_DummyPointerRNA *pyrna, FunctionRNA *func)
{
static PyMethodDef func_meth = {"<generic rna function>", (PyCFunction)pyrna_func_call, METH_VARARGS|METH_KEYWORDS, "python rna function"};
PyObject *self;
@@ -595,7 +595,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
case PROP_INT:
{
int param = PyLong_AsSsize_t(value);
- if (PyErr_Occurred()) {
+ if (param==-1 && PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError, "%.200s expected an int type", error_prefix);
return -1;
} else {
@@ -816,7 +816,7 @@ static int pyrna_py_to_prop_index(BPy_PropertyRNA *self, int index, PyObject *va
case PROP_INT:
{
int param = PyLong_AsSsize_t(value);
- if (PyErr_Occurred()) {
+ if (param==-1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, "expected an int type");
ret = -1;
} else {
@@ -1371,7 +1371,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
ret = pyrna_prop_to_py(&self->ptr, prop);
}
else if ((func = RNA_struct_find_function(&self->ptr, name))) {
- ret = pyrna_func_to_py(self, func);
+ ret = pyrna_func_to_py((BPy_DummyPointerRNA *)self, func);
}
else if (self->ptr.type == &RNA_Context) {
PointerRNA newptr;
@@ -1470,54 +1470,130 @@ static int pyrna_struct_setattro( BPy_StructRNA * self, PyObject *pyname, PyObje
return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "StructRNA - Attribute (setattr):");
}
-static PyObject *pyrna_prop_getattro( BPy_PropertyRNA * self, PyObject *pyname )
+static PyObject *pyrna_prop_get_active( BPy_PropertyRNA * self )
{
- char *name = _PyUnicode_AsString(pyname);
+ PropertyRNA *prop_act;
- if(strcmp(name, "active")==0) {
- PropertyRNA *prop_act;
+ if (RNA_property_type(self->prop) != PROP_COLLECTION) {
+ PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not a collection");
+ return NULL;
+ }
- if (RNA_property_type(self->prop) != PROP_COLLECTION) {
- PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not a collection");
- return NULL;
- }
+ prop_act= RNA_property_collection_active(self->prop);
+ if (prop_act==NULL) {
+ PyErr_SetString( PyExc_TypeError, "collection has no active");
+ return NULL;
+ }
- prop_act= RNA_property_collection_active(self->prop);
- if (prop_act==NULL) {
- PyErr_SetString( PyExc_TypeError, "collection has no active");
- return NULL;
- }
+ return pyrna_prop_to_py(&self->ptr, prop_act);
+}
- return pyrna_prop_to_py(&self->ptr, prop_act);
+static int pyrna_prop_set_active( BPy_PropertyRNA * self, PyObject * value )
+{
+ PropertyRNA *prop_act;
+
+ if (RNA_property_type(self->prop) != PROP_COLLECTION) {
+ PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not a collection");
+ return -1;
+ }
+
+ prop_act= RNA_property_collection_active(self->prop);
+ if (prop_act==NULL) {
+ PyErr_SetString( PyExc_TypeError, "collection has no active");
+ return -1;
}
- return PyObject_GenericGetAttr((PyObject *)self, pyname);
+ return pyrna_py_to_prop(&self->ptr, prop_act, NULL, value, "StructRNA - Attribute (setattr):");
}
-//--------------- setattr-------------------------------------------
-static int pyrna_prop_setattro( BPy_PropertyRNA * self, PyObject *pyname, PyObject * value )
+/* odd case, we need to be able return a python method from a tp_getset */
+static PyObject *pyrna_prop_add(BPy_PropertyRNA *self);
+static PyMethodDef pyrna_prop_add_meth[] = {{"add", (PyCFunction)pyrna_prop_add, METH_NOARGS, NULL}};
+static PyObject *pyrna_prop_add(BPy_PropertyRNA *self)
{
- char *name = _PyUnicode_AsString(pyname);
- if(strcmp(name, "active")==0) {
- PropertyRNA *prop_act;
+ PointerRNA r_ptr;
- if (RNA_property_type(self->prop) != PROP_COLLECTION) {
- PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not a collection");
- return -1;
- }
+ RNA_property_collection_add(&self->ptr, self->prop, &r_ptr);
+ if(!r_ptr.data) {
+ PyErr_SetString( PyExc_TypeError, "add() not supported for this collection");
+ return NULL;
+ }
+ else {
+ return pyrna_struct_CreatePyObject(&r_ptr);
+ }
+}
- prop_act= RNA_property_collection_active(self->prop);
- if (prop_act==NULL) {
- PyErr_SetString( PyExc_TypeError, "collection has no active");
- return -1;
+
+static PyObject *pyrna_prop_remove(BPy_PropertyRNA *self, PyObject *value);
+static PyMethodDef pyrna_prop_remove_meth[] = {{"remove", (PyCFunction)pyrna_prop_remove, METH_O, NULL}};
+static PyObject *pyrna_prop_remove(BPy_PropertyRNA *self, PyObject *value)
+{
+ PyObject *ret;
+ int key= PyLong_AsSsize_t(value);
+
+ if (key==-1 && PyErr_Occurred()) {
+ PyErr_SetString( PyExc_TypeError, "remove() expected one int argument");
+ return NULL;
+ }
+
+ if(!RNA_property_collection_remove(&self->ptr, self->prop, key)) {
+ PyErr_SetString( PyExc_TypeError, "remove() not supported for this collection");
+ return NULL;
+ }
+
+ ret = Py_None;
+ Py_INCREF(ret);
+
+ return ret;
+}
+
+static PyObject *pyrna_prop_get_add_func( BPy_PropertyRNA * self )
+{
+ FunctionRNA *func;
+
+ if (RNA_property_type(self->prop) == PROP_COLLECTION) {
+ func = RNA_property_collection_add_func(self->prop);
+ if (func==NULL) {
+ PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA collection has no add() function");
+ return NULL;
}
- return pyrna_py_to_prop(&self->ptr, prop_act, NULL, value, "StructRNA - Attribute (setattr):");
+ return pyrna_func_to_py((BPy_DummyPointerRNA *)self, func);
}
+ else {
+ return PyCFunction_New(pyrna_prop_add_meth, (PyObject *)self);
+ }
+}
- return PyObject_GenericSetAttr((PyObject *)self, pyname, value);
+static PyObject *pyrna_prop_get_remove_func( BPy_PropertyRNA * self )
+{
+ FunctionRNA *func;
+
+ if (RNA_property_type(self->prop) == PROP_COLLECTION) {
+ func = RNA_property_collection_remove_func(self->prop);
+ if (func==NULL) {
+ PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA collection has no add() function");
+ return NULL;
+ }
+
+ return pyrna_func_to_py((BPy_DummyPointerRNA *)self, func);
+ }
+ else {
+ return PyCFunction_New(pyrna_prop_remove_meth, (PyObject *)self);
+ }
}
+/*****************************************************************************/
+/* Python attributes get/set structure: */
+/*****************************************************************************/
+static PyGetSetDef pyrna_prop_getseters[] = {
+ {"active", (getter)pyrna_prop_get_active, (setter)pyrna_prop_set_active, "", NULL},
+ /* rna functions */
+ {"add", (getter)pyrna_prop_get_add_func, NULL, "", NULL},
+ {"remove", (getter)pyrna_prop_get_remove_func, NULL, "", NULL},
+ {NULL,NULL,NULL,NULL,NULL} /* Sentinel */
+};
+
static PyObject *pyrna_prop_keys(BPy_PropertyRNA *self)
{
PyObject *ret;
@@ -1630,40 +1706,6 @@ static PyObject *pyrna_prop_get(BPy_PropertyRNA *self, PyObject *args)
return def;
}
-
-static PyObject *pyrna_prop_add(BPy_PropertyRNA *self, PyObject *args)
-{
- PointerRNA newptr;
-
- RNA_property_collection_add(&self->ptr, self->prop, &newptr);
- if(!newptr.data) {
- PyErr_SetString( PyExc_TypeError, "add() not supported for this collection");
- return NULL;
- }
- else {
- return pyrna_struct_CreatePyObject(&newptr);
- }
-}
-
-static PyObject *pyrna_prop_remove(BPy_PropertyRNA *self, PyObject *args)
-{
- PyObject *ret;
- int key= 0;
-
- if (!PyArg_ParseTuple(args, "i:remove", &key))
- return NULL;
-
- if(!RNA_property_collection_remove(&self->ptr, self->prop, key)) {
- PyErr_SetString( PyExc_TypeError, "remove() not supported for this collection");
- return NULL;
- }
-
- ret = Py_None;
- Py_INCREF(ret);
-
- return ret;
-}
-
static void foreach_attr_type( BPy_PropertyRNA *self, char *attr,
/* values to assign */
RawPropertyType *raw_type, int *attr_tot, int *attr_signed )
@@ -1951,8 +1993,11 @@ static struct PyMethodDef pyrna_prop_methods[] = {
{"get", (PyCFunction)pyrna_prop_get, METH_VARARGS, NULL},
- {"add", (PyCFunction)pyrna_prop_add, METH_VARARGS, NULL},
- {"remove", (PyCFunction)pyrna_prop_remove, METH_VARARGS, NULL},
+ /* moved into a getset */
+#if 0
+ {"add", (PyCFunction)pyrna_prop_add, METH_NOARGS, NULL},
+ {"remove", (PyCFunction)pyrna_prop_remove, METH_O, NULL},
+#endif
/* array accessor function */
{"foreach_get", (PyCFunction)pyrna_prop_foreach_get, METH_VARARGS, NULL},
@@ -2123,7 +2168,8 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
{
- PointerRNA *self_ptr= &(((BPy_StructRNA *)PyTuple_GET_ITEM(self, 0))->ptr);
+ /* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here */
+ PointerRNA *self_ptr= &(((BPy_DummyPointerRNA *)PyTuple_GET_ITEM(self, 0))->ptr);
FunctionRNA *self_func= PyCObject_AsVoidPtr(PyTuple_GET_ITEM(self, 1));
PointerRNA funcptr;
@@ -2429,8 +2475,8 @@ PyTypeObject pyrna_prop_Type = {
NULL, /* reprfunc tp_str; */
/* will only use these if this is a subtype of a py class */
- ( getattrofunc ) pyrna_prop_getattro, /* getattrofunc tp_getattro; */
- ( setattrofunc ) pyrna_prop_setattro, /* setattrofunc tp_setattro; */
+ ( getattrofunc ) NULL, /* getattrofunc tp_getattro; */
+ ( setattrofunc ) NULL, /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
NULL, /* PyBufferProcs *tp_as_buffer; */
@@ -2461,7 +2507,7 @@ PyTypeObject pyrna_prop_Type = {
/*** Attribute descriptor and subclassing stuff ***/
pyrna_prop_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
- NULL, /* struct PyGetSetDef *tp_getset; */
+ pyrna_prop_getseters, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
NULL, /* PyObject *tp_dict; */
NULL, /* descrgetfunc tp_descr_get; */
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index fe38ddb6bd9..0e40bf7258c 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -39,11 +39,9 @@ extern PyTypeObject pyrna_prop_Type;
#define BPy_PropertyRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_prop_Type)
typedef struct {
- void * _a;
- void * _b;
- PyTypeObject *py_type;
-} BPy_StructFakeType;
-
+ PyObject_HEAD /* required python macro */
+ PointerRNA ptr;
+} BPy_DummyPointerRNA;
typedef struct {
PyObject_HEAD /* required python macro */