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