forked from bartvdbraak/blender
2.5 weight paint:
* Refactored weight paint to use the new stroke code, now does smooth stroke and stroke spacing. Note: weight paint is failing to free it's MocNodes in 2.5, someone might want to look into that
This commit is contained in:
parent
1e0bd07522
commit
a54af8e3ba
@ -429,7 +429,9 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel):
|
||||
|
||||
def poll(self, context):
|
||||
settings = self.paint_settings(context)
|
||||
return (settings and settings.brush and (context.sculpt_object or context.vertex_paint_object))
|
||||
return (settings and settings.brush and (context.sculpt_object or
|
||||
context.vertex_paint_object or
|
||||
context.weight_paint_object))
|
||||
|
||||
def draw(self, context):
|
||||
settings = self.paint_settings(context)
|
||||
|
@ -1273,58 +1273,109 @@ struct WPaintData {
|
||||
float wpimat[3][3];
|
||||
};
|
||||
|
||||
static void wpaint_exit(bContext *C, wmOperator *op)
|
||||
static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
struct PaintStroke *stroke = op->customdata;
|
||||
ToolSettings *ts= CTX_data_tool_settings(C);
|
||||
VPaint *wp= ts->wpaint;
|
||||
Object *ob= CTX_data_active_object(C);
|
||||
struct WPaintData *wpd= op->customdata;
|
||||
struct WPaintData *wpd;
|
||||
Mesh *me;
|
||||
float mat[4][4], imat[4][4];
|
||||
|
||||
if(wpd->vertexcosnos)
|
||||
MEM_freeN(wpd->vertexcosnos);
|
||||
MEM_freeN(wpd->indexar);
|
||||
if(scene->obedit) return OPERATOR_CANCELLED;
|
||||
|
||||
/* frees prev buffer */
|
||||
copy_wpaint_prev(ts->wpaint, NULL, 0);
|
||||
me= get_mesh(ob);
|
||||
if(me==NULL || me->totface==0) return OPERATOR_PASS_THROUGH;
|
||||
|
||||
/* and particles too */
|
||||
if(ob->particlesystem.first) {
|
||||
ParticleSystem *psys;
|
||||
int i;
|
||||
/* if nothing was added yet, we make dverts and a vertex deform group */
|
||||
if (!me->dvert)
|
||||
create_dverts(&me->id);
|
||||
|
||||
for(psys= ob->particlesystem.first; psys; psys= psys->next) {
|
||||
for(i=0; i<PSYS_TOT_VG; i++) {
|
||||
if(psys->vgroup[i]==ob->actdef) {
|
||||
psys->recalc |= PSYS_RECALC_RESET;
|
||||
/* make mode data storage */
|
||||
wpd= MEM_callocN(sizeof(struct WPaintData), "WPaintData");
|
||||
paint_stroke_set_mode_data(stroke, wpd);
|
||||
view3d_set_viewcontext(C, &wpd->vc);
|
||||
wpd->vgroup_mirror= -1;
|
||||
|
||||
// if(qual & LR_CTRLKEY) {
|
||||
// sample_wpaint(scene, ar, v3d, 0);
|
||||
// return;
|
||||
// }
|
||||
// if(qual & LR_SHIFTKEY) {
|
||||
// sample_wpaint(scene, ar, v3d, 1);
|
||||
// return;
|
||||
// }
|
||||
|
||||
/* ALLOCATIONS! no return after this line */
|
||||
/* painting on subsurfs should give correct points too, this returns me->totvert amount */
|
||||
wpd->vertexcosnos= mesh_get_mapped_verts_nors(scene, ob);
|
||||
wpd->indexar= get_indexarray();
|
||||
copy_wpaint_prev(wp, me->dvert, me->totvert);
|
||||
|
||||
/* this happens on a Bone select, when no vgroup existed yet */
|
||||
if(ob->actdef<=0) {
|
||||
Object *modob;
|
||||
if((modob = modifiers_isDeformedByArmature(ob))) {
|
||||
bPoseChannel *pchan;
|
||||
for(pchan= modob->pose->chanbase.first; pchan; pchan= pchan->next)
|
||||
if(pchan->bone->flag & SELECT)
|
||||
break;
|
||||
if(pchan) {
|
||||
bDeformGroup *dg= get_named_vertexgroup(ob, pchan->name);
|
||||
if(dg==NULL)
|
||||
dg= add_defgroup_name(ob, pchan->name); /* sets actdef */
|
||||
else
|
||||
ob->actdef= get_defgroup_num(ob, dg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ob->defbase.first==NULL) {
|
||||
add_defgroup(ob);
|
||||
}
|
||||
|
||||
// if(ob->lay & v3d->lay); else error("Active object is not in this layer");
|
||||
|
||||
/* imat for normals */
|
||||
Mat4MulMat4(mat, ob->obmat, wpd->vc.rv3d->viewmat);
|
||||
Mat4Invert(imat, mat);
|
||||
Mat3CpyMat4(wpd->wpimat, imat);
|
||||
|
||||
/* if mirror painting, find the other group */
|
||||
if(wp->flag & VP_MIRROR_X) {
|
||||
bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1);
|
||||
if(defgroup) {
|
||||
bDeformGroup *curdef;
|
||||
int actdef= 0;
|
||||
char name[32];
|
||||
|
||||
BLI_strncpy(name, defgroup->name, 32);
|
||||
bone_flip_name(name, 0); /* 0 = don't strip off number extensions */
|
||||
|
||||
for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++)
|
||||
if (!strcmp(curdef->name, name))
|
||||
break;
|
||||
if(curdef==NULL) {
|
||||
int olddef= ob->actdef; /* tsk, add_defgroup sets the active defgroup */
|
||||
curdef= add_defgroup_name (ob, name);
|
||||
ob->actdef= olddef;
|
||||
}
|
||||
|
||||
if(curdef && curdef!=defgroup)
|
||||
wpd->vgroup_mirror= actdef;
|
||||
}
|
||||
}
|
||||
|
||||
DAG_object_flush_update(CTX_data_scene(C), ob, OB_RECALC_DATA);
|
||||
|
||||
MEM_freeN(wpd);
|
||||
op->customdata= NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int wpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
|
||||
{
|
||||
ToolSettings *ts= CTX_data_tool_settings(C);
|
||||
VPaint *wp= ts->wpaint;
|
||||
Brush *brush = paint_brush(&wp->paint);
|
||||
|
||||
switch(event->type) {
|
||||
case LEFTMOUSE:
|
||||
if(event->val==0) { /* release */
|
||||
wpaint_exit(C, op);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
/* pass on, first press gets painted too */
|
||||
|
||||
case MOUSEMOVE:
|
||||
{
|
||||
struct WPaintData *wpd= op->customdata;
|
||||
struct WPaintData *wpd= paint_stroke_mode_data(stroke);
|
||||
ViewContext *vc= &wpd->vc;
|
||||
Object *ob= vc->obact;
|
||||
Mesh *me= ob->data;
|
||||
@ -1341,10 +1392,11 @@ static int wpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
wmGetSingleMatrix(mat);
|
||||
wmLoadMatrix(wpd->vc.rv3d->viewmat);
|
||||
|
||||
MTC_Mat4SwapMat4(wpd->vc.rv3d->persmat, mat);
|
||||
RNA_float_get_array(itemptr, "mouse", mval);
|
||||
mval[0]-= vc->ar->winrct.xmin;
|
||||
mval[1]-= vc->ar->winrct.ymin;
|
||||
|
||||
mval[0]= event->x - vc->ar->winrct.xmin;
|
||||
mval[1]= event->y - vc->ar->winrct.ymin;
|
||||
MTC_Mat4SwapMat4(wpd->vc.rv3d->persmat, mat);
|
||||
|
||||
/* which faces are involved */
|
||||
if(wp->flag & VP_AREA) {
|
||||
@ -1465,107 +1517,48 @@ static int wpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
|
||||
DAG_object_flush_update(vc->scene, ob, OB_RECALC_DATA);
|
||||
ED_region_tag_redraw(vc->ar);
|
||||
}
|
||||
|
||||
static void wpaint_stroke_done(bContext *C, struct PaintStroke *stroke)
|
||||
{
|
||||
ToolSettings *ts= CTX_data_tool_settings(C);
|
||||
Object *ob= CTX_data_active_object(C);
|
||||
struct WPaintData *wpd= paint_stroke_mode_data(stroke);
|
||||
|
||||
if(wpd->vertexcosnos)
|
||||
MEM_freeN(wpd->vertexcosnos);
|
||||
MEM_freeN(wpd->indexar);
|
||||
|
||||
/* frees prev buffer */
|
||||
copy_wpaint_prev(ts->wpaint, NULL, 0);
|
||||
|
||||
/* and particles too */
|
||||
if(ob->particlesystem.first) {
|
||||
ParticleSystem *psys;
|
||||
int i;
|
||||
|
||||
for(psys= ob->particlesystem.first; psys; psys= psys->next) {
|
||||
for(i=0; i<PSYS_TOT_VG; i++) {
|
||||
if(psys->vgroup[i]==ob->actdef) {
|
||||
psys->recalc |= PSYS_RECALC_RESET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
DAG_object_flush_update(CTX_data_scene(C), ob, OB_RECALC_DATA);
|
||||
|
||||
MEM_freeN(wpd);
|
||||
}
|
||||
|
||||
|
||||
static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
ToolSettings *ts= CTX_data_tool_settings(C);
|
||||
VPaint *wp= ts->wpaint;
|
||||
Object *ob= CTX_data_active_object(C);
|
||||
struct WPaintData *wpd;
|
||||
Mesh *me;
|
||||
float mat[4][4], imat[4][4];
|
||||
|
||||
if(scene->obedit) return OPERATOR_CANCELLED;
|
||||
// XXX if(multires_level1_test()) return;
|
||||
|
||||
me= get_mesh(ob);
|
||||
if(me==NULL || me->totface==0) return OPERATOR_PASS_THROUGH;
|
||||
|
||||
/* if nothing was added yet, we make dverts and a vertex deform group */
|
||||
if (!me->dvert)
|
||||
create_dverts(&me->id);
|
||||
|
||||
/* make customdata storage */
|
||||
op->customdata= wpd= MEM_callocN(sizeof(struct WPaintData), "WPaintData");
|
||||
view3d_set_viewcontext(C, &wpd->vc);
|
||||
wpd->vgroup_mirror= -1;
|
||||
|
||||
// if(qual & LR_CTRLKEY) {
|
||||
// sample_wpaint(scene, ar, v3d, 0);
|
||||
// return;
|
||||
// }
|
||||
// if(qual & LR_SHIFTKEY) {
|
||||
// sample_wpaint(scene, ar, v3d, 1);
|
||||
// return;
|
||||
// }
|
||||
|
||||
/* ALLOCATIONS! no return after this line */
|
||||
/* painting on subsurfs should give correct points too, this returns me->totvert amount */
|
||||
wpd->vertexcosnos= mesh_get_mapped_verts_nors(scene, ob);
|
||||
wpd->indexar= get_indexarray();
|
||||
copy_wpaint_prev(wp, me->dvert, me->totvert);
|
||||
|
||||
/* this happens on a Bone select, when no vgroup existed yet */
|
||||
if(ob->actdef<=0) {
|
||||
Object *modob;
|
||||
if((modob = modifiers_isDeformedByArmature(ob))) {
|
||||
bPoseChannel *pchan;
|
||||
for(pchan= modob->pose->chanbase.first; pchan; pchan= pchan->next)
|
||||
if(pchan->bone->flag & SELECT)
|
||||
break;
|
||||
if(pchan) {
|
||||
bDeformGroup *dg= get_named_vertexgroup(ob, pchan->name);
|
||||
if(dg==NULL)
|
||||
dg= add_defgroup_name(ob, pchan->name); /* sets actdef */
|
||||
else
|
||||
ob->actdef= get_defgroup_num(ob, dg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ob->defbase.first==NULL) {
|
||||
add_defgroup(ob);
|
||||
}
|
||||
|
||||
// if(ob->lay & v3d->lay); else error("Active object is not in this layer");
|
||||
|
||||
/* imat for normals */
|
||||
Mat4MulMat4(mat, ob->obmat, wpd->vc.rv3d->viewmat);
|
||||
Mat4Invert(imat, mat);
|
||||
Mat3CpyMat4(wpd->wpimat, imat);
|
||||
|
||||
/* if mirror painting, find the other group */
|
||||
if(wp->flag & VP_MIRROR_X) {
|
||||
bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1);
|
||||
if(defgroup) {
|
||||
bDeformGroup *curdef;
|
||||
int actdef= 0;
|
||||
char name[32];
|
||||
|
||||
BLI_strncpy(name, defgroup->name, 32);
|
||||
bone_flip_name(name, 0); /* 0 = don't strip off number extensions */
|
||||
|
||||
for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++)
|
||||
if (!strcmp(curdef->name, name))
|
||||
break;
|
||||
if(curdef==NULL) {
|
||||
int olddef= ob->actdef; /* tsk, add_defgroup sets the active defgroup */
|
||||
curdef= add_defgroup_name (ob, name);
|
||||
ob->actdef= olddef;
|
||||
}
|
||||
|
||||
if(curdef && curdef!=defgroup)
|
||||
wpd->vgroup_mirror= actdef;
|
||||
}
|
||||
}
|
||||
|
||||
/* do paint once for click only paint */
|
||||
wpaint_modal(C, op, event);
|
||||
op->customdata = paint_stroke_new(C, wpaint_stroke_test_start,
|
||||
wpaint_stroke_update_step,
|
||||
wpaint_stroke_done);
|
||||
|
||||
/* add modal handler */
|
||||
WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
|
||||
@ -1582,13 +1575,14 @@ void PAINT_OT_weight_paint(wmOperatorType *ot)
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke= wpaint_invoke;
|
||||
ot->modal= wpaint_modal;
|
||||
ot->modal= paint_stroke_modal;
|
||||
/* ot->exec= vpaint_exec; <-- needs stroke property */
|
||||
ot->poll= wp_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
|
||||
|
||||
RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
|
||||
}
|
||||
|
||||
/* ************ set / clear vertex paint mode ********** */
|
||||
|
Loading…
Reference in New Issue
Block a user