Armature: Switch envelope weight calculation to the new subdiv code
There should be minimal user-measurable changes since the old algorithm is not the same as OpenSubdiv. For example now creases (both edge and vertex ones) are properly supported. This allows to have less dependencies on the old subdivision surface code which ideally will be removed soon. Pull Request: https://projects.blender.org/blender/blender/pulls/143712
This commit is contained in:
committed by
Sergey Sharybin
parent
d6cc9a0793
commit
55942f5fbe
@@ -45,4 +45,11 @@ float3 mesh_interpolate_position_on_edge(Span<float3> coarse_positions,
|
||||
bool is_simple,
|
||||
float u);
|
||||
|
||||
/**
|
||||
* Calculate positions position of the given mesh vertices at the limit surface of the mesh.
|
||||
*
|
||||
* The limit_positions is to be sized at exactly the number of the base mesh vertices.
|
||||
*/
|
||||
void calculate_limit_positions(Mesh *mesh, MutableSpan<float3> limit_positions);
|
||||
|
||||
} // namespace blender::bke::subdiv
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_mapping.hh"
|
||||
#include "BKE_subdiv.hh"
|
||||
#include "BKE_subdiv_deform.hh"
|
||||
#include "BKE_subdiv_eval.hh"
|
||||
#include "BKE_subdiv_foreach.hh"
|
||||
#include "BKE_subdiv_mesh.hh"
|
||||
@@ -1246,4 +1247,35 @@ Mesh *subdiv_to_mesh(Subdiv *subdiv, const ToMeshSettings *settings, const Mesh
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Limit surface
|
||||
* \{ */
|
||||
|
||||
void calculate_limit_positions(Mesh *mesh, MutableSpan<float3> limit_positions)
|
||||
{
|
||||
BLI_assert(mesh->verts_num == limit_positions.size());
|
||||
|
||||
limit_positions.copy_from(mesh->vert_positions());
|
||||
|
||||
Settings settings{};
|
||||
settings.is_simple = false;
|
||||
settings.is_adaptive = true;
|
||||
settings.level = 1;
|
||||
settings.use_creases = true;
|
||||
|
||||
/* Default subdivision surface modifier settings:
|
||||
* - UV Smooth:Keep Corners.
|
||||
* - BoundarySmooth: All. */
|
||||
settings.vtx_boundary_interpolation = SUBDIV_VTX_BOUNDARY_EDGE_ONLY;
|
||||
settings.fvar_linear_interpolation = SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_AND_JUNCTIONS;
|
||||
|
||||
Subdiv *subdiv = update_from_mesh(nullptr, &settings, mesh);
|
||||
if (subdiv) {
|
||||
deform_coarse_vertices(subdiv, mesh, limit_positions);
|
||||
free(subdiv);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::bke::subdiv
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "BKE_object.hh"
|
||||
#include "BKE_object_deform.h"
|
||||
#include "BKE_report.hh"
|
||||
#include "BKE_subdiv_mesh.hh"
|
||||
#include "BKE_subsurf.hh"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
@@ -199,7 +200,7 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap)
|
||||
|
||||
static void envelope_bone_weighting(Object *ob,
|
||||
Mesh *mesh,
|
||||
float (*verts)[3],
|
||||
const blender::Span<blender::float3> verts,
|
||||
int numbones,
|
||||
Bone **bonelist,
|
||||
bDeformGroup **dgrouplist,
|
||||
@@ -298,7 +299,8 @@ static void add_verts_to_dgroups(ReportList *reports,
|
||||
bPoseChannel *pchan;
|
||||
Mesh *mesh;
|
||||
Mat4 bbone_array[MAX_BBONE_SUBDIV], *bbone = nullptr;
|
||||
float(*root)[3], (*tip)[3], (*verts)[3];
|
||||
float(*root)[3], (*tip)[3];
|
||||
blender::Array<blender::float3> verts;
|
||||
bool *selected;
|
||||
int numbones, vertsfilled = 0, segments = 0;
|
||||
const bool wpmode = (ob->mode & OB_MODE_WEIGHT_PAINT);
|
||||
@@ -412,15 +414,15 @@ static void add_verts_to_dgroups(ReportList *reports,
|
||||
|
||||
/* create verts */
|
||||
mesh = static_cast<Mesh *>(ob->data);
|
||||
verts = static_cast<float(*)[3]>(
|
||||
MEM_callocN(mesh->verts_num * sizeof(*verts), "closestboneverts"));
|
||||
verts.reinitialize(mesh->verts_num);
|
||||
|
||||
if (wpmode) {
|
||||
/* if in weight paint mode, use final verts from evaluated mesh */
|
||||
const Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
|
||||
const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
|
||||
if (mesh_eval) {
|
||||
BKE_mesh_foreach_mapped_vert_coords_get(mesh_eval, verts, mesh->verts_num);
|
||||
BKE_mesh_foreach_mapped_vert_coords_get(
|
||||
mesh_eval, reinterpret_cast<float(*)[3]>(verts.data()), mesh->verts_num);
|
||||
vertsfilled = 1;
|
||||
}
|
||||
}
|
||||
@@ -428,7 +430,7 @@ static void add_verts_to_dgroups(ReportList *reports,
|
||||
/* Is subdivision-surface on? Lets use the verts on the limit surface then.
|
||||
* = same amount of vertices as mesh, but vertices moved to the
|
||||
* subdivision-surfaced position, like for 'optimal'. */
|
||||
subsurf_calculate_limit_positions(mesh, verts);
|
||||
blender::bke::subdiv::calculate_limit_positions(mesh, verts);
|
||||
vertsfilled = 1;
|
||||
}
|
||||
|
||||
@@ -445,8 +447,16 @@ static void add_verts_to_dgroups(ReportList *reports,
|
||||
if (heat) {
|
||||
const char *error = nullptr;
|
||||
|
||||
heat_bone_weighting(
|
||||
ob, mesh, verts, numbones, dgrouplist, dgroupflip, root, tip, selected, &error);
|
||||
heat_bone_weighting(ob,
|
||||
mesh,
|
||||
reinterpret_cast<float(*)[3]>(verts.data()),
|
||||
numbones,
|
||||
dgrouplist,
|
||||
dgroupflip,
|
||||
root,
|
||||
tip,
|
||||
selected,
|
||||
&error);
|
||||
if (error) {
|
||||
BKE_report(reports, RPT_WARNING, error);
|
||||
}
|
||||
@@ -475,7 +485,6 @@ static void add_verts_to_dgroups(ReportList *reports,
|
||||
MEM_freeN(root);
|
||||
MEM_freeN(tip);
|
||||
MEM_freeN(selected);
|
||||
MEM_freeN(verts);
|
||||
}
|
||||
|
||||
void ED_object_vgroup_calc_from_armature(ReportList *reports,
|
||||
|
||||
Reference in New Issue
Block a user