Initial revision
[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
35 #ifdef WIN32
36 #include <io.h>
37 #include "BLI_winstuff.h"
38 #else
39 #include <unistd.h>
40 #endif   
41
42 #include "MEM_guardedalloc.h"
43
44 #include "IMB_imbuf.h"
45
46 #include "BLI_blenlib.h"
47 #include "BLI_arithb.h"
48 #include "BLI_editVert.h"
49 #include "MTC_matrixops.h"
50
51 #include "DNA_mesh_types.h"
52 #include "DNA_object_types.h"
53 #include "DNA_screen_types.h"
54 #include "DNA_scene_types.h"
55 #include "DNA_view3d_types.h"
56
57 #include "BKE_utildefines.h"
58 #include "BKE_mesh.h"
59 #include "BKE_displist.h"
60 #include "BKE_global.h"
61
62 #include "BIF_graphics.h"
63 #include "BIF_interface.h"
64 #include "BIF_mywindow.h"
65 #include "BIF_editview.h"
66 #include "BIF_space.h"
67 #include "BIF_screen.h"
68 #include "BIF_toolbox.h"
69 #include "BIF_gl.h"
70
71 #include "BDR_vpaint.h"
72
73 #include "BSE_drawview.h"
74 #include "BSE_trans_types.h"
75 #include "BSE_view.h"
76
77 #include "mydevice.h"
78 #include "blendef.h"
79
80 #include "BIF_editdeform.h"
81
82         /* Gvp.mode */
83 #define VP_MIX  0
84 #define VP_ADD  1
85 #define VP_SUB  2
86 #define VP_MUL  3
87 #define VP_FILT 4
88
89         /* Gvp.flag */
90 #define VP_COLINDEX     1
91 #define VP_AREA         2
92 #define VP_SOFT         4
93 #define VP_NORMALS      8
94
95 #define MAXINDEX        65336
96
97 VPaint Gvp= {1.0, 1.0, 1.0, 0.2, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT};
98 float vpimat[3][3];
99 unsigned int *vpaintundobuf=0;
100 int totvpaintundo;
101 short *indexar= 0;
102
103 int totwpaintundo;
104 MDeformVert *wpaintundobuf=NULL;
105
106 /* Function prototypes */
107 int calc_vp_alpha_dl(DispList *disp, MVert *mvert, int vert, short *mval);
108
109 /* in tegenstelling tot cpack teken kleuren, zijn de MCOL kleuren (vpaint kleuren) per byte! 
110    en dus endian ongevoelig. Mcol = ABGR!!! Oppassen met cpack functies */
111
112 unsigned int rgba_to_mcol(float r, float g, float b, float a)
113 {
114         int ir, ig, ib, ia;
115         unsigned int col;
116         char *cp;
117         
118         ir= floor(255.0*r);
119         if(ir<0) ir= 0; else if(ir>255) ir= 255;
120         ig= floor(255.0*g);
121         if(ig<0) ig= 0; else if(ig>255) ig= 255;
122         ib= floor(255.0*b);
123         if(ib<0) ib= 0; else if(ib>255) ib= 255;
124         ia= floor(255.0*a);
125         if(ia<0) ia= 0; else if(ia>255) ia= 255;
126         
127         cp= (char *)&col;
128         cp[0]= ia;
129         cp[1]= ib;
130         cp[2]= ig;
131         cp[3]= ir;
132         
133         return col;
134         
135 }
136
137 unsigned int vpaint_get_current_col(void)
138 {
139         return rgba_to_mcol(Gvp.r, Gvp.g, Gvp.b, 1.0);
140 }
141
142 void do_shared_vertexcol(Mesh *me)
143 {
144         /* als geen mcol: niet doen */
145         /* als tface: alleen de betreffende vlakken, anders alles */
146         MFace *mface;
147         TFace *tface;
148         int a;
149         short *scolmain, *scol;
150         char *mcol;
151         
152         if(me->mcol==0 || me->totvert==0 || me->totface==0) return;
153         
154         scolmain= MEM_callocN(4*sizeof(short)*me->totvert, "colmain");
155         
156         tface= me->tface;
157         mface= me->mface;
158         mcol= (char *)me->mcol;
159         for(a=me->totface; a>0; a--, mface++, mcol+=16) {
160                 if(mface->v3) {
161                         if(tface==0 || (tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) {
162                                 
163                                 scol= scolmain+4*mface->v1;
164                                 scol[0]++; scol[1]+= mcol[1]; scol[2]+= mcol[2]; scol[3]+= mcol[3];
165                                 scol= scolmain+4*mface->v2;
166                                 scol[0]++; scol[1]+= mcol[5]; scol[2]+= mcol[6]; scol[3]+= mcol[7];
167                                 scol= scolmain+4*mface->v3;
168                                 scol[0]++; scol[1]+= mcol[9]; scol[2]+= mcol[10]; scol[3]+= mcol[11];
169                                 if(mface->v4) {
170                                         scol= scolmain+4*mface->v4;
171                                         scol[0]++; scol[1]+= mcol[13]; scol[2]+= mcol[14]; scol[3]+= mcol[15];
172                                 }
173                         }
174                 }
175                 if(tface) tface++;
176         }
177         
178         a= me->totvert;
179         scol= scolmain;
180         while(a--) {
181                 if(scol[0]>1) {
182                         scol[1]/= scol[0];
183                         scol[2]/= scol[0];
184                         scol[3]/= scol[0];
185                 }
186                 scol+= 4;
187         }
188         
189         tface= me->tface;
190         mface= me->mface;
191         mcol= (char *)me->mcol;
192         for(a=me->totface; a>0; a--, mface++, mcol+=16) {
193                 if(mface->v3) {
194                         if(tface==0 || (tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) {
195                                 
196                                 scol= scolmain+4*mface->v1;
197                                 mcol[1]= scol[1]; mcol[2]= scol[2]; mcol[3]= scol[3];
198                                 
199                                 scol= scolmain+4*mface->v2;
200                                 mcol[5]= scol[1]; mcol[6]= scol[2]; mcol[7]= scol[3];
201                                 
202                                 scol= scolmain+4*mface->v3;
203                                 mcol[9]= scol[1]; mcol[10]= scol[2]; mcol[11]= scol[3];
204                                 
205                                 if(mface->v4) {
206                                         scol= scolmain+4*mface->v4;
207                                         mcol[13]= scol[1]; mcol[14]= scol[2]; mcol[15]= scol[3];
208                                 }
209                         }
210                 }
211                 if(tface) tface++;
212         }
213
214         MEM_freeN(scolmain);
215 }
216
217 void make_vertexcol()   /* single ob */
218 {
219         Object *ob;
220         Mesh *me;
221         DispList *dl;
222         
223         /*
224          * Always copies from shadedisplist to mcol.
225          * When there are tfaces, it copies the colors and frees mcol
226          */
227         
228         if(G.obedit) {
229                 error("Unable to perform function in EditMode");
230                 return;
231         }
232         
233         ob= OBACT;
234         me= get_mesh(ob);
235         if(me==0) return;
236
237         if(me->flag & ME_TWOSIDED) {
238                 me->flag &= ~ME_TWOSIDED;
239         }
240         
241         dl= ob->disp.first;
242         
243         if(dl==0 || dl->col1==NULL) {
244                 shadeDispList(ob);
245                 dl= ob->disp.first;
246         }
247         if(dl && dl->col1) {
248                 int i;
249                 
250                 if(me->mcol) MEM_freeN(me->mcol);
251                 
252                 me->mcol= MEM_dupallocN(dl->col1);
253                 if (me->mcol) {
254                         for (i=0; i<me->totface*4; i++) {
255                                 MCol *mcol= &me->mcol[i];
256                                 mcol->a= 255;
257                         }
258                 }
259                 
260                 if(me->tface) mcol_to_tface(me, 1);
261         }
262         freedisplist(&(ob->disp));
263         
264         
265         allqueue(REDRAWBUTSEDIT, 0);
266         allqueue(REDRAWVIEW3D, 0);
267 }
268
269
270
271 void copy_vpaint_undo(unsigned int *mcol, int tot)
272 {
273         if(vpaintundobuf) MEM_freeN(vpaintundobuf);
274         vpaintundobuf= 0;
275         
276         if(mcol==0 || tot==0) return;
277         
278         vpaintundobuf= MEM_mallocN(4*sizeof(int)*tot, "vpaintundobuf");
279         memcpy(vpaintundobuf, mcol, 4*sizeof(int)*tot);
280         totvpaintundo= tot;
281         
282 }
283
284 void vpaint_undo()
285 {
286         Mesh *me;
287         Object *ob;
288         unsigned int temp, *from, *to;
289         int a;
290         
291         if((G.f & G_VERTEXPAINT)==0) return;
292         if(vpaintundobuf==0) return;
293
294         ob= OBACT;
295         me= get_mesh(ob);
296         if(me==0 || me->totface==0) return;
297
298         if(me->tface) tface_to_mcol(me);
299         else if(me->mcol==0) return;
300         
301         a= MIN2(me->totface, totvpaintundo);
302         from= vpaintundobuf;
303         to= (unsigned int *)me->mcol;
304         a*= 4;
305         while(a--) {
306                 temp= *to;
307                 *to= *from;
308                 *from= temp;
309                 to++; from++;
310         }
311         allqueue(REDRAWVIEW3D, 0);
312         if(me->tface) mcol_to_tface(me, 1);
313 }
314
315 void clear_vpaint()
316 {
317         Mesh *me;
318         Object *ob;
319         unsigned int *to, paintcol;
320         int a;
321         
322         if((G.f & G_VERTEXPAINT)==0) return;
323
324         ob= OBACT;
325         me= get_mesh(ob);
326         if(me==0 || me->totface==0) return;
327
328         if(me->tface) tface_to_mcol(me);
329         if(me->mcol==0) return;
330
331         paintcol= vpaint_get_current_col();
332
333         to= (unsigned int *)me->mcol;
334         copy_vpaint_undo(to, me->totface);
335         a= 4*me->totface;
336         while(a--) {
337                 *to= paintcol;
338                 to++; 
339         }
340         allqueue(REDRAWVIEW3D, 0);
341         if(me->tface) mcol_to_tface(me, 1);
342 }
343
344 void clear_vpaint_selectedfaces()
345 {
346         Mesh *me;
347         TFace *tf;
348         Object *ob;
349         unsigned int paintcol;
350         int i;
351
352         ob= OBACT;
353
354         me= get_mesh(ob);
355         tf = me->tface;
356         if (!tf) return; /* should not happen, but you never know */
357
358         if(me==0 || me->totface==0) return;
359
360         paintcol= vpaint_get_current_col();
361
362         for (i = 0; i < me->totface; i++) {
363                 if (tf[i].flag & TF_SELECT) {
364                         tf[i].col[0] = paintcol;
365                         tf[i].col[1] = paintcol;
366                         tf[i].col[2] = paintcol;
367                         tf[i].col[3] = paintcol;
368                 }
369         }
370         allqueue(REDRAWVIEW3D, 0);
371 }
372
373 void vpaint_dogamma()
374 {
375         Mesh *me;
376         Object *ob;
377         float igam, fac;
378         int a, temp;
379         char *cp, gamtab[256];
380
381         if((G.f & G_VERTEXPAINT)==0) return;
382
383         ob= OBACT;
384         me= get_mesh(ob);
385         if(me==0 || me->totface==0) return;
386
387         if(me->tface) tface_to_mcol(me);
388         else if(me->mcol==0) return;
389
390         copy_vpaint_undo((unsigned int *)me->mcol, me->totface);
391
392         igam= 1.0/Gvp.gamma;
393         for(a=0; a<256; a++) {
394                 
395                 fac= ((float)a)/255.0;
396                 fac= Gvp.mul*pow( fac, igam);
397                 
398                 temp= 255.9*fac;
399                 
400                 if(temp<=0) gamtab[a]= 0;
401                 else if(temp>=255) gamtab[a]= 255;
402                 else gamtab[a]= temp;
403         }
404
405         a= 4*me->totface;
406         cp= (char *)me->mcol;
407         while(a--) {
408                 
409                 cp[1]= gamtab[ cp[1] ];
410                 cp[2]= gamtab[ cp[2] ];
411                 cp[3]= gamtab[ cp[3] ];
412                 
413                 cp+= 4;
414         }
415         allqueue(REDRAWVIEW3D, 0);
416         
417         if(me->tface) mcol_to_tface(me, 1);
418 }
419
420
421 void sample_vpaint()    /* frontbuf */
422 {
423         unsigned int col;
424         int x, y;
425         short mval[2];
426         char *cp;
427         
428         getmouseco_areawin(mval);
429         x= mval[0]; y= mval[1];
430         
431         if(x<0 || y<0) return;
432         if(x>=curarea->winx || y>=curarea->winy) return;
433         
434         x+= curarea->winrct.xmin;
435         y+= curarea->winrct.ymin;
436         
437         glReadBuffer(GL_FRONT);
438         glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
439         glReadBuffer(GL_BACK);
440
441         cp = (char *)&col;
442         
443         Gvp.r= cp[0];
444         Gvp.r /= 255.0;
445
446         Gvp.g= cp[1];
447         Gvp.g /= 255.0;
448
449         Gvp.b= cp[2];
450         Gvp.b /= 255.0;
451
452         allqueue(REDRAWBUTSGAME, 0);
453 }
454
455 void init_vertexpaint()
456 {
457         
458         indexar= MEM_mallocN(sizeof(short)*MAXINDEX + 2, "vertexpaint");
459 }
460
461
462 void free_vertexpaint()
463 {
464         
465         if(indexar) MEM_freeN(indexar);
466         indexar= NULL;
467         if(vpaintundobuf) MEM_freeN(vpaintundobuf);
468         vpaintundobuf= NULL;
469         if(wpaintundobuf) 
470                 free_dverts(wpaintundobuf, totwpaintundo);
471         wpaintundobuf= NULL;
472 }
473
474
475 static unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac)
476 {
477         char *cp1, *cp2, *cp;
478         int mfac;
479         unsigned int col=0;
480         
481         if(fac==0) return col1;
482         if(fac>=255) return col2;
483
484         mfac= 255-fac;
485         
486         cp1= (char *)&col1;
487         cp2= (char *)&col2;
488         cp=  (char *)&col;
489         
490         cp[0]= 255;
491         cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8;
492         cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8;
493         cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8;
494         
495         return col;
496 }
497
498 static unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac)
499 {
500         char *cp1, *cp2, *cp;
501         int temp;
502         unsigned int col=0;
503         
504         if(fac==0) return col1;
505         
506         cp1= (char *)&col1;
507         cp2= (char *)&col2;
508         cp=  (char *)&col;
509         
510         cp[0]= 255;
511         temp= cp1[1] + ((fac*cp2[1])>>8);
512         if(temp>254) cp[1]= 255; else cp[1]= temp;
513         temp= cp1[2] + ((fac*cp2[2])>>8);
514         if(temp>254) cp[2]= 255; else cp[2]= temp;
515         temp= cp1[3] + ((fac*cp2[3])>>8);
516         if(temp>254) cp[3]= 255; else cp[3]= temp;
517         
518         return col;
519 }
520
521 static unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac)
522 {
523         char *cp1, *cp2, *cp;
524         int temp;
525         unsigned int col=0;
526         
527         if(fac==0) return col1;
528         
529         cp1= (char *)&col1;
530         cp2= (char *)&col2;
531         cp=  (char *)&col;
532         
533         cp[0]= 255;
534         temp= cp1[1] - ((fac*cp2[1])>>8);
535         if(temp<0) cp[1]= 0; else cp[1]= temp;
536         temp= cp1[2] - ((fac*cp2[2])>>8);
537         if(temp<0) cp[2]= 0; else cp[2]= temp;
538         temp= cp1[3] - ((fac*cp2[3])>>8);
539         if(temp<0) cp[3]= 0; else cp[3]= temp;
540         
541         return col;
542 }
543
544 static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac)
545 {
546         char *cp1, *cp2, *cp;
547         int mfac;
548         unsigned int col=0;
549         
550         if(fac==0) return col1;
551
552         mfac= 255-fac;
553         
554         cp1= (char *)&col1;
555         cp2= (char *)&col2;
556         cp=  (char *)&col;
557         
558         /* eerstmullen, dan fac blenden */
559         cp[0]= 255;
560         cp[1]= (mfac*cp1[1] + fac*((cp2[1]*cp1[1])>>8)  )>>8;
561         cp[2]= (mfac*cp1[2] + fac*((cp2[2]*cp1[2])>>8)  )>>8;
562         cp[3]= (mfac*cp1[3] + fac*((cp2[3]*cp1[3])>>8)  )>>8;
563
564         
565         return col;
566 }
567
568 static void vpaint_blend( unsigned int *col, unsigned int paintcol, int alpha)
569 {
570         
571         if(Gvp.mode==VP_MIX || Gvp.mode==VP_FILT) *col= mcol_blend( *col, paintcol, alpha);
572         else if(Gvp.mode==VP_ADD) *col= mcol_add( *col, paintcol, alpha);
573         else if(Gvp.mode==VP_SUB) *col= mcol_sub( *col, paintcol, alpha);
574         else if(Gvp.mode==VP_MUL) *col= mcol_mul( *col, paintcol, alpha);
575 }
576
577
578 static int sample_backbuf_area(int x, int y)
579 {
580         unsigned int rect[129*129], *rt;
581         int x1, y1, x2, y2, size, a, tot=0, index;
582         
583         if(totvpaintundo>=MAXINDEX) return 0;
584         
585         if(Gvp.size>64.0) Gvp.size= 64.0;
586         
587         x1= x-Gvp.size;
588         x2= x+Gvp.size;
589         CLAMP(x1, 0, curarea->winx);
590         CLAMP(x2, 0, curarea->winx);
591         y1= y-Gvp.size;
592         y2= y+Gvp.size;
593         CLAMP(y1, 0, curarea->winy);
594         CLAMP(y2, 0, curarea->winy);
595         
596         glReadPixels(x1+curarea->winrct.xmin, y1+curarea->winrct.ymin, x2-x1+1, y2-y1+1, GL_RGBA, GL_UNSIGNED_BYTE,  rect);
597         if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr( (int)(4*Gvp.size*Gvp.size), rect);
598
599         rt= rect;
600         size= (y2-y1)*(x2-x1);
601         if(size<=0) return 0;
602
603         memset(indexar, 0, 2*totvpaintundo+2);  /* plus 2! first element is total */
604         
605         while(size--) {
606                         
607                 if(*rt) {
608                         index= framebuffer_to_index(*rt);
609                         if(index>0 && index<=totvpaintundo)
610                                 indexar[index] = 1;
611                 }
612         
613                 rt++;
614         }
615         
616         for(a=1; a<=totvpaintundo; a++) {
617                 if(indexar[a]) indexar[tot++]= a;
618         }
619         
620         return tot;
621 }
622
623 static unsigned int sample_backbuf(int x, int y)
624 {
625         unsigned int col;
626         
627         if(x>=curarea->winx || y>=curarea->winy) return 0;
628         
629         x+= curarea->winrct.xmin;
630         y+= curarea->winrct.ymin;
631         
632         glReadPixels(x,  y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,  &col);
633         if(G.order==B_ENDIAN) SWITCH_INT(col);
634                 
635         return framebuffer_to_index(col);
636 }
637
638 static int calc_vp_alpha(MVert *mvert, short *mval)
639 {
640         float fac, dx, dy, nor[3];
641         int alpha;
642         short vertco[2];
643         
644         if(Gvp.flag & VP_SOFT) {
645                 project_short_noclip(mvert->co , vertco);
646                 dx= mval[0]-vertco[0];
647                 dy= mval[1]-vertco[1];
648                 
649                 fac= sqrt(dx*dx + dy*dy);
650                 if(fac > Gvp.size) return 0;
651         
652                 alpha= 255.0*Gvp.a*(1.0-fac/Gvp.size);
653         }
654         else {
655                 alpha= 255.0*Gvp.a;
656         }
657         if(Gvp.flag & VP_NORMALS) {
658                 VECCOPY(nor, mvert->no);
659                 
660                 /* transpose ! */
661                 fac= vpimat[2][0]*nor[0]+vpimat[2][1]*nor[1]+vpimat[2][2]*nor[2];
662                 if(fac>0.0) {
663                         dx= vpimat[0][0]*nor[0]+vpimat[0][1]*nor[1]+vpimat[0][2]*nor[2];
664                         dy= vpimat[1][0]*nor[0]+vpimat[1][1]*nor[1]+vpimat[1][2]*nor[2];
665                         
666                         alpha*= fac/sqrt(dx*dx + dy*dy + fac*fac);
667                 }
668                 else return 0;
669         }
670         
671         return alpha;
672
673 }
674
675 int calc_vp_alpha_dl(DispList *disp, MVert *mvert, int vert, short *mval)
676 /* Lets us do soft vertex painting onto a deformed mesh */
677 {
678         float fac, dx, dy, nor[3];
679         int alpha;
680         short vertco[2];
681         
682         /* For safety's sake !*/
683         if (!disp || !disp->verts || !disp->nors)
684                 return calc_vp_alpha (mvert+vert, mval);
685
686 //       make display list 
687         if(Gvp.flag & VP_SOFT) {
688                 project_short_noclip(disp->verts+(vert*3), vertco);
689                 dx= mval[0]-vertco[0];
690                 dy= mval[1]-vertco[1];
691                 
692                 fac= sqrt(dx*dx + dy*dy);
693                 if(fac > Gvp.size) return 0;
694         
695                 alpha= 255.0*Gvp.a*(1.0-fac/Gvp.size);
696         }
697         else {
698                 alpha= 255.0*Gvp.a;
699         }
700
701         if(Gvp.flag & VP_NORMALS) {
702
703                 VECCOPY(nor, disp->nors+(vert*3));
704                 
705 //               transpose ! 
706                 fac= vpimat[2][0]*nor[0]+vpimat[2][1]*nor[1]+vpimat[2][2]*nor[2];
707                 if(fac>0.0) {
708                         dx= vpimat[0][0]*nor[0]+vpimat[0][1]*nor[1]+vpimat[0][2]*nor[2];
709                         dy= vpimat[1][0]*nor[0]+vpimat[1][1]*nor[1]+vpimat[1][2]*nor[2];
710                         
711                         alpha*= fac/sqrt(dx*dx + dy*dy + fac*fac);
712                 }
713                 else return 0;
714         }
715         
716         return alpha;
717
718 }
719
720
721 void wpaint_undo (void){
722         Mesh    *me;
723
724         me = get_mesh(OBACT);
725         if (!me)
726                 return;
727
728         if (!wpaintundobuf)
729                 return;
730
731         if (!me->dvert)
732                 return;
733
734         if (totwpaintundo != me->totvert)
735                 return;
736
737         free_dverts(me->dvert, me->totvert);
738
739         me->dvert= MEM_mallocN(sizeof(MDeformVert)*me->totvert, "deformVert");
740         copy_dverts(me->dvert, wpaintundobuf, totwpaintundo);
741
742         makeDispList(OBACT);
743         scrarea_do_windraw(curarea);
744         
745 };
746
747 void copy_wpaint_undo (MDeformVert *dverts, int dcount){
748         if (wpaintundobuf)
749                 free_dverts(wpaintundobuf, totwpaintundo);
750
751         wpaintundobuf = MEM_mallocN (sizeof(MDeformVert)*dcount, "wpaintundo");
752         totwpaintundo = dcount;
753         copy_dverts (wpaintundobuf, dverts, dcount);
754 };
755
756 void weight_paint(void)
757 {
758         Object *ob; 
759         Mesh *me;
760         MFace *mface;
761         TFace *tface;
762         float mat[4][4], imat[4][4];
763         int index, totindex;
764         short mval[2], mvalo[2], firsttime=1;
765         MDeformWeight   *dw, *uw;
766         extern float editbutvweight;
767         DispList *dl;
768
769
770         if((G.f & G_WEIGHTPAINT)==0) return;
771         if(G.obedit) return;
772         if(G.obpose) return;
773         
774         if(indexar==0) init_vertexpaint();
775         
776         ob= OBACT;
777         me= get_mesh(ob);
778         if (!me->dvert){
779                 return;
780         }
781         if(me==0 || me->totface==0) return;
782         if(ob->lay & G.vd->lay); else error("Active object not in this layer!");
783         
784 //      if(me->tface==NULL && me->mcol==NULL) make_vertexcol();
785
786 //      if(me->tface==NULL && me->mcol==NULL) return;
787         
788         /* imat voor normalen */
789         Mat4MulMat4(mat, ob->obmat, G.vd->viewmat);
790         Mat4Invert(imat, mat);
791         Mat3CpyMat4(vpimat, imat);
792         
793         /* projektiematrix laden */
794         mymultmatrix(ob->obmat);
795         mygetsingmatrix(mat);
796         myloadmatrix(G.vd->viewmat);
797         
798         getmouseco_areawin(mvalo);
799         
800         if(me->tface) tface_to_mcol(me);
801         copy_vpaint_undo( (unsigned int *)me->mcol, me->totface);
802         copy_wpaint_undo(me->dvert, me->totvert);
803         
804         getmouseco_areawin(mval);
805         mvalo[0]= mval[0];
806         mvalo[1]= mval[1];
807         
808         while (get_mbut() & L_MOUSE) {
809                 getmouseco_areawin(mval);
810                 
811                 if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
812                         
813                         if(firsttime) draw_sel_circle(mval, 0, Gvp.size, Gvp.size, 0);
814                         else draw_sel_circle(mval, mvalo, Gvp.size, Gvp.size, 0);
815
816                         firsttime= 0;
817
818                         /* welke vlakken doen mee */
819                         if(Gvp.flag & VP_AREA) {
820                                 totindex= sample_backbuf_area(mval[0], mval[1]);
821                         }
822                         else {
823                                 indexar[0]= sample_backbuf(mval[0], mval[1]);
824                                 if(indexar[0]) totindex= 1;
825                                 else totindex= 0;
826                         }
827                         
828                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
829                         
830                         if(Gvp.flag & VP_COLINDEX) {
831                                 for(index=0; index<totindex; index++) {
832                                         if(indexar[index] && indexar[index]<=me->totface) {
833                                         
834                                                 mface= ((MFace *)me->mface) + (indexar[index]-1);
835                                         
836                                                 if(mface->mat_nr!=ob->actcol-1) {
837                                                         indexar[index]= 0;
838                                                 }
839                                         }                                       
840                                 }
841                         }
842
843                         if((G.f & G_FACESELECT) && me->tface) {
844                                 for(index=0; index<totindex; index++) {
845                                         if(indexar[index] && indexar[index]<=me->totface) {
846                                         
847                                                 tface= ((TFace *)me->tface) + (indexar[index]-1);
848                                         
849                                                 if((tface->flag & TF_SELECT)==0) {
850                                                         indexar[index]= 0;
851                                                 }
852                                         }                                       
853                                 }
854                         }
855                         
856                         dl= find_displist(&ob->disp, DL_VERTS);
857                         for(index=0; index<totindex; index++) {
858                                 
859                                 if(indexar[index] && indexar[index]<=me->totface) {
860                                         mface= ((MFace *)me->mface) + (indexar[index]-1);
861                                         
862
863                                         if (calc_vp_alpha_dl(dl, me->mvert, mface->v1, mval)){
864                                                 dw= verify_defweight(me->dvert+mface->v1, ob->actdef-1);
865                                                 uw= verify_defweight(wpaintundobuf+mface->v1, ob->actdef-1);
866                                                 if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a));
867                                         }
868                                         
869                                         if (calc_vp_alpha_dl(dl, me->mvert, mface->v2, mval)){
870                                                 dw= verify_defweight(me->dvert+mface->v2, ob->actdef-1);
871                                                 uw= verify_defweight(wpaintundobuf+mface->v2, ob->actdef-1);
872                                                 if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a));
873                                         }
874                                         
875                                         if (calc_vp_alpha_dl(dl, me->mvert, mface->v3, mval)){
876                                                 dw= verify_defweight(me->dvert+mface->v3, ob->actdef-1);
877                                                 uw= verify_defweight(wpaintundobuf+mface->v3, ob->actdef-1);
878                                                 if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a));
879                                         }
880                                         
881                                         if(mface->v4) {
882                                         if (calc_vp_alpha_dl(dl, me->mvert, mface->v4, mval)){
883                                                         dw= verify_defweight(me->dvert+mface->v4, ob->actdef-1);
884                                                         uw= verify_defweight(wpaintundobuf+mface->v4, ob->actdef-1);
885                                                         if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a));
886                                                 }
887                                         }
888                                 }
889                         }
890                         
891                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
892                         
893                 }
894                 else BIF_wait_for_statechange();
895                 
896                 if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
897 //                      makeDispList(ob);
898                         scrarea_do_windraw(curarea);
899                         screen_swapbuffers();
900                         backdrawview3d(0);
901                         draw_sel_circle(mval, 0, Gvp.size, Gvp.size, 0);
902         
903                         mvalo[0]= mval[0];
904                         mvalo[1]= mval[1];
905                 }
906         }
907         
908         if(me->tface) {
909                 MEM_freeN(me->mcol);
910                 me->mcol= 0;
911         }
912         
913         /* cirkel wissen */
914         draw_sel_circle(0, mvalo, 0, Gvp.size, 1);
915         
916         makeDispList(ob);
917         
918         allqueue(REDRAWVIEW3D, 0);
919
920 }
921
922 void vertex_paint()
923 {
924         Object *ob;
925         Mesh *me;
926         MFace *mface;
927         TFace *tface;
928         float mat[4][4], imat[4][4];
929         unsigned int paintcol=0, *mcol, fcol1, fcol2;
930         int index, alpha, totindex, total;
931         short mval[2], mvalo[2], firsttime=1;
932         
933         if((G.f & G_VERTEXPAINT)==0) return;
934         if(G.obedit) return;
935         
936         if(indexar==0) init_vertexpaint();
937         
938         ob= OBACT;
939         me= get_mesh(ob);
940         if(me==0 || me->totface==0) return;
941         if(ob->lay & G.vd->lay); else error("Active object not in this layer!");
942         
943         if(me->tface==NULL && me->mcol==NULL) make_vertexcol();
944
945         if(me->tface==NULL && me->mcol==NULL) return;
946         
947         /* imat voor normalen */
948         Mat4MulMat4(mat, ob->obmat, G.vd->viewmat);
949         Mat4Invert(imat, mat);
950         Mat3CpyMat4(vpimat, imat);
951         
952         /* projektiematrix laden */
953         mymultmatrix(ob->obmat);
954         mygetsingmatrix(mat);
955         myloadmatrix(G.vd->viewmat);
956         
957         paintcol= vpaint_get_current_col();
958         
959         getmouseco_areawin(mvalo);
960         
961         if(me->tface) tface_to_mcol(me);
962         copy_vpaint_undo( (unsigned int *)me->mcol, me->totface);
963         
964         getmouseco_areawin(mval);
965         mvalo[0]= mval[0];
966         mvalo[1]= mval[1];
967         
968         while (get_mbut() & L_MOUSE) {
969                 getmouseco_areawin(mval);
970                 
971                 if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
972                         
973                         if(firsttime) draw_sel_circle(mval, 0, Gvp.size, Gvp.size, 0);
974                         else draw_sel_circle(mval, mvalo, Gvp.size, Gvp.size, 0);
975
976                         firsttime= 0;
977
978                         /* welke vlakken doen mee */
979                         if(Gvp.flag & VP_AREA) {
980                                 totindex= sample_backbuf_area(mval[0], mval[1]);
981                         }
982                         else {
983                                 indexar[0]= sample_backbuf(mval[0], mval[1]);
984                                 if(indexar[0]) totindex= 1;
985                                 else totindex= 0;
986                         }
987                         
988                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
989                         
990                         if(Gvp.flag & VP_COLINDEX) {
991                                 for(index=0; index<totindex; index++) {
992                                         if(indexar[index] && indexar[index]<=me->totface) {
993                                         
994                                                 mface= ((MFace *)me->mface) + (indexar[index]-1);
995                                         
996                                                 if(mface->mat_nr!=ob->actcol-1) {
997                                                         indexar[index]= 0;
998                                                 }
999                                         }                                       
1000                                 }
1001                         }
1002                         if((G.f & G_FACESELECT) && me->tface) {
1003                                 for(index=0; index<totindex; index++) {
1004                                         if(indexar[index] && indexar[index]<=me->totface) {
1005                                         
1006                                                 tface= ((TFace *)me->tface) + (indexar[index]-1);
1007                                         
1008                                                 if((tface->flag & TF_SELECT)==0) {
1009                                                         indexar[index]= 0;
1010                                                 }
1011                                         }                                       
1012                                 }
1013                         }
1014                         
1015                         for(index=0; index<totindex; index++) {
1016
1017                                 if(indexar[index] && indexar[index]<=me->totface) {
1018                                 
1019                                         mface= ((MFace *)me->mface) + (indexar[index]-1);
1020                                         mcol= ( (unsigned int *)me->mcol) + 4*(indexar[index]-1);
1021
1022                                         if(Gvp.mode==VP_FILT) {
1023                                                 fcol1= mcol_blend( mcol[0], mcol[1], 128);
1024                                                 if(mface->v4) {
1025                                                         fcol2= mcol_blend( mcol[2], mcol[3], 128);
1026                                                         paintcol= mcol_blend( fcol1, fcol2, 128);
1027                                                 }
1028                                                 else {
1029                                                         paintcol= mcol_blend( mcol[2], fcol1, 170);
1030                                                 }
1031                                                 
1032                                         }
1033                                         
1034                                         total= 0;
1035                                         
1036                                         total+= alpha= calc_vp_alpha(me->mvert+mface->v1, mval);
1037                                         if(alpha) vpaint_blend( mcol, paintcol, alpha);
1038                                         
1039                                         total+= alpha= calc_vp_alpha(me->mvert+mface->v2, mval);
1040                                         if(alpha) vpaint_blend( mcol+1, paintcol, alpha);
1041         
1042                                         total+= alpha= calc_vp_alpha(me->mvert+mface->v3, mval);
1043                                         if(alpha) vpaint_blend( mcol+2, paintcol, alpha);
1044
1045                                         if(mface->v4) {
1046                                                 total+= alpha= calc_vp_alpha(me->mvert+mface->v4, mval);
1047                                                 if(alpha) vpaint_blend( mcol+3, paintcol, alpha);
1048                                         }
1049                                         
1050                                         /* if(total==0) { */
1051                                         /*      alpha= 25*Gvp.a; */
1052                                         /*      vpaint_blend( mcol, paintcol, alpha); */
1053                                         /*      vpaint_blend( mcol+1, paintcol, alpha); */
1054                                         /*      vpaint_blend( mcol+2, paintcol, alpha); */
1055                                         /*      if(mface->v4) vpaint_blend( mcol+3, paintcol, alpha); */
1056                                         /* } */
1057                                 }
1058                         }
1059                         
1060                         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1061                         
1062                 }
1063                 else BIF_wait_for_statechange();
1064                 
1065                 if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
1066                         do_shared_vertexcol(me);
1067                         if(me->tface) {
1068                                 mcol_to_tface(me, 0);
1069                         }
1070         
1071                         scrarea_do_windraw(curarea);
1072                         screen_swapbuffers();
1073                         backdrawview3d(0);
1074                         draw_sel_circle(mval, 0, Gvp.size, Gvp.size, 0);
1075         
1076                         mvalo[0]= mval[0];
1077                         mvalo[1]= mval[1];
1078                 }
1079         }
1080         
1081         if(me->tface) {
1082                 MEM_freeN(me->mcol);
1083                 me->mcol= 0;
1084         }
1085         
1086         /* cirkel wissen */
1087         draw_sel_circle(0, mvalo, 0, Gvp.size, 1);
1088         
1089         allqueue(REDRAWVIEW3D, 0);
1090 }
1091
1092 void set_wpaint(void)           /* toggle */
1093 {               
1094         Object *ob;
1095         Mesh *me;
1096         
1097         scrarea_queue_headredraw(curarea);
1098         ob= OBACT;
1099         me= get_mesh(ob);
1100                 
1101         if(me && me->totface>=MAXINDEX) {
1102                 error("Maximum number of faces: %d", MAXINDEX-1);
1103                 G.f &= ~G_WEIGHTPAINT;
1104                 return;
1105         }
1106         
1107 //      if(me && me->tface==NULL && me->mcol==NULL) make_vertexcol();
1108         
1109         if(G.f & G_WEIGHTPAINT) G.f &= ~G_WEIGHTPAINT;
1110         else G.f |= G_WEIGHTPAINT;
1111         
1112         allqueue(REDRAWVIEW3D, 0);
1113         allqueue(REDRAWBUTSEDIT, 0);
1114         allqueue(REDRAWBUTSGAME, 0);
1115         
1116         if(G.f & G_WEIGHTPAINT) {
1117                 setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT);
1118         }
1119         else {
1120                 freefastshade();        /* voor zekerheid */
1121                 if (ob)
1122                         makeDispList(ob);
1123                 if(!(G.f & G_FACESELECT))
1124                         setcursor_space(SPACE_VIEW3D, CURSOR_STD);
1125         }
1126 }
1127
1128
1129 void set_vpaint(void)           /* toggle */
1130 {               
1131         Object *ob;
1132         Mesh *me;
1133         
1134         scrarea_queue_headredraw(curarea);
1135         ob= OBACT;
1136         me= get_mesh(ob);
1137         
1138         if(me && me->totface>=MAXINDEX) {
1139                 error("Maximum number of faces: %d", MAXINDEX-1);
1140                 G.f &= ~G_VERTEXPAINT;
1141                 return;
1142         }
1143         
1144         if(me && me->tface==NULL && me->mcol==NULL) make_vertexcol();
1145         
1146         if(G.f & G_VERTEXPAINT){
1147                 G.f &= ~G_VERTEXPAINT;
1148         }
1149         else {
1150                 G.f |= G_VERTEXPAINT;
1151                 /* Turn off weight painting */
1152                 if (G.f & G_WEIGHTPAINT)
1153                         set_wpaint();
1154         }
1155         
1156         allqueue(REDRAWVIEW3D, 0);
1157         allqueue(REDRAWBUTSEDIT, 0);
1158         allqueue(REDRAWBUTSGAME, 0);
1159         
1160         if(G.f & G_VERTEXPAINT) {
1161                 setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT);
1162         }
1163         else {
1164                 freefastshade();        /* voor zekerheid */
1165                 if (ob) makeDispList(ob);
1166                 if((G.f & G_FACESELECT)==0) setcursor_space(SPACE_VIEW3D, CURSOR_STD);
1167         }
1168 }
1169