python api for collection add()/remove()
Added a group example C = bpy.context ob = C.active_object bpy.data.groups[0].objects.add(ob) - add_to_group and rem_from_group now take optional scene and base flags and deal with updating the object & base flags - operators that add objects to groups were setting ob->recalc= OB_RECALC_OB; looks like its not needed. - previously add() ignored python args, now add and remove are called like any other FunctionRNA from python. - made the pyrna api use tp_getset's for collestions active/add()/remove()
This commit is contained in:
parent
f243928055
commit
bc6190f3e3
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,53 +1470,129 @@ 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");
|
||||
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);
|
||||
}
|
||||
|
||||
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 pyrna_py_to_prop(&self->ptr, prop_act, NULL, value, "StructRNA - Attribute (setattr):");
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
PointerRNA r_ptr;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
prop_act= RNA_property_collection_active(self->prop);
|
||||
if (prop_act==NULL) {
|
||||
PyErr_SetString( PyExc_TypeError, "collection has no active");
|
||||
return pyrna_func_to_py((BPy_DummyPointerRNA *)self, func);
|
||||
}
|
||||
else {
|
||||
return PyCFunction_New(pyrna_prop_add_meth, (PyObject *)self);
|
||||
}
|
||||
}
|
||||
|
||||
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_prop_to_py(&self->ptr, prop_act);
|
||||
return pyrna_func_to_py((BPy_DummyPointerRNA *)self, func);
|
||||
}
|
||||
else {
|
||||
return PyCFunction_New(pyrna_prop_remove_meth, (PyObject *)self);
|
||||
}
|
||||
|
||||
return PyObject_GenericGetAttr((PyObject *)self, pyname);
|
||||
}
|
||||
|
||||
//--------------- setattr-------------------------------------------
|
||||
static int pyrna_prop_setattro( BPy_PropertyRNA * self, PyObject *pyname, PyObject * value )
|
||||
{
|
||||
char *name = _PyUnicode_AsString(pyname);
|
||||
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 -1;
|
||||
}
|
||||
|
||||
prop_act= RNA_property_collection_active(self->prop);
|
||||
if (prop_act==NULL) {
|
||||
PyErr_SetString( PyExc_TypeError, "collection has no active");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pyrna_py_to_prop(&self->ptr, prop_act, NULL, value, "StructRNA - Attribute (setattr):");
|
||||
}
|
||||
|
||||
return PyObject_GenericSetAttr((PyObject *)self, pyname, value);
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/* 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)
|
||||
{
|
||||
@ -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; */
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user