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
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_action.h6
-rw-r--r--source/blender/blenkernel/BKE_animsys.h6
-rw-r--r--source/blender/blenkernel/BKE_armature.h1
-rw-r--r--source/blender/blenkernel/BKE_brush.h1
-rw-r--r--source/blender/blenkernel/BKE_cachefile.h2
-rw-r--r--source/blender/blenkernel/BKE_camera.h1
-rw-r--r--source/blender/blenkernel/BKE_constraint.h1
-rw-r--r--source/blender/blenkernel/BKE_curve.h1
-rw-r--r--source/blender/blenkernel/BKE_font.h1
-rw-r--r--source/blender/blenkernel/BKE_freestyle.h2
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h1
-rw-r--r--source/blender/blenkernel/BKE_group.h1
-rw-r--r--source/blender/blenkernel/BKE_idprop.h3
-rw-r--r--source/blender/blenkernel/BKE_image.h1
-rw-r--r--source/blender/blenkernel/BKE_key.h1
-rw-r--r--source/blender/blenkernel/BKE_lamp.h1
-rw-r--r--source/blender/blenkernel/BKE_lattice.h1
-rw-r--r--source/blender/blenkernel/BKE_library.h70
-rw-r--r--source/blender/blenkernel/BKE_linestyle.h15
-rw-r--r--source/blender/blenkernel/BKE_mask.h1
-rw-r--r--source/blender/blenkernel/BKE_material.h1
-rw-r--r--source/blender/blenkernel/BKE_mball.h1
-rw-r--r--source/blender/blenkernel/BKE_mesh.h1
-rw-r--r--source/blender/blenkernel/BKE_modifier.h1
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h1
-rw-r--r--source/blender/blenkernel/BKE_node.h2
-rw-r--r--source/blender/blenkernel/BKE_object.h10
-rw-r--r--source/blender/blenkernel/BKE_paint.h6
-rw-r--r--source/blender/blenkernel/BKE_particle.h3
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h2
-rw-r--r--source/blender/blenkernel/BKE_rigidbody.h6
-rw-r--r--source/blender/blenkernel/BKE_sca.h14
-rw-r--r--source/blender/blenkernel/BKE_scene.h1
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h4
-rw-r--r--source/blender/blenkernel/BKE_sound.h2
-rw-r--r--source/blender/blenkernel/BKE_speaker.h1
-rw-r--r--source/blender/blenkernel/BKE_text.h1
-rw-r--r--source/blender/blenkernel/BKE_texture.h7
-rw-r--r--source/blender/blenkernel/BKE_tracking.h2
-rw-r--r--source/blender/blenkernel/BKE_world.h1
-rw-r--r--source/blender/blenkernel/intern/action.c88
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c13
-rw-r--r--source/blender/blenkernel/intern/armature.c78
-rw-r--r--source/blender/blenkernel/intern/brush.c50
-rw-r--r--source/blender/blenkernel/intern/cachefile.c28
-rw-r--r--source/blender/blenkernel/intern/camera.c25
-rw-r--r--source/blender/blenkernel/intern/constraint.c24
-rw-r--r--source/blender/blenkernel/intern/curve.c59
-rw-r--r--source/blender/blenkernel/intern/font.c19
-rw-r--r--source/blender/blenkernel/intern/freestyle.c18
-rw-r--r--source/blender/blenkernel/intern/gpencil.c81
-rw-r--r--source/blender/blenkernel/intern/group.c33
-rw-r--r--source/blender/blenkernel/intern/idprop.c51
-rw-r--r--source/blender/blenkernel/intern/image.c66
-rw-r--r--source/blender/blenkernel/intern/key.c51
-rw-r--r--source/blender/blenkernel/intern/lamp.c56
-rw-r--r--source/blender/blenkernel/intern/lattice.c45
-rw-r--r--source/blender/blenkernel/intern/library.c511
-rw-r--r--source/blender/blenkernel/intern/library_remap.c90
-rw-r--r--source/blender/blenkernel/intern/linestyle.c127
-rw-r--r--source/blender/blenkernel/intern/mask.c32
-rw-r--r--source/blender/blenkernel/intern/material.c71
-rw-r--r--source/blender/blenkernel/intern/mball.c37
-rw-r--r--source/blender/blenkernel/intern/mesh.c67
-rw-r--r--source/blender/blenkernel/intern/modifier.c29
-rw-r--r--source/blender/blenkernel/intern/movieclip.c38
-rw-r--r--source/blender/blenkernel/intern/node.c291
-rw-r--r--source/blender/blenkernel/intern/object.c170
-rw-r--r--source/blender/blenkernel/intern/paint.c65
-rw-r--r--source/blender/blenkernel/intern/particle.c57
-rw-r--r--source/blender/blenkernel/intern/pointcache.c9
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c32
-rw-r--r--source/blender/blenkernel/intern/sca.c32
-rw-r--r--source/blender/blenkernel/intern/scene.c479
-rw-r--r--source/blender/blenkernel/intern/sequencer.c22
-rw-r--r--source/blender/blenkernel/intern/sound.c30
-rw-r--r--source/blender/blenkernel/intern/speaker.c28
-rw-r--r--source/blender/blenkernel/intern/text.c72
-rw-r--r--source/blender/blenkernel/intern/texture.c102
-rw-r--r--source/blender/blenkernel/intern/tracking.c44
-rw-r--r--source/blender/blenkernel/intern/world.c54
-rw-r--r--source/blender/blenlib/BLI_vfontdata.h2
-rw-r--r--source/blender/blenlib/intern/freetypefont.c29
-rw-r--r--source/blender/blenloader/intern/readfile.c2
-rw-r--r--source/blender/blenloader/intern/writefile.c3
-rw-r--r--source/blender/editors/armature/armature_relations.c4
-rw-r--r--source/blender/editors/io/io_cache.c2
-rw-r--r--source/blender/editors/object/object_edit.c18
-rw-r--r--source/blender/editors/object/object_relations.c4
-rw-r--r--source/blender/editors/physics/particle_object.c2
-rw-r--r--source/blender/editors/render/render_shading.c8
-rw-r--r--source/blender/editors/screen/screen_edit.c12
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c6
-rw-r--r--source/blender/makesdna/DNA_ID.h10
-rw-r--r--source/blender/modifiers/intern/MOD_armature.c8
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c14
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c6
-rw-r--r--source/blender/modifiers/intern/MOD_wave.c6
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c4
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgmix.c6
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c6
-rw-r--r--source/blender/windowmanager/intern/wm.c2
102 files changed, 2216 insertions, 1396 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 5db0c3c9130..28be2b04c71 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -57,8 +57,9 @@ extern "C" {
/* Allocate a new bAction with the given name */
struct bAction *add_empty_action(struct Main *bmain, const char name[]);
-/* Allocate a copy of the given Action and all its data */
-struct bAction *BKE_action_copy(struct Main *bmain, const struct bAction *src);
+void BKE_action_copy_data(struct Main *bmain, struct bAction *act_dst, const struct bAction *act_src, const int flag);
+/* Allocate a copy of the given Action and all its data */
+struct bAction *BKE_action_copy(struct Main *bmain, const struct bAction *act_src);
/* Deallocate all of the Action's data, but not the Action itself */
void BKE_action_free(struct bAction *act);
@@ -150,6 +151,7 @@ void BKE_pose_free_data_ex(struct bPose *pose, bool do_id_user);
void BKE_pose_free_data(struct bPose *pose);
void BKE_pose_free(struct bPose *pose);
void BKE_pose_free_ex(struct bPose *pose, bool do_id_user);
+void BKE_pose_copy_data_ex(struct bPose **dst, const struct bPose *src, const int flag, const bool copy_constraints);
void BKE_pose_copy_data(struct bPose **dst, const struct bPose *src, const bool copy_constraints);
void BKE_pose_channel_copy_data(struct bPoseChannel *pchan, const struct bPoseChannel *pchan_from);
struct bPoseChannel *BKE_pose_channel_find_name(const struct bPose *pose, const char *name);
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 3e6e24a28b0..7984202f03f 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -67,10 +67,10 @@ bool BKE_animdata_set_action(struct ReportList *reports, struct ID *id, struct b
void BKE_animdata_free(struct ID *id, const bool do_id_user);
/* Copy AnimData */
-struct AnimData *BKE_animdata_copy(struct AnimData *adt, const bool do_action);
+struct AnimData *BKE_animdata_copy(struct Main *bmain, struct AnimData *adt, const bool do_action);
/* Copy AnimData */
-bool BKE_animdata_copy_id(struct ID *id_to, struct ID *id_from, const bool do_action);
+bool BKE_animdata_copy_id(struct Main *bmain, struct ID *id_to, struct ID *id_from, const bool do_action);
/* Copy AnimData Actions */
void BKE_animdata_copy_id_action(struct ID *id, const bool set_newid);
@@ -102,7 +102,7 @@ struct KS_Path *BKE_keyingset_add_path(struct KeyingSet *ks, struct ID *id, cons
struct KS_Path *BKE_keyingset_find_path(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode);
/* Copy all KeyingSets in the given list */
-void BKE_keyingsets_copy(struct ListBase *newlist, struct ListBase *list);
+void BKE_keyingsets_copy(struct ListBase *newlist, const struct ListBase *list);
/* Free the given Keying Set path */
void BKE_keyingset_free_path(struct KeyingSet *ks, struct KS_Path *ksp);
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 41783700bf6..8e67bc43b3f 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -79,6 +79,7 @@ int BKE_armature_bonelist_count(struct ListBase *lb);
void BKE_armature_bonelist_free(struct ListBase *lb);
void BKE_armature_free(struct bArmature *arm);
void BKE_armature_make_local(struct Main *bmain, struct bArmature *arm, const bool lib_local);
+void BKE_armature_copy_data(struct Main *bmain, struct bArmature *arm_dst, const struct bArmature *arm_src, const int flag);
struct bArmature *BKE_armature_copy(struct Main *bmain, const struct bArmature *arm);
/* Bounding box. */
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index 42e4e73f2d5..dedb75a080a 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -44,6 +44,7 @@ void BKE_brush_system_exit(void);
void BKE_brush_init(struct Brush *brush);
struct Brush *BKE_brush_add(struct Main *bmain, const char *name, short ob_mode);
struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode);
+void BKE_brush_copy_data(struct Main *bmain, struct Brush *brush_dst, const struct Brush *brush_src, const int flag);
struct Brush *BKE_brush_copy(struct Main *bmain, const struct Brush *brush);
void BKE_brush_make_local(struct Main *bmain, struct Brush *brush, const bool lib_local);
void BKE_brush_unlink(struct Main *bmain, struct Brush *brush);
diff --git a/source/blender/blenkernel/BKE_cachefile.h b/source/blender/blenkernel/BKE_cachefile.h
index db8ddb2ba68..e0419d0e749 100644
--- a/source/blender/blenkernel/BKE_cachefile.h
+++ b/source/blender/blenkernel/BKE_cachefile.h
@@ -47,6 +47,8 @@ void BKE_cachefile_init(struct CacheFile *cache_file);
void BKE_cachefile_free(struct CacheFile *cache_file);
+void BKE_cachefile_copy_data(
+ struct Main *bmain, struct CacheFile *cache_file_dst, const struct CacheFile *cache_file_src, const int flag);
struct CacheFile *BKE_cachefile_copy(struct Main *bmain, const struct CacheFile *cache_file);
void BKE_cachefile_make_local(struct Main *bmain, struct CacheFile *cache_file, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index 22165212ed8..2234cee0e0d 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -53,6 +53,7 @@ struct GPUFXSettings;
void BKE_camera_init(struct Camera *cam);
void *BKE_camera_add(struct Main *bmain, const char *name);
+void BKE_camera_copy_data(struct Main *bmain, struct Camera *cam_dst, const struct Camera *cam_src, const int flag);
struct Camera *BKE_camera_copy(struct Main *bmain, const struct Camera *cam);
void BKE_camera_make_local(struct Main *bmain, struct Camera *cam, const bool lib_local);
void BKE_camera_free(struct Camera *ca);
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 6490418edbe..33fc91b2c3c 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -121,6 +121,7 @@ void BKE_constraint_unique_name(struct bConstraint *con, struct ListBase *list);
void BKE_constraints_free(struct ListBase *list);
void BKE_constraints_free_ex(struct ListBase *list, bool do_id_user);
void BKE_constraints_copy(struct ListBase *dst, const struct ListBase *src, bool do_extern);
+void BKE_constraints_copy_ex(struct ListBase *dst, const struct ListBase *src, const int flag, bool do_extern);
void BKE_constraints_id_loop(struct ListBase *list, ConstraintIDFunc func, void *userdata);
void BKE_constraint_free_data(struct bConstraint *con);
void BKE_constraint_free_data_ex(struct bConstraint *con, bool do_id_user);
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 501a623acea..e748c5082ad 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -79,6 +79,7 @@ void BKE_curve_free(struct Curve *cu);
void BKE_curve_editfont_free(struct Curve *cu);
void BKE_curve_init(struct Curve *cu);
struct Curve *BKE_curve_add(struct Main *bmain, const char *name, int type);
+void BKE_curve_copy_data(struct Main *bmain, struct Curve *cu_dst, const struct Curve *cu_src, const int flag);
struct Curve *BKE_curve_copy(struct Main *bmain, const struct Curve *cu);
void BKE_curve_make_local(struct Main *bmain, struct Curve *cu, const bool lib_local);
short BKE_curve_type_get(struct Curve *cu);
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index e7ae0f606e7..60ad061bf77 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -78,6 +78,7 @@ void BKE_vfont_builtin_register(void *mem, int size);
void BKE_vfont_free_data(struct VFont *vfont);
void BKE_vfont_free(struct VFont *sc);
void BKE_vfont_init(struct VFont *vfont);
+void BKE_vfont_copy_data(struct Main *bmain, struct VFont *vfont_dst, const struct VFont *vfont_src, const int flag);
struct VFont *BKE_vfont_builtin_get(void);
struct VFont *BKE_vfont_load(struct Main *bmain, const char *filepath);
struct VFont *BKE_vfont_load_exists_ex(struct Main *bmain, const char *filepath, bool *r_exists);
diff --git a/source/blender/blenkernel/BKE_freestyle.h b/source/blender/blenkernel/BKE_freestyle.h
index 50407f3bdfc..1045fde0039 100644
--- a/source/blender/blenkernel/BKE_freestyle.h
+++ b/source/blender/blenkernel/BKE_freestyle.h
@@ -50,7 +50,7 @@ typedef struct FreestyleModuleSettings FreestyleModuleSettings;
/* FreestyleConfig */
void BKE_freestyle_config_init(FreestyleConfig *config);
void BKE_freestyle_config_free(FreestyleConfig *config);
-void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *config);
+void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *config, const int flag);
/* FreestyleConfig.modules */
FreestyleModuleConfig *BKE_freestyle_module_add(FreestyleConfig *config);
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index bdd28baf137..b6de922c245 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -60,6 +60,7 @@ struct bGPdata *BKE_gpencil_data_addnew(const char name[]);
struct bGPDframe *BKE_gpencil_frame_duplicate(const struct bGPDframe *gpf_src);
struct bGPDlayer *BKE_gpencil_layer_duplicate(const struct bGPDlayer *gpl_src);
+void BKE_gpencil_copy_data(struct Main *bmain, struct bGPdata *gpd_dst, const struct bGPdata *gpd_src, const int flag);
struct bGPdata *BKE_gpencil_data_duplicate(struct Main *bmain, const struct bGPdata *gpd, bool internal_copy);
void BKE_gpencil_make_local(struct Main *bmain, struct bGPdata *gpd, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h
index 4555bbf076d..fd0b23b242a 100644
--- a/source/blender/blenkernel/BKE_group.h
+++ b/source/blender/blenkernel/BKE_group.h
@@ -43,6 +43,7 @@ struct Scene;
void BKE_group_free(struct Group *group);
struct Group *BKE_group_add(struct Main *bmain, const char *name);
+void BKE_group_copy_data(struct Main *bmain, struct Group *group_dst, const struct Group *group_src, const int flag);
struct Group *BKE_group_copy(struct Main *bmain, const struct Group *group);
void BKE_group_make_local(struct Main *bmain, struct Group *group, const bool lib_local);
bool BKE_group_object_add(struct Group *group, struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index ab8728faedb..5d8cd02756d 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -58,7 +58,7 @@ typedef union IDPropertyTemplate {
/* ----------- Property Array Type ---------- */
IDProperty *IDP_NewIDPArray(const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-IDProperty *IDP_CopyIDPArray(const IDProperty *array) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+IDProperty *IDP_CopyIDPArray(const IDProperty *array, const int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
/* shallow copies item */
void IDP_SetIndexArray(struct IDProperty *prop, int index, struct IDProperty *item) ATTR_NONNULL();
@@ -103,6 +103,7 @@ IDProperty *IDP_GetPropertyTypeFromGroup(struct IDProperty *prop, const char *na
/*-------- Main Functions --------*/
struct IDProperty *IDP_GetProperties(struct ID *id, const bool create_if_needed) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
struct IDProperty *IDP_CopyProperty(const struct IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+struct IDProperty *IDP_CopyProperty_ex(const struct IDProperty *prop, const int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is_strict) ATTR_WARN_UNUSED_RESULT;
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index e155b0719cc..3f8be511212 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -250,6 +250,7 @@ void BKE_image_packfiles_from_mem(struct ReportList *reports, struct Image *ima,
void BKE_image_print_memlist(void);
/* empty image block, of similar type and filename */
+void BKE_image_copy_data(struct Main *bmain, struct Image *ima_dst, const struct Image *ima_src, const int flag);
struct Image *BKE_image_copy(struct Main *bmain, const struct Image *ima);
/* merge source into dest, and free source */
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index 94e8a24fbc5..5eef44ef896 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -51,6 +51,7 @@ extern "C" {
void BKE_key_free(struct Key *sc);
void BKE_key_free_nolib(struct Key *key);
struct Key *BKE_key_add(struct ID *id);
+void BKE_key_copy_data(struct Main *bmain, struct Key *key_dst, const struct Key *key_src, const int flag);
struct Key *BKE_key_copy(struct Main *bmain, const struct Key *key);
struct Key *BKE_key_copy_nolib(struct Key *key);
void BKE_key_sort(struct Key *key);
diff --git a/source/blender/blenkernel/BKE_lamp.h b/source/blender/blenkernel/BKE_lamp.h
index 713ca80fb1a..b68da654520 100644
--- a/source/blender/blenkernel/BKE_lamp.h
+++ b/source/blender/blenkernel/BKE_lamp.h
@@ -44,6 +44,7 @@ struct Scene;
void BKE_lamp_init(struct Lamp *la);
struct Lamp *BKE_lamp_add(struct Main *bmain, const char *name) ATTR_WARN_UNUSED_RESULT;
+void BKE_lamp_copy_data(struct Main *bmain, struct Lamp *la_dst, const struct Lamp *la_src, const int flag);
struct Lamp *BKE_lamp_copy(struct Main *bmain, const struct Lamp *la) ATTR_WARN_UNUSED_RESULT;
struct Lamp *localize_lamp(struct Lamp *la) ATTR_WARN_UNUSED_RESULT;
void BKE_lamp_make_local(struct Main *bmain, struct Lamp *la, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h
index fe3d388178e..181dc5d31ae 100644
--- a/source/blender/blenkernel/BKE_lattice.h
+++ b/source/blender/blenkernel/BKE_lattice.h
@@ -48,6 +48,7 @@ struct EvaluationContext;
void BKE_lattice_resize(struct Lattice *lt, int u, int v, int w, struct Object *ltOb);
void BKE_lattice_init(struct Lattice *lt);
struct Lattice *BKE_lattice_add(struct Main *bmain, const char *name);
+void BKE_lattice_copy_data(struct Main *bmain, struct Lattice *lt_dst, const struct Lattice *lt_src, const int flag);
struct Lattice *BKE_lattice_copy(struct Main *bmain, const struct Lattice *lt);
void BKE_lattice_free(struct Lattice *lt);
void BKE_lattice_make_local(struct Main *bmain, struct Lattice *lt, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index bfe8cea7519..eac4dc81582 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -52,11 +52,38 @@ struct PropertyRNA;
size_t BKE_libblock_get_alloc_info(short type, const char **name);
void *BKE_libblock_alloc_notest(short type);
-void *BKE_libblock_alloc(struct Main *bmain, short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void *BKE_libblock_alloc(struct Main *bmain, short type, const char *name, const int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void BKE_libblock_init_empty(struct ID *id);
+
+/**
+ * New ID creation/copying options.
+ */
+enum {
+ /* *** Generic options (should be handled by all ID types copying, ID creation, etc.). *** */
+ /* Create datablock outside of any main database - similar to 'localize' functions of materials etc. */
+ LIB_ID_CREATE_NO_MAIN = 1 << 0,
+ /* Do not affect user refcount of datablocks used by new one (which also gets zero usercount then).
+ * Implies LIB_ID_CREATE_NO_MAIN. */
+ LIB_ID_CREATE_NO_USER_REFCOUNT = 1 << 1,
+ /* Assume given 'newid' already points to allocated memory for whole datablock (ID + data) - USE WITH CAUTION!
+ * Implies LIB_ID_CREATE_NO_MAIN. */
+ LIB_ID_CREATE_NO_ALLOCATE = 1 << 2,
+
+ LIB_ID_CREATE_NO_DEG_TAG = 1 << 8, /* Do not tag new ID for update in depsgraph. */
+
+ /* Specific options to some ID types or usages, may be ignored by unrelated ID copying functions. */
+ LIB_ID_COPY_NO_PROXY_CLEAR = 1 << 16, /* Object only, needed by make_local code. */
+ LIB_ID_COPY_NO_PREVIEW = 1 << 17, /* Do not copy preview data, when supported. */
+ LIB_ID_COPY_CACHES = 1 << 18, /* Copy runtime data caches. */
+ /* XXX TODO Do we want to keep that? would rather try to get rid of it... */
+ LIB_ID_COPY_ACTIONS = 1 << 19, /* EXCEPTION! Deep-copy actions used by animdata of copied ID. */
+};
+
+void BKE_libblock_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag);
void *BKE_libblock_copy(struct Main *bmain, const struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+/* "Deprecated" old API. */
void *BKE_libblock_copy_nolib(const struct ID *id, const bool do_action) ATTR_NONNULL();
-void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action);
+
void BKE_libblock_rename(struct Main *bmain, struct ID *id, const char *name) ATTR_NONNULL();
void BLI_libblock_ensure_unique_name(struct Main *bmain, const char *name) ATTR_NONNULL();
@@ -64,13 +91,45 @@ struct ID *BKE_libblock_find_name_ex(struct Main *bmain, const short type, const
struct ID *BKE_libblock_find_name(const short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
/* library_remap.c (keep here since they're general functions) */
-void BKE_libblock_free(struct Main *bmain, void *idv) ATTR_NONNULL();
-void BKE_libblock_free_datablock(struct ID *id) ATTR_NONNULL();
+/**
+ * New freeing logic options.
+ */
+enum {
+ /* *** Generic options (should be handled by all ID types freeing). *** */
+ /* Do not try to remove freed ID from given Main (passed Main may be NULL). */
+ LIB_ID_FREE_NO_MAIN = 1 << 0,
+ /* Do not affect user refcount of datablocks used by freed one.
+ * Implies LIB_ID_FREE_NO_MAIN. */
+ LIB_ID_FREE_NO_USER_REFCOUNT = 1 << 1,
+ /* Assume freed ID datablock memory is managed elsewhere, do not free it
+ * (still calls relevant ID type's freeing function though) - USE WITH CAUTION!
+ * Implies LIB_ID_FREE_NO_MAIN. */
+ LIB_ID_FREE_NOT_ALLOCATED = 1 << 2,
+
+ LIB_ID_FREE_NO_DEG_TAG = 1 << 8, /* Do not tag freed ID for update in depsgraph. */
+ LIB_ID_FREE_NO_UI_USER = 1 << 9, /* Do not attempt to remove freed ID from UI data/notifiers/... */
+};
+
+void BKE_id_free_ex(struct Main *bmain, void *idv, int flag, const bool use_flag_from_idtag);
+void BKE_id_free(struct Main *bmain, void *idv);
+/* Those three naming are bad actually, should be BKE_id_free... (since it goes beyond mere datablock). */
+/* "Deprecated" old API */
void BKE_libblock_free_ex(struct Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user) ATTR_NONNULL();
+void BKE_libblock_free(struct Main *bmain, void *idv) ATTR_NONNULL();
void BKE_libblock_free_us(struct Main *bmain, void *idv) ATTR_NONNULL();
-void BKE_libblock_free_data(struct ID *id, const bool do_id_user) ATTR_NONNULL();
+
+void BKE_libblock_management_main_add(struct Main *bmain, void *idv);
+void BKE_libblock_management_main_remove(struct Main *bmain, void *idv);
+
+void BKE_libblock_management_usercounts_set(struct Main *bmain, void *idv);
+void BKE_libblock_management_usercounts_clear(struct Main *bmain, void *idv);
+
+/* TODO should be named "BKE_id_delete()". */
void BKE_libblock_delete(struct Main *bmain, void *idv) ATTR_NONNULL();
+void BKE_libblock_free_datablock(struct ID *id, const int flag) ATTR_NONNULL();
+void BKE_libblock_free_data(struct ID *id, const bool do_id_user) ATTR_NONNULL();
+
void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id);
void id_lib_extern(struct ID *id);
void BKE_library_filepath_set(struct Library *lib, const char *filepath);
@@ -87,6 +146,7 @@ void BKE_id_make_local_generic(struct Main *bmain, struct ID *id, const bool id_
bool id_make_local(struct Main *bmain, struct ID *id, const bool test, const bool force_local);
bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop);
bool id_copy(struct Main *bmain, const struct ID *id, struct ID **newid, bool test);
+bool BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag, const bool test);
void id_sort_by_name(struct ListBase *lb, struct ID *id);
void BKE_id_expand_local(struct Main *bmain, struct ID *id);
void BKE_id_copy_ensure_local(struct Main *bmain, const struct ID *old_id, struct ID *new_id);
diff --git a/source/blender/blenkernel/BKE_linestyle.h b/source/blender/blenkernel/BKE_linestyle.h
index c7b323d0f6e..3ba4fbe0338 100644
--- a/source/blender/blenkernel/BKE_linestyle.h
+++ b/source/blender/blenkernel/BKE_linestyle.h
@@ -52,6 +52,9 @@ struct bContext;
void BKE_linestyle_init(struct FreestyleLineStyle *linestyle);
FreestyleLineStyle *BKE_linestyle_new(struct Main *bmain, const char *name);
void BKE_linestyle_free(FreestyleLineStyle *linestyle);
+void BKE_linestyle_copy_data(
+ struct Main *bmain, struct FreestyleLineStyle *linestyle_dst, const struct FreestyleLineStyle *linestyle_src,
+ const int flag);
FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, const FreestyleLineStyle *linestyle);
void BKE_linestyle_make_local(struct Main *bmain, struct FreestyleLineStyle *linestyle, const bool lib_local);
@@ -63,10 +66,14 @@ LineStyleModifier *BKE_linestyle_alpha_modifier_add(FreestyleLineStyle *linestyl
LineStyleModifier *BKE_linestyle_thickness_modifier_add(FreestyleLineStyle *linestyle, const char *name, int type);
LineStyleModifier *BKE_linestyle_geometry_modifier_add(FreestyleLineStyle *linestyle, const char *name, int type);
-LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m);
-LineStyleModifier *BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m);
-LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m);
-LineStyleModifier *BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m);
+LineStyleModifier *BKE_linestyle_color_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int flag);
+LineStyleModifier *BKE_linestyle_alpha_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int flag);
+LineStyleModifier *BKE_linestyle_thickness_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int flag);
+LineStyleModifier *BKE_linestyle_geometry_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int flag);
int BKE_linestyle_color_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier);
int BKE_linestyle_alpha_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier);
diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h
index 0735d2d97a1..6e154241af7 100644
--- a/source/blender/blenkernel/BKE_mask.h
+++ b/source/blender/blenkernel/BKE_mask.h
@@ -122,6 +122,7 @@ void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, const eMask
/* general */
struct Mask *BKE_mask_new(struct Main *bmain, const char *name);
+void BKE_mask_copy_data(struct Main *bmain, struct Mask *mask_dst, const struct Mask *mask_src, const int flag);
struct Mask *BKE_mask_copy_nolib(struct Mask *mask);
struct Mask *BKE_mask_copy(struct Main *bmain, const struct Mask *mask);
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 14820587200..d42bd1c8c35 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -54,6 +54,7 @@ void BKE_material_init(struct Material *ma);
void BKE_material_remap_object(struct Object *ob, const unsigned int *remap);
void BKE_material_remap_object_calc(struct Object *ob_dst, struct Object *ob_src, short *remap_src_to_dst);
struct Material *BKE_material_add(struct Main *bmain, const char *name);
+void BKE_material_copy_data(struct Main *bmain, struct Material *ma_dst, const struct Material *ma_src, const int flag);
struct Material *BKE_material_copy(struct Main *bmain, const struct Material *ma);
struct Material *localize_material(struct Material *ma);
struct Material *give_node_material(struct Material *ma); /* returns node material or self */
diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h
index c00a0743ebb..a02a068b920 100644
--- a/source/blender/blenkernel/BKE_mball.h
+++ b/source/blender/blenkernel/BKE_mball.h
@@ -41,6 +41,7 @@ struct MetaElem;
void BKE_mball_free(struct MetaBall *mb);
void BKE_mball_init(struct MetaBall *mb);
struct MetaBall *BKE_mball_add(struct Main *bmain, const char *name);
+void BKE_mball_copy_data(struct Main *bmain, struct MetaBall *mb_dst, const struct MetaBall *mb_src, const int flag);
struct MetaBall *BKE_mball_copy(struct Main *bmain, const struct MetaBall *mb);
void BKE_mball_make_local(struct Main *bmain, struct MetaBall *mb, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 4766f1d37eb..4ec2594b599 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -88,6 +88,7 @@ int BKE_mesh_edge_other_vert(const struct MEdge *e, int v);
void BKE_mesh_free(struct Mesh *me);
void BKE_mesh_init(struct Mesh *me);
struct Mesh *BKE_mesh_add(struct Main *bmain, const char *name);
+void BKE_mesh_copy_data(struct Main *bmain, struct Mesh *me_dst, const struct Mesh *me_src, const int flag);
struct Mesh *BKE_mesh_copy(struct Main *bmain, const struct Mesh *me);
void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd);
void BKE_mesh_ensure_skin_customdata(struct Mesh *me);
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index ca74993156d..412805e6cc6 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -337,6 +337,7 @@ bool modifier_unique_name(struct ListBase *modifiers, struct ModifierDa
void modifier_copyData_generic(const struct ModifierData *md, struct ModifierData *target);
void modifier_copyData(struct ModifierData *md, struct ModifierData *target);
+void modifier_copyData_ex(struct ModifierData *md, struct ModifierData *target, const int flag);
bool modifier_dependsOnTime(struct ModifierData *md);
bool modifier_supportsMapping(struct ModifierData *md);
bool modifier_supportsCage(struct Scene *scene, struct ModifierData *md);
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index 69fdad5ef7b..3ddf75f204e 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -41,6 +41,7 @@ struct MovieDistortion;
void BKE_movieclip_free(struct MovieClip *clip);
+void BKE_movieclip_copy_data(struct Main *bmain, struct MovieClip *clip_dst, const struct MovieClip *clip_src, const int flag);
struct MovieClip *BKE_movieclip_copy(struct Main *bmain, const struct MovieClip *clip);
void BKE_movieclip_make_local(struct Main *bmain, struct MovieClip *clip, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index a668ae9a7af..dc61a2d825f 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -336,6 +336,7 @@ struct bNodeTree *ntreeAddTree(struct Main *bmain, const char *name, const char
/* copy/free funcs, need to manage ID users */
void ntreeFreeTree(struct bNodeTree *ntree);
+void BKE_node_tree_copy_data(struct Main *bmain, struct bNodeTree *ntree_dst, const struct bNodeTree *ntree_src, const int flag);
struct bNodeTree *ntreeCopyTree_ex(const struct bNodeTree *ntree, struct Main *bmain, const bool do_id_user);
struct bNodeTree *ntreeCopyTree(struct Main *bmain, const struct bNodeTree *ntree);
/* node->id user count */
@@ -453,6 +454,7 @@ void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node);
void nodeUniqueName(struct bNodeTree *ntree, struct bNode *node);
void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node);
+struct bNode *BKE_node_copy_ex(struct bNodeTree *ntree, struct bNode *node_src, const int flag);
struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node);
struct bNodeLink *nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock);
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index d763b33b88f..b63a7173d7d 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -54,10 +54,10 @@ void BKE_object_workob_clear(struct Object *workob);
void BKE_object_workob_calc_parent(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct Object *workob);
void BKE_object_transform_copy(struct Object *ob_tar, const struct Object *ob_src);
-struct SoftBody *copy_softbody(const struct SoftBody *sb, bool copy_caches);
-struct BulletSoftBody *copy_bulletsoftbody(const struct BulletSoftBody *sb);
-struct ParticleSystem *BKE_object_copy_particlesystem(struct ParticleSystem *psys);
-void BKE_object_copy_particlesystems(struct Object *ob_dst, const struct Object *ob_src);
+struct SoftBody *copy_softbody(const struct SoftBody *sb, const int flag);
+struct BulletSoftBody *copy_bulletsoftbody(const struct BulletSoftBody *sb, const int flag);
+struct ParticleSystem *BKE_object_copy_particlesystem(struct ParticleSystem *psys, const int flag);
+void BKE_object_copy_particlesystems(struct Object *ob_dst, const struct Object *ob_src, const int flag);
void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src);
void BKE_object_free_particlesystems(struct Object *ob);
void BKE_object_free_softbody(struct Object *ob);
@@ -106,7 +106,7 @@ bool BKE_object_lod_is_usable(struct Object *ob, struct SceneLayer *sl);
struct Object *BKE_object_lod_meshob_get(struct Object *ob, struct SceneLayer *sl);
struct Object *BKE_object_lod_matob_get(struct Object *ob, struct SceneLayer *sl);
-struct Object *BKE_object_copy_ex(struct Main *bmain, const struct Object *ob, bool copy_caches);
+void BKE_object_copy_data(struct Main *bmain, struct Object *ob_dst, const struct Object *ob_src, const int flag);
struct Object *BKE_object_copy(struct Main *bmain, const struct Object *ob);
void BKE_object_make_local(struct Main *bmain, struct Object *ob, const bool lib_local);
void BKE_object_make_local_ex(struct Main *bmain, struct Object *ob, const bool lib_local, const bool clear_proxy);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index e9287465528..e73e3800af0 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -101,6 +101,8 @@ void BKE_paint_set_overlay_override(enum OverlayFlags flag);
/* palettes */
void BKE_palette_free(struct Palette *palette);
struct Palette *BKE_palette_add(struct Main *bmain, const char *name);
+void BKE_palette_copy_data(
+ struct Main *bmain, struct Palette *palette_dst, const struct Palette *palette_src, const int flag);
struct Palette *BKE_palette_copy(struct Main *bmain, const struct Palette *palette);
void BKE_palette_make_local(struct Main *bmain, struct Palette *palette, const bool lib_local);
struct PaletteColor *BKE_palette_color_add(struct Palette *palette);
@@ -111,12 +113,14 @@ void BKE_palette_clear(struct Palette *palette);
/* paint curves */
struct PaintCurve *BKE_paint_curve_add(struct Main *bmain, const char *name);
void BKE_paint_curve_free(struct PaintCurve *pc);
+void BKE_paint_curve_copy_data(
+ struct Main *bmain, struct PaintCurve *pc_dst, const struct PaintCurve *pc_src, const int flag);
struct PaintCurve *BKE_paint_curve_copy(struct Main *bmain, const struct PaintCurve *pc);
void BKE_paint_curve_make_local(struct Main *bmain, struct PaintCurve *pc, const bool lib_local);
void BKE_paint_init(struct Scene *sce, PaintMode mode, const char col[3]);
void BKE_paint_free(struct Paint *p);
-void BKE_paint_copy(struct Paint *src, struct Paint *tar);
+void BKE_paint_copy(struct Paint *src, struct Paint *tar, const int flag);
void BKE_paint_cavity_curve_preset(struct Paint *p, int preset);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index f8b1bc2a52a..fed4e98c9f9 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -326,6 +326,9 @@ struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct P
struct ModifierData *object_add_particle_system(struct Scene *scene, struct Object *ob, const char *name);
void object_remove_particle_system(struct Scene *scene, struct Object *ob);
struct ParticleSettings *psys_new_settings(const char *name, struct Main *main);
+void BKE_particlesettings_copy_data(
+ struct Main *bmain, struct ParticleSettings *part_dst, const struct ParticleSettings *part_src,
+ const int flag);
struct ParticleSettings *BKE_particlesettings_copy(struct Main *bmain, const struct ParticleSettings *part);
void BKE_particlesettings_make_local(struct Main *bmain, struct ParticleSettings *part, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 02f6c435ee2..f0819c8d79d 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -314,7 +314,7 @@ struct PointCache *BKE_ptcache_add(struct ListBase *ptcaches);
void BKE_ptcache_free_mem(struct ListBase *mem_cache);
void BKE_ptcache_free(struct PointCache *cache);
void BKE_ptcache_free_list(struct ListBase *ptcaches);
-struct PointCache *BKE_ptcache_copy_list(struct ListBase *ptcaches_new, const struct ListBase *ptcaches_old, bool copy_data);
+struct PointCache *BKE_ptcache_copy_list(struct ListBase *ptcaches_new, const struct ListBase *ptcaches_old, const int flag);
/********************** Baking *********************/
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h
index 41e2a117eeb..ec68253e162 100644
--- a/source/blender/blenkernel/BKE_rigidbody.h
+++ b/source/blender/blenkernel/BKE_rigidbody.h
@@ -50,8 +50,8 @@ void BKE_rigidbody_free_constraint(struct Object *ob);
/* ...... */
-struct RigidBodyOb *BKE_rigidbody_copy_object(const struct Object *ob);
-struct RigidBodyCon *BKE_rigidbody_copy_constraint(const struct Object *ob);
+struct RigidBodyOb *BKE_rigidbody_copy_object(const struct Object *ob, const int flag);
+struct RigidBodyCon *BKE_rigidbody_copy_constraint(const struct Object *ob, const int flag);
/* Callback format for performing operations on ID-pointers for rigidbody world. */
typedef void (*RigidbodyWorldIDFunc)(struct RigidBodyWorld *rbw, struct ID **idpoin, void *userdata, int cb_flag);
@@ -67,7 +67,7 @@ struct RigidBodyOb *BKE_rigidbody_create_object(struct Scene *scene, struct Obje
struct RigidBodyCon *BKE_rigidbody_create_constraint(struct Scene *scene, struct Object *ob, short type);
/* copy */
-struct RigidBodyWorld *BKE_rigidbody_world_copy(struct RigidBodyWorld *rbw);
+struct RigidBodyWorld *BKE_rigidbody_world_copy(struct RigidBodyWorld *rbw, const int flag);
void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw);
/* 'validate' (i.e. make new or replace old) Physics-Engine objects */
diff --git a/source/blender/blenkernel/BKE_sca.h b/source/blender/blenkernel/BKE_sca.h
index 10cddd7b454..35bcd91a9b1 100644
--- a/source/blender/blenkernel/BKE_sca.h
+++ b/source/blender/blenkernel/BKE_sca.h
@@ -52,16 +52,16 @@ void free_actuators(struct ListBase *lb);
void free_sensor(struct bSensor *sens);
void free_sensors(struct ListBase *lb);
-struct bSensor *copy_sensor(struct bSensor *sens);
-void copy_sensors(struct ListBase *lbn, const struct ListBase *lbo);
+struct bSensor *copy_sensor(struct bSensor *sens, const int flag);
+void copy_sensors(struct ListBase *lbn, const struct ListBase *lbo, const int flag);
void init_sensor(struct bSensor *sens);
struct bSensor *new_sensor(int type);
-struct bController *copy_controller(struct bController *cont);
-void copy_controllers(struct ListBase *lbn, const struct ListBase *lbo);
+struct bController *copy_controller(struct bController *cont, const int flag);
+void copy_controllers(struct ListBase *lbn, const struct ListBase *lbo, const int flag);
void init_controller(struct bController *cont);
struct bController *new_controller(int type);
-struct bActuator *copy_actuator(struct bActuator *act);
-void copy_actuators(struct ListBase *lbn, const struct ListBase *lbo);
+struct bActuator *copy_actuator(struct bActuator *act, const int flag);
+void copy_actuators(struct ListBase *lbn, const struct ListBase *lbo, const int flag);
void init_actuator(struct bActuator *act);
struct bActuator *new_actuator(int type);
void clear_sca_new_poins_ob(struct Object *ob);
@@ -70,7 +70,7 @@ void set_sca_new_poins_ob(struct Object *ob);
void set_sca_new_poins(void);
void BKE_sca_logic_links_remap(struct Main *bmain, struct Object *ob_old, struct Object *ob_new);
-void BKE_sca_logic_copy(struct Object *ob_new, const struct Object *ob);
+void BKE_sca_logic_copy(struct Object *ob_new, const struct Object *ob, const int flag);
void sca_move_sensor(struct bSensor *sens_to_move, struct Object *ob, int move_up);
void sca_move_controller(struct bController *cont_to_move, struct Object *ob, int move_up);
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 6ca79d8c7cd..e7e36dd40b4 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -112,6 +112,7 @@ void BKE_scene_object_base_flag_sync_from_object(struct Base *base);
void BKE_scene_set_background(struct Main *bmain, struct Scene *sce);
struct Scene *BKE_scene_set_name(struct Main *bmain, const char *name);
+void BKE_scene_copy_data(struct Main *bmain, struct Scene *sce_dst, const struct Scene *sce_src, const int flag);
struct Scene *BKE_scene_copy(struct Main *bmain, struct Scene *sce, int type);
void BKE_scene_groups_relink(struct Scene *sce);
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 5a2c49f5527..49b08af97d6 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -352,8 +352,8 @@ void BKE_sequencer_refresh_sound_length(struct Scene *scene);
void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq);
void BKE_sequence_base_dupli_recursive(
- struct Scene *scene, struct Scene *scene_to, ListBase *nseqbase, ListBase *seqbase,
- int dupe_flag);
+ const struct Scene *scene, struct Scene *scene_to, struct ListBase *nseqbase, const struct ListBase *seqbase,
+ int dupe_flag, const int flag);
bool BKE_sequence_is_valid_check(struct Sequence *seq);
void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce);
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index a5c626e74d7..6f8274fabc8 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -80,6 +80,8 @@ void BKE_sound_load(struct Main *main, struct bSound *sound);
void BKE_sound_free(struct bSound *sound);
+void BKE_sound_copy_data(struct Main *bmain, struct bSound *sound_dst, const struct bSound *sound_src, const int flag);
+
void BKE_sound_make_local(struct Main *bmain, struct bSound *sound, const bool lib_local);
#if defined(__AUD_C_API_H__) || defined(WITH_SYSTEM_AUDASPACE)
diff --git a/source/blender/blenkernel/BKE_speaker.h b/source/blender/blenkernel/BKE_speaker.h
index 907558f9203..57f4c37f129 100644
--- a/source/blender/blenkernel/BKE_speaker.h
+++ b/source/blender/blenkernel/BKE_speaker.h
@@ -33,6 +33,7 @@ struct Speaker;
void BKE_speaker_init(struct Speaker *spk);
void *BKE_speaker_add(struct Main *bmain, const char *name);
+void BKE_speaker_copy_data(struct Main *bmain, struct Speaker *spk_dst, const struct Speaker *spk_src, const int flag);
struct Speaker *BKE_speaker_copy(struct Main *bmain, const struct Speaker *spk);
void BKE_speaker_make_local(struct Main *bmain, struct Speaker *spk, const bool lib_local);
void BKE_speaker_free(struct Speaker *spk);
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index c8fb483cdf2..14d3318e059 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -52,6 +52,7 @@ bool BKE_text_reload(struct Text *text);
struct Text *BKE_text_load_ex(struct Main *bmain, const char *file, const char *relpath,
const bool is_internal);
struct Text *BKE_text_load (struct Main *bmain, const char *file, const char *relpath);
+void BKE_text_copy_data(struct Main *bmain, struct Text *ta_dst, const struct Text *ta_src, const int flag);
struct Text *BKE_text_copy (struct Main *bmain, const struct Text *ta);
void BKE_text_make_local (struct Main *bmain, struct Text *text, const bool lib_local);
void BKE_text_clear (struct Text *text);
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 190fdeafaec..8a9171673ea 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -70,6 +70,7 @@ void colorband_update_sort(struct ColorBand *coba);
void BKE_texture_free(struct Tex *tex);
void BKE_texture_default(struct Tex *tex);
+void BKE_texture_copy_data(struct Main *bmain, struct Tex *tex_dst, const struct Tex *tex_src, const int flag);
struct Tex *BKE_texture_copy(struct Main *bmain, const struct Tex *tex);
struct Tex *BKE_texture_add(struct Main *bmain, const char *name);
struct Tex *BKE_texture_localize(struct Tex *tex);
@@ -114,13 +115,13 @@ void BKE_texture_colormapping_default(struct ColorMapping *color
void BKE_texture_envmap_free_data(struct EnvMap *env);
void BKE_texture_envmap_free(struct EnvMap *env);
struct EnvMap *BKE_texture_envmap_add(void);
-struct EnvMap *BKE_texture_envmap_copy(const struct EnvMap *env);
+struct EnvMap *BKE_texture_envmap_copy(const struct EnvMap *env, const int flag);
void BKE_texture_pointdensity_init_data(struct PointDensity *pd);
void BKE_texture_pointdensity_free_data(struct PointDensity *pd);
void BKE_texture_pointdensity_free(struct PointDensity *pd);
struct PointDensity *BKE_texture_pointdensity_add(void);
-struct PointDensity *BKE_texture_pointdensity_copy(const struct PointDensity *pd);
+struct PointDensity *BKE_texture_pointdensity_copy(const struct PointDensity *pd, const int flag);
void BKE_texture_voxeldata_free_data(struct VoxelData *vd);
void BKE_texture_voxeldata_free(struct VoxelData *vd);
@@ -129,7 +130,7 @@ struct VoxelData *BKE_texture_voxeldata_copy(struct VoxelData *vd);
void BKE_texture_ocean_free(struct OceanTex *ot);
struct OceanTex *BKE_texture_ocean_add(void);
-struct OceanTex *BKE_texture_ocean_copy(const struct OceanTex *ot);
+struct OceanTex *BKE_texture_ocean_copy(const struct OceanTex *ot, const int flag);
bool BKE_texture_dependsOnTime(const struct Tex *texture);
bool BKE_texture_is_image_user(const struct Tex *tex);
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index d149654fc82..b4ca1b79238 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -53,7 +53,7 @@ struct rcti;
/* **** Common functions **** */
void BKE_tracking_free(struct MovieTracking *tracking);
-void BKE_tracking_copy(struct MovieTracking *tracking_dst, const struct MovieTracking *tracking_src);
+void BKE_tracking_copy(struct MovieTracking *tracking_dst, const struct MovieTracking *tracking_src, const int flag);
void BKE_tracking_settings_init(struct MovieTracking *tracking);
diff --git a/source/blender/blenkernel/BKE_world.h b/source/blender/blenkernel/BKE_world.h
index 5175edcd3d6..f6127956597 100644
--- a/source/blender/blenkernel/BKE_world.h
+++ b/source/blender/blenkernel/BKE_world.h
@@ -39,6 +39,7 @@ struct World;
void BKE_world_free(struct World *sc);
void BKE_world_init(struct World *wrld);
struct World *add_world(struct Main *bmian, const char *name);
+void BKE_world_copy_data(struct Main *bmain, struct World *wrld_dst, const struct World *wrld_src, const int flag);
struct World *BKE_world_copy(struct Main *bmain, const struct World *wrld);
struct World *localize_world(struct World *wrld);
void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib_local);
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 8a94d4b8666..00b9e0a283b 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -89,7 +89,7 @@ bAction *add_empty_action(Main *bmain, const char name[])
{
bAction *act;
- act = BKE_libblock_alloc(bmain, ID_AC, name);
+ act = BKE_libblock_alloc(bmain, ID_AC, name, 0);
return act;
}
@@ -121,46 +121,56 @@ void BKE_action_free(bAction *act)
/* .................................. */
-bAction *BKE_action_copy(Main *bmain, const bAction *src)
+/**
+ * Only copy internal data of Action ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_action_copy_data(Main *UNUSED(bmain), bAction *act_dst, const bAction *act_src, const int UNUSED(flag))
{
- bAction *dst = NULL;
- bActionGroup *dgrp, *sgrp;
- FCurve *dfcu, *sfcu;
-
- if (src == NULL)
- return NULL;
- dst = BKE_libblock_copy(bmain, &src->id);
-
+ bActionGroup *grp_dst, *grp_src;
+ FCurve *fcu_dst, *fcu_src;
+
/* duplicate the lists of groups and markers */
- BLI_duplicatelist(&dst->groups, &src->groups);
- BLI_duplicatelist(&dst->markers, &src->markers);
-
+ BLI_duplicatelist(&act_dst->groups, &act_src->groups);
+ BLI_duplicatelist(&act_dst->markers, &act_src->markers);
+
/* copy F-Curves, fixing up the links as we go */
- BLI_listbase_clear(&dst->curves);
-
- for (sfcu = src->curves.first; sfcu; sfcu = sfcu->next) {
+ BLI_listbase_clear(&act_dst->curves);
+
+ for (fcu_src = act_src->curves.first; fcu_src; fcu_src = fcu_src->next) {
/* duplicate F-Curve */
- dfcu = copy_fcurve(sfcu);
- BLI_addtail(&dst->curves, dfcu);
-
+ fcu_dst = copy_fcurve(fcu_src); /* XXX TODO pass subdata flag? But surprisingly does not seem to be doing any ID refcounting... */
+ BLI_addtail(&act_dst->curves, fcu_dst);
+
/* fix group links (kindof bad list-in-list search, but this is the most reliable way) */
- for (dgrp = dst->groups.first, sgrp = src->groups.first; dgrp && sgrp; dgrp = dgrp->next, sgrp = sgrp->next) {
- if (sfcu->grp == sgrp) {
- dfcu->grp = dgrp;
-
- if (dgrp->channels.first == sfcu)
- dgrp->channels.first = dfcu;
- if (dgrp->channels.last == sfcu)
- dgrp->channels.last = dfcu;
-
+ for (grp_dst = act_dst->groups.first, grp_src = act_src->groups.first;
+ grp_dst && grp_src;
+ grp_dst = grp_dst->next, grp_src = grp_src->next)
+ {
+ if (fcu_src->grp == grp_src) {
+ fcu_dst->grp = grp_dst;
+
+ if (grp_dst->channels.first == fcu_src) {
+ grp_dst->channels.first = fcu_dst;
+ }
+ if (grp_dst->channels.last == fcu_src) {
+ grp_dst->channels.last = fcu_dst;
+ }
break;
}
}
}
-
- BKE_id_copy_ensure_local(bmain, &src->id, &dst->id);
+}
- return dst;
+bAction *BKE_action_copy(Main *bmain, const bAction *act_src)
+{
+ bAction *act_copy;
+ BKE_id_copy_ex(bmain, &act_src->id, (ID **)&act_copy, 0, false);
+ return act_copy;
}
/* *************** Action Groups *************** */
@@ -524,7 +534,7 @@ const char *BKE_pose_ikparam_get_name(bPose *pose)
*
* \param dst Should be freed already, makes entire duplicate.
*/
-void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constraints)
+void BKE_pose_copy_data_ex(bPose **dst, const bPose *src, const int flag, const bool copy_constraints)
{
bPose *outPose;
bPoseChannel *pchan;
@@ -554,9 +564,8 @@ void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constrain
outPose->avs = src->avs;
for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) {
-
- if (pchan->custom) {
- id_us_plus(&pchan->custom->id);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)pchan->custom);
}
/* warning, O(n2) here, if done without the hash, but these are rarely used features. */
@@ -571,13 +580,13 @@ void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constrain
}
if (copy_constraints) {
- BKE_constraints_copy(&listb, &pchan->constraints, true); // BKE_constraints_copy NULLs listb
+ BKE_constraints_copy_ex(&listb, &pchan->constraints, flag, true); // BKE_constraints_copy NULLs listb
pchan->constraints = listb;
pchan->mpath = NULL; /* motion paths should not get copied yet... */
}
if (pchan->prop) {
- pchan->prop = IDP_CopyProperty(pchan->prop);
+ pchan->prop = IDP_CopyProperty_ex(pchan->prop, flag);
}
pchan->draw_data = NULL; /* Drawing cache, no need to copy. */
@@ -591,6 +600,11 @@ void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constrain
*dst = outPose;
}
+void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constraints)
+{
+ BKE_pose_copy_data_ex(dst, src, 0, copy_constraints);
+}
+
void BKE_pose_itasc_init(bItasc *itasc)
{
if (itasc) {
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 3b3dff21206..68556354a6c 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -261,7 +261,7 @@ void BKE_animdata_free(ID *id, const bool do_id_user)
/* Copying -------------------------------------------- */
/* Make a copy of the given AnimData - to be used when copying datablocks */
-AnimData *BKE_animdata_copy(AnimData *adt, const bool do_action)
+AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const bool do_action)
{
AnimData *dadt;
@@ -272,8 +272,9 @@ AnimData *BKE_animdata_copy(AnimData *adt, const bool do_action)
/* make a copy of action - at worst, user has to delete copies... */
if (do_action) {
- dadt->action = BKE_action_copy(G.main, adt->action);
- dadt->tmpact = BKE_action_copy(G.main, adt->tmpact);
+ BLI_assert(bmain != NULL);
+ BKE_id_copy_ex(bmain, (ID *)dadt->action, (ID **)&dadt->action, 0, false);
+ BKE_id_copy_ex(bmain, (ID *)dadt->tmpact, (ID **)&dadt->tmpact, 0, false);
}
else {
id_us_plus((ID *)dadt->action);
@@ -293,7 +294,7 @@ AnimData *BKE_animdata_copy(AnimData *adt, const bool do_action)
return dadt;
}
-bool BKE_animdata_copy_id(ID *id_to, ID *id_from, const bool do_action)
+bool BKE_animdata_copy_id(Main *bmain, ID *id_to, ID *id_from, const bool do_action)
{
AnimData *adt;
@@ -305,7 +306,7 @@ bool BKE_animdata_copy_id(ID *id_to, ID *id_from, const bool do_action)
adt = BKE_animdata_from_id(id_from);
if (adt) {
IdAdtTemplate *iat = (IdAdtTemplate *)id_to;
- iat->adt = BKE_animdata_copy(adt, do_action);
+ iat->adt = BKE_animdata_copy(bmain, adt, do_action);
}
return true;
@@ -1349,7 +1350,7 @@ void BKE_keyingset_free_path(KeyingSet *ks, KS_Path *ksp)
}
/* Copy all KeyingSets in the given list */
-void BKE_keyingsets_copy(ListBase *newlist, ListBase *list)
+void BKE_keyingsets_copy(ListBase *newlist, const ListBase *list)
{
KeyingSet *ksn;
KS_Path *kspn;
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 81796683761..0f989f0a8ed 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -82,7 +82,7 @@ bArmature *BKE_armature_add(Main *bmain, const char *name)
{
bArmature *arm;
- arm = BKE_libblock_alloc(bmain, ID_AR, name);
+ arm = BKE_libblock_alloc(bmain, ID_AR, name, 0);
arm->deformflag = ARM_DEF_VGROUP | ARM_DEF_ENVELOPE;
arm->flag = ARM_COL_CUSTOM; /* custom bone-group colors */
arm->layer = 1;
@@ -149,54 +149,70 @@ void BKE_armature_make_local(Main *bmain, bArmature *arm, const bool lib_local)
BKE_id_make_local_generic(bmain, &arm->id, true, lib_local);
}
-static void copy_bonechildren(Bone *newBone, const Bone *oldBone, const Bone *actBone, Bone **newActBone)
+static void copy_bonechildren(
+ Bone *bone_dst, const Bone *bone_src, const Bone *bone_src_act, Bone **r_bone_dst_act, const int flag)
{
- Bone *curBone, *newChildBone;
+ Bone *bone_src_child, *bone_dst_child;
- if (oldBone == actBone)
- *newActBone = newBone;
+ if (bone_src == bone_src_act) {
+ *r_bone_dst_act = bone_dst;
+ }
- if (oldBone->prop)
- newBone->prop = IDP_CopyProperty(oldBone->prop);
+ if (bone_src->prop) {
+ bone_dst->prop = IDP_CopyProperty_ex(bone_src->prop, flag);
+ }
/* Copy this bone's list */
- BLI_duplicatelist(&newBone->childbase, &oldBone->childbase);
+ BLI_duplicatelist(&bone_dst->childbase, &bone_src->childbase);
/* For each child in the list, update it's children */
- newChildBone = newBone->childbase.first;
- for (curBone = oldBone->childbase.first; curBone; curBone = curBone->next) {
- newChildBone->parent = newBone;
- copy_bonechildren(newChildBone, curBone, actBone, newActBone);
- newChildBone = newChildBone->next;
+ for (bone_src_child = bone_src->childbase.first, bone_dst_child = bone_dst->childbase.first;
+ bone_src_child;
+ bone_src_child = bone_src_child->next, bone_dst_child = bone_dst_child->next)
+ {
+ bone_dst_child->parent = bone_dst;
+ copy_bonechildren(bone_dst_child, bone_src_child, bone_src_act, r_bone_dst_act, flag);
}
}
-bArmature *BKE_armature_copy(Main *bmain, const bArmature *arm)
+/**
+ * Only copy internal data of Armature ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_armature_copy_data(Main *UNUSED(bmain), bArmature *arm_dst, const bArmature *arm_src, const int flag)
{
- bArmature *newArm;
- Bone *oldBone, *newBone;
- Bone *newActBone = NULL;
+ Bone *bone_src, *bone_dst;
+ Bone *bone_dst_act = NULL;
+
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
- newArm = BKE_libblock_copy(bmain, &arm->id);
- BLI_duplicatelist(&newArm->bonebase, &arm->bonebase);
+ BLI_duplicatelist(&arm_dst->bonebase, &arm_src->bonebase);
/* Duplicate the childrens' lists */
- newBone = newArm->bonebase.first;
- for (oldBone = arm->bonebase.first; oldBone; oldBone = oldBone->next) {
- newBone->parent = NULL;
- copy_bonechildren(newBone, oldBone, arm->act_bone, &newActBone);
- newBone = newBone->next;
+ bone_dst = arm_dst->bonebase.first;
+ for (bone_src = arm_src->bonebase.first; bone_src; bone_src = bone_src->next) {
+ bone_dst->parent = NULL;
+ copy_bonechildren(bone_dst, bone_src, arm_src->act_bone, &bone_dst_act, flag_subdata);
+ bone_dst = bone_dst->next;
}
- newArm->act_bone = newActBone;
-
- newArm->edbo = NULL;
- newArm->act_edbone = NULL;
- newArm->sketch = NULL;
+ arm_dst->act_bone = bone_dst_act;
- BKE_id_copy_ensure_local(bmain, &arm->id, &newArm->id);
+ arm_dst->edbo = NULL;
+ arm_dst->act_edbone = NULL;
+ arm_dst->sketch = NULL;
+}
- return newArm;
+bArmature *BKE_armature_copy(Main *bmain, const bArmature *arm)
+{
+ bArmature *arm_copy;
+ BKE_id_copy_ex(bmain, &arm->id, (ID **)&arm_copy, 0, false);
+ return arm_copy;
}
static Bone *get_named_bone_bonechildren(ListBase *lb, const char *name)
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index aae323a5056..03b0710c8fc 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -152,7 +152,7 @@ Brush *BKE_brush_add(Main *bmain, const char *name, short ob_mode)
{
Brush *brush;
- brush = BKE_libblock_alloc(bmain, ID_BR, name);
+ brush = BKE_libblock_alloc(bmain, ID_BR, name, 0);
BKE_brush_init(brush);
@@ -172,34 +172,38 @@ struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode)
return NULL;
}
-Brush *BKE_brush_copy(Main *bmain, const Brush *brush)
+/**
+ * Only copy internal data of Brush ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_brush_copy_data(Main *UNUSED(bmain), Brush *brush_dst, const Brush *brush_src, const int flag)
{
- Brush *brushn;
-
- brushn = BKE_libblock_copy(bmain, &brush->id);
-
- if (brush->mtex.tex)
- id_us_plus((ID *)brush->mtex.tex);
-
- if (brush->mask_mtex.tex)
- id_us_plus((ID *)brush->mask_mtex.tex);
-
- if (brush->paint_curve)
- id_us_plus((ID *)brush->paint_curve);
-
- if (brush->icon_imbuf)
- brushn->icon_imbuf = IMB_dupImBuf(brush->icon_imbuf);
+ if (brush_src->icon_imbuf) {
+ brush_dst->icon_imbuf = IMB_dupImBuf(brush_src->icon_imbuf);
+ }
- brushn->preview = NULL;
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&brush_dst->id, &brush_src->id);
+ }
+ else {
+ brush_dst->preview = NULL;
+ }
- brushn->curve = curvemapping_copy(brush->curve);
+ brush_dst->curve = curvemapping_copy(brush_src->curve);
/* enable fake user by default */
- id_fake_user_set(&brushn->id);
-
- BKE_id_copy_ensure_local(bmain, &brush->id, &brushn->id);
+ id_fake_user_set(&brush_dst->id);
+}
- return brushn;
+Brush *BKE_brush_copy(Main *bmain, const Brush *brush)
+{
+ Brush *brush_copy;
+ BKE_id_copy_ex(bmain, &brush->id, (ID **)&brush_copy, 0, false);
+ return brush_copy;
}
/** Free (or release) any data used by this brush (does not free the brush itself). */
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index 2294e23d4d5..9d02a27187c 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -66,7 +66,7 @@ void BKE_cachefiles_exit(void)
void *BKE_cachefile_add(Main *bmain, const char *name)
{
- CacheFile *cache_file = BKE_libblock_alloc(bmain, ID_CF, name);
+ CacheFile *cache_file = BKE_libblock_alloc(bmain, ID_CF, name, 0);
BKE_cachefile_init(cache_file);
@@ -100,16 +100,26 @@ void BKE_cachefile_free(CacheFile *cache_file)
BLI_freelistN(&cache_file->object_paths);
}
-CacheFile *BKE_cachefile_copy(Main *bmain, const CacheFile *cache_file)
+/**
+ * Only copy internal data of CacheFile ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_cachefile_copy_data(
+ Main *UNUSED(bmain), CacheFile *cache_file_dst, const CacheFile *UNUSED(cache_file_src), const int UNUSED(flag))
{
- CacheFile *new_cache_file = BKE_libblock_copy(bmain, &cache_file->id);
- new_cache_file->handle = NULL;
-
- BLI_listbase_clear(&new_cache_file->object_paths);
-
- BKE_id_copy_ensure_local(bmain, &cache_file->id, &new_cache_file->id);
+ cache_file_dst->handle = NULL;
+ BLI_listbase_clear(&cache_file_dst->object_paths);
+}
- return new_cache_file;
+CacheFile *BKE_cachefile_copy(Main *bmain, const CacheFile *cache_file)
+{
+ CacheFile *cache_file_copy;
+ BKE_id_copy_ex(bmain, &cache_file->id, (ID **)&cache_file_copy, 0, false);
+ return cache_file_copy;
}
void BKE_cachefile_make_local(Main *bmain, CacheFile *cache_file, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 2e36de4e8d4..97bb679f8b0 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -86,22 +86,31 @@ void *BKE_camera_add(Main *bmain, const char *name)
{
Camera *cam;
- cam = BKE_libblock_alloc(bmain, ID_CA, name);
+ cam = BKE_libblock_alloc(bmain, ID_CA, name, 0);
BKE_camera_init(cam);
return cam;
}
-Camera *BKE_camera_copy(Main *bmain, const Camera *cam)
+/**
+ * Only copy internal data of Camera ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_camera_copy_data(Main *UNUSED(bmain), Camera *UNUSED(cam_dst), const Camera *UNUSED(cam_src), const int UNUSED(flag))
{
- Camera *camn;
-
- camn = BKE_libblock_copy(bmain, &cam->id);
-
- BKE_id_copy_ensure_local(bmain, &cam->id, &camn->id);
+ /* Nothing to do! */
+}
- return camn;
+Camera *BKE_camera_copy(Main *bmain, const Camera *cam)
+{
+ Camera *cam_copy;
+ BKE_id_copy_ex(bmain, &cam->id, (ID **)&cam_copy, 0, false);
+ return cam_copy;
}
void BKE_camera_make_local(Main *bmain, Camera *cam, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index ac7168b6561..1bd7a01b1b8 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -4737,29 +4737,30 @@ static void con_fix_copied_refs_cb(bConstraint *UNUSED(con), ID **idpoin, bool i
}
/* duplicate all of the constraints in a constraint stack */
-void BKE_constraints_copy(ListBase *dst, const ListBase *src, bool do_extern)
+void BKE_constraints_copy_ex(ListBase *dst, const ListBase *src, const int flag, bool do_extern)
{
bConstraint *con, *srccon;
-
+
BLI_listbase_clear(dst);
BLI_duplicatelist(dst, src);
-
+
for (con = dst->first, srccon = src->first; con && srccon; srccon = srccon->next, con = con->next) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
-
+
/* make a new copy of the constraint's data */
con->data = MEM_dupallocN(con->data);
-
+
/* only do specific constraints if required */
if (cti) {
/* perform custom copying operations if needed */
if (cti->copy_data)
cti->copy_data(con, srccon);
-
- /* fix usercounts for all referenced data in referenced data */
- if (cti->id_looper)
+
+ /* Fix usercounts for all referenced data that need it. */
+ if (cti->id_looper && (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
cti->id_looper(con, con_fix_copied_refs_cb, NULL);
-
+ }
+
/* for proxies we don't want to make extern */
if (do_extern) {
/* go over used ID-links for this constraint to ensure that they are valid for proxies */
@@ -4770,6 +4771,11 @@ void BKE_constraints_copy(ListBase *dst, const ListBase *src, bool do_extern)
}
}
+void BKE_constraints_copy(ListBase *dst, const ListBase *src, bool do_extern)
+{
+ BKE_constraints_copy_ex(dst, src, 0, do_extern);
+}
+
/* ......... */
bConstraint *BKE_constraints_find_name(ListBase *list, const char *name)
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 6018c07835b..f613fe388aa 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -182,7 +182,7 @@ Curve *BKE_curve_add(Main *bmain, const char *name, int type)
{
Curve *cu;
- cu = BKE_libblock_alloc(bmain, ID_CU, name);
+ cu = BKE_libblock_alloc(bmain, ID_CU, name, 0);
cu->type = type;
BKE_curve_init(cu);
@@ -190,43 +190,40 @@ Curve *BKE_curve_add(Main *bmain, const char *name, int type)
return cu;
}
-Curve *BKE_curve_copy(Main *bmain, const Curve *cu)
+/**
+ * Only copy internal data of Curve ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_curve_copy_data(Main *bmain, Curve *cu_dst, const Curve *cu_src, const int flag)
{
- Curve *cun;
- int a;
-
- cun = BKE_libblock_copy(bmain, &cu->id);
+ BLI_listbase_clear(&cu_dst->nurb);
+ BKE_nurbList_duplicate(&(cu_dst->nurb), &(cu_src->nurb));
- BLI_listbase_clear(&cun->nurb);
- BKE_nurbList_duplicate(&(cun->nurb), &(cu->nurb));
+ cu_dst->mat = MEM_dupallocN(cu_src->mat);
- cun->mat = MEM_dupallocN(cu->mat);
- for (a = 0; a < cun->totcol; a++) {
- id_us_plus((ID *)cun->mat[a]);
- }
-
- cun->str = MEM_dupallocN(cu->str);
- cun->strinfo = MEM_dupallocN(cu->strinfo);
- cun->tb = MEM_dupallocN(cu->tb);
- cun->bb = MEM_dupallocN(cu->bb);
- cun->batch_cache = NULL;
+ cu_dst->str = MEM_dupallocN(cu_src->str);
+ cu_dst->strinfo = MEM_dupallocN(cu_src->strinfo);
+ cu_dst->tb = MEM_dupallocN(cu_src->tb);
+ cu_dst->bb = MEM_dupallocN(cu_src->bb);
+ cu_dst->batch_cache = NULL;
- if (cu->key) {
- cun->key = BKE_key_copy(bmain, cu->key);
- cun->key->from = (ID *)cun;
+ if (cu_src->key) {
+ BKE_id_copy_ex(bmain, &cu_src->key->id, (ID **)&cu_dst->key, flag, false);
}
- cun->editnurb = NULL;
- cun->editfont = NULL;
-
- id_us_plus((ID *)cun->vfont);
- id_us_plus((ID *)cun->vfontb);
- id_us_plus((ID *)cun->vfonti);
- id_us_plus((ID *)cun->vfontbi);
-
- BKE_id_copy_ensure_local(bmain, &cu->id, &cun->id);
+ cu_dst->editnurb = NULL;
+ cu_dst->editfont = NULL;
+}
- return cun;
+Curve *BKE_curve_copy(Main *bmain, const Curve *cu)
+{
+ Curve *cu_copy;
+ BKE_id_copy_ex(bmain, &cu->id, (ID **)&cu_copy, 0, false);
+ return cu_copy;
}
void BKE_curve_make_local(Main *bmain, Curve *cu, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 401fed74c52..d6b28cfaf70 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -106,6 +106,23 @@ void BKE_vfont_free(struct VFont *vf)
}
}
+void BKE_vfont_copy_data(Main *UNUSED(bmain), VFont *vfont_dst, const VFont *UNUSED(vfont_src), const int flag)
+{
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
+
+ /* Just to be sure, should not have any value actually after reading time. */
+ vfont_dst->temp_pf = NULL;
+
+ if (vfont_dst->packedfile) {
+ vfont_dst->packedfile = dupPackedFile(vfont_dst->packedfile);
+ }
+
+ if (vfont_dst->data) {
+ vfont_dst->data = BLI_vfontdata_copy(vfont_dst->data, flag_subdata);
+ }
+}
+
static void *builtin_font_data = NULL;
static int builtin_font_size = 0;
@@ -249,7 +266,7 @@ VFont *BKE_vfont_load(Main *bmain, const char *filepath)
vfd = BLI_vfontdata_from_freetypefont(pf);
if (vfd) {
- vfont = BKE_libblock_alloc(bmain, ID_VF, filename);
+ vfont = BKE_libblock_alloc(bmain, ID_VF, filename, 0);
vfont->data = vfd;
/* if there's a font name, use it for the ID name */
diff --git a/source/blender/blenkernel/intern/freestyle.c b/source/blender/blenkernel/intern/freestyle.c
index 0a0b023df82..e45a938a4fc 100644
--- a/source/blender/blenkernel/intern/freestyle.c
+++ b/source/blender/blenkernel/intern/freestyle.c
@@ -44,7 +44,7 @@
// function declarations
static FreestyleLineSet *alloc_lineset(void);
-static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *lineset);
+static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *lineset, const int flag);
static FreestyleModuleConfig *alloc_module(void);
static void copy_module(FreestyleModuleConfig *new_module, FreestyleModuleConfig *module);
@@ -79,7 +79,7 @@ void BKE_freestyle_config_free(FreestyleConfig *config)
BLI_freelistN(&config->modules);
}
-void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *config)
+void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *config, const int flag)
{
FreestyleLineSet *lineset, *new_lineset;
FreestyleModuleConfig *module, *new_module;
@@ -93,7 +93,7 @@ void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *con
BLI_listbase_clear(&new_config->linesets);
for (lineset = (FreestyleLineSet *)config->linesets.first; lineset; lineset = lineset->next) {
new_lineset = alloc_lineset();
- copy_lineset(new_lineset, lineset);
+ copy_lineset(new_lineset, lineset, flag);
BLI_addtail(&new_config->linesets, (void *)new_lineset);
}
@@ -105,11 +105,9 @@ void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *con
}
}
-static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *lineset)
+static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *lineset, const int flag)
{
new_lineset->linestyle = lineset->linestyle;
- if (new_lineset->linestyle)
- id_us_plus(&new_lineset->linestyle->id);
new_lineset->flags = lineset->flags;
new_lineset->selection = lineset->selection;
new_lineset->qi = lineset->qi;
@@ -118,10 +116,12 @@ static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *linese
new_lineset->edge_types = lineset->edge_types;
new_lineset->exclude_edge_types = lineset->exclude_edge_types;
new_lineset->group = lineset->group;
- if (new_lineset->group) {
- id_us_plus(&new_lineset->group->id);
- }
strcpy(new_lineset->name, lineset->name);
+
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)new_lineset->linestyle);
+ id_us_plus((ID *)new_lineset->group);
+ }
}
static FreestyleModuleConfig *alloc_module(void)
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 758438bb051..ee0d0b41898 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -627,7 +627,7 @@ bGPdata *BKE_gpencil_data_addnew(const char name[])
bGPdata *gpd;
/* allocate memory for a new block */
- gpd = BKE_libblock_alloc(G.main, ID_GD, name);
+ gpd = BKE_libblock_alloc(G.main, ID_GD, name, 0);
/* initial settings */
gpd->flag = (GP_DATA_DISPINFO | GP_DATA_EXPAND);
@@ -753,47 +753,62 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src)
return gpl_dst;
}
-/* make a copy of a given gpencil datablock */
-bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool internal_copy)
+/**
+ * Only copy internal data of GreasePencil ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_gpencil_copy_data(Main *UNUSED(bmain), bGPdata *gpd_dst, const bGPdata *gpd_src, const int UNUSED(flag))
{
- const bGPDlayer *gpl_src;
- bGPDlayer *gpl_dst;
- bGPdata *gpd_dst;
+ /* copy layers */
+ BLI_listbase_clear(&gpd_dst->layers);
+ for (const bGPDlayer *gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) {
+ /* make a copy of source layer and its data */
+ bGPDlayer *gpl_dst = BKE_gpencil_layer_duplicate(gpl_src); /* TODO here too could add unused flags... */
+ BLI_addtail(&gpd_dst->layers, gpl_dst);
+ }
- /* error checking */
- if (gpd_src == NULL) {
- return NULL;
+ /* copy palettes */
+ BLI_listbase_clear(&gpd_dst->palettes);
+ for (const bGPDpalette *palette_src = gpd_src->palettes.first; palette_src; palette_src = palette_src->next) {
+ bGPDpalette *palette_dst = BKE_gpencil_palette_duplicate(palette_src); /* TODO here too could add unused flags... */
+ BLI_addtail(&gpd_dst->palettes, palette_dst);
}
-
- /* make a copy of the base-data */
+}
+
+/* make a copy of a given gpencil datablock */
+bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool internal_copy)
+{
+ /* Yuck and super-uber-hyper yuck!!!
+ * Should be replaceable with a no-main copy (LIB_ID_COPY_NO_MAIN etc.), but not sure about it,
+ * so for now keep old code for that one. */
if (internal_copy) {
+ const bGPDlayer *gpl_src;
+ bGPDlayer *gpl_dst;
+ bGPdata *gpd_dst;
+
/* make a straight copy for undo buffers used during stroke drawing */
gpd_dst = MEM_dupallocN(gpd_src);
+
+ /* copy layers */
+ BLI_listbase_clear(&gpd_dst->layers);
+ for (gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) {
+ /* make a copy of source layer and its data */
+ gpl_dst = BKE_gpencil_layer_duplicate(gpl_src);
+ BLI_addtail(&gpd_dst->layers, gpl_dst);
+ }
+
+ /* return new */
+ return gpd_dst;
}
else {
- /* make a copy when others use this */
- gpd_dst = BKE_libblock_copy(bmain, &gpd_src->id);
- }
-
- /* copy layers */
- BLI_listbase_clear(&gpd_dst->layers);
- for (gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) {
- /* make a copy of source layer and its data */
- gpl_dst = BKE_gpencil_layer_duplicate(gpl_src);
- BLI_addtail(&gpd_dst->layers, gpl_dst);
- }
- if (!internal_copy) {
- /* copy palettes */
- bGPDpalette *palette_src, *palette_dst;
- BLI_listbase_clear(&gpd_dst->palettes);
- for (palette_src = gpd_src->palettes.first; palette_src; palette_src = palette_src->next) {
- palette_dst = BKE_gpencil_palette_duplicate(palette_src);
- BLI_addtail(&gpd_dst->palettes, palette_dst);
- }
+ bGPdata *gpd_copy;
+ BKE_id_copy_ex(bmain, &gpd_src->id, (ID **)&gpd_copy, 0, false);
+ return gpd_copy;
}
-
- /* return new */
- return gpd_dst;
}
void BKE_gpencil_make_local(Main *bmain, bGPdata *gpd, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 94a341de366..d584cb03b90 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -77,7 +77,7 @@ Group *BKE_group_add(Main *bmain, const char *name)
{
Group *group;
- group = BKE_libblock_alloc(bmain, ID_GR, name);
+ group = BKE_libblock_alloc(bmain, ID_GR, name, 0);
id_us_min(&group->id);
id_us_ensure_real(&group->id);
group->layer = (1 << 20) - 1;
@@ -87,19 +87,32 @@ Group *BKE_group_add(Main *bmain, const char *name)
return group;
}
-Group *BKE_group_copy(Main *bmain, const Group *group)
+/**
+ * Only copy internal data of Group ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_group_copy_data(Main *UNUSED(bmain), Group *group_dst, const Group *group_src, const int flag)
{
- Group *groupn;
-
- groupn = BKE_libblock_copy(bmain, &group->id);
- BLI_duplicatelist(&groupn->gobject, &group->gobject);
+ BLI_duplicatelist(&group_dst->gobject, &group_src->gobject);
/* Do not copy group's preview (same behavior as for objects). */
- groupn->preview = NULL;
-
- BKE_id_copy_ensure_local(bmain, &group->id, &groupn->id);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0 && false) { /* XXX TODO temp hack */
+ BKE_previewimg_id_copy(&group_dst->id, &group_src->id);
+ }
+ else {
+ group_dst->preview = NULL;
+ }
+}
- return groupn;
+Group *BKE_group_copy(Main *bmain, const Group *group)
+{
+ Group *group_copy;
+ BKE_id_copy_ex(bmain, &group->id, (ID **)&group_copy, 0, false);
+ return group_copy;
}
void BKE_group_make_local(Main *bmain, Group *group, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index a3bd15252cb..9796903afc4 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -90,7 +90,7 @@ IDProperty *IDP_NewIDPArray(const char *name)
return prop;
}
-IDProperty *IDP_CopyIDPArray(const IDProperty *array)
+IDProperty *IDP_CopyIDPArray(const IDProperty *array, const int flag)
{
/* don't use MEM_dupallocN because this may be part of an array */
IDProperty *narray, *tmp;
@@ -109,7 +109,7 @@ IDProperty *IDP_CopyIDPArray(const IDProperty *array)
* then free it. this makes for more maintainable
* code than simply reimplementing the copy functions
* in this loop.*/
- tmp = IDP_CopyProperty(GETPROP(narray, i));
+ tmp = IDP_CopyProperty_ex(GETPROP(narray, i), flag);
memcpy(GETPROP(narray, i), tmp, sizeof(IDProperty));
MEM_freeN(tmp);
}
@@ -285,9 +285,9 @@ void IDP_FreeArray(IDProperty *prop)
}
-static IDProperty *idp_generic_copy(const IDProperty *prop)
+static IDProperty *idp_generic_copy(const IDProperty *prop, const int UNUSED(flag))
{
- IDProperty *newp = MEM_callocN(sizeof(IDProperty), "IDProperty array dup");
+ IDProperty *newp = MEM_callocN(sizeof(IDProperty), __func__);
BLI_strncpy(newp->name, prop->name, MAX_IDPROP_NAME);
newp->type = prop->type;
@@ -298,9 +298,9 @@ static IDProperty *idp_generic_copy(const IDProperty *prop)
return newp;
}
-static IDProperty *IDP_CopyArray(const IDProperty *prop)
+static IDProperty *IDP_CopyArray(const IDProperty *prop, const int flag)
{
- IDProperty *newp = idp_generic_copy(prop);
+ IDProperty *newp = idp_generic_copy(prop, flag);
if (prop->data.pointer) {
newp->data.pointer = MEM_dupallocN(prop->data.pointer);
@@ -310,7 +310,7 @@ static IDProperty *IDP_CopyArray(const IDProperty *prop)
int a;
for (a = 0; a < prop->len; a++)
- array[a] = IDP_CopyProperty(array[a]);
+ array[a] = IDP_CopyProperty_ex(array[a], flag);
}
}
newp->len = prop->len;
@@ -363,12 +363,12 @@ IDProperty *IDP_NewString(const char *st, const char *name, int maxlen)
return prop;
}
-static IDProperty *IDP_CopyString(const IDProperty *prop)
+static IDProperty *IDP_CopyString(const IDProperty *prop, const int flag)
{
IDProperty *newp;
BLI_assert(prop->type == IDP_STRING);
- newp = idp_generic_copy(prop);
+ newp = idp_generic_copy(prop, flag);
if (prop->data.pointer)
newp->data.pointer = MEM_dupallocN(prop->data.pointer);
@@ -442,15 +442,17 @@ void IDP_FreeString(IDProperty *prop)
/** \name IDProperty ID API
* \{ */
-static IDProperty *IDP_CopyID(const IDProperty *prop)
+static IDProperty *IDP_CopyID(const IDProperty *prop, const int flag)
{
IDProperty *newp;
BLI_assert(prop->type == IDP_ID);
- newp = idp_generic_copy(prop);
+ newp = idp_generic_copy(prop, flag);
newp->data.pointer = prop->data.pointer;
- id_us_plus(IDP_Id(newp));
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus(IDP_Id(newp));
+ }
return newp;
}
@@ -467,17 +469,17 @@ static IDProperty *IDP_CopyID(const IDProperty *prop)
/**
* Checks if a property with the same name as prop exists, and if so replaces it.
*/
-static IDProperty *IDP_CopyGroup(const IDProperty *prop)
+static IDProperty *IDP_CopyGroup(const IDProperty *prop, const int flag)
{
IDProperty *newp, *link;
BLI_assert(prop->type == IDP_GROUP);
- newp = idp_generic_copy(prop);
+ newp = idp_generic_copy(prop, flag);
newp->len = prop->len;
newp->subtype = prop->subtype;
for (link = prop->data.group.first; link; link = link->next) {
- BLI_addtail(&newp->data.group, IDP_CopyProperty(link));
+ BLI_addtail(&newp->data.group, IDP_CopyProperty_ex(link, flag));
}
return newp;
@@ -748,18 +750,23 @@ static void IDP_FreeGroup(IDProperty *prop, const bool do_id_user)
/** \name IDProperty Main API
* \{ */
-IDProperty *IDP_CopyProperty(const IDProperty *prop)
+IDProperty *IDP_CopyProperty_ex(const IDProperty *prop, const int flag)
{
switch (prop->type) {
- case IDP_GROUP: return IDP_CopyGroup(prop);
- case IDP_STRING: return IDP_CopyString(prop);
- case IDP_ID: return IDP_CopyID(prop);
- case IDP_ARRAY: return IDP_CopyArray(prop);
- case IDP_IDPARRAY: return IDP_CopyIDPArray(prop);
- default: return idp_generic_copy(prop);
+ case IDP_GROUP: return IDP_CopyGroup(prop, flag);
+ case IDP_STRING: return IDP_CopyString(prop, flag);
+ case IDP_ID: return IDP_CopyID(prop, flag);
+ case IDP_ARRAY: return IDP_CopyArray(prop, flag);
+ case IDP_IDPARRAY: return IDP_CopyIDPArray(prop, flag);
+ default: return idp_generic_copy(prop, flag);
}
}
+IDProperty *IDP_CopyProperty(const IDProperty *prop)
+{
+ return IDP_CopyProperty_ex(prop, 0);
+}
+
/* Updates ID pointers after an object has been copied */
/* TODO Nuke this once its only user has been correctly converted to use generic ID management from BKE_library! */
void IDP_RelinkProperty(struct IDProperty *prop)
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 2915e9d715d..355aa67a947 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -383,7 +383,7 @@ static Image *image_alloc(Main *bmain, const char *name, short source, short typ
{
Image *ima;
- ima = BKE_libblock_alloc(bmain, ID_IM, name);
+ ima = BKE_libblock_alloc(bmain, ID_IM, name, 0);
if (ima) {
image_init(ima, source, type);
}
@@ -434,39 +434,53 @@ static void copy_image_packedfiles(ListBase *lb_dst, const ListBase *lb_src)
}
}
-/* empty image block, of similar type and filename */
-Image *BKE_image_copy(Main *bmain, const Image *ima)
+/**
+ * Only copy internal data of Image ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_image_copy_data(Main *UNUSED(bmain), Image *ima_dst, const Image *ima_src, const int flag)
{
- Image *nima = image_alloc(bmain, ima->id.name + 2, ima->source, ima->type);
-
- BLI_strncpy(nima->name, ima->name, sizeof(ima->name));
-
- nima->flag = ima->flag;
- nima->tpageflag = ima->tpageflag;
-
- nima->gen_x = ima->gen_x;
- nima->gen_y = ima->gen_y;
- nima->gen_type = ima->gen_type;
- copy_v4_v4(nima->gen_color, ima->gen_color);
-
- nima->animspeed = ima->animspeed;
+ BKE_color_managed_colorspace_settings_copy(&ima_dst->colorspace_settings, &ima_src->colorspace_settings);
- nima->aspx = ima->aspx;
- nima->aspy = ima->aspy;
+ copy_image_packedfiles(&ima_dst->packedfiles, &ima_src->packedfiles);
- BKE_color_managed_colorspace_settings_copy(&nima->colorspace_settings, &ima->colorspace_settings);
+ ima_dst->stereo3d_format = MEM_dupallocN(ima_src->stereo3d_format);
+ BLI_duplicatelist(&ima_dst->views, &ima_src->views);
- copy_image_packedfiles(&nima->packedfiles, &ima->packedfiles);
+ /* Cleanup stuff that cannot be copied. */
+ ima_dst->cache = NULL;
+ ima_dst->rr = NULL;
+ for (int i = 0; i < IMA_MAX_RENDER_SLOT; i++) {
+ ima_dst->renders[i] = NULL;
+ }
- /* nima->stere3d_format is already allocated by image_alloc... */
- *nima->stereo3d_format = *ima->stereo3d_format;
- BLI_duplicatelist(&nima->views, &ima->views);
+ BLI_listbase_clear(&ima_dst->anims);
- BKE_previewimg_id_copy(&nima->id, &ima->id);
+ ima_dst->totbind = 0;
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ ima_dst->bindcode[i] = 0;
+ ima_dst->gputexture[i] = NULL;
+ }
+ ima_dst->repbind = NULL;
- BKE_id_copy_ensure_local(bmain, &ima->id, &nima->id);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&ima_dst->id, &ima_src->id);
+ }
+ else {
+ ima_dst->preview = NULL;
+ }
+}
- return nima;
+/* empty image block, of similar type and filename */
+Image *BKE_image_copy(Main *bmain, const Image *ima)
+{
+ Image *ima_copy;
+ BKE_id_copy_ex(bmain, &ima->id, (ID **)&ima_copy, 0, false);
+ return ima_copy;
}
void BKE_image_make_local(Main *bmain, Image *ima, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 98b251294ae..364817438c5 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -107,7 +107,7 @@ Key *BKE_key_add(ID *id) /* common function */
Key *key;
char *el;
- key = BKE_libblock_alloc(G.main, ID_KE, "Key");
+ key = BKE_libblock_alloc(G.main, ID_KE, "Key", 0);
key->type = KEY_NORMAL;
key->from = id;
@@ -151,31 +151,40 @@ Key *BKE_key_add(ID *id) /* common function */
return key;
}
-Key *BKE_key_copy(Main *bmain, const Key *key)
+/**
+ * Only copy internal data of ShapeKey ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_key_copy_data(Main *UNUSED(bmain), Key *key_dst, const Key *key_src, const int UNUSED(flag))
{
- Key *keyn;
- KeyBlock *kbn, *kb;
-
- keyn = BKE_libblock_copy(bmain, &key->id);
-
- BLI_duplicatelist(&keyn->block, &key->block);
-
- kb = key->block.first;
- kbn = keyn->block.first;
- while (kbn) {
-
- if (kbn->data) kbn->data = MEM_dupallocN(kbn->data);
- if (kb == key->refkey) keyn->refkey = kbn;
-
- kbn = kbn->next;
- kb = kb->next;
- }
+ BLI_duplicatelist(&key_dst->block, &key_src->block);
- BKE_id_copy_ensure_local(bmain, &key->id, &keyn->id);
+ KeyBlock *kb_dst, *kb_src;
+ for (kb_src = key_src->block.first, kb_dst = key_dst->block.first;
+ kb_dst;
+ kb_src = kb_src->next, kb_dst = kb_dst->next)
+ {
+ if (kb_dst->data) {
+ kb_dst->data = MEM_dupallocN(kb_dst->data);
+ }
+ if (kb_src == key_src->refkey) {
+ key_dst->refkey = kb_dst;
+ }
+ }
+}
- return keyn;
+Key *BKE_key_copy(Main *bmain, const Key *key)
+{
+ Key *key_copy;
+ BKE_id_copy_ex(bmain, &key->id, (ID **)&key_copy, 0, false);
+ return key_copy;
}
+/* XXX TODO get rid of this! */
Key *BKE_key_copy_nolib(Key *key)
{
Key *keyn;
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index 4a3a1c50195..dc736b3f084 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -110,42 +110,60 @@ Lamp *BKE_lamp_add(Main *bmain, const char *name)
{
Lamp *la;
- la = BKE_libblock_alloc(bmain, ID_LA, name);
+ la = BKE_libblock_alloc(bmain, ID_LA, name, 0);
BKE_lamp_init(la);
return la;
}
-Lamp *BKE_lamp_copy(Main *bmain, const Lamp *la)
+/**
+ * Only copy internal data of Lamp ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_lamp_copy_data(Main *bmain, Lamp *la_dst, const Lamp *la_src, const int flag)
{
- Lamp *lan;
- int a;
-
- lan = BKE_libblock_copy(bmain, &la->id);
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (lan->mtex[a]) {
- lan->mtex[a] = MEM_mallocN(sizeof(MTex), "copylamptex");
- memcpy(lan->mtex[a], la->mtex[a], sizeof(MTex));
- id_us_plus((ID *)lan->mtex[a]->tex);
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (la_dst->mtex[a]) {
+ la_dst->mtex[a] = MEM_mallocN(sizeof(*la_dst->mtex[a]), __func__);
+ *la_dst->mtex[a] = *la_src->mtex[a];
}
}
-
- lan->curfalloff = curvemapping_copy(la->curfalloff);
- if (la->nodetree)
- lan->nodetree = ntreeCopyTree(bmain, la->nodetree);
+ la_dst->curfalloff = curvemapping_copy(la_src->curfalloff);
- BKE_previewimg_id_copy(&lan->id, &la->id);
+ if (la_src->nodetree) {
+ BKE_id_copy_ex(bmain, (ID *)la_src->nodetree, (ID **)&la_dst->nodetree, flag, false);
+ }
- BKE_id_copy_ensure_local(bmain, &la->id, &lan->id);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&la_dst->id, &la_src->id);
+ }
+ else {
+ la_dst->preview = NULL;
+ }
+}
- return lan;
+Lamp *BKE_lamp_copy(Main *bmain, const Lamp *la)
+{
+ Lamp *la_copy;
+ BKE_id_copy_ex(bmain, &la->id, (ID **)&la_copy, 0, false);
+ return la_copy;
}
Lamp *localize_lamp(Lamp *la)
{
+ /* TODO replace with something like
+ * Lamp *la_copy;
+ * BKE_id_copy_ex(bmain, &la->id, (ID **)&la_copy, LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT, false);
+ * return la_copy;
+ *
+ * ... Once f*** nodes are fully converted to that too :( */
+
Lamp *lan;
int a;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index fd984c17356..9f382020555 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -269,39 +269,46 @@ Lattice *BKE_lattice_add(Main *bmain, const char *name)
{
Lattice *lt;
- lt = BKE_libblock_alloc(bmain, ID_LT, name);
+ lt = BKE_libblock_alloc(bmain, ID_LT, name, 0);
BKE_lattice_init(lt);
return lt;
}
-Lattice *BKE_lattice_copy(Main *bmain, const Lattice *lt)
+/**
+ * Only copy internal data of Lattice ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_lattice_copy_data(Main *bmain, Lattice *lt_dst, const Lattice *lt_src, const int flag)
{
- Lattice *ltn;
-
- ltn = BKE_libblock_copy(bmain, &lt->id);
- ltn->def = MEM_dupallocN(lt->def);
+ lt_dst->def = MEM_dupallocN(lt_src->def);
- if (lt->key) {
- ltn->key = BKE_key_copy(bmain, ltn->key);
- ltn->key->from = (ID *)ltn;
- }
-
- if (lt->dvert) {
- int tot = lt->pntsu * lt->pntsv * lt->pntsw;
- ltn->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
- BKE_defvert_array_copy(ltn->dvert, lt->dvert, tot);
+ if (lt_src->key) {
+ BKE_id_copy_ex(bmain, &lt_src->key->id, (ID **)&lt_dst->key, flag, false);
}
- ltn->editlatt = NULL;
+ if (lt_src->dvert) {
+ int tot = lt_src->pntsu * lt_src->pntsv * lt_src->pntsw;
+ lt_dst->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
+ BKE_defvert_array_copy(lt_dst->dvert, lt_src->dvert, tot);
+ }
- BKE_id_copy_ensure_local(bmain, &lt->id, &ltn->id);
+ lt_dst->editlatt = NULL;
+}
- return ltn;
+Lattice *BKE_lattice_copy(Main *bmain, const Lattice *lt)
+{
+ Lattice *lt_copy;
+ BKE_id_copy_ex(bmain, &lt->id, (ID **)&lt_copy, 0, false);
+ return lt_copy;
}
-/** Free (or release) any data used by this lattice (does not free the lattice itself). */
+ /** Free (or release) any data used by this lattice (does not free the lattice itself). */
void BKE_lattice_free(Lattice *lt)
{
BKE_animdata_free(&lt->id, false);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index ed64de9b1aa..92ddbe99f00 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -385,7 +385,6 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
switch ((ID_Type)GS(id->name)) {
case ID_SCE:
- /* Partially implemented (has no copy...). */
if (!test) BKE_scene_make_local(bmain, (Scene *)id, lib_local);
return true;
case ID_OB:
@@ -428,14 +427,12 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
if (!test) BKE_world_make_local(bmain, (World *)id, lib_local);
return true;
case ID_VF:
- /* Partially implemented (has no copy...). */
if (!test) BKE_vfont_make_local(bmain, (VFont *)id, lib_local);
return true;
case ID_TXT:
if (!test) BKE_text_make_local(bmain, (Text *)id, lib_local);
return true;
case ID_SO:
- /* Partially implemented (has no copy...). */
if (!test) BKE_sound_make_local(bmain, (bSound *)id, lib_local);
return true;
case ID_GR:
@@ -493,118 +490,191 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
return false;
}
+struct IDCopyLibManagementData {
+ const ID *id_src;
+ int flag;
+};
+
+/* Increases usercount as required, and remap self ID pointers. */
+static int id_copy_libmanagement_cb(void *user_data, ID *id_self, ID **id_pointer, int cb_flag)
+{
+ struct IDCopyLibManagementData *data = user_data;
+ ID *id = *id_pointer;
+
+ /* Remap self-references to new copied ID. */
+ if (id == data->id_src) {
+ id = *id_pointer = id_self;
+ }
+
+ /* Increase used IDs refcount if needed and required. */
+ if ((data->flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0 && (cb_flag & IDWALK_CB_USER)) {
+ id_us_plus(id);
+ }
+
+ return IDWALK_RET_NOP;
+}
+
/**
- * Invokes the appropriate copy method for the block and returns the result in
- * newid, unless test. Returns true if the block can be copied.
+ * Generic entry point for copying a datablock (new API).
+ *
+ * \note Copy is only affecting given data-block (no ID used by copied one will be affected, besides usercount).
+ * There is only one exception, if LIB_ID_COPY_ACTIONS is defined, actions used by animdata will be duplicated.
+ *
+ * \note Usercount of new copy is always set to 1.
+ *
+ * \param bmain Main database, may be NULL only if LIB_ID_COPY_NO_MAIN is specified.
+ * \param id Source datablock.
+ * \param r_newid Pointer to new (copied) ID pointer.
+ * \param flag Set of copy options, see DNA_ID.h enum for details (leave to zero for default, full copy).
+ * \param test If set, do not do any copy, just test whether copy is supported.
+ * \return False when copying that ID type is not supported, true otherwise.
*/
-bool id_copy(Main *bmain, const ID *id, ID **newid, bool test)
+/* XXX TODO remove test thing, *all* IDs should be copyable that way! */
+bool BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag, const bool test)
{
- if (!test) {
- *newid = NULL;
+#define LIB_ID_TYPES_NOCOPY ID_LI, ID_SCR, ID_WM, /* Not supported */ \
+ ID_IP /* Deprecated */
+
+ BLI_assert(test || (r_newid != NULL));
+ if (r_newid != NULL) {
+ *r_newid = NULL;
+ }
+ if (id == NULL) {
+ return false;
+ }
+
+ if (ELEM(GS(id->name), LIB_ID_TYPES_NOCOPY)) {
+ return false;
+ }
+ else if (test) {
+ return true;
}
- /* conventions:
- * - make shallow copy, only this ID block
- * - id.us of the new ID is set to 1 */
+ 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:
- if (!test) *newid = (ID *)BKE_object_copy(bmain, (Object *)id);
- return true;
+ BKE_object_copy_data(bmain, (Object *)*r_newid, (Object *)id, flag);
+ break;
case ID_ME:
- if (!test) *newid = (ID *)BKE_mesh_copy(bmain, (Mesh *)id);
- return true;
+ BKE_mesh_copy_data(bmain, (Mesh *)*r_newid, (Mesh *)id, flag);
+ break;
case ID_CU:
- if (!test) *newid = (ID *)BKE_curve_copy(bmain, (Curve *)id);
- return true;
+ BKE_curve_copy_data(bmain, (Curve *)*r_newid, (Curve *)id, flag);
+ break;
case ID_MB:
- if (!test) *newid = (ID *)BKE_mball_copy(bmain, (MetaBall *)id);
- return true;
+ BKE_mball_copy_data(bmain, (MetaBall *)*r_newid, (MetaBall *)id, flag);
+ break;
case ID_MA:
- if (!test) *newid = (ID *)BKE_material_copy(bmain, (Material *)id);
- return true;
+ BKE_material_copy_data(bmain, (Material *)*r_newid, (Material *)id, flag);
+ break;
case ID_TE:
- if (!test) *newid = (ID *)BKE_texture_copy(bmain, (Tex *)id);
- return true;
+ BKE_texture_copy_data(bmain, (Tex *)*r_newid, (Tex *)id, flag);
+ break;
case ID_IM:
- if (!test) *newid = (ID *)BKE_image_copy(bmain, (Image *)id);
- return true;
+ BKE_image_copy_data(bmain, (Image *)*r_newid, (Image *)id, flag);
+ break;
case ID_LT:
- if (!test) *newid = (ID *)BKE_lattice_copy(bmain, (Lattice *)id);
- return true;
+ BKE_lattice_copy_data(bmain, (Lattice *)*r_newid, (Lattice *)id, flag);
+ break;
case ID_LA:
- if (!test) *newid = (ID *)BKE_lamp_copy(bmain, (Lamp *)id);
- return true;
+ BKE_lamp_copy_data(bmain, (Lamp *)*r_newid, (Lamp *)id, flag);
+ break;
case ID_SPK:
- if (!test) *newid = (ID *)BKE_speaker_copy(bmain, (Speaker *)id);
- return true;
+ BKE_speaker_copy_data(bmain, (Speaker *)*r_newid, (Speaker *)id, flag);
+ break;
case ID_LP:
- if (!test) *newid = (ID *)BKE_lightprobe_copy(bmain, (LightProbe *)id);
- return true;
+ BKE_lightprobe_copy_data(bmain, (LightProbe *)*r_newid, (LightProbe *)id, flag);
+ break;
case ID_CA:
- if (!test) *newid = (ID *)BKE_camera_copy(bmain, (Camera *)id);
- return true;
+ BKE_camera_copy_data(bmain, (Camera *)*r_newid, (Camera *)id, flag);
+ break;
case ID_KE:
- if (!test) *newid = (ID *)BKE_key_copy(bmain, (Key *)id);
- return true;
+ BKE_key_copy_data(bmain, (Key *)*r_newid, (Key *)id, flag);
+ break;
case ID_WO:
- if (!test) *newid = (ID *)BKE_world_copy(bmain, (World *)id);
- return true;
+ BKE_world_copy_data(bmain, (World *)*r_newid, (World *)id, flag);
+ break;
case ID_TXT:
- if (!test) *newid = (ID *)BKE_text_copy(bmain, (Text *)id);
- return true;
+ BKE_text_copy_data(bmain, (Text *)*r_newid, (Text *)id, flag);
+ break;
case ID_GR:
- if (!test) *newid = (ID *)BKE_group_copy(bmain, (Group *)id);
- return true;
+ BKE_group_copy_data(bmain, (Group *)*r_newid, (Group *)id, flag);
+ break;
case ID_AR:
- if (!test) *newid = (ID *)BKE_armature_copy(bmain, (bArmature *)id);
- return true;
+ BKE_armature_copy_data(bmain, (bArmature *)*r_newid, (bArmature *)id, flag);
+ break;
case ID_AC:
- if (!test) *newid = (ID *)BKE_action_copy(bmain, (bAction *)id);
- return true;
+ BKE_action_copy_data(bmain, (bAction *)*r_newid, (bAction *)id, flag);
+ break;
case ID_NT:
- if (!test) *newid = (ID *)ntreeCopyTree(bmain, (bNodeTree *)id);
- return true;
+ BKE_node_tree_copy_data(bmain, (bNodeTree *)*r_newid, (bNodeTree *)id, flag);
+ break;
case ID_BR:
- if (!test) *newid = (ID *)BKE_brush_copy(bmain, (Brush *)id);
- return true;
+ BKE_brush_copy_data(bmain, (Brush *)*r_newid, (Brush *)id, flag);
+ break;
case ID_PA:
- if (!test) *newid = (ID *)BKE_particlesettings_copy(bmain, (ParticleSettings *)id);
- return true;
+ BKE_particlesettings_copy_data(bmain, (ParticleSettings *)*r_newid, (ParticleSettings *)id, flag);
+ break;
case ID_GD:
- if (!test) *newid = (ID *)BKE_gpencil_data_duplicate(bmain, (bGPdata *)id, false);
- return true;
+ BKE_gpencil_copy_data(bmain, (bGPdata *)*r_newid, (bGPdata *)id, flag);
+ break;
case ID_MC:
- if (!test) *newid = (ID *)BKE_movieclip_copy(bmain, (MovieClip *)id);
- return true;
+ BKE_movieclip_copy_data(bmain, (MovieClip *)*r_newid, (MovieClip *)id, flag);
+ break;
case ID_MSK:
- if (!test) *newid = (ID *)BKE_mask_copy(bmain, (Mask *)id);
- return true;
+ BKE_mask_copy_data(bmain, (Mask *)*r_newid, (Mask *)id, flag);
+ break;
case ID_LS:
- if (!test) *newid = (ID *)BKE_linestyle_copy(bmain, (FreestyleLineStyle *)id);
- return true;
+ BKE_linestyle_copy_data(bmain, (FreestyleLineStyle *)*r_newid, (FreestyleLineStyle *)id, flag);
+ break;
case ID_PAL:
- if (!test) *newid = (ID *)BKE_palette_copy(bmain, (Palette *)id);
- return true;
+ BKE_palette_copy_data(bmain, (Palette *)*r_newid, (Palette *)id, flag);
+ break;
case ID_PC:
- if (!test) *newid = (ID *)BKE_paint_curve_copy(bmain, (PaintCurve *)id);
- return true;
+ BKE_paint_curve_copy_data(bmain, (PaintCurve *)*r_newid, (PaintCurve *)id, flag);
+ break;
case ID_CF:
- if (!test) *newid = (ID *)BKE_cachefile_copy(bmain, (CacheFile *)id);
- return true;
- case ID_WS:
- case ID_SCE:
+ 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:
- return false; /* can't be copied from here */
- case ID_VF:
- case ID_SO:
- return false; /* not implemented */
+ case ID_WS:
case ID_IP:
- return false; /* deprecated */
+ BLI_assert(0); /* Should have been rejected at start of function! */
+ break;
}
-
- return false;
+
+ /* Update ID refcount, remap pointers to self in new ID. */
+ struct IDCopyLibManagementData data = {.id_src=id, .flag=flag};
+ BKE_library_foreach_ID_link(bmain, *r_newid, id_copy_libmanagement_cb, &data, IDWALK_NOP);
+
+ /* Do not make new copy local in case we are copying outside of main...
+ * XXX TODO: is this behavior OK, or should we need own flag to control that? */
+ if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
+ BKE_id_copy_ensure_local(bmain, id, *r_newid);
+ }
+
+ return true;
+}
+
+/**
+ * Invokes the appropriate copy method for the block and returns the result in
+ * newid, unless test. Returns true if the block can be copied.
+ */
+bool id_copy(Main *bmain, const ID *id, ID **newid, bool test)
+{
+ return BKE_id_copy_ex(bmain, id, newid, 0, test);
}
/** Does *not* set ID->newid pointer. */
@@ -636,6 +706,101 @@ bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
return false;
}
+static int libblock_management_us_plus(void *UNUSED(user_data), ID *UNUSED(id_self), ID **id_pointer, int cb_flag)
+{
+ if (cb_flag & IDWALK_CB_USER) {
+ id_us_plus(*id_pointer);
+ }
+ if (cb_flag & IDWALK_CB_USER_ONE) {
+ id_us_ensure_real(*id_pointer);
+ }
+
+ return IDWALK_RET_NOP;
+}
+
+static int libblock_management_us_min(void *UNUSED(user_data), ID *UNUSED(id_self), ID **id_pointer, int cb_flag)
+{
+ if (cb_flag & IDWALK_CB_USER) {
+ id_us_min(*id_pointer);
+ }
+ /* We can do nothing in IDWALK_CB_USER_ONE case! */
+
+ return IDWALK_RET_NOP;
+}
+
+/** Add a 'NO_MAIN' datablock to given main (also sets usercounts of its IDs if needed). */
+void BKE_libblock_management_main_add(Main *bmain, void *idv)
+{
+ ID *id = idv;
+
+ BLI_assert(bmain != NULL);
+ if ((id->tag & LIB_TAG_NO_MAIN) == 0) {
+ return;
+ }
+
+ if ((id->tag & LIB_TAG_NOT_ALLOCATED) != 0) {
+ /* We cannot add non-allocated ID to Main! */
+ return;
+ }
+
+ /* We cannot allow non-userrefcounting IDs in Main database! */
+ if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) != 0) {
+ BKE_library_foreach_ID_link(bmain, id, libblock_management_us_plus, NULL, IDWALK_NOP);
+ }
+
+ ListBase *lb = which_libbase(bmain, GS(id->name));
+ BKE_main_lock(bmain);
+ BLI_addtail(lb, id);
+ new_id(lb, id, NULL);
+ /* alphabetic insertion: is in new_id */
+ id->tag &= ~(LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT);
+ BKE_main_unlock(bmain);
+}
+
+/** Remove a datablock from given main (set it to 'NO_MAIN' status). */
+void BKE_libblock_management_main_remove(Main *bmain, void *idv)
+{
+ ID *id = idv;
+
+ BLI_assert(bmain != NULL);
+ if ((id->tag & LIB_TAG_NO_MAIN) != 0) {
+ return;
+ }
+
+ /* For now, allow userrefcounting IDs to get out of Main - can be handy in some cases... */
+
+ ListBase *lb = which_libbase(bmain, GS(id->name));
+ BKE_main_lock(bmain);
+ BLI_remlink(lb, id);
+ id->tag |= LIB_TAG_NO_MAIN;
+ BKE_main_unlock(bmain);
+}
+
+void BKE_libblock_management_usercounts_set(Main *bmain, void *idv)
+{
+ ID *id = idv;
+
+ if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) == 0) {
+ return;
+ }
+
+ BKE_library_foreach_ID_link(bmain, id, libblock_management_us_plus, NULL, IDWALK_NOP);
+ id->tag &= ~LIB_TAG_NO_USER_REFCOUNT;
+}
+
+void BKE_libblock_management_usercounts_clear(Main *bmain, void *idv)
+{
+ ID *id = idv;
+
+ /* We do not allow IDs in Main database to not be userrefcounting. */
+ if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) != 0 || (id->tag & LIB_TAG_NO_MAIN) != 0) {
+ return;
+ }
+
+ BKE_library_foreach_ID_link(bmain, id, libblock_management_us_min, NULL, IDWALK_NOP);
+ id->tag |= LIB_TAG_NO_USER_REFCOUNT;
+}
+
ListBase *which_libbase(Main *mainlib, short type)
{
switch ((ID_Type)type) {
@@ -953,23 +1118,43 @@ void *BKE_libblock_alloc_notest(short type)
* The user count is set to 1, all other content (apart from name and links) being
* initialized to zero.
*/
-void *BKE_libblock_alloc(Main *bmain, short type, const char *name)
+void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int flag)
{
ID *id = NULL;
- ListBase *lb = which_libbase(bmain, type);
+
+ BLI_assert((flag & LIB_ID_CREATE_NO_ALLOCATE) == 0);
id = BKE_libblock_alloc_notest(type);
+
+ if ((flag & LIB_ID_CREATE_NO_MAIN) != 0) {
+ id->tag |= LIB_TAG_NO_MAIN;
+ }
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) != 0) {
+ id->tag |= LIB_TAG_NO_USER_REFCOUNT;
+ }
+
if (id) {
- BKE_main_lock(bmain);
- BLI_addtail(lb, id);
- id->us = 1;
id->icon_id = 0;
*( (short *)id->name) = type;
- new_id(lb, id, name);
- /* alphabetic insertion: is in new_id */
- BKE_main_unlock(bmain);
+ if ((flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0) {
+ id->us = 1;
+ }
+ if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
+ ListBase *lb = which_libbase(bmain, type);
+
+ BKE_main_lock(bmain);
+ BLI_addtail(lb, id);
+ new_id(lb, id, name);
+ /* alphabetic insertion: is in new_id */
+ BKE_main_unlock(bmain);
+
+ /* TODO to be removed from here! */
+ if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0) {
+ DEG_id_type_tag(bmain, type);
+ }
+ }
}
- DEG_id_type_tag(bmain, type);
+
return id;
}
@@ -1095,70 +1280,80 @@ void BKE_libblock_init_empty(ID *id)
/* by spec, animdata is first item after ID */
/* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */
-static void id_copy_animdata(ID *id, const bool do_action)
+static void id_copy_animdata(Main *bmain, ID *id, const bool do_action)
{
AnimData *adt = BKE_animdata_from_id(id);
if (adt) {
IdAdtTemplate *iat = (IdAdtTemplate *)id;
- iat->adt = BKE_animdata_copy(iat->adt, do_action); /* could be set to false, need to investigate */
+ iat->adt = BKE_animdata_copy(bmain, iat->adt, do_action); /* could be set to false, need to investigate */
}
}
-/* material nodes use this since they are not treated as libdata */
-void BKE_libblock_copy_data(ID *id, const ID *id_from, const bool do_action)
+void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag)
{
- if (id_from->properties)
- id->properties = IDP_CopyProperty(id_from->properties);
+ ID *new_id = *r_newid;
+
+ /* Grrrrrrrrr... Not adding 'root' nodetrees to bmain.... grrrrrrrrrrrrrrrrrrrr! */
+ /* This is taken from original ntree copy code, might be weak actually? */
+ const bool use_nodetree_alloc_exception = ((GS(id->name) == ID_NT) && (bmain != NULL) &&
+ (BLI_findindex(&bmain->nodetree, id) < 0));
+
+ BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || bmain != NULL);
+ BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || (flag & LIB_ID_CREATE_NO_ALLOCATE) == 0);
+ BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) == 0 || (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) != 0);
+
+ if ((flag & LIB_ID_CREATE_NO_ALLOCATE) != 0) {
+ /* r_newid already contains pointer to allocated memory. */
+ /* TODO do we want to memset(0) whole mem before filling it? */
+ BLI_strncpy(new_id->name, id->name, sizeof(new_id->name));
+ new_id->us = 0;
+ new_id->tag |= LIB_TAG_NOT_ALLOCATED | LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT;
+ /* TODO Do we want/need to copy more from ID struct itself? */
+ }
+ else {
+ new_id = BKE_libblock_alloc(bmain, GS(id->name), id->name + 2, flag | (use_nodetree_alloc_exception ? LIB_ID_CREATE_NO_MAIN : 0));
+ }
+ BLI_assert(new_id != NULL);
+
+ const size_t id_len = BKE_libblock_get_alloc_info(GS(new_id->name), NULL);
+ const size_t id_offset = sizeof(ID);
+ if ((int)id_len - (int)id_offset > 0) { /* signed to allow neg result */ /* XXX ????? */
+ const char *cp = (const char *)id;
+ char *cpn = (char *)new_id;
+
+ memcpy(cpn + id_offset, cp + id_offset, id_len - id_offset);
+ }
+
+ if (id->properties) {
+ new_id->properties = IDP_CopyProperty_ex(id->properties, flag);
+ }
/* the duplicate should get a copy of the animdata */
- id_copy_animdata(id, do_action);
+ id_copy_animdata(bmain, new_id, (flag & LIB_ID_COPY_ACTIONS) != 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0);
+
+ if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0) {
+ DAG_id_type_tag(bmain, GS(new_id->name));
+ }
+
+ *r_newid = new_id;
}
/* used everywhere in blenkernel */
void *BKE_libblock_copy(Main *bmain, const ID *id)
{
ID *idn;
- size_t idn_len;
-
- idn = BKE_libblock_alloc(bmain, GS(id->name), id->name + 2);
- assert(idn != NULL);
+ BKE_libblock_copy_ex(bmain, id, &idn, 0);
- idn_len = MEM_allocN_len(idn);
- if ((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */
- const char *cp = (const char *)id;
- char *cpn = (char *)idn;
-
- memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID));
- }
-
- BKE_libblock_copy_data(idn, id, false);
-
return idn;
}
void *BKE_libblock_copy_nolib(const ID *id, const bool do_action)
{
ID *idn;
- size_t idn_len;
-
- idn = BKE_libblock_alloc_notest(GS(id->name));
- assert(idn != NULL);
-
- BLI_strncpy(idn->name, id->name, sizeof(idn->name));
-
- idn_len = MEM_allocN_len(idn);
- if ((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */
- const char *cp = (const char *)id;
- char *cpn = (char *)idn;
-
- memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID));
- }
-
- idn->us = 1;
- BKE_libblock_copy_data(idn, id, do_action);
+ BKE_libblock_copy_ex(NULL, id, &idn, LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT | (do_action ? LIB_ID_COPY_ACTIONS : 0));
return idn;
}
@@ -1198,41 +1393,41 @@ void BKE_main_free(Main *mainvar)
/* errors freeing ID's can be hard to track down,
* enable this so valgrind will give the line number in its error log */
switch (a) {
- case 0: BKE_libblock_free_ex(mainvar, id, false); break;
- case 1: BKE_libblock_free_ex(mainvar, id, false); break;
- case 2: BKE_libblock_free_ex(mainvar, id, false); break;
- case 3: BKE_libblock_free_ex(mainvar, id, false); break;
- case 4: BKE_libblock_free_ex(mainvar, id, false); break;
- case 5: BKE_libblock_free_ex(mainvar, id, false); break;
- case 6: BKE_libblock_free_ex(mainvar, id, false); break;
- case 7: BKE_libblock_free_ex(mainvar, id, false); break;
- case 8: BKE_libblock_free_ex(mainvar, id, false); break;
- case 9: BKE_libblock_free_ex(mainvar, id, false); break;
- case 10: BKE_libblock_free_ex(mainvar, id, false); break;
- case 11: BKE_libblock_free_ex(mainvar, id, false); break;
- case 12: BKE_libblock_free_ex(mainvar, id, false); break;
- case 13: BKE_libblock_free_ex(mainvar, id, false); break;
- case 14: BKE_libblock_free_ex(mainvar, id, false); break;
- case 15: BKE_libblock_free_ex(mainvar, id, false); break;
- case 16: BKE_libblock_free_ex(mainvar, id, false); break;
- case 17: BKE_libblock_free_ex(mainvar, id, false); break;
- case 18: BKE_libblock_free_ex(mainvar, id, false); break;
- case 19: BKE_libblock_free_ex(mainvar, id, false); break;
- case 20: BKE_libblock_free_ex(mainvar, id, false); break;
- case 21: BKE_libblock_free_ex(mainvar, id, false); break;
- case 22: BKE_libblock_free_ex(mainvar, id, false); break;
- case 23: BKE_libblock_free_ex(mainvar, id, false); break;
- case 24: BKE_libblock_free_ex(mainvar, id, false); break;
- case 25: BKE_libblock_free_ex(mainvar, id, false); break;
- case 26: BKE_libblock_free_ex(mainvar, id, false); break;
- case 27: BKE_libblock_free_ex(mainvar, id, false); break;
- case 28: BKE_libblock_free_ex(mainvar, id, false); break;
- case 29: BKE_libblock_free_ex(mainvar, id, false); break;
- case 30: BKE_libblock_free_ex(mainvar, id, false); break;
- case 31: BKE_libblock_free_ex(mainvar, id, false); break;
- case 32: BKE_libblock_free_ex(mainvar, id, false); break;
- case 33: BKE_libblock_free_ex(mainvar, id, false); break;
- case 34: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 0: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 1: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 2: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 3: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 4: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 5: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 6: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 7: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 8: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 9: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 10: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 11: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 12: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 13: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 14: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 15: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 16: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 17: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 18: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 19: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 20: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 21: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 22: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 23: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 24: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 25: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 26: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 27: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 28: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 29: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 30: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 31: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 32: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 33: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 34: BKE_libblock_free_ex(mainvar, id, false, false); break;
default:
BLI_assert(0);
break;
diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c
index 7310370ca10..a3dc6e37ea0 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -758,9 +758,11 @@ void BKE_libblock_free_data(ID *id, const bool do_id_user)
IDP_FreeProperty_ex(id->properties, do_id_user);
MEM_freeN(id->properties);
}
+
+ /* XXX TODO remove animdata handling from each type's freeing func, and do it here, like for copy! */
}
-void BKE_libblock_free_datablock(ID *id)
+void BKE_libblock_free_datablock(ID *id, const int UNUSED(flag))
{
const short type = GS(id->name);
switch (type) {
@@ -876,6 +878,90 @@ void BKE_libblock_free_datablock(ID *id)
}
}
+
+void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_idtag)
+{
+ ID *id = idv;
+
+ if (use_flag_from_idtag) {
+ if ((id->tag & LIB_TAG_NO_MAIN) != 0) {
+ flag |= LIB_ID_FREE_NO_MAIN;
+ }
+ else {
+ flag &= ~LIB_ID_FREE_NO_MAIN;
+ }
+
+ if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) != 0) {
+ flag |= LIB_ID_FREE_NO_USER_REFCOUNT;
+ }
+ else {
+ flag &= ~LIB_ID_FREE_NO_USER_REFCOUNT;
+ }
+
+ if ((id->tag & LIB_TAG_NOT_ALLOCATED) != 0) {
+ flag |= LIB_ID_FREE_NOT_ALLOCATED;
+ }
+ else {
+ flag &= ~LIB_ID_FREE_NOT_ALLOCATED;
+ }
+ }
+
+ BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || bmain != NULL);
+ BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || (flag & LIB_ID_FREE_NOT_ALLOCATED) == 0);
+ BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || (flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0);
+
+ const short type = GS(id->name);
+
+ if (bmain && (flag & LIB_ID_FREE_NO_DEG_TAG) == 0) {
+ DAG_id_type_tag(bmain, type);
+ }
+
+#ifdef WITH_PYTHON
+ BPY_id_release(id);
+#endif
+
+ if ((flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0) {
+ BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
+ }
+
+ BKE_libblock_free_datablock(id, flag);
+
+ /* avoid notifying on removed data */
+ if (bmain) {
+ BKE_main_lock(bmain);
+ }
+
+ if ((flag & LIB_ID_FREE_NO_UI_USER) == 0) {
+ if (free_notifier_reference_cb) {
+ free_notifier_reference_cb(id);
+ }
+
+ if (remap_editor_id_reference_cb) {
+ remap_editor_id_reference_cb(id, NULL);
+ }
+ }
+
+ if ((flag & LIB_ID_FREE_NO_MAIN) == 0) {
+ ListBase *lb = which_libbase(bmain, type);
+ BLI_remlink(lb, id);
+ }
+
+ BKE_libblock_free_data(id, (flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0);
+
+ if (bmain) {
+ BKE_main_unlock(bmain);
+ }
+
+ if ((flag & LIB_ID_FREE_NOT_ALLOCATED) == 0) {
+ MEM_freeN(id);
+ }
+}
+
+void BKE_id_free(Main *bmain, void *idv)
+{
+ BKE_id_free_ex(bmain, idv, 0, true);
+}
+
/**
* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c
*
@@ -905,7 +991,7 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b
BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
}
- BKE_libblock_free_datablock(id);
+ BKE_libblock_free_datablock(id, 0);
/* avoid notifying on removed data */
BKE_main_lock(bmain);
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index 771e81ddc4f..1b1a12e702a 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -119,7 +119,7 @@ FreestyleLineStyle *BKE_linestyle_new(struct Main *bmain, const char *name)
{
FreestyleLineStyle *linestyle;
- linestyle = (FreestyleLineStyle *)BKE_libblock_alloc(bmain, ID_LS, name);
+ linestyle = (FreestyleLineStyle *)BKE_libblock_alloc(bmain, ID_LS, name, 0);
BKE_linestyle_init(linestyle);
@@ -155,73 +155,54 @@ void BKE_linestyle_free(FreestyleLineStyle *linestyle)
BKE_linestyle_geometry_modifier_remove(linestyle, m);
}
-FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, const FreestyleLineStyle *linestyle)
+/**
+ * Only copy internal data of Linestyle ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_linestyle_copy_data(
+ struct Main *bmain, FreestyleLineStyle *linestyle_dst, const FreestyleLineStyle *linestyle_src, const int flag)
{
- FreestyleLineStyle *new_linestyle;
- LineStyleModifier *m;
- int a;
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
- new_linestyle = BKE_linestyle_new(bmain, linestyle->id.name + 2);
- BKE_linestyle_free(new_linestyle);
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (linestyle->mtex[a]) {
- new_linestyle->mtex[a] = MEM_mallocN(sizeof(MTex), "BKE_linestyle_copy");
- memcpy(new_linestyle->mtex[a], linestyle->mtex[a], sizeof(MTex));
- id_us_plus((ID *)new_linestyle->mtex[a]->tex);
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (linestyle_src->mtex[a]) {
+ linestyle_dst->mtex[a] = MEM_mallocN(sizeof(*linestyle_dst->mtex[a]), __func__);
+ *linestyle_dst->mtex[a] = *linestyle_src->mtex[a];
}
}
- if (linestyle->nodetree) {
- new_linestyle->nodetree = ntreeCopyTree(bmain, linestyle->nodetree);
+ if (linestyle_src->nodetree) {
+ BKE_id_copy_ex(bmain, (ID *)linestyle_src->nodetree, (ID **)&linestyle_dst->nodetree, flag, false);
}
- new_linestyle->r = linestyle->r;
- new_linestyle->g = linestyle->g;
- new_linestyle->b = linestyle->b;
- new_linestyle->alpha = linestyle->alpha;
- new_linestyle->thickness = linestyle->thickness;
- new_linestyle->thickness_position = linestyle->thickness_position;
- new_linestyle->thickness_ratio = linestyle->thickness_ratio;
- new_linestyle->flag = linestyle->flag;
- new_linestyle->caps = linestyle->caps;
- new_linestyle->chaining = linestyle->chaining;
- new_linestyle->rounds = linestyle->rounds;
- new_linestyle->split_length = linestyle->split_length;
- new_linestyle->min_angle = linestyle->min_angle;
- new_linestyle->max_angle = linestyle->max_angle;
- new_linestyle->min_length = linestyle->min_length;
- new_linestyle->max_length = linestyle->max_length;
- new_linestyle->chain_count = linestyle->chain_count;
- new_linestyle->split_dash1 = linestyle->split_dash1;
- new_linestyle->split_gap1 = linestyle->split_gap1;
- new_linestyle->split_dash2 = linestyle->split_dash2;
- new_linestyle->split_gap2 = linestyle->split_gap2;
- new_linestyle->split_dash3 = linestyle->split_dash3;
- new_linestyle->split_gap3 = linestyle->split_gap3;
- new_linestyle->dash1 = linestyle->dash1;
- new_linestyle->gap1 = linestyle->gap1;
- new_linestyle->dash2 = linestyle->dash2;
- new_linestyle->gap2 = linestyle->gap2;
- new_linestyle->dash3 = linestyle->dash3;
- new_linestyle->gap3 = linestyle->gap3;
- new_linestyle->panel = linestyle->panel;
- new_linestyle->sort_key = linestyle->sort_key;
- new_linestyle->integration_type = linestyle->integration_type;
- new_linestyle->texstep = linestyle->texstep;
- new_linestyle->pr_texture = linestyle->pr_texture;
- new_linestyle->use_nodes = linestyle->use_nodes;
- for (m = (LineStyleModifier *)linestyle->color_modifiers.first; m; m = m->next)
- BKE_linestyle_color_modifier_copy(new_linestyle, m);
- for (m = (LineStyleModifier *)linestyle->alpha_modifiers.first; m; m = m->next)
- BKE_linestyle_alpha_modifier_copy(new_linestyle, m);
- for (m = (LineStyleModifier *)linestyle->thickness_modifiers.first; m; m = m->next)
- BKE_linestyle_thickness_modifier_copy(new_linestyle, m);
- for (m = (LineStyleModifier *)linestyle->geometry_modifiers.first; m; m = m->next)
- BKE_linestyle_geometry_modifier_copy(new_linestyle, m);
-
- BKE_id_copy_ensure_local(bmain, &linestyle->id, &new_linestyle->id);
-
- return new_linestyle;
+ LineStyleModifier *m;
+ BLI_listbase_clear(&linestyle_dst->color_modifiers);
+ for (m = (LineStyleModifier *)linestyle_src->color_modifiers.first; m; m = m->next) {
+ BKE_linestyle_color_modifier_copy(linestyle_dst, m, flag_subdata);
+ }
+ BLI_listbase_clear(&linestyle_dst->alpha_modifiers);
+ for (m = (LineStyleModifier *)linestyle_src->alpha_modifiers.first; m; m = m->next) {
+ BKE_linestyle_alpha_modifier_copy(linestyle_dst, m, flag_subdata);
+ }
+ BLI_listbase_clear(&linestyle_dst->thickness_modifiers);
+ for (m = (LineStyleModifier *)linestyle_src->thickness_modifiers.first; m; m = m->next) {
+ BKE_linestyle_thickness_modifier_copy(linestyle_dst, m, flag_subdata);
+ }
+ BLI_listbase_clear(&linestyle_dst->geometry_modifiers);
+ for (m = (LineStyleModifier *)linestyle_src->geometry_modifiers.first; m; m = m->next) {
+ BKE_linestyle_geometry_modifier_copy(linestyle_dst, m, flag_subdata);
+ }
+}
+
+FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, const FreestyleLineStyle *linestyle)
+{
+ FreestyleLineStyle *linestyle_copy;
+ BKE_id_copy_ex(bmain, &linestyle->id, (ID **)&linestyle_copy, 0, false);
+ return linestyle_copy;
}
void BKE_linestyle_make_local(struct Main *bmain, FreestyleLineStyle *linestyle, const bool lib_local)
@@ -355,7 +336,8 @@ LineStyleModifier *BKE_linestyle_color_modifier_add(FreestyleLineStyle *linestyl
return m;
}
-LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m)
+LineStyleModifier *BKE_linestyle_color_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int flag)
{
LineStyleModifier *new_m;
@@ -388,9 +370,10 @@ LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linesty
{
LineStyleColorModifier_DistanceFromObject *p = (LineStyleColorModifier_DistanceFromObject *)m;
LineStyleColorModifier_DistanceFromObject *q = (LineStyleColorModifier_DistanceFromObject *)new_m;
- if (p->target)
- id_us_plus(&p->target->id);
q->target = p->target;
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)q->target);
+ }
q->color_ramp = MEM_dupallocN(p->color_ramp);
q->range_min = p->range_min;
q->range_max = p->range_max;
@@ -594,7 +577,8 @@ LineStyleModifier *BKE_linestyle_alpha_modifier_add(FreestyleLineStyle *linestyl
return m;
}
-LineStyleModifier *BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m)
+LineStyleModifier *BKE_linestyle_alpha_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int UNUSED(flag))
{
LineStyleModifier *new_m;
@@ -863,7 +847,8 @@ LineStyleModifier *BKE_linestyle_thickness_modifier_add(FreestyleLineStyle *line
return m;
}
-LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m)
+LineStyleModifier *BKE_linestyle_thickness_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int flag)
{
LineStyleModifier *new_m;
@@ -901,9 +886,10 @@ LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *lin
{
LineStyleThicknessModifier_DistanceFromObject *p = (LineStyleThicknessModifier_DistanceFromObject *)m;
LineStyleThicknessModifier_DistanceFromObject *q = (LineStyleThicknessModifier_DistanceFromObject *)new_m;
- if (p->target)
- id_us_plus(&p->target->id);
q->target = p->target;
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)q->target);
+ }
q->curve = curvemapping_copy(p->curve);
q->flags = p->flags;
q->range_min = p->range_min;
@@ -1195,7 +1181,8 @@ LineStyleModifier *BKE_linestyle_geometry_modifier_add(FreestyleLineStyle *lines
return m;
}
-LineStyleModifier *BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m)
+LineStyleModifier *BKE_linestyle_geometry_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int UNUSED(flag))
{
LineStyleModifier *new_m;
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index ae27e9bcd34..435bc949af0 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -794,7 +794,7 @@ static Mask *mask_alloc(Main *bmain, const char *name)
{
Mask *mask;
- mask = BKE_libblock_alloc(bmain, ID_MSK, name);
+ mask = BKE_libblock_alloc(bmain, ID_MSK, name, 0);
id_fake_user_set(&mask->id);
@@ -821,6 +821,7 @@ Mask *BKE_mask_new(Main *bmain, const char *name)
}
/* TODO(sergey): Use generic BKE_libblock_copy_nolib() instead. */
+/* TODO(bastien): Use new super cool & generic BKE_id_copy_ex() instead! */
Mask *BKE_mask_copy_nolib(Mask *mask)
{
Mask *mask_new;
@@ -840,22 +841,29 @@ Mask *BKE_mask_copy_nolib(Mask *mask)
return mask_new;
}
-Mask *BKE_mask_copy(Main *bmain, const Mask *mask)
+/**
+ * Only copy internal data of Mask ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_mask_copy_data(Main *UNUSED(bmain), Mask *mask_dst, const Mask *mask_src, const int UNUSED(flag))
{
- Mask *mask_new;
+ BLI_listbase_clear(&mask_dst->masklayers);
- mask_new = BKE_libblock_copy(bmain, &mask->id);
-
- BLI_listbase_clear(&mask_new->masklayers);
-
- BKE_mask_layer_copy_list(&mask_new->masklayers, &mask->masklayers);
+ BKE_mask_layer_copy_list(&mask_dst->masklayers, &mask_src->masklayers); /* TODO add unused flag to those as well. */
/* enable fake user by default */
- id_fake_user_set(&mask_new->id);
-
- BKE_id_copy_ensure_local(bmain, &mask->id, &mask_new->id);
+ id_fake_user_set(&mask_dst->id);
+}
- return mask_new;
+Mask *BKE_mask_copy(Main *bmain, const Mask *mask)
+{
+ Mask *mask_copy;
+ BKE_id_copy_ex(bmain, &mask->id, (ID **)&mask_copy, 0, false);
+ return mask_copy;
}
void BKE_mask_make_local(Main *bmain, Mask *mask, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 7038fb0ddcf..5caeff4df1c 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -215,53 +215,70 @@ Material *BKE_material_add(Main *bmain, const char *name)
{
Material *ma;
- ma = BKE_libblock_alloc(bmain, ID_MA, name);
+ ma = BKE_libblock_alloc(bmain, ID_MA, name, 0);
BKE_material_init(ma);
return ma;
}
-/* XXX keep synced with next function */
-Material *BKE_material_copy(Main *bmain, const Material *ma)
+/**
+ * Only copy internal data of Material ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_material_copy_data(Main *bmain, Material *ma_dst, const Material *ma_src, const int flag)
{
- Material *man;
- int a;
-
- man = BKE_libblock_copy(bmain, &ma->id);
-
- id_lib_extern((ID *)man->group);
- id_lib_extern((ID *)man->edit_image);
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (ma->mtex[a]) {
- man->mtex[a] = MEM_mallocN(sizeof(MTex), "copymaterial");
- memcpy(man->mtex[a], ma->mtex[a], sizeof(MTex));
- id_us_plus((ID *)man->mtex[a]->tex);
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (ma_src->mtex[a]) {
+ ma_dst->mtex[a] = MEM_mallocN(sizeof(*ma_dst->mtex[a]), __func__);
+ *ma_dst->mtex[a] = *ma_src->mtex[a];
}
}
-
- if (ma->ramp_col) man->ramp_col = MEM_dupallocN(ma->ramp_col);
- if (ma->ramp_spec) man->ramp_spec = MEM_dupallocN(ma->ramp_spec);
-
- if (ma->nodetree) {
- man->nodetree = ntreeCopyTree(bmain, ma->nodetree);
+
+ if (ma_src->ramp_col) {
+ ma_dst->ramp_col = MEM_dupallocN(ma_src->ramp_col);
+ }
+ if (ma_src->ramp_spec) {
+ ma_dst->ramp_spec = MEM_dupallocN(ma_src->ramp_spec);
}
- BKE_previewimg_id_copy(&man->id, &ma->id);
+ if (ma_src->nodetree) {
+ BKE_id_copy_ex(bmain, (ID *)ma_src->nodetree, (ID **)&ma_dst->nodetree, flag, false);
+ }
- BLI_listbase_clear(&man->gpumaterial);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&ma_dst->id, &ma_src->id);
+ }
+ else {
+ ma_dst->preview = NULL;
+ }
- /* TODO Duplicate Engine Settings and set runtime to NULL */
+ BLI_listbase_clear(&ma_dst->gpumaterial);
- BKE_id_copy_ensure_local(bmain, &ma->id, &man->id);
+ /* TODO Duplicate Engine Settings and set runtime to NULL */
+}
- return man;
+Material *BKE_material_copy(Main *bmain, const Material *ma)
+{
+ Material *ma_copy;
+ BKE_id_copy_ex(bmain, &ma->id, (ID **)&ma_copy, 0, false);
+ return ma_copy;
}
/* XXX (see above) material copy without adding to main dbase */
Material *localize_material(Material *ma)
{
+ /* TODO replace with something like
+ * Material *ma_copy;
+ * BKE_id_copy_ex(bmain, &ma->id, (ID **)&ma_copy, LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT, false);
+ * return ma_copy;
+ *
+ * ... Once f*** nodes are fully converted to that too :( */
+
Material *man;
int a;
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 27e2b17b4e2..fd226bf20ec 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -97,33 +97,36 @@ MetaBall *BKE_mball_add(Main *bmain, const char *name)
{
MetaBall *mb;
- mb = BKE_libblock_alloc(bmain, ID_MB, name);
+ mb = BKE_libblock_alloc(bmain, ID_MB, name, 0);
BKE_mball_init(mb);
return mb;
}
-MetaBall *BKE_mball_copy(Main *bmain, const MetaBall *mb)
+/**
+ * Only copy internal data of MetaBall ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_mball_copy_data(Main *UNUSED(bmain), MetaBall *mb_dst, const MetaBall *mb_src, const int UNUSED(flag))
{
- MetaBall *mbn;
- int a;
-
- mbn = BKE_libblock_copy(bmain, &mb->id);
+ BLI_duplicatelist(&mb_dst->elems, &mb_src->elems);
- BLI_duplicatelist(&mbn->elems, &mb->elems);
-
- mbn->mat = MEM_dupallocN(mb->mat);
- for (a = 0; a < mbn->totcol; a++) {
- id_us_plus((ID *)mbn->mat[a]);
- }
+ mb_dst->mat = MEM_dupallocN(mb_src->mat);
- mbn->editelems = NULL;
- mbn->lastelem = NULL;
-
- BKE_id_copy_ensure_local(bmain, &mb->id, &mbn->id);
+ mb_dst->editelems = NULL;
+ mb_dst->lastelem = NULL;
+}
- return mbn;
+MetaBall *BKE_mball_copy(Main *bmain, const MetaBall *mb)
+{
+ MetaBall *mb_copy;
+ BKE_id_copy_ex(bmain, &mb->id, (ID **)&mb_copy, 0, false);
+ return mb_copy;
}
void BKE_mball_make_local(Main *bmain, MetaBall *mb, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 9be072f1a21..a52b8cc030d 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -533,54 +533,57 @@ Mesh *BKE_mesh_add(Main *bmain, const char *name)
{
Mesh *me;
- me = BKE_libblock_alloc(bmain, ID_ME, name);
+ me = BKE_libblock_alloc(bmain, ID_ME, name, 0);
BKE_mesh_init(me);
return me;
}
-Mesh *BKE_mesh_copy(Main *bmain, const Mesh *me)
+/**
+ * Only copy internal data of Mesh ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_mesh_copy_data(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int flag)
{
- Mesh *men;
- int a;
- const int do_tessface = ((me->totface != 0) && (me->totpoly == 0)); /* only do tessface if we have no polys */
-
- men = BKE_libblock_copy(bmain, &me->id);
-
- men->mat = MEM_dupallocN(me->mat);
- for (a = 0; a < men->totcol; a++) {
- id_us_plus((ID *)men->mat[a]);
- }
- id_us_plus((ID *)men->texcomesh);
+ const bool do_tessface = ((me_src->totface != 0) && (me_src->totpoly == 0)); /* only do tessface if we have no polys */
- CustomData_copy(&me->vdata, &men->vdata, CD_MASK_MESH, CD_DUPLICATE, men->totvert);
- CustomData_copy(&me->edata, &men->edata, CD_MASK_MESH, CD_DUPLICATE, men->totedge);
- CustomData_copy(&me->ldata, &men->ldata, CD_MASK_MESH, CD_DUPLICATE, men->totloop);
- CustomData_copy(&me->pdata, &men->pdata, CD_MASK_MESH, CD_DUPLICATE, men->totpoly);
+ me_dst->mat = MEM_dupallocN(me_src->mat);
+
+ CustomData_copy(&me_src->vdata, &me_dst->vdata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totvert);
+ CustomData_copy(&me_src->edata, &me_dst->edata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totedge);
+ CustomData_copy(&me_src->ldata, &me_dst->ldata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totloop);
+ CustomData_copy(&me_src->pdata, &me_dst->pdata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totpoly);
if (do_tessface) {
- CustomData_copy(&me->fdata, &men->fdata, CD_MASK_MESH, CD_DUPLICATE, men->totface);
+ CustomData_copy(&me_src->fdata, &me_dst->fdata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totface);
}
else {
- mesh_tessface_clear_intern(men, false);
+ mesh_tessface_clear_intern(me_dst, false);
}
- BKE_mesh_update_customdata_pointers(men, do_tessface);
+ BKE_mesh_update_customdata_pointers(me_dst, do_tessface);
- men->edit_btmesh = NULL;
- men->batch_cache = NULL;
+ me_dst->edit_btmesh = NULL;
+ me_dst->batch_cache = NULL;
- men->mselect = MEM_dupallocN(men->mselect);
- men->bb = MEM_dupallocN(men->bb);
+ me_dst->mselect = MEM_dupallocN(me_dst->mselect);
+ me_dst->bb = MEM_dupallocN(me_dst->bb);
- if (me->key) {
- men->key = BKE_key_copy(bmain, me->key);
- men->key->from = (ID *)men;
+ /* TODO Do we want to add flag to prevent this? */
+ if (me_src->key) {
+ BKE_id_copy_ex(bmain, &me_src->key->id, (ID **)&me_dst->key, flag, false);
}
+}
- BKE_id_copy_ensure_local(bmain, &me->id, &men->id);
-
- return men;
+Mesh *BKE_mesh_copy(Main *bmain, const Mesh *me)
+{
+ Mesh *me_copy;
+ BKE_id_copy_ex(bmain, &me->id, (ID **)&me_copy, 0, false);
+ return me_copy;
}
BMesh *BKE_mesh_to_bmesh(
@@ -2487,7 +2490,9 @@ Mesh *BKE_mesh_new_from_object(
int uv_from_orco;
/* copies object and modifiers (but not the data) */
- Object *tmpobj = BKE_object_copy_ex(bmain, ob, true);
+ Object *tmpobj;
+ /* TODO: make it temp copy outside bmain! */
+ BKE_id_copy_ex(bmain, &ob->id, (ID **)&tmpobj, LIB_ID_COPY_CACHES, false);
tmpcu = (Curve *)tmpobj->data;
id_us_min(&tmpcu->id);
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index b4eb132353c..cefdbc3edc1 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -59,6 +59,8 @@
#include "BKE_appdir.h"
#include "BKE_key.h"
+#include "BKE_library.h"
+#include "BKE_library_query.h"
#include "BKE_multires.h"
#include "BKE_DerivedMesh.h"
@@ -269,14 +271,37 @@ void modifier_copyData_generic(const ModifierData *md_src, ModifierData *md_dst)
memcpy(md_dst_data, md_src_data, (size_t)mti->structSize - data_size);
}
-void modifier_copyData(ModifierData *md, ModifierData *target)
+static void modifier_copy_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
+{
+ ID *id = *idpoin;
+ if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
+ id_us_plus(id);
+ }
+}
+
+void modifier_copyData_ex(ModifierData *md, ModifierData *target, const int flag)
{
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
target->mode = md->mode;
- if (mti->copyData)
+ if (mti->copyData) {
mti->copyData(md, target);
+ }
+
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ if (mti->foreachIDLink) {
+ mti->foreachIDLink(target, NULL, modifier_copy_data_id_us_cb, NULL);
+ }
+ else if (mti->foreachObjectLink) {
+ mti->foreachObjectLink(target, NULL, (ObjectWalkFunc)modifier_copy_data_id_us_cb, NULL);
+ }
+ }
+}
+
+void modifier_copyData(ModifierData *md, ModifierData *target)
+{
+ modifier_copyData_ex(md, target, 0);
}
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index dfa8742a295..16d597e25fa 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -588,7 +588,7 @@ static MovieClip *movieclip_alloc(Main *bmain, const char *name)
{
MovieClip *clip;
- clip = BKE_libblock_alloc(bmain, ID_MC, name);
+ clip = BKE_libblock_alloc(bmain, ID_MC, name, 0);
clip->aspx = clip->aspy = 1.0f;
@@ -1488,25 +1488,33 @@ void BKE_movieclip_free(MovieClip *clip)
BKE_animdata_free((ID *) clip, false);
}
-MovieClip *BKE_movieclip_copy(Main *bmain, const MovieClip *clip)
+/**
+ * Only copy internal data of MovieClip ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_movieclip_copy_data(Main *UNUSED(bmain), MovieClip *clip_dst, const MovieClip *clip_src, const int flag)
{
- MovieClip *clip_new;
-
- clip_new = BKE_libblock_copy(bmain, &clip->id);
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
- clip_new->anim = NULL;
- clip_new->cache = NULL;
+ clip_dst->anim = NULL;
+ clip_dst->cache = NULL;
- BKE_tracking_copy(&clip_new->tracking, &clip->tracking);
- clip_new->tracking_context = NULL;
+ BKE_tracking_copy(&clip_dst->tracking, &clip_src->tracking, flag_subdata);
+ clip_dst->tracking_context = NULL;
- id_us_plus((ID *)clip_new->gpd);
-
- BKE_color_managed_colorspace_settings_copy(&clip_new->colorspace_settings, &clip->colorspace_settings);
-
- BKE_id_copy_ensure_local(bmain, &clip->id, &clip_new->id);
+ BKE_color_managed_colorspace_settings_copy(&clip_dst->colorspace_settings, &clip_src->colorspace_settings);
+}
- return clip_new;
+MovieClip *BKE_movieclip_copy(Main *bmain, const MovieClip *clip)
+{
+ MovieClip *clip_copy;
+ BKE_id_copy_ex(bmain, &clip->id, (ID **)&clip_copy, 0, false);
+ return clip_copy;
}
void BKE_movieclip_make_local(Main *bmain, MovieClip *clip, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 05d6b981dc1..ad0e2324fba 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -902,80 +902,100 @@ bNode *nodeAddStaticNode(const struct bContext *C, bNodeTree *ntree, int type)
return nodeAddNode(C, ntree, idname);
}
-static void node_socket_copy(bNodeSocket *dst, bNodeSocket *src)
+static void node_socket_copy(bNodeSocket *sock_dst, bNodeSocket *sock_src, const int flag)
{
- src->new_sock = dst;
-
- if (src->prop)
- dst->prop = IDP_CopyProperty(src->prop);
-
- if (src->default_value)
- dst->default_value = MEM_dupallocN(src->default_value);
-
- dst->stack_index = 0;
+ sock_src->new_sock = sock_dst;
+
+ if (sock_src->prop) {
+ sock_dst->prop = IDP_CopyProperty_ex(sock_src->prop, flag);
+ }
+
+ if (sock_src->default_value) {
+ sock_dst->default_value = MEM_dupallocN(sock_src->default_value);
+ }
+
+ sock_dst->stack_index = 0;
/* XXX some compositor node (e.g. image, render layers) still store
* some persistent buffer data here, need to clear this to avoid dangling pointers.
*/
- dst->cache = NULL;
+ sock_dst->cache = NULL;
}
/* keep socket listorder identical, for copying links */
/* ntree is the target tree */
-bNode *nodeCopyNode(bNodeTree *ntree, bNode *node)
+bNode *BKE_node_copy_ex(bNodeTree *ntree, bNode *node_src, const int flag)
{
- bNode *nnode = MEM_callocN(sizeof(bNode), "dupli node");
- bNodeSocket *sock, *oldsock;
- bNodeLink *link, *oldlink;
+ bNode *node_dst = MEM_callocN(sizeof(bNode), "dupli node");
+ bNodeSocket *sock_dst, *sock_src;
+ bNodeLink *link_dst, *link_src;
- *nnode = *node;
+ *node_dst = *node_src;
/* can be called for nodes outside a node tree (e.g. clipboard) */
if (ntree) {
- nodeUniqueName(ntree, nnode);
+ nodeUniqueName(ntree, node_dst);
- BLI_addtail(&ntree->nodes, nnode);
+ BLI_addtail(&ntree->nodes, node_dst);
}
- BLI_duplicatelist(&nnode->inputs, &node->inputs);
- oldsock = node->inputs.first;
- for (sock = nnode->inputs.first; sock; sock = sock->next, oldsock = oldsock->next)
- node_socket_copy(sock, oldsock);
-
- BLI_duplicatelist(&nnode->outputs, &node->outputs);
- oldsock = node->outputs.first;
- for (sock = nnode->outputs.first; sock; sock = sock->next, oldsock = oldsock->next)
- node_socket_copy(sock, oldsock);
-
- if (node->prop)
- nnode->prop = IDP_CopyProperty(node->prop);
-
- BLI_duplicatelist(&nnode->internal_links, &node->internal_links);
- oldlink = node->internal_links.first;
- for (link = nnode->internal_links.first; link; link = link->next, oldlink = oldlink->next) {
- link->fromnode = nnode;
- link->tonode = nnode;
- link->fromsock = link->fromsock->new_sock;
- link->tosock = link->tosock->new_sock;
+ BLI_duplicatelist(&node_dst->inputs, &node_src->inputs);
+ for (sock_dst = node_dst->inputs.first, sock_src = node_src->inputs.first;
+ sock_dst != NULL;
+ sock_dst = sock_dst->next, sock_src = sock_src->next)
+ {
+ node_socket_copy(sock_dst, sock_src, flag);
}
-
- /* don't increase node->id users, freenode doesn't decrement either */
-
- if (node->typeinfo->copyfunc)
- node->typeinfo->copyfunc(ntree, nnode, node);
-
- node->new_node = nnode;
- nnode->new_node = NULL;
-
- if (nnode->typeinfo->copyfunc_api) {
+
+ BLI_duplicatelist(&node_dst->outputs, &node_src->outputs);
+ for (sock_dst = node_dst->outputs.first, sock_src = node_src->outputs.first;
+ sock_dst != NULL;
+ sock_dst = sock_dst->next, sock_src = sock_src->next)
+ {
+ node_socket_copy(sock_dst, sock_src, flag);
+ }
+
+ if (node_src->prop) {
+ node_dst->prop = IDP_CopyProperty_ex(node_src->prop, flag);
+ }
+
+ BLI_duplicatelist(&node_dst->internal_links, &node_src->internal_links);
+ for (link_dst = node_dst->internal_links.first, link_src = node_src->internal_links.first;
+ link_dst != NULL;
+ link_dst = link_dst->next, link_src = link_src->next)
+ {
+ link_dst->fromnode = node_dst;
+ link_dst->tonode = node_dst;
+ link_dst->fromsock = link_dst->fromsock->new_sock;
+ link_dst->tosock = link_dst->tosock->new_sock;
+ }
+
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus(node_dst->id);
+ }
+
+ if (node_src->typeinfo->copyfunc) {
+ node_src->typeinfo->copyfunc(ntree, node_dst, node_src);
+ }
+
+ node_src->new_node = node_dst;
+ node_dst->new_node = NULL;
+
+ if (node_dst->typeinfo->copyfunc_api) {
PointerRNA ptr;
- RNA_pointer_create((ID *)ntree, &RNA_Node, nnode, &ptr);
-
- nnode->typeinfo->copyfunc_api(&ptr, node);
+ RNA_pointer_create((ID *)ntree, &RNA_Node, node_dst, &ptr);
+
+ node_dst->typeinfo->copyfunc_api(&ptr, node_src);
}
-
- if (ntree)
+
+ if (ntree) {
ntree->update |= NTREE_UPDATE_NODES;
-
- return nnode;
+ }
+
+ return node_dst;
+}
+
+bNode *nodeCopyNode(bNodeTree *ntree, bNode *node)
+{
+ return BKE_node_copy_ex(ntree, node, LIB_ID_CREATE_NO_USER_REFCOUNT);
}
/* also used via rna api, so we check for proper input output direction */
@@ -1172,7 +1192,7 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
* node groups and other tree types are created as library data.
*/
if (bmain) {
- ntree = BKE_libblock_alloc(bmain, ID_NT, name);
+ ntree = BKE_libblock_alloc(bmain, ID_NT, name, 0);
}
else {
ntree = MEM_callocN(sizeof(bNodeTree), "new node tree");
@@ -1191,119 +1211,101 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
return ntree;
}
-/* Warning: this function gets called during some rather unexpected times
- * - this gets called when executing compositing updates (for threaded previews)
- * - when the nodetree datablock needs to be copied (i.e. when users get copied)
- * - for scene duplication use ntreeSwapID() after so we don't have stale pointers.
+/**
+ * Only copy internal data of NodeTree ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
*
- * do_make_extern: keep enabled for general use, only reason _not_ to enable is when
- * copying for internal use (threads for eg), where you wont want it to modify the
- * scene data.
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
*/
-static bNodeTree *ntreeCopyTree_internal(
- const bNodeTree *ntree, Main *bmain,
- bool skip_database, bool do_id_user, bool do_make_extern, bool copy_previews)
+void BKE_node_tree_copy_data(Main *UNUSED(bmain), bNodeTree *ntree_dst, const bNodeTree *ntree_src, const int flag)
{
- bNodeTree *newtree;
- bNode *node /*, *nnode */ /* UNUSED */, *last;
- bNodeSocket *sock, *oldsock;
- bNodeLink *link;
-
- if (ntree == NULL) return NULL;
-
- /* is ntree part of library? */
- if (bmain && !skip_database && BLI_findindex(&bmain->nodetree, ntree) >= 0) {
- newtree = BKE_libblock_copy(bmain, &ntree->id);
- }
- else {
- newtree = BKE_libblock_copy_nolib(&ntree->id, true);
- }
+ bNode *node_src;
+ bNodeSocket *sock_dst, *sock_src;
+ bNodeLink *link_dst;
- id_us_plus((ID *)newtree->gpd);
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
- /* in case a running nodetree is copied */
- newtree->execdata = NULL;
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)ntree_dst->gpd);
+ }
- newtree->duplilock = NULL;
-
- BLI_listbase_clear(&newtree->nodes);
- BLI_listbase_clear(&newtree->links);
-
- last = ntree->nodes.last;
- for (node = ntree->nodes.first; node; node = node->next) {
+ /* in case a running nodetree is copied */
+ ntree_dst->execdata = NULL;
- /* ntreeUserDecrefID inline */
- if (do_id_user) {
- id_us_plus(node->id);
- }
+ ntree_dst->duplilock = NULL;
- if (do_make_extern) {
- id_lib_extern(node->id);
- }
+ BLI_listbase_clear(&ntree_dst->nodes);
+ BLI_listbase_clear(&ntree_dst->links);
- node->new_node = NULL;
- /* nnode = */ nodeCopyNode(newtree, node); /* sets node->new */
-
- /* make sure we don't copy new nodes again! */
- if (node == last)
- break;
+ for (node_src = ntree_src->nodes.first; node_src; node_src = node_src->next) {
+ BKE_node_copy_ex(ntree_dst, node_src, flag_subdata);
}
-
+
/* copy links */
- BLI_duplicatelist(&newtree->links, &ntree->links);
- for (link = newtree->links.first; link; link = link->next) {
- link->fromnode = (link->fromnode ? link->fromnode->new_node : NULL);
- link->fromsock = (link->fromsock ? link->fromsock->new_sock : NULL);
- link->tonode = (link->tonode ? link->tonode->new_node : NULL);
- link->tosock = (link->tosock ? link->tosock->new_sock : NULL);
+ BLI_duplicatelist(&ntree_dst->links, &ntree_src->links);
+ for (link_dst = ntree_dst->links.first; link_dst; link_dst = link_dst->next) {
+ link_dst->fromnode = (link_dst->fromnode ? link_dst->fromnode->new_node : NULL);
+ link_dst->fromsock = (link_dst->fromsock ? link_dst->fromsock->new_sock : NULL);
+ link_dst->tonode = (link_dst->tonode ? link_dst->tonode->new_node : NULL);
+ link_dst->tosock = (link_dst->tosock ? link_dst->tosock->new_sock : NULL);
/* update the link socket's pointer */
- if (link->tosock)
- link->tosock->link = link;
+ if (link_dst->tosock) {
+ link_dst->tosock->link = link_dst;
+ }
}
-
+
/* copy interface sockets */
- BLI_duplicatelist(&newtree->inputs, &ntree->inputs);
- oldsock = ntree->inputs.first;
- for (sock = newtree->inputs.first; sock; sock = sock->next, oldsock = oldsock->next)
- node_socket_copy(sock, oldsock);
-
- BLI_duplicatelist(&newtree->outputs, &ntree->outputs);
- oldsock = ntree->outputs.first;
- for (sock = newtree->outputs.first; sock; sock = sock->next, oldsock = oldsock->next)
- node_socket_copy(sock, oldsock);
-
+ BLI_duplicatelist(&ntree_dst->inputs, &ntree_src->inputs);
+ for (sock_dst = ntree_dst->inputs.first, sock_src = ntree_src->inputs.first;
+ sock_dst != NULL;
+ sock_dst = sock_dst->next, sock_src = sock_src->next)
+ {
+ node_socket_copy(sock_dst, sock_src, flag_subdata);
+ }
+
+ BLI_duplicatelist(&ntree_dst->outputs, &ntree_src->outputs);
+ for (sock_dst = ntree_dst->outputs.first, sock_src = ntree_src->outputs.first;
+ sock_dst != NULL;
+ sock_dst = sock_dst->next, sock_src = sock_src->next)
+ {
+ node_socket_copy(sock_dst, sock_src, flag_subdata);
+ }
+
/* copy preview hash */
- if (ntree->previews && copy_previews) {
+ if (ntree_src->previews && (flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
bNodeInstanceHashIterator iter;
-
- newtree->previews = BKE_node_instance_hash_new("node previews");
-
- NODE_INSTANCE_HASH_ITER(iter, ntree->previews) {
+
+ ntree_dst->previews = BKE_node_instance_hash_new("node previews");
+
+ NODE_INSTANCE_HASH_ITER(iter, ntree_src->previews) {
bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter);
bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
- BKE_node_instance_hash_insert(newtree->previews, key, BKE_node_preview_copy(preview));
+ BKE_node_instance_hash_insert(ntree_dst->previews, key, BKE_node_preview_copy(preview));
}
}
- else
- newtree->previews = NULL;
-
+ else {
+ ntree_dst->previews = NULL;
+ }
+
/* update node->parent pointers */
- for (node = newtree->nodes.first; node; node = node->next) {
- if (node->parent)
- node->parent = node->parent->new_node;
+ for (node_src = ntree_dst->nodes.first; node_src; node_src = node_src->next) {
+ if (node_src->parent) {
+ node_src->parent = node_src->parent->new_node;
+ }
}
-
- /* node tree will generate its own interface type */
- newtree->interface_type = NULL;
-
- BKE_id_copy_ensure_local(bmain, &ntree->id, &newtree->id);
- return newtree;
+ /* node tree will generate its own interface type */
+ ntree_dst->interface_type = NULL;
}
bNodeTree *ntreeCopyTree_ex(const bNodeTree *ntree, Main *bmain, const bool do_id_user)
{
- return ntreeCopyTree_internal(ntree, bmain, false, do_id_user, true, true);
+ bNodeTree *ntree_copy;
+ BKE_id_copy_ex(bmain, (ID *)ntree, (ID **)&ntree_copy, do_id_user ? 0 : LIB_ID_CREATE_NO_USER_REFCOUNT, false);
+ return ntree_copy;
}
bNodeTree *ntreeCopyTree(Main *bmain, const bNodeTree *ntree)
{
@@ -1994,10 +1996,11 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
adt->tmpact = NULL;
}
- /* Make full copy.
+ /* Make full copy outside of Main database.
* Note: previews are not copied here.
*/
- ltree = ntreeCopyTree_internal(ntree, G.main, true, false, false, false);
+ BKE_id_copy_ex(G.main, (ID *)ntree, (ID **)&ltree,
+ LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_COPY_NO_PREVIEW, false);
ltree->flag |= NTREE_IS_LOCALIZED;
for (node = ltree->nodes.first; node; node = node->next) {
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index efe8498ace5..d7b97ef672d 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -319,7 +319,7 @@ void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_sr
modifier_unique_name(&ob_dst->modifiers, nmd);
}
- BKE_object_copy_particlesystems(ob_dst, ob_src);
+ BKE_object_copy_particlesystems(ob_dst, ob_src, 0);
/* TODO: smoke?, cloth? */
}
@@ -705,7 +705,7 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
if (!name)
name = get_obdata_defname(type);
- ob = BKE_libblock_alloc(bmain, ID_OB, name);
+ ob = BKE_libblock_alloc(bmain, ID_OB, name, 0);
/* default object vars */
ob->type = type;
@@ -875,7 +875,7 @@ struct Object *BKE_object_lod_matob_get(Object *ob, SceneLayer *sl)
#endif /* WITH_GAMEENGINE */
-SoftBody *copy_softbody(const SoftBody *sb, bool copy_caches)
+SoftBody *copy_softbody(const SoftBody *sb, const int flag)
{
SoftBody *sbn;
@@ -883,7 +883,7 @@ SoftBody *copy_softbody(const SoftBody *sb, bool copy_caches)
sbn = MEM_dupallocN(sb);
- if (copy_caches == false) {
+ if ((flag & LIB_ID_COPY_CACHES) == 0) {
sbn->totspring = sbn->totpoint = 0;
sbn->bpoint = NULL;
sbn->bspring = NULL;
@@ -912,7 +912,7 @@ SoftBody *copy_softbody(const SoftBody *sb, bool copy_caches)
sbn->scratch = NULL;
- sbn->pointcache = BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches, copy_caches);
+ sbn->pointcache = BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches, flag);
if (sb->effector_weights)
sbn->effector_weights = MEM_dupallocN(sb->effector_weights);
@@ -920,7 +920,7 @@ SoftBody *copy_softbody(const SoftBody *sb, bool copy_caches)
return sbn;
}
-BulletSoftBody *copy_bulletsoftbody(const BulletSoftBody *bsb)
+BulletSoftBody *copy_bulletsoftbody(const BulletSoftBody *bsb, const int UNUSED(flag))
{
BulletSoftBody *bsbn;
@@ -931,7 +931,7 @@ BulletSoftBody *copy_bulletsoftbody(const BulletSoftBody *bsb)
return bsbn;
}
-ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys)
+ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys, const int flag)
{
ParticleSystem *psysn;
ParticleData *pa;
@@ -968,7 +968,7 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys)
if (psys->clmd) {
psysn->clmd = (ClothModifierData *)modifier_new(eModifierType_Cloth);
- modifier_copyData((ModifierData *)psys->clmd, (ModifierData *)psysn->clmd);
+ modifier_copyData_ex((ModifierData *)psys->clmd, (ModifierData *)psysn->clmd, flag);
psys->hair_in_dm = psys->hair_out_dm = NULL;
}
@@ -987,7 +987,8 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys)
BLI_listbase_clear(&psysn->childcachebufs);
psysn->renderdata = NULL;
- psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, false);
+ /* XXX Never copy caches here? */
+ psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, flag & ~LIB_ID_COPY_CACHES);
/* XXX - from reading existing code this seems correct but intended usage of
* pointcache should /w cloth should be added in 'ParticleSystem' - campbell */
@@ -995,12 +996,14 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys)
psysn->clmd->point_cache = psysn->pointcache;
}
- id_us_plus((ID *)psysn->part);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)psysn->part);
+ }
return psysn;
}
-void BKE_object_copy_particlesystems(Object *ob_dst, const Object *ob_src)
+void BKE_object_copy_particlesystems(Object *ob_dst, const Object *ob_src, const int flag)
{
ParticleSystem *psys, *npsys;
ModifierData *md;
@@ -1012,7 +1015,7 @@ void BKE_object_copy_particlesystems(Object *ob_dst, const Object *ob_src)
BLI_listbase_clear(&ob_dst->particlesystem);
for (psys = ob_src->particlesystem.first; psys; psys = psys->next) {
- npsys = BKE_object_copy_particlesystem(psys);
+ npsys = BKE_object_copy_particlesystem(psys, flag);
BLI_addtail(&ob_dst->particlesystem, npsys);
@@ -1049,23 +1052,25 @@ void BKE_object_copy_softbody(Object *ob_dst, const Object *ob_src)
{
if (ob_src->soft) {
ob_dst->softflag = ob_src->softflag;
- ob_dst->soft = copy_softbody(ob_src->soft, false);
+ ob_dst->soft = copy_softbody(ob_src->soft, 0);
}
}
-static void copy_object_pose(Object *obn, const Object *ob)
+static void copy_object_pose(Object *obn, const Object *ob, const int flag)
{
bPoseChannel *chan;
/* note: need to clear obn->pose pointer first, so that BKE_pose_copy_data works (otherwise there's a crash) */
obn->pose = NULL;
- BKE_pose_copy_data(&obn->pose, ob->pose, 1); /* 1 = copy constraints */
+ BKE_pose_copy_data_ex(&obn->pose, ob->pose, flag, true); /* true = copy constraints */
for (chan = obn->pose->chanbase.first; chan; chan = chan->next) {
bConstraint *con;
chan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE);
+ /* XXX Remapping object pointing onto itself should be handled by generic BKE_library_remap stuff, but...
+ * the flush_constraint_targets callback am not sure about, so will delay that for now. */
for (con = chan->constraints.first; con; con = con->next) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
@@ -1086,13 +1091,10 @@ static void copy_object_pose(Object *obn, const Object *ob)
}
}
-static void copy_object_lod(Object *obn, const Object *ob)
+static void copy_object_lod(Object *obn, const Object *ob, const int UNUSED(flag))
{
BLI_duplicatelist(&obn->lodlevels, &ob->lodlevels);
- if (obn->lodlevels.first)
- ((LodLevel *)obn->lodlevels.first)->source = obn;
-
obn->currentlod = (LodLevel *)obn->lodlevels.first;
}
@@ -1137,100 +1139,100 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
copy_v3_v3(ob_tar->size, ob_src->size);
}
-Object *BKE_object_copy_ex(Main *bmain, const Object *ob, bool copy_caches)
+/**
+ * Only copy internal data of Object ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_src, const int flag)
{
- Object *obn;
ModifierData *md;
- int a;
- obn = BKE_libblock_copy(bmain, &ob->id);
-
- if (ob->totcol) {
- obn->mat = MEM_dupallocN(ob->mat);
- obn->matbits = MEM_dupallocN(ob->matbits);
- obn->totcol = ob->totcol;
+ /* 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;
}
- if (ob->iuser) obn->iuser = MEM_dupallocN(ob->iuser);
+ if (ob_src->iuser) ob_dst->iuser = MEM_dupallocN(ob_src->iuser);
- if (ob->bb) obn->bb = MEM_dupallocN(ob->bb);
- obn->flag &= ~OB_FROMGROUP;
+ if (ob_src->bb) ob_dst->bb = MEM_dupallocN(ob_src->bb);
+ ob_dst->flag &= ~OB_FROMGROUP;
- BLI_listbase_clear(&obn->modifiers);
+ BLI_listbase_clear(&ob_dst->modifiers);
- for (md = ob->modifiers.first; md; md = md->next) {
+ 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(md, nmd);
- BLI_addtail(&obn->modifiers, nmd);
+ modifier_copyData_ex(md, nmd, flag_subdata);
+ BLI_addtail(&ob_dst->modifiers, nmd);
}
- BLI_listbase_clear(&obn->prop);
- BKE_bproperty_copy_list(&obn->prop, &ob->prop);
+ BLI_listbase_clear(&ob_dst->prop);
+ BKE_bproperty_copy_list(&ob_dst->prop, &ob_src->prop);
- BKE_sca_logic_copy(obn, ob);
+ BKE_sca_logic_copy(ob_dst, ob_src, flag_subdata);
- if (ob->pose) {
- copy_object_pose(obn, ob);
+ 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->type == OB_ARMATURE)
- BKE_pose_rebuild(obn, obn->data);
+ if (ob_src->type == OB_ARMATURE)
+ BKE_pose_rebuild(ob_dst, ob_dst->data);
}
- defgroup_copy_list(&obn->defbase, &ob->defbase);
+ defgroup_copy_list(&ob_dst->defbase, &ob_src->defbase);
BKE_object_facemap_copy_list(&obn->fmaps, &ob->fmaps);
- BKE_constraints_copy(&obn->constraints, &ob->constraints, true);
+ BKE_constraints_copy_ex(&ob_dst->constraints, &ob_src->constraints, flag_subdata, true);
- obn->mode = OB_MODE_OBJECT;
- obn->sculpt = NULL;
+ ob_dst->mode = OB_MODE_OBJECT;
+ ob_dst->sculpt = NULL;
- /* increase user numbers */
- id_us_plus((ID *)obn->data);
- id_us_plus((ID *)obn->poselib);
- id_us_plus((ID *)obn->gpd);
- id_us_plus((ID *)obn->dup_group);
+ 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);
+ }
+ }
+ ob_dst->soft = copy_softbody(ob_src->soft, flag_subdata);
+ ob_dst->bsoft = copy_bulletsoftbody(ob_src->bsoft, flag_subdata);
+ ob_dst->rigidbody_object = BKE_rigidbody_copy_object(ob_src, flag_subdata);
+ ob_dst->rigidbody_constraint = BKE_rigidbody_copy_constraint(ob_src, flag_subdata);
- for (a = 0; a < obn->totcol; a++) id_us_plus((ID *)obn->mat[a]);
+ BKE_object_copy_particlesystems(ob_dst, ob_src, flag_subdata);
- if (ob->pd) {
- obn->pd = MEM_dupallocN(ob->pd);
- if (obn->pd->tex)
- id_us_plus(&(obn->pd->tex->id));
- if (obn->pd->rng)
- obn->pd->rng = MEM_dupallocN(ob->pd->rng);
- }
- obn->soft = copy_softbody(ob->soft, copy_caches);
- obn->bsoft = copy_bulletsoftbody(ob->bsoft);
- obn->rigidbody_object = BKE_rigidbody_copy_object(ob);
- obn->rigidbody_constraint = BKE_rigidbody_copy_constraint(ob);
-
- BKE_object_copy_particlesystems(obn, ob);
-
- obn->derivedDeform = NULL;
- obn->derivedFinal = NULL;
+ ob_dst->derivedDeform = NULL;
+ ob_dst->derivedFinal = NULL;
- BLI_listbase_clear(&obn->gpulamp);
- BLI_listbase_clear(&obn->pc_ids);
- BLI_listbase_clear(&obn->drawdata);
+ BLI_listbase_clear(&ob_dst->gpulamp);
+ BLI_listbase_clear(&ob_dst->pc_ids);
- obn->mpath = NULL;
+ ob_dst->mpath = NULL;
- copy_object_lod(obn, ob);
+ copy_object_lod(ob_dst, ob_src, flag_subdata);
- /* Copy runtime surve data. */
- obn->curve_cache = NULL;
-
- BKE_id_copy_ensure_local(bmain, &ob->id, &obn->id);
+ /* Do not copy runtime curve data. */
+ ob_dst->curve_cache = NULL;
/* Do not copy object's preview (mostly due to the fact renderers create temp copy of objects). */
- obn->preview = NULL;
-
- return obn;
+ 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;
+ }
}
/* copy objects, will re-initialize cached simulation data */
Object *BKE_object_copy(Main *bmain, const Object *ob)
{
- return BKE_object_copy_ex(bmain, ob, false);
+ Object *ob_copy;
+ BKE_id_copy_ex(bmain, &ob->id, (ID **)&ob_copy, 0, false);
+ return ob_copy;
}
void BKE_object_make_local_ex(Main *bmain, Object *ob, const bool lib_local, const bool clear_proxy)
@@ -1306,10 +1308,10 @@ static void armature_set_id_extern(Object *ob)
unsigned int lay = arm->layer_protected;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- if (!(pchan->bone->layer & lay)) {
+ if (!(pchan->bone->layer & lay))
id_lib_extern((ID *)pchan->custom);
- }
}
+
}
void BKE_object_copy_proxy_drivers(Object *ob, Object *target)
@@ -1428,7 +1430,7 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
/* type conversions */
if (target->type == OB_ARMATURE) {
- copy_object_pose(ob, target); /* data copy, object pointers in constraints */
+ copy_object_pose(ob, target, 0); /* data copy, object pointers in constraints */
BKE_pose_rest(ob->pose); /* clear all transforms in channels */
BKE_pose_rebuild(ob, ob->data); /* set all internal links */
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index eebe514c7ca..1831ca02ee8 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -312,24 +312,31 @@ PaintCurve *BKE_paint_curve_add(Main *bmain, const char *name)
{
PaintCurve *pc;
- pc = BKE_libblock_alloc(bmain, ID_PC, name);
+ pc = BKE_libblock_alloc(bmain, ID_PC, name, 0);
return pc;
}
-PaintCurve *BKE_paint_curve_copy(Main *bmain, const PaintCurve *pc)
+/**
+ * Only copy internal data of PaintCurve ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_paint_curve_copy_data(Main *UNUSED(bmain), PaintCurve *pc_dst, const PaintCurve *pc_src, const int UNUSED(flag))
{
- PaintCurve *pc_new;
-
- pc_new = BKE_libblock_copy(bmain, &pc->id);
-
- if (pc->tot_points != 0) {
- pc_new->points = MEM_dupallocN(pc->points);
+ if (pc_src->tot_points != 0) {
+ pc_dst->points = MEM_dupallocN(pc_src->points);
}
+}
- BKE_id_copy_ensure_local(bmain, &pc->id, &pc_new->id);
-
- return pc_new;
+PaintCurve *BKE_paint_curve_copy(Main *bmain, const PaintCurve *pc)
+{
+ PaintCurve *pc_copy;
+ BKE_id_copy_ex(bmain, &pc->id, (ID **)&pc_copy, 0, false);
+ return pc_copy;
}
void BKE_paint_curve_make_local(Main *bmain, PaintCurve *pc, const bool lib_local)
@@ -391,7 +398,7 @@ Palette *BKE_palette_add(Main *bmain, const char *name)
{
Palette *palette;
- palette = BKE_libblock_alloc(bmain, ID_PAL, name);
+ palette = BKE_libblock_alloc(bmain, ID_PAL, name, 0);
/* enable fake user by default */
id_fake_user_set(&palette->id);
@@ -399,17 +406,24 @@ Palette *BKE_palette_add(Main *bmain, const char *name)
return palette;
}
-Palette *BKE_palette_copy(Main *bmain, const Palette *palette)
+/**
+ * Only copy internal data of Palette ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_palette_copy_data(Main *UNUSED(bmain), Palette *palette_dst, const Palette *palette_src, const int UNUSED(flag))
{
- Palette *palette_new;
-
- palette_new = BKE_libblock_copy(bmain, &palette->id);
-
- BLI_duplicatelist(&palette_new->colors, &palette->colors);
-
- BKE_id_copy_ensure_local(bmain, &palette->id, &palette_new->id);
+ BLI_duplicatelist(&palette_dst->colors, &palette_src->colors);
+}
- return palette_new;
+Palette *BKE_palette_copy(Main *bmain, const Palette *palette)
+{
+ Palette *palette_copy;
+ BKE_id_copy_ex(bmain, &palette->id, (ID **)&palette_copy, 0, false);
+ return palette_copy;
}
void BKE_palette_make_local(Main *bmain, Palette *palette, const bool lib_local)
@@ -540,12 +554,15 @@ void BKE_paint_free(Paint *paint)
* still do a id_us_plus(), rather then if we were copying between 2 existing
* scenes where a matching value should decrease the existing user count as
* with paint_brush_set() */
-void BKE_paint_copy(Paint *src, Paint *tar)
+void BKE_paint_copy(Paint *src, Paint *tar, const int flag)
{
tar->brush = src->brush;
- id_us_plus((ID *)tar->brush);
- id_us_plus((ID *)tar->palette);
tar->cavity_curve = curvemapping_copy(src->cavity_curve);
+
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)tar->brush);
+ id_us_plus((ID *)tar->palette);
+ }
}
void BKE_paint_stroke_get_average(Scene *scene, Object *ob, float stroke[3])
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index ed644bc8a99..bf9c693d903 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3306,7 +3306,7 @@ ParticleSettings *psys_new_settings(const char *name, Main *main)
if (main == NULL)
main = G.main;
- part = BKE_libblock_alloc(main, ID_PA, name);
+ part = BKE_libblock_alloc(main, ID_PA, name, 0);
default_particle_settings(part);
@@ -3337,38 +3337,45 @@ void BKE_particlesettings_rough_curve_init(ParticleSettings *part)
part->roughcurve = cumap;
}
-ParticleSettings *BKE_particlesettings_copy(Main *bmain, const ParticleSettings *part)
+/**
+ * Only copy internal data of ParticleSettings ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_particlesettings_copy_data(
+ Main *UNUSED(bmain), ParticleSettings *part_dst, const ParticleSettings *part_src, const int UNUSED(flag))
{
- ParticleSettings *partn;
- int a;
+ part_dst->pd = MEM_dupallocN(part_src->pd);
+ part_dst->pd2 = MEM_dupallocN(part_src->pd2);
+ part_dst->effector_weights = MEM_dupallocN(part_src->effector_weights);
+ part_dst->fluid = MEM_dupallocN(part_src->fluid);
- partn = BKE_libblock_copy(bmain, &part->id);
+ if (part_src->clumpcurve) {
+ part_dst->clumpcurve = curvemapping_copy(part_src->clumpcurve);
+ }
+ if (part_src->roughcurve) {
+ part_dst->roughcurve = curvemapping_copy(part_src->roughcurve);
+ }
- partn->pd = MEM_dupallocN(part->pd);
- partn->pd2 = MEM_dupallocN(part->pd2);
- partn->effector_weights = MEM_dupallocN(part->effector_weights);
- partn->fluid = MEM_dupallocN(part->fluid);
+ part_dst->boids = boid_copy_settings(part_src->boids);
- if (part->clumpcurve)
- partn->clumpcurve = curvemapping_copy(part->clumpcurve);
- if (part->roughcurve)
- partn->roughcurve = curvemapping_copy(part->roughcurve);
-
- partn->boids = boid_copy_settings(part->boids);
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (part->mtex[a]) {
- partn->mtex[a] = MEM_mallocN(sizeof(MTex), "psys_copy_tex");
- memcpy(partn->mtex[a], part->mtex[a], sizeof(MTex));
- id_us_plus((ID *)partn->mtex[a]->tex);
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (part_src->mtex[a]) {
+ part_dst->mtex[a] = MEM_dupallocN(part_src->mtex[a]);
}
}
- BLI_duplicatelist(&partn->dupliweights, &part->dupliweights);
-
- BKE_id_copy_ensure_local(bmain, &part->id, &partn->id);
+ BLI_duplicatelist(&part_dst->dupliweights, &part_src->dupliweights);
+}
- return partn;
+ParticleSettings *BKE_particlesettings_copy(Main *bmain, const ParticleSettings *part)
+{
+ ParticleSettings *part_copy;
+ BKE_id_copy_ex(bmain, &part->id, (ID **)&part_copy, 0, false);
+ return part_copy;
}
void BKE_particlesettings_make_local(Main *bmain, ParticleSettings *part, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 0b152534dcb..341a4d1fde5 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -3449,7 +3449,7 @@ void BKE_ptcache_free_list(ListBase *ptcaches)
}
}
-static PointCache *ptcache_copy(PointCache *cache, bool copy_data)
+static PointCache *ptcache_copy(PointCache *cache, const bool copy_data)
{
PointCache *ncache;
@@ -3492,14 +3492,15 @@ static PointCache *ptcache_copy(PointCache *cache, bool copy_data)
}
/* returns first point cache */
-PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, const ListBase *ptcaches_old, bool copy_data)
+PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, const ListBase *ptcaches_old, const int flag)
{
PointCache *cache = ptcaches_old->first;
BLI_listbase_clear(ptcaches_new);
- for (; cache; cache=cache->next)
- BLI_addtail(ptcaches_new, ptcache_copy(cache, copy_data));
+ for (; cache; cache=cache->next) {
+ BLI_addtail(ptcaches_new, ptcache_copy(cache, (flag & LIB_ID_COPY_CACHES) != 0));
+ }
return ptcaches_new->first;
}
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index ee78bc4d678..9a8ab97ffa0 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -183,7 +183,7 @@ void BKE_rigidbody_free_constraint(Object *ob)
* be added to relevant groups later...
*/
-RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob)
+RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int UNUSED(flag))
{
RigidBodyOb *rboN = NULL;
@@ -203,7 +203,7 @@ RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob)
return rboN;
}
-RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob)
+RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob, const int UNUSED(flag))
{
RigidBodyCon *rbcN = NULL;
@@ -944,24 +944,26 @@ RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
return rbw;
}
-RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw)
+RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag)
{
- RigidBodyWorld *rbwn = MEM_dupallocN(rbw);
+ RigidBodyWorld *rbw_copy = MEM_dupallocN(rbw);
- if (rbw->effector_weights)
- rbwn->effector_weights = MEM_dupallocN(rbw->effector_weights);
- if (rbwn->group)
- id_us_plus(&rbwn->group->id);
- if (rbwn->constraints)
- id_us_plus(&rbwn->constraints->id);
+ if (rbw->effector_weights) {
+ rbw_copy->effector_weights = MEM_dupallocN(rbw->effector_weights);
+ }
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)rbw_copy->group);
+ id_us_plus((ID *)rbw_copy->constraints);
+ }
- rbwn->pointcache = BKE_ptcache_copy_list(&rbwn->ptcaches, &rbw->ptcaches, false);
+ /* XXX Never copy caches here? */
+ rbw_copy->pointcache = BKE_ptcache_copy_list(&rbw_copy->ptcaches, &rbw->ptcaches, flag & ~LIB_ID_COPY_CACHES);
- rbwn->objects = NULL;
- rbwn->physics_world = NULL;
- rbwn->numbodies = 0;
+ rbw_copy->objects = NULL;
+ rbw_copy->physics_world = NULL;
+ rbw_copy->numbodies = 0;
- return rbwn;
+ return rbw_copy;
}
void BKE_rigidbody_world_groups_relink(RigidBodyWorld *rbw)
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index 19d646daf9f..fb81ed4d47f 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -72,7 +72,7 @@ void free_sensors(ListBase *lb)
}
}
-bSensor *copy_sensor(bSensor *sens)
+bSensor *copy_sensor(bSensor *sens, const int UNUSED(flag))
{
bSensor *sensn;
@@ -87,14 +87,14 @@ bSensor *copy_sensor(bSensor *sens)
return sensn;
}
-void copy_sensors(ListBase *lbn, const ListBase *lbo)
+void copy_sensors(ListBase *lbn, const ListBase *lbo, const int flag)
{
bSensor *sens, *sensn;
lbn->first= lbn->last= NULL;
sens= lbo->first;
while (sens) {
- sensn= copy_sensor(sens);
+ sensn= copy_sensor(sens, flag);
BLI_addtail(lbn, sensn);
sens= sens->next;
}
@@ -234,7 +234,7 @@ void free_controllers(ListBase *lb)
}
}
-bController *copy_controller(bController *cont)
+bController *copy_controller(bController *cont, const int UNUSED(flag))
{
bController *contn;
@@ -251,14 +251,14 @@ bController *copy_controller(bController *cont)
return contn;
}
-void copy_controllers(ListBase *lbn, const ListBase *lbo)
+void copy_controllers(ListBase *lbn, const ListBase *lbo, const int flag)
{
bController *cont, *contn;
lbn->first= lbn->last= NULL;
cont= lbo->first;
while (cont) {
- contn= copy_controller(cont);
+ contn= copy_controller(cont, flag);
BLI_addtail(lbn, contn);
cont= cont->next;
}
@@ -359,7 +359,7 @@ void free_actuators(ListBase *lb)
}
}
-bActuator *copy_actuator(bActuator *act)
+bActuator *copy_actuator(bActuator *act, const int flag)
{
bActuator *actn;
@@ -374,29 +374,31 @@ bActuator *copy_actuator(bActuator *act)
case ACT_SHAPEACTION:
{
bActionActuator *aa = (bActionActuator *)act->data;
- if (aa->act)
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
id_us_plus((ID *)aa->act);
+ }
break;
}
case ACT_SOUND:
{
bSoundActuator *sa = (bSoundActuator *)act->data;
- if (sa->sound)
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
id_us_plus((ID *)sa->sound);
+ }
break;
}
}
return actn;
}
-void copy_actuators(ListBase *lbn, const ListBase *lbo)
+void copy_actuators(ListBase *lbn, const ListBase *lbo, const int flag)
{
bActuator *act, *actn;
lbn->first= lbn->last= NULL;
act= lbo->first;
while (act) {
- actn= copy_actuator(act);
+ actn= copy_actuator(act, flag);
BLI_addtail(lbn, actn);
act= act->next;
}
@@ -783,11 +785,11 @@ void BKE_sca_logic_links_remap(Main *bmain, Object *ob_old, Object *ob_new)
* Handle the copying of logic data into a new object, including internal logic links update.
* External links (links between logic bricks of different objects) must be handled separately.
*/
-void BKE_sca_logic_copy(Object *ob_new, const Object *ob)
+void BKE_sca_logic_copy(Object *ob_new, const Object *ob, const int flag)
{
- copy_sensors(&ob_new->sensors, &ob->sensors);
- copy_controllers(&ob_new->controllers, &ob->controllers);
- copy_actuators(&ob_new->actuators, &ob->actuators);
+ copy_sensors(&ob_new->sensors, &ob->sensors, flag);
+ copy_controllers(&ob_new->controllers, &ob->controllers, flag);
+ copy_actuators(&ob_new->actuators, &ob->actuators, flag);
for (bSensor *sens = ob_new->sensors.first; sens; sens = sens->next) {
if (sens->flag & SENS_NEW) {
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 4ebc47244fb..937b5ccffd6 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -213,272 +213,357 @@ static void layer_collections_recreate(SceneLayer *sl, ListBase *lb, SceneCollec
}
}
-Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
-{
- Scene *scen;
- SceneRenderLayer *srl, *new_srl;
- FreestyleLineSet *lineset;
- ToolSettings *ts;
- BaseLegacy *legacy_base, *olegacy_base;
-
- if (type == SCE_COPY_EMPTY) {
- ListBase rl, rv;
- scen = BKE_scene_add(bmain, sce->id.name + 2);
-
- rl = scen->r.layers;
- rv = scen->r.views;
- curvemapping_free_data(&scen->r.mblur_shutter_curve);
- scen->r = sce->r;
- scen->r.layers = rl;
- scen->r.actlay = 0;
- scen->r.views = rv;
- scen->unit = sce->unit;
- scen->physics_settings = sce->physics_settings;
- scen->gm = sce->gm;
- scen->audio = sce->audio;
-
- if (sce->id.properties)
- scen->id.properties = IDP_CopyProperty(sce->id.properties);
-
- MEM_freeN(scen->toolsettings);
- BKE_sound_destroy_scene(scen);
- }
- else {
- scen = BKE_libblock_copy(bmain, &sce->id);
- BLI_duplicatelist(&(scen->base), &(sce->base));
-
- if (type != SCE_COPY_FULL) {
- id_us_plus((ID *)scen->world);
+/**
+ * Only copy internal data of Scene ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, const int flag)
+{
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
+
+ sce_dst->ed = NULL;
+ sce_dst->theDag = NULL;
+ sce_dst->depsgraph = NULL;
+ sce_dst->obedit = NULL;
+ sce_dst->stats = NULL;
+ sce_dst->fps_info = NULL;
+
+ BLI_duplicatelist(&(sce_dst->base), &(sce_src->base));
+ for (BaseLegacy *base_dst = sce_dst->base.first, *base_src = sce_src->base.first;
+ base_dst;
+ base_dst = base_dst->next, base_src = base_src->next)
+ {
+ if (base_src == sce_src->basact) {
+ sce_dst->basact = base_dst;
}
- id_us_plus((ID *)scen->set);
- /* id_us_plus((ID *)scen->gm.dome.warptext); */ /* XXX Not refcounted? see readfile.c */
-
- scen->ed = NULL;
- scen->theDag = NULL;
- scen->depsgraph_legacy = NULL;
- scen->obedit = NULL;
- scen->fps_info = NULL;
+ }
- if (sce->rigidbody_world)
- scen->rigidbody_world = BKE_rigidbody_world_copy(sce->rigidbody_world);
+ /* layers and collections */
+ sce_dst->collection = MEM_dupallocN(sce_src->collection);
+ SceneCollection *mcn = BKE_collection_master(sce_dst);
+ SceneCollection *mc = BKE_collection_master(sce_src);
- BLI_duplicatelist(&(scen->markers), &(sce->markers));
- BLI_duplicatelist(&(scen->r.layers), &(sce->r.layers));
- BLI_duplicatelist(&(scen->r.views), &(sce->r.views));
- BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets));
+ /* recursively creates a new SceneCollection tree */
+ scene_collection_copy(mcn, mc);
- if (sce->nodetree) {
- /* ID's are managed on both copy and switch */
- scen->nodetree = ntreeCopyTree(bmain, sce->nodetree);
- BKE_libblock_relink_ex(bmain, scen->nodetree, &sce->id, &scen->id, false);
- }
+ IDPropertyTemplate val = {0};
+ BLI_duplicatelist(&sce_dst->render_layers, &sce_src->render_layers);
+ SceneLayer *new_sl = sce_dst->render_layers.first;
+ for (SceneLayer *sl = sce_src->render_layers.first; sl; sl = sl->next) {
+ new_sl->stats = NULL;
+ new_sl->properties_evaluated = NULL;
+ new_sl->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ IDP_MergeGroup(new_sl->properties, sl->properties, true);
+
+ /* we start fresh with no overrides and no visibility flags set
+ * instead of syncing both trees we simply unlink and relink the scene collection */
+ BLI_listbase_clear(&new_sl->layer_collections);
+ BLI_listbase_clear(&new_sl->object_bases);
+ BLI_listbase_clear(&new_sl->drawdata);
+ layer_collections_recreate(new_sl, &sl->layer_collections, mcn, mc);
+
+ Object *active_ob = OBACT_NEW;
+ Base *new_base = new_sl->object_bases.first;
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ new_base->flag = base->flag;
+ new_base->flag_legacy = base->flag_legacy;
+
+ if (new_base->object == active_ob) {
+ new_sl->basact = new_base;
+ }
- olegacy_base = sce->base.first;
- legacy_base = scen->base.first;
- while (legacy_base) {
- id_us_plus(&legacy_base->object->id);
- if (olegacy_base == sce->basact) scen->basact = legacy_base;
-
- olegacy_base = olegacy_base->next;
- legacy_base = legacy_base->next;
+ new_base = new_base->next;
}
+ new_sl = new_sl->next;
+ }
- /* copy action and remove animation used by sequencer */
- BKE_animdata_copy_id_action(&scen->id, false);
+ sce_dst->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ sce_dst->layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
- if (type != SCE_COPY_FULL)
- remove_sequencer_fcurves(scen);
+ BLI_duplicatelist(&(sce_dst->markers), &(sce_src->markers));
+ BLI_duplicatelist(&(sce_dst->r.layers), &(sce_src->r.layers));
+ BLI_duplicatelist(&(sce_dst->r.views), &(sce_src->r.views));
+ BKE_keyingsets_copy(&(sce_dst->keyingsets), &(sce_src->keyingsets));
- /* copy Freestyle settings */
- new_srl = scen->r.layers.first;
- for (srl = sce->r.layers.first; srl; srl = srl->next) {
- if (new_srl->prop != NULL) {
- new_srl->prop = IDP_CopyProperty(new_srl->prop);
- }
- BKE_freestyle_config_copy(&new_srl->freestyleConfig, &srl->freestyleConfig);
- if (type == SCE_COPY_FULL) {
- for (lineset = new_srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
- if (lineset->linestyle) {
- /* Has been incremented by BKE_freestyle_config_copy(). */
- id_us_min(&lineset->linestyle->id);
- lineset->linestyle = BKE_linestyle_copy(bmain, lineset->linestyle);
- }
- }
- }
- new_srl = new_srl->next;
- }
+ if (sce_src->nodetree) {
+ BKE_id_copy_ex(bmain, (ID *)sce_src->nodetree, (ID **)&sce_dst->nodetree, flag, false);
+ BKE_libblock_relink_ex(bmain, sce_dst->nodetree, (void *)(&sce_src->id), &sce_dst->id, false);
+ }
- /* layers and collections */
- scen->collection = MEM_dupallocN(sce->collection);
- SceneCollection *mcn = BKE_collection_master(scen);
- SceneCollection *mc = BKE_collection_master(sce);
-
- /* recursively creates a new SceneCollection tree */
- scene_collection_copy(mcn, mc);
-
- IDPropertyTemplate val = {0};
- BLI_duplicatelist(&scen->render_layers, &sce->render_layers);
- SceneLayer *new_sl = scen->render_layers.first;
- for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
- new_sl->stats = NULL;
- new_sl->properties_evaluated = NULL;
- new_sl->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
- IDP_MergeGroup(new_sl->properties, sl->properties, true);
-
- /* we start fresh with no overrides and no visibility flags set
- * instead of syncing both trees we simply unlink and relink the scene collection */
- BLI_listbase_clear(&new_sl->layer_collections);
- BLI_listbase_clear(&new_sl->object_bases);
- BLI_listbase_clear(&new_sl->drawdata);
- layer_collections_recreate(new_sl, &sl->layer_collections, mcn, mc);
-
- Object *active_ob = OBACT_NEW;
- Base *new_base = new_sl->object_bases.first;
- for (Base *base = sl->object_bases.first; base; base = base->next) {
- new_base->flag = base->flag;
- new_base->flag_legacy = base->flag_legacy;
-
- if (new_base->object == active_ob) {
- new_sl->basact = new_base;
- }
+ if (sce_src->rigidbody_world) {
+ sce_dst->rigidbody_world = BKE_rigidbody_world_copy(sce_src->rigidbody_world, flag_subdata);
+ }
- new_base = new_base->next;
- }
- new_sl = new_sl->next;
+ /* copy Freestyle settings */
+ for (SceneRenderLayer *srl_dst = sce_dst->r.layers.first, *srl_src = sce_src->r.layers.first;
+ srl_src;
+ srl_dst = srl_dst->next, srl_src = srl_src->next)
+ {
+ if (srl_dst->prop != NULL) {
+ srl_dst->prop = IDP_CopyProperty_ex(srl_dst->prop, flag_subdata);
}
-
- scen->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
- scen->layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ BKE_freestyle_config_copy(&srl_dst->freestyleConfig, &srl_src->freestyleConfig, flag_subdata);
}
/* copy color management settings */
- BKE_color_managed_display_settings_copy(&scen->display_settings, &sce->display_settings);
- BKE_color_managed_view_settings_copy(&scen->view_settings, &sce->view_settings);
- BKE_color_managed_colorspace_settings_copy(&scen->sequencer_colorspace_settings, &sce->sequencer_colorspace_settings);
+ BKE_color_managed_display_settings_copy(&sce_dst->display_settings, &sce_src->display_settings);
+ BKE_color_managed_view_settings_copy(&sce_dst->view_settings, &sce_src->view_settings);
+ BKE_color_managed_colorspace_settings_copy(&sce_dst->sequencer_colorspace_settings, &sce_src->sequencer_colorspace_settings);
- BKE_color_managed_display_settings_copy(&scen->r.im_format.display_settings, &sce->r.im_format.display_settings);
- BKE_color_managed_view_settings_copy(&scen->r.im_format.view_settings, &sce->r.im_format.view_settings);
+ BKE_color_managed_display_settings_copy(&sce_dst->r.im_format.display_settings, &sce_src->r.im_format.display_settings);
+ BKE_color_managed_view_settings_copy(&sce_dst->r.im_format.view_settings, &sce_src->r.im_format.view_settings);
- BKE_color_managed_display_settings_copy(&scen->r.bake.im_format.display_settings, &sce->r.bake.im_format.display_settings);
- BKE_color_managed_view_settings_copy(&scen->r.bake.im_format.view_settings, &sce->r.bake.im_format.view_settings);
+ BKE_color_managed_display_settings_copy(&sce_dst->r.bake.im_format.display_settings, &sce_src->r.bake.im_format.display_settings);
+ BKE_color_managed_view_settings_copy(&sce_dst->r.bake.im_format.view_settings, &sce_src->r.bake.im_format.view_settings);
- curvemapping_copy_data(&scen->r.mblur_shutter_curve, &sce->r.mblur_shutter_curve);
+ curvemapping_copy_data(&sce_dst->r.mblur_shutter_curve, &sce_src->r.mblur_shutter_curve);
/* tool settings */
- scen->toolsettings = MEM_dupallocN(sce->toolsettings);
-
- ts = scen->toolsettings;
- if (ts) {
+ if (sce_dst->toolsettings != NULL) {
+ ToolSettings *ts = sce_dst->toolsettings = MEM_dupallocN(sce_dst->toolsettings);
if (ts->vpaint) {
ts->vpaint = MEM_dupallocN(ts->vpaint);
ts->vpaint->paintcursor = NULL;
ts->vpaint->vpaint_prev = NULL;
ts->vpaint->wpaint_prev = NULL;
- BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint);
+ BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint, flag_subdata);
}
if (ts->wpaint) {
ts->wpaint = MEM_dupallocN(ts->wpaint);
ts->wpaint->paintcursor = NULL;
ts->wpaint->vpaint_prev = NULL;
ts->wpaint->wpaint_prev = NULL;
- BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint);
+ BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint, flag_subdata);
}
if (ts->sculpt) {
ts->sculpt = MEM_dupallocN(ts->sculpt);
- BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint);
+ BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint, flag_subdata);
}
if (ts->uvsculpt) {
ts->uvsculpt = MEM_dupallocN(ts->uvsculpt);
- BKE_paint_copy(&ts->uvsculpt->paint, &ts->uvsculpt->paint);
+ BKE_paint_copy(&ts->uvsculpt->paint, &ts->uvsculpt->paint, flag_subdata);
}
- BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint);
+ BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint, flag_subdata);
ts->imapaint.paintcursor = NULL;
- id_us_plus((ID *)ts->imapaint.stencil);
- id_us_plus((ID *)ts->imapaint.clone);
- id_us_plus((ID *)ts->imapaint.canvas);
ts->particle.paintcursor = NULL;
ts->particle.scene = NULL;
ts->particle.object = NULL;
-
+
/* duplicate Grease Pencil Drawing Brushes */
BLI_listbase_clear(&ts->gp_brushes);
- for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) {
+ for (bGPDbrush *brush = sce_src->toolsettings->gp_brushes.first; brush; brush = brush->next) {
bGPDbrush *newbrush = BKE_gpencil_brush_duplicate(brush);
BLI_addtail(&ts->gp_brushes, newbrush);
}
-
+
/* duplicate Grease Pencil interpolation curve */
ts->gp_interpolate.custom_ipo = curvemapping_copy(ts->gp_interpolate.custom_ipo);
}
-
+
/* make a private copy of the avicodecdata */
- if (sce->r.avicodecdata) {
- scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata);
- scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat);
- scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms);
+ if (sce_src->r.avicodecdata) {
+ sce_dst->r.avicodecdata = MEM_dupallocN(sce_src->r.avicodecdata);
+ sce_dst->r.avicodecdata->lpFormat = MEM_dupallocN(sce_dst->r.avicodecdata->lpFormat);
+ sce_dst->r.avicodecdata->lpParms = MEM_dupallocN(sce_dst->r.avicodecdata->lpParms);
}
-
+
/* make a private copy of the qtcodecdata */
- if (sce->r.qtcodecdata) {
- scen->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata);
- scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms);
+ if (sce_src->r.qtcodecdata) {
+ sce_dst->r.qtcodecdata = MEM_dupallocN(sce_src->r.qtcodecdata);
+ sce_dst->r.qtcodecdata->cdParms = MEM_dupallocN(sce_dst->r.qtcodecdata->cdParms);
}
-
- if (sce->r.ffcodecdata.properties) { /* intentionally check scen not sce. */
- scen->r.ffcodecdata.properties = IDP_CopyProperty(sce->r.ffcodecdata.properties);
+
+ if (sce_src->r.ffcodecdata.properties) { /* intentionally check sce_dst not sce_src. */ /* XXX ??? comment outdated... */
+ sce_dst->r.ffcodecdata.properties = IDP_CopyProperty_ex(sce_src->r.ffcodecdata.properties, flag_subdata);
}
- /* NOTE: part of SCE_COPY_LINK_DATA and SCE_COPY_FULL operations
- * are done outside of blenkernel with ED_objects_single_users! */
+ /* before scene copy */
+ BKE_sound_create_scene(sce_dst);
- /* camera */
- if (type == SCE_COPY_LINK_DATA || type == SCE_COPY_FULL) {
- ID_NEW_REMAP(scen->camera);
+ /* Copy sequencer, this is local data! */
+ if (sce_src->ed) {
+ sce_dst->ed = MEM_callocN(sizeof(*sce_dst->ed), __func__);
+ sce_dst->ed->seqbasep = &sce_dst->ed->seqbase;
+ BKE_sequence_base_dupli_recursive(
+ sce_src, sce_dst, &sce_dst->ed->seqbase, &sce_src->ed->seqbase, SEQ_DUPE_ALL, flag_subdata);
}
-
- /* before scene copy */
- BKE_sound_create_scene(scen);
- /* world */
- if (type == SCE_COPY_FULL) {
- if (scen->world) {
- scen->world = BKE_world_copy(bmain, scen->world);
- BKE_animdata_copy_id_action((ID *)scen->world, false);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&sce_dst->id, &sce_src->id);
+ }
+ else {
+ sce_dst->preview = NULL;
+ }
+}
+
+Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
+{
+ Scene *sce_copy;
+
+ /* TODO this should/could most likely be replaced by call to more generic code at some point...
+ * But for now, let's keep it well isolated here. */
+ if (type == SCE_COPY_EMPTY) {
+ ToolSettings *ts;
+ ListBase rl, rv;
+
+ sce_copy = BKE_scene_add(bmain, sce->id.name + 2);
+
+ rl = sce_copy->r.layers;
+ rv = sce_copy->r.views;
+ curvemapping_free_data(&sce_copy->r.mblur_shutter_curve);
+ sce_copy->r = sce->r;
+ sce_copy->r.layers = rl;
+ sce_copy->r.actlay = 0;
+ sce_copy->r.views = rv;
+ sce_copy->unit = sce->unit;
+ sce_copy->physics_settings = sce->physics_settings;
+ sce_copy->gm = sce->gm;
+ sce_copy->audio = sce->audio;
+
+ if (sce->id.properties)
+ sce_copy->id.properties = IDP_CopyProperty(sce->id.properties);
+
+ MEM_freeN(sce_copy->toolsettings);
+ BKE_sound_destroy_scene(sce_copy);
+
+ /* copy color management settings */
+ BKE_color_managed_display_settings_copy(&sce_copy->display_settings, &sce->display_settings);
+ BKE_color_managed_view_settings_copy(&sce_copy->view_settings, &sce->view_settings);
+ BKE_color_managed_colorspace_settings_copy(&sce_copy->sequencer_colorspace_settings, &sce->sequencer_colorspace_settings);
+
+ BKE_color_managed_display_settings_copy(&sce_copy->r.im_format.display_settings, &sce->r.im_format.display_settings);
+ BKE_color_managed_view_settings_copy(&sce_copy->r.im_format.view_settings, &sce->r.im_format.view_settings);
+
+ BKE_color_managed_display_settings_copy(&sce_copy->r.bake.im_format.display_settings, &sce->r.bake.im_format.display_settings);
+ BKE_color_managed_view_settings_copy(&sce_copy->r.bake.im_format.view_settings, &sce->r.bake.im_format.view_settings);
+
+ curvemapping_copy_data(&sce_copy->r.mblur_shutter_curve, &sce->r.mblur_shutter_curve);
+
+ /* tool settings */
+ sce_copy->toolsettings = MEM_dupallocN(sce->toolsettings);
+
+ ts = sce_copy->toolsettings;
+ if (ts) {
+ if (ts->vpaint) {
+ ts->vpaint = MEM_dupallocN(ts->vpaint);
+ ts->vpaint->paintcursor = NULL;
+ ts->vpaint->vpaint_prev = NULL;
+ ts->vpaint->wpaint_prev = NULL;
+ BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint, 0);
+ }
+ if (ts->wpaint) {
+ ts->wpaint = MEM_dupallocN(ts->wpaint);
+ ts->wpaint->paintcursor = NULL;
+ ts->wpaint->vpaint_prev = NULL;
+ ts->wpaint->wpaint_prev = NULL;
+ BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint, 0);
+ }
+ if (ts->sculpt) {
+ ts->sculpt = MEM_dupallocN(ts->sculpt);
+ BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint, 0);
+ }
+ if (ts->uvsculpt) {
+ ts->uvsculpt = MEM_dupallocN(ts->uvsculpt);
+ BKE_paint_copy(&ts->uvsculpt->paint, &ts->uvsculpt->paint, 0);
+ }
+
+ BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint, 0);
+ ts->imapaint.paintcursor = NULL;
+ id_us_plus((ID *)ts->imapaint.stencil);
+ id_us_plus((ID *)ts->imapaint.clone);
+ id_us_plus((ID *)ts->imapaint.canvas);
+ ts->particle.paintcursor = NULL;
+ ts->particle.scene = NULL;
+ ts->particle.object = NULL;
+
+ /* duplicate Grease Pencil Drawing Brushes */
+ BLI_listbase_clear(&ts->gp_brushes);
+ for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) {
+ bGPDbrush *newbrush = BKE_gpencil_brush_duplicate(brush);
+ BLI_addtail(&ts->gp_brushes, newbrush);
+ }
+
+ /* duplicate Grease Pencil interpolation curve */
+ ts->gp_interpolate.custom_ipo = curvemapping_copy(ts->gp_interpolate.custom_ipo);
+ }
+
+ /* make a private copy of the avicodecdata */
+ if (sce->r.avicodecdata) {
+ sce_copy->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata);
+ sce_copy->r.avicodecdata->lpFormat = MEM_dupallocN(sce_copy->r.avicodecdata->lpFormat);
+ sce_copy->r.avicodecdata->lpParms = MEM_dupallocN(sce_copy->r.avicodecdata->lpParms);
}
- if (sce->ed) {
- scen->ed = MEM_callocN(sizeof(Editing), "addseq");
- scen->ed->seqbasep = &scen->ed->seqbase;
- BKE_sequence_base_dupli_recursive(sce, scen, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL);
+ /* make a private copy of the qtcodecdata */
+ if (sce->r.qtcodecdata) {
+ sce_copy->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata);
+ sce_copy->r.qtcodecdata->cdParms = MEM_dupallocN(sce_copy->r.qtcodecdata->cdParms);
}
+
+ if (sce->r.ffcodecdata.properties) { /* intentionally check scen not sce. */
+ sce_copy->r.ffcodecdata.properties = IDP_CopyProperty(sce->r.ffcodecdata.properties);
+ }
+
+ /* before scene copy */
+ BKE_sound_create_scene(sce_copy);
+
+ /* grease pencil */
+ sce_copy->gpd = NULL;
+
+ sce_copy->preview = NULL;
+
+ return sce_copy;
}
-
- /* grease pencil */
- if (scen->gpd) {
+ else {
+ BKE_id_copy_ex(bmain, (ID *)sce, (ID **)&sce_copy, LIB_ID_COPY_ACTIONS, false);
+
+ /* Extra actions, most notably SCE_FULL_COPY also duplicates several 'children' datablocks... */
+
if (type == SCE_COPY_FULL) {
- scen->gpd = BKE_gpencil_data_duplicate(bmain, scen->gpd, false);
- }
- else if (type == SCE_COPY_EMPTY) {
- scen->gpd = NULL;
+ /* Copy Freestyle LineStyle datablocks. */
+ for (SceneRenderLayer *srl_dst = sce_copy->r.layers.first; srl_dst; srl_dst = srl_dst->next) {
+ for (FreestyleLineSet *lineset = srl_dst->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
+ if (lineset->linestyle) {
+ /* XXX Not copying anim/actions here? */
+ BKE_id_copy_ex(bmain, (ID *)lineset->linestyle, (ID **)&lineset->linestyle, 0, false);
+ }
+ }
+ }
+
+ /* Full copy of world (included animations) */
+ if (sce_copy->world) {
+ BKE_id_copy_ex(bmain, (ID *)sce_copy->world, (ID **)&sce_copy->world, LIB_ID_COPY_ACTIONS, false);
+ }
+
+ /* Full copy of GreasePencil. */
+ /* XXX Not copying anim/actions here? */
+ if (sce_copy->gpd) {
+ BKE_id_copy_ex(bmain, (ID *)sce_copy->gpd, (ID **)&sce_copy->gpd, 0, false);
+ }
}
else {
- id_us_plus((ID *)scen->gpd);
+ /* Remove sequencer if not full copy */
+ /* XXX Why in Hell? :/ */
+ remove_sequencer_fcurves(sce_copy);
+ BKE_sequencer_editing_free(sce_copy);
}
- }
- BKE_previewimg_id_copy(&scen->id, &sce->id);
+ /* NOTE: part of SCE_COPY_LINK_DATA and SCE_COPY_FULL operations
+ * are done outside of blenkernel with ED_objects_single_users! */
- if (type != SCE_COPY_NEW) {
- if (sce->collection_properties) {
- IDP_MergeGroup(scen->collection_properties, sce->collection_properties, true);
- }
- if (sce->layer_properties) {
- IDP_MergeGroup(scen->layer_properties, sce->layer_properties, true);
+ /* camera */
+ if (ELEM(type, SCE_COPY_LINK_DATA, SCE_COPY_FULL)) {
+ ID_NEW_REMAP(sce_copy->camera);
}
- }
- return scen;
+ return sce_copy;
+ }
}
void BKE_scene_groups_relink(Scene *sce)
@@ -549,7 +634,7 @@ void BKE_scene_free_ex(Scene *sce, const bool do_id_user)
BLI_freelistN(&sce->markers);
BLI_freelistN(&sce->r.layers);
BLI_freelistN(&sce->r.views);
-
+
if (sce->toolsettings) {
if (sce->toolsettings->vpaint) {
BKE_paint_free(&sce->toolsettings->vpaint->paint);
@@ -994,7 +1079,7 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
{
Scene *sce;
- sce = BKE_libblock_alloc(bmain, ID_SCE, name);
+ sce = BKE_libblock_alloc(bmain, ID_SCE, name, 0);
id_us_min(&sce->id);
id_us_ensure_real(&sce->id);
@@ -1581,7 +1666,7 @@ void BKE_scene_update_for_newframe(EvaluationContext *eval_ctx, Main *bmain, Sce
BKE_image_update_frame(bmain, sce->r.cfra);
BKE_sound_set_cfra(sce->r.cfra);
-
+
/* clear animation overrides */
/* XXX TODO... */
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 0c384f8b8c8..8a4f09763f5 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -5373,7 +5373,7 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
return seq;
}
-static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dupe_flag)
+static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dupe_flag, const int flag)
{
Scene *sce_audio = scene_to ? scene_to : scene;
Sequence *seqn = MEM_dupallocN(seq);
@@ -5399,7 +5399,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
}
if (seq->prop) {
- seqn->prop = IDP_CopyProperty(seq->prop);
+ seqn->prop = IDP_CopyProperty_ex(seq->prop, flag);
}
if (seqn->modifiers.first) {
@@ -5437,7 +5437,9 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
if (seq->scene_sound)
seqn->scene_sound = BKE_sound_add_scene_sound_defaults(sce_audio, seqn);
- id_us_plus((ID *)seqn->sound);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)seqn->sound);
+ }
}
else if (seq->type == SEQ_TYPE_IMAGE) {
seqn->strip->stripdata =
@@ -5493,7 +5495,7 @@ Sequence *BKE_sequence_dupli_recursive(Scene *scene, Scene *scene_to, Sequence *
Sequence *seqn;
seq->tmp = NULL;
- seqn = seq_dupli(scene, scene_to, seq, dupe_flag);
+ seqn = seq_dupli(scene, scene_to, seq, dupe_flag, 0);
if (seq->type == SEQ_TYPE_META) {
Sequence *s;
for (s = seq->seqbase.first; s; s = s->next) {
@@ -5510,19 +5512,19 @@ Sequence *BKE_sequence_dupli_recursive(Scene *scene, Scene *scene_to, Sequence *
}
void BKE_sequence_base_dupli_recursive(
- Scene *scene, Scene *scene_to, ListBase *nseqbase, ListBase *seqbase,
- int dupe_flag)
+ const Scene *scene, Scene *scene_to, ListBase *nseqbase, const ListBase *seqbase,
+ int dupe_flag, const int flag)
{
Sequence *seq;
Sequence *seqn = NULL;
- Sequence *last_seq = BKE_sequencer_active_get(scene);
+ Sequence *last_seq = BKE_sequencer_active_get((Scene *)scene);
/* always include meta's strips */
int dupe_flag_recursive = dupe_flag | SEQ_DUPE_ALL;
for (seq = seqbase->first; seq; seq = seq->next) {
seq->tmp = NULL;
if ((seq->flag & SELECT) || (dupe_flag & SEQ_DUPE_ALL)) {
- seqn = seq_dupli(scene, scene_to, seq, dupe_flag);
+ seqn = seq_dupli((Scene *)scene, scene_to, seq, dupe_flag, flag);
if (seqn) { /*should never fail */
if (dupe_flag & SEQ_DUPE_CONTEXT) {
seq->flag &= ~SEQ_ALLSEL;
@@ -5533,12 +5535,12 @@ void BKE_sequence_base_dupli_recursive(
if (seq->type == SEQ_TYPE_META) {
BKE_sequence_base_dupli_recursive(
scene, scene_to, &seqn->seqbase, &seq->seqbase,
- dupe_flag_recursive);
+ dupe_flag_recursive, flag);
}
if (dupe_flag & SEQ_DUPE_CONTEXT) {
if (seq == last_seq) {
- BKE_sequencer_active_set(scene, seqn);
+ BKE_sequencer_active_set(scene_to, seqn);
}
}
}
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 8469351c54a..45d1f969d64 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -83,7 +83,7 @@ bSound *BKE_sound_new_file(struct Main *bmain, const char *filepath)
BLI_path_abs(str, path);
- sound = BKE_libblock_alloc(bmain, ID_SO, BLI_path_basename(filepath));
+ sound = BKE_libblock_alloc(bmain, ID_SO, BLI_path_basename(filepath), 0);
BLI_strncpy(sound->name, filepath, FILE_MAX);
/* sound->type = SOUND_TYPE_FILE; */ /* XXX unused currently */
@@ -155,6 +155,34 @@ void BKE_sound_free(bSound *sound)
}
}
+/**
+ * Only copy internal data of Sound ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_sound_copy_data(Main *bmain, bSound *sound_dst, const bSound *UNUSED(sound_src), const int UNUSED(flag))
+{
+ sound_dst->handle = NULL;
+ sound_dst->cache = NULL;
+ sound_dst->waveform = NULL;
+ sound_dst->playback_handle = NULL;
+ sound_dst->spinlock = NULL; /* Think this is OK? Otherwise, easy to create new spinlock here... */
+
+ /* Just to be sure, should not have any value actually after reading time. */
+ sound_dst->ipo = NULL;
+ sound_dst->newpackedfile = NULL;
+
+ if (sound_dst->packedfile) {
+ sound_dst->packedfile = dupPackedFile(sound_dst->packedfile);
+ }
+
+ /* Initialize whole runtime (audaspace) stuff. */
+ BKE_sound_load(bmain, sound_dst);
+}
+
void BKE_sound_make_local(Main *bmain, bSound *sound, const bool lib_local)
{
BKE_id_make_local_generic(bmain, &sound->id, true, lib_local);
diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c
index d00e4b1a0d2..9d604a9382a 100644
--- a/source/blender/blenkernel/intern/speaker.c
+++ b/source/blender/blenkernel/intern/speaker.c
@@ -61,25 +61,31 @@ void *BKE_speaker_add(Main *bmain, const char *name)
{
Speaker *spk;
- spk = BKE_libblock_alloc(bmain, ID_SPK, name);
+ spk = BKE_libblock_alloc(bmain, ID_SPK, name, 0);
BKE_speaker_init(spk);
return spk;
}
-Speaker *BKE_speaker_copy(Main *bmain, const Speaker *spk)
+/**
+ * Only copy internal data of Speaker ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_speaker_copy_data(Main *UNUSED(bmain), Speaker *UNUSED(spk_dst), const Speaker *UNUSED(spk_src), const int UNUSED(flag))
{
- Speaker *spkn;
-
- spkn = BKE_libblock_copy(bmain, &spk->id);
-
- if (spkn->sound)
- id_us_plus(&spkn->sound->id);
-
- BKE_id_copy_ensure_local(bmain, &spk->id, &spkn->id);
+ /* Nothing to do! */
+}
- return spkn;
+Speaker *BKE_speaker_copy(Main *bmain, const Speaker *spk)
+{
+ Speaker *spk_copy;
+ BKE_id_copy_ex(bmain, &spk->id, (ID **)&spk_copy, 0, false);
+ return spk_copy;
}
void BKE_speaker_make_local(Main *bmain, Speaker *spk, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 9444e605e6d..4ae9818f891 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -223,7 +223,7 @@ Text *BKE_text_add(Main *bmain, const char *name)
{
Text *ta;
- ta = BKE_libblock_alloc(bmain, ID_TXT, name);
+ ta = BKE_libblock_alloc(bmain, ID_TXT, name, 0);
BKE_text_init(ta);
@@ -409,7 +409,7 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const
return false;
}
- ta = BKE_libblock_alloc(bmain, ID_TXT, BLI_path_basename(filepath_abs));
+ ta = BKE_libblock_alloc(bmain, ID_TXT, BLI_path_basename(filepath_abs), 0);
ta->id.us = 0;
BLI_listbase_clear(&ta->lines);
@@ -448,53 +448,49 @@ Text *BKE_text_load(Main *bmain, const char *file, const char *relpath)
return BKE_text_load_ex(bmain, file, relpath, false);
}
-Text *BKE_text_copy(Main *bmain, const Text *ta)
+/**
+ * Only copy internal data of Text ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_text_copy_data(Main *UNUSED(bmain), Text *ta_dst, const Text *ta_src, const int UNUSED(flag))
{
- Text *tan;
- TextLine *line, *tmp;
-
- tan = BKE_libblock_copy(bmain, &ta->id);
-
/* file name can be NULL */
- if (ta->name) {
- tan->name = BLI_strdup(ta->name);
- }
- else {
- tan->name = NULL;
+ if (ta_src->name) {
+ ta_dst->name = BLI_strdup(ta_src->name);
}
- tan->flags = ta->flags | TXT_ISDIRTY;
-
- BLI_listbase_clear(&tan->lines);
- tan->curl = tan->sell = NULL;
- tan->compiled = NULL;
-
- tan->nlines = ta->nlines;
+ ta_dst->flags |= TXT_ISDIRTY;
+
+ BLI_listbase_clear(&ta_dst->lines);
+ ta_dst->curl = ta_dst->sell = NULL;
+ ta_dst->compiled = NULL;
- line = ta->lines.first;
/* Walk down, reconstructing */
- while (line) {
- tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline");
- tmp->line = MEM_mallocN(line->len + 1, "textline_string");
- tmp->format = NULL;
-
- strcpy(tmp->line, line->line);
+ for (TextLine *line_src = ta_src->lines.first; line_src; line_src = line_src->next) {
+ TextLine *line_dst = MEM_mallocN(sizeof(*line_dst), __func__);
- tmp->len = line->len;
-
- BLI_addtail(&tan->lines, tmp);
-
- line = line->next;
- }
+ line_dst->line = BLI_strdup(line_src->line);
+ line_dst->format = NULL;
+ line_dst->len = line_src->len;
- tan->curl = tan->sell = tan->lines.first;
- tan->curc = tan->selc = 0;
+ BLI_addtail(&ta_dst->lines, line_dst);
+ }
- init_undo_text(tan);
+ ta_dst->curl = ta_dst->sell = ta_dst->lines.first;
+ ta_dst->curc = ta_dst->selc = 0;
- BKE_id_copy_ensure_local(bmain, &ta->id, &tan->id);
+ init_undo_text(ta_dst);
+}
- return tan;
+Text *BKE_text_copy(Main *bmain, const Text *ta)
+{
+ Text *ta_copy;
+ BKE_id_copy_ex(bmain, &ta->id, (ID **)&ta_copy, 0, false);
+ return ta_copy;
}
void BKE_text_make_local(Main *bmain, Text *text, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 1e0659d3d67..89a3842a230 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -707,7 +707,7 @@ Tex *BKE_texture_add(Main *bmain, const char *name)
{
Tex *tex;
- tex = BKE_libblock_alloc(bmain, ID_TE, name);
+ tex = BKE_libblock_alloc(bmain, ID_TE, name, 0);
BKE_texture_default(tex);
@@ -846,41 +846,71 @@ MTex *BKE_texture_mtex_add_id(ID *id, int slot)
/* ------------------------------------------------------------------------- */
-Tex *BKE_texture_copy(Main *bmain, const Tex *tex)
+/**
+ * Only copy internal data of Texture ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_texture_copy_data(Main *bmain, Tex *tex_dst, const Tex *tex_src, const int flag)
{
- Tex *texn;
-
- texn = BKE_libblock_copy(bmain, &tex->id);
- if (BKE_texture_is_image_user(tex)) {
- id_us_plus((ID *)texn->ima);
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
+
+ if (!BKE_texture_is_image_user(tex_src)) {
+ tex_dst->ima = NULL;
}
- else {
- texn->ima = NULL;
+
+ if (tex_dst->coba) {
+ tex_dst->coba = MEM_dupallocN(tex_dst->coba);
+ }
+ if (tex_dst->env) {
+ tex_dst->env = BKE_texture_envmap_copy(tex_dst->env, flag_subdata);
+ }
+ if (tex_dst->pd) {
+ tex_dst->pd = BKE_texture_pointdensity_copy(tex_dst->pd, flag_subdata);
+ }
+ if (tex_dst->vd) {
+ tex_dst->vd = MEM_dupallocN(tex_dst->vd);
+ }
+ if (tex_dst->ot) {
+ tex_dst->ot = BKE_texture_ocean_copy(tex_dst->ot, flag_subdata);
}
-
- if (texn->coba) texn->coba = MEM_dupallocN(texn->coba);
- if (texn->env) texn->env = BKE_texture_envmap_copy(texn->env);
- if (texn->pd) texn->pd = BKE_texture_pointdensity_copy(texn->pd);
- if (texn->vd) texn->vd = MEM_dupallocN(texn->vd);
- if (texn->ot) texn->ot = BKE_texture_ocean_copy(texn->ot);
- if (tex->nodetree) {
- if (tex->nodetree->execdata) {
- ntreeTexEndExecTree(tex->nodetree->execdata);
+ if (tex_src->nodetree) {
+ if (tex_src->nodetree->execdata) {
+ ntreeTexEndExecTree(tex_src->nodetree->execdata);
}
- texn->nodetree = ntreeCopyTree(bmain, tex->nodetree);
+ BKE_id_copy_ex(bmain, (ID *)tex_src->nodetree, (ID **)&tex_dst->nodetree, flag, false);
}
- BKE_previewimg_id_copy(&texn->id, &tex->id);
-
- BKE_id_copy_ensure_local(bmain, &tex->id, &texn->id);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&tex_dst->id, &tex_src->id);
+ }
+ else {
+ tex_dst->preview = NULL;
+ }
+}
- return texn;
+Tex *BKE_texture_copy(Main *bmain, const Tex *tex)
+{
+ Tex *tex_copy;
+ BKE_id_copy_ex(bmain, &tex->id, (ID **)&tex_copy, 0, false);
+ return tex_copy;
}
/* texture copy without adding to main dbase */
Tex *BKE_texture_localize(Tex *tex)
{
+ /* TODO replace with something like
+ * Tex *tex_copy;
+ * BKE_id_copy_ex(bmain, &tex->id, (ID **)&tex_copy, LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT, false);
+ * return tex_copy;
+ *
+ * ... Once f*** nodes are fully converted to that too :( */
+
Tex *texn;
texn = BKE_libblock_copy_nolib(&tex->id, false);
@@ -889,17 +919,17 @@ Tex *BKE_texture_localize(Tex *tex)
if (texn->coba) texn->coba = MEM_dupallocN(texn->coba);
if (texn->env) {
- texn->env = BKE_texture_envmap_copy(texn->env);
+ texn->env = BKE_texture_envmap_copy(texn->env, LIB_ID_CREATE_NO_USER_REFCOUNT);
id_us_min(&texn->env->ima->id);
}
- if (texn->pd) texn->pd = BKE_texture_pointdensity_copy(texn->pd);
+ if (texn->pd) texn->pd = BKE_texture_pointdensity_copy(texn->pd, LIB_ID_CREATE_NO_USER_REFCOUNT);
if (texn->vd) {
texn->vd = MEM_dupallocN(texn->vd);
if (texn->vd->dataset)
texn->vd->dataset = MEM_dupallocN(texn->vd->dataset);
}
if (texn->ot) {
- texn->ot = BKE_texture_ocean_copy(tex->ot);
+ texn->ot = BKE_texture_ocean_copy(tex->ot, LIB_ID_CREATE_NO_USER_REFCOUNT);
}
texn->preview = NULL;
@@ -1263,16 +1293,20 @@ EnvMap *BKE_texture_envmap_add(void)
/* ------------------------------------------------------------------------- */
-EnvMap *BKE_texture_envmap_copy(const EnvMap *env)
+EnvMap *BKE_texture_envmap_copy(const EnvMap *env, const int flag)
{
EnvMap *envn;
int a;
envn = MEM_dupallocN(env);
envn->ok = 0;
- for (a = 0; a < 6; a++) envn->cube[a] = NULL;
- if (envn->ima) id_us_plus((ID *)envn->ima);
-
+ for (a = 0; a < 6; a++) {
+ envn->cube[a] = NULL;
+ }
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)envn->ima);
+ }
+
return envn;
}
@@ -1336,14 +1370,16 @@ PointDensity *BKE_texture_pointdensity_add(void)
return pd;
}
-PointDensity *BKE_texture_pointdensity_copy(const PointDensity *pd)
+PointDensity *BKE_texture_pointdensity_copy(const PointDensity *pd, const int UNUSED(flag))
{
PointDensity *pdn;
pdn = MEM_dupallocN(pd);
pdn->point_tree = NULL;
pdn->point_data = NULL;
- if (pdn->coba) pdn->coba = MEM_dupallocN(pdn->coba);
+ if (pdn->coba) {
+ pdn->coba = MEM_dupallocN(pdn->coba);
+ }
pdn->falloff_curve = curvemapping_copy(pdn->falloff_curve); /* can be NULL */
return pdn;
}
@@ -1430,7 +1466,7 @@ OceanTex *BKE_texture_ocean_add(void)
return ot;
}
-OceanTex *BKE_texture_ocean_copy(const OceanTex *ot)
+OceanTex *BKE_texture_ocean_copy(const OceanTex *ot, const int UNUSED(flag))
{
OceanTex *otn = MEM_dupallocN(ot);
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 9120d384a16..b4ef381534f 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -190,7 +190,7 @@ void BKE_tracking_free(MovieTracking *tracking)
}
/* Copy the whole list of tracks. */
-static void tracking_tracks_copy(ListBase *tracks_dst, const ListBase *tracks_src, GHash *tracks_mapping)
+static void tracking_tracks_copy(ListBase *tracks_dst, const ListBase *tracks_src, GHash *tracks_mapping, const int flag)
{
MovieTrackingTrack *track_dst, *track_src;
@@ -202,7 +202,9 @@ static void tracking_tracks_copy(ListBase *tracks_dst, const ListBase *tracks_sr
if (track_src->markers) {
track_dst->markers = MEM_dupallocN(track_src->markers);
}
- id_us_plus(&track_dst->gpd->id);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus(&track_dst->gpd->id);
+ }
BLI_addtail(tracks_dst, track_dst);
BLI_ghash_insert(tracks_mapping, track_src, track_dst);
}
@@ -210,7 +212,8 @@ static void tracking_tracks_copy(ListBase *tracks_dst, const ListBase *tracks_sr
/* copy the whole list of plane tracks (need whole MovieTracking structures due to embedded pointers to tracks).
* WARNING: implies tracking_[dst/src] and their tracks have already been copied. */
-static void tracking_plane_tracks_copy(ListBase *plane_tracks_dst, const ListBase *plane_tracks_src, GHash *tracks_mapping)
+static void tracking_plane_tracks_copy(
+ ListBase *plane_tracks_dst, const ListBase *plane_tracks_src, GHash *tracks_mapping, const int flag)
{
MovieTrackingPlaneTrack *plane_track_dst, *plane_track_src;
@@ -225,14 +228,17 @@ static void tracking_plane_tracks_copy(ListBase *plane_tracks_dst, const ListBas
for (int i = 0; i < plane_track_dst->point_tracksnr; i++) {
plane_track_dst->point_tracks[i] = BLI_ghash_lookup(tracks_mapping, plane_track_src->point_tracks[i]);
}
- id_us_plus(&plane_track_dst->image->id);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus(&plane_track_dst->image->id);
+ }
BLI_addtail(plane_tracks_dst, plane_track_dst);
}
}
/* Copy reconstruction structure. */
static void tracking_reconstruction_copy(
- MovieTrackingReconstruction *reconstruction_dst, const MovieTrackingReconstruction *reconstruction_src)
+ MovieTrackingReconstruction *reconstruction_dst, const MovieTrackingReconstruction *reconstruction_src,
+ const int UNUSED(flag))
{
*reconstruction_dst = *reconstruction_src;
if (reconstruction_src->cameras) {
@@ -242,23 +248,25 @@ static void tracking_reconstruction_copy(
/* Copy stabilization structure. */
static void tracking_stabilization_copy(
- MovieTrackingStabilization *stabilization_dst, const MovieTrackingStabilization *stabilization_src)
+ MovieTrackingStabilization *stabilization_dst, const MovieTrackingStabilization *stabilization_src,
+ const int UNUSED(flag))
{
*stabilization_dst = *stabilization_src;
}
/* Copy tracking object. */
static void tracking_object_copy(
- MovieTrackingObject *object_dst, const MovieTrackingObject *object_src, GHash *tracks_mapping)
+ MovieTrackingObject *object_dst, const MovieTrackingObject *object_src, GHash *tracks_mapping, const int flag)
{
*object_dst = *object_src;
- tracking_tracks_copy(&object_dst->tracks, &object_src->tracks, tracks_mapping);
- tracking_plane_tracks_copy(&object_dst->plane_tracks, &object_src->plane_tracks, tracks_mapping);
- tracking_reconstruction_copy(&object_dst->reconstruction, &object_src->reconstruction);
+ tracking_tracks_copy(&object_dst->tracks, &object_src->tracks, tracks_mapping, flag);
+ tracking_plane_tracks_copy(&object_dst->plane_tracks, &object_src->plane_tracks, tracks_mapping, flag);
+ tracking_reconstruction_copy(&object_dst->reconstruction, &object_src->reconstruction, flag);
}
/* Copy list of tracking objects. */
-static void tracking_objects_copy(ListBase *objects_dst, const ListBase *objects_src, GHash *tracks_mapping)
+static void tracking_objects_copy(
+ ListBase *objects_dst, const ListBase *objects_src, GHash *tracks_mapping, const int flag)
{
MovieTrackingObject *object_dst, *object_src;
@@ -266,22 +274,22 @@ static void tracking_objects_copy(ListBase *objects_dst, const ListBase *objects
for (object_src = objects_src->first; object_src != NULL; object_src = object_src->next) {
object_dst = MEM_mallocN(sizeof(*object_dst), __func__);
- tracking_object_copy(object_dst, object_src, tracks_mapping);
+ tracking_object_copy(object_dst, object_src, tracks_mapping, flag);
BLI_addtail(objects_dst, object_dst);
}
}
/* Copy tracking structure content. */
-void BKE_tracking_copy(MovieTracking *tracking_dst, const MovieTracking *tracking_src)
+void BKE_tracking_copy(MovieTracking *tracking_dst, const MovieTracking *tracking_src, const int flag)
{
GHash *tracks_mapping = BLI_ghash_ptr_new(__func__);
*tracking_dst = *tracking_src;
- tracking_tracks_copy(&tracking_dst->tracks, &tracking_src->tracks, tracks_mapping);
- tracking_plane_tracks_copy(&tracking_dst->plane_tracks, &tracking_src->plane_tracks, tracks_mapping);
- tracking_reconstruction_copy(&tracking_dst->reconstruction, &tracking_src->reconstruction);
- tracking_stabilization_copy(&tracking_dst->stabilization, &tracking_src->stabilization);
+ tracking_tracks_copy(&tracking_dst->tracks, &tracking_src->tracks, tracks_mapping, flag);
+ tracking_plane_tracks_copy(&tracking_dst->plane_tracks, &tracking_src->plane_tracks, tracks_mapping, flag);
+ tracking_reconstruction_copy(&tracking_dst->reconstruction, &tracking_src->reconstruction, flag);
+ tracking_stabilization_copy(&tracking_dst->stabilization, &tracking_src->stabilization, flag);
if (tracking_src->act_track) {
tracking_dst->act_track = BLI_ghash_lookup(tracks_mapping, tracking_src->act_track);
}
@@ -299,7 +307,7 @@ void BKE_tracking_copy(MovieTracking *tracking_dst, const MovieTracking *trackin
}
/* Warning! Will override tracks_mapping. */
- tracking_objects_copy(&tracking_dst->objects, &tracking_src->objects, tracks_mapping);
+ tracking_objects_copy(&tracking_dst->objects, &tracking_src->objects, tracks_mapping, flag);
/* Those remaining are runtime data, they will be reconstructed as needed, do not bother copying them. */
tracking_dst->dopesheet.ok = false;
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 2adbdc83a36..d20dac5a4ae 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -112,43 +112,59 @@ World *add_world(Main *bmain, const char *name)
{
World *wrld;
- wrld = BKE_libblock_alloc(bmain, ID_WO, name);
+ wrld = BKE_libblock_alloc(bmain, ID_WO, name, 0);
BKE_world_init(wrld);
return wrld;
}
-World *BKE_world_copy(Main *bmain, const World *wrld)
+/**
+ * Only copy internal data of World ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_world_copy_data(Main *bmain, World *wrld_dst, const World *wrld_src, const int flag)
{
- World *wrldn;
- int a;
-
- wrldn = BKE_libblock_copy(bmain, &wrld->id);
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (wrld->mtex[a]) {
- wrldn->mtex[a] = MEM_mallocN(sizeof(MTex), "BKE_world_copy");
- memcpy(wrldn->mtex[a], wrld->mtex[a], sizeof(MTex));
- id_us_plus((ID *)wrldn->mtex[a]->tex);
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (wrld_src->mtex[a]) {
+ wrld_dst->mtex[a] = MEM_dupallocN(wrld_src->mtex[a]);
}
}
- if (wrld->nodetree) {
- wrldn->nodetree = ntreeCopyTree(bmain, wrld->nodetree);
+ if (wrld_src->nodetree) {
+ BKE_id_copy_ex(bmain, (ID *)wrld_src->nodetree, (ID **)&wrld_dst->nodetree, flag, false);
}
-
- BKE_previewimg_id_copy(&wrldn->id, &wrld->id);
- BLI_listbase_clear(&wrldn->gpumaterial);
+ BLI_listbase_clear(&wrld_dst->gpumaterial);
- BKE_id_copy_ensure_local(bmain, &wrld->id, &wrldn->id);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&wrld_dst->id, &wrld_src->id);
+ }
+ else {
+ wrld_dst->preview = NULL;
+ }
+}
- return wrldn;
+World *BKE_world_copy(Main *bmain, const World *wrld)
+{
+ World *wrld_copy;
+ BKE_id_copy_ex(bmain, &wrld->id, (ID **)&wrld_copy, 0, false);
+ return wrld_copy;
}
World *localize_world(World *wrld)
{
+ /* TODO replace with something like
+ * World *wrld_copy;
+ * BKE_id_copy_ex(bmain, &wrld->id, (ID **)&wrld_copy, LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT, false);
+ * return wrld_copy;
+ *
+ * ... Once f*** nodes are fully converted to that too :( */
+
World *wrldn;
int a;
diff --git a/source/blender/blenlib/BLI_vfontdata.h b/source/blender/blenlib/BLI_vfontdata.h
index 8a7079b6c5f..0cd50319a33 100644
--- a/source/blender/blenlib/BLI_vfontdata.h
+++ b/source/blender/blenlib/BLI_vfontdata.h
@@ -52,8 +52,10 @@ typedef struct VChar {
} VChar;
VFontData *BLI_vfontdata_from_freetypefont(struct PackedFile *pf);
+VFontData *BLI_vfontdata_copy(const VFontData *vfont_src, const int flag);
VChar *BLI_vfontchar_from_freetypefont(struct VFont *vfont, unsigned long character);
+VChar *BLI_vfontchar_copy(const VChar *vchar_src, const int flag);
#endif
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index 8719c92a2a6..b97e41402d7 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -481,6 +481,21 @@ VFontData *BLI_vfontdata_from_freetypefont(PackedFile *pf)
return vfd;
}
+static void *vfontdata_copy_characters_value_cb(const void *src) {
+ return BLI_vfontchar_copy(src, 0);
+}
+
+VFontData *BLI_vfontdata_copy(const VFontData *vfont_src, const int UNUSED(flag))
+{
+ VFontData *vfont_dst = MEM_dupallocN(vfont_src);
+
+ if (vfont_src->characters != NULL) {
+ vfont_dst->characters = BLI_ghash_copy(vfont_src->characters, NULL, vfontdata_copy_characters_value_cb);
+ }
+
+ return vfont_dst;
+}
+
VChar *BLI_vfontchar_from_freetypefont(VFont *vfont, unsigned long character)
{
VChar *che = NULL;
@@ -503,6 +518,20 @@ VChar *BLI_vfontchar_from_freetypefont(VFont *vfont, unsigned long character)
return che;
}
+/* Yeah, this is very bad... But why is this in BLI in the first place, since it uses Nurb data?
+ * Anyway, do not feel like duplicating whole Nurb copy code here, so unless someone has a better idea... */
+#include "../../blenkernel/BKE_curve.h"
+
+VChar *BLI_vfontchar_copy(const VChar *vchar_src, const int UNUSED(flag))
+{
+ VChar *vchar_dst = MEM_dupallocN(vchar_src);
+
+ BLI_listbase_clear(&vchar_dst->nurbsbase);
+ BKE_nurbList_duplicate(&vchar_dst->nurbsbase, &vchar_src->nurbsbase);
+
+ return vchar_dst;
+}
+
#if 0
/* Freetype2 Outline struct */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 6349269440e..573ecce3224 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -649,7 +649,7 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab
/* Add library datablock itself to 'main' Main, since libraries are **never** linked data.
* Fixes bug where you could end with all ID_LI datablocks having the same name... */
- lib = BKE_libblock_alloc(mainlist->first, ID_LI, "Lib");
+ lib = BKE_libblock_alloc(mainlist->first, ID_LI, "Lib", 0);
lib->id.us = ID_FAKE_USERS(lib); /* Important, consistency with main ID reading code from read_libblock(). */
BLI_strncpy(lib->name, filepath, sizeof(lib->name));
BLI_strncpy(lib->filepath, name1, sizeof(lib->filepath));
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 9acd868daba..b4f5df8891e 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -3946,6 +3946,9 @@ static bool write_file_handle(
}
for (; id; id = id->next) {
+ /* We should never attempt to write non-regular IDs (i.e. all kind of temp/runtime ones). */
+ BLI_assert((id->tag & (LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT | LIB_TAG_NOT_ALLOCATED)) == 0);
+
switch ((ID_Type)GS(id->name)) {
case ID_WM:
write_windowmanager(wd, (wmWindowManager *)id);
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index a6f63548c96..99907e9e6ae 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -383,7 +383,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
if (base->object->adt) {
if (ob->adt == NULL) {
/* no animdata, so just use a copy of the whole thing */
- ob->adt = BKE_animdata_copy(base->object->adt, false);
+ ob->adt = BKE_animdata_copy(bmain, base->object->adt, false);
}
else {
/* merge in data - we'll fix the drivers manually */
@@ -394,7 +394,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
if (curarm->adt) {
if (arm->adt == NULL) {
/* no animdata, so just use a copy of the whole thing */
- arm->adt = BKE_animdata_copy(curarm->adt, false);
+ arm->adt = BKE_animdata_copy(bmain, curarm->adt, false);
}
else {
/* merge in data - we'll fix the drivers manually */
diff --git a/source/blender/editors/io/io_cache.c b/source/blender/editors/io/io_cache.c
index a5e90ebbe7a..975bbddd893 100644
--- a/source/blender/editors/io/io_cache.c
+++ b/source/blender/editors/io/io_cache.c
@@ -93,7 +93,7 @@ static int cachefile_open_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
- CacheFile *cache_file = BKE_libblock_alloc(bmain, ID_CF, BLI_path_basename(filename));
+ CacheFile *cache_file = BKE_libblock_alloc(bmain, ID_CF, BLI_path_basename(filename), 0);
BLI_strncpy(cache_file->filepath, filename, FILE_MAX);
BKE_cachefile_reload(bmain, cache_file);
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 478d6eb1235..13f9f950236 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -591,9 +591,9 @@ static void copymenu_logicbricks(SceneLayer *sl, Object *ob)
/* now copy it, this also works without logicbricks! */
clear_sca_new_poins_ob(ob);
- copy_sensors(&base->object->sensors, &ob->sensors);
- copy_controllers(&base->object->controllers, &ob->controllers);
- copy_actuators(&base->object->actuators, &ob->actuators);
+ copy_sensors(&base->object->sensors, &ob->sensors, 0);
+ copy_controllers(&base->object->controllers, &ob->controllers, 0);
+ copy_actuators(&base->object->actuators, &ob->actuators, 0);
set_sca_new_poins_ob(base->object);
/* some menu settings */
@@ -752,7 +752,7 @@ static void copy_attr(Main *bmain, Scene *scene, SceneLayer *sl, short event)
base->object->collision_boundtype = ob->collision_boundtype;
}
base->object->margin = ob->margin;
- base->object->bsoft = copy_bulletsoftbody(ob->bsoft);
+ base->object->bsoft = copy_bulletsoftbody(ob->bsoft, 0);
}
else if (event == 17) { /* tex space */
@@ -860,7 +860,7 @@ static void copy_attr(Main *bmain, Scene *scene, SceneLayer *sl, short event)
base->object->softflag = ob->softflag;
if (base->object->soft) sbFree(base->object->soft);
- base->object->soft = copy_softbody(ob->soft, false);
+ base->object->soft = copy_softbody(ob->soft, 0);
if (!modifiers_findByType(base->object, eModifierType_Softbody)) {
BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody));
@@ -1942,9 +1942,9 @@ static int logicbricks_copy_exec(bContext *C, wmOperator *UNUSED(op))
/* now copy it, this also works without logicbricks! */
clear_sca_new_poins_ob(ob);
- copy_sensors(&ob_iter->sensors, &ob->sensors);
- copy_controllers(&ob_iter->controllers, &ob->controllers);
- copy_actuators(&ob_iter->actuators, &ob->actuators);
+ copy_sensors(&ob_iter->sensors, &ob->sensors, 0);
+ copy_controllers(&ob_iter->controllers, &ob->controllers, 0);
+ copy_actuators(&ob_iter->actuators, &ob->actuators, 0);
set_sca_new_poins_ob(ob_iter);
/* some menu settings */
@@ -2005,7 +2005,7 @@ static int game_physics_copy_exec(bContext *C, wmOperator *UNUSED(op))
copy_v3_v3(ob_iter->anisotropicFriction, ob->anisotropicFriction);
ob_iter->collision_boundtype = ob->collision_boundtype;
ob_iter->margin = ob->margin;
- ob_iter->bsoft = copy_bulletsoftbody(ob->bsoft);
+ ob_iter->bsoft = copy_bulletsoftbody(ob->bsoft, 0);
if (ob->restrictflag & OB_RESTRICT_RENDER)
ob_iter->restrictflag |= OB_RESTRICT_RENDER;
else
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 8b4eb794820..e7c3ed38296 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1470,13 +1470,13 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
break;
case MAKE_LINKS_ANIMDATA:
- BKE_animdata_copy_id((ID *)ob_dst, (ID *)ob_src, false);
+ BKE_animdata_copy_id(bmain, (ID *)ob_dst, (ID *)ob_src, false);
if (ob_dst->data && ob_src->data) {
if (ID_IS_LINKED_DATABLOCK(obdata_id)) {
is_lib = true;
break;
}
- BKE_animdata_copy_id((ID *)ob_dst->data, (ID *)ob_src->data, false);
+ BKE_animdata_copy_id(bmain, (ID *)ob_dst->data, (ID *)ob_src->data, false);
}
DEG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
break;
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 8a08be75421..2a526e28c44 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -1045,7 +1045,7 @@ static bool copy_particle_systems_to_object(const bContext *C,
psys_from;
psys_from = PSYS_FROM_NEXT(psys_from), ++i) {
- psys = BKE_object_copy_particlesystem(psys_from);
+ psys = BKE_object_copy_particlesystem(psys_from, 0);
tmp_psys[i] = psys;
if (psys_start == NULL)
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 5071c5db4ea..016013ab492 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -1302,16 +1302,16 @@ static int freestyle_modifier_copy_exec(bContext *C, wmOperator *op)
switch (freestyle_get_modifier_type(&ptr)) {
case LS_MODIFIER_TYPE_COLOR:
- BKE_linestyle_color_modifier_copy(lineset->linestyle, modifier);
+ BKE_linestyle_color_modifier_copy(lineset->linestyle, modifier, 0);
break;
case LS_MODIFIER_TYPE_ALPHA:
- BKE_linestyle_alpha_modifier_copy(lineset->linestyle, modifier);
+ BKE_linestyle_alpha_modifier_copy(lineset->linestyle, modifier, 0);
break;
case LS_MODIFIER_TYPE_THICKNESS:
- BKE_linestyle_thickness_modifier_copy(lineset->linestyle, modifier);
+ BKE_linestyle_thickness_modifier_copy(lineset->linestyle, modifier, 0);
break;
case LS_MODIFIER_TYPE_GEOMETRY:
- BKE_linestyle_geometry_modifier_copy(lineset->linestyle, modifier);
+ BKE_linestyle_geometry_modifier_copy(lineset->linestyle, modifier, 0);
break;
default:
BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index d762419b550..56fe11a5006 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -463,8 +463,8 @@ bScreen *screen_add(const char *name, const int winsize_x, const int winsize_y)
{
bScreen *sc;
ScrVert *sv1, *sv2, *sv3, *sv4;
-
- sc = BKE_libblock_alloc(G.main, ID_SCR, name);
+
+ sc = BKE_libblock_alloc(G.main, ID_SCR, name, 0);
sc->do_refresh = true;
sc->redraws_flag = TIME_ALL_3D_WIN | TIME_ALL_ANIM_WIN;
@@ -472,15 +472,15 @@ bScreen *screen_add(const char *name, const int winsize_x, const int winsize_y)
sv2 = screen_addvert(sc, 0, winsize_y - 1);
sv3 = screen_addvert(sc, winsize_x - 1, winsize_y - 1);
sv4 = screen_addvert(sc, winsize_x - 1, 0);
-
+
screen_addedge(sc, sv1, sv2);
screen_addedge(sc, sv2, sv3);
screen_addedge(sc, sv3, sv4);
screen_addedge(sc, sv4, sv1);
-
+
/* dummy type, no spacedata */
screen_addarea(sc, sv1, sv2, sv3, sv4, HEADERDOWN, SPACE_EMPTY);
-
+
return sc;
}
@@ -992,7 +992,7 @@ void ED_region_exit(bContext *C, ARegion *ar)
wm_subwindow_close(win, ar->swinid);
ar->swinid = 0;
}
-
+
if (ar->headerstr) {
MEM_freeN(ar->headerstr);
ar->headerstr = NULL;
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 650687429b4..631c31251ec 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -2139,7 +2139,7 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
if (ed == NULL)
return OPERATOR_CANCELLED;
- BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT);
+ BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT, 0);
if (nseqbase.first) {
Sequence *seq = nseqbase.first;
@@ -3177,7 +3177,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, ed->seqbasep, SEQ_DUPE_UNIQUE_NAME);
+ BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, ed->seqbasep, SEQ_DUPE_UNIQUE_NAME, 0);
/* To make sure the copied strips have unique names between each other add
* them temporarily to the end of the original seqbase. (bug 25932)
@@ -3244,7 +3244,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
ED_sequencer_deselect_all(scene);
ofs = scene->r.cfra - seqbase_clipboard_frame;
- BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, &seqbase_clipboard, SEQ_DUPE_UNIQUE_NAME);
+ BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, &seqbase_clipboard, SEQ_DUPE_UNIQUE_NAME, 0);
/* transform pasted strips before adding */
if (ofs) {
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index d457401bb33..63752142b84 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -138,8 +138,7 @@ typedef struct ID {
/**
* LIB_TAG_... tags (runtime only, cleared at read time).
*/
- short tag;
- short pad_s1;
+ int tag;
int us;
int icon_id;
IDProperty *properties;
@@ -367,6 +366,13 @@ enum {
/* The datablock is a copy-on-write version. */
LIB_TAG_COPY_ON_WRITE = (1 << 15),
+
+ /* RESET_NEVER tag datablock for freeing etc. behavior (usually set when copying real one into temp/runtime one). */
+ LIB_TAG_NO_MAIN = 1 << 16, /* Datablock is not listed in Main database. */
+ LIB_TAG_NO_USER_REFCOUNT = 1 << 17, /* Datablock does not refcount usages of other IDs. */
+ /* Datablock was not allocated by standard system (BKE_libblock_alloc), do not free its memory
+ * (usual type-specific freeing is called though). */
+ LIB_TAG_NOT_ALLOCATED = 1 << 18,
};
/* To filter ID types (filter_id) */
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c
index 7530cc4427b..47fb01cd281 100644
--- a/source/blender/modifiers/intern/MOD_armature.c
+++ b/source/blender/modifiers/intern/MOD_armature.c
@@ -62,13 +62,13 @@ static void initData(ModifierData *md)
static void copyData(ModifierData *md, ModifierData *target)
{
+#if 0
ArmatureModifierData *amd = (ArmatureModifierData *) md;
+#endif
ArmatureModifierData *tamd = (ArmatureModifierData *) target;
- tamd->object = amd->object;
- tamd->deformflag = amd->deformflag;
- tamd->multi = amd->multi;
- BLI_strncpy(tamd->defgrp_name, amd->defgrp_name, sizeof(tamd->defgrp_name));
+ modifier_copyData_generic(md, target);
+ tamd->prevCos = NULL;
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md))
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index b0433cac569..42f451b74ac 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -65,19 +65,11 @@ static void initData(ModifierData *md)
static void copyData(ModifierData *md, ModifierData *target)
{
+#if 0
BevelModifierData *bmd = (BevelModifierData *) md;
BevelModifierData *tbmd = (BevelModifierData *) target;
-
- tbmd->value = bmd->value;
- tbmd->res = bmd->res;
- tbmd->flags = bmd->flags;
- tbmd->val_flags = bmd->val_flags;
- tbmd->lim_flags = bmd->lim_flags;
- tbmd->e_flags = bmd->e_flags;
- tbmd->mat = bmd->mat;
- tbmd->profile = bmd->profile;
- tbmd->bevel_angle = bmd->bevel_angle;
- BLI_strncpy(tbmd->defgrp_name, bmd->defgrp_name, sizeof(tbmd->defgrp_name));
+#endif
+ modifier_copyData_generic(md, target);
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index a1f526507f9..28b388208b8 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -74,14 +74,10 @@ static void copyData(ModifierData *md, ModifierData *target)
{
#if 0
DisplaceModifierData *dmd = (DisplaceModifierData *) md;
-#endif
DisplaceModifierData *tdmd = (DisplaceModifierData *) target;
+#endif
modifier_copyData_generic(md, target);
-
- if (tdmd->texture) {
- id_us_plus(&tdmd->texture->id);
- }
}
static void freeData(ModifierData *md)
diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c
index 6d3f621105c..9d924ce4fe3 100644
--- a/source/blender/modifiers/intern/MOD_wave.c
+++ b/source/blender/modifiers/intern/MOD_wave.c
@@ -88,14 +88,10 @@ static void copyData(ModifierData *md, ModifierData *target)
{
#if 0
WaveModifierData *wmd = (WaveModifierData *) md;
-#endif
WaveModifierData *twmd = (WaveModifierData *) target;
+#endif
modifier_copyData_generic(md, target);
-
- if (twmd->texture) {
- id_us_plus(&twmd->texture->id);
- }
}
static bool dependsOnTime(ModifierData *UNUSED(md))
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index af92277bb30..89c0761f762 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -92,10 +92,6 @@ static void copyData(ModifierData *md, ModifierData *target)
modifier_copyData_generic(md, target);
twmd->cmap_curve = curvemapping_copy(wmd->cmap_curve);
-
- if (twmd->mask_texture) {
- id_us_plus(&twmd->mask_texture->id);
- }
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index 75edc216879..9ef99563dc1 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -137,14 +137,10 @@ static void copyData(ModifierData *md, ModifierData *target)
{
#if 0
WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
-#endif
WeightVGMixModifierData *twmd = (WeightVGMixModifierData *) target;
+#endif
modifier_copyData_generic(md, target);
-
- if (twmd->mask_texture) {
- id_us_plus(&twmd->mask_texture->id);
- }
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index 4c8a1be5ceb..0f197b8b5be 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -287,14 +287,10 @@ static void copyData(ModifierData *md, ModifierData *target)
{
#if 0
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
-#endif
WeightVGProximityModifierData *twmd = (WeightVGProximityModifierData *) target;
+#endif
modifier_copyData_generic(md, target);
-
- if (twmd->mask_texture) {
- id_us_plus(&twmd->mask_texture->id);
- }
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index da1b5feea3d..6da6d1df348 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -430,7 +430,7 @@ void wm_clear_default_size(bContext *C)
/* on startup, it adds all data, for matching */
void wm_add_default(bContext *C)
{
- wmWindowManager *wm = BKE_libblock_alloc(CTX_data_main(C), ID_WM, "WinMan");
+ wmWindowManager *wm = BKE_libblock_alloc(CTX_data_main(C), ID_WM, "WinMan", 0);
wmWindow *win;
bScreen *screen = CTX_wm_screen(C); /* XXX from file read hrmf */
struct WorkSpace *workspace = G.main->workspaces.last;