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:
Diffstat (limited to 'source/blender/blenkernel/intern/object.c')
-rw-r--r--source/blender/blenkernel/intern/object.c474
1 files changed, 184 insertions, 290 deletions
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 127c5243c7e..f77c79a2be7 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1532,12 +1532,12 @@ void BKE_object_copy_particlesystems(Object *ob_dst, const Object *ob_src, const
}
}
else if (md->type == eModifierType_Fluid) {
- FluidModifierData *mmd = (FluidModifierData *)md;
+ FluidModifierData *fmd = (FluidModifierData *)md;
- if (mmd->type == MOD_FLUID_TYPE_FLOW) {
- if (mmd->flow) {
- if (mmd->flow->psys == psys) {
- mmd->flow->psys = npsys;
+ if (fmd->type == MOD_FLUID_TYPE_FLOW) {
+ if (fmd->flow) {
+ if (fmd->flow->psys == psys) {
+ fmd->flow->psys = npsys;
}
}
}
@@ -1758,300 +1758,172 @@ Object *BKE_object_copy(Main *bmain, const Object *ob)
* \note Caller MUST free \a newid pointers itself (#BKE_main_id_clear_newpoins()) and call updates
* of DEG too (#DAG_relations_tag_update()).
*/
-Object *BKE_object_duplicate(Main *bmain, const Object *ob, const int dupflag)
+Object *BKE_object_duplicate(Main *bmain,
+ Object *ob,
+ eDupli_ID_Flags dupflag,
+ const eLibIDDuplicateFlags duplicate_options)
{
+ const bool is_subprocess = (duplicate_options & LIB_ID_DUPLICATE_IS_SUBPROCESS) != 0;
+
+ if (!is_subprocess) {
+ BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
+ BKE_main_id_clear_newpoins(bmain);
+ /* In case root duplicated ID is linked, assume we want to get a local copy of it and duplicate
+ * all expected linked data. */
+ if (ID_IS_LINKED(ob)) {
+ dupflag |= USER_DUP_LINKED_ID;
+ }
+ }
+
Material ***matarar;
- ID *id;
- int a, didit;
- const bool is_object_liboverride = ID_IS_OVERRIDE_LIBRARY(ob);
- Object *obn = BKE_object_copy(bmain, ob);
+ Object *obn;
+ BKE_id_copy(bmain, &ob->id, (ID **)&obn);
+ id_us_min(&obn->id);
+ if (is_subprocess) {
+ ID_NEW_SET(ob, obn);
+ }
/* 0 == full linked. */
if (dupflag == 0) {
return obn;
}
-#define ID_NEW_REMAP_US(a) \
- if ((a)->id.newid) { \
- (a) = (void *)(a)->id.newid; \
- (a)->id.us++; \
- }
-#define ID_NEW_REMAP_US2(a) \
- if (((ID *)a)->newid) { \
- (a) = ((ID *)a)->newid; \
- ((ID *)a)->us++; \
- }
-
- /* duplicates using userflags */
- if (dupflag & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(bmain, &obn->id, true);
- }
+ BKE_animdata_duplicate_id_action(bmain, &obn->id, dupflag);
if (dupflag & USER_DUP_MAT) {
- for (a = 0; a < obn->totcol; a++) {
- id = (ID *)obn->mat[a];
- if (id) {
- if (is_object_liboverride && ID_IS_LINKED(id)) {
- continue;
- }
- ID_NEW_REMAP_US(obn->mat[a])
- else
- {
- obn->mat[a] = ID_NEW_SET(obn->mat[a], BKE_material_copy(bmain, obn->mat[a]));
- if (dupflag & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(bmain, &obn->mat[a]->id, true);
- }
- }
- id_us_min(id);
- }
+ for (int i = 0; i < obn->totcol; i++) {
+ BKE_id_copy_for_duplicate(bmain, (ID *)obn->mat[i], dupflag);
}
}
if (dupflag & USER_DUP_PSYS) {
ParticleSystem *psys;
for (psys = obn->particlesystem.first; psys; psys = psys->next) {
- id = (ID *)psys->part;
- if (id) {
- if (is_object_liboverride && ID_IS_LINKED(id)) {
- continue;
- }
- ID_NEW_REMAP_US(psys->part)
- else
- {
- psys->part = ID_NEW_SET(psys->part, BKE_particlesettings_copy(bmain, psys->part));
- if (dupflag & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(bmain, &psys->part->id, true);
- }
- }
- id_us_min(id);
- }
- }
- }
-
- id = obn->data;
- didit = 0;
-
- if (!is_object_liboverride || !ID_IS_LINKED(id)) {
- switch (obn->type) {
- case OB_MESH:
- if (dupflag & USER_DUP_MESH) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_mesh_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_CURVE:
- if (dupflag & USER_DUP_CURVE) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_SURF:
- if (dupflag & USER_DUP_SURF) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_FONT:
- if (dupflag & USER_DUP_FONT) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_MBALL:
- if (dupflag & USER_DUP_MBALL) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_mball_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_LAMP:
- if (dupflag & USER_DUP_LAMP) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_light_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_ARMATURE:
- if (dupflag != 0) {
- DEG_id_tag_update(&obn->id, ID_RECALC_GEOMETRY);
- if (obn->pose) {
- BKE_pose_tag_recalc(bmain, obn->pose);
- }
- if (dupflag & USER_DUP_ARM) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_armature_copy(bmain, obn->data));
- BKE_pose_rebuild(bmain, obn, obn->data, true);
- didit = 1;
- }
- id_us_min(id);
- }
- }
- break;
- case OB_LATTICE:
- if (dupflag != 0) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_lattice_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_CAMERA:
- if (dupflag != 0) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_camera_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_LIGHTPROBE:
- if (dupflag & USER_DUP_LIGHTPROBE) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_lightprobe_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_SPEAKER:
- if (dupflag != 0) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_speaker_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_GPENCIL:
- if (dupflag & USER_DUP_GPENCIL) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_gpencil_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_HAIR:
- if (dupflag & USER_DUP_HAIR) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_hair_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_POINTCLOUD:
- if (dupflag & USER_DUP_POINTCLOUD) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_pointcloud_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_VOLUME:
- if (dupflag & USER_DUP_VOLUME) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_volume_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
+ BKE_id_copy_for_duplicate(bmain, (ID *)psys->part, dupflag);
}
}
- /* Check if obdata is copied. */
- if (didit) {
- Key *key = BKE_key_from_object(obn);
-
- Key *oldkey = BKE_key_from_object(ob);
- if (oldkey != NULL) {
- ID_NEW_SET(oldkey, key);
- }
+ ID *id_old = obn->data;
+ ID *id_new = NULL;
+ const bool need_to_duplicate_obdata = (id_old != NULL) && (id_old->newid == NULL);
- if (dupflag & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(bmain, (ID *)obn->data, true);
- if (key) {
- BKE_animdata_copy_id_action(bmain, (ID *)key, true);
+ switch (obn->type) {
+ case OB_MESH:
+ if (dupflag & USER_DUP_MESH) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
- }
+ break;
+ case OB_CURVE:
+ if (dupflag & USER_DUP_CURVE) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ case OB_SURF:
+ if (dupflag & USER_DUP_SURF) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ case OB_FONT:
+ if (dupflag & USER_DUP_FONT) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ case OB_MBALL:
+ if (dupflag & USER_DUP_MBALL) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ case OB_LAMP:
+ if (dupflag & USER_DUP_LAMP) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ case OB_ARMATURE:
+ if (dupflag & USER_DUP_ARM) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ case OB_LATTICE:
+ if (dupflag != 0) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ case OB_CAMERA:
+ if (dupflag != 0) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ case OB_LIGHTPROBE:
+ if (dupflag & USER_DUP_LIGHTPROBE) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ case OB_SPEAKER:
+ if (dupflag != 0) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ case OB_GPENCIL:
+ if (dupflag & USER_DUP_GPENCIL) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ case OB_HAIR:
+ if (dupflag & USER_DUP_HAIR) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ case OB_POINTCLOUD:
+ if (dupflag & USER_DUP_POINTCLOUD) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ case OB_VOLUME:
+ if (dupflag & USER_DUP_VOLUME) {
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+ }
+ break;
+ }
+ /* If obdata has been copied, we may also have to duplicate the materials assigned to it. */
+ if (need_to_duplicate_obdata && !ELEM(id_new, NULL, id_old)) {
if (dupflag & USER_DUP_MAT) {
matarar = BKE_object_material_array_p(obn);
if (matarar) {
- for (a = 0; a < obn->totcol; a++) {
- id = (ID *)(*matarar)[a];
- if (id) {
- if (is_object_liboverride && ID_IS_LINKED(id)) {
- continue;
- }
- ID_NEW_REMAP_US((*matarar)[a])
- else
- {
- (*matarar)[a] = ID_NEW_SET((*matarar)[a], BKE_material_copy(bmain, (*matarar)[a]));
- if (dupflag & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(bmain, &(*matarar)[a]->id, true);
- }
- }
- id_us_min(id);
- }
+ for (int i = 0; i < obn->totcol; i++) {
+ BKE_id_copy_for_duplicate(bmain, (ID *)(*matarar)[i], dupflag);
}
}
}
}
-#undef ID_NEW_REMAP_US
-#undef ID_NEW_REMAP_US2
+ if (!is_subprocess) {
+ /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW.*/
+ BKE_libblock_relink_to_newid(&obn->id);
- if (ob->data != NULL) {
+#ifndef NDEBUG
+ /* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those flags. */
+ ID *id_iter;
+ FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
+ BLI_assert((id_iter->tag & LIB_TAG_NEW) == 0);
+ }
+ FOREACH_MAIN_ID_END;
+#endif
+
+ /* Cleanup. */
+ BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
+ BKE_main_id_clear_newpoins(bmain);
+ }
+
+ if (obn->type == OB_ARMATURE) {
+ DEG_id_tag_update(&obn->id, ID_RECALC_GEOMETRY);
+ if (obn->pose) {
+ BKE_pose_tag_recalc(bmain, obn->pose);
+ }
+ // BKE_pose_rebuild(bmain, obn, obn->data, true);
+ }
+
+ if (obn->data != NULL) {
DEG_id_tag_update_ex(bmain, (ID *)obn->data, ID_RECALC_EDITORS);
}
@@ -2216,7 +2088,7 @@ void BKE_object_make_proxy(Main *bmain, Object *ob, Object *target, Object *cob)
/* type conversions */
if (target->type == OB_ARMATURE) {
copy_object_pose(ob, target, 0); /* data copy, object pointers in constraints */
- BKE_pose_rest(ob->pose); /* clear all transforms in channels */
+ BKE_pose_rest(ob->pose, false); /* clear all transforms in channels */
BKE_pose_rebuild(bmain, ob, ob->data, true); /* set all internal links */
armature_set_id_extern(ob);
@@ -2512,7 +2384,6 @@ void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4])
}
/**
- * \param depsgraph: Used for dupli-frame time.
* \return success if \a mat is set.
*/
static bool ob_parcurve(Object *ob, Object *par, float mat[4][4])
@@ -2538,7 +2409,7 @@ static bool ob_parcurve(Object *ob, Object *par, float mat[4][4])
/* ctime is now a proper var setting of Curve which gets set by Animato like any other var
* that's animated, but this will only work if it actually is animated.
*
- * We divide the curvetime calculated in the previous step by the length of the path,
+ * We divide the curve-time calculated in the previous step by the length of the path,
* to get a time factor, which then gets clamped to lie within 0.0 - 1.0 range.
*/
if (cu->pathlen) {
@@ -2616,9 +2487,10 @@ static void give_parvert(Object *par, int nr, float vec[3])
if (me_eval) {
int count = 0;
- const int numVerts = me_eval->totvert;
+ int numVerts = me_eval->totvert;
- if (em && me_eval->runtime.is_original) {
+ if (em && me_eval->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
+ numVerts = em->bm->totvert;
if (em->bm->elem_table_dirty & BM_VERT) {
#ifdef VPARENT_THREADING_HACK
BLI_mutex_lock(&vparent_lock);
@@ -2631,10 +2503,18 @@ static void give_parvert(Object *par, int nr, float vec[3])
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
#endif
}
+ if (nr < numVerts) {
+ if (me_eval && me_eval->runtime.edit_data && me_eval->runtime.edit_data->vertexCos) {
+ add_v3_v3(vec, me_eval->runtime.edit_data->vertexCos[nr]);
+ }
+ else {
+ const BMVert *v = BM_vert_at_index(em->bm, nr);
+ add_v3_v3(vec, v->co);
+ }
+ count++;
+ }
}
-
- if (CustomData_has_layer(&me_eval->vdata, CD_ORIGINDEX) &&
- !(em && me_eval->runtime.is_original)) {
+ else if (CustomData_has_layer(&me_eval->vdata, CD_ORIGINDEX)) {
const int *index = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
/* Get the average of all verts with (original index == nr). */
for (int i = 0; i < numVerts; i++) {
@@ -2866,7 +2746,10 @@ void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *o
{
/* Execute drivers and animation. */
const bool flush_to_original = DEG_is_active(depsgraph);
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, ctime, ADT_RECALC_ALL, flush_to_original);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ ctime);
+ BKE_animsys_evaluate_animdata(
+ &ob->id, ob->adt, &anim_eval_context, ADT_RECALC_ALL, flush_to_original);
object_where_is_calc_ex(depsgraph, scene, ob, ctime, NULL, NULL);
}
@@ -3179,9 +3062,9 @@ void BKE_object_dimensions_set_ex(Object *ob,
}
}
- if (len[i] > 0.0f) {
-
- ob->scale[i] = copysignf(value[i] / len[i], ob->scale[i]);
+ const float scale = copysignf(value[i] / len[i], ob->scale[i]);
+ if (isfinite(scale)) {
+ ob->scale[i] = scale;
}
}
}
@@ -4081,15 +3964,20 @@ int BKE_object_is_modified(Scene *scene, Object *ob)
return flag;
}
-/* Check of objects moves in time. */
-/* NOTE: This function is currently optimized for usage in combination
- * with mti->canDeform, so modifiers can quickly check if their target
- * objects moves (causing deformation motion blur) or not.
+/**
+ * Check of objects moves in time.
+ *
+ * \note This function is currently optimized for usage in combination
+ * with modifier deformation checks (#eModifierTypeType_OnlyDeform),
+ * so modifiers can quickly check if their target objects moves
+ * (causing deformation motion blur) or not.
*
* This makes it possible to give some degree of false-positives here,
* but it's currently an acceptable tradeoff between complexity and check
* speed. In combination with checks of modifier stack and real life usage
- * percentage of false-positives shouldn't be that height.
+ * percentage of false-positives shouldn't be that high.
+ *
+ * \note This function does not consider physics systems.
*/
bool BKE_object_moves_in_time(const Object *object, bool recurse_parent)
{
@@ -4713,9 +4601,9 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph,
}
}
else if (type == eModifierType_Fluid) {
- FluidModifierData *mmd = (FluidModifierData *)md;
+ FluidModifierData *fmd = (FluidModifierData *)md;
- if (mmd && (mmd->type & MOD_FLUID_TYPE_DOMAIN) != 0) {
+ if (fmd && (fmd->type & MOD_FLUID_TYPE_DOMAIN) != 0) {
return true;
}
}
@@ -4763,9 +4651,13 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph,
/* was originally ID_RECALC_ALL - TODO - which flags are really needed??? */
/* TODO(sergey): What about animation? */
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ frame);
+
ob->id.recalc |= ID_RECALC_ALL;
if (update_mesh) {
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, frame, ADT_RECALC_ANIM, flush_to_original);
+ BKE_animsys_evaluate_animdata(
+ &ob->id, ob->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
/* ignore cache clear during subframe updates
* to not mess up cache validity */
object_cacheIgnoreClear(ob, 1);
@@ -4779,12 +4671,14 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph,
/* for curve following objects, parented curve has to be updated too */
if (ob->type == OB_CURVE) {
Curve *cu = ob->data;
- BKE_animsys_evaluate_animdata(&cu->id, cu->adt, frame, ADT_RECALC_ANIM, flush_to_original);
+ BKE_animsys_evaluate_animdata(
+ &cu->id, cu->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
}
/* and armatures... */
if (ob->type == OB_ARMATURE) {
bArmature *arm = ob->data;
- BKE_animsys_evaluate_animdata(&arm->id, arm->adt, frame, ADT_RECALC_ANIM, flush_to_original);
+ BKE_animsys_evaluate_animdata(
+ &arm->id, arm->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
BKE_pose_where_is(depsgraph, scene, ob);
}