diff options
Diffstat (limited to 'source/blender/blenkernel/intern/object.c')
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 249 |
1 files changed, 152 insertions, 97 deletions
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 647aadf237c..ffb614fdf11 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -67,7 +67,7 @@ #include "BLI_linklist.h" #include "BLI_kdtree.h" -#include "BLF_translation.h" +#include "BLT_translation.h" #include "BKE_pbvh.h" #include "BKE_main.h" @@ -87,6 +87,7 @@ #include "BKE_effect.h" #include "BKE_fcurve.h" #include "BKE_group.h" +#include "BKE_icons.h" #include "BKE_key.h" #include "BKE_lamp.h" #include "BKE_lattice.h" @@ -457,6 +458,8 @@ void BKE_object_free_ex(Object *ob, bool do_id_user) free_path(ob->curve_cache->path); MEM_freeN(ob->curve_cache); } + + BKE_previewimg_free(&ob->preview); } void BKE_object_free(Object *ob) @@ -464,7 +467,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; @@ -969,19 +972,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); + /* BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(ob, id)); */ /* ob->type is already initialized... */ - ob = BKE_libblock_alloc(bmain, ID_OB, name); - - /* default object vars */ - ob->type = type; - ob->col[0] = ob->col[1] = ob->col[2] = 1.0; ob->col[3] = 1.0; @@ -1009,7 +1003,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; } @@ -1038,8 +1032,10 @@ 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; /* NT fluid sim defaults */ ob->fluidsimSettings = NULL; @@ -1048,6 +1044,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; } @@ -1557,6 +1569,9 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches) BKE_id_lib_local_paths(bmain, ob->id.lib, &obn->id); } + /* Do not copy object's preview (mostly due to the fact renderers create temp copy of objects). */ + obn->preview = NULL; + return obn; } @@ -1567,8 +1582,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 */ @@ -1593,6 +1607,8 @@ static void extern_local_object(Object *ob) id_lib_extern((ID *)psys->part); modifiers_foreachIDLink(ob, extern_local_object__modifiersForeachIDLink, NULL); + + ob->preview = NULL; } void BKE_object_make_local(Object *ob) @@ -1941,9 +1957,15 @@ void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], bool use_compat) } 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_to_quat(quat, mat); + axis_angle_to_quat(dquat, ob->drotAxis, ob->drotAngle); + invert_qt(dquat); + mul_qt_qtqt(quat, dquat, quat); + quat_to_axis_angle(ob->rotAxis, &ob->rotAngle, quat); break; } default: /* euler */ @@ -2074,24 +2096,29 @@ void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4]) /* extern */ int enable_cu_speed = 1; -static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4]) +/** + * \param scene: Used when curve cache needs to be calculated, or for dupli-frame time. + * \return success if \a mat is set. + */ +static bool ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4]) { - Curve *cu; + Curve *cu = par->data; float vec[4], dir[3], quat[4], radius, ctime; - - unit_m4(mat); - - cu = par->data; - if (par->curve_cache == NULL) /* only happens on reload file, but violates depsgraph still... fix! */ + + /* only happens on reload file, but violates depsgraph still... fix! */ + if (par->curve_cache == NULL) { + if (scene == NULL) { + return false; + } BKE_displist_make_curveTypes(scene, par, 0); - if (par->curve_cache->path == NULL) return; - - /* catch exceptions: feature for nla stride editing */ - if (ob->ipoflag & OB_DISABLE_PATH) { - ctime = 0.0f; } + + if (par->curve_cache->path == NULL) { + return false; + } + /* catch exceptions: curve paths used as a duplicator */ - else if (enable_cu_speed) { + if (enable_cu_speed) { /* 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... * @@ -2108,6 +2135,11 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4]) CLAMP(ctime, 0.0f, 1.0f); } else { + /* For dupli-frames only */ + if (scene == NULL) { + return false; + } + ctime = BKE_scene_frame_get(scene); if (cu->pathlen) { ctime /= cu->pathlen; @@ -2116,6 +2148,8 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4]) CLAMP(ctime, 0.0f, 1.0f); } + unit_m4(mat); + /* vec: 4 items! */ if (where_on_path(par, ctime, vec, dir, (cu->flag & CU_FOLLOW) ? quat : NULL, &radius, NULL)) { @@ -2149,6 +2183,8 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4]) copy_v3_v3(mat[3], vec); } + + return true; } static void ob_parbone(Object *ob, Object *par, float mat[4][4]) @@ -2365,8 +2401,9 @@ void BKE_object_get_parent_matrix(Scene *scene, Object *ob, Object *par, float p case PAROBJECT: ok = 0; if (par->type == OB_CURVE) { - if (scene && ((Curve *)par->data)->flag & CU_PATH) { - ob_parcurve(scene, ob, par, tmat); + if ((((Curve *)par->data)->flag & CU_PATH) && + (ob_parcurve(scene, ob, par, tmat))) + { ok = 1; } } @@ -2631,6 +2668,76 @@ void BKE_boundbox_calc_size_aabb(const BoundBox *bb, float r_size[3]) r_size[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]); } +void BKE_boundbox_minmax(const BoundBox *bb, float obmat[4][4], float r_min[3], float r_max[3]) +{ + int i; + for (i = 0; i < 8; i++) { + float vec[3]; + mul_v3_m4v3(vec, obmat, bb->vec[i]); + minmax_v3v3_v3(r_min, r_max, vec); + } +} + +/** + * 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. + * + * \param bb the input bbox to check. + * \param bb_temp the temp bbox to modify (\a bb content is never changed). + * \param epsilon the minimum dimension to ensure. + * \return either bb (if nothing needed to be changed) or bb_temp. + */ +BoundBox *BKE_boundbox_ensure_minimum_dimensions(BoundBox *bb, BoundBox *bb_temp, const float epsilon) +{ + if (fabsf(bb->vec[0][0] - bb->vec[4][0]) < epsilon) { + /* Flat along X axis... */ + *bb_temp = *bb; + bb = bb_temp; + bb->vec[0][0] -= epsilon; + bb->vec[1][0] -= epsilon; + bb->vec[2][0] -= epsilon; + bb->vec[3][0] -= epsilon; + bb->vec[4][0] += epsilon; + bb->vec[5][0] += epsilon; + bb->vec[6][0] += epsilon; + bb->vec[7][0] += epsilon; + } + + if (fabsf(bb->vec[0][1] - bb->vec[3][1]) < epsilon) { + /* Flat along Y axis... */ + if (bb != bb_temp) { + *bb_temp = *bb; + bb = bb_temp; + } + bb->vec[0][1] -= epsilon; + bb->vec[1][1] -= epsilon; + bb->vec[4][1] -= epsilon; + bb->vec[5][1] -= epsilon; + bb->vec[2][1] += epsilon; + bb->vec[3][1] += epsilon; + bb->vec[6][1] += epsilon; + bb->vec[7][1] += epsilon; + } + + if (fabsf(bb->vec[0][2] - bb->vec[1][2]) < epsilon) { + /* Flat along Z axis... */ + if (bb != bb_temp) { + *bb_temp = *bb; + bb = bb_temp; + } + bb->vec[0][2] -= epsilon; + bb->vec[3][2] -= epsilon; + bb->vec[4][2] -= epsilon; + bb->vec[7][2] -= epsilon; + bb->vec[1][2] += epsilon; + bb->vec[2][2] += epsilon; + bb->vec[5][2] += epsilon; + bb->vec[6][2] += epsilon; + } + + return bb; +} + BoundBox *BKE_object_boundbox_get(Object *ob) { BoundBox *bb = NULL; @@ -2644,6 +2751,12 @@ BoundBox *BKE_object_boundbox_get(Object *ob) else if (ob->type == OB_MBALL) { bb = ob->bb; } + else if (ob->type == OB_LATTICE) { + bb = BKE_lattice_boundbox_get(ob); + } + else if (ob->type == OB_ARMATURE) { + bb = BKE_armature_boundbox_get(ob); + } return bb; } @@ -2700,7 +2813,6 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const bool us { BoundBox bb; float vec[3]; - int a; bool changed = false; switch (ob->type) { @@ -2709,11 +2821,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const bool us case OB_SURF: { bb = *BKE_curve_boundbox_get(ob); - - for (a = 0; a < 8; a++) { - mul_m4_v3(ob->obmat, bb.vec[a]); - minmax_v3v3_v3(min_r, max_r, bb.vec[a]); - } + BKE_boundbox_minmax(&bb, ob->obmat, min_r, max_r); changed = true; break; } @@ -2736,23 +2844,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const bool us } case OB_ARMATURE: { - if (ob->pose) { - bArmature *arm = ob->data; - bPoseChannel *pchan; - - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - /* XXX pchan->bone may be NULL for duplicated bones, see duplicateEditBoneObjects() comment - * (editarmature.c:2592)... Skip in this case too! */ - if (pchan->bone && !((use_hidden == false) && (PBONE_VISIBLE(arm, pchan->bone) == false))) { - mul_v3_m4v3(vec, ob->obmat, pchan->pose_head); - minmax_v3v3_v3(min_r, max_r, vec); - mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail); - minmax_v3v3_v3(min_r, max_r, vec); - - changed = true; - } - } - } + changed = BKE_pose_minmax(ob, min_r, max_r, use_hidden, false); break; } case OB_MESH: @@ -2761,11 +2853,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const bool us if (me) { bb = *BKE_mesh_boundbox_get(ob); - - for (a = 0; a < 8; a++) { - mul_m4_v3(ob->obmat, bb.vec[a]); - minmax_v3v3_v3(min_r, max_r, bb.vec[a]); - } + BKE_boundbox_minmax(&bb, ob->obmat, min_r, max_r); changed = true; } break; @@ -3641,38 +3729,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; @@ -3988,9 +4044,8 @@ bool BKE_object_modifier_use_time(Object *ob, ModifierData *md) AnimData *adt = ob->adt; FCurve *fcu; - char pattern[MAX_NAME + 10]; - /* TODO(sergey): Escape modifier name. */ - BLI_snprintf(pattern, sizeof(pattern), "modifiers[%s", md->name); + char pattern[MAX_NAME + 16]; + BLI_snprintf(pattern, sizeof(pattern), "modifiers[\"%s\"]", md->name); /* action - check for F-Curves with paths containing 'modifiers[' */ if (adt->action) { |