Final merge of HEAD (bf-blender) into the orange branch.
[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);
610         CLAMP(x2, 0, curarea->winx);
611         y1= y-size;
612         y2= y+size;
613         CLAMP(y1, 0, curarea->winy);
614         CLAMP(y2, 0, curarea->winy);
615 #ifdef __APPLE__
616         glReadBuffer(GL_AUX0);
617 #endif
618         ibuf = IMB_allocImBuf(2*size + 1, 2*size + 1, 32, IB_rect, 0);
619         glReadPixels(x1+curarea->winrct.xmin, y1+curarea->winrct.ymin, x2-x1+1, y2-y1+1, GL_RGBA, GL_UNSIGNED_BYTE,  ibuf->rect);
620         glReadBuffer(GL_BACK);  
621
622         if(G.order==B_ENDIAN)  {
623                 IMB_convert_rgba_to_abgr(ibuf);
624         }
625
626         rt= ibuf->rect;
627         size= (y2-y1)*(x2-x1);
628         if(size<=0) return 0;
629
630         memset(indexar, 0, sizeof(int)*totvpaintundo+2);        /* plus 2! first element is total */
631         
632         while(size--) {
633                         
634                 if(*rt) {
635                         index= framebuffer_to_index(*rt);
636                         if(index>0 && index<=totvpaintundo)
637                                 indexar[index] = 1;
638                 }
639         
640                 rt++;
641         }
642         
643         for(a=1; a<=totvpaintundo; a++) {
644                 if(indexar[a]) indexar[tot++]= a;
645         }
646
647         IMB_freeImBuf(ibuf);
648         
649         return tot;
650 }
651
652 static unsigned int sample_backbuf(int x, int y)
653 {
654         unsigned int col;
655         
656         if(x>=curarea->winx || y>=curarea->winy) return 0;
657         
658         x+= curarea->winrct.xmin;
659         y+= curarea->winrct.ymin;
660
661 #ifdef __APPLE__
662         glReadBuffer(GL_AUX0);
663 #endif
664         glReadPixels(x,  y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,  &col);
665         glReadBuffer(GL_BACK);  
666
667         if(G.order==B_ENDIAN) SWITCH_INT(col);
668                 
669         return framebuffer_to_index(col);
670 }
671
672 static int calc_vp_alpha_dl(VPaint *vp, float *vert_nor, short *mval)
673 {
674         float fac, dx, dy;
675         int alpha;
676         short vertco[2];
677         
678         if(vp->flag & VP_SOFT) {
679                 project_short_noclip(vert_nor, vertco);
680                 dx= mval[0]-vertco[0];
681                 dy= mval[1]-vertco[1];
682                 
683                 fac= sqrt(dx*dx + dy*dy);
684                 if(fac > vp->size) return 0;
685
686                 alpha= 255.0*vp->a*(1.0-fac/vp->size);
687         }
688         else {
689                 alpha= 255.0*vp->a;
690         }
691
692         if(vp->flag & VP_NORMALS) {
693                 float *no= vert_nor+3;
694                 
695                         /* transpose ! */
696                 fac= vpimat[2][0]*no[0]+vpimat[2][1]*no[1]+vpimat[2][2]*no[2];
697                 if(fac>0.0) {
698                         dx= vpimat[0][0]*no[0]+vpimat[0][1]*no[1]+vpimat[0][2]*no[2];
699                         dy= vpimat[1][0]*no[0]+vpimat[1][1]*no[1]+vpimat[1][2]*no[2];
700                         
701                         alpha*= fac/sqrt(dx*dx + dy*dy + fac*fac);
702                 }
703                 else return 0;
704         }
705         
706         return alpha;
707 }
708
709
710 void wpaint_undo (void)
711 {
712         Object *ob= OBACT;
713         Mesh    *me;
714         MDeformVert *swapbuf;
715
716         me = get_mesh(ob);
717         if (!me)
718                 return;
719
720         if (!wpaintundobuf)
721                 return;
722
723         if (!me->dvert)
724                 return;
725
726         if (totwpaintundo != me->totvert)
727                 return;
728
729         swapbuf= me->dvert;
730
731         /* copy undobuf to mesh */
732         me->dvert= MEM_mallocN(sizeof(MDeformVert)*me->totvert, "deformVert");
733         copy_dverts(me->dvert, wpaintundobuf, totwpaintundo);
734         
735         /* copy previous mesh to undo */
736         free_dverts(wpaintundobuf, me->totvert);
737         wpaintundobuf= MEM_mallocN(sizeof(MDeformVert)*me->totvert, "wpaintundo");
738         copy_dverts(wpaintundobuf, swapbuf, totwpaintundo);
739         
740         /* now free previous mesh dverts */
741         free_dverts(swapbuf, me->totvert);
742
743         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
744         DAG_object_flush_update(G.scene, modifiers_isDeformedByArmature(ob), OB_RECALC_DATA);
745         scrarea_do_windraw(curarea);
746         
747 }
748
749 void copy_wpaint_undo (MDeformVert *dverts, int dcount)
750 {
751         if (wpaintundobuf)
752                 free_dverts(wpaintundobuf, totwpaintundo);
753
754         wpaintundobuf = MEM_mallocN (sizeof(MDeformVert)*dcount, "wpaintundo");
755         totwpaintundo = dcount;
756         copy_dverts (wpaintundobuf, dverts, dcount);
757 }
758
759 static void wpaint_blend(MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval)
760 {
761         
762         if(dw==NULL || uw==NULL) return;
763         
764         if(Gwp.mode==VP_MIX || Gwp.mode==VP_FILT)
765                 dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
766         else if(Gwp.mode==VP_ADD)
767                 dw->weight += paintval*alpha;
768         else if(Gwp.mode==VP_SUB) 
769                 dw->weight -= paintval*alpha;
770         else if(Gwp.mode==VP_MUL) 
771                 /* first mul, then blend the fac */
772                 dw->weight = ((1.0-alpha) + alpha*paintval)*dw->weight;
773         
774         CLAMP(dw->weight, 0.0f, 1.0f);
775         
776         /* if no spray, clip result with orig weight & orig alpha */
777         if((Gwp.flag & VP_SPRAY)==0) {
778                 float testw=0.0f;
779                 
780                 alpha= Gwp.a;
781                 
782                 if(Gwp.mode==VP_MIX || Gwp.mode==VP_FILT)
783                         testw = paintval*alpha + uw->weight*(1.0-alpha);
784                 else if(Gwp.mode==VP_ADD)
785                         testw = uw->weight + paintval*alpha;
786                 else if(Gwp.mode==VP_SUB) 
787                         testw = uw->weight - paintval*alpha;
788                 else if(Gwp.mode==VP_MUL) 
789                         /* first mul, then blend the fac */
790                         testw = ((1.0-alpha) + alpha*paintval)*uw->weight;
791                 
792                 CLAMP(testw, 0.0f, 1.0f);
793                 
794                 if( testw<uw->weight ) {
795                         if(dw->weight < testw) dw->weight= testw;
796                         else if(dw->weight > uw->weight) dw->weight= uw->weight;
797                 }
798                 else {
799                         if(dw->weight > testw) dw->weight= testw;
800                         else if(dw->weight < uw->weight) dw->weight= uw->weight;
801                 }
802         }
803         
804 }
805
806 static MDeformWeight *get_defweight(MDeformVert *dv, int defgroup)
807 {
808         int i;
809         for (i=0; i<dv->totweight; i++){
810                 if (dv->dw[i].def_nr == defgroup)
811                         return dv->dw+i;
812         }
813         return NULL;
814 }
815
816 /* ----------------------------------------------------- */
817
818 /* used for 3d view, on active object, assumes me->dvert exists */
819 /* if mode==1: */
820 /*     samples cursor location, and gives menu with vertex groups to activate */
821 /* else */
822 /*     sets editbutvweight to the closest weight value to vertex */
823 /*     note: we cant sample frontbuf, weight colors are interpolated too unpredictable */
824 static void sample_wpaint(int mode)
825 {
826         Object *ob= OBACT;
827         Mesh *me= get_mesh(ob);
828         int index;
829         short mval[2], sco[2];
830         
831         getmouseco_areawin(mval);
832         index= sample_backbuf(mval[0], mval[1]);
833         
834         if(index && index<=me->totface) {
835                 MFace *mface;
836                 
837                 mface= ((MFace *)me->mface) + index-1;
838                 
839                 if(mode==1) {   /* sampe which groups are in here */
840                         MDeformVert *dv;
841                         int a, totgroup;
842                         
843                         totgroup= BLI_countlist(&ob->defbase);
844                         if(totgroup) {
845                                 int totmenu=0;
846                                 int *groups=MEM_callocN(totgroup*sizeof(int), "groups");
847                                 
848                                 dv= me->dvert+mface->v1;
849                                 for(a=0; a<dv->totweight; a++) {
850                                         if (dv->dw[a].def_nr<totgroup)
851                                                 groups[dv->dw[a].def_nr]= 1;
852                                 }
853                                 dv= me->dvert+mface->v2;
854                                 for(a=0; a<dv->totweight; a++) {
855                                         if (dv->dw[a].def_nr<totgroup)
856                                                 groups[dv->dw[a].def_nr]= 1;
857                                 }
858                                 dv= me->dvert+mface->v3;
859                                 for(a=0; a<dv->totweight; a++) {
860                                         if (dv->dw[a].def_nr<totgroup)
861                                                 groups[dv->dw[a].def_nr]= 1;
862                                 }
863                                 if(mface->v4) {
864                                         dv= me->dvert+mface->v4;
865                                         for(a=0; a<dv->totweight; a++) {
866                                                 if (dv->dw[a].def_nr<totgroup)
867                                                         groups[dv->dw[a].def_nr]= 1;
868                                         }
869                                 }
870                                 for(a=0; a<totgroup; a++)
871                                         if(groups[a]) totmenu++;
872                                 
873                                 if(totmenu==0) {
874                                         notice("No Vertex Group Selected");
875                                 }
876                                 else {
877                                         bDeformGroup *dg;
878                                         short val;
879                                         char item[40], *str= MEM_mallocN(40*totmenu+40, "menu");
880                                         
881                                         strcpy(str, "Vertex Groups %t");
882                                         for(a=0, dg=ob->defbase.first; dg && a<totgroup; a++, dg= dg->next) {
883                                                 if(groups[a]) {
884                                                         sprintf(item, "|%s %%x%d", dg->name, a);
885                                                         strcat(str, item);
886                                                 }
887                                         }
888                                         
889                                         val= pupmenu(str);
890                                         if(val>=0) {
891                                                 ob->actdef= val+1;
892                                                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
893                                                 allqueue(REDRAWVIEW3D, 0);
894                                                 allqueue(REDRAWOOPS, 0);
895                                                 allqueue(REDRAWBUTSEDIT, 0);
896                                         }
897                                         MEM_freeN(str);
898                                 }
899                                 MEM_freeN(groups);
900                         }
901                         else notice("No Vertex Groups in Object");
902                 }
903                 else {
904                         DerivedMesh *dm;
905                         MDeformWeight *dw;
906                         extern float editbutvweight;
907                         float w1, w2, w3, w4, co[3], fac;
908                         int needsFree;
909                         
910                         dm = mesh_get_derived_final(ob, &needsFree);
911                         if(dm->getVertCo==NULL) {
912                                 notice("Not supported yet");
913                         }
914                         else {
915                                 /* calc 3 or 4 corner weights */
916                                 dm->getVertCo(dm, mface->v1, co);
917                                 project_short_noclip(co, sco);
918                                 w1= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
919                                 
920                                 dm->getVertCo(dm, mface->v2, co);
921                                 project_short_noclip(co, sco);
922                                 w2= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
923                                 
924                                 dm->getVertCo(dm, mface->v3, co);
925                                 project_short_noclip(co, sco);
926                                 w3= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
927                                 
928                                 if(mface->v4) {
929                                         dm->getVertCo(dm, mface->v4, co);
930                                         project_short_noclip(co, sco);
931                                         w4= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
932                                 }
933                                 else w4= 1.0e10;
934                                 
935                                 fac= MIN4(w1, w2, w3, w4);
936                                 if(w1==fac) {
937                                         dw= get_defweight(me->dvert+mface->v1, ob->actdef-1);
938                                         if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
939                                 }
940                                 else if(w2==fac) {
941                                         dw= get_defweight(me->dvert+mface->v2, ob->actdef-1);
942                                         if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
943                                 }
944                                 else if(w3==fac) {
945                                         dw= get_defweight(me->dvert+mface->v3, ob->actdef-1);
946                                         if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
947                                 }
948                                 else if(w4==fac) {
949                                         if(mface->v4) {
950                                                 dw= get_defweight(me->dvert+mface->v4, ob->actdef-1);
951                                                 if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
952                                         }
953                                 }
954                                 if (needsFree)
955                                         dm->release(dm);
956                         }
957                 }               
958                 
959         }
960         allqueue(REDRAWBUTSEDIT, 0);
961         
962 }
963
964 static void do_weight_paint_vertex(Object *ob, int index, int alpha, float paintweight, int vgroup_mirror)
965 {
966         Mesh *me= ob->data;
967         MDeformWeight   *dw, *uw;
968         int vgroup= ob->actdef-1;
969         
970         dw= verify_defweight(me->dvert+index, vgroup);
971         uw= verify_defweight(wpaintundobuf+index, vgroup);
972         wpaint_blend(dw, uw, (float)alpha/255.0, paintweight);
973         
974         if(Gwp.flag & VP_MIRROR_X) {    /* x mirror painting */
975                 int j= mesh_get_x_mirror_vert(ob, index);
976                 if(j>=0) {
977                         /* copy, not paint again */
978                         if(vgroup_mirror != -1)
979                                 uw= verify_defweight(me->dvert+j, vgroup_mirror);
980                         else
981                                 uw= verify_defweight(me->dvert+j, vgroup);
982                                 
983                         uw->weight= dw->weight;
984                 }
985         }
986 }
987
988 void weight_paint(void)
989 {
990         extern float editbutvweight;
991         Object *ob; 
992         Mesh *me;
993         MFace *mface;
994         TFace *tface;
995         float mat[4][4], imat[4][4], paintweight, *vertexcosnos;
996         int index, totindex, alpha, totw;
997         int vgroup_mirror= -1;
998         short mval[2], mvalo[2], firsttime=1, mousebut;
999
1000         if((G.f & G_WEIGHTPAINT)==0) return;
1001         if(G.obedit) return;
1002         
1003         if(indexar==NULL) init_vertexpaint();
1004         
1005         ob= OBACT;
1006         if(ob->id.lib) return;
1007
1008         me= get_mesh(ob);
1009         if(me==NULL || me->totface==0) return;
1010         
1011         /* if nothing was added yet, we make dverts and a vertex deform group */
1012         if (!me->dvert)
1013                 create_dverts(me);
1014         
1015         if(G.qual & LR_CTRLKEY) {
1016                 sample_wpaint(0);
1017                 return;
1018         }
1019         if(G.qual & LR_SHIFTKEY) {
1020                 sample_wpaint(1);
1021                 return;
1022         }
1023         
1024         /* painting on subsurfs should give correct points too, this returns me->totvert amount */
1025         vertexcosnos= mesh_get_mapped_verts_nors(ob);
1026         
1027         /* this happens on a Bone select, when no vgroup existed yet */
1028         if(ob->actdef<=0) {
1029                 Object *modob;
1030                 if((modob = modifiers_isDeformedByArmature(ob))) {
1031                         bPoseChannel *pchan;
1032                         for(pchan= modob->pose->chanbase.first; pchan; pchan= pchan->next)
1033                                 if(pchan->bone->flag & SELECT)
1034                                         break;
1035                         if(pchan) {
1036                                 bDeformGroup *dg= get_named_vertexgroup(ob, pchan->name);
1037                                 if(dg==NULL)
1038                                         dg= add_defgroup_name(ob, pchan->name); // sets actdef
1039                                 else
1040                                         ob->actdef= get_defgroup_num(ob, dg);
1041                                 allqueue(REDRAWBUTSEDIT, 0);
1042                         }
1043                 }
1044         }
1045         if(ob->defbase.first==NULL) {
1046                 add_defgroup(ob);
1047                 allqueue(REDRAWBUTSEDIT, 0);
1048         }       
1049         
1050         if(ob->lay & G.vd->lay); else error("Active object is not in this layer");
1051         
1052         persp(PERSP_VIEW);
1053         /* imat for normals */
1054         Mat4MulMat4(mat, ob->obmat, G.vd->viewmat);
1055         Mat4Invert(imat, mat);
1056         Mat3CpyMat4(vpimat, imat);
1057         
1058         /* load projection matrix */
1059         mymultmatrix(ob->obmat);
1060         mygetsingmatrix(mat);
1061         myloadmatrix(G.vd->viewmat);
1062         
1063         getmouseco_areawin(mvalo);
1064         
1065         if(me->tface) tface_to_mcol(me);
1066         copy_vpaint_undo( (unsigned int *)me->mcol, me->totface);
1067         copy_wpaint_undo(me->dvert, me->totvert);
1068         
1069         getmouseco_areawin(mval);
1070         mvalo[0]= mval[0];
1071         mvalo[1]= mval[1];
1072         
1073         if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE;
1074         else mousebut = L_MOUSE;
1075         
1076         /* if mirror painting, find the other group */                  
1077         if(Gwp.flag & VP_MIRROR_X) {
1078                 bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1);
1079                 if(defgroup) {
1080                         bDeformGroup *curdef;
1081                         int actdef= 0;
1082                         char name[32];
1083
1084                         BLI_strncpy(name, defgroup->name, 32);
1085                         bone_flip_name(name, 0);                // 0 = don't strip off number extensions
1086                         
1087                         for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++)
1088                                 if (!strcmp(curdef->name, name))
1089                                         break;
1090                         if(curdef==NULL) {
1091                                 int olddef= ob->actdef; /* tsk, add_defgroup sets the active defgroup */
1092                                 curdef= add_defgroup_name (ob, name);
1093                                 ob->actdef= olddef;
1094                         }
1095                         
1096                         if(curdef && curdef!=defgroup)
1097                                 vgroup_mirror= actdef;
1098                 }
1099         }
1100         
1101         while (get_mbut() & mousebut) {
1102                 getmouseco_areawin(mval);
1103                 
1104                 if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
1105                         firsttime= 0;
1106                         
1107                         /* which faces are involved */
1108                         if(Gwp.flag & VP_AREA) {
1109                                 totindex= sample_backbuf_area(mval[0], mval[1], Gwp.size);
1110                         }
1111                         else {
1112                                 indexar[0]= sample_backbuf(mval[0], mval[1]);
1113                                 if(indexar[0]) totindex= 1;
1114                                 else totindex= 0;
1115                         }
1116                         
1117                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1118                         
1119                         if(Gwp.flag & VP_COLINDEX) {
1120                                 for(index=0; index<totindex; index++) {
1121                                         if(indexar[index] && indexar[index]<=me->totface) {
1122                                         
1123                                                 mface= ((MFace *)me->mface) + (indexar[index]-1);
1124                                         
1125                                                 if(mface->mat_nr!=ob->actcol-1) {
1126                                                         indexar[index]= 0;
1127                                                 }
1128                                         }                                       
1129                                 }
1130                         }
1131
1132                         if((G.f & G_FACESELECT) && me->tface) {
1133                                 for(index=0; index<totindex; index++) {
1134                                         if(indexar[index] && indexar[index]<=me->totface) {
1135                                         
1136                                                 tface= ((TFace *)me->tface) + (indexar[index]-1);
1137                                         
1138                                                 if((tface->flag & TF_SELECT)==0) {
1139                                                         indexar[index]= 0;
1140                                                 }
1141                                         }                                       
1142                                 }
1143                         }
1144                         
1145                         /* make sure each vertex gets treated only once */
1146                         /* and calculate filter weight */
1147                         totw= 0;
1148                         if(Gwp.mode==VP_FILT) 
1149                                 paintweight= 0.0f;
1150                         else
1151                                 paintweight= editbutvweight;
1152                         
1153                         for(index=0; index<totindex; index++) {
1154                                 if(indexar[index] && indexar[index]<=me->totface) {
1155                                         mface= me->mface + (indexar[index]-1);
1156                                         
1157                                         (me->dvert+mface->v1)->flag= 1;
1158                                         (me->dvert+mface->v2)->flag= 1;
1159                                         (me->dvert+mface->v3)->flag= 1;
1160                                         if(mface->v4) (me->dvert+mface->v4)->flag= 1;
1161                                         
1162                                         if(Gwp.mode==VP_FILT) {
1163                                                 MDeformWeight *dw;
1164                                                 dw= verify_defweight(me->dvert+mface->v1, ob->actdef-1);
1165                                                 if(dw) {paintweight+= dw->weight; totw++;}
1166                                                 dw= verify_defweight(me->dvert+mface->v2, ob->actdef-1);
1167                                                 if(dw) {paintweight+= dw->weight; totw++;}
1168                                                 dw= verify_defweight(me->dvert+mface->v3, ob->actdef-1);
1169                                                 if(dw) {paintweight+= dw->weight; totw++;}
1170                                                 if(mface->v4) {
1171                                                         dw= verify_defweight(me->dvert+mface->v4, ob->actdef-1);
1172                                                         if(dw) {paintweight+= dw->weight; totw++;}
1173                                                 }
1174                                         }
1175                                 }
1176                         }
1177                         
1178                         if(Gwp.mode==VP_FILT) 
1179                                 paintweight/= (float)totw;
1180                         
1181                         for(index=0; index<totindex; index++) {
1182                                 
1183                                 if(indexar[index] && indexar[index]<=me->totface) {
1184                                         mface= me->mface + (indexar[index]-1);
1185                                         
1186                                         if((me->dvert+mface->v1)->flag) {
1187                                                 alpha= calc_vp_alpha_dl(&Gwp, vertexcosnos+6*mface->v1, mval);
1188                                                 if(alpha) {
1189                                                         do_weight_paint_vertex(ob, mface->v1, alpha, paintweight, vgroup_mirror);
1190                                                 }
1191                                                 (me->dvert+mface->v1)->flag= 0;
1192                                         }
1193                                         
1194                                         if((me->dvert+mface->v2)->flag) {
1195                                                 alpha= calc_vp_alpha_dl(&Gwp, vertexcosnos+6*mface->v2, mval);
1196                                                 if(alpha) {
1197                                                         do_weight_paint_vertex(ob, mface->v2, alpha, paintweight, vgroup_mirror);
1198                                                 }
1199                                                 (me->dvert+mface->v2)->flag= 0;
1200                                         }
1201                                         
1202                                         if((me->dvert+mface->v3)->flag) {
1203                                                 alpha= calc_vp_alpha_dl(&Gwp, vertexcosnos+6*mface->v3, mval);
1204                                                 if(alpha) {
1205                                                         do_weight_paint_vertex(ob, mface->v3, alpha, paintweight, vgroup_mirror);
1206                                                 }
1207                                                 (me->dvert+mface->v3)->flag= 0;
1208                                         }
1209                                         
1210                                         if((me->dvert+mface->v4)->flag) {
1211                                                 if(mface->v4) {
1212                                                         alpha= calc_vp_alpha_dl(&Gwp, vertexcosnos+6*mface->v4, mval);
1213                                                         if(alpha) {
1214                                                                 do_weight_paint_vertex(ob, mface->v4, alpha, paintweight, vgroup_mirror);
1215                                                         }
1216                                                         (me->dvert+mface->v4)->flag= 0;
1217                                                 }
1218                                         }
1219                                 }
1220                         }
1221                         
1222                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1223                         
1224                 }
1225                 else BIF_wait_for_statechange();
1226                 
1227                 if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
1228
1229                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1230                         scrarea_do_windraw(curarea);
1231                         
1232                         if(Gwp.flag & (VP_AREA|VP_SOFT)) {
1233                                 /* draw circle in backbuf! */
1234                                 persp(PERSP_WIN);
1235                                 fdrawXORcirc((float)mval[0], (float)mval[1], Gwp.size);
1236                                 persp(PERSP_VIEW);
1237                         }
1238
1239                         screen_swapbuffers();
1240                         backdrawview3d(0);
1241         
1242                         mvalo[0]= mval[0];
1243                         mvalo[1]= mval[1];
1244                 }
1245         }
1246         
1247         if(me->tface) {
1248                 MEM_freeN(me->mcol);
1249                 me->mcol= 0;
1250         }
1251         if(vertexcosnos)
1252                 MEM_freeN(vertexcosnos);
1253         
1254         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1255         // this flag is event for softbody to refresh weightpaint values
1256         if(ob->soft) ob->softflag |= OB_SB_REDO;
1257         
1258         allqueue(REDRAWVIEW3D, 0);
1259 }
1260
1261 void vertex_paint()
1262 {
1263         Object *ob;
1264         Mesh *me;
1265         MFace *mface;
1266         TFace *tface;
1267         float mat[4][4], imat[4][4], *vertexcosnos;
1268         unsigned int paintcol=0, *mcol, *mcolorig, fcol1, fcol2;
1269         int index, alpha, totindex;
1270         short mval[2], mvalo[2], firsttime=1, mousebut;
1271         
1272         if((G.f & G_VERTEXPAINT)==0) return;
1273         if(G.obedit) return;
1274         
1275         if(indexar==NULL) init_vertexpaint();
1276         
1277         ob= OBACT;
1278         if(ob->id.lib) return;
1279
1280         me= get_mesh(ob);
1281         if(me==NULL || me->totface==0) return;
1282         if(ob->lay & G.vd->lay); else error("Active object is not in this layer");
1283         
1284         if(me->tface==NULL && me->mcol==NULL) make_vertexcol();
1285
1286         if(me->tface==NULL && me->mcol==NULL) return;
1287         
1288         /* painting on subsurfs should give correct points too, this returns me->totvert amount */
1289         vertexcosnos= mesh_get_mapped_verts_nors(ob);
1290         
1291         persp(PERSP_VIEW);
1292         /* imat for normals */
1293         Mat4MulMat4(mat, ob->obmat, G.vd->viewmat);
1294         Mat4Invert(imat, mat);
1295         Mat3CpyMat4(vpimat, imat);
1296         
1297         /* load projection matrix */
1298         mymultmatrix(ob->obmat);
1299         mygetsingmatrix(mat);
1300         myloadmatrix(G.vd->viewmat);
1301         
1302         paintcol= vpaint_get_current_col();
1303         
1304         getmouseco_areawin(mvalo);
1305         
1306         if(me->tface) tface_to_mcol(me);
1307         copy_vpaint_undo( (unsigned int *)me->mcol, me->totface);
1308         
1309         getmouseco_areawin(mval);
1310         mvalo[0]= mval[0];
1311         mvalo[1]= mval[1];
1312         
1313         if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE;
1314         else mousebut = L_MOUSE;
1315         
1316         while (get_mbut() & mousebut) {
1317                 getmouseco_areawin(mval);
1318                 
1319                 if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
1320
1321                         firsttime= 0;
1322
1323                         /* which faces are involved */
1324                         if(Gvp.flag & VP_AREA) {
1325                                 totindex= sample_backbuf_area(mval[0], mval[1], Gvp.size);
1326                         }
1327                         else {
1328                                 indexar[0]= sample_backbuf(mval[0], mval[1]);
1329                                 if(indexar[0]) totindex= 1;
1330                                 else totindex= 0;
1331                         }
1332                         
1333                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1334                         
1335                         if(Gvp.flag & VP_COLINDEX) {
1336                                 for(index=0; index<totindex; index++) {
1337                                         if(indexar[index] && indexar[index]<=me->totface) {
1338                                         
1339                                                 mface= ((MFace *)me->mface) + (indexar[index]-1);
1340                                         
1341                                                 if(mface->mat_nr!=ob->actcol-1) {
1342                                                         indexar[index]= 0;
1343                                                 }
1344                                         }                                       
1345                                 }
1346                         }
1347                         if((G.f & G_FACESELECT) && me->tface) {
1348                                 for(index=0; index<totindex; index++) {
1349                                         if(indexar[index] && indexar[index]<=me->totface) {
1350                                         
1351                                                 tface= ((TFace *)me->tface) + (indexar[index]-1);
1352                                         
1353                                                 if((tface->flag & TF_SELECT)==0) {
1354                                                         indexar[index]= 0;
1355                                                 }
1356                                         }                                       
1357                                 }
1358                         }
1359
1360                         for(index=0; index<totindex; index++) {
1361
1362                                 if(indexar[index] && indexar[index]<=me->totface) {
1363                                 
1364                                         mface= ((MFace *)me->mface) + (indexar[index]-1);
1365                                         mcol=     ( (unsigned int *)me->mcol) + 4*(indexar[index]-1);
1366                                         mcolorig= ( (unsigned int *)vpaintundobuf) + 4*(indexar[index]-1);
1367
1368                                         if(Gvp.mode==VP_FILT) {
1369                                                 fcol1= mcol_blend( mcol[0], mcol[1], 128);
1370                                                 if(mface->v4) {
1371                                                         fcol2= mcol_blend( mcol[2], mcol[3], 128);
1372                                                         paintcol= mcol_blend( fcol1, fcol2, 128);
1373                                                 }
1374                                                 else {
1375                                                         paintcol= mcol_blend( mcol[2], fcol1, 170);
1376                                                 }
1377                                                 
1378                                         }
1379                                         
1380                                         alpha= calc_vp_alpha_dl(&Gvp, vertexcosnos+6*mface->v1, mval);
1381                                         if(alpha) vpaint_blend( mcol, mcolorig, paintcol, alpha);
1382                                         
1383                                         alpha= calc_vp_alpha_dl(&Gvp, vertexcosnos+6*mface->v2, mval);
1384                                         if(alpha) vpaint_blend( mcol+1, mcolorig+1, paintcol, alpha);
1385         
1386                                         alpha= calc_vp_alpha_dl(&Gvp, vertexcosnos+6*mface->v3, mval);
1387                                         if(alpha) vpaint_blend( mcol+2, mcolorig+2, paintcol, alpha);
1388
1389                                         if(mface->v4) {
1390                                                 alpha= calc_vp_alpha_dl(&Gvp, vertexcosnos+6*mface->v4, mval);
1391                                                 if(alpha) vpaint_blend( mcol+3, mcolorig+3, paintcol, alpha);
1392                                         }
1393                                 }
1394                         }
1395                                 
1396                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1397                         
1398                         do_shared_vertexcol(me);
1399                         if(me->tface) {
1400                                 mcol_to_tface(me, 0);
1401                         }
1402         
1403                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1404                         scrarea_do_windraw(curarea);
1405
1406                         if(Gvp.flag & (VP_AREA|VP_SOFT)) {
1407                                 /* draw circle in backbuf! */
1408                                 persp(PERSP_WIN);
1409                                 fdrawXORcirc((float)mval[0], (float)mval[1], Gvp.size);
1410                                 persp(PERSP_VIEW);
1411                         }
1412                         screen_swapbuffers();
1413                         backdrawview3d(0);
1414                         
1415                         mvalo[0]= mval[0];
1416                         mvalo[1]= mval[1];
1417                 }
1418                 else BIF_wait_for_statechange();
1419         }
1420         
1421         if(me->tface) {
1422                 MEM_freeN(me->mcol);
1423                 me->mcol= 0;
1424         }
1425         if(vertexcosnos)
1426                 MEM_freeN(vertexcosnos);
1427
1428         allqueue(REDRAWVIEW3D, 0);
1429 }
1430
1431 void set_wpaint(void)           /* toggle */
1432 {               
1433         Object *ob;
1434         Mesh *me;
1435         
1436         scrarea_queue_headredraw(curarea);
1437         ob= OBACT;
1438         if(ob->id.lib) return;
1439         me= get_mesh(ob);
1440                 
1441         if(me && me->totface>=MAXINDEX) {
1442                 error("Maximum number of faces: %d", MAXINDEX-1);
1443                 G.f &= ~G_WEIGHTPAINT;
1444                 return;
1445         }
1446         
1447         if(G.f & G_WEIGHTPAINT) G.f &= ~G_WEIGHTPAINT;
1448         else G.f |= G_WEIGHTPAINT;
1449         
1450         allqueue(REDRAWVIEW3D, 1);      /* including header */
1451         allqueue(REDRAWBUTSEDIT, 0);
1452         
1453                 /* Weightpaint works by overriding colors in mesh,
1454                  * so need to make sure we recalc on enter and
1455                  * exit (exit needs doing regardless because we
1456                  * should redeform).
1457                  */
1458         if (me) {
1459                 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1460         }
1461
1462         if(G.f & G_WEIGHTPAINT) {
1463                 Object *par;
1464                 
1465                 setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT);
1466                 
1467                 mesh_octree_table(ob, NULL, 's');
1468
1469                 /* verify if active weight group is also active bone */
1470                 par= modifiers_isDeformedByArmature(ob);
1471                 if(par && (par->flag & OB_POSEMODE)) {
1472                         bPoseChannel *pchan;
1473                         for(pchan= par->pose->chanbase.first; pchan; pchan= pchan->next)
1474                                 if(pchan->bone->flag & BONE_ACTIVE)
1475                                         break;
1476                         if(pchan)
1477                                 vertexgroup_select_by_name(ob, pchan->name);
1478                 }
1479         }
1480         else {
1481                 freefastshade();        /* to be sure */
1482                 if(!(G.f & G_FACESELECT))
1483                         setcursor_space(SPACE_VIEW3D, CURSOR_STD);
1484                 
1485                 mesh_octree_table(ob, NULL, 'e');
1486         }
1487 }
1488
1489
1490 void set_vpaint(void)           /* toggle */
1491 {               
1492         Object *ob;
1493         Mesh *me;
1494         
1495         scrarea_queue_headredraw(curarea);
1496         ob= OBACT;
1497         if(ob->id.lib) {
1498                 G.f &= ~G_VERTEXPAINT;
1499                 return;
1500         }
1501         
1502         me= get_mesh(ob);
1503         
1504         if(me && me->totface>=MAXINDEX) {
1505                 error("Maximum number of faces: %d", MAXINDEX-1);
1506                 G.f &= ~G_VERTEXPAINT;
1507                 return;
1508         }
1509         
1510         if(me && me->tface==NULL && me->mcol==NULL) make_vertexcol();
1511         
1512         if(G.f & G_VERTEXPAINT){
1513                 G.f &= ~G_VERTEXPAINT;
1514         }
1515         else {
1516                 G.f |= G_VERTEXPAINT;
1517                 /* Turn off weight painting */
1518                 if (G.f & G_WEIGHTPAINT)
1519                         set_wpaint();
1520         }
1521         
1522         allqueue(REDRAWVIEW3D, 1);      /* including header */
1523         allqueue(REDRAWBUTSEDIT, 0);
1524         
1525         if(G.f & G_VERTEXPAINT) {
1526                 setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT);
1527         }
1528         else {
1529                 freefastshade();        /* to be sure */
1530                 if (me) {
1531                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1532                 }
1533                 if((G.f & G_FACESELECT)==0) setcursor_space(SPACE_VIEW3D, CURSOR_STD);
1534         }
1535 }
1536