Sculpt: add option for use the center of mass to the sphere mesh filter

This commit is contained in:
Pablo Dobarro 2021-01-05 21:59:15 +01:00
parent 6d6ab057e4
commit f91a2a0831
3 changed files with 59 additions and 6 deletions

View File

@ -1393,6 +1393,8 @@ class _defs_sculpt:
layout.prop(props, "sharpen_smooth_ratio", expand=False)
layout.prop(props, "sharpen_intensify_detail_strength", expand=False)
layout.prop(props, "sharpen_curvature_smooth_iterations", expand=False)
elif props.type == 'SPHERE':
layout.prop(props, "sphere_center", expand=False)
return dict(
idname="builtin.mesh_filter",

View File

@ -271,6 +271,25 @@ static EnumPropertyItem prop_mesh_filter_orientation_items[] = {
{0, NULL, 0, NULL, NULL},
};
typedef enum eMeshFilterSphereCenterType {
MESH_FILTER_SPHERE_CENTER_AVERAGE = 1 << 0,
MESH_FILTER_SPHERE_CENTER_OBJECT = 1 << 1,
} eMeshFilterSphereCenterType;
static EnumPropertyItem prop_mesh_filter_sphere_center_items[] = {
{MESH_FILTER_SPHERE_CENTER_AVERAGE,
"AVERAGE",
0,
"Center of Mass",
"Use the average position of all vertices as the sphere center"},
{MESH_FILTER_SPHERE_CENTER_OBJECT,
"OBJECT",
0,
"Object Origin",
"Use the object origin as the sphere center"},
{0, NULL, 0, NULL, NULL},
};
static bool sculpt_mesh_filter_needs_pmap(eSculptMeshFilterType filter_type)
{
return ELEM(filter_type,
@ -352,8 +371,10 @@ static void mesh_filter_task_cb(void *__restrict userdata,
mul_m3_v3(transform, val);
sub_v3_v3v3(disp, val, orig_co);
break;
case MESH_FILTER_SPHERE:
normalize_v3_v3(disp, orig_co);
case MESH_FILTER_SPHERE: {
float sphere_space_co[3];
sub_v3_v3v3(sphere_space_co, orig_co, filter_cache->sphere_center);
normalize_v3_v3(disp, sphere_space_co);
if (fade > 0.0f) {
mul_v3_v3fl(disp, disp, filter_cache->sphere_radius * fade);
}
@ -368,11 +389,11 @@ static void mesh_filter_task_cb(void *__restrict userdata,
else {
scale_m3_fl(transform, 1.0f + fade);
}
copy_v3_v3(val, orig_co);
copy_v3_v3(val, sphere_space_co);
mul_m3_v3(transform, val);
sub_v3_v3v3(disp2, val, orig_co);
sub_v3_v3v3(disp2, val, sphere_space_co);
mid_v3_v3v3(disp, disp, disp2);
break;
} break;
case MESH_FILTER_RANDOM: {
normal_short_to_float_v3(normal, orig_data.no);
/* Index is not unique for multires, so hash by vertex coordinates. */
@ -493,13 +514,32 @@ static void mesh_filter_enhance_details_init_directions(SculptSession *ss)
}
}
static void mesh_filter_sphere_center_calculate(
SculptSession *ss, const eMeshFilterSphereCenterType sphere_center_mode)
{
FilterCache *filter_cache = ss->filter_cache;
switch (sphere_center_mode) {
case MESH_FILTER_SPHERE_CENTER_AVERAGE: {
const int totvert = SCULPT_vertex_count_get(ss);
float center_accum[3] = {0.0f};
for (int i = 0; i < totvert; i++) {
add_v3_v3(center_accum, SCULPT_vertex_co_get(ss, i));
}
mul_v3_v3fl(filter_cache->sphere_center, center_accum, 1.0f / totvert);
} break;
case MESH_FILTER_SPHERE_CENTER_OBJECT:
zero_v3(filter_cache->sphere_center);
break;
}
}
static void mesh_filter_sphere_radius_calculate(SculptSession *ss)
{
const int totvert = SCULPT_vertex_count_get(ss);
FilterCache *filter_cache = ss->filter_cache;
float accum = 0.0f;
for (int i = 0; i < totvert; i++) {
accum += len_v3(SCULPT_vertex_co_get(ss, i));
accum += len_v3v3(filter_cache->sphere_center, SCULPT_vertex_co_get(ss, i));
}
filter_cache->sphere_radius = accum / totvert;
}
@ -745,6 +785,9 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
break;
}
case MESH_FILTER_SPHERE: {
const eMeshFilterSphereCenterType sphere_center_mode = RNA_enum_get(op->ptr,
"sphere_center");
mesh_filter_sphere_center_calculate(ss, sphere_center_mode);
mesh_filter_sphere_radius_calculate(ss);
break;
}
@ -851,4 +894,11 @@ void SCULPT_OT_mesh_filter(struct wmOperatorType *ot)
"How much smooth the resulting shape is, ignoring high frequency details",
0,
10);
RNA_def_enum(ot->srna,
"sphere_center",
prop_mesh_filter_sphere_center_items,
MESH_FILTER_SPHERE_CENTER_AVERAGE,
"Sphere Center",
"Position of the center of the sphere created by the filter");
}

View File

@ -1159,6 +1159,7 @@ typedef struct FilterCache {
float (*detail_directions)[3];
/* Sphere mesh filter. */
float sphere_center[3];
float sphere_radius;
/* Filter orientaiton. */