diff options
Diffstat (limited to 'source/blender/src/vpaint.c')
-rw-r--r-- | source/blender/src/vpaint.c | 1621 |
1 files changed, 0 insertions, 1621 deletions
diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c deleted file mode 100644 index 4e1c6cd59a6..00000000000 --- a/source/blender/src/vpaint.c +++ /dev/null @@ -1,1621 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - */ - -#include <math.h> -#include <string.h> - -#ifdef WIN32 -#include <io.h> -#else -#include <unistd.h> -#endif - -#include "MEM_guardedalloc.h" - -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -#include "MTC_matrixops.h" - -#include "DNA_action_types.h" -#include "DNA_armature_types.h" -#include "DNA_brush_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_modifier_types.h" -#include "DNA_object_types.h" -#include "DNA_object_force.h" -#include "DNA_screen_types.h" -#include "DNA_space_types.h" -#include "DNA_scene_types.h" -#include "DNA_view3d_types.h" -#include "DNA_userdef_types.h" - -#include "BKE_armature.h" -#include "BKE_DerivedMesh.h" -#include "BKE_customdata.h" -#include "BKE_depsgraph.h" -#include "BKE_deform.h" -#include "BKE_displist.h" -#include "BKE_global.h" -#include "BKE_mesh.h" -#include "BKE_modifier.h" -#include "BKE_object.h" -#include "BKE_utildefines.h" - -#include "BIF_editview.h" -#include "BIF_graphics.h" -#include "BIF_glutil.h" -#include "BIF_gl.h" -#include "BIF_interface.h" -#include "BIF_meshtools.h" -#include "BIF_mywindow.h" -#include "BIF_space.h" -#include "BIF_screen.h" -#include "BIF_toolbox.h" - -#include "BDR_vpaint.h" -#include "BDR_editobject.h" - -#include "BSE_drawview.h" -#include "BSE_trans_types.h" -#include "BSE_view.h" - -#include "multires.h" -#include "mydevice.h" -#include "blendef.h" - -#include "BIF_editdeform.h" - - /* Gvp.mode */ -#define VP_MIX 0 -#define VP_ADD 1 -#define VP_SUB 2 -#define VP_MUL 3 -#define VP_BLUR 4 -#define VP_LIGHTEN 5 -#define VP_DARKEN 6 - -#define MAXINDEX 512000 - -VPaint Gvp= {1.0, 1.0, 1.0, 0.2, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT+VP_SPRAY, 0}; -VPaint Gwp= {1.0, 1.0, 1.0, 1.0, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT, 0}; - -static int *get_indexarray(void) -{ - return MEM_mallocN(sizeof(int)*MAXINDEX + 2, "vertexpaint"); -} - -void free_vertexpaint() -{ - - if(Gvp.vpaint_prev) MEM_freeN(Gvp.vpaint_prev); - Gvp.vpaint_prev= NULL; - - mesh_octree_table(NULL, NULL, 'e'); -} - -/* in contradiction to cpack drawing colors, the MCOL colors (vpaint colors) are per byte! - so not endian sensitive. Mcol = ABGR!!! so be cautious with cpack calls */ - -unsigned int rgba_to_mcol(float r, float g, float b, float a) -{ - int ir, ig, ib, ia; - unsigned int col; - char *cp; - - ir= floor(255.0*r); - if(ir<0) ir= 0; else if(ir>255) ir= 255; - ig= floor(255.0*g); - if(ig<0) ig= 0; else if(ig>255) ig= 255; - ib= floor(255.0*b); - if(ib<0) ib= 0; else if(ib>255) ib= 255; - ia= floor(255.0*a); - if(ia<0) ia= 0; else if(ia>255) ia= 255; - - cp= (char *)&col; - cp[0]= ia; - cp[1]= ib; - cp[2]= ig; - cp[3]= ir; - - return col; - -} - -static unsigned int vpaint_get_current_col(VPaint *vp) -{ - return rgba_to_mcol(vp->r, vp->g, vp->b, 1.0f); -} - -void do_shared_vertexcol(Mesh *me) -{ - /* if no mcol: do not do */ - /* if tface: only the involved faces, otherwise all */ - MFace *mface; - MTFace *tface; - int a; - short *scolmain, *scol; - char *mcol; - - if(me->mcol==0 || me->totvert==0 || me->totface==0) return; - - scolmain= MEM_callocN(4*sizeof(short)*me->totvert, "colmain"); - - tface= me->mtface; - mface= me->mface; - mcol= (char *)me->mcol; - for(a=me->totface; a>0; a--, mface++, mcol+=16) { - if((tface && tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) { - scol= scolmain+4*mface->v1; - scol[0]++; scol[1]+= mcol[1]; scol[2]+= mcol[2]; scol[3]+= mcol[3]; - scol= scolmain+4*mface->v2; - scol[0]++; scol[1]+= mcol[5]; scol[2]+= mcol[6]; scol[3]+= mcol[7]; - scol= scolmain+4*mface->v3; - scol[0]++; scol[1]+= mcol[9]; scol[2]+= mcol[10]; scol[3]+= mcol[11]; - if(mface->v4) { - scol= scolmain+4*mface->v4; - scol[0]++; scol[1]+= mcol[13]; scol[2]+= mcol[14]; scol[3]+= mcol[15]; - } - } - if(tface) tface++; - } - - a= me->totvert; - scol= scolmain; - while(a--) { - if(scol[0]>1) { - scol[1]/= scol[0]; - scol[2]/= scol[0]; - scol[3]/= scol[0]; - } - scol+= 4; - } - - tface= me->mtface; - mface= me->mface; - mcol= (char *)me->mcol; - for(a=me->totface; a>0; a--, mface++, mcol+=16) { - if((tface && tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) { - scol= scolmain+4*mface->v1; - mcol[1]= scol[1]; mcol[2]= scol[2]; mcol[3]= scol[3]; - scol= scolmain+4*mface->v2; - mcol[5]= scol[1]; mcol[6]= scol[2]; mcol[7]= scol[3]; - scol= scolmain+4*mface->v3; - mcol[9]= scol[1]; mcol[10]= scol[2]; mcol[11]= scol[3]; - if(mface->v4) { - scol= scolmain+4*mface->v4; - mcol[13]= scol[1]; mcol[14]= scol[2]; mcol[15]= scol[3]; - } - } - if(tface) tface++; - } - - MEM_freeN(scolmain); -} - -void make_vertexcol(int shade) /* single ob */ -{ - Object *ob; - Mesh *me; - - if(G.obedit) { - error("Unable to perform function in Edit Mode"); - return; - } - - ob= OBACT; - if(!ob || ob->id.lib) return; - me= get_mesh(ob); - if(me==0) return; - - /* copies from shadedisplist to mcol */ - if(!me->mcol) { - CustomData_add_layer(&me->fdata, CD_MCOL, CD_CALLOC, NULL, me->totface); - mesh_update_customdata_pointers(me); - } - - if(shade) - shadeMeshMCol(ob, me); - else - memset(me->mcol, 255, 4*sizeof(MCol)*me->totface); - - if (me->mr) multires_load_cols(me); - - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - - allqueue(REDRAWBUTSEDIT, 0); - allqueue(REDRAWVIEW3D, 0); -} - -static void copy_vpaint_prev(VPaint *vp, unsigned int *mcol, int tot) -{ - if(vp->vpaint_prev) { - MEM_freeN(vp->vpaint_prev); - vp->vpaint_prev= NULL; - } - vp->tot= tot; - - if(mcol==NULL || tot==0) return; - - vp->vpaint_prev= MEM_mallocN(4*sizeof(int)*tot, "vpaint_prev"); - memcpy(vp->vpaint_prev, mcol, 4*sizeof(int)*tot); - -} - -static void copy_wpaint_prev (VPaint *vp, MDeformVert *dverts, int dcount) -{ - if (vp->wpaint_prev) { - free_dverts(vp->wpaint_prev, vp->tot); - vp->wpaint_prev= NULL; - } - - if(dverts && dcount) { - - vp->wpaint_prev = MEM_mallocN (sizeof(MDeformVert)*dcount, "wpaint prev"); - vp->tot = dcount; - copy_dverts (vp->wpaint_prev, dverts, dcount); - } -} - - -void clear_vpaint() -{ - Mesh *me; - Object *ob; - unsigned int *to, paintcol; - int a; - - if((G.f & G_VERTEXPAINT)==0) return; - - ob= OBACT; - me= get_mesh(ob); - if(!ob || ob->id.lib) return; - - if(me==0 || me->mcol==0 || me->totface==0) return; - - paintcol= vpaint_get_current_col(&Gvp); - - to= (unsigned int *)me->mcol; - a= 4*me->totface; - while(a--) { - *to= paintcol; - to++; - } - BIF_undo_push("Clear vertex colors"); - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - - allqueue(REDRAWVIEW3D, 0); -} - -void clear_vpaint_selectedfaces() -{ - Mesh *me; - MFace *mf; - Object *ob; - unsigned int paintcol, *mcol; - int i; - - ob= OBACT; - me= get_mesh(ob); - if(me==0 || me->totface==0) return; - - if(!me->mcol) - make_vertexcol(0); - - paintcol= vpaint_get_current_col(&Gvp); - - mf = me->mface; - mcol = (unsigned int*)me->mcol; - for (i = 0; i < me->totface; i++, mf++, mcol+=4) { - if (mf->flag & ME_FACE_SEL) { - mcol[0] = paintcol; - mcol[1] = paintcol; - mcol[2] = paintcol; - mcol[3] = paintcol; - } - } - - BIF_undo_push("Clear vertex colors"); - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - allqueue(REDRAWVIEW3D, 0); -} - - -/* fills in the selected faces with the current weight and vertex group */ -void clear_wpaint_selectedfaces() -{ - extern float editbutvweight; - float paintweight= editbutvweight; - Mesh *me; - MFace *mface; - Object *ob; - MDeformWeight *dw, *uw; - int *indexar; - int index, vgroup; - unsigned int faceverts[5]={0,0,0,0,0}; - unsigned char i; - int vgroup_mirror= -1; - - ob= OBACT; - me= ob->data; - if(me==0 || me->totface==0 || me->dvert==0 || !me->mface) return; - - indexar= get_indexarray(); - for(index=0, mface=me->mface; index<me->totface; index++, mface++) { - if((mface->flag & ME_FACE_SEL)==0) - indexar[index]= 0; - else - indexar[index]= index+1; - } - - vgroup= ob->actdef-1; - - /* directly copied from weight_paint, should probaby split into a seperate function */ - /* if mirror painting, find the other group */ - if(Gwp.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) - vgroup_mirror= actdef; - } - } - /* end copy from weight_paint*/ - - copy_wpaint_prev(&Gwp, me->dvert, me->totvert); - - for(index=0; index<me->totface; index++) { - if(indexar[index] && indexar[index]<=me->totface) { - mface= me->mface + (indexar[index]-1); - /* just so we can loop through the verts */ - faceverts[0]= mface->v1; - faceverts[1]= mface->v2; - faceverts[2]= mface->v3; - faceverts[3]= mface->v4; - for (i=0; i<3 || faceverts[i]; i++) { - if(!((me->dvert+faceverts[i])->flag)) { - dw= verify_defweight(me->dvert+faceverts[i], vgroup); - if(dw) { - uw= verify_defweight(Gwp.wpaint_prev+faceverts[i], vgroup); - uw->weight= dw->weight; /* set the undio weight */ - dw->weight= paintweight; - - if(Gwp.flag & VP_MIRROR_X) { /* x mirror painting */ - int j= mesh_get_x_mirror_vert(ob, faceverts[i]); - if(j>=0) { - /* copy, not paint again */ - if(vgroup_mirror != -1) { - dw= verify_defweight(me->dvert+j, vgroup_mirror); - uw= verify_defweight(Gwp.wpaint_prev+j, vgroup_mirror); - } else { - dw= verify_defweight(me->dvert+j, vgroup); - uw= verify_defweight(Gwp.wpaint_prev+j, vgroup); - } - uw->weight= dw->weight; /* set the undo weight */ - dw->weight= paintweight; - } - } - } - (me->dvert+faceverts[i])->flag= 1; - } - } - } - } - - index=0; - while (index<me->totvert) { - (me->dvert+index)->flag= 0; - index++; - } - - MEM_freeN(indexar); - copy_wpaint_prev(&Gwp, NULL, 0); - - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - BIF_undo_push("Set vertex weight"); - allqueue(REDRAWVIEW3D, 0); -} - - -void vpaint_dogamma() -{ - Mesh *me; - Object *ob; - float igam, fac; - int a, temp; - char *cp, gamtab[256]; - - if((G.f & G_VERTEXPAINT)==0) return; - - ob= OBACT; - me= get_mesh(ob); - if(me==0 || me->mcol==0 || me->totface==0) return; - - igam= 1.0/Gvp.gamma; - for(a=0; a<256; a++) { - - fac= ((float)a)/255.0; - fac= Gvp.mul*pow( fac, igam); - - temp= 255.9*fac; - - if(temp<=0) gamtab[a]= 0; - else if(temp>=255) gamtab[a]= 255; - else gamtab[a]= temp; - } - - a= 4*me->totface; - cp= (char *)me->mcol; - while(a--) { - - cp[1]= gamtab[ cp[1] ]; - cp[2]= gamtab[ cp[2] ]; - cp[3]= gamtab[ cp[3] ]; - - cp+= 4; - } - allqueue(REDRAWVIEW3D, 0); -} - -/* used for both 3d view and image window */ -void sample_vpaint() /* frontbuf */ -{ - unsigned int col; - int x, y; - short mval[2]; - char *cp; - - getmouseco_areawin(mval); - x= mval[0]; y= mval[1]; - - if(x<0 || y<0) return; - if(x>=curarea->winx || y>=curarea->winy) return; - - x+= curarea->winrct.xmin; - y+= curarea->winrct.ymin; - - glReadBuffer(GL_FRONT); - glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); - glReadBuffer(GL_BACK); - - cp = (char *)&col; - - if(G.f & (G_VERTEXPAINT|G_WEIGHTPAINT)) { - Gvp.r= cp[0]/255.0f; - Gvp.g= cp[1]/255.0f; - Gvp.b= cp[2]/255.0f; - } - else { - Brush *brush= G.scene->toolsettings->imapaint.brush; - - if(brush) { - brush->rgb[0]= cp[0]/255.0f; - brush->rgb[1]= cp[1]/255.0f; - brush->rgb[2]= cp[2]/255.0f; - - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWIMAGE, 0); - } - } - - allqueue(REDRAWBUTSEDIT, 0); - addqueue(curarea->win, REDRAW, 1); /* needed for when panel is open... */ -} - -static unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac) -{ - char *cp1, *cp2, *cp; - int mfac; - unsigned int col=0; - - if(fac==0) return col1; - if(fac>=255) return col2; - - mfac= 255-fac; - - cp1= (char *)&col1; - cp2= (char *)&col2; - cp= (char *)&col; - - cp[0]= 255; - cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8; - cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8; - cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8; - - return col; -} - -static unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac) -{ - char *cp1, *cp2, *cp; - int temp; - unsigned int col=0; - - if(fac==0) return col1; - - cp1= (char *)&col1; - cp2= (char *)&col2; - cp= (char *)&col; - - cp[0]= 255; - temp= cp1[1] + ((fac*cp2[1])>>8); - if(temp>254) cp[1]= 255; else cp[1]= temp; - temp= cp1[2] + ((fac*cp2[2])>>8); - if(temp>254) cp[2]= 255; else cp[2]= temp; - temp= cp1[3] + ((fac*cp2[3])>>8); - if(temp>254) cp[3]= 255; else cp[3]= temp; - - return col; -} - -static unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac) -{ - char *cp1, *cp2, *cp; - int temp; - unsigned int col=0; - - if(fac==0) return col1; - - cp1= (char *)&col1; - cp2= (char *)&col2; - cp= (char *)&col; - - cp[0]= 255; - temp= cp1[1] - ((fac*cp2[1])>>8); - if(temp<0) cp[1]= 0; else cp[1]= temp; - temp= cp1[2] - ((fac*cp2[2])>>8); - if(temp<0) cp[2]= 0; else cp[2]= temp; - temp= cp1[3] - ((fac*cp2[3])>>8); - if(temp<0) cp[3]= 0; else cp[3]= temp; - - return col; -} - -static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac) -{ - char *cp1, *cp2, *cp; - int mfac; - unsigned int col=0; - - if(fac==0) return col1; - - mfac= 255-fac; - - cp1= (char *)&col1; - cp2= (char *)&col2; - cp= (char *)&col; - - /* first mul, then blend the fac */ - cp[0]= 255; - cp[1]= (mfac*cp1[1] + fac*((cp2[1]*cp1[1])>>8) )>>8; - cp[2]= (mfac*cp1[2] + fac*((cp2[2]*cp1[2])>>8) )>>8; - cp[3]= (mfac*cp1[3] + fac*((cp2[3]*cp1[3])>>8) )>>8; - - - return col; -} - -static unsigned int mcol_lighten(unsigned int col1, unsigned int col2, int fac) -{ - char *cp1, *cp2, *cp; - int mfac; - unsigned int col=0; - - if(fac==0) return col1; - if(fac>=255) return col2; - - mfac= 255-fac; - - cp1= (char *)&col1; - cp2= (char *)&col2; - cp= (char *)&col; - - /* See if are lighter, if so mix, else dont do anything. - if the paint col is darker then the original, then ignore */ - if (cp1[1]+cp1[2]+cp1[3] > cp2[1]+cp2[2]+cp2[3]) - return col1; - - cp[0]= 255; - cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8; - cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8; - cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8; - - return col; -} - -static unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac) -{ - char *cp1, *cp2, *cp; - int mfac; - unsigned int col=0; - - if(fac==0) return col1; - if(fac>=255) return col2; - - mfac= 255-fac; - - cp1= (char *)&col1; - cp2= (char *)&col2; - cp= (char *)&col; - - /* See if were darker, if so mix, else dont do anything. - if the paint col is brighter then the original, then ignore */ - if (cp1[1]+cp1[2]+cp1[3] < cp2[1]+cp2[2]+cp2[3]) - return col1; - - cp[0]= 255; - cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8; - cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8; - cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8; - return col; -} - -static void vpaint_blend( unsigned int *col, unsigned int *colorig, unsigned int paintcol, int alpha) -{ - - if(Gvp.mode==VP_MIX || Gvp.mode==VP_BLUR) *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); - else if(Gvp.mode==VP_LIGHTEN) *col= mcol_lighten( *col, paintcol, alpha); - else if(Gvp.mode==VP_DARKEN) *col= mcol_darken( *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_BLUR) 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); - else if(Gvp.mode==VP_LIGHTEN) testcol= mcol_lighten( *colorig, paintcol, alpha); - else if(Gvp.mode==VP_DARKEN) testcol= mcol_darken( *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(VPaint *vp, int *indexar, int totface, int x, int y, float size) -{ - unsigned int *rt; - struct ImBuf *ibuf; - int x1, y1, x2, y2, a, tot=0, index; - - if(totface>=MAXINDEX) return 0; - - if(size>64.0) size= 64.0; - - x1= x-size; - x2= x+size; - CLAMP(x1, 0, curarea->winx-1); - CLAMP(x2, 0, curarea->winx-1); - y1= y-size; - y2= y+size; - CLAMP(y1, 0, curarea->winy-1); - CLAMP(y2, 0, curarea->winy-1); -#ifdef __APPLE__ - glReadBuffer(GL_AUX0); -#endif - - if(x1>=x2 || y1>=y2) return 0; - - ibuf = IMB_allocImBuf(2*size + 4, 2*size + 4, 32, IB_rect, 0); - glReadPixels(x1+curarea->winrct.xmin, y1+curarea->winrct.ymin, x2-x1+1, y2-y1+1, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); - glReadBuffer(GL_BACK); - - if(G.order==B_ENDIAN) { - IMB_convert_rgba_to_abgr(ibuf); - } - - rt= ibuf->rect; - size= (y2-y1)*(x2-x1); - if(size<=0) return 0; - - memset(indexar, 0, sizeof(int)*totface+2); /* plus 2! first element is total */ - - while(size--) { - - if(*rt) { - index= framebuffer_to_index(*rt); - if(index>0 && index<=totface) - indexar[index] = 1; - } - - rt++; - } - - for(a=1; a<=totface; a++) { - if(indexar[a]) indexar[tot++]= a; - } - - IMB_freeImBuf(ibuf); - - return tot; -} - -static int calc_vp_alpha_dl(VPaint *vp, float vpimat[][3], float *vert_nor, short *mval) -{ - float fac, dx, dy; - int alpha; - short vertco[2]; - - if(vp->flag & VP_SOFT) { - project_short_noclip(vert_nor, vertco); - dx= mval[0]-vertco[0]; - dy= mval[1]-vertco[1]; - - fac= sqrt(dx*dx + dy*dy); - if(fac > vp->size) return 0; - if(vp->flag & VP_HARD) - alpha= 255; - else - alpha= 255.0*vp->a*(1.0-fac/vp->size); - } - else { - alpha= 255.0*vp->a; - } - - if(vp->flag & VP_NORMALS) { - float *no= vert_nor+3; - - /* transpose ! */ - fac= vpimat[2][0]*no[0]+vpimat[2][1]*no[1]+vpimat[2][2]*no[2]; - if(fac>0.0) { - dx= vpimat[0][0]*no[0]+vpimat[0][1]*no[1]+vpimat[0][2]*no[2]; - dy= vpimat[1][0]*no[0]+vpimat[1][1]*no[1]+vpimat[1][2]*no[2]; - - alpha*= fac/sqrt(dx*dx + dy*dy + fac*fac); - } - else return 0; - } - - return alpha; -} - -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_BLUR) - 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; - else if(Gwp.mode==VP_LIGHTEN) { - if (dw->weight < paintval) - dw->weight = paintval*alpha + dw->weight*(1.0-alpha); - } else if(Gwp.mode==VP_DARKEN) { - if (dw->weight > paintval) - dw->weight = paintval*alpha + dw->weight*(1.0-alpha); - } - 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_BLUR) - 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; - else if(Gwp.mode==VP_LIGHTEN) { - if (uw->weight < paintval) - testw = paintval*alpha + uw->weight*(1.0-alpha); - else - testw = uw->weight; - } else if(Gwp.mode==VP_DARKEN) { - if (uw->weight > paintval) - testw = paintval*alpha + uw->weight*(1.0-alpha); - else - testw = 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; - } - } - -} - -/* ----------------------------------------------------- */ - -/* used for 3d view, on active object, assumes me->dvert exists */ -/* if mode==1: */ -/* samples cursor location, and gives menu with vertex groups to activate */ -/* else */ -/* sets editbutvweight to the closest weight value to vertex */ -/* note: we cant sample frontbuf, weight colors are interpolated too unpredictable */ -static void sample_wpaint(int mode) -{ - Object *ob= OBACT; - Mesh *me= get_mesh(ob); - int index; - short mval[2], sco[2]; - - if (!me) return; - - getmouseco_areawin(mval); - index= sample_backbuf(mval[0], mval[1]); - - if(index && index<=me->totface) { - MFace *mface; - - mface= ((MFace *)me->mface) + index-1; - - if(mode==1) { /* sampe which groups are in here */ - MDeformVert *dv; - int a, totgroup; - - totgroup= BLI_countlist(&ob->defbase); - if(totgroup) { - int totmenu=0; - int *groups=MEM_callocN(totgroup*sizeof(int), "groups"); - - dv= me->dvert+mface->v1; - for(a=0; a<dv->totweight; a++) { - if (dv->dw[a].def_nr<totgroup) - groups[dv->dw[a].def_nr]= 1; - } - dv= me->dvert+mface->v2; - for(a=0; a<dv->totweight; a++) { - if (dv->dw[a].def_nr<totgroup) - groups[dv->dw[a].def_nr]= 1; - } - dv= me->dvert+mface->v3; - for(a=0; a<dv->totweight; a++) { - if (dv->dw[a].def_nr<totgroup) - groups[dv->dw[a].def_nr]= 1; - } - if(mface->v4) { - dv= me->dvert+mface->v4; - for(a=0; a<dv->totweight; a++) { - if (dv->dw[a].def_nr<totgroup) - groups[dv->dw[a].def_nr]= 1; - } - } - for(a=0; a<totgroup; a++) - if(groups[a]) totmenu++; - - if(totmenu==0) { - notice("No Vertex Group Selected"); - } - else { - bDeformGroup *dg; - short val; - char item[40], *str= MEM_mallocN(40*totmenu+40, "menu"); - - strcpy(str, "Vertex Groups %t"); - for(a=0, dg=ob->defbase.first; dg && a<totgroup; a++, dg= dg->next) { - if(groups[a]) { - sprintf(item, "|%s %%x%d", dg->name, a); - strcat(str, item); - } - } - - val= pupmenu(str); - if(val>=0) { - ob->actdef= val+1; - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWOOPS, 0); - allqueue(REDRAWBUTSEDIT, 0); - } - MEM_freeN(str); - } - MEM_freeN(groups); - } - else notice("No Vertex Groups in Object"); - } - else { - DerivedMesh *dm; - MDeformWeight *dw; - extern float editbutvweight; - float w1, w2, w3, w4, co[3], fac; - - dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH); - if(dm->getVertCo==NULL) { - notice("Not supported yet"); - } - else { - /* calc 3 or 4 corner weights */ - dm->getVertCo(dm, mface->v1, co); - project_short_noclip(co, sco); - w1= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1])); - - dm->getVertCo(dm, mface->v2, co); - project_short_noclip(co, sco); - w2= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1])); - - dm->getVertCo(dm, mface->v3, co); - project_short_noclip(co, sco); - w3= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1])); - - if(mface->v4) { - dm->getVertCo(dm, mface->v4, co); - project_short_noclip(co, sco); - w4= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1])); - } - else w4= 1.0e10; - - fac= MIN4(w1, w2, w3, w4); - if(w1==fac) { - dw= get_defweight(me->dvert+mface->v1, ob->actdef-1); - if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f; - } - else if(w2==fac) { - dw= get_defweight(me->dvert+mface->v2, ob->actdef-1); - if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f; - } - else if(w3==fac) { - dw= get_defweight(me->dvert+mface->v3, ob->actdef-1); - if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f; - } - else if(w4==fac) { - if(mface->v4) { - dw= get_defweight(me->dvert+mface->v4, ob->actdef-1); - if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f; - } - } - } - dm->release(dm); - } - - } - allqueue(REDRAWBUTSEDIT, 0); - -} - -static void do_weight_paint_vertex(Object *ob, int index, int alpha, float paintweight, int vgroup_mirror) -{ - Mesh *me= ob->data; - MDeformWeight *dw, *uw; - int vgroup= ob->actdef-1; - - if(Gwp.flag & VP_ONLYVGROUP) { - dw= get_defweight(me->dvert+index, vgroup); - uw= get_defweight(Gwp.wpaint_prev+index, vgroup); - } - else { - dw= verify_defweight(me->dvert+index, vgroup); - uw= verify_defweight(Gwp.wpaint_prev+index, vgroup); - } - if(dw==NULL || uw==NULL) - return; - - wpaint_blend(dw, uw, (float)alpha/255.0, paintweight); - - if(Gwp.flag & VP_MIRROR_X) { /* x mirror painting */ - int j= mesh_get_x_mirror_vert(ob, index); - if(j>=0) { - /* copy, not paint again */ - if(vgroup_mirror != -1) - uw= verify_defweight(me->dvert+j, vgroup_mirror); - else - uw= verify_defweight(me->dvert+j, vgroup); - - uw->weight= dw->weight; - } - } -} - -void weight_paint(void) -{ - extern float editbutvweight; - Object *ob; - Mesh *me; - MFace *mface; - float mat[4][4], imat[4][4], paintweight, *vertexcosnos; - float vpimat[3][3]; - int *indexar, index, totindex, alpha, totw; - int vgroup_mirror= -1; - short mval[2], mvalo[2], firsttime=1; - - if((G.f & G_WEIGHTPAINT)==0) return; - if(G.obedit) return; - if(multires_level1_test()) return; - - ob= OBACT; - if(!ob || ob->id.lib) return; - - me= get_mesh(ob); - if(me==NULL || me->totface==0) return; - - /* if nothing was added yet, we make dverts and a vertex deform group */ - if (!me->dvert) - create_dverts(&me->id); - - if(G.qual & LR_CTRLKEY) { - sample_wpaint(0); - return; - } - if(G.qual & LR_SHIFTKEY) { - sample_wpaint(1); - return; - } - - /* ALLOCATIONS! no return after this line */ - /* painting on subsurfs should give correct points too, this returns me->totvert amount */ - vertexcosnos= mesh_get_mapped_verts_nors(ob); - indexar= get_indexarray(); - copy_wpaint_prev(&Gwp, 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); - allqueue(REDRAWBUTSEDIT, 0); - } - } - } - if(ob->defbase.first==NULL) { - add_defgroup(ob); - allqueue(REDRAWBUTSEDIT, 0); - } - - if(ob->lay & G.vd->lay); else error("Active object is not in this layer"); - - persp(PERSP_VIEW); - /* imat for normals */ - Mat4MulMat4(mat, ob->obmat, G.vd->viewmat); - Mat4Invert(imat, mat); - Mat3CpyMat4(vpimat, imat); - - /* load projection matrix */ - mymultmatrix(ob->obmat); - mygetsingmatrix(mat); - myloadmatrix(G.vd->viewmat); - - getmouseco_areawin(mvalo); - - getmouseco_areawin(mval); - mvalo[0]= mval[0]; - mvalo[1]= mval[1]; - - /* if mirror painting, find the other group */ - if(Gwp.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) - vgroup_mirror= actdef; - } - } - - while (get_mbut() & L_MOUSE) { - getmouseco_areawin(mval); - - if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { - firsttime= 0; - - /* which faces are involved */ - if(Gwp.flag & VP_AREA) { - totindex= sample_backbuf_area(&Gwp, indexar, me->totface, mval[0], mval[1], Gwp.size); - } - else { - indexar[0]= sample_backbuf(mval[0], mval[1]); - if(indexar[0]) totindex= 1; - else totindex= 0; - } - - MTC_Mat4SwapMat4(G.vd->persmat, mat); - - if(Gwp.flag & VP_COLINDEX) { - for(index=0; index<totindex; index++) { - if(indexar[index] && indexar[index]<=me->totface) { - - mface= ((MFace *)me->mface) + (indexar[index]-1); - - if(mface->mat_nr!=ob->actcol-1) { - indexar[index]= 0; - } - } - } - } - - if((G.f & G_FACESELECT) && me->mface) { - for(index=0; index<totindex; index++) { - if(indexar[index] && indexar[index]<=me->totface) { - - mface= ((MFace *)me->mface) + (indexar[index]-1); - - if((mface->flag & ME_FACE_SEL)==0) { - indexar[index]= 0; - } - } - } - } - - /* make sure each vertex gets treated only once */ - /* and calculate filter weight */ - totw= 0; - if(Gwp.mode==VP_BLUR) - 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_BLUR) { - MDeformWeight *dw, *(*dw_func)(MDeformVert *, int) = verify_defweight; - - if(Gwp.flag & VP_ONLYVGROUP) - dw_func= get_defweight; - - dw= dw_func(me->dvert+mface->v1, ob->actdef-1); - if(dw) {paintweight+= dw->weight; totw++;} - dw= dw_func(me->dvert+mface->v2, ob->actdef-1); - if(dw) {paintweight+= dw->weight; totw++;} - dw= dw_func(me->dvert+mface->v3, ob->actdef-1); - if(dw) {paintweight+= dw->weight; totw++;} - if(mface->v4) { - dw= dw_func(me->dvert+mface->v4, ob->actdef-1); - if(dw) {paintweight+= dw->weight; totw++;} - } - } - } - } - - if(Gwp.mode==VP_BLUR) - paintweight/= (float)totw; - - for(index=0; index<totindex; index++) { - - if(indexar[index] && indexar[index]<=me->totface) { - mface= me->mface + (indexar[index]-1); - - if((me->dvert+mface->v1)->flag) { - alpha= calc_vp_alpha_dl(&Gwp, vpimat, vertexcosnos+6*mface->v1, mval); - if(alpha) { - do_weight_paint_vertex(ob, mface->v1, alpha, paintweight, vgroup_mirror); - } - (me->dvert+mface->v1)->flag= 0; - } - - if((me->dvert+mface->v2)->flag) { - alpha= calc_vp_alpha_dl(&Gwp, vpimat, vertexcosnos+6*mface->v2, mval); - if(alpha) { - do_weight_paint_vertex(ob, mface->v2, alpha, paintweight, vgroup_mirror); - } - (me->dvert+mface->v2)->flag= 0; - } - - if((me->dvert+mface->v3)->flag) { - alpha= calc_vp_alpha_dl(&Gwp, vpimat, vertexcosnos+6*mface->v3, mval); - if(alpha) { - do_weight_paint_vertex(ob, mface->v3, alpha, paintweight, vgroup_mirror); - } - (me->dvert+mface->v3)->flag= 0; - } - - if((me->dvert+mface->v4)->flag) { - if(mface->v4) { - alpha= calc_vp_alpha_dl(&Gwp, vpimat, vertexcosnos+6*mface->v4, mval); - if(alpha) { - do_weight_paint_vertex(ob, mface->v4, alpha, paintweight, vgroup_mirror); - } - (me->dvert+mface->v4)->flag= 0; - } - } - } - } - - MTC_Mat4SwapMat4(G.vd->persmat, mat); - - } - else BIF_wait_for_statechange(); - - if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { - - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - scrarea_do_windraw(curarea); - - 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); - - mvalo[0]= mval[0]; - mvalo[1]= mval[1]; - } - } - - if(vertexcosnos) - MEM_freeN(vertexcosnos); - MEM_freeN(indexar); - copy_wpaint_prev(&Gwp, NULL, 0); - - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - /* this flag is event for softbody to refresh weightpaint values */ - if(ob->soft) ob->softflag |= OB_SB_REDO; - - BIF_undo_push("Weight Paint"); - allqueue(REDRAWVIEW3D, 0); -} - -void vertex_paint() -{ - Object *ob; - Mesh *me; - MFace *mface; - float mat[4][4], imat[4][4], *vertexcosnos; - float vpimat[3][3]; - unsigned int paintcol=0, *mcol, *mcolorig, fcol1, fcol2; - int *indexar, index, alpha, totindex; - short mval[2], mvalo[2], firsttime=1; - - if((G.f & G_VERTEXPAINT)==0) return; - if(G.obedit) return; - - ob= OBACT; - if(!ob || ob->id.lib) return; - - me= get_mesh(ob); - if(me==NULL || me->totface==0) return; - if(ob->lay & G.vd->lay); else error("Active object is not in this layer"); - - if(me->mcol==NULL) make_vertexcol(1); - - if(me->mcol==NULL) return; - - /* ALLOCATIONS! No return after his line */ - - /* painting on subsurfs should give correct points too, this returns me->totvert amount */ - vertexcosnos= mesh_get_mapped_verts_nors(ob); - indexar= get_indexarray(); - copy_vpaint_prev(&Gvp, (unsigned int *)me->mcol, me->totface); - - /* opengl/matrix stuff */ - persp(PERSP_VIEW); - /* imat for normals */ - Mat4MulMat4(mat, ob->obmat, G.vd->viewmat); - Mat4Invert(imat, mat); - Mat3CpyMat4(vpimat, imat); - - /* load projection matrix */ - mymultmatrix(ob->obmat); - mygetsingmatrix(mat); - myloadmatrix(G.vd->viewmat); - - paintcol= vpaint_get_current_col(&Gvp); - - getmouseco_areawin(mvalo); - - getmouseco_areawin(mval); - mvalo[0]= mval[0]; - mvalo[1]= mval[1]; - - while (get_mbut() & L_MOUSE) { - getmouseco_areawin(mval); - - if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { - - firsttime= 0; - - /* which faces are involved */ - if(Gvp.flag & VP_AREA) { - totindex= sample_backbuf_area(&Gvp, indexar, me->totface, mval[0], mval[1], Gvp.size); - } - else { - indexar[0]= sample_backbuf(mval[0], mval[1]); - if(indexar[0]) totindex= 1; - else totindex= 0; - } - - MTC_Mat4SwapMat4(G.vd->persmat, mat); - - if(Gvp.flag & VP_COLINDEX) { - for(index=0; index<totindex; index++) { - if(indexar[index] && indexar[index]<=me->totface) { - - mface= ((MFace *)me->mface) + (indexar[index]-1); - - if(mface->mat_nr!=ob->actcol-1) { - indexar[index]= 0; - } - } - } - } - if((G.f & G_FACESELECT) && me->mface) { - for(index=0; index<totindex; index++) { - if(indexar[index] && indexar[index]<=me->totface) { - mface= ((MFace *)me->mface) + (indexar[index]-1); - - if((mface->flag & ME_FACE_SEL)==0) - indexar[index]= 0; - } - } - } - - for(index=0; index<totindex; index++) { - - if(indexar[index] && indexar[index]<=me->totface) { - - mface= ((MFace *)me->mface) + (indexar[index]-1); - mcol= ( (unsigned int *)me->mcol) + 4*(indexar[index]-1); - mcolorig= ( (unsigned int *)Gvp.vpaint_prev) + 4*(indexar[index]-1); - - if(Gvp.mode==VP_BLUR) { - fcol1= mcol_blend( mcol[0], mcol[1], 128); - if(mface->v4) { - fcol2= mcol_blend( mcol[2], mcol[3], 128); - paintcol= mcol_blend( fcol1, fcol2, 128); - } - else { - paintcol= mcol_blend( mcol[2], fcol1, 170); - } - - } - - alpha= calc_vp_alpha_dl(&Gvp, vpimat, vertexcosnos+6*mface->v1, mval); - if(alpha) vpaint_blend( mcol, mcolorig, paintcol, alpha); - - alpha= calc_vp_alpha_dl(&Gvp, vpimat, vertexcosnos+6*mface->v2, mval); - if(alpha) vpaint_blend( mcol+1, mcolorig+1, paintcol, alpha); - - alpha= calc_vp_alpha_dl(&Gvp, vpimat, vertexcosnos+6*mface->v3, mval); - if(alpha) vpaint_blend( mcol+2, mcolorig+2, paintcol, alpha); - - if(mface->v4) { - alpha= calc_vp_alpha_dl(&Gvp, vpimat, vertexcosnos+6*mface->v4, mval); - if(alpha) vpaint_blend( mcol+3, mcolorig+3, paintcol, alpha); - } - } - } - - MTC_Mat4SwapMat4(G.vd->persmat, mat); - - do_shared_vertexcol(me); - - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - scrarea_do_windraw(curarea); - - 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); - - mvalo[0]= mval[0]; - mvalo[1]= mval[1]; - } - else BIF_wait_for_statechange(); - } - - if(vertexcosnos) - MEM_freeN(vertexcosnos); - MEM_freeN(indexar); - - /* frees prev buffer */ - copy_vpaint_prev(&Gvp, NULL, 0); - - BIF_undo_push("Vertex Paint"); - - allqueue(REDRAWVIEW3D, 0); -} - -void set_wpaint(void) /* toggle */ -{ - Object *ob; - Mesh *me; - - scrarea_queue_headredraw(curarea); - ob= OBACT; - if(!ob || ob->id.lib) return; - me= get_mesh(ob); - - if(me && me->totface>=MAXINDEX) { - error("Maximum number of faces: %d", MAXINDEX-1); - G.f &= ~G_WEIGHTPAINT; - return; - } - - if(G.f & G_WEIGHTPAINT) G.f &= ~G_WEIGHTPAINT; - else G.f |= G_WEIGHTPAINT; - - allqueue(REDRAWVIEW3D, 1); /* including header */ - allqueue(REDRAWBUTSEDIT, 0); - - /* Weightpaint works by overriding colors in mesh, - * so need to make sure we recalc on enter and - * exit (exit needs doing regardless because we - * should redeform). - */ - if (me) { - DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); - } - - if(G.f & G_WEIGHTPAINT) { - Object *par; - - setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT); - - mesh_octree_table(ob, NULL, 's'); - - /* verify if active weight group is also active bone */ - par= modifiers_isDeformedByArmature(ob); - if(par && (par->flag & OB_POSEMODE)) { - bPoseChannel *pchan; - for(pchan= par->pose->chanbase.first; pchan; pchan= pchan->next) - if(pchan->bone->flag & BONE_ACTIVE) - break; - if(pchan) - vertexgroup_select_by_name(ob, pchan->name); - } - } - else { - if(!(G.f & G_FACESELECT)) - setcursor_space(SPACE_VIEW3D, CURSOR_STD); - - mesh_octree_table(ob, NULL, 'e'); - } -} - - -void set_vpaint(void) /* toggle */ -{ - Object *ob; - Mesh *me; - - scrarea_queue_headredraw(curarea); - ob= OBACT; - if(!ob || object_data_is_libdata(ob)) { - G.f &= ~G_VERTEXPAINT; - return; - } - - me= get_mesh(ob); - - if(me && me->totface>=MAXINDEX) { - error("Maximum number of faces: %d", MAXINDEX-1); - G.f &= ~G_VERTEXPAINT; - return; - } - - if(me && me->mcol==NULL) make_vertexcol(1); - - if(G.f & G_VERTEXPAINT){ - G.f &= ~G_VERTEXPAINT; - } - else { - G.f |= G_VERTEXPAINT; - /* Turn off weight painting */ - if (G.f & G_WEIGHTPAINT) - set_wpaint(); - } - - allqueue(REDRAWVIEW3D, 1); /* including header */ - allqueue(REDRAWBUTSEDIT, 0); - - if (me) - /* update modifier stack for mapping requirements */ - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - - if(G.f & G_VERTEXPAINT) { - setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT); - } - else { - if((G.f & G_FACESELECT)==0) setcursor_space(SPACE_VIEW3D, CURSOR_STD); - } -} - |