a59de393942205dac9a018acbec16a05b0b53872
[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         }
1723         else {
1724
1725                 start= 0; end= me->totface;
1726                 set_buildvars(ob, &start, &end);
1727                 mface+= start;
1728                 if(tface) tface+= start;
1729                 
1730                 dl= find_displist(&ob->disp, DL_VERTS);
1731                 if(dl) extverts= dl->verts;
1732         
1733                 glBegin(GL_QUADS);
1734                 glmode= GL_QUADS;
1735                 
1736                 for(a=start; a<end; a++, mface++, nors+=3) {
1737                         if(mface->v3) {
1738                                 if(tface && (tface->flag & TF_HIDE)) {
1739                                         if( (G.f & G_BACKBUFSEL)==0) {
1740                                                 glBegin(GL_LINE_LOOP);
1741                                                 glVertex3fv( (mvert+mface->v1)->co);
1742                                                 glVertex3fv( (mvert+mface->v2)->co);
1743                                                 glVertex3fv( (mvert+mface->v3)->co);
1744                                                 if(mface->v4) glVertex3fv( (mvert+mface->v1)->co);
1745                                                 glEnd();
1746                                                 tface++;
1747                                         }
1748                                 }
1749                                 else {
1750                                         if(extverts) {
1751                                                 v1= extverts+3*mface->v1;
1752                                                 v2= extverts+3*mface->v2;
1753                                                 v3= extverts+3*mface->v3;
1754                                                 if(mface->v4) v4= extverts+3*mface->v4;
1755                                                 else v4= 0;
1756                                         }
1757                                         else {
1758                                                 v1= (mvert+mface->v1)->co;
1759                                                 v2= (mvert+mface->v2)->co;
1760                                                 v3= (mvert+mface->v3)->co;
1761                                                 if(mface->v4) v4= (mvert+mface->v4)->co;
1762                                                 else v4= 0;
1763                                         }
1764                                         
1765                                         
1766                                         if(tface) {
1767                                                 if(tface->mode & TF_TWOSIDE) glEnable(GL_CULL_FACE);
1768                                                 else glDisable(GL_CULL_FACE);
1769                                         }
1770                                         
1771         
1772                                         /* dit GL_QUADS grapje is op snelheid getest: factor 2! */
1773                                                 
1774                                         if(v4) {if(glmode==GL_TRIANGLES) {glmode= GL_QUADS; glEnd(); glBegin(GL_QUADS);}}
1775                                         else {if(glmode==GL_QUADS) {glmode= GL_TRIANGLES; glEnd(); glBegin(GL_TRIANGLES);}}
1776                                                 
1777                                         if(G.f & G_BACKBUFSEL) {
1778                                                 if(vertexpaint) {
1779                                                         i= index_to_framebuffer(a+1);
1780                                                         cpack(i);
1781                                                 }
1782         
1783                                                 glVertex3fv( v1 );
1784                                                 glVertex3fv( v2 );
1785                                                 glVertex3fv( v3 );
1786                                                 if(v4) glVertex3fv( v4 );
1787                                                 
1788                                         }
1789                                         else {
1790                                                 
1791                                                 if(mface->mat_nr!=matnr) {
1792                                                         matnr= mface->mat_nr;
1793                                                         set_gl_material(matnr+1);
1794                                                 }
1795         
1796                                                 if( (me->flag & ME_AUTOSMOOTH)==0 && (mface->flag & ME_SMOOTH)) {
1797                                                         if(setsmooth==0) {
1798                                                                 glEnd();
1799                                                                 glShadeModel(GL_SMOOTH);
1800                                                                 if(glmode==GL_TRIANGLES) glBegin(GL_TRIANGLES);
1801                                                                 else glBegin(GL_QUADS);
1802                                                                 setsmooth= 1;
1803                                                         }
1804                                                         n1= (mvert+mface->v1)->no;
1805                                                         n2= (mvert+mface->v2)->no;
1806                                                         n3= (mvert+mface->v3)->no;
1807                                                         if(v4) n4= (mvert+mface->v4)->no;
1808                                                 
1809                                                         if(mface->puno & ME_FLIPV1) {
1810                                                                 no[0]= -n1[0]; no[1]= -n1[1]; no[2]= -n1[2];
1811                                                                 glNormal3sv(no);
1812                                                         }
1813                                                         else glNormal3sv(n1);
1814                                                         glVertex3fv( v1 );
1815                                                         
1816                                                         if(mface->puno & ME_FLIPV2) {
1817                                                                 no[0]= -n2[0]; no[1]= -n2[1]; no[2]= -n2[2];
1818                                                                 glNormal3sv(no);
1819                                                         }
1820                                                         else glNormal3sv(n2);
1821                                                         glVertex3fv( v2 );
1822                                                         
1823                                                         if(mface->puno & ME_FLIPV3) {
1824                                                                 no[0]= -n3[0]; no[1]= -n3[1]; no[2]= -n3[2];
1825                                                                 glNormal3sv(no);
1826                                                         }
1827                                                         else glNormal3sv(n3);
1828                                                         glVertex3fv( v3 );
1829                                                         
1830                                                         if(v4) {
1831                                                                 if(mface->puno & ME_FLIPV4) {
1832                                                                         no[0]= -n4[0]; no[1]= -n4[1]; no[2]= -n4[2];
1833                                                                         glNormal3sv(no);
1834                                                                 }
1835                                                                 else glNormal3sv(n4);
1836                                                                 glVertex3fv( v4 );
1837                                                         }
1838                                                 }
1839                                                 else {
1840                                                         if(setsmooth==1) {
1841                                                                 glEnd();
1842                                                                 glShadeModel(GL_FLAT);
1843                                                                 if(glmode==GL_TRIANGLES) glBegin(GL_TRIANGLES);
1844                                                                 else glBegin(GL_QUADS);
1845                                                                 setsmooth= 0;
1846                                                         }
1847                                                         glNormal3fv(nors);
1848                                                         glVertex3fv( v1 );
1849                                                         glVertex3fv( v2 );
1850                                                         glVertex3fv( v3 );
1851                                                         if(v4) glVertex3fv( v4 );
1852                                                 }
1853                                         }
1854                                 }
1855                                 if(tface) tface++;
1856                         }
1857                 }
1858                 
1859                 glEnd();
1860         }
1861         
1862         /* SOLVE */
1863 /*      if ELEM(ob->type, OB_SECTOR, OB_LIFE) glDisable(GL_CULL_FACE); */
1864
1865         if(G.f & G_BACKBUFSEL) {
1866                 glDisable(GL_CULL_FACE);
1867         }
1868         glDisable(GL_LIGHTING);
1869
1870 }
1871
1872 static void drawmeshshaded(Object *ob, unsigned int *col1, unsigned int *col2)
1873 {
1874         Mesh *me;
1875         MVert *mvert;
1876         MFace *mface;
1877         TFace *tface;
1878         DispList *dl;
1879         float *extverts=0, *v1, *v2, *v3, *v4;
1880         int a, start, end, twoside;
1881         char *cp1, *cp2 = NULL;
1882         int lglmode;
1883         
1884         glShadeModel(GL_SMOOTH);
1885         glDisable(GL_LIGHTING);
1886
1887         me= ob->data;
1888         mface= me->mface;
1889         
1890         /* tekent ie geen hide */
1891         if( (G.f & G_FACESELECT) && ob==((G.scene->basact) ? (G.scene->basact->object) : 0)) tface= me->tface;
1892         else tface= 0;
1893         
1894         mvert= me->mvert;
1895         a= me->totface;
1896         
1897         twoside= me->flag & ME_TWOSIDED;
1898         if(col2==0) twoside= 0;
1899         
1900         if(twoside) glEnable(GL_CULL_FACE);
1901         
1902         start= 0; end= me->totface;
1903         set_buildvars(ob, &start, &end);
1904         mface+= start;
1905         if(tface) tface+= start;
1906         col1+= 4*start;
1907         if(col2) col2+= 4*start;
1908         
1909         dl= find_displist(&ob->disp, DL_VERTS);
1910         if(dl) extverts= dl->verts;
1911
1912         glBegin(lglmode= GL_QUADS);
1913         
1914         cp1= (char *)col1;
1915         if(col2) cp2= (char *)col2;
1916
1917         for(a=start; a<end; a++, mface++, cp1+= 16) {
1918                 if(mface->v3) {
1919                         if(tface && (tface->flag & TF_HIDE)) tface++;
1920                         else {
1921                                 int nglmode= mface->v4?GL_QUADS:GL_TRIANGLES;
1922                                 
1923                                 if (nglmode!=lglmode) {
1924                                         glEnd();
1925                                         glBegin(lglmode= nglmode);
1926                                 }
1927                                 
1928                                 if(extverts) {
1929                                         v1= extverts+3*mface->v1;
1930                                         v2= extverts+3*mface->v2;
1931                                         v3= extverts+3*mface->v3;
1932                                         if(mface->v4) v4= extverts+3*mface->v4;
1933                                         else v4= 0;
1934                                 }
1935                                 else {
1936                                         v1= (mvert+mface->v1)->co;
1937                                         v2= (mvert+mface->v2)->co;
1938                                         v3= (mvert+mface->v3)->co;
1939                                         if(mface->v4) v4= (mvert+mface->v4)->co;
1940                                         else v4= 0;
1941                                 }
1942
1943                                 if(tface) {
1944                                         if(tface->mode & TF_TWOSIDE) glEnable(GL_CULL_FACE);
1945                                         else glDisable(GL_CULL_FACE);
1946                                 }
1947                                 
1948                                 glColor3ub(cp1[3], cp1[2], cp1[1]);
1949                                 glVertex3fv( v1 );
1950                                 glColor3ub(cp1[7], cp1[6], cp1[5]);
1951                                 glVertex3fv( v2 );
1952                                 glColor3ub(cp1[11], cp1[10], cp1[9]);
1953                                 glVertex3fv( v3 );
1954                                 if(v4) {
1955                                         glColor3ub(cp1[15], cp1[14], cp1[13]);
1956                                         glVertex3fv( v4 );
1957                                 }
1958                                 
1959                                 if(twoside) {
1960
1961                                         glColor3ub(cp2[11], cp2[10], cp2[9]);
1962                                         glVertex3fv( v3 );
1963                                         glColor3ub(cp2[7], cp2[6], cp2[5]);
1964                                         glVertex3fv( v2 );
1965                                         glColor3ub(cp2[3], cp2[2], cp2[1]);
1966                                         glVertex3fv( v1 );
1967                                         if(mface->v4) {
1968                                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
1969                                                 glVertex3fv( v4 );
1970                                         }
1971                                 }
1972                         }
1973                 }
1974                 if(col2) cp2+= 16;
1975         }
1976         
1977         glEnd();
1978         glShadeModel(GL_FLAT);
1979         if(twoside) glDisable(GL_CULL_FACE);
1980         
1981 }
1982
1983 static void drawDispList(Object *ob, int dt)
1984 {
1985         ListBase *lb=0;
1986         DispList *dl;
1987         Mesh *me;
1988         int solid;
1989
1990         
1991         solid= (dt > OB_WIRE);
1992
1993         switch(ob->type) {
1994         case OB_MESH:
1995                 
1996                 me= get_mesh(ob);
1997                 if(me==0) return;
1998                 
1999                 if(me->bb==0) tex_space_mesh(me);
2000                 if(me->totface>4) if(boundbox_clip(ob->obmat, me->bb)==0) return;
2001                 
2002                 
2003                 
2004                 if(dt==OB_SOLID ) {
2005                         
2006                         lb= &me->disp;
2007                         if(lb->first==0) addnormalsDispList(ob, lb);
2008                         
2009                         dl= lb->first;
2010                         if(dl==0) return;
2011
2012                         if(mesh_uses_displist(me)) {
2013                                 int vertexpaint= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0));
2014
2015                                         /* vertexpaint only true when selecting */
2016                                 if (vertexpaint)
2017                                         drawmeshsolid(ob, NULL);
2018                                 else {
2019                                         init_gl_materials(ob);
2020                                         two_sided(me->flag & ME_TWOSIDED);
2021                                         drawDispListsolid(lb, ob);
2022                                 }
2023                         }
2024                         else drawmeshsolid(ob, dl->nors);
2025                         
2026                 }
2027                 else if(dt==OB_SHADED) {
2028 #ifdef __NLA
2029                         if( G.f & G_WEIGHTPAINT && me->dvert) {
2030                                 unsigned char *wtcol, *curwt;
2031                                 MFace *curface;
2032                                 int i;
2033                                 unsigned char r,g,b;
2034                                 float val1,val2,val3,val4;
2035                                 
2036                                 wtcol = curwt= MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
2037                                 
2038                                 memset (wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
2039                                 for (i=0, curface=(MFace*)me->mface; i<me->totface; i++, curface++){
2040                                         
2041                                         val1 = get_mvert_weight (ob, curface->v1, ob->actdef-1);
2042                                         val2 = get_mvert_weight (ob, curface->v2, ob->actdef-1);
2043                                         val3 = get_mvert_weight (ob, curface->v3, ob->actdef-1);
2044                                         if (curface->v4)
2045                                                 val4 = get_mvert_weight (ob, curface->v4, ob->actdef-1);
2046                                         
2047                                         color_temperature (val1, &r, &g, &b);
2048                                         *curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r;
2049                                         color_temperature (val2, &r, &g, &b);
2050                                         *curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r;
2051                                         color_temperature (val3, &r, &g, &b);
2052                                         *curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r;
2053                                         color_temperature (val4, &r, &g, &b);
2054                                         *curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r;
2055                                         
2056                                 }
2057                                 
2058                                 drawmeshshaded(ob, (unsigned int*)wtcol, 0);
2059                                 MEM_freeN (wtcol);
2060                                 
2061                         }
2062                         else
2063 #endif
2064                         if( G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) {
2065                                 /* in deze volgorde: vertexpaint heeft soms al mcol gemaakt */
2066 ///*
2067
2068 //*/
2069                                 if(me->mcol)
2070                                         drawmeshshaded(ob, (unsigned int *)me->mcol, 0);
2071                                 else if(me->tface) {
2072                                         tface_to_mcol(me);
2073                                         drawmeshshaded(ob, (unsigned int *)me->mcol, 0);
2074                                         MEM_freeN(me->mcol); me->mcol= 0;
2075                                 }
2076                                 else 
2077                                         drawmeshwire(ob);
2078                                 
2079                         }
2080                         else {
2081                                 dl= ob->disp.first;
2082                                 
2083                                 if(dl==0 || dl->col1==0) {
2084                                         shadeDispList(ob);
2085                                         dl= ob->disp.first;
2086                                 }
2087                                 if(dl) {
2088                                         if(mesh_uses_displist(me)) 
2089                                                 drawDispListshaded(&me->disp, ob);
2090                                         else 
2091                                                 drawmeshshaded(ob, dl->col1, dl->col2);
2092                                 }
2093                         }
2094                 }
2095                 
2096                 if(ob==((G.scene->basact) ? (G.scene->basact->object) : 0) && (G.f & G_FACESELECT)) {
2097                         draw_tfaces3D(ob, me);
2098                 }
2099                 
2100                 break;
2101                 
2102         case OB_FONT:
2103         case OB_CURVE:
2104         
2105                 lb= &((Curve *)ob->data)->disp;
2106                 if(lb->first==0) makeDispList(ob);
2107                 
2108                 if(solid && ob!=G.obedit) {
2109                         dl= lb->first;
2110                         if(dl==0) return;
2111                         
2112                         /* regel: dl->type INDEX3 altijd vooraan in lijst */
2113                         if(dl->type!=DL_INDEX3) {
2114                                 curve_to_filledpoly(ob->data, lb);
2115                                 dl= lb->first;
2116                         }
2117                         if(dl->nors==0) addnormalsDispList(ob, lb);
2118                         
2119                         index3_nors_incr= 0;
2120                         
2121                         if(dt==OB_SHADED) {
2122                                 if(ob->disp.first==0) shadeDispList(ob);
2123                                 drawDispListshaded(lb, ob);
2124                         }
2125                         else {
2126                                 init_gl_materials(ob);
2127                                 two_sided(0);
2128                                 drawDispListsolid(lb, ob);
2129                         }
2130                         index3_nors_incr= 1;
2131                 }
2132                 else {
2133                         draw_index_wire= 0;
2134                         drawDispListwire(lb);
2135                         draw_index_wire= 1;
2136                 }
2137                 break;
2138         case OB_SURF:
2139         
2140                 lb= &((Curve *)ob->data)->disp;
2141                 if(lb->first==0) makeDispList(ob);
2142                 
2143                 if(solid) {
2144                         dl= lb->first;
2145                         if(dl==0) return;
2146                         
2147                         if(dl->nors==0) addnormalsDispList(ob, lb);
2148                         
2149                         if(dt==OB_SHADED) {
2150                                 if(ob->disp.first==0) shadeDispList(ob);
2151                                 drawDispListshaded(lb, ob);
2152                         }
2153                         else {
2154                                 init_gl_materials(ob);
2155                                 two_sided(0);
2156                         
2157                                 drawDispListsolid(lb, ob);
2158                         }
2159                 }
2160                 else {
2161                         drawDispListwire(lb);
2162                 }
2163                 break;
2164         case OB_MBALL:
2165
2166                 lb= &ob->disp;
2167                 if(lb->first==0) makeDispList(ob);
2168
2169                 if(solid) {
2170                         
2171                         if(dt==OB_SHADED) {
2172                                 dl= lb->first;
2173                                 if(dl && dl->col1==0) shadeDispList(ob);
2174                                 drawDispListshaded(lb, ob);
2175                         }
2176                         else {
2177                                 init_gl_materials(ob);
2178                                 two_sided(0);
2179                         
2180                                 drawDispListsolid(lb, ob);
2181                         }
2182                 }
2183                 else drawDispListwire(lb);
2184                 break;
2185         }
2186         
2187 }
2188
2189 /* ******************************** */
2190
2191
2192 static void draw_particle_system(Object *ob, PartEff *paf)
2193 {
2194         Particle *pa;
2195         float ptime, ctime, vec[3], vec1[3];
2196         int a;
2197         
2198         pa= paf->keys;
2199         if(pa==0) {
2200                 build_particle_system(ob);
2201                 pa= paf->keys;
2202                 if(pa==0) return;
2203         }
2204         
2205         myloadmatrix(G.vd->viewmat);
2206         
2207         if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
2208         else ptime= 0.0;
2209         ctime= bsystem_time(ob, 0, (float)(G.scene->r.cfra), ptime);
2210
2211         glPointSize(1.0);
2212         if(paf->stype!=PAF_VECT) glBegin(GL_POINTS);
2213
2214         for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
2215                 
2216                 if(ctime > pa->time) {
2217                         if(ctime < pa->time+pa->lifetime) {
2218                         
2219                                 if(paf->stype==PAF_VECT) {
2220                                         where_is_particle(paf, pa, ctime, vec);
2221                                         where_is_particle(paf, pa, ctime+1.0, vec1);
2222                 
2223
2224                                         glBegin(GL_LINE_STRIP);
2225                                                 glVertex3fv(vec);
2226                                                 glVertex3fv(vec1);
2227                                         glEnd();
2228                                         
2229                                 }
2230                                 else {
2231                                         where_is_particle(paf, pa, ctime, vec);
2232                                         
2233                                         glVertex3fv(vec);
2234                                                 
2235                                 }
2236                         }
2237                 }
2238         }
2239         if(paf->stype!=PAF_VECT) glEnd();
2240
2241 }
2242
2243 static void draw_static_particle_system(Object *ob, PartEff *paf)
2244 {
2245         Particle *pa;
2246         float ctime, mtime, vec[3], vec1[3];
2247         int a;
2248         
2249         pa= paf->keys;
2250         if(pa==0) {
2251                 build_particle_system(ob);
2252                 pa= paf->keys;
2253                 if(pa==0) return;
2254         }
2255         
2256         glPointSize(1.0);
2257         if(paf->stype!=PAF_VECT) glBegin(GL_POINTS);
2258
2259         for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
2260                 
2261                 where_is_particle(paf, pa, pa->time, vec1);
2262                 
2263                 mtime= pa->time+pa->lifetime+paf->staticstep-1;
2264                 
2265                 for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
2266                         
2267                         /* make sure hair grows until the end.. */ 
2268                         if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
2269                         
2270                         if(paf->stype==PAF_VECT) {
2271                                 where_is_particle(paf, pa, ctime+1, vec);
2272
2273                                 glBegin(GL_LINE_STRIP);
2274                                         glVertex3fv(vec);
2275                                         glVertex3fv(vec1);
2276                                 glEnd();
2277                                 
2278                                 VECCOPY(vec1, vec);
2279                         }
2280                         else {
2281                                 where_is_particle(paf, pa, ctime, vec);
2282                                 
2283                                 glVertex3fv(vec);
2284                                         
2285                         }
2286                 }
2287         }
2288         if(paf->stype!=PAF_VECT) glEnd();
2289
2290 }
2291
2292 static void drawmeshwire(Object *ob)
2293 {
2294         extern float editbutsize;       /* buttons.c */
2295         Mesh *me;
2296         MVert *mvert;
2297         MFace *mface;
2298         DispList *dl;
2299         Material *ma;
2300         EditEdge *eed;
2301         EditVlak *evl;
2302         float fvec[3], cent[3], *f1, *f2, *f3, *f4, *extverts=0;
2303         int a, start, end, test, /*  colbcol=0, */ ok;
2304
2305         me= get_mesh(ob);
2306
2307         if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) {
2308                 
2309                 if(G.zbuf==0 && mesh_uses_displist(me)) {
2310                         cpack(0x505050);
2311                         drawDispListwire(&me->disp);
2312                 }
2313                 cpack(0x0);
2314                 
2315                 eed= G.eded.first;
2316
2317                 glBegin(GL_LINES);
2318                 while(eed) {
2319                         if(eed->h==0) {
2320                                 glVertex3fv(eed->v1->co);
2321                                 glVertex3fv(eed->v2->co);
2322                         }
2323                         eed= eed->next;
2324                 }
2325                 glEnd();
2326                 
2327                 if(ob!=G.obedit) return;
2328                 
2329                 calc_meshverts();
2330
2331                 if(G.zbuf) glDisable(GL_DEPTH_TEST);
2332                 tekenvertices(0);
2333                 tekenvertices(1);
2334 #ifdef __NLA
2335                 tekenvertices(2);       /* __TEKENTEST */
2336 #endif
2337                 if(G.zbuf) glEnable(GL_DEPTH_TEST);
2338
2339                 if(G.f & G_DRAWNORMALS) {       /* normals */
2340                         cpack(0xDDDD22);
2341
2342                         glBegin(GL_LINES);
2343                         
2344                         evl= G.edvl.first;
2345                         while(evl) {
2346                                 if(evl->v1->h==0 && evl->v2->h==0 && evl->v3->h==0) {
2347                                         if(evl->v4) CalcCent4f(fvec, evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co);
2348                                         else CalcCent3f(fvec, evl->v1->co, evl->v2->co, evl->v3->co);
2349
2350                                         glVertex3fv(fvec);
2351                                         fvec[0]+= editbutsize*evl->n[0];
2352                                         fvec[1]+= editbutsize*evl->n[1];
2353                                         fvec[2]+= editbutsize*evl->n[2];
2354                                         glVertex3fv(fvec);
2355                                         
2356                                 }
2357                                 evl= evl->next;
2358                         }
2359
2360                         glEnd();
2361                 }
2362                 if(G.f & (G_FACESELECT+G_DRAWFACES)) {  /* vlakken */
2363                         
2364                         evl= G.edvl.first;
2365                         while(evl) {
2366                                 if(evl->v1->h==0 && evl->v2->h==0 && evl->v3->h==0) {
2367                                         
2368                                         if(vlakselectedAND(evl, 1)) cpack(0x559999);
2369                                         else cpack(0x664466);
2370                                 
2371                                         if(evl->v4 && evl->v4->h==0) {
2372                                         
2373                                                 CalcCent4f(cent, evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co);
2374                                                 glBegin(GL_LINE_LOOP);
2375                                                         VecMidf(fvec, cent, evl->v1->co); glVertex3fv(fvec);
2376                                                         VecMidf(fvec, cent, evl->v2->co); glVertex3fv(fvec);
2377                                                         VecMidf(fvec, cent, evl->v3->co); glVertex3fv(fvec);
2378                                                         VecMidf(fvec, cent, evl->v4->co); glVertex3fv(fvec);
2379                                                 glEnd();
2380                                         }
2381                                         else {
2382
2383                                                 CalcCent3f(cent, evl->v1->co, evl->v2->co, evl->v3->co);
2384                                                 glBegin(GL_LINE_LOOP);
2385                                                         VecMidf(fvec, cent, evl->v1->co); glVertex3fv(fvec);
2386                                                         VecMidf(fvec, cent, evl->v2->co); glVertex3fv(fvec);
2387                                                         VecMidf(fvec, cent, evl->v3->co); glVertex3fv(fvec);
2388                                                 glEnd();
2389                                         }
2390                                 }
2391                                 evl= evl->next;
2392                         }
2393                 }
2394         }
2395         else {
2396                 
2397                 if(me==0) return;
2398                 
2399                 if(me->bb==0) tex_space_mesh(me);
2400                 if(me->totface>4) if(boundbox_clip(ob->obmat, me->bb)==0) return;
2401                 
2402                 if(mesh_uses_displist(me)) drawDispListwire(&me->disp);
2403                 else {
2404                         
2405                         mvert= me->mvert;
2406                         mface= me->mface;
2407                         
2408                         ok= 0;
2409                         if(me->totface==0) ok= 1;
2410                         else {
2411                                 ma= give_current_material(ob, 1);
2412                                 if(ma && (ma->mode & MA_HALO)) ok= 1;
2413                         }
2414                         
2415                         dl= find_displist(&ob->disp, DL_VERTS);
2416                         if(dl) extverts= dl->verts;
2417                         
2418                         if(ok) {
2419                                 
2420                                 start= 0; end= me->totvert;
2421                                 set_buildvars(ob, &start, &end);
2422                                 
2423                                 glPointSize(1.5);
2424                                 glBegin(GL_POINTS);
2425                                 
2426                                 if(extverts) {
2427                                         extverts+= 3*start;
2428                                         for(a= start; a<end; a++, extverts+=3) {
2429                                                 glVertex3fv(extverts);
2430                                         }
2431                                 }
2432                                 else {
2433                                         mvert+= start;
2434                                         for(a= start; a<end; a++, mvert++) {
2435                                                 glVertex3fv(mvert->co);
2436                                         }
2437                                 }
2438                                 
2439                                 glEnd();
2440                                 glPointSize(1.0);
2441                         }
2442                         else {
2443                                 
2444                                 start= 0; end= me->totface;
2445                                 set_buildvars(ob, &start, &end);
2446                                 mface+= start;
2447                                 
2448                                 for(a=start; a<end; a++, mface++) {
2449                                         test= mface->edcode;
2450                                         
2451                                         if(test) {
2452                                                 if(extverts) {
2453                                                         f1= extverts+3*mface->v1;
2454                                                         f2= extverts+3*mface->v2;
2455                                                 }
2456                                                 else {
2457                                                         f1= (mvert+mface->v1)->co;
2458                                                         f2= (mvert+mface->v2)->co;
2459                                                 }
2460                                                 
2461                                                 if(mface->v4) {
2462                                                         if(extverts) {
2463                                                                 f3= extverts+3*mface->v3;
2464                                                                 f4= extverts+3*mface->v4;
2465                                                         }
2466                                                         else {
2467                                                                 f3= (mvert+mface->v3)->co;
2468                                                                 f4= (mvert+mface->v4)->co;
2469                                                         }
2470                                                         
2471                                                         if(test== ME_V1V2+ME_V2V3+ME_V3V4+ME_V4V1) {
2472                                                                 glBegin(GL_LINE_LOOP);
2473                                                                         glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f4);
2474                                                                 glEnd();
2475                                                         }
2476                                                         else if(test== ME_V1V2+ME_V2V3+ME_V3V4) {
2477         
2478                                                                 glBegin(GL_LINE_STRIP);
2479                                                                         glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f4);
2480                                                                 glEnd();
2481                                                         }
2482                                                         else if(test== ME_V2V3+ME_V3V4+ME_V4V1) {
2483         
2484                                                                 glBegin(GL_LINE_STRIP);
2485                                                                         glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f4); glVertex3fv(f1);
2486                                                                 glEnd();
2487                                                         }
2488                                                         else if(test== ME_V3V4+ME_V4V1+ME_V1V2) {
2489         
2490                                                                 glBegin(GL_LINE_STRIP);
2491                                                                         glVertex3fv(f3); glVertex3fv(f4); glVertex3fv(f1); glVertex3fv(f2);
2492                                                                 glEnd();
2493                                                         }
2494                                                         else if(test== ME_V4V1+ME_V1V2+ME_V2V3) {
2495         
2496                                                                 glBegin(GL_LINE_STRIP);
2497                                                                         glVertex3fv(f4); glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3);
2498                                                                 glEnd();
2499                                                         }
2500                                                         else {
2501                                                                 if(test & ME_V1V2) {
2502         
2503                                                                         glBegin(GL_LINE_STRIP);
2504                                                                                 glVertex3fv(f1); glVertex3fv(f2);
2505                                                                         glEnd();
2506                                                                 }
2507                                                                 if(test & ME_V2V3) {
2508         
2509                                                                         glBegin(GL_LINE_STRIP);
2510                                                                                 glVertex3fv(f2); glVertex3fv(f3);
2511                                                                         glEnd();
2512                                                                 }
2513                                                                 if(test & ME_V3V4) {
2514         
2515                                                                         glBegin(GL_LINE_STRIP);
2516                                                                                 glVertex3fv(f3); glVertex3fv(f4);
2517                                                                         glEnd();
2518                                                                 }
2519                                                                 if(test & ME_V4V1) {
2520         
2521                                                                         glBegin(GL_LINE_STRIP);
2522                                                                                 glVertex3fv(f4); glVertex3fv(f1);
2523                                                                         glEnd();
2524                                                                 }
2525                                                         }
2526                                                 }
2527                                                 else if(mface->v3) {
2528                                                         if(extverts) f3= extverts+3*mface->v3;
2529                                                         else f3= (mvert+mface->v3)->co;
2530                 
2531                                                         if(test== ME_V1V2+ME_V2V3+ME_V3V1) {
2532                                                                 glBegin(GL_LINE_LOOP);
2533                                                                         glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3);
2534                                                                 glEnd();
2535                                                         }
2536                                                         else if(test== ME_V1V2+ME_V2V3) {
2537         
2538                                                                 glBegin(GL_LINE_STRIP);
2539                                                                         glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3);
2540                                                                 glEnd();
2541                                                         }
2542                                                         else if(test== ME_V2V3+ME_V3V1) {
2543         
2544                                                                 glBegin(GL_LINE_STRIP);
2545                                                                         glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f1);
2546                                                                 glEnd();
2547                                                         }
2548                                                         else if(test== ME_V1V2+ME_V3V1) {
2549         
2550                                                                 glBegin(GL_LINE_STRIP);
2551                                                                         glVertex3fv(f3); glVertex3fv(f1); glVertex3fv(f2);
2552                                                                 glEnd();
2553                                                         }
2554                                                         else {
2555                                                                 if(test & ME_V1V2) {
2556         
2557                                                                         glBegin(GL_LINE_STRIP);
2558                                                                                 glVertex3fv(f1); glVertex3fv(f2);
2559                                                                         glEnd();
2560                                                                 }
2561                                                                 if(test & ME_V2V3) {
2562         
2563                                                                         glBegin(GL_LINE_STRIP);
2564                                                                                 glVertex3fv(f2); glVertex3fv(f3);
2565                                                                         glEnd();
2566                                                                 }
2567                                                                 if(test & ME_V3V1) {
2568         
2569                                                                         glBegin(GL_LINE_STRIP);
2570                                                                                 glVertex3fv(f3); glVertex3fv(f1);
2571                                                                         glEnd();
2572                                                                 }
2573                                                         }
2574                                                 }
2575                                                 else if(test & ME_V1V2) {
2576         
2577                                                         glBegin(GL_LINE_STRIP);
2578                                                                 glVertex3fv(f1); glVertex3fv(f2);
2579                                                         glEnd();
2580                                                 }
2581                                         }
2582                                 }
2583                         }
2584                         
2585                 }
2586         }
2587 }
2588
2589 unsigned int nurbcol[8]= {
2590         0, 0x9090, 0x409030, 0x603080, 0, 0x40fff0, 0x40c033, 0xA090F0 };
2591
2592 static void tekenhandlesN(Nurb *nu, short sel)
2593 {
2594         BezTriple *bezt;
2595         float *fp;
2596         unsigned int *col;
2597         int a;
2598
2599         if(nu->hide) return;
2600         if( (nu->type & 7)==1) {
2601                 if(sel) col= nurbcol+4;
2602                 else col= nurbcol;
2603
2604                 bezt= nu->bezt;
2605                 a= nu->pntsu;
2606                 while(a--) {
2607                         if(bezt->hide==0) {
2608                                 if( (bezt->f2 & 1)==sel) {
2609                                         fp= bezt->vec[0];
2610                                         cpack(col[bezt->h1]);
2611
2612                                         glBegin(GL_LINE_STRIP); 
2613                                         glVertex3fv(fp);
2614                                         glVertex3fv(fp+3); 
2615                                         glEnd();
2616                                         cpack(col[bezt->h2]);
2617
2618                                         glBegin(GL_LINE_STRIP); 
2619                                         glVertex3fv(fp+3); 
2620                                         glVertex3fv(fp+6); 
2621                                         glEnd();
2622                                 }
2623                                 else if( (bezt->f1 & 1)==sel) {
2624                                         fp= bezt->vec[0];
2625                                         cpack(col[bezt->h1]);
2626
2627                                         glBegin(GL_LINE_STRIP); 
2628                                         glVertex3fv(fp); 
2629                                         glVertex3fv(fp+3); 
2630                                         glEnd();
2631                                 }
2632                                 else if( (bezt->f3 & 1)==sel) {
2633                                         fp= bezt->vec[1];
2634                                         cpack(col[bezt->h2]);
2635
2636                                         glBegin(GL_LINE_STRIP); 
2637                                         glVertex3fv(fp); 
2638                                         glVertex3fv(fp+3); 
2639                                         glEnd();
2640                                 }
2641                         }
2642                         bezt++;
2643                 }
2644         }
2645 }
2646
2647 static void tekenvertsN(Nurb *nu, short sel)
2648 {
2649         BezTriple *bezt;
2650         BPoint *bp;
2651         int a;
2652
2653         if(nu->hide) return;
2654
2655         if(sel) cpack(B_YELLOW);
2656         else cpack(B_PURPLE);
2657         glPointSize(3.0);
2658         
2659         glBegin(GL_POINTS);
2660         
2661         if((nu->type & 7)==1) {
2662
2663                 bezt= nu->bezt;
2664                 a= nu->pntsu;
2665                 while(a--) {
2666                         if(bezt->hide==0) {
2667                                 if((bezt->f1 & 1)==sel) glVertex3fv(bezt->vec[0]);
2668                                 if((bezt->f2 & 1)==sel) glVertex3fv(bezt->vec[1]);
2669                                 if((bezt->f3 & 1)==sel) glVertex3fv(bezt->vec[2]);
2670                         }
2671                         bezt++;
2672                 }
2673         }
2674         else {
2675                 bp= nu->bp;
2676                 a= nu->pntsu*nu->pntsv;
2677                 while(a--) {
2678                         if(bp->hide==0) {
2679                                 if((bp->f1 & 1)==sel) glVertex3fv(bp->vec);
2680                         }
2681                         bp++;
2682                 }
2683         }
2684         
2685         glEnd();
2686         glPointSize(1.0);
2687 }
2688
2689 static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
2690 {
2691         Nurb *nu;
2692         BPoint *bp, *bp1;
2693         int a, b, ofs;
2694         
2695         nu= nurb;
2696         while(nu) {
2697                 if(nu->hide==0) {
2698                         switch(nu->type & 7) {
2699                         case CU_POLY:
2700                                 cpack(nurbcol[3]);
2701                                 bp= nu->bp;
2702                                 for(b=0; b<nu->pntsv; b++) {
2703                                         if(nu->flagu & 1) glBegin(GL_LINE_LOOP);
2704
2705                                         else glBegin(GL_LINE_STRIP);
2706
2707                                         for(a=0; a<nu->pntsu; a++, bp++) {
2708                                                 glVertex3fv(bp->vec);
2709                                         }
2710
2711                                         if(nu->flagu & 1) glEnd();
2712                                         else glEnd();
2713                                 }
2714                                 break;
2715                         case CU_NURBS:
2716
2717                                 bp= nu->bp;
2718                                 for(b=0; b<nu->pntsv; b++) {
2719                                         bp1= bp;
2720                                         bp++;
2721                                         for(a=nu->pntsu-1; a>0; a--, bp++) {
2722                                                 if(bp->hide==0 && bp1->hide==0) {
2723                                                         if(sel) {
2724                                                                 if( (bp->f1 & 1) && ( bp1->f1 & 1) ) {
2725                                                                         cpack(nurbcol[5]);
2726                 
2727                                                                         glBegin(GL_LINE_STRIP);
2728                                                                         glVertex3fv(bp->vec); 
2729                                                                         glVertex3fv(bp1->vec);
2730                                                                         glEnd();
2731                                                                 }
2732                                                         }
2733                                                         else {
2734                                                                 if( (bp->f1 & 1) && ( bp1->f1 & 1) );
2735                                                                 else {
2736                                                                         cpack(nurbcol[1]);
2737                 
2738                                                                         glBegin(GL_LINE_STRIP);
2739                                                                         glVertex3fv(bp->vec); 
2740                                                                         glVertex3fv(bp1->vec);
2741                                                                         glEnd();
2742                                                                 }
2743                                                         }
2744                                                 }
2745                                                 bp1= bp;
2746                                         }
2747                                 }
2748                                 if(nu->pntsv > 1) {     /* surface */
2749
2750                                         ofs= nu->pntsu;
2751                                         for(b=0; b<nu->pntsu; b++) {
2752                                                 bp1= nu->bp+b;
2753                                                 bp= bp1+ofs;
2754                                                 for(a=nu->pntsv-1; a>0; a--, bp+=ofs) {
2755                                                         if(bp->hide==0 && bp1->hide==0) {
2756                                                                 if(sel) {
2757                                                                         if( (bp->f1 & 1) && ( bp1->f1 & 1) ) {
2758                                                                                 cpack(nurbcol[7]);
2759                         
2760                                                                                 glBegin(GL_LINE_STRIP);
2761                                                                                 glVertex3fv(bp->vec); 
2762                                                                                 glVertex3fv(bp1->vec);
2763                                                                                 glEnd();
2764                                                                         }
2765                                                                 }
2766                                                                 else {
2767                                                                         if( (bp->f1 & 1) && ( bp1->f1 & 1) );
2768                                                                         else {
2769                                                                                 cpack(nurbcol[3]);
2770                         
2771                                                                                 glBegin(GL_LINE_STRIP);
2772                                                                                 glVertex3fv(bp->vec); 
2773                                                                                 glVertex3fv(bp1->vec);
2774                                                                                 glEnd();
2775                                                                         }
2776                                                                 }
2777                                                         }
2778                                                         bp1= bp;
2779                                                 }
2780                                         }
2781
2782                                 }
2783                                 break;
2784                         }
2785                 }
2786                 nu= nu->next;
2787         }
2788 }
2789
2790 static void drawnurb(Object *ob, Nurb *nurb, int dt)
2791 {
2792         extern float editbutsize;       /* buttons.c */
2793         Curve *cu;
2794         Nurb *nu;
2795         BevPoint *bevp;
2796         BevList *bl;
2797         float vec[3];
2798         int a, nr, skip;
2799
2800         /* eerst handles niet select */
2801         nu= nurb;
2802         while(nu) {
2803                 if((nu->type & 7)==CU_BEZIER) {
2804                         tekenhandlesN(nu, 0);
2805                 }
2806                 nu= nu->next;
2807         }
2808         
2809         /* dan DispList */
2810         
2811         cpack(0);
2812         cu= ob->data;
2813         drawDispList(ob, dt);
2814
2815         draw_editnurb(ob, nurb, 0);
2816         draw_editnurb(ob, nurb, 1);
2817
2818         if(cu->flag & CU_3D) {
2819         
2820                 if(cu->bev.first==0) makeBevelList(ob);
2821                 
2822                 cpack(0x0);
2823                 bl= cu->bev.first;
2824                 nu= nurb;
2825                 while(nu && bl) {
2826                         bevp= (BevPoint *)(bl+1);               
2827                         nr= bl->nr;
2828                         
2829                         skip= nu->resolu/16;
2830                         
2831                         while(nr-- > 0) {
2832                                 
2833                                 glBegin(GL_LINE_STRIP);
2834                                 vec[0]= bevp->x-editbutsize*bevp->mat[0][0];
2835                                 vec[1]= bevp->y-editbutsize*bevp->mat[0][1];
2836                                 vec[2]= bevp->z-editbutsize*bevp->mat[0][2];
2837                                 glVertex3fv(vec);
2838                                 vec[0]= bevp->x+editbutsize*bevp->mat[0][0];
2839                                 vec[1]= bevp->y+editbutsize*bevp->mat[0][1];
2840                                 vec[2]= bevp->z+editbutsize*bevp->mat[0][2];
2841                                 glVertex3fv(vec);
2842
2843                                 glEnd();
2844                                 
2845                                 bevp++;
2846                                 
2847                                 a= skip;
2848                                 while(a--) {
2849                                         bevp++;
2850                                         nr--;
2851                                 }
2852                         }
2853
2854                         bl= bl->next;
2855                         nu= nu->next;
2856                 }
2857         }
2858
2859         calc_Nurbverts(nurb);
2860
2861         if(G.zbuf) glDisable(GL_DEPTH_TEST);
2862         
2863         nu= nurb;
2864         while(nu) {
2865                 if((nu->type & 7)==1) tekenhandlesN(nu, 1);
2866                 tekenvertsN(nu, 0);
2867                 nu= nu->next;
2868         }
2869
2870         nu= nurb;
2871         while(nu) {
2872                 tekenvertsN(nu, 1);
2873                 nu= nu->next;
2874         }
2875         
2876         if(G.zbuf) glEnable(GL_DEPTH_TEST); 
2877 }