Add 'projection' option for volume-preserving smoothing to

smooth corrective modifier
This commit is contained in:
Joseph Eagar 2021-07-23 15:46:01 -07:00
parent 70a4956020
commit ec4b9dff19
3 changed files with 60 additions and 11 deletions

View File

@ -1843,10 +1843,10 @@ typedef struct CorrectiveSmoothModifierData {
/* NOTE: -1 is used to bind. */
unsigned int bind_coords_num;
float lambda, scale;
float lambda, scale, projection;
short repeat, flag;
char smooth_type, rest_source;
char _pad[6];
char _pad[2];
/** MAX_VGROUP_NAME. */
char defgrp_name[64];
@ -1900,10 +1900,7 @@ typedef struct UVWarpModifierData {
} UVWarpModifierData;
/* UVWarp modifier flags */
enum {
MOD_UVWARP_INVERT_VGROUP = 1 << 0,
MOD_UVWARP_RESTRICT_ISLANDS = 1<<1
};
enum { MOD_UVWARP_INVERT_VGROUP = 1 << 0, MOD_UVWARP_RESTRICT_ISLANDS = 1 << 1 };
/* cache modifier */
typedef struct MeshCacheModifierData {

View File

@ -3296,6 +3296,13 @@ static void rna_def_modifier_correctivesmooth(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Lambda Factor", "Smooth factor effect");
RNA_def_property_update(prop, 0, "rna_CorrectiveSmoothModifier_update");
prop = RNA_def_property(srna, "projection", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "projection");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0, 1.0, 5, 3);
RNA_def_property_ui_text(prop, "Projection", "Volume preserving projection");
RNA_def_property_update(prop, 0, "rna_CorrectiveSmoothModifier_update");
prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "repeat");
RNA_def_property_ui_range(prop, 0, 200, 1, -1);

View File

@ -193,7 +193,10 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd,
uint i;
const uint numEdges = (uint)mesh->totedge;
const float projection = csmd->projection;
const MEdge *edges = mesh->medge;
const MVert *verts = mesh->mvert;
float *vertex_edge_count_div;
struct SmoothingData_Simple {
@ -239,8 +242,24 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd,
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);
if (projection > 0.0f) {
float edge_dir2[3];
float no[3];
normal_short_to_float_v3(no, verts[edges[i].v1].no);
madd_v3_v3v3fl(edge_dir2, edge_dir, no, -dot_v3v3(edge_dir, no) * projection);
add_v3_v3(sd_v1->delta, edge_dir2);
negate_v3(edge_dir);
normal_short_to_float_v3(no, verts[edges[i].v2].no);
madd_v3_v3v3fl(edge_dir2, edge_dir, no, -dot_v3v3(edge_dir, no) * projection);
add_v3_v3(sd_v2->delta, edge_dir2);
}
else {
add_v3_v3(sd_v1->delta, edge_dir);
sub_v3_v3(sd_v2->delta, edge_dir);
}
}
for (i = 0; i < numVerts; i++) {
@ -270,7 +289,9 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd,
/* 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 float projection = csmd->projection;
const MEdge *edges = mesh->medge;
const MVert *verts = mesh->mvert;
float *vertex_edge_count;
uint i;
@ -305,8 +326,24 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd,
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);
if (projection > 0.0f) {
float edge_dir2[3];
float no[3];
normal_short_to_float_v3(no, verts[edges[i].v1].no);
madd_v3_v3v3fl(edge_dir2, edge_dir, no, -dot_v3v3(edge_dir, no) * projection);
add_v3_v3(sd_v1->delta, edge_dir2);
negate_v3(edge_dir);
normal_short_to_float_v3(no, verts[edges[i].v2].no);
madd_v3_v3v3fl(edge_dir2, edge_dir, no, -dot_v3v3(edge_dir, no) * projection);
add_v3_v3(sd_v2->delta, edge_dir2);
}
else {
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;
@ -787,6 +824,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
uiItemR(layout, ptr, "factor", 0, IFACE_("Factor"), ICON_NONE);
uiItemR(layout, ptr, "projection", 0, IFACE_("Projection"), ICON_NONE);
uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "scale", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "smooth_type", 0, NULL, ICON_NONE);
@ -821,6 +859,13 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md)
}
}
bool dependsOnNormals(ModifierData *md)
{
CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
return csmd->projection > 0.0f;
}
static void blendRead(BlendDataReader *reader, ModifierData *md)
{
CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
@ -859,7 +904,7 @@ ModifierTypeInfo modifierType_CorrectiveSmooth = {
/* isDisabled */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
/* dependsOnNormals */ dependsOnNormals,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,