This replaces the somewhat hackish and usafe code used previously.
Also fixes a potential bug, where the newly created `local_id` was
dereferenced before checking for it to be non-null.
Pull Request: https://projects.blender.org/blender/blender/pulls/108328
Seems to work OK in basic cases, but needs more work when copying
outside of Main at least.
Note: There is no behavioral changes expected from this commit.
Note that there are at least two known usecases for this change:
* Liboverrides, as with recursive resync and proxies conversion it
often ends up creating 'virtual' linked data that does not actually
exists in the library blend files.
* Complex versionning code (`do_versions_after_setup`) when it needs
to create new IDs (currently handling linked data that way is just not
supported!).
Implements #107847.
For example, creating the "position" attribute with the wrong name or type
could crash Blender when exiting edit mode. This is because some data isn't
stored as attributes in Blender, and the attribute API doesn't work very well
with BMesh.
Two parts to the solution:
- Remove builtin attributes with incorrect domains or names when
converting from BMesh to Mesh.
- Add error messages when creating builtin attributes in edit mode. It's still
possible to create name-convention attributes, because Blender should be
able to handle different types and domains for them.
Pull Request: https://projects.blender.org/blender/blender/pulls/119110
The copy constructor of the Layer class didn't do a copy
of the frames storage (DNA) and only a copy of the frames map (runtime).
This is fine, but we need to make sure to tag the frames storage,
because it is out of sync otherwise.
During edit mode undo, the layers were copied (but the frames storage not tagged) which meant that after undoing and then saving the file,
the frames would be gone after reloading.
The fix makes sure we tag the frames storage, so that it is properly synced.
The "capture field on geometry" utility is used in many places to store
the result of field evaluation as an attribute. There is a special case
for when an attribute already exists with the same name, data type, and
domain. But when exactly the same attribute was stored, it would assert
because it ended up copying an array to itself. Arguments for those copy
functions aren't supposed to alias each other.
As a fix, clarify the logic a bit to return earlier in this case.
Also remove a redundant case handling the same thing later on
in the function.
Pull Request: https://projects.blender.org/blender/blender/pulls/119063
This allows deleting a bunch of duplicate code, since there doesn't
need to be a special single-threaded case anymore. It also just
reduces the necessary boilerplate.
Also change naming a bit and use signed integers instead of unsigned.
I didn't notice any performance difference.
Pull Request: https://projects.blender.org/blender/blender/pulls/119069
Split `BKE_fcurve_blend_write(writer, listbase)` into two functions:
- `BKE_fcurve_blend_write_data(writer, fcurve)` for the data of a single
F-Curve, and
- `BKE_fcurve_blend_write_listbase(writer, listbase)` for writing a list
of F-Curves.
And the same for `BKE_fcurve_blend_read_data()`.
This is necessary for the upcoming Animation data-block, which will
store F-Curves as arrays instead of `ListBase`s.
No functional changes.
- Pass null instead of an empty string to BKE_tempdir_init
because the string isn't meant to be used.
- Never pass null to BLI_temp_directory_path_copy_if_valid
(the caller must check).
- Additional comments for which checks are performed & why
from discussion about #95411.
It's possible that multiple custom data layers share the same underlying data.
This data is only written once (per data-block) currently. However, when reading
the data again, two separate `ImplicitSharingInfo` were constructed which
referenced the same underlying memory. The fix is to reuse previously created
`ImplicitSharingInfo` that manage the same data.
Pull Request: https://projects.blender.org/blender/blender/pulls/118991
Second issue reported in the comment was caused by some shapekeys
flagged as embedded liboverride data, when their owner ID (Mesh e.g.)
is not a liboverride at all.
The `BKE_lib_override_library_validate` called on file read was only
covering real liboverride IDs, which where then supposed to take care of
their own embedded data. But since the owner ID is already a full
non-override ID, its embedded data ended up never being properly
sanitized.
Most likely more corruption data from quite old files and/or deprecated
experimental features.
No functional changes.
This PR replaces the uses of the C-style `BLI_BITMAP`
with `blender::BitVector` in `keyframing.cc`.
Note that in `BKE_animsys_nla_remap_keyframe_values` I had to
add code that maps from one to the other because I don't feel
comfortable ripping out the `BLI_BITMAP` from
`NlaEvalChannelSnapshot->remap_domain`
Pull Request: https://projects.blender.org/blender/blender/pulls/118957
This adds implicit sharing support for the `MemFile` undo-step. This decreases memory
usage and increases performance.
Implicit sharing allows the undo system to take (shared) ownership of some data.
Previously, the data would always be serialized and compared to the previous undo-step.
So this turns an O(n) operation into O(1) (in terms of memory usage and time).
Read/write code that wants to make use of this has to use the new `BLO_read_shared`
and `BLO_write_shared` functions respectively. Those either make use of implicit-sharing
internally or do the "full" read/write based on a passed-in function. It seems possible to
use the same API in the future to store shared data to .blend files.
Improvements:
* Much faster undo step creation in many cases by avoiding the majority data copies
and equality checks. This fixes#98574. I found undo step creation and undo step
decoding to be 2-5 times faster in some demo files from the blender website and in
some production files from the Heist project.
* Reduced memory usage when there is large data in `bmain`. For example, when
loading the same highly subdivided mesh that I used in #106228 the memory usage
is 1.03 GB now (compared to 1.62 GB in `main` currently). The main remaining copy
of the data now is done by rendering code.
* Some significant performance improvements were also measured for the new grease
pencil type (#105540).
There is one main downside of using implicit-sharing as implemented here: `MemFile`
undo steps can't be written as .blend files anymore. This has a few consequences:
* Auto-save becomes slower (up to 3x), because it can't just save the previous undo step
anymore and does a normal save instead. This has been discussed in more detail here:
https://devtalk.blender.org/t/remove-support-for-saving-memfile-undo-steps-as-blend-files-proposal/33544
It would be nice to work towards asynchronous auto-save to alleviate this problem.
Some previous work has been done to reduce the impact of this change in 41b10424c7
and f0f304e240. This has been committed separately in efb511a76d.
* Writing `quit.blend` has to do a normal file save now. So it's a bit slower too, but it's
less of a problem in practice.
* The `USE_WRITE_CRASH_BLEND` functionality does not work anymore. It doesn't seem
to be used by anyone (removed in e90f5d03c4)
There are also benefits to not writing `MemFile` from undo steps to disk. It allows us to
more safely do undo-specific optimizations without risking corrupted .blend files. This
is especially useful when we want to preserve forward compatibility in some cases.
This requires converting data before writing the .blend files, but this conversion is not
necessary for undo steps. Trying to implement this kind of optimization in the past has
often lead to bugs (e.g. 43b37fbc93).
Another new problem is that it is harder to know the size of each undo step. Currently, a
heuristic is used to approximate the memory usage, but better solutions could be found
if necessary.
Pull Request: https://projects.blender.org/blender/blender/pulls/106903
Add percentage closer filtering to shadowmap sampling and a
`shadow_filter_radius` property to lights to control it.
Notes:
* This adds PCF to `eevee_shadow_tracing_lib`, but not to
`eevee_shadow_lib`, which is used by volumes (not required) and
thickness.
* PCF is computed based on the LOD0 size. This assumes that higher
LODs are only used when the shadowmap resolution is actually good
enough to match the render resolution.
Pull Request: https://projects.blender.org/blender/blender/pulls/118220
- Skip leading forward slashes when setting the temp directory.
- Add a utility function to set the temporary directory
which is used for the user preferences & environment variables.
This issue was raised by #95411 where "//" resolves to "/",
then asserts when passed to Blender's file-system functions.
However the crash referenced in this report looks to be caused
by Collada failing to write to the temporary directory which
can be handled separately.
Ref !118872
Adds two nodes as "grid" equivalents to the existing volume nodes:
- **Grid to Mesh**
- **Distribute Points in Grid**
The code for the latter is just duplicated for now. In a later step
old node can be replaced by versioning with two new nodes.
Pull Request: https://projects.blender.org/blender/blender/pulls/118830
Any access to this after calling what_does_obaction would reference
invalid stack memory with undefined behavior.
Set to null to ensure this never happens.
There probably are more cases where crash will happen as it is
rooting into the issue with BKE_object_workob_calc_parent() which
is used in multiple places.
The issue is caused by the access to a runtime field of workob
outside of the BKE_object_workob_calc_parent(): the runtime field
is stack-allocated in the function, and can not be accessed outside
of the function.
The easiest way to reproduce is to use ASAN, and parent mesh to an
armature with automatic weights. Although, on macOS ASAN did not
report issues, so setting workob->runtime to nullptr at the end of
of the BKE_object_workob_calc_parent() was the easiest.
The solution is simple: make the function to return the matrix,
and take care of the working object inside of it, so all tricky
parts are hidden from the API.
The patch is targeting the main branch, as in 4.1 it is not
required to do such change because all uses of the function only
access object_to_world, which is stored in the object in 4.1.
A double-check in the what_does_obaction() might be needed as it
follows the similar pattern, but it does not seem that runtime
field of the workob is accessed in usages of the what_does_obaction().
Pull Request: https://projects.blender.org/blender/blender/pulls/118847
The time offset modifier was working differently than in GPv2. This is because in the new implementation, the time offset modifier actually modifies the keyframe mappings. And thus the order of the modifiers, and where the time offset modifier is placed in the stack, matters.
The problem is that this can lead to unexpected results like seeing unmodified drawings.
Technically, the issue here is that other modifiers only modify the current frame as supposed to all drawings in the timeline.
This is done as an optimization, but doesn't work when drawings can be shifted around on the timeline using the time offset modifier.
The fix changes the way the modifiers are executed. Because the time offset modifier can only modify **when** the drawings
are show, and not the drawing data themselves, we execute all the time offset modifiers first (in the order they appear in the stack) and then execute all the other modifiers after.
This means that the user can no longer run into the issue of "moving" drawings away from the current frame where they can't be seen.
It also makes time offset modifier behave the same as they did in GPv2.
Pull Request: https://projects.blender.org/blender/blender/pulls/118842