Depsgraph: remove features incompatible with new system.

Some features are incompatible with multithreading and reliable evaluation
of dependencies. We are now removing them as part of a bigger cleanup to
fix bugs in keyframing and invalid animation evaluations.

* Dupliframes have been removed. This was a hack added before there were
  more powerful features like the array modifier.
* Slow parent has been removed, never worked in 2.8. It was always
  unreliable for use in production due to depending on whatever frame was
  previously evaluated, which was not always the previous frame.
* Particle instanced objects used to have their transform evaluated at
  the particle time. Now it always gets the current time transform.
* Boids can no longer do predictive avoidance of force field objects,
  but still for other particles.

Differential Revision: https://developer.blender.org/D4274
This commit is contained in:
Brecht Van Lommel 2019-01-28 17:52:46 +01:00
parent 3e072da45b
commit 7400aa7e59
15 changed files with 34 additions and 389 deletions

View File

@ -149,13 +149,6 @@ class OBJECT_PT_relations(ObjectButtonsPanel, Panel):
sub.prop_search(ob, "parent_bone", parent.data, "bones")
sub.active = (parent is not None)
col = flow.column()
col.active = (ob.parent is not None)
col.prop(ob, "use_slow_parent")
sub = col.column()
sub.active = (ob.use_slow_parent)
sub.prop(ob, "slow_parent_offset", text="Offset")
col.separator()
col = flow.column()
@ -295,20 +288,7 @@ class OBJECT_PT_duplication(ObjectButtonsPanel, Panel):
layout.use_property_split = True
flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
if ob.instance_type == 'FRAMES':
col = flow.column(align=True)
col.prop(ob, "instance_frames_start", text="Start")
col.prop(ob, "instance_frames_end", text="End")
col = flow.column(align=True)
col.prop(ob, "instance_frames_on", text="On")
col.prop(ob, "instance_frames_off", text="Off")
col = flow.column(align=True)
col.prop(ob, "use_instance_frames_speed", text="Speed")
elif ob.instance_type == 'VERTS':
if ob.instance_type == 'VERTS':
layout.prop(ob, "use_instance_vertices_rotation", text="Rotation")
elif ob.instance_type == 'FACES':

View File

@ -105,7 +105,6 @@ typedef struct EffectorCache {
/* precalculated for guides */
struct GuideEffectorData *guide_data;
float guide_loc[4], guide_dir[3], guide_radius;
float velocity[3];
float frame;
int flag;

View File

@ -159,8 +159,6 @@ struct Base **BKE_object_pose_base_array_get(struct ViewLayer *view_layer, struc
void BKE_object_get_parent_matrix(
struct Object *ob, struct Object *par, float parentmat[4][4]);
void BKE_object_get_parent_matrix_for_dupli(
struct Object *ob, struct Object *par, float dupli_ctime, int dupli_transflag, float parentmat[4][4]);
void BKE_object_where_is_calc(
struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
void BKE_object_where_is_calc_ex(
@ -168,10 +166,8 @@ void BKE_object_where_is_calc_ex(
struct Object *ob, float r_originmat[3][3]);
void BKE_object_where_is_calc_time(
struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, float ctime);
void BKE_object_where_is_calc_time_for_dupli(
struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, float ctime, int dupli_transflag);
void BKE_object_where_is_calc_time_ex(
struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, float ctime, int dupli_transflag,
struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, float ctime,
struct RigidBodyWorld *rbw, float r_originmat[3][3]);
void BKE_object_where_is_calc_mat4(struct Object *ob, float obmat[4][4]);

View File

@ -183,16 +183,6 @@ static void precalculate_effector(struct Depsgraph *depsgraph, EffectorCache *ef
}
else if (eff->psys)
psys_update_particle_tree(eff->psys, ctime);
/* Store object velocity */
if (eff->ob) {
float old_vel[3];
BKE_object_where_is_calc_time(depsgraph, eff->scene, eff->ob, cfra - 1.0f);
copy_v3_v3(old_vel, eff->ob->obmat[3]);
BKE_object_where_is_calc_time(depsgraph, eff->scene, eff->ob, cfra);
sub_v3_v3v3(eff->velocity, eff->ob->obmat[3], old_vel);
}
}
static void add_effector_relation(ListBase *relations, Object *ob, ParticleSystem *psys, PartDeflect *pd)
@ -690,9 +680,7 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
copy_v3_v3(efd->loc, ob->obmat[3]);
}
if (real_velocity) {
copy_v3_v3(efd->vel, eff->velocity);
}
zero_v3(efd->vel);
efd->size = 0.0f;
ret = 1;

View File

@ -857,8 +857,6 @@ void BKE_object_init(Object *ob)
ob->upflag = OB_POSZ;
}
ob->dupon = 1; ob->dupoff = 0;
ob->dupsta = 1; ob->dupend = 100;
ob->dupfacesca = 1.0;
ob->col_group = 0x01;
@ -1915,8 +1913,7 @@ 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 dupli_ctime, int dupli_transflag, float mat[4][4])
static bool ob_parcurve(Object *ob, Object *par, float mat[4][4])
{
Curve *cu = par->data;
float vec[4], dir[3], quat[4], radius, ctime;
@ -1936,29 +1933,19 @@ static bool ob_parcurve(Object *ob, Object *par,
return false;
}
/* catch exceptions: curve paths used as a duplicator */
if ((dupli_transflag & OB_DUPLINOSPEED) == 0) {
/* 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, to get a time
* factor, which then gets clamped to lie within 0.0 - 1.0 range
*/
if (cu->pathlen) {
ctime = cu->ctime / cu->pathlen;
}
else {
ctime = cu->ctime;
}
CLAMP(ctime, 0.0f, 1.0f);
/* 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, to get a time
* factor, which then gets clamped to lie within 0.0 - 1.0 range
*/
if (cu->pathlen) {
ctime = cu->ctime / cu->pathlen;
}
else {
ctime = dupli_ctime;
if (cu->pathlen) {
ctime /= cu->pathlen;
}
CLAMP(ctime, 0.0f, 1.0f);
ctime = cu->ctime;
}
CLAMP(ctime, 0.0f, 1.0f);
unit_m4(mat);
@ -2145,9 +2132,7 @@ static void ob_parvert3(Object *ob, Object *par, float mat[4][4])
}
}
void BKE_object_get_parent_matrix_for_dupli(Object *ob, Object *par,
float dupli_ctime, int dupli_transflag,
float parentmat[4][4])
void BKE_object_get_parent_matrix(Object *ob, Object *par, float parentmat[4][4])
{
float tmat[4][4];
float vec[3];
@ -2158,7 +2143,7 @@ void BKE_object_get_parent_matrix_for_dupli(Object *ob, Object *par,
ok = 0;
if (par->type == OB_CURVE) {
if ((((Curve *)par->data)->flag & CU_PATH) &&
(ob_parcurve(ob, par, dupli_ctime, dupli_transflag, tmat)))
(ob_parcurve(ob, par, tmat)))
{
ok = 1;
}
@ -2188,20 +2173,13 @@ void BKE_object_get_parent_matrix_for_dupli(Object *ob, Object *par,
copy_m4_m4(parentmat, par->obmat);
break;
}
}
void BKE_object_get_parent_matrix(Object *ob, Object *par, float parentmat[4][4])
{
BKE_object_get_parent_matrix_for_dupli(ob, par, 0, 0, parentmat);
}
/**
* \param r_originmat: Optional matrix that stores the space the object is in (without its own matrix applied)
*/
static void solve_parenting(Object *ob, Object *par, float obmat[4][4], float slowmat[4][4],
float r_originmat[3][3], const bool set_origin,
float dupli_ctime, int dupli_transflag)
static void solve_parenting(Object *ob, Object *par, float obmat[4][4],
float r_originmat[3][3], const bool set_origin)
{
float totmat[4][4];
float tmat[4][4];
@ -2209,9 +2187,7 @@ static void solve_parenting(Object *ob, Object *par, float obmat[4][4], float sl
BKE_object_to_mat4(ob, locmat);
if (ob->partype & PARSLOW) copy_m4_m4(slowmat, obmat);
BKE_object_get_parent_matrix_for_dupli(ob, par, dupli_ctime, dupli_transflag, totmat);
BKE_object_get_parent_matrix(ob, par, totmat);
/* total */
mul_m4_m4m4(tmat, totmat, ob->parentinv);
@ -2233,29 +2209,9 @@ static void solve_parenting(Object *ob, Object *par, float obmat[4][4], float sl
}
}
static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[4][4])
{
float *fp1, *fp2;
float fac1, fac2;
int a;
/* include framerate */
fac1 = (1.0f / (1.0f + fabsf(ob->sf)));
if (fac1 >= 1.0f) return false;
fac2 = 1.0f - fac1;
fp1 = obmat[0];
fp2 = slowmat[0];
for (a = 0; a < 16; a++, fp1++, fp2++) {
fp1[0] = fac1 * fp1[0] + fac2 * fp2[0];
}
return true;
}
/* note, scene is the active scene while actual_scene is the scene the object resides in */
void BKE_object_where_is_calc_time_ex(
Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime, int dupli_transflag,
Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime,
RigidBodyWorld *rbw, float r_originmat[3][3])
{
if (ob == NULL) return;
@ -2265,19 +2221,9 @@ void BKE_object_where_is_calc_time_ex(
if (ob->parent) {
Object *par = ob->parent;
float slowmat[4][4];
/* calculate parent matrix */
solve_parenting(ob, par, ob->obmat, slowmat, r_originmat, true,
ctime, dupli_transflag);
/* "slow parent" is definitely not threadsafe, and may also give bad results jumping around
* An old-fashioned hack which probably doesn't really cut it anymore
*/
if (ob->partype & PARSLOW) {
if (!where_is_object_parslow(ob, ob->obmat, slowmat))
return;
}
solve_parenting(ob, par, ob->obmat, r_originmat, true);
}
else {
BKE_object_to_mat4(ob, ob->obmat);
@ -2303,32 +2249,18 @@ void BKE_object_where_is_calc_time_ex(
void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime)
{
BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, ctime, 0, NULL, NULL);
BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, ctime, NULL, NULL);
}
void BKE_object_where_is_calc_time_for_dupli(
Depsgraph *depsgraph, Scene *scene, struct Object *ob, float ctime, int dupli_transflag)
{
BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, ctime, dupli_transflag, NULL, NULL);
}
/* get object transformation matrix without recalculating dependencies and
* constraints -- assume dependencies are already solved by depsgraph.
* no changes to object and it's parent would be done.
* used for bundles orientation in 3d space relative to parented blender camera */
void BKE_object_where_is_calc_mat4(Object *ob, float obmat[4][4])
{
if (ob->parent) {
float slowmat[4][4];
Object *par = ob->parent;
solve_parenting(ob, par, obmat, slowmat, NULL, false, 0.0f, 0);
if (ob->partype & PARSLOW)
where_is_object_parslow(ob, obmat, slowmat);
solve_parenting(ob, par, obmat, NULL, false);
}
else {
BKE_object_to_mat4(ob, obmat);
@ -2337,11 +2269,11 @@ void BKE_object_where_is_calc_mat4(Object *ob, float obmat[4][4])
void BKE_object_where_is_calc_ex(Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3])
{
BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, DEG_get_ctime(depsgraph), 0, rbw, r_originmat);
BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, DEG_get_ctime(depsgraph), rbw, r_originmat);
}
void BKE_object_where_is_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, DEG_get_ctime(depsgraph), 0, NULL, NULL);
BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, DEG_get_ctime(depsgraph), NULL, NULL);
}
/**

View File

@ -311,74 +311,6 @@ static const DupliGenerator gen_dupli_collection = {
make_duplis_collection /* make_duplis */
};
/* OB_DUPLIFRAMES */
static void make_duplis_frames(const DupliContext *ctx)
{
Depsgraph *depsgraph = ctx->depsgraph;
Scene *scene = ctx->scene;
Object *ob = ctx->object;
Object copyob;
int dupend = ob->dupend;
/* dupliframes not supported inside collections */
if (ctx->collection)
return;
/* if we don't have any data/settings which will lead to object movement,
* don't waste time trying, as it will all look the same...
*/
if (ob->parent == NULL && BLI_listbase_is_empty(&ob->constraints) && ob->adt == NULL)
return;
/* make a copy of the object's original data (before any dupli-data overwrites it)
* as we'll need this to keep track of unkeyed data
* - this doesn't take into account other data that can be reached from the object,
* for example it's shapekeys or bones, hence the need for an update flush at the end
*/
copyob = *ob;
/* duplicate over the required range */
const int dupli_transflag = (ob->transflag & OB_DUPLINOSPEED);
for (int frame = ob->dupsta; frame <= dupend; frame++) {
int ok = 1;
/* - dupoff = how often a frames within the range shouldn't be made into duplis
* - dupon = the length of each "skipping" block in frames
*/
if (ob->dupoff) {
ok = frame - ob->dupsta;
ok = ok % (ob->dupon + ob->dupoff);
ok = (ok < ob->dupon);
}
if (ok) {
/* WARNING: doing animation updates in this way is not terribly accurate, as the dependencies
* and/or other objects which may affect this object's transforms are not updated either.
* However, this has always been the way that this worked (i.e. pre 2.5), so I guess that it'll be fine!
*/
/* ob-eval will do drivers, so we don't need to do them */
BKE_animsys_evaluate_animdata(depsgraph, scene, &ob->id, ob->adt, (float)frame, ADT_RECALC_ANIM);
BKE_object_where_is_calc_time_for_dupli(depsgraph, scene, ob, (float)frame, dupli_transflag);
make_dupli(ctx, ob, ob->obmat, frame);
}
}
/* ob-eval will do drivers, so we don't need to do them */
const float original_ctime = DEG_get_ctime(depsgraph);
BKE_animsys_evaluate_animdata(depsgraph, scene, &ob->id, ob->adt, original_ctime, ADT_RECALC_ANIM);
BKE_object_where_is_calc_time(depsgraph, scene, ob, original_ctime);
/* but, to make sure unkeyed object transforms are still sane,
* let's copy object's original data back over
*/
*ob = copyob;
}
static const DupliGenerator gen_dupli_frames = {
OB_DUPLIFRAMES, /* type */
make_duplis_frames /* make_duplis */
};
/* OB_DUPLIVERTS */
typedef struct VertexDupliData {
Mesh *me_eval;
@ -791,7 +723,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
bool for_render = mode == DAG_EVAL_RENDER;
bool use_texcoords = for_render;
Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL;
Object *ob = NULL, **oblist = NULL;
DupliObject *dob;
ParticleDupliWeight *dw;
ParticleSettings *part;
@ -799,7 +731,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
ChildParticle *cpa = NULL;
ParticleKey state;
ParticleCacheKey *cache;
float ctime, pa_time, scale = 1.0f;
float ctime, scale = 1.0f;
float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size = 0.0;
float (*obmat)[4];
int a, b, hair = 0;
@ -896,10 +828,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
}
/* we also copy the actual objects to restore afterwards, since
* BKE_object_where_is_calc_time will change the object which breaks transform */
oblist = MEM_callocN((size_t)totcollection * sizeof(Object *), "dupcollection object list");
obcopylist = MEM_callocN((size_t)totcollection * sizeof(Object), "dupcollection copy list");
if (part->draw & PART_DRAW_COUNT_GR) {
a = 0;
@ -909,7 +838,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
if (dw->ob == object) {
for (b = 0; b < dw->count; b++, a++) {
oblist[a] = dw->ob;
obcopylist[a] = *dw->ob;
}
break;
}
@ -922,7 +850,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN(part->dup_group, object, mode)
{
oblist[a] = object;
obcopylist[a] = *object;
a++;
}
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
@ -930,7 +857,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
}
else {
ob = part->dup_ob;
obcopy = *ob;
}
if (totchild == 0 || part->draw & PART_DRAW_PARENT)
@ -945,7 +871,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
continue;
/* pa_num = pa->num; */ /* UNUSED */
pa_time = pa->time;
size = pa->size;
}
else {
@ -953,7 +878,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
cpa = &psys->child[a - totpart];
/* pa_num = a; */ /* UNUSED */
pa_time = psys->particles[cpa->parent].time;
size = psys_get_child_size(psys, cpa, ctime, NULL);
}
@ -1043,9 +967,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
}
else {
/* to give ipos in object correct offset */
BKE_object_where_is_calc_time(ctx->depsgraph, scene, ob, ctime - pa_time);
copy_v3_v3(vec, obmat[3]);
obmat[3][0] = obmat[3][1] = obmat[3][2] = 0.0f;
@ -1092,22 +1013,12 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
}
}
/* restore objects since they were changed in BKE_object_where_is_calc_time */
if (part->ren_as == PART_DRAW_GR) {
for (a = 0; a < totcollection; a++)
*(oblist[a]) = obcopylist[a];
}
else
*ob = obcopy;
BLI_rng_free(rng);
}
/* clean up */
if (oblist)
MEM_freeN(oblist);
if (obcopylist)
MEM_freeN(obcopylist);
if (psys->lattice_deform_data) {
end_latt_deform(psys->lattice_deform_data);
@ -1164,9 +1075,6 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
if (ctx->object->type == OB_MESH)
return &gen_dupli_faces;
}
else if (transflag & OB_DUPLIFRAMES) {
return &gen_dupli_frames;
}
else if (transflag & OB_DUPLICOLLECTION) {
return &gen_dupli_collection;
}
@ -1218,11 +1126,6 @@ int count_duplilist(Object *ob)
}
}
}
else if (ob->transflag & OB_DUPLIFRAMES) {
int tot = ob->dupend - ob->dupsta;
tot /= (ob->dupon + ob->dupoff);
return tot * ob->dupon;
}
}
return 1;
}

View File

@ -544,17 +544,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
}
}
if (bmain->versionfile <= 105) {
Object *ob = bmain->object.first;
while (ob) {
ob->dupon = 1;
ob->dupoff = 0;
ob->dupsta = 1;
ob->dupend = 100;
ob = ob->id.next;
}
}
if (bmain->versionfile <= 106) {
/* mcol changed */
Mesh *me = bmain->mesh.first;

View File

@ -115,7 +115,7 @@ static bool deg_object_hide_original(eEvaluationMode eval_mode, Object *ob, Dupl
* visible otherwise. The better solution eventually would be for objects
* to specify which object they instance, instead of through parenting. */
if (eval_mode == DAG_EVAL_RENDER || dob) {
const int hide_original_types = OB_DUPLIFRAMES | OB_DUPLIVERTS | OB_DUPLIFACES;
const int hide_original_types = OB_DUPLIVERTS | OB_DUPLIFACES;
if (!dob || !(dob->type & hide_original_types)) {
if (ob->parent && (ob->parent->transflag & hide_original_types)) {

View File

@ -65,8 +65,6 @@ void OBJECT_OT_parent_clear(struct wmOperatorType *ot);
void OBJECT_OT_vertex_parent_set(struct wmOperatorType *ot);
void OBJECT_OT_track_set(struct wmOperatorType *ot);
void OBJECT_OT_track_clear(struct wmOperatorType *ot);
void OBJECT_OT_slow_parent_set(struct wmOperatorType *ot);
void OBJECT_OT_slow_parent_clear(struct wmOperatorType *ot);
void OBJECT_OT_make_local(struct wmOperatorType *ot);
void OBJECT_OT_make_override_static(struct wmOperatorType *ot);
void OBJECT_OT_make_single_user(struct wmOperatorType *ot);

View File

@ -87,8 +87,6 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_parent_set);
WM_operatortype_append(OBJECT_OT_track_set);
WM_operatortype_append(OBJECT_OT_track_clear);
WM_operatortype_append(OBJECT_OT_slow_parent_set);
WM_operatortype_append(OBJECT_OT_slow_parent_clear);
WM_operatortype_append(OBJECT_OT_make_local);
WM_operatortype_append(OBJECT_OT_make_override_static);
WM_operatortype_append(OBJECT_OT_make_single_user);

View File

@ -1081,83 +1081,6 @@ void OBJECT_OT_parent_no_inverse_set(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/************************ Clear Slow Parent Operator *********************/
static int object_slow_parent_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
Scene *scene = CTX_data_scene(C);
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
if (ob->parent) {
if (ob->partype & PARSLOW) {
ob->partype -= PARSLOW;
BKE_object_where_is_calc(depsgraph, scene, ob);
ob->partype |= PARSLOW;
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
}
}
}
CTX_DATA_END;
WM_event_add_notifier(C, NC_SCENE, scene);
return OPERATOR_FINISHED;
}
void OBJECT_OT_slow_parent_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Clear Slow Parent";
ot->description = "Clear the object's slow parent";
ot->idname = "OBJECT_OT_slow_parent_clear";
/* api callbacks */
ot->invoke = WM_operator_confirm;
ot->exec = object_slow_parent_clear_exec;
ot->poll = ED_operator_view3d_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/********************** Make Slow Parent Operator *********************/
static int object_slow_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
if (ob->parent)
ob->partype |= PARSLOW;
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
}
CTX_DATA_END;
WM_event_add_notifier(C, NC_SCENE, scene);
return OPERATOR_FINISHED;
}
void OBJECT_OT_slow_parent_set(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Set Slow Parent";
ot->description = "Set the object's slow parent";
ot->idname = "OBJECT_OT_slow_parent_set";
/* api callbacks */
ot->invoke = WM_operator_confirm;
ot->exec = object_slow_parent_set_exec;
ot->poll = ED_operator_view3d_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Clear Track Operator ******************* */
enum {

View File

@ -387,12 +387,6 @@ static void stats_dupli_object(Object *ob, SceneStats *stats)
stats->totobj += tot;
stats_object(ob, is_selected, tot, stats);
}
else if (ob->transflag & OB_DUPLIFRAMES) {
/* Dupli Frames */
int tot = count_duplilist(ob);
stats->totobj += tot;
stats_object(ob, is_selected, tot, stats);
}
else if ((ob->transflag & OB_DUPLICOLLECTION) && ob->dup_group) {
/* Dupli Group */
int tot = count_duplilist(ob);

View File

@ -295,9 +295,6 @@ typedef struct Object {
char pad12;
char duplicator_visibility_flag;
/* dupli-frame settings */
int dupon, dupoff, dupsta, dupend;
/* Depsgraph */
/** Used by depsgraph, flushed from base. */
short base_flag;
@ -324,16 +321,13 @@ typedef struct Object {
/** Dupliface scale. */
float dupfacesca;
/** Sf is time-offset. */
float sf;
/** Custom index, for renderpasses. */
short index;
/** Current deformation group, note: index starts at 1. */
unsigned short actdef;
/** Current face map, note: index starts at 1. */
unsigned short actfmap;
unsigned char pad5[6];
unsigned char pad5[2];
/** Object color. */
float col[4];
@ -501,8 +495,7 @@ enum {
PARVERT3 = 6,
PARBONE = 7,
/** Slow parenting - is not threadsafe and/or may give errors after jumping. */
PARSLOW = 16,
PAR_DEPRECATED = 16,
};
/* (short) transflag */
@ -510,10 +503,10 @@ enum {
OB_TRANSFLAG_DEPRECATED_0 = 1 << 0,
OB_TRANSFLAG_DEPRECATED_1 = 1 << 1,
OB_NEG_SCALE = 1 << 2,
OB_DUPLIFRAMES = 1 << 3,
OB_TRANSFLAG_DEPRECATED_3 = 1 << 3,
OB_DUPLIVERTS = 1 << 4,
OB_DUPLIROT = 1 << 5,
OB_DUPLINOSPEED = 1 << 6,
OB_TRANSFLAG_DEPRECATED_4 = 1 << 6,
/* runtime, calculate derivedmesh for dupli before it's used */
OB_DUPLICALCDERIVED = 1 << 7,
OB_DUPLICOLLECTION = 1 << 8,
@ -526,7 +519,7 @@ enum {
/* hack to work around particle issue */
OB_NO_PSYS_UPDATE = 1 << 14,
OB_DUPLI = OB_DUPLIFRAMES | OB_DUPLIVERTS | OB_DUPLICOLLECTION | OB_DUPLIFACES | OB_DUPLIPARTS,
OB_DUPLI = OB_DUPLIVERTS | OB_DUPLICOLLECTION | OB_DUPLIFACES | OB_DUPLIPARTS,
};
/* (short) trackflag / upflag */

View File

@ -135,7 +135,6 @@ static const EnumPropertyItem parent_type_items[] = {
#define INSTANCE_ITEMS_SHARED \
{0, "NONE", 0, "None", ""}, \
{OB_DUPLIFRAMES, "FRAMES", 0, "Frames", "Make instance of object for every frame"}, \
{OB_DUPLIVERTS, "VERTS", 0, "Verts", "Instantiate child objects on all vertices"}, \
{OB_DUPLIFACES, "FACES", 0, "Faces", "Instantiate child objects on all faces"}
@ -2606,21 +2605,6 @@ static void rna_def_object(BlenderRNA *brna)
rna_def_animviz_common(srna);
rna_def_motionpath_common(srna);
/* slow parenting */
/* XXX: evil old crap */
prop = RNA_def_property(srna, "use_slow_parent", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "partype", PARSLOW);
RNA_def_property_ui_text(prop, "Slow Parent",
"Create a delay in the parent relationship (beware: this isn't renderfarm "
"safe and may be invalid after jumping around the timeline)");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
prop = RNA_def_property(srna, "slow_parent_offset", PROP_FLOAT, PROP_NONE | PROP_UNIT_TIME);
RNA_def_property_float_sdna(prop, NULL, "sf");
RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF);
RNA_def_property_ui_text(prop, "Slow Parent Offset", "Delay in the parent relationship");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
/* instancing */
prop = RNA_def_property(srna, "instance_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "transflag");
@ -2629,12 +2613,6 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Instance Type", "If not None, object instancing method to use");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_dependency_update");
prop = RNA_def_property(srna, "use_instance_frames_speed", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "transflag", OB_DUPLINOSPEED);
RNA_def_property_ui_text(prop, "Instance Frames Speed",
"Set frames instancing to use the current frame instead of parent curve's evaluation time");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
prop = RNA_def_property(srna, "use_instance_vertices_rotation", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_DUPLIROT);
RNA_def_property_ui_text(prop, "Instance Verts Rotation", "Rotate instance according to vertex normal");
@ -2659,32 +2637,6 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Instance Collection", "Instance an existing collection");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_dependency_update");
prop = RNA_def_property(srna, "instance_frames_start", PROP_INT, PROP_NONE | PROP_UNIT_TIME);
RNA_def_property_int_sdna(prop, NULL, "dupsta");
RNA_def_property_range(prop, MINAFRAME, MAXFRAME);
RNA_def_property_ui_text(prop, "Instance Frames Start", "Start frame for frame instances");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
prop = RNA_def_property(srna, "instance_frames_end", PROP_INT, PROP_NONE | PROP_UNIT_TIME);
RNA_def_property_int_sdna(prop, NULL, "dupend");
RNA_def_property_range(prop, MINAFRAME, MAXFRAME);
RNA_def_property_ui_text(prop, "Instance Frames End", "End frame for frame instances");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
prop = RNA_def_property(srna, "instance_frames_on", PROP_INT, PROP_NONE | PROP_UNIT_TIME);
RNA_def_property_int_sdna(prop, NULL, "dupon");
RNA_def_property_range(prop, 1, MAXFRAME);
RNA_def_property_ui_range(prop, 1, 1500, 1, -1);
RNA_def_property_ui_text(prop, "Instance Frames On", "Number of frames to use between DupOff frames");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
prop = RNA_def_property(srna, "instance_frames_off", PROP_INT, PROP_NONE | PROP_UNIT_TIME);
RNA_def_property_int_sdna(prop, NULL, "dupoff");
RNA_def_property_range(prop, 0, MAXFRAME);
RNA_def_property_ui_range(prop, 0, 1500, 1, -1);
RNA_def_property_ui_text(prop, "Instance Frames Off", "Recurring frames to exclude from the frame instances");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
prop = RNA_def_property(srna, "is_instancer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_DUPLI);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);

View File

@ -1234,7 +1234,7 @@ bool RE_allow_render_generic_object(Object *ob)
if (ob->transflag & OB_DUPLIPARTS) {
/* pass */ /* let particle system(s) handle showing vs. not showing */
}
else if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) {
else if (ob->transflag & OB_DUPLI) {
return false;
}
return true;