diff options
author | Jacques Lucke <jacques@blender.org> | 2022-07-08 15:45:48 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2022-07-08 15:47:10 +0300 |
commit | 05b38ecc7835b32a9f3aedf36ead4b3e41ec6ca4 (patch) | |
tree | 847549cae6eb8cf0344b14c6c0bc4d0cf5497a6e /source/blender/blenkernel/intern/mesh.cc | |
parent | aa78278ef6571b3784fe3d883ee00dc44bc7ed15 (diff) |
Curves: support deforming curves on surface
Curves that are attached to a surface can now follow the surface when
it is modified using shape keys or modifiers (but not when the original
surface is deformed in edit or sculpt mode).
The surface is allowed to be changed in any way that keeps uv maps
intact. So deformation is allowed, but also some topology changes like
subdivision.
The following features are added:
* A new `Deform Curves on Surface` node, which deforms curves with
attachment information based on the surface object and uv map set
in the properties panel.
* A new `Add Rest Position` checkbox in the shape keys panel. When checked,
a new `rest_position` vector attribute is added to the mesh before shape
keys and modifiers are applied. This is necessary to support proper
deformation of the curves, but can also be used for other purposes.
* The `Add > Curve > Empty Hair` operator now sets up a simple geometry
nodes setup that deforms the hair. It also makes sure that the rest
position attribute is added to the surface.
* A new `Object (Attach Curves to Surface)` operator in the `Set Parent To`
(ctrl+P) menu, which attaches existing curves to the surface and sets the
surface object as parent.
Limitations:
* Sculpting the procedurally deformed curves will be implemented separately.
* The `Deform Curves on Surface` node is not generic and can only be used
for one specific purpose currently. We plan to generalize this more in the
future by adding support by exposing more inputs and/or by turning it into
a node group.
Differential Revision: https://developer.blender.org/D14864
Diffstat (limited to 'source/blender/blenkernel/intern/mesh.cc')
-rw-r--r-- | source/blender/blenkernel/intern/mesh.cc | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 98fa551590c..2a14370bf93 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1848,9 +1848,25 @@ void BKE_mesh_vert_coords_apply_with_mat4(Mesh *mesh, BKE_mesh_tag_coords_changed(mesh); } -void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray *r_lnors_spacearr) +static float (*ensure_corner_normal_layer(Mesh &mesh))[3] { float(*r_loopnors)[3]; + if (CustomData_has_layer(&mesh.ldata, CD_NORMAL)) { + r_loopnors = (float(*)[3])CustomData_get_layer(&mesh.ldata, CD_NORMAL); + memset(r_loopnors, 0, sizeof(float[3]) * mesh.totloop); + } + else { + r_loopnors = (float(*)[3])CustomData_add_layer( + &mesh.ldata, CD_NORMAL, CD_CALLOC, nullptr, mesh.totloop); + CustomData_set_layer_flag(&mesh.ldata, CD_NORMAL, CD_FLAG_TEMPORARY); + } + return r_loopnors; +} + +void BKE_mesh_calc_normals_split_ex(Mesh *mesh, + MLoopNorSpaceArray *r_lnors_spacearr, + float (*r_corner_normals)[3]) +{ short(*clnors)[2] = nullptr; /* Note that we enforce computing clnors when the clnor space array is requested by caller here. @@ -1860,16 +1876,6 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray *r_lnors_spac ((mesh->flag & ME_AUTOSMOOTH) != 0); const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : (float)M_PI; - if (CustomData_has_layer(&mesh->ldata, CD_NORMAL)) { - r_loopnors = (float(*)[3])CustomData_get_layer(&mesh->ldata, CD_NORMAL); - memset(r_loopnors, 0, sizeof(float[3]) * mesh->totloop); - } - else { - r_loopnors = (float(*)[3])CustomData_add_layer( - &mesh->ldata, CD_NORMAL, CD_CALLOC, nullptr, mesh->totloop); - CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); - } - /* may be nullptr */ clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); @@ -1879,7 +1885,7 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray *r_lnors_spac mesh->medge, mesh->totedge, mesh->mloop, - r_loopnors, + r_corner_normals, mesh->totloop, mesh->mpoly, BKE_mesh_poly_normals_ensure(mesh), @@ -1895,7 +1901,7 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray *r_lnors_spac void BKE_mesh_calc_normals_split(Mesh *mesh) { - BKE_mesh_calc_normals_split_ex(mesh, nullptr); + BKE_mesh_calc_normals_split_ex(mesh, nullptr, ensure_corner_normal_layer(*mesh)); } /* Split faces helper functions. */ @@ -2114,7 +2120,7 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals) MLoopNorSpaceArray lnors_spacearr = {nullptr}; /* Compute loop normals and loop normal spaces (a.k.a. smooth fans of faces around vertices). */ - BKE_mesh_calc_normals_split_ex(mesh, &lnors_spacearr); + BKE_mesh_calc_normals_split_ex(mesh, &lnors_spacearr, ensure_corner_normal_layer(*mesh)); /* Stealing memarena from loop normals space array. */ MemArena *memarena = lnors_spacearr.mem; |