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