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