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:
authorLukas Tönne <lukas.toenne@gmail.com>2017-08-19 14:02:03 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2017-08-19 14:02:03 +0300
commit45f0f3dc0457a53a25103784f0e0d100c7a17cbe (patch)
tree94767d8e4fa6ea23f2bbd2274f239ecbbdc5931a /source/blender/blenkernel/intern
parent0d67f8d5c46fcc97cbb0544ef7d8c3c0056025c4 (diff)
parent9a262ed47ecb1c9f43053b0653364c59d9595fdf (diff)
Merge branch 'blender2.8' into strand_editmode
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c108
-rw-r--r--source/blender/blenkernel/intern/action.c88
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c17
-rw-r--r--source/blender/blenkernel/intern/appdir.c12
-rw-r--r--source/blender/blenkernel/intern/armature.c86
-rw-r--r--source/blender/blenkernel/intern/armature_update.c27
-rw-r--r--source/blender/blenkernel/intern/blender_copybuffer.c5
-rw-r--r--source/blender/blenkernel/intern/blendfile.c7
-rw-r--r--source/blender/blenkernel/intern/brush.c50
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c13
-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/cdderivedmesh.c17
-rw-r--r--source/blender/blenkernel/intern/cloth.c5
-rw-r--r--source/blender/blenkernel/intern/constraint.c46
-rw-r--r--source/blender/blenkernel/intern/crazyspace.c14
-rw-r--r--source/blender/blenkernel/intern/curve.c88
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c7
-rw-r--r--source/blender/blenkernel/intern/displist.c60
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c35
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c16
-rw-r--r--source/blender/blenkernel/intern/effect.c17
-rw-r--r--source/blender/blenkernel/intern/fluidsim.c4
-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.c35
-rw-r--r--source/blender/blenkernel/intern/idprop.c70
-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.c56
-rw-r--r--source/blender/blenkernel/intern/layer.c6
-rw-r--r--source/blender/blenkernel/intern/library.c522
-rw-r--r--source/blender/blenkernel/intern/library_remap.c110
-rw-r--r--source/blender/blenkernel/intern/lightprobe.c26
-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.c73
-rw-r--r--source/blender/blenkernel/intern/mball.c60
-rw-r--r--source/blender/blenkernel/intern/mball_tessellate.c4
-rw-r--r--source/blender/blenkernel/intern/mesh.c73
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c17
-rw-r--r--source/blender/blenkernel/intern/mesh_sample.c2
-rw-r--r--source/blender/blenkernel/intern/modifier.c37
-rw-r--r--source/blender/blenkernel/intern/movieclip.c38
-rw-r--r--source/blender/blenkernel/intern/multires.c14
-rw-r--r--source/blender/blenkernel/intern/nla.c2
-rw-r--r--source/blender/blenkernel/intern/node.c290
-rw-r--r--source/blender/blenkernel/intern/object.c204
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c10
-rw-r--r--source/blender/blenkernel/intern/object_update.c23
-rw-r--r--source/blender/blenkernel/intern/paint.c72
-rw-r--r--source/blender/blenkernel/intern/particle.c63
-rw-r--r--source/blender/blenkernel/intern/particle_system.c8
-rw-r--r--source/blender/blenkernel/intern/pointcache.c9
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c62
-rw-r--r--source/blender/blenkernel/intern/sca.c32
-rw-r--r--source/blender/blenkernel/intern/scene.c573
-rw-r--r--source/blender/blenkernel/intern/screen.c1
-rw-r--r--source/blender/blenkernel/intern/sequencer.c49
-rw-r--r--source/blender/blenkernel/intern/smoke.c18
-rw-r--r--source/blender/blenkernel/intern/softbody.c18
-rw-r--r--source/blender/blenkernel/intern/sound.c63
-rw-r--r--source/blender/blenkernel/intern/speaker.c28
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c19
-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/tracking_auto.c109
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c146
-rw-r--r--source/blender/blenkernel/intern/workspace.c2
-rw-r--r--source/blender/blenkernel/intern/world.c56
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c4
74 files changed, 2587 insertions, 1860 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 7b3eebb45dc..309fcad0d0a 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -96,6 +96,10 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm);
# define ASSERT_IS_VALID_DM(dm)
#endif
+
+static ThreadMutex loops_cache_lock = BLI_MUTEX_INITIALIZER;
+
+
static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *ob);
static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid);
@@ -238,6 +242,23 @@ static int dm_getNumLoopTri(DerivedMesh *dm)
return numlooptris;
}
+static const MLoopTri *dm_getLoopTriArray(DerivedMesh *dm)
+{
+ if (dm->looptris.array) {
+ BLI_assert(dm->getNumLoopTri(dm) == dm->looptris.num);
+ }
+ else {
+ BLI_mutex_lock(&loops_cache_lock);
+ /* We need to ensure array is still NULL inside mutex-protected code, some other thread might have already
+ * recomputed those looptris. */
+ if (dm->looptris.array == NULL) {
+ dm->recalcLoopTri(dm);
+ }
+ BLI_mutex_unlock(&loops_cache_lock);
+ }
+ return dm->looptris.array;
+}
+
static CustomData *dm_getVertCData(DerivedMesh *dm)
{
return &dm->vertData;
@@ -281,6 +302,8 @@ void DM_init_funcs(DerivedMesh *dm)
dm->dupLoopArray = dm_dupLoopArray;
dm->dupPolyArray = dm_dupPolyArray;
+ dm->getLoopTriArray = dm_getLoopTriArray;
+
/* subtypes handle getting actual data */
dm->getNumLoopTri = dm_getNumLoopTri;
@@ -501,19 +524,6 @@ void DM_ensure_looptri_data(DerivedMesh *dm)
}
}
-/**
- * The purpose of this function is that we can call:
- * `dm->getLoopTriArray(dm)` and get the array returned.
- */
-void DM_ensure_looptri(DerivedMesh *dm)
-{
- const int numPolys = dm->getNumPolys(dm);
-
- if ((dm->looptris.num == 0) && (numPolys != 0)) {
- dm->recalcLoopTri(dm);
- }
-}
-
void DM_verttri_from_looptri(MVertTri *verttri, const MLoop *mloop, const MLoopTri *looptri, int looptri_num)
{
int i;
@@ -1126,7 +1136,7 @@ DerivedMesh *mesh_create_derived(Mesh *me, float (*vertCos)[3])
}
DerivedMesh *mesh_create_derived_for_modifier(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
ModifierData *md, int build_shapekey_layers)
{
Mesh *me = ob->data;
@@ -1732,7 +1742,7 @@ static void dm_ensure_display_normals(DerivedMesh *dm)
* - apply deform modifiers and input vertexco
*/
static void mesh_calc_modifiers(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float (*inputVertexCos)[3],
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float (*inputVertexCos)[3],
const bool useRenderParams, int useDeform,
const bool need_mapping, CustomDataMask dataMask,
const int index, const bool useCache, const bool build_shapekey_layers,
@@ -2203,7 +2213,6 @@ static void mesh_calc_modifiers(
if (dataMask & CD_MASK_MFACE) {
DM_ensure_tessface(finaldm);
}
- DM_ensure_looptri(finaldm);
/* without this, drawing ngon tri's faces will show ugly tessellated face
* normals and will also have to calculate normals on the fly, try avoid
@@ -2288,7 +2297,7 @@ bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *
}
static void editbmesh_calc_modifiers(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
BMEditMesh *em, CustomDataMask dataMask,
/* return args */
DerivedMesh **r_cage, DerivedMesh **r_final)
@@ -2618,7 +2627,7 @@ static bool calc_modifiers_skip_orco(Scene *scene,
#endif
static void mesh_build_data(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask,
const bool build_shapekey_layers, const bool need_mapping)
{
BLI_assert(ob->type == OB_MESH);
@@ -2654,7 +2663,9 @@ static void mesh_build_data(
BLI_assert(!(ob->derivedFinal->dirty & DM_DIRTY_NORMALS));
}
-static void editbmesh_build_data(struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask)
+static void editbmesh_build_data(
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *obedit, BMEditMesh *em, CustomDataMask dataMask)
{
BKE_object_free_derived_caches(obedit);
BKE_object_sculpt_modifiers_changed(obedit);
@@ -2721,7 +2732,7 @@ static CustomDataMask object_get_datamask(const Scene *scene, Object *ob, bool *
}
void makeDerivedMesh(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BMEditMesh *em,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BMEditMesh *em,
CustomDataMask dataMask, const bool build_shapekey_layers)
{
bool need_mapping;
@@ -2737,7 +2748,8 @@ void makeDerivedMesh(
/***/
-DerivedMesh *mesh_get_derived_final(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask)
+DerivedMesh *mesh_get_derived_final(
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask)
{
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
@@ -2756,7 +2768,7 @@ DerivedMesh *mesh_get_derived_final(struct EvaluationContext *eval_ctx, Scene *s
return ob->derivedFinal;
}
-DerivedMesh *mesh_get_derived_deform(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask)
+DerivedMesh *mesh_get_derived_deform(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask)
{
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
@@ -2775,7 +2787,7 @@ DerivedMesh *mesh_get_derived_deform(struct EvaluationContext *eval_ctx, Scene *
return ob->derivedDeform;
}
-DerivedMesh *mesh_create_derived_render(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask)
+DerivedMesh *mesh_create_derived_render(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask)
{
DerivedMesh *final;
@@ -2786,7 +2798,7 @@ DerivedMesh *mesh_create_derived_render(struct EvaluationContext *eval_ctx, Scen
return final;
}
-DerivedMesh *mesh_create_derived_index_render(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask, int index)
+DerivedMesh *mesh_create_derived_index_render(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask, int index)
{
DerivedMesh *final;
@@ -2798,7 +2810,7 @@ DerivedMesh *mesh_create_derived_index_render(struct EvaluationContext *eval_ctx
}
DerivedMesh *mesh_create_derived_view(
- struct EvaluationContext *eval_ctx, Scene *scene,
+ const struct EvaluationContext *eval_ctx, Scene *scene,
Object *ob, CustomDataMask dataMask)
{
DerivedMesh *final;
@@ -2819,7 +2831,7 @@ DerivedMesh *mesh_create_derived_view(
}
DerivedMesh *mesh_create_derived_no_deform(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
float (*vertCos)[3], CustomDataMask dataMask)
{
DerivedMesh *final;
@@ -2832,7 +2844,7 @@ DerivedMesh *mesh_create_derived_no_deform(
}
DerivedMesh *mesh_create_derived_no_virtual(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
float (*vertCos)[3], CustomDataMask dataMask)
{
DerivedMesh *final;
@@ -2845,7 +2857,7 @@ DerivedMesh *mesh_create_derived_no_virtual(
}
DerivedMesh *mesh_create_derived_physics(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
float (*vertCos)[3], CustomDataMask dataMask)
{
DerivedMesh *final;
@@ -2858,7 +2870,7 @@ DerivedMesh *mesh_create_derived_physics(
}
DerivedMesh *mesh_create_derived_no_deform_render(
- struct EvaluationContext *eval_ctx, Scene *scene,
+ const struct EvaluationContext *eval_ctx, Scene *scene,
Object *ob, float (*vertCos)[3],
CustomDataMask dataMask)
{
@@ -2874,7 +2886,7 @@ DerivedMesh *mesh_create_derived_no_deform_render(
/***/
DerivedMesh *editbmesh_get_derived_cage_and_final(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit, BMEditMesh *em,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit, BMEditMesh *em,
CustomDataMask dataMask,
/* return args */
DerivedMesh **r_final)
@@ -2895,7 +2907,9 @@ DerivedMesh *editbmesh_get_derived_cage_and_final(
return em->derivedCage;
}
-DerivedMesh *editbmesh_get_derived_cage(struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask)
+DerivedMesh *editbmesh_get_derived_cage(
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit, BMEditMesh *em,
+ CustomDataMask dataMask)
{
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
@@ -3951,35 +3965,3 @@ MFace *DM_get_tessface_array(DerivedMesh *dm, bool *r_allocated)
return mface;
}
-
-const MLoopTri *DM_get_looptri_array(
- DerivedMesh *dm,
- const MVert *mvert,
- const MPoly *mpoly, int mpoly_len,
- const MLoop *mloop, int mloop_len,
- bool *r_allocated)
-{
- const MLoopTri *looptri = dm->getLoopTriArray(dm);
- *r_allocated = false;
-
- if (looptri == NULL) {
- if (mpoly_len > 0) {
- const int looptris_num = poly_to_tri_count(mpoly_len, mloop_len);
- MLoopTri *looptri_data;
-
- looptri_data = MEM_mallocN(sizeof(MLoopTri) * looptris_num, __func__);
-
- BKE_mesh_recalc_looptri(
- mloop, mpoly,
- mvert,
- mloop_len, mpoly_len,
- looptri_data);
-
- looptri = looptri_data;
-
- *r_allocated = true;
- }
- }
-
- return looptri;
-}
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..f71238031a2 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;
@@ -2849,7 +2850,7 @@ void BKE_animsys_evaluate_all_animation(Main *main, Scene *scene, float ctime)
#define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf
-void BKE_animsys_eval_animdata(EvaluationContext *eval_ctx, ID *id)
+void BKE_animsys_eval_animdata(const EvaluationContext *eval_ctx, ID *id)
{
AnimData *adt = BKE_animdata_from_id(id);
Scene *scene = NULL; /* XXX: this is only needed for flushing RNA updates,
@@ -2859,7 +2860,7 @@ void BKE_animsys_eval_animdata(EvaluationContext *eval_ctx, ID *id)
BKE_animsys_evaluate_animdata(scene, id, adt, eval_ctx->ctime, ADT_RECALC_ANIM);
}
-void BKE_animsys_eval_driver(EvaluationContext *eval_ctx,
+void BKE_animsys_eval_driver(const EvaluationContext *eval_ctx,
ID *id,
FCurve *fcu)
{
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index 43fd47981b1..f39d8006f76 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -106,7 +106,8 @@ const char *BKE_appdir_folder_default(void)
static char *blender_version_decimal(const int ver)
{
static char version_str[5];
- sprintf(version_str, "%d.%02d", ver / 100, ver % 100);
+ BLI_assert(ver < 1000);
+ BLI_snprintf(version_str, sizeof(version_str), "%d.%02d", ver / 100, ver % 100);
return version_str;
}
@@ -212,8 +213,10 @@ static bool get_path_local(
/* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */
#ifdef __APPLE__
/* due new codesign situation in OSX > 10.9.5 we must move the blender_version dir with contents to Resources */
- static char osx_resourses[FILE_MAX];
- sprintf(osx_resourses, "%s../Resources", bprogdir);
+ char osx_resourses[FILE_MAX];
+ BLI_snprintf(osx_resourses, sizeof(osx_resourses), "%s../Resources", bprogdir);
+ /* Remove the '/../' added above. */
+ BLI_cleanup_path(NULL, osx_resourses);
return test_path(targetpath, targetpath_len, osx_resourses, blender_version_decimal(ver), relfolder);
#else
return test_path(targetpath, targetpath_len, bprogdir, blender_version_decimal(ver), relfolder);
@@ -591,6 +594,9 @@ static void where_am_i(char *fullname, const size_t maxlen, const char *name)
else {
BLI_path_program_search(fullname, maxlen, name);
}
+ /* Remove "/./" and "/../" so string comparisons can be used on the path. */
+ BLI_cleanup_path(NULL, fullname);
+
#if defined(DEBUG)
if (!STREQ(name, fullname)) {
printf("guessing '%s' == '%s'\n", name, fullname);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 81796683761..7dfc4df114c 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)
@@ -1445,7 +1461,7 @@ void BKE_armature_loc_pose_to_bone(bPoseChannel *pchan, const float inloc[3], fl
copy_v3_v3(outloc, nLocMat[3]);
}
-void BKE_armature_mat_pose_to_bone_ex(struct EvaluationContext *eval_ctx, Object *ob, bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
+void BKE_armature_mat_pose_to_bone_ex(const struct EvaluationContext *eval_ctx, Object *ob, bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
{
bPoseChannel work_pchan = *pchan;
@@ -2178,7 +2194,9 @@ void BKE_pose_where_is_bone_tail(bPoseChannel *pchan)
/* pchan is validated, as having bone and parent pointer
* 'do_extra': when zero skips loc/size/rot, constraints and strip modifiers.
*/
-void BKE_pose_where_is_bone(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *pchan, float ctime, bool do_extra)
+void BKE_pose_where_is_bone(
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob, bPoseChannel *pchan, float ctime, bool do_extra)
{
/* This gives a chan_mat with actions (ipos) results. */
if (do_extra)
@@ -2239,7 +2257,7 @@ void BKE_pose_where_is_bone(struct EvaluationContext *eval_ctx, Scene *scene, Ob
/* This only reads anim data from channels, and writes to channels */
/* This is the only function adding poses */
-void BKE_pose_where_is(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void BKE_pose_where_is(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
bArmature *arm;
Bone *bone;
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index 5d579b97619..0bd4d3b864f 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -266,8 +266,9 @@ static void splineik_init_tree(Scene *scene, Object *ob, float UNUSED(ctime))
/* ----------- */
/* Evaluate spline IK for a given bone */
-static void splineik_evaluate_bone(struct EvaluationContext *eval_ctx, tSplineIK_Tree *tree, Scene *scene, Object *ob, bPoseChannel *pchan,
- int index, float ctime)
+static void splineik_evaluate_bone(
+ const struct EvaluationContext *eval_ctx, tSplineIK_Tree *tree, Scene *scene, Object *ob, bPoseChannel *pchan,
+ int index, float ctime)
{
bSplineIKConstraint *ikData = tree->ikData;
float poseHead[3], poseTail[3], poseMat[4][4];
@@ -516,7 +517,7 @@ static void splineik_evaluate_bone(struct EvaluationContext *eval_ctx, tSplineIK
}
/* Evaluate the chain starting from the nominated bone */
-static void splineik_execute_tree(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
+static void splineik_execute_tree(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
{
tSplineIK_Tree *tree;
@@ -549,14 +550,16 @@ void BKE_pose_splineik_init_tree(Scene *scene, Object *ob, float ctime)
splineik_init_tree(scene, ob, ctime);
}
-void BKE_splineik_execute_tree(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
+void BKE_splineik_execute_tree(
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob, bPoseChannel *pchan_root, float ctime)
{
splineik_execute_tree(eval_ctx, scene, ob, pchan_root, ctime);
}
/* *************** Depsgraph evaluation callbacks ************ */
-void BKE_pose_eval_init(struct EvaluationContext *eval_ctx,
+void BKE_pose_eval_init(const struct EvaluationContext *eval_ctx,
Scene *scene,
Object *ob,
bPose *pose)
@@ -590,7 +593,7 @@ void BKE_pose_eval_init(struct EvaluationContext *eval_ctx,
BKE_pose_splineik_init_tree(scene, ob, ctime);
}
-void BKE_pose_eval_bone(struct EvaluationContext *eval_ctx,
+void BKE_pose_eval_bone(const struct EvaluationContext *eval_ctx,
Scene *scene,
Object *ob,
bPoseChannel *pchan)
@@ -625,7 +628,7 @@ void BKE_pose_eval_bone(struct EvaluationContext *eval_ctx,
}
}
-void BKE_pose_constraints_evaluate(struct EvaluationContext *eval_ctx,
+void BKE_pose_constraints_evaluate(const struct EvaluationContext *eval_ctx,
Scene *scene,
Object *ob,
bPoseChannel *pchan)
@@ -646,7 +649,7 @@ void BKE_pose_constraints_evaluate(struct EvaluationContext *eval_ctx,
}
}
-void BKE_pose_bone_done(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_pose_bone_done(const struct EvaluationContext *UNUSED(eval_ctx),
bPoseChannel *pchan)
{
float imat[4][4];
@@ -657,7 +660,7 @@ void BKE_pose_bone_done(struct EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_pose_iktree_evaluate(struct EvaluationContext *eval_ctx,
+void BKE_pose_iktree_evaluate(const struct EvaluationContext *eval_ctx,
Scene *scene,
Object *ob,
bPoseChannel *rootchan)
@@ -667,7 +670,7 @@ void BKE_pose_iktree_evaluate(struct EvaluationContext *eval_ctx,
BIK_execute_tree(eval_ctx, scene, ob, rootchan, ctime);
}
-void BKE_pose_splineik_evaluate(struct EvaluationContext *eval_ctx,
+void BKE_pose_splineik_evaluate(const struct EvaluationContext *eval_ctx,
Scene *scene,
Object *ob,
bPoseChannel *rootchan)
@@ -677,7 +680,7 @@ void BKE_pose_splineik_evaluate(struct EvaluationContext *eval_ctx,
BKE_splineik_execute_tree(eval_ctx, scene, ob, rootchan, ctime);
}
-void BKE_pose_eval_flush(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_pose_eval_flush(const struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob,
bPose *UNUSED(pose))
@@ -692,7 +695,7 @@ void BKE_pose_eval_flush(struct EvaluationContext *UNUSED(eval_ctx),
ob->recalc &= ~OB_RECALC_ALL;
}
-void BKE_pose_eval_proxy_copy(struct EvaluationContext *UNUSED(eval_ctx), Object *ob)
+void BKE_pose_eval_proxy_copy(const struct EvaluationContext *UNUSED(eval_ctx), Object *ob)
{
BLI_assert(ID_IS_LINKED_DATABLOCK(ob) && ob->proxy_from != NULL);
DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);
diff --git a/source/blender/blenkernel/intern/blender_copybuffer.c b/source/blender/blenkernel/intern/blender_copybuffer.c
index 206b0f2a8cc..2d37f3ab0cb 100644
--- a/source/blender/blenkernel/intern/blender_copybuffer.c
+++ b/source/blender/blenkernel/intern/blender_copybuffer.c
@@ -49,6 +49,7 @@
#include "BKE_main.h"
#include "BKE_scene.h"
+#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "BLO_readfile.h"
@@ -160,6 +161,10 @@ bool BKE_copybuffer_paste(bContext *C, const char *libname, const short flag, Re
/* recreate dependency graph to include new objects */
DEG_relations_tag_update(bmain);
+ /* Tag update the scene to flush base collection settings, since the new object is added to a
+ * new (active) collection, not its original collection, thus need recalculation. */
+ DEG_id_tag_update(&scene->id, 0);
+
BLO_blendhandle_close(bh);
/* remove library... */
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index 09760fcc4cb..e1350aa8a46 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -117,6 +117,7 @@ static void setup_app_data(
const char *filepath, ReportList *reports)
{
Scene *curscene = NULL;
+ const bool is_startup = (bfd->filename[0] == '\0');
const bool recover = (G.fileflags & G_FILE_RECOVER) != 0;
enum {
LOAD_UI = 1,
@@ -132,7 +133,7 @@ static void setup_app_data(
else if (BLI_listbase_is_empty(&bfd->main->screen)) {
mode = LOAD_UNDO;
}
- else if (G.fileflags & G_FILE_NO_UI) {
+ else if ((G.fileflags & G_FILE_NO_UI) && (is_startup == false)) {
mode = LOAD_UI_OFF;
}
else {
@@ -264,7 +265,9 @@ static void setup_app_data(
CTX_data_scene_set(C, curscene);
}
else {
- G.fileflags = bfd->fileflags;
+ /* Keep state from preferences. */
+ const int fileflags_skip = G_FILE_FLAGS_RUNTIME;
+ G.fileflags = (G.fileflags & fileflags_skip) | (bfd->fileflags & ~fileflags_skip);
CTX_wm_manager_set(C, G.main->wm.first);
CTX_wm_screen_set(C, bfd->curscreen);
CTX_data_scene_set(C, bfd->curscene);
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 5219148a414..60ea78f3f2b 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/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index c1fad4f80c8..775499304d4 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -1137,7 +1137,6 @@ BVHTree *bvhtree_from_mesh_looptri(
const MLoopTri *looptri = NULL;
bool vert_allocated = false;
bool loop_allocated = false;
- bool looptri_allocated = false;
BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_LOOPTRI);
@@ -1150,12 +1149,7 @@ BVHTree *bvhtree_from_mesh_looptri(
mpoly = DM_get_poly_array(dm, &poly_allocated);
mloop = DM_get_loop_array(dm, &loop_allocated);
- looptri = DM_get_looptri_array(
- dm,
- mvert,
- mpoly, dm->getNumPolys(dm),
- mloop, dm->getNumLoops(dm),
- &looptri_allocated);
+ looptri = dm->getLoopTriArray(dm);
if (poly_allocated) {
MEM_freeN(mpoly);
@@ -1193,7 +1187,7 @@ BVHTree *bvhtree_from_mesh_looptri(
data, tree, true, epsilon,
mvert, vert_allocated,
mloop, loop_allocated,
- looptri, looptri_allocated);
+ looptri, false);
}
else {
if (vert_allocated) {
@@ -1202,9 +1196,6 @@ BVHTree *bvhtree_from_mesh_looptri(
if (loop_allocated) {
MEM_freeN(mloop);
}
- if (looptri_allocated) {
- MEM_freeN((void *)looptri);
- }
memset(data, 0, sizeof(*data));
}
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/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 155634c9d9c..eb5fc304749 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1807,19 +1807,6 @@ void CDDM_recalc_looptri(DerivedMesh *dm)
cddm->dm.looptris.array);
}
-static const MLoopTri *cdDM_getLoopTriArray(DerivedMesh *dm)
-{
- if (dm->looptris.array) {
- BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
- }
- else {
- dm->recalcLoopTri(dm);
-
- /* ccdm is an exception here, that recalcLoopTri will fill in the array too */
- }
- return dm->looptris.array;
-}
-
static void cdDM_free_internal(CDDerivedMesh *cddm)
{
if (cddm->pmap) MEM_freeN(cddm->pmap);
@@ -1870,8 +1857,6 @@ static CDDerivedMesh *cdDM_create(const char *desc)
dm->getEdgeDataArray = DM_get_edge_data_layer;
dm->getTessFaceDataArray = DM_get_tessface_data_layer;
- dm->getLoopTriArray = cdDM_getLoopTriArray;
-
dm->calcNormals = CDDM_calc_normals;
dm->calcLoopNormals = CDDM_calc_loop_normals;
dm->calcLoopNormalsSpaceArray = CDDM_calc_loop_normals_spacearr;
@@ -3056,7 +3041,7 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
MPoly *target_poly = cddm->mpoly + *(cddm->pmap[v_target].indices + i_poly);
if (cddm_poly_compare(cddm->mloop, mp, target_poly, vtargetmap, +1) ||
- cddm_poly_compare(cddm->mloop, mp, target_poly, vtargetmap, -1))
+ cddm_poly_compare(cddm->mloop, mp, target_poly, vtargetmap, -1))
{
found = true;
break;
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 05e92613c62..09b793629f7 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -345,7 +345,7 @@ static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
return 1;
}
-static int do_step_cloth(struct EvaluationContext *eval_ctx, Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr)
+static int do_step_cloth(const struct EvaluationContext *eval_ctx, Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr)
{
ClothVertex *verts = NULL;
Cloth *cloth;
@@ -400,7 +400,7 @@ static int do_step_cloth(struct EvaluationContext *eval_ctx, Object *ob, ClothMo
/************************************************
* clothModifier_do - main simulation function
************************************************/
-void clothModifier_do(ClothModifierData *clmd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3])
+void clothModifier_do(ClothModifierData *clmd, const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3])
{
PointCache *cache;
PTCacheID pid;
@@ -806,7 +806,6 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
if ( !dm )
return 0;
- DM_ensure_looptri(dm);
cloth_from_mesh ( clmd, dm );
// create springs
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index ac7168b6561..e87086380bd 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -689,7 +689,7 @@ static bConstraintTypeInfo CTI_CONSTRNAME = {
/* This function should be used for the get_target_matrix member of all
* constraints that are not picky about what happens to their target matrix.
*/
-static void default_get_tarmat(struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
+static void default_get_tarmat(const struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
{
if (VALID_CONS_TARGET(ct))
constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->flag, con->headtail);
@@ -1155,7 +1155,7 @@ static void kinematic_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
}
}
-static void kinematic_get_tarmat(struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void kinematic_get_tarmat(const struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
bKinematicConstraint *data = con->data;
@@ -1242,7 +1242,7 @@ static void followpath_flush_tars(bConstraint *con, ListBase *list, bool no_copy
}
}
-static void followpath_get_tarmat(struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void followpath_get_tarmat(const struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
bFollowPathConstraint *data = con->data;
@@ -2024,7 +2024,7 @@ static void pycon_id_looper(bConstraint *con, ConstraintIDFunc func, void *userd
}
/* Whether this approach is maintained remains to be seen (aligorith) */
-static void pycon_get_tarmat(struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void pycon_get_tarmat(const struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
#ifdef WITH_PYTHON
bPythonConstraint *data = con->data;
@@ -2142,7 +2142,7 @@ static void actcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
}
}
-static void actcon_get_tarmat(struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void actcon_get_tarmat(const struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
bActionConstraint *data = con->data;
@@ -3131,7 +3131,7 @@ static void clampto_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
}
}
-static void clampto_get_tarmat(struct EvaluationContext *eval_ctx, bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void clampto_get_tarmat(const struct EvaluationContext *eval_ctx, bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
#ifdef CYCLIC_DEPENDENCY_WORKAROUND
if (VALID_CONS_TARGET(ct)) {
@@ -3474,7 +3474,7 @@ static void shrinkwrap_flush_tars(bConstraint *con, ListBase *list, bool no_copy
}
-static void shrinkwrap_get_tarmat(struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void shrinkwrap_get_tarmat(const struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *) con->data;
@@ -3806,7 +3806,7 @@ static void splineik_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
}
}
-static void splineik_get_tarmat(struct EvaluationContext *eval_ctx, bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void splineik_get_tarmat(const struct EvaluationContext *eval_ctx, bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
#ifdef CYCLIC_DEPENDENCY_WORKAROUND
if (VALID_CONS_TARGET(ct)) {
@@ -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)
@@ -4858,7 +4864,7 @@ bool BKE_constraints_proxylocked_owner(Object *ob, bPoseChannel *pchan)
* None of the actual calculations of the matrices should be done here! Also, this function is
* not to be used by any new constraints, particularly any that have multiple targets.
*/
-void BKE_constraint_target_matrix_get(struct EvaluationContext *eval_ctx, Scene *scene, bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime)
+void BKE_constraint_target_matrix_get(const struct EvaluationContext *eval_ctx, Scene *scene, bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime)
{
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
@@ -4925,7 +4931,7 @@ void BKE_constraint_target_matrix_get(struct EvaluationContext *eval_ctx, Scene
}
/* Get the list of targets required for solving a constraint */
-void BKE_constraint_targets_for_solving_get(struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
+void BKE_constraint_targets_for_solving_get(const struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
{
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
@@ -4960,7 +4966,7 @@ void BKE_constraint_targets_for_solving_get(struct EvaluationContext *eval_ctx,
* BKE_constraints_make_evalob and BKE_constraints_clear_evalob should be called before and
* after running this function, to sort out cob
*/
-void BKE_constraints_solve(struct EvaluationContext *eval_ctx, ListBase *conlist, bConstraintOb *cob, float ctime)
+void BKE_constraints_solve(const struct EvaluationContext *eval_ctx, ListBase *conlist, bConstraintOb *cob, float ctime)
{
bConstraint *con;
float oldmat[4][4];
diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c
index da05c05a694..d2ffbbcf27b 100644
--- a/source/blender/blenkernel/intern/crazyspace.c
+++ b/source/blender/blenkernel/intern/crazyspace.c
@@ -99,7 +99,8 @@ static int modifiers_disable_subsurf_temporary(Object *ob)
}
/* disable subsurf temporal, get mapped cos, and enable it */
-float (*BKE_crazyspace_get_mapped_editverts(struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit))[3]
+float (*BKE_crazyspace_get_mapped_editverts(
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit))[3]
{
Mesh *me = obedit->data;
DerivedMesh *dm;
@@ -250,8 +251,9 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me, float (*origcos)[3], float (*mapped
/** returns an array of deform matrices for crazyspace correction, and the
* number of modifiers left */
-int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BMEditMesh *em,
- float (**deformmats)[3][3], float (**deformcos)[3])
+int BKE_crazyspace_get_first_deform_matrices_editbmesh(
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BMEditMesh *em,
+ float (**deformmats)[3][3], float (**deformcos)[3])
{
ModifierData *md;
DerivedMesh *dm;
@@ -310,7 +312,9 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct EvaluationContext
return numleft;
}
-int BKE_sculpt_get_first_deform_matrices(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
+int BKE_sculpt_get_first_deform_matrices(
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
{
ModifierData *md;
DerivedMesh *dm;
@@ -369,7 +373,7 @@ int BKE_sculpt_get_first_deform_matrices(struct EvaluationContext *eval_ctx, Sce
return numleft;
}
-void BKE_crazyspace_build_sculpt(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
+void BKE_crazyspace_build_sculpt(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
{
int totleft = BKE_sculpt_get_first_deform_matrices(eval_ctx, scene, ob, deformmats, deformcos);
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 6018c07835b..351f443cbc9 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(&cun->nurb);
- BKE_nurbList_duplicate(&(cun->nurb), &(cu->nurb));
+ BLI_listbase_clear(&cu_dst->nurb);
+ BKE_nurbList_duplicate(&(cu_dst->nurb), &(cu_src->nurb));
- cun->mat = MEM_dupallocN(cu->mat);
- for (a = 0; a < cun->totcol; a++) {
- id_us_plus((ID *)cun->mat[a]);
- }
+ cu_dst->mat = MEM_dupallocN(cu_src->mat);
- 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)
@@ -1625,7 +1622,7 @@ float *BKE_curve_surf_make_orco(Object *ob)
/* NOTE: This routine is tied to the order of vertex
* built by displist and as passed to the renderer.
*/
-float *BKE_curve_make_orco(EvaluationContext *eval_ctx, Scene *scene, Object *ob, int *r_numVerts)
+float *BKE_curve_make_orco(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, int *r_numVerts)
{
Curve *cu = ob->data;
DispList *dl;
@@ -1724,8 +1721,9 @@ float *BKE_curve_make_orco(EvaluationContext *eval_ctx, Scene *scene, Object *ob
/* ***************** BEVEL ****************** */
-void BKE_curve_bevel_make(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *disp,
- const bool for_render, const bool use_render_resolution)
+void BKE_curve_bevel_make(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *disp,
+ const bool for_render, const bool use_render_resolution)
{
DispList *dl, *dlnew;
Curve *bevcu, *cu;
@@ -4449,7 +4447,9 @@ bool BKE_curve_center_bounds(Curve *cu, float cent[3])
}
-void BKE_curve_transform_ex(Curve *cu, float mat[4][4], const bool do_keys, const float unit_scale)
+void BKE_curve_transform_ex(
+ Curve *cu, float mat[4][4],
+ const bool do_keys, const bool do_props, const float unit_scale)
{
Nurb *nu;
BPoint *bp;
@@ -4463,7 +4463,9 @@ void BKE_curve_transform_ex(Curve *cu, float mat[4][4], const bool do_keys, cons
mul_m4_v3(mat, bezt->vec[0]);
mul_m4_v3(mat, bezt->vec[1]);
mul_m4_v3(mat, bezt->vec[2]);
- bezt->radius *= unit_scale;
+ if (do_props) {
+ bezt->radius *= unit_scale;
+ }
}
BKE_nurb_handles_calc(nu);
}
@@ -4471,7 +4473,9 @@ void BKE_curve_transform_ex(Curve *cu, float mat[4][4], const bool do_keys, cons
i = nu->pntsu * nu->pntsv;
for (bp = nu->bp; i--; bp++) {
mul_m4_v3(mat, bp->vec);
- bp->radius *= unit_scale;
+ if (do_props) {
+ bp->radius *= unit_scale;
+ }
}
}
}
@@ -4487,10 +4491,12 @@ void BKE_curve_transform_ex(Curve *cu, float mat[4][4], const bool do_keys, cons
}
}
-void BKE_curve_transform(Curve *cu, float mat[4][4], const bool do_keys)
+void BKE_curve_transform(
+ Curve *cu, float mat[4][4],
+ const bool do_keys, const bool do_props)
{
float unit_scale = mat4_to_scale(mat);
- BKE_curve_transform_ex(cu, mat, do_keys, unit_scale);
+ BKE_curve_transform_ex(cu, mat, do_keys, do_props, unit_scale);
}
void BKE_curve_translate(Curve *cu, float offset[3], const bool do_keys)
@@ -4669,7 +4675,7 @@ void BKE_curve_rect_from_textbox(const struct Curve *cu, const struct TextBox *t
/* **** Depsgraph evaluation **** */
-void BKE_curve_eval_geometry(EvaluationContext *UNUSED(eval_ctx),
+void BKE_curve_eval_geometry(const EvaluationContext *UNUSED(eval_ctx),
Curve *curve)
{
if (G.debug & G_DEBUG_DEPSGRAPH) {
@@ -4680,7 +4686,7 @@ void BKE_curve_eval_geometry(EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_curve_eval_path(EvaluationContext *UNUSED(eval_ctx),
+void BKE_curve_eval_path(const EvaluationContext *UNUSED(eval_ctx),
Curve *curve)
{
/* TODO(sergey): This will probably need to be a part of
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 0b88cc48a96..00b8063110d 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -1010,7 +1010,8 @@ static bool data_transfer_layersmapping_generate(
* to get (as much as possible) exact copy of source data layout.
*/
void BKE_object_data_transfer_layout(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, Object *ob_dst, const int data_types, const bool use_delete,
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob_src, Object *ob_dst, const int data_types, const bool use_delete,
const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX])
{
DerivedMesh *dm_src;
@@ -1085,7 +1086,7 @@ void BKE_object_data_transfer_layout(
}
bool BKE_object_data_transfer_dm(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, Object *ob_dst, DerivedMesh *dm_dst,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, Object *ob_dst, DerivedMesh *dm_dst,
const int data_types, bool use_create, const int map_vert_mode, const int map_edge_mode,
const int map_loop_mode, const int map_poly_mode, SpaceTransform *space_transform, const bool auto_transform,
const float max_distance, const float ray_radius, const float islands_handling_precision,
@@ -1457,7 +1458,7 @@ bool BKE_object_data_transfer_dm(
}
bool BKE_object_data_transfer_mesh(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, Object *ob_dst, const int data_types,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, Object *ob_dst, const int data_types,
const bool use_create, const int map_vert_mode, const int map_edge_mode, const int map_loop_mode,
const int map_poly_mode, SpaceTransform *space_transform, const bool auto_transform,
const float max_distance, const float ray_radius, const float islands_handling_precision,
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index fd22aaa291b..8316d68b35c 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -678,7 +678,7 @@ static void curve_to_filledpoly(Curve *cu, ListBase *UNUSED(nurb), ListBase *dis
* - first point left, last point right
* - based on subdivided points in original curve, not on points in taper curve (still)
*/
-static float displist_calc_taper(EvaluationContext *eval_ctx, Scene *scene, Object *taperobj, float fac)
+static float displist_calc_taper(const EvaluationContext *eval_ctx, Scene *scene, Object *taperobj, float fac)
{
DispList *dl;
@@ -718,14 +718,14 @@ static float displist_calc_taper(EvaluationContext *eval_ctx, Scene *scene, Obje
return 1.0;
}
-float BKE_displist_calc_taper(EvaluationContext *eval_ctx, Scene *scene, Object *taperobj, int cur, int tot)
+float BKE_displist_calc_taper(const EvaluationContext *eval_ctx, Scene *scene, Object *taperobj, int cur, int tot)
{
float fac = ((float)cur) / (float)(tot - 1);
return displist_calc_taper(eval_ctx, scene, taperobj, fac);
}
-void BKE_displist_make_mball(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void BKE_displist_make_mball(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
if (!ob || ob->type != OB_MBALL)
return;
@@ -748,7 +748,7 @@ void BKE_displist_make_mball(EvaluationContext *eval_ctx, Scene *scene, Object *
}
}
-void BKE_displist_make_mball_forRender(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase)
+void BKE_displist_make_mball_forRender(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase)
{
BKE_mball_polygonize(eval_ctx, scene, ob, dispbase);
BKE_mball_texspace_calc(ob);
@@ -798,8 +798,9 @@ static ModifierData *curve_get_tessellate_point(Scene *scene, Object *ob,
return pretessellatePoint;
}
-static void curve_calc_modifiers_pre(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *nurb,
- const bool for_render, const bool use_render_resolution)
+static void curve_calc_modifiers_pre(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *nurb,
+ const bool for_render, const bool use_render_resolution)
{
VirtualModifierData virtualModifierData;
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
@@ -908,9 +909,10 @@ static void displist_apply_allverts(ListBase *dispbase, float (*allverts)[3])
}
}
-static void curve_calc_modifiers_post(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *nurb,
- ListBase *dispbase, DerivedMesh **r_dm_final,
- const bool for_render, const bool use_render_resolution)
+static void curve_calc_modifiers_post(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *nurb,
+ ListBase *dispbase, DerivedMesh **r_dm_final,
+ const bool for_render, const bool use_render_resolution)
{
VirtualModifierData virtualModifierData;
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
@@ -1090,7 +1092,7 @@ static void displist_surf_indices(DispList *dl)
}
}
-static DerivedMesh *create_orco_dm(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+static DerivedMesh *create_orco_dm(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
DerivedMesh *dm;
ListBase disp = {NULL, NULL};
@@ -1134,8 +1136,9 @@ static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
}
-static void curve_calc_orcodm(EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm_final,
- const bool for_render, const bool use_render_resolution)
+static void curve_calc_orcodm(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm_final,
+ const bool for_render, const bool use_render_resolution)
{
/* this function represents logic of mesh's orcodm calculation
* for displist-based objects
@@ -1201,9 +1204,10 @@ static void curve_calc_orcodm(EvaluationContext *eval_ctx, Scene *scene, Object
orcodm->release(orcodm);
}
-void BKE_displist_make_surf(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase,
- DerivedMesh **r_dm_final,
- const bool for_render, const bool for_orco, const bool use_render_resolution)
+void BKE_displist_make_surf(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase,
+ DerivedMesh **r_dm_final,
+ const bool for_render, const bool for_orco, const bool use_render_resolution)
{
ListBase nubase = {NULL, NULL};
Nurb *nu;
@@ -1513,9 +1517,10 @@ static void calc_bevfac_mapping(Curve *cu, BevList *bl, Nurb *nu,
}
}
-static void do_makeDispListCurveTypes(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase,
- DerivedMesh **r_dm_final,
- const bool for_render, const bool for_orco, const bool use_render_resolution)
+static void do_makeDispListCurveTypes(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase,
+ DerivedMesh **r_dm_final,
+ const bool for_render, const bool for_orco, const bool use_render_resolution)
{
Curve *cu = ob->data;
@@ -1761,7 +1766,7 @@ static void do_makeDispListCurveTypes(EvaluationContext *eval_ctx, Scene *scene,
}
}
-void BKE_displist_make_curveTypes(EvaluationContext *eval_ctx, Scene *scene, Object *ob, const bool for_orco)
+void BKE_displist_make_curveTypes(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, const bool for_orco)
{
ListBase *dispbase;
@@ -1784,9 +1789,10 @@ void BKE_displist_make_curveTypes(EvaluationContext *eval_ctx, Scene *scene, Obj
boundbox_displist_object(ob);
}
-void BKE_displist_make_curveTypes_forRender(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase,
- DerivedMesh **r_dm_final, const bool for_orco,
- const bool use_render_resolution)
+void BKE_displist_make_curveTypes_forRender(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase,
+ DerivedMesh **r_dm_final, const bool for_orco,
+ const bool use_render_resolution)
{
if (ob->curve_cache == NULL) {
ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve");
@@ -1795,7 +1801,8 @@ void BKE_displist_make_curveTypes_forRender(EvaluationContext *eval_ctx, Scene *
do_makeDispListCurveTypes(eval_ctx, scene, ob, dispbase, r_dm_final, true, for_orco, use_render_resolution);
}
-void BKE_displist_make_curveTypes_forOrco(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase)
+void BKE_displist_make_curveTypes_forOrco(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase)
{
if (ob->curve_cache == NULL) {
ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve");
@@ -1805,9 +1812,10 @@ void BKE_displist_make_curveTypes_forOrco(EvaluationContext *eval_ctx, Scene *sc
}
/* add Orco layer to the displist object which has got derived mesh and return orco */
-float *BKE_displist_make_orco(EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm_final,
- const bool for_render,
- const bool use_render_resolution)
+float *BKE_displist_make_orco(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm_final,
+ const bool for_render,
+ const bool use_render_resolution)
{
float *orco;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 6ac284d6b73..724b30d0cb1 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -500,7 +500,7 @@ static int surface_getBrushFlags(DynamicPaintSurface *surface, const SceneLayer
if (surface->brush_group)
go = surface->brush_group->gobject.first;
else
- base = FIRSTBASE_NEW;
+ base = FIRSTBASE_NEW(sl);
while (base || go) {
brushObj = NULL;
@@ -1975,7 +1975,9 @@ static void canvas_copyDerivedMesh(DynamicPaintCanvasSettings *canvas, DerivedMe
/*
* Updates derived mesh copy and processes dynamic paint step / caches.
*/
-static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm)
+static void dynamicPaint_frameUpdate(
+ DynamicPaintModifierData *pmd, const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob, DerivedMesh *dm)
{
if (pmd->canvas) {
DynamicPaintCanvasSettings *canvas = pmd->canvas;
@@ -2057,14 +2059,13 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, struct Evalu
}
/* Modifier call. Processes dynamic paint modifier step. */
-DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm)
+DerivedMesh *dynamicPaint_Modifier_do(
+ DynamicPaintModifierData *pmd, const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob, DerivedMesh *dm)
{
if (pmd->canvas) {
DerivedMesh *ret;
- /* For now generate looptris in every case */
- DM_ensure_looptri(dm);
-
/* Update canvas data for a new frame */
dynamicPaint_frameUpdate(pmd, eval_ctx, scene, ob, dm);
@@ -2074,9 +2075,6 @@ DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, struct Eval
return ret;
}
else {
- /* For now generate looptris in every case */
- DM_ensure_looptri(dm);
-
/* Update canvas data for a new frame */
dynamicPaint_frameUpdate(pmd, eval_ctx, scene, ob, dm);
@@ -3584,7 +3582,8 @@ static void dynamic_paint_brush_velocity_compute_cb(void *userdata, const int i)
}
static void dynamicPaint_brushMeshCalculateVelocity(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DynamicPaintBrushSettings *brush, Vec3f **brushVel, float timescale)
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob, DynamicPaintBrushSettings *brush, Vec3f **brushVel, float timescale)
{
float prev_obmat[4][4];
DerivedMesh *dm_p, *dm_c;
@@ -3642,7 +3641,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(
}
/* calculate velocity for object center point */
-static void dynamicPaint_brushObjectCalculateVelocity(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, Vec3f *brushVel, float timescale)
+static void dynamicPaint_brushObjectCalculateVelocity(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, Vec3f *brushVel, float timescale)
{
float prev_obmat[4][4];
float cur_loc[3] = {0.0f}, prev_loc[3] = {0.0f};
@@ -4038,7 +4037,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(
}
}
-static int dynamicPaint_paintMesh(struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface,
+static int dynamicPaint_paintMesh(const struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface,
DynamicPaintBrushSettings *brush,
Object *brushOb,
BrushMaterials *bMats,
@@ -4532,7 +4531,7 @@ static void dynamic_paint_paint_single_point_cb_ex(
}
static int dynamicPaint_paintSinglePoint(
- struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface, float *pointCoord, DynamicPaintBrushSettings *brush,
+ const struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface, float *pointCoord, DynamicPaintBrushSettings *brush,
Object *brushOb, BrushMaterials *bMats, Scene *scene, float timescale)
{
PaintSurfaceData *sData = surface->data;
@@ -4847,7 +4846,7 @@ static void dynamic_paint_prepare_effect_cb(void *userdata, const int index)
}
static int dynamicPaint_prepareEffectStep(
- struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface, Scene *scene, Object *ob, float **force, float timescale)
+ const struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface, Scene *scene, Object *ob, float **force, float timescale)
{
double average_force = 0.0f;
float shrink_speed = 0.0f, spread_speed = 0.0f;
@@ -5760,7 +5759,7 @@ static int dynamicPaint_generateBakeData(DynamicPaintSurface *surface, const Sce
/*
* Do Dynamic Paint step. Paints scene brush objects of current state/frame to the surface.
*/
-static int dynamicPaint_doStep(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DynamicPaintSurface *surface, float timescale, float subframe)
+static int dynamicPaint_doStep(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DynamicPaintSurface *surface, float timescale, float subframe)
{
PaintSurfaceData *sData = surface->data;
PaintBakeData *bData = sData->bData;
@@ -5794,7 +5793,7 @@ static int dynamicPaint_doStep(struct EvaluationContext *eval_ctx, Scene *scene,
if (surface->brush_group)
go = surface->brush_group->gobject.first;
else
- base = FIRSTBASE_NEW;
+ base = FIRSTBASE_NEW(sl);
while (base || go) {
brushObj = NULL;
@@ -5931,7 +5930,9 @@ static int dynamicPaint_doStep(struct EvaluationContext *eval_ctx, Scene *scene,
/*
* Calculate a single frame and included subframes for surface
*/
-int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, struct EvaluationContext *eval_ctx, Scene *scene, Object *cObject, int frame)
+int dynamicPaint_calculateFrame(
+ DynamicPaintSurface *surface, const struct EvaluationContext *eval_ctx,
+ Scene *scene, Object *cObject, int frame)
{
float timescale = 1.0f;
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index df3c652ee19..2beb15ed995 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -299,18 +299,6 @@ static void emDM_recalcLoopTri(DerivedMesh *dm)
}
}
-static const MLoopTri *emDM_getLoopTriArray(DerivedMesh *dm)
-{
- if (dm->looptris.array) {
- BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
- }
- else {
- dm->recalcLoopTri(dm);
- }
-
- return dm->looptris.array;
-}
-
static void emDM_foreachMappedVert(
DerivedMesh *dm,
void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
@@ -1639,8 +1627,6 @@ DerivedMesh *getEditDerivedBMesh(
bmdm->dm.getNumLoops = emDM_getNumLoops;
bmdm->dm.getNumPolys = emDM_getNumPolys;
- bmdm->dm.getLoopTriArray = emDM_getLoopTriArray;
-
bmdm->dm.getVert = emDM_getVert;
bmdm->dm.getVertCo = emDM_getVertCo;
bmdm->dm.getVertNo = emDM_getVertNo;
@@ -2183,7 +2169,7 @@ static void cage_mapped_verts_callback(
}
}
-float (*BKE_editmesh_vertexCos_get(struct EvaluationContext *eval_ctx, BMEditMesh *em, Scene *scene, int *r_numVerts))[3]
+float (*BKE_editmesh_vertexCos_get(const struct EvaluationContext *eval_ctx, BMEditMesh *em, Scene *scene, int *r_numVerts))[3]
{
DerivedMesh *cage, *final;
BLI_bitmap *visit_bitmap;
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index af1d4cc2e7d..36f7f6d604e 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -147,7 +147,7 @@ void free_partdeflect(PartDeflect *pd)
MEM_freeN(pd);
}
-static EffectorCache *new_effector_cache(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
+static EffectorCache *new_effector_cache(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
{
EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache");
eff->eval_ctx = eval_ctx;
@@ -158,7 +158,7 @@ static EffectorCache *new_effector_cache(struct EvaluationContext *eval_ctx, Sce
eff->frame = -1;
return eff;
}
-static void add_object_to_effectors(ListBase **effectors, struct EvaluationContext *eval_ctx, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src, bool for_simulation)
+static void add_object_to_effectors(ListBase **effectors, const struct EvaluationContext *eval_ctx, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src, bool for_simulation)
{
EffectorCache *eff = NULL;
@@ -183,7 +183,7 @@ static void add_object_to_effectors(ListBase **effectors, struct EvaluationConte
BLI_addtail(*effectors, eff);
}
-static void add_particles_to_effectors(ListBase **effectors, struct EvaluationContext *eval_ctx, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src, bool for_simulation)
+static void add_particles_to_effectors(ListBase **effectors, const struct EvaluationContext *eval_ctx, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src, bool for_simulation)
{
ParticleSettings *part= psys->part;
@@ -209,8 +209,9 @@ static void add_particles_to_effectors(ListBase **effectors, struct EvaluationCo
}
/* returns ListBase handle with objects taking part in the effecting */
-ListBase *pdInitEffectors(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, ParticleSystem *psys_src,
- EffectorWeights *weights, bool for_simulation)
+ListBase *pdInitEffectors(
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, ParticleSystem *psys_src,
+ EffectorWeights *weights, bool for_simulation)
{
SceneLayer *sl;
Base *base;
@@ -243,7 +244,7 @@ ListBase *pdInitEffectors(struct EvaluationContext *eval_ctx, Scene *scene, Obje
}
}
else {
- for (base = FIRSTBASE_NEW; base; base = base->next) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
if ( base->object->pd && base->object->pd->forcefield )
add_object_to_effectors(&effectors, eval_ctx, scene, weights, base->object, ob_src, for_simulation);
@@ -278,7 +279,7 @@ void pdEndEffectors(ListBase **effectors)
}
}
-static void precalculate_effector(struct EvaluationContext *eval_ctx, EffectorCache *eff)
+static void precalculate_effector(const struct EvaluationContext *eval_ctx, EffectorCache *eff)
{
unsigned int cfra = (unsigned int)(eff->scene->r.cfra >= 0 ? eff->scene->r.cfra : -eff->scene->r.cfra);
if (!eff->pd->rng)
@@ -318,7 +319,7 @@ static void precalculate_effector(struct EvaluationContext *eval_ctx, EffectorCa
}
}
-void pdPrecalculateEffectors(struct EvaluationContext *eval_ctx, ListBase *effectors)
+void pdPrecalculateEffectors(const struct EvaluationContext *eval_ctx, ListBase *effectors)
{
if (effectors) {
EffectorCache *eff = effectors->first;
diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c
index 5599190010d..12b9abc6d03 100644
--- a/source/blender/blenkernel/intern/fluidsim.c
+++ b/source/blender/blenkernel/intern/fluidsim.c
@@ -65,7 +65,7 @@
// file handling
//-------------------------------------------------------------------------------
-void initElbeemMesh(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
+void initElbeemMesh(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
int *numVertices, float **vertices,
int *numTriangles, int **triangles,
int useGlobalCoords, int modifierIndex)
@@ -80,8 +80,6 @@ void initElbeemMesh(struct EvaluationContext *eval_ctx, struct Scene *scene, str
dm = mesh_create_derived_index_render(eval_ctx, scene, ob, CD_MASK_BAREMESH, modifierIndex);
- DM_ensure_looptri(dm);
-
mvert = dm->getVertArray(dm);
mloop = dm->getLoopArray(dm);
looptri = dm->getLoopTriArray(dm);
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..5ccbe9f7054 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)
@@ -314,7 +327,7 @@ static void group_replaces_nla(Object *parent, Object *target, char mode)
* you can draw everything, leaves tags in objects to signal it needs further updating */
/* note: does not work for derivedmesh and render... it recreates all again in convertblender.c */
-void BKE_group_handle_recalc_and_update(struct EvaluationContext *eval_ctx, Scene *scene, Object *UNUSED(parent), Group *group)
+void BKE_group_handle_recalc_and_update(const struct EvaluationContext *eval_ctx, Scene *scene, Object *UNUSED(parent), Group *group)
{
GroupObject *go;
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index a3bd15252cb..b00a62a1a87 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;
@@ -603,7 +605,7 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
* If a property is missing in \a dest, add it.
* Do it recursively.
*/
-void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overwrite)
+void IDP_MergeGroup_ex(IDProperty *dest, const IDProperty *src, const bool do_overwrite, const int flag)
{
IDProperty *prop;
@@ -616,12 +618,12 @@ void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overw
IDProperty *prop_exist = IDP_GetPropertyFromGroup(dest, prop->name);
if (prop_exist != NULL) {
- IDP_MergeGroup(prop_exist, prop, do_overwrite);
+ IDP_MergeGroup_ex(prop_exist, prop, do_overwrite, flag);
continue;
}
}
- IDProperty *copy = IDP_CopyProperty(prop);
+ IDProperty *copy = IDP_CopyProperty_ex(prop, flag);
IDP_ReplaceInGroup(dest, copy);
}
}
@@ -630,12 +632,12 @@ void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overw
IDProperty *prop_exist = IDP_GetPropertyFromGroup(dest, prop->name);
if (prop_exist != NULL) {
if (prop->type == IDP_GROUP) {
- IDP_MergeGroup(prop_exist, prop, do_overwrite);
+ IDP_MergeGroup_ex(prop_exist, prop, do_overwrite, flag);
continue;
}
}
else {
- IDProperty *copy = IDP_CopyProperty(prop);
+ IDProperty *copy = IDP_CopyProperty_ex(prop, flag);
dest->len++;
BLI_addtail(&dest->data.group, copy);
}
@@ -644,6 +646,15 @@ void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overw
}
/**
+ * If a property is missing in \a dest, add it.
+ * Do it recursively.
+ */
+void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overwrite)
+{
+ IDP_MergeGroup_ex(dest, src, do_overwrite, 0);
+}
+
+/**
* This function has a sanity check to make sure ID properties with the same name don't
* get added to the group.
*
@@ -748,18 +759,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..0f26f53113f 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);
@@ -596,7 +603,7 @@ static bool where_on_path_deform(Object *ob, float ctime, float vec[4], float di
/* co: local coord, result local too */
/* returns quaternion for rotation, using cd->no_rot_axis */
/* axis is using another define!!! */
-static bool calc_curve_deform(struct EvaluationContext *eval_ctx, Scene *scene, Object *par, float co[3],
+static bool calc_curve_deform(const struct EvaluationContext *eval_ctx, Scene *scene, Object *par, float co[3],
const short axis, CurveDeform *cd, float r_quat[4])
{
Curve *cu = par->data;
@@ -700,7 +707,8 @@ static bool calc_curve_deform(struct EvaluationContext *eval_ctx, Scene *scene,
}
void curve_deform_verts(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3],
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3],
int numVerts, const char *vgroup, short defaxis)
{
Curve *cu;
@@ -818,7 +826,7 @@ void curve_deform_verts(
/* input vec and orco = local coord in armature space */
/* orco is original not-animated or deformed reference point */
/* result written in vec and mat */
-void curve_deform_vector(struct EvaluationContext *eval_ctx, Scene *scene, Object *cuOb, Object *target,
+void curve_deform_vector(const struct EvaluationContext *eval_ctx, Scene *scene, Object *cuOb, Object *target,
float orco[3], float vec[3], float mat[3][3], int no_rot_axis)
{
CurveDeform cd;
@@ -1027,7 +1035,7 @@ void BKE_lattice_vertexcos_apply(struct Object *ob, float (*vertexCos)[3])
}
}
-void BKE_lattice_modifiers_calc(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void BKE_lattice_modifiers_calc(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
Lattice *lt = ob->data;
VirtualModifierData virtualModifierData;
@@ -1228,7 +1236,7 @@ void BKE_lattice_translate(Lattice *lt, float offset[3], bool do_keys)
/* **** Depsgraph evaluation **** */
-void BKE_lattice_eval_geometry(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_lattice_eval_geometry(const struct EvaluationContext *UNUSED(eval_ctx),
Lattice *UNUSED(latt))
{
}
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 56b9bd2cc1e..16a4477977f 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -1734,7 +1734,7 @@ static void idproperty_reset(IDProperty **props, IDProperty *props_ref)
}
}
-void BKE_layer_eval_layer_collection_pre(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_layer_eval_layer_collection_pre(const struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene, SceneLayer *scene_layer)
{
DEBUG_PRINT("%s on %s (%p)\n", __func__, scene_layer->name, scene_layer);
@@ -1751,7 +1751,7 @@ void BKE_layer_eval_layer_collection_pre(struct EvaluationContext *UNUSED(eval_c
scene_layer->flag |= SCENE_LAYER_ENGINE_DIRTY;
}
-void BKE_layer_eval_layer_collection(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_layer_eval_layer_collection(const struct EvaluationContext *UNUSED(eval_ctx),
LayerCollection *layer_collection,
LayerCollection *parent_layer_collection)
{
@@ -1798,7 +1798,7 @@ void BKE_layer_eval_layer_collection(struct EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_layer_eval_layer_collection_post(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_layer_eval_layer_collection_post(const struct EvaluationContext *UNUSED(eval_ctx),
SceneLayer *scene_layer)
{
DEBUG_PRINT("%s on %s (%p)\n", __func__, scene_layer->name, scene_layer);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index ed64de9b1aa..71fbb3d726a 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,193 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
return false;
}
+struct IDCopyLibManagementData {
+ const ID *id_src;
+ ID *id_dst;
+ int flag;
+};
+
+/* Increases usercount as required, and remap self ID pointers. */
+static int id_copy_libmanagement_cb(void *user_data, ID *UNUSED(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) {
+ /* We cannot use id_self here, it is not *always* id_dst (thanks to $£!+@#&/? nodetrees). */
+ id = *id_pointer = data->id_dst;
+ }
+
+ /* 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;
}
- /* conventions:
- * - make shallow copy, only this ID block
- * - id.us of the new ID is set to 1 */
+ if (ELEM(GS(id->name), LIB_ID_TYPES_NOCOPY)) {
+ return false;
+ }
+ else if (test) {
+ return true;
+ }
+
+ 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, .id_dst = *r_newid, .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 +708,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 +1120,44 @@ 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);
-
- id = BKE_libblock_alloc_notest(type);
+ BLI_assert((flag & LIB_ID_CREATE_NO_ALLOCATE) == 0);
+
+ ID *id = BKE_libblock_alloc_notest(type);
+
if (id) {
- BKE_main_lock(bmain);
- BLI_addtail(lb, id);
- id->us = 1;
+ 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;
+ }
+
id->icon_id = 0;
- *( (short *)id->name) = type;
- new_id(lb, id, name);
- /* alphabetic insertion: is in new_id */
- BKE_main_unlock(bmain);
+ *((short *)id->name) = type;
+ if ((flag & LIB_ID_CREATE_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);
+ }
+ }
+ else {
+ BLI_strncpy(id->name + 2, name, sizeof(id->name) - 2);
+ }
}
- DEG_id_type_tag(bmain, type);
+
return id;
}
@@ -1095,70 +1283,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) {
+ DEG_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 +1396,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..8f0bb26a0c1 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -248,7 +248,7 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
return IDWALK_RET_NOP;
}
-/* Some reamapping unfortunately require extra and/or specific handling, tackle those here. */
+/* Some remapping unfortunately require extra and/or specific handling, tackle those here. */
static void libblock_remap_data_preprocess_scene_base_unlink(
IDRemap *r_id_remap_data, Scene *sce, BaseLegacy *base, const bool skip_indirect, const bool is_indirect)
{
@@ -352,7 +352,7 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
}
}
-static void libblock_remap_data_postprocess_object_fromgroup_update(Main *bmain, Object *old_ob, Object *new_ob)
+static void libblock_remap_data_postprocess_object_update(Main *bmain, Object *old_ob, Object *new_ob)
{
if (old_ob->flag & OB_FROMGROUP) {
/* Note that for Scene's BaseObject->flag, either we:
@@ -371,6 +371,13 @@ static void libblock_remap_data_postprocess_object_fromgroup_update(Main *bmain,
new_ob->flag |= OB_FROMGROUP;
}
}
+ if (old_ob->type == OB_MBALL) {
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->type == OB_MBALL && BKE_mball_is_basis_for(ob, old_ob)) {
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ }
+ }
+ }
}
static void libblock_remap_data_postprocess_group_scene_unlink(Main *UNUSED(bmain), Scene *sce, ID *old_id)
@@ -575,7 +582,7 @@ void BKE_libblock_remap_locked(
*/
switch (GS(old_id->name)) {
case ID_OB:
- libblock_remap_data_postprocess_object_fromgroup_update(bmain, (Object *)old_id, (Object *)new_id);
+ libblock_remap_data_postprocess_object_update(bmain, (Object *)old_id, (Object *)new_id);
break;
case ID_GR:
if (!new_id) { /* Only affects us in case group was unlinked. */
@@ -605,7 +612,7 @@ void BKE_libblock_remap_locked(
libblock_remap_data_postprocess_nodetree_update(bmain, new_id);
BKE_main_lock(bmain);
- /* Full rebuild of DAG! */
+ /* Full rebuild of DEG! */
DEG_relations_tag_update(bmain);
}
@@ -685,8 +692,7 @@ void BKE_libblock_relink_ex(
switch (GS(old_id->name)) {
case ID_OB:
{
- libblock_remap_data_postprocess_object_fromgroup_update(
- bmain, (Object *)old_id, (Object *)new_id);
+ libblock_remap_data_postprocess_object_update(bmain, (Object *)old_id, (Object *)new_id);
break;
}
case ID_GR:
@@ -701,7 +707,7 @@ void BKE_libblock_relink_ex(
else {
/* No choice but to check whole objects/groups. */
for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
- libblock_remap_data_postprocess_object_fromgroup_update(bmain, ob, NULL);
+ libblock_remap_data_postprocess_object_update(bmain, ob, NULL);
}
for (Group *grp = bmain->group.first; grp; grp = grp->id.next) {
libblock_remap_data_postprocess_group_scene_unlink(bmain, sce, NULL);
@@ -758,9 +764,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 +884,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) {
+ DEG_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 +997,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/lightprobe.c b/source/blender/blenkernel/intern/lightprobe.c
index a1fa266512b..5601fa5ad42 100644
--- a/source/blender/blenkernel/intern/lightprobe.c
+++ b/source/blender/blenkernel/intern/lightprobe.c
@@ -59,22 +59,32 @@ void *BKE_lightprobe_add(Main *bmain, const char *name)
{
LightProbe *probe;
- probe = BKE_libblock_alloc(bmain, ID_LP, name);
+ probe = BKE_libblock_alloc(bmain, ID_LP, name, 0);
BKE_lightprobe_init(probe);
return probe;
}
-LightProbe *BKE_lightprobe_copy(Main *bmain, LightProbe *probe)
+/**
+ * Only copy internal data of LightProbe 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_lightprobe_copy_data(
+ Main *UNUSED(bmain), LightProbe *UNUSED(probe_dst), const LightProbe *UNUSED(probe_src), const int UNUSED(flag))
{
- LightProbe *probe_new;
-
- probe_new = BKE_libblock_copy(bmain, &probe->id);
-
- BKE_id_copy_ensure_local(bmain, &probe->id, &probe_new->id);
+ /* Nothing to do here. */
+}
- return probe_new;
+LightProbe *BKE_lightprobe_copy(Main *bmain, const LightProbe *probe)
+{
+ LightProbe *probe_copy;
+ BKE_id_copy_ex(bmain, &probe->id, (ID **)&probe_copy, 0, false);
+ return probe_copy;
}
void BKE_lightprobe_make_local(Main *bmain, LightProbe *probe, const bool lib_local)
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..be3cc288818 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;
@@ -1798,7 +1815,7 @@ bool BKE_object_material_edit_image_set(Object *ob, short mat_nr, Image *image)
return false;
}
-void BKE_material_eval(struct EvaluationContext *UNUSED(eval_ctx), Material *material)
+void BKE_material_eval(const struct EvaluationContext *UNUSED(eval_ctx), Material *material)
{
if (G.debug & G_DEBUG_DEPSGRAPH) {
printf("%s on %s (%p)\n", __func__, material->id.name, material);
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 27e2b17b4e2..f1e549b1400 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)
@@ -469,7 +472,7 @@ bool BKE_mball_center_bounds(MetaBall *mb, float r_cent[3])
return false;
}
-void BKE_mball_transform(MetaBall *mb, float mat[4][4])
+void BKE_mball_transform(MetaBall *mb, float mat[4][4], const bool do_props)
{
MetaElem *me;
float quat[4];
@@ -481,14 +484,17 @@ void BKE_mball_transform(MetaBall *mb, float mat[4][4])
for (me = mb->elems.first; me; me = me->next) {
mul_m4_v3(mat, &me->x);
mul_qt_qtqt(me->quat, quat, me->quat);
- me->rad *= scale;
- /* hrmf, probably elems shouldn't be
- * treating scale differently - campbell */
- if (!MB_TYPE_SIZE_SQUARED(me->type)) {
- mul_v3_fl(&me->expx, scale);
- }
- else {
- mul_v3_fl(&me->expx, scale_sqrt);
+
+ if (do_props) {
+ me->rad *= scale;
+ /* hrmf, probably elems shouldn't be
+ * treating scale differently - campbell */
+ if (!MB_TYPE_SIZE_SQUARED(me->type)) {
+ mul_v3_fl(&me->expx, scale);
+ }
+ else {
+ mul_v3_fl(&me->expx, scale_sqrt);
+ }
}
}
}
@@ -532,7 +538,7 @@ void BKE_mball_select_swap(struct MetaBall *mb)
/* **** Depsgraph evaluation **** */
-void BKE_mball_eval_geometry(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_mball_eval_geometry(const struct EvaluationContext *UNUSED(eval_ctx),
MetaBall *UNUSED(mball))
{
}
diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c
index d897213d362..1d9c580d45b 100644
--- a/source/blender/blenkernel/intern/mball_tessellate.c
+++ b/source/blender/blenkernel/intern/mball_tessellate.c
@@ -1079,7 +1079,7 @@ static void polygonize(PROCESS *process)
* Iterates over ALL objects in the scene and all of its sets, including
* making all duplis(not only metas). Copies metas to mainb array.
* Computes bounding boxes for building BVH. */
-static void init_meta(EvaluationContext *eval_ctx, PROCESS *process, Scene *scene, Object *ob)
+static void init_meta(const EvaluationContext *eval_ctx, PROCESS *process, Scene *scene, Object *ob)
{
Scene *sce_iter = scene;
BaseLegacy *base;
@@ -1256,7 +1256,7 @@ static void init_meta(EvaluationContext *eval_ctx, PROCESS *process, Scene *scen
}
}
-void BKE_mball_polygonize(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase)
+void BKE_mball_polygonize(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase)
{
MetaBall *mb;
DispList *dl;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 9be072f1a21..a0edc75a7b4 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(
@@ -1628,7 +1631,7 @@ void BKE_mesh_to_curve_nurblist(DerivedMesh *dm, ListBase *nurblist, const int e
}
}
-void BKE_mesh_to_curve(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void BKE_mesh_to_curve(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
/* make new mesh data from the original copy */
DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_MESH);
@@ -2466,7 +2469,7 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
/* settings: 1 - preview, 2 - render */
Mesh *BKE_mesh_new_from_object(
- EvaluationContext *eval_ctx, Main *bmain, Scene *sce, Object *ob,
+ const EvaluationContext *eval_ctx, Main *bmain, Scene *sce, Object *ob,
int apply_modifiers, int settings, int calc_tessface, int calc_undeformed)
{
Mesh *tmpmesh;
@@ -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);
@@ -2701,7 +2706,7 @@ Mesh *BKE_mesh_new_from_object(
/* **** Depsgraph evaluation **** */
-void BKE_mesh_eval_geometry(EvaluationContext *UNUSED(eval_ctx),
+void BKE_mesh_eval_geometry(const EvaluationContext *UNUSED(eval_ctx),
Mesh *mesh)
{
if (G.debug & G_DEBUG_DEPSGRAPH) {
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index c5fa9b15896..d2fe8f27f4a 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -1184,7 +1184,6 @@ void BKE_mesh_remap_calc_loops_from_dm(
bool polys_allocated_src;
MPoly *polys_src = DM_get_poly_array(dm_src, &polys_allocated_src);
const int num_polys_src = dm_src->getNumPolys(dm_src);
- bool looptri_allocated_src = false;
const MLoopTri *looptri_src = NULL;
int num_looptri_src = 0;
@@ -1374,17 +1373,11 @@ void BKE_mesh_remap_calc_loops_from_dm(
if (dirty_tess_flag) {
dm_src->dirty &= ~dirty_tess_flag;
}
- DM_ensure_looptri(dm_src);
if (dirty_tess_flag) {
dm_src->dirty |= dirty_tess_flag;
}
- looptri_src = DM_get_looptri_array(
- dm_src,
- verts_src,
- polys_src, num_polys_src,
- loops_src, num_loops_src,
- &looptri_allocated_src);
+ looptri_src = dm_src->getLoopTriArray(dm_src);
num_looptri_src = dm_src->getNumLoopTri(dm_src);
looptri_active = BLI_BITMAP_NEW((size_t)num_looptri_src, __func__);
@@ -1403,7 +1396,7 @@ void BKE_mesh_remap_calc_loops_from_dm(
&treedata[tindex],
verts_src, verts_allocated_src,
loops_src, loops_allocated_src,
- looptri_src, num_looptri_src, looptri_allocated_src,
+ looptri_src, num_looptri_src, false,
looptri_active, num_looptri_active, bvh_epsilon, 2, 6);
if (verts_allocated_src) {
verts_allocated_src = false; /* Only 'give' our verts once, to first tree! */
@@ -1411,9 +1404,6 @@ void BKE_mesh_remap_calc_loops_from_dm(
if (loops_allocated_src) {
loops_allocated_src = false; /* Only 'give' our loops once, to first tree! */
}
- if (looptri_allocated_src) {
- looptri_allocated_src = false; /* Only 'give' our looptri once, to first tree! */
- }
}
MEM_freeN(looptri_active);
@@ -1928,9 +1918,6 @@ void BKE_mesh_remap_calc_loops_from_dm(
if (polys_allocated_src) {
MEM_freeN(polys_src);
}
- if (looptri_allocated_src) {
- MEM_freeN((void *)looptri_src);
- }
if (vert_to_loop_map_src) {
MEM_freeN(vert_to_loop_map_src);
}
diff --git a/source/blender/blenkernel/intern/mesh_sample.c b/source/blender/blenkernel/intern/mesh_sample.c
index 53d14c9dd16..8e823350fce 100644
--- a/source/blender/blenkernel/intern/mesh_sample.c
+++ b/source/blender/blenkernel/intern/mesh_sample.c
@@ -428,7 +428,7 @@ MeshSampleGenerator *BKE_mesh_sample_gen_surface_random_ex(DerivedMesh *dm, unsi
MSurfaceSampleGenerator_Random *gen;
DM_ensure_normals(dm);
- DM_ensure_looptri(dm);
+ DM_ensure_looptri_data(dm);
gen = MEM_callocN(sizeof(MSurfaceSampleGenerator_Random), "MSurfaceSampleGenerator_Random");
sample_generator_init(&gen->base, (GeneratorFreeFp)generator_random_free, (GeneratorMakeSampleFp)generator_random_make_sample);
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index b4eb132353c..1a146dc67d1 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);
}
@@ -732,7 +757,7 @@ void modifier_path_init(char *path, int path_maxlen, const char *name)
/* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */
struct DerivedMesh *modwrap_applyModifier(
- ModifierData *md, struct EvaluationContext *eval_ctx,
+ ModifierData *md, const struct EvaluationContext *eval_ctx,
Object *ob, struct DerivedMesh *dm,
ModifierApplyFlag flag)
{
@@ -746,7 +771,7 @@ struct DerivedMesh *modwrap_applyModifier(
}
struct DerivedMesh *modwrap_applyModifierEM(
- ModifierData *md, struct EvaluationContext *eval_ctx,
+ ModifierData *md, const struct EvaluationContext *eval_ctx,
Object *ob, struct BMEditMesh *em,
DerivedMesh *dm,
ModifierApplyFlag flag)
@@ -761,7 +786,7 @@ struct DerivedMesh *modwrap_applyModifierEM(
}
void modwrap_deformVerts(
- ModifierData *md, struct EvaluationContext *eval_ctx,
+ ModifierData *md, const struct EvaluationContext *eval_ctx,
Object *ob, DerivedMesh *dm,
float (*vertexCos)[3], int numVerts,
ModifierApplyFlag flag)
@@ -776,7 +801,7 @@ void modwrap_deformVerts(
}
void modwrap_deformVertsEM(
- ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob,
+ ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob,
struct BMEditMesh *em, DerivedMesh *dm,
float (*vertexCos)[3], int numVerts)
{
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/multires.c b/source/blender/blenkernel/intern/multires.c
index 3e4828afb55..7ef4b588dcd 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -276,7 +276,7 @@ static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level)
return mdisps;
}
-DerivedMesh *get_multires_dm(struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *ob)
+DerivedMesh *get_multires_dm(const struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *ob)
{
ModifierData *md = (ModifierData *)mmd;
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -397,7 +397,7 @@ void multires_force_render_update(Object *ob)
multires_force_update(ob);
}
-int multiresModifier_reshapeFromDM(struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd,
+int multiresModifier_reshapeFromDM(const struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd,
Object *ob, DerivedMesh *srcdm)
{
DerivedMesh *mrdm = get_multires_dm(eval_ctx, scene, mmd, ob);
@@ -419,13 +419,13 @@ int multiresModifier_reshapeFromDM(struct EvaluationContext *eval_ctx, Scene *sc
}
/* Returns 1 on success, 0 if the src's totvert doesn't match */
-int multiresModifier_reshape(struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *dst, Object *src)
+int multiresModifier_reshape(const struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *dst, Object *src)
{
DerivedMesh *srcdm = mesh_get_derived_final(eval_ctx, scene, src, CD_MASK_BAREMESH);
return multiresModifier_reshapeFromDM(eval_ctx, scene, mmd, dst, srcdm);
}
-int multiresModifier_reshapeFromDeformMod(struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd,
+int multiresModifier_reshapeFromDeformMod(const struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd,
Object *ob, ModifierData *md)
{
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -2174,7 +2174,7 @@ static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst)
}
}
-static void multires_apply_smat(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float smat[3][3])
+static void multires_apply_smat(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float smat[3][3])
{
DerivedMesh *dm = NULL, *cddm = NULL, *subdm = NULL;
CCGElem **gridData, **subGridData;
@@ -2276,7 +2276,7 @@ int multires_mdisp_corners(MDisps *s)
return 0;
}
-void multiresModifier_scale_disp(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void multiresModifier_scale_disp(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
float smat[3][3];
@@ -2286,7 +2286,7 @@ void multiresModifier_scale_disp(struct EvaluationContext *eval_ctx, Scene *scen
multires_apply_smat(eval_ctx, scene, ob, smat);
}
-void multiresModifier_prepare_join(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, Object *to_ob)
+void multiresModifier_prepare_join(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, Object *to_ob)
{
float smat[3][3], tmat[3][3], mat[3][3];
multires_sync_levels(scene, to_ob, ob);
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 148fc3827e0..478b854c4df 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -59,7 +59,7 @@
#include "BKE_library.h"
#ifdef WITH_AUDASPACE
-# include AUD_SPECIAL_H
+# include <AUD_Special.h>
#endif
#include "RNA_access.h"
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 05d6b981dc1..ed1e2fe1c19 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,96 @@ 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.
+ *
+ * WARNING! This function will not handle ID user count!
*
- * 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.
+ * \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);
- }
+ 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;
-
- 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) {
+ 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 (bNode *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 (bNode *node_dst = ntree_dst->nodes.first, *node_src = ntree_src->nodes.first; node_dst; node_dst = node_dst->next, node_src = node_src->next) {
+ if (node_dst->parent) {
+ node_dst->parent = node_dst->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 +1991,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) {
@@ -2277,7 +2275,7 @@ StructRNA *ntreeInterfaceTypeGet(bNodeTree *ntree, int create)
/* rename the RNA type */
RNA_def_struct_free_pointers(srna);
- RNA_def_struct_identifier(srna, identifier);
+ RNA_def_struct_identifier(&BLENDER_RNA, srna, identifier);
RNA_def_struct_ui_text(srna, name, description);
RNA_def_struct_duplicate_pointers(srna);
}
@@ -3596,12 +3594,10 @@ static void registerShaderNodes(void)
register_node_type_sh_add_shader();
register_node_type_sh_uvmap();
register_node_type_sh_uvalongstroke();
- register_node_type_sh_eevee_metallic();
register_node_type_sh_eevee_specular();
register_node_type_sh_output_lamp();
register_node_type_sh_output_material();
- register_node_type_sh_output_eevee_material();
register_node_type_sh_output_world();
register_node_type_sh_output_linestyle();
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index d7c60f67c05..07de120ff48 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? */
}
@@ -337,14 +337,14 @@ void BKE_object_free_derived_caches(Object *ob)
Mesh *me = ob->data;
if (me && me->bb) {
- atomic_fetch_and_or_uint32((uint*)&me->bb->flag, BOUNDBOX_DIRTY);
+ atomic_fetch_and_or_uint32((uint *)&me->bb->flag, BOUNDBOX_DIRTY);
}
}
else if (ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
Curve *cu = ob->data;
if (cu && cu->bb) {
- atomic_fetch_and_or_uint32((uint*)&cu->bb->flag, BOUNDBOX_DIRTY);
+ atomic_fetch_and_or_uint32((uint *)&cu->bb->flag, BOUNDBOX_DIRTY);
}
}
@@ -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;
@@ -834,7 +834,7 @@ static LodLevel *lod_level_select(Object *ob, const float camera_position[3])
bool BKE_object_lod_is_usable(Object *ob, SceneLayer *sl)
{
- bool active = (sl) ? ob == OBACT_NEW : false;
+ bool active = (sl) ? ob == OBACT_NEW(sl) : false;
return (ob->mode == OB_MODE_OBJECT || !active);
}
@@ -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;
}
@@ -988,7 +988,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 */
@@ -996,12 +997,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;
@@ -1013,7 +1016,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);
@@ -1050,23 +1053,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};
@@ -1087,13 +1092,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;
}
@@ -1138,100 +1140,101 @@ 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);
- BKE_object_facemap_copy_list(&obn->fmaps, &ob->fmaps);
- BKE_constraints_copy(&obn->constraints, &ob->constraints, true);
+ defgroup_copy_list(&ob_dst->defbase, &ob_src->defbase);
+ BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps);
+ BKE_constraints_copy_ex(&ob_dst->constraints, &ob_src->constraints, flag_subdata, true);
- 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->drawdata);
+ 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)
@@ -1307,10 +1310,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)
@@ -1429,7 +1432,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 */
@@ -2102,8 +2105,9 @@ static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat
}
/* note, scene is the active scene while actual_scene is the scene the object resides in */
-void BKE_object_where_is_calc_time_ex(EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime,
- RigidBodyWorld *rbw, float r_originmat[3][3])
+void BKE_object_where_is_calc_time_ex(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime,
+ RigidBodyWorld *rbw, float r_originmat[3][3])
{
if (ob == NULL) return;
@@ -2147,7 +2151,7 @@ void BKE_object_where_is_calc_time_ex(EvaluationContext *eval_ctx, Scene *scene,
else ob->transflag &= ~OB_NEG_SCALE;
}
-void BKE_object_where_is_calc_time(EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime)
+void BKE_object_where_is_calc_time(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime)
{
BKE_object_where_is_calc_time_ex(eval_ctx, scene, ob, ctime, NULL, NULL);
}
@@ -2174,17 +2178,17 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
}
}
-void BKE_object_where_is_calc_ex(EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3])
+void BKE_object_where_is_calc_ex(const EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3])
{
BKE_object_where_is_calc_time_ex(eval_ctx, scene, ob, BKE_scene_frame_get(scene), rbw, r_originmat);
}
-void BKE_object_where_is_calc(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void BKE_object_where_is_calc(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
BKE_object_where_is_calc_time_ex(eval_ctx, scene, ob, BKE_scene_frame_get(scene), NULL, NULL);
}
/* for calculation of the inverse parent transform, only used for editor */
-void BKE_object_workob_calc_parent(EvaluationContext *eval_ctx, Scene *scene, Object *ob, Object *workob)
+void BKE_object_workob_calc_parent(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, Object *workob)
{
BKE_object_workob_clear(workob);
@@ -2537,7 +2541,7 @@ void BKE_scene_foreach_display_point(
Base *base;
Object *ob;
- for (base = FIRSTBASE_NEW; base; base = base->next) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
if (((base->flag & BASE_VISIBLED) != 0) && ((base->flag & BASE_SELECTED) != 0)) {
ob = base->object;
@@ -2636,7 +2640,7 @@ bool BKE_object_parent_loop_check(const Object *par, const Object *ob)
/* the main object update call, for object matrix, constraints, keys and displist (modifiers) */
/* requires flags to be set! */
/* Ideally we shouldn't have to pass the rigid body world, but need bigger restructuring to avoid id */
-void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
+void BKE_object_handle_update_ex(const EvaluationContext *eval_ctx,
Scene *scene, Object *ob,
RigidBodyWorld *rbw,
const bool do_proxy_update)
@@ -2715,7 +2719,7 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
* e.g. "scene" <-- set 1 <-- set 2 ("ob" lives here) <-- set 3 <-- ... <-- set n
* rigid bodies depend on their world so use BKE_object_handle_update_ex() to also pass along the corrent rigid body world
*/
-void BKE_object_handle_update(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void BKE_object_handle_update(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
BKE_object_handle_update_ex(eval_ctx, scene, ob, NULL, true);
}
@@ -3631,9 +3635,9 @@ static void object_cacheIgnoreClear(Object *ob, int state)
/* Note: this function should eventually be replaced by depsgraph functionality.
* Avoid calling this in new code unless there is a very good reason for it!
*/
-bool BKE_object_modifier_update_subframe(EvaluationContext *eval_ctx, Scene *scene, Object *ob, bool update_mesh,
- int parent_recursion, float frame,
- int type)
+bool BKE_object_modifier_update_subframe(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, bool update_mesh,
+ int parent_recursion, float frame, int type)
{
ModifierData *md = modifiers_findByType(ob, (ModifierType)type);
bConstraint *con;
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 66cacd67a85..c25207d81bf 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -69,7 +69,7 @@
/* Dupli-Geometry */
typedef struct DupliContext {
- EvaluationContext *eval_ctx;
+ const EvaluationContext *eval_ctx;
bool do_update;
bool animated;
Group *group; /* XXX child objects are selected from this group if set, could be nicer */
@@ -95,7 +95,7 @@ typedef struct DupliGenerator {
static const DupliGenerator *get_dupli_generator(const DupliContext *ctx);
/* create initial context for root object */
-static void init_context(DupliContext *r_ctx, EvaluationContext *eval_ctx, Scene *scene, Object *ob, float space_mat[4][4], bool update)
+static void init_context(DupliContext *r_ctx, const EvaluationContext *eval_ctx, Scene *scene, Object *ob, float space_mat[4][4], bool update)
{
r_ctx->eval_ctx = eval_ctx;
r_ctx->scene = scene;
@@ -1216,7 +1216,7 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
/* ---- ListBase dupli container implementation ---- */
/* Returns a list of DupliObject */
-ListBase *object_duplilist_ex(EvaluationContext *eval_ctx, Scene *scene, Object *ob, bool update)
+ListBase *object_duplilist_ex(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, bool update)
{
ListBase *duplilist = MEM_callocN(sizeof(ListBase), "duplilist");
DupliContext ctx;
@@ -1231,7 +1231,7 @@ ListBase *object_duplilist_ex(EvaluationContext *eval_ctx, Scene *scene, Object
/* note: previously updating was always done, this is why it defaults to be on
* but there are likely places it can be called without updating */
-ListBase *object_duplilist(EvaluationContext *eval_ctx, Scene *sce, Object *ob)
+ListBase *object_duplilist(const EvaluationContext *eval_ctx, Scene *sce, Object *ob)
{
return object_duplilist_ex(eval_ctx, sce, ob, true);
}
@@ -1272,7 +1272,7 @@ int count_duplilist(Object *ob)
return 1;
}
-DupliApplyData *duplilist_apply(EvaluationContext *eval_ctx, Object *ob, Scene *scene, ListBase *duplilist)
+DupliApplyData *duplilist_apply(const EvaluationContext *eval_ctx, Object *ob, Scene *scene, ListBase *duplilist)
{
DupliApplyData *apply_data = NULL;
int num_objects = BLI_listbase_count(duplilist);
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 0bbfbb8a4e7..c5d267ace9d 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -69,7 +69,7 @@
static ThreadMutex material_lock = BLI_MUTEX_INITIALIZER;
-void BKE_object_eval_local_transform(EvaluationContext *UNUSED(eval_ctx),
+void BKE_object_eval_local_transform(const EvaluationContext *UNUSED(eval_ctx),
Scene *UNUSED(scene),
Object *ob)
{
@@ -81,7 +81,7 @@ void BKE_object_eval_local_transform(EvaluationContext *UNUSED(eval_ctx),
/* Evaluate parent */
/* NOTE: based on solve_parenting(), but with the cruft stripped out */
-void BKE_object_eval_parent(EvaluationContext *UNUSED(eval_ctx),
+void BKE_object_eval_parent(const EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob)
{
@@ -113,7 +113,7 @@ void BKE_object_eval_parent(EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_object_eval_constraints(EvaluationContext *eval_ctx,
+void BKE_object_eval_constraints(const EvaluationContext *eval_ctx,
Scene *scene,
Object *ob)
{
@@ -136,7 +136,7 @@ void BKE_object_eval_constraints(EvaluationContext *eval_ctx,
BKE_constraints_clear_evalob(cob);
}
-void BKE_object_eval_done(EvaluationContext *UNUSED(eval_ctx), Object *ob)
+void BKE_object_eval_done(const EvaluationContext *UNUSED(eval_ctx), Object *ob)
{
DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);
@@ -145,9 +145,10 @@ void BKE_object_eval_done(EvaluationContext *UNUSED(eval_ctx), Object *ob)
else ob->transflag &= ~OB_NEG_SCALE;
}
-void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
- Scene *scene,
- Object *ob)
+void BKE_object_handle_data_update(
+ const EvaluationContext *eval_ctx,
+ Scene *scene,
+ Object *ob)
{
ID *data_id = (ID *)ob->data;
AnimData *adt = BKE_animdata_from_id(data_id);
@@ -296,7 +297,7 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
/* quick cache removed */
}
-void BKE_object_eval_uber_transform(EvaluationContext *UNUSED(eval_ctx),
+void BKE_object_eval_uber_transform(const EvaluationContext *UNUSED(eval_ctx),
Scene *UNUSED(scene),
Object *ob)
{
@@ -326,7 +327,7 @@ void BKE_object_eval_uber_transform(EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_object_eval_uber_data(EvaluationContext *eval_ctx,
+void BKE_object_eval_uber_data(const EvaluationContext *eval_ctx,
Scene *scene,
Object *ob)
{
@@ -401,13 +402,13 @@ void BKE_object_eval_uber_data(EvaluationContext *eval_ctx,
ob->recalc &= ~(OB_RECALC_DATA | OB_RECALC_TIME);
}
-void BKE_object_eval_cloth(EvaluationContext *UNUSED(eval_ctx), Scene *scene, Object *object)
+void BKE_object_eval_cloth(const EvaluationContext *UNUSED(eval_ctx), Scene *scene, Object *object)
{
DEBUG_PRINT("%s on %s\n", __func__, object->id.name);
BKE_ptcache_object_reset(scene, object, PTCACHE_RESET_DEPSGRAPH);
}
-void BKE_object_eval_update_shading(EvaluationContext *UNUSED(eval_ctx), Object *object)
+void BKE_object_eval_update_shading(const EvaluationContext *UNUSED(eval_ctx), Object *object)
{
DEBUG_PRINT("%s on %s\n", __func__, object->id.name);
if (object->type == OB_MESH) {
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index eebe514c7ca..81b26f13a9f 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])
@@ -694,7 +711,7 @@ void BKE_sculptsession_bm_to_me_for_render(Object *object)
if (object->sculpt->bm) {
/* Ensure no points to old arrays are stored in DM
*
- * Apparently, we could not use DAG_id_tag_update
+ * Apparently, we could not use DEG_id_tag_update
* here because this will lead to the while object
* surface to disappear, so we'll release DM in place.
*/
@@ -823,8 +840,9 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
/**
* \param need_mask So the DerivedMesh thats returned has mask data
*/
-void BKE_sculpt_update_mesh_elements(EvaluationContext *eval_ctx, Scene *scene, Sculpt *sd, Object *ob,
- bool need_pmap, bool need_mask)
+void BKE_sculpt_update_mesh_elements(
+ const EvaluationContext *eval_ctx, Scene *scene, Sculpt *sd, Object *ob,
+ bool need_pmap, bool need_mask)
{
DerivedMesh *dm;
SculptSession *ss = ob->sculpt;
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index baa4214123e..79c4ad6e618 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1856,7 +1856,7 @@ void precalc_guides(ParticleSimulationData *sim, ListBase *effectors)
}
}
-int do_guides(EvaluationContext *eval_ctx, ParticleSettings *part, ListBase *effectors, ParticleKey *state, int index, float time)
+int do_guides(const EvaluationContext *eval_ctx, ParticleSettings *part, ListBase *effectors, ParticleKey *state, int index, float time)
{
CurveMapping *clumpcurve = (part->child_flag & PART_CHILD_USE_CLUMP_CURVE) ? part->clumpcurve : NULL;
CurveMapping *roughcurve = (part->child_flag & PART_CHILD_USE_ROUGH_CURVE) ? part->roughcurve : NULL;
@@ -2768,7 +2768,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
if (vg_length)
MEM_freeN(vg_length);
}
-void psys_cache_edit_paths(EvaluationContext *eval_ctx, Scene *scene, Object *ob, PTCacheEdit *edit, float cfra, const bool use_render_params)
+void psys_cache_edit_paths(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, PTCacheEdit *edit, float cfra, const bool use_render_params)
{
ParticleCacheKey *ca, **cache = edit->pathcache;
ParticleEditSettings *pset = &scene->toolsettings->particle;
@@ -3317,7 +3317,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);
@@ -3348,38 +3348,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)
@@ -4318,7 +4325,7 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3]
madd_v3_v3fl(center, yvec, bb->offset[1]);
}
-void psys_apply_hair_lattice(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys)
+void psys_apply_hair_lattice(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys)
{
ParticleSimulationData sim = {0};
sim.eval_ctx = eval_ctx;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 044f52832e6..0591ea073cc 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -980,7 +980,7 @@ void psys_get_birth_coords(ParticleSimulationData *sim, ParticleData *pa, Partic
}
/* recursively evaluate emitter parent anim at cfra */
-static void evaluate_emitter_anim(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float cfra)
+static void evaluate_emitter_anim(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float cfra)
{
if (ob->parent)
evaluate_emitter_anim(eval_ctx, scene, ob->parent, cfra);
@@ -4158,7 +4158,7 @@ static int hair_needs_recalc(ParticleSystem *psys)
/* main particle update call, checks that things are ok on the large scale and
* then advances in to actual particle calculations depending on particle type */
-void particle_system_update(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys, const bool use_render_params)
+void particle_system_update(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys, const bool use_render_params)
{
ParticleSimulationData sim= {0};
ParticleSettings *part = psys->part;
@@ -4361,7 +4361,7 @@ void BKE_particlesystem_id_loop(ParticleSystem *psys, ParticleSystemIDFunc func,
/* **** Depsgraph evaluation **** */
-void BKE_particle_system_settings_eval(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_particle_system_settings_eval(const struct EvaluationContext *UNUSED(eval_ctx),
ParticleSystem *psys)
{
if (G.debug & G_DEBUG_DEPSGRAPH) {
@@ -4379,7 +4379,7 @@ void BKE_particle_system_settings_recalc_clear(struct EvaluationContext *UNUSED(
particle_settings->recalc = 0;
}
-void BKE_particle_system_eval_init(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_particle_system_eval_init(const struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob)
{
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..df048ce5036 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;
@@ -290,8 +290,6 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
if (dm == NULL)
return NULL;
- DM_ensure_looptri(dm);
-
mvert = dm->getVertArray(dm);
totvert = dm->getNumVerts(dm);
looptri = dm->getLoopTriArray(dm);
@@ -523,8 +521,6 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
if (dm == NULL)
return;
- DM_ensure_looptri(dm);
-
mvert = dm->getVertArray(dm);
totvert = dm->getNumVerts(dm);
lt = dm->getLoopTriArray(dm);
@@ -608,8 +604,6 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
if (dm == NULL)
return;
- DM_ensure_looptri(dm);
-
mvert = dm->getVertArray(dm);
totvert = dm->getNumVerts(dm);
looptri = dm->getLoopTriArray(dm);
@@ -944,24 +938,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)
@@ -1226,7 +1222,7 @@ static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw)
rigidbody_update_ob_array(rbw);
}
-static void rigidbody_update_sim_ob(struct EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo)
+static void rigidbody_update_sim_ob(const struct EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo)
{
float loc[3];
float rot[4];
@@ -1315,7 +1311,7 @@ static void rigidbody_update_sim_ob(struct EvaluationContext *eval_ctx, Scene *s
*
* \param rebuild Rebuild entire simulation
*/
-static void rigidbody_update_simulation(struct EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, bool rebuild)
+static void rigidbody_update_simulation(const struct EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, bool rebuild)
{
GroupObject *go;
@@ -1559,7 +1555,7 @@ void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
/* Rebuild rigid body world */
/* NOTE: this needs to be called before frame update to work correctly */
-void BKE_rigidbody_rebuild_world(struct EvaluationContext *eval_ctx, Scene *scene, float ctime)
+void BKE_rigidbody_rebuild_world(const struct EvaluationContext *eval_ctx, Scene *scene, float ctime)
{
RigidBodyWorld *rbw = scene->rigidbody_world;
PointCache *cache;
@@ -1587,7 +1583,7 @@ void BKE_rigidbody_rebuild_world(struct EvaluationContext *eval_ctx, Scene *scen
}
/* Run RigidBody simulation for the specified physics world */
-void BKE_rigidbody_do_simulation(struct EvaluationContext *eval_ctx, Scene *scene, float ctime)
+void BKE_rigidbody_do_simulation(const struct EvaluationContext *eval_ctx, Scene *scene, float ctime)
{
float timestep;
RigidBodyWorld *rbw = scene->rigidbody_world;
@@ -1657,13 +1653,13 @@ void BKE_rigidbody_do_simulation(struct EvaluationContext *eval_ctx, Scene *scen
# pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
-struct RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob) { return NULL; }
-struct RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob) { return NULL; }
+struct RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int flag) { return NULL; }
+struct RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob, const int flag) { return NULL; }
void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild) {}
void BKE_rigidbody_calc_volume(Object *ob, float *r_vol) { if (r_vol) *r_vol = 0.0f; }
void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3]) { zero_v3(r_center); }
struct RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene) { return NULL; }
-struct RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw) { return NULL; }
+struct RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag) { return NULL; }
void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw) {}
void BKE_rigidbody_world_id_loop(struct RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata) {}
struct RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type) { return NULL; }
@@ -1675,8 +1671,8 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {}
bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) { return false; }
void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
-void BKE_rigidbody_rebuild_world(struct EvaluationContext *eval_ctx, Scene *scene, float ctime) {}
-void BKE_rigidbody_do_simulation(struct EvaluationContext *eval_ctx, Scene *scene, float ctime) {}
+void BKE_rigidbody_rebuild_world(const struct EvaluationContext *eval_ctx, Scene *scene, float ctime) {}
+void BKE_rigidbody_do_simulation(const struct EvaluationContext *eval_ctx, Scene *scene, float ctime) {}
#ifdef __GNUC__
# pragma GCC diagnostic pop
@@ -1687,7 +1683,7 @@ void BKE_rigidbody_do_simulation(struct EvaluationContext *eval_ctx, Scene *scen
/* -------------------- */
/* Depsgraph evaluation */
-void BKE_rigidbody_rebuild_sim(struct EvaluationContext *eval_ctx,
+void BKE_rigidbody_rebuild_sim(const struct EvaluationContext *eval_ctx,
Scene *scene)
{
float ctime = BKE_scene_frame_get(scene);
@@ -1702,7 +1698,7 @@ void BKE_rigidbody_rebuild_sim(struct EvaluationContext *eval_ctx,
}
}
-void BKE_rigidbody_eval_simulation(struct EvaluationContext *eval_ctx,
+void BKE_rigidbody_eval_simulation(const struct EvaluationContext *eval_ctx,
Scene *scene)
{
float ctime = BKE_scene_frame_get(scene);
@@ -1717,7 +1713,7 @@ void BKE_rigidbody_eval_simulation(struct EvaluationContext *eval_ctx,
}
}
-void BKE_rigidbody_object_sync_transforms(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_rigidbody_object_sync_transforms(const struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob)
{
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 eada47fbb5f..b380a98932d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -161,324 +161,438 @@ static void remove_sequencer_fcurves(Scene *sce)
}
/* copy SceneCollection tree but keep pointing to the same objects */
-static void scene_collection_copy(SceneCollection *scn, SceneCollection *sc)
+static void scene_collection_copy(SceneCollection *sc_dst, SceneCollection *sc_src, const int flag)
{
- BLI_duplicatelist(&scn->objects, &sc->objects);
- for (LinkData *link = scn->objects.first; link; link = link->next) {
- id_us_plus(link->data);
+ BLI_duplicatelist(&sc_dst->objects, &sc_src->objects);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ for (LinkData *link = sc_dst->objects.first; link; link = link->next) {
+ id_us_plus(link->data);
+ }
}
- BLI_duplicatelist(&scn->filter_objects, &sc->filter_objects);
- for (LinkData *link = scn->filter_objects.first; link; link = link->next) {
- id_us_plus(link->data);
+ BLI_duplicatelist(&sc_dst->filter_objects, &sc_src->filter_objects);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ for (LinkData *link = sc_dst->filter_objects.first; link; link = link->next) {
+ id_us_plus(link->data);
+ }
}
- BLI_duplicatelist(&scn->scene_collections, &sc->scene_collections);
- SceneCollection *nscn = scn->scene_collections.first; /* nested SceneCollection new */
- for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
- scene_collection_copy(nscn, nsc);
- nscn = nscn->next;
+ BLI_duplicatelist(&sc_dst->scene_collections, &sc_src->scene_collections);
+ for (SceneCollection *nsc_src = sc_src->scene_collections.first, *nsc_dst = sc_dst->scene_collections.first;
+ nsc_src;
+ nsc_src = nsc_src->next, nsc_dst = nsc_dst->next) {
+ scene_collection_copy(nsc_dst, nsc_src, flag);
}
}
/* Find the equivalent SceneCollection in the new tree */
-static SceneCollection *scene_collection_from_new_tree(SceneCollection *sc_reference, SceneCollection *scn, SceneCollection *sc)
+static SceneCollection *scene_collection_from_new_tree(SceneCollection *sc_reference, SceneCollection *sc_dst, SceneCollection *sc_src)
{
- if (sc == sc_reference) {
- return scn;
+ if (sc_src == sc_reference) {
+ return sc_dst;
}
- SceneCollection *nscn = scn->scene_collections.first; /* nested master collection new */
- for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
-
- SceneCollection *found = scene_collection_from_new_tree(sc_reference, nscn, nsc);
- if (found) {
+ for (SceneCollection *nsc_src = sc_src->scene_collections.first, *nsc_dst = sc_dst->scene_collections.first;
+ nsc_src;
+ nsc_src = nsc_src->next, nsc_dst = nsc_dst->next)
+ {
+ SceneCollection *found = scene_collection_from_new_tree(sc_reference, nsc_dst, nsc_src);
+ if (found != NULL) {
return found;
}
- nscn = nscn->next;
}
return NULL;
}
-/* recreate the LayerCollection tree */
-static void layer_collections_recreate(SceneLayer *sl, ListBase *lb, SceneCollection *mcn, SceneCollection *mc)
+static void layer_collections_sync_flags(ListBase *layer_collections_dst, const ListBase *layer_collections_src)
{
- for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ LayerCollection *layer_collection_dst = (LayerCollection *)layer_collections_dst->first;
+ const LayerCollection *layer_collection_src = (const LayerCollection *)layer_collections_src->first;
+ while (layer_collection_dst != NULL) {
+ layer_collection_dst->flag = layer_collection_src->flag;
+ layer_collections_sync_flags(&layer_collection_dst->layer_collections,
+ &layer_collection_src->layer_collections);
+ /* TODO(sergey/dfelinto): Overrides. */
+ layer_collection_dst = layer_collection_dst->next;
+ layer_collection_src = layer_collection_src->next;
+ }
+}
+
- SceneCollection *sc = scene_collection_from_new_tree(lc->scene_collection, mcn, mc);
- BLI_assert(sc);
+/* recreate the LayerCollection tree */
+static void layer_collections_recreate(
+ SceneLayer *sl_dst, ListBase *lb_src, SceneCollection *mc_dst, SceneCollection *mc_src)
+{
+ for (LayerCollection *lc_src = lb_src->first; lc_src; lc_src = lc_src->next) {
+ SceneCollection *sc_dst = scene_collection_from_new_tree(lc_src->scene_collection, mc_dst, mc_src);
+ BLI_assert(sc_dst);
- /* instead of syncronizing both trees we simply re-create it */
- BKE_collection_link(sl, sc);
+ /* instead of synchronizing both trees we simply re-create it */
+ BKE_collection_link(sl_dst, sc_dst);
}
}
-Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
+/**
+ * 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)
{
- 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;
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
- if (sce->id.properties)
- scen->id.properties = IDP_CopyProperty(sce->id.properties);
+ sce_dst->ed = NULL;
+ sce_dst->theDag = NULL;
+ sce_dst->depsgraph_legacy = NULL;
+ sce_dst->obedit = NULL;
+ sce_dst->fps_info = NULL;
- 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);
+ 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 *mc_src = BKE_collection_master(sce_src);
+ SceneCollection *mc_dst = BKE_collection_master(sce_dst);
- 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(mc_dst, mc_src, flag_subdata);
- 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);
+ for (SceneLayer *sl_src = sce_src->render_layers.first, *sl_dst = sce_dst->render_layers.first;
+ sl_src;
+ sl_src = sl_src->next, sl_dst = sl_dst->next)
+ {
+ sl_dst->stats = NULL;
+ sl_dst->properties_evaluated = NULL;
+ sl_dst->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ IDP_MergeGroup_ex(sl_dst->properties, sl_src->properties, true, flag_subdata);
+
+ /* 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(&sl_dst->layer_collections);
+ BLI_listbase_clear(&sl_dst->object_bases);
+ BLI_listbase_clear(&sl_dst->drawdata);
+
+ layer_collections_recreate(sl_dst, &sl_src->layer_collections, mc_dst, mc_src);
+
+ /* Now we handle the syncing for visibility, selectability, ... */
+ layer_collections_sync_flags(&sl_dst->layer_collections, &sl_src->layer_collections);
+
+ Object *active_ob = OBACT_NEW(sl_src);
+ for (Base *base_src = sl_src->object_bases.first, *base_dst = sl_dst->object_bases.first;
+ base_src;
+ base_src = base_src->next, base_dst = base_dst->next)
+ {
+ base_dst->flag = base_src->flag;
+ base_dst->flag_legacy = base_src->flag_legacy;
- 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;
+ if (base_dst->object == active_ob) {
+ sl_dst->basact = base_dst;
+ }
}
+ }
- /* 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);
+ if (sce_src->collection_properties) {
+ IDP_MergeGroup_ex(sce_dst->collection_properties, sce_src->collection_properties, true, flag_subdata);
+ }
+ sce_dst->layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ if (sce_src->layer_properties) {
+ IDP_MergeGroup_ex(sce_dst->layer_properties, sce_src->layer_properties, true, flag_subdata);
+ }
- 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);
+ /* camera */
+ if (ELEM(type, SCE_COPY_LINK_DATA, SCE_COPY_FULL)) {
+ ID_NEW_REMAP(sce_copy->camera);
}
- if (sce->layer_properties) {
- IDP_MergeGroup(scen->layer_properties, sce->layer_properties, true);
- }
- }
- return scen;
+ return sce_copy;
+ }
}
void BKE_scene_groups_relink(Scene *sce)
@@ -549,7 +663,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);
@@ -720,7 +834,7 @@ void BKE_scene_init(Scene *sce)
sce->r.seq_prev_type = OB_SOLID;
sce->r.seq_rend_type = OB_SOLID;
- sce->r.seq_flag = R_SEQ_GL_PREV;
+ sce->r.seq_flag = 0;
sce->r.threads = 1;
@@ -999,7 +1113,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);
@@ -1089,8 +1203,9 @@ Scene *BKE_scene_set_name(Main *bmain, const char *name)
}
/* Used by metaballs, return *all* objects (including duplis) existing in the scene (including scene's sets) */
-int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
- Scene **scene, int val, BaseLegacy **base, Object **ob)
+int BKE_scene_base_iter_next(
+ const EvaluationContext *eval_ctx, SceneBaseIter *iter,
+ Scene **scene, int val, BaseLegacy **base, Object **ob)
{
bool run_again = true;
@@ -1586,7 +1701,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... */
@@ -1950,6 +2065,14 @@ int BKE_scene_num_threads(const Scene *scene)
return BKE_render_num_threads(&scene->r);
}
+int BKE_render_preview_pixel_size(const RenderData *r)
+{
+ if (r->preview_pixel_size == 0) {
+ return (U.pixelsize > 1.5f)? 2 : 1;
+ }
+ return r->preview_pixel_size;
+}
+
/* Apply the needed correction factor to value, based on unit_type (only length-related are affected currently)
* and unit->scale_length.
*/
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index a07abe166f0..6bd88099792 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -185,6 +185,7 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
newar->swinid = 0;
newar->manipulator_map = NULL;
newar->regiontimer = NULL;
+ newar->headerstr = NULL;
/* use optional regiondata callback */
if (ar->regiondata) {
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 0c384f8b8c8..18c721c8e3f 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -91,7 +91,7 @@
#include "BKE_sound.h"
#ifdef WITH_AUDASPACE
-# include AUD_SPECIAL_H
+# include <AUD_Special.h>
#endif
/* mutable state for sequencer */
@@ -3235,7 +3235,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
const bool is_background = G.background;
const bool do_seq_gl = is_rendering ?
0 /* (context->scene->r.seq_flag & R_SEQ_GL_REND) */ :
- (context->scene->r.seq_flag & R_SEQ_GL_PREV) != 0;
+ (context->scene->r.seq_prev_type) != OB_RENDER;
// bool have_seq = false; /* UNUSED */
bool have_comp = false;
bool use_gpencil = true;
@@ -5373,9 +5373,8 @@ 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(const Scene *scene_src, Scene *scene_dst, Sequence *seq, int dupe_flag, const int flag)
{
- Scene *sce_audio = scene_to ? scene_to : scene;
Sequence *seqn = MEM_dupallocN(seq);
seq->tmp = seqn;
@@ -5399,7 +5398,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) {
@@ -5418,7 +5417,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
else if (seq->type == SEQ_TYPE_SCENE) {
seqn->strip->stripdata = NULL;
if (seq->scene_sound)
- seqn->scene_sound = BKE_sound_scene_add_scene_sound_defaults(sce_audio, seqn);
+ seqn->scene_sound = BKE_sound_scene_add_scene_sound_defaults(scene_dst, seqn);
}
else if (seq->type == SEQ_TYPE_MOVIECLIP) {
/* avoid assert */
@@ -5435,9 +5434,11 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
seqn->strip->stripdata =
MEM_dupallocN(seq->strip->stripdata);
if (seq->scene_sound)
- seqn->scene_sound = BKE_sound_add_scene_sound_defaults(sce_audio, seqn);
+ seqn->scene_sound = BKE_sound_add_scene_sound_defaults(scene_dst, 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 =
@@ -5457,11 +5458,15 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
BLI_assert(0);
}
- if (dupe_flag & SEQ_DUPE_UNIQUE_NAME)
- BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqn);
+ if (scene_src == scene_dst) {
+ if (dupe_flag & SEQ_DUPE_UNIQUE_NAME) {
+ BKE_sequence_base_unique_name_recursive(&scene_dst->ed->seqbase, seqn);
+ }
- if (dupe_flag & SEQ_DUPE_ANIM)
- BKE_sequencer_dupe_animdata(scene, seq->name + 2, seqn->name + 2);
+ if (dupe_flag & SEQ_DUPE_ANIM) {
+ BKE_sequencer_dupe_animdata(scene_dst, seq->name + 2, seqn->name + 2);
+ }
+ }
return seqn;
}
@@ -5488,16 +5493,16 @@ static void seq_new_fix_links_recursive(Sequence *seq)
}
}
-Sequence *BKE_sequence_dupli_recursive(Scene *scene, Scene *scene_to, Sequence *seq, int dupe_flag)
+Sequence *BKE_sequence_dupli_recursive(const Scene *scene_src, Scene *scene_dst, Sequence *seq, int dupe_flag)
{
Sequence *seqn;
seq->tmp = NULL;
- seqn = seq_dupli(scene, scene_to, seq, dupe_flag);
+ seqn = seq_dupli(scene_src, scene_dst, seq, dupe_flag, 0);
if (seq->type == SEQ_TYPE_META) {
Sequence *s;
for (s = seq->seqbase.first; s; s = s->next) {
- Sequence *n = BKE_sequence_dupli_recursive(scene, scene_to, s, dupe_flag);
+ Sequence *n = BKE_sequence_dupli_recursive(scene_src, scene_dst, s, dupe_flag);
if (n) {
BLI_addtail(&seqn->seqbase, n);
}
@@ -5510,19 +5515,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_src, Scene *scene_dst, 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_src);
/* 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_src, scene_dst, seq, dupe_flag, flag);
if (seqn) { /*should never fail */
if (dupe_flag & SEQ_DUPE_CONTEXT) {
seq->flag &= ~SEQ_ALLSEL;
@@ -5532,13 +5537,13 @@ void BKE_sequence_base_dupli_recursive(
BLI_addtail(nseqbase, seqn);
if (seq->type == SEQ_TYPE_META) {
BKE_sequence_base_dupli_recursive(
- scene, scene_to, &seqn->seqbase, &seq->seqbase,
- dupe_flag_recursive);
+ scene_src, scene_dst, &seqn->seqbase, &seq->seqbase,
+ 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_dst, seqn);
}
}
}
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 664305ac715..218ac64f3e0 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -128,7 +128,7 @@ void smoke_initWaveletBlenderRNA(struct WTURBULENCE *UNUSED(wt), float *UNUSED(s
void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity),
int *UNUSED(border_colli), float *UNUSED(burning_rate), float *UNUSED(flame_smoke), float *UNUSED(flame_smoke_color),
float *UNUSED(flame_vorticity), float *UNUSED(flame_ignition_temp), float *UNUSED(flame_max_temp)) {}
-struct DerivedMesh *smokeModifier_do(SmokeModifierData *UNUSED(smd), struct EvaluationContext *UNUSED(eval_ctx), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) { return NULL; }
+struct DerivedMesh *smokeModifier_do(SmokeModifierData *UNUSED(smd), const struct EvaluationContext *UNUSED(eval_ctx), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) { return NULL; }
float smoke_get_velocity_at(struct Object *UNUSED(ob), float UNUSED(position[3]), float UNUSED(velocity[3])) { return 0.0f; }
#endif /* WITH_SMOKE */
@@ -704,7 +704,7 @@ static int get_lamp(SceneLayer *sl, float *light)
int found_lamp = 0;
// try to find a lamp, preferably local
- for (base_tmp = FIRSTBASE_NEW; base_tmp; base_tmp = base_tmp->next) {
+ for (base_tmp = FIRSTBASE_NEW(sl); base_tmp; base_tmp = base_tmp->next) {
if (base_tmp->object->type == OB_LAMP) {
Lamp *la = base_tmp->object->data;
@@ -2073,7 +2073,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value
}
}
-static void update_flowsfluids(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt)
+static void update_flowsfluids(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt)
{
Object **flowobjs = NULL;
EmissionMap *emaps = NULL;
@@ -2489,7 +2489,7 @@ static void update_effectors_task_cb(void *userdata, const int x)
}
}
-static void update_effectors(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeDomainSettings *sds, float UNUSED(dt))
+static void update_effectors(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeDomainSettings *sds, float UNUSED(dt))
{
ListBase *effectors;
/* make sure smoke flow influence is 0.0f */
@@ -2518,7 +2518,7 @@ static void update_effectors(struct EvaluationContext *eval_ctx, Scene *scene, O
pdEndEffectors(&effectors);
}
-static void step(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh *domain_dm, float fps)
+static void step(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh *domain_dm, float fps)
{
SmokeDomainSettings *sds = smd->domain;
/* stability values copied from wturbulence.cpp */
@@ -2685,7 +2685,8 @@ static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob)
return result;
}
-static void smokeModifier_process(SmokeModifierData *smd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm)
+static void smokeModifier_process(
+ SmokeModifierData *smd, const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm)
{
if ((smd->type & MOD_SMOKE_TYPE_FLOW))
{
@@ -2694,7 +2695,6 @@ static void smokeModifier_process(SmokeModifierData *smd, struct EvaluationConte
if (smd->flow->dm) smd->flow->dm->release(smd->flow->dm);
smd->flow->dm = CDDM_copy(dm);
- DM_ensure_looptri(smd->flow->dm);
if (scene->r.cfra > smd->time)
{
@@ -2717,7 +2717,6 @@ static void smokeModifier_process(SmokeModifierData *smd, struct EvaluationConte
smd->coll->dm->release(smd->coll->dm);
smd->coll->dm = CDDM_copy(dm);
- DM_ensure_looptri(smd->coll->dm);
}
smd->time = scene->r.cfra;
@@ -2829,7 +2828,8 @@ static void smokeModifier_process(SmokeModifierData *smd, struct EvaluationConte
}
}
-struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm)
+struct DerivedMesh *smokeModifier_do(
+ SmokeModifierData *smd, const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm)
{
/* lock so preview render does not read smoke data while it gets modified */
if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 4d8270568ba..7cea1e4940f 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -532,7 +532,7 @@ static void ccd_build_deflector_hash(SceneLayer *sl, Group *group, Object *verte
}
}
else {
- for (Base *base = FIRSTBASE_NEW; base; base = base->next) {
+ for (Base *base = FIRSTBASE_NEW(sl); base; base = base->next) {
/*Only proceed for mesh object in same layer */
if (base->object->type == OB_MESH) {
ob = base->object;
@@ -578,7 +578,7 @@ static void ccd_update_deflector_hash(SceneLayer *sl, Group *group, Object *vert
}
}
else {
- for (Base *base = FIRSTBASE_NEW; base; base = base->next) {
+ for (Base *base = FIRSTBASE_NEW(sl); base; base = base->next) {
/*Only proceed for mesh object in same layer */
if (base->object->type == OB_MESH) {
ob = base->object;
@@ -988,7 +988,7 @@ static bool are_there_deflectors(SceneLayer *sl, Group *group)
}
}
else {
- for (Base *base = FIRSTBASE_NEW; base; base = base->next) {
+ for (Base *base = FIRSTBASE_NEW(sl); base; base = base->next) {
if (base->object->pd) {
if (base->object->pd->deflect)
return 1;
@@ -1546,7 +1546,7 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
}
-static void scan_for_ext_spring_forces(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float timenow)
+static void scan_for_ext_spring_forces(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float timenow)
{
SoftBody *sb = ob->soft;
ListBase *do_effector = NULL;
@@ -1563,7 +1563,7 @@ static void *exec_scan_for_ext_spring_forces(void *data)
return NULL;
}
-static void sb_sfesf_threads_run(struct EvaluationContext *eval_ctx, Scene *scene, struct Object *ob, float timenow, int totsprings, int *UNUSED(ptr_to_break_func(void)))
+static void sb_sfesf_threads_run(const struct EvaluationContext *eval_ctx, Scene *scene, struct Object *ob, float timenow, int totsprings, int *UNUSED(ptr_to_break_func(void)))
{
ListBase *do_effector = NULL;
ListBase threads;
@@ -2235,7 +2235,7 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t
MEM_freeN(sb_threads);
}
-static void softbody_calc_forcesEx(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float forcetime, float timenow)
+static void softbody_calc_forcesEx(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float forcetime, float timenow)
{
/* rule we never alter free variables :bp->vec bp->pos in here !
* this will ruin adaptive stepsize AKA heun! (BM)
@@ -2280,7 +2280,7 @@ static void softbody_calc_forcesEx(struct EvaluationContext *eval_ctx, Scene *sc
}
-static void softbody_calc_forces(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float forcetime, float timenow)
+static void softbody_calc_forces(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float forcetime, float timenow)
{
/* redirection to the new threaded Version */
if (!(G.debug_value & 0x10)) { // 16
@@ -3512,7 +3512,7 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int
}
}
-static void softbody_step(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SoftBody *sb, float dtime)
+static void softbody_step(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SoftBody *sb, float dtime)
{
/* the simulator */
float forcetime;
@@ -3646,7 +3646,7 @@ static void softbody_step(struct EvaluationContext *eval_ctx, Scene *scene, Obje
}
/* simulates one step. framenr is in frames */
-void sbObjectStep(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], int numVerts)
+void sbObjectStep(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], int numVerts)
{
SoftBody *sb= ob->soft;
PointCache *cache;
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 8469351c54a..94fa81308fe 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -48,13 +48,11 @@
#include "DNA_speaker_types.h"
#ifdef WITH_AUDASPACE
-# include AUD_SOUND_H
-# include AUD_SEQUENCE_H
-# include AUD_HANDLE_H
-# include AUD_SPECIAL_H
-# ifdef WITH_SYSTEM_AUDASPACE
-# include "../../../intern/audaspace/intern/AUD_Set.h"
-# endif
+# include <AUD_Sound.h>
+# include <AUD_Sequence.h>
+# include <AUD_Handle.h>
+# include <AUD_Special.h>
+# include "../../../intern/audaspace/intern/AUD_Set.h"
#endif
#include "BKE_global.h"
@@ -83,7 +81,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 +153,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);
@@ -274,7 +300,6 @@ void BKE_sound_exit_once(void)
sound_device = NULL;
AUD_exitOnce();
-#ifdef WITH_SYSTEM_AUDASPACE
if (audio_device_names != NULL) {
int i;
for (i = 0; audio_device_names[i]; i++) {
@@ -283,7 +308,6 @@ void BKE_sound_exit_once(void)
free(audio_device_names);
audio_device_names = NULL;
}
-#endif
}
/* XXX unused currently */
@@ -879,28 +903,12 @@ float BKE_sound_get_length(bSound *sound)
char **BKE_sound_get_device_names(void)
{
if (audio_device_names == NULL) {
-#ifdef WITH_SYSTEM_AUDASPACE
audio_device_names = AUD_getDeviceNames();
-#else
- static const char *names[] = {
- "Null", "SDL", "OpenAL", "JACK", NULL
- };
- audio_device_names = (char **)names;
-#endif
}
return audio_device_names;
}
-bool BKE_sound_is_jack_supported(void)
-{
-#ifdef WITH_SYSTEM_AUDASPACE
- return 1;
-#else
- return (bool)AUD_isJackSupported();
-#endif
-}
-
#else /* WITH_AUDASPACE */
#include "BLI_utildefines.h"
@@ -947,5 +955,6 @@ void BKE_sound_set_scene_sound_pan(void *UNUSED(handle), float UNUSED(pan), char
void BKE_sound_set_scene_volume(struct Scene *UNUSED(scene), float UNUSED(volume)) {}
void BKE_sound_set_scene_sound_pitch(void *UNUSED(handle), float UNUSED(pitch), char UNUSED(animated)) {}
float BKE_sound_get_length(struct bSound *UNUSED(sound)) { return 0; }
-bool BKE_sound_is_jack_supported(void) { return false; }
+char **BKE_sound_get_device_names(void) { static char *names[1] = {NULL}; return names; }
+
#endif /* WITH_AUDASPACE */
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/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 1f72744bdee..d4280205cfb 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -4220,10 +4220,10 @@ static void ccgDM_recalcTessellation(DerivedMesh *UNUSED(dm))
/* Nothing to do: CCG handles creating its own tessfaces */
}
+/* WARNING! *MUST* be called in an 'loops_cache_rwlock' protected thread context! */
static void ccgDM_recalcLoopTri(DerivedMesh *dm)
{
- BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE);
- MLoopTri *mlooptri;
+ MLoopTri *mlooptri = dm->looptris.array;
const int tottri = dm->numPolyData * 2;
int i, poly_index;
@@ -4248,19 +4248,6 @@ static void ccgDM_recalcLoopTri(DerivedMesh *dm)
lt->tri[2] = (poly_index * 4) + 2;
lt->poly = poly_index;
}
- BLI_rw_mutex_unlock(&loops_cache_rwlock);
-}
-
-static const MLoopTri *ccgDM_getLoopTriArray(DerivedMesh *dm)
-{
- if (dm->looptris.array) {
- BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
- }
- else {
- dm->recalcLoopTri(dm);
- }
-
- return dm->looptris.array;
}
static void ccgDM_calcNormals(DerivedMesh *dm)
@@ -4279,8 +4266,6 @@ static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm)
ccgdm->dm.getNumPolys = ccgDM_getNumPolys;
ccgdm->dm.getNumTessFaces = ccgDM_getNumTessFaces;
- ccgdm->dm.getLoopTriArray = ccgDM_getLoopTriArray;
-
ccgdm->dm.getVert = ccgDM_getFinalVert;
ccgdm->dm.getEdge = ccgDM_getFinalEdge;
ccgdm->dm.getTessFace = ccgDM_getFinalFace;
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/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c
index 9475925cdda..30981ed8f23 100644
--- a/source/blender/blenkernel/intern/tracking_auto.c
+++ b/source/blender/blenkernel/intern/tracking_auto.c
@@ -312,7 +312,7 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip,
int num_total_tracks = BLI_listbase_count(tracksbase);
context->tracks =
- MEM_callocN(sizeof(MovieTrackingTrack*) * num_total_tracks,
+ MEM_callocN(sizeof(MovieTrackingTrack *) * num_total_tracks,
"auto track pointers");
context->image_accessor =
@@ -381,7 +381,7 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip,
bool BKE_autotrack_context_step(AutoTrackContext *context)
{
- int frame_delta = context->backwards ? -1 : 1;
+ const int frame_delta = context->backwards ? -1 : 1;
bool ok = false;
int track;
@@ -395,67 +395,64 @@ bool BKE_autotrack_context_step(AutoTrackContext *context)
libmv_reference_marker,
libmv_tracked_marker;
libmv_TrackRegionResult libmv_result;
- int frame = BKE_movieclip_remap_scene_to_clip_frame(
- context->clips[options->clip_index],
- context->user.framenr);
- bool has_marker;
-
+ const int frame = BKE_movieclip_remap_scene_to_clip_frame(
+ context->clips[options->clip_index],
+ context->user.framenr);
BLI_spin_lock(&context->spin_lock);
- has_marker = libmv_autoTrackGetMarker(context->autotrack,
- options->clip_index,
- frame,
- options->track_index,
- &libmv_current_marker);
+ const bool has_marker = libmv_autoTrackGetMarker(context->autotrack,
+ options->clip_index,
+ frame,
+ options->track_index,
+ &libmv_current_marker);
BLI_spin_unlock(&context->spin_lock);
-
- if (has_marker) {
- if (!tracking_check_marker_margin(&libmv_current_marker,
- options->track->margin,
- context->frame_width,
- context->frame_height))
- {
- continue;
- }
-
- libmv_tracked_marker = libmv_current_marker;
- libmv_tracked_marker.frame = frame + frame_delta;
-
- if (options->use_keyframe_match) {
- libmv_tracked_marker.reference_frame =
- libmv_current_marker.reference_frame;
- libmv_autoTrackGetMarker(context->autotrack,
- options->clip_index,
- libmv_tracked_marker.reference_frame,
- options->track_index,
- &libmv_reference_marker);
- }
- else {
- libmv_tracked_marker.reference_frame = frame;
- libmv_reference_marker = libmv_current_marker;
- }
-
- if (libmv_autoTrackMarker(context->autotrack,
- &options->track_region_options,
- &libmv_tracked_marker,
- &libmv_result))
- {
- BLI_spin_lock(&context->spin_lock);
- libmv_autoTrackAddMarker(context->autotrack,
- &libmv_tracked_marker);
- BLI_spin_unlock(&context->spin_lock);
- }
- else {
- options->is_failed = true;
- options->failed_frame = frame + frame_delta;
- }
- ok = true;
+ /* Check whether we've got marker to sync with. */
+ if (!has_marker) {
+ continue;
+ }
+ /* Check whether marker is going outside of allowed frame margin. */
+ if (!tracking_check_marker_margin(&libmv_current_marker,
+ options->track->margin,
+ context->frame_width,
+ context->frame_height))
+ {
+ continue;
+ }
+ libmv_tracked_marker = libmv_current_marker;
+ libmv_tracked_marker.frame = frame + frame_delta;
+ /* Update reference frame. */
+ if (options->use_keyframe_match) {
+ libmv_tracked_marker.reference_frame =
+ libmv_current_marker.reference_frame;
+ libmv_autoTrackGetMarker(context->autotrack,
+ options->clip_index,
+ libmv_tracked_marker.reference_frame,
+ options->track_index,
+ &libmv_reference_marker);
}
+ else {
+ libmv_tracked_marker.reference_frame = frame;
+ libmv_reference_marker = libmv_current_marker;
+ }
+ /* Perform actual tracking. */
+ if (libmv_autoTrackMarker(context->autotrack,
+ &options->track_region_options,
+ &libmv_tracked_marker,
+ &libmv_result))
+ {
+ BLI_spin_lock(&context->spin_lock);
+ libmv_autoTrackAddMarker(context->autotrack, &libmv_tracked_marker);
+ BLI_spin_unlock(&context->spin_lock);
+ }
+ else {
+ options->is_failed = true;
+ options->failed_frame = frame + frame_delta;
+ }
+ ok = true;
}
-
+ /* Advance the frame. */
BLI_spin_lock(&context->spin_lock);
context->user.framenr += frame_delta;
BLI_spin_unlock(&context->spin_lock);
-
return ok;
}
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index a95399562d5..b1a092517de 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -58,6 +58,15 @@
#include "libmv-capi.h"
+/* Uncomment this to have caching-specific debug prints. */
+// #define DEBUG_CACHE
+
+#ifdef DEBUG_CACHE
+# define CACHE_PRINTF(...) printf(__VA_ARGS__)
+#else
+# define CACHE_PRINTF(...)
+#endif
+
/*********************** Tracks map *************************/
TracksMap *tracks_map_new(const char *object_name, bool is_camera, int num_tracks, int customdata_size)
@@ -523,6 +532,8 @@ typedef struct AccessCacheKey {
int frame;
int downscale;
libmv_InputMode input_mode;
+ bool has_region;
+ float region_min[2], region_max[2];
int64_t transform_key;
} AccessCacheKey;
@@ -537,23 +548,44 @@ static bool accesscache_hashcmp(const void *a_v, const void *b_v)
{
const AccessCacheKey *a = (const AccessCacheKey *) a_v;
const AccessCacheKey *b = (const AccessCacheKey *) b_v;
-
-#define COMPARE_FIELD(field)
- { \
- if (a->clip_index != b->clip_index) { \
- return false; \
- } \
- } (void) 0
-
- COMPARE_FIELD(clip_index);
- COMPARE_FIELD(frame);
- COMPARE_FIELD(downscale);
- COMPARE_FIELD(input_mode);
- COMPARE_FIELD(transform_key);
-
-#undef COMPARE_FIELD
-
- return true;
+ if (a->clip_index != b->clip_index ||
+ a->frame != b->frame ||
+ a->downscale != b->downscale ||
+ a->input_mode != b->input_mode ||
+ a->has_region != b->has_region ||
+ a->transform_key != b->transform_key)
+ {
+ return true;
+ }
+ /* If there is region applied, compare it. */
+ if (a->has_region) {
+ if (!equals_v2v2(a->region_min, b->region_min) ||
+ !equals_v2v2(a->region_max, b->region_max))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+static void accesscache_construct_key(AccessCacheKey *key,
+ int clip_index,
+ int frame,
+ libmv_InputMode input_mode,
+ int downscale,
+ const libmv_Region *region,
+ int64_t transform_key)
+{
+ key->clip_index = clip_index;
+ key->frame = frame;
+ key->input_mode = input_mode;
+ key->downscale = downscale;
+ key->has_region = (region != NULL);
+ if (key->has_region) {
+ copy_v2_v2(key->region_min, region->min);
+ copy_v2_v2(key->region_max, region->max);
+ }
+ key->transform_key = transform_key;
}
static void accesscache_put(TrackingImageAccessor *accessor,
@@ -561,15 +593,13 @@ static void accesscache_put(TrackingImageAccessor *accessor,
int frame,
libmv_InputMode input_mode,
int downscale,
+ const libmv_Region *region,
int64_t transform_key,
ImBuf *ibuf)
{
AccessCacheKey key;
- key.clip_index = clip_index;
- key.frame = frame;
- key.input_mode = input_mode;
- key.downscale = downscale;
- key.transform_key = transform_key;
+ accesscache_construct_key(&key, clip_index, frame, input_mode, downscale,
+ region, transform_key);
IMB_moviecache_put(accessor->cache, &key, ibuf);
}
@@ -578,14 +608,12 @@ static ImBuf *accesscache_get(TrackingImageAccessor *accessor,
int frame,
libmv_InputMode input_mode,
int downscale,
+ const libmv_Region *region,
int64_t transform_key)
{
AccessCacheKey key;
- key.clip_index = clip_index;
- key.frame = frame;
- key.input_mode = input_mode;
- key.downscale = downscale;
- key.transform_key = transform_key;
+ accesscache_construct_key(&key, clip_index, frame, input_mode, downscale,
+ region, transform_key);
return IMB_moviecache_get(accessor->cache, &key);
}
@@ -674,29 +702,37 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
{
ImBuf *ibuf, *orig_ibuf, *final_ibuf;
int64_t transform_key = 0;
-
if (transform != NULL) {
transform_key = libmv_frameAccessorgetTransformKey(transform);
}
-
/* First try to get fully processed image from the cache. */
+ BLI_spin_lock(&accessor->cache_lock);
ibuf = accesscache_get(accessor,
clip_index,
frame,
input_mode,
downscale,
+ region,
transform_key);
+ BLI_spin_unlock(&accessor->cache_lock);
if (ibuf != NULL) {
+ CACHE_PRINTF("Used cached buffer for frame %d\n", frame);
+ /* This is a little heuristic here: if we re-used image once, this is
+ * a high probability of the image to be related to a keyframe matched
+ * reference image. Those images we don't want to be thrown away because
+ * if we toss them out we'll be re-calculating them at the next
+ * iteration.
+ */
+ ibuf->userflags |= IB_PERSISTENT;
return ibuf;
}
-
+ CACHE_PRINTF("Calculate new buffer for frame %d\n", frame);
/* And now we do postprocessing of the original frame. */
orig_ibuf = accessor_get_preprocessed_ibuf(accessor, clip_index, frame);
-
if (orig_ibuf == NULL) {
return NULL;
}
-
+ /* Cut a region if requested. */
if (region != NULL) {
int width = region->max[0] - region->min[0],
height = region->max[1] - region->min[1];
@@ -756,7 +792,7 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
BLI_unlock_thread(LOCK_MOVIECLIP);
final_ibuf = orig_ibuf;
}
-
+ /* Downscale if needed. */
if (downscale > 0) {
if (final_ibuf == orig_ibuf) {
final_ibuf = IMB_dupImBuf(orig_ibuf);
@@ -765,7 +801,7 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
orig_ibuf->x / (1 << downscale),
orig_ibuf->y / (1 << downscale));
}
-
+ /* Apply possible transformation. */
if (transform != NULL) {
libmv_FloatImage input_image, output_image;
ibuf_to_float_image(final_ibuf, &input_image);
@@ -778,12 +814,13 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
final_ibuf = float_image_to_ibuf(&output_image);
libmv_floatImageDestroy(&output_image);
}
-
+ /* Transform number of channels. */
if (input_mode == LIBMV_IMAGE_MODE_RGBA) {
BLI_assert(orig_ibuf->channels == 3 || orig_ibuf->channels == 4);
/* pass */
}
else /* if (input_mode == LIBMV_IMAGE_MODE_MONO) */ {
+ BLI_assert(input_mode == LIBMV_IMAGE_MODE_MONO);
if (final_ibuf->channels != 1) {
ImBuf *grayscale_ibuf = make_grayscale_ibuf_copy(final_ibuf);
if (final_ibuf != orig_ibuf) {
@@ -793,37 +830,24 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
final_ibuf = grayscale_ibuf;
}
}
-
- /* it's possible processing still didn't happen at this point,
+ /* It's possible processing still didn't happen at this point,
* but we really need a copy of the buffer to be transformed
* and to be put to the cache.
*/
if (final_ibuf == orig_ibuf) {
final_ibuf = IMB_dupImBuf(orig_ibuf);
}
-
IMB_freeImBuf(orig_ibuf);
-
- /* We put postprocessed frame to the cache always for now,
- * not the smartest thing in the world, but who cares at this point.
- */
-
- /* TODO(sergey): Disable cache for now, because we don't store region
- * in the cache key and can't check whether cached version is usable for
- * us or not.
- *
- * Need to think better about what to cache and when.
- */
- if (false) {
- accesscache_put(accessor,
- clip_index,
- frame,
- input_mode,
- downscale,
- transform_key,
- final_ibuf);
- }
-
+ BLI_spin_lock(&accessor->cache_lock);
+ /* Put final buffer to cache. */
+ accesscache_put(accessor,
+ clip_index,
+ frame,
+ input_mode,
+ downscale,
+ region,
+ transform_key,
+ final_ibuf);
return final_ibuf;
}
@@ -876,7 +900,7 @@ static void accessor_release_image_callback(libmv_CacheKey cache_key)
}
static libmv_CacheKey accessor_get_mask_for_track_callback(
- libmv_FrameAccessorUserData* user_data,
+ libmv_FrameAccessorUserData *user_data,
int clip_index,
int frame,
int track_index,
@@ -958,6 +982,8 @@ TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR
accessor_get_mask_for_track_callback,
accessor_release_mask_callback);
+ BLI_spin_init(&accessor->cache_lock);
+
return accessor;
}
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 82fface7d06..65eb08aba27 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -137,7 +137,7 @@ static bool UNUSED_FUNCTION(workspaces_is_screen_used)(
WorkSpace *BKE_workspace_add(Main *bmain, const char *name)
{
- WorkSpace *new_workspace = BKE_libblock_alloc(bmain, ID_WS, name);
+ WorkSpace *new_workspace = BKE_libblock_alloc(bmain, ID_WS, name, 0);
return new_workspace;
}
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 2adbdc83a36..cbe00e3bbc6 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;
@@ -176,7 +192,7 @@ void BKE_world_make_local(Main *bmain, World *wrld, const bool lib_local)
BKE_id_make_local_generic(bmain, &wrld->id, true, lib_local);
}
-void BKE_world_eval(struct EvaluationContext *UNUSED(eval_ctx), World *world)
+void BKE_world_eval(const struct EvaluationContext *UNUSED(eval_ctx), World *world)
{
if (G.debug & G_DEBUG_DEPSGRAPH) {
printf("%s on %s (%p)\n", __func__, world->id.name, world);
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 156b74f5c3d..4a226dbda11 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -45,8 +45,8 @@
#include "BLI_blenlib.h"
#ifdef WITH_AUDASPACE
-# include AUD_DEVICE_H
-# include AUD_SPECIAL_H
+# include <AUD_Device.h>
+# include <AUD_Special.h>
#endif
#include "BLI_utildefines.h"