(@plasmasolutions): When the particle emitter is parented to a fast
moving object, the emission locations will not be interpolated over
subframes. This works if the particle emitter is animated itself.
Particle system evaluates the emitter location for each subframe, but
has to do this for the parent objects as well to get reliable results.
Evaluating the animation is causing the object to get tagged as changed, but in
this case it's not a permanent change so no one should be notified. Also found
a case where the persistent ID for duplis wasn't unique, fixed that as well.
The main idea is to store (during tessellation) or recreate (during tessdata update) a tessfaceverts-to-loops mapping, and then update all tessdata
in one pass, instead of calling `BKE_mesh_loops_to_mface_corners` repeatedly for all tfaces!
Differential Revision: https://developer.blender.org/D226
Reviewed by Campbell, thanks a lot!
This is a first step toward improving our dupli system. It implements a more
generic way of treating the various methods of dupli generation by adding a few
structs:
* DupliContext holds a number of arguments commonly used in the recursive dupli functions and defines a recursion state for generating sub-duplis (nested groups). It also helps to prevent bloated argument lists.
* DupliGenerator is a type struct that unifies the different dupli creation methods (groups, frames, verts, text chars, faces, particles). (As with context there should be no overhead from pointer indirection because everything can still be inlined inside anim.c)
Beside making the code more easily understandable this implementation should
also help to avoid weird side effects from custom matrix hacks by defining
clearly what a generator does. The DupliContext is deliberately made const, so a
generator can not simply add hidden matrix or flag modifications that are hard
to track down.
The result container for the generated duplis is stored in the context instead
of being passed explicitly. This means the generators are oblivious to the
storage of duplis, all they need to do is call the make_dupli function. This
will allow us to implement more efficient ways of storing DupliObject instances,
such as MemPools or batches. These can be implemented alongside the current
ListBase so we can improve dupli bottlenecks without having to replace each and
every dupli use case at once.
Differential Revision: https://developer.blender.org/D189
This is because of the animdata cleanup in rBd2e55cb. This works ok in
general, but causes issues with the localized node trees used for compo/
shader/texture previews. These localized trees share the same default
action as their original trees, and then remove fcurves when removing
muted nodes (which should affect the localized tree only).
node_free_node_ex now has an argument for disabling animdata cleanup,
which is also not necessary when freeing the whole node tree (because
animdata is freed in advance anyway). In addition to that it also checks
the NTREE_IS_LOCALIZED flag to prevent freeing of fcurves in the action.
Increase the maximum allowed amount of points in a spline from currently 32,767 (short) to 2,147,483,647 (int).
Change variables that get assigned the value from pntsu/pntsv to int type all over the codebase.
Change function parameters that previously passed the count as short to int type as well.
(because https://developer.blender.org/T38191)
Reviewed By: sergey
Differential Revision: https://developer.blender.org/D212
It was an issue with early object update check which was
screwing up for second scene because of first one reset
ID recalc flags.
From the comment in the code about this:
We need to check all visible scenes, otherwise resetting
OB_ID changed flag will only work fine for first scene of
multiple visible and all the rest will skip update.
This could also lead to wrong behavior scene update handlers
because of missing ID datablock changed flags.
This is a bit of a bummer to allocate list here, but likely
it wouldn't become too much bad because it only happens when
objects were actually changed.
Issue was caused by some objects being in bMain and tagged
for update but not being in the DAG. This means objects
wouldn't be updated and their recalc flag remains untouched
triggering threaded for the next frame.
Solved by tweaking POST_UPDATE_HANDLER_WORKAROUND in the way
that it checks objects' recalc flags from the DAG, not from
the bMain. This will work a bit longer since DAG stored more
nodes than objects in the scene, but this code only runs in
cases when there're some objects tagged for update, which
keeps overall CPU usage on such a workaround pretty low.
Now CPU usage on 11a_comp scene from project Pampa went down
from ~15% down to ~5% (2,69 release uses ~%7).
Pointed by Thomas Dinges in IRC.
Previously this only worked for some datablocks relevant to rendering, now it
can be used to detect if any type of datablock was added or removed (but not
yet to detect if it was modified, we need many more depsgraph tags for that).
Most of the changes are some function parameter changes, the important parts
are the DAG_id_type_tag calls.
Reviewed By: sergey, brecht
Differential Revision: https://developer.blender.org/D195
Issue is caused by the evaluation flags getter called with
NULL depsgraph. It happens on direct object update from the
transform code after duplicating the curve.
Proper solution is probably to make sure depsgraph is rebuild
after duplication, but for now it's better to prevent crashes.
Issue was caused by evaluation flags getter function polluting
the DAG. Need to use dag_find_node() instead.
Still need to doublecheck exporting objects with curve deform
works properly. On the first thought it should, but might be
wrong again.
This adds an ImageUser to such empties with all the typical settings.
Reviewed By: brecht, campbellbarton
Differential Revision: https://developer.blender.org/D108
It was a missing fcurve evaluation in scene update function which lead to
materials only being updated on frame change.
Added the same exception as we've got for the scene animation. It only
runs when there're materials tagged for the update, so wouldn't expect
speed regressions or so.
Issue was caused by cache limitor removing viewer image buffer
from the memory during compositing. Now made it so all viewer
images are persistent in the memory.
This solves the crash mentioned above and also makes it so
render/compo results are never lost.
Further tweaks are possible, but pretty much happy now, at
least no stoppers for work are there.
There were couple of reasons why it wasn't safe for usage from
multiple threads.
First of all, it was trying to cache BVH in derived mesh, which
wasn't safe because multiple threads might have requested BVH
tree and simultaneous reading and writing to the cache became a
big headache.
Solved this with RW lock so now access to BVH cache is safe.
Another issue is causes by the fact that it's not guaranteed
DM to have vert/edge/face arrays pre-allocated and when one
was calling functions like getVertDataArray() array could
have been allocated and marked as temporary. This is REALLY
bad, because NO ONE is ever allowed to modify data which
doesn't belong to him. This lead to situations when multiple
threads were using BVH tree and they run into race condition
with this temporary allocated arrays.
Now bvhtree owns allocated arrays and keeps track of them, so
no race condition happens with temporary data stored in the
derived mesh. This solved threading issues and likely wouldn't
introduce noticeable slowdown. Even when DM was keeping track
of this arrays, they were re-allocated on every BVH creation
anyway, because those arrays were temporary and were freed
with dm->release() call.
We might re-consider this a bit and make it so BVH trees are
allocated when DM itself is being allocated based on the DAG
layout, but that i'd consider an optimization and not something
we need to do 1st priority.
Fixes crash happening with 05_4g_track.blend from Mango after
the threaded object update landed to master.
Graph traversal which is based on counting parents which are still
to be updated fails in cases there are cycles in the graph.
If there are cyclic dependencies in the scene all the objects from
the cycles will be updated in a single thread now one by one. This
makes blender behave the same way as it was before multi-threaded
DAG landed to master.
This needed to tweak depsgraph a bit so now dag_check_cycle() sets
is_acyclic field of DAG forest if there are cycles in the graph.
TODO: It might be possible to save some time on evaluation when
all the tagged objects were updated in multi-threaded DAG
traversal.
This is a regression since threaded dependency graph landed to master.
Root of the issue goes to the loads of graph preparation being done
even if there's nothing to be updated.
The idea of this change is to use ID type recalc bits to determine
whether there're objects to be updated. Generally speaking, we now
check object and object data datablocks with DAG_id_type_tagged()
and if there's no such IDs tagged we skip the whole task pool creation
and so,
The only difficult aspect was that in some circumstances it was possible
that there are tagged objects but nothing in ID recalc bit fields.
There were several different circumstances when it was possible:
* When one assigns object->recalc flag directly DAG flush didn't
set corresponding bits to ID recalc bits. Partially it is fixed
by making it so flush will set bitfield, but also for object
types there's no reason to assign recalc flag directly. Using
generic DAG_id_type_tag works almost the same fast as direct
assignment, ensures all the bitflags are set properly and for the
long run it seems it's what we would actually want to.
* DAG_on_visible_update() didn't set recalc bits at all.
* Some areas were checking for object->recalc != 0, however it is was
possible that object recalc flag contains PSYS_RECALC_CHILD which
was never cleaned from there.
No idea why would we need to assign such a flag when enabling
scene simplification, this is to be investigated separately.
* It is possible that scene_update_post and frame_update_post handlers
will modify objects. The issue is that DAG_ids_clear_recalc is called
just after callbacks, which leaves objects with recalc flags but no
corresponding bit in ID recalc bitfield. This leads to some kind of
regression when using ID type tag fields to check whether there objects
to be updated internally comparing threaded DAG with legacy one.
For now let's have a workaround which will preserve tag for ID_OB
if there're objects with OB_RECALC_ALL bits. This keeps behavior
unchanged comparing with 2.69 release.
This solves threading conflict which happens when having
multiple objects using Curve Deform modifier with the same
curve datablock. This conflict was caused by the fact that
curve_deform_verts() used to temporary override curve's
flags to make it path is there.
Actually, it was setting CU_FOLLOW flag temporary which
was only used where_on_path() (only in terms that this
temporary assignment only affected this function) but it
is now commented out for a while, so no reason to set
this flag temporary, If it's ever to be done, we'll need
to pass flags as an additional function argument.
For the path creation i've extended DegNode structure
which now holds extra bits which indicates what additional
data depending on the graph topology is to be evaluated.
Currently this is only used to indicate that curve needs
path to be evaluated regardless to cu->flag state. This
is so Curve Deform modifier is always happy.
In the future this flag might also be used to indicate
whether bmesh verts are to update (see recent commit to
3-vertex parent crash fix) or to indicate that the object
is the motherball etc.
This goes back to ancient era again and such a call isn't
safe for threading and really DAG is to make it sure display
list for dependencies is always there.
BKE_curve_bevel_make() is only used from object_handle_update()
friends and never called directly. This means if there's no
display list ready for the bevel object it's something wrong
happened with DAG.
In fact, this check goes back to ancient era and from tests
it appears this check is no longer needed.
It was some kind of workaround for DAG glitch in 2009
(commit hash 8c5c7ebb0) and according to the comment
was needed to make select outline show immediately.
After some tests it appears DAG behaves almost fine now
(just needed to make it so layer is flushed properly to
the set scene) and no reason to have rather confusing
call in the code.