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