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
path: root/source
diff options
context:
space:
mode:
authorDalai Felinto <dfelinto@gmail.com>2016-11-23 19:44:28 +0300
committerDalai Felinto <dfelinto@gmail.com>2016-11-23 20:26:06 +0300
commit75d6c0cae6426d0a37c45476b527a406eaffd08b (patch)
tree0fb8626f703519b1333fc6d9d574dccbd53c9d7a /source
parentb3de810bf22ad0cbdec1b806bf6998ed64d849df (diff)
Fix mem leak for recursive collections and get layer.bases and objects
to work (also some base util functions, and a refactor to unify the functions for nested and non nested collections)
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_scene.h17
-rw-r--r--source/blender/blenkernel/intern/scene.c130
-rw-r--r--source/blender/makesrna/intern/rna_scene.c101
3 files changed, 187 insertions, 61 deletions
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 4039ff909e7..865d6b31dc1 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -97,6 +97,15 @@ int BKE_scene_base_iter_next(struct EvaluationContext *eval_ctx, struct SceneBas
void BKE_scene_base_flag_to_objects(struct Scene *scene);
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);
+void BKE_scene_layer_base_deselect_all(struct SceneLayer *sl);
+void BKE_scene_layer_base_select(struct SceneLayer *sl, struct Base *selbase);
+
+void BKE_scene_layer_base_flag_to_objects(struct SceneLayer *sl);
+void BKE_scene_layer_base_flag_from_objects(struct SceneLayer *sl);
+
void BKE_scene_set_background(struct Main *bmain, struct Scene *sce);
struct Scene *BKE_scene_set_name(struct Main *bmain, const char *name);
@@ -126,13 +135,11 @@ void BKE_scene_update_tagged(struct EvaluationContext *eval_ctx, struct Main *bm
void BKE_scene_update_for_newframe(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, unsigned int lay);
void BKE_scene_update_for_newframe_ex(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, unsigned int lay, bool do_invisible_flush);
+struct SceneLayer *BKE_scene_layer_from_collection(struct Scene *scene, struct LayerCollection *lc);
struct SceneLayer *BKE_scene_add_layer(struct Scene *sce, const char *name);
bool BKE_scene_remove_layer(struct Main *main, struct Scene *scene, struct SceneLayer *sl);
-struct LayerCollection *BKE_scene_add_collection(struct SceneLayer *sl, const char *name);
-bool BKE_scene_remove_nested_collection(struct SceneLayer *sl, struct LayerCollection *lc_parent, struct LayerCollection *lc);
-struct SceneLayer *BKE_scene_layer_from_collection(struct Scene *scene, struct LayerCollection *lc);
-bool BKE_scene_remove_collection(struct SceneLayer *sl, struct LayerCollection *lc);
-struct LayerCollection *BKE_scene_add_nested_collection(struct SceneLayer *sl, struct LayerCollection *lc, const char *name);
+struct LayerCollection *BKE_scene_add_collection(struct SceneLayer *sl, struct LayerCollection *lc_parent, const char *name);
+bool BKE_scene_remove_collection(struct SceneLayer *sl, struct LayerCollection *lc_parent, struct LayerCollection *lc);
struct LayerCollection *BKE_scene_layer_collection_active(struct SceneLayer *sl);
int BKE_scene_layer_collection_count(struct SceneLayer *sl);
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index f8319318e52..6ea9825b33e 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -103,6 +103,9 @@
#include "bmesh.h"
+/* prototypes */
+static void layer_collections_free(ListBase *lb);
+
const char *RE_engine_id_BLENDER_RENDER = "BLENDER_RENDER";
const char *RE_engine_id_BLENDER_GAME = "BLENDER_GAME";
const char *RE_engine_id_CYCLES = "CYCLES";
@@ -501,11 +504,7 @@ void BKE_scene_free(Scene *sce)
sl->basact = NULL;
BLI_freelistN(&sl->base);
- for (LayerCollection *lc = sl->collections.first; lc; lc = lc->next) {
- BLI_freelistN(&lc->elements);
- BLI_freelistN(&lc->overrides);
- }
- BLI_freelistN(&sl->collections);
+ layer_collections_free(&sl->collections);
}
BLI_freelistN(&sce->layers);
}
@@ -873,6 +872,24 @@ Base *BKE_scene_base_find(Scene *scene, Object *ob)
return BLI_findptr(&scene->base, ob, offsetof(Base, object));
}
+Base *BKE_scene_layer_base_find_by_name(struct SceneLayer *sl, const char *name)
+{
+ Base *base;
+
+ for (base = sl->base.first; base; base = base->next) {
+ if (STREQ(base->object->id.name + 2, name)) {
+ break;
+ }
+ }
+
+ return base;
+}
+
+Base *BKE_scene_layer_base_find(SceneLayer *sl, Object *ob)
+{
+ return BLI_findptr(&sl->base, ob, offsetof(Base, object));
+}
+
/**
* 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.
@@ -1219,6 +1236,25 @@ void BKE_scene_base_select(Scene *sce, Base *selbase)
sce->basact = selbase;
}
+void BKE_scene_layer_base_deselect_all(SceneLayer *sl)
+{
+ Base *b;
+
+ for (b = sl->base.first; b; b = b->next) {
+ b->flag &= ~SELECT;
+ b->object->flag = b->flag;
+ }
+}
+
+void BKE_scene_layer_base_select(SceneLayer *sl, Base *selbase)
+{
+ selbase->flag |= SELECT;
+ selbase->object->flag = selbase->flag;
+
+ sl->basact = selbase;
+}
+
+
/* checks for cycle, returns 1 if it's all OK */
bool BKE_scene_validate_setscene(Main *bmain, Scene *sce)
{
@@ -2123,72 +2159,47 @@ SceneLayer *BKE_scene_layer_from_collection(Scene *scene, LayerCollection *lc)
return NULL;
}
-LayerCollection *BKE_scene_add_nested_collection(SceneLayer *sl, LayerCollection *lc, const char *name)
+/* lc_parent is optional, to be used only for nested collections */
+LayerCollection *BKE_scene_add_collection(SceneLayer *sl, LayerCollection *lc_parent, const char *name)
{
+ ListBase *lb = (lc_parent ? &lc_parent->collections : &sl->collections);
LayerCollection *lc_new;
lc_new = MEM_callocN(sizeof(LayerCollection), "new layer collection");
BLI_strncpy(lc_new->name, name, sizeof(lc_new->name));
BLI_uniquename(&sl->collections, lc_new, DATA_("Collection"), '.', offsetof(LayerCollection, name), sizeof(lc_new->name));
- BLI_addtail(&lc->collections, lc_new);
+ BLI_addtail(lb, lc_new);
return lc_new;
}
-static void free_collection(LayerCollection *lc)
+static void layer_collection_free(LayerCollection *lc)
{
BLI_freelistN(&lc->elements);
BLI_freelistN(&lc->overrides);
+ layer_collections_free(&lc->collections);
}
-bool BKE_scene_remove_nested_collection(SceneLayer *sl, LayerCollection *lc_parent, LayerCollection *lc)
+static void layer_collections_free(ListBase *lb)
{
- const int act = BLI_findindex(&lc_parent->collections, lc);
- if (act == -1) {
- return false;
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ layer_collection_free(lc);
}
-
- BLI_remlink(&lc_parent->collections, lc);
- free_collection(lc);
- MEM_freeN(lc);
-
- /* TODO only change active_collection if necessary */
- sl->active_collection = 0;
-
- return true;
+ BLI_freelistN(lb);
}
-LayerCollection *BKE_scene_add_collection(SceneLayer *sl, const char *name)
+/* lc_parent is optional, to be used only for nested collections */
+bool BKE_scene_remove_collection(SceneLayer *sl, LayerCollection *lc_parent, LayerCollection *lc)
{
- LayerCollection *lc;
-
- lc = MEM_callocN(sizeof(LayerCollection), "new layer collection");
- BLI_strncpy(lc->name, name, sizeof(lc->name));
- BLI_uniquename(&sl->collections, lc, DATA_("Collection"), '.', offsetof(LayerCollection, name), sizeof(lc->name));
- BLI_addtail(&sl->collections, lc);
-
- return lc;
-}
+ ListBase *lb = (lc_parent ? &lc_parent->collections : &sl->collections);
+ const int act = BLI_findindex(lb, lc);
-bool BKE_scene_remove_collection(SceneLayer *sl, LayerCollection *lc)
-{
- const int act = BLI_findindex(&sl->collections, lc);
if (act == -1) {
return false;
}
- else if ( (sl->collections.first == sl->collections.last) &&
- (sl->collections.first == lc))
- {
- /* ensure 1 layer is kept */
- return false;
- }
- BLI_remlink(&sl->collections, lc);
- free_collection(lc);
- MEM_freeN(lc);
-
- BLI_freelistN(&lc->elements);
- BLI_freelistN(&lc->overrides);
+ BLI_remlink(lb, lc);
+ layer_collection_free(lc);
MEM_freeN(lc);
/* TODO only change active_collection if necessary */
@@ -2210,7 +2221,7 @@ SceneLayer *BKE_scene_add_layer(Scene *sce, const char *name)
BLI_uniquename(&sce->layers, sl, DATA_("Layer"), '.', offsetof(SceneLayer, name), sizeof(sl->name));
/* Initial collection */
- BKE_scene_add_collection(sl, "Collection");
+ BKE_scene_add_collection(sl, NULL, "Collection");
BLI_addtail(&sce->layers, sl);
return sl;
}
@@ -2232,11 +2243,8 @@ bool BKE_scene_remove_layer(Main *bmain, Scene *scene, SceneLayer *sl)
BLI_freelistN(&sl->base);
- for (LayerCollection *lc = sl->collections.first; lc; lc = lc->next) {
- free_collection(lc);
- }
+ layer_collections_free(&sl->collections);
- BLI_freelistN(&sl->collections);
MEM_freeN(sl);
/* TODO only change active_layer if necessary */
@@ -2478,6 +2486,26 @@ void BKE_scene_base_flag_from_objects(struct Scene *scene)
}
}
+void BKE_scene_layer_base_flag_to_objects(struct SceneLayer *sl)
+{
+ Base *base = sl->base.first;
+
+ while (base) {
+ base->object->flag = base->flag;
+ base = base->next;
+ }
+}
+
+void BKE_scene_layer_base_flag_from_objects(struct SceneLayer *sl)
+{
+ Base *base = sl->base.first;
+
+ while (base) {
+ base->flag = base->object->flag;
+ base = base->next;
+ }
+}
+
void BKE_scene_disable_color_management(Scene *scene)
{
ColorManagedDisplaySettings *display_settings = &scene->display_settings;
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 117adb9ba21..9439c00e295 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -632,6 +632,29 @@ static void rna_Scene_object_unlink(Scene *scene, ReportList *reports, Object *o
WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, scene);
}
+static int rna_Scene_layer_object_bases_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
+{
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ Base *base;
+
+ for (base = sl->base.first; base; base = base->next) {
+ if (STREQLEN(base->object->id.name + 2, key, sizeof(base->object->id.name) - 2)) {
+ *r_ptr = rna_pointer_inherit_refine(ptr, &RNA_ObjectBase, base);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static PointerRNA rna_Scene_layer_objects_get(CollectionPropertyIterator *iter)
+{
+ ListBaseIterator *internal = &iter->internal.listbase;
+
+ /* we are actually iterating a Base list, so override get */
+ return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((Base *)internal->link)->object);
+}
+
static void rna_Scene_skgen_etch_template_set(PointerRNA *ptr, PointerRNA value)
{
ToolSettings *ts = (ToolSettings *)ptr->data;
@@ -1335,11 +1358,26 @@ static void rna_FFmpegSettings_codec_settings_update(Main *UNUSED(bmain), Scene
}
#endif
+static PointerRNA rna_Scene_layer_active_object_get(PointerRNA *ptr)
+{
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_Object, sl->basact ? sl->basact->object : NULL);
+}
+
+static void rna_Scene_layer_active_object_set(PointerRNA *ptr, PointerRNA value)
+{
+ SceneLayer *sl = (SceneLayer *)ptr->data;
+ if (value.data)
+ sl->basact = BKE_scene_layer_base_find(sl, (Object *)value.data);
+ else
+ sl->basact = NULL;
+}
+
static LayerCollection *rna_LayerNestedCollection_new(ID *id, LayerCollection *lc, const char *name)
{
Scene *scene = (Scene *)id;
SceneLayer *sl = BKE_scene_layer_from_collection(scene, lc);
- LayerCollection *lc_new = BKE_scene_add_nested_collection(sl, lc, name);
+ LayerCollection *lc_new = BKE_scene_add_collection(sl, lc, name);
DAG_id_tag_update(id, 0);
WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
@@ -1354,7 +1392,7 @@ static void rna_LayerNestedCollection_remove(
SceneLayer *sl = BKE_scene_layer_from_collection(scene, lc_parent);
LayerCollection *lc = lc_ptr->data;
- if (!BKE_scene_remove_nested_collection(sl, lc_parent, lc)) {
+ if (!BKE_scene_remove_collection(sl, lc_parent, lc)) {
BKE_reportf(reports, RPT_ERROR, "Nested collection '%s' could not be removed from collection '%s'",
lc->name, lc_parent->name );
return;
@@ -1404,7 +1442,7 @@ static void rna_Layer_active_collection_set(PointerRNA *ptr, PointerRNA value)
static LayerCollection *rna_LayerCollection_new(ID *id, SceneLayer *sl, const char *name)
{
- LayerCollection *lc = BKE_scene_add_collection(sl, name);
+ LayerCollection *lc = BKE_scene_add_collection(sl, NULL, name);
DAG_id_tag_update(id, 0);
WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
@@ -1418,7 +1456,7 @@ static void rna_LayerCollection_remove(
Scene *scene = (Scene *)id;
LayerCollection *lc = lc_ptr->data;
- if (!BKE_scene_remove_collection(sl, lc)) {
+ if (!BKE_scene_remove_collection(sl, NULL, lc)) {
BKE_reportf(reports, RPT_ERROR, "Layer collection '%s' could not be removed from layer '%s'",
lc->name, sl->name );
return;
@@ -5103,6 +5141,44 @@ static void rna_def_gpu_fx(BlenderRNA *brna)
/* Scene Layers */
+/* layer.bases */
+static void rna_def_layer_bases(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ RNA_def_property_srna(cprop, "LayerBases");
+ srna = RNA_def_struct(brna, "LayerBases", NULL);
+ RNA_def_struct_sdna(srna, "SceneLayer");
+ RNA_def_struct_ui_text(srna, "Layer Bases", "Collection of layer bases");
+
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "ObjectBase");
+ RNA_def_property_pointer_sdna(prop, NULL, "basact");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Active Base", "Active object base in the scene layer");
+ RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, NULL);
+}
+
+/* layer.objects */
+static void rna_def_layer_objects(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ RNA_def_property_srna(cprop, "LayerObjects");
+ srna = RNA_def_struct(brna, "LayerObjects", NULL);
+ RNA_def_struct_sdna(srna, "SceneLayer");
+ RNA_def_struct_ui_text(srna, "Layer Objects", "Collection of layer objects");
+
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_pointer_funcs(prop, "rna_Scene_layer_active_object_get", "rna_Scene_layer_active_object_set", NULL, NULL);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
+ RNA_def_property_ui_text(prop, "Active Object", "Active object for this scene layer");
+ RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, NULL);
+}
+
static void rna_def_layer_nested_collections(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
@@ -5235,7 +5311,22 @@ static void rna_def_scene_layer(BlenderRNA *brna)
/* TODO engine */
/* TODO mode */
- /* TODO baselist (selected objects, ...) */
+
+ /* Bases/Objects */
+ prop = RNA_def_property(srna, "object_bases", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "base", NULL);
+ RNA_def_property_struct_type(prop, "ObjectBase");
+ RNA_def_property_ui_text(prop, "Bases", "");
+ RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, NULL, NULL,
+ "rna_Scene_layer_object_bases_lookup_string", NULL);
+ rna_def_layer_bases(brna, prop);
+
+ prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "base", NULL);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_ui_text(prop, "Objects", "");
+ RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_Scene_layer_objects_get", NULL, NULL, NULL, NULL);
+ rna_def_layer_objects(brna, prop);
/* Nestled Data */
rna_def_layer_collection(brna);