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.c107
1 files changed, 63 insertions, 44 deletions
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 6647102acad..02dd3ed2df5 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1350,7 +1350,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(bmain, dob->ob);
+ Object *ob = ID_NEW_SET(dob->ob, BKE_object_copy(bmain, dob->ob));
/* font duplis can have a totcol without material, we get them from parent
* should be implemented better...
@@ -1394,6 +1394,11 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
}
}
+ /* Remap new object to itself, and clear again newid pointer of orig object. */
+ BKE_libblock_relink(&ob->id);
+ set_sca_new_poins_ob(ob);
+ BKE_id_clear_newpoin(&dob->ob->id);
+
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
@@ -1484,8 +1489,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
if (parent_gh)
BLI_ghash_free(parent_gh, NULL, NULL);
- copy_object_set_idnew(C);
-
free_object_duplilist(lb);
base->object->transflag &= ~OB_DUPLI;
@@ -1960,8 +1963,12 @@ void OBJECT_OT_convert(wmOperatorType *ot)
/* used below, assumes id.new is correct */
/* leaves selection of base/object unaltered */
+/* Does set ID->newid pointers. */
static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base, int dupflag)
{
+#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++; }
+
Base *basen = NULL;
Material ***matarar;
Object *ob, *obn;
@@ -1973,7 +1980,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
; /* nothing? */
}
else {
- obn = BKE_object_copy(bmain, ob);
+ obn = ID_NEW_SET(ob, 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");
@@ -1995,20 +2002,21 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
/* duplicates using userflags */
if (dupflag & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(&obn->id);
+ BKE_animdata_copy_id_action(&obn->id, true);
}
if (dupflag & USER_DUP_MAT) {
for (a = 0; a < obn->totcol; a++) {
id = (ID *)obn->mat[a];
if (id) {
- ID_NEW_US(obn->mat[a])
- else
- obn->mat[a] = BKE_material_copy(bmain, obn->mat[a]);
+ 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(&obn->mat[a]->id);
+ BKE_animdata_copy_id_action(&obn->mat[a]->id, true);
}
}
}
@@ -2018,12 +2026,13 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
for (psys = obn->particlesystem.first; psys; psys = psys->next) {
id = (ID *) psys->part;
if (id) {
- ID_NEW_US(psys->part)
- else
- psys->part = BKE_particlesettings_copy(bmain, psys->part);
+ 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(&psys->part->id);
+ BKE_animdata_copy_id_action(&psys->part->id, true);
}
id_us_min(id);
@@ -2037,9 +2046,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
switch (obn->type) {
case OB_MESH:
if (dupflag & USER_DUP_MESH) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_mesh_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_mesh_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2047,9 +2056,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_CURVE:
if (dupflag & USER_DUP_CURVE) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_curve_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2057,9 +2066,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_SURF:
if (dupflag & USER_DUP_SURF) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_curve_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2067,9 +2076,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_FONT:
if (dupflag & USER_DUP_FONT) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_curve_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2077,9 +2086,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_MBALL:
if (dupflag & USER_DUP_MBALL) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_mball_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_mball_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2087,9 +2096,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_LAMP:
if (dupflag & USER_DUP_LAMP) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_lamp_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_lamp_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2100,9 +2109,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (obn->pose)
BKE_pose_tag_recalc(bmain, obn->pose);
if (dupflag & USER_DUP_ARM) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_armature_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_armature_copy(bmain, obn->data));
BKE_pose_rebuild(obn, obn->data);
didit = 1;
}
@@ -2111,9 +2120,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_LATTICE:
if (dupflag != 0) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_lattice_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_lattice_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2121,9 +2130,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_CAMERA:
if (dupflag != 0) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_camera_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_camera_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2131,9 +2140,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_SPEAKER:
if (dupflag != 0) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_speaker_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_speaker_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2148,12 +2157,15 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (dupflag & USER_DUP_ACT) {
bActuator *act;
- BKE_animdata_copy_id_action((ID *)obn->data);
+ BKE_animdata_copy_id_action((ID *)obn->data, true);
if (key) {
- BKE_animdata_copy_id_action((ID *)key);
+ BKE_animdata_copy_id_action((ID *)key, true);
}
/* Update the duplicated action in the action actuators */
+ /* XXX TODO this code is all wrong! actact->act is user-refcounted (see readfile.c),
+ * and what about other ID pointers of other BGE logic bricks,
+ * and since this is object-level, why is it only ran if obdata was duplicated??? -mont29 */
for (act = obn->actuators.first; act; act = act->next) {
if (act->type == ACT_ACTION) {
bActionActuator *actact = (bActionActuator *) act->data;
@@ -2170,9 +2182,10 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
for (a = 0; a < obn->totcol; a++) {
id = (ID *)(*matarar)[a];
if (id) {
- ID_NEW_US((*matarar)[a])
- else
- (*matarar)[a] = BKE_material_copy(bmain, (*matarar)[a]);
+ ID_NEW_REMAP_US((*matarar)[a])
+ else {
+ (*matarar)[a] = ID_NEW_SET((*matarar)[a], BKE_material_copy(bmain, (*matarar)[a]));
+ }
id_us_min(id);
}
}
@@ -2181,6 +2194,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
}
}
return basen;
+
+#undef ID_NEW_REMAP_US
+#undef ID_NEW_REMAP_US2
}
/* single object duplicate, if dupflag==0, fully linked, else it uses the flags given */
@@ -2193,8 +2209,7 @@ Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag
Base *basen;
Object *ob;
- BKE_main_id_clear_newpoins(bmain);
- clear_sca_new_poins(); /* sensor/contr/act */
+ clear_sca_new_poins(); /* BGE logic */
basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
if (basen == NULL) {
@@ -2213,6 +2228,8 @@ Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag
ED_render_id_flush_update(bmain, ob->data);
}
+ BKE_main_id_clear_newpoins(bmain);
+
return basen;
}
@@ -2224,8 +2241,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
const bool linked = RNA_boolean_get(op->ptr, "linked");
int dupflag = (linked) ? 0 : U.dupflag;
- BKE_main_id_clear_newpoins(bmain);
- clear_sca_new_poins(); /* sensor/contr/act */
+ clear_sca_new_poins(); /* BGE logic */
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
@@ -2251,6 +2267,8 @@ static int duplicate_exec(bContext *C, wmOperator *op)
copy_object_set_idnew(C);
+ BKE_main_id_clear_newpoins(bmain);
+
DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
@@ -2309,8 +2327,7 @@ static int add_named_exec(bContext *C, wmOperator *op)
base->flag = ob->flag;
/* prepare dupli */
- BKE_main_id_clear_newpoins(bmain);
- clear_sca_new_poins(); /* sensor/contr/act */
+ clear_sca_new_poins(); /* BGE logic */
basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
@@ -2336,6 +2353,8 @@ static int add_named_exec(bContext *C, wmOperator *op)
copy_object_set_idnew(C);
+ BKE_main_id_clear_newpoins(bmain);
+
DAG_relations_tag_update(bmain);
MEM_freeN(base);