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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2013-04-25 03:09:25 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2013-04-25 03:09:25 +0400
commit2043d801e88c8f56b0153f8acf0cccb554f0fa0c (patch)
treebffa8f8ea9769d092e7e75b9817b9bd4be7e6862
parent11c6abe53b77baefa09737fa8f615f5c734f4b63 (diff)
Fix #34806: rigid body world settings were not copied with a full scene copy.
Now copying a scene will also duplicate groups that consist entirely of objects that are duplicated with the scene. The rigid body world will then also pointers to these new groups.
-rw-r--r--source/blender/blenkernel/BKE_rigidbody.h4
-rw-r--r--source/blender/blenkernel/BKE_scene.h1
-rw-r--r--source/blender/blenkernel/intern/group.c2
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c37
-rw-r--r--source/blender/blenkernel/intern/scene.c10
-rw-r--r--source/blender/editors/include/ED_object.h4
-rw-r--r--source/blender/editors/interface/interface_templates.c3
-rw-r--r--source/blender/editors/object/object_relations.c55
-rw-r--r--source/blender/editors/screen/screen_ops.c4
9 files changed, 99 insertions, 21 deletions
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h
index 75647876419..ef5b8349d60 100644
--- a/source/blender/blenkernel/BKE_rigidbody.h
+++ b/source/blender/blenkernel/BKE_rigidbody.h
@@ -62,6 +62,10 @@ struct RigidBodyWorld *BKE_rigidbody_create_world(struct Scene *scene);
struct RigidBodyOb *BKE_rigidbody_create_object(struct Scene *scene, struct Object *ob, short type);
struct RigidBodyCon *BKE_rigidbody_create_constraint(struct Scene *scene, struct Object *ob, short type);
+/* copy */
+struct RigidBodyWorld *BKE_rigidbody_world_copy(struct RigidBodyWorld *rbw);
+void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw);
+
/* 'validate' (i.e. make new or replace old) Physics-Engine objects */
void BKE_rigidbody_validate_sim_world(struct Scene *scene, struct RigidBodyWorld *rbw, short rebuild);
void BKE_rigidbody_validate_sim_object(struct RigidBodyWorld *rbw, struct Object *ob, short rebuild);
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 9bf0991272a..1171e42cad7 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -84,6 +84,7 @@ void BKE_scene_set_background(struct Main *bmain, struct Scene *sce);
struct Scene *BKE_scene_set_name(struct Main *bmain, const char *name);
struct Scene *BKE_scene_copy(struct Scene *sce, int type);
+void BKE_scene_groups_relink(struct Scene *sce);
void BKE_scene_unlink(struct Main *bmain, struct Scene *sce, struct Scene *newsce);
struct Object *BKE_scene_camera_find(struct Scene *sc);
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index b1d0e8df754..ad0aed4691a 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -148,7 +148,7 @@ Group *BKE_group_copy(Group *group)
{
Group *groupn;
- groupn = MEM_dupallocN(group);
+ groupn = BKE_libblock_copy(&group->id);
BLI_duplicatelist(&groupn->gobject, &group->gobject);
return groupn;
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index ca7bb542598..879ba6651c2 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -58,12 +58,13 @@
#include "BKE_animsys.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_effect.h"
+#include "BKE_global.h"
#include "BKE_group.h"
-#include "BKE_object.h"
+#include "BKE_library.h"
#include "BKE_mesh.h"
+#include "BKE_object.h"
#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
-#include "BKE_global.h"
#include "BKE_utildefines.h"
#include "RNA_access.h"
@@ -724,6 +725,36 @@ RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
return rbw;
}
+RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw)
+{
+ RigidBodyWorld *rbwn = MEM_dupallocN(rbw);
+
+ if (rbw->effector_weights)
+ rbwn->effector_weights = MEM_dupallocN(rbw->effector_weights);
+ if (rbwn->group)
+ id_us_plus(&rbwn->group->id);
+ if (rbwn->constraints)
+ id_us_plus(&rbwn->constraints->id);
+
+ rbwn->pointcache = BKE_ptcache_copy_list(&rbwn->ptcaches, &rbw->ptcaches, FALSE);
+
+ rbwn->objects = NULL;
+ rbwn->physics_world = NULL;
+ rbwn->numbodies = 0;
+
+ return rbwn;
+}
+
+void BKE_rigidbody_world_groups_relink(RigidBodyWorld *rbw)
+{
+ if (rbw->group && rbw->group->id.newid)
+ rbw->group = (Group*)rbw->group->id.newid;
+ if (rbw->constraints && rbw->constraints->id.newid)
+ rbw->constraints = (Group*)rbw->constraints->id.newid;
+ if (rbw->effector_weights->group && rbw->effector_weights->group->id.newid)
+ rbw->effector_weights->group = (Group*)rbw->effector_weights->group->id.newid;
+}
+
/* Add rigid body settings to the specified object */
RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
{
@@ -1332,6 +1363,8 @@ void BKE_rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, short re
void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, short rebuild) {}
void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, short rebuild) {}
struct RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene) { return NULL; }
+struct RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw) { return NULL; }
+void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw) {}
struct RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type) { return NULL; }
struct RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type) { return NULL; }
struct RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene) { return NULL; }
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 29396a7edfe..d140dfa6a2d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -176,7 +176,9 @@ Scene *BKE_scene_copy(Scene *sce, int type)
scen->obedit = NULL;
scen->stats = NULL;
scen->fps_info = NULL;
- scen->rigidbody_world = NULL; /* RB_TODO figure out a way of copying the rigid body world */
+
+ if(sce->rigidbody_world)
+ scen->rigidbody_world = BKE_rigidbody_world_copy(sce->rigidbody_world);
BLI_duplicatelist(&(scen->markers), &(sce->markers));
BLI_duplicatelist(&(scen->transform_spaces), &(sce->transform_spaces));
@@ -295,6 +297,12 @@ Scene *BKE_scene_copy(Scene *sce, int type)
return scen;
}
+void BKE_scene_groups_relink(Scene *sce)
+{
+ if (sce->rigidbody_world)
+ BKE_rigidbody_world_groups_relink(sce->rigidbody_world);
+}
+
/* do not free scene itself */
void BKE_scene_free(Scene *sce)
{
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 108d666c3aa..00b8fc4535d 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -146,8 +146,8 @@ int ED_object_add_generic_get_opts(struct bContext *C, struct wmOperator *op, f
struct Object *ED_object_add_type(struct bContext *C, int type, const float loc[3], const float rot[3],
int enter_editmode, unsigned int layer);
-void ED_object_single_users(struct Main *bmain, struct Scene *scene, int full);
-void ED_object_single_user(struct Scene *scene, struct Object *ob);
+void ED_object_single_users(struct Main *bmain, struct Scene *scene, bool full, bool copy_groups);
+void ED_object_single_user(struct Main *bmain, struct Scene *scene, struct Object *ob);
/* object motion paths */
void ED_objects_clear_paths(struct bContext *C);
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 7d968b30bac..3c0160ce5ba 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -304,8 +304,9 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
/* make copy */
if (do_scene_obj) {
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- ED_object_single_user(scene, (struct Object *)id);
+ ED_object_single_user(bmain, scene, (struct Object *)id);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
}
else {
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 9838c99a81b..2e96ffe8c21 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -44,6 +44,7 @@
#include "DNA_material_types.h"
#include "DNA_meta_types.h"
#include "DNA_particle_types.h"
+#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
#include "DNA_speaker_types.h"
#include "DNA_world_types.h"
@@ -1601,22 +1602,24 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot)
/**************************** Make Single User ********************************/
-static void single_object_users(Scene *scene, View3D *v3d, int flag)
+static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, int flag, bool copy_groups)
{
Base *base;
Object *ob, *obn;
+ 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 [#26002] */
+ for (ob = bmain->object.first; ob; ob = ob->id.next)
+ ob->id.newid = NULL;
+
/* duplicate (must set newid) */
for (base = FIRSTBASE; base; base = base->next) {
ob = base->object;
- /* newid may still have some trash from Outliner tree building,
- * so clear that first to avoid errors [#26002]
- */
- ob->id.newid = NULL;
-
if ((base->flag & flag) == flag) {
if (ob->id.lib == NULL && ob->id.us > 1) {
/* base gets copy of object */
@@ -1626,11 +1629,37 @@ static void single_object_users(Scene *scene, View3D *v3d, int flag)
}
}
}
+
+ /* 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;
+
+ for (go = group->gobject.first; go; go = go->next) {
+ if (!(go->ob && (go->ob->id.newid))) {
+ all_duplicated = false;
+ break;
+ }
+ }
+
+ if (all_duplicated) {
+ groupn = BKE_group_copy(group);
+
+ for (go = groupn->gobject.first; go; go = go->next)
+ go->ob = (Object*)go->ob->id.newid;
+ }
+ }
+ }
+
+ /* group pointers in scene */
+ BKE_scene_groups_relink(scene);
ID_NEW(scene->camera);
if (v3d) ID_NEW(v3d->camera);
- /* object pointers */
+ /* object and group pointers */
for (base = FIRSTBASE; base; base = base->next) {
BKE_object_relink(base->object);
}
@@ -1640,16 +1669,17 @@ static void single_object_users(Scene *scene, View3D *v3d, int flag)
/* not an especially efficient function, only added so the single user
* button can be functional.*/
-void ED_object_single_user(Scene *scene, Object *ob)
+void ED_object_single_user(Main *bmain, Scene *scene, Object *ob)
{
Base *base;
+ bool copy_groups = false;
for (base = FIRSTBASE; base; base = base->next) {
if (base->object == ob) base->flag |= OB_DONE;
else base->flag &= ~OB_DONE;
}
- single_object_users(scene, NULL, OB_DONE);
+ single_object_users(bmain, scene, NULL, OB_DONE, copy_groups);
}
static void new_id_matar(Material **matar, int totcol)
@@ -1907,9 +1937,9 @@ static void single_mat_users_expand(Main *bmain)
}
/* used for copying scenes */
-void ED_object_single_users(Main *bmain, Scene *scene, int full)
+void ED_object_single_users(Main *bmain, Scene *scene, bool full, bool copy_groups)
{
- single_object_users(scene, NULL, 0);
+ single_object_users(bmain, scene, NULL, 0, copy_groups);
if (full) {
single_obdata_users(bmain, scene, 0);
@@ -2078,9 +2108,10 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C); /* ok if this is NULL */
int flag = RNA_enum_get(op->ptr, "type"); /* 0==ALL, SELECTED==selected objecs */
+ bool copy_groups = false;
if (RNA_boolean_get(op->ptr, "object"))
- single_object_users(scene, v3d, flag);
+ single_object_users(bmain, scene, v3d, flag, copy_groups);
if (RNA_boolean_get(op->ptr, "obdata"))
single_obdata_users(bmain, scene, flag);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 86e26bf0681..310783e5199 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -3537,10 +3537,10 @@ static int scene_new_exec(bContext *C, wmOperator *op)
/* these can't be handled in blenkernel curently, so do them here */
if (type == SCE_COPY_LINK_DATA) {
- ED_object_single_users(bmain, newscene, 0);
+ ED_object_single_users(bmain, newscene, false, true);
}
else if (type == SCE_COPY_FULL) {
- ED_object_single_users(bmain, newscene, 1);
+ ED_object_single_users(bmain, newscene, true, true);
}
}