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
path: root/source
diff options
context:
space:
mode:
authorBastien Montagne <b.mont29@gmail.com>2020-03-05 12:54:00 +0300
committerBastien Montagne <b.mont29@gmail.com>2020-03-05 12:58:58 +0300
commitc328049535a4bc9453f5e93365a00759347e3a05 (patch)
treea6a058f3887e81e653c93400ecd163755796bddc /source
parent6665ce8951b2110e5dbd7126aae3c120bb6205e5 (diff)
Initial step for IDTypeInfo refactor 'cleanup' project.
Introduce new IDTypeInfo structure. Each ID type will have its own, with some minimal basic common info, and ID management callbacks. This patch only does it for Object type, for demo/testing purpose. Moving all existing IDs is a goal of next "cleanup Friday". Note that BKE_idcode features should then be merged back into BKE_idtype - but this will have to be done later, once all ID types have been properly converted to the new system. Another later TODO might be to try and add callbacks for file read/write, and lib_query ID usages looper. This is part of T73719. Thanks to @brecht for initial idea, and reviewing the patch. Differential Revision: https://developer.blender.org/D6966
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_idtype.h142
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/idtype.c81
-rw-r--r--source/blender/blenkernel/intern/lib_id.c255
-rw-r--r--source/blender/blenkernel/intern/lib_id_delete.c10
-rw-r--r--source/blender/blenkernel/intern/object.c448
-rw-r--r--source/creator/creator.c2
7 files changed, 633 insertions, 307 deletions
diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h
new file mode 100644
index 00000000000..ba0cf04dfc6
--- /dev/null
+++ b/source/blender/blenkernel/BKE_idtype.h
@@ -0,0 +1,142 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+#ifndef __BKE_IDTYPE_H__
+#define __BKE_IDTYPE_H__
+
+/** \file
+ * \ingroup bke
+ *
+ * ID type structure, helping to factorize common operations and data for all data-block types.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ID;
+struct Main;
+
+/** IDTypeInfo.flags. */
+enum {
+ /** Indicates that the given IDType does not support copying. */
+ IDTYPE_FLAGS_NO_COPY = 1 << 0,
+ /** Indicates that the given IDType does not support linking/appending from a library file. */
+ IDTYPE_FLAGS_NO_LIBLINKING = 1 << 1,
+ /** Indicates that the given IDType does not support making a library-linked ID local. */
+ IDTYPE_FLAGS_NO_MAKELOCAL = 1 << 2,
+};
+
+/* ********** Prototypes for IDTypeInfo callbacks. ********** */
+
+typedef void (*IDTypeInitDataFunction)(struct ID *id);
+
+/** \param flag: Copying options (see BKE_lib_id.h's LIB_ID_COPY_... flags for more). */
+typedef void (*IDTypeCopyDataFunction)(struct Main *bmain,
+ struct ID *id_dst,
+ const struct ID *id_src,
+ const int flag);
+
+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 flags);
+
+typedef struct IDTypeInfo {
+ /* ********** General IDType data. ********** */
+
+ /**
+ * Unique identifier of this type, either as a short or an array of two chars, see DNA_ID.h's
+ * ID_XX enums.
+ */
+ short id_code;
+ /**
+ * Bitflag matching id_code, used for filtering (e.g. in file browser), see DNA_ID.h's
+ * FILTER_ID_XX enums.
+ */
+ int id_filter;
+
+ /**
+ * Define the position of this data-block type in the virtual list of all data in a Main that is
+ * returned by `set_listbasepointers()`.
+ * Very important, this has to be unique and below INDEX_ID_MAX, see DNA_ID.h.
+ */
+ short main_listbase_index;
+
+ /** Memory size of a data-block of that type. */
+ size_t struct_size;
+
+ /** The user visible name for this data-block, also used as default name for a new data-block. */
+ const char *name;
+ /** Plural version of the user-visble name. */
+ const char *name_plural;
+ /** Translation context to use for UI messages related to that type of data-block. */
+ const char *translation_context;
+
+ /** Generic info flags about that data-block type. */
+ int flags;
+
+ /* ********** ID management callbacks ********** */
+
+ /* TODO: Note about callbacks: Ideally we could also handle here `BKE_lib_query`'s behavior, as
+ * well as read/write of files. However, this is a bit more involved than basic ID management
+ * callbacks, so we'll check on this later. */
+
+ /**
+ * Initialize a new, empty calloc'ed data-block. May be NULL if there is nothing to do.
+ */
+ IDTypeInitDataFunction init_data;
+
+ /**
+ * Copy the given data-block's data from source to destination. May be NULL if mere memcopy of
+ * the ID struct itself is enough.
+ */
+ IDTypeCopyDataFunction copy_data;
+
+ /**
+ * Free the data of the data-block (NOT the ID itself). May be NULL if there is nothing to do.
+ */
+ IDTypeFreeDataFunction free_data;
+
+ /**
+ * Make a linked data-block local. May be NULL if default behavior from
+ * `BKE_lib_id_make_local_generic()` is enough.
+ */
+ IDTypeMakeLocalFunction make_local;
+} IDTypeInfo;
+
+/* ********** Declaration of each IDTypeInfo. ********** */
+
+/* Those are defined in the respective BKE files. */
+extern IDTypeInfo IDType_ID_OB;
+
+/* ********** Helpers/Utils API. ********** */
+
+/* Module initialization. */
+void BKE_idtype_init(void);
+
+/* General helpers. */
+const struct IDTypeInfo *BKE_idtype_get_info_from_idcode(const short id_code);
+const struct IDTypeInfo *BKE_idtype_get_info_from_id(const struct ID *id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BKE_IDTYPE_H__ */
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 0a3b2450390..87ac82aaa55 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -125,6 +125,7 @@ set(SRC
intern/idcode.c
intern/idprop.c
intern/idprop_utils.c
+ intern/idtype.c
intern/image.c
intern/image_gen.c
intern/image_save.c
@@ -292,6 +293,7 @@ set(SRC
BKE_icons.h
BKE_idcode.h
BKE_idprop.h
+ BKE_idtype.h
BKE_image.h
BKE_image_save.h
BKE_ipo.h
diff --git a/source/blender/blenkernel/intern/idtype.c b/source/blender/blenkernel/intern/idtype.c
new file mode 100644
index 00000000000..494d83535b4
--- /dev/null
+++ b/source/blender/blenkernel/intern/idtype.c
@@ -0,0 +1,81 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 by the Blender Foundation.
+ * All rights reserved.
+ * Modifier stack implementation.
+ *
+ * BKE_modifier.h contains the function prototypes for this file.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+
+#include "CLG_log.h"
+
+#include "BLT_translation.h"
+
+#include "DNA_ID.h"
+
+#include "BKE_idcode.h"
+
+#include "BKE_idtype.h"
+
+// static CLG_LogRef LOG = {"bke.idtype"};
+
+static IDTypeInfo *id_types[INDEX_ID_MAX] = {NULL};
+
+static void id_type_init(void)
+{
+#define INIT_TYPE(_id_code) \
+ { \
+ BLI_assert(IDType_##_id_code.main_listbase_index == INDEX_##_id_code); \
+ id_types[INDEX_##_id_code] = &IDType_##_id_code; \
+ } \
+ (void)0
+
+ INIT_TYPE(ID_OB);
+
+#undef INIT_TYPE
+}
+
+void BKE_idtype_init(void)
+{
+ /* Initialize data-block types. */
+ id_type_init();
+}
+
+const IDTypeInfo *BKE_idtype_get_info_from_idcode(const short id_code)
+{
+ int id_index = BKE_idcode_to_index(id_code);
+
+ if (id_index >= 0 && id_index < INDEX_ID_MAX && id_types[id_index] != NULL &&
+ id_types[id_index]->name[0] != '\0') {
+ return id_types[id_index];
+ }
+ else {
+ return NULL;
+ }
+}
+
+const IDTypeInfo *BKE_idtype_get_info_from_id(const ID *id)
+{
+ return BKE_idtype_get_info_from_idcode(GS(id->name));
+}
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index 73a03294c51..416de844691 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -91,6 +91,7 @@
#include "BKE_gpencil.h"
#include "BKE_idcode.h"
#include "BKE_idprop.h"
+#include "BKE_idtype.h"
#include "BKE_image.h"
#include "BKE_key.h"
#include "BKE_light.h"
@@ -447,6 +448,23 @@ bool BKE_lib_id_make_local(Main *bmain, ID *id, const bool test, const int flags
return false;
}
+ const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_id(id);
+
+ if (idtype_info != NULL) {
+ if ((idtype_info->flags & IDTYPE_FLAGS_NO_MAKELOCAL) == 0) {
+ if (!test) {
+ if (idtype_info->make_local != NULL) {
+ idtype_info->make_local(bmain, id, flags);
+ }
+ else {
+ BKE_lib_id_make_local_generic(bmain, id, flags);
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
switch ((ID_Type)GS(id->name)) {
case ID_SCE:
if (!test) {
@@ -689,115 +707,131 @@ bool BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag)
if (id == NULL) {
return false;
}
- if (!BKE_id_copy_is_allowed(id)) {
- return false;
+
+ const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_id(id);
+
+ if (idtype_info != NULL) {
+ if ((idtype_info->flags & IDTYPE_FLAGS_NO_COPY) != 0) {
+ return false;
+ }
+
+ BKE_libblock_copy_ex(bmain, id, r_newid, flag);
+
+ if (idtype_info->copy_data != NULL) {
+ idtype_info->copy_data(bmain, *r_newid, id, flag);
+ }
}
+ else {
+ if (!BKE_id_copy_is_allowed(id)) {
+ return false;
+ }
- BKE_libblock_copy_ex(bmain, id, r_newid, flag);
+ BKE_libblock_copy_ex(bmain, id, r_newid, flag);
- switch ((ID_Type)GS(id->name)) {
- case ID_SCE:
- BKE_scene_copy_data(bmain, (Scene *)*r_newid, (Scene *)id, flag);
- break;
- case ID_OB:
- BKE_object_copy_data(bmain, (Object *)*r_newid, (Object *)id, flag);
- break;
- case ID_ME:
- BKE_mesh_copy_data(bmain, (Mesh *)*r_newid, (Mesh *)id, flag);
- break;
- case ID_CU:
- BKE_curve_copy_data(bmain, (Curve *)*r_newid, (Curve *)id, flag);
- break;
- case ID_MB:
- BKE_mball_copy_data(bmain, (MetaBall *)*r_newid, (MetaBall *)id, flag);
- break;
- case ID_MA:
- BKE_material_copy_data(bmain, (Material *)*r_newid, (Material *)id, flag);
- break;
- case ID_TE:
- BKE_texture_copy_data(bmain, (Tex *)*r_newid, (Tex *)id, flag);
- break;
- case ID_IM:
- BKE_image_copy_data(bmain, (Image *)*r_newid, (Image *)id, flag);
- break;
- case ID_LT:
- BKE_lattice_copy_data(bmain, (Lattice *)*r_newid, (Lattice *)id, flag);
- break;
- case ID_LA:
- BKE_light_copy_data(bmain, (Light *)*r_newid, (Light *)id, flag);
- break;
- case ID_SPK:
- BKE_speaker_copy_data(bmain, (Speaker *)*r_newid, (Speaker *)id, flag);
- break;
- case ID_LP:
- BKE_lightprobe_copy_data(bmain, (LightProbe *)*r_newid, (LightProbe *)id, flag);
- break;
- case ID_CA:
- BKE_camera_copy_data(bmain, (Camera *)*r_newid, (Camera *)id, flag);
- break;
- case ID_KE:
- BKE_key_copy_data(bmain, (Key *)*r_newid, (Key *)id, flag);
- break;
- case ID_WO:
- BKE_world_copy_data(bmain, (World *)*r_newid, (World *)id, flag);
- break;
- case ID_TXT:
- BKE_text_copy_data(bmain, (Text *)*r_newid, (Text *)id, flag);
- break;
- case ID_GR:
- BKE_collection_copy_data(bmain, (Collection *)*r_newid, (Collection *)id, flag);
- break;
- case ID_AR:
- BKE_armature_copy_data(bmain, (bArmature *)*r_newid, (bArmature *)id, flag);
- break;
- case ID_AC:
- BKE_action_copy_data(bmain, (bAction *)*r_newid, (bAction *)id, flag);
- break;
- case ID_NT:
- BKE_node_tree_copy_data(bmain, (bNodeTree *)*r_newid, (bNodeTree *)id, flag);
- break;
- case ID_BR:
- BKE_brush_copy_data(bmain, (Brush *)*r_newid, (Brush *)id, flag);
- break;
- case ID_PA:
- BKE_particlesettings_copy_data(
- bmain, (ParticleSettings *)*r_newid, (ParticleSettings *)id, flag);
- break;
- case ID_GD:
- BKE_gpencil_copy_data((bGPdata *)*r_newid, (bGPdata *)id, flag);
- break;
- case ID_MC:
- BKE_movieclip_copy_data(bmain, (MovieClip *)*r_newid, (MovieClip *)id, flag);
- break;
- case ID_MSK:
- BKE_mask_copy_data(bmain, (Mask *)*r_newid, (Mask *)id, flag);
- break;
- case ID_LS:
- BKE_linestyle_copy_data(
- bmain, (FreestyleLineStyle *)*r_newid, (FreestyleLineStyle *)id, flag);
- break;
- case ID_PAL:
- BKE_palette_copy_data(bmain, (Palette *)*r_newid, (Palette *)id, flag);
- break;
- case ID_PC:
- BKE_paint_curve_copy_data(bmain, (PaintCurve *)*r_newid, (PaintCurve *)id, flag);
- break;
- case ID_CF:
- BKE_cachefile_copy_data(bmain, (CacheFile *)*r_newid, (CacheFile *)id, flag);
- break;
- case ID_SO:
- BKE_sound_copy_data(bmain, (bSound *)*r_newid, (bSound *)id, flag);
- break;
- case ID_VF:
- BKE_vfont_copy_data(bmain, (VFont *)*r_newid, (VFont *)id, flag);
- break;
- case ID_LI:
- case ID_SCR:
- case ID_WM:
- case ID_WS:
- case ID_IP:
- BLI_assert(0); /* Should have been rejected at start of function! */
- break;
+ switch ((ID_Type)GS(id->name)) {
+ case ID_SCE:
+ BKE_scene_copy_data(bmain, (Scene *)*r_newid, (Scene *)id, flag);
+ break;
+ case ID_OB:
+ BKE_object_copy_data(bmain, (Object *)*r_newid, (Object *)id, flag);
+ break;
+ case ID_ME:
+ BKE_mesh_copy_data(bmain, (Mesh *)*r_newid, (Mesh *)id, flag);
+ break;
+ case ID_CU:
+ BKE_curve_copy_data(bmain, (Curve *)*r_newid, (Curve *)id, flag);
+ break;
+ case ID_MB:
+ BKE_mball_copy_data(bmain, (MetaBall *)*r_newid, (MetaBall *)id, flag);
+ break;
+ case ID_MA:
+ BKE_material_copy_data(bmain, (Material *)*r_newid, (Material *)id, flag);
+ break;
+ case ID_TE:
+ BKE_texture_copy_data(bmain, (Tex *)*r_newid, (Tex *)id, flag);
+ break;
+ case ID_IM:
+ BKE_image_copy_data(bmain, (Image *)*r_newid, (Image *)id, flag);
+ break;
+ case ID_LT:
+ BKE_lattice_copy_data(bmain, (Lattice *)*r_newid, (Lattice *)id, flag);
+ break;
+ case ID_LA:
+ BKE_light_copy_data(bmain, (Light *)*r_newid, (Light *)id, flag);
+ break;
+ case ID_SPK:
+ BKE_speaker_copy_data(bmain, (Speaker *)*r_newid, (Speaker *)id, flag);
+ break;
+ case ID_LP:
+ BKE_lightprobe_copy_data(bmain, (LightProbe *)*r_newid, (LightProbe *)id, flag);
+ break;
+ case ID_CA:
+ BKE_camera_copy_data(bmain, (Camera *)*r_newid, (Camera *)id, flag);
+ break;
+ case ID_KE:
+ BKE_key_copy_data(bmain, (Key *)*r_newid, (Key *)id, flag);
+ break;
+ case ID_WO:
+ BKE_world_copy_data(bmain, (World *)*r_newid, (World *)id, flag);
+ break;
+ case ID_TXT:
+ BKE_text_copy_data(bmain, (Text *)*r_newid, (Text *)id, flag);
+ break;
+ case ID_GR:
+ BKE_collection_copy_data(bmain, (Collection *)*r_newid, (Collection *)id, flag);
+ break;
+ case ID_AR:
+ BKE_armature_copy_data(bmain, (bArmature *)*r_newid, (bArmature *)id, flag);
+ break;
+ case ID_AC:
+ BKE_action_copy_data(bmain, (bAction *)*r_newid, (bAction *)id, flag);
+ break;
+ case ID_NT:
+ BKE_node_tree_copy_data(bmain, (bNodeTree *)*r_newid, (bNodeTree *)id, flag);
+ break;
+ case ID_BR:
+ BKE_brush_copy_data(bmain, (Brush *)*r_newid, (Brush *)id, flag);
+ break;
+ case ID_PA:
+ BKE_particlesettings_copy_data(
+ bmain, (ParticleSettings *)*r_newid, (ParticleSettings *)id, flag);
+ break;
+ case ID_GD:
+ BKE_gpencil_copy_data((bGPdata *)*r_newid, (bGPdata *)id, flag);
+ break;
+ case ID_MC:
+ BKE_movieclip_copy_data(bmain, (MovieClip *)*r_newid, (MovieClip *)id, flag);
+ break;
+ case ID_MSK:
+ BKE_mask_copy_data(bmain, (Mask *)*r_newid, (Mask *)id, flag);
+ break;
+ case ID_LS:
+ BKE_linestyle_copy_data(
+ bmain, (FreestyleLineStyle *)*r_newid, (FreestyleLineStyle *)id, flag);
+ break;
+ case ID_PAL:
+ BKE_palette_copy_data(bmain, (Palette *)*r_newid, (Palette *)id, flag);
+ break;
+ case ID_PC:
+ BKE_paint_curve_copy_data(bmain, (PaintCurve *)*r_newid, (PaintCurve *)id, flag);
+ break;
+ case ID_CF:
+ BKE_cachefile_copy_data(bmain, (CacheFile *)*r_newid, (CacheFile *)id, flag);
+ break;
+ case ID_SO:
+ BKE_sound_copy_data(bmain, (bSound *)*r_newid, (bSound *)id, flag);
+ break;
+ case ID_VF:
+ BKE_vfont_copy_data(bmain, (VFont *)*r_newid, (VFont *)id, flag);
+ break;
+ case ID_LI:
+ case ID_SCR:
+ case ID_WM:
+ case ID_WS:
+ case ID_IP:
+ BLI_assert(0); /* Should have been rejected at start of function! */
+ break;
+ }
}
/* Update ID refcount, remap pointers to self in new ID. */
@@ -1298,6 +1332,15 @@ void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int fl
*/
void BKE_libblock_init_empty(ID *id)
{
+ const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_id(id);
+
+ if (idtype_info != NULL) {
+ if (idtype_info->init_data != NULL) {
+ idtype_info->init_data(id);
+ }
+ return;
+ }
+
/* Note that only ID types that are not valid when filled of zero should have a callback here. */
switch ((ID_Type)GS(id->name)) {
case ID_SCE:
diff --git a/source/blender/blenkernel/intern/lib_id_delete.c b/source/blender/blenkernel/intern/lib_id_delete.c
index f2fa6946d4b..d47510ea9af 100644
--- a/source/blender/blenkernel/intern/lib_id_delete.c
+++ b/source/blender/blenkernel/intern/lib_id_delete.c
@@ -66,6 +66,7 @@
#include "BKE_font.h"
#include "BKE_gpencil.h"
#include "BKE_idprop.h"
+#include "BKE_idtype.h"
#include "BKE_image.h"
#include "BKE_ipo.h"
#include "BKE_key.h"
@@ -124,6 +125,15 @@ void BKE_libblock_free_data(ID *id, const bool do_id_user)
void BKE_libblock_free_datablock(ID *id, const int UNUSED(flag))
{
+ const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_id(id);
+
+ if (idtype_info != NULL) {
+ if (idtype_info->free_data != NULL) {
+ idtype_info->free_data(id);
+ }
+ return;
+ }
+
const short type = GS(id->name);
switch (type) {
case ID_SCE:
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index a742d0bb29f..3fded3e5881 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -85,6 +85,7 @@
#include "BKE_fcurve.h"
#include "BKE_gpencil_modifier.h"
#include "BKE_icons.h"
+#include "BKE_idtype.h"
#include "BKE_key.h"
#include "BKE_light.h"
#include "BKE_layer.h"
@@ -144,6 +145,248 @@ 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;
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(ob, id));
+
+ MEMCPY_STRUCT_AFTER(ob, DNA_struct_default_get(Object), id);
+
+ ob->type = OB_EMPTY;
+
+ ob->trackflag = OB_POSY;
+ ob->upflag = OB_POSZ;
+
+ /* Animation Visualization defaults */
+ 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,
+ .main_listbase_index = INDEX_ID_OB,
+ .struct_size = sizeof(Object),
+ .name = "Object",
+ .name_plural = "objects",
+ .translation_context = BLT_I18NCONTEXT_ID_OBJECT,
+ .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)
{
memset(workob, 0, sizeof(Object));
@@ -542,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(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);
+ object_free_data(&ob->id);
}
/* actual check for internal data, not context or flags */
@@ -872,9 +1067,7 @@ void *BKE_object_obdata_add_from_type(Main *bmain, int type, const char *name)
void BKE_object_init(Object *ob, const short ob_type)
{
- BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(ob, id));
-
- MEMCPY_STRUCT_AFTER(ob, DNA_struct_default_get(Object), id);
+ object_init_data(&ob->id);
ob->type = ob_type;
@@ -886,13 +1079,6 @@ void BKE_object_init(Object *ob, const short ob_type)
ob->trackflag = OB_NEGZ;
ob->upflag = OB_POSY;
}
- else {
- ob->trackflag = OB_POSY;
- ob->upflag = OB_POSZ;
- }
-
- /* Animation Visualization defaults */
- animviz_settings_init(&ob->avs);
}
/* more general add: creates minimum required data, but without vertices etc. */
@@ -1363,105 +1549,7 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
*/
void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, const int flag)
{
- 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;
- }
+ object_copy_data(bmain, &ob_dst->id, &ob_src->id, flag);
}
/* copy objects, will re-initialize cached simulation data */
@@ -1743,49 +1831,7 @@ Object *BKE_object_duplicate(Main *bmain, const Object *ob, const int dupflag)
void BKE_object_make_local(Main *bmain, Object *ob, const int flags)
{
- 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);
- }
- }
- }
+ object_make_local(bmain, &ob->id, flags);
}
/* Returns true if the Object is from an external blend file (libdata) */
diff --git a/source/creator/creator.c b/source/creator/creator.c
index cf25be95472..14db899b4fd 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -55,6 +55,7 @@
#include "BKE_context.h"
#include "BKE_font.h"
#include "BKE_global.h"
+#include "BKE_idtype.h"
#include "BKE_material.h"
#include "BKE_modifier.h"
#include "BKE_gpencil_modifier.h"
@@ -366,6 +367,7 @@ int main(int argc,
BKE_blender_globals_init(); /* blender.c */
+ BKE_idtype_init();
IMB_init();
BKE_cachefiles_init();
BKE_images_init();