This gives better asserts in debug builds through use of Span, more
safety when name convention attributes happen to have different types
or domains, and simpler code in some cases. But the main reasoning is to
avoid relying on the specifics of CustomData more to allow us to replace
it in the future.
The version of BM_elem_attrs_copy that took a map used a reference
the version without a map didn't, which is fairly confusing.
Pass by pointer now unless this is part of a wider refactor
to move to references everywhere.
Continuation of fix for #115776. Removes attribute copy functions
that calculate the map inline, this is error prone as it's easy to
call these functions from a loop which may result in poor performance.
Fixes#115776
Create a minimal structure that contains the instructions necessary to
copy from one custom data format to another. This structure is similar
to the one used in dfacaf4f40. It should have been used in
9175d9b7c2, which instead introduced quadratic performance
relative to the number of layers when copying every element.
In this commit, copying the entire mesh and adding new custom data
are explicitly changed to use the new map to speed up copying many
elements at a time.
The non-map attribute copy functions are also changed to check for when
the source and result BMeshes are the same. In that case it's much
faster to call the "same format" function from 9175d9b7c2.
For numbers, the timings are arbitrarily influenced by how many layers
I add in my testing. With 50 or so layers, a 10x difference is easily
observable though.
Pull Request: https://projects.blender.org/blender/blender/pulls/115824
"mesh" reads much better than "me" since "me" is a different word.
There's no reason to avoid using two more characters here. Replacing
all of these at once is better than encountering it repeatedly and
doing the same change bit by bit.
NDEBUG is part of the C standard and disables asserts. Only this will
now be used to decide if asserts are enabled.
DEBUG was a Blender specific define, that has now been removed.
_DEBUG is a Visual Studio define for builds in Debug configuration.
Blender defines this for all platforms. This is still used in a few
places in the draw code, and in external libraries Bullet and Mantaflow.
Pull Request: https://projects.blender.org/blender/blender/pulls/115774
While it may be useful to detect threading issues for low poly meshes in debug
builds, it can also cause confusion when one breaks but not the other.
Further, having this logic for just a handlful bmesh functions while everything
else does not makes little sense.
After previous commits, there is a new function to copy a BMesh
custom data block that doesn't go through the "find common layers
between two formats" code. This is *much* faster when there is a
large amount of layers with the same type, since that code is
quadratic currently. It may not be noticeable in many simpler
setups though.
Related to #115776
Overload the attribute copy function for each element type, avoiding
the switch of different abstraction levels. The two extra arguments
besides the meshes and elements were constant, so the resulting
logic can be inlined as well.
When the BMesh source and result arguments are the same, restore
performance lost by 9175d9b7c2, which made copying layers
have quadratic time complexity. When we know the custom data format
is the same between the source and result, the copying can be much
simpler, so it's worth specializing this case. There is still more
to be done, because often we only know that the two meshes are the
same at runtime. A followup commit will add that check.
The quadratic runtime means performance is fine for low layer counts,
and terrible with higher layer counts. For example, in my testing with
47 boolean attributes, copying 250k vertices went from 2.3 seconds to
316 ms.
The implementation uses a new CustomData function that copies an entire
BMesh custom data block, called by a function in the BMesh module
overloaded for every BMesh element type. That handles the extra data
like flags, normals, and material indices.
Related to #115776
For now it has the same implementation as the function that allows
passing separate source and destination custom data formats. But
copying to the same format can potentially be much simpler.
Use blender::Set which is similar but offsers better type safety
and likely better performance as well. The only remaining user
was the mesh edit mode knife tool, and replacing that usage
with `Set` and `Map` was straightforward.
Store paint masks as generic float attributes, with the name
`".sculpt_mask"`. This is similar to 060a534141, which made
the same change for face sets. The benefits are general
consistency, nicer code, and more support in newer areas
that deal with attributes like geometry nodes.
The RNA API is replaced with one created in Python. The new
API only presents a single layer as an attribute class, so it
should be simpler to use in general:
- Before: `object.data.vertex_paint_masks[0].data[0].value`
- After: `object.data.vertex_paint_mask.data[0].value`
Pull Request: https://projects.blender.org/blender/blender/pulls/115119
Function Module Inclusive Time Exclusive Time
--------------------------------------------------------------------------
mesh_render_data_update_normals blender 297.51 0.00
315 -> 297
acos() usage in all places related to normal calculations shows up in the
profiler. Given that "angle between faces" is only additional heuristic
weight in there (the effect of it at all is very subtle), approximate but
faster version of acos() might be just fine. Especially since some other
parts of Blender (e.g. mikktspace) use approximate acos in a conceptually
the same part.
- Adds safe_acos_approx() to BLI_math_base.hh. Implementation the same
as already exists in Cycles; max error 0.00258 degrees. Between 2x and 4x
faster in my tests.
- Changes all normals related calculations to use the function above instead
of saacos.
Computing normals on a Stanford Lucy (14m verts) mesh:
- Mac (arm64, M1 Max): 247ms -> 229ms
- Win (x64, Ryzen 5950X): 276ms -> 250ms
All places that are about "normal calculation" were changed, including e.g.
Corrective Smooth modifier. Applying that one to the same 14m vertices mesh,
Mac M1 Max: 9.96s -> 9.76s
Tiny changes in several test output expectations w.r.t. normals are
observed, these were reviewed and updated expectations checked in svn.
Pull Request: https://projects.blender.org/blender/blender/pulls/114501
Design task: #93551
This PR replaces the auto smooth option with a geometry nodes modifier
that sets the sharp edge attribute. This solves a fair number of long-
standing problems related to auto smooth, simplifies the process of
normal computation, and allows Blender to automatically choose between
face, vertex, and face corner normals based on the sharp edge and face
attributes.
Versioning adds a geometry node group to objects with meshes that had
auto-smooth enabled. The modifier can be applied, which also improves
performance.
Auto smooth is now unnecessary to get a combination of sharp and smooth
edges. In general workflows are changed a bit. Separate procedural and
destructive workflows are available. Custom normals can be used
immediately without turning on the removed auto smooth option.
**Procedural**
The node group asset "Smooth by Angle" is the main way to set sharp
normals based on the edge angle. It can be accessed directly in the add
modifier menu. Of course the modifier can be reordered, muted, or
applied like any other, or changed internally like any geometry nodes
modifier.
**Destructive**
Often the sharp edges don't need to be dynamic. This can give better
performance since edge angles don't need to be recalculated. In edit
mode the two operators "Select Sharp Edges" and "Mark Sharp" can be
used. In other modes, the "Shade Smooth by Angle" controls the edge
sharpness directly.
### Breaking API Changes
- `use_auto_smooth` is removed. Face corner normals are now used
automatically if there are mixed smooth vs. not smooth tags. Meshes
now always use custom normals if they exist.
- In Cycles, the lack of the separate auto smooth state makes normals look
triangulated when all faces are shaded smooth.
- `auto_smooth_angle` is removed. Replaced by a modifier (or operator)
controlling the sharp edge attribute. This means the mesh itself
(without an object) doesn't know anything about automatically smoothing
by angle anymore.
- `create_normals_split`, `calc_normals_split`, and `free_normals_split`
are removed, and are replaced by the simpler `Mesh.corner_normals`
collection property. Since it gives access to the normals cache, it
is automatically updated when relevant data changes.
Addons are updated here: https://projects.blender.org/blender/blender-addons/pulls/104609
### Tests
- `geo_node_curves_test_deform_curves_on_surface` has slightly different
results because face corner normals are used instead of interpolated
vertex normals.
- `bf_wavefront_obj_tests` has different export results for one file
which mixed sharp and smooth faces without turning on auto smooth.
- `cycles_mesh_cpu` has one object which is completely flat shaded.
Previously every edge was split before rendering, now it looks triangulated.
Pull Request: https://projects.blender.org/blender/blender/pulls/108014
Check for multiple faces that use the same vertices. The implementation
uses a a Map with a Set of vertex pointers, so is not necessarily fast,
but this is just a debug check anyway.
Pull Request: https://projects.blender.org/blender/blender/pulls/113899
This replaces the older dynamic c arrays with blender::Vector as
appropriate. Many files required minimal changes and the before/after
are quite similar.
There's 3 remaining usages of the old machinery but those will require
more involved changes and design.
See #103343
Pull Request: https://projects.blender.org/blender/blender/pulls/110981
The hash tables and vector blenlib headers were pulling many more
headers than they actually need, including the C base math header,
our C string API header, and the StringRef header. All of this
potentially slows down compilation and polutes autocomplete
with unrelated information.
Also remove the `ListBase` constructor for `Vector`. It wasn't used
much, and making it easy to use `ListBase` isn't worth it for the
same reasons mentioned above.
It turns out a lot of files depended on indirect includes of
`BLI_string.h` and `BLI_listbase.h`, so those are fixed here.
Pull Request: https://projects.blender.org/blender/blender/pulls/111801
The `EdgeHash` and `EdgeSet` data structures are designed specifically
as a hash of an order agnostic pair of integers. This specialization can
be achieved much more easily with the templated C++ data structures,
which gives improved performance, readability, and type safety.
This PR removes the older data structures and replaces their use with
`Map`, `Set`, or `VectorSet` depending on the situation. The changes
are mostly straightforward, but there are a few places where the old
API made the goals of the code confusing.
The last time these removed data structures were significantly changed,
they were already moving closer to the implementation of the newer
C++ data structures (aa63a87d37).
Pull Request: https://projects.blender.org/blender/blender/pulls/111391
Listing the "Blender Foundation" as copyright holder implied the Blender
Foundation holds copyright to files which may include work from many
developers.
While keeping copyright on headers makes sense for isolated libraries,
Blender's own code may be refactored or moved between files in a way
that makes the per file copyright holders less meaningful.
Copyright references to the "Blender Foundation" have been replaced with
"Blender Authors", with the exception of `./extern/` since these this
contains libraries which are more isolated, any changed to license
headers there can be handled on a case-by-case basis.
Some directories in `./intern/` have also been excluded:
- `./intern/cycles/` it's own `AUTHORS` file is planned.
- `./intern/opensubdiv/`.
An "AUTHORS" file has been added, using the chromium projects authors
file as a template.
Design task: #110784
Ref !110783.
Using ClangBuildAnalyzer on the whole Blender build, it was pointing
out that BLI_math.h is the heaviest "header hub" (i.e. non tiny file
that is included a lot).
However, there's very little (actually zero) source files in Blender
that need "all the math" (base, colors, vectors, matrices,
quaternions, intersection, interpolation, statistics, solvers and
time). A common use case is source files needing just vectors, or
just vectors & matrices, or just colors etc. Actually, 181 files
were including the whole math thing without needing it at all.
This change removes BLI_math.h completely, and instead in all the
places that need it, includes BLI_math_vector.h or BLI_math_color.h
and so on.
Change from that:
- BLI_math_color.h was included 1399 times -> now 408 (took 114.0sec
to parse -> now 36.3sec)
- BLI_simd.h 1403 -> 418 (109.7sec -> 34.9sec).
Full rebuild of Blender (Apple M1, Xcode, RelWithDebInfo) is not
affected much (342sec -> 334sec). Most of benefit would be when
someone's changing BLI_simd.h or BLI_math_color.h or similar files,
that now there's 3x fewer files result in a recompile.
Pull Request #110944
The file bmesh_opdefines.c was recently converted to bmesh_opdefines.cc,
but the manual builder was not updated accordingly.
Also, update some comments in the code which were still mentioning the C
version of this file.
Pull Request: https://projects.blender.org/blender/blender/pulls/110532