Depsgraph: Remove all layer bit flags related checks

These bits became obsolete with the new layer system, so we can
simplify some code around them or avoid existing workarounds which
were trying to keep things working for them.

There are still work needed to be done for on_visible_change to
avoid unnecessary updates, but that can also happen later.
This commit is contained in:
2017-04-05 11:11:44 +02:00
parent 1f6037c887
commit ba5b792dd9
42 changed files with 84 additions and 438 deletions

View File

@@ -588,5 +588,5 @@ void AbcExporter::setCurrentFrame(Main *bmain, double t)
{
m_scene->r.cfra = static_cast<int>(t);
m_scene->r.subframe = static_cast<float>(t) - m_scene->r.cfra;
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, m_scene, m_scene->lay);
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, m_scene);
}

View File

@@ -296,8 +296,7 @@ static void export_startjob(void *customdata, short *stop, short *do_update, flo
if (CFRA != orig_frame) {
CFRA = orig_frame;
BKE_scene_update_for_newframe(data->bmain->eval_ctx, data->bmain,
scene, scene->lay);
BKE_scene_update_for_newframe(data->bmain->eval_ctx, data->bmain, scene);
}
}
catch (const std::exception &e) {

View File

@@ -148,7 +148,7 @@ void collision_get_collider_velocity(float vel_old[3], float vel_new[3], struct
/////////////////////////////////////////////////
/* explicit control over layer mask and dupli recursion */
struct Object **get_collisionobjects_ext(struct Scene *scene, struct Object *self, struct Group *group, int layer, unsigned int *numcollobj, unsigned int modifier_type, bool dupli);
struct Object **get_collisionobjects_ext(struct Scene *scene, struct Object *self, struct Group *group, unsigned int *numcollobj, unsigned int modifier_type, bool dupli);
struct Object **get_collisionobjects(struct Scene *scene, struct Object *self, struct Group *group, unsigned int *numcollobj, unsigned int modifier_type);

View File

@@ -132,8 +132,7 @@ void BKE_scene_frame_set(struct Scene *scene, double cfra);
/* ** Scene evaluation ** */
void BKE_scene_update_tagged(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce);
void BKE_scene_update_for_newframe(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, unsigned int lay);
void BKE_scene_update_for_newframe_ex(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, unsigned int lay, bool do_invisible_flush);
void BKE_scene_update_for_newframe(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce);
struct SceneRenderLayer *BKE_scene_add_render_layer(struct Scene *sce, const char *name);
bool BKE_scene_remove_render_layer(struct Main *main, struct Scene *scene, struct SceneRenderLayer *srl);

View File

@@ -318,7 +318,7 @@ static void motionpaths_calc_update_scene(Scene *scene)
/* rigid body simulation needs complete update to work correctly for now */
/* RB_TODO investigate if we could avoid updating everything */
if (BKE_scene_check_rigidbody_active(scene)) {
BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene, scene->lay);
BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene);
}
else { /* otherwise we can optimize by restricting updates */
BaseLegacy *base, *last = NULL;
@@ -353,7 +353,7 @@ static void motionpaths_calc_update_scene(Scene *scene)
* that doesn't force complete update, but for now, this is the
* most accurate way!
*/
BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene, scene->lay); /* XXX this is the best way we can get anything moving */
BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene); /* XXX this is the best way we can get anything moving */
#endif
}

View File

@@ -512,7 +512,7 @@ static void add_collision_object(Object ***objs, unsigned int *numobj, unsigned
// return all collision objects in scene
// collision object will exclude self
Object **get_collisionobjects_ext(Scene *scene, Object *self, Group *group, int UNUSED(layer), unsigned int *numcollobj, unsigned int modifier_type, bool dupli)
Object **get_collisionobjects_ext(Scene *scene, Object *self, Group *group, unsigned int *numcollobj, unsigned int modifier_type, bool dupli)
{
Base *base;
Object **objs;
@@ -547,7 +547,7 @@ Object **get_collisionobjects(Scene *scene, Object *self, Group *group, unsigned
{
/* Need to check for active layers, too.
Otherwise this check fails if the objects are not on the same layer - DG */
return get_collisionobjects_ext(scene, self, group, self->lay | scene->lay, numcollobj, modifier_type, true);
return get_collisionobjects_ext(scene, self, group, numcollobj, modifier_type, true);
}
static void add_collider_cache_object(ListBase **objs, Object *ob, Object *self, int level)

View File

@@ -3654,7 +3654,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
stime = ptime = PIL_check_seconds_timer();
for (int fr = CFRA; fr <= endframe; fr += baker->quick_step, CFRA = fr) {
BKE_scene_update_for_newframe(G.main->eval_ctx, bmain, scene, scene->lay);
BKE_scene_update_for_newframe(G.main->eval_ctx, bmain, scene);
if (baker->update_progress) {
float progress = ((float)(CFRA - startframe)/(float)(endframe - startframe));
@@ -3740,7 +3740,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
CFRA = cfrao;
if (bake) { /* already on cfra unless baking */
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
}
/* TODO: call redraw all windows somehow */

View File

@@ -1520,12 +1520,7 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
}
/* applies changes right away, does all sets too */
void BKE_scene_update_for_newframe(EvaluationContext *eval_ctx, Main *bmain, Scene *sce, unsigned int lay)
{
BKE_scene_update_for_newframe_ex(eval_ctx, bmain, sce, lay, false);
}
void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain, Scene *sce, unsigned int lay, bool UNUSED(do_invisible_flush))
void BKE_scene_update_for_newframe(EvaluationContext *eval_ctx, Main *bmain, Scene *sce)
{
float ctime = BKE_scene_frame_get(sce);
Scene *sce_iter;
@@ -1564,7 +1559,7 @@ void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain,
BKE_main_id_tag_idcode(bmain, ID_LA, LIB_TAG_DOIT, false);
/* BKE_object_handle_update() on all objects, groups and sets */
DEG_evaluate_on_framechange(eval_ctx, bmain, sce->depsgraph, ctime, lay);
DEG_evaluate_on_framechange(eval_ctx, bmain, sce->depsgraph, ctime);
/* update sound system animation (TODO, move to depsgraph) */
BKE_sound_update_scene(bmain, sce);

View File

@@ -3302,7 +3302,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
context->scene->r.seq_prev_type = 3 /* == OB_SOLID */;
/* opengl offscreen render */
BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene, scene->lay);
BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene);
ibuf = sequencer_view3d_cb(
/* set for OpenGL render (NULL when scrubbing) */
scene, BKE_scene_layer_render_active(scene), camera, width, height, IB_rect,
@@ -3335,7 +3335,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
if (re == NULL)
re = RE_NewRender(scene->id.name);
BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene, scene->lay);
BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene);
RE_BlenderFrame(re, context->bmain, scene, NULL, camera, scene->lay, frame, false);
/* restore previous state after it was toggled on & off by RE_BlenderFrame */
@@ -3395,7 +3395,7 @@ finally:
scene->r.subframe = orig_data.subframe;
if (is_frame_update) {
BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene, scene->lay);
BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene);
}
#ifdef DURIAN_CAMERA_SWITCH

View File

@@ -938,7 +938,7 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
float ctime = BKE_scene_frame_get_from_ctime(scene, *it);
CFRA = BKE_scene_frame_get_from_ctime(scene, *it);
//BKE_scene_update_for_newframe(G.main->eval_ctx, G.main,scene,scene->lay);
//BKE_scene_update_for_newframe(G.main->eval_ctx, G.main,scene);
BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_ALL);
if (bone) {

View File

@@ -167,16 +167,13 @@ void DEG_evaluation_context_free(struct EvaluationContext *eval_ctx);
void DEG_evaluate_on_framechange(struct EvaluationContext *eval_ctx,
struct Main *bmain,
Depsgraph *graph,
float ctime,
const unsigned int layer);
float ctime);
/* Data changed recalculation entry point.
* < context_type: context to perform evaluation for
* < layers: visible layers bitmask to update the graph for
*/
void DEG_evaluate_on_refresh_ex(struct EvaluationContext *eval_ctx,
Depsgraph *graph,
const unsigned int layers);
Depsgraph *graph);
/* Data changed recalculation entry point.
* < context_type: context to perform evaluation for

View File

@@ -163,7 +163,6 @@ void DEG_add_collision_relations(struct DepsNodeHandle *handle,
struct Scene *scene,
Object *ob,
struct Group *group,
int layer,
unsigned int modifier_type,
DEG_CollobjFilterFunction fn,
bool dupli,

View File

@@ -60,119 +60,21 @@ string deg_fcurve_id_name(const FCurve *fcu)
return string(fcu->rna_path) + index_buf;
}
static bool check_object_needs_evaluation(Object *object)
{
if (object->recalc & OB_RECALC_ALL) {
/* Object is tagged for update anyway, no need to re-tag it. */
return false;
}
if (object->type == OB_MESH) {
return object->derivedFinal == NULL;
}
else if (ELEM(object->type,
OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE))
{
return object->curve_cache == NULL;
}
return false;
}
void deg_graph_build_flush_layers(Depsgraph *graph)
{
std::stack<OperationDepsNode *> stack;
foreach (OperationDepsNode *node, graph->operations) {
IDDepsNode *id_node = node->owner->owner;
node->done = 0;
node->num_links_pending = 0;
foreach (DepsRelation *rel, node->outlinks) {
if ((rel->from->type == DEPSNODE_TYPE_OPERATION) &&
(rel->flag & DEPSREL_FLAG_CYCLIC) == 0)
{
++node->num_links_pending;
}
}
if (node->num_links_pending == 0) {
stack.push(node);
node->done = 1;
}
node->owner->layers = id_node->layers;
id_node->id->tag |= LIB_TAG_DOIT;
}
while (!stack.empty()) {
OperationDepsNode *node = stack.top();
stack.pop();
/* Flush layers to parents. */
foreach (DepsRelation *rel, node->inlinks) {
if (rel->from->type == DEPSNODE_TYPE_OPERATION) {
OperationDepsNode *from = (OperationDepsNode *)rel->from;
from->owner->layers |= node->owner->layers;
}
}
/* Schedule parent nodes. */
foreach (DepsRelation *rel, node->inlinks) {
if (rel->from->type == DEPSNODE_TYPE_OPERATION) {
OperationDepsNode *from = (OperationDepsNode *)rel->from;
if ((rel->flag & DEPSREL_FLAG_CYCLIC) == 0) {
BLI_assert(from->num_links_pending > 0);
--from->num_links_pending;
}
if (from->num_links_pending == 0 && from->done == 0) {
stack.push(from);
from->done = 1;
}
}
}
}
}
void deg_graph_build_finalize(Depsgraph *graph)
{
/* STEP 1: Make sure new invisible dependencies are ready for use.
*
* TODO(sergey): This might do a bit of extra tagging, but it's kinda nice
* to do it ahead of a time and don't spend time on flushing updates on
* every frame change.
*/
GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, graph->id_hash)
{
if (id_node->layers == 0) {
ID *id = id_node->id;
if (GS(id->name) == ID_OB) {
Object *object = (Object *)id;
if (check_object_needs_evaluation(object)) {
id_node->tag_update(graph);
}
}
}
}
GHASH_FOREACH_END();
/* STEP 2: Flush visibility layers from children to parent. */
deg_graph_build_flush_layers(graph);
/* STEP 3: Re-tag IDs for update if it was tagged before the relations
/* Re-tag IDs for update if it was tagged before the relations
* update tag.
*/
GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, graph->id_hash)
{
GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp, id_node->components)
{
id_node->layers |= comp->layers;
}
GHASH_FOREACH_END();
if ((id_node->layers & graph->layers) != 0 || graph->layers == 0) {
ID *id = id_node->id;
if ((id->tag & LIB_TAG_ID_RECALC_ALL) &&
(id->tag & LIB_TAG_DOIT))
{
if ((id->tag & LIB_TAG_ID_RECALC_ALL)) {
id_node->tag_update(graph);
id->tag &= ~LIB_TAG_DOIT;
}
else if (GS(id->name) == ID_OB) {
Object *object = (Object *)id;
if (object->recalc & OB_RECALC_ALL) {
id_node->tag_update(graph);
id->tag &= ~LIB_TAG_DOIT;
}
}
}
id_node->finalize_build();

View File

@@ -42,6 +42,5 @@ struct Depsgraph;
string deg_fcurve_id_name(const FCurve *fcu);
void deg_graph_build_finalize(struct Depsgraph *graph);
void deg_graph_build_flush_layers(struct Depsgraph *graph);
} // namespace DEG

View File

@@ -387,29 +387,14 @@ SubgraphDepsNode *DepsgraphNodeBuilder::build_subgraph(Group *group)
void DepsgraphNodeBuilder::build_object(Scene *scene, Object *ob)
{
const bool has_object = (ob->id.tag & LIB_TAG_DOIT);
IDDepsNode *id_node = (has_object)
? m_graph->find_id_node(&ob->id)
: add_id_node(&ob->id);
/* Update node layers.
* Do it for both new and existing ID nodes. This is so because several
* bases might be sharing same object.
*/
/* Blender 2.8 transition: we don't have bases and do not have
* layer masks, but still want objects to be updated
*/
id_node->layers |= ((1 << 20) - 1);
if (ob == scene->camera) {
/* Camera should always be updated, it used directly by viewport. */
id_node->layers |= (unsigned int)(-1);
}
/* Skip rest of components if the ID node was already there. */
if (has_object) {
if (ob->id.tag & LIB_TAG_DOIT) {
return;
}
ob->id.tag |= LIB_TAG_DOIT;
/* Create ID node for obejct and begin init. */
IDDepsNode *id_node = add_id_node(&ob->id);
ob->customdata_mask = 0;
/* Standard components. */

View File

@@ -274,10 +274,10 @@ void DepsgraphRelationBuilder::add_operation_relation(
}
}
void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, int layer, bool dupli, const char *name)
void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, bool dupli, const char *name)
{
unsigned int numcollobj;
Object **collobjs = get_collisionobjects_ext(scene, ob, group, layer, &numcollobj, eModifierType_Collision, dupli);
Object **collobjs = get_collisionobjects_ext(scene, ob, group, &numcollobj, eModifierType_Collision, dupli);
for (unsigned int i = 0; i < numcollobj; i++)
{
@@ -329,7 +329,7 @@ void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key,
}
if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) {
add_collision_relations(key, scene, ob, NULL, eff->ob->lay, true, "Force Absorption");
add_collision_relations(key, scene, ob, NULL, true, "Force Absorption");
}
}
}
@@ -1308,10 +1308,10 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
/* collisions */
if (part->type != PART_HAIR) {
add_collision_relations(psys_key, scene, ob, part->collision_group, ob->lay, true, "Particle Collision");
add_collision_relations(psys_key, scene, ob, part->collision_group, true, "Particle Collision");
}
else if ((psys->flag & PSYS_HAIR_DYNAMICS) && psys->clmd && psys->clmd->coll_parms) {
add_collision_relations(psys_key, scene, ob, psys->clmd->coll_parms->group, ob->lay | scene->lay, true, "Hair Collision");
add_collision_relations(psys_key, scene, ob, psys->clmd->coll_parms->group, true, "Hair Collision");
}
/* effectors */

View File

@@ -232,7 +232,7 @@ struct DepsgraphRelationBuilder
void build_mask(Mask *mask);
void build_movieclip(MovieClip *clip);
void add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, int layer, bool dupli, const char *name);
void add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, bool dupli, const char *name);
void add_forcefield_relations(const OperationKey &key, Scene *scene, Object *ob, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name);
struct LayerCollectionState {

View File

@@ -287,12 +287,6 @@ static void deg_debug_graphviz_node_single(const DebugContext &ctx,
const char *shape = "box";
string name = node->identifier();
float priority = -1.0f;
if (node->type == DEPSNODE_TYPE_ID_REF) {
IDDepsNode *id_node = (IDDepsNode *)node;
char buf[256];
BLI_snprintf(buf, sizeof(buf), " (Layers: %u)", id_node->layers);
name += buf;
}
if (ctx.show_eval_priority && node->tclass == DEPSNODE_CLASS_OPERATION) {
priority = ((OperationDepsNode *)node)->eval_priority;
}
@@ -323,12 +317,6 @@ static void deg_debug_graphviz_node_cluster_begin(const DebugContext &ctx,
const DepsNode *node)
{
string name = node->identifier();
if (node->type == DEPSNODE_TYPE_ID_REF) {
IDDepsNode *id_node = (IDDepsNode *)node;
char buf[256];
BLI_snprintf(buf, sizeof(buf), " (Layers: %u)", id_node->layers);
name += buf;
}
deg_debug_fprintf(ctx, "// %s\n", name.c_str());
deg_debug_fprintf(ctx, "subgraph \"cluster_%p\" {" NL, node);
// deg_debug_fprintf(ctx, "label=<<B>%s</B>>;" NL, name);

View File

@@ -70,8 +70,7 @@ static DEG_EditorUpdateScenePreCb deg_editor_update_scene_pre_cb = NULL;
Depsgraph::Depsgraph()
: root_node(NULL),
need_update(false),
layers(0)
need_update(false)
{
BLI_spin_init(&lock);
id_hash = BLI_ghash_ptr_new("Depsgraph id hash");

View File

@@ -172,11 +172,6 @@ struct Depsgraph {
*/
SpinLock lock;
/* Layers Visibility .................. */
/* Visible layers bitfield, used for skipping invisible objects updates. */
unsigned int layers;
// XXX: additional stuff like eval contexts, mempools for allocating nodes from, etc.
};

View File

@@ -330,14 +330,13 @@ void DEG_add_collision_relations(DepsNodeHandle *handle,
Scene *scene,
Object *ob,
Group *group,
int layer,
unsigned int modifier_type,
DEG_CollobjFilterFunction fn,
bool dupli,
const char *name)
{
unsigned int numcollobj;
Object **collobjs = get_collisionobjects_ext(scene, ob, group, layer, &numcollobj, modifier_type, dupli);
Object **collobjs = get_collisionobjects_ext(scene, ob, group, &numcollobj, modifier_type, dupli);
for (unsigned int i = 0; i < numcollobj; i++) {
Object *ob1 = collobjs[i];
@@ -392,7 +391,6 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle,
scene,
ob,
NULL,
eff->ob->lay,
eModifierType_Collision,
NULL,
true,

View File

@@ -93,22 +93,14 @@ void DEG_evaluate_on_refresh(EvaluationContext *eval_ctx,
/* Update time on primary timesource. */
DEG::TimeSourceDepsNode *tsrc = deg_graph->find_time_source();
tsrc->cfra = BKE_scene_frame_get(scene);
unsigned int layers = deg_graph->layers;
/* XXX(sergey): This works around missing updates in temp scenes used
* by various scripts, but is weak and needs closer investigation.
*/
if (layers == 0) {
layers = scene->lay;
}
DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph, layers);
DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph);
}
/* Frame-change happened for root scene that graph belongs to. */
void DEG_evaluate_on_framechange(EvaluationContext *eval_ctx,
Main *bmain,
Depsgraph *graph,
float ctime,
const unsigned int layers)
float ctime)
{
DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
/* Update time on primary timesource. */
@@ -117,7 +109,7 @@ void DEG_evaluate_on_framechange(EvaluationContext *eval_ctx,
tsrc->tag_update(deg_graph);
DEG::deg_graph_flush_updates(bmain, deg_graph);
/* Perform recalculation updates. */
DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph, layers);
DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph);
}
bool DEG_needs_eval(Depsgraph *graph)

View File

@@ -290,86 +290,14 @@ void DEG_ids_flush_tagged(Main *bmain)
/* Update dependency graph when visible scenes/layers changes. */
void DEG_graph_on_visible_update(Main *bmain, Scene *scene)
{
(void) bmain;
DEG::Depsgraph *graph = reinterpret_cast<DEG::Depsgraph *>(scene->depsgraph);
wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
int old_layers = graph->layers;
if (wm != NULL) {
BKE_main_id_tag_listbase(&bmain->scene, LIB_TAG_DOIT, true);
graph->layers = 0;
for (wmWindow *win = (wmWindow *)wm->windows.first;
win != NULL;
win = (wmWindow *)win->next)
{
Scene *scene = win->screen->scene;
if (scene->id.tag & LIB_TAG_DOIT) {
graph->layers |= BKE_screen_visible_layers(win->screen, scene);
scene->id.tag &= ~LIB_TAG_DOIT;
}
}
}
else {
/* All the layers for background render for now. */
graph->layers = (1 << 20) - 1;
}
if (old_layers != graph->layers) {
/* Tag all objects which becomes visible (or which becomes needed for dependencies)
* for recalc.
*
* This is mainly needed on file load only, after that updates of invisible objects
* will be stored in the pending list.
*/
GHASH_FOREACH_BEGIN(DEG::IDDepsNode *, id_node, graph->id_hash)
{
ID *id = id_node->id;
if ((id->tag & LIB_TAG_ID_RECALC_ALL) != 0 ||
(id_node->layers & scene->lay_updated) == 0)
{
id_node->tag_update(graph);
}
/* A bit of magic: if object->recalc is set it means somebody tagged
* it for update. If corresponding ID recalc flags are zero it means
* graph has been evaluated after that and the recalc was skipped
* because of visibility check.
*/
if (GS(id->name) == ID_OB) {
Object *object = (Object *)id;
if ((id->tag & LIB_TAG_ID_RECALC_ALL) == 0 &&
(object->recalc & OB_RECALC_ALL) != 0)
{
id_node->tag_update(graph);
DEG::ComponentDepsNode *anim_comp =
id_node->find_component(DEG::DEPSNODE_TYPE_ANIMATION);
if (anim_comp != NULL && object->recalc & OB_RECALC_TIME) {
anim_comp->tag_update(graph);
}
}
}
}
GHASH_FOREACH_END();
}
scene->lay_updated |= graph->layers;
/* Special trick to get local view to work. */
LINKLIST_FOREACH (Base *, base, &scene->base) {
Object *object = base->object;
DEG::IDDepsNode *id_node = graph->find_id_node(&object->id);
id_node->layers = 0;
}
LINKLIST_FOREACH (Base *, base, &scene->base) {
Object *object = base->object;
DEG::IDDepsNode *id_node = graph->find_id_node(&object->id);
id_node->layers |= base->lay;
}
DEG::deg_graph_build_flush_layers(graph);
LINKLIST_FOREACH (Base *, base, &scene->base) {
Object *object = base->object;
DEG::IDDepsNode *id_node = graph->find_id_node(&object->id);
GHASH_FOREACH_BEGIN(DEG::ComponentDepsNode *, comp, id_node->components)
{
id_node->layers |= comp->layers;
}
GHASH_FOREACH_END();
}
}
void DEG_on_visible_update(Main *bmain, const bool UNUSED(do_time))
{

View File

@@ -73,13 +73,11 @@ namespace DEG {
static void schedule_children(TaskPool *pool,
Depsgraph *graph,
OperationDepsNode *node,
const unsigned int layers,
const int thread_id);
struct DepsgraphEvalState {
EvaluationContext *eval_ctx;
Depsgraph *graph;
unsigned int layers;
};
static void deg_task_run_func(TaskPool *pool,
@@ -126,38 +124,30 @@ static void deg_task_run_func(TaskPool *pool,
#endif
}
schedule_children(pool, state->graph, node, state->layers, thread_id);
schedule_children(pool, state->graph, node, thread_id);
}
typedef struct CalculatePengindData {
Depsgraph *graph;
unsigned int layers;
} CalculatePengindData;
static void calculate_pending_func(void *data_v, int i)
{
CalculatePengindData *data = (CalculatePengindData *)data_v;
Depsgraph *graph = data->graph;
unsigned int layers = data->layers;
OperationDepsNode *node = graph->operations[i];
IDDepsNode *id_node = node->owner->owner;
node->num_links_pending = 0;
node->scheduled = false;
/* count number of inputs that need updates */
if ((id_node->layers & layers) != 0 &&
(node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0)
{
if ((node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) {
foreach (DepsRelation *rel, node->inlinks) {
if (rel->from->type == DEPSNODE_TYPE_OPERATION &&
(rel->flag & DEPSREL_FLAG_CYCLIC) == 0)
{
OperationDepsNode *from = (OperationDepsNode *)rel->from;
IDDepsNode *id_from_node = from->owner->owner;
if ((id_from_node->layers & layers) != 0 &&
(from->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0)
{
if ((from->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) {
++node->num_links_pending;
}
}
@@ -165,13 +155,12 @@ static void calculate_pending_func(void *data_v, int i)
}
}
static void calculate_pending_parents(Depsgraph *graph, unsigned int layers)
static void calculate_pending_parents(Depsgraph *graph)
{
const int num_operations = graph->operations.size();
const bool do_threads = num_operations > 256;
CalculatePengindData data;
data.graph = graph;
data.layers = layers;
BLI_task_parallel_range(0,
num_operations,
&data,
@@ -210,15 +199,11 @@ static void calculate_eval_priority(OperationDepsNode *node)
* dec_parents: Decrement pending parents count, true when child nodes are
* scheduled after a task has been completed.
*/
static void schedule_node(TaskPool *pool, Depsgraph *graph, unsigned int layers,
static void schedule_node(TaskPool *pool, Depsgraph *graph,
OperationDepsNode *node, bool dec_parents,
const int thread_id)
{
unsigned int id_layers = node->owner->owner->layers;
if ((node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0 &&
(id_layers & layers) != 0)
{
if ((node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) {
if (dec_parents) {
BLI_assert(node->num_links_pending > 0);
atomic_sub_and_fetch_uint32(&node->num_links_pending, 1);
@@ -230,7 +215,7 @@ static void schedule_node(TaskPool *pool, Depsgraph *graph, unsigned int layers,
if (!is_scheduled) {
if (node->is_noop()) {
/* skip NOOP node, schedule children right away */
schedule_children(pool, graph, node, layers, thread_id);
schedule_children(pool, graph, node, thread_id);
}
else {
/* children are scheduled once this task is completed */
@@ -246,19 +231,16 @@ static void schedule_node(TaskPool *pool, Depsgraph *graph, unsigned int layers,
}
}
static void schedule_graph(TaskPool *pool,
Depsgraph *graph,
const unsigned int layers)
static void schedule_graph(TaskPool *pool, Depsgraph *graph)
{
foreach (OperationDepsNode *node, graph->operations) {
schedule_node(pool, graph, layers, node, false, 0);
schedule_node(pool, graph, node, false, 0);
}
}
static void schedule_children(TaskPool *pool,
Depsgraph *graph,
OperationDepsNode *node,
const unsigned int layers,
const int thread_id)
{
foreach (DepsRelation *rel, node->outlinks) {
@@ -270,7 +252,6 @@ static void schedule_children(TaskPool *pool,
}
schedule_node(pool,
graph,
layers,
child,
(rel->flag & DEPSREL_FLAG_CYCLIC) == 0,
thread_id);
@@ -285,8 +266,7 @@ static void schedule_children(TaskPool *pool,
* \note Time sources should be all valid!
*/
void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
Depsgraph *graph,
const unsigned int layers)
Depsgraph *graph)
{
/* Generate base evaluation context, upon which all the others are derived. */
// TODO: this needs both main and scene access...
@@ -296,11 +276,6 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
return;
}
DEG_DEBUG_PRINTF("%s: layers:%u, graph->layers:%u\n",
__func__,
layers,
graph->layers);
/* Set time for the current graph evaluation context. */
TimeSourceDepsNode *time_src = graph->find_time_source();
eval_ctx->ctime = time_src->cfra;
@@ -309,7 +284,6 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
DepsgraphEvalState state;
state.eval_ctx = eval_ctx;
state.graph = graph;
state.layers = layers;
TaskScheduler *task_scheduler;
bool need_free_scheduler;
@@ -325,7 +299,7 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
TaskPool *task_pool = BLI_task_pool_create_suspended(task_scheduler, &state);
calculate_pending_parents(graph, layers);
calculate_pending_parents(graph);
/* Clear tags. */
foreach (OperationDepsNode *node, graph->operations) {
@@ -341,7 +315,7 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
DepsgraphDebug::eval_begin(eval_ctx);
schedule_graph(task_pool, graph, layers);
schedule_graph(task_pool, graph);
BLI_task_pool_work_and_wait(task_pool);
BLI_task_pool_free(task_pool);

View File

@@ -46,7 +46,6 @@ struct Depsgraph;
* \note Time sources should be all valid!
*/
void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
Depsgraph *graph,
const unsigned int layers);
Depsgraph *graph);
} // namespace DEG

View File

@@ -190,14 +190,8 @@ void IDDepsNode::init(const ID *id, const char *UNUSED(subdata))
/* Store ID-pointer. */
BLI_assert(id != NULL);
this->id = (ID *)id;
this->layers = (1 << 20) - 1;
this->eval_flags = 0;
/* For object we initialize layers to layer from base. */
if (GS(id->name) == ID_OB) {
this->layers = 0;
}
components = BLI_ghash_new(id_deps_node_hash_key,
id_deps_node_hash_key_cmp,
"Depsgraph id components hash");

View File

@@ -173,9 +173,6 @@ struct IDDepsNode : public DepsNode {
/* Hash to make it faster to look up components. */
GHash *components;
/* Layers of this node with accumulated layers of it's output relations. */
unsigned int layers;
/* Additional flags needed for scene evaluation.
* TODO(sergey): Only needed for until really granular updates
* of all the entities.

View File

@@ -123,8 +123,7 @@ static void comp_node_hash_value_free(void *value_v)
ComponentDepsNode::ComponentDepsNode() :
entry_operation(NULL),
exit_operation(NULL),
layers(0)
exit_operation(NULL)
{
operations_map = BLI_ghash_new(comp_node_hash_key,
comp_node_hash_key_cmp,
@@ -157,10 +156,7 @@ string ComponentDepsNode::identifier() const
char typebuf[16];
sprintf(typebuf, "(%d)", type);
char layers[16];
sprintf(layers, "%u", this->layers);
return string(typebuf) + name + " : " + idname + " (Layers: " + layers + ")";
return string(typebuf) + name + " : " + idname;
}
OperationDepsNode *ComponentDepsNode::find_operation(OperationIDKey key) const
@@ -406,12 +402,11 @@ static DepsNodeFactoryImpl<ShadingComponentDepsNode> DNTI_SHADING;
DEG_DEPSNODE_DEFINE(CacheComponentDepsNode, DEPSNODE_TYPE_CACHE, "Cache Component");
static DepsNodeFactoryImpl<CacheComponentDepsNode> DNTI_CACHE;
/* Layer COllections Defines ============================ */
/* Layer Collections Defines ============================ */
DEG_DEPSNODE_DEFINE(LayerCollectionsDepsNode, DEPSNODE_TYPE_LAYER_COLLECTIONS, "Layer Collections Component");
static DepsNodeFactoryImpl<LayerCollectionsDepsNode> DNTI_LAYER_COLLECTIONS;
/* Node Types Register =================================== */
void deg_register_component_depsnodes()

View File

@@ -145,9 +145,6 @@ struct ComponentDepsNode : public DepsNode {
OperationDepsNode *exit_operation;
// XXX: a poll() callback to check if component's first node can be started?
/* Temporary bitmask, used during graph construction. */
unsigned int layers;
};
/* ---------------------------------------- */

View File

@@ -150,17 +150,6 @@ typedef struct OGLRender {
#endif
} OGLRender;
/* added because v3d is not always valid */
static unsigned int screen_opengl_layers(OGLRender *oglrender)
{
if (oglrender->v3d) {
return oglrender->scene->lay | oglrender->v3d->lay;
}
else {
return oglrender->scene->lay;
}
}
static bool screen_opengl_is_multiview(OGLRender *oglrender)
{
View3D *v3d = oglrender->v3d;
@@ -796,7 +785,7 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
if (oglrender->timer) { /* exec will not have a timer */
scene->r.cfra = oglrender->cfrao;
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender));
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer);
}
@@ -1008,12 +997,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
if (CFRA < oglrender->nfra)
CFRA++;
while (CFRA < oglrender->nfra) {
unsigned int lay = screen_opengl_layers(oglrender);
if (lay & 0xFF000000)
lay &= 0xFF000000;
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, lay);
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
CFRA++;
}
@@ -1035,7 +1019,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
WM_cursor_time(oglrender->win, scene->r.cfra);
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender));
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
if (view_context) {
if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera && oglrender->v3d->scenelock) {

View File

@@ -1839,10 +1839,6 @@ void ED_screen_animation_timer_update(bScreen *screen, int redraws, int refresh)
* screen can be NULL */
void ED_update_for_newframe(Main *bmain, Scene *scene, int UNUSED(mute))
{
wmWindowManager *wm = bmain->wm.first;
wmWindow *window;
int layers = 0;
#ifdef DURIAN_CAMERA_SWITCH
void *camera = BKE_scene_camera_switch_find(scene);
if (camera && scene->camera != camera) {
@@ -1857,12 +1853,8 @@ void ED_update_for_newframe(Main *bmain, Scene *scene, int UNUSED(mute))
ED_clip_update_frame(bmain, scene->r.cfra);
/* get layers from all windows */
for (window = wm->windows.first; window; window = window->next)
layers |= BKE_screen_visible_layers(window->screen, scene);
/* this function applies the changes too */
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, layers);
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
/* composite */
if (scene->use_nodes && scene->nodetree)

View File

@@ -318,11 +318,11 @@ static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op))
for (cfra = (scene->r.sfra > 0) ? (scene->r.sfra - 1) : 0; cfra <= scene->r.efra + 1; cfra++) {
scene->r.cfra = cfra;
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
}
scene->r.cfra = oldfra;
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
return OPERATOR_FINISHED;
}

View File

@@ -1762,7 +1762,7 @@ static int game_engine_exec(bContext *C, wmOperator *op)
//XXX restore_all_scene_cfra(scene_cfra_store);
BKE_scene_set_background(CTX_data_main(C), startscene);
//XXX BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
//XXX BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
BLI_callback_exec(bmain, &startscene->id, BLI_CB_EVT_GAME_POST);

View File

@@ -86,8 +86,7 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe)
BPy_BEGIN_ALLOW_THREADS;
#endif
/* It's possible that here we're including layers which were never visible before. */
BKE_scene_update_for_newframe_ex(G.main->eval_ctx, G.main, scene, (1 << 20) - 1, true);
BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene);
#ifdef WITH_PYTHON
BPy_END_ALLOW_THREADS;

View File

@@ -126,7 +126,7 @@ static void updateDepsgraph(ModifierData *md,
ClothModifierData *clmd = (ClothModifierData *)md;
if (clmd != NULL) {
/* Actual code uses get_collisionobjects */
DEG_add_collision_relations(node, scene, ob, clmd->coll_parms->group, ob->lay|scene->lay, eModifierType_Collision, NULL, true, "Cloth Collision");
DEG_add_collision_relations(node, scene, ob, clmd->coll_parms->group, eModifierType_Collision, NULL, true, "Cloth Collision");
DEG_add_forcefield_relations(node, scene, ob, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
}

View File

@@ -134,7 +134,7 @@ static void updateDepsgraph(ModifierData *md,
}
/* Actual code uses custom loop over group/scene without layer checks in dynamicPaint_doStep */
DEG_add_collision_relations(node, scene, ob, surface->brush_group, -1, eModifierType_DynamicPaint, is_brush_cb, false, "Dynamic Paint Brush");
DEG_add_collision_relations(node, scene, ob, surface->brush_group, eModifierType_DynamicPaint, is_brush_cb, false, "Dynamic Paint Brush");
}
}
}

View File

@@ -139,8 +139,8 @@ static void updateDepsgraph(ModifierData *md,
if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) {
/* Actual code uses get_collisionobjects */
DEG_add_collision_relations(node, scene, ob, smd->domain->fluid_group, ob->lay|scene->lay, eModifierType_Smoke, is_flow_cb, true, "Smoke Flow");
DEG_add_collision_relations(node, scene, ob, smd->domain->coll_group, ob->lay|scene->lay, eModifierType_Smoke, is_coll_cb, true, "Smoke Coll");
DEG_add_collision_relations(node, scene, ob, smd->domain->fluid_group, eModifierType_Smoke, is_flow_cb, true, "Smoke Flow");
DEG_add_collision_relations(node, scene, ob, smd->domain->coll_group, eModifierType_Smoke, is_coll_cb, true, "Smoke Coll");
DEG_add_forcefield_relations(node, scene, ob, smd->domain->effector_weights, true, PFIELD_SMOKEFLOW, "Smoke Force Field");
}

View File

@@ -70,7 +70,7 @@ static void updateDepsgraph(ModifierData *UNUSED(md),
{
if (ob->soft) {
/* Actual code uses ccd_build_deflector_hash */
DEG_add_collision_relations(node, scene, ob, ob->soft->collision_group, ob->lay, eModifierType_Collision, NULL, false, "Softbody Collision");
DEG_add_collision_relations(node, scene, ob, ob->soft->collision_group, eModifierType_Collision, NULL, false, "Softbody Collision");
DEG_add_forcefield_relations(node, scene, ob, ob->soft->effector_weights, true, 0, "Softbody Field");
}

View File

@@ -5206,7 +5206,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
/* applies changes fully */
if ((re->r.scemode & (R_NO_FRAME_UPDATE|R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) {
BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, lay);
BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene);
render_update_anim_renderdata(re, &re->scene->r);
}
@@ -5376,13 +5376,9 @@ static void database_fromscene_vectors(Render *re, Scene *scene, unsigned int la
re->i.totface=re->i.totvert=re->i.totstrand=re->i.totlamp=re->i.tothalo= 0;
re->lights.first= re->lights.last= NULL;
/* in localview, lamps are using normal layers, objects only local bits */
if (re->lay & 0xFF000000)
lay &= 0xFF000000;
/* applies changes fully */
scene->r.cfra += timeoffset;
BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, lay);
BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene);
/* if no camera, viewmat should have been set! */
if (camera) {

View File

@@ -581,8 +581,7 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
BPy_BEGIN_ALLOW_THREADS;
#endif
/* It's possible that here we're including layers which were never visible before. */
BKE_scene_update_for_newframe_ex(re->eval_ctx, re->main, scene, (1 << 20) - 1, true);
BKE_scene_update_for_newframe(re->eval_ctx, re->main, scene);
#ifdef WITH_PYTHON
BPy_END_ALLOW_THREADS;
@@ -593,17 +592,6 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
/* Render */
static bool render_layer_exclude_animated(Scene *scene, SceneRenderLayer *srl)
{
PointerRNA ptr;
PropertyRNA *prop;
RNA_pointer_create(&scene->id, &RNA_SceneRenderLayer, srl, &ptr);
prop = RNA_struct_find_property(&ptr, "layers_exclude");
return RNA_property_animated(&ptr, prop);
}
int RE_engine_render(Render *re, int do_all)
{
RenderEngineType *type = RE_engines_find(re->r.engine);
@@ -628,40 +616,7 @@ int RE_engine_render(Render *re, int do_all)
/* update animation here so any render layer animation is applied before
* creating the render result */
if ((re->r.scemode & (R_NO_FRAME_UPDATE | R_BUTS_PREVIEW)) == 0) {
unsigned int lay = re->lay;
/* don't update layers excluded on all render layers */
if (type->flag & RE_USE_EXCLUDE_LAYERS) {
SceneRenderLayer *srl;
unsigned int non_excluded_lay = 0;
if (re->r.scemode & R_SINGLE_LAYER) {
srl = BLI_findlink(&re->r.layers, re->r.actlay);
if (srl) {
non_excluded_lay |= ~(srl->lay_exclude & ~srl->lay_zmask);
/* in this case we must update all because animation for
* the scene has not been updated yet, and so may not be
* up to date until after BKE_scene_update_for_newframe */
if (render_layer_exclude_animated(re->scene, srl))
non_excluded_lay |= ~0;
}
}
else {
for (srl = re->r.layers.first; srl; srl = srl->next) {
if (!(srl->layflag & SCE_LAY_DISABLE)) {
non_excluded_lay |= ~(srl->lay_exclude & ~srl->lay_zmask);
if (render_layer_exclude_animated(re->scene, srl))
non_excluded_lay |= ~0;
}
}
}
lay &= non_excluded_lay;
}
BKE_scene_update_for_newframe_ex(re->eval_ctx, re->main, re->scene, lay, true);
BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene);
render_update_anim_renderdata(re, &re->scene->r);
}

View File

@@ -1698,7 +1698,7 @@ static void do_render_blur_3d(Render *re)
/* make sure motion blur changes get reset to current frame */
if ((re->r.scemode & (R_NO_FRAME_UPDATE|R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) {
BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, re->lay);
BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene);
}
/* weak... the display callback wants an active renderlayer pointer... */
@@ -2588,7 +2588,7 @@ static void do_render_composite_fields_blur_3d(Render *re)
R.i.cfra = re->i.cfra;
if (update_newframe)
BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, re->lay);
BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene);
if (re->r.scemode & R_FULL_SAMPLE)
do_merge_fullsample(re, ntree);
@@ -3640,19 +3640,8 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
render_initialize_from_main(re, &rd, bmain, scene, NULL, camera_override, lay_override, 1, 0);
if (nfra != scene->r.cfra) {
/*
* Skip this frame, but update for physics and particles system.
* From convertblender.c:
* in localview, lamps are using normal layers, objects only local bits.
*/
unsigned int updatelay;
if (re->lay & 0xFF000000)
updatelay = re->lay & 0xFF000000;
else
updatelay = re->lay;
BKE_scene_update_for_newframe(re->eval_ctx, bmain, scene, updatelay);
/* Skip this frame, but update for physics and particles system. */
BKE_scene_update_for_newframe(re->eval_ctx, bmain, scene);
continue;
}
else

View File

@@ -3854,7 +3854,7 @@ static void redraw_timer_step(
}
else if (type == eRTAnimationStep) {
scene->r.cfra += (cfra == scene->r.cfra) ? 1 : -1;
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
}
else if (type == eRTAnimationPlay) {
/* play anim, return on same frame as started with */
@@ -3866,7 +3866,7 @@ static void redraw_timer_step(
if (scene->r.cfra > scene->r.efra)
scene->r.cfra = scene->r.sfra;
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
redraw_timer_window_swap(C);
}
}