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/blenkernel/intern/object.c')
-rw-r--r--source/blender/blenkernel/intern/object.c234
1 files changed, 234 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 3c57a5f7086..c4d80fdd5e2 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1427,6 +1427,240 @@ Object *BKE_object_copy(Main *bmain, const Object *ob)
return ob_copy;
}
+Object *BKE_object_duplicate(Main *bmain, const Object *ob, const int dupflag)
+{
+ Material ***matarar;
+ ID *id;
+ int a, didit;
+ Object *obn = BKE_object_copy(bmain, ob);
+
+ /* 0 == full linked. */
+ if (dupflag == 0) {
+ return obn;
+ }
+
+#define ID_NEW_REMAP_US(a) if ( (a)->id.newid) { (a) = (void *)(a)->id.newid; (a)->id.us++; }
+#define ID_NEW_REMAP_US2(a) if (((ID *)a)->newid) { (a) = ((ID *)a)->newid; ((ID *)a)->us++; }
+
+ /* duplicates using userflags */
+ if (dupflag & USER_DUP_ACT) {
+ BKE_animdata_copy_id_action(bmain, &obn->id, true);
+ }
+
+ if (dupflag & USER_DUP_MAT) {
+ for (a = 0; a < obn->totcol; a++) {
+ id = (ID *)obn->mat[a];
+ if (id) {
+ ID_NEW_REMAP_US(obn->mat[a])
+ else {
+ obn->mat[a] = ID_NEW_SET(obn->mat[a], BKE_material_copy(bmain, obn->mat[a]));
+ }
+ id_us_min(id);
+
+ if (dupflag & USER_DUP_ACT) {
+ BKE_animdata_copy_id_action(bmain, &obn->mat[a]->id, true);
+ }
+ }
+ }
+ }
+ if (dupflag & USER_DUP_PSYS) {
+ ParticleSystem *psys;
+ for (psys = obn->particlesystem.first; psys; psys = psys->next) {
+ id = (ID *) psys->part;
+ if (id) {
+ ID_NEW_REMAP_US(psys->part)
+ else {
+ psys->part = ID_NEW_SET(psys->part, BKE_particlesettings_copy(bmain, psys->part));
+ }
+
+ if (dupflag & USER_DUP_ACT) {
+ BKE_animdata_copy_id_action(bmain, &psys->part->id, true);
+ }
+
+ id_us_min(id);
+ }
+ }
+ }
+
+ id = obn->data;
+ didit = 0;
+
+ switch (obn->type) {
+ case OB_MESH:
+ if (dupflag & USER_DUP_MESH) {
+ ID_NEW_REMAP_US2(obn->data)
+ else {
+ obn->data = ID_NEW_SET(obn->data, BKE_mesh_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
+ }
+ break;
+ case OB_CURVE:
+ if (dupflag & USER_DUP_CURVE) {
+ ID_NEW_REMAP_US2(obn->data)
+ else {
+ obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
+ }
+ break;
+ case OB_SURF:
+ if (dupflag & USER_DUP_SURF) {
+ ID_NEW_REMAP_US2(obn->data)
+ else {
+ obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
+ }
+ break;
+ case OB_FONT:
+ if (dupflag & USER_DUP_FONT) {
+ ID_NEW_REMAP_US2(obn->data)
+ else {
+ obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
+ }
+ break;
+ case OB_MBALL:
+ if (dupflag & USER_DUP_MBALL) {
+ ID_NEW_REMAP_US2(obn->data)
+ else {
+ obn->data = ID_NEW_SET(obn->data, BKE_mball_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
+ }
+ break;
+ case OB_LAMP:
+ if (dupflag & USER_DUP_LAMP) {
+ ID_NEW_REMAP_US2(obn->data)
+ else {
+ obn->data = ID_NEW_SET(obn->data, BKE_light_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
+ }
+ break;
+ case OB_ARMATURE:
+ DEG_id_tag_update(&obn->id, ID_RECALC_GEOMETRY);
+ if (obn->pose)
+ BKE_pose_tag_recalc(bmain, obn->pose);
+ if (dupflag & USER_DUP_ARM) {
+ ID_NEW_REMAP_US2(obn->data)
+ else {
+ obn->data = ID_NEW_SET(obn->data, BKE_armature_copy(bmain, obn->data));
+ BKE_pose_rebuild(bmain, obn, obn->data, true);
+ didit = 1;
+ }
+ id_us_min(id);
+ }
+ break;
+ case OB_LATTICE:
+ if (dupflag != 0) {
+ ID_NEW_REMAP_US2(obn->data)
+ else {
+ obn->data = ID_NEW_SET(obn->data, BKE_lattice_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
+ }
+ break;
+ case OB_CAMERA:
+ if (dupflag != 0) {
+ ID_NEW_REMAP_US2(obn->data)
+ else {
+ obn->data = ID_NEW_SET(obn->data, BKE_camera_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
+ }
+ break;
+ case OB_LIGHTPROBE:
+ if (dupflag != 0) {
+ ID_NEW_REMAP_US2(obn->data)
+ else {
+ obn->data = ID_NEW_SET(obn->data, BKE_lightprobe_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
+ }
+ break;
+ case OB_SPEAKER:
+ if (dupflag != 0) {
+ ID_NEW_REMAP_US2(obn->data)
+ else {
+ obn->data = ID_NEW_SET(obn->data, BKE_speaker_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
+ }
+ break;
+ case OB_GPENCIL:
+ if (dupflag != 0) {
+ ID_NEW_REMAP_US2(obn->data)
+ else {
+ obn->data = ID_NEW_SET(obn->data, BKE_gpencil_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
+ }
+ break;
+ }
+
+ /* Check if obdata is copied. */
+ if (didit) {
+ Key *key = BKE_key_from_object(obn);
+
+ Key *oldkey = BKE_key_from_object(ob);
+ if (oldkey != NULL) {
+ ID_NEW_SET(oldkey, key);
+ }
+
+ if (dupflag & USER_DUP_ACT) {
+ BKE_animdata_copy_id_action(bmain, (ID *)obn->data, true);
+ if (key) {
+ BKE_animdata_copy_id_action(bmain, (ID *)key, true);
+ }
+ }
+
+ if (dupflag & USER_DUP_MAT) {
+ matarar = give_matarar(obn);
+ if (matarar) {
+ for (a = 0; a < obn->totcol; a++) {
+ id = (ID *)(*matarar)[a];
+ if (id) {
+ ID_NEW_REMAP_US((*matarar)[a])
+ else {
+ (*matarar)[a] = ID_NEW_SET((*matarar)[a], BKE_material_copy(bmain, (*matarar)[a]));
+ }
+ id_us_min(id);
+ }
+ }
+ }
+ }
+ }
+
+#undef ID_NEW_REMAP_US
+#undef ID_NEW_REMAP_US2
+
+ BKE_libblock_relink_to_newid(&obn->id);
+
+ /* DAG_relations_tag_update(bmain); */ /* caller must do */
+
+ if (ob->data != NULL) {
+ DEG_id_tag_update_ex(bmain, (ID *)obn->data, ID_RECALC_EDITORS);
+ }
+
+ /* BKE_main_id_clear_newpoins(bmain); */ /* Called must do. */
+
+ return obn;
+}
+
void BKE_object_make_local_ex(Main *bmain, Object *ob, const bool lib_local, const bool clear_proxy)
{
bool is_local = false, is_lib = false;