From d2745986c84ef574c84a14db08944cdc69453feb Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 28 Jun 2018 14:27:19 +0200 Subject: Static Override: add support to override items (objects/sub-collections) in Collection IDs. Was kind of a PITA to get working, but simple tests seem to pass well... --- source/blender/makesrna/intern/rna_group.c | 92 ++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) (limited to 'source/blender/makesrna/intern/rna_group.c') diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c index de773e1f20d..ff3900705e4 100644 --- a/source/blender/makesrna/intern/rna_group.c +++ b/source/blender/makesrna/intern/rna_group.c @@ -45,10 +45,14 @@ #include "DEG_depsgraph_build.h" #include "BKE_collection.h" +#include "BKE_global.h" #include "BKE_layer.h" +#include "BKE_library.h" #include "WM_api.h" +#include "RNA_access.h" + static void rna_Collection_all_objects_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { Collection *collection = (Collection *)ptr->data; @@ -104,6 +108,49 @@ static void rna_Collection_objects_unlink(Collection *collection, Main *bmain, R WM_main_add_notifier(NC_OBJECT | ND_DRAW, &object->id); } +static bool rna_Collection_objects_override_apply( + PointerRNA *ptr_dst, PointerRNA *UNUSED(ptr_src), PointerRNA *UNUSED(ptr_storage), + PropertyRNA *UNUSED(prop_dst), PropertyRNA *UNUSED(prop_src), PropertyRNA *UNUSED(prop_storage), + const int UNUSED(len_dst), const int UNUSED(len_src), const int UNUSED(len_storage), + PointerRNA *ptr_item_dst, PointerRNA *ptr_item_src, PointerRNA *UNUSED(ptr_item_storage), + IDOverrideStaticPropertyOperation *opop) +{ + BLI_assert(opop->operation == IDOVERRIDESTATIC_OP_REPLACE && + "Unsupported RNA override operation on collections' objects"); + + Collection *coll_dst = ptr_dst->id.data; + + if (ptr_item_dst->type == NULL || ptr_item_src->type == NULL) { + BLI_assert(0 && "invalid source or destination object."); + return false; + } + + Object *ob_dst = ptr_item_dst->data; + Object *ob_src = ptr_item_src->data; + + CollectionObject *cob_dst = BLI_findptr(&coll_dst->gobject, ob_dst, offsetof(CollectionObject, ob)); + + if (cob_dst == NULL) { + BLI_assert(0 && "Could not find destination object in destination collection!"); + return false; + } + + /* XXX TODO We most certainly rather want to have a 'swap object pointer in collection' util in BKE_collection... + * This is only temp auick dirty test! */ + id_us_min(&cob_dst->ob->id); + cob_dst->ob = ob_src; + id_us_plus(&cob_dst->ob->id); + + if (BKE_collection_is_in_scene(coll_dst)) { + BKE_main_collection_sync(G.main); /* YUCK!!!!!!!!!!!!! */ + } + + return true; +} + + + + static void rna_Collection_children_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { Collection *collection = (Collection *)ptr->data; @@ -143,6 +190,48 @@ static void rna_Collection_children_unlink(Collection *collection, Main *bmain, WM_main_add_notifier(NC_OBJECT | ND_DRAW, &child->id); } +static bool rna_Collection_children_override_apply( + PointerRNA *ptr_dst, PointerRNA *UNUSED(ptr_src), PointerRNA *UNUSED(ptr_storage), + PropertyRNA *UNUSED(prop_dst), PropertyRNA *UNUSED(prop_src), PropertyRNA *UNUSED(prop_storage), + const int UNUSED(len_dst), const int UNUSED(len_src), const int UNUSED(len_storage), + PointerRNA *ptr_item_dst, PointerRNA *ptr_item_src, PointerRNA *UNUSED(ptr_item_storage), + IDOverrideStaticPropertyOperation *opop) +{ + BLI_assert(opop->operation == IDOVERRIDESTATIC_OP_REPLACE && + "Unsupported RNA override operation on collections' objects"); + + Collection *coll_dst = ptr_dst->id.data; + + if (ptr_item_dst->type == NULL || ptr_item_src->type == NULL) { + BLI_assert(0 && "invalid source or destination sub-collection."); + return false; + } + + Collection *subcoll_dst = ptr_item_dst->data; + Collection *subcoll_src = ptr_item_src->data; + + CollectionChild *collchild_dst = BLI_findptr(&coll_dst->children, subcoll_dst, offsetof(CollectionChild, collection)); + + if (collchild_dst == NULL) { + BLI_assert(0 && "Could not find destination sub-collection in destination collection!"); + return false; + } + + /* XXX TODO We most certainly rather want to have a 'swap object pointer in collection' util in BKE_collection... + * This is only temp auick dirty test! */ + id_us_min(&collchild_dst->collection->id); + collchild_dst->collection = subcoll_src; + id_us_plus(&collchild_dst->collection->id); + + BKE_collection_object_cache_free(coll_dst); + BKE_main_collection_sync(G.main); /* YUCK!!!!!!!!!!!!! */ + + return true; +} + + + + static void rna_Collection_flag_update(Main *bmain, Scene *scene, PointerRNA *ptr) { Collection *collection = (Collection *)ptr->data; @@ -232,6 +321,7 @@ void RNA_def_collections(BlenderRNA *brna) prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); + RNA_def_property_override_funcs(prop, NULL, NULL, "rna_Collection_objects_override_apply"); RNA_def_property_ui_text(prop, "Objects", "Objects that are directly in this collection"); RNA_def_property_collection_funcs(prop, "rna_Collection_objects_begin", "rna_iterator_listbase_next", @@ -251,6 +341,8 @@ void RNA_def_collections(BlenderRNA *brna) prop = RNA_def_property(srna, "children", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "Collection"); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); + RNA_def_property_override_funcs(prop, NULL, NULL, "rna_Collection_children_override_apply"); RNA_def_property_ui_text(prop, "Children", "Collections that are immediate children of this collection"); RNA_def_property_collection_funcs(prop, "rna_Collection_children_begin", "rna_iterator_listbase_next", -- cgit v1.2.3