Commit Graph

379 Commits

Author SHA1 Message Date
Campbell Barton
823685db76 Cleanup: consistent doxygen comment blocks
Also remove doxygen block for comments in a functions body.
2023-05-27 15:10:58 +10:00
Chris Blackbourn
45bd9b58b9 Merge branch 'blender-v3.6-release' 2023-05-27 16:27:03 +12:00
Chris Blackbourn
71d89dfa81 UV: Fix (unreported) uv packing with pinned islands and original bounding box
Pinned islands with "Lock Position" were not interacting correctly
when the packing destination was not at the origin.

This could happen with "Pack To : Original Bounding Box", and also
when packing to a UDIM other than 1001.
2023-05-27 16:17:49 +12:00
Hans Goudey
d7e671028c Curves: Use simpler index mask logic in various places
In several nodes, and sculpt brushes, use the proper `IndexMask` type
instead of a span of ranges to encode a selection. This allows deleting
the duplicate data copying utilities using the second format.
2023-05-26 15:09:16 -04:00
Hans Goudey
0b0b6a687a Cleanup: Move offset size copying utility to generic header
This shows more clearly that there's nothing specific to curves here.
2023-05-26 15:09:16 -04:00
Hans Goudey
986ff5a3a4 Cleanup: Remove IndexRange::as_span() static array and cache
After 2cfcb8b0b8 this was only used in one place that
was easily replaced. In practice this avoids creating a statically
allocated array after the split edges code is called.

Pull Request: https://projects.blender.org/blender/blender/pulls/108249
2023-05-25 15:42:54 +02:00
Hans Goudey
5063f7a725 Cleanup: Simplify IndexMask usage in two geometry nodes
Use the weird but at least consistent "from_groups" method in the sample
curves node, and avoid one logarithmic lookups when merging points.
2023-05-24 20:05:42 -04:00
Jacques Lucke
2cfcb8b0b8 BLI: refactor IndexMask for better performance and memory usage
Goals of this refactor:
* Reduce memory consumption of `IndexMask`. The old `IndexMask` uses an
  `int64_t` for each index which is more than necessary in pretty much all
  practical cases currently. Using `int32_t` might still become limiting
  in the future in case we use this to index e.g. byte buffers larger than
  a few gigabytes. We also don't want to template `IndexMask`, because
  that would cause a split in the "ecosystem", or everything would have to
  be implemented twice or templated.
* Allow for more multi-threading. The old `IndexMask` contains a single
  array. This is generally good but has the problem that it is hard to fill
  from multiple-threads when the final size is not known from the beginning.
  This is commonly the case when e.g. converting an array of bool to an
  index mask. Currently, this kind of code only runs on a single thread.
* Allow for efficient set operations like join, intersect and difference.
  It should be possible to multi-thread those operations.
* It should be possible to iterate over an `IndexMask` very efficiently.
  The most important part of that is to avoid all memory access when iterating
  over continuous ranges. For some core nodes (e.g. math nodes), we generate
  optimized code for the cases of irregular index masks and simple index ranges.

To achieve these goals, a few compromises had to made:
* Slicing of the mask (at specific indices) and random element access is
  `O(log #indices)` now, but with a low constant factor. It should be possible
  to split a mask into n approximately equally sized parts in `O(n)` though,
  making the time per split `O(1)`.
* Using range-based for loops does not work well when iterating over a nested
  data structure like the new `IndexMask`. Therefor, `foreach_*` functions with
  callbacks have to be used. To avoid extra code complexity at the call site,
  the `foreach_*` methods support multi-threading out of the box.

The new data structure splits an `IndexMask` into an arbitrary number of ordered
`IndexMaskSegment`. Each segment can contain at most `2^14 = 16384` indices. The
indices within a segment are stored as `int16_t`. Each segment has an additional
`int64_t` offset which allows storing arbitrary `int64_t` indices. This approach
has the main benefits that segments can be processed/constructed individually on
multiple threads without a serial bottleneck. Also it reduces the memory
requirements significantly.

For more details see comments in `BLI_index_mask.hh`.

I did a few tests to verify that the data structure generally improves
performance and does not cause regressions:
* Our field evaluation benchmarks take about as much as before. This is to be
  expected because we already made sure that e.g. add node evaluation is
  vectorized. The important thing here is to check that changes to the way we
  iterate over the indices still allows for auto-vectorization.
* Memory usage by a mask is about 1/4 of what it was before in the average case.
  That's mainly caused by the switch from `int64_t` to `int16_t` for indices.
  In the worst case, the memory requirements can be larger when there are many
  indices that are very far away. However, when they are far away from each other,
  that indicates that there aren't many indices in total. In common cases, memory
  usage can be way lower than 1/4 of before, because sub-ranges use static memory.
* For some more specific numbers I benchmarked `IndexMask::from_bools` in
  `index_mask_from_selection` on 10.000.000 elements at various probabilities for
  `true` at every index:
  ```
  Probability      Old        New
  0              4.6 ms     0.8 ms
  0.001          5.1 ms     1.3 ms
  0.2            8.4 ms     1.8 ms
  0.5           15.3 ms     3.0 ms
  0.8           20.1 ms     3.0 ms
  0.999         25.1 ms     1.7 ms
  1             13.5 ms     1.1 ms
  ```

Pull Request: https://projects.blender.org/blender/blender/pulls/104629
2023-05-24 18:11:41 +02:00
Hans Goudey
4d841e1b35 Mesh: Reimplement and unify topology maps
Combine the newer less efficient C++ implementations and the older
less convenient C functions. The maps now contain one large array of
indices, split into groups by a separate array of offset indices.
Though performance of creating the maps is relatively unchanged, the
new implementation uses 4 bytes less per source element than the C
maps, and 20 bytes less than the newer C++ functions (which also
had more overhead with larger N-gons). The usage syntax is simpler
than the C functions as well.

The reduced memory usage is helpful for when these maps are cached
in the near future. It will also allow sharing the offsets between
maps for different domains like vertex to corner and vertex to face.

A simple `GroupedSpan` class is introduced to make accessing the
topology maps much simpler. It combines offset indices and a separate
span, splitting it into chunks in an efficient way.

Pull Request: https://projects.blender.org/blender/blender/pulls/107861
2023-05-24 13:16:57 +02:00
Hans Goudey
e704ebaba4 Cleanup: Remove unnecessary template in curve subdivide node
The Catmull Rom curve subdivision arguments use runtime-typed spans,
so the template doesn't help anyway. Makes Blender 27 KB smaller.
2023-05-23 19:57:43 -04:00
Chris Blackbourn
0f87bdfd8f Merge branch 'blender-v3.6-release' 2023-05-24 11:30:01 +12:00
Chris Blackbourn
f96e108b63 UV: Complete options for rotation during uv packing
The rotation options are now:
* None
* Axis-Aligned (Blender 3.3 default)
   - Rotate to a minimal rectangle, either vertical or horizontal.
* Cardinal (new)
   - Only 90 degree rotations are allowed.
* Any
   - Blender 3.6 default.
2023-05-24 11:27:59 +12:00
Campbell Barton
ad87bf3dc7 Cleanup: spelling, wording improvements 2023-05-23 11:50:34 +10:00
Chris Blackbourn
fd887bcb15 Merge branch 'blender-v3.6-release' 2023-05-22 15:58:47 +12:00
Chris Blackbourn
96101a66fc UV: Use correct uv packing method when all/none islands are pinned.
During packing, some combinations of `Fraction` margin method, and
various locking options, interact with situations where all or none
of the islands are pinned.

Previously, the settings were queried to choose the best packing method.

Now, the islands themselves are queried if they can translate or scale,
and the packing method is chosen based on the input, rather than the
parameters.

Fixes unreported crash with "Locked Position" when all islands are pinned.

Reported as #108037 "3. In some case locked position is not respected"
2023-05-22 15:54:38 +12:00
Chris Blackbourn
47cbeabb11 UV: Fix uv packing problem with rotate and scale line-search
When rotation is enabled and doing a scale line-search (locked islands
or "fraction" margin method), if the `rotate_inside_square` would
result in a a tighter packing, the wrong scale value was being used,
resulting in UVs outside of the unit square.

Reported as #108037 "1. Use locked scale on after scaling UV..."
2023-05-22 15:44:01 +12:00
Chris Blackbourn
de4f456ea2 UV: Fix overlap problem during uv packing with scale locked islands
If an island overlaps a pinned island, and that pinned island has
locked scale, then the pinning information must be copied to the
first island so it can be scaled correctly.

Reported in #108037 as "2. Use with Merge Overlapped"
2023-05-22 15:36:03 +12:00
Campbell Barton
8925ea1890 Merge branch 'blender-v3.6-release' 2023-05-20 21:18:02 +10:00
Campbell Barton
bf36a61e62 Cleanup: spelling in comments & some corrections 2023-05-20 21:17:09 +10:00
Hans Goudey
2a56403cb0 Mesh: Move bevel weight to generic attribute
Store bevel weights in two new named float attributes:
- `bevel_weight_vert`
- `bevel_weight_edge`

These attributes are naming conventions. Blender doesn't enforce
their data type or domain at all, but some editing features and
modifiers use the hard-coded name. Eventually those tools should
become more generic, but this is a simple change to allow more
flexibility in the meantime.

The largest user-visible changes are that the attributes populate the
attribute list, and are propagated by geometry nodes. The method of
removing this data is now the attribute list as well.

This is a breaking change. Forward compatibility is not preserved, and
the vertex and edge `bevel_weight` properties are removed. Python API
users are expected to use the attribute API to get and set the values.

Fixes #106949

Pull Request: https://projects.blender.org/blender/blender/pulls/108023
2023-05-19 14:31:31 +02:00
Hans Goudey
71d22331b1 Cleanup: Rename mesh loose edges tag function
To match the more recently added `tag_loose_verts_none`.
2023-05-18 23:06:15 -04:00
Chris Blackbourn
6daa3f6b8a UV: Fix packing problem with locked-position and large island count 2023-05-16 17:19:31 +12:00
Chris Blackbourn
4b4babae8b UV: Improve correctness of uv packer
Minor corrections including:
* Fast packer wasn't treating locked islands correctly.
* Pointer aliasing.
* Fix and some assumptions that might not be always true.
* Improve variable names.
* Improved comments.
2023-05-16 11:00:35 +12:00
Chris Blackbourn
f44795ce17 Fix #107898: UV packer regression
Layouts with >1024 rectangle islands would leave empty UV space.

Regression from ccb2dbddac.
2023-05-14 11:07:24 +12:00
Hans Goudey
4f2ac09886 Cleanup: Reduce binary size by deduplicating attribute processing
This makes the Blender binary 350 KB smaller. The largest change comes
from using `FunctionRef` instead of a template when gathering indices to
mix in the extrude node (which has no performance cost). The rest of the
change comes from consolidating uses of code generation for all
attribute types. This brings us a bit further in the direction of
unifying attribute propagation.

Pull Request: https://projects.blender.org/blender/blender/pulls/107823
2023-05-12 14:44:39 +02:00
Chris Blackbourn
edc12436c6 UV: During packing, add progress bar and ability to cancel
Uses job system.

Co-authored-by: Campbell Barton <campbell@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/107859
2023-05-12 14:50:40 +12:00
Hans Goudey
85ddc1b0de Cleanup: Use OffsetIndices class in extrude node and merge by distance node 2023-05-11 22:15:41 -04:00
Chris Blackbourn
225d111357 UV: Rename ED_UVPACK_PIN_NORMAL to ED_UVPACK_PIN_DEFAULT 2023-05-12 11:09:27 +12:00
Campbell Barton
d9293ca478 Fix missing include, unused argument warning 2023-05-11 17:46:23 +10:00
Chris Blackbourn
ccb2dbddac UV: Simplify packer, improving performance, efficiency and fixing bugs
Adds a generic `is_larger` and `get_aspect_scaled_extent` function to
simplify packing logic.

Migrate several packing functions so that they only improve a layout,
and early-exit packing if a better layout already exists.

Fix a `rotate_inside_square` logic error during xatlas packing.
2023-05-11 17:13:05 +12:00
Hans Goudey
143ca272bd Geometry Nodes: Slightly optimize mesh to curve node
Use the offset indices pattern to avoid keeping separate arrays for the
offset of a vertex's neighbors and the number of neighbors. This gave
a 9% speedup for the conversion, from 42.9 ms to 39.3 ms.
2023-05-10 15:24:12 -04:00
Jacques Lucke
c3365666e5 Fix #107637: crash when using density brush on empty hair 2023-05-08 09:26:15 +02:00
Chris Blackbourn
5abb3c96cf UV: Add pinned island support to uv packer
New pinned modes:
 * Ignore pinned islands
 * Normal (default)
 * Lock scale
 * Lock rotation
 * Lock position of pinned UV islands.
2023-05-07 17:54:51 +12:00
Chris Blackbourn
0eba9e41bf Cleanup: Convert float to double during uv unwrap
`sinf(float_angle)` is sometimes producing different results on
x86_64 cpus and apple silicon cpus. Convert to double precision
to increase accuracy and consistency.

Partial fix for #104513. More to come.
2023-05-07 12:07:40 +12:00
Chris Blackbourn
a684e61cbf Cleanup: fix warnings 2023-05-07 11:47:54 +12:00
Chris Blackbourn
b01f5444a3 UV: Improve packing efficiency
Introduces "Optimal" packing, where the layout is a theoretical
best possible for a given input.

e.g. https://erich-friedman.github.io/packing/squinsqu

Also calls multiple packing algorithms, and chooses the best one.
2023-05-06 10:39:00 +12:00
Hans Goudey
367145209c Cleanup: Move attribute_math to proper blenkernel namespace
The fact that blenlib doesn't know about the set of attribute types is
actually an important detail right now that can influence how things
are designed. Longer term it would be good to consolidate many of
these attribute propagation algorithms anyway.
2023-05-03 12:10:54 -04:00
Campbell Barton
bcedbdcf6f Cleanup: improve code-comments, naming, use defines, correct spelling 2023-05-03 17:34:27 +10:00
Campbell Barton
90361278d7 Cleanup: use function style casts, remove redundant parenthesis 2023-05-02 20:26:17 +10:00
Campbell Barton
6859bb6e67 Cleanup: format (with BraceWrapping::AfterControlStatement "MultiLine") 2023-05-02 09:37:49 +10:00
illua1
0652945dbd Fix #107306: Merge by distance node is not deterministic
In some cases the node didn't reproduce the same results given the
same input. Based on the test results (just 2 very detailed cubes
and a transformation), it doesn't seem to affect performance that
much. Credit to @MMMM who pointed out this option.

Pull Request: https://projects.blender.org/blender/blender/pulls/107312
2023-05-01 22:15:19 +02:00
Hans Goudey
f59fdc40ec Fix: Missing normalization for sampled normals when adding curves
Mistake when splitting up commits for 0a5f0890cc.
2023-05-01 08:41:20 -04:00
Chris Blackbourn
3ea060860a UV: Tuning rotating to minimum square during packing
* Perform rotate_inside_square earler in the pipeline. (improved layout)
* #rotate_inside_square with AABB margin if there is only one island.
* Conservative bounds when using xatlas on non-D4 transforms.
2023-05-01 23:18:15 +12:00
Chris Blackbourn
5c1c45cd59 UV: Improve packing efficiency by rotating to minimum square
After primary packing is completed, perform a deep earch for any
rotation of the entire layout which improves efficiency even further.

This can sometime provides *optimal* packing results. e.g. When packing
a single island, the layout will now touch all 4 sides of the unit square.
2023-04-30 16:55:39 +12:00
Chris Blackbourn
ca00cb5470 Cleanup: format 2023-04-29 13:50:23 +12:00
Chris Blackbourn
69d52c5f1c UV: Fix uv packing overflow with fraction margin method
When UV Packing with the `fraction` margin method, if the UVs
overflowed the unit square, the UVs could sometimes overlap.

(island_index was incorrect.)
2023-04-29 10:25:40 +12:00
Chris Blackbourn
bf56df3236 UV: Add new packing option, scale_to_fit
When `scale_to_fit` is enabled, the existing behavior is used,
UVs will be scaled to fill the unit square.

If disabled, UVs will not be rescaled. They will be packed to the
bottom-left corner, possibly overflowing the unit square, or not
filling space.
2023-04-29 09:50:33 +12:00
Hans Goudey
96fd14a65f Cleanup: Fix typo in mesh sample function name 2023-04-28 14:45:22 -04:00
Hans Goudey
bec033e057 Cleanup: Simplify and deduplicate mesh sampling code
It arguably reads easier if simple operations like reading from indices
of an array don't each get their own line. Also the same corner
attribute sampling was repeated in a few places. And add a new
function to sample normals from the corner domain, and use
lower level arguments to the lower level functions (i.e. not just
a mesh pointer, but the necessary data arrays).
2023-04-28 14:45:22 -04:00
Hans Goudey
0a5f0890cc Cleanup: Use helper function to sample normals when adding curves 2023-04-28 14:45:22 -04:00