BLI code for enums that are meant to be used as "bit flags" defined
an ENUM_OPERATORS macro in BLI_utildefines.h. This cleans up things
related to said macro:
- Move it out into a separate BLI_enum_flags.hh header, instead of
"random bag of things" that is the current place,
- Update it to no longer need manual indication of highest individual
bit value. This originally was added in a31a87f89 (2020 Oct), in
order to silence some UBSan warnings that were coming
from GPU related structures (looking at current GPU code, I don't
think this is happening anymore). However, that caused actual
user-visible bugs due to incorrectly specified max. enum bit value,
and today 14% of all usages have incorrect highest individual
bit value spelled out.
- I have reviewed all usages of operator ~ and none of them are
used for directly producing a DNA-serialized value; all the
usages are for masking out other bits for which the new ~
behavior that just flips all bits is fine.
- Make the macro define flag_is_set() function to ease check of bits
that are set in C++ enum class cases; update existing cases to use
that instead of three other ways that were used.
Pull Request: https://projects.blender.org/blender/blender/pulls/148230
There was a bug in the move_weld_profile_planes function where
it would only move the profile plane involved in a "weld" if
certain vectors were not too small (less than BEVEL_EPSILON in
length). The intent of the code was just to avoid problems with
zero length normals (post normalization), and the normalize_v3
function indicates that with an exact 0.0f return, so there was
no need for an epsilon test.
The example file in the issue had a small-scale model (100 times
smaller than typical), which ended up causing the old code to
prevent moving the profile plane to where it belongs.
Pull Request: https://projects.blender.org/blender/blender/pulls/147898
Resolve regression in [0], remove unintended trailing space passed to
BMO_op_initf, causing a crash when the spin tool was activated.
Ref !147674
[0]: 83097400f0
Replace per UV map selection with a single UV selection for all UV's.
This uses the same data as UV sync select, meaning that it's no longer
possible to keep a different selection when sync-select is disabled.
There is a minor improvement to functionality - previously not possible
to de-select a single face surrounding by selected faces.
Now this is possible because true face selection is supported.
The selection from the active UV-map is converted to use the shared
selection data.
Ref !147523
Co-authored-by: Hans Goudey <hans@blender.org>
Support sync selection in the UV editor, with face-corner selection,
so it's possible to select individual UV vertices/edges in the UV editor
without UV's attached to the same underlying edge also becoming selected.
There is limited support for maintaining the UV selection when selecting
from the 3D viewport, common operations such as picking &
box/circle/lasso select support this, however other selection operations
such as "Select Random" or "Select Similar" will clear this data,
causing all UV's connected to selected mesh elements to become selected.
We may add support for additional operators as needed.
Details:
- UV Sync Selection is now enabled by default.
- In edit-mode the UV selection is stored in BMLoop/BMFace which are
written to custom-data layers when converted to a Mesh.
- To avoid unnecessary overhead - this data is created on demand.
Operators may clear this data - selecting all or none do so,
as there is no reason to store this data for a uniform selection.
- The Python API includes functions to synchronize the selection to/from
UV's as well as flushing based on the mode.
- Python scripts that manipulate the selection will either need to clear
this synchronized state or maintain it.
See:
- Design task: #78393.
- Implementation task: #131642.
Ref !138197
Support optionally flushing down:
- faces -> edges & verts.
- edges -> verts.
For C++ selection logic flushing down is avoided as it's an extra step
and instead, selection logic must take care to de-select edges/faces
before selection, so any shared vertices or edges are selected.
Flushing down means scripts can set the selection on faces or edges,
then flush this to all other elements without being concerned with
the order they have been set.
Ref !147351
The Spin operator generated faces with flipped normals because
extrude_face_region always flipped the input faces.
A new skip input flip option was added to extrude_face_region,
allowing the operator to preserve the original orientation when
needed and avoid creating duplicates with flipped normals.
Ref !146203
The operator passed edges into BM_edge_exists, which asserts both
inputs must be vertices. Mixed selections are now rejected with an
error message, preventing the assert and crash.
Ref !147239
The logic to copy custom normals checked for selection but didn't
account for the selection-history failing to initialize any
custom-normal loops.
Resolve by using the regular selection if the selection-history
cannot be used as a source for loop-normals.
Ref !147087
Regression in [0] removed checks for indices referencing themselves
which need to be kept but can still be used as targets.
Restore this logic as well as fixing another problem (#147022)
where auto-merge would not merge into the nearest vertex, this
was especially noticeable then the threshold was set to a large value
but would happen at smaller values too.
[0]: bdae3e28a2
MeshRuntime was null but required by the implementation
of the attribute API. This code is much hackier than necessary
anyway and should just use BMesh CustomData directly rather
than trying to be clever.
Also part of #122398.
Pull Request: https://projects.blender.org/blender/blender/pulls/146674
The naming was confusing as only some selection flushing functions
were intended to be used when elements had been selected or de-selected.
Replace these with a single function that takes a "select" argument.
The merge by distance operator now has an optional merge centroid
option, when it is enabled, groups of merged vertices are averaged
and moved to their centroid position.
This allows for more predictable results in cases where vertices that
form loops would have otherwise collapsed unevenly and ended up with
jagged lines.
Ref !146478
Previously the method of picking the "target" duplicate wasn't
deterministic from a user perspective.
The behavior has been changed so:
- For a cluster of 3 or more vertices,
use the vertex closest to the centroid.
- For a cluster of 2 use the lowest index.
This mitigates #78916, solving some cases where clusters have a
central vertex although can't be considered fixed as the 2 vertex
case doesn't work so well.
Added a BLI_kdtree_{N}d_calc_duplicates_cb function that lets the
caller choose the index to keep from a cluster of duplicates.
Refactored from !145851.
Ref !146492
Co-authored-by: tariqsulley <tariqsulley3c@gmail.com>
The previous implementation used KDTree duplicate search with
BLI_kdtree_3d_calc_duplicates_fast(). The survivor was always
one of the input vertices, not the centroid of the cluster.
This caused cases where merging a line of vertices did not
collapse to their average position, resulting in jagged loops.
Now vertices within the threshold are clustered, their centroid
is computed, and the chosen survivor is snapped to this centroid.
This ensures predictable and consistent merge results.
Ref !145851
This argument is always passed as null. Removing it simplifies the
transition to `AttributeStorage`. Nowadays it seems that most more
complicated interpolation needs are not handled directly by the
CustomData system.
Pull Request: https://projects.blender.org/blender/blender/pulls/145197
Use of BM_faces_join_pair can result in an invalid mesh with doubled
faces. [0] added an assert to identify when this could occur.
This case has been inspected, and allowing the auto-join logic in
BM_faces_join_pair() to delete the doubled face does not negatively
impact iteration or processing:
1. The eheap and eheap_table used here deal only with edges, not faces.
2. Loop iteration is unchanged.
A conversion to use of BM_ITER_MESH_MUTABLE is not applicable because
the iteration is done on the edge heap, not the mesh.
3. The recomputation of the face normals of each combined face still
works properly.
Ref !144653
[0]: 702efd6846
PR https://projects.blender.org/blender/blender/pulls/144233.
Fix#142296 performance regression caused by merging UV positions
based on face area weights, replacing it with mean average weights
computation. The former method resulted in higher probability in making
subdivision cache invalid between frame updates and thus causing expensive
recreation of blender::bke::subdiv::OpenSubdiv_Evaluator object.
While this fix isn't directly answering a question why specific UV position
updates would cause this reevaluation of subdivision object, it fixes
the performance regression caused by #139595 PR.
Support limiting the merge by connected geometry.
This is useful for operations such as bevel where it's not desirable
for the merge to connect isolated surfaces.
Accessible from the Python API, no user visible changes.
Ref !144036
The check that triangles from a quad point away from each other wasn't
sufficient to avoid creating bow-tie quads.
Resolve by picking the most planar triangle pair.
This is the second time I've needed a function to find an attribute by
name on all attribute domains, with a third time coming soon. It seems
time to put this in a BMesh header.
Pull Request: https://projects.blender.org/blender/blender/pulls/144039
If the BMesh already has a "custom_normal" attribute with the wrong
type, the call to `BM_lnorspace_update` won't be able to add the
attribute with the expected name, and the bevel code ends up using an
invalid offset to access the data.
For the fix, first just guard against that case. But also make sure the
harden normals functionality still works when the input mesh has free
normals. They will no be converted to tangent space normals as
necessary, in bevel and in other BMesh code that requires that
custom normal storage format.
Pull Request: https://projects.blender.org/blender/blender/pulls/143489
While all callers currently operate on the selection, the function
supports other header-flags, so check the selection is being used
before updating & flushing the selection.