|
|
|
@@ -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() */
|
|
|
|
|