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.
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"
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..."
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"
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.
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
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.
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.
`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.
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.
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.
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
* 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.
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.
When UV Packing with the `fraction` margin method, if the UVs
overflowed the unit square, the UVs could sometimes overlap.
(island_index was incorrect.)
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.
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).
Currently `Mesh to Volume` creates a volume using
`openvdb::tools::meshToVolume` which is then filled with the specified
density and the class set to Fog Volume. This is wrong because
`meshToVolume` creates a signed distance field by default that needs
to be converted to a Fog Volume with `openvdb::tools::sdfToFogVolume`
to get a proper Fog volume.
Here is the description of what that function does (from OpenVDB):
"The active and negative-valued interior half of the narrow band
becomes a linear ramp from 0 to 1; the inactive interior becomes
active with a constant value of 1; and the exterior, including the
background and the active exterior half of the narrow band, becomes
inactive with a constant value of 0. The interior, though active,
remains sparse."
This means with this commit old files will not look the same.
There is no way to version this as the options for external band width
and not filling the volume is removed (they don't make any sense for a
proper fog volume).
Pull Request: https://projects.blender.org/blender/blender/pulls/107279
Similar to the cache of loose edges added in 1ea169d90e,
cache the number of loose vertices and which are loose in a bit map.
This can save significant time when drawing large meshes in the
viewport, because recalculations can be avoided when the data doesn't
change, and because many geometry nodes set the loose geometry
caches eagerly when the meshes contain no loose elements.
There are two types of loose vertices:
1. Vertices not used by any edges or faces
`Mesh.loose_verts()`
2. Vertices not used by any faces (may be used by loose edges)
`Mesh.verts_no_face()`
Because both are used by Blender in various places, because the cost
is only a bit per vertex (or constant at best) and for design consistency,
we cache both types of loose elements. The bit maps will only be
allocated when they're actually used, but they are already accessed
in a few important places:
- Attribute domain interpolation
- Subdivision surface modifier
- Viewport drawing
Just skipping viewport drawing calculation after certain geometry
nodes setups can have a large impact. Here is the time taken by
viewport loose geometry extraction before and after the change:
- 4 million vertex grid node: 28 ms to 0 ms
- Large molecular nodes setup (curve to mesh node): 104 ms to 0 ms
- Realize instances with 1 million cubes: 131 ms to 0 ms
Pull Request: https://projects.blender.org/blender/blender/pulls/105567
The typical order is vertex, edge, face(polygon), corner(loop), but in
these three functions polys and loops were reversed. Also use more
typical "num" variable names rather than "len"
Avoid copying the selected edges if all edges are selected, and
parallelize gathering the selection otherwise. Also use `int2` instead
of `std::pair`.
In simple test file I observed an approximate 10% FPS improvement,
though in real world cases the impact is probably much smaller.
Add the ability to retrieve implicit sharing info directly from the
C++ attribute API, which simplifies memory usage and performance
optimizations making use of it. This commit uses the additions to
the API to avoid copies in a few places:
- The "rest_position" attribute in the mesh modifier stack
- Instance on Points node
- Instances to points node
- Mesh to points node
- Points to vertices node
Many files are affected because in order to include the new information
in the API's returned data, I had to switch a bunch of types from
`VArray` to `AttributeReader`. This generally makes sense anyway, since
it allows retrieving the domain, which wasn't possible before in some
cases. I overloaded the `*` deference operator for some syntactic sugar
to avoid the (very ugly) `.varray` that would be necessary otherwise.
Pull Request: https://projects.blender.org/blender/blender/pulls/107059
Implements #95966, as the final step of #95965.
This commit changes the storage of mesh edge vertex indices from the
`MEdge` type to the generic `int2` attribute type. This follows the
general design for geometry and the attribute system, where the data
storage type and the usage semantics are separated.
The main benefit of the change is reduced memory usage-- the
requirements of storing mesh edges is reduced by 1/3. For example,
this saves 8MB on a 1 million vertex grid. This also gives performance
benefits to any memory-bound mesh processing algorithm that uses edges.
Another benefit is that all of the edge's vertex indices are
contiguous. In a few cases, it's helpful to process all of them as
`Span<int>` rather than `Span<int2>`. Similarly, the type is more
likely to match a generic format used by a library, or code that
shouldn't know about specific Blender `Mesh` types.
Various Notes:
- The `.edge_verts` name is used to reflect a mapping between domains,
similar to `.corner_verts`, etc. The period means that it the data
shouldn't change arbitrarily by the user or procedural operations.
- `edge[0]` is now used instead of `edge.v1`
- Signed integers are used instead of unsigned to reduce the mixing
of signed-ness, which can be error prone.
- All of the previously used core mesh data types (`MVert`, `MEdge`,
`MLoop`, `MPoly` are now deprecated. Only generic types are used).
- The `vec2i` DNA type is used in the few C files where necessary.
Pull Request: https://projects.blender.org/blender/blender/pulls/106638