Commit Graph

1696 Commits

Author SHA1 Message Date
Kévin Dietrich
4425e0cd64 Subdivision: add support for vertex creasing
This adds vertex creasing support for OpenSubDiv for modeling, rendering,
Alembic and USD I/O.

For modeling, vertex creasing follows the edge creasing implementation with an
operator accessible through the Vertex menu in Edit Mode, and some parameter in
the properties panel. The option in the Subsurf and Multires to use edge
creasing also affects vertex creasing.

The vertex crease data is stored as a CustomData layer, unlike edge creases
which for now are stored in `MEdge`, but will in the future also be moved to
a `CustomData` layer. See comments for details on the difference in behavior
for the `CD_CREASE` layer between egdes and vertices.

For Cycles this adds sockets on the Mesh node to hold data about which vertices
are creased (one socket for the indices, one for the weigths).

Viewport rendering of vertex creasing reuses the same color scheme as for edges
and creased vertices are drawn bigger than uncreased vertices.

For Alembic and USD, vertex crease support follows the edge crease
implementation, they are always read, but only exported if a `Subsurf` modifier
is present on the Mesh.

Reviewed By: brecht, fclem, sergey, sybren, campbellbarton

Differential Revision: https://developer.blender.org/D10145
2022-01-20 12:21:34 +01:00
Campbell Barton
eb3ff1d6f9 Cleanup: spelling in comments 2022-01-20 11:59:20 +11:00
Campbell Barton
eb63646605 BMesh: add mesh debug information printing
- Add BM_mesh_debug_print & BM_mesh_debug_info.
- Report flags in Mesh.cd_flag in BKE_mesh_debug_print
- Move custom data printing into customdata.cc (noted as a TODO).

Note that the term "runtime" has been removed from
`BKE_mesh_runtime_debug_print` since these are useful for debugging any
kind of mesh data.
2022-01-19 17:16:00 +11:00
Campbell Barton
71879d665d BMesh: improve handling of custom-data flag (Mesh.cd_flag)
Code that handled merging & initializing custom-data from other
meshes sometimes missed checks for this flag, causing bevel weights to
lost when the mesh was converted to a BMesh.

The following changes are a more general fix for T94197.

- Add BM_mesh_copy_init_customdata_from_mesh_array which initializes
  custom-data from multiple meshes at once.
  As well as initializing custom-data layers from Mesh.cd_flag.

  This isn't essential for boolean, however it avoids the overhead of
  resizing custom-data layers.

- Loading mesh data into a BMesh now respects Mesh.cd_flag
  instead of only checking if the BMesh custom-data-layer exists.
  Without this, the order of meshes passed to BM_mesh_bm_from_me could
  give different (incorrect) results.

- Copying mesh data now copies `cd_flag` too. This is a precaution
  as in my tests evaluating modifiers these values always matched.
  Nevertheless it's correct to copy this value as custom-data it's
  self is being copied.
2022-01-19 14:30:10 +11:00
Hans Goudey
cfa53e0fbe Refactor: Move normals out of MVert, lazy calculation
As described in T91186, this commit moves mesh vertex normals into a
contiguous array of float vectors in a custom data layer, how face
normals are currently stored.

The main interface is documented in `BKE_mesh.h`. Vertex and face
normals are now calculated on-demand and cached, retrieved with an
"ensure" function. Since the logical state of a mesh is now "has
normals when necessary", they can be retrieved from a `const` mesh.

The goal is to use on-demand calculation for all derived data, but
leave room for eager calculation for performance purposes (modifier
evaluation is threaded, but viewport data generation is not).

**Benefits**
This moves us closer to a SoA approach rather than the current AoS
paradigm. Accessing a contiguous `float3` is much more efficient than
retrieving data from a larger struct. The memory requirements for
accessing only normals or vertex locations are smaller, and at the
cost of more memory usage for just normals, they now don't have to
be converted between float and short, which also simplifies code

In the future, the remaining items can be removed from `MVert`,
leaving only `float3`, which has similar benefits (see T93602).

Removing the combination of derived and original data makes it
conceptually simpler to only calculate normals when necessary.
This is especially important now that we have more opportunities
for temporary meshes in geometry nodes.

**Performance**
In addition to the theoretical future performance improvements by
making `MVert == float3`, I've done some basic performance testing
on this patch directly. The data is fairly rough, but it gives an idea
about where things stand generally.
 - Mesh line primitive 4m Verts: 1.16x faster (36 -> 31 ms),
   showing that accessing just `MVert` is now more efficient.
 - Spring Splash Screen: 1.03-1.06 -> 1.06-1.11 FPS, a very slight
   change that at least shows there is no regression.
 - Sprite Fright Snail Smoosh: 3.30-3.40 -> 3.42-3.50 FPS, a small
   but observable speedup.
 - Set Position Node with Scaled Normal: 1.36x faster (53 -> 39 ms),
   shows that using normals in geometry nodes is faster.
 - Normal Calculation 1.6m Vert Cube: 1.19x faster (25 -> 21 ms),
   shows that calculating normals is slightly faster now.
 - File Size of 1.6m Vert Cube: 1.03x smaller (214.7 -> 208.4 MB),
   Normals are not saved in files, which can help with large meshes.

As for memory usage, it may be slightly more in some cases, but
I didn't observe any difference in the production files I tested.

**Tests**
Some modifiers and cycles test results need to be updated with this
commit, for two reasons:
 - The subdivision surface modifier is not responsible for calculating
   normals anymore. In master, the modifier creates different normals
   than the result of the `Mesh` normal calculation, so this is a bug
   fix.
 - There are small differences in the results of some modifiers that
   use normals because they are not converted to and from `short`
   anymore.

**Future improvements**
 - Remove `ModifierTypeInfo::dependsOnNormals`. Code in each modifier
   already retrieves normals if they are needed anyway.
 - Copy normals as part of a better CoW system for attributes.
 - Make more areas use lazy instead of eager normal calculation.
 - Remove `BKE_mesh_normals_tag_dirty` in more places since that is
   now the default state of a new mesh.
 - Possibly apply a similar change to derived face corner normals.

Differential Revision: https://developer.blender.org/D12770
2022-01-13 14:38:25 -06:00
Clément Foucault
fb6bd88644 Revert "BLI: Refactor vector types & functions to use templates"
Includes unwanted changes

This reverts commit 46e049d0ce.
2022-01-12 12:50:02 +01:00
Clment Foucault
46e049d0ce BLI: Refactor vector types & functions to use templates
This patch implements the vector types (i.e:`float2`) by making heavy
usage of templating. All vector functions are now outside of the vector
classes (inside the `blender::math` namespace) and are not vector size
dependent for the most part.

In the ongoing effort to make shaders less GL centric, we are aiming
to share more code between GLSL and C++ to avoid code duplication.

####Motivations:
 - We are aiming to share UBO and SSBO structures between GLSL and C++.
 This means we will use many of the existing vector types and others
 we currently don't have (uintX, intX). All these variations were
 asking for many more code duplication.
 - Deduplicate existing code which is duplicated for each vector size.
 - We also want to share small functions. Which means that vector
 functions should be static and not in the class namespace.
 - Reduce friction to use these types in new projects due to their
 incompleteness.
 - The current state of the `BLI_(float|double|mpq)(2|3|4).hh` is a
 bit of a let down. Most clases are incomplete, out of sync with each
 others with different codestyles, and some functions that should be
 static are not (i.e: `float3::reflect()`).

####Upsides:
 - Still support `.x, .y, .z, .w` for readability.
 - Compact, readable and easilly extendable.
 - All of the vector functions are available for all the vectors types
 and can be restricted to certain types. Also template specialization
 let us define exception for special class (like mpq).
 - With optimization ON, the compiler unroll the loops and performance
 is the same.

####Downsides:
 - Might impact debugability. Though I would arge that the bugs are
 rarelly caused by the vector class itself (since the operations are
 quite trivial) but by the type conversions.
 - Might impact compile time. I did not saw a significant impact since
 the usage is not really widespread.
 - Functions needs to be rewritten to support arbitrary vector length.
 For instance, one can't call `len_squared_v3v3` in
 `math::length_squared()` and call it a day.
 - Type cast does not work with the template version of the `math::`
 vector functions. Meaning you need to manually cast `float *` and
 `(float *)[3]` to `float3` for the function calls.
 i.e: `math::distance_squared(float3(nearest.co), positions[i]);`
 - Some parts might loose in readability:
 `float3::dot(v1.normalized(), v2.normalized())`
 becoming
 `math::dot(math::normalize(v1), math::normalize(v2))`
 But I propose, when appropriate, to use
 `using namespace blender::math;` on function local or file scope to
 increase readability.
 `dot(normalize(v1), normalize(v2))`

####Consideration:
 - Include back `.length()` method. It is quite handy and is more C++
 oriented.
 - I considered the GLM library as a candidate for replacement. It felt
 like too much for what we need and would be difficult to extend / modify
 to our needs.
 - I used Macros to reduce code in operators declaration and potential
 copy paste bugs. This could reduce debugability and could be reverted.
 - This touches `delaunay_2d.cc` and the intersection code. I would like
 to know @howardt opinion on the matter.
 - The `noexcept` on the copy constructor of `mpq(2|3)` is being removed.
 But according to @JacquesLucke it is not a real problem for now.

I would like to give a huge thanks to @JacquesLucke who helped during this
and pushed me to reduce the duplication further.

Reviewed By: brecht, sergey, JacquesLucke

Differential Revision: https://developer.blender.org/D13791
2022-01-12 12:47:43 +01:00
Clément Foucault
e5766752d0 Revert "BLI: Refactor vector types & functions to use templates"
Reverted because the commit removes a lot of commits.

This reverts commit a2c1c368af.
2022-01-12 12:44:26 +01:00
Clément Foucault
a2c1c368af BLI: Refactor vector types & functions to use templates
This patch implements the vector types (i.e:float2) by making heavy
usage of templating. All vector functions are now outside of the vector
classes (inside the blender::math namespace) and are not vector size
dependent for the most part.

In the ongoing effort to make shaders less GL centric, we are aiming
to share more code between GLSL and C++ to avoid code duplication.

Motivations:
- We are aiming to share UBO and SSBO structures between GLSL and C++.
  This means we will use many of the existing vector types and others we
  currently don't have (uintX, intX). All these variations were asking
  for many more code duplication.
- Deduplicate existing code which is duplicated for each vector size.
- We also want to share small functions. Which means that vector functions
  should be static and not in the class namespace.
- Reduce friction to use these types in new projects due to their
  incompleteness.
- The current state of the BLI_(float|double|mpq)(2|3|4).hh is a bit of a
  let down. Most clases are incomplete, out of sync with each others with
  different codestyles, and some functions that should be static are not
  (i.e: float3::reflect()).

Upsides:
- Still support .x, .y, .z, .w for readability.
- Compact, readable and easilly extendable.
- All of the vector functions are available for all the vectors types and
  can be restricted to certain types. Also template specialization let us
  define exception for special class (like mpq).
- With optimization ON, the compiler unroll the loops and performance is
  the same.

Downsides:
- Might impact debugability. Though I would arge that the bugs are rarelly
  caused by the vector class itself (since the operations are quite trivial)
  but by the type conversions.
- Might impact compile time. I did not saw a significant impact since the
  usage is not really widespread.
- Functions needs to be rewritten to support arbitrary vector length. For
  instance, one can't call len_squared_v3v3 in math::length_squared() and
  call it a day.
- Type cast does not work with the template version of the math:: vector
  functions. Meaning you need to manually cast float * and (float *)[3] to
  float3 for the function calls.
  i.e: math::distance_squared(float3(nearest.co), positions[i]);
- Some parts might loose in readability:
  float3::dot(v1.normalized(), v2.normalized())
  becoming
  math::dot(math::normalize(v1), math::normalize(v2))
  But I propose, when appropriate, to use
  using namespace blender::math; on function local or file scope to
  increase readability. dot(normalize(v1), normalize(v2))

Consideration:
- Include back .length() method. It is quite handy and is more C++
  oriented.
- I considered the GLM library as a candidate for replacement.
  It felt like too much for what we need and would be difficult to
  extend / modify to our needs.
- I used Macros to reduce code in operators declaration and potential
  copy paste bugs. This could reduce debugability and could be reverted.
- This touches delaunay_2d.cc and the intersection code. I would like to
  know @Howard Trickey (howardt) opinion on the matter.
- The noexcept on the copy constructor of mpq(2|3) is being removed.
  But according to @Jacques Lucke (JacquesLucke) it is not a real problem
  for now.

I would like to give a huge thanks to @Jacques Lucke (JacquesLucke) who
helped during this and pushed me to reduce the duplication further.

Reviewed By: brecht, sergey, JacquesLucke

Differential Revision: http://developer.blender.org/D13791
2022-01-12 12:19:39 +01:00
Henrik Dick
631067e559 Add support for a longest diagonal quad triangulation mode
The new triangulation mode for quads is the opposite of the current default
shortest diagonal mode. It is optimal for cloth simulations using quad meshes.

Differential Revision: http://developer.blender.org/D13777
2022-01-11 18:51:25 +01:00
Campbell Barton
3d3bc74884 Cleanup: remove redundant const qualifiers for POD types
MSVC used to warn about const mismatch for arguments passed by value.
Remove these as newer versions of MSVC no longer show this warning.
2022-01-07 14:16:26 +11:00
Campbell Barton
499fec6f79 Cleanup: spelling in comments 2022-01-06 13:54:52 +11:00
Campbell Barton
a207c1cdaf Cleanup: resolve parameter mis-matches in doc-strings
Renamed or removed parameters which no longer exist.
2021-12-14 18:35:23 +11:00
Campbell Barton
c097c7b855 Cleanup: correct unbalanced doxygen groups
Also add groups in some files.
2021-12-14 16:17:10 +11:00
Campbell Barton
bd2b48e98d Cleanup: move public doc-strings into headers for various API's
Some doc-strings were skipped because of blank-lines between
the doc-string and the symbol and needed to be moved manually.

- Added space below non doc-string comments to make it clear
  these aren't comments for the symbols directly below them.
- Use doxy sections for some headers.

Ref T92709
2021-12-10 21:42:06 +11:00
Campbell Barton
715f57371b Cleanup: spelling in comments 2021-12-10 21:28:56 +11:00
Campbell Barton
c4e041da23 Cleanup: move public doc-strings into headers for 'bmesh'
Some minor improvements to doc-strings too.

Ref T92709
2021-12-03 20:10:57 +11:00
Campbell Barton
de5d36560f Fix T93574: Asset triangulating a mesh
Correct assert for edit-mesh normal calculation.
2021-12-03 16:55:34 +11:00
Campbell Barton
1061f5a1ba Cleanup: remove redundant loop-index access
Use a counter for loop indices as they're being iterated in order.
2021-11-12 18:33:05 +11:00
Campbell Barton
bec72a43ae Fix T92874: Custom normals reset when vertex is deleted
Storing and restoring custom normals was broken by
39b2a7bb7e

This also caused "Sharp Edge" option for Weld by Distance to fail,
reported as T92875.
2021-11-10 21:11:41 +11:00
Campbell Barton
2eb94f3036 Fix T92384: Wrong UV layers used with Boolean Modifier (Fast Solver)
Ensure the layers from the source mesh are used instead of the
object referenced by the boolean modifier.
2021-11-09 17:07:23 +11:00
Campbell Barton
1411118055 Cleanup: spelling in comments 2021-10-24 21:04:04 +11:00
Campbell Barton
74f45ed9c5 Cleanup: spelling in comments 2021-10-03 12:13:29 +11:00
Germano Cavalcante
2ecd963d87 Fix error in previous commit
`v_other` -> `v_step`
2021-09-28 16:57:49 -03:00
Germano Cavalcante
5cdb2aadfc Fix flag wrongly set in 'BM_face_split_edgenet_connect_islands'
Sometimes the `use_partial_connect` option could trigger the assert:
```
BLI_assert(!BM_elem_flag_test(l_iter->v, VERT_NOT_IN_STACK));
```

This can happen when `v_delimit->e` is not part of edgenet, so `v_other` will not have the flag.
2021-09-28 16:54:23 -03:00
Falk David
9b2b32a333 Fix T84638: Wrong scale for primitives with radius
Creating some primitives allows for a scale value (via python) that will
scale the object accordingly. For objects with a radius parameter
(like cylinders, spheres, etc.) passing a scale different to (1,1,1)
would result in unexpected behavior.

For example:
`>>> bpy.ops.mesh.primitive_uv_sphere_add(radius=2, scale=(1,1,2))`
We would expect this to create a sphere with a radius of 2
(dimensions 4,4,4) and then be scaled *2 along the z-axis
(dimensions 4,4,8). But this would previously create a scaled sphere
with dimensions (2,2,4).

The scale was simply divided by two. Maybe because the "radius"
parameter for creating the primitives was confusingly named "diameter"
(but used as the radius).

The fix adds a scale parameter to `ED_object_new_primitive_matrix`
and also renames the wrongly named "diameter" parameters to "radius".

Reviewed By: campbellbarton

Maniphest Tasks: T84638

Ref D10093
2021-09-13 18:02:27 +10:00
Mikkel Gjoel
863d806526 BMesh: optimize edge & face group calculation
This changes the search for unprocessed faces to only search
from the previously found face. Local testing on 1.5 million
triangle meshes gives a 75x speedup
(of the code affected, which is the first half of the work).

The former code would traverse all faces of a mesh until a face was
found that had not been processed. This ended up being slow mainly
because it had to load face-data to determine the state of the flag.
Secondarily, the way it iterated and marked the mesh, it would end up
traversing all previously processed faces to find and unprocessed one.

The same optimization has been made for edge-group calculation.

Reviewed By: campbellbarton

Ref D12379
2021-09-04 23:07:45 +10:00
Campbell Barton
4c8d68c032 Cleanup: replace degenerate check with assert
Use an assert since this should never happen.
2021-08-17 15:16:34 +10:00
Campbell Barton
4cadccebfa Revert "Mesh: replace saacos with acosf for normal calculation"
This reverts commit 41e6509818.

This broke "CubeMaskFirst" test.

Any value even slightly outside the [-1.0..1.0] range
caused the result to be nan, which can happen when calculating
the dot-product between two unit length vectors.
2021-08-13 19:45:01 +10:00
Campbell Barton
41e6509818 Mesh: replace saacos with acosf for normal calculation
The clamped version of acos isn't needed as degenerate (nan) coordinates
result in zeroed vectors which don't need clamping.
2021-08-13 15:39:39 +10:00
Campbell Barton
909e0819ae Fix T90532: Crash editing meshes with auto-smooth
Caused by fix for T90256 and a misunderstanding in D11928.

Don't skip tagging edges when the auto-smooth angle is 180 degrees
since this skips topology checks which are needed for properly
calculating edge loop normals.
2021-08-09 18:32:53 +10:00
Campbell Barton
647a8bff06 Fix T90256: faces are flat shaded in edit mode with auto smooth
Regression in 39b2a7bb7e.
2021-08-05 18:21:17 +10:00
Brecht Van Lommel
8abf6efcf6 Cleanup: rename restrict to hide/visibility in Object, Collection, MaskLayer
This makes the internal naming consistent with the public API. And also gives
us a visibility_flag rather than restrictflag that can be extended with more
flags.
2021-08-04 19:18:34 +02:00
Campbell Barton
26c2c617b4 Fix T90421: edit-mode auto-smooth crash when angle set to 180degrees
Error in 39b2a7bb7e
which failed to set edge flags with single threaded calculation,
used for low poly models.
2021-08-04 22:40:25 +10:00
Campbell Barton
c1a477b497 Cleanup: use C++ comments or 'if 0' for commented code 2021-08-03 15:27:20 +10:00
Campbell Barton
11cfa6c718 Fix T90332: Auto-smooth crashes in edit-mode
Regression in 39b2a7bb7e
that meant non-manifold edges were not being tagged
when they should have been.
2021-08-02 23:58:55 +10:00
Hans Goudey
54bd5efa68 Fix build error in debug builds and uninitialized structs
This BMesh iterator hadn't been used in C++ code yet, and needed
a macro for a proper cast. The parameter structs need to be initialized
when declared without designated initializers.
2021-07-30 14:28:55 -04:00
Campbell Barton
f81a6a2ff1 Cleanup: spelling in comments 2021-07-30 16:16:38 +10:00
Campbell Barton
ced94bc11c Cleanup: code comments punctuation / spacing 2021-07-23 17:03:51 +10:00
Campbell Barton
7ce0d9d791 Cleanup: de-duplicate code for edge-split tagging
Share functionality for single and multi-threaded edge-split tagging.

Remove logic that ensured vert & loop indices in bm_mesh_edges_sharp_tag
(missing from fd9fc809b7).
2021-07-23 16:40:51 +10:00
Campbell Barton
eea65cbd42 Cleanup: remove unused BM_mesh_loop_normals_update function
The only difference with BM_loops_calc_normal_vcos was passing in
custom coordinates which may be NULL.
2021-07-23 15:10:59 +10:00
Campbell Barton
66dfef10a7 Fix error setting sharp edges in recent normal calculation changes
bm_mesh_edges_sharp_tag was called with setting sharp edges enabled.
Error in 39b2a7bb7e.
2021-07-23 15:02:04 +10:00
Campbell Barton
fd9fc809b7 Cleanup: remove normal assignment from bm_mesh_edges_sharp_tag
This was added in 0b7f581397
but seems not to be needed as the assignment was never correct
since only one corner on either side of the smooth edge had the
vertex normal written to it.
2021-07-23 14:36:40 +10:00
Campbell Barton
39b2a7bb7e Edit Mesh: multi-thread auto-smooth sharp-edge calculation
Merge the sharp edge tagging into bm_mesh_loops_calc_normals,
this has the advantage that edge tagging can be performed as part of
walking over each vertices edges - instead of tagging in a separate loop.

Even though this will tag edges twice (once for each vertex),
the computation isn't heavy as it's only calculating a dot-product
between the two face users to compare the angle.

This change combined with 4ba06ad0a8
makes BM_loops_calc_normal_vcos around 5.68x faster,
with an overall speedup over 2.6x when transforming a high poly mesh.
(tested on a system with 32 cores).

Reviewed By: mont29

Ref D11970
2021-07-23 12:55:58 +10:00
Campbell Barton
4ba06ad0a8 Edit Mesh: multi-thread auto-smooth & custom normal calculations
Supported multi-threading for bm_mesh_loops_calc_normals.

This is done by operating on vertex-loops instead of face-loops.

Single threaded operation still loops over faces since iterating
over vertices adds some overhead in the case of custom-normals
as the order used for accessing loops must be the same as iterating
of a faces loops.

From isolated timing tests of bm_mesh_loops_calc_normals on high
poly models, this gives between 3.5x to 10x speedup,
with larger gains for meshes with custom-normals.

NOTE: this is part one of two patches for multi-threaded auto-smooth,
tagging edges as sharp is still single threaded.

Reviewed By: mont29

Ref D11928
2021-07-23 12:54:17 +10:00
Campbell Barton
c3a400b73f Cleanup: use single back-tick quoting in comments
While doxygen supports both, conform to our style guide.

Note that single back-tick's are already used in a majority of comments.
2021-07-20 22:58:14 +10:00
Campbell Barton
0e9c04a3ea Cleanup: spelling 2021-07-20 11:12:24 +10:00
Campbell Barton
42017b006e Cleanup: sort struct declarations 2021-07-16 11:48:54 +10:00
Campbell Barton
bf5b1fa726 Cleanup: remove redundant parentheses 2021-07-16 11:45:52 +10:00
Campbell Barton
8e8a6b80cf Cleanup: replace BLI_assert(!"text") with BLI_assert_msg(0, "text")
This shows the text as part of the assertion message.
2021-07-15 18:29:01 +10:00