Added better safety in vertex/weight paint, so it survives painting outside
[blender.git] / source / blender / src / vpaint.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
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
12  * about this.
13  *
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.
18  *
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.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <math.h>
34 #include <string.h>
35
36 #ifdef WIN32
37 #include <io.h>
38 #else
39 #include <unistd.h>
40 #endif   
41
42 #include "MEM_guardedalloc.h"
43
44 #include "IMB_imbuf.h"
45 #include "IMB_imbuf_types.h"
46
47 #include "BLI_blenlib.h"
48 #include "BLI_arithb.h"
49 #include "MTC_matrixops.h"
50
51 #include "DNA_action_types.h"
52 #include "DNA_armature_types.h"
53 #include "DNA_mesh_types.h"
54 #include "DNA_meshdata_types.h"
55 #include "DNA_modifier_types.h"
56 #include "DNA_object_types.h"
57 #include "DNA_object_force.h"
58 #include "DNA_screen_types.h"
59 #include "DNA_scene_types.h"
60 #include "DNA_view3d_types.h"
61 #include "DNA_userdef_types.h"
62
63 #include "BKE_armature.h"
64 #include "BKE_DerivedMesh.h"
65 #include "BKE_depsgraph.h"
66 #include "BKE_deform.h"
67 #include "BKE_displist.h"
68 #include "BKE_global.h"
69 #include "BKE_mesh.h"
70 #include "BKE_modifier.h"
71 #include "BKE_object.h"
72 #include "BKE_utildefines.h"
73
74 #include "BIF_editview.h"
75 #include "BIF_graphics.h"
76 #include "BIF_glutil.h"
77 #include "BIF_gl.h"
78 #include "BIF_interface.h"
79 #include "BIF_meshtools.h"
80 #include "BIF_mywindow.h"
81 #include "BIF_space.h"
82 #include "BIF_screen.h"
83 #include "BIF_toolbox.h"
84
85 #include "BDR_vpaint.h"
86
87 #include "BSE_drawview.h"
88 #include "BSE_trans_types.h"
89 #include "BSE_view.h"
90
91 #include "mydevice.h"
92 #include "blendef.h"
93
94 #include "BIF_editdeform.h"
95
96         /* Gvp.mode */
97 #define VP_MIX  0
98 #define VP_ADD  1
99 #define VP_SUB  2
100 #define VP_MUL  3
101 #define VP_FILT 4
102
103 #define MAXINDEX        512000
104
105 VPaint Gvp= {1.0, 1.0, 1.0, 0.2, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT+VP_SPRAY};
106 VPaint Gwp= {1.0, 1.0, 1.0, 0.2, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT};
107 float vpimat[3][3];
108 unsigned int *vpaintundobuf= NULL;
109 int totvpaintundo;
110 int *indexar= NULL;
111
112 int totwpaintundo;
113 MDeformVert *wpaintundobuf=NULL;
114
115 /* in contradiction to cpack drawing colors, the MCOL colors (vpaint colors) are per byte! 
116    so not endian sensitive. Mcol = ABGR!!! so be cautious with cpack calls */
117
118 unsigned int rgba_to_mcol(float r, float g, float b, float a)
119 {
120         int ir, ig, ib, ia;
121         unsigned int col;
122         char *cp;
123         
124         ir= floor(255.0*r);
125         if(ir<0) ir= 0; else if(ir>255) ir= 255;
126         ig= floor(255.0*g);
127         if(ig<0) ig= 0; else if(ig>255) ig= 255;
128         ib= floor(255.0*b);
129         if(ib<0) ib= 0; else if(ib>255) ib= 255;
130         ia= floor(255.0*a);
131         if(ia<0) ia= 0; else if(ia>255) ia= 255;
132         
133         cp= (char *)&col;
134         cp[0]= ia;
135         cp[1]= ib;
136         cp[2]= ig;
137         cp[3]= ir;
138         
139         return col;
140         
141 }
142
143 unsigned int vpaint_get_current_col(void)
144 {
145         return rgba_to_mcol(Gvp.r, Gvp.g, Gvp.b, 1.0);
146 }
147
148 void do_shared_vertexcol(Mesh *me)
149 {
150         /* if no mcol: do not do */
151         /* if tface: only the involved faces, otherwise all */
152         MFace *mface;
153         TFace *tface;
154         int a;
155         short *scolmain, *scol;
156         char *mcol;
157         
158         if(me->mcol==0 || me->totvert==0 || me->totface==0) return;
159         
160         scolmain= MEM_callocN(4*sizeof(short)*me->totvert, "colmain");
161         
162         tface= me->tface;
163         mface= me->mface;
164         mcol= (char *)me->mcol;
165         for(a=me->totface; a>0; a--, mface++, mcol+=16) {
166                 if(tface==0 || (tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) {
167                         scol= scolmain+4*mface->v1;
168                         scol[0]++; scol[1]+= mcol[1]; scol[2]+= mcol[2]; scol[3]+= mcol[3];
169                         scol= scolmain+4*mface->v2;
170                         scol[0]++; scol[1]+= mcol[5]; scol[2]+= mcol[6]; scol[3]+= mcol[7];
171                         scol= scolmain+4*mface->v3;
172                         scol[0]++; scol[1]+= mcol[9]; scol[2]+= mcol[10]; scol[3]+= mcol[11];
173                         if(mface->v4) {
174                                 scol= scolmain+4*mface->v4;
175                                 scol[0]++; scol[1]+= mcol[13]; scol[2]+= mcol[14]; scol[3]+= mcol[15];
176                         }
177                 }
178                 if(tface) tface++;
179         }
180         
181         a= me->totvert;
182         scol= scolmain;
183         while(a--) {
184                 if(scol[0]>1) {
185                         scol[1]/= scol[0];
186                         scol[2]/= scol[0];
187                         scol[3]/= scol[0];
188                 }
189                 scol+= 4;
190         }
191         
192         tface= me->tface;
193         mface= me->mface;
194         mcol= (char *)me->mcol;
195         for(a=me->totface; a>0; a--, mface++, mcol+=16) {
196                 if(tface==0 || (tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) {
197                         scol= scolmain+4*mface->v1;
198                         mcol[1]= scol[1]; mcol[2]= scol[2]; mcol[3]= scol[3];
199                         scol= scolmain+4*mface->v2;
200                         mcol[5]= scol[1]; mcol[6]= scol[2]; mcol[7]= scol[3];
201                         scol= scolmain+4*mface->v3;
202                         mcol[9]= scol[1]; mcol[10]= scol[2]; mcol[11]= scol[3];
203                         if(mface->v4) {
204                                 scol= scolmain+4*mface->v4;
205                                 mcol[13]= scol[1]; mcol[14]= scol[2]; mcol[15]= scol[3];
206                         }
207                 }
208                 if(tface) tface++;
209         }
210
211         MEM_freeN(scolmain);
212 }
213
214 void make_vertexcol()   /* single ob */
215 {
216         Object *ob;
217         Mesh *me;
218         int i;
219
220         /*
221          * Always copies from shadedisplist to mcol.
222          * When there are tfaces, it copies the colors and frees mcol
223          */
224         
225         if(G.obedit) {
226                 error("Unable to perform function in Edit Mode");
227                 return;
228         }
229         
230         ob= OBACT;
231         me= get_mesh(ob);
232         if(me==0) return;
233
234         if(me->mcol) MEM_freeN(me->mcol);
235         mesh_create_shadedColors(ob, 1, (unsigned int**) &me->mcol, NULL);
236
237         for (i=0; i<me->totface*4; i++) {
238                 me->mcol[i].a = 255;
239         }
240                 
241         if(me->tface) mcol_to_tface(me, 1);
242         
243         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
244         
245         allqueue(REDRAWBUTSEDIT, 0);
246         allqueue(REDRAWVIEW3D, 0);
247 }
248
249
250
251 void copy_vpaint_undo(unsigned int *mcol, int tot)
252 {
253         if(vpaintundobuf) MEM_freeN(vpaintundobuf);
254         vpaintundobuf= 0;
255         totvpaintundo= tot;     // because of return, it is used by weightpaint
256         
257         if(mcol==0 || tot==0) return;
258         
259         vpaintundobuf= MEM_mallocN(4*sizeof(int)*tot, "vpaintundobuf");
260         memcpy(vpaintundobuf, mcol, 4*sizeof(int)*tot);
261         
262 }
263
264 void vpaint_undo()
265 {
266         Mesh *me;
267         Object *ob;
268         unsigned int temp, *from, *to;
269         int a;
270         
271         if((G.f & G_VERTEXPAINT)==0) return;
272         if(vpaintundobuf==0) return;
273
274         ob= OBACT;
275         me= get_mesh(ob);
276         if(me==0 || me->totface==0) return;
277
278         if(me->tface) tface_to_mcol(me);
279         else if(me->mcol==0) return;
280         
281         a= MIN2(me->totface, totvpaintundo);
282         from= vpaintundobuf;
283         to= (unsigned int *)me->mcol;
284         a*= 4;
285         while(a--) {
286                 temp= *to;
287                 *to= *from;
288                 *from= temp;
289                 to++; from++;
290         }
291         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
292         
293         allqueue(REDRAWVIEW3D, 0);
294         if(me->tface) mcol_to_tface(me, 1);
295 }
296
297 void clear_vpaint()
298 {
299         Mesh *me;
300         Object *ob;
301         unsigned int *to, paintcol;
302         int a;
303         
304         if((G.f & G_VERTEXPAINT)==0) return;
305
306         ob= OBACT;
307         me= get_mesh(ob);
308         if(ob->id.lib) return;
309
310         if(me==0 || me->totface==0) return;
311
312         if(me->tface) tface_to_mcol(me);
313         if(me->mcol==0) return;
314
315         paintcol= vpaint_get_current_col();
316
317         to= (unsigned int *)me->mcol;
318         copy_vpaint_undo(to, me->totface);
319         a= 4*me->totface;
320         while(a--) {
321                 *to= paintcol;
322                 to++; 
323         }
324         BIF_undo_push("Clear vertex colors");
325         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
326         
327         allqueue(REDRAWVIEW3D, 0);
328         if(me->tface) mcol_to_tface(me, 1);
329 }
330
331 void clear_vpaint_selectedfaces()
332 {
333         Mesh *me;
334         TFace *tf;
335         Object *ob;
336         unsigned int paintcol;
337         int i;
338
339         ob= OBACT;
340
341         me= get_mesh(ob);
342         tf = me->tface;
343         if (!tf) return; /* should not happen, but you never know */
344
345         if(me==0 || me->totface==0) return;
346
347         paintcol= vpaint_get_current_col();
348
349         for (i = 0; i < me->totface; i++) {
350                 if (tf[i].flag & TF_SELECT) {
351                         tf[i].col[0] = paintcol;
352                         tf[i].col[1] = paintcol;
353                         tf[i].col[2] = paintcol;
354                         tf[i].col[3] = paintcol;
355                 }
356         }
357         BIF_undo_push("Clear vertex colors");
358         allqueue(REDRAWVIEW3D, 0);
359 }
360
361 void vpaint_dogamma()
362 {
363         Mesh *me;
364         Object *ob;
365         float igam, fac;
366         int a, temp;
367         char *cp, gamtab[256];
368
369         if((G.f & G_VERTEXPAINT)==0) return;
370
371         ob= OBACT;
372         me= get_mesh(ob);
373         if(me==0 || me->totface==0) return;
374
375         if(me->tface) tface_to_mcol(me);
376         else if(me->mcol==0) return;
377
378         copy_vpaint_undo((unsigned int *)me->mcol, me->totface);
379
380         igam= 1.0/Gvp.gamma;
381         for(a=0; a<256; a++) {
382                 
383                 fac= ((float)a)/255.0;
384                 fac= Gvp.mul*pow( fac, igam);
385                 
386                 temp= 255.9*fac;
387                 
388                 if(temp<=0) gamtab[a]= 0;
389                 else if(temp>=255) gamtab[a]= 255;
390                 else gamtab[a]= temp;
391         }
392
393         a= 4*me->totface;
394         cp= (char *)me->mcol;
395         while(a--) {
396                 
397                 cp[1]= gamtab[ cp[1] ];
398                 cp[2]= gamtab[ cp[2] ];
399                 cp[3]= gamtab[ cp[3] ];
400                 
401                 cp+= 4;
402         }
403         allqueue(REDRAWVIEW3D, 0);
404         
405         if(me->tface) mcol_to_tface(me, 1);
406 }
407
408 /* used for both 3d view and image window */
409 void sample_vpaint()    /* frontbuf */
410 {
411         unsigned int col;
412         int x, y;
413         short mval[2];
414         char *cp;
415         
416         getmouseco_areawin(mval);
417         x= mval[0]; y= mval[1];
418         
419         if(x<0 || y<0) return;
420         if(x>=curarea->winx || y>=curarea->winy) return;
421         
422         x+= curarea->winrct.xmin;
423         y+= curarea->winrct.ymin;
424         
425         glReadBuffer(GL_FRONT);
426         glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
427         glReadBuffer(GL_BACK);
428
429         cp = (char *)&col;
430         
431         Gvp.r= cp[0];
432         Gvp.r /= 255.0;
433
434         Gvp.g= cp[1];
435         Gvp.g /= 255.0;
436
437         Gvp.b= cp[2];
438         Gvp.b /= 255.0;
439
440         allqueue(REDRAWBUTSEDIT, 0);
441         addqueue(curarea->win, REDRAW, 1); // needed for when panel is open...
442 }
443
444 void init_vertexpaint()
445 {
446         
447         indexar= MEM_mallocN(sizeof(int)*MAXINDEX + 2, "vertexpaint");
448 }
449
450
451 void free_vertexpaint()
452 {
453         
454         if(indexar) MEM_freeN(indexar);
455         indexar= NULL;
456         if(vpaintundobuf) MEM_freeN(vpaintundobuf);
457         vpaintundobuf= NULL;
458         if(wpaintundobuf) 
459                 free_dverts(wpaintundobuf, totwpaintundo);
460         wpaintundobuf= NULL;
461         
462         mesh_octree_table(NULL, NULL, 'e');
463 }
464
465
466 static unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac)
467 {
468         char *cp1, *cp2, *cp;
469         int mfac;
470         unsigned int col=0;
471         
472         if(fac==0) return col1;
473         if(fac>=255) return col2;
474
475         mfac= 255-fac;
476         
477         cp1= (char *)&col1;
478         cp2= (char *)&col2;
479         cp=  (char *)&col;
480         
481         cp[0]= 255;
482         cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8;
483         cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8;
484         cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8;
485         
486         return col;
487 }
488
489 static unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac)
490 {
491         char *cp1, *cp2, *cp;
492         int temp;
493         unsigned int col=0;
494         
495         if(fac==0) return col1;
496         
497         cp1= (char *)&col1;
498         cp2= (char *)&col2;
499         cp=  (char *)&col;
500         
501         cp[0]= 255;
502         temp= cp1[1] + ((fac*cp2[1])>>8);
503         if(temp>254) cp[1]= 255; else cp[1]= temp;
504         temp= cp1[2] + ((fac*cp2[2])>>8);
505         if(temp>254) cp[2]= 255; else cp[2]= temp;
506         temp= cp1[3] + ((fac*cp2[3])>>8);
507         if(temp>254) cp[3]= 255; else cp[3]= temp;
508         
509         return col;
510 }
511
512 static unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac)
513 {
514         char *cp1, *cp2, *cp;
515         int temp;
516         unsigned int col=0;
517         
518         if(fac==0) return col1;
519         
520         cp1= (char *)&col1;
521         cp2= (char *)&col2;
522         cp=  (char *)&col;
523         
524         cp[0]= 255;
525         temp= cp1[1] - ((fac*cp2[1])>>8);
526         if(temp<0) cp[1]= 0; else cp[1]= temp;
527         temp= cp1[2] - ((fac*cp2[2])>>8);
528         if(temp<0) cp[2]= 0; else cp[2]= temp;
529         temp= cp1[3] - ((fac*cp2[3])>>8);
530         if(temp<0) cp[3]= 0; else cp[3]= temp;
531         
532         return col;
533 }
534
535 static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac)
536 {
537         char *cp1, *cp2, *cp;
538         int mfac;
539         unsigned int col=0;
540         
541         if(fac==0) return col1;
542
543         mfac= 255-fac;
544         
545         cp1= (char *)&col1;
546         cp2= (char *)&col2;
547         cp=  (char *)&col;
548         
549         /* first mul, then blend the fac */
550         cp[0]= 255;
551         cp[1]= (mfac*cp1[1] + fac*((cp2[1]*cp1[1])>>8)  )>>8;
552         cp[2]= (mfac*cp1[2] + fac*((cp2[2]*cp1[2])>>8)  )>>8;
553         cp[3]= (mfac*cp1[3] + fac*((cp2[3]*cp1[3])>>8)  )>>8;
554
555         
556         return col;
557 }
558
559 static void vpaint_blend( unsigned int *col, unsigned int *colorig, unsigned int paintcol, int alpha)
560 {
561
562         if(Gvp.mode==VP_MIX || Gvp.mode==VP_FILT) *col= mcol_blend( *col, paintcol, alpha);
563         else if(Gvp.mode==VP_ADD) *col= mcol_add( *col, paintcol, alpha);
564         else if(Gvp.mode==VP_SUB) *col= mcol_sub( *col, paintcol, alpha);
565         else if(Gvp.mode==VP_MUL) *col= mcol_mul( *col, paintcol, alpha);
566         
567         /* if no spray, clip color adding with colorig & orig alpha */
568         if((Gvp.flag & VP_SPRAY)==0) {
569                 unsigned int testcol=0, a;
570                 char *cp, *ct, *co;
571                 
572                 alpha= (int)(255.0*Gvp.a);
573                 
574                 if(Gvp.mode==VP_MIX || Gvp.mode==VP_FILT) testcol= mcol_blend( *colorig, paintcol, alpha);
575                 else if(Gvp.mode==VP_ADD) testcol= mcol_add( *colorig, paintcol, alpha);
576                 else if(Gvp.mode==VP_SUB) testcol= mcol_sub( *colorig, paintcol, alpha);
577                 else if(Gvp.mode==VP_MUL) testcol= mcol_mul( *colorig, paintcol, alpha);
578                 
579                 cp= (char *)col;
580                 ct= (char *)&testcol;
581                 co= (char *)colorig;
582                 
583                 for(a=0; a<4; a++) {
584                         if( ct[a]<co[a] ) {
585                                 if( cp[a]<ct[a] ) cp[a]= ct[a];
586                                 else if( cp[a]>co[a] ) cp[a]= co[a];
587                         }
588                         else {
589                                 if( cp[a]<co[a] ) cp[a]= co[a];
590                                 else if( cp[a]>ct[a] ) cp[a]= ct[a];
591                         }
592                 }
593         }
594 }
595
596
597 static int sample_backbuf_area(int x, int y, float size)
598 {
599         unsigned int *rt;
600         struct ImBuf *ibuf;
601         int x1, y1, x2, y2, a, tot=0, index;
602         
603         if(totvpaintundo>=MAXINDEX) return 0;
604         
605         if(size>64.0) size= 64.0;
606         
607         x1= x-size;
608         x2= x+size;
609         CLAMP(x1, 0, curarea->winx-1);
610         CLAMP(x2, 0, curarea->winx-1);
611         y1= y-size;
612         y2= y+size;
613         CLAMP(y1, 0, curarea->winy-1);
614         CLAMP(y2, 0, curarea->winy-1);
615 #ifdef __APPLE__
616         glReadBuffer(GL_AUX0);
617 #endif
618         
619         if(x1>=x2 || y1>=y2) return 0;
620         
621         ibuf = IMB_allocImBuf(2*size + 4, 2*size + 4, 32, IB_rect, 0);
622         glReadPixels(x1+curarea->winrct.xmin, y1+curarea->winrct.ymin, x2-x1+1, y2-y1+1, GL_RGBA, GL_UNSIGNED_BYTE,  ibuf->rect);
623         glReadBuffer(GL_BACK);  
624
625         if(G.order==B_ENDIAN)  {
626                 IMB_convert_rgba_to_abgr(ibuf);
627         }
628
629         rt= ibuf->rect;
630         size= (y2-y1)*(x2-x1);
631         if(size<=0) return 0;
632
633         memset(indexar, 0, sizeof(int)*totvpaintundo+2);        /* plus 2! first element is total */
634         
635         while(size--) {
636                         
637                 if(*rt) {
638                         index= framebuffer_to_index(*rt);
639                         if(index>0 && index<=totvpaintundo)
640                                 indexar[index] = 1;
641                 }
642         
643                 rt++;
644         }
645         
646         for(a=1; a<=totvpaintundo; a++) {
647                 if(indexar[a]) indexar[tot++]= a;
648         }
649
650         IMB_freeImBuf(ibuf);
651         
652         return tot;
653 }
654
655 static unsigned int sample_backbuf(int x, int y)
656 {
657         unsigned int col;
658         
659         if(x>=curarea->winx || y>=curarea->winy) return 0;
660         
661         x+= curarea->winrct.xmin;
662         y+= curarea->winrct.ymin;
663
664 #ifdef __APPLE__
665         glReadBuffer(GL_AUX0);
666 #endif
667         glReadPixels(x,  y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,  &col);
668         glReadBuffer(GL_BACK);  
669
670         if(G.order==B_ENDIAN) SWITCH_INT(col);
671                 
672         return framebuffer_to_index(col);
673 }
674
675 static int calc_vp_alpha_dl(VPaint *vp, float *vert_nor, short *mval)
676 {
677         float fac, dx, dy;
678         int alpha;
679         short vertco[2];
680         
681         if(vp->flag & VP_SOFT) {
682                 project_short_noclip(vert_nor, vertco);
683                 dx= mval[0]-vertco[0];
684                 dy= mval[1]-vertco[1];
685                 
686                 fac= sqrt(dx*dx + dy*dy);
687                 if(fac > vp->size) return 0;
688
689                 alpha= 255.0*vp->a*(1.0-fac/vp->size);
690         }
691         else {
692                 alpha= 255.0*vp->a;
693         }
694
695         if(vp->flag & VP_NORMALS) {
696                 float *no= vert_nor+3;
697                 
698                         /* transpose ! */
699                 fac= vpimat[2][0]*no[0]+vpimat[2][1]*no[1]+vpimat[2][2]*no[2];
700                 if(fac>0.0) {
701                         dx= vpimat[0][0]*no[0]+vpimat[0][1]*no[1]+vpimat[0][2]*no[2];
702                         dy= vpimat[1][0]*no[0]+vpimat[1][1]*no[1]+vpimat[1][2]*no[2];
703                         
704                         alpha*= fac/sqrt(dx*dx + dy*dy + fac*fac);
705                 }
706                 else return 0;
707         }
708         
709         return alpha;
710 }
711
712
713 void wpaint_undo (void)
714 {
715         Object *ob= OBACT;
716         Mesh    *me;
717         MDeformVert *swapbuf;
718
719         me = get_mesh(ob);
720         if (!me)
721                 return;
722
723         if (!wpaintundobuf)
724                 return;
725
726         if (!me->dvert)
727                 return;
728
729         if (totwpaintundo != me->totvert)
730                 return;
731
732         swapbuf= me->dvert;
733
734         /* copy undobuf to mesh */
735         me->dvert= MEM_mallocN(sizeof(MDeformVert)*me->totvert, "deformVert");
736         copy_dverts(me->dvert, wpaintundobuf, totwpaintundo);
737         
738         /* copy previous mesh to undo */
739         free_dverts(wpaintundobuf, me->totvert);
740         wpaintundobuf= MEM_mallocN(sizeof(MDeformVert)*me->totvert, "wpaintundo");
741         copy_dverts(wpaintundobuf, swapbuf, totwpaintundo);
742         
743         /* now free previous mesh dverts */
744         free_dverts(swapbuf, me->totvert);
745
746         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
747         DAG_object_flush_update(G.scene, modifiers_isDeformedByArmature(ob), OB_RECALC_DATA);
748         scrarea_do_windraw(curarea);
749         
750 }
751
752 void copy_wpaint_undo (MDeformVert *dverts, int dcount)
753 {
754         if (wpaintundobuf)
755                 free_dverts(wpaintundobuf, totwpaintundo);
756
757         wpaintundobuf = MEM_mallocN (sizeof(MDeformVert)*dcount, "wpaintundo");
758         totwpaintundo = dcount;
759         copy_dverts (wpaintundobuf, dverts, dcount);
760 }
761
762 static void wpaint_blend(MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval)
763 {
764         
765         if(dw==NULL || uw==NULL) return;
766         
767         if(Gwp.mode==VP_MIX || Gwp.mode==VP_FILT)
768                 dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
769         else if(Gwp.mode==VP_ADD)
770                 dw->weight += paintval*alpha;
771         else if(Gwp.mode==VP_SUB) 
772                 dw->weight -= paintval*alpha;
773         else if(Gwp.mode==VP_MUL) 
774                 /* first mul, then blend the fac */
775                 dw->weight = ((1.0-alpha) + alpha*paintval)*dw->weight;
776         
777         CLAMP(dw->weight, 0.0f, 1.0f);
778         
779         /* if no spray, clip result with orig weight & orig alpha */
780         if((Gwp.flag & VP_SPRAY)==0) {
781                 float testw=0.0f;
782                 
783                 alpha= Gwp.a;
784                 
785                 if(Gwp.mode==VP_MIX || Gwp.mode==VP_FILT)
786                         testw = paintval*alpha + uw->weight*(1.0-alpha);
787                 else if(Gwp.mode==VP_ADD)
788                         testw = uw->weight + paintval*alpha;
789                 else if(Gwp.mode==VP_SUB) 
790                         testw = uw->weight - paintval*alpha;
791                 else if(Gwp.mode==VP_MUL) 
792                         /* first mul, then blend the fac */
793                         testw = ((1.0-alpha) + alpha*paintval)*uw->weight;
794                 
795                 CLAMP(testw, 0.0f, 1.0f);
796                 
797                 if( testw<uw->weight ) {
798                         if(dw->weight < testw) dw->weight= testw;
799                         else if(dw->weight > uw->weight) dw->weight= uw->weight;
800                 }
801                 else {
802                         if(dw->weight > testw) dw->weight= testw;
803                         else if(dw->weight < uw->weight) dw->weight= uw->weight;
804                 }
805         }
806         
807 }
808
809 static MDeformWeight *get_defweight(MDeformVert *dv, int defgroup)
810 {
811         int i;
812         for (i=0; i<dv->totweight; i++){
813                 if (dv->dw[i].def_nr == defgroup)
814                         return dv->dw+i;
815         }
816         return NULL;
817 }
818
819 /* ----------------------------------------------------- */
820
821 /* used for 3d view, on active object, assumes me->dvert exists */
822 /* if mode==1: */
823 /*     samples cursor location, and gives menu with vertex groups to activate */
824 /* else */
825 /*     sets editbutvweight to the closest weight value to vertex */
826 /*     note: we cant sample frontbuf, weight colors are interpolated too unpredictable */
827 static void sample_wpaint(int mode)
828 {
829         Object *ob= OBACT;
830         Mesh *me= get_mesh(ob);
831         int index;
832         short mval[2], sco[2];
833         
834         getmouseco_areawin(mval);
835         index= sample_backbuf(mval[0], mval[1]);
836         
837         if(index && index<=me->totface) {
838                 MFace *mface;
839                 
840                 mface= ((MFace *)me->mface) + index-1;
841                 
842                 if(mode==1) {   /* sampe which groups are in here */
843                         MDeformVert *dv;
844                         int a, totgroup;
845                         
846                         totgroup= BLI_countlist(&ob->defbase);
847                         if(totgroup) {
848                                 int totmenu=0;
849                                 int *groups=MEM_callocN(totgroup*sizeof(int), "groups");
850                                 
851                                 dv= me->dvert+mface->v1;
852                                 for(a=0; a<dv->totweight; a++) {
853                                         if (dv->dw[a].def_nr<totgroup)
854                                                 groups[dv->dw[a].def_nr]= 1;
855                                 }
856                                 dv= me->dvert+mface->v2;
857                                 for(a=0; a<dv->totweight; a++) {
858                                         if (dv->dw[a].def_nr<totgroup)
859                                                 groups[dv->dw[a].def_nr]= 1;
860                                 }
861                                 dv= me->dvert+mface->v3;
862                                 for(a=0; a<dv->totweight; a++) {
863                                         if (dv->dw[a].def_nr<totgroup)
864                                                 groups[dv->dw[a].def_nr]= 1;
865                                 }
866                                 if(mface->v4) {
867                                         dv= me->dvert+mface->v4;
868                                         for(a=0; a<dv->totweight; a++) {
869                                                 if (dv->dw[a].def_nr<totgroup)
870                                                         groups[dv->dw[a].def_nr]= 1;
871                                         }
872                                 }
873                                 for(a=0; a<totgroup; a++)
874                                         if(groups[a]) totmenu++;
875                                 
876                                 if(totmenu==0) {
877                                         notice("No Vertex Group Selected");
878                                 }
879                                 else {
880                                         bDeformGroup *dg;
881                                         short val;
882                                         char item[40], *str= MEM_mallocN(40*totmenu+40, "menu");
883                                         
884                                         strcpy(str, "Vertex Groups %t");
885                                         for(a=0, dg=ob->defbase.first; dg && a<totgroup; a++, dg= dg->next) {
886                                                 if(groups[a]) {
887                                                         sprintf(item, "|%s %%x%d", dg->name, a);
888                                                         strcat(str, item);
889                                                 }
890                                         }
891                                         
892                                         val= pupmenu(str);
893                                         if(val>=0) {
894                                                 ob->actdef= val+1;
895                                                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
896                                                 allqueue(REDRAWVIEW3D, 0);
897                                                 allqueue(REDRAWOOPS, 0);
898                                                 allqueue(REDRAWBUTSEDIT, 0);
899                                         }
900                                         MEM_freeN(str);
901                                 }
902                                 MEM_freeN(groups);
903                         }
904                         else notice("No Vertex Groups in Object");
905                 }
906                 else {
907                         DerivedMesh *dm;
908                         MDeformWeight *dw;
909                         extern float editbutvweight;
910                         float w1, w2, w3, w4, co[3], fac;
911                         int needsFree;
912                         
913                         dm = mesh_get_derived_final(ob, &needsFree);
914                         if(dm->getVertCo==NULL) {
915                                 notice("Not supported yet");
916                         }
917                         else {
918                                 /* calc 3 or 4 corner weights */
919                                 dm->getVertCo(dm, mface->v1, co);
920                                 project_short_noclip(co, sco);
921                                 w1= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
922                                 
923                                 dm->getVertCo(dm, mface->v2, co);
924                                 project_short_noclip(co, sco);
925                                 w2= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
926                                 
927                                 dm->getVertCo(dm, mface->v3, co);
928                                 project_short_noclip(co, sco);
929                                 w3= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
930                                 
931                                 if(mface->v4) {
932                                         dm->getVertCo(dm, mface->v4, co);
933                                         project_short_noclip(co, sco);
934                                         w4= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
935                                 }
936                                 else w4= 1.0e10;
937                                 
938                                 fac= MIN4(w1, w2, w3, w4);
939                                 if(w1==fac) {
940                                         dw= get_defweight(me->dvert+mface->v1, ob->actdef-1);
941                                         if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
942                                 }
943                                 else if(w2==fac) {
944                                         dw= get_defweight(me->dvert+mface->v2, ob->actdef-1);
945                                         if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
946                                 }
947                                 else if(w3==fac) {
948                                         dw= get_defweight(me->dvert+mface->v3, ob->actdef-1);
949                                         if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
950                                 }
951                                 else if(w4==fac) {
952                                         if(mface->v4) {
953                                                 dw= get_defweight(me->dvert+mface->v4, ob->actdef-1);
954                                                 if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
955                                         }
956                                 }
957                                 if (needsFree)
958                                         dm->release(dm);
959                         }
960                 }               
961                 
962         }
963         allqueue(REDRAWBUTSEDIT, 0);
964         
965 }
966
967 static void do_weight_paint_vertex(Object *ob, int index, int alpha, float paintweight, int vgroup_mirror)
968 {
969         Mesh *me= ob->data;
970         MDeformWeight   *dw, *uw;
971         int vgroup= ob->actdef-1;
972         
973         dw= verify_defweight(me->dvert+index, vgroup);
974         uw= verify_defweight(wpaintundobuf+index, vgroup);
975         wpaint_blend(dw, uw, (float)alpha/255.0, paintweight);
976         
977         if(Gwp.flag & VP_MIRROR_X) {    /* x mirror painting */
978                 int j= mesh_get_x_mirror_vert(ob, index);
979                 if(j>=0) {
980                         /* copy, not paint again */
981                         if(vgroup_mirror != -1)
982                                 uw= verify_defweight(me->dvert+j, vgroup_mirror);
983                         else
984                                 uw= verify_defweight(me->dvert+j, vgroup);
985                                 
986                         uw->weight= dw->weight;
987                 }
988         }
989 }
990
991 void weight_paint(void)
992 {
993         extern float editbutvweight;
994         Object *ob; 
995         Mesh *me;
996         MFace *mface;
997         TFace *tface;
998         float mat[4][4], imat[4][4], paintweight, *vertexcosnos;
999         int index, totindex, alpha, totw;
1000         int vgroup_mirror= -1;
1001         short mval[2], mvalo[2], firsttime=1, mousebut;
1002
1003         if((G.f & G_WEIGHTPAINT)==0) return;
1004         if(G.obedit) return;
1005         
1006         if(indexar==NULL) init_vertexpaint();
1007         
1008         ob= OBACT;
1009         if(ob->id.lib) return;
1010
1011         me= get_mesh(ob);
1012         if(me==NULL || me->totface==0) return;
1013         
1014         /* if nothing was added yet, we make dverts and a vertex deform group */
1015         if (!me->dvert)
1016                 create_dverts(me);
1017         
1018         if(G.qual & LR_CTRLKEY) {
1019                 sample_wpaint(0);
1020                 return;
1021         }
1022         if(G.qual & LR_SHIFTKEY) {
1023                 sample_wpaint(1);
1024                 return;
1025         }
1026         
1027         /* painting on subsurfs should give correct points too, this returns me->totvert amount */
1028         vertexcosnos= mesh_get_mapped_verts_nors(ob);
1029         
1030         /* this happens on a Bone select, when no vgroup existed yet */
1031         if(ob->actdef<=0) {
1032                 Object *modob;
1033                 if((modob = modifiers_isDeformedByArmature(ob))) {
1034                         bPoseChannel *pchan;
1035                         for(pchan= modob->pose->chanbase.first; pchan; pchan= pchan->next)
1036                                 if(pchan->bone->flag & SELECT)
1037                                         break;
1038                         if(pchan) {
1039                                 bDeformGroup *dg= get_named_vertexgroup(ob, pchan->name);
1040                                 if(dg==NULL)
1041                                         dg= add_defgroup_name(ob, pchan->name); // sets actdef
1042                                 else
1043                                         ob->actdef= get_defgroup_num(ob, dg);
1044                                 allqueue(REDRAWBUTSEDIT, 0);
1045                         }
1046                 }
1047         }
1048         if(ob->defbase.first==NULL) {
1049                 add_defgroup(ob);
1050                 allqueue(REDRAWBUTSEDIT, 0);
1051         }       
1052         
1053         if(ob->lay & G.vd->lay); else error("Active object is not in this layer");
1054         
1055         persp(PERSP_VIEW);
1056         /* imat for normals */
1057         Mat4MulMat4(mat, ob->obmat, G.vd->viewmat);
1058         Mat4Invert(imat, mat);
1059         Mat3CpyMat4(vpimat, imat);
1060         
1061         /* load projection matrix */
1062         mymultmatrix(ob->obmat);
1063         mygetsingmatrix(mat);
1064         myloadmatrix(G.vd->viewmat);
1065         
1066         getmouseco_areawin(mvalo);
1067         
1068         if(me->tface) tface_to_mcol(me);
1069         copy_vpaint_undo( (unsigned int *)me->mcol, me->totface);
1070         copy_wpaint_undo(me->dvert, me->totvert);
1071         
1072         getmouseco_areawin(mval);
1073         mvalo[0]= mval[0];
1074         mvalo[1]= mval[1];
1075         
1076         if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE;
1077         else mousebut = L_MOUSE;
1078         
1079         /* if mirror painting, find the other group */                  
1080         if(Gwp.flag & VP_MIRROR_X) {
1081                 bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1);
1082                 if(defgroup) {
1083                         bDeformGroup *curdef;
1084                         int actdef= 0;
1085                         char name[32];
1086
1087                         BLI_strncpy(name, defgroup->name, 32);
1088                         bone_flip_name(name, 0);                // 0 = don't strip off number extensions
1089                         
1090                         for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++)
1091                                 if (!strcmp(curdef->name, name))
1092                                         break;
1093                         if(curdef==NULL) {
1094                                 int olddef= ob->actdef; /* tsk, add_defgroup sets the active defgroup */
1095                                 curdef= add_defgroup_name (ob, name);
1096                                 ob->actdef= olddef;
1097                         }
1098                         
1099                         if(curdef && curdef!=defgroup)
1100                                 vgroup_mirror= actdef;
1101                 }
1102         }
1103         
1104         while (get_mbut() & mousebut) {
1105                 getmouseco_areawin(mval);
1106                 
1107                 if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
1108                         firsttime= 0;
1109                         
1110                         /* which faces are involved */
1111                         if(Gwp.flag & VP_AREA) {
1112                                 totindex= sample_backbuf_area(mval[0], mval[1], Gwp.size);
1113                         }
1114                         else {
1115                                 indexar[0]= sample_backbuf(mval[0], mval[1]);
1116                                 if(indexar[0]) totindex= 1;
1117                                 else totindex= 0;
1118                         }
1119                         
1120                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1121                         
1122                         if(Gwp.flag & VP_COLINDEX) {
1123                                 for(index=0; index<totindex; index++) {
1124                                         if(indexar[index] && indexar[index]<=me->totface) {
1125                                         
1126                                                 mface= ((MFace *)me->mface) + (indexar[index]-1);
1127                                         
1128                                                 if(mface->mat_nr!=ob->actcol-1) {
1129                                                         indexar[index]= 0;
1130                                                 }
1131                                         }                                       
1132                                 }
1133                         }
1134
1135                         if((G.f & G_FACESELECT) && me->tface) {
1136                                 for(index=0; index<totindex; index++) {
1137                                         if(indexar[index] && indexar[index]<=me->totface) {
1138                                         
1139                                                 tface= ((TFace *)me->tface) + (indexar[index]-1);
1140                                         
1141                                                 if((tface->flag & TF_SELECT)==0) {
1142                                                         indexar[index]= 0;
1143                                                 }
1144                                         }                                       
1145                                 }
1146                         }
1147                         
1148                         /* make sure each vertex gets treated only once */
1149                         /* and calculate filter weight */
1150                         totw= 0;
1151                         if(Gwp.mode==VP_FILT) 
1152                                 paintweight= 0.0f;
1153                         else
1154                                 paintweight= editbutvweight;
1155                         
1156                         for(index=0; index<totindex; index++) {
1157                                 if(indexar[index] && indexar[index]<=me->totface) {
1158                                         mface= me->mface + (indexar[index]-1);
1159                                         
1160                                         (me->dvert+mface->v1)->flag= 1;
1161                                         (me->dvert+mface->v2)->flag= 1;
1162                                         (me->dvert+mface->v3)->flag= 1;
1163                                         if(mface->v4) (me->dvert+mface->v4)->flag= 1;
1164                                         
1165                                         if(Gwp.mode==VP_FILT) {
1166                                                 MDeformWeight *dw;
1167                                                 dw= verify_defweight(me->dvert+mface->v1, ob->actdef-1);
1168                                                 if(dw) {paintweight+= dw->weight; totw++;}
1169                                                 dw= verify_defweight(me->dvert+mface->v2, ob->actdef-1);
1170                                                 if(dw) {paintweight+= dw->weight; totw++;}
1171                                                 dw= verify_defweight(me->dvert+mface->v3, ob->actdef-1);
1172                                                 if(dw) {paintweight+= dw->weight; totw++;}
1173                                                 if(mface->v4) {
1174                                                         dw= verify_defweight(me->dvert+mface->v4, ob->actdef-1);
1175                                                         if(dw) {paintweight+= dw->weight; totw++;}
1176                                                 }
1177                                         }
1178                                 }
1179                         }
1180                         
1181                         if(Gwp.mode==VP_FILT) 
1182                                 paintweight/= (float)totw;
1183                         
1184                         for(index=0; index<totindex; index++) {
1185                                 
1186                                 if(indexar[index] && indexar[index]<=me->totface) {
1187                                         mface= me->mface + (indexar[index]-1);
1188                                         
1189                                         if((me->dvert+mface->v1)->flag) {
1190                                                 alpha= calc_vp_alpha_dl(&Gwp, vertexcosnos+6*mface->v1, mval);
1191                                                 if(alpha) {
1192                                                         do_weight_paint_vertex(ob, mface->v1, alpha, paintweight, vgroup_mirror);
1193                                                 }
1194                                                 (me->dvert+mface->v1)->flag= 0;
1195                                         }
1196                                         
1197                                         if((me->dvert+mface->v2)->flag) {
1198                                                 alpha= calc_vp_alpha_dl(&Gwp, vertexcosnos+6*mface->v2, mval);
1199                                                 if(alpha) {
1200                                                         do_weight_paint_vertex(ob, mface->v2, alpha, paintweight, vgroup_mirror);
1201                                                 }
1202                                                 (me->dvert+mface->v2)->flag= 0;
1203                                         }
1204                                         
1205                                         if((me->dvert+mface->v3)->flag) {
1206                                                 alpha= calc_vp_alpha_dl(&Gwp, vertexcosnos+6*mface->v3, mval);
1207                                                 if(alpha) {
1208                                                         do_weight_paint_vertex(ob, mface->v3, alpha, paintweight, vgroup_mirror);
1209                                                 }
1210                                                 (me->dvert+mface->v3)->flag= 0;
1211                                         }
1212                                         
1213                                         if((me->dvert+mface->v4)->flag) {
1214                                                 if(mface->v4) {
1215                                                         alpha= calc_vp_alpha_dl(&Gwp, vertexcosnos+6*mface->v4, mval);
1216                                                         if(alpha) {
1217                                                                 do_weight_paint_vertex(ob, mface->v4, alpha, paintweight, vgroup_mirror);
1218                                                         }
1219                                                         (me->dvert+mface->v4)->flag= 0;
1220                                                 }
1221                                         }
1222                                 }
1223                         }
1224                         
1225                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1226                         
1227                 }
1228                 else BIF_wait_for_statechange();
1229                 
1230                 if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
1231
1232                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1233                         scrarea_do_windraw(curarea);
1234                         
1235                         if(Gwp.flag & (VP_AREA|VP_SOFT)) {
1236                                 /* draw circle in backbuf! */
1237                                 persp(PERSP_WIN);
1238                                 fdrawXORcirc((float)mval[0], (float)mval[1], Gwp.size);
1239                                 persp(PERSP_VIEW);
1240                         }
1241
1242                         screen_swapbuffers();
1243                         backdrawview3d(0);
1244         
1245                         mvalo[0]= mval[0];
1246                         mvalo[1]= mval[1];
1247                 }
1248         }
1249         
1250         if(me->tface) {
1251                 MEM_freeN(me->mcol);
1252                 me->mcol= 0;
1253         }
1254         if(vertexcosnos)
1255                 MEM_freeN(vertexcosnos);
1256         
1257         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1258         // this flag is event for softbody to refresh weightpaint values
1259         if(ob->soft) ob->softflag |= OB_SB_REDO;
1260         
1261         allqueue(REDRAWVIEW3D, 0);
1262 }
1263
1264 void vertex_paint()
1265 {
1266         Object *ob;
1267         Mesh *me;
1268         MFace *mface;
1269         TFace *tface;
1270         float mat[4][4], imat[4][4], *vertexcosnos;
1271         unsigned int paintcol=0, *mcol, *mcolorig, fcol1, fcol2;
1272         int index, alpha, totindex;
1273         short mval[2], mvalo[2], firsttime=1, mousebut;
1274         
1275         if((G.f & G_VERTEXPAINT)==0) return;
1276         if(G.obedit) return;
1277         
1278         if(indexar==NULL) init_vertexpaint();
1279         
1280         ob= OBACT;
1281         if(ob->id.lib) return;
1282
1283         me= get_mesh(ob);
1284         if(me==NULL || me->totface==0) return;
1285         if(ob->lay & G.vd->lay); else error("Active object is not in this layer");
1286         
1287         if(me->tface==NULL && me->mcol==NULL) make_vertexcol();
1288
1289         if(me->tface==NULL && me->mcol==NULL) return;
1290         
1291         /* painting on subsurfs should give correct points too, this returns me->totvert amount */
1292         vertexcosnos= mesh_get_mapped_verts_nors(ob);
1293         
1294         persp(PERSP_VIEW);
1295         /* imat for normals */
1296         Mat4MulMat4(mat, ob->obmat, G.vd->viewmat);
1297         Mat4Invert(imat, mat);
1298         Mat3CpyMat4(vpimat, imat);
1299         
1300         /* load projection matrix */
1301         mymultmatrix(ob->obmat);
1302         mygetsingmatrix(mat);
1303         myloadmatrix(G.vd->viewmat);
1304         
1305         paintcol= vpaint_get_current_col();
1306         
1307         getmouseco_areawin(mvalo);
1308         
1309         if(me->tface) tface_to_mcol(me);
1310         copy_vpaint_undo( (unsigned int *)me->mcol, me->totface);
1311         
1312         getmouseco_areawin(mval);
1313         mvalo[0]= mval[0];
1314         mvalo[1]= mval[1];
1315         
1316         if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE;
1317         else mousebut = L_MOUSE;
1318         
1319         while (get_mbut() & mousebut) {
1320                 getmouseco_areawin(mval);
1321                 
1322                 if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
1323
1324                         firsttime= 0;
1325
1326                         /* which faces are involved */
1327                         if(Gvp.flag & VP_AREA) {
1328                                 totindex= sample_backbuf_area(mval[0], mval[1], Gvp.size);
1329                         }
1330                         else {
1331                                 indexar[0]= sample_backbuf(mval[0], mval[1]);
1332                                 if(indexar[0]) totindex= 1;
1333                                 else totindex= 0;
1334                         }
1335                         
1336                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1337                         
1338                         if(Gvp.flag & VP_COLINDEX) {
1339                                 for(index=0; index<totindex; index++) {
1340                                         if(indexar[index] && indexar[index]<=me->totface) {
1341                                         
1342                                                 mface= ((MFace *)me->mface) + (indexar[index]-1);
1343                                         
1344                                                 if(mface->mat_nr!=ob->actcol-1) {
1345                                                         indexar[index]= 0;
1346                                                 }
1347                                         }                                       
1348                                 }
1349                         }
1350                         if((G.f & G_FACESELECT) && me->tface) {
1351                                 for(index=0; index<totindex; index++) {
1352                                         if(indexar[index] && indexar[index]<=me->totface) {
1353                                         
1354                                                 tface= ((TFace *)me->tface) + (indexar[index]-1);
1355                                         
1356                                                 if((tface->flag & TF_SELECT)==0) {
1357                                                         indexar[index]= 0;
1358                                                 }
1359                                         }                                       
1360                                 }
1361                         }
1362
1363                         for(index=0; index<totindex; index++) {
1364
1365                                 if(indexar[index] && indexar[index]<=me->totface) {
1366                                 
1367                                         mface= ((MFace *)me->mface) + (indexar[index]-1);
1368                                         mcol=     ( (unsigned int *)me->mcol) + 4*(indexar[index]-1);
1369                                         mcolorig= ( (unsigned int *)vpaintundobuf) + 4*(indexar[index]-1);
1370
1371                                         if(Gvp.mode==VP_FILT) {
1372                                                 fcol1= mcol_blend( mcol[0], mcol[1], 128);
1373                                                 if(mface->v4) {
1374                                                         fcol2= mcol_blend( mcol[2], mcol[3], 128);
1375                                                         paintcol= mcol_blend( fcol1, fcol2, 128);
1376                                                 }
1377                                                 else {
1378                                                         paintcol= mcol_blend( mcol[2], fcol1, 170);
1379                                                 }
1380                                                 
1381                                         }
1382                                         
1383                                         alpha= calc_vp_alpha_dl(&Gvp, vertexcosnos+6*mface->v1, mval);
1384                                         if(alpha) vpaint_blend( mcol, mcolorig, paintcol, alpha);
1385                                         
1386                                         alpha= calc_vp_alpha_dl(&Gvp, vertexcosnos+6*mface->v2, mval);
1387                                         if(alpha) vpaint_blend( mcol+1, mcolorig+1, paintcol, alpha);
1388         
1389                                         alpha= calc_vp_alpha_dl(&Gvp, vertexcosnos+6*mface->v3, mval);
1390                                         if(alpha) vpaint_blend( mcol+2, mcolorig+2, paintcol, alpha);
1391
1392                                         if(mface->v4) {
1393                                                 alpha= calc_vp_alpha_dl(&Gvp, vertexcosnos+6*mface->v4, mval);
1394                                                 if(alpha) vpaint_blend( mcol+3, mcolorig+3, paintcol, alpha);
1395                                         }
1396                                 }
1397                         }
1398                                 
1399                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1400                         
1401                         do_shared_vertexcol(me);
1402                         if(me->tface) {
1403                                 mcol_to_tface(me, 0);
1404                         }
1405         
1406                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1407                         scrarea_do_windraw(curarea);
1408
1409                         if(Gvp.flag & (VP_AREA|VP_SOFT)) {
1410                                 /* draw circle in backbuf! */
1411                                 persp(PERSP_WIN);
1412                                 fdrawXORcirc((float)mval[0], (float)mval[1], Gvp.size);
1413                                 persp(PERSP_VIEW);
1414                         }
1415                         screen_swapbuffers();
1416                         backdrawview3d(0);
1417                         
1418                         mvalo[0]= mval[0];
1419                         mvalo[1]= mval[1];
1420                 }
1421                 else BIF_wait_for_statechange();
1422         }
1423         
1424         if(me->tface) {
1425                 MEM_freeN(me->mcol);
1426                 me->mcol= 0;
1427         }
1428         if(vertexcosnos)
1429                 MEM_freeN(vertexcosnos);
1430
1431         allqueue(REDRAWVIEW3D, 0);
1432 }
1433
1434 void set_wpaint(void)           /* toggle */
1435 {               
1436         Object *ob;
1437         Mesh *me;
1438         
1439         scrarea_queue_headredraw(curarea);
1440         ob= OBACT;
1441         if(ob->id.lib) return;
1442         me= get_mesh(ob);
1443                 
1444         if(me && me->totface>=MAXINDEX) {
1445                 error("Maximum number of faces: %d", MAXINDEX-1);
1446                 G.f &= ~G_WEIGHTPAINT;
1447                 return;
1448         }
1449         
1450         if(G.f & G_WEIGHTPAINT) G.f &= ~G_WEIGHTPAINT;
1451         else G.f |= G_WEIGHTPAINT;
1452         
1453         allqueue(REDRAWVIEW3D, 1);      /* including header */
1454         allqueue(REDRAWBUTSEDIT, 0);
1455         
1456                 /* Weightpaint works by overriding colors in mesh,
1457                  * so need to make sure we recalc on enter and
1458                  * exit (exit needs doing regardless because we
1459                  * should redeform).
1460                  */
1461         if (me) {
1462                 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1463         }
1464
1465         if(G.f & G_WEIGHTPAINT) {
1466                 Object *par;
1467                 
1468                 setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT);
1469                 
1470                 mesh_octree_table(ob, NULL, 's');
1471
1472                 /* verify if active weight group is also active bone */
1473                 par= modifiers_isDeformedByArmature(ob);
1474                 if(par && (par->flag & OB_POSEMODE)) {
1475                         bPoseChannel *pchan;
1476                         for(pchan= par->pose->chanbase.first; pchan; pchan= pchan->next)
1477                                 if(pchan->bone->flag & BONE_ACTIVE)
1478                                         break;
1479                         if(pchan)
1480                                 vertexgroup_select_by_name(ob, pchan->name);
1481                 }
1482         }
1483         else {
1484                 freefastshade();        /* to be sure */
1485                 if(!(G.f & G_FACESELECT))
1486                         setcursor_space(SPACE_VIEW3D, CURSOR_STD);
1487                 
1488                 mesh_octree_table(ob, NULL, 'e');
1489         }
1490 }
1491
1492
1493 void set_vpaint(void)           /* toggle */
1494 {               
1495         Object *ob;
1496         Mesh *me;
1497         
1498         scrarea_queue_headredraw(curarea);
1499         ob= OBACT;
1500         if(ob->id.lib) {
1501                 G.f &= ~G_VERTEXPAINT;
1502                 return;
1503         }
1504         
1505         me= get_mesh(ob);
1506         
1507         if(me && me->totface>=MAXINDEX) {
1508                 error("Maximum number of faces: %d", MAXINDEX-1);
1509                 G.f &= ~G_VERTEXPAINT;
1510                 return;
1511         }
1512         
1513         if(me && me->tface==NULL && me->mcol==NULL) make_vertexcol();
1514         
1515         if(G.f & G_VERTEXPAINT){
1516                 G.f &= ~G_VERTEXPAINT;
1517         }
1518         else {
1519                 G.f |= G_VERTEXPAINT;
1520                 /* Turn off weight painting */
1521                 if (G.f & G_WEIGHTPAINT)
1522                         set_wpaint();
1523         }
1524         
1525         allqueue(REDRAWVIEW3D, 1);      /* including header */
1526         allqueue(REDRAWBUTSEDIT, 0);
1527         
1528         if(G.f & G_VERTEXPAINT) {
1529                 setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT);
1530         }
1531         else {
1532                 freefastshade();        /* to be sure */
1533                 if (me) {
1534                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1535                 }
1536                 if((G.f & G_FACESELECT)==0) setcursor_space(SPACE_VIEW3D, CURSOR_STD);
1537         }
1538 }
1539