diff options
-rw-r--r-- | source/blender/include/blendef.h | 2 | ||||
-rw-r--r-- | source/blender/include/butspace.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_meshdata_types.h | 2 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 106 | ||||
-rw-r--r-- | source/blender/src/editmesh.c | 10 | ||||
-rw-r--r-- | source/blender/src/vpaint.c | 289 |
6 files changed, 286 insertions, 125 deletions
diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h index 16fa5623d26..61e0bae1668 100644 --- a/source/blender/include/blendef.h +++ b/source/blender/include/blendef.h @@ -391,6 +391,6 @@ #define VP_AREA 2 #define VP_SOFT 4 #define VP_NORMALS 8 - +#define VP_SPRAY 16 #endif diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 66914c07ed0..679edbe7683 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -481,7 +481,7 @@ enum { #define B_OPA3_4 2848 #define B_OPA1_0 2849 - +#define B_CLR_WPAINT 2850 /* *********************** */ #define B_RADIOBUTS 3000 diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 479626ba692..83111e87aa9 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -54,7 +54,7 @@ typedef struct MDeformWeight { typedef struct MDeformVert { struct MDeformWeight *dw; int totweight; - int reserved1; + int flag; // flag only in use for weightpaint now } MDeformVert; typedef struct MVert { diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index b6429769dea..1fd69eaf89a 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -2845,11 +2845,12 @@ void do_fpaintbuts(unsigned short event) { Mesh *me; Object *ob; + bDeformGroup *defGroup; extern TFace *lasttface; /* caches info on tface bookkeeping ?*/ - extern VPaint Gvp; /* from vpaint */ + extern VPaint Gwp; /* from vpaint */ ob= OBACT; - if(ob==0) return; + if(ob==NULL) return; switch(event) { @@ -2902,7 +2903,10 @@ void do_fpaintbuts(unsigned short event) } break; case B_SET_VCOL: - clear_vpaint_selectedfaces(); + if(G.f & G_FACESELECT) + clear_vpaint_selectedfaces(); + else + clear_vpaint(); break; case B_REDR_3D_IMA: allqueue(REDRAWVIEW3D, 0); @@ -2953,27 +2957,34 @@ void do_fpaintbuts(unsigned short event) break; case B_OPA1_8: - Gvp.a = 0.125f; + Gwp.a = 0.125f; allqueue(REDRAWBUTSEDIT, 0); break; case B_OPA1_4: - Gvp.a = 0.25f; + Gwp.a = 0.25f; allqueue(REDRAWBUTSEDIT, 0); break; case B_OPA1_2: - Gvp.a = 0.5f; + Gwp.a = 0.5f; allqueue(REDRAWBUTSEDIT, 0); break; case B_OPA3_4: - Gvp.a = 0.75f; + Gwp.a = 0.75f; allqueue(REDRAWBUTSEDIT, 0); break; case B_OPA1_0: - Gvp.a = 1.0f; + Gwp.a = 1.0f; allqueue(REDRAWBUTSEDIT, 0); break; - - + case B_CLR_WPAINT: + defGroup = BLI_findlink(&ob->defbase, ob->actdef-1); + if(defGroup) { + Mesh *me= ob->data; + int a; + for(a=0; a<me->totvert; a++) + remove_vert_defgroup (ob, defGroup, a); + allqueue(REDRAWVIEW3D, 0); + } } } @@ -2982,7 +2993,6 @@ void do_fpaintbuts(unsigned short event) static void editing_panel_mesh_paint(void) { - extern VPaint Gvp; /* from vpaint */ uiBlock *block; block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_paint", UI_EMBOSS, UI_HELV, curarea->win); @@ -2990,43 +3000,66 @@ static void editing_panel_mesh_paint(void) if(G.f & G_WEIGHTPAINT) { + extern VPaint Gwp; /* from vpaint */ Object *ob; ob= OBACT; if(ob==NULL) return; uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, REDRAWVIEW3D, "Weight:",2010,160,400,19, &editbutvweight, 0, 1, 10, 0, "Sets the current vertex group's bone deformation strength"); - uiDefBut(block, BUT, B_WEIGHT0_0 , "0", 2010,140,80,19, 0, 0, 0, 0, 0, ""); - uiDefBut(block, BUT, B_WEIGHT1_4 , "1/4", 2090,140,80,19, 0, 0, 0, 0, 0, ""); - uiDefBut(block, BUT, B_WEIGHT1_2 , "1/2", 2170,140,80,19, 0, 0, 0, 0, 0, ""); - uiDefBut(block, BUT, B_WEIGHT3_4 , "3/4", 2250,140,80,19, 0, 0, 0, 0, 0, ""); - uiDefBut(block, BUT, B_WEIGHT1_0 , "1", 2330,140,80,19, 0, 0, 0, 0, 0, ""); + uiDefButF(block, NUMSLI, REDRAWVIEW3D, "Weight:",10,160,225,19, &editbutvweight, 0, 1, 10, 0, "Sets the current vertex group's bone deformation strength"); + + uiDefBut(block, BUT, B_WEIGHT0_0 , "0", 10,140,45,19, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_WEIGHT1_4 , "1/4", 55,140,45,19, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_WEIGHT1_2 , "1/2", 100,140,45,19, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_WEIGHT3_4 , "3/4", 145,140,45,19, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_WEIGHT1_0 , "1", 190,140,45,19, 0, 0, 0, 0, 0, ""); + + uiDefButF(block, NUMSLI, 0, "Opacity ", 10,120,225,19, &Gwp.a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush"); + + uiDefBut(block, BUT, B_OPA1_8 , "1/8", 10,100,45,19, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_OPA1_4 , "1/4", 55,100,45,19, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_OPA1_2 , "1/2", 100,100,45,19, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_OPA3_4 , "3/4", 145,100,45,19, 0, 0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_OPA1_0 , "1", 190,100,45,19, 0, 0, 0, 0, 0, ""); + + uiDefButF(block, NUMSLI, 0, "Size ", 10,80,225,19, &Gwp.size, 2.0, 64.0, 0, 0, "The size of the brush"); + + uiBlockBeginAlign(block); + uiDefButS(block, ROW, B_DIFF, "Mix", 250,160,60,19, &Gwp.mode, 1.0, 0.0, 0, 0, "Mix the vertex colours"); + uiDefButS(block, ROW, B_DIFF, "Add", 250,140,60,19, &Gwp.mode, 1.0, 1.0, 0, 0, "Add the vertex colour"); + uiDefButS(block, ROW, B_DIFF, "Sub", 250,120,60,19, &Gwp.mode, 1.0, 2.0, 0, 0, "Subtract from the vertex colour"); + uiDefButS(block, ROW, B_DIFF, "Mul", 250,100,60,19, &Gwp.mode, 1.0, 3.0, 0, 0, "Multiply the vertex colour"); + uiDefButS(block, ROW, B_DIFF, "Filter", 250, 80,60,19, &Gwp.mode, 1.0, 4.0, 0, 0, "Mix the colours with an alpha factor"); + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, VP_AREA, 0, "All Faces", 10,50,75,19, &Gwp.flag, 0, 0, 0, 0, "Paint on all faces inside brush"); + uiDefButBitS(block, TOG, VP_SOFT, 0, "Vertex Dist", 85,50,75,19, &Gwp.flag, 0, 0, 0, 0, "Use distances to vertices (instead of paint entire faces)"); + uiDefButBitS(block, TOG, VP_NORMALS, 0, "Normals", 160,50,75,19, &Gwp.flag, 0, 0, 0, 0, "Applies the vertex normal before painting"); + uiDefButBitS(block, TOG, VP_SPRAY, 0, "Spray", 235,50,75,19, &Gwp.flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse"); - uiDefButF(block, NUMSLI, 0, "Opacity ", 2010,120,400,19, &Gvp.a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush"); - uiDefBut(block, BUT, B_OPA1_8 , "1/8", 2010,100,80,19, 0, 0, 0, 0, 0, ""); - uiDefBut(block, BUT, B_OPA1_4 , "1/4", 2090,100,80,19, 0, 0, 0, 0, 0, ""); - uiDefBut(block, BUT, B_OPA1_2 , "1/2", 2170,100,80,19, 0, 0, 0, 0, 0, ""); - uiDefBut(block, BUT, B_OPA3_4 , "3/4", 2250,100,80,19, 0, 0, 0, 0, 0, ""); - uiDefBut(block, BUT, B_OPA1_0 , "1", 2330,100,80,19, 0, 0, 0, 0, 0, ""); - uiDefButF(block, NUMSLI, 0, "Size ", 2010,80,400,19, &Gvp.size, 2.0, 64.0, 0, 0, "The size of the brush"); - uiBlockEndAlign(block); if(ob){ uiBlockBeginAlign(block); - uiDefButBitC(block, TOG, OB_DRAWWIRE, REDRAWVIEW3D, "Wire", 2010,40,194,29, &ob->dtx, 0, 0, 0, 0, "Displays the active object's wireframe in shaded drawing modes"); + uiDefButBitC(block, TOG, OB_DRAWWIRE, REDRAWVIEW3D, "Wire", 10,10,150,19, &ob->dtx, 0, 0, 0, 0, "Displays the active object's wireframe in shaded drawing modes"); + uiDefBut(block, BUT, B_CLR_WPAINT, "Clear", 160,10,150,19, NULL, 0, 0, 0, 0, "Removes reference to this deform group from all vertices"); uiBlockEndAlign(block); } } else{ + extern VPaint Gvp; /* from vpaint */ + uiBlockBeginAlign(block); uiDefButF(block, NUMSLI, 0, "R ", 979,160,194,19, &Gvp.r, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of red used for painting"); uiDefButF(block, NUMSLI, 0, "G ", 979,140,194,19, &Gvp.g, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of green used for painting"); uiDefButF(block, NUMSLI, 0, "B ", 979,120,194,19, &Gvp.b, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of blue used for painting"); + + uiBlockBeginAlign(block); + uiDefButF(block, NUMSLI, 0, "Opacity ", 979,95,194,19, &Gvp.a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush"); + uiDefButF(block, NUMSLI, 0, "Size ", 979,75,194,19, &Gvp.size, 2.0, 64.0, 0, 0, "The size of the brush"); uiBlockEndAlign(block); - uiDefButF(block, NUMSLI, 0, "Opacity ", 979,100,194,19, &Gvp.a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush"); - uiDefButF(block, NUMSLI, 0, "Size ", 979,80,194,19, &Gvp.size, 2.0, 64.0, 0, 0, "The size of the brush"); - uiDefButF(block, COL, B_REDR, "", 1176,99,28,80, &(Gvp.r), 0, 0, 0, B_VPCOLSLI, ""); + uiDefButF(block, COL, B_REDR, "", 1176,120,28,60, &(Gvp.r), 0, 0, 0, B_VPCOLSLI, ""); + uiBlockBeginAlign(block); uiDefButS(block, ROW, B_DIFF, "Mix", 1212,160,63,19, &Gvp.mode, 1.0, 0.0, 0, 0, "Mix the vertex colours"); uiDefButS(block, ROW, B_DIFF, "Add", 1212,140,63,19, &Gvp.mode, 1.0, 1.0, 0, 0, "Add the vertex colour"); @@ -3035,17 +3068,18 @@ static void editing_panel_mesh_paint(void) uiDefButS(block, ROW, B_DIFF, "Filter", 1212, 80,63,19, &Gvp.mode, 1.0, 4.0, 0, 0, "Mix the colours with an alpha factor"); uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, VP_AREA, 0, "Area", 979,50,81,19, &Gvp.flag, 0, 0, 0, 0, "Vertex paint evaluates the area of the face the brush covers (otherwise vertices only)"); - uiDefButBitS(block, TOG, VP_SOFT, 0, "Soft", 1061,50,112,19, &Gvp.flag, 0, 0, 0, 0, "Use a soft brush"); - uiDefButBitS(block, TOG, VP_NORMALS, 0, "Normals", 1174,50,102,19, &Gvp.flag, 0, 0, 0, 0, "Vertex paint applies the vertex normal before painting"); + uiDefButBitS(block, TOG, VP_AREA, 0, "All Faces", 979,50,75,19, &Gvp.flag, 0, 0, 0, 0, "Paint on all faces inside brush"); + uiDefButBitS(block, TOG, VP_SOFT, 0, "Vertex Dist", 1054,50,75,19, &Gvp.flag, 0, 0, 0, 0, "Use distances to vertices (instead of paint entire faces)"); + uiDefButBitS(block, TOG, VP_NORMALS, 0, "Normals", 1129,50,75,19, &Gvp.flag, 0, 0, 0, 0, "Applies the vertex normal before painting"); + uiDefButBitS(block, TOG, VP_SPRAY, 0, "Spray", 1204,50,75,19, &Gvp.flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse"); uiBlockBeginAlign(block); - uiDefBut(block, BUT, B_VPGAMMA, "Set", 979,30,81,19, 0, 0, 0, 0, 0, "Apply Mul and Gamma to vertex colours"); - uiDefButF(block, NUM, B_DIFF, "Mul:", 1061,30,112,19, &Gvp.mul, 0.1, 50.0, 10, 0, "Set the number to multiply vertex colours with"); - uiDefButF(block, NUM, B_DIFF, "Gamma:", 1174,30,102,19, &Gvp.gamma, 0.1, 5.0, 10, 0, "Change the clarity of the vertex colours"); + uiDefBut(block, BUT, B_VPGAMMA, "Set", 979,25,81,19, 0, 0, 0, 0, 0, "Apply Mul and Gamma to vertex colours"); + uiDefButF(block, NUM, B_DIFF, "Mul:", 1061,25,112,19, &Gvp.mul, 0.1, 50.0, 10, 0, "Set the number to multiply vertex colours with"); + uiDefButF(block, NUM, B_DIFF, "Gamma:", 1174,25,102,19, &Gvp.gamma, 0.1, 5.0, 10, 0, "Change the clarity of the vertex colours"); uiBlockEndAlign(block); - uiDefBut(block, BUT, B_SET_VCOL, "Set VertCol", 979,5,81,20, 0, 0, 0, 0, 0, "Set Vertex colour of selection to current (Shift+K)"); + uiDefBut(block, BUT, B_SET_VCOL, "Set VertCol", 979,0,81,20, 0, 0, 0, 0, 0, "Set Vertex colour of selection to current (Shift+K)"); } } diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 698fc4618a2..184c8abac0f 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -946,7 +946,6 @@ void load_editMesh(void) float *fp, *newkey, *oldkey, nor[3]; int i, a, ototvert, totedge=0; MDeformVert *dvert; - int usedDvert = 0; waitcursor(1); countall(); @@ -1014,7 +1013,7 @@ void load_editMesh(void) VecMulf(nor, 32767.0); VECCOPY(mvert->no, nor); - /* NEW VERSION */ + /* note: it used to remove me->dvert when it was not in use, cancelled that... annoying when you have a fresh vgroup */ if (dvert){ dvert->totweight=eve->totweight; if (eve->dw){ @@ -1022,7 +1021,6 @@ void load_editMesh(void) "deformWeight"); memcpy (dvert->dw, eve->dw, sizeof(MDeformWeight)*eve->totweight); - usedDvert++; } } @@ -1037,12 +1035,6 @@ void load_editMesh(void) mvert++; dvert++; } - - /* If we didn't actually need the dverts, get rid of them */ - if (!usedDvert){ - free_dverts(me->dvert, G.totvert); - me->dvert=NULL; - } /* the edges */ if(medge) { diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index 2fcd8995c6c..f0bf9a9003d 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -98,7 +98,8 @@ #define MAXINDEX 512000 -VPaint Gvp= {1.0, 1.0, 1.0, 0.2, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT}; +VPaint Gvp= {1.0, 1.0, 1.0, 0.2, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT+VP_SPRAY}; +VPaint Gwp= {1.0, 1.0, 1.0, 0.2, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT}; float vpimat[3][3]; unsigned int *vpaintundobuf= NULL; int totvpaintundo; @@ -554,31 +555,59 @@ static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac) return col; } -static void vpaint_blend( unsigned int *col, unsigned int paintcol, int alpha) +static void vpaint_blend( unsigned int *col, unsigned int *colorig, unsigned int paintcol, int alpha) { - + if(Gvp.mode==VP_MIX || Gvp.mode==VP_FILT) *col= mcol_blend( *col, paintcol, alpha); else if(Gvp.mode==VP_ADD) *col= mcol_add( *col, paintcol, alpha); else if(Gvp.mode==VP_SUB) *col= mcol_sub( *col, paintcol, alpha); else if(Gvp.mode==VP_MUL) *col= mcol_mul( *col, paintcol, alpha); + + /* if no spray, clip color adding with colorig & orig alpha */ + if((Gvp.flag & VP_SPRAY)==0) { + unsigned int testcol=0, a; + char *cp, *ct, *co; + + alpha= (int)(255.0*Gvp.a); + + if(Gvp.mode==VP_MIX || Gvp.mode==VP_FILT) testcol= mcol_blend( *colorig, paintcol, alpha); + else if(Gvp.mode==VP_ADD) testcol= mcol_add( *colorig, paintcol, alpha); + else if(Gvp.mode==VP_SUB) testcol= mcol_sub( *colorig, paintcol, alpha); + else if(Gvp.mode==VP_MUL) testcol= mcol_mul( *colorig, paintcol, alpha); + + cp= (char *)col; + ct= (char *)&testcol; + co= (char *)colorig; + + for(a=0; a<4; a++) { + if( ct[a]<co[a] ) { + if( cp[a]<ct[a] ) cp[a]= ct[a]; + else if( cp[a]>co[a] ) cp[a]= co[a]; + } + else { + if( cp[a]<co[a] ) cp[a]= co[a]; + else if( cp[a]>ct[a] ) cp[a]= ct[a]; + } + } + } } -static int sample_backbuf_area(int x, int y) +static int sample_backbuf_area(int x, int y, float size) { unsigned int rect[129*129], *rt; - int x1, y1, x2, y2, size, a, tot=0, index; + int x1, y1, x2, y2, a, tot=0, index; if(totvpaintundo>=MAXINDEX) return 0; - if(Gvp.size>64.0) Gvp.size= 64.0; + if(size>64.0) size= 64.0; - x1= x-Gvp.size; - x2= x+Gvp.size; + x1= x-size; + x2= x+size; CLAMP(x1, 0, curarea->winx); CLAMP(x2, 0, curarea->winx); - y1= y-Gvp.size; - y2= y+Gvp.size; + y1= y-size; + y2= y+size; CLAMP(y1, 0, curarea->winy); CLAMP(y2, 0, curarea->winy); #ifdef __APPLE__ @@ -587,7 +616,7 @@ static int sample_backbuf_area(int x, int y) glReadPixels(x1+curarea->winrct.xmin, y1+curarea->winrct.ymin, x2-x1+1, y2-y1+1, GL_RGBA, GL_UNSIGNED_BYTE, rect); glReadBuffer(GL_BACK); - if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr( (int)(4*Gvp.size*Gvp.size), rect); + if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr( (int)(4*size*size), rect); rt= rect; size= (y2-y1)*(x2-x1); @@ -633,14 +662,14 @@ static unsigned int sample_backbuf(int x, int y) return framebuffer_to_index(col); } -static int calc_vp_alpha_dl(DerivedMesh *dm, int vert, short *mval) +static int calc_vp_alpha_dl(VPaint *vp, DerivedMesh *dm, int vert, short *mval) { float co[3], no[3]; float fac, dx, dy; int alpha; short vertco[2]; - if(Gvp.flag & VP_SOFT) { + if(vp->flag & VP_SOFT) { dm->getVertCo(dm, vert, co); project_short_noclip(co, vertco); @@ -648,15 +677,15 @@ static int calc_vp_alpha_dl(DerivedMesh *dm, int vert, short *mval) dy= mval[1]-vertco[1]; fac= sqrt(dx*dx + dy*dy); - if(fac > Gvp.size) return 0; - - alpha= 255.0*Gvp.a*(1.0-fac/Gvp.size); + if(fac > vp->size) return 0; + + alpha= 255.0*vp->a*(1.0-fac/vp->size); } else { - alpha= 255.0*Gvp.a; + alpha= 255.0*vp->a; } - if(Gvp.flag & VP_NORMALS) { + if(vp->flag & VP_NORMALS) { dm->getVertNo(dm, vert, no); /* transpose ! */ @@ -674,8 +703,10 @@ static int calc_vp_alpha_dl(DerivedMesh *dm, int vert, short *mval) } -void wpaint_undo (void){ +void wpaint_undo (void) +{ Mesh *me; + MDeformVert *swapbuf; me = get_mesh(OBACT); if (!me) @@ -690,17 +721,27 @@ void wpaint_undo (void){ if (totwpaintundo != me->totvert) return; - free_dverts(me->dvert, me->totvert); + swapbuf= me->dvert; + /* copy undobuf to mesh */ me->dvert= MEM_mallocN(sizeof(MDeformVert)*me->totvert, "deformVert"); copy_dverts(me->dvert, wpaintundobuf, totwpaintundo); + + /* copy previous mesh to undo */ + free_dverts(wpaintundobuf, me->totvert); + wpaintundobuf= MEM_mallocN(sizeof(MDeformVert)*me->totvert, "wpaintundo"); + copy_dverts(wpaintundobuf, swapbuf, totwpaintundo); + + /* now free previous mesh dverts */ + free_dverts(swapbuf, me->totvert); DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); scrarea_do_windraw(curarea); } -void copy_wpaint_undo (MDeformVert *dverts, int dcount){ +void copy_wpaint_undo (MDeformVert *dverts, int dcount) +{ if (wpaintundobuf) free_dverts(wpaintundobuf, totwpaintundo); @@ -709,17 +750,65 @@ void copy_wpaint_undo (MDeformVert *dverts, int dcount){ copy_dverts (wpaintundobuf, dverts, dcount); } +static void wpaint_blend(MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval) +{ + + if(dw==NULL || uw==NULL) return; + + if(Gwp.mode==VP_MIX || Gwp.mode==VP_FILT) + dw->weight = paintval*alpha + dw->weight*(1.0-alpha); + else if(Gwp.mode==VP_ADD) + dw->weight += paintval*alpha; + else if(Gwp.mode==VP_SUB) + dw->weight -= paintval*alpha; + else if(Gwp.mode==VP_MUL) + /* first mul, then blend the fac */ + dw->weight = ((1.0-alpha) + alpha*paintval)*dw->weight; + + CLAMP(dw->weight, 0.0f, 1.0f); + + /* if no spray, clip result with orig weight & orig alpha */ + if((Gwp.flag & VP_SPRAY)==0) { + float testw=0.0f; + + alpha= Gwp.a; + + if(Gwp.mode==VP_MIX || Gwp.mode==VP_FILT) + testw = paintval*alpha + uw->weight*(1.0-alpha); + else if(Gwp.mode==VP_ADD) + testw = uw->weight + paintval*alpha; + else if(Gwp.mode==VP_SUB) + testw = uw->weight - paintval*alpha; + else if(Gwp.mode==VP_MUL) + /* first mul, then blend the fac */ + testw = ((1.0-alpha) + alpha*paintval)*uw->weight; + + CLAMP(testw, 0.0f, 1.0f); + + if( testw<uw->weight ) { + if(dw->weight < testw) dw->weight= testw; + else if(dw->weight > uw->weight) dw->weight= uw->weight; + } + else { + if(dw->weight > testw) dw->weight= testw; + else if(dw->weight < uw->weight) dw->weight= uw->weight; + } + } + +} + + void weight_paint(void) { + extern float editbutvweight; + MDeformWeight *dw, *uw; Object *ob; Mesh *me; MFace *mface; TFace *tface; - float mat[4][4], imat[4][4]; - int index, totindex; + float mat[4][4], imat[4][4], paintweight; + int index, totindex, alpha, totw; short mval[2], mvalo[2], firsttime=1, mousebut; - MDeformWeight *dw, *uw; - extern float editbutvweight; if((G.f & G_WEIGHTPAINT)==0) return; if(G.obedit) return; @@ -770,8 +859,8 @@ void weight_paint(void) firsttime= 0; /* which faces are involved */ - if(Gvp.flag & VP_AREA) { - totindex= sample_backbuf_area(mval[0], mval[1]); + if(Gwp.flag & VP_AREA) { + totindex= sample_backbuf_area(mval[0], mval[1], Gwp.size); } else { indexar[0]= sample_backbuf(mval[0], mval[1]); @@ -781,7 +870,7 @@ void weight_paint(void) MTC_Mat4SwapMat4(G.vd->persmat, mat); - if(Gvp.flag & VP_COLINDEX) { + if(Gwp.flag & VP_COLINDEX) { for(index=0; index<totindex; index++) { if(indexar[index] && indexar[index]<=me->totface) { @@ -807,35 +896,87 @@ void weight_paint(void) } } + /* make sure each vertex gets treated only once */ + /* and calculate filter weight */ + totw= 0; + if(Gwp.mode==VP_FILT) + paintweight= 0.0f; + else + paintweight= editbutvweight; + + for(index=0; index<totindex; index++) { + if(indexar[index] && indexar[index]<=me->totface) { + mface= me->mface + (indexar[index]-1); + + (me->dvert+mface->v1)->flag= 1; + (me->dvert+mface->v2)->flag= 1; + (me->dvert+mface->v3)->flag= 1; + if(mface->v4) (me->dvert+mface->v4)->flag= 1; + + if(Gwp.mode==VP_FILT) { + dw= verify_defweight(me->dvert+mface->v1, ob->actdef-1); + if(dw) {paintweight+= dw->weight; totw++;} + dw= verify_defweight(me->dvert+mface->v2, ob->actdef-1); + if(dw) {paintweight+= dw->weight; totw++;} + dw= verify_defweight(me->dvert+mface->v3, ob->actdef-1); + if(dw) {paintweight+= dw->weight; totw++;} + if(mface->v4) { + dw= verify_defweight(me->dvert+mface->v4, ob->actdef-1); + if(dw) {paintweight+= dw->weight; totw++;} + } + } + } + } + + if(Gwp.mode==VP_FILT) + paintweight/= (float)totw; + dm = mesh_get_derived_deform(ob, &needsFree); + for(index=0; index<totindex; index++) { if(indexar[index] && indexar[index]<=me->totface) { mface= me->mface + (indexar[index]-1); - if (calc_vp_alpha_dl(dm, mface->v1, mval)){ - dw= verify_defweight(me->dvert+mface->v1, ob->actdef-1); - uw= verify_defweight(wpaintundobuf+mface->v1, ob->actdef-1); - if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a)); + if((me->dvert+mface->v1)->flag) { + alpha= calc_vp_alpha_dl(&Gwp, dm, mface->v1, mval); + if(alpha) { + dw= verify_defweight(me->dvert+mface->v1, ob->actdef-1); + uw= verify_defweight(wpaintundobuf+mface->v1, ob->actdef-1); + wpaint_blend(dw, uw, (float)alpha/255.0, paintweight); + } + (me->dvert+mface->v1)->flag= 0; } - if (calc_vp_alpha_dl(dm, mface->v2, mval)){ - dw= verify_defweight(me->dvert+mface->v2, ob->actdef-1); - uw= verify_defweight(wpaintundobuf+mface->v2, ob->actdef-1); - if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a)); + if((me->dvert+mface->v2)->flag) { + alpha= calc_vp_alpha_dl(&Gwp, dm, mface->v2, mval); + if(alpha) { + dw= verify_defweight(me->dvert+mface->v2, ob->actdef-1); + uw= verify_defweight(wpaintundobuf+mface->v2, ob->actdef-1); + wpaint_blend(dw, uw, (float)alpha/255.0, paintweight); + } + (me->dvert+mface->v2)->flag= 0; } - if (calc_vp_alpha_dl(dm, mface->v3, mval)){ - dw= verify_defweight(me->dvert+mface->v3, ob->actdef-1); - uw= verify_defweight(wpaintundobuf+mface->v3, ob->actdef-1); - if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a)); + if((me->dvert+mface->v3)->flag) { + alpha= calc_vp_alpha_dl(&Gwp, dm, mface->v3, mval); + if(alpha) { + dw= verify_defweight(me->dvert+mface->v3, ob->actdef-1); + uw= verify_defweight(wpaintundobuf+mface->v3, ob->actdef-1); + wpaint_blend(dw, uw, (float)alpha/255.0, paintweight); + } + (me->dvert+mface->v3)->flag= 0; } - if(mface->v4) { - if (calc_vp_alpha_dl(dm, mface->v4, mval)){ - dw= verify_defweight(me->dvert+mface->v4, ob->actdef-1); - uw= verify_defweight(wpaintundobuf+mface->v4, ob->actdef-1); - if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a)); + if((me->dvert+mface->v4)->flag) { + if(mface->v4) { + alpha= calc_vp_alpha_dl(&Gwp, dm, mface->v4, mval); + if(alpha) { + dw= verify_defweight(me->dvert+mface->v4, ob->actdef-1); + uw= verify_defweight(wpaintundobuf+mface->v4, ob->actdef-1); + wpaint_blend(dw, uw, (float)alpha/255.0, paintweight); + } + (me->dvert+mface->v4)->flag= 0; } } } @@ -851,11 +992,13 @@ void weight_paint(void) if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { scrarea_do_windraw(curarea); - - /* draw circle in backbuf! */ - persp(PERSP_WIN); - fdrawXORcirc((float)mval[0], (float)mval[1], Gvp.size); - persp(PERSP_VIEW); + + if(Gwp.flag & (VP_AREA|VP_SOFT)) { + /* draw circle in backbuf! */ + persp(PERSP_WIN); + fdrawXORcirc((float)mval[0], (float)mval[1], Gwp.size); + persp(PERSP_VIEW); + } screen_swapbuffers(); backdrawview3d(0); @@ -885,8 +1028,8 @@ void vertex_paint() MFace *mface; TFace *tface; float mat[4][4], imat[4][4]; - unsigned int paintcol=0, *mcol, fcol1, fcol2; - int index, alpha, totindex, total; + unsigned int paintcol=0, *mcol, *mcolorig, fcol1, fcol2; + int index, alpha, totindex; short mval[2], mvalo[2], firsttime=1, mousebut; if((G.f & G_VERTEXPAINT)==0) return; @@ -941,7 +1084,7 @@ void vertex_paint() /* which faces are involved */ if(Gvp.flag & VP_AREA) { - totindex= sample_backbuf_area(mval[0], mval[1]); + totindex= sample_backbuf_area(mval[0], mval[1], Gvp.size); } else { indexar[0]= sample_backbuf(mval[0], mval[1]); @@ -982,7 +1125,8 @@ void vertex_paint() if(indexar[index] && indexar[index]<=me->totface) { mface= ((MFace *)me->mface) + (indexar[index]-1); - mcol= ( (unsigned int *)me->mcol) + 4*(indexar[index]-1); + mcol= ( (unsigned int *)me->mcol) + 4*(indexar[index]-1); + mcolorig= ( (unsigned int *)vpaintundobuf) + 4*(indexar[index]-1); if(Gvp.mode==VP_FILT) { fcol1= mcol_blend( mcol[0], mcol[1], 128); @@ -996,29 +1140,19 @@ void vertex_paint() } - total= 0; + alpha= calc_vp_alpha_dl(&Gvp, dm, mface->v1, mval); + if(alpha) vpaint_blend( mcol, mcolorig, paintcol, alpha); - total+= alpha= calc_vp_alpha_dl(dm, mface->v1, mval); - if(alpha) vpaint_blend( mcol, paintcol, alpha); - - total+= alpha= calc_vp_alpha_dl(dm, mface->v2, mval); - if(alpha) vpaint_blend( mcol+1, paintcol, alpha); + alpha= calc_vp_alpha_dl(&Gvp, dm, mface->v2, mval); + if(alpha) vpaint_blend( mcol+1, mcolorig+1, paintcol, alpha); - total+= alpha= calc_vp_alpha_dl(dm, mface->v3, mval); - if(alpha) vpaint_blend( mcol+2, paintcol, alpha); + alpha= calc_vp_alpha_dl(&Gvp, dm, mface->v3, mval); + if(alpha) vpaint_blend( mcol+2, mcolorig+2, paintcol, alpha); if(mface->v4) { - total+= alpha= calc_vp_alpha_dl(dm, mface->v4, mval); - if(alpha) vpaint_blend( mcol+3, paintcol, alpha); + alpha= calc_vp_alpha_dl(&Gvp, dm, mface->v4, mval); + if(alpha) vpaint_blend( mcol+3, mcolorig+3, paintcol, alpha); } - - /* if(total==0) { */ - /* alpha= 25*Gvp.a; */ - /* vpaint_blend( mcol, paintcol, alpha); */ - /* vpaint_blend( mcol+1, paintcol, alpha); */ - /* vpaint_blend( mcol+2, paintcol, alpha); */ - /* if(mface->v4) vpaint_blend( mcol+3, paintcol, alpha); */ - /* } */ } } if (needsFree) @@ -1033,11 +1167,12 @@ void vertex_paint() scrarea_do_windraw(curarea); - /* draw circle in backbuf! */ - persp(PERSP_WIN); - fdrawXORcirc((float)mval[0], (float)mval[1], Gvp.size); - persp(PERSP_VIEW); - + if(Gvp.flag & (VP_AREA|VP_SOFT)) { + /* draw circle in backbuf! */ + persp(PERSP_WIN); + fdrawXORcirc((float)mval[0], (float)mval[1], Gvp.size); + persp(PERSP_VIEW); + } screen_swapbuffers(); backdrawview3d(0); |