add vertex color smooth operator.

Since the bug was fixed that made blur brush _not_ blur all verts, there is no way to blur vertex colors after baking.
While this was hidden it was useful especially for baking vertex colors.
This commit is contained in:
Campbell Barton 2013-04-27 19:00:26 +00:00
parent f5e022a0a0
commit 7c27cfc020
4 changed files with 124 additions and 32 deletions

@ -1231,6 +1231,7 @@ class VIEW3D_MT_paint_vertex(Menu):
layout.separator() layout.separator()
layout.operator("paint.vertex_color_set") layout.operator("paint.vertex_color_set")
layout.operator("paint.vertex_color_smooth")
layout.operator("paint.vertex_color_dirt") layout.operator("paint.vertex_color_dirt")

@ -90,8 +90,10 @@ int weight_paint_mode_poll(struct bContext *C);
int vertex_paint_poll(struct bContext *C); int vertex_paint_poll(struct bContext *C);
int vertex_paint_mode_poll(struct bContext *C); int vertex_paint_mode_poll(struct bContext *C);
void vpaint_fill(struct Object *ob, unsigned int paintcol); bool ED_vpaint_fill(struct Object *ob, unsigned int paintcol);
void wpaint_fill(struct VPaint *wp, struct Object *ob, float paintweight); bool ED_wpaint_fill(struct VPaint *wp, struct Object *ob, float paintweight);
bool ED_vpaint_smooth(struct Object *ob);
void PAINT_OT_weight_paint_toggle(struct wmOperatorType *ot); void PAINT_OT_weight_paint_toggle(struct wmOperatorType *ot);
void PAINT_OT_weight_paint(struct wmOperatorType *ot); void PAINT_OT_weight_paint(struct wmOperatorType *ot);

@ -154,10 +154,14 @@ static int vertex_color_set_exec(bContext *C, wmOperator *UNUSED(op))
Scene *scene = CTX_data_scene(C); Scene *scene = CTX_data_scene(C);
Object *obact = CTX_data_active_object(C); Object *obact = CTX_data_active_object(C);
unsigned int paintcol = vpaint_get_current_col(scene->toolsettings->vpaint); unsigned int paintcol = vpaint_get_current_col(scene->toolsettings->vpaint);
vpaint_fill(obact, paintcol);
if (ED_vpaint_fill(obact, paintcol)) {
ED_region_tag_redraw(CTX_wm_region(C)); // XXX - should redraw all 3D views ED_region_tag_redraw(CTX_wm_region(C)); // XXX - should redraw all 3D views
return OPERATOR_FINISHED; return OPERATOR_FINISHED;
}
else {
return OPERATOR_CANCELLED;
}
} }
static void PAINT_OT_vertex_color_set(wmOperatorType *ot) static void PAINT_OT_vertex_color_set(wmOperatorType *ot)
@ -175,6 +179,33 @@ static void PAINT_OT_vertex_color_set(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
} }
static int vertex_color_smooth_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *obact = CTX_data_active_object(C);
if (ED_vpaint_smooth(obact)) {
ED_region_tag_redraw(CTX_wm_region(C)); // XXX - should redraw all 3D views
return OPERATOR_FINISHED;
}
else {
return OPERATOR_CANCELLED;
}
}
static void PAINT_OT_vertex_color_smooth(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Smooth Vertex Colors";
ot->idname = "PAINT_OT_vertex_color_smooth";
ot->description = "Smooth colors across vertices";
/* api callbacks */
ot->exec = vertex_color_smooth_exec;
ot->poll = vertex_paint_mode_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op)) static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op))
{ {
Paint *paint = BKE_paint_get_active_from_context(C); Paint *paint = BKE_paint_get_active_from_context(C);
@ -858,6 +889,7 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(PAINT_OT_vertex_paint_toggle); WM_operatortype_append(PAINT_OT_vertex_paint_toggle);
WM_operatortype_append(PAINT_OT_vertex_paint); WM_operatortype_append(PAINT_OT_vertex_paint);
WM_operatortype_append(PAINT_OT_vertex_color_set); WM_operatortype_append(PAINT_OT_vertex_color_set);
WM_operatortype_append(PAINT_OT_vertex_color_smooth);
/* face-select */ /* face-select */
WM_operatortype_append(PAINT_OT_face_select_linked); WM_operatortype_append(PAINT_OT_face_select_linked);

@ -353,13 +353,17 @@ static void do_shared_vertexcol(Mesh *me, bool *mlooptag, bool *mfacetag, int do
} }
} }
static void make_vertexcol(Object *ob) /* single ob */ static bool make_vertexcol(Object *ob) /* single ob */
{ {
Mesh *me; Mesh *me;
if (!ob || ob->id.lib) return;
me = BKE_mesh_from_object(ob); if ((ob->id.lib) ||
if (me == NULL) return; ((me = BKE_mesh_from_object(ob)) == NULL) ||
if (me->edit_btmesh) return; (me->totpoly == 0) ||
(me->edit_btmesh))
{
return false;
}
/* copies from shadedisplist to mcol */ /* copies from shadedisplist to mcol */
if (!me->mloopcol && me->totloop) { if (!me->mloopcol && me->totloop) {
@ -373,13 +377,10 @@ static void make_vertexcol(Object *ob) /* single ob */
} }
update_tessface_data(ob, me); update_tessface_data(ob, me);
//if (shade)
// shadeMeshMCol(scene, ob, me);
//else
DAG_id_tag_update(&me->id, 0); DAG_id_tag_update(&me->id, 0);
return (me->mloopcol != NULL);
} }
/* mirror_vgroup is set to -1 when invalid */ /* mirror_vgroup is set to -1 when invalid */
@ -452,28 +453,28 @@ static void copy_wpaint_prev(VPaint *wp, MDeformVert *dverts, int dcount)
} }
} }
void vpaint_fill(Object *ob, unsigned int paintcol) bool ED_vpaint_fill(Object *ob, unsigned int paintcol)
{ {
Mesh *me; Mesh *me;
MPoly *mp; MPoly *mp;
MLoopCol *lcol; int i, j;
int i, j, selected; bool selected;
me = BKE_mesh_from_object(ob); if (((me = BKE_mesh_from_object(ob)) == NULL) ||
if (me == NULL || me->totpoly == 0) return; (me->mloopcol == NULL && (make_vertexcol(ob) == false)))
{
return false;
}
if (!me->mloopcol) make_vertexcol(ob); selected = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
if (!me->mloopcol) return; /* possible we can't make mcol's */
selected = (me->editflag & ME_EDIT_PAINT_FACE_SEL);
mp = me->mpoly; mp = me->mpoly;
for (i = 0; i < me->totpoly; i++, mp++) { for (i = 0; i < me->totpoly; i++, mp++) {
if (!(!selected || mp->flag & ME_FACE_SEL)) MLoopCol *lcol = me->mloopcol + mp->loopstart;
if (selected && !(mp->flag & ME_FACE_SEL))
continue; continue;
lcol = me->mloopcol + mp->loopstart;
for (j = 0; j < mp->totloop; j++, lcol++) { for (j = 0; j < mp->totloop; j++, lcol++) {
*(int *)lcol = paintcol; *(int *)lcol = paintcol;
} }
@ -483,11 +484,13 @@ void vpaint_fill(Object *ob, unsigned int paintcol)
BKE_mesh_tessface_clear(me); BKE_mesh_tessface_clear(me);
DAG_id_tag_update(&me->id, 0); DAG_id_tag_update(&me->id, 0);
return true;
} }
/* fills in the selected faces with the current weight and vertex group */ /* fills in the selected faces with the current weight and vertex group */
void wpaint_fill(VPaint *wp, Object *ob, float paintweight) bool ED_wpaint_fill(VPaint *wp, Object *ob, float paintweight)
{ {
Mesh *me = ob->data; Mesh *me = ob->data;
MPoly *mp; MPoly *mp;
@ -498,7 +501,9 @@ void wpaint_fill(VPaint *wp, Object *ob, float paintweight)
/* mutually exclusive, could be made into a */ /* mutually exclusive, could be made into a */
const short paint_selmode = ME_EDIT_PAINT_SEL_MODE(me); const short paint_selmode = ME_EDIT_PAINT_SEL_MODE(me);
if (me->totpoly == 0 || me->dvert == NULL || !me->mpoly) return; if (me->totpoly == 0 || me->dvert == NULL || !me->mpoly) {
return false;
}
vgroup_active = ob->actdef - 1; vgroup_active = ob->actdef - 1;
@ -563,6 +568,54 @@ void wpaint_fill(VPaint *wp, Object *ob, float paintweight)
copy_wpaint_prev(wp, NULL, 0); copy_wpaint_prev(wp, NULL, 0);
DAG_id_tag_update(&me->id, 0); DAG_id_tag_update(&me->id, 0);
return true;
}
bool ED_vpaint_smooth(Object *ob)
{
Mesh *me;
MPoly *mp;
int i, j;
bool *mlooptag;
bool selected;
if (((me = BKE_mesh_from_object(ob)) == NULL) ||
(me->mloopcol == NULL && (make_vertexcol(ob) == false)))
{
return false;
}
selected = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
mlooptag = MEM_callocN(sizeof(bool) * me->totloop, "VPaintData mlooptag");
/* simply tag loops of selected faces */
mp = me->mpoly;
for (i = 0; i < me->totpoly; i++, mp++) {
MLoop *ml = me->mloop + mp->loopstart;
int ml_index = mp->loopstart;
if (selected && !(mp->flag & ME_FACE_SEL))
continue;
for (j = 0; j < mp->totloop; j++, ml_index++, ml++) {
mlooptag[ml_index] = true;
}
}
/* remove stale me->mcol, will be added later */
BKE_mesh_tessface_clear(me);
do_shared_vertexcol(me, mlooptag, NULL, false);
MEM_freeN(mlooptag);
DAG_id_tag_update(&me->id, 0);
return true;
} }
/* XXX: should be re-implemented as a vertex/weight paint 'color correct' operator */ /* XXX: should be re-implemented as a vertex/weight paint 'color correct' operator */
@ -2561,9 +2614,13 @@ static int weight_paint_set_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED; return OPERATOR_CANCELLED;
} }
wpaint_fill(scene->toolsettings->wpaint, obact, vgroup_weight); if (ED_wpaint_fill(scene->toolsettings->wpaint, obact, vgroup_weight)) {
ED_region_tag_redraw(CTX_wm_region(C)); /* XXX - should redraw all 3D views */ ED_region_tag_redraw(CTX_wm_region(C)); /* XXX - should redraw all 3D views */
return OPERATOR_FINISHED; return OPERATOR_FINISHED;
}
else {
return OPERATOR_CANCELLED;
}
} }
void PAINT_OT_weight_set(wmOperatorType *ot) void PAINT_OT_weight_set(wmOperatorType *ot)