Mesh: Add operator to clear sculpt face sets

Added a new mesh operator `MESH_OT_customdata_face_sets_clear` to remove
sculpt face set data from a mesh.

This provides a direct way to clear the `.sculpt_face_set` attribute
from the Object Data → Geometry Data panel, similar to existing
operators for clearing sculpt mask and skin data.

Resolves #154220

Pull Request: https://projects.blender.org/blender/blender/pulls/154912
This commit is contained in:
Aryan Verma 2026-03-16 16:26:10 +01:00 • committed by Sean Kim
parent 06c7fd45d3
commit c0eaafa965
4 changed files with 57 additions and 0 deletions

View file

@ -450,6 +450,7 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
col = layout.column()
col.operator("mesh.customdata_mask_clear", icon='X')
col.operator("mesh.customdata_face_sets_clear", icon='X')
col.operator("mesh.customdata_skin_clear", icon='X')
col.operator("mesh.reorder_vertices_spatial")
if me.has_custom_normals:

View file

@ -500,6 +500,60 @@ static wmOperatorStatus mesh_customdata_mask_clear_exec(bContext *C, wmOperator
return OPERATOR_FINISHED;
}
static bool mesh_customdata_face_sets_clear_poll(bContext *C)
{
Object *object = ed::object::context_object(C);
if (!object || object->type != OB_MESH) {
return false;
}
Mesh *mesh = id_cast<Mesh *>(object->data);
if (!ID_IS_EDITABLE(mesh) || ID_IS_OVERRIDE_LIBRARY(mesh)) {
return false;
}
if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
return CustomData_has_layer_named(&em->bm->pdata, CD_PROP_INT32, ".sculpt_face_set");
}
return mesh->attributes().contains(".sculpt_face_set");
}
static wmOperatorStatus mesh_customdata_face_sets_clear_exec(bContext *C, wmOperator * /*op*/)
{
Object *object = ed::object::context_object(C);
Mesh *mesh = id_cast<Mesh *>(object->data);
bool changed = false;
if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
changed = CustomData_free_layer_named(&em->bm->pdata, ".sculpt_face_set");
}
else {
changed = mesh->attributes_for_write().remove(".sculpt_face_set");
}
if (!changed) {
return OPERATOR_CANCELLED;
}
DEG_id_tag_update(&mesh->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, mesh);
return OPERATOR_FINISHED;
}
void MESH_OT_customdata_face_sets_clear(wmOperatorType *ot)
{
ot->name = "Clear Sculpt Face Sets";
ot->idname = "MESH_OT_customdata_face_sets_clear";
ot->description = "Clear sculpt face set data from the mesh";
ot->exec = mesh_customdata_face_sets_clear_exec;
ot->poll = mesh_customdata_face_sets_clear_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void MESH_OT_customdata_mask_clear(wmOperatorType *ot)
{
ot->name = "Clear Sculpt Mask Data";

View file

@ -310,6 +310,7 @@ void MESH_OT_mark_freestyle_face(wmOperatorType *ot);
void MESH_OT_uv_texture_add(wmOperatorType *ot);
void MESH_OT_uv_texture_remove(wmOperatorType *ot);
void MESH_OT_customdata_mask_clear(wmOperatorType *ot);
void MESH_OT_customdata_face_sets_clear(wmOperatorType *ot);
void MESH_OT_customdata_skin_add(wmOperatorType *ot);
void MESH_OT_customdata_skin_clear(wmOperatorType *ot);
void MESH_OT_customdata_custom_splitnormals_add(wmOperatorType *ot);

View file

@ -143,6 +143,7 @@ void ED_operatortypes_mesh()
WM_operatortype_append(MESH_OT_uv_texture_add);
WM_operatortype_append(MESH_OT_uv_texture_remove);
WM_operatortype_append(MESH_OT_customdata_mask_clear);
WM_operatortype_append(MESH_OT_customdata_face_sets_clear);
WM_operatortype_append(MESH_OT_customdata_skin_add);
WM_operatortype_append(MESH_OT_customdata_skin_clear);
WM_operatortype_append(MESH_OT_customdata_custom_splitnormals_add);