GPencil: New Normalize All operator

This operator works similar to mesh operator but for Stroke and Points data.

Also minor cleanup in Normalize operator.
This commit is contained in:
Antonio Vazquez 2019-04-16 12:12:35 +02:00
parent 5494926ee5
commit 2e3bc99590
4 changed files with 117 additions and 3 deletions

View File

@ -4095,6 +4095,7 @@ class VIEW3D_MT_weight_gpencil(Menu):
def draw(self, context):
layout = self.layout
layout.operator("gpencil.vertex_group_normalize_all", text="Normalize All")
layout.operator("gpencil.vertex_group_normalize", text="Normalize")
layout.separator()

View File

@ -1898,7 +1898,8 @@ static int gpencil_vertex_group_normalize_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
MDeformVert *dvert;
MDeformVert *dvert = NULL;
MDeformWeight *dw = NULL;
const int def_nr = ob->actdef - 1;
bDeformGroup *defgroup = BLI_findlink(&ob->defbase, def_nr);
if (defgroup == NULL) {
@ -1915,7 +1916,7 @@ static int gpencil_vertex_group_normalize_exec(bContext *C, wmOperator *op)
float maxvalue = 0.0f;
for (int i = 0; i < gps->totpoints; i++) {
dvert = &gps->dvert[i];
MDeformWeight *dw = defvert_find_index(dvert, def_nr);
dw = defvert_find_index(dvert, def_nr);
if ((dw != NULL) && (dw->weight > maxvalue)) {
maxvalue = dw->weight;
}
@ -1925,7 +1926,7 @@ static int gpencil_vertex_group_normalize_exec(bContext *C, wmOperator *op)
if (maxvalue > 0.0f) {
for (int i = 0; i < gps->totpoints; i++) {
dvert = &gps->dvert[i];
MDeformWeight *dw = defvert_find_index(dvert, def_nr);
dw = defvert_find_index(dvert, def_nr);
if (dw != NULL) {
dw->weight = dw->weight / maxvalue;
}
@ -1957,6 +1958,116 @@ void GPENCIL_OT_vertex_group_normalize(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* normalize all */
static int gpencil_vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
bool lock_active = RNA_boolean_get(op->ptr, "lock_active");
/* sanity checks */
if (ELEM(NULL, ts, ob, ob->data)) {
return OPERATOR_CANCELLED;
}
bDeformGroup *defgroup = NULL;
MDeformVert *dvert = NULL;
MDeformWeight *dw = NULL;
const int def_nr = ob->actdef - 1;
const int defbase_tot = BLI_listbase_count(&ob->defbase);
if (defbase_tot == 0) {
return OPERATOR_CANCELLED;
}
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
/* verify the strokes has something to change */
if (gps->totpoints == 0) {
continue;
}
/* look for tot value */
float *tot_values = MEM_callocN(gps->totpoints * sizeof(float), __func__);
for (int i = 0; i < gps->totpoints; i++) {
dvert = &gps->dvert[i];
for (int v = 0; v < defbase_tot; v++) {
defgroup = BLI_findlink(&ob->defbase, v);
/* skip NULL or locked groups */
if ((defgroup == NULL) || (defgroup->flag & DG_LOCK_WEIGHT)) {
continue;
}
/* skip current */
if ((lock_active) && (v == def_nr)) {
continue;
}
dw = defvert_find_index(dvert, v);
if (dw != NULL) {
tot_values[i] += dw->weight;
}
}
}
/* normalize weights */
for (int i = 0; i < gps->totpoints; i++) {
if (tot_values[i] == 0.0f) {
continue;
}
dvert = &gps->dvert[i];
for (int v = 0; v < defbase_tot; v++) {
defgroup = BLI_findlink(&ob->defbase, v);
/* skip NULL or locked groups */
if ((defgroup == NULL) || (defgroup->flag & DG_LOCK_WEIGHT)) {
continue;
}
/* skip current */
if ((lock_active) && (v == def_nr)) {
continue;
}
dw = defvert_find_index(dvert, v);
if (dw != NULL) {
dw->weight = dw->weight / tot_values[i];
}
}
}
/* free temp array */
MEM_SAFE_FREE(tot_values);
}
CTX_DATA_END;
/* notifiers */
bGPdata *gpd = ob->data;
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
return OPERATOR_FINISHED;
}
void GPENCIL_OT_vertex_group_normalize_all(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Normalize All Vertex Group";
ot->idname = "GPENCIL_OT_vertex_group_normalize_all";
ot->description = "Normalize all weights of all vertex groups, "
"so that for each vertex, the sum of all weights is 1.0";
/* api callbacks */
ot->poll = gpencil_vertex_group_weight_poll;
ot->exec = gpencil_vertex_group_normalize_all_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
RNA_def_boolean(ot->srna, "lock_active", true, "Lock Active",
"Keep the values of the active group while normalizing others");
}
/****************************** Join ***********************************/
/* userdata for joined_gpencil_fix_animdata_cb() */

View File

@ -497,6 +497,7 @@ void GPENCIL_OT_vertex_group_deselect(struct wmOperatorType *ot);
void GPENCIL_OT_vertex_group_invert(struct wmOperatorType *ot);
void GPENCIL_OT_vertex_group_smooth(struct wmOperatorType *ot);
void GPENCIL_OT_vertex_group_normalize(struct wmOperatorType *ot);
void GPENCIL_OT_vertex_group_normalize_all(struct wmOperatorType *ot);
/* color handle */
void GPENCIL_OT_lock_layer(struct wmOperatorType *ot);

View File

@ -323,6 +323,7 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_vertex_group_invert);
WM_operatortype_append(GPENCIL_OT_vertex_group_smooth);
WM_operatortype_append(GPENCIL_OT_vertex_group_normalize);
WM_operatortype_append(GPENCIL_OT_vertex_group_normalize_all);
/* color handle */
WM_operatortype_append(GPENCIL_OT_lock_layer);