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