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