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