[Bf-blender-cvs] [a77feabb514] master: Collection duplication from Outliner: add a 'duplicate hierarchy' operation.

Bastien Montagne noreply at git.blender.org
Wed Mar 6 15:40:04 CET 2019


Commit: a77feabb51470b9cfb71be7f0ea7e774d6591799
Author: Bastien Montagne
Date:   Wed Mar 6 15:09:16 2019 +0100
Branches: master
https://developer.blender.org/rBa77feabb51470b9cfb71be7f0ea7e774d6591799

Collection duplication from Outliner: add a 'duplicate hierarchy' operation.

Point is, you may want to duplicate your set of collections, but not
duplicate all their objects.

Some notes:
* Am rather skeptical about the practice of using operator name to
define behavior of some common exec code. Imho, that should be a single
operator with an enum to refine its behavior (@cambpellbarton may also
have an opinion here?). Left it as-is for now, because this seems to be
used by other operators too in that code. :/
* @dfelinto, @pablovazquez, @billreynish am not so happy with current
names, but cannot find really good short ones either... Also, shouldn't
we move those into a dedicated `Duplicate` sub-menu?

===================================================================

M	release/scripts/startup/bl_ui/space_outliner.py
M	source/blender/blenkernel/BKE_collection.h
M	source/blender/blenkernel/intern/collection.c
M	source/blender/editors/space_outliner/outliner_collections.c
M	source/blender/editors/space_outliner/outliner_intern.h
M	source/blender/editors/space_outliner/outliner_ops.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py
index 6d90c24ff99..59b6757c308 100644
--- a/release/scripts/startup/bl_ui/space_outliner.py
+++ b/release/scripts/startup/bl_ui/space_outliner.py
@@ -192,8 +192,9 @@ class OUTLINER_MT_collection(Menu):
         space = context.space_data
 
         layout.operator("outliner.collection_new", text="New").nested = True
-        layout.operator("outliner.collection_duplicate", text="Duplicate Collection")
+        layout.operator("outliner.collection_duplicate_hierarchy", text="Duplicate Hierarchy")
         layout.operator("outliner.collection_duplicate_linked", text="Duplicate Linked")
+        layout.operator("outliner.collection_duplicate", text="Duplicate Full")
 
         layout.separator()
 
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index 3ddc28dafdb..0390078fc7f 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -57,7 +57,9 @@ struct Collection *BKE_collection_copy(struct Main *bmain, struct Collection *pa
 void               BKE_collection_copy_data(struct Main *bmain, struct Collection *collection_dst, const struct Collection *collection_src, const int flag);
 void               BKE_collection_make_local(struct Main *bmain, struct Collection *collection, const bool lib_local);
 
-struct Collection *BKE_collection_duplicate(struct Main *bmain, struct Collection *parent, struct Collection *collection, const bool do_hierarchy, const bool do_deep_copy);
+struct Collection *BKE_collection_duplicate(
+        struct Main *bmain, struct Collection *parent, struct Collection *collection,
+        const bool do_hierarchy, const bool do_objects, const bool do_obdata);
 struct Collection *BKE_collection_copy_master(struct Main *bmain, struct Collection *collection, const int flag);
 
 /* Master Collection for Scene */
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 3776c6bd8ca..beefe4b5ac2 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -211,11 +211,12 @@ void BKE_collection_copy_data(
 }
 
 static Collection *collection_duplicate_recursive(
-        Main *bmain, Collection *parent, Collection *collection_old, const bool do_hierarchy, const bool do_deep_copy)
+        Main *bmain, Collection *parent, Collection *collection_old,
+        const bool do_hierarchy, const bool do_objects, const bool do_obdata)
 {
 	Collection *collection_new;
 	bool do_full_process = false;
-	const int object_dupflag = (do_deep_copy) ? U.dupflag : 0;
+	const int object_dupflag = (do_obdata) ? U.dupflag : 0;
 
 	if (!do_hierarchy || collection_old->id.newid == NULL) {
 		BKE_id_copy(bmain, &collection_old->id, (ID **)&collection_new);
@@ -250,19 +251,21 @@ static Collection *collection_duplicate_recursive(
 		return collection_new;
 	}
 
-	/* We can loop on collection_old's objects, that list is currently identical the collection_new' objects,
-	 * and won't be changed here. */
-	for (CollectionObject *cob = collection_old->gobject.first; cob; cob = cob->next) {
-		Object *ob_old = cob->ob;
-		Object *ob_new = (Object *)ob_old->id.newid;
+	if (do_objects) {
+		/* We can loop on collection_old's objects, that list is currently identical the collection_new' objects,
+		 * and won't be changed here. */
+		for (CollectionObject *cob = collection_old->gobject.first; cob; cob = cob->next) {
+			Object *ob_old = cob->ob;
+			Object *ob_new = (Object *)ob_old->id.newid;
 
-		if (ob_new == NULL) {
-			ob_new = BKE_object_duplicate(bmain, ob_old, object_dupflag);
-			ID_NEW_SET(ob_old, ob_new);
-		}
+			if (ob_new == NULL) {
+				ob_new = BKE_object_duplicate(bmain, ob_old, object_dupflag);
+				ID_NEW_SET(ob_old, ob_new);
+			}
 
-		collection_object_add(bmain, collection_new, ob_new, 0, true);
-		collection_object_remove(bmain, collection_new, ob_old, false);
+			collection_object_add(bmain, collection_new, ob_new, 0, true);
+			collection_object_remove(bmain, collection_new, ob_old, false);
+		}
 	}
 
 	/* We can loop on collection_old's children, that list is currently identical the collection_new' children,
@@ -270,7 +273,7 @@ static Collection *collection_duplicate_recursive(
 	for (CollectionChild *child = collection_old->children.first; child; child = child->next) {
 		Collection *child_collection_old = child->collection;
 
-		collection_duplicate_recursive(bmain, collection_new, child_collection_old, do_hierarchy, do_deep_copy);
+		collection_duplicate_recursive(bmain, collection_new, child_collection_old, do_hierarchy, do_objects, do_obdata);
 		collection_child_remove(collection_new, child_collection_old);
 	}
 
@@ -285,7 +288,7 @@ static Collection *collection_duplicate_recursive(
  */
 Collection *BKE_collection_copy(Main *bmain, Collection *parent, Collection *collection)
 {
-	return BKE_collection_duplicate(bmain, parent, collection, false, false);
+	return BKE_collection_duplicate(bmain, parent, collection, false, false, false);
 }
 
 /**
@@ -296,11 +299,12 @@ Collection *BKE_collection_copy(Main *bmain, Collection *parent, Collection *col
  * \warning If any 'deep copy' behavior is enabled, this functions will clear all \a bmain id.idnew pointers.
  *
  * \param do_hierarchy If true, it will recursively make shallow copies of children collections and objects.
- * \param do_deep_copy If true, it will also make deep duplicates of objects, using behavior defined in user settings
- *                     (U.dupflag). This one does nothing if \a do_hierarchy is not set.
+ * \param do_obdata If true, it will also make deep duplicates of objects, using behavior defined in user settings
+ *                  (U.dupflag). This one does nothing if \a do_hierarchy is not set.
  */
 Collection *BKE_collection_duplicate(
-        Main *bmain, Collection *parent, Collection *collection, const bool do_hierarchy, const bool do_deep_copy)
+        Main *bmain, Collection *parent, Collection *collection,
+        const bool do_hierarchy, const bool do_objects, const bool do_obdata)
 {
 	/* It's not allowed to copy the master collection. */
 	if (collection->flag & COLLECTION_IS_MASTER) {
@@ -314,7 +318,7 @@ Collection *BKE_collection_duplicate(
 	}
 
 	Collection *collection_new = collection_duplicate_recursive(
-	                                 bmain, parent, collection, do_hierarchy, do_deep_copy);
+	                                 bmain, parent, collection, do_hierarchy, do_objects, do_obdata);
 
 	/* This code will follows into all ID links using an ID tagged with LIB_TAG_NEW.*/
 	BKE_libblock_relink_to_newid(&collection_new->id);
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index 750c78d76b9..7403525c293 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -448,7 +448,8 @@ static int collection_duplicate_exec(bContext *C, wmOperator *op)
 	Main *bmain = CTX_data_main(C);
 	SpaceOutliner *soops = CTX_wm_space_outliner(C);
 	TreeElement *te = outliner_active_collection(C);
-	bool linked = strstr(op->idname, "linked") != NULL;
+	const bool hierarchy = strstr(op->idname, "hierarchy") != NULL;
+	const bool linked = strstr(op->idname, "linked") != NULL;
 
 	/* Can happen when calling from a key binding. */
 	if (te == NULL) {
@@ -468,7 +469,7 @@ static int collection_duplicate_exec(bContext *C, wmOperator *op)
 		case SO_SCENES:
 		case SO_VIEW_LAYER:
 		case SO_LIBRARIES:
-			BKE_collection_duplicate(bmain, parent, collection, true, !linked);
+			BKE_collection_duplicate(bmain, parent, collection, true, !hierarchy, !linked);
 			break;
 	}
 
@@ -478,12 +479,12 @@ static int collection_duplicate_exec(bContext *C, wmOperator *op)
 	return OPERATOR_FINISHED;
 }
 
-void OUTLINER_OT_collection_duplicate(wmOperatorType *ot)
+void OUTLINER_OT_collection_duplicate_hierarchy(wmOperatorType *ot)
 {
 	/* identifiers */
-	ot->name = "Duplicate Collection";
-	ot->idname = "OUTLINER_OT_collection_duplicate";
-	ot->description = "Duplicate all objects and collections and make them single user";
+	ot->name = "Duplicate Collection Hierarchy";
+	ot->idname = "OUTLINER_OT_collection_duplicate_hierarchy";
+	ot->description = "Recursively duplicate the collection and all its children, with linked objects";
 
 	/* api callbacks */
 	ot->exec = collection_duplicate_exec;
@@ -498,7 +499,22 @@ void OUTLINER_OT_collection_duplicate_linked(wmOperatorType *ot)
 	/* identifiers */
 	ot->name = "Duplicate Linked Collection";
 	ot->idname = "OUTLINER_OT_collection_duplicate_linked";
-	ot->description = "Duplicate all objects and collections with linked object data";
+	ot->description = "Recursively duplicate the collection, all its children and objects, with linked object data";
+
+	/* api callbacks */
+	ot->exec = collection_duplicate_exec;
+	ot->poll = ED_outliner_collections_editor_poll;
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+void OUTLINER_OT_collection_duplicate(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Duplicate Collection";
+	ot->idname = "OUTLINER_OT_collection_duplicate";
+	ot->description = "Recursively duplicate the collection, all its children, objects and object data";
 
 	/* api callbacks */
 	ot->exec = collection_duplicate_exec;
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 0851d5ce9f4..5af8e2252ef 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -315,8 +315,9 @@ bool outliner_is_collection_tree_element(const TreeElement *te);
 struct Collection *outliner_collection_from_tree_element(const TreeElement *te);
 
 void OUTLINER_OT_collection_new(struct wmOperatorType *ot);
-void OUTLINER_OT_collection_duplicate(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_duplicate_hierarchy(struct wmOperatorType *ot);
 void OUTLINER_OT_collection_duplicate_linked(st

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list