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:
Diffstat (limited to 'source/blender/editors/object/object_add.c')
-rw-r--r--source/blender/editors/object/object_add.c88
1 files changed, 58 insertions, 30 deletions
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 9a38a292656..15c1a195db5 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -73,6 +73,7 @@
#include "BKE_lamp.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
+#include "BKE_library_query.h"
#include "BKE_key.h"
#include "BKE_main.h"
#include "BKE_material.h"
@@ -1107,11 +1108,18 @@ static void object_delete_check_glsl_update(Object *ob)
/* note: now unlinks constraints as well */
void ED_base_object_free_and_unlink(Main *bmain, Scene *scene, Base *base)
{
- DAG_id_type_tag(bmain, ID_OB);
+ if (BKE_library_ID_is_indirectly_used(bmain, base->object) && ID_REAL_USERS(base->object) <= 1) {
+ /* We cannot delete indirectly used object... */
+ printf("WARNING, undeletable object '%s', should have been catched before reaching this function!",
+ base->object->id.name + 2);
+ return;
+ }
+
BKE_scene_base_unlink(scene, base);
object_delete_check_glsl_update(base->object);
BKE_libblock_free_us(bmain, base->object);
MEM_freeN(base);
+ DAG_id_type_tag(bmain, ID_OB);
}
static int object_delete_exec(bContext *C, wmOperator *op)
@@ -1128,6 +1136,19 @@ static int object_delete_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
+ const bool is_indirectly_used = BKE_library_ID_is_indirectly_used(bmain, base->object);
+ if (base->object->id.tag & LIB_TAG_INDIRECT) {
+ /* Can this case ever happen? */
+ BKE_reportf(op->reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", base->object->id.name + 2);
+ continue;
+ }
+ else if (is_indirectly_used && ID_REAL_USERS(base->object) <= 1) {
+ BKE_reportf(op->reports, RPT_WARNING,
+ "Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
+ base->object->id.name + 2, scene->id.name + 2);
+ continue;
+ }
+
/* deselect object -- it could be used in other scenes */
base->object->flag &= ~SELECT;
@@ -1140,9 +1161,15 @@ static int object_delete_exec(bContext *C, wmOperator *op)
Base *base_other;
for (scene_iter = bmain->scene.first; scene_iter; scene_iter = scene_iter->id.next) {
- if (scene_iter != scene && !(scene_iter->id.lib)) {
+ if (scene_iter != scene && !ID_IS_LINKED_DATABLOCK(scene_iter)) {
base_other = BKE_scene_base_find(scene_iter, base->object);
if (base_other) {
+ if (is_indirectly_used && ID_REAL_USERS(base->object) <= 1) {
+ BKE_reportf(op->reports, RPT_WARNING,
+ "Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
+ base->object->id.name + 2, scene_iter->id.name + 2);
+ break;
+ }
ED_base_object_free_and_unlink(bmain, scene_iter, base_other);
}
}
@@ -1271,7 +1298,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
for (dob = lb->first; dob; dob = dob->next) {
Base *basen;
- Object *ob = BKE_object_copy(dob->ob);
+ Object *ob = BKE_object_copy(bmain, dob->ob);
/* font duplis can have a totcol without material, we get them from parent
* should be implemented better...
@@ -1487,11 +1514,12 @@ static int convert_poll(bContext *C)
Object *obact = CTX_data_active_object(C);
Scene *scene = CTX_data_scene(C);
- return (!scene->id.lib && obact && scene->obedit != obact && (obact->flag & SELECT) && !(obact->id.lib));
+ return (!ID_IS_LINKED_DATABLOCK(scene) && obact && scene->obedit != obact &&
+ (obact->flag & SELECT) && !ID_IS_LINKED_DATABLOCK(obact));
}
/* Helper for convert_exec */
-static Base *duplibase_for_convert(Scene *scene, Base *base, Object *ob)
+static Base *duplibase_for_convert(Main *bmain, Scene *scene, Base *base, Object *ob)
{
Object *obn;
Base *basen;
@@ -1500,7 +1528,7 @@ static Base *duplibase_for_convert(Scene *scene, Base *base, Object *ob)
ob = base->object;
}
- obn = BKE_object_copy(ob);
+ obn = BKE_object_copy(bmain, ob);
DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
basen = MEM_mallocN(sizeof(Base), "duplibase");
@@ -1580,7 +1608,7 @@ static int convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
if (keep_original) {
- basen = duplibase_for_convert(scene, base, NULL);
+ basen = duplibase_for_convert(bmain, scene, base, NULL);
newob = basen->object;
/* decrement original mesh's usage count */
@@ -1588,7 +1616,7 @@ static int convert_exec(bContext *C, wmOperator *op)
id_us_min(&me->id);
/* make a new copy of the mesh */
- newob->data = BKE_mesh_copy(me);
+ newob->data = BKE_mesh_copy(bmain, me);
}
else {
newob = ob;
@@ -1605,7 +1633,7 @@ static int convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
if (keep_original) {
- basen = duplibase_for_convert(scene, base, NULL);
+ basen = duplibase_for_convert(bmain, scene, base, NULL);
newob = basen->object;
/* decrement original mesh's usage count */
@@ -1613,7 +1641,7 @@ static int convert_exec(bContext *C, wmOperator *op)
id_us_min(&me->id);
/* make a new copy of the mesh */
- newob->data = BKE_mesh_copy(me);
+ newob->data = BKE_mesh_copy(bmain, me);
}
else {
newob = ob;
@@ -1637,14 +1665,14 @@ static int convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
if (keep_original) {
- basen = duplibase_for_convert(scene, base, NULL);
+ basen = duplibase_for_convert(bmain, scene, base, NULL);
newob = basen->object;
/* decrement original curve's usage count */
id_us_min(&((Curve *)newob->data)->id);
/* make a new copy of the curve */
- newob->data = BKE_curve_copy(ob->data);
+ newob->data = BKE_curve_copy(bmain, ob->data);
}
else {
newob = ob;
@@ -1708,14 +1736,14 @@ static int convert_exec(bContext *C, wmOperator *op)
if (target == OB_MESH) {
if (keep_original) {
- basen = duplibase_for_convert(scene, base, NULL);
+ basen = duplibase_for_convert(bmain, scene, base, NULL);
newob = basen->object;
/* decrement original curve's usage count */
id_us_min(&((Curve *)newob->data)->id);
/* make a new copy of the curve */
- newob->data = BKE_curve_copy(ob->data);
+ newob->data = BKE_curve_copy(bmain, ob->data);
}
else {
newob = ob;
@@ -1743,7 +1771,7 @@ static int convert_exec(bContext *C, wmOperator *op)
if (!(baseob->flag & OB_DONE)) {
baseob->flag |= OB_DONE;
- basen = duplibase_for_convert(scene, base, baseob);
+ basen = duplibase_for_convert(bmain, scene, base, baseob);
newob = basen->object;
mb = newob->data;
@@ -1881,7 +1909,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
; /* nothing? */
}
else {
- obn = BKE_object_copy(ob);
+ obn = BKE_object_copy(bmain, ob);
DAG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
basen = MEM_mallocN(sizeof(Base), "duplibase");
@@ -1912,7 +1940,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (id) {
ID_NEW_US(obn->mat[a])
else
- obn->mat[a] = BKE_material_copy(obn->mat[a]);
+ obn->mat[a] = BKE_material_copy(bmain, obn->mat[a]);
id_us_min(id);
if (dupflag & USER_DUP_ACT) {
@@ -1930,7 +1958,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (dupflag & USER_DUP_MESH) {
ID_NEW_US2(obn->data)
else {
- obn->data = BKE_mesh_copy(obn->data);
+ obn->data = BKE_mesh_copy(bmain, obn->data);
didit = 1;
}
id_us_min(id);
@@ -1940,7 +1968,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (dupflag & USER_DUP_CURVE) {
ID_NEW_US2(obn->data)
else {
- obn->data = BKE_curve_copy(obn->data);
+ obn->data = BKE_curve_copy(bmain, obn->data);
didit = 1;
}
id_us_min(id);
@@ -1950,7 +1978,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (dupflag & USER_DUP_SURF) {
ID_NEW_US2(obn->data)
else {
- obn->data = BKE_curve_copy(obn->data);
+ obn->data = BKE_curve_copy(bmain, obn->data);
didit = 1;
}
id_us_min(id);
@@ -1960,7 +1988,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (dupflag & USER_DUP_FONT) {
ID_NEW_US2(obn->data)
else {
- obn->data = BKE_curve_copy(obn->data);
+ obn->data = BKE_curve_copy(bmain, obn->data);
didit = 1;
}
id_us_min(id);
@@ -1970,7 +1998,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (dupflag & USER_DUP_MBALL) {
ID_NEW_US2(obn->data)
else {
- obn->data = BKE_mball_copy(obn->data);
+ obn->data = BKE_mball_copy(bmain, obn->data);
didit = 1;
}
id_us_min(id);
@@ -1980,7 +2008,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (dupflag & USER_DUP_LAMP) {
ID_NEW_US2(obn->data)
else {
- obn->data = BKE_lamp_copy(obn->data);
+ obn->data = BKE_lamp_copy(bmain, obn->data);
didit = 1;
}
id_us_min(id);
@@ -1993,7 +2021,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (dupflag & USER_DUP_ARM) {
ID_NEW_US2(obn->data)
else {
- obn->data = BKE_armature_copy(obn->data);
+ obn->data = BKE_armature_copy(bmain, obn->data);
BKE_pose_rebuild(obn, obn->data);
didit = 1;
}
@@ -2004,7 +2032,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (dupflag != 0) {
ID_NEW_US2(obn->data)
else {
- obn->data = BKE_lattice_copy(obn->data);
+ obn->data = BKE_lattice_copy(bmain, obn->data);
didit = 1;
}
id_us_min(id);
@@ -2014,7 +2042,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (dupflag != 0) {
ID_NEW_US2(obn->data)
else {
- obn->data = BKE_camera_copy(obn->data);
+ obn->data = BKE_camera_copy(bmain, obn->data);
didit = 1;
}
id_us_min(id);
@@ -2024,7 +2052,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (dupflag != 0) {
ID_NEW_US2(obn->data)
else {
- obn->data = BKE_speaker_copy(obn->data);
+ obn->data = BKE_speaker_copy(bmain, obn->data);
didit = 1;
}
id_us_min(id);
@@ -2063,7 +2091,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (id) {
ID_NEW_US((*matarar)[a])
else
- (*matarar)[a] = BKE_material_copy((*matarar)[a]);
+ (*matarar)[a] = BKE_material_copy(bmain, (*matarar)[a]);
id_us_min(id);
}
}
@@ -2260,7 +2288,7 @@ static int join_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
- if (!ob || ob->id.lib) return 0;
+ if (!ob || ID_IS_LINKED_DATABLOCK(ob)) return 0;
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE))
return ED_operator_screenactive(C);
@@ -2313,7 +2341,7 @@ static int join_shapes_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
- if (!ob || ob->id.lib) return 0;
+ if (!ob || ID_IS_LINKED_DATABLOCK(ob)) return 0;
/* only meshes supported at the moment */
if (ob->type == OB_MESH)