A `BitGroupVector` is a compact data structure that allows storing multiple
bits per element, for example 5 bits per vertex. The implementation is
mostly just a wrapper around `BitVector`. There is some additional logic
to make sure that the bit span of every element is bounded (according
to the `is_bounded_span` function). This makes it more efficient to operate
on groups as a whole (e.g. `or` one group into another). In some sense,
this data structure can also be interpreted as a 2D bit array. Functions
like `append` can be added when they become necessary.
The new data structure is used to replace some `MultiValueMap` in
geometry nodes. This simplifies the code.
This can be useful to allow creating these core attributes with shared
arrays. Otherwise CustomData has to be used directly, which is nice
to avoid. This was done in e45ed69349, but not everywhere.
This is consistent with `Span`, and also allows returning a bounded
bit span when taking the front of an existing bounded span, which
can simplify using optimized bit processing.
Pull Request: https://projects.blender.org/blender/blender/pulls/107441
These aren't propagated as attributes since interpolating them with the
generic rules often gives strange results, and they're intended to as
an optimization. Though theoretically it would be nice if this
copying became more generic in the future.
Most of this patch is by Jacques Lucke, from the simulation branch.
This commit adds generic expression evaluation for bit spans, helping
to generalize the optimizations that avoid processing a single bit
at a time. Operations like "for each 1 index", "or", and "and" are
already implemented in this pull request. Bits in full integers are
processed 64 at a time, then remaining bits are processed all at once.
The operations allow implementing a `copy_from` method for bit spans.
Currently this optimized evaluation is only implemented for simpler
bounded bit spans. Bounded bit spans have constraints on their bit
ranges that make them more efficient to process. Large spans must start
at the beginning of the first int, and small spans must start and end
within the first int.
Knowing these constraints at compile time reduces the number of edge
cases in the operations, but mainly allows skipping alignment between
multiple spans with different offsets.
Pull Request: https://projects.blender.org/blender/blender/pulls/107408
The `ED_view3d_grid_steps` function creates steps of units other than
those defined in `unit.c`.
This seems to be used for grid drawing in order to draw a unit after
the miles (in this case it would be something like 10 miles).
But that doesn't seem right as it's an undefined unit.
Therefore, the solution is not to create these different unit values.
The change in the overlay is that the softer grid that used to
correspond to 10 miles now corresponds to mile.
Pull Request: https://projects.blender.org/blender/blender/pulls/107405
No functional changes.
Merge the modal callbacks of the `VIEW3D_OT_move`, `VIEW3D_OT_rotate`
and `VIEW3D_OT_zoom` operators into a single simplified
`view3d_navigate_modal_fn` callback.
Deduplicate code for initialization, also the code for finalization and
the code to get the `event_code`.
Improve support for operation switching by the existing (but unused)
modal keymap items `VIEWROT_MODAL_SWITCH_ZOOM`,
`VIEWROT_MODAL_SWITCH_MOVE` and
`VIEWROT_MODAL_SWITCH_ROTATE`.
Pull Request: https://projects.blender.org/blender/blender/pulls/106279
BKE_image_ensure_tile_token took only the file name component but used
FILE_MAX to limit the input buffer.
Split this function in two, one that takes the full path as this is the
most common usage and another which takes only the filename.
Both now take a string size argument.
This simplifies the code that works with the `BLI_serialize.hh` header.
The various `lookup` methods do a linear search. If there are only a
few elements that can even be faster than building the map first.
In the future it might be nice to transparently build and cache the
map internally if necessary.
The main goal of these changes is to support checking if some data has
been changed over time. This is used by the WIP simulation nodes during
baking to detect which attributes have to be stored in every frame because
they have changed.
By using a combination of a weak user count and a version counter, it is
possible to detect that an attribute (or any data controlled by implicit
sharing) has not been changed with O(1) memory and time. It's still
possible that the data has been changed multiple times and is the same
in the end and beginning of course. That wouldn't be detected using this
mechanism.
The `ImplicitSharingInfo` struct has a new weak user count. A weak
reference is one that does not keep the referenced data alive, but makes sure
that the `ImplicitSharingInfo` itself is not deleted. If some piece of
data has one strong and multiple weak users, it is still mutable. If the
strong user count goes down to zero, the referenced data is freed.
Remaining weak users can check for this condition using `is_expired`.
This is a bit similar to `std::weak_ptr` but there is an important difference:
a weak user can not become a strong user while one can create a `shared_ptr`
from a `weak_ptr`. This restriction is necessary, because some code might
be changing the referenced data assuming that it is the only owner. If
another thread suddenly adds a new owner, the data would be shared again
and the first thread would not have been allowed to modify the data in
the first place.
There is also a new integer version counter in `ImplicitSharingInfo`.
It is incremented whenever some code wants to modify the referenced data.
Obviously, this can only be done when the data is not shared because then
it would be immutable. By comparing an old and new version number of the
same sharing info, one can check if the data has been modified. One has
to keep a weak reference to the sharing info together with the old version
number to ensure that the new sharing info is still the same as the old one.
Without this, it can happen that the sharing info was freed and a new
one was allocated at the same pointer address. Using a strong reference
for this purpose does not work, because then the data would never be
modified because it's shared.
This patch changes the priority for choosing the active output to
prioritize viewer nodes as opposed to composite nodes. This is done to
better work with the workflow of using the Connect To Viewer operator
and better match the expected behavior from users.
The grain size depends on the algorithm, it doesn't make sense to use
the same value for multiple areas just because they relate to `Mesh`.
The comment mentions OpenMP which isn't used anymore.
Also remove an unused forward declaration.
- Avoid a separate memmove call for each `..`.
- Avoid ambiguous path stepping, where separator literals
needed to be checked to avoid fence post errors.
- Correct & update the doc-string.
The CPU compositor sanitizes the colors after HSV/HSL conversion by
clamping negative values to zero. The realtime compositor did no such
sanitization. This patch fixes that by introducing similar sanitization.
This is implemented by removing the attribute and adding it again with
a different name. In the expected case though, implicit sharing is used
to avoid copying the array.
For now this doesn't rename UV sublayers or replace active/default color
attribute names. It's not clear where that should happen, but for now
things are clearer if those stay at a higher level.
Avoid many small allocations and just allocate all the structs in one
array, which is 4 times faster. In a test with an armature modifier and
custom normals, corner normal calculation went from 2.7 to 2.3 ms.
The various stacks are just filled and then emptied. We also expect
them to be fairly small. A vector can handle these cases fairly well.
Also store indices rather than pointers. I didn't notice any performance
changes from these changes.
Instead of storing a 24 byte struct for every face corner we must do
calculations for, just gather the face corner index in the first single
threaded loop. And don't fill them in chunks and use the task pool API.
Instead just fill vectors and use standard "parallel_for" threading.
The check that avoided threading for tiny meshes becomes redundant this
way too, which simplifies the code more. Overall this removes over
100 lines of code.
On a Ryzen 7950x, face corner ("split"/"loop") normal calculation in a
small armature modifier setup with custom normals went from 4.1 ms to
2.8 ms. Calculation for a 12 million face mesh generated with curve to
mesh with end caps went from 776 ms to 568 ms.
Similar commits:
- 9e9ebcdd72
- 9338ab1d62
interior cuts"
This reverts commit 129f79debe.
That commit changed the behavior of how booleans handled vertex weights
as well and made the CubeMaskFirst test modifier test fail.
Not entirely clear to me what the desired behavior would be (current
situation is "wrong" in certain situations as well I think), but until
this is further discussed with the #modeling-module , I think reverting
is the better choice.
In most of the operators the code that loops through the FCurve segments and draws the status header were pretty much identical.
To combat that, create abstract helper functions that can be used.
They are not useful in all cases, e.g. the blend to default operator needs a bit of special code.
Pull Request: https://projects.blender.org/blender/blender/pulls/107170
Using the Knife tool, making cuts that split an edge exactly interpolate
fine for vertex customdata (weights or attributes on the vertex domain)
due to `BM_edge_split` taking care of data layers from the edge and
vertex domain (also mdisps -- which unfortunately dont seem to work
well, but that is for another patch...).
However, making cuts _inside_ a face though dont interpolate at all
(giving default values on new vertices).
With this patch, also interpolate vertex customdata in
`BM_face_split_edgenet`.
Pull Request: https://projects.blender.org/blender/blender/pulls/107367
This patch implements the Corner Pin node for the realtime compositor.
This is different from the existing compositor in that single value
inputs produce single value outputs, instead of assuming the size of the
render.
Pull Request: https://projects.blender.org/blender/blender/pulls/107363