Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / object / object_relations.c
index a3ff8dc..0bfd4b0 100644 (file)
@@ -1730,6 +1730,7 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot)
 
 /**************************** Make Single User ********************************/
 
+/* Warning, sets ID->newid pointers of objects and groups, but does not clear them. */
 static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const int flag, const bool copy_groups)
 {
        Base *base;
@@ -1737,18 +1738,7 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
        Group *group, *groupn;
        GroupObject *go;
 
-       clear_sca_new_poins();  /* sensor/contr/act */
-
-       /* newid may still have some trash from Outliner tree building, so clear that first to avoid errors, see T26002.
-        * We have to clear whole datablocks, not only Object one may be accessed here, see T49905. */
-       ListBase *lbarray[MAX_LIBARRAY];
-       int a = set_listbasepointers(bmain, lbarray);
-       while (a--) {
-               ListBase *lb = lbarray[a];
-               for (ID *id = lb->first; id; id = id->next) {
-                       id->newid = NULL;
-               }
-       }
+       clear_sca_new_poins();  /* BGE logic */
 
        /* duplicate (must set newid) */
        for (base = FIRSTBASE; base; base = base->next) {
@@ -1757,8 +1747,7 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
                if ((base->flag & flag) == flag) {
                        if (!ID_IS_LINKED_DATABLOCK(ob) && ob->id.us > 1) {
                                /* base gets copy of object */
-                               obn = BKE_object_copy(bmain, ob);
-                               base->object = obn;
+                               base->object = obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
 
                                if (copy_groups) {
                                        if (ob->flag & OB_FROMGROUP) {
@@ -1788,8 +1777,6 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
 
        /* duplicate groups that consist entirely of duplicated objects */
        for (group = bmain->group.first; group; group = group->id.next) {
-               group->id.newid = NULL;
-
                if (copy_groups && group->gobject.first) {
                        bool all_duplicated = true;
 
@@ -1801,10 +1788,11 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
                        }
 
                        if (all_duplicated) {
-                               groupn = BKE_group_copy(bmain, group);
+                               groupn = ID_NEW_SET(group, BKE_group_copy(bmain, group));
 
-                               for (go = groupn->gobject.first; go; go = go->next)
+                               for (go = groupn->gobject.first; go; go = go->next) {
                                        go->ob = (Object *)go->ob->id.newid;
+                               }
                        }
                }
        }
@@ -1812,8 +1800,8 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
        /* group pointers in scene */
        BKE_scene_groups_relink(scene);
 
-       ID_NEW(scene->camera);
-       if (v3d) ID_NEW(v3d->camera);
+       ID_NEW_REMAP(scene->camera);
+       if (v3d) ID_NEW_REMAP(v3d->camera);
 
        /* object and group pointers */
        for (base = FIRSTBASE; base; base = base->next) {
@@ -1836,6 +1824,8 @@ void ED_object_single_user(Main *bmain, Scene *scene, Object *ob)
        }
 
        single_object_users(bmain, scene, NULL, OB_DONE, copy_groups);
+
+       BKE_main_id_clear_newpoins(bmain);
 }
 
 static void new_id_matar(Main *bmain, Material **matar, const int totcol)
@@ -1852,9 +1842,8 @@ static void new_id_matar(Main *bmain, Material **matar, const int totcol)
                                id_us_min(id);
                        }
                        else if (id->us > 1) {
-                               matar[a] = BKE_material_copy(bmain, matar[a]);
+                               matar[a] = ID_NEW_SET(id, BKE_material_copy(bmain, matar[a]));
                                id_us_min(id);
-                               id->newid = (ID *)matar[a];
                        }
                }
        }
@@ -1882,45 +1871,46 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag)
 
                                switch (ob->type) {
                                        case OB_LAMP:
-                                               ob->data = la = BKE_lamp_copy(bmain, ob->data);
+                                               ob->data = la = ID_NEW_SET(ob->data, BKE_lamp_copy(bmain, ob->data));
                                                for (a = 0; a < MAX_MTEX; a++) {
                                                        if (la->mtex[a]) {
-                                                               ID_NEW(la->mtex[a]->object);
+                                                               ID_NEW_REMAP(la->mtex[a]->object);
                                                        }
                                                }
                                                break;
                                        case OB_CAMERA:
-                                               ob->data = BKE_camera_copy(bmain, ob->data);
+                                               ob->data = ID_NEW_SET(ob->data, BKE_camera_copy(bmain, ob->data));
                                                break;
                                        case OB_MESH:
-                                               ob->data = me = BKE_mesh_copy(bmain, ob->data);
-                                               if (me->key)
-                                                       BKE_animdata_copy_id_action((ID *)me->key);
+                                               /* Needed to remap texcomesh below. */
+                                               me = ob->data = ID_NEW_SET(ob->data, BKE_mesh_copy(bmain, ob->data));
+                                               if (me->key)  /* We do not need to set me->key->id.newid here... */
+                                                       BKE_animdata_copy_id_action((ID *)me->key, false);
                                                break;
                                        case OB_MBALL:
-                                               ob->data = BKE_mball_copy(bmain, ob->data);
+                                               ob->data = ID_NEW_SET(ob->data, BKE_mball_copy(bmain, ob->data));
                                                break;
                                        case OB_CURVE:
                                        case OB_SURF:
                                        case OB_FONT:
-                                               ob->data = cu = BKE_curve_copy(bmain, ob->data);
-                                               ID_NEW(cu->bevobj);
-                                               ID_NEW(cu->taperobj);
-                                               if (cu->key)
-                                                       BKE_animdata_copy_id_action((ID *)cu->key);
+                                               ob->data = cu = ID_NEW_SET(ob->data, BKE_curve_copy(bmain, ob->data));
+                                               ID_NEW_REMAP(cu->bevobj);
+                                               ID_NEW_REMAP(cu->taperobj);
+                                               if (cu->key)  /* We do not need to set cu->key->id.newid here... */
+                                                       BKE_animdata_copy_id_action((ID *)cu->key, false);
                                                break;
                                        case OB_LATTICE:
-                                               ob->data = lat = BKE_lattice_copy(bmain, ob->data);
-                                               if (lat->key)
-                                                       BKE_animdata_copy_id_action((ID *)lat->key);
+                                               ob->data = lat = ID_NEW_SET(ob->data, BKE_lattice_copy(bmain, ob->data));
+                                               if (lat->key)  /* We do not need to set lat->key->id.newid here... */
+                                                       BKE_animdata_copy_id_action((ID *)lat->key, false);
                                                break;
                                        case OB_ARMATURE:
                                                DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
-                                               ob->data = BKE_armature_copy(bmain, ob->data);
+                                               ob->data = ID_NEW_SET(ob->data, BKE_armature_copy(bmain, ob->data));
                                                BKE_pose_rebuild(ob, ob->data);
                                                break;
                                        case OB_SPEAKER:
-                                               ob->data = BKE_speaker_copy(bmain, ob->data);
+                                               ob->data = ID_NEW_SET(ob->data, BKE_speaker_copy(bmain, ob->data));
                                                break;
                                        default:
                                                if (G.debug & G_DEBUG)
@@ -1933,17 +1923,16 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag)
                                 * AnimData structure, which is not what we want.
                                 *                                             (sergey)
                                 */
-                               BKE_animdata_copy_id_action((ID *)ob->data);
+                               BKE_animdata_copy_id_action((ID *)ob->data, false);
 
                                id_us_min(id);
-                               id->newid = ob->data;
                        }
                }
        }
 
        me = bmain->mesh.first;
        while (me) {
-               ID_NEW(me->texcomesh);
+               ID_NEW_REMAP(me->texcomesh);
                me = me->id.next;
        }
 }
@@ -1957,7 +1946,7 @@ static void single_object_action_users(Scene *scene, const int flag)
                ob = base->object;
                if (!ID_IS_LINKED_DATABLOCK(ob) && (flag == 0 || (base->flag & SELECT)) ) {
                        DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
-                       BKE_animdata_copy_id_action(&ob->id);
+                       BKE_animdata_copy_id_action(&ob->id, false);
                }
        }
 }
@@ -1976,11 +1965,11 @@ static void single_mat_users(Main *bmain, Scene *scene, const int flag, const bo
                        for (a = 1; a <= ob->totcol; a++) {
                                ma = give_current_material(ob, a);
                                if (ma) {
-                                       /* do not test for LIB_TAG_NEW: this functions guaranteed delivers single_users! */
+                                       /* do not test for LIB_TAG_NEW or use newid: this functions guaranteed delivers single_users! */
 
                                        if (ma->id.us > 1) {
                                                man = BKE_material_copy(bmain, ma);
-                                               BKE_animdata_copy_id_action(&man->id);
+                                               BKE_animdata_copy_id_action(&man->id, false);
 
                                                man->id.us = 0;
                                                assign_material(ob, man, a, BKE_MAT_ASSIGN_USERPREF);
@@ -1991,7 +1980,7 @@ static void single_mat_users(Main *bmain, Scene *scene, const int flag, const bo
                                                                        if (tex->id.us > 1) {
                                                                                id_us_min(&tex->id);
                                                                                tex = BKE_texture_copy(bmain, tex);
-                                                                               BKE_animdata_copy_id_action(&tex->id);
+                                                                               BKE_animdata_copy_id_action(&tex->id, false);
                                                                                man->mtex[b]->tex = tex;
                                                                        }
                                                                }
@@ -2017,8 +2006,8 @@ static void do_single_tex_user(Main *bmain, Tex **from)
                id_us_min(&tex->id);
        }
        else if (tex->id.us > 1) {
-               texn = BKE_texture_copy(bmain, tex);
-               BKE_animdata_copy_id_action(&texn->id);
+               texn = ID_NEW_SET(tex, BKE_texture_copy(bmain, tex));
+               BKE_animdata_copy_id_action(&texn->id, false);
                tex->id.newid = (ID *)texn;
                id_us_min(&tex->id);
                *from = texn;
@@ -2095,7 +2084,7 @@ static void single_mat_users_expand(Main *bmain)
                if (ma->id.tag & LIB_TAG_NEW)
                        for (a = 0; a < MAX_MTEX; a++)
                                if (ma->mtex[a])
-                                       ID_NEW(ma->mtex[a]->object);
+                                       ID_NEW_REMAP(ma->mtex[a]->object);
 }
 
 /* used for copying scenes */
@@ -2245,7 +2234,6 @@ static int make_local_exec(bContext *C, wmOperator *op)
        }
 
        tag_localizable_objects(C, mode);
-       BKE_main_id_clear_newpoins(bmain);
 
        CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
        {
@@ -2262,7 +2250,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
        CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
        {
                if (ob->id.lib == NULL) {
-                       ID_NEW(ob->parent);
+                       ID_NEW_REMAP(ob->parent);
                }
        }
        CTX_DATA_END;
@@ -2330,6 +2318,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
                CTX_DATA_END;
        }
 
+       BKE_main_id_clear_newpoins(bmain);
        WM_event_add_notifier(C, NC_WINDOW, NULL);
 
        return OPERATOR_FINISHED;
@@ -2376,8 +2365,6 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
        const bool copy_groups = false;
        bool update_deps = false;
 
-       BKE_main_id_clear_newpoins(bmain);
-
        if (RNA_boolean_get(op->ptr, "object")) {
                single_object_users(bmain, scene, v3d, flag, copy_groups);
 
@@ -2401,11 +2388,6 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
                single_object_action_users(scene, flag);
        }
 
-       /* TODO(sergey): This should not be needed, however some tool still could rely
-        *               on the fact, that id->newid is kept NULL by default.
-        *               Need to make sure all the guys are learing newid before they're
-        *               using it, not after.
-        */
        BKE_main_id_clear_newpoins(bmain);
 
        WM_event_add_notifier(C, NC_WINDOW, NULL);