diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_scene.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 38 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 47 |
3 files changed, 87 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 865d6b31dc1..9c462523c18 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -100,6 +100,8 @@ void BKE_scene_base_flag_from_objects(struct Scene *scene); /* base functions */ struct Base *BKE_scene_layer_base_find_by_name(struct SceneLayer *sl, const char *name); struct Base *BKE_scene_layer_base_find(struct SceneLayer *sl, struct Object *ob); +struct Base *BKE_scene_layer_collection_base_find(struct LayerCollection *lc, struct Object *ob); +struct Base *BKE_scene_layer_base_add(struct SceneLayer *sl, struct LayerCollection *lc, struct Object *ob); void BKE_scene_layer_base_deselect_all(struct SceneLayer *sl); void BKE_scene_layer_base_select(struct SceneLayer *sl, struct Base *selbase); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 6ea9825b33e..1cb628a4750 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -890,6 +890,44 @@ Base *BKE_scene_layer_base_find(SceneLayer *sl, Object *ob) return BLI_findptr(&sl->base, ob, offsetof(Base, object)); } +Base *BKE_scene_layer_collection_base_find(LayerCollection *lc, Object *ob) +{ + for (LinkData *link = lc->elements.first; link; link = link->next) { + Base *base = link->data; + + if (base->object == ob) { + return base; + } + } + return NULL; +} + +static Base *scene_layer_base_add(SceneLayer *sl, Object *ob) +{ + Base *b = MEM_callocN(sizeof(*b), __func__); + BLI_addhead(&sl->base, b); + + b->object = ob; + b->flag = ob->flag; + b->lay = ob->lay; + + return b; +} + +Base *BKE_scene_layer_base_add(SceneLayer *sl, LayerCollection *lc, Object *ob) +{ + Base *base = BKE_scene_layer_base_find(sl, ob); + + if (base == NULL) { + base = scene_layer_base_add(sl, ob); + } + + /* only bump id count for collection */ + id_us_plus(&ob->id); + BLI_addtail(&lc->elements, BLI_genericNodeN(base)); + return base; +} + /** * Sets the active scene, mainly used when running in background mode (``--scene`` command line argument). * This is also called to set the scene directly, bypassing windowing code. diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 60156a60c1e..dcb8ce2892c 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -632,6 +632,31 @@ static void rna_Scene_object_unlink(Scene *scene, ReportList *reports, Object *o WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, scene); } +static Base *rna_LayerCollection_object_link(ID *id, LayerCollection *lc, Main *bmain, ReportList *reports, Object *ob) +{ + Base *base; + Scene *scene = (Scene *)id; + SceneLayer *sl = BKE_scene_layer_from_collection(scene, lc); + + if (BKE_scene_layer_collection_base_find(lc, ob)) { + BKE_reportf(reports, RPT_ERROR, "Object '%s' is already in collection '%s'", ob->id.name + 2, lc->name); + return NULL; + } + + base = BKE_scene_layer_base_add(sl, lc, ob); + + /* TODO(sergey): Only update relations for the current scene layer. */ + DAG_relations_tag_update(bmain); + DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + + /* slows down importers too much, run scene.update() */ + /* DAG_srelations_tag_update(G.main); */ + + WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, scene); + + return base; +} + static int rna_Scene_layer_object_bases_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) { SceneLayer *sl = (SceneLayer *)ptr->data; @@ -5187,6 +5212,27 @@ static void rna_def_layer_objects(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, NULL); } +/* collection.objects */ +static void rna_def_layer_collection_objects(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "CollectionObjects"); + srna = RNA_def_struct(brna, "CollectionObjects", NULL); + RNA_def_struct_sdna(srna, "LayerCollection"); + RNA_def_struct_ui_text(srna, "Collection Objects", "Collection of collection objects"); + + func = RNA_def_function(srna, "link", "rna_LayerCollection_object_link"); + RNA_def_function_ui_description(func, "Link object to collection, run scene.update() after"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS | FUNC_USE_MAIN); + parm = RNA_def_pointer(func, "object", "Object", "", "Object to add to collection"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + parm = RNA_def_pointer(func, "base", "ObjectBase", "", "The newly created base"); + RNA_def_function_return(func, parm); +} + static void rna_def_layer_nested_collections(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; @@ -5233,6 +5279,7 @@ static void rna_def_layer_collection(BlenderRNA *brna) RNA_def_property_struct_type(prop, "Object"); RNA_def_property_ui_text(prop, "Objects", ""); RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_LayerCollection_objects_get", NULL, NULL, NULL, NULL); + rna_def_layer_collection_objects(brna, prop); /* TODO overrides */ |