diff options
Diffstat (limited to 'source/blender/editors/object/object_relations.c')
-rw-r--r-- | source/blender/editors/object/object_relations.c | 98 |
1 files changed, 40 insertions, 58 deletions
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index f448e925dd9..d670f4b8425 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1731,6 +1731,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; @@ -1738,18 +1739,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) { @@ -1758,8 +1748,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) { @@ -1789,8 +1778,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; @@ -1802,10 +1789,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; + } } } } @@ -1813,8 +1801,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) { @@ -1837,6 +1825,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) @@ -1853,9 +1843,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]; } } } @@ -1883,45 +1872,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) @@ -1934,17 +1924,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; } } @@ -1958,7 +1947,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); } } } @@ -1977,11 +1966,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); @@ -1992,7 +1981,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; } } @@ -2018,8 +2007,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; @@ -2096,7 +2085,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 */ @@ -2247,7 +2236,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) { @@ -2264,7 +2252,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; @@ -2335,6 +2323,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; @@ -2381,8 +2370,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); @@ -2406,11 +2393,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); |