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