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