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:
@@ -4095,6 +4095,7 @@ class VIEW3D_MT_weight_gpencil(Menu):
|
|||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
|
layout.operator("gpencil.vertex_group_normalize_all", text="Normalize All")
|
||||||
layout.operator("gpencil.vertex_group_normalize", text="Normalize")
|
layout.operator("gpencil.vertex_group_normalize", text="Normalize")
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
@@ -1898,7 +1898,8 @@ static int gpencil_vertex_group_normalize_exec(bContext *C, wmOperator *op)
|
|||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
MDeformVert *dvert;
|
MDeformVert *dvert = NULL;
|
||||||
|
MDeformWeight *dw = NULL;
|
||||||
const int def_nr = ob->actdef - 1;
|
const int def_nr = ob->actdef - 1;
|
||||||
bDeformGroup *defgroup = BLI_findlink(&ob->defbase, def_nr);
|
bDeformGroup *defgroup = BLI_findlink(&ob->defbase, def_nr);
|
||||||
if (defgroup == NULL) {
|
if (defgroup == NULL) {
|
||||||
@@ -1915,7 +1916,7 @@ static int gpencil_vertex_group_normalize_exec(bContext *C, wmOperator *op)
|
|||||||
float maxvalue = 0.0f;
|
float maxvalue = 0.0f;
|
||||||
for (int i = 0; i < gps->totpoints; i++) {
|
for (int i = 0; i < gps->totpoints; i++) {
|
||||||
dvert = &gps->dvert[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)) {
|
if ((dw != NULL) && (dw->weight > maxvalue)) {
|
||||||
maxvalue = dw->weight;
|
maxvalue = dw->weight;
|
||||||
}
|
}
|
||||||
@@ -1925,7 +1926,7 @@ static int gpencil_vertex_group_normalize_exec(bContext *C, wmOperator *op)
|
|||||||
if (maxvalue > 0.0f) {
|
if (maxvalue > 0.0f) {
|
||||||
for (int i = 0; i < gps->totpoints; i++) {
|
for (int i = 0; i < gps->totpoints; i++) {
|
||||||
dvert = &gps->dvert[i];
|
dvert = &gps->dvert[i];
|
||||||
MDeformWeight *dw = defvert_find_index(dvert, def_nr);
|
dw = defvert_find_index(dvert, def_nr);
|
||||||
if (dw != NULL) {
|
if (dw != NULL) {
|
||||||
dw->weight = dw->weight / maxvalue;
|
dw->weight = dw->weight / maxvalue;
|
||||||
}
|
}
|
||||||
@@ -1957,6 +1958,116 @@ void GPENCIL_OT_vertex_group_normalize(wmOperatorType *ot)
|
|||||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
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 ***********************************/
|
/****************************** Join ***********************************/
|
||||||
|
|
||||||
/* userdata for joined_gpencil_fix_animdata_cb() */
|
/* userdata for joined_gpencil_fix_animdata_cb() */
|
||||||
|
@@ -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_invert(struct wmOperatorType *ot);
|
||||||
void GPENCIL_OT_vertex_group_smooth(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(struct wmOperatorType *ot);
|
||||||
|
void GPENCIL_OT_vertex_group_normalize_all(struct wmOperatorType *ot);
|
||||||
|
|
||||||
/* color handle */
|
/* color handle */
|
||||||
void GPENCIL_OT_lock_layer(struct wmOperatorType *ot);
|
void GPENCIL_OT_lock_layer(struct wmOperatorType *ot);
|
||||||
|
@@ -323,6 +323,7 @@ void ED_operatortypes_gpencil(void)
|
|||||||
WM_operatortype_append(GPENCIL_OT_vertex_group_invert);
|
WM_operatortype_append(GPENCIL_OT_vertex_group_invert);
|
||||||
WM_operatortype_append(GPENCIL_OT_vertex_group_smooth);
|
WM_operatortype_append(GPENCIL_OT_vertex_group_smooth);
|
||||||
WM_operatortype_append(GPENCIL_OT_vertex_group_normalize);
|
WM_operatortype_append(GPENCIL_OT_vertex_group_normalize);
|
||||||
|
WM_operatortype_append(GPENCIL_OT_vertex_group_normalize_all);
|
||||||
|
|
||||||
/* color handle */
|
/* color handle */
|
||||||
WM_operatortype_append(GPENCIL_OT_lock_layer);
|
WM_operatortype_append(GPENCIL_OT_lock_layer);
|
||||||
|
Reference in New Issue
Block a user