Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/modifiers/intern/MOD_correctivesmooth.c')
-rw-r--r--source/blender/modifiers/intern/MOD_correctivesmooth.c1108
1 files changed, 551 insertions, 557 deletions
diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c
index d9e6ed78070..2a332bc9709 100644
--- a/source/blender/modifiers/intern/MOD_correctivesmooth.c
+++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c
@@ -44,10 +44,8 @@
#include "BLI_strict_flags.h"
-
#include "DEG_depsgraph_query.h"
-
// #define DEBUG_TIME
#include "PIL_time.h"
@@ -60,345 +58,343 @@
static void initData(ModifierData *md)
{
- CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
+ CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
- csmd->bind_coords = NULL;
- csmd->bind_coords_num = 0;
+ csmd->bind_coords = NULL;
+ csmd->bind_coords_num = 0;
- csmd->lambda = 0.5f;
- csmd->repeat = 5;
- csmd->flag = 0;
- csmd->smooth_type = MOD_CORRECTIVESMOOTH_SMOOTH_SIMPLE;
+ csmd->lambda = 0.5f;
+ csmd->repeat = 5;
+ csmd->flag = 0;
+ csmd->smooth_type = MOD_CORRECTIVESMOOTH_SMOOTH_SIMPLE;
- csmd->defgrp_name[0] = '\0';
+ csmd->defgrp_name[0] = '\0';
- csmd->delta_cache = NULL;
+ csmd->delta_cache = NULL;
}
-
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
- const CorrectiveSmoothModifierData *csmd = (const CorrectiveSmoothModifierData *)md;
- CorrectiveSmoothModifierData *tcsmd = (CorrectiveSmoothModifierData *)target;
+ const CorrectiveSmoothModifierData *csmd = (const CorrectiveSmoothModifierData *)md;
+ CorrectiveSmoothModifierData *tcsmd = (CorrectiveSmoothModifierData *)target;
- modifier_copyData_generic(md, target, flag);
+ modifier_copyData_generic(md, target, flag);
- if (csmd->bind_coords) {
- tcsmd->bind_coords = MEM_dupallocN(csmd->bind_coords);
- }
+ if (csmd->bind_coords) {
+ tcsmd->bind_coords = MEM_dupallocN(csmd->bind_coords);
+ }
- tcsmd->delta_cache = NULL;
- tcsmd->delta_cache_num = 0;
+ tcsmd->delta_cache = NULL;
+ tcsmd->delta_cache_num = 0;
}
-
static void freeBind(CorrectiveSmoothModifierData *csmd)
{
- MEM_SAFE_FREE(csmd->bind_coords);
- MEM_SAFE_FREE(csmd->delta_cache);
+ MEM_SAFE_FREE(csmd->bind_coords);
+ MEM_SAFE_FREE(csmd->delta_cache);
- csmd->bind_coords_num = 0;
+ csmd->bind_coords_num = 0;
}
-
static void freeData(ModifierData *md)
{
- CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
- freeBind(csmd);
+ CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
+ freeBind(csmd);
}
-
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
+ CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
- /* ask for vertex groups if we need them */
- if (csmd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertex groups if we need them */
+ if (csmd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
-
/* check individual weights for changes and cache values */
-static void mesh_get_weights(
- MDeformVert *dvert, const int defgrp_index,
- const unsigned int numVerts, const bool use_invert_vgroup,
- float *smooth_weights)
+static void mesh_get_weights(MDeformVert *dvert,
+ const int defgrp_index,
+ const unsigned int numVerts,
+ const bool use_invert_vgroup,
+ float *smooth_weights)
{
- unsigned int i;
-
- for (i = 0; i < numVerts; i++, dvert++) {
- const float w = defvert_find_weight(dvert, defgrp_index);
-
- if (use_invert_vgroup == false) {
- smooth_weights[i] = w;
- }
- else {
- smooth_weights[i] = 1.0f - w;
- }
- }
+ unsigned int i;
+
+ for (i = 0; i < numVerts; i++, dvert++) {
+ const float w = defvert_find_weight(dvert, defgrp_index);
+
+ if (use_invert_vgroup == false) {
+ smooth_weights[i] = w;
+ }
+ else {
+ smooth_weights[i] = 1.0f - w;
+ }
+ }
}
-
static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights)
{
- const MPoly *mpoly = mesh->mpoly;
- const MLoop *mloop = mesh->mloop;
- const MEdge *medge = mesh->medge;
- unsigned int mpoly_num, medge_num, i;
- unsigned short *boundaries;
-
- mpoly_num = (unsigned int)mesh->totpoly;
- medge_num = (unsigned int)mesh->totedge;
-
- boundaries = MEM_calloc_arrayN(medge_num, sizeof(*boundaries), __func__);
-
- /* count the number of adjacent faces */
- for (i = 0; i < mpoly_num; i++) {
- const MPoly *p = &mpoly[i];
- const int totloop = p->totloop;
- int j;
- for (j = 0; j < totloop; j++) {
- boundaries[mloop[p->loopstart + j].e]++;
- }
- }
-
- for (i = 0; i < medge_num; i++) {
- if (boundaries[i] == 1) {
- smooth_weights[medge[i].v1] = 0.0f;
- smooth_weights[medge[i].v2] = 0.0f;
- }
- }
-
- MEM_freeN(boundaries);
+ const MPoly *mpoly = mesh->mpoly;
+ const MLoop *mloop = mesh->mloop;
+ const MEdge *medge = mesh->medge;
+ unsigned int mpoly_num, medge_num, i;
+ unsigned short *boundaries;
+
+ mpoly_num = (unsigned int)mesh->totpoly;
+ medge_num = (unsigned int)mesh->totedge;
+
+ boundaries = MEM_calloc_arrayN(medge_num, sizeof(*boundaries), __func__);
+
+ /* count the number of adjacent faces */
+ for (i = 0; i < mpoly_num; i++) {
+ const MPoly *p = &mpoly[i];
+ const int totloop = p->totloop;
+ int j;
+ for (j = 0; j < totloop; j++) {
+ boundaries[mloop[p->loopstart + j].e]++;
+ }
+ }
+
+ for (i = 0; i < medge_num; i++) {
+ if (boundaries[i] == 1) {
+ smooth_weights[medge[i].v1] = 0.0f;
+ smooth_weights[medge[i].v2] = 0.0f;
+ }
+ }
+
+ MEM_freeN(boundaries);
}
-
/* -------------------------------------------------------------------- */
/* Simple Weighted Smoothing
*
* (average of surrounding verts)
*/
-static void smooth_iter__simple(
- CorrectiveSmoothModifierData *csmd, Mesh *mesh,
- float (*vertexCos)[3], unsigned int numVerts,
- const float *smooth_weights,
- unsigned int iterations)
+static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ unsigned int numVerts,
+ const float *smooth_weights,
+ unsigned int iterations)
{
- const float lambda = csmd->lambda;
- unsigned int i;
-
- const unsigned int numEdges = (unsigned int)mesh->totedge;
- const MEdge *edges = mesh->medge;
- float *vertex_edge_count_div;
-
- struct SmoothingData_Simple {
- float delta[3];
- } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__);
-
- vertex_edge_count_div = MEM_calloc_arrayN(numVerts, sizeof(float), __func__);
-
- /* calculate as floats to avoid int->float conversion in #smooth_iter */
- for (i = 0; i < numEdges; i++) {
- vertex_edge_count_div[edges[i].v1] += 1.0f;
- vertex_edge_count_div[edges[i].v2] += 1.0f;
- }
-
- /* a little confusing, but we can include 'lambda' and smoothing weight
- * here to avoid multiplying for every iteration */
- if (smooth_weights == NULL) {
- for (i = 0; i < numVerts; i++) {
- vertex_edge_count_div[i] =
- lambda * (vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) : 1.0f);
- }
- }
- else {
- for (i = 0; i < numVerts; i++) {
- vertex_edge_count_div[i] =
- smooth_weights[i] * lambda * (vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) : 1.0f);
- }
- }
-
- /* -------------------------------------------------------------------- */
- /* Main Smoothing Loop */
-
- while (iterations--) {
- for (i = 0; i < numEdges; i++) {
- struct SmoothingData_Simple *sd_v1;
- struct SmoothingData_Simple *sd_v2;
- float edge_dir[3];
-
- sub_v3_v3v3(edge_dir, vertexCos[edges[i].v2], vertexCos[edges[i].v1]);
-
- sd_v1 = &smooth_data[edges[i].v1];
- sd_v2 = &smooth_data[edges[i].v2];
-
- add_v3_v3(sd_v1->delta, edge_dir);
- sub_v3_v3(sd_v2->delta, edge_dir);
- }
-
-
- for (i = 0; i < numVerts; i++) {
- struct SmoothingData_Simple *sd = &smooth_data[i];
- madd_v3_v3fl(vertexCos[i], sd->delta, vertex_edge_count_div[i]);
- /* zero for the next iteration (saves memset on entire array) */
- memset(sd, 0, sizeof(*sd));
- }
- }
-
- MEM_freeN(vertex_edge_count_div);
- MEM_freeN(smooth_data);
+ const float lambda = csmd->lambda;
+ unsigned int i;
+
+ const unsigned int numEdges = (unsigned int)mesh->totedge;
+ const MEdge *edges = mesh->medge;
+ float *vertex_edge_count_div;
+
+ struct SmoothingData_Simple {
+ float delta[3];
+ } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__);
+
+ vertex_edge_count_div = MEM_calloc_arrayN(numVerts, sizeof(float), __func__);
+
+ /* calculate as floats to avoid int->float conversion in #smooth_iter */
+ for (i = 0; i < numEdges; i++) {
+ vertex_edge_count_div[edges[i].v1] += 1.0f;
+ vertex_edge_count_div[edges[i].v2] += 1.0f;
+ }
+
+ /* a little confusing, but we can include 'lambda' and smoothing weight
+ * here to avoid multiplying for every iteration */
+ if (smooth_weights == NULL) {
+ for (i = 0; i < numVerts; i++) {
+ vertex_edge_count_div[i] = lambda * (vertex_edge_count_div[i] ?
+ (1.0f / vertex_edge_count_div[i]) :
+ 1.0f);
+ }
+ }
+ else {
+ for (i = 0; i < numVerts; i++) {
+ vertex_edge_count_div[i] = smooth_weights[i] * lambda *
+ (vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) :
+ 1.0f);
+ }
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Main Smoothing Loop */
+
+ while (iterations--) {
+ for (i = 0; i < numEdges; i++) {
+ struct SmoothingData_Simple *sd_v1;
+ struct SmoothingData_Simple *sd_v2;
+ float edge_dir[3];
+
+ sub_v3_v3v3(edge_dir, vertexCos[edges[i].v2], vertexCos[edges[i].v1]);
+
+ sd_v1 = &smooth_data[edges[i].v1];
+ sd_v2 = &smooth_data[edges[i].v2];
+
+ add_v3_v3(sd_v1->delta, edge_dir);
+ sub_v3_v3(sd_v2->delta, edge_dir);
+ }
+
+ for (i = 0; i < numVerts; i++) {
+ struct SmoothingData_Simple *sd = &smooth_data[i];
+ madd_v3_v3fl(vertexCos[i], sd->delta, vertex_edge_count_div[i]);
+ /* zero for the next iteration (saves memset on entire array) */
+ memset(sd, 0, sizeof(*sd));
+ }
+ }
+
+ MEM_freeN(vertex_edge_count_div);
+ MEM_freeN(smooth_data);
}
-
/* -------------------------------------------------------------------- */
/* Edge-Length Weighted Smoothing
*/
-static void smooth_iter__length_weight(
- CorrectiveSmoothModifierData *csmd, Mesh *mesh,
- float (*vertexCos)[3], unsigned int numVerts,
- const float *smooth_weights,
- unsigned int iterations)
+static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ unsigned int numVerts,
+ const float *smooth_weights,
+ unsigned int iterations)
{
- const float eps = FLT_EPSILON * 10.0f;
- const unsigned int numEdges = (unsigned int)mesh->totedge;
- /* note: the way this smoothing method works, its approx half as strong as the simple-smooth,
- * and 2.0 rarely spikes, double the value for consistent behavior. */
- const float lambda = csmd->lambda * 2.0f;
- const MEdge *edges = mesh->medge;
- float *vertex_edge_count;
- unsigned int i;
-
- struct SmoothingData_Weighted {
- float delta[3];
- float edge_length_sum;
- } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__);
-
-
- /* calculate as floats to avoid int->float conversion in #smooth_iter */
- vertex_edge_count = MEM_calloc_arrayN(numVerts, sizeof(float), __func__);
- for (i = 0; i < numEdges; i++) {
- vertex_edge_count[edges[i].v1] += 1.0f;
- vertex_edge_count[edges[i].v2] += 1.0f;
- }
-
-
- /* -------------------------------------------------------------------- */
- /* Main Smoothing Loop */
-
- while (iterations--) {
- for (i = 0; i < numEdges; i++) {
- struct SmoothingData_Weighted *sd_v1;
- struct SmoothingData_Weighted *sd_v2;
- float edge_dir[3];
- float edge_dist;
-
- sub_v3_v3v3(edge_dir, vertexCos[edges[i].v2], vertexCos[edges[i].v1]);
- edge_dist = len_v3(edge_dir);
-
- /* weight by distance */
- mul_v3_fl(edge_dir, edge_dist);
-
-
- sd_v1 = &smooth_data[edges[i].v1];
- sd_v2 = &smooth_data[edges[i].v2];
-
- add_v3_v3(sd_v1->delta, edge_dir);
- sub_v3_v3(sd_v2->delta, edge_dir);
-
- sd_v1->edge_length_sum += edge_dist;
- sd_v2->edge_length_sum += edge_dist;
- }
-
- if (smooth_weights == NULL) {
- /* fast-path */
- for (i = 0; i < numVerts; i++) {
- struct SmoothingData_Weighted *sd = &smooth_data[i];
- /* divide by sum of all neighbour distances (weighted) and amount of neighbors, (mean average) */
- const float div = sd->edge_length_sum * vertex_edge_count[i];
- if (div > eps) {
+ const float eps = FLT_EPSILON * 10.0f;
+ const unsigned int numEdges = (unsigned int)mesh->totedge;
+ /* note: the way this smoothing method works, its approx half as strong as the simple-smooth,
+ * and 2.0 rarely spikes, double the value for consistent behavior. */
+ const float lambda = csmd->lambda * 2.0f;
+ const MEdge *edges = mesh->medge;
+ float *vertex_edge_count;
+ unsigned int i;
+
+ struct SmoothingData_Weighted {
+ float delta[3];
+ float edge_length_sum;
+ } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__);
+
+ /* calculate as floats to avoid int->float conversion in #smooth_iter */
+ vertex_edge_count = MEM_calloc_arrayN(numVerts, sizeof(float), __func__);
+ for (i = 0; i < numEdges; i++) {
+ vertex_edge_count[edges[i].v1] += 1.0f;
+ vertex_edge_count[edges[i].v2] += 1.0f;
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Main Smoothing Loop */
+
+ while (iterations--) {
+ for (i = 0; i < numEdges; i++) {
+ struct SmoothingData_Weighted *sd_v1;
+ struct SmoothingData_Weighted *sd_v2;
+ float edge_dir[3];
+ float edge_dist;
+
+ sub_v3_v3v3(edge_dir, vertexCos[edges[i].v2], vertexCos[edges[i].v1]);
+ edge_dist = len_v3(edge_dir);
+
+ /* weight by distance */
+ mul_v3_fl(edge_dir, edge_dist);
+
+ sd_v1 = &smooth_data[edges[i].v1];
+ sd_v2 = &smooth_data[edges[i].v2];
+
+ add_v3_v3(sd_v1->delta, edge_dir);
+ sub_v3_v3(sd_v2->delta, edge_dir);
+
+ sd_v1->edge_length_sum += edge_dist;
+ sd_v2->edge_length_sum += edge_dist;
+ }
+
+ if (smooth_weights == NULL) {
+ /* fast-path */
+ for (i = 0; i < numVerts; i++) {
+ struct SmoothingData_Weighted *sd = &smooth_data[i];
+ /* divide by sum of all neighbour distances (weighted) and amount of neighbors, (mean average) */
+ const float div = sd->edge_length_sum * vertex_edge_count[i];
+ if (div > eps) {
#if 0
- /* first calculate the new location */
- mul_v3_fl(sd->delta, 1.0f / div);
- /* then interpolate */
- madd_v3_v3fl(vertexCos[i], sd->delta, lambda);
+ /* first calculate the new location */
+ mul_v3_fl(sd->delta, 1.0f / div);
+ /* then interpolate */
+ madd_v3_v3fl(vertexCos[i], sd->delta, lambda);
#else
- /* do this in one step */
- madd_v3_v3fl(vertexCos[i], sd->delta, lambda / div);
+ /* do this in one step */
+ madd_v3_v3fl(vertexCos[i], sd->delta, lambda / div);
#endif
- }
- /* zero for the next iteration (saves memset on entire array) */
- memset(sd, 0, sizeof(*sd));
- }
- }
- else {
- for (i = 0; i < numVerts; i++) {
- struct SmoothingData_Weighted *sd = &smooth_data[i];
- const float div = sd->edge_length_sum * vertex_edge_count[i];
- if (div > eps) {
- const float lambda_w = lambda * smooth_weights[i];
- madd_v3_v3fl(vertexCos[i], sd->delta, lambda_w / div);
- }
-
- memset(sd, 0, sizeof(*sd));
- }
- }
- }
-
- MEM_freeN(vertex_edge_count);
- MEM_freeN(smooth_data);
+ }
+ /* zero for the next iteration (saves memset on entire array) */
+ memset(sd, 0, sizeof(*sd));
+ }
+ }
+ else {
+ for (i = 0; i < numVerts; i++) {
+ struct SmoothingData_Weighted *sd = &smooth_data[i];
+ const float div = sd->edge_length_sum * vertex_edge_count[i];
+ if (div > eps) {
+ const float lambda_w = lambda * smooth_weights[i];
+ madd_v3_v3fl(vertexCos[i], sd->delta, lambda_w / div);
+ }
+
+ memset(sd, 0, sizeof(*sd));
+ }
+ }
+ }
+
+ MEM_freeN(vertex_edge_count);
+ MEM_freeN(smooth_data);
}
-
-static void smooth_iter(
- CorrectiveSmoothModifierData *csmd, Mesh *mesh,
- float (*vertexCos)[3], unsigned int numVerts,
- const float *smooth_weights,
- unsigned int iterations)
+static void smooth_iter(CorrectiveSmoothModifierData *csmd,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ unsigned int numVerts,
+ const float *smooth_weights,
+ unsigned int iterations)
{
- switch (csmd->smooth_type) {
- case MOD_CORRECTIVESMOOTH_SMOOTH_LENGTH_WEIGHT:
- smooth_iter__length_weight(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations);
- break;
-
- /* case MOD_CORRECTIVESMOOTH_SMOOTH_SIMPLE: */
- default:
- smooth_iter__simple(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations);
- break;
- }
+ switch (csmd->smooth_type) {
+ case MOD_CORRECTIVESMOOTH_SMOOTH_LENGTH_WEIGHT:
+ smooth_iter__length_weight(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations);
+ break;
+
+ /* case MOD_CORRECTIVESMOOTH_SMOOTH_SIMPLE: */
+ default:
+ smooth_iter__simple(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations);
+ break;
+ }
}
-static void smooth_verts(
- CorrectiveSmoothModifierData *csmd, Mesh *mesh,
- MDeformVert *dvert, const int defgrp_index,
- float (*vertexCos)[3], unsigned int numVerts)
+static void smooth_verts(CorrectiveSmoothModifierData *csmd,
+ Mesh *mesh,
+ MDeformVert *dvert,
+ const int defgrp_index,
+ float (*vertexCos)[3],
+ unsigned int numVerts)
{
- float *smooth_weights = NULL;
+ float *smooth_weights = NULL;
- if (dvert || (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY)) {
+ if (dvert || (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY)) {
- smooth_weights = MEM_malloc_arrayN(numVerts, sizeof(float), __func__);
+ smooth_weights = MEM_malloc_arrayN(numVerts, sizeof(float), __func__);
- if (dvert) {
- mesh_get_weights(
- dvert, defgrp_index,
- numVerts, (csmd->flag & MOD_CORRECTIVESMOOTH_INVERT_VGROUP) != 0,
- smooth_weights);
- }
- else {
- copy_vn_fl(smooth_weights, (int)numVerts, 1.0f);
- }
+ if (dvert) {
+ mesh_get_weights(dvert,
+ defgrp_index,
+ numVerts,
+ (csmd->flag & MOD_CORRECTIVESMOOTH_INVERT_VGROUP) != 0,
+ smooth_weights);
+ }
+ else {
+ copy_vn_fl(smooth_weights, (int)numVerts, 1.0f);
+ }
- if (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY) {
- mesh_get_boundaries(mesh, smooth_weights);
- }
- }
+ if (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY) {
+ mesh_get_boundaries(mesh, smooth_weights);
+ }
+ }
- smooth_iter(csmd, mesh, vertexCos, numVerts, smooth_weights, (unsigned int)csmd->repeat);
+ smooth_iter(csmd, mesh, vertexCos, numVerts, smooth_weights, (unsigned int)csmd->repeat);
- if (smooth_weights) {
- MEM_freeN(smooth_weights);
- }
+ if (smooth_weights) {
+ MEM_freeN(smooth_weights);
+ }
}
/**
@@ -406,109 +402,102 @@ static void smooth_verts(
*/
static void calc_tangent_ortho(float ts[3][3])
{
- float v_tan_a[3], v_tan_b[3];
- float t_vec_a[3], t_vec_b[3];
+ float v_tan_a[3], v_tan_b[3];
+ float t_vec_a[3], t_vec_b[3];
- normalize_v3(ts[2]);
+ normalize_v3(ts[2]);
- copy_v3_v3(v_tan_a, ts[0]);
- copy_v3_v3(v_tan_b, ts[1]);
+ copy_v3_v3(v_tan_a, ts[0]);
+ copy_v3_v3(v_tan_b, ts[1]);
- cross_v3_v3v3(ts[1], ts[2], v_tan_a);
- mul_v3_fl(ts[1], dot_v3v3(ts[1], v_tan_b) < 0.0f ? -1.0f : 1.0f);
+ cross_v3_v3v3(ts[1], ts[2], v_tan_a);
+ mul_v3_fl(ts[1], dot_v3v3(ts[1], v_tan_b) < 0.0f ? -1.0f : 1.0f);
- /* orthognalise tangent */
- mul_v3_v3fl(t_vec_a, ts[2], dot_v3v3(ts[2], v_tan_a));
- sub_v3_v3v3(ts[0], v_tan_a, t_vec_a);
+ /* orthognalise tangent */
+ mul_v3_v3fl(t_vec_a, ts[2], dot_v3v3(ts[2], v_tan_a));
+ sub_v3_v3v3(ts[0], v_tan_a, t_vec_a);
- /* orthognalise bitangent */
- mul_v3_v3fl(t_vec_a, ts[2], dot_v3v3(ts[2], ts[1]));
- mul_v3_v3fl(t_vec_b, ts[0], dot_v3v3(ts[0], ts[1]) / dot_v3v3(v_tan_a, v_tan_a));
- sub_v3_v3(ts[1], t_vec_a);
- sub_v3_v3(ts[1], t_vec_b);
+ /* orthognalise bitangent */
+ mul_v3_v3fl(t_vec_a, ts[2], dot_v3v3(ts[2], ts[1]));
+ mul_v3_v3fl(t_vec_b, ts[0], dot_v3v3(ts[0], ts[1]) / dot_v3v3(v_tan_a, v_tan_a));
+ sub_v3_v3(ts[1], t_vec_a);
+ sub_v3_v3(ts[1], t_vec_b);
- normalize_v3(ts[0]);
- normalize_v3(ts[1]);
+ normalize_v3(ts[0]);
+ normalize_v3(ts[1]);
}
/**
* accumulate edge-vectors from all polys.
*/
-static void calc_tangent_loop_accum(
- const float v_dir_prev[3],
- const float v_dir_next[3],
- float r_tspace[3][3])
+static void calc_tangent_loop_accum(const float v_dir_prev[3],
+ const float v_dir_next[3],
+ float r_tspace[3][3])
{
- add_v3_v3v3(r_tspace[1], v_dir_prev, v_dir_next);
+ add_v3_v3v3(r_tspace[1], v_dir_prev, v_dir_next);
- if (compare_v3v3(v_dir_prev, v_dir_next, FLT_EPSILON * 10.0f) == false) {
- const float weight = fabsf(acosf(dot_v3v3(v_dir_next, v_dir_prev)));
- float nor[3];
+ if (compare_v3v3(v_dir_prev, v_dir_next, FLT_EPSILON * 10.0f) == false) {
+ const float weight = fabsf(acosf(dot_v3v3(v_dir_next, v_dir_prev)));
+ float nor[3];
- cross_v3_v3v3(nor, v_dir_prev, v_dir_next);
- normalize_v3(nor);
+ cross_v3_v3v3(nor, v_dir_prev, v_dir_next);
+ normalize_v3(nor);
- cross_v3_v3v3(r_tspace[0], r_tspace[1], nor);
+ cross_v3_v3v3(r_tspace[0], r_tspace[1], nor);
- mul_v3_fl(nor, weight);
- /* accumulate weighted normals */
- add_v3_v3(r_tspace[2], nor);
- }
+ mul_v3_fl(nor, weight);
+ /* accumulate weighted normals */
+ add_v3_v3(r_tspace[2], nor);
+ }
}
-
-static void calc_tangent_spaces(
- Mesh *mesh, float (*vertexCos)[3],
- float (*r_tangent_spaces)[3][3])
+static void calc_tangent_spaces(Mesh *mesh, float (*vertexCos)[3], float (*r_tangent_spaces)[3][3])
{
- const unsigned int mpoly_num = (unsigned int)mesh->totpoly;
+ const unsigned int mpoly_num = (unsigned int)mesh->totpoly;
#ifndef USE_TANGENT_CALC_INLINE
- const unsigned int mvert_num = (unsigned int)dm->getNumVerts(dm);
+ const unsigned int mvert_num = (unsigned int)dm->getNumVerts(dm);
#endif
- const MPoly *mpoly = mesh->mpoly;
- const MLoop *mloop = mesh->mloop;
- unsigned int i;
-
- for (i = 0; i < mpoly_num; i++) {
- const MPoly *mp = &mpoly[i];
- const MLoop *l_next = &mloop[mp->loopstart];
- const MLoop *l_term = l_next + mp->totloop;
- const MLoop *l_prev = l_term - 2;
- const MLoop *l_curr = l_term - 1;
-
- /* loop directions */
- float v_dir_prev[3], v_dir_next[3];
-
- /* needed entering the loop */
- sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]);
- normalize_v3(v_dir_prev);
-
- for (;
- l_next != l_term;
- l_prev = l_curr, l_curr = l_next, l_next++)
- {
- float (*ts)[3] = r_tangent_spaces[l_curr->v];
-
- /* re-use the previous value */
+ const MPoly *mpoly = mesh->mpoly;
+ const MLoop *mloop = mesh->mloop;
+ unsigned int i;
+
+ for (i = 0; i < mpoly_num; i++) {
+ const MPoly *mp = &mpoly[i];
+ const MLoop *l_next = &mloop[mp->loopstart];
+ const MLoop *l_term = l_next + mp->totloop;
+ const MLoop *l_prev = l_term - 2;
+ const MLoop *l_curr = l_term - 1;
+
+ /* loop directions */
+ float v_dir_prev[3], v_dir_next[3];
+
+ /* needed entering the loop */
+ sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]);
+ normalize_v3(v_dir_prev);
+
+ for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) {
+ float(*ts)[3] = r_tangent_spaces[l_curr->v];
+
+ /* re-use the previous value */
#if 0
- sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]);
- normalize_v3(v_dir_prev);
+ sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]);
+ normalize_v3(v_dir_prev);
#endif
- sub_v3_v3v3(v_dir_next, vertexCos[l_curr->v], vertexCos[l_next->v]);
- normalize_v3(v_dir_next);
+ sub_v3_v3v3(v_dir_next, vertexCos[l_curr->v], vertexCos[l_next->v]);
+ normalize_v3(v_dir_next);
- calc_tangent_loop_accum(v_dir_prev, v_dir_next, ts);
+ calc_tangent_loop_accum(v_dir_prev, v_dir_next, ts);
- copy_v3_v3(v_dir_prev, v_dir_next);
- }
- }
+ copy_v3_v3(v_dir_prev, v_dir_next);
+ }
+ }
- /* do inline */
+ /* do inline */
#ifndef USE_TANGENT_CALC_INLINE
- for (i = 0; i < mvert_num; i++) {
- float (*ts)[3] = r_tangent_spaces[i];
- calc_tangent_ortho(ts);
- }
+ for (i = 0; i < mvert_num; i++) {
+ float(*ts)[3] = r_tangent_spaces[i];
+ calc_tangent_ortho(ts);
+ }
#endif
}
@@ -516,261 +505,266 @@ static void calc_tangent_spaces(
* This calculates #CorrectiveSmoothModifierData.delta_cache
* It's not run on every update (during animation for example).
*/
-static void calc_deltas(
- CorrectiveSmoothModifierData *csmd, Mesh *mesh,
- MDeformVert *dvert, const int defgrp_index,
- const float (*rest_coords)[3], unsigned int numVerts)
+static void calc_deltas(CorrectiveSmoothModifierData *csmd,
+ Mesh *mesh,
+ MDeformVert *dvert,
+ const int defgrp_index,
+ const float (*rest_coords)[3],
+ unsigned int numVerts)
{
- float (*smooth_vertex_coords)[3] = MEM_dupallocN(rest_coords);
- float (*tangent_spaces)[3][3];
- unsigned int i;
+ float(*smooth_vertex_coords)[3] = MEM_dupallocN(rest_coords);
+ float(*tangent_spaces)[3][3];
+ unsigned int i;
- tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__);
+ tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__);
- if (csmd->delta_cache_num != numVerts) {
- MEM_SAFE_FREE(csmd->delta_cache);
- }
+ if (csmd->delta_cache_num != numVerts) {
+ MEM_SAFE_FREE(csmd->delta_cache);
+ }
- /* allocate deltas if they have not yet been allocated, otheriwse we will just write over them */
- if (!csmd->delta_cache) {
- csmd->delta_cache_num = numVerts;
- csmd->delta_cache = MEM_malloc_arrayN(numVerts, sizeof(float[3]), __func__);
- }
+ /* allocate deltas if they have not yet been allocated, otheriwse we will just write over them */
+ if (!csmd->delta_cache) {
+ csmd->delta_cache_num = numVerts;
+ csmd->delta_cache = MEM_malloc_arrayN(numVerts, sizeof(float[3]), __func__);
+ }
- smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords, numVerts);
+ smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords, numVerts);
- calc_tangent_spaces(mesh, smooth_vertex_coords, tangent_spaces);
+ calc_tangent_spaces(mesh, smooth_vertex_coords, tangent_spaces);
- for (i = 0; i < numVerts; i++) {
- float imat[3][3], delta[3];
+ for (i = 0; i < numVerts; i++) {
+ float imat[3][3], delta[3];
#ifdef USE_TANGENT_CALC_INLINE
- calc_tangent_ortho(tangent_spaces[i]);
+ calc_tangent_ortho(tangent_spaces[i]);
#endif
- sub_v3_v3v3(delta, rest_coords[i], smooth_vertex_coords[i]);
- if (UNLIKELY(!invert_m3_m3(imat, tangent_spaces[i]))) {
- transpose_m3_m3(imat, tangent_spaces[i]);
- }
- mul_v3_m3v3(csmd->delta_cache[i], imat, delta);
- }
+ sub_v3_v3v3(delta, rest_coords[i], smooth_vertex_coords[i]);
+ if (UNLIKELY(!invert_m3_m3(imat, tangent_spaces[i]))) {
+ transpose_m3_m3(imat, tangent_spaces[i]);
+ }
+ mul_v3_m3v3(csmd->delta_cache[i], imat, delta);
+ }
- MEM_freeN(tangent_spaces);
- MEM_freeN(smooth_vertex_coords);
+ MEM_freeN(tangent_spaces);
+ MEM_freeN(smooth_vertex_coords);
}
-
-static void correctivesmooth_modifier_do(
- ModifierData *md, Depsgraph *depsgraph, Object *ob, Mesh *mesh,
- float (*vertexCos)[3], unsigned int numVerts,
- struct BMEditMesh *em)
+static void correctivesmooth_modifier_do(ModifierData *md,
+ Depsgraph *depsgraph,
+ Object *ob,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ unsigned int numVerts,
+ struct BMEditMesh *em)
{
- CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
-
- const bool force_delta_cache_update =
- /* XXX, take care! if mesh data its self changes we need to forcefully recalculate deltas */
- ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO) &&
- (((ID *)ob->data)->recalc & ID_RECALC_ALL));
-
- bool use_only_smooth = (csmd->flag & MOD_CORRECTIVESMOOTH_ONLY_SMOOTH) != 0;
- MDeformVert *dvert = NULL;
- int defgrp_index;
-
- MOD_get_vgroup(ob, mesh, csmd->defgrp_name, &dvert, &defgrp_index);
-
- /* if rest bind_coords not are defined, set them (only run during bind) */
- if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) &&
- /* signal to recalculate, whoever sets MUST also free bind coords */
- (csmd->bind_coords_num == (unsigned int)-1))
- {
- if (DEG_is_active(depsgraph)) {
- BLI_assert(csmd->bind_coords == NULL);
- csmd->bind_coords = MEM_dupallocN(vertexCos);
- csmd->bind_coords_num = numVerts;
- BLI_assert(csmd->bind_coords != NULL);
- /* Copy bound data to the original modifier. */
- CorrectiveSmoothModifierData *csmd_orig =
- (CorrectiveSmoothModifierData *)modifier_get_original(&csmd->modifier);
- csmd_orig->bind_coords = MEM_dupallocN(csmd->bind_coords);
- csmd_orig->bind_coords_num = csmd->bind_coords_num;
- }
- else {
- modifier_setError(md, "Attempt to bind from inactive dependency graph");
- }
- }
-
- if (UNLIKELY(use_only_smooth)) {
- smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts);
- return;
- }
-
- if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) && (csmd->bind_coords == NULL)) {
- modifier_setError(md, "Bind data required");
- goto error;
- }
-
- /* If the number of verts has changed, the bind is invalid, so we do nothing */
- if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
- if (csmd->bind_coords_num != numVerts) {
- modifier_setError(md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts);
- goto error;
- }
- }
- else {
- /* MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO */
- if (ob->type != OB_MESH) {
- modifier_setError(md, "Object is not a mesh");
- goto error;
- }
- else {
- unsigned int me_numVerts = (unsigned int)((em) ? em->bm->totvert : ((Mesh *)ob->data)->totvert);
-
- if (me_numVerts != numVerts) {
- modifier_setError(md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts);
- goto error;
- }
- }
- }
-
- /* check to see if our deltas are still valid */
- if (!csmd->delta_cache || (csmd->delta_cache_num != numVerts) || force_delta_cache_update) {
- const float (*rest_coords)[3];
- bool is_rest_coords_alloc = false;
-
- if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
- /* caller needs to do sanity check here */
- csmd->bind_coords_num = numVerts;
- rest_coords = (const float (*)[3])csmd->bind_coords;
- }
- else {
- int me_numVerts;
- rest_coords = (const float (*)[3]) ((em) ?
- BKE_editmesh_vertexCos_get_orco(em, &me_numVerts) :
- BKE_mesh_vertexCos_get(ob->data, &me_numVerts));
-
- BLI_assert((unsigned int)me_numVerts == numVerts);
- is_rest_coords_alloc = true;
- }
+ CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
+
+ const bool force_delta_cache_update =
+ /* XXX, take care! if mesh data its self changes we need to forcefully recalculate deltas */
+ ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO) &&
+ (((ID *)ob->data)->recalc & ID_RECALC_ALL));
+
+ bool use_only_smooth = (csmd->flag & MOD_CORRECTIVESMOOTH_ONLY_SMOOTH) != 0;
+ MDeformVert *dvert = NULL;
+ int defgrp_index;
+
+ MOD_get_vgroup(ob, mesh, csmd->defgrp_name, &dvert, &defgrp_index);
+
+ /* if rest bind_coords not are defined, set them (only run during bind) */
+ if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) &&
+ /* signal to recalculate, whoever sets MUST also free bind coords */
+ (csmd->bind_coords_num == (unsigned int)-1)) {
+ if (DEG_is_active(depsgraph)) {
+ BLI_assert(csmd->bind_coords == NULL);
+ csmd->bind_coords = MEM_dupallocN(vertexCos);
+ csmd->bind_coords_num = numVerts;
+ BLI_assert(csmd->bind_coords != NULL);
+ /* Copy bound data to the original modifier. */
+ CorrectiveSmoothModifierData *csmd_orig = (CorrectiveSmoothModifierData *)
+ modifier_get_original(&csmd->modifier);
+ csmd_orig->bind_coords = MEM_dupallocN(csmd->bind_coords);
+ csmd_orig->bind_coords_num = csmd->bind_coords_num;
+ }
+ else {
+ modifier_setError(md, "Attempt to bind from inactive dependency graph");
+ }
+ }
+
+ if (UNLIKELY(use_only_smooth)) {
+ smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts);
+ return;
+ }
+
+ if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) && (csmd->bind_coords == NULL)) {
+ modifier_setError(md, "Bind data required");
+ goto error;
+ }
+
+ /* If the number of verts has changed, the bind is invalid, so we do nothing */
+ if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
+ if (csmd->bind_coords_num != numVerts) {
+ modifier_setError(
+ md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts);
+ goto error;
+ }
+ }
+ else {
+ /* MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO */
+ if (ob->type != OB_MESH) {
+ modifier_setError(md, "Object is not a mesh");
+ goto error;
+ }
+ else {
+ unsigned int me_numVerts = (unsigned int)((em) ? em->bm->totvert :
+ ((Mesh *)ob->data)->totvert);
+
+ if (me_numVerts != numVerts) {
+ modifier_setError(md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts);
+ goto error;
+ }
+ }
+ }
+
+ /* check to see if our deltas are still valid */
+ if (!csmd->delta_cache || (csmd->delta_cache_num != numVerts) || force_delta_cache_update) {
+ const float(*rest_coords)[3];
+ bool is_rest_coords_alloc = false;
+
+ if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
+ /* caller needs to do sanity check here */
+ csmd->bind_coords_num = numVerts;
+ rest_coords = (const float(*)[3])csmd->bind_coords;
+ }
+ else {
+ int me_numVerts;
+ rest_coords = (const float(*)[3])((em) ? BKE_editmesh_vertexCos_get_orco(em, &me_numVerts) :
+ BKE_mesh_vertexCos_get(ob->data, &me_numVerts));
+
+ BLI_assert((unsigned int)me_numVerts == numVerts);
+ is_rest_coords_alloc = true;
+ }
#ifdef DEBUG_TIME
- TIMEIT_START(corrective_smooth_deltas);
+ TIMEIT_START(corrective_smooth_deltas);
#endif
- calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords, numVerts);
+ calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords, numVerts);
#ifdef DEBUG_TIME
- TIMEIT_END(corrective_smooth_deltas);
+ TIMEIT_END(corrective_smooth_deltas);
#endif
- if (is_rest_coords_alloc) {
- MEM_freeN((void *)rest_coords);
- }
- }
-
- if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
- /* this could be a check, but at this point it _must_ be valid */
- BLI_assert(csmd->bind_coords_num == numVerts && csmd->delta_cache);
- }
+ if (is_rest_coords_alloc) {
+ MEM_freeN((void *)rest_coords);
+ }
+ }
+ if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
+ /* this could be a check, but at this point it _must_ be valid */
+ BLI_assert(csmd->bind_coords_num == numVerts && csmd->delta_cache);
+ }
#ifdef DEBUG_TIME
- TIMEIT_START(corrective_smooth);
+ TIMEIT_START(corrective_smooth);
#endif
- /* do the actual delta mush */
- smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts);
+ /* do the actual delta mush */
+ smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts);
- {
- unsigned int i;
+ {
+ unsigned int i;
- float (*tangent_spaces)[3][3];
+ float(*tangent_spaces)[3][3];
- /* calloc, since values are accumulated */
- tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__);
+ /* calloc, since values are accumulated */
+ tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__);
- calc_tangent_spaces(mesh, vertexCos, tangent_spaces);
+ calc_tangent_spaces(mesh, vertexCos, tangent_spaces);
- for (i = 0; i < numVerts; i++) {
- float delta[3];
+ for (i = 0; i < numVerts; i++) {
+ float delta[3];
#ifdef USE_TANGENT_CALC_INLINE
- calc_tangent_ortho(tangent_spaces[i]);
+ calc_tangent_ortho(tangent_spaces[i]);
#endif
- mul_v3_m3v3(delta, tangent_spaces[i], csmd->delta_cache[i]);
- add_v3_v3(vertexCos[i], delta);
- }
+ mul_v3_m3v3(delta, tangent_spaces[i], csmd->delta_cache[i]);
+ add_v3_v3(vertexCos[i], delta);
+ }
- MEM_freeN(tangent_spaces);
- }
+ MEM_freeN(tangent_spaces);
+ }
#ifdef DEBUG_TIME
- TIMEIT_END(corrective_smooth);
+ TIMEIT_END(corrective_smooth);
#endif
- return;
+ return;
- /* when the modifier fails to execute */
+ /* when the modifier fails to execute */
error:
- MEM_SAFE_FREE(
- csmd->delta_cache);
- csmd->delta_cache_num = 0;
-
+ MEM_SAFE_FREE(csmd->delta_cache);
+ csmd->delta_cache_num = 0;
}
-
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- correctivesmooth_modifier_do(md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, NULL);
+ correctivesmooth_modifier_do(
+ md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, NULL);
- if (mesh_src != mesh) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (mesh_src != mesh) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *editData,
- Mesh *mesh, float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *editData,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, NULL, numVerts, false, false);
- correctivesmooth_modifier_do(md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, editData);
+ correctivesmooth_modifier_do(
+ md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, editData);
- if (mesh_src != mesh) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (mesh_src != mesh) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-
ModifierTypeInfo modifierType_CorrectiveSmooth = {
- /* name */ "CorrectiveSmooth",
- /* structName */ "CorrectiveSmoothModifierData",
- /* structSize */ sizeof(CorrectiveSmoothModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ copyData,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ freeData,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "CorrectiveSmooth",
+ /* structName */ "CorrectiveSmoothModifierData",
+ /* structSize */ sizeof(CorrectiveSmoothModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};