More fix various gcc warning, mainly related to signed/unsigned parameters
[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_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         MTFace *tf;
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         tf = me->mtface;
337         mcol = (unsigned int*)me->mcol;
338         for (i = 0; i < me->totface; i++, tf++, mcol+=4) {
339                 if (tf->flag & TF_SELECT) {
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         MTFace *tface;
360         MFace *mface;
361         Object *ob;
362         MDeformWeight *dw, *uw;
363         int *indexar;
364         int index, vgroup;
365         unsigned int faceverts[5]={0,0,0,0,0};
366         unsigned char i;
367         int vgroup_mirror= -1;
368         
369         ob= OBACT;
370         me= ob->data;
371         if(me==0 || me->totface==0 || me->dvert==0 || !me->mtface) return;
372         
373         indexar= get_indexarray();
374         for(index=0, tface=me->mtface; index<me->totface; index++, tface++) {
375                 if((tface->flag & TF_SELECT)==0)
376                         indexar[index]= 0;
377                 else
378                         indexar[index]= index+1;
379         }
380         
381         vgroup= ob->actdef-1;
382         
383         /* directly copied from weight_paint, should probaby split into a seperate function */
384         /* if mirror painting, find the other group */          
385         if(Gwp.flag & VP_MIRROR_X) {
386                 bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1);
387                 if(defgroup) {
388                         bDeformGroup *curdef;
389                         int actdef= 0;
390                         char name[32];
391
392                         BLI_strncpy(name, defgroup->name, 32);
393                         bone_flip_name(name, 0);                /* 0 = don't strip off number extensions */
394                         
395                         for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++)
396                                 if (!strcmp(curdef->name, name))
397                                         break;
398                         if(curdef==NULL) {
399                                 int olddef= ob->actdef; /* tsk, add_defgroup sets the active defgroup */
400                                 curdef= add_defgroup_name (ob, name);
401                                 ob->actdef= olddef;
402                         }
403                         
404                         if(curdef && curdef!=defgroup)
405                                 vgroup_mirror= actdef;
406                 }
407         }
408         /* end copy from weight_paint*/
409         
410         copy_wpaint_prev(&Gwp, me->dvert, me->totvert);
411         
412         for(index=0; index<me->totface; index++) {
413                 if(indexar[index] && indexar[index]<=me->totface) {
414                         mface= me->mface + (indexar[index]-1);
415                         /* just so we can loop through the verts */
416                         faceverts[0]= mface->v1;
417                         faceverts[1]= mface->v2;
418                         faceverts[2]= mface->v3;
419                         faceverts[3]= mface->v4;
420                         for (i=0; i<3 || faceverts[i]; i++) {
421                                 if(!((me->dvert+faceverts[i])->flag)) {
422                                         dw= verify_defweight(me->dvert+faceverts[i], vgroup);
423                                         if(dw) {
424                                                 uw= verify_defweight(Gwp.wpaint_prev+faceverts[i], vgroup);
425                                                 uw->weight= dw->weight; /* set the undio weight */
426                                                 dw->weight= paintweight;
427                                                 
428                                                 if(Gwp.flag & VP_MIRROR_X) {    /* x mirror painting */
429                                                         int j= mesh_get_x_mirror_vert(ob, faceverts[i]);
430                                                         if(j>=0) {
431                                                                 /* copy, not paint again */
432                                                                 if(vgroup_mirror != -1) {
433                                                                         dw= verify_defweight(me->dvert+j, vgroup_mirror);
434                                                                         uw= verify_defweight(Gwp.wpaint_prev+j, vgroup_mirror);
435                                                                 } else {
436                                                                         dw= verify_defweight(me->dvert+j, vgroup);
437                                                                         uw= verify_defweight(Gwp.wpaint_prev+j, vgroup);
438                                                                 }
439                                                                 uw->weight= dw->weight; /* set the undo weight */
440                                                                 dw->weight= paintweight;
441                                                         }
442                                                 }
443                                         }
444                                         (me->dvert+faceverts[i])->flag= 1;
445                                 }
446                         }
447                 }
448         }
449         
450         index=0;
451         while (index<me->totvert) {
452                 (me->dvert+index)->flag= 0;
453                 index++;
454         }
455         
456         MEM_freeN(indexar);
457         copy_wpaint_prev(&Gwp, NULL, 0);
458
459         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
460         BIF_undo_push("Set vertex weight");
461         allqueue(REDRAWVIEW3D, 0);
462 }
463
464
465 void vpaint_dogamma()
466 {
467         Mesh *me;
468         Object *ob;
469         float igam, fac;
470         int a, temp;
471         char *cp, gamtab[256];
472
473         if((G.f & G_VERTEXPAINT)==0) return;
474
475         ob= OBACT;
476         me= get_mesh(ob);
477         if(me==0 || me->mcol==0 || me->totface==0) return;
478
479         igam= 1.0/Gvp.gamma;
480         for(a=0; a<256; a++) {
481                 
482                 fac= ((float)a)/255.0;
483                 fac= Gvp.mul*pow( fac, igam);
484                 
485                 temp= 255.9*fac;
486                 
487                 if(temp<=0) gamtab[a]= 0;
488                 else if(temp>=255) gamtab[a]= 255;
489                 else gamtab[a]= temp;
490         }
491
492         a= 4*me->totface;
493         cp= (char *)me->mcol;
494         while(a--) {
495                 
496                 cp[1]= gamtab[ cp[1] ];
497                 cp[2]= gamtab[ cp[2] ];
498                 cp[3]= gamtab[ cp[3] ];
499                 
500                 cp+= 4;
501         }
502         allqueue(REDRAWVIEW3D, 0);
503 }
504
505 /* used for both 3d view and image window */
506 void sample_vpaint()    /* frontbuf */
507 {
508         unsigned int col;
509         int x, y;
510         short mval[2];
511         char *cp;
512         
513         getmouseco_areawin(mval);
514         x= mval[0]; y= mval[1];
515         
516         if(x<0 || y<0) return;
517         if(x>=curarea->winx || y>=curarea->winy) return;
518         
519         x+= curarea->winrct.xmin;
520         y+= curarea->winrct.ymin;
521         
522         glReadBuffer(GL_FRONT);
523         glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
524         glReadBuffer(GL_BACK);
525
526         cp = (char *)&col;
527         
528         if(G.f & (G_VERTEXPAINT|G_WEIGHTPAINT)) {
529                 Gvp.r= cp[0]/255.0f;
530                 Gvp.g= cp[1]/255.0f;
531                 Gvp.b= cp[2]/255.0f;
532         }
533         else {
534                 Brush *brush= G.scene->toolsettings->imapaint.brush;
535
536                 if(brush) {
537                         brush->rgb[0]= cp[0]/255.0f;
538                         brush->rgb[1]= cp[1]/255.0f;
539                         brush->rgb[2]= cp[2]/255.0f;
540
541                         allqueue(REDRAWVIEW3D, 0);
542                         allqueue(REDRAWIMAGE, 0);
543                 }
544         }
545
546         allqueue(REDRAWBUTSEDIT, 0);
547         addqueue(curarea->win, REDRAW, 1); /* needed for when panel is open... */
548 }
549
550 static unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac)
551 {
552         char *cp1, *cp2, *cp;
553         int mfac;
554         unsigned int col=0;
555         
556         if(fac==0) return col1;
557         if(fac>=255) return col2;
558
559         mfac= 255-fac;
560         
561         cp1= (char *)&col1;
562         cp2= (char *)&col2;
563         cp=  (char *)&col;
564         
565         cp[0]= 255;
566         cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8;
567         cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8;
568         cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8;
569         
570         return col;
571 }
572
573 static unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac)
574 {
575         char *cp1, *cp2, *cp;
576         int temp;
577         unsigned int col=0;
578         
579         if(fac==0) return col1;
580         
581         cp1= (char *)&col1;
582         cp2= (char *)&col2;
583         cp=  (char *)&col;
584         
585         cp[0]= 255;
586         temp= cp1[1] + ((fac*cp2[1])>>8);
587         if(temp>254) cp[1]= 255; else cp[1]= temp;
588         temp= cp1[2] + ((fac*cp2[2])>>8);
589         if(temp>254) cp[2]= 255; else cp[2]= temp;
590         temp= cp1[3] + ((fac*cp2[3])>>8);
591         if(temp>254) cp[3]= 255; else cp[3]= temp;
592         
593         return col;
594 }
595
596 static unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac)
597 {
598         char *cp1, *cp2, *cp;
599         int temp;
600         unsigned int col=0;
601         
602         if(fac==0) return col1;
603         
604         cp1= (char *)&col1;
605         cp2= (char *)&col2;
606         cp=  (char *)&col;
607         
608         cp[0]= 255;
609         temp= cp1[1] - ((fac*cp2[1])>>8);
610         if(temp<0) cp[1]= 0; else cp[1]= temp;
611         temp= cp1[2] - ((fac*cp2[2])>>8);
612         if(temp<0) cp[2]= 0; else cp[2]= temp;
613         temp= cp1[3] - ((fac*cp2[3])>>8);
614         if(temp<0) cp[3]= 0; else cp[3]= temp;
615         
616         return col;
617 }
618
619 static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac)
620 {
621         char *cp1, *cp2, *cp;
622         int mfac;
623         unsigned int col=0;
624         
625         if(fac==0) return col1;
626
627         mfac= 255-fac;
628         
629         cp1= (char *)&col1;
630         cp2= (char *)&col2;
631         cp=  (char *)&col;
632         
633         /* first mul, then blend the fac */
634         cp[0]= 255;
635         cp[1]= (mfac*cp1[1] + fac*((cp2[1]*cp1[1])>>8)  )>>8;
636         cp[2]= (mfac*cp1[2] + fac*((cp2[2]*cp1[2])>>8)  )>>8;
637         cp[3]= (mfac*cp1[3] + fac*((cp2[3]*cp1[3])>>8)  )>>8;
638
639         
640         return col;
641 }
642
643 static unsigned int mcol_lighten(unsigned int col1, unsigned int col2, int fac)
644 {
645         char *cp1, *cp2, *cp;
646         int mfac;
647         unsigned int col=0;
648         
649         if(fac==0) return col1;
650         if(fac>=255) return col2;
651
652         mfac= 255-fac;
653         
654         cp1= (char *)&col1;
655         cp2= (char *)&col2;
656         cp=  (char *)&col;
657         
658         /* See if are lighter, if so mix, else dont do anything.
659         if the paint col is darker then the original, then ignore */
660         if (cp1[1]+cp1[2]+cp1[3] > cp2[1]+cp2[2]+cp2[3])
661                 return col1;
662         
663         cp[0]= 255;
664         cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8;
665         cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8;
666         cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8;
667         
668         return col;
669 }
670
671 static unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac)
672 {
673         char *cp1, *cp2, *cp;
674         int mfac;
675         unsigned int col=0;
676         
677         if(fac==0) return col1;
678         if(fac>=255) return col2;
679
680         mfac= 255-fac;
681         
682         cp1= (char *)&col1;
683         cp2= (char *)&col2;
684         cp=  (char *)&col;
685         
686         /* See if were darker, if so mix, else dont do anything.
687         if the paint col is brighter then the original, then ignore */
688         if (cp1[1]+cp1[2]+cp1[3] < cp2[1]+cp2[2]+cp2[3])
689                 return col1;
690         
691         cp[0]= 255;
692         cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8;
693         cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8;
694         cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8;
695         return col;
696 }
697
698 static void vpaint_blend( unsigned int *col, unsigned int *colorig, unsigned int paintcol, int alpha)
699 {
700
701         if(Gvp.mode==VP_MIX || Gvp.mode==VP_FILT) *col= mcol_blend( *col, paintcol, alpha);
702         else if(Gvp.mode==VP_ADD) *col= mcol_add( *col, paintcol, alpha);
703         else if(Gvp.mode==VP_SUB) *col= mcol_sub( *col, paintcol, alpha);
704         else if(Gvp.mode==VP_MUL) *col= mcol_mul( *col, paintcol, alpha);
705         else if(Gvp.mode==VP_LIGHTEN) *col= mcol_lighten( *col, paintcol, alpha);
706         else if(Gvp.mode==VP_DARKEN) *col= mcol_darken( *col, paintcol, alpha);
707         
708         /* if no spray, clip color adding with colorig & orig alpha */
709         if((Gvp.flag & VP_SPRAY)==0) {
710                 unsigned int testcol=0, a;
711                 char *cp, *ct, *co;
712                 
713                 alpha= (int)(255.0*Gvp.a);
714                 
715                 if(Gvp.mode==VP_MIX || Gvp.mode==VP_FILT) testcol= mcol_blend( *colorig, paintcol, alpha);
716                 else if(Gvp.mode==VP_ADD) testcol= mcol_add( *colorig, paintcol, alpha);
717                 else if(Gvp.mode==VP_SUB) testcol= mcol_sub( *colorig, paintcol, alpha);
718                 else if(Gvp.mode==VP_MUL) testcol= mcol_mul( *colorig, paintcol, alpha);
719                 else if(Gvp.mode==VP_LIGHTEN)  testcol= mcol_lighten( *colorig, paintcol, alpha);
720                 else if(Gvp.mode==VP_DARKEN)   testcol= mcol_darken( *colorig, paintcol, alpha);
721                 
722                 cp= (char *)col;
723                 ct= (char *)&testcol;
724                 co= (char *)colorig;
725                 
726                 for(a=0; a<4; a++) {
727                         if( ct[a]<co[a] ) {
728                                 if( cp[a]<ct[a] ) cp[a]= ct[a];
729                                 else if( cp[a]>co[a] ) cp[a]= co[a];
730                         }
731                         else {
732                                 if( cp[a]<co[a] ) cp[a]= co[a];
733                                 else if( cp[a]>ct[a] ) cp[a]= ct[a];
734                         }
735                 }
736         }
737 }
738
739
740 static int sample_backbuf_area(VPaint *vp, int *indexar, int totface, int x, int y, float size)
741 {
742         unsigned int *rt;
743         struct ImBuf *ibuf;
744         int x1, y1, x2, y2, a, tot=0, index;
745         
746         if(totface>=MAXINDEX) return 0;
747         
748         if(size>64.0) size= 64.0;
749         
750         x1= x-size;
751         x2= x+size;
752         CLAMP(x1, 0, curarea->winx-1);
753         CLAMP(x2, 0, curarea->winx-1);
754         y1= y-size;
755         y2= y+size;
756         CLAMP(y1, 0, curarea->winy-1);
757         CLAMP(y2, 0, curarea->winy-1);
758 #ifdef __APPLE__
759         glReadBuffer(GL_AUX0);
760 #endif
761         
762         if(x1>=x2 || y1>=y2) return 0;
763         
764         ibuf = IMB_allocImBuf(2*size + 4, 2*size + 4, 32, IB_rect, 0);
765         glReadPixels(x1+curarea->winrct.xmin, y1+curarea->winrct.ymin, x2-x1+1, y2-y1+1, GL_RGBA, GL_UNSIGNED_BYTE,  ibuf->rect);
766         glReadBuffer(GL_BACK);  
767
768         if(G.order==B_ENDIAN)  {
769                 IMB_convert_rgba_to_abgr(ibuf);
770         }
771
772         rt= ibuf->rect;
773         size= (y2-y1)*(x2-x1);
774         if(size<=0) return 0;
775
776         memset(indexar, 0, sizeof(int)*totface+2);      /* plus 2! first element is total */
777         
778         while(size--) {
779                         
780                 if(*rt) {
781                         index= framebuffer_to_index(*rt);
782                         if(index>0 && index<=totface)
783                                 indexar[index] = 1;
784                 }
785         
786                 rt++;
787         }
788         
789         for(a=1; a<=totface; a++) {
790                 if(indexar[a]) indexar[tot++]= a;
791         }
792
793         IMB_freeImBuf(ibuf);
794         
795         return tot;
796 }
797
798 static int calc_vp_alpha_dl(VPaint *vp, float vpimat[][3], float *vert_nor, short *mval)
799 {
800         float fac, dx, dy;
801         int alpha;
802         short vertco[2];
803         
804         if(vp->flag & VP_SOFT) {
805                 project_short_noclip(vert_nor, vertco);
806                 dx= mval[0]-vertco[0];
807                 dy= mval[1]-vertco[1];
808                 
809                 fac= sqrt(dx*dx + dy*dy);
810                 if(fac > vp->size) return 0;
811                 if(vp->flag & VP_HARD)
812                         alpha= 255;
813                 else
814                         alpha= 255.0*vp->a*(1.0-fac/vp->size);
815         }
816         else {
817                 alpha= 255.0*vp->a;
818         }
819
820         if(vp->flag & VP_NORMALS) {
821                 float *no= vert_nor+3;
822                 
823                         /* transpose ! */
824                 fac= vpimat[2][0]*no[0]+vpimat[2][1]*no[1]+vpimat[2][2]*no[2];
825                 if(fac>0.0) {
826                         dx= vpimat[0][0]*no[0]+vpimat[0][1]*no[1]+vpimat[0][2]*no[2];
827                         dy= vpimat[1][0]*no[0]+vpimat[1][1]*no[1]+vpimat[1][2]*no[2];
828                         
829                         alpha*= fac/sqrt(dx*dx + dy*dy + fac*fac);
830                 }
831                 else return 0;
832         }
833         
834         return alpha;
835 }
836
837 static void wpaint_blend(MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval)
838 {
839         
840         if(dw==NULL || uw==NULL) return;
841         
842         if(Gwp.mode==VP_MIX || Gwp.mode==VP_FILT)
843                 dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
844         else if(Gwp.mode==VP_ADD)
845                 dw->weight += paintval*alpha;
846         else if(Gwp.mode==VP_SUB) 
847                 dw->weight -= paintval*alpha;
848         else if(Gwp.mode==VP_MUL) 
849                 /* first mul, then blend the fac */
850                 dw->weight = ((1.0-alpha) + alpha*paintval)*dw->weight;
851         else if(Gwp.mode==VP_LIGHTEN) {
852                 if (dw->weight < paintval)
853                         dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
854         } else if(Gwp.mode==VP_DARKEN) {
855                 if (dw->weight > paintval)
856                         dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
857         }
858         CLAMP(dw->weight, 0.0f, 1.0f);
859         
860         /* if no spray, clip result with orig weight & orig alpha */
861         if((Gwp.flag & VP_SPRAY)==0) {
862                 float testw=0.0f;
863                 
864                 alpha= Gwp.a;
865                 if(Gwp.mode==VP_MIX || Gwp.mode==VP_FILT)
866                         testw = paintval*alpha + uw->weight*(1.0-alpha);
867                 else if(Gwp.mode==VP_ADD)
868                         testw = uw->weight + paintval*alpha;
869                 else if(Gwp.mode==VP_SUB) 
870                         testw = uw->weight - paintval*alpha;
871                 else if(Gwp.mode==VP_MUL) 
872                         /* first mul, then blend the fac */
873                         testw = ((1.0-alpha) + alpha*paintval)*uw->weight;              
874                 else if(Gwp.mode==VP_LIGHTEN) {
875                         if (uw->weight < paintval)
876                                 testw = paintval*alpha + uw->weight*(1.0-alpha);
877                         else
878                                 testw = uw->weight;
879                 } else if(Gwp.mode==VP_DARKEN) {
880                         if (uw->weight > paintval)
881                                 testw = paintval*alpha + uw->weight*(1.0-alpha);
882                         else
883                                 testw = uw->weight;
884                 }
885                 CLAMP(testw, 0.0f, 1.0f);
886                 
887                 if( testw<uw->weight ) {
888                         if(dw->weight < testw) dw->weight= testw;
889                         else if(dw->weight > uw->weight) dw->weight= uw->weight;
890                 }
891                 else {
892                         if(dw->weight > testw) dw->weight= testw;
893                         else if(dw->weight < uw->weight) dw->weight= uw->weight;
894                 }
895         }
896         
897 }
898
899 /* ----------------------------------------------------- */
900
901 /* used for 3d view, on active object, assumes me->dvert exists */
902 /* if mode==1: */
903 /*     samples cursor location, and gives menu with vertex groups to activate */
904 /* else */
905 /*     sets editbutvweight to the closest weight value to vertex */
906 /*     note: we cant sample frontbuf, weight colors are interpolated too unpredictable */
907 static void sample_wpaint(int mode)
908 {
909         Object *ob= OBACT;
910         Mesh *me= get_mesh(ob);
911         int index;
912         short mval[2], sco[2];
913
914         if (!me) return;
915         
916         getmouseco_areawin(mval);
917         index= sample_backbuf(mval[0], mval[1]);
918         
919         if(index && index<=me->totface) {
920                 MFace *mface;
921                 
922                 mface= ((MFace *)me->mface) + index-1;
923                 
924                 if(mode==1) {   /* sampe which groups are in here */
925                         MDeformVert *dv;
926                         int a, totgroup;
927                         
928                         totgroup= BLI_countlist(&ob->defbase);
929                         if(totgroup) {
930                                 int totmenu=0;
931                                 int *groups=MEM_callocN(totgroup*sizeof(int), "groups");
932                                 
933                                 dv= me->dvert+mface->v1;
934                                 for(a=0; a<dv->totweight; a++) {
935                                         if (dv->dw[a].def_nr<totgroup)
936                                                 groups[dv->dw[a].def_nr]= 1;
937                                 }
938                                 dv= me->dvert+mface->v2;
939                                 for(a=0; a<dv->totweight; a++) {
940                                         if (dv->dw[a].def_nr<totgroup)
941                                                 groups[dv->dw[a].def_nr]= 1;
942                                 }
943                                 dv= me->dvert+mface->v3;
944                                 for(a=0; a<dv->totweight; a++) {
945                                         if (dv->dw[a].def_nr<totgroup)
946                                                 groups[dv->dw[a].def_nr]= 1;
947                                 }
948                                 if(mface->v4) {
949                                         dv= me->dvert+mface->v4;
950                                         for(a=0; a<dv->totweight; a++) {
951                                                 if (dv->dw[a].def_nr<totgroup)
952                                                         groups[dv->dw[a].def_nr]= 1;
953                                         }
954                                 }
955                                 for(a=0; a<totgroup; a++)
956                                         if(groups[a]) totmenu++;
957                                 
958                                 if(totmenu==0) {
959                                         notice("No Vertex Group Selected");
960                                 }
961                                 else {
962                                         bDeformGroup *dg;
963                                         short val;
964                                         char item[40], *str= MEM_mallocN(40*totmenu+40, "menu");
965                                         
966                                         strcpy(str, "Vertex Groups %t");
967                                         for(a=0, dg=ob->defbase.first; dg && a<totgroup; a++, dg= dg->next) {
968                                                 if(groups[a]) {
969                                                         sprintf(item, "|%s %%x%d", dg->name, a);
970                                                         strcat(str, item);
971                                                 }
972                                         }
973                                         
974                                         val= pupmenu(str);
975                                         if(val>=0) {
976                                                 ob->actdef= val+1;
977                                                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
978                                                 allqueue(REDRAWVIEW3D, 0);
979                                                 allqueue(REDRAWOOPS, 0);
980                                                 allqueue(REDRAWBUTSEDIT, 0);
981                                         }
982                                         MEM_freeN(str);
983                                 }
984                                 MEM_freeN(groups);
985                         }
986                         else notice("No Vertex Groups in Object");
987                 }
988                 else {
989                         DerivedMesh *dm;
990                         MDeformWeight *dw;
991                         extern float editbutvweight;
992                         float w1, w2, w3, w4, co[3], fac;
993                         
994                         dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
995                         if(dm->getVertCo==NULL) {
996                                 notice("Not supported yet");
997                         }
998                         else {
999                                 /* calc 3 or 4 corner weights */
1000                                 dm->getVertCo(dm, mface->v1, co);
1001                                 project_short_noclip(co, sco);
1002                                 w1= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
1003                                 
1004                                 dm->getVertCo(dm, mface->v2, co);
1005                                 project_short_noclip(co, sco);
1006                                 w2= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
1007                                 
1008                                 dm->getVertCo(dm, mface->v3, co);
1009                                 project_short_noclip(co, sco);
1010                                 w3= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
1011                                 
1012                                 if(mface->v4) {
1013                                         dm->getVertCo(dm, mface->v4, co);
1014                                         project_short_noclip(co, sco);
1015                                         w4= ((mval[0]-sco[0])*(mval[0]-sco[0]) + (mval[1]-sco[1])*(mval[1]-sco[1]));
1016                                 }
1017                                 else w4= 1.0e10;
1018                                 
1019                                 fac= MIN4(w1, w2, w3, w4);
1020                                 if(w1==fac) {
1021                                         dw= get_defweight(me->dvert+mface->v1, ob->actdef-1);
1022                                         if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
1023                                 }
1024                                 else if(w2==fac) {
1025                                         dw= get_defweight(me->dvert+mface->v2, ob->actdef-1);
1026                                         if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
1027                                 }
1028                                 else if(w3==fac) {
1029                                         dw= get_defweight(me->dvert+mface->v3, ob->actdef-1);
1030                                         if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
1031                                 }
1032                                 else if(w4==fac) {
1033                                         if(mface->v4) {
1034                                                 dw= get_defweight(me->dvert+mface->v4, ob->actdef-1);
1035                                                 if(dw) editbutvweight= dw->weight; else editbutvweight= 0.0f;
1036                                         }
1037                                 }
1038                         }
1039                         dm->release(dm);
1040                 }               
1041                 
1042         }
1043         allqueue(REDRAWBUTSEDIT, 0);
1044         
1045 }
1046
1047 static void do_weight_paint_vertex(Object *ob, int index, int alpha, float paintweight, int vgroup_mirror)
1048 {
1049         Mesh *me= ob->data;
1050         MDeformWeight   *dw, *uw;
1051         int vgroup= ob->actdef-1;
1052         
1053         if(Gwp.flag & VP_ONLYVGROUP) {
1054                 dw= get_defweight(me->dvert+index, vgroup);
1055                 uw= get_defweight(Gwp.wpaint_prev+index, vgroup);
1056         }
1057         else {
1058                 dw= verify_defweight(me->dvert+index, vgroup);
1059                 uw= verify_defweight(Gwp.wpaint_prev+index, vgroup);
1060         }
1061         if(dw==NULL || uw==NULL)
1062                 return;
1063         
1064         wpaint_blend(dw, uw, (float)alpha/255.0, paintweight);
1065         
1066         if(Gwp.flag & VP_MIRROR_X) {    /* x mirror painting */
1067                 int j= mesh_get_x_mirror_vert(ob, index);
1068                 if(j>=0) {
1069                         /* copy, not paint again */
1070                         if(vgroup_mirror != -1)
1071                                 uw= verify_defweight(me->dvert+j, vgroup_mirror);
1072                         else
1073                                 uw= verify_defweight(me->dvert+j, vgroup);
1074                                 
1075                         uw->weight= dw->weight;
1076                 }
1077         }
1078 }
1079
1080 void weight_paint(void)
1081 {
1082         extern float editbutvweight;
1083         Object *ob; 
1084         Mesh *me;
1085         MFace *mface;
1086         MTFace *tface;
1087         float mat[4][4], imat[4][4], paintweight, *vertexcosnos;
1088         float vpimat[3][3];
1089         int *indexar, index, totindex, alpha, totw;
1090         int vgroup_mirror= -1;
1091         short mval[2], mvalo[2], firsttime=1, mousebut;
1092
1093         if((G.f & G_WEIGHTPAINT)==0) return;
1094         if(G.obedit) return;
1095         if(multires_level1_test()) return;
1096         
1097         ob= OBACT;
1098         if(!ob || ob->id.lib) return;
1099
1100         me= get_mesh(ob);
1101         if(me==NULL || me->totface==0) return;
1102         
1103         /* if nothing was added yet, we make dverts and a vertex deform group */
1104         if (!me->dvert)
1105                 create_dverts(&me->id);
1106         
1107         if(G.qual & LR_CTRLKEY) {
1108                 sample_wpaint(0);
1109                 return;
1110         }
1111         if(G.qual & LR_SHIFTKEY) {
1112                 sample_wpaint(1);
1113                 return;
1114         }
1115         
1116         /* ALLOCATIONS! no return after this line */
1117                 /* painting on subsurfs should give correct points too, this returns me->totvert amount */
1118         vertexcosnos= mesh_get_mapped_verts_nors(ob);
1119         indexar= get_indexarray();
1120         copy_wpaint_prev(&Gwp, me->dvert, me->totvert);
1121
1122         /* this happens on a Bone select, when no vgroup existed yet */
1123         if(ob->actdef<=0) {
1124                 Object *modob;
1125                 if((modob = modifiers_isDeformedByArmature(ob))) {
1126                         bPoseChannel *pchan;
1127                         for(pchan= modob->pose->chanbase.first; pchan; pchan= pchan->next)
1128                                 if(pchan->bone->flag & SELECT)
1129                                         break;
1130                         if(pchan) {
1131                                 bDeformGroup *dg= get_named_vertexgroup(ob, pchan->name);
1132                                 if(dg==NULL)
1133                                         dg= add_defgroup_name(ob, pchan->name); /* sets actdef */
1134                                 else
1135                                         ob->actdef= get_defgroup_num(ob, dg);
1136                                 allqueue(REDRAWBUTSEDIT, 0);
1137                         }
1138                 }
1139         }
1140         if(ob->defbase.first==NULL) {
1141                 add_defgroup(ob);
1142                 allqueue(REDRAWBUTSEDIT, 0);
1143         }       
1144         
1145         if(ob->lay & G.vd->lay); else error("Active object is not in this layer");
1146         
1147         persp(PERSP_VIEW);
1148         /* imat for normals */
1149         Mat4MulMat4(mat, ob->obmat, G.vd->viewmat);
1150         Mat4Invert(imat, mat);
1151         Mat3CpyMat4(vpimat, imat);
1152         
1153         /* load projection matrix */
1154         mymultmatrix(ob->obmat);
1155         mygetsingmatrix(mat);
1156         myloadmatrix(G.vd->viewmat);
1157         
1158         getmouseco_areawin(mvalo);
1159         
1160         getmouseco_areawin(mval);
1161         mvalo[0]= mval[0];
1162         mvalo[1]= mval[1];
1163         
1164         if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE;
1165         else mousebut = L_MOUSE;
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() & mousebut) {
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->mtface) {
1224                                 for(index=0; index<totindex; index++) {
1225                                         if(indexar[index] && indexar[index]<=me->totface) {
1226                                         
1227                                                 tface= ((MTFace *)me->mtface) + (indexar[index]-1);
1228                                         
1229                                                 if((tface->flag & TF_SELECT)==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_FILT) 
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_FILT) {
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_FILT) 
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         BIF_undo_push("Weight Paint");
1352         allqueue(REDRAWVIEW3D, 0);
1353 }
1354
1355 void vertex_paint()
1356 {
1357         Object *ob;
1358         Mesh *me;
1359         MFace *mface;
1360         MTFace *tface;
1361         float mat[4][4], imat[4][4], *vertexcosnos;
1362         float vpimat[3][3];
1363         unsigned int paintcol=0, *mcol, *mcolorig, fcol1, fcol2;
1364         int *indexar, index, alpha, totindex;
1365         short mval[2], mvalo[2], firsttime=1, mousebut;
1366         
1367         if((G.f & G_VERTEXPAINT)==0) return;
1368         if(G.obedit) return;
1369         
1370         ob= OBACT;
1371         if(!ob || ob->id.lib) return;
1372
1373         me= get_mesh(ob);
1374         if(me==NULL || me->totface==0) return;
1375         if(ob->lay & G.vd->lay); else error("Active object is not in this layer");
1376         
1377         if(me->mtface==NULL && me->mcol==NULL) make_vertexcol(1);
1378
1379         if(me->mtface==NULL && me->mcol==NULL) return;
1380         
1381         /* ALLOCATIONS! No return after his line */
1382         
1383                                 /* painting on subsurfs should give correct points too, this returns me->totvert amount */
1384         vertexcosnos= mesh_get_mapped_verts_nors(ob);
1385         indexar= get_indexarray();
1386         copy_vpaint_prev(&Gvp, (unsigned int *)me->mcol, me->totface);
1387         
1388         /* opengl/matrix stuff */
1389         persp(PERSP_VIEW);
1390         /* imat for normals */
1391         Mat4MulMat4(mat, ob->obmat, G.vd->viewmat);
1392         Mat4Invert(imat, mat);
1393         Mat3CpyMat4(vpimat, imat);
1394         
1395         /* load projection matrix */
1396         mymultmatrix(ob->obmat);
1397         mygetsingmatrix(mat);
1398         myloadmatrix(G.vd->viewmat);
1399         
1400         paintcol= vpaint_get_current_col(&Gvp);
1401         
1402         getmouseco_areawin(mvalo);
1403         
1404         getmouseco_areawin(mval);
1405         mvalo[0]= mval[0];
1406         mvalo[1]= mval[1];
1407         
1408         if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE;
1409         else mousebut = L_MOUSE;
1410         
1411         while (get_mbut() & mousebut) {
1412                 getmouseco_areawin(mval);
1413                 
1414                 if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
1415
1416                         firsttime= 0;
1417
1418                         /* which faces are involved */
1419                         if(Gvp.flag & VP_AREA) {
1420                                 totindex= sample_backbuf_area(&Gvp, indexar, me->totface, mval[0], mval[1], Gvp.size);
1421                         }
1422                         else {
1423                                 indexar[0]= sample_backbuf(mval[0], mval[1]);
1424                                 if(indexar[0]) totindex= 1;
1425                                 else totindex= 0;
1426                         }
1427                         
1428                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1429                         
1430                         if(Gvp.flag & VP_COLINDEX) {
1431                                 for(index=0; index<totindex; index++) {
1432                                         if(indexar[index] && indexar[index]<=me->totface) {
1433                                         
1434                                                 mface= ((MFace *)me->mface) + (indexar[index]-1);
1435                                         
1436                                                 if(mface->mat_nr!=ob->actcol-1) {
1437                                                         indexar[index]= 0;
1438                                                 }
1439                                         }                                       
1440                                 }
1441                         }
1442                         if((G.f & G_FACESELECT) && me->mtface) {
1443                                 for(index=0; index<totindex; index++) {
1444                                         if(indexar[index] && indexar[index]<=me->totface) {
1445                                                 tface= ((MTFace *)me->mtface) + (indexar[index]-1);
1446                                         
1447                                                 if((tface->flag & TF_SELECT)==0)
1448                                                         indexar[index]= 0;
1449                                         }                                       
1450                                 }
1451                         }
1452
1453                         for(index=0; index<totindex; index++) {
1454
1455                                 if(indexar[index] && indexar[index]<=me->totface) {
1456                                 
1457                                         mface= ((MFace *)me->mface) + (indexar[index]-1);
1458                                         mcol=     ( (unsigned int *)me->mcol) + 4*(indexar[index]-1);
1459                                         mcolorig= ( (unsigned int *)Gvp.vpaint_prev) + 4*(indexar[index]-1);
1460
1461                                         if(Gvp.mode==VP_FILT) {
1462                                                 fcol1= mcol_blend( mcol[0], mcol[1], 128);
1463                                                 if(mface->v4) {
1464                                                         fcol2= mcol_blend( mcol[2], mcol[3], 128);
1465                                                         paintcol= mcol_blend( fcol1, fcol2, 128);
1466                                                 }
1467                                                 else {
1468                                                         paintcol= mcol_blend( mcol[2], fcol1, 170);
1469                                                 }
1470                                                 
1471                                         }
1472                                         
1473                                         alpha= calc_vp_alpha_dl(&Gvp, vpimat, vertexcosnos+6*mface->v1, mval);
1474                                         if(alpha) vpaint_blend( mcol, mcolorig, paintcol, alpha);
1475                                         
1476                                         alpha= calc_vp_alpha_dl(&Gvp, vpimat, vertexcosnos+6*mface->v2, mval);
1477                                         if(alpha) vpaint_blend( mcol+1, mcolorig+1, paintcol, alpha);
1478         
1479                                         alpha= calc_vp_alpha_dl(&Gvp, vpimat, vertexcosnos+6*mface->v3, mval);
1480                                         if(alpha) vpaint_blend( mcol+2, mcolorig+2, paintcol, alpha);
1481
1482                                         if(mface->v4) {
1483                                                 alpha= calc_vp_alpha_dl(&Gvp, vpimat, vertexcosnos+6*mface->v4, mval);
1484                                                 if(alpha) vpaint_blend( mcol+3, mcolorig+3, paintcol, alpha);
1485                                         }
1486                                 }
1487                         }
1488                                 
1489                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1490                         
1491                         do_shared_vertexcol(me);
1492         
1493                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1494                         scrarea_do_windraw(curarea);
1495
1496                         if(Gvp.flag & (VP_AREA|VP_SOFT)) {
1497                                 /* draw circle in backbuf! */
1498                                 persp(PERSP_WIN);
1499                                 fdrawXORcirc((float)mval[0], (float)mval[1], Gvp.size);
1500                                 persp(PERSP_VIEW);
1501                         }
1502                         screen_swapbuffers();
1503                         backdrawview3d(0);
1504                         
1505                         mvalo[0]= mval[0];
1506                         mvalo[1]= mval[1];
1507                 }
1508                 else BIF_wait_for_statechange();
1509         }
1510         
1511         if(vertexcosnos)
1512                 MEM_freeN(vertexcosnos);
1513         MEM_freeN(indexar);
1514         
1515         /* frees prev buffer */
1516         copy_vpaint_prev(&Gvp, NULL, 0);
1517
1518         BIF_undo_push("Vertex Paint");
1519         
1520         allqueue(REDRAWVIEW3D, 0);
1521 }
1522
1523 void set_wpaint(void)           /* toggle */
1524 {               
1525         Object *ob;
1526         Mesh *me;
1527         
1528         scrarea_queue_headredraw(curarea);
1529         ob= OBACT;
1530         if(!ob || ob->id.lib) return;
1531         me= get_mesh(ob);
1532                 
1533         if(me && me->totface>=MAXINDEX) {
1534                 error("Maximum number of faces: %d", MAXINDEX-1);
1535                 G.f &= ~G_WEIGHTPAINT;
1536                 return;
1537         }
1538         
1539         if(G.f & G_WEIGHTPAINT) G.f &= ~G_WEIGHTPAINT;
1540         else G.f |= G_WEIGHTPAINT;
1541         
1542         allqueue(REDRAWVIEW3D, 1);      /* including header */
1543         allqueue(REDRAWBUTSEDIT, 0);
1544         
1545                 /* Weightpaint works by overriding colors in mesh,
1546                  * so need to make sure we recalc on enter and
1547                  * exit (exit needs doing regardless because we
1548                  * should redeform).
1549                  */
1550         if (me) {
1551                 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1552         }
1553
1554         if(G.f & G_WEIGHTPAINT) {
1555                 Object *par;
1556                 
1557                 setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT);
1558                 
1559                 mesh_octree_table(ob, NULL, 's');
1560
1561                 /* verify if active weight group is also active bone */
1562                 par= modifiers_isDeformedByArmature(ob);
1563                 if(par && (par->flag & OB_POSEMODE)) {
1564                         bPoseChannel *pchan;
1565                         for(pchan= par->pose->chanbase.first; pchan; pchan= pchan->next)
1566                                 if(pchan->bone->flag & BONE_ACTIVE)
1567                                         break;
1568                         if(pchan)
1569                                 vertexgroup_select_by_name(ob, pchan->name);
1570                 }
1571         }
1572         else {
1573                 if(!(G.f & G_FACESELECT))
1574                         setcursor_space(SPACE_VIEW3D, CURSOR_STD);
1575                 
1576                 mesh_octree_table(ob, NULL, 'e');
1577         }
1578 }
1579
1580
1581 void set_vpaint(void)           /* toggle */
1582 {               
1583         Object *ob;
1584         Mesh *me;
1585         
1586         scrarea_queue_headredraw(curarea);
1587         ob= OBACT;
1588         if(!ob || ob->id.lib) {
1589                 G.f &= ~G_VERTEXPAINT;
1590                 return;
1591         }
1592         
1593         me= get_mesh(ob);
1594         
1595         if(me && me->totface>=MAXINDEX) {
1596                 error("Maximum number of faces: %d", MAXINDEX-1);
1597                 G.f &= ~G_VERTEXPAINT;
1598                 return;
1599         }
1600         
1601         if(me && me->mcol==NULL) make_vertexcol(1);
1602         
1603         if(G.f & G_VERTEXPAINT){
1604                 G.f &= ~G_VERTEXPAINT;
1605         }
1606         else {
1607                 G.f |= G_VERTEXPAINT;
1608                 /* Turn off weight painting */
1609                 if (G.f & G_WEIGHTPAINT)
1610                         set_wpaint();
1611         }
1612         
1613         allqueue(REDRAWVIEW3D, 1);      /* including header */
1614         allqueue(REDRAWBUTSEDIT, 0);
1615         
1616         if (me)
1617                 /* update modifier stack for mapping requirements */
1618                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1619
1620         if(G.f & G_VERTEXPAINT) {
1621                 setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT);
1622         }
1623         else {
1624                 if((G.f & G_FACESELECT)==0) setcursor_space(SPACE_VIEW3D, CURSOR_STD);
1625         }
1626 }
1627