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.c291
1 files changed, 210 insertions, 81 deletions
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 526a71b477d..1ba4852623c 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -40,6 +40,7 @@
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
#include "DNA_constraint_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_group_types.h"
#include "DNA_key_types.h"
#include "DNA_lamp_types.h"
@@ -210,6 +211,9 @@ void BKE_object_free_modifiers(Object *ob)
/* same for softbody */
BKE_object_free_softbody(ob);
+
+ /* modifiers may have stored data in the DM cache */
+ BKE_object_free_derived_caches(ob);
}
void BKE_object_modifier_hook_reset(Object *ob, HookModifierData *hmd)
@@ -360,10 +364,15 @@ void BKE_object_free_caches(Object *object)
for (md = object->modifiers.first; md != NULL; md = md->next) {
if (md->type == eModifierType_ParticleSystem) {
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
- if (psmd->dm != NULL) {
- psmd->dm->needsFree = 1;
- psmd->dm->release(psmd->dm);
- psmd->dm = NULL;
+ if (psmd->dm_final != NULL) {
+ psmd->dm_final->needsFree = 1;
+ psmd->dm_final->release(psmd->dm_final);
+ psmd->dm_final = NULL;
+ if (psmd->dm_deformed != NULL) {
+ psmd->dm_deformed->needsFree = 1;
+ psmd->dm_deformed->release(psmd->dm_deformed);
+ psmd->dm_deformed = NULL;
+ }
psmd->flag |= eParticleSystemFlag_file_loaded;
update_flag |= OB_RECALC_DATA;
}
@@ -384,12 +393,12 @@ void BKE_object_free_ex(Object *ob, bool do_id_user)
{
int a;
- BKE_object_free_derived_caches(ob);
+ BKE_object_free_modifiers(ob);
/* disconnect specific data, but not for lib data (might be indirect data, can get relinked) */
if (ob->data) {
ID *id = ob->data;
- id->us--;
+ id_us_min(id);
if (id->us == 0 && id->lib == NULL) {
switch (ob->type) {
case OB_MESH:
@@ -408,7 +417,8 @@ void BKE_object_free_ex(Object *ob, bool do_id_user)
if (ob->mat) {
for (a = 0; a < ob->totcol; a++) {
- if (ob->mat[a]) ob->mat[a]->id.us--;
+ if (ob->mat[a])
+ id_us_min(&ob->mat[a]->id);
}
MEM_freeN(ob->mat);
}
@@ -420,8 +430,10 @@ void BKE_object_free_ex(Object *ob, bool do_id_user)
if (ob->bb) MEM_freeN(ob->bb);
ob->bb = NULL;
if (ob->adt) BKE_animdata_free((ID *)ob);
- if (ob->poselib) ob->poselib->id.us--;
- if (ob->gpd) ((ID *)ob->gpd)->us--;
+ if (ob->poselib)
+ id_us_min(&ob->poselib->id);
+ if (ob->gpd)
+ id_us_min(&ob->gpd->id);
if (ob->defbase.first)
BLI_freelistN(&ob->defbase);
if (ob->pose)
@@ -429,7 +441,6 @@ void BKE_object_free_ex(Object *ob, bool do_id_user)
if (ob->mpath)
animviz_free_motionpath(ob->mpath);
BKE_bproperty_free_list(&ob->prop);
- BKE_object_free_modifiers(ob);
free_sensors(&ob->sensors);
free_controllers(&ob->controllers);
@@ -467,7 +478,7 @@ void BKE_object_free(Object *ob)
BKE_object_free_ex(ob, true);
}
-static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Object **obpoin)
+static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Object **obpoin, int UNUSED(cd_flag))
{
Object *unlinkOb = userData;
@@ -478,9 +489,8 @@ static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Objec
}
}
-void BKE_object_unlink(Object *ob)
+void BKE_object_unlink(Main *bmain, Object *ob)
{
- Main *bmain = G.main;
Object *obt;
Material *mat;
World *wrld;
@@ -972,19 +982,10 @@ void *BKE_object_obdata_add_from_type(Main *bmain, int type, const char *name)
}
}
-/* more general add: creates minimum required data, but without vertices etc. */
-Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
+void BKE_object_init(Object *ob)
{
- Object *ob;
-
- if (!name)
- name = get_obdata_defname(type);
-
- ob = BKE_libblock_alloc(bmain, ID_OB, name);
+ /* BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(ob, id)); */ /* ob->type is already initialized... */
- /* default object vars */
- ob->type = type;
-
ob->col[0] = ob->col[1] = ob->col[2] = 1.0;
ob->col[3] = 1.0;
@@ -1012,7 +1013,7 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
ob->empty_drawtype = OB_PLAINAXES;
ob->empty_drawsize = 1.0;
- if (ELEM(type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) {
+ if (ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) {
ob->trackflag = OB_NEGZ;
ob->upflag = OB_POSY;
}
@@ -1041,6 +1042,7 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
ob->step_height = 0.15f;
ob->jump_speed = 10.0f;
ob->fall_speed = 55.0f;
+ ob->max_jumps = 1;
ob->col_group = 0x01;
ob->col_mask = 0xffff;
ob->preview = NULL;
@@ -1052,6 +1054,22 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
/* Animation Visualization defaults */
animviz_settings_init(&ob->avs);
+}
+
+/* more general add: creates minimum required data, but without vertices etc. */
+Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
+{
+ Object *ob;
+
+ if (!name)
+ name = get_obdata_defname(type);
+
+ ob = BKE_libblock_alloc(bmain, ID_OB, name);
+
+ /* default object vars */
+ ob->type = type;
+
+ BKE_object_init(ob);
return ob;
}
@@ -1148,16 +1166,15 @@ bool BKE_object_lod_remove(Object *ob, int level)
static LodLevel *lod_level_select(Object *ob, const float camera_position[3])
{
LodLevel *current = ob->currentlod;
- float dist_sq, dist_sq_curr;
+ float dist_sq;
if (!current) return NULL;
dist_sq = len_squared_v3v3(ob->obmat[3], camera_position);
- dist_sq_curr = current->distance * current->distance;
- if (dist_sq < dist_sq_curr) {
+ if (dist_sq < SQUARE(current->distance)) {
/* check for higher LoD */
- while (current->prev && dist_sq < dist_sq_curr) {
+ while (current->prev && dist_sq < SQUARE(current->distance)) {
current = current->prev;
}
}
@@ -1574,8 +1591,7 @@ Object *BKE_object_copy(Object *ob)
}
static void extern_local_object__modifiersForeachIDLink(
- void *UNUSED(userData), Object *UNUSED(ob),
- ID **idpoin)
+ void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int UNUSED(cd_flag))
{
if (*idpoin) {
/* intentionally omit ID_OB */
@@ -1651,8 +1667,8 @@ void BKE_object_make_local(Object *ob)
while (base) {
if (base->object == ob) {
base->object = ob_new;
- ob_new->id.us++;
- ob->id.us--;
+ id_us_plus(&ob_new->id);
+ id_us_min(&ob->id);
}
base = base->next;
}
@@ -1791,7 +1807,7 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
/* set object type and link to data */
ob->type = target->type;
ob->data = target->data;
- id_us_plus((ID *)ob->data); /* ensures lib data becomes LIB_EXTERN */
+ id_us_plus((ID *)ob->data); /* ensures lib data becomes LIB_TAG_EXTERN */
/* copy material and index information */
ob->actcol = ob->totcol = 0;
@@ -1938,39 +1954,45 @@ void BKE_object_rot_to_mat3(Object *ob, float mat[3][3], bool use_drot)
void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], bool use_compat)
{
+ BLI_ASSERT_UNIT_M3(mat);
+
switch (ob->rotmode) {
case ROT_MODE_QUAT:
{
float dquat[4];
- mat3_to_quat(ob->quat, mat);
+ mat3_normalized_to_quat(ob->quat, mat);
normalize_qt_qt(dquat, ob->dquat);
- invert_qt(dquat);
+ invert_qt_normalized(dquat);
mul_qt_qtqt(ob->quat, dquat, ob->quat);
break;
}
case ROT_MODE_AXISANGLE:
{
- mat3_to_axis_angle(ob->rotAxis, &ob->rotAngle, mat);
- sub_v3_v3(ob->rotAxis, ob->drotAxis);
- ob->rotAngle -= ob->drotAngle;
+ float quat[4];
+ float dquat[4];
+
+ /* without drot we could apply 'mat' directly */
+ mat3_normalized_to_quat(quat, mat);
+ axis_angle_to_quat(dquat, ob->drotAxis, ob->drotAngle);
+ invert_qt_normalized(dquat);
+ mul_qt_qtqt(quat, dquat, quat);
+ quat_to_axis_angle(ob->rotAxis, &ob->rotAngle, quat);
break;
}
default: /* euler */
{
float quat[4];
float dquat[4];
- float tmat[3][3];
/* without drot we could apply 'mat' directly */
- mat3_to_quat(quat, mat);
+ mat3_normalized_to_quat(quat, mat);
eulO_to_quat(dquat, ob->drot, ob->rotmode);
- invert_qt(dquat);
+ invert_qt_normalized(dquat);
mul_qt_qtqt(quat, dquat, quat);
- quat_to_mat3(tmat, quat);
/* end drot correction */
- if (use_compat) mat3_to_compatible_eulO(ob->rot, ob->rot, ob->rotmode, tmat);
- else mat3_to_eulO(ob->rot, ob->rotmode, tmat);
+ if (use_compat) quat_to_compatible_eulO(ob->rot, ob->rot, ob->rotmode, quat);
+ else quat_to_eulO(ob->rot, ob->rotmode, quat);
break;
}
}
@@ -2665,6 +2687,18 @@ void BKE_boundbox_minmax(const BoundBox *bb, float obmat[4][4], float r_min[3],
}
}
+void BKE_boundbox_scale(struct BoundBox *bb_dst, const struct BoundBox *bb_src, float scale)
+{
+ float cent[3];
+ BKE_boundbox_calc_center_aabb(bb_src, cent);
+
+ for (int i = 0; i < ARRAY_SIZE(bb_dst->vec); i++) {
+ bb_dst->vec[i][0] = ((bb_src->vec[i][0] - cent[0]) * scale) + cent[0];
+ bb_dst->vec[i][1] = ((bb_src->vec[i][1] - cent[1]) * scale) + cent[1];
+ bb_dst->vec[i][2] = ((bb_src->vec[i][2] - cent[2]) * scale) + cent[2];
+ }
+}
+
/**
* Returns a BBox which each dimensions are at least epsilon.
* \note In case a given dimension needs to be enlarged, its final value will be in [epsilon, 3 * epsilon] range.
@@ -3197,6 +3231,9 @@ int BKE_object_obdata_texspace_get(Object *ob, short **r_texflag, float **r_loc,
case ID_ME:
{
Mesh *me = ob->data;
+ if (me->bb == NULL || (me->bb->flag & BOUNDBOX_DIRTY)) {
+ BKE_mesh_texspace_calc(me);
+ }
if (r_texflag) *r_texflag = &me->texflag;
if (r_loc) *r_loc = me->loc;
if (r_size) *r_size = me->size;
@@ -3206,6 +3243,9 @@ int BKE_object_obdata_texspace_get(Object *ob, short **r_texflag, float **r_loc,
case ID_CU:
{
Curve *cu = ob->data;
+ if (cu->bb == NULL || (cu->bb->flag & BOUNDBOX_DIRTY)) {
+ BKE_curve_texspace_calc(cu);
+ }
if (r_texflag) *r_texflag = &cu->texflag;
if (r_loc) *r_loc = cu->loc;
if (r_size) *r_size = cu->size;
@@ -3613,6 +3653,17 @@ static bool object_moves_in_time(Object *object)
return false;
}
+static bool object_deforms_in_time(Object *object)
+{
+ if (BKE_key_from_object(object) != NULL) {
+ return true;
+ }
+ if (!BLI_listbase_is_empty(&object->modifiers)) {
+ return true;
+ }
+ return object_moves_in_time(object);
+}
+
static bool constructive_modifier_is_deform_modified(ModifierData *md)
{
/* TODO(sergey): Consider generalizing this a bit so all modifier logic
@@ -3672,8 +3723,16 @@ int BKE_object_is_deform_modified(Scene *scene, Object *ob)
int flag = 0;
const bool is_modifier_animated = modifiers_has_animation_check(ob);
- if (BKE_key_from_object(ob))
+ if (BKE_key_from_object(ob)) {
flag |= eModifierMode_Realtime | eModifierMode_Render;
+ }
+
+ if (ob->type == OB_CURVE) {
+ Curve *cu = (Curve *)ob->data;
+ if (cu->taperobj != NULL && object_deforms_in_time(cu->taperobj)) {
+ flag |= eModifierMode_Realtime | eModifierMode_Render;
+ }
+ }
/* cloth */
for (md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
@@ -3716,38 +3775,6 @@ bool BKE_object_is_animated(Scene *scene, Object *ob)
return false;
}
-static void copy_object__forwardModifierLinks(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin)
-{
- /* this is copied from ID_NEW; it might be better to have a macro */
- if (*idpoin && (*idpoin)->newid) *idpoin = (*idpoin)->newid;
-}
-
-void BKE_object_relink(Object *ob)
-{
- if (ob->id.lib)
- return;
-
- BKE_constraints_relink(&ob->constraints);
- if (ob->pose) {
- bPoseChannel *chan;
- for (chan = ob->pose->chanbase.first; chan; chan = chan->next) {
- BKE_constraints_relink(&chan->constraints);
- }
- }
- modifiers_foreachIDLink(ob, copy_object__forwardModifierLinks, NULL);
-
- if (ob->adt)
- BKE_animdata_relink(ob->adt);
-
- if (ob->rigidbody_constraint)
- BKE_rigidbody_relink_constraint(ob->rigidbody_constraint);
-
- ID_NEW(ob->parent);
-
- ID_NEW(ob->proxy);
- ID_NEW(ob->proxy_group);
-}
-
MovieClip *BKE_object_movieclip_get(Scene *scene, Object *ob, bool use_default)
{
MovieClip *clip = use_default ? scene->clip : NULL;
@@ -3798,13 +3825,13 @@ static Object *obrel_armature_find(Object *ob)
static bool obrel_list_test(Object *ob)
{
- return ob && !(ob->id.flag & LIB_DOIT);
+ return ob && !(ob->id.tag & LIB_TAG_DOIT);
}
static void obrel_list_add(LinkNode **links, Object *ob)
{
BLI_linklist_prepend(links, ob);
- ob->id.flag |= LIB_DOIT;
+ ob->id.tag |= LIB_TAG_DOIT;
}
/*
@@ -3822,7 +3849,7 @@ LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectS
/* Remove markers from all objects */
for (base = scene->base.first; base; base = base->next) {
- base->object->id.flag &= ~LIB_DOIT;
+ base->object->id.tag &= ~LIB_TAG_DOIT;
}
/* iterate over all selected and visible objects */
@@ -4097,3 +4124,105 @@ bool BKE_object_modifier_use_time(Object *ob, ModifierData *md)
return false;
}
+
+/* set "ignore cache" flag for all caches on this object */
+static void object_cacheIgnoreClear(Object *ob, int state)
+{
+ ListBase pidlist;
+ PTCacheID *pid;
+ BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0);
+
+ for (pid = pidlist.first; pid; pid = pid->next) {
+ if (pid->cache) {
+ if (state)
+ pid->cache->flag |= PTCACHE_IGNORE_CLEAR;
+ else
+ pid->cache->flag &= ~PTCACHE_IGNORE_CLEAR;
+ }
+ }
+
+ BLI_freelistN(&pidlist);
+}
+
+/* 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(Scene *scene, Object *ob, bool update_mesh,
+ int parent_recursion, float frame,
+ int type)
+{
+ ModifierData *md = modifiers_findByType(ob, (ModifierType)type);
+ bConstraint *con;
+
+ if (type == eModifierType_DynamicPaint) {
+ DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
+
+ /* if other is dynamic paint canvas, don't update */
+ if (pmd && pmd->canvas)
+ return true;
+ }
+ else if (type == eModifierType_Smoke) {
+ SmokeModifierData *smd = (SmokeModifierData *)md;
+
+ if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) != 0)
+ return true;
+ }
+
+ /* if object has parents, update them too */
+ if (parent_recursion) {
+ int recursion = parent_recursion - 1;
+ bool no_update = false;
+ if (ob->parent) no_update |= BKE_object_modifier_update_subframe(scene, ob->parent, 0, recursion, frame, type);
+ if (ob->track) no_update |= BKE_object_modifier_update_subframe(scene, ob->track, 0, recursion, frame, type);
+
+ /* skip subframe if object is parented
+ * to vertex of a dynamic paint canvas */
+ if (no_update && (ob->partype == PARVERT1 || ob->partype == PARVERT3))
+ return false;
+
+ /* also update constraint targets */
+ for (con = ob->constraints.first; con; con = con->next) {
+ const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
+ ListBase targets = {NULL, NULL};
+
+ if (cti && cti->get_constraint_targets) {
+ bConstraintTarget *ct;
+ cti->get_constraint_targets(con, &targets);
+ for (ct = targets.first; ct; ct = ct->next) {
+ if (ct->tar)
+ BKE_object_modifier_update_subframe(scene, ct->tar, 0, recursion, frame, type);
+ }
+ /* free temp targets */
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
+ }
+ }
+ }
+
+ /* was originally OB_RECALC_ALL - TODO - which flags are really needed??? */
+ ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, frame, ADT_RECALC_ANIM);
+ if (update_mesh) {
+ /* ignore cache clear during subframe updates
+ * to not mess up cache validity */
+ object_cacheIgnoreClear(ob, 1);
+ BKE_object_handle_update(G.main->eval_ctx, scene, ob);
+ object_cacheIgnoreClear(ob, 0);
+ }
+ else
+ BKE_object_where_is_calc_time(scene, ob, frame);
+
+ /* for curve following objects, parented curve has to be updated too */
+ if (ob->type == OB_CURVE) {
+ Curve *cu = ob->data;
+ BKE_animsys_evaluate_animdata(scene, &cu->id, cu->adt, frame, ADT_RECALC_ANIM);
+ }
+ /* and armatures... */
+ if (ob->type == OB_ARMATURE) {
+ bArmature *arm = ob->data;
+ BKE_animsys_evaluate_animdata(scene, &arm->id, arm->adt, frame, ADT_RECALC_ANIM);
+ BKE_pose_where_is(scene, ob);
+ }
+
+ return false;
+}