4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version. The Blender
10 * Foundation also sells licenses for use in proprietary software under
11 * the Blender License. See http://www.blender.org/BL/ for information
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file.
28 * Contributor(s): none yet.
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
42 #include "MEM_guardedalloc.h"
44 #include "IMB_imbuf.h"
45 #include "IMB_imbuf_types.h"
47 #include "BLI_blenlib.h"
48 #include "BLI_arithb.h"
49 #include "MTC_matrixops.h"
51 #include "DNA_action_types.h"
52 #include "DNA_armature_types.h"
53 #include "DNA_brush_types.h"
54 #include "DNA_mesh_types.h"
55 #include "DNA_meshdata_types.h"
56 #include "DNA_modifier_types.h"
57 #include "DNA_object_types.h"
58 #include "DNA_object_force.h"
59 #include "DNA_screen_types.h"
60 #include "DNA_space_types.h"
61 #include "DNA_scene_types.h"
62 #include "DNA_view3d_types.h"
63 #include "DNA_userdef_types.h"
65 #include "BKE_armature.h"
66 #include "BKE_DerivedMesh.h"
67 #include "BKE_cloth.h"
68 #include "BKE_customdata.h"
69 #include "BKE_depsgraph.h"
70 #include "BKE_deform.h"
71 #include "BKE_displist.h"
72 #include "BKE_global.h"
74 #include "BKE_modifier.h"
75 #include "BKE_multires.h"
76 #include "BKE_object.h"
77 #include "BKE_utildefines.h"
79 #include "BIF_editview.h"
80 #include "BIF_graphics.h"
81 #include "BIF_glutil.h"
83 #include "BIF_interface.h"
84 #include "BIF_meshtools.h"
85 #include "BIF_mywindow.h"
86 #include "BIF_space.h"
87 #include "BIF_screen.h"
88 #include "BIF_toolbox.h"
90 #include "BDR_vpaint.h"
91 #include "BDR_editobject.h"
93 #include "BSE_drawview.h"
94 #include "BSE_trans_types.h"
101 #include "BIF_editdeform.h"
112 #define MAXINDEX 512000
114 VPaint Gvp= {1.0, 1.0, 1.0, 0.2, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT+VP_SPRAY, 0};
115 VPaint Gwp= {1.0, 1.0, 1.0, 1.0, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT, 0};
117 static int *get_indexarray(void)
119 return MEM_mallocN(sizeof(int)*MAXINDEX + 2, "vertexpaint");
122 void free_vertexpaint()
125 if(Gvp.vpaint_prev) MEM_freeN(Gvp.vpaint_prev);
126 Gvp.vpaint_prev= NULL;
128 mesh_octree_table(NULL, NULL, 'e');
131 /* in contradiction to cpack drawing colors, the MCOL colors (vpaint colors) are per byte!
132 so not endian sensitive. Mcol = ABGR!!! so be cautious with cpack calls */
134 unsigned int rgba_to_mcol(float r, float g, float b, float a)
141 if(ir<0) ir= 0; else if(ir>255) ir= 255;
143 if(ig<0) ig= 0; else if(ig>255) ig= 255;
145 if(ib<0) ib= 0; else if(ib>255) ib= 255;
147 if(ia<0) ia= 0; else if(ia>255) ia= 255;
159 static unsigned int vpaint_get_current_col(VPaint *vp)
161 return rgba_to_mcol(vp->r, vp->g, vp->b, 1.0f);
164 void do_shared_vertexcol(Mesh *me)
166 /* if no mcol: do not do */
167 /* if tface: only the involved faces, otherwise all */
171 short *scolmain, *scol;
174 if(me->mcol==0 || me->totvert==0 || me->totface==0) return;
176 scolmain= MEM_callocN(4*sizeof(short)*me->totvert, "colmain");
180 mcol= (char *)me->mcol;
181 for(a=me->totface; a>0; a--, mface++, mcol+=16) {
182 if((tface && tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) {
183 scol= scolmain+4*mface->v1;
184 scol[0]++; scol[1]+= mcol[1]; scol[2]+= mcol[2]; scol[3]+= mcol[3];
185 scol= scolmain+4*mface->v2;
186 scol[0]++; scol[1]+= mcol[5]; scol[2]+= mcol[6]; scol[3]+= mcol[7];
187 scol= scolmain+4*mface->v3;
188 scol[0]++; scol[1]+= mcol[9]; scol[2]+= mcol[10]; scol[3]+= mcol[11];
190 scol= scolmain+4*mface->v4;
191 scol[0]++; scol[1]+= mcol[13]; scol[2]+= mcol[14]; scol[3]+= mcol[15];
210 mcol= (char *)me->mcol;
211 for(a=me->totface; a>0; a--, mface++, mcol+=16) {
212 if((tface && tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) {
213 scol= scolmain+4*mface->v1;
214 mcol[1]= scol[1]; mcol[2]= scol[2]; mcol[3]= scol[3];
215 scol= scolmain+4*mface->v2;
216 mcol[5]= scol[1]; mcol[6]= scol[2]; mcol[7]= scol[3];
217 scol= scolmain+4*mface->v3;
218 mcol[9]= scol[1]; mcol[10]= scol[2]; mcol[11]= scol[3];
220 scol= scolmain+4*mface->v4;
221 mcol[13]= scol[1]; mcol[14]= scol[2]; mcol[15]= scol[3];
230 void make_vertexcol(int shade) /* single ob */
236 error("Unable to perform function in Edit Mode");
241 if(!ob || ob->id.lib) return;
245 /* copies from shadedisplist to mcol */
247 CustomData_add_layer(&me->fdata, CD_MCOL, CD_CALLOC, NULL, me->totface);
248 mesh_update_customdata_pointers(me);
252 shadeMeshMCol(ob, me);
254 memset(me->mcol, 255, 4*sizeof(MCol)*me->totface);
256 if (me->mr) multires_load_cols(me);
258 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
260 allqueue(REDRAWBUTSEDIT, 0);
261 allqueue(REDRAWVIEW3D, 0);
264 static void copy_vpaint_prev(VPaint *vp, unsigned int *mcol, int tot)
266 if(vp->vpaint_prev) {
267 MEM_freeN(vp->vpaint_prev);
268 vp->vpaint_prev= NULL;
272 if(mcol==NULL || tot==0) return;
274 vp->vpaint_prev= MEM_mallocN(4*sizeof(int)*tot, "vpaint_prev");
275 memcpy(vp->vpaint_prev, mcol, 4*sizeof(int)*tot);
279 static void copy_wpaint_prev (VPaint *vp, MDeformVert *dverts, int dcount)
281 if (vp->wpaint_prev) {
282 free_dverts(vp->wpaint_prev, vp->tot);
283 vp->wpaint_prev= NULL;
286 if(dverts && dcount) {
288 vp->wpaint_prev = MEM_mallocN (sizeof(MDeformVert)*dcount, "wpaint prev");
290 copy_dverts (vp->wpaint_prev, dverts, dcount);
299 unsigned int *to, paintcol;
302 if((G.f & G_VERTEXPAINT)==0) return;
306 if(!ob || ob->id.lib) return;
308 if(me==0 || me->mcol==0 || me->totface==0) return;
310 paintcol= vpaint_get_current_col(&Gvp);
312 to= (unsigned int *)me->mcol;
318 BIF_undo_push("Clear vertex colors");
319 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
321 allqueue(REDRAWVIEW3D, 0);
324 void clear_vpaint_selectedfaces()
329 unsigned int paintcol, *mcol;
334 if(me==0 || me->totface==0) return;
339 paintcol= vpaint_get_current_col(&Gvp);
342 mcol = (unsigned int*)me->mcol;
343 for (i = 0; i < me->totface; i++, mf++, mcol+=4) {
344 if (mf->flag & ME_FACE_SEL) {
352 BIF_undo_push("Clear vertex colors");
353 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
354 allqueue(REDRAWVIEW3D, 0);
358 /* fills in the selected faces with the current weight and vertex group */
359 void clear_wpaint_selectedfaces()
361 extern float editbutvweight;
362 float paintweight= editbutvweight;
366 MDeformWeight *dw, *uw;
369 unsigned int faceverts[5]={0,0,0,0,0};
371 int vgroup_mirror= -1;
375 if(me==0 || me->totface==0 || me->dvert==0 || !me->mface) return;
377 indexar= get_indexarray();
378 for(index=0, mface=me->mface; index<me->totface; index++, mface++) {
379 if((mface->flag & ME_FACE_SEL)==0)
382 indexar[index]= index+1;
385 vgroup= ob->actdef-1;
387 /* directly copied from weight_paint, should probaby split into a seperate function */
388 /* if mirror painting, find the other group */
389 if(Gwp.flag & VP_MIRROR_X) {
390 bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1);
392 bDeformGroup *curdef;
396 BLI_strncpy(name, defgroup->name, 32);
397 bone_flip_name(name, 0); /* 0 = don't strip off number extensions */
399 for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++)
400 if (!strcmp(curdef->name, name))
403 int olddef= ob->actdef; /* tsk, add_defgroup sets the active defgroup */
404 curdef= add_defgroup_name (ob, name);
408 if(curdef && curdef!=defgroup)
409 vgroup_mirror= actdef;
412 /* end copy from weight_paint*/
414 copy_wpaint_prev(&Gwp, me->dvert, me->totvert);
416 for(index=0; index<me->totface; index++) {
417 if(indexar[index] && indexar[index]<=me->totface) {
418 mface= me->mface + (indexar[index]-1);
419 /* just so we can loop through the verts */
420 faceverts[0]= mface->v1;
421 faceverts[1]= mface->v2;
422 faceverts[2]= mface->v3;
423 faceverts[3]= mface->v4;
424 for (i=0; i<3 || faceverts[i]; i++) {
425 if(!((me->dvert+faceverts[i])->flag)) {
426 dw= verify_defweight(me->dvert+faceverts[i], vgroup);
428 uw= verify_defweight(Gwp.wpaint_prev+faceverts[i], vgroup);
429 uw->weight= dw->weight; /* set the undio weight */
430 dw->weight= paintweight;
432 if(Gwp.flag & VP_MIRROR_X) { /* x mirror painting */
433 int j= mesh_get_x_mirror_vert(ob, faceverts[i]);
435 /* copy, not paint again */
436 if(vgroup_mirror != -1) {
437 dw= verify_defweight(me->dvert+j, vgroup_mirror);
438 uw= verify_defweight(Gwp.wpaint_prev+j, vgroup_mirror);
440 dw= verify_defweight(me->dvert+j, vgroup);
441 uw= verify_defweight(Gwp.wpaint_prev+j, vgroup);
443 uw->weight= dw->weight; /* set the undo weight */
444 dw->weight= paintweight;
448 (me->dvert+faceverts[i])->flag= 1;
455 while (index<me->totvert) {
456 (me->dvert+index)->flag= 0;
461 copy_wpaint_prev(&Gwp, NULL, 0);
463 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
464 BIF_undo_push("Set vertex weight");
465 allqueue(REDRAWVIEW3D, 0);
469 void vpaint_dogamma()
475 char *cp, gamtab[256];
477 if((G.f & G_VERTEXPAINT)==0) return;
481 if(me==0 || me->mcol==0 || me->totface==0) return;
484 for(a=0; a<256; a++) {
486 fac= ((float)a)/255.0;
487 fac= Gvp.mul*pow( fac, igam);
491 if(temp<=0) gamtab[a]= 0;
492 else if(temp>=255) gamtab[a]= 255;
493 else gamtab[a]= temp;
497 cp= (char *)me->mcol;
500 cp[1]= gamtab[ cp[1] ];
501 cp[2]= gamtab[ cp[2] ];
502 cp[3]= gamtab[ cp[3] ];
506 allqueue(REDRAWVIEW3D, 0);
509 /* used for both 3d view and image window */
510 void sample_vpaint() /* frontbuf */
517 getmouseco_areawin(mval);
518 x= mval[0]; y= mval[1];
520 if(x<0 || y<0) return;
521 if(x>=curarea->winx || y>=curarea->winy) return;
523 x+= curarea->winrct.xmin;
524 y+= curarea->winrct.ymin;
526 glReadBuffer(GL_FRONT);
527 glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
528 glReadBuffer(GL_BACK);
532 if(G.f & (G_VERTEXPAINT|G_WEIGHTPAINT)) {
538 Brush *brush= G.scene->toolsettings->imapaint.brush;
541 brush->rgb[0]= cp[0]/255.0f;
542 brush->rgb[1]= cp[1]/255.0f;
543 brush->rgb[2]= cp[2]/255.0f;
545 allqueue(REDRAWVIEW3D, 0);
546 allqueue(REDRAWIMAGE, 0);
550 allqueue(REDRAWBUTSEDIT, 0);
551 addqueue(curarea->win, REDRAW, 1); /* needed for when panel is open... */
554 static unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac)
556 char *cp1, *cp2, *cp;
560 if(fac==0) return col1;
561 if(fac>=255) return col2;
570 cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8;
571 cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8;
572 cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8;
577 static unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac)
579 char *cp1, *cp2, *cp;
583 if(fac==0) return col1;
590 temp= cp1[1] + ((fac*cp2[1])>>8);
591 if(temp>254) cp[1]= 255; else cp[1]= temp;
592 temp= cp1[2] + ((fac*cp2[2])>>8);
593 if(temp>254) cp[2]= 255; else cp[2]= temp;
594 temp= cp1[3] + ((fac*cp2[3])>>8);
595 if(temp>254) cp[3]= 255; else cp[3]= temp;
600 static unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac)
602 char *cp1, *cp2, *cp;
606 if(fac==0) return col1;
613 temp= cp1[1] - ((fac*cp2[1])>>8);
614 if(temp<0) cp[1]= 0; else cp[1]= temp;
615 temp= cp1[2] - ((fac*cp2[2])>>8);
616 if(temp<0) cp[2]= 0; else cp[2]= temp;
617 temp= cp1[3] - ((fac*cp2[3])>>8);
618 if(temp<0) cp[3]= 0; else cp[3]= temp;
623 static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac)
625 char *cp1, *cp2, *cp;
629 if(fac==0) return col1;
637 /* first mul, then blend the fac */
639 cp[1]= (mfac*cp1[1] + fac*((cp2[1]*cp1[1])>>8) )>>8;
640 cp[2]= (mfac*cp1[2] + fac*((cp2[2]*cp1[2])>>8) )>>8;
641 cp[3]= (mfac*cp1[3] + fac*((cp2[3]*cp1[3])>>8) )>>8;
647 static unsigned int mcol_lighten(unsigned int col1, unsigned int col2, int fac)
649 char *cp1, *cp2, *cp;
653 if(fac==0) return col1;
654 if(fac>=255) return col2;
662 /* See if are lighter, if so mix, else dont do anything.
663 if the paint col is darker then the original, then ignore */
664 if (cp1[1]+cp1[2]+cp1[3] > cp2[1]+cp2[2]+cp2[3])
668 cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8;
669 cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8;
670 cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8;
675 static unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac)
677 char *cp1, *cp2, *cp;
681 if(fac==0) return col1;
682 if(fac>=255) return col2;
690 /* See if were darker, if so mix, else dont do anything.
691 if the paint col is brighter then the original, then ignore */
692 if (cp1[1]+cp1[2]+cp1[3] < cp2[1]+cp2[2]+cp2[3])
696 cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8;
697 cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8;
698 cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8;
702 static void vpaint_blend( unsigned int *col, unsigned int *colorig, unsigned int paintcol, int alpha)
705 if(Gvp.mode==VP_MIX || Gvp.mode==VP_BLUR) *col= mcol_blend( *col, paintcol, alpha);
706 else if(Gvp.mode==VP_ADD) *col= mcol_add( *col, paintcol, alpha);
707 else if(Gvp.mode==VP_SUB) *col= mcol_sub( *col, paintcol, alpha);
708 else if(Gvp.mode==VP_MUL) *col= mcol_mul( *col, paintcol, alpha);
709 else if(Gvp.mode==VP_LIGHTEN) *col= mcol_lighten( *col, paintcol, alpha);
710 else if(Gvp.mode==VP_DARKEN) *col= mcol_darken( *col, paintcol, alpha);
712 /* if no spray, clip color adding with colorig & orig alpha */
713 if((Gvp.flag & VP_SPRAY)==0) {
714 unsigned int testcol=0, a;
717 alpha= (int)(255.0*Gvp.a);
719 if(Gvp.mode==VP_MIX || Gvp.mode==VP_BLUR) testcol= mcol_blend( *colorig, paintcol, alpha);
720 else if(Gvp.mode==VP_ADD) testcol= mcol_add( *colorig, paintcol, alpha);
721 else if(Gvp.mode==VP_SUB) testcol= mcol_sub( *colorig, paintcol, alpha);
722 else if(Gvp.mode==VP_MUL) testcol= mcol_mul( *colorig, paintcol, alpha);
723 else if(Gvp.mode==VP_LIGHTEN) testcol= mcol_lighten( *colorig, paintcol, alpha);
724 else if(Gvp.mode==VP_DARKEN) testcol= mcol_darken( *colorig, paintcol, alpha);
727 ct= (char *)&testcol;
732 if( cp[a]<ct[a] ) cp[a]= ct[a];
733 else if( cp[a]>co[a] ) cp[a]= co[a];
736 if( cp[a]<co[a] ) cp[a]= co[a];
737 else if( cp[a]>ct[a] ) cp[a]= ct[a];
744 static int sample_backbuf_area(VPaint *vp, int *indexar, int totface, int x, int y, float size)
748 int x1, y1, x2, y2, a, tot=0, index;
750 if(totface>=MAXINDEX) return 0;
752 if(size>64.0) size= 64.0;
756 CLAMP(x1, 0, curarea->winx-1);
757 CLAMP(x2, 0, curarea->winx-1);
760 CLAMP(y1, 0, curarea->winy-1);
761 CLAMP(y2, 0, curarea->winy-1);
763 glReadBuffer(GL_AUX0);
766 if(x1>=x2 || y1>=y2) return 0;
768 ibuf = IMB_allocImBuf(2*size + 4, 2*size + 4, 32, IB_rect, 0);
769 glReadPixels(x1+curarea->winrct.xmin, y1+curarea->winrct.ymin, x2-x1+1, y2-y1+1, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
770 glReadBuffer(GL_BACK);
772 if(G.order==B_ENDIAN) {
773 IMB_convert_rgba_to_abgr(ibuf);
777 size= (y2-y1)*(x2-x1);
778 if(size<=0) return 0;
780 memset(indexar, 0, sizeof(int)*totface+2); /* plus 2! first element is total */
785 index= framebuffer_to_index(*rt);
786 if(index>0 && index<=totface)
793 for(a=1; a<=totface; a++) {
794 if(indexar[a]) indexar[tot++]= a;
802 static int calc_vp_alpha_dl(VPaint *vp, float vpimat[][3], float *vert_nor, short *mval)
808 if(vp->flag & VP_SOFT) {
809 project_short_noclip(vert_nor, vertco);
810 dx= mval[0]-vertco[0];
811 dy= mval[1]-vertco[1];
813 fac= sqrt(dx*dx + dy*dy);
814 if(fac > vp->size) return 0;
815 if(vp->flag & VP_HARD)
818 alpha= 255.0*vp->a*(1.0-fac/vp->size);
824 if(vp->flag & VP_NORMALS) {
825 float *no= vert_nor+3;
828 fac= vpimat[2][0]*no[0]+vpimat[2][1]*no[1]+vpimat[2][2]*no[2];
830 dx= vpimat[0][0]*no[0]+vpimat[0][1]*no[1]+vpimat[0][2]*no[2];
831 dy= vpimat[1][0]*no[0]+vpimat[1][1]*no[1]+vpimat[1][2]*no[2];
833 alpha*= fac/sqrt(dx*dx + dy*dy + fac*fac);
841 static void wpaint_blend(MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval)
844 if(dw==NULL || uw==NULL) return;
846 if(Gwp.mode==VP_MIX || Gwp.mode==VP_BLUR)
847 dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
848 else if(Gwp.mode==VP_ADD)
849 dw->weight += paintval*alpha;
850 else if(Gwp.mode==VP_SUB)
851 dw->weight -= paintval*alpha;
852 else if(Gwp.mode==VP_MUL)
853 /* first mul, then blend the fac */
854 dw->weight = ((1.0-alpha) + alpha*paintval)*dw->weight;
855 else if(Gwp.mode==VP_LIGHTEN) {
856 if (dw->weight < paintval)
857 dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
858 } else if(Gwp.mode==VP_DARKEN) {
859 if (dw->weight > paintval)
860 dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
862 CLAMP(dw->weight, 0.0f, 1.0f);
864 /* if no spray, clip result with orig weight & orig alpha */
865 if((Gwp.flag & VP_SPRAY)==0) {
869 if(Gwp.mode==VP_MIX || Gwp.mode==VP_BLUR)
870 testw = paintval*alpha + uw->weight*(1.0-alpha);
871 else if(Gwp.mode==VP_ADD)
872 testw = uw->weight + paintval*alpha;
873 else if(Gwp.mode==VP_SUB)
874 testw = uw->weight - paintval*alpha;
875 else if(Gwp.mode==VP_MUL)
876 /* first mul, then blend the fac */
877 testw = ((1.0-alpha) + alpha*paintval)*uw->weight;
878 else if(Gwp.mode==VP_LIGHTEN) {
879 if (uw->weight < paintval)
880 testw = paintval*alpha + uw->weight*(1.0-alpha);
883 } else if(Gwp.mode==VP_DARKEN) {
884 if (uw->weight > paintval)
885 testw = paintval*alpha + uw->weight*(1.0-alpha);
889 CLAMP(testw, 0.0f, 1.0f);
891 if( testw<uw->weight ) {
892 if(dw->weight < testw) dw->weight= testw;
893 else if(dw->weight > uw->weight) dw->weight= uw->weight;
896 if(dw->weight > testw) dw->weight= testw;
897 else if(dw->weight < uw->weight) dw->weight= uw->weight;
903 /* ----------------------------------------------------- */
905 /* used for 3d view, on active object, assumes me->dvert exists */
907 /* samples cursor location, and gives menu with vertex groups to activate */
909 /* sets editbutvweight to the closest weight value to vertex */
910 /* note: we cant sample frontbuf, weight colors are interpolated too unpredictable */
911 static void sample_wpaint(int mode)
914 Mesh *me= get_mesh(ob);
916 short mval[2], sco[2];
920 getmouseco_areawin(mval);
921 index= sample_backbuf(mval[0], mval[1]);
923 if(index && index<=me->totface) {
926 mface= ((MFace *)me->mface) + index-1;
928 if(mode==1) { /* sampe which groups are in here */
932 totgroup= BLI_countlist(&ob->defbase);
935 int *groups=MEM_callocN(totgroup*sizeof(int), "groups");
937 dv= me->dvert+mface->v1;
938 for(a=0; a<dv->totweight; a++) {
939 if (dv->dw[a].def_nr<totgroup)
940 groups[dv->dw[a].def_nr]= 1;
942 dv= me->dvert+mface->v2;
943 for(a=0; a<dv->totweight; a++) {
944 if (dv->dw[a].def_nr<totgroup)
945 groups[dv->dw[a].def_nr]= 1;
947 dv= me->dvert+mface->v3;
948 for(a=0; a<dv->totweight; a++) {
949 if (dv->dw[a].def_nr<totgroup)
950 groups[dv->dw[a].def_nr]= 1;
953 dv= me->dvert+mface->v4;
954 for(a=0; a<dv->totweight; a++) {
955 if (dv->dw[a].def_nr<totgroup)
956 groups[dv->dw[a].def_nr]= 1;
959 for(a=0; a<totgroup; a++)
960 if(groups[a]) totmenu++;
963 notice("No Vertex Group Selected");
968 char item[40], *str= MEM_mallocN(40*totmenu+40, "menu");
970 strcpy(str, "Vertex Groups %t");
971 for(a=0, dg=ob->defbase.first; dg && a<totgroup; a++, dg= dg->next) {
973 sprintf(item, "|%s %%x%d", dg->name, a);
981 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
982 allqueue(REDRAWVIEW3D, 0);
983 allqueue(REDRAWOOPS, 0);
984 allqueue(REDRAWBUTSEDIT, 0);
990 else notice("No Vertex Groups in Object");
995 extern float editbutvweight;
996 float w1, w2, w3, w4, co[3], fac;
998 dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
999 if(dm->getVertCo==NULL) {
1000 notice("Not supported yet");
1003 /* calc 3 or 4 corner weights */
1004 dm->getVertCo(dm, mface->v1, co);
1005 project_short_noclip(co, sco);
1006 w1= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
1008 dm->getVertCo(dm, mface->v2, co);
1009 project_short_noclip(co, sco);
1010 w2= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
1012 dm->getVertCo(dm, mface->v3, co);
1013 project_short_noclip(co, sco);
1014 w3= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
1017 dm->getVertCo(dm, mface->v4, co);
1018 project_short_noclip(co, sco);
1019 w4= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
1023 fac= MIN4(w1, w2, w3, w4);
1025 dw= get_defweight(me->dvert+mface->v1, ob->actdef-1);
1026 if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
1029 dw= get_defweight(me->dvert+mface->v2, ob->actdef-1);
1030 if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
1033 dw= get_defweight(me->dvert+mface->v3, ob->actdef-1);
1034 if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
1038 dw= get_defweight(me->dvert+mface->v4, ob->actdef-1);
1039 if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
1047 allqueue(REDRAWBUTSEDIT, 0);
1051 static void do_weight_paint_vertex(Object *ob, int index, int alpha, float paintweight, int vgroup_mirror)
1054 MDeformWeight *dw, *uw;
1055 int vgroup= ob->actdef-1;
1057 if(Gwp.flag & VP_ONLYVGROUP) {
1058 dw= get_defweight(me->dvert+index, vgroup);
1059 uw= get_defweight(Gwp.wpaint_prev+index, vgroup);
1062 dw= verify_defweight(me->dvert+index, vgroup);
1063 uw= verify_defweight(Gwp.wpaint_prev+index, vgroup);
1065 if(dw==NULL || uw==NULL)
1068 wpaint_blend(dw, uw, (float)alpha/255.0, paintweight);
1070 if(Gwp.flag & VP_MIRROR_X) { /* x mirror painting */
1071 int j= mesh_get_x_mirror_vert(ob, index);
1073 /* copy, not paint again */
1074 if(vgroup_mirror != -1)
1075 uw= verify_defweight(me->dvert+j, vgroup_mirror);
1077 uw= verify_defweight(me->dvert+j, vgroup);
1079 uw->weight= dw->weight;
1084 void weight_paint(void)
1086 extern float editbutvweight;
1090 float mat[4][4], imat[4][4], paintweight, *vertexcosnos;
1092 int *indexar, index, totindex, alpha, totw;
1093 int vgroup_mirror= -1;
1094 short mval[2], mvalo[2], firsttime=1;
1096 if((G.f & G_WEIGHTPAINT)==0) return;
1097 if(G.obedit) return;
1098 if(multires_level1_test()) return;
1101 if(!ob || ob->id.lib) return;
1104 if(me==NULL || me->totface==0) return;
1106 /* if nothing was added yet, we make dverts and a vertex deform group */
1108 create_dverts(&me->id);
1110 if(G.qual & LR_CTRLKEY) {
1114 if(G.qual & LR_SHIFTKEY) {
1119 /* ALLOCATIONS! no return after this line */
1120 /* painting on subsurfs should give correct points too, this returns me->totvert amount */
1121 vertexcosnos= mesh_get_mapped_verts_nors(ob);
1122 indexar= get_indexarray();
1123 copy_wpaint_prev(&Gwp, me->dvert, me->totvert);
1125 /* this happens on a Bone select, when no vgroup existed yet */
1128 if((modob = modifiers_isDeformedByArmature(ob))) {
1129 bPoseChannel *pchan;
1130 for(pchan= modob->pose->chanbase.first; pchan; pchan= pchan->next)
1131 if(pchan->bone->flag & SELECT)
1134 bDeformGroup *dg= get_named_vertexgroup(ob, pchan->name);
1136 dg= add_defgroup_name(ob, pchan->name); /* sets actdef */
1138 ob->actdef= get_defgroup_num(ob, dg);
1139 allqueue(REDRAWBUTSEDIT, 0);
1143 if(ob->defbase.first==NULL) {
1145 allqueue(REDRAWBUTSEDIT, 0);
1148 if(ob->lay & G.vd->lay); else error("Active object is not in this layer");
1151 /* imat for normals */
1152 Mat4MulMat4(mat, ob->obmat, G.vd->viewmat);
1153 Mat4Invert(imat, mat);
1154 Mat3CpyMat4(vpimat, imat);
1156 /* load projection matrix */
1157 mymultmatrix(ob->obmat);
1158 mygetsingmatrix(mat);
1159 myloadmatrix(G.vd->viewmat);
1161 getmouseco_areawin(mvalo);
1163 getmouseco_areawin(mval);
1167 /* if mirror painting, find the other group */
1168 if(Gwp.flag & VP_MIRROR_X) {
1169 bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1);
1171 bDeformGroup *curdef;
1175 BLI_strncpy(name, defgroup->name, 32);
1176 bone_flip_name(name, 0); /* 0 = don't strip off number extensions */
1178 for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++)
1179 if (!strcmp(curdef->name, name))
1182 int olddef= ob->actdef; /* tsk, add_defgroup sets the active defgroup */
1183 curdef= add_defgroup_name (ob, name);
1187 if(curdef && curdef!=defgroup)
1188 vgroup_mirror= actdef;
1192 while (get_mbut() & L_MOUSE) {
1193 getmouseco_areawin(mval);
1195 if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
1198 /* which faces are involved */
1199 if(Gwp.flag & VP_AREA) {
1200 totindex= sample_backbuf_area(&Gwp, indexar, me->totface, mval[0], mval[1], Gwp.size);
1203 indexar[0]= sample_backbuf(mval[0], mval[1]);
1204 if(indexar[0]) totindex= 1;
1208 MTC_Mat4SwapMat4(G.vd->persmat, mat);
1210 if(Gwp.flag & VP_COLINDEX) {
1211 for(index=0; index<totindex; index++) {
1212 if(indexar[index] && indexar[index]<=me->totface) {
1214 mface= ((MFace *)me->mface) + (indexar[index]-1);
1216 if(mface->mat_nr!=ob->actcol-1) {
1223 if((G.f & G_FACESELECT) && me->mface) {
1224 for(index=0; index<totindex; index++) {
1225 if(indexar[index] && indexar[index]<=me->totface) {
1227 mface= ((MFace *)me->mface) + (indexar[index]-1);
1229 if((mface->flag & ME_FACE_SEL)==0) {
1236 /* make sure each vertex gets treated only once */
1237 /* and calculate filter weight */
1239 if(Gwp.mode==VP_BLUR)
1242 paintweight= editbutvweight;
1244 for(index=0; index<totindex; index++) {
1245 if(indexar[index] && indexar[index]<=me->totface) {
1246 mface= me->mface + (indexar[index]-1);
1248 (me->dvert+mface->v1)->flag= 1;
1249 (me->dvert+mface->v2)->flag= 1;
1250 (me->dvert+mface->v3)->flag= 1;
1251 if(mface->v4) (me->dvert+mface->v4)->flag= 1;
1253 if(Gwp.mode==VP_BLUR) {
1254 MDeformWeight *dw, *(*dw_func)(MDeformVert *, int) = verify_defweight;
1256 if(Gwp.flag & VP_ONLYVGROUP)
1257 dw_func= get_defweight;
1259 dw= dw_func(me->dvert+mface->v1, ob->actdef-1);
1260 if(dw) {paintweight+= dw->weight; totw++;}
1261 dw= dw_func(me->dvert+mface->v2, ob->actdef-1);
1262 if(dw) {paintweight+= dw->weight; totw++;}
1263 dw= dw_func(me->dvert+mface->v3, ob->actdef-1);
1264 if(dw) {paintweight+= dw->weight; totw++;}
1266 dw= dw_func(me->dvert+mface->v4, ob->actdef-1);
1267 if(dw) {paintweight+= dw->weight; totw++;}
1273 if(Gwp.mode==VP_BLUR)
1274 paintweight/= (float)totw;
1276 for(index=0; index<totindex; index++) {
1278 if(indexar[index] && indexar[index]<=me->totface) {
1279 mface= me->mface + (indexar[index]-1);
1281 if((me->dvert+mface->v1)->flag) {
1282 alpha= calc_vp_alpha_dl(&Gwp, vpimat, vertexcosnos+6*mface->v1, mval);
1284 do_weight_paint_vertex(ob, mface->v1, alpha, paintweight, vgroup_mirror);
1286 (me->dvert+mface->v1)->flag= 0;
1289 if((me->dvert+mface->v2)->flag) {
1290 alpha= calc_vp_alpha_dl(&Gwp, vpimat, vertexcosnos+6*mface->v2, mval);
1292 do_weight_paint_vertex(ob, mface->v2, alpha, paintweight, vgroup_mirror);
1294 (me->dvert+mface->v2)->flag= 0;
1297 if((me->dvert+mface->v3)->flag) {
1298 alpha= calc_vp_alpha_dl(&Gwp, vpimat, vertexcosnos+6*mface->v3, mval);
1300 do_weight_paint_vertex(ob, mface->v3, alpha, paintweight, vgroup_mirror);
1302 (me->dvert+mface->v3)->flag= 0;
1305 if((me->dvert+mface->v4)->flag) {
1307 alpha= calc_vp_alpha_dl(&Gwp, vpimat, vertexcosnos+6*mface->v4, mval);
1309 do_weight_paint_vertex(ob, mface->v4, alpha, paintweight, vgroup_mirror);
1311 (me->dvert+mface->v4)->flag= 0;
1317 MTC_Mat4SwapMat4(G.vd->persmat, mat);
1320 else BIF_wait_for_statechange();
1322 if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
1324 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1325 scrarea_do_windraw(curarea);
1327 if(Gwp.flag & (VP_AREA|VP_SOFT)) {
1328 /* draw circle in backbuf! */
1330 fdrawXORcirc((float)mval[0], (float)mval[1], Gwp.size);
1334 screen_swapbuffers();
1343 MEM_freeN(vertexcosnos);
1345 copy_wpaint_prev(&Gwp, NULL, 0);
1347 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1348 /* this flag is event for softbody to refresh weightpaint values */
1349 if(ob->soft) ob->softflag |= OB_SB_REDO;
1351 // same goes for cloth
1352 if(modifiers_isClothEnabled(ob)) {
1353 cloth_free_modifier(modifiers_isClothEnabled(ob));
1356 BIF_undo_push("Weight Paint");
1357 allqueue(REDRAWVIEW3D, 0);
1365 float mat[4][4], imat[4][4], *vertexcosnos;
1367 unsigned int paintcol=0, *mcol, *mcolorig, fcol1, fcol2;
1368 int *indexar, index, alpha, totindex;
1369 short mval[2], mvalo[2], firsttime=1;
1371 if((G.f & G_VERTEXPAINT)==0) return;
1372 if(G.obedit) return;
1375 if(!ob || ob->id.lib) return;
1378 if(me==NULL || me->totface==0) return;
1379 if(ob->lay & G.vd->lay); else error("Active object is not in this layer");
1381 if(me->mcol==NULL) make_vertexcol(1);
1383 if(me->mcol==NULL) return;
1385 /* ALLOCATIONS! No return after his line */
1387 /* painting on subsurfs should give correct points too, this returns me->totvert amount */
1388 vertexcosnos= mesh_get_mapped_verts_nors(ob);
1389 indexar= get_indexarray();
1390 copy_vpaint_prev(&Gvp, (unsigned int *)me->mcol, me->totface);
1392 /* opengl/matrix stuff */
1394 /* imat for normals */
1395 Mat4MulMat4(mat, ob->obmat, G.vd->viewmat);
1396 Mat4Invert(imat, mat);
1397 Mat3CpyMat4(vpimat, imat);
1399 /* load projection matrix */
1400 mymultmatrix(ob->obmat);
1401 mygetsingmatrix(mat);
1402 myloadmatrix(G.vd->viewmat);
1404 paintcol= vpaint_get_current_col(&Gvp);
1406 getmouseco_areawin(mvalo);
1408 getmouseco_areawin(mval);
1412 while (get_mbut() & L_MOUSE) {
1413 getmouseco_areawin(mval);
1415 if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
1419 /* which faces are involved */
1420 if(Gvp.flag & VP_AREA) {
1421 totindex= sample_backbuf_area(&Gvp, indexar, me->totface, mval[0], mval[1], Gvp.size);
1424 indexar[0]= sample_backbuf(mval[0], mval[1]);
1425 if(indexar[0]) totindex= 1;
1429 MTC_Mat4SwapMat4(G.vd->persmat, mat);
1431 if(Gvp.flag & VP_COLINDEX) {
1432 for(index=0; index<totindex; index++) {
1433 if(indexar[index] && indexar[index]<=me->totface) {
1435 mface= ((MFace *)me->mface) + (indexar[index]-1);
1437 if(mface->mat_nr!=ob->actcol-1) {
1443 if((G.f & G_FACESELECT) && me->mface) {
1444 for(index=0; index<totindex; index++) {
1445 if(indexar[index] && indexar[index]<=me->totface) {
1446 mface= ((MFace *)me->mface) + (indexar[index]-1);
1448 if((mface->flag & ME_FACE_SEL)==0)
1454 for(index=0; index<totindex; index++) {
1456 if(indexar[index] && indexar[index]<=me->totface) {
1458 mface= ((MFace *)me->mface) + (indexar[index]-1);
1459 mcol= ( (unsigned int *)me->mcol) + 4*(indexar[index]-1);
1460 mcolorig= ( (unsigned int *)Gvp.vpaint_prev) + 4*(indexar[index]-1);
1462 if(Gvp.mode==VP_BLUR) {
1463 fcol1= mcol_blend( mcol[0], mcol[1], 128);
1465 fcol2= mcol_blend( mcol[2], mcol[3], 128);
1466 paintcol= mcol_blend( fcol1, fcol2, 128);
1469 paintcol= mcol_blend( mcol[2], fcol1, 170);
1474 alpha= calc_vp_alpha_dl(&Gvp, vpimat, vertexcosnos+6*mface->v1, mval);
1475 if(alpha) vpaint_blend( mcol, mcolorig, paintcol, alpha);
1477 alpha= calc_vp_alpha_dl(&Gvp, vpimat, vertexcosnos+6*mface->v2, mval);
1478 if(alpha) vpaint_blend( mcol+1, mcolorig+1, paintcol, alpha);
1480 alpha= calc_vp_alpha_dl(&Gvp, vpimat, vertexcosnos+6*mface->v3, mval);
1481 if(alpha) vpaint_blend( mcol+2, mcolorig+2, paintcol, alpha);
1484 alpha= calc_vp_alpha_dl(&Gvp, vpimat, vertexcosnos+6*mface->v4, mval);
1485 if(alpha) vpaint_blend( mcol+3, mcolorig+3, paintcol, alpha);
1490 MTC_Mat4SwapMat4(G.vd->persmat, mat);
1492 do_shared_vertexcol(me);
1494 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1495 scrarea_do_windraw(curarea);
1497 if(Gvp.flag & (VP_AREA|VP_SOFT)) {
1498 /* draw circle in backbuf! */
1500 fdrawXORcirc((float)mval[0], (float)mval[1], Gvp.size);
1503 screen_swapbuffers();
1509 else BIF_wait_for_statechange();
1513 MEM_freeN(vertexcosnos);
1516 /* frees prev buffer */
1517 copy_vpaint_prev(&Gvp, NULL, 0);
1519 BIF_undo_push("Vertex Paint");
1521 allqueue(REDRAWVIEW3D, 0);
1524 void set_wpaint(void) /* toggle */
1529 scrarea_queue_headredraw(curarea);
1531 if(!ob || ob->id.lib) return;
1534 if(me && me->totface>=MAXINDEX) {
1535 error("Maximum number of faces: %d", MAXINDEX-1);
1536 G.f &= ~G_WEIGHTPAINT;
1540 if(G.f & G_WEIGHTPAINT) G.f &= ~G_WEIGHTPAINT;
1541 else G.f |= G_WEIGHTPAINT;
1543 allqueue(REDRAWVIEW3D, 1); /* including header */
1544 allqueue(REDRAWBUTSEDIT, 0);
1546 /* Weightpaint works by overriding colors in mesh,
1547 * so need to make sure we recalc on enter and
1548 * exit (exit needs doing regardless because we
1552 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1555 if(G.f & G_WEIGHTPAINT) {
1558 setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT);
1560 mesh_octree_table(ob, NULL, 's');
1562 /* verify if active weight group is also active bone */
1563 par= modifiers_isDeformedByArmature(ob);
1564 if(par && (par->flag & OB_POSEMODE)) {
1565 bPoseChannel *pchan;
1566 for(pchan= par->pose->chanbase.first; pchan; pchan= pchan->next)
1567 if(pchan->bone->flag & BONE_ACTIVE)
1570 vertexgroup_select_by_name(ob, pchan->name);
1574 if(!(G.f & G_FACESELECT))
1575 setcursor_space(SPACE_VIEW3D, CURSOR_STD);
1577 mesh_octree_table(ob, NULL, 'e');
1582 void set_vpaint(void) /* toggle */
1587 scrarea_queue_headredraw(curarea);
1589 if(!ob || object_data_is_libdata(ob)) {
1590 G.f &= ~G_VERTEXPAINT;
1596 if(me && me->totface>=MAXINDEX) {
1597 error("Maximum number of faces: %d", MAXINDEX-1);
1598 G.f &= ~G_VERTEXPAINT;
1602 if(me && me->mcol==NULL) make_vertexcol(1);
1604 if(G.f & G_VERTEXPAINT){
1605 G.f &= ~G_VERTEXPAINT;
1608 G.f |= G_VERTEXPAINT;
1609 /* Turn off weight painting */
1610 if (G.f & G_WEIGHTPAINT)
1614 allqueue(REDRAWVIEW3D, 1); /* including header */
1615 allqueue(REDRAWBUTSEDIT, 0);
1618 /* update modifier stack for mapping requirements */
1619 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1621 if(G.f & G_VERTEXPAINT) {
1622 setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT);
1625 if((G.f & G_FACESELECT)==0) setcursor_space(SPACE_VIEW3D, CURSOR_STD);