Object: support removing unused weights for selected objects
This is useful to run in object-mode, instead of from the property editor, note that this still only used the current object when activated from the property editor.
This commit is contained in:
parent
1a650fdcb2
commit
530ccde909
Notes:
blender-bot
2023-02-14 01:57:12 +01:00
Referenced by issue #74157, Use menus for operator search & various improvements
|
@ -72,15 +72,80 @@
|
|||
|
||||
#include "ED_mesh.h"
|
||||
#include "ED_object.h"
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "object_intern.h"
|
||||
|
||||
static bool vertex_group_supported_poll_ex(bContext *C, const Object *ob);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public Utility Functions
|
||||
/** \name Local Utility Functions
|
||||
* \{ */
|
||||
|
||||
static Object **object_array_for_wpaint_impl(bContext *C,
|
||||
bool (*filter_fn)(struct Object *ob, void *user_data),
|
||||
void *filter_user_data,
|
||||
uint *r_objects_len)
|
||||
{
|
||||
Object **objects;
|
||||
|
||||
Object *ob = NULL;
|
||||
bool use_ob = true;
|
||||
if (CTX_wm_space_properties(C)) {
|
||||
/* May return pinned object. */
|
||||
ob = ED_object_context(C);
|
||||
}
|
||||
else if (CTX_data_mode_enum(C) == CTX_MODE_PAINT_WEIGHT) {
|
||||
/* When painting, limit to active. */
|
||||
ob = CTX_data_active_object(C);
|
||||
}
|
||||
else {
|
||||
/* Otherwise use full selection. */
|
||||
use_ob = false;
|
||||
}
|
||||
|
||||
if (use_ob) {
|
||||
if (!filter_fn(ob, filter_user_data)) {
|
||||
ob = NULL;
|
||||
}
|
||||
*r_objects_len = (ob != NULL) ? 1 : 0;
|
||||
objects = MEM_mallocN(sizeof(*objects) * *r_objects_len, __func__);
|
||||
if (ob != NULL) {
|
||||
objects[0] = ob;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
const View3D *v3d = CTX_wm_view3d(C); /* may be NULL. */
|
||||
objects = BKE_view_layer_array_selected_objects_params(
|
||||
view_layer,
|
||||
v3d,
|
||||
r_objects_len,
|
||||
&((const struct ObjectsInViewLayerParams){
|
||||
.no_dup_data = true,
|
||||
.filter_fn = filter_fn,
|
||||
.filter_userdata = filter_user_data,
|
||||
}));
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
|
||||
static bool object_array_for_wpaint_filter(Object *ob, void *user_data)
|
||||
{
|
||||
bContext *C = user_data;
|
||||
if (vertex_group_supported_poll_ex(C, ob)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static Object **object_array_for_wpaint(bContext *C, uint *r_objects_len)
|
||||
{
|
||||
return object_array_for_wpaint_impl(C, object_array_for_wpaint_filter, C, r_objects_len);
|
||||
}
|
||||
|
||||
static bool vertex_group_use_vert_sel(Object *ob)
|
||||
{
|
||||
if (ob->mode == OB_MODE_EDIT) {
|
||||
|
@ -100,6 +165,12 @@ static Lattice *vgroup_edit_lattice(Object *ob)
|
|||
return (lt->editlatt) ? lt->editlatt->latt : lt;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public Utility Functions
|
||||
* \{ */
|
||||
|
||||
bool ED_vgroup_sync_from_pose(Object *ob)
|
||||
{
|
||||
Object *armobj = BKE_object_pose_armature_get(ob);
|
||||
|
@ -2659,14 +2730,21 @@ static void vgroup_assign_verts(Object *ob, const float weight)
|
|||
/** \name Shared Operator Poll Functions
|
||||
* \{ */
|
||||
|
||||
static bool vertex_group_supported_poll_ex(bContext *C, const Object *ob)
|
||||
{
|
||||
if (!ED_operator_object_active_local_editable_ex(C, ob)) {
|
||||
return false;
|
||||
}
|
||||
const ID *data = ob->data;
|
||||
return (OB_TYPE_SUPPORT_VGROUP(ob->type) &&
|
||||
/* Data checks. */
|
||||
(data != NULL) && !ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data));
|
||||
}
|
||||
|
||||
static bool vertex_group_supported_poll(bContext *C)
|
||||
{
|
||||
Object *ob = ED_object_context(C);
|
||||
ID *data = (ob) ? ob->data : NULL;
|
||||
|
||||
return (ob && !ID_IS_LINKED(ob) && OB_TYPE_SUPPORT_VGROUP(ob->type) &&
|
||||
!ID_IS_OVERRIDE_LIBRARY(ob) && data && !ID_IS_LINKED(data) &&
|
||||
!ID_IS_OVERRIDE_LIBRARY(data));
|
||||
return vertex_group_supported_poll_ex(C, ob);
|
||||
}
|
||||
|
||||
static bool vertex_group_poll(bContext *C)
|
||||
|
@ -3512,22 +3590,11 @@ static int vertex_group_smooth_exec(bContext *C, wmOperator *op)
|
|||
{
|
||||
const float fac = RNA_float_get(op->ptr, "factor");
|
||||
const int repeat = RNA_int_get(op->ptr, "repeat");
|
||||
eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
|
||||
const eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
|
||||
const float fac_expand = RNA_float_get(op->ptr, "expand");
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
Object *ob_ctx = ED_object_context(C);
|
||||
|
||||
uint objects_len;
|
||||
Object **objects;
|
||||
if (ob_ctx->mode == OB_MODE_WEIGHT_PAINT) {
|
||||
/* Until weight paint supports multi-edit, use only the active. */
|
||||
objects_len = 1;
|
||||
objects = &ob_ctx;
|
||||
}
|
||||
else {
|
||||
objects = BKE_view_layer_array_from_objects_in_mode_unique_data(
|
||||
view_layer, CTX_wm_view3d(C), &objects_len, ob_ctx->mode);
|
||||
}
|
||||
Object **objects = object_array_for_wpaint(C, &objects_len);
|
||||
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *ob = objects[ob_index];
|
||||
|
@ -3544,9 +3611,7 @@ static int vertex_group_smooth_exec(bContext *C, wmOperator *op)
|
|||
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
|
||||
}
|
||||
if (objects != &ob_ctx) {
|
||||
MEM_freeN(objects);
|
||||
}
|
||||
MEM_freeN(objects);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
@ -3588,22 +3653,29 @@ void OBJECT_OT_vertex_group_smooth(wmOperatorType *ot)
|
|||
|
||||
static int vertex_group_clean_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob = ED_object_context(C);
|
||||
const float limit = RNA_float_get(op->ptr, "limit");
|
||||
const bool keep_single = RNA_boolean_get(op->ptr, "keep_single");
|
||||
const eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
|
||||
|
||||
float limit = RNA_float_get(op->ptr, "limit");
|
||||
bool keep_single = RNA_boolean_get(op->ptr, "keep_single");
|
||||
eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
|
||||
uint objects_len;
|
||||
Object **objects = object_array_for_wpaint(C, &objects_len);
|
||||
|
||||
int subset_count, vgroup_tot;
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *ob = objects[ob_index];
|
||||
|
||||
const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(
|
||||
ob, subset_type, &vgroup_tot, &subset_count);
|
||||
vgroup_clean_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit, keep_single);
|
||||
MEM_freeN((void *)vgroup_validmap);
|
||||
int subset_count, vgroup_tot;
|
||||
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
|
||||
const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(
|
||||
ob, subset_type, &vgroup_tot, &subset_count);
|
||||
|
||||
vgroup_clean_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit, keep_single);
|
||||
MEM_freeN((void *)vgroup_validmap);
|
||||
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
|
||||
}
|
||||
MEM_freeN(objects);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
@ -3611,7 +3683,7 @@ static int vertex_group_clean_exec(bContext *C, wmOperator *op)
|
|||
void OBJECT_OT_vertex_group_clean(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Clean Vertex Group";
|
||||
ot->name = "Clean Vertex Group Weights";
|
||||
ot->idname = "OBJECT_OT_vertex_group_clean";
|
||||
ot->description = "Remove vertex group assignments which are not required";
|
||||
|
||||
|
|
Loading…
Reference in New Issue