[Bf-blender-cvs] [d0e28c5b797] idtype-refactor: Update Object IDTypeInfo with new callbacks.

Bastien Montagne noreply at git.blender.org
Wed Mar 4 14:44:04 CET 2020


Commit: d0e28c5b79790cfaa525878ec9af89b0e7aa11d3
Author: Bastien Montagne
Date:   Wed Mar 4 12:38:53 2020 +0100
Branches: idtype-refactor
https://developer.blender.org/rBd0e28c5b79790cfaa525878ec9af89b0e7aa11d3

Update Object IDTypeInfo with new callbacks.

Also add/improve flags for IDTypeInfo.

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

M	source/blender/blenkernel/BKE_idtype.h
M	source/blender/blenkernel/intern/object.c

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

diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h
index 2e60edee09b..31b8e11821b 100644
--- a/source/blender/blenkernel/BKE_idtype.h
+++ b/source/blender/blenkernel/BKE_idtype.h
@@ -34,7 +34,10 @@ struct ID;
 struct Main;
 
 enum {
-  IDTYPE_FLAGS_IS_LINKABLE = 1 << 0,
+  /* Indicates that the given IDType does not support the matching feature. */
+  IDTYPE_FLAGS_NO_COPY = 1 << 0,
+  IDTYPE_FLAGS_NO_LIBLINKING = 1 << 1,
+  IDTYPE_FLAGS_NO_MAKELOCAL = 1 << 2,
 };
 
 typedef void (*IDTypeInitDataFunction)(struct ID *id);
@@ -45,10 +48,10 @@ typedef void (*IDTypeCopyDataFunction)(struct Main *bmain,
                                        const struct ID *id_src,
                                        const int flag);
 
-typedef void (*IDTypeFreeFunction)(struct ID *id);
+typedef void (*IDTypeFreeDataFunction)(struct ID *id);
 
 /** \param flag: See BKE_lib_id.h's LIB_ID_MAKELOCAL_... flags. */
-typedef void (*IDTypeMakeLocalFunction)(struct Main *bmain, struct ID *id, const int flag);
+typedef void (*IDTypeMakeLocalFunction)(struct Main *bmain, struct ID *id, const int flags);
 
 typedef struct IDTypeInfo {
   /* Unique identifier of this type, either as a short or an array of two chars. */
@@ -77,8 +80,7 @@ typedef struct IDTypeInfo {
   /* ********** ID management callbacks ********** */
   IDTypeInitDataFunction init_data;
   IDTypeCopyDataFunction copy_data;
-  IDTypeFreeFunction free;
-
+  IDTypeFreeDataFunction free_data;
   IDTypeMakeLocalFunction make_local;
 } IDTypeInfo;
 
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 7584d4816e5..dbacac83c7c 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -145,6 +145,9 @@ static CLG_LogRef LOG = {"bke.object"};
 static ThreadMutex vparent_lock = BLI_MUTEX_INITIALIZER;
 #endif
 
+static void copy_object_pose(Object *obn, const Object *ob, const int flag);
+static void copy_object_lod(Object *obn, const Object *ob, const int flag);
+
 static void object_init_data(ID *id)
 {
   Object *ob = (Object *)id;
@@ -161,6 +164,213 @@ static void object_init_data(ID *id)
   animviz_settings_init(&ob->avs);
 }
 
+static void object_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
+{
+  Object *ob_dst = (Object *)id_dst;
+  const Object *ob_src = (const Object *)id_src;
+  ModifierData *md;
+  GpencilModifierData *gmd;
+  ShaderFxData *fx;
+
+  /* Do not copy runtime data. */
+  BKE_object_runtime_reset_on_copy(ob_dst, flag);
+
+  /* We never handle usercount here for own data. */
+  const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
+
+  if (ob_src->totcol) {
+    ob_dst->mat = MEM_dupallocN(ob_src->mat);
+    ob_dst->matbits = MEM_dupallocN(ob_src->matbits);
+    ob_dst->totcol = ob_src->totcol;
+  }
+  else if (ob_dst->mat != NULL || ob_dst->matbits != NULL) {
+    /* This shall not be needed, but better be safe than sorry. */
+    BLI_assert(!"Object copy: non-NULL material pointers with zero counter, should not happen.");
+    ob_dst->mat = NULL;
+    ob_dst->matbits = NULL;
+  }
+
+  if (ob_src->iuser) {
+    ob_dst->iuser = MEM_dupallocN(ob_src->iuser);
+  }
+
+  if (ob_src->runtime.bb) {
+    ob_dst->runtime.bb = MEM_dupallocN(ob_src->runtime.bb);
+  }
+
+  BLI_listbase_clear(&ob_dst->modifiers);
+
+  for (md = ob_src->modifiers.first; md; md = md->next) {
+    ModifierData *nmd = modifier_new(md->type);
+    BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
+    modifier_copyData_ex(md, nmd, flag_subdata);
+    BLI_addtail(&ob_dst->modifiers, nmd);
+  }
+
+  BLI_listbase_clear(&ob_dst->greasepencil_modifiers);
+
+  for (gmd = ob_src->greasepencil_modifiers.first; gmd; gmd = gmd->next) {
+    GpencilModifierData *nmd = BKE_gpencil_modifier_new(gmd->type);
+    BLI_strncpy(nmd->name, gmd->name, sizeof(nmd->name));
+    BKE_gpencil_modifier_copyData_ex(gmd, nmd, flag_subdata);
+    BLI_addtail(&ob_dst->greasepencil_modifiers, nmd);
+  }
+
+  BLI_listbase_clear(&ob_dst->shader_fx);
+
+  for (fx = ob_src->shader_fx.first; fx; fx = fx->next) {
+    ShaderFxData *nfx = BKE_shaderfx_new(fx->type);
+    BLI_strncpy(nfx->name, fx->name, sizeof(nfx->name));
+    BKE_shaderfx_copyData_ex(fx, nfx, flag_subdata);
+    BLI_addtail(&ob_dst->shader_fx, nfx);
+  }
+
+  if (ob_src->pose) {
+    copy_object_pose(ob_dst, ob_src, flag_subdata);
+    /* backwards compat... non-armatures can get poses in older files? */
+    if (ob_src->type == OB_ARMATURE) {
+      const bool do_pose_id_user = (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0;
+      BKE_pose_rebuild(bmain, ob_dst, ob_dst->data, do_pose_id_user);
+    }
+  }
+  defgroup_copy_list(&ob_dst->defbase, &ob_src->defbase);
+  BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps);
+  BKE_constraints_copy_ex(&ob_dst->constraints, &ob_src->constraints, flag_subdata, true);
+
+  ob_dst->mode = ob_dst->type != OB_GPENCIL ? OB_MODE_OBJECT : ob_dst->mode;
+  ob_dst->sculpt = NULL;
+
+  if (ob_src->pd) {
+    ob_dst->pd = MEM_dupallocN(ob_src->pd);
+    if (ob_dst->pd->rng) {
+      ob_dst->pd->rng = MEM_dupallocN(ob_src->pd->rng);
+    }
+  }
+  BKE_object_copy_softbody(ob_dst, ob_src, flag_subdata);
+  BKE_rigidbody_object_copy(bmain, ob_dst, ob_src, flag_subdata);
+
+  BKE_object_copy_particlesystems(ob_dst, ob_src, flag_subdata);
+
+  BLI_listbase_clear((ListBase *)&ob_dst->drawdata);
+  BLI_listbase_clear(&ob_dst->pc_ids);
+
+  ob_dst->avs = ob_src->avs;
+  ob_dst->mpath = animviz_copy_motionpath(ob_src->mpath);
+
+  copy_object_lod(ob_dst, ob_src, flag_subdata);
+
+  /* Do not copy object's preview
+   * (mostly due to the fact renderers create temp copy of objects). */
+  if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0 && false) { /* XXX TODO temp hack */
+    BKE_previewimg_id_copy(&ob_dst->id, &ob_src->id);
+  }
+  else {
+    ob_dst->preview = NULL;
+  }
+}
+
+static void object_free_data(ID *id)
+{
+  Object *ob = (Object *)id;
+  BKE_animdata_free((ID *)ob, false);
+
+  DRW_drawdata_free((ID *)ob);
+
+  /* BKE_<id>_free shall never touch to ID->us. Never ever. */
+  BKE_object_free_modifiers(ob, LIB_ID_CREATE_NO_USER_REFCOUNT);
+  BKE_object_free_shaderfx(ob, LIB_ID_CREATE_NO_USER_REFCOUNT);
+
+  MEM_SAFE_FREE(ob->mat);
+  MEM_SAFE_FREE(ob->matbits);
+  MEM_SAFE_FREE(ob->iuser);
+  MEM_SAFE_FREE(ob->runtime.bb);
+
+  BLI_freelistN(&ob->defbase);
+  BLI_freelistN(&ob->fmaps);
+  if (ob->pose) {
+    BKE_pose_free_ex(ob->pose, false);
+    ob->pose = NULL;
+  }
+  if (ob->mpath) {
+    animviz_free_motionpath(ob->mpath);
+    ob->mpath = NULL;
+  }
+
+  BKE_constraints_free_ex(&ob->constraints, false);
+
+  BKE_partdeflect_free(ob->pd);
+  BKE_rigidbody_free_object(ob, NULL);
+  BKE_rigidbody_free_constraint(ob);
+
+  sbFree(ob);
+
+  BKE_sculptsession_free(ob);
+
+  BLI_freelistN(&ob->pc_ids);
+
+  BLI_freelistN(&ob->lodlevels);
+
+  /* Free runtime curves data. */
+  if (ob->runtime.curve_cache) {
+    BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev);
+    if (ob->runtime.curve_cache->path) {
+      free_path(ob->runtime.curve_cache->path);
+    }
+    MEM_freeN(ob->runtime.curve_cache);
+    ob->runtime.curve_cache = NULL;
+  }
+
+  BKE_previewimg_free(&ob->preview);
+}
+
+static void object_make_local(Main *bmain, ID *id, const int flags)
+{
+  Object *ob = (Object *)id;
+  const bool lib_local = (flags & LIB_ID_MAKELOCAL_FULL_LIBRARY) != 0;
+  const bool clear_proxy = (flags & LIB_ID_MAKELOCAL_OBJECT_NO_PROXY_CLEARING) == 0;
+  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
+   * In case we make a whole lib's content local,
+   * we always want to localize, and we skip remapping (done later).
+   */
+
+  if (!ID_IS_LINKED(ob)) {
+    return;
+  }
+
+  BKE_library_ID_test_usages(bmain, ob, &is_local, &is_lib);
+
+  if (lib_local || is_local) {
+    if (!is_lib) {
+      BKE_lib_id_clear_library_data(bmain, &ob->id);
+      BKE_lib_id_expand_local(bmain, &ob->id);
+      if (clear_proxy) {
+        if (ob->proxy_from != NULL) {
+          ob->proxy_from->proxy = NULL;
+          ob->proxy_from->proxy_group = NULL;
+        }
+        ob->proxy = ob->proxy_from = ob->proxy_group = NULL;
+      }
+    }
+    else {
+      Object *ob_new = BKE_object_copy(bmain, ob);
+
+      ob_new->id.us = 0;
+      ob_new->proxy = ob_new->proxy_from = ob_new->proxy_group = NULL;
+
+      /* setting newid is mandatory for complex make_lib_local logic... */
+      ID_NEW_SET(ob, ob_new);
+
+      if (!lib_local) {
+        BKE_libblock_remap(bmain, ob, ob_new, ID_REMAP_SKIP_INDIRECT_USAGE);
+      }
+    }
+  }
+}
+
 IDTypeInfo IDType_ID_OB = {
     .id_code = ID_OB,
     .id_filter = FILTER_ID_OB,
@@ -169,9 +379,12 @@ IDTypeInfo IDType_ID_OB = {
     .name = "Object",
     .name_plural = "objects",
     .translation_context = BLT_I18NCONTEXT_ID_OBJECT,
-    .flags = IDTYPE_FLAGS_IS_LINKABLE,
+    .flags = 0,
 
     .init_data = object_init_data,
+    .copy_data = object_copy_data,
+    .free_data = object_free_data,
+    .make_local = object_make_local,
 };
 
 void BKE_object_workob_clear(Object *workob)
@@ -572,55 +785,7 @@ void BKE_object_free_caches(Object *object)
 /** Free (or release) any data used by this object (does not free the object itself). */
 void BKE_object_free(Object *ob)
 {
-  BKE_animdata_free((ID *)ob, false);
-
-  DRW_drawdata_free((ID *)ob);
-
-  /* BKE_<id>_free shall never touch to ID->us. Never ever. */
-  BKE_object_free_modifiers(ob, LIB_ID_CREATE_NO_USER_REFCOUNT);
-  BKE_object_free_shaderfx(ob, LIB_ID_CREATE_NO_USER_REFCOUNT);
-
-  MEM_SAFE_FREE(ob->mat);
-  MEM_SAFE_FREE(ob->matbits);
-  MEM_SAFE_FREE(ob->iuser);
-  MEM_SAFE_FREE(ob->runtime.bb);
-
-  BLI_freelistN(&ob->defbase);
-  BLI_freelistN(&ob->fmaps);
-  if (ob->pose) {
-    BKE_pose_free_ex(ob->pose, false);
-    ob->pose = NULL;
-  }
-  if (ob->mpath) {
-    animviz_free_motionpath(ob->mpath);
-    ob->mpath = NULL;
-  }
-
-  BKE_constraints_free_ex(&ob->constraints, false);
-
-  BKE_partdeflect_free(ob->pd);
-  BKE_rigidbody_free_object(ob, NULL);
-  BKE_rigidbody_free_constraint(

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list