uninitialized variable used in mesh_foreachScreenVert__mapFunc
[blender.git] / source / blender / src / drawobject.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL 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.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <string.h>
31 #include <math.h>
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #include "MEM_guardedalloc.h"
38
39 #include "BMF_Api.h"
40
41 #include "IMB_imbuf.h"
42
43
44 #include "MTC_matrixops.h"
45
46 #include "DNA_armature_types.h"
47 #include "DNA_camera_types.h"
48 #include "DNA_curve_types.h"
49 #include "DNA_constraint_types.h" // for drawing constraint
50 #include "DNA_effect_types.h"
51 #include "DNA_ipo_types.h"
52 #include "DNA_lamp_types.h"
53 #include "DNA_lattice_types.h"
54 #include "DNA_material_types.h"
55 #include "DNA_mesh_types.h"
56 #include "DNA_meshdata_types.h"
57 #include "DNA_meta_types.h"
58 #include "DNA_modifier_types.h"
59 #include "DNA_object_types.h"
60 #include "DNA_object_force.h"
61 #include "DNA_particle_types.h"
62 #include "DNA_space_types.h"
63 #include "DNA_scene_types.h"
64 #include "DNA_screen_types.h"
65 #include "DNA_userdef_types.h"
66 #include "DNA_view3d_types.h"
67 #include "DNA_world_types.h"
68 // FSPARTICLE
69 #include "DNA_object_fluidsim.h"
70
71 #include "BLI_blenlib.h"
72 #include "BLI_arithb.h"
73 #include "BLI_editVert.h"
74 #include "BLI_edgehash.h"
75 #include "BLI_rand.h"
76
77 #include "BKE_utildefines.h"
78 #include "BKE_curve.h"
79 #include "BKE_constraint.h" // for the get_constraint_target function
80 #include "BKE_DerivedMesh.h"
81 #include "BKE_displist.h"
82 #include "BKE_effect.h"
83 #include "BKE_font.h"
84 #include "BKE_global.h"
85 #include "BKE_image.h"
86 #include "BKE_ipo.h"
87 #include "BKE_key.h"
88 #include "BKE_lattice.h"
89 #include "BKE_mesh.h"
90 #include "BKE_material.h"
91 #include "BKE_mball.h"
92 #include "BKE_modifier.h"
93 #include "BKE_object.h"
94 #include "BKE_anim.h"                   //for the where_on_path function
95 #include "BKE_particle.h"
96 #include "BKE_property.h"
97 #include "BKE_utildefines.h"
98 #ifdef WITH_VERSE
99 #include "BKE_verse.h"
100 #endif
101
102 #include "BIF_editarmature.h"
103 #include "BIF_editdeform.h"
104 #include "BIF_editmesh.h"
105 #include "BIF_editparticle.h"
106 #include "BIF_glutil.h"
107 #include "BIF_gl.h"
108 #include "BIF_glutil.h"
109 #include "BIF_mywindow.h"
110 #include "BIF_resources.h"
111 #include "BIF_retopo.h"
112 #include "BIF_screen.h"
113 #include "BIF_space.h"
114 #include "BIF_toolbox.h"
115
116 #include "BDR_drawmesh.h"
117 #include "BDR_drawobject.h"
118 #include "BDR_editobject.h"
119 #include "BDR_sculptmode.h"
120 #include "BDR_vpaint.h"
121
122 #include "BSE_drawview.h"
123 #include "BSE_node.h"
124 #include "BSE_trans_types.h"
125 #include "BSE_view.h"
126
127 #include "blendef.h"
128 #include "mydevice.h"
129 #include "nla.h"
130
131 #include "BKE_deform.h"
132
133 #include "GPU_draw.h"
134 #include "GPU_material.h"
135 #include "GPU_extensions.h"
136
137 /* pretty stupid */
138 /*  extern Lattice *editLatt; already in BKE_lattice.h  */
139 /* editcurve.c */
140 extern ListBase editNurb;
141 /* editmball.c */
142 extern ListBase editelems;
143
144 static void draw_bounding_volume(Object *ob);
145
146 static void drawcube_size(float size);
147 static void drawcircle_size(float size);
148 static void draw_empty_sphere(float size);
149 static void draw_empty_cone(float size);
150
151 /* check for glsl drawing */
152
153 int draw_glsl_material(Object *ob, int dt)
154 {
155         if(!GPU_extensions_minimum_support())
156                 return 0;
157         if(G.f & G_PICKSEL)
158                 return 0;
159         if(!CHECK_OB_DRAWTEXTURE(G.vd, dt))
160                 return 0;
161         if(ob==OBACT && (G.f & G_WEIGHTPAINT))
162                 return 0;
163         
164         return ((G.fileflags & G_FILE_GAME_MAT) &&
165            (G.fileflags & G_FILE_GAME_MAT_GLSL) && (dt >= OB_SHADED));
166 }
167
168 static int check_material_alpha(Base *base, Object *ob, int glsl)
169 {
170         if(base->flag & OB_FROMDUPLI)
171                 return 0;
172
173         if(G.f & G_PICKSEL)
174                 return 0;
175                         
176         if(G.obedit && G.obedit->data==ob->data)
177                 return 0;
178         
179         return (glsl || (ob->dtx & OB_DRAWTRANSP));
180 }
181
182         /***/
183 static unsigned int colortab[24]=
184         {0x0,           0xFF88FF, 0xFFBBFF, 
185          0x403000,      0xFFFF88, 0xFFFFBB, 
186          0x104040,      0x66CCCC, 0x77CCCC, 
187          0x104010,      0x55BB55, 0x66FF66, 
188          0xFFFFFF
189 };
190
191
192 static float cube[8][3] = {
193         {-1.0, -1.0, -1.0},
194         {-1.0, -1.0,  1.0},
195         {-1.0,  1.0,  1.0},
196         {-1.0,  1.0, -1.0},
197         { 1.0, -1.0, -1.0},
198         { 1.0, -1.0,  1.0},
199         { 1.0,  1.0,  1.0},
200         { 1.0,  1.0, -1.0},
201 };
202
203 /* ----------------- OpenGL Circle Drawing - Tables for Optimised Drawing Speed ------------------ */
204 /* 32 values of sin function (still same result!) */
205 static float sinval[32] = {
206         0.00000000,
207         0.20129852,
208         0.39435585,
209         0.57126821,
210         0.72479278,
211         0.84864425,
212         0.93775213,
213         0.98846832,
214         0.99871650,
215         0.96807711,
216         0.89780453,
217         0.79077573,
218         0.65137248,
219         0.48530196,
220         0.29936312,
221         0.10116832,
222         -0.10116832,
223         -0.29936312,
224         -0.48530196,
225         -0.65137248,
226         -0.79077573,
227         -0.89780453,
228         -0.96807711,
229         -0.99871650,
230         -0.98846832,
231         -0.93775213,
232         -0.84864425,
233         -0.72479278,
234         -0.57126821,
235         -0.39435585,
236         -0.20129852,
237         0.00000000
238 };
239
240 /* 32 values of cos function (still same result!) */
241 static float cosval[32] ={
242         1.00000000,
243         0.97952994,
244         0.91895781,
245         0.82076344,
246         0.68896691,
247         0.52896401,
248         0.34730525,
249         0.15142777,
250         -0.05064916,
251         -0.25065253,
252         -0.44039415,
253         -0.61210598,
254         -0.75875812,
255         -0.87434661,
256         -0.95413925,
257         -0.99486932,
258         -0.99486932,
259         -0.95413925,
260         -0.87434661,
261         -0.75875812,
262         -0.61210598,
263         -0.44039415,
264         -0.25065253,
265         -0.05064916,
266         0.15142777,
267         0.34730525,
268         0.52896401,
269         0.68896691,
270         0.82076344,
271         0.91895781,
272         0.97952994,
273         1.00000000
274 };
275
276 /* flag is same as for draw_object */
277 void drawaxes(float size, int flag, char drawtype)
278 {
279         int axis;
280         float v1[3]= {0.0, 0.0, 0.0};
281         float v2[3]= {0.0, 0.0, 0.0};
282         float v3[3]= {0.0, 0.0, 0.0};
283
284         if(G.f & G_RENDER_SHADOW)
285                 return;
286         
287         switch(drawtype) {
288         
289         case OB_PLAINAXES:
290                 for (axis=0; axis<3; axis++) {
291                         float v1[3]= {0.0, 0.0, 0.0};
292                         float v2[3]= {0.0, 0.0, 0.0};
293                         
294                         glBegin(GL_LINES);
295
296                         v1[axis]= size;
297                         v2[axis]= -size;
298                         glVertex3fv(v1);
299                         glVertex3fv(v2);
300                         
301                         glEnd();
302                 }
303                 break;
304         case OB_SINGLE_ARROW:
305         
306                 glBegin(GL_LINES);
307                 /* in positive z direction only */
308                 v1[2]= size;
309                 glVertex3fv(v1);
310                 glVertex3fv(v2);
311                 glEnd();
312                 
313                 /* square pyramid */
314                 glBegin(GL_TRIANGLES);
315                 
316                 v2[0]= size*0.035; v2[1] = size*0.035;
317                 v3[0]= size*-0.035; v3[1] = size*0.035;
318                 v2[2]= v3[2]= size*0.75;
319                 
320                 for (axis=0; axis<4; axis++) {
321                         if (axis % 2 == 1) {
322                                 v2[0] *= -1;
323                                 v3[1] *= -1;
324                         } else {
325                                 v2[1] *= -1;
326                                 v3[0] *= -1;
327                         }
328                         
329                         glVertex3fv(v1);
330                         glVertex3fv(v2);
331                         glVertex3fv(v3);
332                         
333                 }
334                 glEnd();
335                 
336                 break;
337         case OB_CUBE:
338                 drawcube_size(size);
339                 break;
340                 
341         case OB_CIRCLE:
342                 drawcircle_size(size);
343                 break;
344         
345         case OB_EMPTY_SPHERE:
346                  draw_empty_sphere(size);
347              break;
348
349         case OB_EMPTY_CONE:
350                  draw_empty_cone(size);
351              break;
352
353         case OB_ARROWS:
354         default:
355                 for (axis=0; axis<3; axis++) {
356                         float v1[3]= {0.0, 0.0, 0.0};
357                         float v2[3]= {0.0, 0.0, 0.0};
358                         int arrow_axis= (axis==0)?1:0;
359                         
360                         glBegin(GL_LINES);
361
362                         v2[axis]= size;
363                         glVertex3fv(v1);
364                         glVertex3fv(v2);
365                                 
366                         v1[axis]= size*0.8;
367                         v1[arrow_axis]= -size*0.125;
368                         glVertex3fv(v1);
369                         glVertex3fv(v2);
370                                 
371                         v1[arrow_axis]= size*0.125;
372                         glVertex3fv(v1);
373                         glVertex3fv(v2);
374
375                         glEnd();
376                                 
377                         v2[axis]+= size*0.125;
378                         glRasterPos3fv(v2);
379                         
380                         // patch for 3d cards crashing on glSelect for text drawing (IBM)
381                         if((flag & DRAW_PICKING) == 0) {
382                                 if (axis==0)
383                                         BMF_DrawString(G.font, "x");
384                                 else if (axis==1)
385                                         BMF_DrawString(G.font, "y");
386                                 else
387                                         BMF_DrawString(G.font, "z");
388                         }
389                 }
390                 break;
391         }
392 }
393
394 /* circle for object centers, special_color is for library or ob users */
395 static void drawcentercircle(float *vec, int selstate, int special_color)
396 {
397         View3D *v3d= G.vd;
398         float size;
399         
400         size= v3d->persmat[0][3]*vec[0]+ v3d->persmat[1][3]*vec[1]+ v3d->persmat[2][3]*vec[2]+ v3d->persmat[3][3];
401         size*= v3d->pixsize*((float)U.obcenter_dia*0.5f);
402
403         /* using gldepthfunc guarantees that it does write z values, but not checks for it, so centers remain visible independt order of drawing */
404         if(v3d->zbuf)  glDepthFunc(GL_ALWAYS);
405         glEnable(GL_BLEND);
406         
407         if(special_color) {
408 #ifdef WITH_VERSE
409                 if (selstate==VERSE) glColor4ub(0x00, 0xFF, 0x00, 155);
410                 else if (selstate==ACTIVE || selstate==SELECT) glColor4ub(0x88, 0xFF, 0xFF, 155);
411 #else
412                 if (selstate==ACTIVE || selstate==SELECT) glColor4ub(0x88, 0xFF, 0xFF, 155);
413 #endif
414
415                 else glColor4ub(0x55, 0xCC, 0xCC, 155);
416         }
417         else {
418                 if (selstate == ACTIVE) BIF_ThemeColorShadeAlpha(TH_ACTIVE, 0, -80);
419                 else if (selstate == SELECT) BIF_ThemeColorShadeAlpha(TH_SELECT, 0, -80);
420                 else if (selstate == DESELECT) BIF_ThemeColorShadeAlpha(TH_TRANSFORM, 0, -80);
421         }
422         drawcircball(GL_POLYGON, vec, size, v3d->viewinv);
423         
424         BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -30);
425         drawcircball(GL_LINE_LOOP, vec, size, v3d->viewinv);
426         
427         glDisable(GL_BLEND);
428         if(v3d->zbuf)  glDepthFunc(GL_LEQUAL);
429 }
430
431
432 void drawsolidcube(float size)
433 {
434         float n[3];
435
436         glPushMatrix();
437         glScalef(size, size, size);
438         
439         n[0]=0; n[1]=0; n[2]=0;
440         glBegin(GL_QUADS);
441                 n[0]= -1.0;
442                 glNormal3fv(n); 
443                 glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
444                 n[0]=0;
445         glEnd();
446
447         glBegin(GL_QUADS);
448                 n[1]= -1.0;
449                 glNormal3fv(n); 
450                 glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]);
451                 n[1]=0;
452         glEnd();
453
454         glBegin(GL_QUADS);
455                 n[0]= 1.0;
456                 glNormal3fv(n); 
457                 glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]);
458                 n[0]=0;
459         glEnd();
460
461         glBegin(GL_QUADS);
462                 n[1]= 1.0;
463                 glNormal3fv(n); 
464                 glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]);
465                 n[1]=0;
466         glEnd();
467
468         glBegin(GL_QUADS);
469                 n[2]= 1.0;
470                 glNormal3fv(n); 
471                 glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]);
472                 n[2]=0;
473         glEnd();
474
475         glBegin(GL_QUADS);
476                 n[2]= -1.0;
477                 glNormal3fv(n); 
478                 glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
479         glEnd();
480         
481         glPopMatrix();
482 }
483
484 static void drawcube(void)
485 {
486
487         glBegin(GL_LINE_STRIP);
488                 glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]);
489                 glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]);
490                 glVertex3fv(cube[7]); glVertex3fv(cube[4]);
491         glEnd();
492
493         glBegin(GL_LINE_STRIP);
494                 glVertex3fv(cube[1]); glVertex3fv(cube[5]);
495         glEnd();
496
497         glBegin(GL_LINE_STRIP);
498                 glVertex3fv(cube[2]); glVertex3fv(cube[6]);
499         glEnd();
500
501         glBegin(GL_LINE_STRIP);
502                 glVertex3fv(cube[3]); glVertex3fv(cube[7]);
503         glEnd();
504 }
505
506 /* draws a cube on given the scaling of the cube, assuming that 
507  * all required matrices have been set (used for drawing empties)
508  */
509 static void drawcube_size(float size)
510 {
511         glBegin(GL_LINE_STRIP);
512                 glVertex3f(-size,-size,-size); glVertex3f(-size,-size,size);glVertex3f(-size,size,size); glVertex3f(-size,size,-size);
513                 glVertex3f(-size,-size,-size); glVertex3f(size,-size,-size);glVertex3f(size,-size,size); glVertex3f(size,size,size);
514                 glVertex3f(size,size,-size); glVertex3f(size,-size,-size);
515         glEnd();
516
517         glBegin(GL_LINE_STRIP);
518                 glVertex3f(-size,-size,size); glVertex3f(size,-size,size);
519         glEnd();
520
521         glBegin(GL_LINE_STRIP);
522                 glVertex3f(-size,size,size); glVertex3f(size,size,size);
523         glEnd();
524
525         glBegin(GL_LINE_STRIP);
526                 glVertex3f(-size,size,-size); glVertex3f(size,size,-size);
527         glEnd();
528 }
529
530 /* this is an unused (old) cube-drawing function based on a given size */
531 #if 0
532 static void drawcube_size(float *size)
533 {
534
535         glPushMatrix();
536         glScalef(size[0],  size[1],  size[2]);
537         
538
539         glBegin(GL_LINE_STRIP);
540                 glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]);
541                 glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]);
542                 glVertex3fv(cube[7]); glVertex3fv(cube[4]);
543         glEnd();
544
545         glBegin(GL_LINE_STRIP);
546                 glVertex3fv(cube[1]); glVertex3fv(cube[5]);
547         glEnd();
548
549         glBegin(GL_LINE_STRIP);
550                 glVertex3fv(cube[2]); glVertex3fv(cube[6]);
551         glEnd();
552
553         glBegin(GL_LINE_STRIP);
554                 glVertex3fv(cube[3]); glVertex3fv(cube[7]);
555         glEnd();
556         
557         glPopMatrix();
558 }
559 #endif
560
561 static void drawshadbuflimits(Lamp *la, float mat[][4])
562 {
563         float sta[3], end[3], lavec[3];
564
565         lavec[0]= -mat[2][0];
566         lavec[1]= -mat[2][1];
567         lavec[2]= -mat[2][2];
568         Normalize(lavec);
569
570         sta[0]= mat[3][0]+ la->clipsta*lavec[0];
571         sta[1]= mat[3][1]+ la->clipsta*lavec[1];
572         sta[2]= mat[3][2]+ la->clipsta*lavec[2];
573
574         end[0]= mat[3][0]+ la->clipend*lavec[0];
575         end[1]= mat[3][1]+ la->clipend*lavec[1];
576         end[2]= mat[3][2]+ la->clipend*lavec[2];
577
578
579         glBegin(GL_LINE_STRIP);
580                 glVertex3fv(sta);
581                 glVertex3fv(end);
582         glEnd();
583
584         glPointSize(3.0);
585         bglBegin(GL_POINTS);
586         bglVertex3fv(sta);
587         bglVertex3fv(end);
588         bglEnd();
589         glPointSize(1.0);
590 }
591
592
593
594 static void spotvolume(float *lvec, float *vvec, float inp)
595 {
596         /* camera is at 0,0,0 */
597         float temp[3],plane[3],mat1[3][3],mat2[3][3],mat3[3][3],mat4[3][3],q[4],co,si,angle;
598
599         Normalize(lvec);
600         Normalize(vvec);                                /* is this the correct vector ? */
601
602         Crossf(temp,vvec,lvec);         /* equation for a plane through vvec en lvec */
603         Crossf(plane,lvec,temp);                /* a plane perpendicular to this, parrallel with lvec */
604
605         Normalize(plane);
606
607         /* now we've got two equations: one of a cone and one of a plane, but we have
608         three unknowns. We remove one unkown by rotating the plane to z=0 (the plane normal) */
609
610         /* rotate around cross product vector of (0,0,1) and plane normal, dot product degrees */
611         /* according definition, we derive cross product is (plane[1],-plane[0],0), en cos = plane[2]);*/
612
613         /* translating this comment to english didnt really help me understanding the math! :-) (ton) */
614         
615         q[1] = plane[1] ; 
616         q[2] = -plane[0] ; 
617         q[3] = 0 ;
618         Normalize(&q[1]);
619
620         angle = saacos(plane[2])/2.0;
621         co = cos(angle);
622         si = sqrt(1-co*co);
623
624         q[0] =  co;
625         q[1] *= si;
626         q[2] *= si;
627         q[3] =  0;
628
629         QuatToMat3(q,mat1);
630
631         /* rotate lamp vector now over acos(inp) degrees */
632
633         vvec[0] = lvec[0] ; 
634         vvec[1] = lvec[1] ; 
635         vvec[2] = lvec[2] ;
636
637         Mat3One(mat2);
638         co = inp;
639         si = sqrt(1-inp*inp);
640
641         mat2[0][0] =  co;
642         mat2[1][0] = -si;
643         mat2[0][1] =  si;
644         mat2[1][1] =  co;
645         Mat3MulMat3(mat3,mat2,mat1);
646
647         mat2[1][0] =  si;
648         mat2[0][1] = -si;
649         Mat3MulMat3(mat4,mat2,mat1);
650         Mat3Transp(mat1);
651
652         Mat3MulMat3(mat2,mat1,mat3);
653         Mat3MulVecfl(mat2,lvec);
654         Mat3MulMat3(mat2,mat1,mat4);
655         Mat3MulVecfl(mat2,vvec);
656
657         return;
658 }
659
660 static void drawlamp(Object *ob)
661 {
662         Lamp *la;
663         View3D *v3d= G.vd;
664         float vec[3], lvec[3], vvec[3], circrad, x,y,z;
665         float pixsize, lampsize;
666         float imat[4][4], curcol[4];
667         char col[4];
668
669         if(G.f & G_RENDER_SHADOW)
670                 return;
671         
672         la= ob->data;
673         
674         /* we first draw only the screen aligned & fixed scale stuff */
675         glPushMatrix();
676         myloadmatrix(G.vd->viewmat);
677
678         /* lets calculate the scale: */
679         pixsize= v3d->persmat[0][3]*ob->obmat[3][0]+ v3d->persmat[1][3]*ob->obmat[3][1]+ v3d->persmat[2][3]*ob->obmat[3][2]+ v3d->persmat[3][3];
680         pixsize*= v3d->pixsize;
681         lampsize= pixsize*((float)U.obcenter_dia*0.5f);
682
683         /* and view aligned matrix: */
684         Mat4CpyMat4(imat, G.vd->viewinv);
685         Normalize(imat[0]);
686         Normalize(imat[1]);
687         
688         /* for AA effects */
689         glGetFloatv(GL_CURRENT_COLOR, curcol);
690         curcol[3]= 0.6;
691         glColor4fv(curcol);
692         
693         if(ob->id.us>1) {
694                 if (ob==OBACT || (ob->flag & SELECT)) glColor4ub(0x88, 0xFF, 0xFF, 155);
695                 else glColor4ub(0x77, 0xCC, 0xCC, 155);
696         }
697         
698         /* Inner Circle */
699         VECCOPY(vec, ob->obmat[3]);
700         glEnable(GL_BLEND);
701         drawcircball(GL_LINE_LOOP, vec, lampsize, imat);
702         glDisable(GL_BLEND);
703         drawcircball(GL_POLYGON, vec, lampsize, imat);
704         
705         /* restore */
706         if(ob->id.us>1)
707                 glColor4fv(curcol);
708                 
709         /* Outer circle */
710         circrad = 3.0f*lampsize;
711         drawcircball(GL_LINE_LOOP, vec, circrad, imat);
712         
713         setlinestyle(3);
714
715         /* draw dashed outer circle if shadow is on. remember some lamps can't have certain shadows! */
716         if (la->type!=LA_HEMI) {
717                 if ((la->mode & LA_SHAD_RAY) ||
718                         ((la->mode & LA_SHAD_BUF) && (la->type==LA_SPOT)) )
719                 {
720                         drawcircball(GL_LINE_LOOP, vec, circrad + 3.0f*pixsize, imat);
721                 }
722         }
723         
724         /* draw the pretty sun rays */
725         if(la->type==LA_SUN) {
726                 float v1[3], v2[3], mat[3][3];
727                 short axis;
728                 
729                 /* setup a 45 degree rotation matrix */
730                 VecRotToMat3(imat[2], M_PI/4.0f, mat);
731                 
732                 /* vectors */
733                 VECCOPY(v1, imat[0]);
734                 VecMulf(v1, circrad*1.2f);
735                 VECCOPY(v2, imat[0]);
736                 VecMulf(v2, circrad*2.5f);
737                 
738                 /* center */
739                 glTranslatef(vec[0], vec[1], vec[2]);
740                 
741                 setlinestyle(3);
742                 
743                 glBegin(GL_LINES);
744                 for (axis=0; axis<8; axis++) {
745                         glVertex3fv(v1);
746                         glVertex3fv(v2);
747                         Mat3MulVecfl(mat, v1);
748                         Mat3MulVecfl(mat, v2);
749                 }
750                 glEnd();
751                 
752                 glTranslatef(-vec[0], -vec[1], -vec[2]);
753
754         }               
755         
756         if (la->type==LA_LOCAL) {
757                 if(la->mode & LA_SPHERE) {
758                         drawcircball(GL_LINE_LOOP, vec, la->dist, imat);
759                 }
760                 /* yafray: for photonlight also draw lightcone as for spot */
761         }
762         
763         glPopMatrix();  /* back in object space */
764         vec[0]= vec[1]= vec[2]= 0.0f;
765         
766         if ((la->type==LA_SPOT) || (la->type==LA_YF_PHOTON)) {  
767                 lvec[0]=lvec[1]= 0.0; 
768                 lvec[2] = 1.0;
769                 x = G.vd->persmat[0][2];
770                 y = G.vd->persmat[1][2];
771                 z = G.vd->persmat[2][2];
772                 vvec[0]= x*ob->obmat[0][0] + y*ob->obmat[0][1] + z*ob->obmat[0][2];
773                 vvec[1]= x*ob->obmat[1][0] + y*ob->obmat[1][1] + z*ob->obmat[1][2];
774                 vvec[2]= x*ob->obmat[2][0] + y*ob->obmat[2][1] + z*ob->obmat[2][2];
775
776                 y = cos( M_PI*la->spotsize/360.0 );
777                 spotvolume(lvec, vvec, y);
778                 x = -la->dist;
779                 lvec[0] *=  x ; 
780                 lvec[1] *=  x ; 
781                 lvec[2] *=  x;
782                 vvec[0] *= x ; 
783                 vvec[1] *= x ; 
784                 vvec[2] *= x;
785
786                 /* draw the angled sides of the cone */
787                 glBegin(GL_LINE_STRIP);
788                         glVertex3fv(vvec);
789                         glVertex3fv(vec);
790                         glVertex3fv(lvec);
791                 glEnd();
792                 
793                 z = x*sqrt(1.0 - y*y);
794                 x *= y;
795
796                 /* draw the circle/square at the end of the cone */
797                 glTranslatef(0.0, 0.0 ,  x);
798                 if(la->mode & LA_SQUARE) {
799                         vvec[0]= fabs(z);
800                         vvec[1]= fabs(z);
801                         vvec[2]= 0.0;
802                         glBegin(GL_LINE_LOOP);
803                                 glVertex3fv(vvec);
804                                 vvec[1]= -fabs(z);
805                                 glVertex3fv(vvec);
806                                 vvec[0]= -fabs(z);
807                                 glVertex3fv(vvec);
808                                 vvec[1]= fabs(z);
809                                 glVertex3fv(vvec);
810                         glEnd();
811                 }
812                 else circ(0.0, 0.0, fabs(z));
813                 
814                 /* draw the circle/square representing spotbl */
815                 if(la->type==LA_SPOT) {
816                         float spotblcirc = fabs(z)*(1 - pow(la->spotblend, 2));
817                         /* make sure the line is always visible - prevent it from reaching the outer border (or 0) 
818                          * values are kinda arbitrary - just what seemed to work well */
819                         if (spotblcirc == 0) spotblcirc = 0.15;
820                         else if (spotblcirc == fabs(z)) spotblcirc = fabs(z) - 0.07;
821                         circ(0.0, 0.0, spotblcirc);
822                 }
823                 
824         }
825         else if ELEM(la->type, LA_HEMI, LA_SUN) {
826                 
827                 /* draw the line from the circle along the dist */
828                 glBegin(GL_LINE_STRIP);
829                         vec[2] = -circrad;
830                         glVertex3fv(vec); 
831                         vec[2]= -la->dist; 
832                         glVertex3fv(vec);
833                 glEnd();
834                 
835                 if(la->type==LA_HEMI) {
836                         /* draw the hemisphere curves */
837                         short axis, steps, dir;
838                         float outdist, zdist, mul;
839                         vec[0]=vec[1]=vec[2]= 0.0;
840                         outdist = 0.14; mul = 1.4; dir = 1;
841                         
842                         setlinestyle(4);
843                         /* loop over the 4 compass points, and draw each arc as a LINE_STRIP */
844                         for (axis=0; axis<4; axis++) {
845                                 float v[3]= {0.0, 0.0, 0.0};
846                                 zdist = 0.02;
847                                 
848                                 glBegin(GL_LINE_STRIP);
849                                 
850                                 for (steps=0; steps<6; steps++) {
851                                         if (axis == 0 || axis == 1) {           /* x axis up, x axis down */    
852                                                 /* make the arcs start at the edge of the energy circle */
853                                                 if (steps == 0) v[0] = dir*circrad;
854                                                 else v[0] = v[0] + dir*(steps*outdist);
855                                         } else if (axis == 2 || axis == 3) {            /* y axis up, y axis down */
856                                                 /* make the arcs start at the edge of the energy circle */
857                                                 if (steps == 0) v[1] = dir*circrad;
858                                                 else v[1] = v[1] + dir*(steps*outdist); 
859                                         }
860                 
861                                         v[2] = v[2] - steps*zdist;
862                                         
863                                         glVertex3fv(v);
864                                         
865                                         zdist = zdist * mul;
866                                 }
867                                 
868                                 glEnd();
869                                 /* flip the direction */
870                                 dir = -dir;
871                         }
872                 }
873         } else if(la->type==LA_AREA) {
874                 setlinestyle(3);
875                 if(la->area_shape==LA_AREA_SQUARE) 
876                         fdrawbox(-la->area_size*0.5, -la->area_size*0.5, la->area_size*0.5, la->area_size*0.5);
877                 else if(la->area_shape==LA_AREA_RECT) 
878                         fdrawbox(-la->area_size*0.5, -la->area_sizey*0.5, la->area_size*0.5, la->area_sizey*0.5);
879
880                 glBegin(GL_LINE_STRIP); 
881                 glVertex3f(0.0,0.0,-circrad);
882                 glVertex3f(0.0,0.0,-la->dist);
883                 glEnd();
884         }
885         
886         /* and back to viewspace */
887         myloadmatrix(G.vd->viewmat);
888         VECCOPY(vec, ob->obmat[3]);
889
890         setlinestyle(0);
891         
892         if(la->type==LA_SPOT && (la->mode & LA_SHAD_BUF) ) {
893                 drawshadbuflimits(la, ob->obmat);
894         }
895         
896         BIF_GetThemeColor4ubv(TH_LAMP, col);
897         glColor4ub(col[0], col[1], col[2], col[3]);
898          
899         glEnable(GL_BLEND);
900         
901         if (vec[2]>0) vec[2] -= circrad;
902         else vec[2] += circrad;
903         
904         glBegin(GL_LINE_STRIP);
905                 glVertex3fv(vec); 
906                 vec[2]= 0; 
907                 glVertex3fv(vec);
908         glEnd();
909         
910         glPointSize(2.0);
911         glBegin(GL_POINTS);
912                 glVertex3fv(vec);
913         glEnd();
914         glPointSize(1.0);
915         
916         glDisable(GL_BLEND);
917         
918         /* restore for drawing extra stuff */
919         glColor3fv(curcol);
920
921 }
922
923 static void draw_limit_line(float sta, float end, unsigned int col)
924 {
925         glBegin(GL_LINES);
926         glVertex3f(0.0, 0.0, -sta);
927         glVertex3f(0.0, 0.0, -end);
928         glEnd();
929
930         glPointSize(3.0);
931         glBegin(GL_POINTS);
932         cpack(col);
933         glVertex3f(0.0, 0.0, -sta);
934         glVertex3f(0.0, 0.0, -end);
935         glEnd();
936         glPointSize(1.0);
937 }               
938
939
940 /* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */
941 /* qdn: now also enabled for Blender to set focus point for defocus composit node */
942 static void draw_focus_cross(float dist, float size)
943 {
944         glBegin(GL_LINES);
945         glVertex3f(-size, 0.f, -dist);
946         glVertex3f(size, 0.f, -dist);
947         glVertex3f(0.f, -size, -dist);
948         glVertex3f(0.f, size, -dist);
949         glEnd();
950 }
951
952 /* flag similar to draw_object() */
953 static void drawcamera(Object *ob, int flag)
954 {
955         /* a standing up pyramid with (0,0,0) as top */
956         Camera *cam;
957         World *wrld;
958         float vec[8][4], tmat[4][4], fac, facx, facy, depth;
959         int i;
960
961         if(G.f & G_RENDER_SHADOW)
962                 return;
963
964         cam= ob->data;
965         
966         glDisable(GL_LIGHTING);
967         glDisable(GL_CULL_FACE);
968         
969         if(G.vd->persp>=2 && cam->type==CAM_ORTHO && ob==G.vd->camera) {
970                 facx= 0.5*cam->ortho_scale*1.28;
971                 facy= 0.5*cam->ortho_scale*1.024;
972                 depth= -cam->clipsta-0.1;
973         }
974         else {
975                 fac= cam->drawsize;
976                 if(G.vd->persp>=2 && ob==G.vd->camera) fac= cam->clipsta+0.1; /* that way it's always visible */
977                 
978                 depth= - fac*cam->lens/16.0;
979                 facx= fac*1.28;
980                 facy= fac*1.024;
981         }
982         
983         vec[0][0]= 0.0; vec[0][1]= 0.0; vec[0][2]= 0.001;       /* GLBUG: for picking at iris Entry (well thats old!) */
984         vec[1][0]= facx; vec[1][1]= facy; vec[1][2]= depth;
985         vec[2][0]= facx; vec[2][1]= -facy; vec[2][2]= depth;
986         vec[3][0]= -facx; vec[3][1]= -facy; vec[3][2]= depth;
987         vec[4][0]= -facx; vec[4][1]= facy; vec[4][2]= depth;
988
989         glBegin(GL_LINE_LOOP);
990                 glVertex3fv(vec[1]); 
991                 glVertex3fv(vec[2]); 
992                 glVertex3fv(vec[3]); 
993                 glVertex3fv(vec[4]);
994         glEnd();
995         
996
997         if(G.vd->persp>=2 && ob==G.vd->camera) return;
998         
999         glBegin(GL_LINE_STRIP);
1000                 glVertex3fv(vec[2]); 
1001                 glVertex3fv(vec[0]);
1002                 glVertex3fv(vec[1]);
1003                 glVertex3fv(vec[4]);
1004                 glVertex3fv(vec[0]);
1005                 glVertex3fv(vec[3]); 
1006         glEnd();
1007
1008
1009         /* arrow on top */
1010         vec[0][2]= depth;
1011
1012         
1013         /* draw an outline arrow for inactive cameras and filled
1014          * for active cameras. We actually draw both outline+filled
1015          * for active cameras so the wire can be seen side-on */        
1016         for (i=0;i<2;i++) {
1017                 if (i==0) glBegin(GL_LINE_LOOP);
1018                 else if (i==1 && (ob == G.vd->camera)) glBegin(GL_TRIANGLES);
1019                 else break;
1020                 
1021                 vec[0][0]= -0.7*cam->drawsize;
1022                 vec[0][1]= 1.1*cam->drawsize;
1023                 glVertex3fv(vec[0]);
1024                 
1025                 vec[0][0]= 0.0; 
1026                 vec[0][1]= 1.8*cam->drawsize;
1027                 glVertex3fv(vec[0]);
1028                 
1029                 vec[0][0]= 0.7*cam->drawsize; 
1030                 vec[0][1]= 1.1*cam->drawsize;
1031                 glVertex3fv(vec[0]);
1032         
1033                 glEnd();
1034         }
1035
1036         if(flag==0) {
1037                 if(cam->flag & (CAM_SHOWLIMITS+CAM_SHOWMIST)) {
1038                         myloadmatrix(G.vd->viewmat);
1039                         Mat4CpyMat4(vec, ob->obmat);
1040                         Mat4Ortho(vec);
1041                         mymultmatrix(vec);
1042
1043                         MTC_Mat4SwapMat4(G.vd->persmat, tmat);
1044                         mygetsingmatrix(G.vd->persmat);
1045
1046                         if(cam->flag & CAM_SHOWLIMITS) {
1047                                 draw_limit_line(cam->clipsta, cam->clipend, 0x77FFFF);
1048                                 /* qdn: was yafray only, now also enabled for Blender to be used with defocus composit node */
1049                                 draw_focus_cross(dof_camera(ob), cam->drawsize);
1050                         }
1051
1052                         wrld= G.scene->world;
1053                         if(cam->flag & CAM_SHOWMIST) 
1054                                 if(wrld) draw_limit_line(wrld->miststa, wrld->miststa+wrld->mistdist, 0xFFFFFF);
1055                                 
1056                         MTC_Mat4SwapMat4(G.vd->persmat, tmat);
1057                 }
1058         }
1059 }
1060
1061 static void lattice_draw_verts(Lattice *lt, DispList *dl, short sel)
1062 {
1063         BPoint *bp = lt->def;
1064         float *co = dl?dl->verts:NULL;
1065         int u, v, w;
1066
1067         BIF_ThemeColor(sel?TH_VERTEX_SELECT:TH_VERTEX);
1068         glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
1069         bglBegin(GL_POINTS);
1070
1071         for(w=0; w<lt->pntsw; w++) {
1072                 int wxt = (w==0 || w==lt->pntsw-1);
1073                 for(v=0; v<lt->pntsv; v++) {
1074                         int vxt = (v==0 || v==lt->pntsv-1);
1075                         for(u=0; u<lt->pntsu; u++, bp++, co+=3) {
1076                                 int uxt = (u==0 || u==lt->pntsu-1);
1077                                 if(!(lt->flag & LT_OUTSIDE) || uxt || vxt || wxt) {
1078                                         if(bp->hide==0) {
1079                                                 if((bp->f1 & SELECT)==sel) {
1080                                                         bglVertex3fv(dl?co:bp->vec);
1081                                                 }
1082                                         }
1083                                 }
1084                         }
1085                 }
1086         }
1087         
1088         glPointSize(1.0);
1089         bglEnd();       
1090 }
1091
1092 void lattice_foreachScreenVert(void (*func)(void *userData, BPoint *bp, int x, int y), void *userData)
1093 {
1094         int i, N = editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
1095         DispList *dl = find_displist(&G.obedit->disp, DL_VERTS);
1096         float *co = dl?dl->verts:NULL;
1097         BPoint *bp = editLatt->def;
1098         float pmat[4][4], vmat[4][4];
1099         short s[2];
1100
1101         view3d_get_object_project_mat(curarea, G.obedit, pmat, vmat);
1102
1103         for (i=0; i<N; i++, bp++, co+=3) {
1104                 if (bp->hide==0) {
1105                         view3d_project_short_clip(curarea, dl?co:bp->vec, s, pmat, vmat);
1106                         func(userData, bp, s[0], s[1]);
1107                 }
1108         }
1109 }
1110
1111 static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int use_wcol)
1112 {
1113         int index = ((w*lt->pntsv + v)*lt->pntsu) + u;
1114
1115         if(use_wcol) {
1116                 float col[3];
1117                 MDeformWeight *mdw= get_defweight (lt->dvert+index, use_wcol-1);
1118                 
1119                 weight_to_rgb(mdw?mdw->weight:0.0f, col, col+1, col+2);
1120                 glColor3fv(col);
1121         }
1122         
1123         if (dl) {
1124                 glVertex3fv(&dl->verts[index*3]);
1125         } else {
1126                 glVertex3fv(lt->def[index].vec);
1127         }
1128 }
1129
1130 /* lattice color is hardcoded, now also shows weightgroup values in edit mode */
1131 static void drawlattice(Object *ob)
1132 {
1133         Lattice *lt;
1134         DispList *dl;
1135         int u, v, w;
1136         int use_wcol= 0;
1137
1138         lt= (ob==G.obedit)?editLatt:ob->data;
1139         
1140         /* now we default make displist, this will modifiers work for non animated case */
1141         if(ob->disp.first==NULL)
1142                 lattice_calc_modifiers(ob);
1143         dl= find_displist(&ob->disp, DL_VERTS);
1144         
1145         if(ob==G.obedit) {
1146                 cpack(0x004000);
1147                 
1148                 if(ob->defbase.first && lt->dvert) {
1149                         use_wcol= ob->actdef;
1150                         glShadeModel(GL_SMOOTH);
1151                 }
1152         }
1153         
1154         glBegin(GL_LINES);
1155         for(w=0; w<lt->pntsw; w++) {
1156                 int wxt = (w==0 || w==lt->pntsw-1);
1157                 for(v=0; v<lt->pntsv; v++) {
1158                         int vxt = (v==0 || v==lt->pntsv-1);
1159                         for(u=0; u<lt->pntsu; u++) {
1160                                 int uxt = (u==0 || u==lt->pntsu-1);
1161
1162                                 if(w && ((uxt || vxt) || !(lt->flag & LT_OUTSIDE))) {
1163                                         drawlattice__point(lt, dl, u, v, w-1, use_wcol);
1164                                         drawlattice__point(lt, dl, u, v, w, use_wcol);
1165                                 }
1166                                 if(v && ((uxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
1167                                         drawlattice__point(lt, dl, u, v-1, w, use_wcol);
1168                                         drawlattice__point(lt, dl, u, v, w, use_wcol);
1169                                 }
1170                                 if(u && ((vxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
1171                                         drawlattice__point(lt, dl, u-1, v, w, use_wcol);
1172                                         drawlattice__point(lt, dl, u, v, w, use_wcol);
1173                                 }
1174                         }
1175                 }
1176         }               
1177         glEnd();
1178         
1179         /* restoration for weight colors */
1180         if(use_wcol)
1181                 glShadeModel(GL_FLAT);
1182
1183         if(ob==G.obedit) {
1184                 if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
1185                 
1186                 lattice_draw_verts(lt, dl, 0);
1187                 lattice_draw_verts(lt, dl, 1);
1188                 
1189                 if(G.vd->zbuf) glEnable(GL_DEPTH_TEST); 
1190         }
1191 }
1192
1193 /* ***************** ******************** */
1194
1195 static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
1196 {
1197         struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
1198         EditVert *eve = EM_get_vert_for_index(index);
1199
1200         if (eve->h==0) {
1201                 short s[2]= {IS_CLIPPED, 0};
1202                 if (data->clipVerts) {
1203                         view3d_project_short_clip(curarea, co, s, data->pmat, data->vmat);
1204                 } else {
1205                         view3d_project_short_noclip(curarea, co, s, data->pmat);
1206                 }
1207                 
1208                 if (s[0]==IS_CLIPPED)
1209                         return;
1210                 
1211                 data->func(data->userData, eve, s[0], s[1], index);
1212         }
1213 }
1214 void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, int clipVerts)
1215 {
1216         struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
1217         DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
1218
1219         data.func = func;
1220         data.userData = userData;
1221         data.clipVerts = clipVerts;
1222
1223         view3d_get_object_project_mat(curarea, G.obedit, data.pmat, data.vmat);
1224
1225         EM_init_index_arrays(1, 0, 0);
1226         dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);
1227         EM_free_index_arrays();
1228
1229         dm->release(dm);
1230 }
1231
1232 static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co)
1233 {
1234         struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
1235         EditEdge *eed = EM_get_edge_for_index(index);
1236         short s[2][2];
1237
1238         if (eed->h==0) {
1239                 if (data->clipVerts==1) {
1240                         view3d_project_short_clip(curarea, v0co, s[0], data->pmat, data->vmat);
1241                         view3d_project_short_clip(curarea, v1co, s[1], data->pmat, data->vmat);
1242                 } else {
1243                         view3d_project_short_noclip(curarea, v0co, s[0], data->pmat);
1244                         view3d_project_short_noclip(curarea, v1co, s[1], data->pmat);
1245
1246                         if (data->clipVerts==2) {
1247                 if (!(s[0][0]>=0 && s[0][1]>= 0 && s[0][0]<curarea->winx && s[0][1]<curarea->winy)) 
1248                                         if (!(s[1][0]>=0 && s[1][1]>= 0 && s[1][0]<curarea->winx && s[1][1]<curarea->winy)) 
1249                                                 return;
1250                         }
1251                 }
1252
1253                 data->func(data->userData, eed, s[0][0], s[0][1], s[1][0], s[1][1], index);
1254         }
1255 }
1256 void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts)
1257 {
1258         struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
1259         DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
1260
1261         data.func = func;
1262         data.userData = userData;
1263         data.clipVerts = clipVerts;
1264
1265         view3d_get_object_project_mat(curarea, G.obedit, data.pmat, data.vmat);
1266
1267         EM_init_index_arrays(0, 1, 0);
1268         dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);
1269         EM_free_index_arrays();
1270
1271         dm->release(dm);
1272 }
1273
1274 static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *no)
1275 {
1276         struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float pmat[4][4], vmat[4][4]; } *data = userData;
1277         EditFace *efa = EM_get_face_for_index(index);
1278         short s[2];
1279
1280         if (efa && efa->h==0 && efa->fgonf!=EM_FGON) {
1281                 view3d_project_short_clip(curarea, cent, s, data->pmat, data->vmat);
1282
1283                 data->func(data->userData, efa, s[0], s[1], index);
1284         }
1285 }
1286 void mesh_foreachScreenFace(void (*func)(void *userData, EditFace *efa, int x, int y, int index), void *userData)
1287 {
1288         struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float pmat[4][4], vmat[4][4]; } data;
1289         DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
1290
1291         data.func = func;
1292         data.userData = userData;
1293
1294         view3d_get_object_project_mat(curarea, G.obedit, data.pmat, data.vmat);
1295
1296         EM_init_index_arrays(0, 0, 1);
1297         dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
1298         EM_free_index_arrays();
1299
1300         dm->release(dm);
1301 }
1302
1303 void nurbs_foreachScreenVert(void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y), void *userData)
1304 {
1305         float pmat[4][4], vmat[4][4];
1306         short s[2];
1307         Nurb *nu;
1308         int i;
1309
1310         view3d_get_object_project_mat(curarea, G.obedit, pmat, vmat);
1311
1312         for (nu= editNurb.first; nu; nu=nu->next) {
1313                 if((nu->type & 7)==CU_BEZIER) {
1314                         for (i=0; i<nu->pntsu; i++) {
1315                                 BezTriple *bezt = &nu->bezt[i];
1316
1317                                 if(bezt->hide==0) {
1318                                         if (G.f & G_HIDDENHANDLES) {
1319                                                 view3d_project_short_clip(curarea, bezt->vec[1], s, pmat, vmat);
1320                                                 if (s[0] != IS_CLIPPED)
1321                                                         func(userData, nu, NULL, bezt, 1, s[0], s[1]);
1322                                         } else {
1323                                                 view3d_project_short_clip(curarea, bezt->vec[0], s, pmat, vmat);
1324                                                 if (s[0] != IS_CLIPPED)
1325                                                         func(userData, nu, NULL, bezt, 0, s[0], s[1]);
1326                                                 view3d_project_short_clip(curarea, bezt->vec[1], s, pmat, vmat);
1327                                                 if (s[0] != IS_CLIPPED)
1328                                                         func(userData, nu, NULL, bezt, 1, s[0], s[1]);
1329                                                 view3d_project_short_clip(curarea, bezt->vec[2], s, pmat, vmat);
1330                                                 if (s[0] != IS_CLIPPED)
1331                                                         func(userData, nu, NULL, bezt, 2, s[0], s[1]);
1332                                         }
1333                                 }
1334                         }
1335                 }
1336                 else {
1337                         for (i=0; i<nu->pntsu*nu->pntsv; i++) {
1338                                 BPoint *bp = &nu->bp[i];
1339
1340                                 if(bp->hide==0) {
1341                                         view3d_project_short_clip(curarea, bp->vec, s, pmat, vmat);
1342                                         func(userData, nu, bp, NULL, -1, s[0], s[1]);
1343                                 }
1344                         }
1345                 }
1346         }
1347 }
1348
1349 /* ************** DRAW MESH ****************** */
1350
1351 /* First section is all the "simple" draw routines, 
1352  * ones that just pass some sort of primitive to GL,
1353  * with perhaps various options to control lighting,
1354  * color, etc.
1355  *
1356  * These routines should not have user interface related
1357  * logic!!!
1358  */
1359
1360 static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent, float *no)
1361 {
1362         EditFace *efa = EM_get_face_for_index(index);
1363
1364         if (efa->h==0 && efa->fgonf!=EM_FGON) {
1365                 glVertex3fv(cent);
1366                 glVertex3f(     cent[0] + no[0]*G.scene->editbutsize,
1367                                         cent[1] + no[1]*G.scene->editbutsize,
1368                                         cent[2] + no[2]*G.scene->editbutsize);
1369         }
1370 }
1371 static void draw_dm_face_normals(DerivedMesh *dm) {
1372         glBegin(GL_LINES);
1373         dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, 0);
1374         glEnd();
1375 }
1376
1377 static void draw_dm_face_centers__mapFunc(void *userData, int index, float *cent, float *no)
1378 {
1379         EditFace *efa = EM_get_face_for_index(index);
1380         int sel = *((int*) userData);
1381
1382         if (efa->h==0 && efa->fgonf!=EM_FGON && (efa->f&SELECT)==sel) {
1383                 bglVertex3fv(cent);
1384         }
1385 }
1386 static void draw_dm_face_centers(DerivedMesh *dm, int sel)
1387 {
1388         bglBegin(GL_POINTS);
1389         dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, &sel);
1390         bglEnd();
1391 }
1392
1393 static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
1394 {
1395         EditVert *eve = EM_get_vert_for_index(index);
1396
1397         if (eve->h==0) {
1398                 glVertex3fv(co);
1399
1400                 if (no_f) {
1401                         glVertex3f(     co[0] + no_f[0]*G.scene->editbutsize,
1402                                                 co[1] + no_f[1]*G.scene->editbutsize,
1403                                                 co[2] + no_f[2]*G.scene->editbutsize);
1404                 } else {
1405                         glVertex3f(     co[0] + no_s[0]*G.scene->editbutsize/32767.0f,
1406                                                 co[1] + no_s[1]*G.scene->editbutsize/32767.0f,
1407                                                 co[2] + no_s[2]*G.scene->editbutsize/32767.0f);
1408                 }
1409         }
1410 }
1411 static void draw_dm_vert_normals(DerivedMesh *dm) {
1412         glBegin(GL_LINES);
1413         dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, NULL);
1414         glEnd();
1415 }
1416
1417         /* Draw verts with color set based on selection */
1418 static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
1419 {
1420         struct { int sel; EditVert *eve_act; } * data = userData;
1421         EditVert *eve = EM_get_vert_for_index(index);
1422
1423         if (eve->h==0 && (eve->f&SELECT)==data->sel) {
1424                 /* draw active larger - need to stop/start point drawing for this :/ */
1425                 if (eve==data->eve_act) {
1426                         float size = BIF_GetThemeValuef(TH_VERTEX_SIZE);
1427                         BIF_ThemeColor4(TH_EDITMESH_ACTIVE);
1428                         
1429                         bglEnd();
1430                         
1431                         glPointSize(size);
1432                         bglBegin(GL_POINTS);
1433                         bglVertex3fv(co);
1434                         bglEnd();
1435                         
1436                         BIF_ThemeColor4(data->sel?TH_VERTEX_SELECT:TH_VERTEX);
1437                         glPointSize(size);
1438                         bglBegin(GL_POINTS);
1439                 } else {
1440                         bglVertex3fv(co);
1441                 }
1442         }
1443 }
1444 static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act)
1445 {
1446         struct { int sel; EditVert *eve_act; } data;
1447         data.sel = sel;
1448         data.eve_act = eve_act;
1449         
1450         bglBegin(GL_POINTS);
1451         dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data);
1452         bglEnd();
1453 }
1454
1455         /* Draw edges with color set based on selection */
1456 static int draw_dm_edges_sel__setDrawOptions(void *userData, int index)
1457 {
1458         EditEdge *eed = EM_get_edge_for_index(index);
1459         //unsigned char **cols = userData, *col;
1460         struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } * data = userData;
1461         unsigned char *col;
1462
1463         if (eed->h==0) {
1464                 if (eed==data->eed_act) {
1465                         glColor4ubv(data->actCol);
1466                 } else {
1467                         if (eed->f&SELECT) {
1468                                 col = data->selCol;
1469                         } else {
1470                                 col = data->baseCol;
1471                         }
1472                         /* no alpha, this is used so a transparent color can disable drawing unselected edges in editmode  */
1473                         if (col[3]==0) return 0;
1474                         
1475                         glColor4ubv(col);
1476                 }
1477                 return 1;
1478         } else {
1479                 return 0;
1480         }
1481 }
1482 static void draw_dm_edges_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditEdge *eed_act) 
1483 {
1484         struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } data;
1485         
1486         data.baseCol = baseCol;
1487         data.selCol = selCol;
1488         data.actCol = actCol;
1489         data.eed_act = eed_act;
1490         dm->drawMappedEdges(dm, draw_dm_edges_sel__setDrawOptions, &data);
1491 }
1492
1493         /* Draw edges */
1494 static int draw_dm_edges__setDrawOptions(void *userData, int index)
1495 {
1496         return EM_get_edge_for_index(index)->h==0;
1497 }
1498 static void draw_dm_edges(DerivedMesh *dm) 
1499 {
1500         dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, NULL);
1501 }
1502
1503         /* Draw edges with color interpolated based on selection */
1504 static int draw_dm_edges_sel_interp__setDrawOptions(void *userData, int index)
1505 {
1506         return EM_get_edge_for_index(index)->h==0;
1507 }
1508 static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int index, float t)
1509 {
1510         EditEdge *eed = EM_get_edge_for_index(index);
1511         unsigned char **cols = userData;
1512         unsigned char *col0 = cols[(eed->v1->f&SELECT)?1:0];
1513         unsigned char *col1 = cols[(eed->v2->f&SELECT)?1:0];
1514
1515         glColor4ub(     col0[0] + (col1[0]-col0[0])*t,
1516                                 col0[1] + (col1[1]-col0[1])*t,
1517                                 col0[2] + (col1[2]-col0[2])*t,
1518                                 col0[3] + (col1[3]-col0[3])*t);
1519 }
1520 static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
1521 {
1522         unsigned char *cols[2];
1523         cols[0] = baseCol;
1524         cols[1] = selCol;
1525         dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols);
1526 }
1527
1528         /* Draw only seam edges */
1529 static int draw_dm_edges_seams__setDrawOptions(void *userData, int index)
1530 {
1531         EditEdge *eed = EM_get_edge_for_index(index);
1532
1533         return (eed->h==0 && eed->seam);
1534 }
1535 static void draw_dm_edges_seams(DerivedMesh *dm)
1536 {
1537         dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, NULL);
1538 }
1539
1540         /* Draw only sharp edges */
1541 static int draw_dm_edges_sharp__setDrawOptions(void *userData, int index)
1542 {
1543         EditEdge *eed = EM_get_edge_for_index(index);
1544
1545         return (eed->h==0 && eed->sharp);
1546 }
1547 static void draw_dm_edges_sharp(DerivedMesh *dm)
1548 {
1549         dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, NULL);
1550 }
1551
1552
1553         /* Draw faces with color set based on selection
1554          * return 2 for the active face so it renders with stipple enabled */
1555 static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *drawSmooth_r)
1556 {
1557         struct { unsigned char *cols[3]; EditFace *efa_act; } * data = userData;
1558         EditFace *efa = EM_get_face_for_index(index);
1559         unsigned char *col;
1560         
1561         if (efa->h==0) {
1562                 if (efa == data->efa_act) {
1563                         glColor4ubv(data->cols[2]);
1564                         return 2; /* stipple */
1565                 } else {
1566                         col = data->cols[(efa->f&SELECT)?1:0];
1567                         if (col[3]==0) return 0;
1568                         glColor4ubv(col);
1569                         return 1;
1570                 }
1571         }
1572         return 0;
1573 }
1574
1575 /* also draws the active face */
1576 static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act) 
1577 {
1578         struct { unsigned char *cols[3]; EditFace *efa_act; } data;
1579         data.cols[0] = baseCol;
1580         data.cols[1] = selCol;
1581         data.cols[2] = actCol;
1582         data.efa_act = efa_act;
1583         
1584         dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0);
1585 }
1586
1587 static int draw_dm_creases__setDrawOptions(void *userData, int index)
1588 {
1589         EditEdge *eed = EM_get_edge_for_index(index);
1590
1591         if (eed->h==0 && eed->crease!=0.0) {
1592                 BIF_ThemeColorBlend(TH_WIRE, TH_EDGE_SELECT, eed->crease);
1593                 return 1;
1594         } else {
1595                 return 0;
1596         }
1597 }
1598 static void draw_dm_creases(DerivedMesh *dm)
1599 {
1600         glLineWidth(3.0);
1601         dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, NULL);
1602         glLineWidth(1.0);
1603 }
1604
1605 static int draw_dm_bweights__setDrawOptions(void *userData, int index)
1606 {
1607         EditEdge *eed = EM_get_edge_for_index(index);
1608
1609         if (eed->h==0 && eed->bweight!=0.0) {
1610                 BIF_ThemeColorBlend(TH_WIRE, TH_EDGE_SELECT, eed->bweight);
1611                 return 1;
1612         } else {
1613                 return 0;
1614         }
1615 }
1616 static void draw_dm_bweights__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
1617 {
1618         EditVert *eve = EM_get_vert_for_index(index);
1619
1620         if (eve->h==0 && eve->bweight!=0.0) {
1621                 BIF_ThemeColorBlend(TH_VERTEX, TH_VERTEX_SELECT, eve->bweight);
1622                 bglVertex3fv(co);
1623         }
1624 }
1625 static void draw_dm_bweights(DerivedMesh *dm)
1626 {
1627         if (G.scene->selectmode & SCE_SELECT_VERTEX) {
1628                 glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE) + 2);
1629                 bglBegin(GL_POINTS);
1630                 dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, NULL);
1631                 bglEnd();
1632         }
1633         else {
1634                 glLineWidth(3.0);
1635                 dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, NULL);
1636                 glLineWidth(1.0);
1637         }
1638 }
1639
1640 /* Second section of routines: Combine first sets to form fancy
1641  * drawing routines (for example rendering twice to get overlays).
1642  *
1643  * Also includes routines that are basic drawing but are too
1644  * specialized to be split out (like drawing creases or measurements).
1645  */
1646
1647 /* EditMesh drawing routines*/
1648
1649 static void draw_em_fancy_verts(EditMesh *em, DerivedMesh *cageDM, EditVert *eve_act)
1650 {
1651         int sel;
1652
1653         if(G.vd->zbuf) glDepthMask(0);          // disable write in zbuffer, zbuf select
1654
1655         for (sel=0; sel<2; sel++) {
1656                 char col[4], fcol[4];
1657                 int pass;
1658
1659                 BIF_GetThemeColor3ubv(sel?TH_VERTEX_SELECT:TH_VERTEX, col);
1660                 BIF_GetThemeColor3ubv(sel?TH_FACE_DOT:TH_WIRE, fcol);
1661
1662                 for (pass=0; pass<2; pass++) {
1663                         float size = BIF_GetThemeValuef(TH_VERTEX_SIZE);
1664                         float fsize = BIF_GetThemeValuef(TH_FACEDOT_SIZE);
1665
1666                         if (pass==0) {
1667                                 if(G.vd->zbuf && !(G.vd->flag&V3D_ZBUF_SELECT)) {
1668                                         glDisable(GL_DEPTH_TEST);
1669                                                 
1670                                         glEnable(GL_BLEND);
1671                                 } else {
1672                                         continue;
1673                                 }
1674
1675                                 size = (size>2.1?size/2.0:size);
1676                                 fsize = (fsize>2.1?fsize/2.0:fsize);
1677                                 col[3] = fcol[3] = 100;
1678                         } else {
1679                                 col[3] = fcol[3] = 255;
1680                         }
1681                                 
1682                         if(G.scene->selectmode & SCE_SELECT_VERTEX) {
1683                                 glPointSize(size);
1684                                 glColor4ubv((GLubyte *)col);
1685                                 draw_dm_verts(cageDM, sel, eve_act);
1686                         }
1687                         
1688                         if( CHECK_OB_DRAWFACEDOT(G.scene, G.vd, G.obedit->dt) ) {
1689                                 glPointSize(fsize);
1690                                 glColor4ubv((GLubyte *)fcol);
1691                                 draw_dm_face_centers(cageDM, sel);
1692                         }
1693                         
1694                         if (pass==0) {
1695                                 glDisable(GL_BLEND);
1696                                 glEnable(GL_DEPTH_TEST);
1697                         }
1698                 }
1699         }
1700
1701         if(G.vd->zbuf) glDepthMask(1);
1702         glPointSize(1.0);
1703 }
1704
1705 static void draw_em_fancy_edges(DerivedMesh *cageDM, short sel_only, EditEdge *eed_act)
1706 {
1707         int pass;
1708         unsigned char wireCol[4], selCol[4], actCol[4];
1709
1710         /* since this function does transparant... */
1711         BIF_GetThemeColor4ubv(TH_EDGE_SELECT, (char *)selCol);
1712         BIF_GetThemeColor4ubv(TH_WIRE, (char *)wireCol);
1713         BIF_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, (char *)actCol);
1714         
1715         /* when sel only is used, dont render wire, only selected, this is used for
1716          * textured draw mode when the 'edges' option is disabled */
1717         if (sel_only)
1718                 wireCol[3] = 0;
1719
1720         for (pass=0; pass<2; pass++) {
1721                         /* show wires in transparant when no zbuf clipping for select */
1722                 if (pass==0) {
1723                         if (G.vd->zbuf && (G.vd->flag & V3D_ZBUF_SELECT)==0) {
1724                                 glEnable(GL_BLEND);
1725                                 glDisable(GL_DEPTH_TEST);
1726                                 selCol[3] = 85;
1727                                 if (!sel_only) wireCol[3] = 85;
1728                         } else {
1729                                 continue;
1730                         }
1731                 } else {
1732                         selCol[3] = 255;
1733                         if (!sel_only) wireCol[3] = 255;
1734                 }
1735
1736                 if(G.scene->selectmode == SCE_SELECT_FACE) {
1737                         draw_dm_edges_sel(cageDM, wireCol, selCol, actCol, eed_act);
1738                 }       
1739                 else if( (G.f & G_DRAWEDGES) || (G.scene->selectmode & SCE_SELECT_EDGE) ) {     
1740                         if(cageDM->drawMappedEdgesInterp && (G.scene->selectmode & SCE_SELECT_VERTEX)) {
1741                                 glShadeModel(GL_SMOOTH);
1742                                 draw_dm_edges_sel_interp(cageDM, wireCol, selCol);
1743                                 glShadeModel(GL_FLAT);
1744                         } else {
1745                                 draw_dm_edges_sel(cageDM, wireCol, selCol, actCol, eed_act);
1746                         }
1747                 }
1748                 else {
1749                         if (!sel_only) {
1750                                 glColor4ubv(wireCol);
1751                                 draw_dm_edges(cageDM);
1752                         }
1753                 }
1754
1755                 if (pass==0) {
1756                         glDisable(GL_BLEND);
1757                         glEnable(GL_DEPTH_TEST);
1758                 }
1759         }
1760 }       
1761
1762 #ifdef WITH_VERSE
1763 /*
1764  * draw some debug info about verse mesh (vertex indexes,
1765  * face indexes, status of )
1766  */
1767 static void draw_verse_debug(Object *ob, EditMesh *em)
1768 {
1769         struct EditVert *eve=NULL;
1770         struct EditFace *efa=NULL;
1771         float v1[3], v2[3], v3[3], v4[3], fvec[3], col[3];
1772         char val[32];
1773
1774         if(G.f & G_RENDER_SHADOW)
1775                 return;
1776         
1777         if(G.vd->zbuf && (G.vd->flag & V3D_ZBUF_SELECT)==0)
1778                 glDisable(GL_DEPTH_TEST);
1779
1780         if(G.vd->zbuf) bglPolygonOffset(5.0);
1781
1782         BIF_GetThemeColor3fv(TH_TEXT, col);
1783         /* make color a bit more red */
1784         if(col[0]> 0.5) {col[1]*=0.7; col[2]*= 0.7;}
1785         else col[0]= col[0]*0.7 + 0.3;
1786         glColor3fv(col);
1787
1788         /* draw IDs of verse vertexes */
1789         for(eve = em->verts.first; eve; eve = eve->next) {
1790                 if(eve->vvert) {
1791                         VecLerpf(fvec, ob->loc, eve->co, 1.1);
1792                         glRasterPos3f(fvec[0], fvec[1], fvec[2]);
1793
1794                         sprintf(val, "%d", ((VerseVert*)eve->vvert)->id);
1795                         BMF_DrawString(G.fonts, val);
1796                 }
1797         }
1798
1799         /* draw IDs of verse faces */
1800         for(efa = em->faces.first; efa; efa = efa->next) {
1801                 if(efa->vface) {
1802                         VECCOPY(v1, efa->v1->co);
1803                         VECCOPY(v2, efa->v2->co);
1804                         VECCOPY(v3, efa->v3->co);
1805                         if(efa->v4) {
1806                                 VECCOPY(v4, efa->v4->co);
1807                                 glRasterPos3f(0.25*(v1[0]+v2[0]+v3[0]+v4[0]),
1808                                                 0.25*(v1[1]+v2[1]+v3[1]+v4[1]),
1809                                                 0.25*(v1[2]+v2[2]+v3[2]+v4[2]));
1810                         }
1811                         else {
1812                                 glRasterPos3f((v1[0]+v2[0]+v3[0])/3,
1813                                                 (v1[1]+v2[1]+v3[1])/3,
1814                                                 (v1[2]+v2[2]+v3[2])/3);
1815                         }
1816                         
1817                         sprintf(val, "%d", ((VerseFace*)efa->vface)->id);
1818                         BMF_DrawString(G.fonts, val);
1819                         
1820                 }
1821         }
1822         
1823         if(G.vd->zbuf) {
1824                 glEnable(GL_DEPTH_TEST);
1825                 bglPolygonOffset(0.0);
1826         }
1827 }
1828 #endif
1829
1830 static void draw_em_measure_stats(Object *ob, EditMesh *em)
1831 {
1832         EditEdge *eed;
1833         EditFace *efa;
1834         float v1[3], v2[3], v3[3], v4[3];
1835         float fvec[3];
1836         char val[32]; /* Stores the measurement display text here */
1837         char conv_float[5]; /* Use a float conversion matching the grid size */
1838         float area, col[3]; /* area of the face,  color of the text to draw */
1839         
1840         if(G.f & (G_RENDER_OGL|G_RENDER_SHADOW))
1841                 return;
1842
1843         /* make the precission of the pronted value proportionate to the gridsize */
1844         if ((G.vd->grid) < 0.01)
1845                 strcpy(conv_float, "%.6f");
1846         else if ((G.vd->grid) < 0.1)
1847                 strcpy(conv_float, "%.5f");
1848         else if ((G.vd->grid) < 1.0)
1849                 strcpy(conv_float, "%.4f");
1850         else if ((G.vd->grid) < 10.0)
1851                 strcpy(conv_float, "%.3f");
1852         else
1853                 strcpy(conv_float, "%.2f");
1854         
1855         
1856         if(G.vd->zbuf && (G.vd->flag & V3D_ZBUF_SELECT)==0)
1857                 glDisable(GL_DEPTH_TEST);
1858
1859         if(G.vd->zbuf) bglPolygonOffset(5.0);
1860         
1861         if(G.f & G_DRAW_EDGELEN) {
1862                 BIF_GetThemeColor3fv(TH_TEXT, col);
1863                 /* make color a bit more red */
1864                 if(col[0]> 0.5) {col[1]*=0.7; col[2]*= 0.7;}
1865                 else col[0]= col[0]*0.7 + 0.3;
1866                 glColor3fv(col);
1867                 
1868                 for(eed= em->edges.first; eed; eed= eed->next) {
1869                         /* draw non fgon edges, or selected edges, or edges next to selected verts while draging */
1870                         if((eed->h != EM_FGON) && ((eed->f & SELECT) || (G.moving && ((eed->v1->f & SELECT) || (eed->v2->f & SELECT)) ))) {
1871                                 VECCOPY(v1, eed->v1->co);
1872                                 VECCOPY(v2, eed->v2->co);
1873                                 
1874                                 glRasterPos3f( 0.5*(v1[0]+v2[0]),  0.5*(v1[1]+v2[1]),  0.5*(v1[2]+v2[2]));
1875                                 
1876                                 if(G.vd->flag & V3D_GLOBAL_STATS) {
1877                                         Mat4MulVecfl(ob->obmat, v1);
1878                                         Mat4MulVecfl(ob->obmat, v2);
1879                                 }
1880                                 
1881                                 sprintf(val, conv_float, VecLenf(v1, v2));
1882                                 BMF_DrawString( G.fonts, val);
1883                         }
1884                 }
1885         }
1886
1887         if(G.f & G_DRAW_FACEAREA) {
1888                 extern int faceselectedOR(EditFace *efa, int flag);             // editmesh.h shouldn't be in this file... ok for now?
1889                 
1890                 BIF_GetThemeColor3fv(TH_TEXT, col);
1891                 /* make color a bit more green */
1892                 if(col[1]> 0.5) {col[0]*=0.7; col[2]*= 0.7;}
1893                 else col[1]= col[1]*0.7 + 0.3;
1894                 glColor3fv(col);
1895                 
1896                 for(efa= em->faces.first; efa; efa= efa->next) {
1897                         if((efa->f & SELECT) || (G.moving && faceselectedOR(efa, SELECT)) ) {
1898                                 VECCOPY(v1, efa->v1->co);
1899                                 VECCOPY(v2, efa->v2->co);
1900                                 VECCOPY(v3, efa->v3->co);
1901                                 if (efa->v4) {
1902                                         VECCOPY(v4, efa->v4->co);
1903                                 }
1904                                 if(G.vd->flag & V3D_GLOBAL_STATS) {
1905                                         Mat4MulVecfl(ob->obmat, v1);
1906                                         Mat4MulVecfl(ob->obmat, v2);
1907                                         Mat4MulVecfl(ob->obmat, v3);
1908                                         if (efa->v4) Mat4MulVecfl(ob->obmat, v4);
1909                                 }
1910                                 
1911                                 if (efa->v4)
1912                                         area=  AreaQ3Dfl(v1, v2, v3, v4);
1913                                 else
1914                                         area = AreaT3Dfl(v1, v2, v3);
1915
1916                                 sprintf(val, conv_float, area);
1917                                 glRasterPos3fv(efa->cent);
1918                                 BMF_DrawString( G.fonts, val);
1919                         }
1920                 }
1921         }
1922
1923         if(G.f & G_DRAW_EDGEANG) {
1924                 EditEdge *e1, *e2, *e3, *e4;
1925                 
1926                 BIF_GetThemeColor3fv(TH_TEXT, col);
1927                 /* make color a bit more blue */
1928                 if(col[2]> 0.5) {col[0]*=0.7; col[1]*= 0.7;}
1929                 else col[2]= col[2]*0.7 + 0.3;
1930                 glColor3fv(col);
1931                 
1932                 for(efa= em->faces.first; efa; efa= efa->next) {
1933                         VECCOPY(v1, efa->v1->co);
1934                         VECCOPY(v2, efa->v2->co);
1935                         VECCOPY(v3, efa->v3->co);
1936                         if(efa->v4) {
1937                                 VECCOPY(v4, efa->v4->co); 
1938                         }
1939                         else {
1940                                 VECCOPY(v4, v3);
1941                         }
1942                         if(G.vd->flag & V3D_GLOBAL_STATS) {
1943                                 Mat4MulVecfl(ob->obmat, v1);
1944                                 Mat4MulVecfl(ob->obmat, v2);
1945                                 Mat4MulVecfl(ob->obmat, v3);
1946                                 Mat4MulVecfl(ob->obmat, v4);
1947                         }
1948                         
1949                         e1= efa->e1;
1950                         e2= efa->e2;
1951                         e3= efa->e3;
1952                         if(efa->e4) e4= efa->e4; else e4= e3;
1953                         
1954                         /* Calculate the angles */
1955                                 
1956                         if( (e4->f & e1->f & SELECT) || (G.moving && (efa->v1->f & SELECT)) ) {
1957                                 /* Vec 1 */
1958                                 sprintf(val,"%.3f", VecAngle3(v4, v1, v2));
1959                                 VecLerpf(fvec, efa->cent, efa->v1->co, 0.8);
1960                                 glRasterPos3fv(fvec);
1961                                 BMF_DrawString( G.fonts, val);
1962                         }
1963                         if( (e1->f & e2->f & SELECT) || (G.moving && (efa->v2->f & SELECT)) ) {
1964                                 /* Vec 2 */
1965                                 sprintf(val,"%.3f", VecAngle3(v1, v2, v3));
1966                                 VecLerpf(fvec, efa->cent, efa->v2->co, 0.8);
1967                                 glRasterPos3fv(fvec);
1968                                 BMF_DrawString( G.fonts, val);
1969                         }
1970                         if( (e2->f & e3->f & SELECT) || (G.moving && (efa->v3->f & SELECT)) ) {
1971                                 /* Vec 3 */
1972                                 if(efa->v4) 
1973                                         sprintf(val,"%.3f", VecAngle3(v2, v3, v4));
1974                                 else
1975                                         sprintf(val,"%.3f", VecAngle3(v2, v3, v1));
1976                                 VecLerpf(fvec, efa->cent, efa->v3->co, 0.8);
1977                                 glRasterPos3fv(fvec);
1978                                 BMF_DrawString( G.fonts, val);
1979                         }
1980                                 /* Vec 4 */
1981                         if(efa->v4) {
1982                                 if( (e3->f & e4->f & SELECT) || (G.moving && (efa->v4->f & SELECT)) ) {
1983                                         sprintf(val,"%.3f", VecAngle3(v3, v4, v1));
1984                                         VecLerpf(fvec, efa->cent, efa->v4->co, 0.8);
1985                                         glRasterPos3fv(fvec);
1986                                         BMF_DrawString( G.fonts, val);
1987                                 }
1988                         }
1989                 }
1990         }    
1991         
1992         if(G.vd->zbuf) {
1993                 glEnable(GL_DEPTH_TEST);
1994                 bglPolygonOffset(0.0);
1995         }
1996 }
1997
1998 static int draw_em_fancy__setFaceOpts(void *userData, int index, int *drawSmooth_r)
1999 {
2000         EditFace *efa = EM_get_face_for_index(index);
2001
2002         if (efa->h==0) {
2003                 GPU_enable_material(efa->mat_nr+1, NULL);
2004                 return 1;
2005         }
2006         else
2007                 return 0;
2008 }
2009
2010 static int draw_em_fancy__setGLSLFaceOpts(void *userData, int index)
2011 {
2012         EditFace *efa = EM_get_face_for_index(index);
2013
2014         return (efa->h==0);
2015 }
2016
2017 static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, int dt)
2018 {
2019         Mesh *me = ob->data;
2020         EditFace *efa_act = EM_get_actFace(0); /* annoying but active faces is stored differently */
2021         EditEdge *eed_act = NULL;
2022         EditVert *eve_act = NULL;
2023         
2024         if (G.editMesh->selected.last) {
2025                 EditSelection *ese = G.editMesh->selected.last;
2026                 /* face is handeled above */
2027                 /*if (ese->type == EDITFACE ) {
2028                         efa_act = (EditFace *)ese->data;
2029                 } else */ if ( ese->type == EDITEDGE ) {
2030                         eed_act = (EditEdge *)ese->data;
2031                 } else if ( ese->type == EDITVERT ) {
2032                         eve_act = (EditVert *)ese->data;
2033                 }
2034         }
2035         
2036         EM_init_index_arrays(1, 1, 1);
2037
2038         if(dt>OB_WIRE) {
2039                 if(CHECK_OB_DRAWTEXTURE(G.vd, dt)) {
2040                         if(draw_glsl_material(ob, dt)) {
2041                                 glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
2042
2043                                 finalDM->drawMappedFacesGLSL(finalDM, GPU_enable_material,
2044                                         draw_em_fancy__setGLSLFaceOpts, NULL);
2045                                 GPU_disable_material();
2046
2047                                 glFrontFace(GL_CCW);
2048                         }
2049                         else {
2050                                 draw_mesh_textured(ob, finalDM, 0);
2051                         }
2052                 }
2053                 else {
2054                         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED);
2055
2056                         glEnable(GL_LIGHTING);
2057                         glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
2058
2059                         finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0);
2060
2061                         glFrontFace(GL_CCW);
2062                         glDisable(GL_LIGHTING);
2063                 }
2064                         
2065                 // Setup for drawing wire over, disable zbuffer
2066                 // write to show selected edge wires better
2067                 BIF_ThemeColor(TH_WIRE);
2068
2069                 bglPolygonOffset(1.0);
2070                 glDepthMask(0);
2071         } 
2072         else {
2073                 if (cageDM!=finalDM) {
2074                         BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7);
2075                         finalDM->drawEdges(finalDM, 1);
2076                 }
2077         }
2078         
2079         if((G.f & (G_DRAWFACES)) || FACESEL_PAINT_TEST) {       /* transp faces */
2080                 unsigned char col1[4], col2[4], col3[4];
2081                         
2082                 BIF_GetThemeColor4ubv(TH_FACE, (char *)col1);
2083                 BIF_GetThemeColor4ubv(TH_FACE_SELECT, (char *)col2);
2084                 BIF_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, (char *)col3);
2085                 
2086                 glEnable(GL_BLEND);
2087                 glDepthMask(0);         // disable write in zbuffer, needed for nice transp
2088                 
2089                 /* dont draw unselected faces, only selected, this is MUCH nicer when texturing */
2090                 if CHECK_OB_DRAWTEXTURE(G.vd, dt)
2091                         col1[3] = 0;
2092                 
2093                 draw_dm_faces_sel(cageDM, col1, col2, col3, efa_act);
2094
2095                 glDisable(GL_BLEND);
2096                 glDepthMask(1);         // restore write in zbuffer
2097         } else if (efa_act) {
2098                 /* even if draw faces is off it would be nice to draw the stipple face
2099                  * Make all other faces zero alpha except for the active
2100                  * */
2101                 unsigned char col1[4], col2[4], col3[4];
2102                 col1[3] = col2[3] = 0; /* dont draw */
2103                 BIF_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, (char *)col3);
2104                 
2105                 glEnable(GL_BLEND);
2106                 glDepthMask(0);         // disable write in zbuffer, needed for nice transp
2107                 
2108                 draw_dm_faces_sel(cageDM, col1, col2, col3, efa_act);
2109
2110                 glDisable(GL_BLEND);
2111                 glDepthMask(1);         // restore write in zbuffer
2112                 
2113         }
2114
2115         /* here starts all fancy draw-extra over */
2116         if((G.f & G_DRAWEDGES)==0 && CHECK_OB_DRAWTEXTURE(G.vd, dt)) {
2117                 /* we are drawing textures and 'G_DRAWEDGES' is disabled, dont draw any edges */
2118                 
2119                 /* only draw selected edges otherwise there is no way of telling if a face is selected */
2120                 draw_em_fancy_edges(cageDM, 1, eed_act);
2121                 
2122         } else {
2123                 if(G.f & G_DRAWSEAMS) {
2124                         BIF_ThemeColor(TH_EDGE_SEAM);
2125                         glLineWidth(2);
2126         
2127                         draw_dm_edges_seams(cageDM);
2128         
2129                         glColor3ub(0,0,0);
2130                         glLineWidth(1);
2131                 }
2132                 
2133                 if(G.f & G_DRAWSHARP) {
2134                         BIF_ThemeColor(TH_EDGE_SHARP);
2135                         glLineWidth(2);
2136         
2137                         draw_dm_edges_sharp(cageDM);
2138         
2139                         glColor3ub(0,0,0);
2140                         glLineWidth(1);
2141                 }
2142         
2143                 if(G.f & G_DRAWCREASES) {
2144                         draw_dm_creases(cageDM);
2145                 }
2146                 if(G.f & G_DRAWBWEIGHTS) {
2147                         draw_dm_bweights(cageDM);
2148                 }
2149         
2150                 draw_em_fancy_edges(cageDM, 0, eed_act);
2151         }
2152         if(ob==G.obedit) {
2153                 retopo_matrix_update(G.vd);
2154
2155                 draw_em_fancy_verts(em, cageDM, eve_act);
2156
2157                 if(G.f & G_DRAWNORMALS) {
2158                         BIF_ThemeColor(TH_NORMAL);
2159                         draw_dm_face_normals(cageDM);
2160                 }
2161                 if(G.f & G_DRAW_VNORMALS) {
2162                         BIF_ThemeColor(TH_NORMAL);
2163                         draw_dm_vert_normals(cageDM);
2164                 }
2165
2166                 if(G.f & (G_DRAW_EDGELEN|G_DRAW_FACEAREA|G_DRAW_EDGEANG))
2167                         draw_em_measure_stats(ob, em);
2168 #ifdef WITH_VERSE
2169                 if(em->vnode && (G.f & G_DRAW_VERSE_DEBUG))
2170                         draw_verse_debug(ob, em);
2171 #endif
2172         }
2173
2174         if(dt>OB_WIRE) {
2175                 glDepthMask(1);
2176                 bglPolygonOffset(0.0);
2177                 GPU_disable_material();
2178         }
2179
2180         EM_free_index_arrays();
2181 }
2182
2183 /* Mesh drawing routines */
2184
2185 static void draw_mesh_object_outline(Object *ob, DerivedMesh *dm)
2186 {
2187         
2188         if(G.vd->transp==0) {   // not when we draw the transparent pass
2189                 glLineWidth(2.0);
2190                 glDepthMask(0);
2191                 
2192                 /* if transparent, we cannot draw the edges for solid select... edges have no material info.
2193                    drawFacesSolid() doesn't draw the transparent faces */
2194                 if(ob->dtx & OB_DRAWTRANSP) {
2195                         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
2196                         dm->drawFacesSolid(dm, GPU_enable_material);
2197                         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
2198                         GPU_disable_material();
2199                 }
2200                 else {
2201                         dm->drawEdges(dm, 0);
2202                 }
2203                                         
2204                 glLineWidth(1.0);
2205                 glDepthMask(1);
2206         }
2207 }
2208
2209 static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
2210 {
2211         *drawSmooth_r = 1;
2212         return 1;
2213 }
2214
2215 static void draw_mesh_fancy(Base *base, int dt, int flag)
2216 {
2217         Object *ob= base->object;
2218         Mesh *me = ob->data;
2219         Material *ma= give_current_material(ob, 1);
2220         int hasHaloMat = (ma && (ma->mode&MA_HALO));
2221         int draw_wire = 0;
2222         int totvert, totedge, totface;
2223         DispList *dl;
2224         DerivedMesh *dm= mesh_get_derived_final(ob, get_viewedit_datamask());
2225
2226         if(!dm)
2227                 return;
2228         
2229         if (ob->dtx&OB_DRAWWIRE) {
2230                 draw_wire = 2; /* draw wire after solid using zoffset and depth buffer adjusment */
2231         }
2232         
2233 #ifdef WITH_VERSE
2234         if(me->vnode) {
2235                 struct VNode *vnode = (VNode*)me->vnode;
2236                 struct VLayer *vert_vlayer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
2237                 struct VLayer *face_vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
2238
2239                 if(vert_vlayer) totvert = vert_vlayer->dl.da.count;
2240                 else totvert = 0;
2241                 totedge = 0;    /* total count of edge needn't to be zero, but verse doesn't know edges */
2242                 if(face_vlayer) totface = face_vlayer->dl.da.count;
2243                 else totface = 0;
2244         }
2245         else {
2246                 totvert = dm->getNumVerts(dm);
2247                 totedge = dm->getNumEdges(dm);
2248                 totface = dm->getNumFaces(dm);
2249         }
2250 #else
2251         totvert = dm->getNumVerts(dm);
2252         totedge = dm->getNumEdges(dm);
2253         totface = dm->getNumFaces(dm);
2254 #endif
2255         
2256         /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
2257         if(dt!=OB_SHADED)
2258                 glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
2259
2260                 // Unwanted combination.
2261         if (ob==OBACT && FACESEL_PAINT_TEST) draw_wire = 0;
2262
2263         if(dt==OB_BOUNDBOX) {
2264                 draw_bounding_volume(ob);
2265         }
2266         else if(hasHaloMat || (totface==0 && totedge==0)) {
2267                 glPointSize(1.5);
2268                 dm->drawVerts(dm);
2269                 glPointSize(1.0);
2270         }
2271         else if(dt==OB_WIRE || totface==0) {
2272                 draw_wire = 1; /* draw wire only, no depth buffer stuff  */
2273         }
2274         else if(        (ob==OBACT && (G.f & G_TEXTUREPAINT || FACESEL_PAINT_TEST)) ||
2275                                 CHECK_OB_DRAWTEXTURE(G.vd, dt))
2276         {
2277                 int faceselect= (ob==OBACT && FACESEL_PAINT_TEST);
2278
2279                 if ((G.vd->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !(G.f&G_PICKSEL || FACESEL_PAINT_TEST) && !draw_wire) {
2280                         draw_mesh_object_outline(ob, dm);
2281                 }
2282
2283                 if(draw_glsl_material(ob, dt)) {
2284                         glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
2285
2286                         dm->drawFacesGLSL(dm, GPU_enable_material);
2287                         if(get_ob_property(ob, "Text"))
2288                                 draw_mesh_text(ob, 1);
2289                         GPU_disable_material();
2290
2291                         glFrontFace(GL_CCW);
2292                 }
2293                 else {
2294                         draw_mesh_textured(ob, dm, faceselect);
2295                 }
2296
2297                 if(!faceselect) {
2298                         if(base->flag & SELECT)
2299                                 BIF_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT);
2300                         else
2301                                 BIF_ThemeColor(TH_WIRE);
2302
2303                         dm->drawLooseEdges(dm);
2304                 }
2305         }
2306         else if(dt==OB_SOLID) {
2307                 if((G.vd->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !draw_wire)
2308                         draw_mesh_object_outline(ob, dm);
2309
2310                 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED );
2311
2312                 glEnable(GL_LIGHTING);
2313                 glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
2314
2315                 dm->drawFacesSolid(dm, GPU_enable_material);
2316                 GPU_disable_material();
2317
2318                 glFrontFace(GL_CCW);
2319                 glDisable(GL_LIGHTING);
2320
2321                 if(base->flag & SELECT) {
2322                         BIF_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT);
2323                 } else {
2324                         BIF_ThemeColor(TH_WIRE);
2325                 }
2326                 dm->drawLooseEdges(dm);
2327         }
2328         else if(dt==OB_SHADED) {
2329                 int do_draw= 1; /* to resolve all G.f settings below... */
2330                 
2331                 if(ob==OBACT) {
2332                         do_draw= 0;
2333                         if( (G.f & G_WEIGHTPAINT)) {
2334                                 /* enforce default material settings */
2335                                 GPU_enable_material(0, NULL);
2336                                 
2337                                 /* but set default spec */
2338                                 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
2339                                 glEnable(GL_COLOR_MATERIAL);    /* according manpages needed */
2340                                 glColor3ub(120, 120, 120);
2341                                 glDisable(GL_COLOR_MATERIAL);
2342                                 /* diffuse */
2343                                 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
2344                                 glEnable(GL_LIGHTING);
2345                                 glEnable(GL_COLOR_MATERIAL);
2346
2347                                 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me->mface, 1);
2348                                 glDisable(GL_COLOR_MATERIAL);
2349                                 glDisable(GL_LIGHTING);
2350
2351                                 GPU_disable_material();
2352                         }
2353                         else if((G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) && me->mcol) {
2354                                 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1);
2355                         }
2356                         else if(G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) {
2357                                 glColor3f(1.0f, 1.0f, 1.0f);
2358                                 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 0);
2359                         }
2360                         else do_draw= 1;
2361                 }
2362                 if(do_draw) {
2363                         dl = ob->disp.first;
2364                         if (!dl || !dl->col1) {
2365                                 /* release and reload derivedmesh because it might be freed in
2366                                    shadeDispList due to a different datamask */
2367                                 dm->release(dm);
2368                                 shadeDispList(base);
2369                                 dl = find_displist(&ob->disp, DL_VERTCOL);
2370                                 dm= mesh_get_derived_final(ob, get_viewedit_datamask());
2371                         }
2372
2373                         if ((G.vd->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !draw_wire) {
2374                                 draw_mesh_object_outline(ob, dm);
2375                         }
2376
2377                                 /* False for dupliframe objects */
2378                         if (dl) {
2379                                 unsigned int *obCol1 = dl->col1;
2380                                 unsigned int *obCol2 = dl->col2;
2381
2382                                 dm->drawFacesColored(dm, me->flag&ME_TWOSIDED, (unsigned char*) obCol1, (unsigned char*) obCol2);
2383                         }
2384
2385                         if(base->flag & SELECT) {
2386                                 BIF_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT);
2387                         } else {
2388                                 BIF_ThemeColor(TH_WIRE);
2389                         }
2390                         dm->drawLooseEdges(dm);
2391                 }
2392         }
2393         
2394         /* set default draw color back for wire or for draw-extra later on */
2395         if (dt!=OB_WIRE) {
2396                 if(base->flag & SELECT) {
2397                         if(ob==OBACT && ob->flag & OB_FROMGROUP) 
2398                                 BIF_ThemeColor(TH_GROUP_ACTIVE);
2399                         else if(ob->flag & OB_FROMGROUP) 
2400                                 BIF_ThemeColorShade(TH_GROUP_ACTIVE, -16);
2401                         else if(flag!=DRAW_CONSTCOLOR)
2402                                 BIF_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT);
2403                         else
2404                                 glColor3ub(80,80,80);
2405                 } else {
2406                         if (ob->flag & OB_FROMGROUP) 
2407                                 BIF_ThemeColor(TH_GROUP);
2408                         else {
2409                                 if(ob->dtx & OB_DRAWWIRE && flag==DRAW_CONSTCOLOR)
2410                                         glColor3ub(80,80,80);
2411                                 else
2412                                         BIF_ThemeColor(TH_WIRE);
2413                         }
2414                 }
2415         }
2416         if (draw_wire) {
2417                         /* If drawing wire and drawtype is not OB_WIRE then we are
2418                                 * overlaying the wires.
2419                                 *
2420                                 * UPDATE bug #10290 - With this wire-only objects can draw
2421                                 * behind other objects depending on their order in the scene. 2x if 0's below. undo'ing zr's commit: r4059
2422                                 * 
2423                                 * if draw wire is 1 then just drawing wire, no need for depth buffer stuff,
2424                                 * otherwise this wire is to overlay solid mode faces so do some depth buffer tricks.
2425                                 */
2426                 if (dt!=OB_WIRE && draw_wire==2) {
2427                         bglPolygonOffset(1.0);
2428                         glDepthMask(0); // disable write in zbuffer, selected edge wires show better
2429                 }
2430                 
2431                 dm->drawEdges(dm, (dt==OB_WIRE || totface==0));
2432                 
2433                 if (dt!=OB_WIRE && draw_wire==2) {
2434                         glDepthMask(1);
2435                         bglPolygonOffset(0.0);
2436                 }
2437         }
2438
2439         dm->release(dm);
2440 }
2441
2442 /* returns 1 if nothing was drawn, for detecting to draw an object center */
2443 static int draw_mesh_object(Base *base, int dt, int flag)
2444 {
2445         Object *ob= base->object;
2446         Mesh *me= ob->data;
2447         int do_alpha_pass= 0, drawlinked= 0, retval= 0, glsl, check_alpha;
2448         
2449         if(G.obedit && ob!=G.obedit && ob->data==G.obedit->data) {
2450                 if(ob_get_key(ob));
2451                 else drawlinked= 1;
2452         }
2453         
2454         if(ob==G.obedit || drawlinked) {
2455                 DerivedMesh *finalDM, *cageDM;
2456                 
2457                 if (G.obedit!=ob)
2458                         finalDM = cageDM = editmesh_get_derived_base();
2459                 else
2460                         cageDM = editmesh_get_derived_cage_and_final(&finalDM,
2461                                                         get_viewedit_datamask());
2462
2463                 if(dt>OB_WIRE) {
2464                         // no transp in editmode, the fancy draw over goes bad then
2465                         glsl = draw_glsl_material(ob, dt);
2466                         GPU_set_object_materials(G.scene, ob, glsl, NULL);
2467                 }
2468
2469                 draw_em_fancy(ob, G.editMesh, cageDM, finalDM, dt);
2470
2471                 if (G.obedit!=ob && finalDM)
2472                         finalDM->release(finalDM);
2473         }
2474         else if(!G.obedit && (G.f & G_SCULPTMODE) &&(G.scene->sculptdata.flags & SCULPT_DRAW_FAST) &&
2475                 OBACT==ob && !sculpt_modifiers_active(ob)) {
2476                 sculptmode_draw_mesh(0);
2477         }
2478         else {
2479                 /* don't create boundbox here with mesh_get_bb(), the derived system will make it, puts deformed bb's OK */
2480                 if(me->totface<=4 || boundbox_clip(ob->obmat, (ob->bb)? ob->bb: me->bb)) {
2481                         glsl = draw_glsl_material(ob, dt);
2482                         check_alpha = check_material_alpha(base, ob, glsl);
2483
2484                         if(dt==OB_SOLID || glsl) {
2485                                 GPU_set_object_materials(G.scene, ob, glsl,
2486                                         (check_alpha)? &do_alpha_pass: NULL);
2487                         }
2488
2489                         draw_mesh_fancy(base, dt, flag);
2490                         
2491                         if(me->totvert==0) retval= 1;
2492                 }
2493         }
2494         
2495         /* GPU_set_object_materials checked if this is needed */
2496         if(do_alpha_pass) add_view3d_after(G.vd, base, V3D_TRANSP, flag);
2497         
2498         return retval;
2499 }
2500
2501 /* ************** DRAW DISPLIST ****************** */
2502
2503 static int draw_index_wire= 1;
2504 static int index3_nors_incr= 1;
2505
2506 /* returns 1 when nothing was drawn */
2507 static int drawDispListwire(ListBase *dlbase)
2508 {
2509         DispList *dl;
2510         int parts, nr;
2511         float *data;
2512
2513         if(dlbase==NULL) return 1;
2514         
2515         glDisableClientState(GL_NORMAL_ARRAY);
2516         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
2517
2518         for(dl= dlbase->first; dl; dl= dl->next) {
2519                 if(dl->parts==0 || dl->nr==0)
2520                         continue;
2521                 
2522                 data= dl->verts;
2523         
2524                 switch(dl->type) {
2525                 case DL_SEGM:
2526                         
2527                         glVertexPointer(3, GL_FLOAT, 0, data);
2528                         
2529                         for(parts=0; parts<dl->parts; parts++)
2530                                 glDrawArrays(GL_LINE_STRIP, parts*dl->nr, dl->nr);
2531                                 
2532                         break;
2533                 case DL_POLY:
2534                         
2535                         glVertexPointer(3, GL_FLOAT, 0, data);
2536                         
2537                         for(parts=0; parts<dl->parts; parts++)
2538                                 glDrawArrays(GL_LINE_LOOP, parts*dl->nr, dl->nr);
2539                         
2540                         break;
2541                 case DL_SURF:
2542                         
2543                         glVertexPointer(3, GL_FLOAT, 0, data);
2544                         
2545                         for(parts=0; parts<dl->parts; parts++) {
2546                                 if(dl->flag & DL_CYCL_U) 
2547                                         glDrawArrays(GL_LINE_LOOP, parts*dl->nr, dl->nr);
2548                                 else
2549                                         glDrawArrays(GL_LINE_STRIP, parts*dl->nr, dl->nr);
2550                         }
2551                         
2552                         for(nr=0; nr<dl->nr; nr++) {
2553                                 int ofs= 3*dl->nr;
2554                                 
2555                                 data= (  dl->verts )+3*nr;
2556                                 parts= dl->parts;
2557
2558                                 if(dl->flag & DL_CYCL_V) glBegin(GL_LINE_LOOP);
2559                                 else glBegin(GL_LINE_STRIP);
2560                                 
2561                                 while(parts--) {
2562                                         glVertex3fv(data);
2563                                         data+=ofs;
2564                                 }
2565                                 glEnd();
2566                                 
2567                                 /* (ton) this code crashes for me when resolv is 86 or higher... no clue */
2568 //                              glVertexPointer(3, GL_FLOAT, sizeof(float)*3*dl->nr, data + 3*nr);
2569 //                              if(dl->flag & DL_CYCL_V) 
2570 //                                      glDrawArrays(GL_LINE_LOOP, 0, dl->parts);
2571 //                              else
2572 //                                      glDrawArrays(GL_LINE_STRIP, 0, dl->parts);
2573                         }
2574                         break;
2575                         
2576                 case DL_INDEX3:
2577                         if(draw_index_wire) {
2578                                 glVertexPointer(3, GL_FLOAT, 0, dl->verts);
2579                                 glDrawElements(GL_TRIANGLES, 3*dl->parts, GL_UNSIGNED_INT, dl->index);
2580                         }
2581                         break;
2582                         
2583                 case DL_INDEX4:
2584                         if(draw_index_wire) {
2585                                 glVertexPointer(3, GL_FLOAT, 0, dl->verts);
2586                                 glDrawElements(GL_QUADS, 4*dl->parts, GL_UNSIGNED_INT, dl->index);
2587                         }
2588                         break;
2589                 }
2590         }
2591         
2592         glEnableClientState(GL_NORMAL_ARRAY);
2593         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 
2594         
2595         return 0;
2596 }
2597
2598 static void drawDispListsolid(ListBase *lb, Object *ob, int glsl)
2599 {
2600         DispList *dl;
2601         GPUVertexAttribs gattribs;
2602         float *data, curcol[4];
2603         float *ndata;
2604         
2605         if(lb==NULL) return;
2606         
2607         /* for drawing wire */
2608         glGetFloatv(GL_CURRENT_COLOR, curcol);
2609
2610         glEnable(GL_LIGHTING);
2611         
2612         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
2613         else glFrontFace(GL_CCW);
2614         
2615         if(ob->type==OB_MBALL) {        // mball always smooth shaded
2616                 glShadeModel(GL_SMOOTH);
2617         }
2618         
2619         dl= lb->first;
2620         while(dl) {
2621                 data= dl->verts;
2622                 ndata= dl->nors;
2623
2624                 switch(dl->type) {
2625                 case DL_SEGM:
2626                         if(ob->type==OB_SURF) {
2627                                 int nr;
2628
2629                                 glDisable(GL_LIGHTING);
2630                                 glColor3fv(curcol);
2631                                 
2632                                 // glVertexPointer(3, GL_FLOAT, 0, dl->verts);
2633                                 // glDrawArrays(GL_LINE_STRIP, 0, dl->nr);
2634
2635                                 glBegin(GL_LINE_STRIP);
2636                                 for(nr= dl->nr; nr; nr--, data+=3)
2637                                         glVertex3fv(data);
2638                                 glEnd();
2639
2640                                 glEnable(GL_LIGHTING);
2641                         }
2642                         break;
2643                 case DL_POLY:
2644                         if(ob->type==OB_SURF) {
2645                                 int nr;
2646                                 
2647                                 BIF_ThemeColor(TH_WIRE);
2648                                 glDisable(GL_LIGHTING);
2649                                 
2650                                 /* for some reason glDrawArrays crashes here in half of the platforms (not osx) */
2651                                 //glVertexPointer(3, GL_FLOAT, 0, dl->verts);
2652                                 //glDrawArrays(GL_LINE_LOOP, 0, dl->nr);
2653                                 
2654                                 glBegin(GL_LINE_LOOP);
2655                                 for(nr= dl->nr; nr; nr--, data+=3)
2656                                         glVertex3fv(data);
2657                                 glEnd();
2658                                 
2659                                 glEnable(GL_LIGHTING);
2660                                 break;
2661                         }
2662                 case DL_SURF:
2663                         
2664                         if(dl->index) {
2665                                 GPU_enable_material(dl->col+1, (glsl)? &gattribs: NULL);
2666                                 
2667                                 if(dl->rt & CU_SMOOTH) glShadeModel(GL_SMOOTH);
2668                                 else glShadeModel(GL_FLAT);
2669                                 
2670                                 glVertexPointer(3, GL_FLOAT, 0, dl->verts);
2671                                 glNormalPointer(GL_FLOAT, 0, dl->nors);
2672                                 glDrawElements(GL_QUADS, 4*dl->totindex, GL_UNSIGNED_INT, dl->index);
2673                                 GPU_disable_material();
2674                         }                       
2675                         break;
2676
2677                 case DL_INDEX3:
2678                         GPU_enable_material(dl->col+1, (glsl)? &gattribs: NULL);
2679                         
2680                         glVertexPointer(3, GL_FLOAT, 0, dl->verts);
2681                         
2682                         /* voor polys only one normal needed */
2683                         if(index3_nors_incr==0) {
2684                                 glDisableClientState(GL_NORMAL_ARRAY);
2685                                 glNormal3fv(ndata);
2686                         }
2687                         else
2688                                 glNormalPointer(GL_FLOAT, 0, dl->nors);
2689                         
2690                         glDrawElements(GL_TRIANGLES, 3*dl->parts, GL_UNSIGNED_INT, dl->index);
2691                         GPU_disable_material();
2692                         
2693                         if(index3_nors_incr==0)
2694                                 glEnableClientState(GL_NORMAL_ARRAY);
2695
2696                         break;
2697
2698                 case DL_INDEX4:
2699                         GPU_enable_material(dl->col+1, (glsl)? &gattribs: NULL);
2700                         
2701                         glVertexPointer(3, GL_FLOAT, 0, dl->verts);
2702                         glNormalPointer(GL_FLOAT, 0, dl->nors);
2703                         glDrawElements(GL_QUADS, 4*dl->parts, GL_UNSIGNED_INT, dl->index);
2704
2705                         GPU_disable_material();
2706                         
2707                         break;
2708                 }
2709                 dl= dl->next;
2710         }
2711
2712         glShadeModel(GL_FLAT);
2713         glDisable(GL_LIGHTING);
2714         glFrontFace(GL_CCW);
2715 }
2716
2717 static void drawDispListshaded(ListBase *lb, Object *ob)
2718 {
2719         DispList *dl, *dlob;
2720         unsigned int *cdata;
2721
2722         if(lb==NULL) return;
2723
2724         glShadeModel(GL_SMOOTH);
2725         glDisableClientState(GL_NORMAL_ARRAY);
2726         glEnableClientState(GL_COLOR_ARRAY);
2727         
2728         dl= lb->first;
2729         dlob= ob->disp.first;
2730         while(dl && dlob) {
2731                 
2732                 cdata= dlob->col1;
2733                 if(cdata==NULL) break;
2734                 
2735                 switch(dl->type) {
2736                 case DL_SURF:
2737                         if(dl->index) {
2738                                 glVertexPointer(3, GL_FLOAT, 0, dl->verts);
2739                                 glColorPointer(4, GL_UNSIGNED_BYTE, 0, cdata);
2740                                 glDrawElements(GL_QUADS, 4*dl->totindex, GL_UNSIGNED_INT, dl->index);
2741                         }                       
2742                         break;
2743
2744                 case DL_INDEX3:
2745                         
2746                         glVertexPointer(3, GL_FLOAT, 0, dl->verts);
2747                         glColorPointer(4, GL_UNSIGNED_BYTE, 0, cdata);
2748                         glDrawElements(GL_TRIANGLES, 3*dl->parts, GL_UNSIGNED_INT, dl->index);
2749                         break;
2750
2751                 case DL_INDEX4:
2752                         
2753                         glVertexPointer(3, GL_FLOAT, 0, dl->verts);
2754                         glColorPointer(4, GL_UNSIGNED_BYTE, 0, cdata);
2755                         glDrawElements(GL_QUADS, 4*dl->parts, GL_UNSIGNED_INT, dl->index);
2756                         break;
2757                 }
2758                 
2759                 dl= dl->next;
2760                 dlob= dlob->next;
2761         }
2762         
2763         glShadeModel(GL_FLAT);
2764         glEnableClientState(GL_NORMAL_ARRAY);
2765         glDisableClientState(GL_COLOR_ARRAY);
2766 }
2767
2768 /* returns 1 when nothing was drawn */
2769 static int drawDispList(Base *base, int dt)
2770 {
2771         Object *ob= base->object;
2772         ListBase *lb=0;
2773         DispList *dl;
2774         Curve *cu;
2775         int solid, retval= 0;
2776         
2777         solid= (dt > OB_WIRE);
2778
2779         switch(ob->type) {
2780         case OB_FONT:
2781         case OB_CURVE:
2782                 cu= ob->data;
2783                 
2784                 lb= &cu->disp;
2785                 
2786                 if(solid) {
2787                         dl= lb->first;
2788                         if(dl==NULL) return 1;
2789                         
2790                         if(dl->nors==0) addnormalsDispList(ob, lb);
2791                         index3_nors_incr= 0;
2792                         
2793                         if( displist_has_faces(lb)==0) {
2794                                 draw_index_wire= 0;
2795                                 drawDispListwire(lb);
2796                                 draw_index_wire= 1;
2797                         }
2798                         else {
2799                                 if(draw_glsl_material(ob, dt)) {
2800                                         GPU_set_object_materials(G.scene, ob, 1, NULL);
2801                                         drawDispListsolid(lb, ob, 1);
2802                                 }
2803                                 else if(dt == OB_SHADED) {
2804                                         if(ob->disp.first==0) shadeDispList(base);
2805                                         drawDispListshaded(lb, ob);
2806                                 }
2807                                 else {
2808                                         GPU_set_object_materials(G.scene, ob, 0, NULL);
2809                                         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
2810                                         drawDispListsolid(lb, ob, 0);
2811                                 }
2812                                 if(ob==G.obedit && cu->bevobj==NULL && cu->taperobj==NULL && cu->ext1 == 0.0 && cu->ext2 == 0.0) {
2813                                         cpack(0);
2814                                         draw_index_wire= 0;
2815                                         drawDispListwire(lb);
2816                                         draw_index_wire= 1;
2817                                 }
2818                         }
2819                         index3_nors_incr= 1;
2820                 }
2821                 else {
2822                         draw_index_wire= 0;
2823                         retval= drawDispListwire(lb);
2824                         draw_index_wire= 1;
2825                 }
2826                 break;
2827         case OB_SURF:
2828         
2829                 lb= &((Curve *)ob->data)->disp;
2830                 
2831                 if(solid) {
2832                         dl= lb->first;
2833                         if(dl==NULL) return 1;
2834                         
2835                         if(dl->nors==NULL) addnormalsDispList(ob, lb);
2836                         
2837                         if(draw_glsl_material(ob, dt)) {
2838                                 GPU_set_object_materials(G.scene, ob, 1, NULL);
2839                                 drawDispListsolid(lb, ob, 1);
2840                         }
2841                         else if(dt==OB_SHADED) {
2842                                 if(ob->disp.first==NULL) shadeDispList(base);
2843                                 drawDispListshaded(lb, ob);
2844                         }
2845                         else {
2846                                 GPU_set_object_materials(G.scene, ob, 0, NULL);
2847                                 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
2848                         
2849                                 drawDispListsolid(lb, ob, 0);
2850                         }
2851                 }
2852                 else {
2853                         retval= drawDispListwire(lb);
2854                 }
2855                 break;
2856         case OB_MBALL:
2857                 
2858                 if( is_basis_mball(ob)) {
2859                         lb= &ob->disp;
2860                         if(lb->first==NULL) makeDispListMBall(ob);
2861                         if(lb->first==NULL) return 1;
2862                         
2863                         if(solid) {
2864                                 
2865                                 if(draw_glsl_material(ob, dt)) {
2866                                         GPU_set_object_materials(G.scene, ob, 1, NULL);
2867                                         drawDispListsolid(lb, ob, 1);
2868                                 }
2869                                 else if(dt == OB_SHADED) {
2870                                         dl= lb->first;
2871                                         if(dl && dl->col1==0) shadeDispList(base);
2872                                         drawDispListshaded(lb, ob);
2873                                 }
2874                                 else {
2875                                         GPU_set_object_materials(G.scene, ob, 0, NULL);
2876                                         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
2877                                 
2878                                         drawDispListsolid(lb, ob, 0);
2879                                 }
2880                         }
2881                         else{
2882                                 /* MetaBalls use DL_INDEX4 type of DispList */
2883                                 retval= drawDispListwire(lb);
2884                         }
2885                 }
2886                 break;
2887         }
2888         
2889         return retval;
2890 }
2891
2892 /* unified drawing of all new particle systems draw types except dupli ob & group       */
2893 /* mostly tries to use vertex arrays for speed                                                                          */
2894
2895 /* 1. check that everything is ok & updated */
2896 /* 2. start initialising things                         */
2897 /* 3. initialize according to draw type         */
2898 /* 4. allocate drawing data arrays                      */
2899 /* 5. start filling the arrays                          */
2900 /* 6. draw the arrays                                           */
2901 /* 7. clean up                                                          */
2902 static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
2903 {
2904         View3D *v3d= G.vd;
2905         Object *ob=base->object;
2906         ParticleSystemModifierData *psmd;
2907         ParticleSettings *part;
2908         ParticleData *pars, *pa;
2909         ParticleKey state, *states=0;
2910         ParticleCacheKey *cache=0;
2911         Material *ma;
2912         Object *bb_ob=0;
2913         float vel[3], vec[3], vec2[3], imat[4][4], onevec[3]={0.0f,0.0f,0.0f}, bb_center[3];
2914         float timestep, pixsize=1.0, pa_size, pa_time, r_tilt;
2915         float cfra=bsystem_time(ob,(float)CFRA,0.0);
2916         float *vdata=0, *vedata=0, *cdata=0, *ndata=0, *vd=0, *ved=0, *cd=0, *nd=0, xvec[3], yvec[3], zvec[3];
2917         float ma_r=0.0f, ma_g=0.0f, ma_b=0.0f;
2918         int a, k, k_max=0, totpart, totpoint=0, draw_as, path_nbr=0;
2919         int path_possible=0, keys_possible=0, draw_keys=0, totchild=0;
2920         int select=ob->flag&SELECT, create_cdata=0;
2921         GLint polygonmode[2];
2922         char val[32];
2923
2924 /* 1. */
2925         if(psys==0)
2926                 return;
2927
2928         part=psys->part;
2929         pars=psys->particles;
2930
2931         if(part==0 || !psys_check_enabled(ob, psys))
2932                 return;
2933
2934         if(pars==0) return;
2935
2936         if(!G.obedit && psys_in_edit_mode(psys)
2937                 && psys->flag & PSYS_HAIR_DONE && part->draw_as==PART_DRAW_PATH)
2938                 return;
2939                 
2940         if(part->draw_as==PART_DRAW_NOT) return;
2941
2942 /* 2. */
2943         if(part->phystype==PART_PHYS_KEYED){
2944                 if(psys->flag & PSYS_FIRST_KEYED){
2945                         if(psys->flag&PSYS_KEYED){
2946                                 select=psys_count_keyed_targets(ob,psys);
2947                                 if(psys->totkeyed==0)
2948                                         return;
2949                         }
2950                 }
2951                 else
2952                         return;
2953         }
2954
2955         if(select){
2956                 select=0;
2957                 if(psys_get_current(ob)==psys)
2958                         select=1;
2959         }
2960
2961         psys->flag|=PSYS_DRAWING;
2962
2963         if(part->type==PART_HAIR && !psys->childcache)
2964                 totchild=0;
2965         else
2966                 totchild=psys->totchild*part->disp/100;
2967         
2968         ma= give_current_material(ob,part->omat);
2969
2970         if(ma) {
2971                 ma_r = ma->r;
2972                 ma_g = ma->g;
2973                 ma_b = ma->b;
2974         }
2975
2976         if(G.vd->zbuf) glDepthMask(1);
2977
2978         if(select)
2979                 cpack(0xFFFFFF);
2980         else if((ma) && (part->draw&PART_DRAW_MAT_COL)) {
2981                 glColor3f(ma->r,ma->g,ma->b);
2982                 create_cdata = 1;
2983         }
2984         else
2985                 cpack(0);
2986
2987         psmd= psys_get_modifier(ob,psys);
2988
2989         timestep= psys_get_timestep(part);
2990
2991         myloadmatrix(G.vd->viewmat);
2992
2993         if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) {
2994                 float mat[4][4];
2995                 Mat4MulMat4(mat, psys->imat, ob->obmat);
2996                 mymultmatrix(mat);
2997         }
2998
2999         totpart=psys->totpart;
3000         draw_as=part->draw_as;
3001
3002         if(part->flag&PART_GLOB_TIME)
3003                 cfra=bsystem_time(0,(float)CFRA,0.0);
3004
3005         if(psys->pathcache){
3006                 path_possible=1;
3007                 keys_possible=1;
3008         }
3009         if(draw_as==PART_DRAW_PATH && path_possible==0)
3010                 draw_as=PART_DRAW_DOT;
3011
3012         if(draw_as!=PART_DRAW_PATH && keys_possible && part->draw&PART_DRAW_KEYS){
3013                 path_nbr=part->keys_step;
3014                 draw_keys=1;
3015         }
3016
3017 /* 3. */
3018         switch(draw_as){
3019                 case PART_DRAW_DOT:
3020                         if(part->draw_size)
3021                                 glPointSize(part->draw_size);
3022                         else
3023                                 glPointSize(2.0); /* default dot size */
3024                         break;
3025                 case PART_DRAW_CIRC:
3026                         /* calculate view aligned matrix: */
3027                         Mat4CpyMat4(imat, G.vd->viewinv);
3028                         Normalize(imat[0]);
3029                         Normalize(imat[1]);
3030                         /* no break! */
3031                 case PART_DRAW_CROSS:
3032                 case PART_DRAW_AXIS:
3033                         /* lets calculate the scale: */
3034                         pixsize= v3d->persmat[0][3]*ob->obmat[3][0]+ v3d->persmat[1][3]*ob->obmat[3][1]+ v3d->persmat[2][3]*ob->obmat[3][2]+ v3d->persmat[3][3];
3035                         pixsize*= v3d->pixsize;
3036                         if(part->draw_size==0.0)
3037                                 pixsize*=2.0;
3038                         else
3039                                 pixsize*=part->draw_size;
3040                         break;
3041                 case PART_DRAW_OB:
3042                         if(part->dup_ob==0)
3043                                 draw_as=PART_DRAW_DOT;
3044                         else
3045                                 draw_as=0;
3046                         break;
3047                 case PART_DRAW_GR:
3048                         if(part->dup_group==0)
3049                                 draw_as=PART_DRAW_DOT;
3050                         else
3051                                 draw_as=0;
3052                         break;
3053                 case PART_DRAW_BB:
3054                         if(G.vd->camera==0 && part->bb_ob==0){
3055                                 error("Billboards need an active camera or a target object!");
3056
3057                                 draw_as=part->draw_as=PART_DRAW_DOT;
3058
3059                                 if(part->draw_size)
3060                                         glPointSize(part->draw_size);
3061                                 else
3062                                         glPointSize(2.0); /* default dot size */
3063                         }
3064                         else if(part->bb_ob)
3065                                 bb_ob=part->bb_ob;
3066                         else
3067                                 bb_ob=G.vd->camera;
3068
3069                         if(part->bb_align<PART_BB_VIEW)
3070                                 onevec[part->bb_align]=1.0f;
3071                         break;
3072                 case PART_DRAW_PATH:
3073                         break;
3074         }
3075         if(part->draw & PART_DRAW_SIZE && part->draw_as!=PART_DRAW_CIRC){
3076                 Mat4CpyMat4(imat, G.vd->viewinv);
3077                 Normalize(imat[0]);
3078                 Normalize(imat[1]);
3079         }
3080
3081 /* 4. */
3082         if(draw_as && draw_as!=PART_DRAW_PATH){
3083                 if(draw_as!=PART_DRAW_CIRC){
3084                         switch(draw_as){
3085                                 case PART_DRAW_AXIS:
3086                                 case PART_DRAW_CROSS:
3087                                         if(draw_as!=PART_DRAW_CROSS || create_cdata)
3088                                                 cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_cdata");
3089                                         vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_vdata");
3090                                         break;
3091                                 case PART_DRAW_LINE:
3092                                         if(create_cdata)
3093                                                 cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_cdata");
3094                                         vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_vdata");
3095                                         break;
3096                                 case PART_DRAW_BB:
3097                                         if(create_cdata)
3098                                                 cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_cdata");
3099                                         vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata");
3100                                         ndata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata");
3101                                         break;
3102                                 default:
3103                                         if(create_cdata)
3104                                                 cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_cdata");
3105                                         vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_vdata");
3106                         }
3107                 }
3108
3109                 if(part->draw&PART_DRAW_VEL && draw_as!=PART_DRAW_LINE)
3110                         vedata=MEM_callocN((totpart+totchild)*2*3*(path_nbr+1)*sizeof(float), "particle_vedata");
3111
3112                 vd=vdata;
3113                 ved=vedata;
3114                 cd=cdata;
3115                 nd=ndata;
3116
3117                 psys->lattice=psys_get_lattice(ob,psys);
3118         }
3119
3120         if(draw_as){
3121 /* 5. */
3122                 for(a=0,pa=pars; a<totpart+totchild; a++, pa++){
3123                         if(a<totpart){
3124                                 if(totchild && (part->draw&PART_DRAW_PARENT)==0) continue;
3125                                 if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue;
3126
3127                                 pa_time=(cfra-pa->time)/pa->lifetime;
3128                                 pa_size=pa->size;
3129
3130                                 if((part->flag&PART_ABS_TIME)==0){                              
3131                                         if(ma && ma->ipo){
3132                                                 IpoCurve *icu;
3133
3134                                                 /* correction for lifetime */
3135                                                 calc_ipo(ma->ipo, 100.0f*pa_time);
3136
3137                                                 for(icu = ma->ipo->curve.first; icu; icu=icu->next) {
3138                                                         if(icu->adrcode == MA_COL_R)
3139                                                                 ma_r = icu->curval;
3140                                                         else if(icu->adrcode == MA_COL_G)
3141                                                                 ma_g = icu->curval;
3142                                                         else if(icu->adrcode == MA_COL_B)
3143                                                                 ma_b = icu->curval;
3144                                                 }
3145                                         }
3146                                         if(part->ipo) {
3147                                                 IpoCurve *icu;
3148
3149                                                 /* correction for lifetime */
3150                                                 calc_ipo(part->ipo, 100*pa_time);
3151
3152                                                 for(icu = part->ipo->curve.first; icu; icu=icu->next) {
3153                                                         if(icu->adrcode == PART_SIZE)
3154                                                                 pa_size = icu->curval;
3155                                                 }
3156                                         }
3157                                 }
3158
3159                                 r_tilt=1.0f+pa->r_ave[0];
3160
3161                                 if(path_nbr){
3162                                         cache=psys->pathcache[a];
3163                                         k_max=(int)(cache->steps);
3164                                 }
3165                         }
3166                         else{
3167                                 ChildParticle *cpa= &psys->child[a-totpart];
3168
3169                                 pa_time=psys_get_child_time(psys,cpa,cfra);
3170
3171                                 if((part->flag&PART_ABS_TIME)==0) {
3172                                         if(ma && ma->ipo){
3173                                                 IpoCurve *icu;
3174
3175                                                 /* correction for lifetime */
3176                                                 calc_ipo(ma->ipo, 100.0f*pa_time);
3177
3178                                                 for(icu = ma->ipo->curve.first; icu; icu=icu->next) {
3179                                                         if(icu->adrcode == MA_COL_R)
3180                                                                 ma_r = icu->curval;
3181                                                         else if(icu->adrcode == MA_COL_G)
3182                                                                 ma_g = icu->curval;
3183                                                         else if(icu->adrcode == MA_COL_B)
3184                                                                 ma_b = icu->curval;
3185                                                 }
3186                                         }
3187                                 }
3188
3189                                 pa_size=psys_get_child_size(psys,cpa,cfra,0);
3190
3191                                 r_tilt=2.0f*cpa->rand[2];