Beispiel #1
0
void BKE_brush_make_local(Main *bmain, Brush *brush, const bool lib_local)
{
	bool is_local = false, is_lib = false;

	/* - only lib users: do nothing (unless force_local is set)
	 * - only local users: set flag
	 * - mixed: make copy
	 */

	if (!ID_IS_LINKED_DATABLOCK(brush)) {
		return;
	}

	if (brush->clone.image) {
		/* Special case: ima always local immediately. Clone image should only have one user anyway. */
		id_make_local(bmain, &brush->clone.image->id, false, false);
	}

	BKE_library_ID_test_usages(bmain, brush, &is_local, &is_lib);

	if (lib_local || is_local) {
		if (!is_lib) {
			id_clear_lib_data(bmain, &brush->id);
			BKE_id_expand_local(&brush->id);

			/* enable fake user by default */
			id_fake_user_set(&brush->id);
		}
		else {
			Brush *brush_new = BKE_brush_copy(bmain, brush);  /* Ensures FAKE_USER is set */

			brush_new->id.us = 0;

			/* setting newid is mandatory for complex make_lib_local logic... */
			ID_NEW_SET(brush, brush_new);

			if (!lib_local) {
				BKE_libblock_remap(bmain, brush, brush_new, ID_REMAP_SKIP_INDIRECT_USAGE);
			}
		}
	}
}
Beispiel #2
0
static Collection *collection_duplicate_recursive(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_obdata) ? U.dupflag : 0;

  if (!do_hierarchy || collection_old->id.newid == NULL) {
    BKE_id_copy(bmain, &collection_old->id, (ID **)&collection_new);
    id_us_min(
        &collection_new->id); /* Copying add one user by default, need to get rid of that one. */

    if (do_hierarchy) {
      ID_NEW_SET(collection_old, collection_new);
    }
    do_full_process = true;
  }
  else {
    collection_new = (Collection *)collection_old->id.newid;
  }

  /* Optionally add to parent (we always want to do that,
   * even if collection_old had already been duplicated). */
  if (parent != NULL) {
    if (collection_child_add(parent, collection_new, 0, true)) {
      /* Put collection right after existing one. */
      CollectionChild *child = collection_find_child(parent, collection_old);
      CollectionChild *child_new = collection_find_child(parent, collection_new);

      if (child && child_new) {
        BLI_remlink(&parent->children, child_new);
        BLI_insertlinkafter(&parent->children, child, child_new);
      }
    }
  }

  /* If we are not doing any kind of deep-copy, we can return immediately.
   * False do_full_process means collection_old had already been duplicated,
   * no need to redo some deep-copy on it. */
  if (!do_hierarchy || !do_full_process) {
    return collection_new;
  }

  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);
      }

      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, and won't be changed here. */
  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_objects, do_obdata);
    collection_child_remove(collection_new, child_collection_old);
  }

  return collection_new;
}