Quite a large one this time... but now we have:
[blender.git] / source / blender / src / drawobject.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <string.h>
34 #include <math.h>
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #ifdef _WIN32
41 #include "BLI_winstuff.h"
42 #endif
43 #include "MEM_guardedalloc.h"
44
45 #include "BMF_Api.h"
46
47 #include "IMB_imbuf.h"
48
49
50 #include "MTC_matrixops.h"
51
52 #include "DNA_camera_types.h"
53 #include "DNA_curve_types.h"
54 #include "DNA_constraint_types.h" // for drawing constraint
55 #include "DNA_effect_types.h"
56 #include "DNA_ipo_types.h"
57 #include "DNA_lamp_types.h"
58 #include "DNA_lattice_types.h"
59 #include "DNA_material_types.h"
60 #include "DNA_mesh_types.h"
61 #include "DNA_meshdata_types.h"
62 #include "DNA_meta_types.h"
63 #include "DNA_object_types.h"
64 #include "DNA_space_types.h"
65 #include "DNA_scene_types.h"
66 #include "DNA_screen_types.h"
67 #include "DNA_view3d_types.h"
68 #include "DNA_world_types.h"
69
70 #include "BLI_blenlib.h"
71 #include "BLI_arithb.h"
72 #include "BLI_editVert.h"
73
74 #include "BKE_utildefines.h"
75 #include "BKE_curve.h"
76 #include "BKE_constraint.h" // for the get_constraint_target function
77 #include "BKE_object.h"
78 #include "BKE_global.h"
79 #include "BKE_displist.h"
80 #include "BKE_material.h"
81 #include "BKE_mball.h"
82 #include "BKE_ipo.h"
83 #include "BKE_mesh.h"
84 #include "BKE_effect.h"
85 #include "BKE_lattice.h"
86
87 #include "BIF_gl.h"
88 #include "BIF_mywindow.h"
89 #include "BIF_screen.h"
90 #include "BIF_space.h"
91 #include "BIF_editarmature.h"
92 #include "BIF_editika.h"
93 #include "BIF_editmesh.h"
94 #include "BIF_resources.h"
95
96 #include "BDR_drawmesh.h"
97 #include "BDR_drawobject.h"
98 #include "BDR_editobject.h"
99
100 #include "BSE_view.h"
101 #include "BSE_drawview.h"
102 #include "BSE_trans_types.h"
103
104 #include "blendef.h"
105 #include "mydevice.h"
106 #include "nla.h"
107
108 #include "BKE_deform.h"
109
110 /* pretty stupid */
111 /*  extern Lattice *editLatt; already in BKE_lattice.h  */
112 /* editcurve.c */
113 extern ListBase editNurb;
114 /* editmball.c */
115 extern ListBase editelems;
116
117 /* more or less needed forwards */
118 static void drawmeshwire(Object *ob);
119
120         /***/
121
122 // Materials start counting at # one....
123 #define MAXMATBUF (MAXMAT + 1)
124 static float matbuf[MAXMATBUF][2][4];
125
126 static void init_gl_materials(Object *ob)
127 {
128         extern Material defmaterial;
129         Material *ma;
130         int a;
131         
132         if(ob->totcol==0) {
133                 matbuf[0][0][0]= defmaterial.r;
134                 matbuf[0][0][1]= defmaterial.g;
135                 matbuf[0][0][2]= defmaterial.b;
136                 matbuf[0][0][3]= 1.0;
137
138                 matbuf[0][1][0]= defmaterial.specr;
139                 matbuf[0][1][1]= defmaterial.specg;
140                 matbuf[0][1][2]= defmaterial.specb;
141                 matbuf[0][1][3]= 1.0;
142                 
143                 /* do material 1 too, for displists! */
144                 VECCOPY(matbuf[1][0], matbuf[0][0]);
145                 VECCOPY(matbuf[1][1], matbuf[0][1]);
146         }
147         
148         for(a=1; a<=ob->totcol; a++) {
149                 ma= give_current_material(ob, a);
150                 if(ma==NULL) ma= &defmaterial;
151                 if(a<MAXMATBUF) {
152                         matbuf[a][0][0]= (ma->ref+ma->emit)*ma->r;
153                         matbuf[a][0][1]= (ma->ref+ma->emit)*ma->g;
154                         matbuf[a][0][2]= (ma->ref+ma->emit)*ma->b;
155                         matbuf[a][0][3]= 1.0;
156                         
157                         matbuf[a][1][0]= ma->spec*ma->specr;
158                         matbuf[a][1][1]= ma->spec*ma->specg;
159                         matbuf[a][1][2]= ma->spec*ma->specb;
160                         matbuf[a][1][3]= 1.0;
161                 }
162         }
163 }
164
165 static void set_gl_material(int nr)
166 {
167         if(nr<MAXMATBUF) {
168                 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matbuf[nr][0]);
169                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matbuf[nr][1]);
170         }
171 }
172
173         /***/
174         
175 unsigned int rect_desel[16]= {0x707070,0x0,0x0,0x707070,0x407070,0x70cccc,0x407070,0x0,0xaaffff,0xffffff,0x70cccc,0x0,0x70cccc,0xaaffff,0x407070,0x707070};
176 unsigned int rect_sel[16]= {0x707070,0x0,0x0,0x707070,0x702070,0xcc50cc,0x702070,0x0,0xff80ff,0xffffff,0xcc50cc,0x0,0xcc50cc,0xff80ff,0x702070,0x707070};
177
178 unsigned int rectu_desel[16]= {0xff4e4e4e,0xff5c2309,0xff000000,0xff4e4f4d,0xff000000,0xffff9d72,0xffff601c,0xff000000,0xff5d2409,0xffffffff,0xffff9d72,0xff5b2209,0xff4e4e4e,0xff5c2309,0xff010100,0xff4f4f4f};
179 unsigned int rectu_sel[16]= {0xff4e4e4e,0xff403c00,0xff000000,0xff4e4e4d,0xff000000,0xfffff64c,0xffaaa100,0xff000000,0xff403c00,0xffffffff,0xfffff64c,0xff403c00,0xff4f4f4f,0xff403c00,0xff010100,0xff4e4e4e};
180
181 unsigned int rectl_desel[81]= {0x777777,0x777777,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777,0x777777,0xa9fefe,0xaafefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0xaaffff,0xa9fefe,0x4e4e4e,0x0,0x124040,0x0,0x4e4e4e,0xaafefe,0xaaffff,0xaaffff,0x777777,0x0,0x227777,0x55cccc,0x227777,0x0,0x777777,0xaaffff,0xaaffff,0x777777,0x124040,0x88ffff,0xffffff,0x55cccc,0x124040,0x777777,0xaaffff,0xaaffff,0x777777,0x0,0x55cccc,0x88ffff,0x227777,0x0,0x777777,0xaaffff,0xaafefe,0xaafefe,0x4f4f4f,0x0,0x124040,0x0,0x4e4e4e,0xa9fefe,0xaaffff,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777};
182 unsigned int rectl_sel[81]= {0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x4e4e4e,0x10101,0x402440,0x0,0x4e4e4e,0xffaaff,0xffaaff,0xffaaff,0x777777,0x0,0x774477,0xcc77cc,0x774477,0x0,0x777777,0xffaaff,0xffaaff,0x777777,0x402440,0xffaaff,0xffffff,0xcc77cc,0x412541,0x777777,0xffaaff,0xffaaff,0x777777,0x10101,0xcc77cc,0xffaaff,0x774477,0x0,0x777777,0xffaaff,0xffaaff,0xffaaff,0x4e4e4e,0x10101,0x402440,0x0,0x4e4e4e,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777};
183 unsigned int rectlus_desel[81]= {0x777777,0x777777,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777,0x777777,0xa9fefe,0xaafefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0xaaffff,0xa9fefe,0x4e4e4e,0x0,0x5c2309,0x0,0x4e4f4d,0xaafefe,0xaaffff,0xaaffff,0x777777,0x0,0xff601c,0xff9d72,0xff601c,0x0,0x777777,0xaaffff,0xaaffff,0x777777,0x5d2409,0xffceb8,0xff9d72,0xff9d72,0x5b2209,0x777777,0xaaffff,0xaaffff,0x777777,0x10100,0xffceb8,0xffceb8,0xff601c,0x0,0x777777,0xaaffff,0xaafefe,0xaafefe,0x4e4e4e,0x0,0x5c2309,0x10100,0x4f4f4f,0xa9fefe,0xaaffff,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777};
184 unsigned int rectlus_sel[81]= {0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x4e4e4e,0x10100,0x403c00,0x0,0x4e4e4d,0xffaaff,0xffaaff,0xffaaff,0x777777,0x0,0xaaa100,0xfff64c,0xaaa100,0x0,0x777777,0xffaaff,0xffaaff,0x777777,0x403c00,0xfffde2,0xffffff,0xfff64c,0x403c00,0x777777,0xffaaff,0xffaaff,0x777777,0x10100,0xfff64c,0xfffde2,0xaaa100,0x0,0x777777,0xffaaff,0xffaaff,0xffaaff,0x4f4f4f,0x0,0x403c00,0x10100,0x4e4e4e,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777};
185 unsigned int rectllib_desel[81]= {0xff777777,0xff777777,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xff777777,0xb9b237,0xb9b237,0x4e4e4e,0x0,0x5c2309,0x0,0x4e4f4d,0xb9b237,0xb9b237,0xb9b237,0xff777777,0x0,0xff601c,0xff9d72,0xff601c,0x0,0xff777777,0xb9b237,0xb9b237,0xff777777,0x5d2409,0xffceb8,0xff9d72,0xff9d72,0x5b2209,0xff777777,0xb9b237,0xb9b237,0xff777777,0x10100,0xffceb8,0xffceb8,0xff601c,0x0,0xff777777,0xb9b237,0xb9b237,0xb9b237,0x4e4e4e,0x0,0x5c2309,0x10100,0x4f4f4f,0xb9b237,0xb9b237,0xff777777,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xff777777,0xff777777};
186 unsigned int rectllib_sel[81]= {0xff777777,0xff777777,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xff777777,0xfff64c,0xfff64c,0x4e4e4e,0x10100,0x403c00,0x0,0x4e4e4d,0xfff64c,0xfff64c,0xfff64c,0xff777777,0x0,0xaaa100,0xfff64c,0xaaa100,0x0,0xff777777,0xfff64c,0xfff64c,0xff777777,0x403c00,0xfffde2,0xffffff,0xfff64c,0x403c00,0xff777777,0xfff64c,0xfff64c,0xff777777,0x10100,0xfff64c,0xfffde2,0xaaa100,0x0,0xff777777,0xfff64c,0xfff64c,0xfff64c,0x4f4f4f,0x0,0x403c00,0x10100,0x4e4e4e,0xfff64c,0xfff64c,0xff777777,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xff777777,0xff777777};
187
188 unsigned int rectl_set[81]= {0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xaaaaaa,0xaaaaaa,0x4e4e4e,0x10100,0x202020,0x0,0x4e4e4d,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xff777777,0x0,0xaaa100,0xaaaaaa,0xaaa100,0x0,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0x202020,0xfffde2,0xffffff,0xaaaaaa,0x202020,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0x10100,0xaaaaaa,0xfffde2,0xaaa100,0x0,0xff777777,0xaaaaaa,0xaaaaaa,0xaaaaaa,0x4f4f4f,0x0,0x202020,0x10100,0x4e4e4e,0xaaaaaa,0xaaaaaa,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777};
189
190
191 static unsigned int colortab[24]=
192         {0x0,           0xFF88FF, 0xFFBBFF, 
193          0x403000,      0xFFFF88, 0xFFFFBB, 
194          0x104040,      0x66CCCC, 0x77CCCC, 
195          0x101040,      0x5588FF, 0x88BBFF, 
196          0xFFFFFF
197         };
198
199
200 static float cube[8][3] = {
201         {-1.0, -1.0, -1.0},
202         {-1.0, -1.0,  1.0},
203         {-1.0,  1.0,  1.0},
204         {-1.0,  1.0, -1.0},
205         { 1.0, -1.0, -1.0},
206         { 1.0, -1.0,  1.0},
207         { 1.0,  1.0,  1.0},
208         { 1.0,  1.0, -1.0},
209 };
210
211 void init_draw_rects(void)
212 {
213         if(G.order==B_ENDIAN) {
214                 IMB_convert_rgba_to_abgr(16, rect_desel);
215                 IMB_convert_rgba_to_abgr(16, rect_sel);
216                 
217                 IMB_convert_rgba_to_abgr(16, rectu_desel);
218                 IMB_convert_rgba_to_abgr(16, rectu_sel);
219                 
220                 IMB_convert_rgba_to_abgr(81, rectl_desel);
221                 IMB_convert_rgba_to_abgr(81, rectl_sel);
222         
223                 IMB_convert_rgba_to_abgr(81, rectlus_desel);
224                 IMB_convert_rgba_to_abgr(81, rectlus_sel);
225         
226                 IMB_convert_rgba_to_abgr(81, rectllib_desel);
227                 IMB_convert_rgba_to_abgr(81, rectllib_sel);
228                                 
229                 IMB_convert_rgba_to_abgr(81, rectl_set);
230         }
231 }
232
233 static void draw_icon_centered(float *pos, unsigned int *rect, int rectsize) 
234 {
235         float hsize= (float) rectsize/2.0;
236         GLubyte dummy= 0;
237         
238         glRasterPos3fv(pos);
239         
240                 /* use bitmap to shift rasterpos in pixels */
241         glBitmap(0, 0, 0.0, 0.0, -hsize, -hsize, &dummy);
242 #if defined (__sun__) || defined ( __sun ) || defined (__sparc) || defined (__sparc__)
243         glFlush(); 
244 #endif  
245         glDrawPixels(rectsize, rectsize, GL_RGBA, GL_UNSIGNED_BYTE, rect);
246 }
247
248 void helpline(float *vec)
249 {
250         float vecrot[3], cent[2];
251         short mval[2];
252
253         VECCOPY(vecrot, vec);
254         if(G.obedit) Mat4MulVecfl(G.obedit->obmat, vecrot);
255
256         getmouseco_areawin(mval);
257         project_float(vecrot, cent);    // no overflow in extreme cases
258
259         persp(PERSP_WIN);
260         
261         glDrawBuffer(GL_FRONT);
262         
263         BIF_ThemeColor(TH_WIRE);
264
265         setlinestyle(3);
266         glBegin(GL_LINE_STRIP); 
267                 glVertex2sv(mval); 
268                 glVertex2fv(cent); 
269         glEnd();
270         setlinestyle(0);
271         
272         persp(PERSP_VIEW);
273         glFlush(); // flush display for frontbuffer
274         glDrawBuffer(GL_BACK);
275 }
276
277 void drawaxes(float size)
278 {
279         int axis;
280
281         for (axis=0; axis<3; axis++) {
282                 float v1[3]= {0.0, 0.0, 0.0};
283                 float v2[3]= {0.0, 0.0, 0.0};
284                 int arrow_axis= (axis==0)?1:0;
285                 
286                 glBegin(GL_LINES);
287
288                 v2[axis]= size;
289                 glVertex3fv(v1);
290                 glVertex3fv(v2);
291                         
292                 v1[axis]= size*0.8;
293                 v1[arrow_axis]= -size*0.125;
294                 glVertex3fv(v1);
295                 glVertex3fv(v2);
296                         
297                 v1[arrow_axis]= size*0.125;
298                 glVertex3fv(v1);
299                 glVertex3fv(v2);
300
301                 glEnd();
302                         
303                 v2[axis]+= size*0.125;
304                 glRasterPos3fv(v2);
305                 
306                 // patch for 3d cards crashing on glSelect for text drawing (IBM)
307                 if((G.f & G_PICKSEL) == 0) {
308                         if (axis==0)
309                                 BMF_DrawString(G.font, "x");
310                         else if (axis==1)
311                                 BMF_DrawString(G.font, "y");
312                         else
313                                 BMF_DrawString(G.font, "z");
314                 }
315         }
316 }
317
318 #if 0
319 static void drawgourcube(void)
320 {
321         float n[3];
322
323         n[0]=0; n[1]=0; n[2]=0;
324         glBegin(GL_QUADS);
325                 n[0]= -1.0;
326                 glNormal3fv(n); 
327                 glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
328                 n[0]=0;
329         glEnd();
330
331         glBegin(GL_QUADS);
332                 n[1]= -1.0;
333                 glNormal3fv(n); 
334                 glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]);
335                 n[1]=0;
336         glEnd();
337
338         glBegin(GL_QUADS);
339                 n[0]= 1.0;
340                 glNormal3fv(n); 
341                 glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]);
342                 n[0]=0;
343         glEnd();
344
345         glBegin(GL_QUADS);
346                 n[1]= 1.0;
347                 glNormal3fv(n); 
348                 glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]);
349                 n[1]=0;
350         glEnd();
351
352         glBegin(GL_QUADS);
353                 n[2]= 1.0;
354                 glNormal3fv(n); 
355                 glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]);
356                 n[2]=0;
357         glEnd();
358
359         glBegin(GL_QUADS);
360                 n[2]= -1.0;
361                 glNormal3fv(n); 
362                 glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
363         glEnd();
364 }
365 #endif
366
367 static void drawcube(void)
368 {
369
370         glBegin(GL_LINE_STRIP);
371                 glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]);
372                 glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]);
373                 glVertex3fv(cube[7]); glVertex3fv(cube[4]);
374         glEnd();
375
376         glBegin(GL_LINE_STRIP);
377                 glVertex3fv(cube[1]); glVertex3fv(cube[5]);
378         glEnd();
379
380         glBegin(GL_LINE_STRIP);
381                 glVertex3fv(cube[2]); glVertex3fv(cube[6]);
382         glEnd();
383
384         glBegin(GL_LINE_STRIP);
385                 glVertex3fv(cube[3]); glVertex3fv(cube[7]);
386         glEnd();
387 }
388
389 #if 0
390 static void drawcube_size(float *size)
391 {
392
393         glPushMatrix();
394         glScalef(size[0],  size[1],  size[2]);
395         
396
397         glBegin(GL_LINE_STRIP);
398                 glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]);
399                 glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]);
400                 glVertex3fv(cube[7]); glVertex3fv(cube[4]);
401         glEnd();
402
403         glBegin(GL_LINE_STRIP);
404                 glVertex3fv(cube[1]); glVertex3fv(cube[5]);
405         glEnd();
406
407         glBegin(GL_LINE_STRIP);
408                 glVertex3fv(cube[2]); glVertex3fv(cube[6]);
409         glEnd();
410
411         glBegin(GL_LINE_STRIP);
412                 glVertex3fv(cube[3]); glVertex3fv(cube[7]);
413         glEnd();
414         
415         glPopMatrix();
416 }
417 #endif
418
419 static void tekenshadbuflimits(Lamp *la, float mat[][4])
420 {
421         float sta[3], end[3], lavec[3];
422
423         lavec[0]= -mat[2][0];
424         lavec[1]= -mat[2][1];
425         lavec[2]= -mat[2][2];
426         Normalise(lavec);
427
428         sta[0]= mat[3][0]+ la->clipsta*lavec[0];
429         sta[1]= mat[3][1]+ la->clipsta*lavec[1];
430         sta[2]= mat[3][2]+ la->clipsta*lavec[2];
431
432         end[0]= mat[3][0]+ la->clipend*lavec[0];
433         end[1]= mat[3][1]+ la->clipend*lavec[1];
434         end[2]= mat[3][2]+ la->clipend*lavec[2];
435
436
437         glBegin(GL_LINE_STRIP);
438                 glVertex3fv(sta);
439                 glVertex3fv(end);
440         glEnd();
441
442         glPointSize(3.0);
443         glBegin(GL_POINTS);
444         BIF_ThemeColor(TH_WIRE);
445         glVertex3fv(sta);
446         glVertex3fv(end);
447         glEnd();
448         glPointSize(1.0);
449 }
450
451
452
453 static void spotvolume(float *lvec, float *vvec, float inp)
454 {
455         /* camera is at 0,0,0 */
456         float temp[3],plane[3],mat1[3][3],mat2[3][3],mat3[3][3],mat4[3][3],q[4],co,si,hoek;
457
458         Normalise(lvec);
459         Normalise(vvec);                                /* is this the correct vector ? */
460
461         Crossf(temp,vvec,lvec);         /* equation for a plane through vvec en lvec */
462         Crossf(plane,lvec,temp);                /* a plane perpendicular to this, parrallel with lvec */
463
464         Normalise(plane);
465
466         /* now we've got two equations: one of a cone and one of a plane, but we have
467         three unknowns. We remove one unkown by rotating the plane to z=0 (the plane normal) */
468
469         /* rotate around cross product vector of (0,0,1) and plane normal, dot product degrees */
470         /* according definition, we derive cross product is (plane[1],-plane[0],0), en cos = plane[2]);*/
471
472         /* translating this comment to english didnt really help me understanding the math! :-) (ton) */
473         
474         q[1] = plane[1] ; 
475         q[2] = -plane[0] ; 
476         q[3] = 0 ;
477         Normalise(&q[1]);
478
479         hoek = saacos(plane[2])/2.0;
480         co = cos(hoek);
481         si = sqrt(1-co*co);
482
483         q[0] =  co;
484         q[1] *= si;
485         q[2] *= si;
486         q[3] =  0;
487
488         QuatToMat3(q,mat1);
489
490         /* rotate lamp vector now over acos(inp) degrees */
491
492         vvec[0] = lvec[0] ; 
493         vvec[1] = lvec[1] ; 
494         vvec[2] = lvec[2] ;
495
496         Mat3One(mat2);
497         co = inp;
498         si = sqrt(1-inp*inp);
499
500         mat2[0][0] =  co;
501         mat2[1][0] = -si;
502         mat2[0][1] =  si;
503         mat2[1][1] =  co;
504         Mat3MulMat3(mat3,mat2,mat1);
505
506         mat2[1][0] =  si;
507         mat2[0][1] = -si;
508         Mat3MulMat3(mat4,mat2,mat1);
509         Mat3Transp(mat1);
510
511         Mat3MulMat3(mat2,mat1,mat3);
512         Mat3MulVecfl(mat2,lvec);
513         Mat3MulMat3(mat2,mat1,mat4);
514         Mat3MulVecfl(mat2,vvec);
515
516         return;
517 }
518
519
520
521 static void drawlamp(Object *ob)
522 {
523         Lamp *la;
524         float vec[3], lvec[3], vvec[3],x,y,z;
525         
526         la= ob->data;
527         vec[0]=vec[1]=vec[2]= 0.0;
528         
529         setlinestyle(4);
530         
531         if(la->type==LA_SPOT) {
532                 
533                 lvec[0]=lvec[1]= 0.0; 
534                 lvec[2] = 1.0;
535                 x = G.vd->persmat[0][2];
536                 y = G.vd->persmat[1][2];
537                 z = G.vd->persmat[2][2];
538                 vvec[0]= x*ob->obmat[0][0] + y*ob->obmat[0][1] + z*ob->obmat[0][2];
539                 vvec[1]= x*ob->obmat[1][0] + y*ob->obmat[1][1] + z*ob->obmat[1][2];
540                 vvec[2]= x*ob->obmat[2][0] + y*ob->obmat[2][1] + z*ob->obmat[2][2];
541
542                 y = cos( M_PI*la->spotsize/360.0 );
543                 spotvolume(lvec, vvec, y);
544                 x = -la->dist;
545                 lvec[0] *=  x ; 
546                 lvec[1] *=  x ; 
547                 lvec[2] *=  x;
548                 vvec[0] *= x ; 
549                 vvec[1] *= x ; 
550                 vvec[2] *= x;
551
552                 glBegin(GL_LINE_STRIP);
553                         glVertex3fv(vvec);
554                         glVertex3fv(vec);
555                         glVertex3fv(lvec);
556                 glEnd();
557                 
558                 z = x*sqrt(1.0 - y*y);
559                 x *= y;
560
561                 glTranslatef(0.0 ,  0.0 ,  x);
562                 if(la->mode & LA_SQUARE) {
563                         vvec[0]= fabs(z);
564                         vvec[1]= fabs(z);
565                         vvec[2]= 0.0;
566                         glBegin(GL_LINE_LOOP);
567                                 glVertex3fv(vvec);
568                                 vvec[1]= -fabs(z);
569                                 glVertex3fv(vvec);
570                                 vvec[0]= -fabs(z);
571                                 glVertex3fv(vvec);
572                                 vvec[1]= fabs(z);
573                                 glVertex3fv(vvec);
574                         glEnd();
575                 }
576                 else circ(0.0, 0.0, fabs(z));
577                 
578         }
579         else if ELEM(la->type, LA_HEMI, LA_SUN) {
580                 glBegin(GL_LINE_STRIP);
581                         glVertex3fv(vec); 
582                         vec[2]= -la->dist; 
583                         glVertex3fv(vec);
584                 glEnd();
585         }
586         else {
587                 if(la->type==LA_AREA) {
588                         setlinestyle(0);
589                         if(la->area_shape==LA_AREA_SQUARE) 
590                                 fdrawbox(-la->area_size*0.5, -la->area_size*0.5, la->area_size*0.5, la->area_size*0.5);
591                         else if(la->area_shape==LA_AREA_RECT) 
592                                 fdrawbox(-la->area_size*0.5, -la->area_sizey*0.5, la->area_size*0.5, la->area_sizey*0.5);
593                         setlinestyle(3);
594                         glBegin(GL_LINE_STRIP); 
595                         glVertex3f(0.0,0.0,0.0);
596                         glVertex3f(0.0,0.0,-la->dist);
597                         glEnd();
598                         setlinestyle(0);
599                 }
600                 else if(la->mode & LA_SPHERE) {
601
602                         float tmat[4][4], imat[4][4];
603                         
604                         vec[0]= vec[1]= vec[2]= 0.0;
605                         mygetmatrix(tmat);
606                         Mat4Invert(imat, tmat);
607                         
608                         drawcircball(vec, la->dist, imat);
609
610                 }
611         }
612         myloadmatrix(G.vd->viewmat);
613         
614         VECCOPY(vec, ob->obmat[3]);
615         
616         setlinestyle(3);
617         glBegin(GL_LINE_STRIP);
618                 glVertex3fv(vec); 
619                 vec[2]= 0; 
620                 glVertex3fv(vec);
621         glEnd();
622         setlinestyle(0);
623                 
624         if(la->type==LA_SPOT && (la->mode & LA_SHAD) ) {
625                 tekenshadbuflimits(la, ob->obmat);
626         }
627 }
628
629 static void draw_limit_line(float sta, float end, unsigned int col)
630 {
631         glBegin(GL_LINES);
632         glVertex3f(0.0, 0.0, -sta);
633         glVertex3f(0.0, 0.0, -end);
634         glEnd();
635
636         glPointSize(3.0);
637         glBegin(GL_POINTS);
638         cpack(col);
639         glVertex3f(0.0, 0.0, -sta);
640         glVertex3f(0.0, 0.0, -end);
641         glEnd();
642         glPointSize(1.0);
643 }               
644
645
646 void drawcamera(Object *ob)
647 {
648         /* a standing up pyramid with (0,0,0) as top */
649         Camera *cam;
650         World *wrld;
651         float vec[8][4], tmat[4][4], fac, facx, facy, depth;
652
653         cam= ob->data;
654         glDisable(GL_LIGHTING);
655         glDisable(GL_CULL_FACE);
656         
657         /* that way it's always visible */
658         fac= cam->drawsize;
659         if(G.vd->persp>=2) fac= cam->clipsta+0.1;
660         
661         depth= - fac*cam->lens/16.0;
662         facx= fac*1.28;
663         facy= fac*1.024;
664         
665         vec[0][0]= 0; vec[0][1]= 0; vec[0][2]= 0.001;   /* GLBUG: for picking at iris Entry (well thats old!) */
666         vec[1][0]= facx; vec[1][1]= facy; vec[1][2]= depth;
667         vec[2][0]= facx; vec[2][1]= -facy; vec[2][2]= depth;
668         vec[3][0]= -facx; vec[3][1]= -facy; vec[3][2]= depth;
669         vec[4][0]= -facx; vec[4][1]= facy; vec[4][2]= depth;
670
671         glBegin(GL_LINE_LOOP);
672                 glVertex3fv(vec[0]); 
673                 glVertex3fv(vec[1]); 
674                 glVertex3fv(vec[2]); 
675                 glVertex3fv(vec[0]); 
676                 glVertex3fv(vec[3]); 
677                 glVertex3fv(vec[4]);
678         glEnd();
679
680         glBegin(GL_LINES);
681                 glVertex3fv(vec[2]); 
682                 glVertex3fv(vec[3]);
683         glEnd();
684
685         glBegin(GL_LINES);
686                 glVertex3fv(vec[4]); 
687                 glVertex3fv(vec[1]);
688         glEnd();
689
690         if(G.vd->persp>=2) return;
691         if(G.f & G_BACKBUFSEL) return;
692         
693         /* arrow on top */
694         vec[0][2]= depth;
695
696         glBegin(GL_QUADS);
697
698                 vec[0][0]= -0.2*cam->drawsize; 
699                 vec[0][1]= cam->drawsize;
700                 glVertex3fv(vec[0]);
701                 
702                 vec[0][0]= 0.2*cam->drawsize;
703                 glVertex3fv(vec[0]);
704                 
705                 vec[0][1]= 1.6*cam->drawsize;
706                 glVertex3fv(vec[0]);
707                 
708                 vec[0][0]= -0.2*cam->drawsize; 
709                 glVertex3fv(vec[0]);
710         glEnd();
711
712         glBegin(GL_TRIANGLES);
713         
714                 vec[0][0]= -0.4*cam->drawsize;
715                 vec[0][1]= 1.6*cam->drawsize;
716                 glVertex3fv(vec[0]);
717                 
718                 vec[0][0]= 0.0; 
719                 vec[0][1]= 2.0*cam->drawsize;
720                 glVertex3fv(vec[0]);
721                 
722                 vec[0][0]= 0.4*cam->drawsize; 
723                 vec[0][1]= 1.6*cam->drawsize;
724                 glVertex3fv(vec[0]);
725         
726         glEnd();
727         
728         if(cam->flag & (CAM_SHOWLIMITS+CAM_SHOWMIST)) {
729                 myloadmatrix(G.vd->viewmat);
730                 Mat4CpyMat4(vec, ob->obmat);
731                 Mat4Ortho(vec);
732                 mymultmatrix(vec);
733
734                 MTC_Mat4SwapMat4(G.vd->persmat, tmat);
735                 mygetsingmatrix(G.vd->persmat);
736
737                 if(cam->flag & CAM_SHOWLIMITS) 
738                         draw_limit_line(cam->clipsta, cam->clipend, 0x77FFFF);
739
740                 wrld= G.scene->world;
741                 if(cam->flag & CAM_SHOWMIST) 
742                         if(wrld) draw_limit_line(wrld->miststa, wrld->miststa+wrld->mistdist, 0xFFFFFF);
743                         
744                 MTC_Mat4SwapMat4(G.vd->persmat, tmat);
745         }
746 }
747
748 static void tekenvertslatt(short sel)
749 {
750         Lattice *lt;
751         BPoint *bp;
752         float size;
753         int a, uxt, u, vxt, v, wxt, w;
754
755         size= BIF_GetThemeValuef(TH_VERTEX_SIZE);
756         glPointSize(size);
757
758         if(sel) BIF_ThemeColor(TH_VERTEX_SELECT);
759         else BIF_ThemeColor(TH_VERTEX);
760
761         glBegin(GL_POINTS);
762
763         bp= editLatt->def;
764         lt= editLatt;
765         
766         if(lt->flag & LT_OUTSIDE) {
767                 
768                 for(w=0; w<lt->pntsw; w++) {
769                         if(w==0 || w==lt->pntsw-1) wxt= 1; else wxt= 0;
770                         for(v=0; v<lt->pntsv; v++) {
771                                 if(v==0 || v==lt->pntsv-1) vxt= 1; else vxt= 0;
772                                 
773                                 for(u=0; u<lt->pntsu; u++, bp++) {
774                                         if(u==0 || u==lt->pntsu-1) uxt= 1; else uxt= 0;
775                                         if(uxt || vxt || wxt) {
776                                                 if(bp->hide==0) {
777                                                         if((bp->f1 & 1)==sel) glVertex3fv(bp->vec);
778                                                 }
779                                         }
780                                 }
781                         }
782                 }
783         }
784         else {
785
786                 a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
787                 while(a--) {
788                         if(bp->hide==0) {
789                                 if((bp->f1 & 1)==sel) glVertex3fv(bp->vec);
790                         }
791                         bp++;
792                 }
793         }
794         
795         glPointSize(1.0);
796         glEnd();        
797 }
798
799 static void calc_lattverts(void)
800 {
801         BPoint *bp;
802         float mat[4][4];
803         int a;
804
805         MTC_Mat4SwapMat4(G.vd->persmat, mat);
806         mygetsingmatrix(G.vd->persmat);
807         
808          bp= editLatt->def;
809         
810         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
811         while(a--) {
812                 project_short(bp->vec, bp->s);
813                 bp++;
814         }
815
816         MTC_Mat4SwapMat4(G.vd->persmat, mat);
817 }
818
819
820 void calc_lattverts_ext(void)
821 {
822
823         areawinset(curarea->win);
824         persp(PERSP_VIEW);
825         mymultmatrix(G.obedit->obmat);
826         calc_lattverts();
827         myloadmatrix(G.vd->viewmat);
828         
829 }
830
831
832 static void drawlattice(Object *ob)
833 {
834         Lattice *lt;
835         BPoint *bp, *bpu;
836         int u, v, w, dv, dw, uxt, vxt, wxt;
837
838         lt= ob->data;
839         if(ob==G.obedit) {
840                 bp= editLatt->def;
841                 
842                 cpack(0x004000);
843         }
844         else {
845                 bp= lt->def;
846         }
847         
848         dv= lt->pntsu;
849         dw= dv*lt->pntsv;
850         
851         if(lt->flag & LT_OUTSIDE) {
852                 
853                 for(w=0; w<lt->pntsw; w++) {
854                         
855                         if(w==0 || w==lt->pntsw-1) wxt= 1; else wxt= 0;
856                         
857                         for(v=0; v<lt->pntsv; v++) {
858                                 
859                                 if(v==0 || v==lt->pntsv-1) vxt= 1; else vxt= 0;
860                                 
861                                 for(u=0, bpu=0; u<lt->pntsu; u++, bp++) {
862                                 
863                                         if(u==0 || u==lt->pntsu-1) uxt= 1; else uxt= 0;
864                                         
865                                         if(uxt || vxt || wxt) {
866                                         
867                                                 if(w && (uxt || vxt)) {
868
869                                                         glBegin(GL_LINE_STRIP);
870                                                         glVertex3fv( (bp-dw)->vec ); glVertex3fv(bp->vec);
871                                                         glEnd();
872                                                 }
873                                                 if(v && (uxt || wxt)) {
874
875                                                         glBegin(GL_LINES);
876                                                         glVertex3fv( (bp-dv)->vec ); glVertex3fv(bp->vec);
877                                                         glEnd();
878                                                 }
879                                                 if(u && (vxt || wxt)) {
880
881                                                         glBegin(GL_LINES);
882                                                         glVertex3fv(bpu->vec); glVertex3fv(bp->vec);
883                                                         glEnd();
884                                                 }
885                                         }
886                                         
887                                         bpu= bp;
888                                 }
889                         }
890                 }               
891         }
892         else {
893                 for(w=0; w<lt->pntsw; w++) {
894                         
895                         for(v=0; v<lt->pntsv; v++) {
896                                 
897                                 for(u=0, bpu=0; u<lt->pntsu; u++, bp++) {
898                                 
899                                         if(w) {
900
901                                                 glBegin(GL_LINES);
902                                                 glVertex3fv( (bp-dw)->vec ); glVertex3fv(bp->vec);
903                                                 glEnd();
904                                         }
905                                         if(v) {
906
907                                                 glBegin(GL_LINES);
908                                                 glVertex3fv( (bp-dv)->vec ); glVertex3fv(bp->vec);
909                                                 glEnd();
910                                         }
911                                         if(u) {
912
913                                                 glBegin(GL_LINES);
914                                                 glVertex3fv(bpu->vec); glVertex3fv(bp->vec);
915                                                 glEnd();
916                                         }
917                                         bpu= bp;
918                                 }
919                         }
920                 }
921         }
922         
923         if(ob==G.obedit) {
924                 
925                 calc_lattverts();
926                 
927                 if(G.zbuf) glDisable(GL_DEPTH_TEST);
928                 
929                 tekenvertslatt(0);
930                 tekenvertslatt(1);
931                 
932                 if(G.zbuf) glEnable(GL_DEPTH_TEST); 
933         }
934 }
935
936 /* ***************** ******************** */
937
938 /* window coord, assuming all matrices are set OK */
939 void calc_meshverts(void)
940 {
941         EditMesh *em = G.editMesh;
942         EditVert *eve;
943         float mat[4][4];
944
945         if(em->verts.first==0) return;
946         eve= em->verts.first;
947
948         MTC_Mat4SwapMat4(G.vd->persmat, mat);
949         mygetsingmatrix(G.vd->persmat);
950
951         eve= em->verts.first;
952         while(eve) {
953                 if(eve->h==0) {
954                         project_short(eve->co, &(eve->xs));
955                 }
956                 eve= eve->next;
957         }
958         MTC_Mat4SwapMat4(G.vd->persmat, mat);
959 }
960
961 /* window coord for current window, sets matrices temporal */
962 void calc_meshverts_ext(void)
963 {
964
965         areawinset(curarea->win);
966         persp(PERSP_VIEW);
967         
968         mymultmatrix(G.obedit->obmat);
969         calc_meshverts();
970         myloadmatrix(G.vd->viewmat);
971         
972 }
973
974 /* window coord for current window, sets matrices temporal, sets (eve->f & 2) when not visible */
975 void calc_meshverts_ext_f2(void)
976 {
977         EditMesh *em = G.editMesh;
978         EditVert *eve;
979         float mat[4][4];
980         
981         /* matrices */
982         areawinset(curarea->win);
983         persp(PERSP_VIEW);
984         mymultmatrix(G.obedit->obmat);
985         
986         if(em->verts.first==0) return;
987         eve= em->verts.first;
988
989         MTC_Mat4SwapMat4(G.vd->persmat, mat);
990         mygetsingmatrix(G.vd->persmat);
991
992         eve= em->verts.first;
993         while(eve) {
994                 eve->f &= ~2;
995                 if(eve->h==0) {
996                         project_short_noclip(eve->co, &(eve->xs));
997                         if( eve->xs >= 0 && eve->ys >= 0 && eve->xs<curarea->winx && eve->ys<curarea->winy);
998                         else eve->f |= 2;
999                 }
1000                 eve= eve->next;
1001         }
1002         
1003         /* restore */
1004         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1005         myloadmatrix(G.vd->viewmat);
1006         
1007 }
1008
1009
1010 static void calc_Nurbverts(Nurb *nurb)
1011 {
1012         Nurb *nu;
1013         BezTriple *bezt;
1014         BPoint *bp;
1015         float mat[4][4];
1016         int a;
1017
1018         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1019         mygetsingmatrix(G.vd->persmat);
1020
1021         nu= nurb;
1022         while(nu) {
1023                 if((nu->type & 7)==1) {
1024                         bezt= nu->bezt;
1025                         a= nu->pntsu;
1026                         while(a--) {
1027                                 project_short(bezt->vec[0], bezt->s[0]);
1028                                 project_short(bezt->vec[1], bezt->s[1]);
1029                                 project_short(bezt->vec[2], bezt->s[2]);
1030                                 bezt++;
1031                         }
1032                 }
1033                 else {
1034                         bp= nu->bp;
1035                         a= nu->pntsu*nu->pntsv;
1036                         while(a--) {
1037                                 project_short(bp->vec, bp->s);
1038                                 bp++;
1039                         }
1040                 }
1041                 nu= nu->next;
1042         }
1043
1044         MTC_Mat4SwapMat4(G.vd->persmat, mat);
1045 }
1046
1047 void calc_nurbverts_ext(void)
1048 {
1049
1050         areawinset(curarea->win);
1051         persp(PERSP_VIEW);
1052         mymultmatrix(G.obedit->obmat);
1053         calc_Nurbverts(editNurb.first);
1054         myloadmatrix(G.vd->viewmat);
1055         
1056 }
1057
1058 void tekenvertices(short sel)
1059 {
1060         EditMesh *em = G.editMesh;
1061         EditVert *eve;
1062         float size;
1063         char col[3];
1064         
1065         /* draws in zbuffer mode twice, to show invisible vertices transparent */
1066
1067         size= BIF_GetThemeValuef(TH_VERTEX_SIZE);
1068         if(sel) BIF_GetThemeColor3ubv(TH_VERTEX_SELECT, col);
1069         else BIF_GetThemeColor3ubv(TH_VERTEX, col);
1070         
1071         if(G.zbuf) {
1072                 glPointSize(size>2.1?size/2.0: size);
1073
1074                 glDisable(GL_DEPTH_TEST);
1075                 glColor4ub(col[0], col[1], col[2], 100);
1076                 
1077                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1078                 glEnable(GL_BLEND);
1079
1080                 glBegin(GL_POINTS);
1081                 for(eve= em->verts.first; eve; eve= eve->next) {
1082                         if(eve->h==0 && (eve->f & 1)==sel ) glVertex3fv(eve->co);
1083                 }
1084                 glEnd();
1085                 
1086                 glDisable(GL_BLEND);
1087                 glEnable(GL_DEPTH_TEST);
1088         }
1089
1090         glPointSize(size);
1091         glColor3ub(col[0], col[1], col[2]);
1092
1093         glBegin(GL_POINTS);
1094         for(eve= em->verts.first; eve; eve= eve->next) {
1095                 if(eve->h==0 && (eve->f & 1)==sel ) glVertex3fv(eve->co);
1096         }
1097         glEnd();
1098
1099         glPointSize(1.0);
1100 }
1101
1102
1103 /* ************** DRAW DISPLIST ****************** */
1104
1105 /* DispListMesh, comes from subsurf or decimator */
1106
1107 static void displistmesh_draw_wire(DispListMesh *dlm) 
1108 {
1109         MVert *mvert= dlm->mvert;
1110         MEdge *medge;
1111         int i, optim;
1112         
1113         if(dlm->medge) {
1114                 optim= dlm->flag & ME_OPT_EDGES;
1115                 medge= dlm->medge;
1116         
1117                 glBegin(GL_LINES);
1118                 for (i=0; i<dlm->totedge; i++, medge++) {
1119                         if(optim==0 || (medge->flag & ME_EDGEDRAW)) {
1120                                 glVertex3fv(mvert[medge->v1].co); 
1121                                 glVertex3fv(mvert[medge->v2].co);
1122                         }
1123         
1124                 }
1125                 glEnd();
1126         }
1127         else {
1128                 for (i=0; i<dlm->totface; i++) {
1129                         MFace *mf= &dlm->mface[i];
1130                         
1131                         glBegin(GL_LINE_LOOP);
1132                         glVertex3fv(dlm->mvert[mf->v1].co);
1133                         glVertex3fv(dlm->mvert[mf->v2].co);
1134                         if (mf->v3) {
1135                                 glVertex3fv(dlm->mvert[mf->v3].co);
1136                                 if (mf->v4)
1137                                         glVertex3fv(dlm->mvert[mf->v4].co);
1138                         }
1139                         glEnd();
1140                 }
1141         }
1142 }
1143
1144 static void displistmesh_draw_solid(DispListMesh *dlm, int drawsmooth, float *nors) 
1145 {
1146         int lmode, lshademodel= -1, lmat_nr= -1;
1147         int i;
1148
1149 #define PASSVERT(ind) {                                                                 \
1150         if (drawsmooth && lshademodel==GL_SMOOTH)                               \
1151                 glNormal3sv(dlm->mvert[(ind)].no);                                      \
1152         glVertex3fv(dlm->mvert[(ind)].co);                                              \
1153 }
1154
1155         glBegin(lmode= GL_QUADS);
1156         for (i=0; i<dlm->totface; i++) {
1157                 MFace *mf= &dlm->mface[i];
1158                 
1159                 if (mf->v3) {
1160                         int nmode= mf->v4?GL_QUADS:GL_TRIANGLES;
1161                         
1162                         if (nmode!=lmode) {
1163                                 glEnd();
1164                                 glBegin(lmode= nmode);
1165                         }
1166                         
1167                         if (drawsmooth) {
1168                                 int nshademodel= (mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
1169
1170                                 if (nshademodel!=lshademodel) {
1171                                         glEnd();
1172                                         glShadeModel(lshademodel= nshademodel);
1173                                         glBegin(lmode);
1174                                 }
1175                         
1176                                 if (mf->mat_nr!=lmat_nr) {
1177                                         glEnd();
1178                                         set_gl_material((lmat_nr= mf->mat_nr)+1);
1179                                         glBegin(lmode);
1180                                 }
1181                         }
1182                         
1183                         if (drawsmooth && lshademodel==GL_FLAT)
1184                                 glNormal3fv(&nors[i*3]);
1185                                 
1186                         PASSVERT(mf->v1);
1187                         PASSVERT(mf->v2);
1188                         PASSVERT(mf->v3);
1189                         if (mf->v4)
1190                                 PASSVERT(mf->v4);
1191                 }
1192         }
1193         glEnd();
1194         
1195 #undef PASSVERT
1196 }
1197
1198 static void displistmesh_draw_shaded(DispListMesh *dlm, unsigned char *vcols1, unsigned char *vcols2) 
1199 {
1200         int i, lmode;
1201         
1202         glShadeModel(GL_SMOOTH);
1203         if (vcols2)
1204                 glEnable(GL_CULL_FACE);
1205                 
1206 #define PASSVERT(vidx, fidx) {                          \
1207         unsigned char *col= &colbase[fidx*4];           \
1208         glColor3ub(col[3], col[2], col[1]);                     \
1209         glVertex3fv(dlm->mvert[(vidx)].co);                     \
1210 }
1211
1212         glBegin(lmode= GL_QUADS);
1213         for (i=0; i<dlm->totface; i++) {
1214                 MFace *mf= &dlm->mface[i];
1215                 
1216                 if (mf->v3) {
1217                         int nmode= mf->v4?GL_QUADS:GL_TRIANGLES;
1218                         unsigned char *colbase= &vcols1[i*16];
1219                         
1220                         if (nmode!=lmode) {
1221                                 glEnd();
1222                                 glBegin(lmode= nmode);
1223                         }
1224                         
1225                         PASSVERT(mf->v1, 0);
1226                         PASSVERT(mf->v2, 1);
1227                         PASSVERT(mf->v3, 2);
1228                         if (mf->v4)
1229                                 PASSVERT(mf->v4, 3);
1230                         
1231                         if (vcols2) {
1232                                 unsigned char *colbase= &vcols2[i*16];
1233
1234                                 if (mf->v4)
1235                                         PASSVERT(mf->v4, 3);
1236                                 PASSVERT(mf->v3, 2);
1237                                 PASSVERT(mf->v2, 1);
1238                                 PASSVERT(mf->v1, 0);
1239                         }
1240                 }
1241         }
1242         glEnd();
1243
1244         if (vcols2)
1245                 glDisable(GL_CULL_FACE);
1246         
1247 #undef PASSVERT
1248 }
1249
1250         /***/
1251         
1252 static int draw_index_wire= 1;
1253 static int index3_nors_incr= 1;
1254
1255 static void drawDispListwire(ListBase *dlbase)
1256 {
1257         DispList *dl;
1258         int parts, nr, ofs, *index;
1259         float *data;
1260
1261         if(dlbase==0) return;
1262
1263         dl= dlbase->first;
1264         while(dl) {
1265                 data= dl->verts;
1266         
1267                 switch(dl->type) {
1268                 case DL_SEGM:
1269                         parts= dl->parts;
1270                         while(parts--) {
1271                                 nr= dl->nr;
1272                                 glBegin(GL_LINE_STRIP);
1273                                 while(nr--) {
1274                                         glVertex3fv(data);
1275                                         data+=3;
1276                                 }
1277                                 glEnd();
1278                         }
1279                         break;
1280                 case DL_POLY:
1281                         parts= dl->parts;
1282                         while(parts--) {
1283                                 nr= dl->nr;
1284                                 glBegin(GL_LINE_LOOP);
1285                                 while(nr--) {
1286                                         glVertex3fv(data);
1287                                         data+=3;
1288                                 }
1289                                 glEnd();
1290                         }
1291                         break;
1292                 case DL_SURF:
1293                         parts= dl->parts;
1294                         while(parts--) {
1295                                 nr= dl->nr;
1296                                 if(dl->flag & DL_CYCL_U) glBegin(GL_LINE_LOOP);
1297                                 else glBegin(GL_LINE_STRIP);
1298
1299                                 while(nr--) {
1300                                         glVertex3fv(data);
1301                                         data+=3;
1302                                 }
1303                                 glEnd();
1304                         }
1305                         ofs= 3*dl->nr;
1306                         nr= dl->nr;
1307                         while(nr--) {
1308                                 data= (  dl->verts )+3*nr;
1309                                 parts= dl->parts;
1310                                 if(dl->flag & DL_CYCL_V) glBegin(GL_LINE_LOOP);
1311                                 else glBegin(GL_LINE_STRIP);
1312                                 
1313                                 while(parts--) {
1314                                         glVertex3fv(data);
1315                                         data+=ofs;
1316                                 }
1317                                 glEnd();
1318                         }
1319                         break;
1320                         
1321                 case DL_INDEX3:
1322                         if(draw_index_wire) {
1323                                 parts= dl->parts;
1324                                 data= dl->verts;
1325                                 index= dl->index;
1326                                 while(parts--) {
1327
1328                                         glBegin(GL_LINE_LOOP);
1329                                                 glVertex3fv(data+3*index[0]);
1330                                                 glVertex3fv(data+3*index[1]);
1331                                                 glVertex3fv(data+3*index[2]);
1332                                         glEnd();
1333                                         index+= 3;
1334                                 }
1335                         }
1336                         break;
1337                         
1338                 case DL_INDEX4:
1339                         if(draw_index_wire) {
1340                                 parts= dl->parts;
1341                                 data= dl->verts;
1342                                 index= dl->index;
1343                                 while(parts--) {
1344
1345                                         glBegin(GL_LINE_LOOP);
1346                                                 glVertex3fv(data+3*index[0]);
1347                                                 glVertex3fv(data+3*index[1]);
1348                                                 glVertex3fv(data+3*index[2]);
1349                                                 if(index[3]) glVertex3fv(data+3*index[3]);
1350                                         glEnd();
1351                                         index+= 4;
1352                                 }
1353                         }
1354                         break;
1355                         
1356                 case DL_MESH:
1357                         displistmesh_draw_wire(dl->mesh);
1358                         break;
1359                 }
1360                 dl= dl->next;
1361         }
1362 }
1363
1364 static void drawDispListsolid(ListBase *lb, Object *ob)
1365 {
1366         DispList *dl;
1367         int parts, ofs, p1, p2, p3, p4, a, b, *index;
1368         float *data, *v1, *v2, *v3, *v4;
1369         float *ndata, *n1, *n2, *n3, *n4;
1370         int drawsmooth= !(G.f & G_BACKBUFSEL);
1371         
1372         if(lb==0) return;
1373         
1374         /* drawsmooth abused here, except for Mesh this draws with smooth default */
1375         if (drawsmooth) {
1376                 glShadeModel(GL_SMOOTH);
1377                 glEnable(GL_LIGHTING);
1378                 
1379                 if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
1380                 else glFrontFace(GL_CCW);
1381         }
1382         
1383         dl= lb->first;
1384         while(dl) {
1385                 data= dl->verts;
1386                 ndata= dl->nors;
1387
1388                 switch(dl->type) {
1389                 case DL_SURF:
1390                         if(!drawsmooth) {
1391                                 for(a=0; a<dl->parts; a++) {
1392         
1393                                         DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
1394         
1395                                         v1= data+ 3*p1; 
1396                                         v2= data+ 3*p2;
1397                                         v3= data+ 3*p3; 
1398                                         v4= data+ 3*p4;
1399         
1400                                         glBegin(GL_QUAD_STRIP);
1401                                         
1402                                         glVertex3fv(v2);
1403                                         glVertex3fv(v4);
1404
1405                                         for(; b<dl->nr; b++) {
1406                                                 
1407                                                 glVertex3fv(v1);
1408                                                 glVertex3fv(v3);
1409
1410                                                 v2= v1; v1+= 3;
1411                                                 v4= v3; v3+= 3;
1412                                         }
1413                                         
1414                                         
1415                                         glEnd();
1416                                 }
1417                         }
1418                         else {
1419
1420                                 set_gl_material(dl->col+1);
1421
1422                                 for(a=0; a<dl->parts; a++) {
1423                                         
1424                                         DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
1425                                         
1426                                         v1= data+ 3*p1; 
1427                                         v2= data+ 3*p2;
1428                                         v3= data+ 3*p3; 
1429                                         v4= data+ 3*p4;
1430                                         n1= ndata+ 3*p1; 
1431                                         n2= ndata+ 3*p2;
1432                                         n3= ndata+ 3*p3; 
1433                                         n4= ndata+ 3*p4;
1434                                         
1435                                         glBegin(GL_QUAD_STRIP);
1436                                         
1437                                         glNormal3fv(n2); glVertex3fv(v2);
1438                                         glNormal3fv(n4); glVertex3fv(v4);
1439
1440                                         for(; b<dl->nr; b++) {
1441                                                 
1442                                                 glNormal3fv(n1); glVertex3fv(v1);
1443                                                 glNormal3fv(n3); glVertex3fv(v3);
1444
1445                                                 v2= v1; v1+= 3;
1446                                                 v4= v3; v3+= 3;
1447                                                 n2= n1; n1+= 3;
1448                                                 n4= n3; n3+= 3;
1449                                         }
1450                                         
1451                                         
1452                                         glEnd();
1453                                 }
1454                         }
1455                         break;
1456
1457                 case DL_INDEX3:
1458                 
1459                         parts= dl->parts;
1460                         data= dl->verts;
1461                         ndata= dl->nors;
1462                         index= dl->index;
1463                         
1464                         if(!drawsmooth) {
1465                                 while(parts--) {
1466
1467                                         glBegin(GL_TRIANGLES);
1468                                                 glVertex3fv(data+3*index[0]);
1469                                                 glVertex3fv(data+3*index[1]);
1470                                                 glVertex3fv(data+3*index[2]);
1471                                         glEnd();
1472                                         index+= 3;
1473                                 }
1474                         }
1475                         else {
1476
1477                                 set_gl_material(dl->col+1);
1478                                                                 
1479                                 /* voor polys only one normal needed */
1480                                 if(index3_nors_incr==0) {
1481                                         while(parts--) {
1482
1483                                                 glBegin(GL_TRIANGLES);
1484                                                         glNormal3fv(ndata);
1485                                                         glVertex3fv(data+3*index[0]);
1486                                                         glVertex3fv(data+3*index[1]);
1487                                                         glVertex3fv(data+3*index[2]);
1488                                                 glEnd();
1489                                                 index+= 3;
1490                                         }
1491                                 }
1492                                 else {
1493                                         while(parts--) {
1494
1495                                                 glBegin(GL_TRIANGLES);
1496                                                         ofs= 3*index[0];
1497                                                         glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
1498                                                         ofs= 3*index[1];
1499                                                         glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
1500                                                         ofs= 3*index[2];
1501                                                         glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
1502                                                 glEnd();
1503                                                 index+= 3;
1504                                         }
1505                                 }
1506                         }
1507                         break;
1508
1509                 case DL_INDEX4:
1510
1511                         parts= dl->parts;
1512                         data= dl->verts;
1513                         ndata= dl->nors;
1514                         index= dl->index;
1515
1516                         if(!drawsmooth) {
1517                                 while(parts--) {
1518
1519                                         glBegin(index[3]?GL_QUADS:GL_TRIANGLES);
1520                                                 glVertex3fv(data+3*index[0]);
1521                                                 glVertex3fv(data+3*index[1]);
1522                                                 glVertex3fv(data+3*index[2]);
1523                                                 if(index[3]) glVertex3fv(data+3*index[3]);
1524                                         glEnd();
1525                                         index+= 4;
1526                                 }
1527                         }
1528                         else {
1529                                 
1530                                 set_gl_material(dl->col+1);
1531                         
1532                                 while(parts--) {
1533
1534                                         glBegin(index[3]?GL_QUADS:GL_TRIANGLES);
1535                                                 ofs= 3*index[0];
1536                                                 glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
1537                                                 ofs= 3*index[1];
1538                                                 glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
1539                                                 ofs= 3*index[2];
1540                                                 glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
1541                                                 if(index[3]) {
1542                                                         ofs= 3*index[3];
1543                                                         glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
1544                                                 }
1545                                         glEnd();
1546                                         index+= 4;
1547                                 }
1548                         }
1549                         break;
1550                 
1551                 case DL_MESH:
1552                         if (!dl->nors)
1553                                 addnormalsDispList(ob, lb);
1554                         displistmesh_draw_solid(dl->mesh, drawsmooth, dl->nors);
1555                         break;
1556                                 
1557                 }
1558                 dl= dl->next;
1559         }
1560
1561         if(drawsmooth) {
1562                 glShadeModel(GL_FLAT);
1563                 glDisable(GL_LIGHTING);
1564                 glFrontFace(GL_CCW);
1565         }
1566 }
1567
1568 static void drawDispListshaded(ListBase *lb, Object *ob)
1569 {
1570         DispList *dl, *dlob;
1571         int parts, p1, p2, p3, p4, a, b, *index;
1572         float *data, *v1, *v2, *v3, *v4;/*  , *extverts=0 */
1573         unsigned int *cdata, *c1, *c2, *c3, *c4;
1574         char *cp;
1575
1576         if(lb==0) return;
1577
1578         glShadeModel(GL_SMOOTH);
1579
1580         dl= lb->first;
1581         dlob= ob->disp.first;
1582         while(dl && dlob) {
1583                 
1584                 cdata= dlob->col1;
1585                 data= dl->verts;
1586                 if(cdata==0) break;
1587                 
1588                 switch(dl->type) {
1589                 case DL_SURF:
1590
1591                         for(a=0; a<dl->parts; a++) {
1592
1593                                 DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
1594
1595                                 v1= data+ 3*p1; 
1596                                 v2= data+ 3*p2;
1597                                 v3= data+ 3*p3; 
1598                                 v4= data+ 3*p4;
1599                                 c1= cdata+ p1; 
1600                                 c2= cdata+ p2;
1601                                 c3= cdata+ p3; 
1602                                 c4= cdata+ p4;
1603
1604                                 for(; b<dl->nr; b++) {
1605
1606                                         glBegin(GL_QUADS);
1607                                                 cp= (char *)c1;
1608                                                 glColor3ub(cp[3], cp[2], cp[1]);
1609                                                 glVertex3fv(v1);
1610                                                 cp= (char *)c2;
1611                                                 glColor3ub(cp[3], cp[2], cp[1]);
1612                                                 glVertex3fv(v2);
1613                                                 cp= (char *)c4;
1614                                                 glColor3ub(cp[3], cp[2], cp[1]);
1615                                                 glVertex3fv(v4);
1616                                                 cp= (char *)c3;
1617                                                 glColor3ub(cp[3], cp[2], cp[1]);
1618                                                 glVertex3fv(v3);
1619                                         glEnd();
1620
1621                                         v2= v1; v1+= 3;
1622                                         v4= v3; v3+= 3;
1623                                         c2= c1; c1++;
1624                                         c4= c3; c3++;
1625                                 }
1626                         }
1627                         break;
1628
1629                 case DL_INDEX3:
1630                         
1631                         parts= dl->parts;
1632                         index= dl->index;
1633                         
1634                         while(parts--) {
1635
1636                                 glBegin(GL_TRIANGLES);
1637                                         cp= (char *)(cdata+index[0]);
1638                                         glColor3ub(cp[3], cp[2], cp[1]);                                        
1639                                         glVertex3fv(data+3*index[0]);
1640
1641                                         cp= (char *)(cdata+index[1]);
1642                                         glColor3ub(cp[3], cp[2], cp[1]);                                        
1643                                         glVertex3fv(data+3*index[1]);
1644
1645                                         cp= (char *)(cdata+index[2]);
1646                                         glColor3ub(cp[3], cp[2], cp[1]);                                        
1647                                         glVertex3fv(data+3*index[2]);
1648                                 glEnd();
1649                                 index+= 3;
1650                         }
1651                         break;
1652
1653                 case DL_INDEX4:
1654                 
1655                         parts= dl->parts;
1656                         index= dl->index;
1657                         while(parts--) {
1658
1659                                 glBegin(index[3]?GL_QUADS:GL_TRIANGLES);
1660                                         cp= (char *)(cdata+index[0]);
1661                                         glColor3ub(cp[3], cp[2], cp[1]);                                        
1662                                         glVertex3fv(data+3*index[0]);
1663
1664                                         cp= (char *)(cdata+index[1]);
1665                                         glColor3ub(cp[3], cp[2], cp[1]);                                        
1666                                         glVertex3fv(data+3*index[1]);
1667
1668                                         cp= (char *)(cdata+index[2]);
1669                                         glColor3ub(cp[3], cp[2], cp[1]);                                        
1670                                         glVertex3fv(data+3*index[2]);
1671                                         
1672                                         if(index[3]) {
1673                                         
1674                                                 cp= (char *)(cdata+index[3]);
1675                                                 glColor3ub(cp[3], cp[2], cp[1]);        
1676                                                 glVertex3fv(data+3*index[3]);
1677                                         }
1678                                 glEnd();
1679                                 index+= 4;
1680                         }
1681                         break;
1682
1683                 case DL_MESH:
1684                         displistmesh_draw_shaded(dl->mesh, (unsigned char*) dlob->col1, (unsigned char*) dlob->col2);
1685                         break;
1686                         
1687                 }
1688                 dl= dl->next;
1689                 dlob= dlob->next;
1690         }
1691         
1692         glShadeModel(GL_FLAT);
1693 }
1694
1695
1696 static void drawmeshsolid(Object *ob, float *nors)
1697 {
1698         EditMesh *em = G.editMesh;
1699         Mesh *me;
1700         DispList *dl;
1701         MVert *mvert;
1702         TFace *tface;
1703         MFace *mface;
1704         EditVlak *evl;
1705         float *extverts=0, *v1, *v2, *v3, *v4;
1706         int glmode, setsmooth=0, a, start, end, matnr= -1, vertexpaint, i;
1707         short no[3], *n1, *n2, *n3, *n4 = NULL;
1708         
1709         vertexpaint= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0));
1710
1711         me= get_mesh(ob);
1712         if(me==0) return;
1713
1714         glShadeModel(GL_FLAT);
1715
1716         if( (G.f & G_BACKBUFSEL)==0 ) {
1717                 glEnable(GL_LIGHTING);
1718                 init_gl_materials(ob);
1719
1720                 two_sided( me->flag & ME_TWOSIDED );
1721
1722                 if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
1723                 else glFrontFace(GL_CCW);
1724         }
1725
1726         mface= me->mface;
1727         if( (G.f & G_FACESELECT) && ob==((G.scene->basact) ? (G.scene->basact->object) : 0)) tface= me->tface;
1728         else tface= 0;
1729
1730         mvert= me->mvert;
1731         a= me->totface;
1732
1733         /* SOLVE */
1734         /* if ELEM(ob->type, OB_SECTOR, OB_LIFE) glEnable(GL_CULL_FACE); */
1735
1736         if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) {
1737                 
1738                 evl= em->faces.first;
1739                 while(evl) {
1740                         if(evl->v1->h==0 && evl->v2->h==0 && evl->v3->h==0) {
1741                                 
1742                                 if(evl->mat_nr!=matnr) {
1743                                         matnr= evl->mat_nr;
1744                                         set_gl_material(matnr+1);
1745                                 }
1746                                 
1747                                 if(evl->v4 && evl->v4->h==0) {
1748                                 
1749                                         glBegin(GL_QUADS);
1750                                                 glNormal3fv(evl->n);
1751                                                 glVertex3fv(evl->v1->co);
1752                                                 glVertex3fv(evl->v2->co);
1753                                                 glVertex3fv(evl->v3->co);
1754                                                 glVertex3fv(evl->v4->co);
1755                                         glEnd();
1756                                 }
1757                                 else {
1758
1759                                         glBegin(GL_TRIANGLES);
1760                                                 glNormal3fv(evl->n);
1761                                                 glVertex3fv(evl->v1->co);
1762                                                 glVertex3fv(evl->v2->co);
1763                                                 glVertex3fv(evl->v3->co);
1764                                         glEnd();
1765                                 }
1766                         }
1767                         evl= evl->next;
1768                 }
1769                 
1770                 glDisable(GL_LIGHTING);
1771                 glShadeModel(GL_FLAT);
1772         }
1773         else {          /* [nors] should never be zero, but is weak code... the displist 
1774                                    system needs a make over (ton)
1775                           
1776                                    Face select and vertex paint calls drawmeshsolid() with nors = NULL!
1777                                    It's still weak code but hey, as ton says, the whole system needs 
1778                            a good thrashing! ;) (aphex) */
1779
1780                 start= 0; end= me->totface;
1781                 set_buildvars(ob, &start, &end);
1782                 mface+= start;
1783                 if(tface) tface+= start;
1784                 
1785                 dl= find_displist(&ob->disp, DL_VERTS);
1786                 if(dl) extverts= dl->verts;
1787         
1788                 glBegin(GL_QUADS);
1789                 glmode= GL_QUADS;
1790                 
1791                 for(a=start; a<end; a++, mface++, nors+=3) {
1792                         if(mface->v3) {
1793                                 if(tface && (tface->flag & TF_HIDE)) {
1794                                         if( (G.f & G_BACKBUFSEL)==0) {
1795                                                 glBegin(GL_LINE_LOOP);
1796                                                 glVertex3fv( (mvert+mface->v1)->co);
1797                                                 glVertex3fv( (mvert+mface->v2)->co);
1798                                                 glVertex3fv( (mvert+mface->v3)->co);
1799                                                 if(mface->v4) glVertex3fv( (mvert+mface->v1)->co);
1800                                                 glEnd();
1801                                                 tface++;
1802                                         }
1803                                 }
1804                                 else {
1805                                         if(extverts) {
1806                                                 v1= extverts+3*mface->v1;
1807                                                 v2= extverts+3*mface->v2;
1808                                                 v3= extverts+3*mface->v3;
1809                                                 if(mface->v4) v4= extverts+3*mface->v4;
1810                                                 else v4= 0;
1811                                         }
1812                                         else {
1813                                                 v1= (mvert+mface->v1)->co;
1814                                                 v2= (mvert+mface->v2)->co;
1815                                                 v3= (mvert+mface->v3)->co;
1816                                                 if(mface->v4) v4= (mvert+mface->v4)->co;
1817                                                 else v4= 0;
1818                                         }
1819                                         
1820                                         
1821                                         if(tface) {
1822                                                 if(tface->mode & TF_TWOSIDE) glEnable(GL_CULL_FACE);
1823                                                 else glDisable(GL_CULL_FACE);
1824                                         }
1825                                         
1826         
1827                                         /* this GL_QUADS joke below was tested for speed: a factor 2! */
1828                                                 
1829                                         if(v4) {if(glmode==GL_TRIANGLES) {glmode= GL_QUADS; glEnd(); glBegin(GL_QUADS);}}
1830                                         else {if(glmode==GL_QUADS) {glmode= GL_TRIANGLES; glEnd(); glBegin(GL_TRIANGLES);}}
1831                                                 
1832                                         if(G.f & G_BACKBUFSEL) {
1833                                                 if(vertexpaint) {
1834                                                         i= index_to_framebuffer(a+1);
1835                                                         cpack(i);
1836                                                 }
1837         
1838                                                 glVertex3fv( v1 );
1839                                                 glVertex3fv( v2 );
1840                                                 glVertex3fv( v3 );
1841                                                 if(v4) glVertex3fv( v4 );
1842                                                 
1843                                         }
1844                                         else {
1845                                                 
1846                                                 if(mface->mat_nr!=matnr) {
1847                                                         glEnd();
1848
1849                                                         matnr= mface->mat_nr;
1850                                                         set_gl_material(matnr+1);
1851
1852                                                         glBegin(glmode);
1853                                                 }
1854         
1855                                                 if( (me->flag & ME_AUTOSMOOTH)==0 && (mface->flag & ME_SMOOTH)) {
1856                                                         if(setsmooth==0) {
1857                                                                 glEnd();
1858                                                                 glShadeModel(GL_SMOOTH);
1859                                                                 glBegin(glmode);
1860                                                                 setsmooth= 1;
1861                                                         }
1862                                                         n1= (mvert+mface->v1)->no;
1863                                                         n2= (mvert+mface->v2)->no;
1864                                                         n3= (mvert+mface->v3)->no;
1865                                                         if(v4) n4= (mvert+mface->v4)->no;
1866                                                 
1867                                                         if(mface->puno & ME_FLIPV1) {
1868                                                                 no[0]= -n1[0]; no[1]= -n1[1]; no[2]= -n1[2];
1869                                                                 glNormal3sv(no);
1870                                                         }
1871                                                         else glNormal3sv(n1);
1872                                                         glVertex3fv( v1 );
1873                                                         
1874                                                         if(mface->puno & ME_FLIPV2) {
1875                                                                 no[0]= -n2[0]; no[1]= -n2[1]; no[2]= -n2[2];
1876                                                                 glNormal3sv(no);
1877                                                         }
1878                                                         else glNormal3sv(n2);
1879                                                         glVertex3fv( v2 );
1880                                                         
1881                                                         if(mface->puno & ME_FLIPV3) {
1882                                                                 no[0]= -n3[0]; no[1]= -n3[1]; no[2]= -n3[2];
1883                                                                 glNormal3sv(no);
1884                                                         }
1885                                                         else glNormal3sv(n3);
1886                                                         glVertex3fv( v3 );
1887                                                         
1888                                                         if(v4) {
1889                                                                 if(mface->puno & ME_FLIPV4) {
1890                                                                         no[0]= -n4[0]; no[1]= -n4[1]; no[2]= -n4[2];
1891                                                                         glNormal3sv(no);
1892                                                                 }
1893                                                                 else glNormal3sv(n4);
1894                                                                 glVertex3fv( v4 );
1895                                                         }
1896                                                 }
1897                                                 else {
1898                                                         if(setsmooth==1) {
1899                                                                 glEnd();
1900                                                                 glShadeModel(GL_FLAT);
1901                                                                 glBegin(glmode);
1902                                                                 setsmooth= 0;
1903                                                         }
1904                                                         glNormal3fv(nors);
1905                                                         glVertex3fv( v1 );
1906                                                         glVertex3fv( v2 );
1907                                                         glVertex3fv( v3 );
1908                                                         if(v4) glVertex3fv( v4 );
1909                                                 }
1910                                         }
1911                                 }
1912                                 if(tface) tface++;
1913                         }
1914                 }
1915                 
1916                 glEnd();
1917         }
1918         
1919         /* SOLVE */
1920 /*      if ELEM(ob->type, OB_SECTOR, OB_LIFE) glDisable(GL_CULL_FACE); */
1921
1922         if(G.f & G_BACKBUFSEL) {
1923                 glDisable(GL_CULL_FACE);
1924         }
1925         glDisable(GL_LIGHTING);
1926         glFrontFace(GL_CCW);
1927 }
1928
1929 static void drawmeshshaded(Object *ob, unsigned int *col1, unsigned int *col2)
1930 {
1931         Mesh *me;
1932         MVert *mvert;
1933         MFace *mface;
1934         TFace *tface;
1935         DispList *dl;
1936         float *extverts=0, *v1, *v2, *v3, *v4;
1937         int a, start, end, twoside;
1938         char *cp1, *cp2 = NULL;
1939         int lglmode;
1940         
1941         glShadeModel(GL_SMOOTH);
1942         glDisable(GL_LIGHTING);
1943
1944         me= ob->data;
1945         mface= me->mface;
1946         
1947         /* then it does not draw hide */
1948         if( (G.f & G_FACESELECT) && ob==((G.scene->basact) ? (G.scene->basact->object) : 0)) tface= me->tface;
1949         else tface= 0;
1950         
1951         mvert= me->mvert;
1952         a= me->totface;
1953         
1954         twoside= me->flag & ME_TWOSIDED;
1955         if(col2==0) twoside= 0;
1956         
1957         if(twoside) glEnable(GL_CULL_FACE);
1958         
1959         start= 0; end= me->totface;
1960         set_buildvars(ob, &start, &end);
1961         mface+= start;
1962         if(tface) tface+= start;
1963         col1+= 4*start;
1964         if(col2) col2+= 4*start;
1965         
1966         dl= find_displist(&ob->disp, DL_VERTS);
1967         if(dl) extverts= dl->verts;
1968
1969         glBegin(lglmode= GL_QUADS);
1970         
1971         cp1= (char *)col1;
1972         if(col2) cp2= (char *)col2;
1973
1974         for(a=start; a<end; a++, mface++, cp1+= 16) {
1975                 if(mface->v3) {
1976                         if(tface && (tface->flag & TF_HIDE)) tface++;
1977                         else {
1978                                 int nglmode= mface->v4?GL_QUADS:GL_TRIANGLES;
1979                                 
1980                                 if (nglmode!=lglmode) {
1981                                         glEnd();
1982                                         glBegin(lglmode= nglmode);
1983                                 }
1984                                 
1985                                 if(extverts) {
1986                                         v1= extverts+3*mface->v1;
1987                                         v2= extverts+3*mface->v2;
1988                                         v3= extverts+3*mface->v3;
1989                                         if(mface->v4) v4= extverts+3*mface->v4;
1990                                         else v4= 0;
1991                                 }
1992                                 else {
1993                                         v1= (mvert+mface->v1)->co;
1994                                         v2= (mvert+mface->v2)->co;
1995                                         v3= (mvert+mface->v3)->co;
1996                                         if(mface->v4) v4= (mvert+mface->v4)->co;
1997                                         else v4= 0;
1998                                 }
1999
2000                                 if(tface) {
2001                                         if(tface->mode & TF_TWOSIDE) glEnable(GL_CULL_FACE);
2002                                         else glDisable(GL_CULL_FACE);
2003                                 }
2004                                 
2005                                 glColor3ub(cp1[3], cp1[2], cp1[1]);
2006                                 glVertex3fv( v1 );
2007                                 glColor3ub(cp1[7], cp1[6], cp1[5]);
2008                                 glVertex3fv( v2 );
2009                                 glColor3ub(cp1[11], cp1[10], cp1[9]);
2010                                 glVertex3fv( v3 );
2011                                 if(v4) {
2012                                         glColor3ub(cp1[15], cp1[14], cp1[13]);
2013                                         glVertex3fv( v4 );
2014                                 }
2015                                 
2016                                 if(twoside) {
2017
2018                                         glColor3ub(cp2[11], cp2[10], cp2[9]);
2019                                         glVertex3fv( v3 );
2020                                         glColor3ub(cp2[7], cp2[6], cp2[5]);
2021                                         glVertex3fv( v2 );
2022                                         glColor3ub(cp2[3], cp2[2], cp2[1]);
2023                                         glVertex3fv( v1 );
2024                                         if(mface->v4) {
2025                                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
2026                                                 glVertex3fv( v4 );
2027                                         }
2028                                 }
2029                         }
2030                 }
2031                 if(col2) cp2+= 16;
2032         }
2033         
2034         glEnd();
2035         glShadeModel(GL_FLAT);
2036         if(twoside) glDisable(GL_CULL_FACE);
2037 }
2038
2039 static void drawDispList(Object *ob, int dt)
2040 {
2041         ListBase *lb=0;
2042         DispList *dl;
2043         Mesh *me;
2044         int solid;
2045
2046         
2047         solid= (dt > OB_WIRE);
2048
2049         switch(ob->type) {
2050         case OB_MESH:
2051                 
2052                 me= get_mesh(ob);
2053                 if(me==0) return;
2054                 
2055                 if(me->bb==0) tex_space_mesh(me);
2056                 if(me->totface>4) if(boundbox_clip(ob->obmat, me->bb)==0) return;
2057                 
2058                 
2059                 
2060                 if(dt==OB_SOLID ) {
2061                         
2062                         lb= &me->disp;
2063                         if(lb->first==0) addnormalsDispList(ob, lb);
2064                         
2065                         dl= lb->first;
2066                         if(dl==0) return;
2067
2068                         if(mesh_uses_displist(me)) {
2069                                 int vertexpaint= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0));
2070
2071                                         /* vertexpaint only true when selecting */
2072                                 if (vertexpaint) {
2073                                         drawmeshsolid(ob, NULL);
2074                                 } else {
2075                                         init_gl_materials(ob);
2076                                         two_sided(me->flag & ME_TWOSIDED);
2077                                         drawDispListsolid(lb, ob);
2078                                 }
2079                         }
2080                         else {
2081                                 drawmeshsolid(ob, dl->nors);
2082                         }
2083                         
2084                 }
2085                 else if(dt==OB_SHADED) {
2086                         if( G.f & G_WEIGHTPAINT && me->dvert) {
2087                                 unsigned char *wtcol, *curwt;
2088                                 MFace *curface;
2089                                 int i;
2090                                 unsigned char r,g,b;
2091                                 float val1,val2,val3,val4=0;
2092                                 
2093                                 wtcol = curwt= MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
2094                                 
2095                                 memset (wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
2096                                 for (i=0, curface=(MFace*)me->mface; i<me->totface; i++, curface++){
2097                                         
2098                                         val1 = get_mvert_weight (ob, curface->v1, ob->actdef-1);
2099                                         val2 = get_mvert_weight (ob, curface->v2, ob->actdef-1);
2100                                         val3 = get_mvert_weight (ob, curface->v3, ob->actdef-1);
2101                                         if (curface->v4)
2102                                                 val4 = get_mvert_weight (ob, curface->v4, ob->actdef-1);
2103                                         
2104                                         color_temperature (val1, &r, &g, &b);
2105                                         *curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r;
2106                                         color_temperature (val2, &r, &g, &b);
2107                                         *curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r;
2108                                         color_temperature (val3, &r, &g, &b);
2109                                         *curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r;
2110                                         color_temperature (val4, &r, &g, &b);
2111                                         *curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r;
2112                                         
2113                                 }
2114                                 
2115                                 drawmeshshaded(ob, (unsigned int*)wtcol, 0);
2116                                 
2117                                 MEM_freeN (wtcol);
2118                                 
2119                         }
2120                         else
2121
2122                         if( G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) {
2123                                 /* in order: vertexpaint already made mcol */
2124                                 if(me->mcol) {
2125                                         drawmeshshaded(ob, (unsigned int *)me->mcol, 0);
2126                                 } else if(me->tface) {
2127                                         tface_to_mcol(me);
2128                                         drawmeshshaded(ob, (unsigned int *)me->mcol, 0);        
2129                                         MEM_freeN(me->mcol); me->mcol= 0;
2130                                 }
2131                                 else 
2132                                         drawmeshwire(ob);
2133                                 
2134                         }
2135                         else {
2136                                 dl= ob->disp.first;
2137                                 
2138                                 if(dl==0 || dl->col1==0) {
2139                                         shadeDispList(ob);
2140                                         dl= ob->disp.first;
2141                                 }
2142                                 if(dl) {
2143                                         if(mesh_uses_displist(me)) {
2144                                                 drawDispListshaded(&me->disp, ob);
2145                                         } else {
2146                                                 drawmeshshaded(ob, dl->col1, dl->col2);
2147                                         }
2148                                 }
2149                         }
2150                 }
2151                 
2152                 if(ob==((G.scene->basact) ? (G.scene->basact->object) : 0) && (G.f & G_FACESELECT)) {
2153                         draw_tfaces3D(ob, me);
2154                 }
2155                 
2156                 break;
2157                 
2158         case OB_FONT:
2159         case OB_CURVE:
2160         
2161                 lb= &((Curve *)ob->data)->disp;
2162                 if(lb->first==0) makeDispList(ob);
2163                 
2164                 if(solid && ob!=G.obedit) {
2165                         dl= lb->first;
2166                         if(dl==0) return;
2167                         
2168                         /* rule: dl->type INDEX3 is always first in list */
2169                         if(dl->type!=DL_INDEX3) {
2170                                 curve_to_filledpoly(ob->data, lb);
2171                                 dl= lb->first;
2172                         }
2173                         if(dl->nors==0) addnormalsDispList(ob, lb);
2174                         
2175                         index3_nors_incr= 0;
2176                         
2177                         if(dt==OB_SHADED) {
2178                                 if(ob->disp.first==0) shadeDispList(ob);
2179                                 drawDispListshaded(lb, ob);
2180                         }
2181                         else {
2182                                 init_gl_materials(ob);
2183                                 two_sided(0);
2184                                 drawDispListsolid(lb, ob);
2185                         }
2186                         index3_nors_incr= 1;
2187                 }
2188                 else {
2189                         draw_index_wire= 0;
2190                         drawDispListwire(lb);
2191                         draw_index_wire= 1;
2192                 }
2193                 break;
2194         case OB_SURF:
2195         
2196                 lb= &((Curve *)ob->data)->disp;
2197                 if(lb->first==0) makeDispList(ob);
2198                 
2199                 if(solid) {
2200                         dl= lb->first;
2201                         if(dl==0) return;
2202                         
2203                         if(dl->nors==0) addnormalsDispList(ob, lb);
2204                         
2205                         if(dt==OB_SHADED) {
2206                                 if(ob->disp.first==0) shadeDispList(ob);
2207                                 drawDispListshaded(lb, ob);
2208                         }
2209                         else {
2210                                 init_gl_materials(ob);
2211                                 two_sided(0);
2212                         
2213                                 drawDispListsolid(lb, ob);
2214                         }
2215                 }
2216                 else {
2217                         drawDispListwire(lb);
2218                 }
2219                 break;
2220         case OB_MBALL:
2221                 
2222                 if( is_basis_mball(ob)) {
2223                         lb= &ob->disp;
2224                         if(lb->first==0) makeDispList(ob);
2225         
2226                         if(solid) {
2227                                 
2228                                 if(dt==OB_SHADED) {
2229                                         dl= lb->first;
2230                                         if(dl && dl->col1==0) shadeDispList(ob);
2231                                         drawDispListshaded(lb, ob);
2232                                 }
2233                                 else {
2234                                         init_gl_materials(ob);
2235                                         two_sided(0);
2236                                 
2237                                         drawDispListsolid(lb, ob);      
2238                                 }
2239                         }
2240                         else drawDispListwire(lb);
2241                 }
2242                 break;
2243         }
2244         
2245 }
2246
2247 /* ******************************** */
2248
2249
2250 static void draw_particle_system(Object *ob, PartEff *paf)
2251 {
2252         Particle *pa;
2253         float ptime, ctime, vec[3], vec1[3];
2254         int a;
2255         
2256         pa= paf->keys;
2257         if(pa==0) {
2258                 build_particle_system(ob);
2259                 pa= paf->keys;
2260                 if(pa==0) return;
2261         }
2262         
2263         myloadmatrix(G.vd->viewmat);
2264         
2265         if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
2266         else ptime= 0.0;
2267         ctime= bsystem_time(ob, 0, (float)(G.scene->r.cfra), ptime);
2268
2269         glPointSize(1.0);
2270         if(paf->stype!=PAF_VECT) glBegin(GL_POINTS);
2271
2272         for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
2273                 
2274                 if(ctime > pa->time) {
2275                         if(ctime < pa->time+pa->lifetime) {
2276                         
2277                                 if(paf->stype==PAF_VECT) {
2278                                         where_is_particle(paf, pa, ctime, vec);
2279                                         where_is_particle(paf, pa, ctime+1.0, vec1);
2280                 
2281
2282                                         glBegin(GL_LINE_STRIP);
2283                                                 glVertex3fv(vec);
2284                                                 glVertex3fv(vec1);
2285                                         glEnd();
2286                                         
2287                                 }
2288                                 else {
2289                                         where_is_particle(paf, pa, ctime, vec);
2290                                         
2291                                         glVertex3fv(vec);
2292                                                 
2293                                 }
2294                         }
2295                 }
2296         }
2297         if(paf->stype!=PAF_VECT) glEnd();
2298
2299 }
2300
2301 static void draw_static_particle_system(Object *ob, PartEff *paf)
2302 {
2303         Particle *pa;
2304         float ctime, mtime, vec[3], vec1[3];
2305         int a;
2306         
2307         pa= paf->keys;
2308         if(pa==0) {
2309                 build_particle_system(ob);
2310                 pa= paf->keys;
2311                 if(pa==0) return;
2312         }
2313         
2314         glPointSize(1.0);
2315         if(paf->stype!=PAF_VECT) glBegin(GL_POINTS);
2316
2317         for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
2318                 
2319                 where_is_particle(paf, pa, pa->time, vec1);
2320                 
2321                 mtime= pa->time+pa->lifetime+paf->staticstep-1;
2322                 
2323                 for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
2324                         
2325                         /* make sure hair grows until the end.. */ 
2326                         if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
2327                         
2328                         if(paf->stype==PAF_VECT) {
2329                                 where_is_particle(paf, pa, ctime+1, vec);
2330
2331                                 glBegin(GL_LINE_STRIP);
2332                                         glVertex3fv(vec);
2333                                         glVertex3fv(vec1);
2334                                 glEnd();
2335                                 
2336                                 VECCOPY(vec1, vec);
2337                         }
2338                         else {
2339                                 where_is_particle(paf, pa, ctime, vec);
2340                                 
2341                                 glVertex3fv(vec);
2342                                         
2343                         }
2344                 }
2345         }
2346         if(paf->stype!=PAF_VECT) glEnd();
2347
2348 }
2349
2350 static void drawmeshwire(Object *ob)
2351 {
2352         EditMesh *em = G.editMesh;
2353         extern float editbutsize;       /* buttons.c */
2354         Mesh *me;
2355         MVert *mvert;
2356         MFace *mface;
2357         DispList *dl;
2358         Material *ma;
2359         EditEdge *eed;
2360         EditVlak *evl;
2361         float fvec[3], cent[3], *f1, *f2, *f3, *f4, *extverts=NULL;
2362         int a, start, end, test, ok, handles=0;
2363
2364         me= get_mesh(ob);
2365
2366         if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) {
2367                 
2368                 if( (me->flag & ME_OPT_EDGES) && (me->flag & ME_SUBSURF) && me->subdiv) handles= 1;
2369                 
2370                 if(handles==0 && (G.f & (G_FACESELECT+G_DRAWFACES))) {  /* faces */
2371                         char col1[4], col2[4];
2372                         
2373                         BIF_GetThemeColor4ubv(TH_FACE, col1);
2374                         BIF_GetThemeColor4ubv(TH_FACE_SELECT, col2);
2375                         
2376                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2377                         glEnable(GL_BLEND);
2378                         glDepthMask(0);         // disable write in zbuffer, needed for nice transp
2379                         
2380                         evl= em->faces.first;
2381                         while(evl) {
2382                                 if(evl->v1->h==0 && evl->v2->h==0 && evl->v3->h==0 && (evl->v4==NULL || evl->v4->h==0)) {
2383                                         
2384                                         if(1) {
2385                                                 if(vlakselectedAND(evl, 1)) glColor4ub(col2[0], col2[1], col2[2], col2[3]); 
2386                                                 else glColor4ub(col1[0], col1[1], col1[2], col1[3]);
2387                                                 
2388                                                 glBegin(evl->v4?GL_QUADS:GL_TRIANGLES);
2389                                                 glVertex3fv(evl->v1->co);
2390                                                 glVertex3fv(evl->v2->co);
2391                                                 glVertex3fv(evl->v3->co);
2392                                                 if(evl->v4) glVertex3fv(evl->v4->co);
2393                                                 glEnd();
2394                                                 
2395                                         } else {
2396                                                 if(vlakselectedAND(evl, 1)) glColor4ub(col2[0], col2[1], col2[2], col2[3]); 
2397                                                 else glColor4ub(col1[0], col1[1], col1[2], col1[3]);
2398                                         
2399                                                 if(evl->v4 && evl->v4->h==0) {
2400                                                 
2401                                                         CalcCent4f(cent, evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co);
2402                                                         glBegin(GL_QUADS);
2403                                                                 VecMidf(fvec, cent, evl->v1->co); glVertex3fv(fvec);
2404                                                                 VecMidf(fvec, cent, evl->v2->co); glVertex3fv(fvec);
2405                                                                 VecMidf(fvec, cent, evl->v3->co); glVertex3fv(fvec);
2406                                                                 VecMidf(fvec, cent, evl->v4->co); glVertex3fv(fvec);
2407                                                         glEnd();
2408                                                 }
2409                                                 else {
2410         
2411                                                         CalcCent3f(cent, evl->v1->co, evl->v2->co, evl->v3->co);
2412                                                         glBegin(GL_TRIANGLES);
2413                                                                 VecMidf(fvec, cent, evl->v1->co); glVertex3fv(fvec);
2414                                                                 VecMidf(fvec, cent, evl->v2->co); glVertex3fv(fvec);
2415                                                                 VecMidf(fvec, cent, evl->v3->co); glVertex3fv(fvec);
2416                                                         glEnd();
2417                                                 }
2418                                         }
2419                                 }
2420                                 evl= evl->next;
2421                         }
2422                         glDisable(GL_BLEND);
2423                         glDepthMask(1);         // restore write in zbuffer
2424                 }
2425
2426                 if(mesh_uses_displist(me)) {
2427                         /* dont draw the subsurf when solid... then this is a 'drawextra' */
2428                         if(handles==0 && ob->dt>OB_WIRE && G.vd->drawtype>OB_WIRE);
2429                         else {
2430                                 if(handles) BIF_ThemeColor(TH_WIRE);
2431                                 else BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7);
2432                                         
2433                                 drawDispListwire(&me->disp);
2434                         }
2435                 }
2436                 
2437                 if(handles==0 && (G.f & G_DRAWCREASES)) {       /* Use crease edge Highlighting */
2438
2439                         eed= em->edges.first;
2440                         glBegin(GL_LINES);
2441                         while(eed) {
2442                                 if(eed->h==0) {
2443                                         BIF_ThemeColorBlend(TH_WIRE, TH_EDGE_SELECT, eed->crease);
2444                                         glVertex3fv(eed->v1->co);
2445                                         glVertex3fv(eed->v2->co);
2446                                 }
2447                                 eed= eed->next;
2448                         }
2449                         glEnd();
2450                 }
2451                 else if(handles==0 && (G.f & G_DRAWEDGES)) {    /* Use edge Highlighting */
2452                         char col[4], colhi[4];
2453                         
2454                         BIF_GetThemeColor3ubv(TH_EDGE_SELECT, colhi);
2455                         BIF_GetThemeColor3ubv(TH_WIRE, col);
2456
2457                         glShadeModel(GL_SMOOTH);
2458
2459                         eed= em->edges.first;
2460                         glBegin(GL_LINES);
2461                         while(eed) {
2462                                 if(eed->h==0) {
2463                                 
2464                                         if(eed->v1->f & 1) glColor3ub(colhi[0], colhi[1], colhi[2]);
2465                                         else glColor3ub(col[0], col[1], col[2]);
2466                                 
2467                                         glVertex3fv(eed->v1->co);
2468                                         
2469                                         if(eed->v2->f & 1) glColor3ub(colhi[0], colhi[1], colhi[2]);
2470                                         else glColor3ub(col[0], col[1], col[2]);
2471
2472                                         glVertex3fv(eed->v2->co);
2473                                 }
2474                                 eed= eed->next;
2475                         }
2476                         glEnd();
2477                         glShadeModel(GL_FLAT);
2478                 }
2479                 else if(handles==0) {
2480                         BIF_ThemeColor(TH_WIRE);
2481                         eed= em->edges.first;
2482                         glBegin(GL_LINES);
2483                         while(eed) {
2484                                 if(eed->h==0) {
2485                                         glVertex3fv(eed->v1->co);
2486                                         glVertex3fv(eed->v2->co);
2487                                 }
2488                                 eed= eed->next;
2489                         }
2490                         glEnd();
2491                 }
2492                 if(ob!=G.obedit) return;
2493                 
2494                 calc_meshverts();
2495
2496                 tekenvertices(0);
2497                 tekenvertices(1);
2498
2499                 if(G.f & G_DRAWNORMALS) {       /* normals */
2500                         cpack(0xDDDD22);
2501
2502                         glBegin(GL_LINES);
2503                         
2504                         evl= em->faces.first;
2505                         while(evl) {
2506                                 if(evl->v1->h==0 && evl->v2->h==0 && evl->v3->h==0) {
2507                                         if(evl->v4) CalcCent4f(fvec, evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co);
2508                                         else CalcCent3f(fvec, evl->v1->co, evl->v2->co, evl->v3->co);
2509
2510                                         glVertex3fv(fvec);
2511                                         fvec[0]+= editbutsize*evl->n[0];
2512                                         fvec[1]+= editbutsize*evl->n[1];
2513                                         fvec[2]+= editbutsize*evl->n[2];
2514                                         glVertex3fv(fvec);
2515                                         
2516                                 }
2517                                 evl= evl->next;
2518                         }
2519
2520                         glEnd();
2521                 }
2522         }
2523         else { /* Object mode draw */
2524                 
2525                 if(me==NULL) return;
2526                 
2527                 if(me->bb==NULL) tex_space_mesh(me);
2528                 if(me->totface>4) if(boundbox_clip(ob->obmat, me->bb)==0) return;
2529                 
2530                 /* check for drawing vertices only */
2531                 ok= 0;
2532                 if(me->totface==0 && me->totedge==0) ok= 1;
2533                 else {
2534                         ma= give_current_material(ob, 1);
2535                         if(ma && (ma->mode & MA_HALO)) ok= 1;
2536                 }
2537                 mvert= me->mvert;
2538                 mface= me->mface;
2539                 
2540                 dl= find_displist(&ob->disp, DL_VERTS);
2541                 if(dl) extverts= dl->verts;
2542                                         
2543                 if(ok) {
2544                         start= 0; end= me->totvert;
2545                         set_buildvars(ob, &start, &end);
2546                         
2547                         glPointSize(1.5);
2548                         glBegin(GL_POINTS);
2549                 
2550                         if(extverts) {
2551                                 extverts+= 3*start;
2552                                 for(a= start; a<end; a++, extverts+=3) { /* DispList found, Draw displist */
2553                                         glVertex3fv(extverts);
2554                                 }
2555                         }
2556                         else {
2557                                 mvert+= start;
2558                                 for(a= start; a<end; a++, mvert++) { /* else Draw mesh verts directly */
2559                                         glVertex3fv(mvert->co);
2560                                 }
2561                         }
2562                         glEnd();
2563                         glPointSize(1.0);
2564                 }
2565                 else {
2566         
2567                         if(mesh_uses_displist(me)) drawDispListwire(&me->disp); /* Subsurf */
2568                         else {
2569                                 
2570                                 /* build effect only works on faces */
2571                                 start= 0; end= me->totface;
2572                                 set_buildvars(ob, &start, &end);
2573                                 mface+= start;
2574                                 
2575                                 /* now decide whether to draw edges block */
2576                                 if(me->medge && start==0 && end==me->totface) {
2577                                         MEdge *medge= me->medge;
2578                                         
2579                                         glBegin(GL_LINES);
2580                                         for(a=me->totedge; a>0; a--, medge++) {
2581                                                 if(medge->flag & ME_EDGEDRAW) {
2582                                                         if(extverts) {
2583                                                                 f1= extverts+3*medge->v1;
2584                                                                 f2= extverts+3*medge->v2;
2585                                                         }
2586                                                         else {
2587                                                                 f1= (mvert+medge->v1)->co;
2588                                                                 f2= (mvert+medge->v2)->co;
2589                                                         }
2590                                                         glVertex3fv(f1); glVertex3fv(f2); 
2591                                                 }
2592                                         }
2593                                         glEnd();
2594                                 }
2595                                 else {
2596                                 
2597                                         for(a=start; a<end; a++, mface++) {
2598                                                 test= mface->edcode;
2599                                                 
2600                                                 if(test) {
2601                                                         if(extverts) {
2602                                                                 f1= extverts+3*mface->v1;
2603                                                                 f2= extverts+3*mface->v2;
2604                                                         }
2605                                                         else {
2606                                                                 f1= (mvert+mface->v1)->co;
2607                                                                 f2= (mvert+mface->v2)->co;
2608                                                         }
2609                                                         
2610                                                         if(mface->v4) {
2611                                                                 if(extverts) {
2612                                                                         f3= extverts+3*mface->v3;
2613                                                                         f4= extverts+3*mface->v4;
2614                                                                 }
2615                                                                 else {
2616                                                                         f3= (mvert+mface->v3)->co;
2617                                                                         f4= (mvert+mface->v4)->co;
2618                                                                 }
2619                                                                 
2620                                                                 if(test== ME_V1V2+ME_V2V3+ME_V3V4+ME_V4V1) {
2621                                                                         glBegin(GL_LINE_LOOP);
2622                                                                                 glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f4);
2623                                                                         glEnd();
2624                                                                 }
2625                                                                 else if(test== ME_V1V2+ME_V2V3+ME_V3V4) {
2626                 
2627                                                                         glBegin(GL_LINE_STRIP);
2628                                                                                 glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f4);
2629                                                                         glEnd();
2630                                                                 }
2631                                                                 else if(test== ME_V2V3+ME_V3V4+ME_V4V1) {
2632                 
2633                                                                         glBegin(GL_LINE_STRIP);
2634                                                                                 glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f4); glVertex3fv(f1);
2635                                                                         glEnd();
2636                                                                 }
2637                                                                 else if(test== ME_V3V4+ME_V4V1+ME_V1V2) {
2638                 
2639                                                                         glBegin(GL_LINE_STRIP);
2640                                                                                 glVertex3fv(f3); glVertex3fv(f4); glVertex3fv(f1); glVertex3fv(f2);
2641                                                                         glEnd();
2642                                                                 }
2643                                                                 else if(test== ME_V4V1+ME_V1V2+ME_V2V3) {
2644                 
2645                                                                         glBegin(GL_LINE_STRIP);
2646                                                                                 glVertex3fv(f4); glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3);
2647                                                                         glEnd();
2648                                                                 }
2649                                                                 else {
2650                                                                         if(test & ME_V1V2) {
2651                 
2652                                                                                 glBegin(GL_LINE_STRIP);
2653                                                                                         glVertex3fv(f1); glVertex3fv(f2);
2654                                                                                 glEnd();
2655                                                                         }
2656                                                                         if(test & ME_V2V3) {
2657                 
2658                                                                                 glBegin(GL_LINE_STRIP);
2659                                                                                         glVertex3fv(f2); glVertex3fv(f3);
2660                                                                                 glEnd();
2661                                                                         }
2662                                                                         if(test & ME_V3V4) {
2663                 
2664                                                                                 glBegin(GL_LINE_STRIP);
2665                                                                                         glVertex3fv(f3); glVertex3fv(f4);
2666                                                                                 glEnd();
2667                                                                         }
2668                                                                         if(test & ME_V4V1) {
2669                 
2670                                                                                 glBegin(GL_LINE_STRIP);
2671                                                                                         glVertex3fv(f4); glVertex3fv(f1);
2672                                                                                 glEnd();
2673                                                                         }
2674                                                                 }
2675                                                         }
2676                                                         else if(mface->v3) {
2677                                                                 if(extverts) f3= extverts+3*mface->v3;
2678                                                                 else f3= (mvert+mface->v3)->co;
2679                         
2680                                                                 if(test== ME_V1V2+ME_V2V3+ME_V3V1) {
2681                                                                         glBegin(GL_LINE_LOOP);
2682                                                                                 glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3);
2683                                                                         glEnd();
2684                                                                 }
2685                                                                 else if(test== ME_V1V2+ME_V2V3) {
2686                 
2687                                                                         glBegin(GL_LINE_STRIP);
2688                                                                                 glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3);
2689                                                                         glEnd();
2690                                                                 }
2691                                                                 else if(test== ME_V2V3+ME_V3V1) {
2692                 
2693                                                                         glBegin(GL_LINE_STRIP);
2694                                                                                 glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f1);
2695                                                                         glEnd();
2696                                                                 }
2697                                                                 else if(test== ME_V1V2+ME_V3V1) {
2698                 
2699                                                                         glBegin(GL_LINE_STRIP);
2700                                                                                 glVertex3fv(f3); glVertex3fv(f1); glVertex3fv(f2);
2701                                                                         glEnd();
2702                                                                 }
2703                                                                 else {
2704                                                                         if(test & ME_V1V2) {
2705                 
2706                                                                                 glBegin(GL_LINE_STRIP);
2707                                                                                         glVertex3fv(f1); glVertex3fv(f2);
2708                                                                                 glEnd();
2709                                                                         }
2710                                                                         if(test & ME_V2V3) {
2711                 
2712                                                                                 glBegin(GL_LINE_STRIP);
2713                                                                                         glVertex3fv(f2); glVertex3fv(f3);
2714                                                                                 glEnd();
2715                                                                         }
2716                                                                         if(test & ME_V3V1) {
2717                 
2718                                                                                 glBegin(GL_LINE_STRIP);
2719                                                                                         glVertex3fv(f3); glVertex3fv(f1);
2720                                                                                 glEnd();
2721                                                                         }
2722                                                                 }
2723                                                         }
2724                                                         else if(test & ME_V1V2) {
2725                 
2726                                                                 glBegin(GL_LINE_STRIP);
2727                                                                         glVertex3fv(f1); glVertex3fv(f2);
2728                                                                 glEnd();
2729                                                         }
2730                                                 }
2731                                         }
2732                                 }
2733                         }
2734                 }
2735         }
2736 }
2737
2738 unsigned int nurbcol[8]= {
2739         0, 0x9090, 0x409030, 0x603080, 0, 0x40fff0, 0x40c033, 0xA090F0 };
2740
2741 static void tekenhandlesN(Nurb *nu, short sel)
2742 {
2743         BezTriple *bezt;
2744         float *fp;
2745         unsigned int *col;
2746         int a;
2747
2748         if(nu->hide) return;
2749         if( (nu->type & 7)==1) {
2750                 if(sel) col= nurbcol+4;
2751                 else col= nurbcol;
2752
2753                 bezt= nu->bezt;
2754                 a= nu->pntsu;
2755                 while(a--) {
2756                         if(bezt->hide==0) {
2757                                 if( (bezt->f2 & 1)==sel) {
2758                                         fp= bezt->vec[0];
2759                                         cpack(col[bezt->h1]);
2760
2761                                         glBegin(GL_LINE_STRIP); 
2762                                         glVertex3fv(fp);
2763                                         glVertex3fv(fp+3); 
2764                                         glEnd();
2765                                         cpack(col[bezt->h2]);
2766
2767                                         glBegin(GL_LINE_STRIP); 
2768                                         glVertex3fv(fp+3); 
2769                                         glVertex3fv(fp+6); 
2770                                         glEnd();
2771                                 }
2772                                 else if( (bezt->f1 & 1)==sel) {
2773                                         fp= bezt->vec[0];
2774                                         cpack(col[bezt->h1]);
2775
2776                                         glBegin(GL_LINE_STRIP); 
2777                                         glVertex3fv(fp); 
2778                                         glVertex3fv(fp+3); 
2779                                         glEnd();
2780                                 }
2781                                 else if( (bezt->f3 & 1)==sel) {
2782                                         fp= bezt->vec[1];
2783                                         cpack(col[bezt->h2]);
2784
2785                                         glBegin(GL_LINE_STRIP); 
2786                                         glVertex3fv(fp); 
2787                                         glVertex3fv(fp+3); 
2788                                         glEnd();
2789                                 }
2790                         }
2791                         bezt++;
2792                 }
2793         }
2794 }
2795
2796 static void tekenvertsN(Nurb *nu, short sel)
2797 {
2798         BezTriple *bezt;
2799         BPoint *bp;
2800         float size;
2801         int a;
2802
2803         if(nu->hide) return;
2804
2805         if(sel) BIF_ThemeColor(TH_VERTEX_SELECT);
2806         else BIF_ThemeColor(TH_VERTEX);
2807
2808         size= BIF_GetThemeValuef(TH_VERTEX_SIZE);
2809         glPointSize(size);
2810         
2811         glBegin(GL_POINTS);
2812         
2813         if((nu->type & 7)==1) {
2814
2815                 bezt= nu->bezt;
2816                 a= nu->pntsu;
2817                 while(a--) {
2818                         if(bezt->hide==0) {
2819                                 if((bezt->f1 & 1)==sel) glVertex3fv(bezt->vec[0]);
2820                                 if((bezt->f2 & 1)==sel) glVertex3fv(bezt->vec[1]);
2821                                 if((bezt->f3 & 1)==sel) glVertex3fv(bezt->vec[2]);
2822                         }
2823                         bezt++;
2824                 }
2825         }
2826         else {
2827                 bp= nu->bp;
2828                 a= nu->pntsu*nu->pntsv;
2829                 while(a--) {
2830                         if(bp->hide==0) {
2831                                 if((bp->f1 & 1)==sel) glVertex3fv(bp->vec);
2832                         }
2833                         bp++;
2834                 }
2835         }
2836         
2837         glEnd();
2838         glPointSize(1.0);
2839 }
2840
2841 static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
2842 {
2843         Nurb *nu;
2844         BPoint *bp, *bp1;
2845         int a, b, ofs;
2846         
2847         nu= nurb;
2848         while(nu) {
2849                 if(nu->hide==0) {
2850                         switch(nu->type & 7) {
2851                         case CU_POLY:
2852                                 cpack(nurbcol[3]);
2853                                 bp= nu->bp;
2854                                 for(b=0; b<nu->pntsv; b++) {
2855                                         if(nu->flagu & 1) glBegin(GL_LINE_LOOP);
2856
2857                                         else glBegin(GL_LINE_STRIP);
2858
2859                                         for(a=0; a<nu->pntsu; a++, bp++) {
2860                                                 glVertex3fv(bp->vec);
2861                                         }
2862
2863                                         if(nu->flagu & 1) glEnd();
2864                                         else glEnd();
2865                                 }
2866                                 break;
2867                         case CU_NURBS:
2868
<