Exemplo n.º 1
0
/**
 * Make either a shallow copy, or deeper duplicate of given collection.
 *
 * If \a do_hierarchy and \a do_deep_copy are false, this is a regular (shallow) ID copy.
 *
 * \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.
 * \param do_objects If true, it will also make duplicates of objects.
 *                   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 and \a do_objects are not set.
 */
Collection *BKE_collection_duplicate(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) {
    BLI_assert("!Master collection can't be duplicated");
    return NULL;
  }

  if (do_hierarchy) {
    BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
    BKE_main_id_clear_newpoins(bmain);
  }

  Collection *collection_new = collection_duplicate_recursive(
      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);

  if (do_hierarchy) {
    /* Cleanup. */
    BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
    BKE_main_id_clear_newpoins(bmain);
  }

  BKE_main_collection_sync(bmain);

  return collection_new;
}
Exemplo n.º 2
0
static int id_relink_to_newid_looper(void *UNUSED(user_data), ID *UNUSED(self_id), ID **id_pointer, const int cb_flag)
{
	if (cb_flag & IDWALK_CB_PRIVATE) {
		return IDWALK_RET_NOP;
	}

	ID *id = *id_pointer;
	if (id) {
		/* See: NEW_ID macro */
		if (id->newid) {
			BKE_library_update_ID_link_user(id->newid, id, cb_flag);
			*id_pointer = id->newid;
		}
		else if (id->tag & LIB_TAG_NEW) {
			id->tag &= ~LIB_TAG_NEW;
			BKE_libblock_relink_to_newid(id);
		}
	}
	return IDWALK_RET_NOP;
}