f53fd967daa72e86fe537c2178e711dd05e0657c
[blender-staging.git] / source / blender / editors / space_view3d / drawobject.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, full recode and added functions
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/space_view3d/drawobject.c
27  *  \ingroup spview3d
28  */
29
30 #include "MEM_guardedalloc.h"
31
32 #include "DNA_camera_types.h"
33 #include "DNA_curve_types.h"
34 #include "DNA_constraint_types.h"  /* for drawing constraint */
35 #include "DNA_lamp_types.h"
36 #include "DNA_lattice_types.h"
37 #include "DNA_material_types.h"
38 #include "DNA_mesh_types.h"
39 #include "DNA_meta_types.h"
40 #include "DNA_rigidbody_types.h"
41 #include "DNA_scene_types.h"
42 #include "DNA_smoke_types.h"
43 #include "DNA_world_types.h"
44 #include "DNA_object_types.h"
45
46 #include "BLI_listbase.h"
47 #include "BLI_link_utils.h"
48 #include "BLI_string.h"
49 #include "BLI_math.h"
50 #include "BLI_memarena.h"
51
52 #include "BKE_anim.h"  /* for the where_on_path function */
53 #include "BKE_armature.h"
54 #include "BKE_camera.h"
55 #include "BKE_colortools.h"
56 #include "BKE_constraint.h"  /* for the get_constraint_target function */
57 #include "BKE_curve.h"
58 #include "BKE_DerivedMesh.h"
59 #include "BKE_deform.h"
60 #include "BKE_displist.h"
61 #include "BKE_font.h"
62 #include "BKE_global.h"
63 #include "BKE_image.h"
64 #include "BKE_key.h"
65 #include "BKE_lattice.h"
66 #include "BKE_main.h"
67 #include "BKE_mesh.h"
68 #include "BKE_material.h"
69 #include "BKE_mball.h"
70 #include "BKE_modifier.h"
71 #include "BKE_movieclip.h"
72 #include "BKE_object.h"
73 #include "BKE_paint.h"
74 #include "BKE_particle.h"
75 #include "BKE_pointcache.h"
76 #include "BKE_scene.h"
77 #include "BKE_unit.h"
78 #include "BKE_tracking.h"
79
80 #include "BKE_editmesh.h"
81
82 #include "IMB_imbuf.h"
83 #include "IMB_imbuf_types.h"
84
85 #include "BIF_gl.h"
86 #include "BIF_glutil.h"
87
88 #include "GPU_draw.h"
89 #include "GPU_extensions.h"
90 #include "GPU_select.h"
91
92 #include "ED_mesh.h"
93 #include "ED_particle.h"
94 #include "ED_screen.h"
95 #include "ED_sculpt.h"
96 #include "ED_types.h"
97
98 #include "UI_resources.h"
99 #include "UI_interface_icons.h"
100
101 #include "WM_api.h"
102 #include "BLF_api.h"
103
104 #include "view3d_intern.h"  /* bad level include */
105
106 /* Workaround for sequencer scene render mode.
107  *
108  * Strips doesn't use DAG to update objects or so, which
109  * might lead to situations when object is drawing without
110  * curve cache ready.
111  *
112  * Ideally we don't want to evaluate objects from drawing,
113  * but it'll require some major sequencer re-design. So
114  * for now just fallback to legacy behavior with calling
115  * display ist creating from draw().
116  */
117 #define SEQUENCER_DAG_WORKAROUND
118
119 typedef enum eWireDrawMode {
120         OBDRAW_WIRE_OFF = 0,
121         OBDRAW_WIRE_ON = 1,
122         OBDRAW_WIRE_ON_DEPTH = 2
123 } eWireDrawMode;
124
125 typedef struct drawDMVerts_userData {
126         BMesh *bm;
127
128         BMVert *eve_act;
129         char sel;
130
131         /* cached theme values */
132         unsigned char th_editmesh_active[4];
133         unsigned char th_vertex_select[4];
134         unsigned char th_vertex[4];
135         unsigned char th_skin_root[4];
136         float th_vertex_size;
137
138         /* for skin node drawing */
139         int cd_vskin_offset;
140         float imat[4][4];
141 } drawDMVerts_userData;
142
143 typedef struct drawDMEdgesSel_userData {
144         BMesh *bm;
145
146         unsigned char *baseCol, *selCol, *actCol;
147         BMEdge *eed_act;
148 } drawDMEdgesSel_userData;
149
150 typedef struct drawDMEdgesSelInterp_userData {
151         BMesh *bm;
152
153         unsigned char *baseCol, *selCol;
154         unsigned char *lastCol;
155 } drawDMEdgesSelInterp_userData;
156
157 typedef struct drawDMEdgesWeightInterp_userData {
158         BMesh *bm;
159
160         int cd_dvert_offset;
161         int defgroup_tot;
162         int vgroup_index;
163         char weight_user;
164         float alert_color[3];
165
166 } drawDMEdgesWeightInterp_userData;
167
168 typedef struct drawDMFacesSel_userData {
169 #ifdef WITH_FREESTYLE
170         unsigned char *cols[4];
171 #else
172         unsigned char *cols[3];
173 #endif
174
175         DerivedMesh *dm;
176         BMesh *bm;
177
178         BMFace *efa_act;
179         const int *orig_index_mf_to_mpoly;
180         const int *orig_index_mp_to_orig;
181 } drawDMFacesSel_userData;
182
183 typedef struct drawDMNormal_userData {
184         BMesh *bm;
185         int uniform_scale;
186         float normalsize;
187         float tmat[3][3];
188         float imat[3][3];
189 } drawDMNormal_userData;
190
191 typedef struct drawMVertOffset_userData {
192         MVert *mvert;
193         int offset;
194 } drawMVertOffset_userData;
195
196 typedef struct drawDMLayer_userData {
197         BMesh *bm;
198         int cd_layer_offset;
199 } drawDMLayer_userData;
200
201 typedef struct drawBMOffset_userData {
202         BMesh *bm;
203         int offset;
204 } drawBMOffset_userData;
205
206 typedef struct drawBMSelect_userData {
207         BMesh *bm;
208         bool select;
209 } drawBMSelect_userData;
210
211 static void draw_bounding_volume(Object *ob, char type);
212
213 static void drawcube_size(float size);
214 static void drawcircle_size(float size);
215 static void draw_empty_sphere(float size);
216 static void draw_empty_cone(float size);
217 static void draw_box(float vec[8][3], bool solid);
218
219 static void ob_wire_color_blend_theme_id(const unsigned char ob_wire_col[4], const int theme_id, float fac)
220 {
221         float col_wire[3], col_bg[3], col[3];
222
223         rgb_uchar_to_float(col_wire, ob_wire_col);
224
225         UI_GetThemeColor3fv(theme_id, col_bg);
226         interp_v3_v3v3(col, col_bg, col_wire, fac);
227         glColor3fv(col);
228 }
229
230 /* this condition has been made more complex since editmode can draw textures */
231 bool check_object_draw_texture(Scene *scene, View3D *v3d, const char drawtype)
232 {
233         /* texture and material draw modes */
234         if (ELEM(v3d->drawtype, OB_TEXTURE, OB_MATERIAL) && drawtype > OB_SOLID) {
235                 return true;
236         }
237
238         /* textured solid */
239         if ((v3d->drawtype == OB_SOLID) &&
240             (v3d->flag2 & V3D_SOLID_TEX) &&
241             (BKE_scene_use_new_shading_nodes(scene) == false))
242         {
243                 return true;
244         }
245         
246         if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) {
247                 return true;
248         }
249         
250         return false;
251 }
252
253 static bool check_object_draw_editweight(Mesh *me, DerivedMesh *finalDM)
254 {
255         if (me->drawflag & ME_DRAWEIGHT) {
256                 /* editmesh handles its own weight drawing */
257                 if (finalDM->type != DM_TYPE_EDITBMESH) {
258                         return true;
259                 }
260         }
261
262         return false;
263 }
264
265 static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
266 {
267         if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0)
268                 return false;
269
270         if (G.f & G_BACKBUFSEL)
271                 return false;
272
273         if ((vd->flag & V3D_ZBUF_SELECT) == 0)
274                 return true;
275
276         /* if its drawing textures with zbuf sel, then don't draw dots */
277         if (dt == OB_TEXTURE && vd->drawtype == OB_TEXTURE)
278                 return false;
279
280         if ((vd->drawtype >= OB_SOLID) && (vd->flag2 & V3D_SOLID_TEX))
281                 return false;
282
283         return true;
284 }
285
286 /* ************************ */
287
288 /* check for glsl drawing */
289
290 bool draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
291 {
292         if (!GPU_glsl_support())
293                 return false;
294         if (G.f & G_PICKSEL)
295                 return false;
296         if (!check_object_draw_texture(scene, v3d, dt))
297                 return false;
298         if (ob == OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
299                 return false;
300         
301         if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)
302                 return true;
303         
304         if (BKE_scene_use_new_shading_nodes(scene))
305                 return false;
306         
307         return ((scene->gm.matmode == GAME_MAT_GLSL && v3d->drawtype == OB_TEXTURE) ||
308                 (v3d->drawtype == OB_MATERIAL)) && (dt > OB_SOLID);
309 }
310
311 static bool check_alpha_pass(Base *base)
312 {
313         if (base->flag & OB_FROMDUPLI)
314                 return false;
315
316         if (G.f & G_PICKSEL)
317                 return false;
318
319         if (base->object->mode & OB_MODE_ALL_PAINT)
320                 return false;
321
322         return (base->object->dtx & OB_DRAWTRANSP);
323 }
324
325 /***/
326 static const unsigned int colortab[] = {
327         0x0, 0x403000, 0xFFFF88
328 };
329
330 /* ----------------- OpenGL Circle Drawing - Tables for Optimized Drawing Speed ------------------ */
331 /* 32 values of sin function (still same result!) */
332 #define CIRCLE_RESOL 32
333
334 static const float sinval[CIRCLE_RESOL] = {
335         0.00000000,
336         0.20129852,
337         0.39435585,
338         0.57126821,
339         0.72479278,
340         0.84864425,
341         0.93775213,
342         0.98846832,
343         0.99871650,
344         0.96807711,
345         0.89780453,
346         0.79077573,
347         0.65137248,
348         0.48530196,
349         0.29936312,
350         0.10116832,
351         -0.10116832,
352         -0.29936312,
353         -0.48530196,
354         -0.65137248,
355         -0.79077573,
356         -0.89780453,
357         -0.96807711,
358         -0.99871650,
359         -0.98846832,
360         -0.93775213,
361         -0.84864425,
362         -0.72479278,
363         -0.57126821,
364         -0.39435585,
365         -0.20129852,
366         0.00000000
367 };
368
369 /* 32 values of cos function (still same result!) */
370 static const float cosval[CIRCLE_RESOL] = {
371         1.00000000,
372         0.97952994,
373         0.91895781,
374         0.82076344,
375         0.68896691,
376         0.52896401,
377         0.34730525,
378         0.15142777,
379         -0.05064916,
380         -0.25065253,
381         -0.44039415,
382         -0.61210598,
383         -0.75875812,
384         -0.87434661,
385         -0.95413925,
386         -0.99486932,
387         -0.99486932,
388         -0.95413925,
389         -0.87434661,
390         -0.75875812,
391         -0.61210598,
392         -0.44039415,
393         -0.25065253,
394         -0.05064916,
395         0.15142777,
396         0.34730525,
397         0.52896401,
398         0.68896691,
399         0.82076344,
400         0.91895781,
401         0.97952994,
402         1.00000000
403 };
404
405 static void draw_xyz_wire(const float c[3], float size, int axis)
406 {
407         float v1[3] = {0.0f, 0.0f, 0.0f}, v2[3] = {0.0f, 0.0f, 0.0f};
408         float dim = size * 0.1f;
409         float dx[3], dy[3], dz[3];
410
411         dx[0] = dim;  dx[1] = 0.0f; dx[2] = 0.0f;
412         dy[0] = 0.0f; dy[1] = dim;  dy[2] = 0.0f;
413         dz[0] = 0.0f; dz[1] = 0.0f; dz[2] = dim;
414
415         switch (axis) {
416                 case 0:     /* x axis */
417                         glBegin(GL_LINES);
418                         
419                         /* bottom left to top right */
420                         sub_v3_v3v3(v1, c, dx);
421                         sub_v3_v3(v1, dy);
422                         add_v3_v3v3(v2, c, dx);
423                         add_v3_v3(v2, dy);
424                         
425                         glVertex3fv(v1);
426                         glVertex3fv(v2);
427                         
428                         /* top left to bottom right */
429                         mul_v3_fl(dy, 2.0f);
430                         add_v3_v3(v1, dy);
431                         sub_v3_v3(v2, dy);
432                         
433                         glVertex3fv(v1);
434                         glVertex3fv(v2);
435                         
436                         glEnd();
437                         break;
438                 case 1:     /* y axis */
439                         glBegin(GL_LINES);
440                         
441                         /* bottom left to top right */
442                         mul_v3_fl(dx, 0.75f);
443                         sub_v3_v3v3(v1, c, dx);
444                         sub_v3_v3(v1, dy);
445                         add_v3_v3v3(v2, c, dx);
446                         add_v3_v3(v2, dy);
447                         
448                         glVertex3fv(v1);
449                         glVertex3fv(v2);
450                         
451                         /* top left to center */
452                         mul_v3_fl(dy, 2.0f);
453                         add_v3_v3(v1, dy);
454                         copy_v3_v3(v2, c);
455                         
456                         glVertex3fv(v1);
457                         glVertex3fv(v2);
458                         
459                         glEnd();
460                         break;
461                 case 2:     /* z axis */
462                         glBegin(GL_LINE_STRIP);
463                         
464                         /* start at top left */
465                         sub_v3_v3v3(v1, c, dx);
466                         add_v3_v3v3(v1, c, dz);
467                         
468                         glVertex3fv(v1);
469                         
470                         mul_v3_fl(dx, 2.0f);
471                         add_v3_v3(v1, dx);
472
473                         glVertex3fv(v1);
474                         
475                         mul_v3_fl(dz, 2.0f);
476                         sub_v3_v3(v1, dx);
477                         sub_v3_v3(v1, dz);
478                         
479                         glVertex3fv(v1);
480                         
481                         add_v3_v3(v1, dx);
482                 
483                         glVertex3fv(v1);
484                         
485                         glEnd();
486                         break;
487         }
488 }
489
490 void drawaxes(float size, char drawtype)
491 {
492         int axis;
493         float v1[3] = {0.0, 0.0, 0.0};
494         float v2[3] = {0.0, 0.0, 0.0};
495         float v3[3] = {0.0, 0.0, 0.0};
496         
497         switch (drawtype) {
498
499                 case OB_PLAINAXES:
500                         for (axis = 0; axis < 3; axis++) {
501                                 glBegin(GL_LINES);
502
503                                 v1[axis] = size;
504                                 v2[axis] = -size;
505                                 glVertex3fv(v1);
506                                 glVertex3fv(v2);
507
508                                 /* reset v1 & v2 to zero */
509                                 v1[axis] = v2[axis] = 0.0f;
510
511                                 glEnd();
512                         }
513                         break;
514                 case OB_SINGLE_ARROW:
515
516                         glBegin(GL_LINES);
517                         /* in positive z direction only */
518                         v1[2] = size;
519                         glVertex3fv(v1);
520                         glVertex3fv(v2);
521                         glEnd();
522
523                         /* square pyramid */
524                         glBegin(GL_TRIANGLES);
525
526                         v2[0] = size * 0.035f; v2[1] = size * 0.035f;
527                         v3[0] = size * -0.035f; v3[1] = size * 0.035f;
528                         v2[2] = v3[2] = size * 0.75f;
529
530                         for (axis = 0; axis < 4; axis++) {
531                                 if (axis % 2 == 1) {
532                                         v2[0] = -v2[0];
533                                         v3[1] = -v3[1];
534                                 }
535                                 else {
536                                         v2[1] = -v2[1];
537                                         v3[0] = -v3[0];
538                                 }
539
540                                 glVertex3fv(v1);
541                                 glVertex3fv(v2);
542                                 glVertex3fv(v3);
543
544                         }
545                         glEnd();
546
547                         break;
548                 case OB_CUBE:
549                         drawcube_size(size);
550                         break;
551
552                 case OB_CIRCLE:
553                         drawcircle_size(size);
554                         break;
555
556                 case OB_EMPTY_SPHERE:
557                         draw_empty_sphere(size);
558                         break;
559
560                 case OB_EMPTY_CONE:
561                         draw_empty_cone(size);
562                         break;
563
564                 case OB_ARROWS:
565                 default:
566                 {
567                         for (axis = 0; axis < 3; axis++) {
568                                 const int arrow_axis = (axis == 0) ? 1 : 0;
569
570                                 glBegin(GL_LINES);
571
572                                 v2[axis] = size;
573                                 glVertex3fv(v1);
574                                 glVertex3fv(v2);
575                                 
576                                 v1[axis] = size * 0.85f;
577                                 v1[arrow_axis] = -size * 0.08f;
578                                 glVertex3fv(v1);
579                                 glVertex3fv(v2);
580                                 
581                                 v1[arrow_axis] = size * 0.08f;
582                                 glVertex3fv(v1);
583                                 glVertex3fv(v2);
584
585                                 glEnd();
586                                 
587                                 v2[axis] += size * 0.125f;
588
589                                 draw_xyz_wire(v2, size, axis);
590
591
592                                 /* reset v1 & v2 to zero */
593                                 v1[arrow_axis] = v1[axis] = v2[axis] = 0.0f;
594                         }
595                         break;
596                 }
597         }
598 }
599
600
601 /* Function to draw an Image on an empty Object */
602 static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4])
603 {
604         Image *ima = ob->data;
605         ImBuf *ibuf = BKE_image_acquire_ibuf(ima, ob->iuser, NULL);
606
607         float scale, ofs_x, ofs_y, sca_x, sca_y;
608         int ima_x, ima_y;
609
610         if (ibuf && (ibuf->rect == NULL) && (ibuf->rect_float != NULL)) {
611                 IMB_rect_from_float(ibuf);
612         }
613
614         /* Get the buffer dimensions so we can fallback to fake ones */
615         if (ibuf && ibuf->rect) {
616                 ima_x = ibuf->x;
617                 ima_y = ibuf->y;
618         }
619         else {
620                 ima_x = 1;
621                 ima_y = 1;
622         }
623
624         /* Get the image aspect even if the buffer is invalid */
625         if (ima) {
626                 if (ima->aspx > ima->aspy) {
627                         sca_x = 1.0f;
628                         sca_y = ima->aspy / ima->aspx;
629                 }
630                 else if (ima->aspx < ima->aspy) {
631                         sca_x = ima->aspx / ima->aspy;
632                         sca_y = 1.0f;
633                 }
634                 else {
635                         sca_x = 1.0f;
636                         sca_y = 1.0f;
637                 }
638         }
639         else {
640                 sca_x = 1.0f;
641                 sca_y = 1.0f;
642         }
643
644         /* Calculate the scale center based on object's origin */
645         ofs_x = ob->ima_ofs[0] * ima_x;
646         ofs_y = ob->ima_ofs[1] * ima_y;
647
648         glMatrixMode(GL_MODELVIEW);
649         glPushMatrix();
650
651         /* Calculate Image scale */
652         scale = (ob->empty_drawsize / max_ff((float)ima_x * sca_x, (float)ima_y * sca_y));
653
654         /* Set the object scale */
655         glScalef(scale * sca_x, scale * sca_y, 1.0f);
656
657         if (ibuf && ibuf->rect) {
658                 const bool use_clip = (U.glalphaclip != 1.0f);
659                 int zoomfilter = (U.gameflags & USER_DISABLE_MIPMAP ) ? GL_NEAREST : GL_LINEAR;
660                 /* Setup GL params */
661                 glEnable(GL_BLEND);
662                 glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA);
663
664                 if (use_clip) {
665                         glEnable(GL_ALPHA_TEST);
666                         glAlphaFunc(GL_GREATER, U.glalphaclip);
667                 }
668
669                 /* Use the object color and alpha */
670                 glColor4fv(ob->col);
671
672                 /* Draw the Image on the screen */
673                 glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_RGBA, GL_UNSIGNED_BYTE, zoomfilter, ibuf->rect);
674                 glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
675
676                 glDisable(GL_BLEND);
677
678                 if (use_clip) {
679                         glDisable(GL_ALPHA_TEST);
680                         glAlphaFunc(GL_GREATER, 0.0f);
681                 }
682         }
683
684         if ((dflag & DRAW_CONSTCOLOR) == 0) {
685                 glColor3ubv(ob_wire_col);
686         }
687
688         /* Calculate the outline vertex positions */
689         glBegin(GL_LINE_LOOP);
690         glVertex2f(ofs_x, ofs_y);
691         glVertex2f(ofs_x + ima_x, ofs_y);
692         glVertex2f(ofs_x + ima_x, ofs_y + ima_y);
693         glVertex2f(ofs_x, ofs_y + ima_y);
694         glEnd();
695
696
697         /* Reset GL settings */
698         glMatrixMode(GL_MODELVIEW);
699         glPopMatrix();
700
701         BKE_image_release_ibuf(ima, ibuf, NULL);
702 }
703
704 static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, float tmat[4][4])
705 {
706         float vx[3], vy[3];
707         float *viter = (float *)verts;
708         unsigned int a;
709
710         mul_v3_v3fl(vx, tmat[0], rad);
711         mul_v3_v3fl(vy, tmat[1], rad);
712
713         for (a = 0; a < CIRCLE_RESOL; a++, viter += 3) {
714                 viter[0] = cent[0] + sinval[a] * vx[0] + cosval[a] * vy[0];
715                 viter[1] = cent[1] + sinval[a] * vx[1] + cosval[a] * vy[1];
716                 viter[2] = cent[2] + sinval[a] * vx[2] + cosval[a] * vy[2];
717         }
718 }
719
720 void drawcircball(int mode, const float cent[3], float rad, float tmat[4][4])
721 {
722         float verts[CIRCLE_RESOL][3];
723
724         circball_array_fill(verts, cent, rad, tmat);
725
726         glEnableClientState(GL_VERTEX_ARRAY);
727         glVertexPointer(3, GL_FLOAT, 0, verts);
728         glDrawArrays(mode, 0, CIRCLE_RESOL);
729         glDisableClientState(GL_VERTEX_ARRAY);
730 }
731
732 /* circle for object centers, special_color is for library or ob users */
733 static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, const float co[3], int selstate, bool special_color)
734 {
735         const float size = ED_view3d_pixel_size(rv3d, co) * (float)U.obcenter_dia * 0.5f;
736         float verts[CIRCLE_RESOL][3];
737
738         /* using gldepthfunc guarantees that it does write z values,
739          * but not checks for it, so centers remain visible independent order of drawing */
740         if (v3d->zbuf) glDepthFunc(GL_ALWAYS);
741         /* write to near buffer always */
742         glDepthRange(0.0, 0.0);
743         glEnable(GL_BLEND);
744         
745         if (special_color) {
746                 if (selstate == ACTIVE || selstate == SELECT) glColor4ub(0x88, 0xFF, 0xFF, 155);
747
748                 else glColor4ub(0x55, 0xCC, 0xCC, 155);
749         }
750         else {
751                 if (selstate == ACTIVE) UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -80);
752                 else if (selstate == SELECT) UI_ThemeColorShadeAlpha(TH_SELECT, 0, -80);
753                 else if (selstate == DESELECT) UI_ThemeColorShadeAlpha(TH_TRANSFORM, 0, -80);
754         }
755
756         circball_array_fill(verts, co, size, rv3d->viewinv);
757
758         /* enable vertex array */
759         glEnableClientState(GL_VERTEX_ARRAY);
760         glVertexPointer(3, GL_FLOAT, 0, verts);
761
762         /* 1. draw filled, blended polygon */
763         glDrawArrays(GL_POLYGON, 0, CIRCLE_RESOL);
764
765         /* 2. draw outline */
766         UI_ThemeColorShadeAlpha(TH_WIRE, 0, -30);
767         glDrawArrays(GL_LINE_LOOP, 0, CIRCLE_RESOL);
768
769         /* finish up */
770         glDisableClientState(GL_VERTEX_ARRAY);
771
772         glDepthRange(0.0, 1.0);
773         glDisable(GL_BLEND);
774
775         if (v3d->zbuf) glDepthFunc(GL_LEQUAL);
776 }
777
778 /* *********** text drawing for object/particles/armature ************* */
779
780 typedef struct ViewCachedString {
781         struct ViewCachedString *next;
782         float vec[3];
783         union {
784                 unsigned char ub[4];
785                 int pack;
786         } col;
787         short sco[2];
788         short xoffs;
789         short flag;
790         int str_len;
791
792         /* str is allocated past the end */
793         char str[0];
794 } ViewCachedString;
795
796 /* one arena for all 3 string lists */
797 static MemArena         *g_v3d_strings_arena = NULL;
798 static ViewCachedString *g_v3d_strings[3] = {NULL, NULL, NULL};
799 static int g_v3d_string_level = -1;
800
801 void view3d_cached_text_draw_begin(void)
802 {
803         g_v3d_string_level++;
804
805         BLI_assert(g_v3d_string_level >= 0);
806
807         if (g_v3d_string_level == 0) {
808                 BLI_assert(g_v3d_strings_arena == NULL);
809         }
810 }
811
812 void view3d_cached_text_draw_add(const float co[3],
813                                  const char *str, const size_t str_len,
814                                  short xoffs, short flag,
815                                  const unsigned char col[4])
816 {
817         int alloc_len = str_len + 1;
818         ViewCachedString *vos;
819
820         BLI_assert(str_len == strlen(str));
821
822         if (g_v3d_strings_arena == NULL) {
823                 g_v3d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__);
824         }
825
826         vos = BLI_memarena_alloc(g_v3d_strings_arena, sizeof(ViewCachedString) + alloc_len);
827
828         BLI_LINKS_PREPEND(g_v3d_strings[g_v3d_string_level], vos);
829
830         copy_v3_v3(vos->vec, co);
831         copy_v4_v4_char((char *)vos->col.ub, (const char *)col);
832         vos->xoffs = xoffs;
833         vos->flag = flag;
834         vos->str_len = str_len;
835
836         /* allocate past the end */
837         memcpy(vos->str, str, alloc_len);
838 }
839
840 void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, float mat[4][4])
841 {
842         RegionView3D *rv3d = ar->regiondata;
843         ViewCachedString *vos;
844         int tot = 0;
845         
846         BLI_assert(g_v3d_string_level >= 0 && g_v3d_string_level <= 2);
847
848         /* project first and test */
849         for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) {
850                 if (mat && !(vos->flag & V3D_CACHE_TEXT_WORLDSPACE))
851                         mul_m4_v3(mat, vos->vec);
852
853                 if (ED_view3d_project_short_ex(ar,
854                                                (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob,
855                                                (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0,
856                                                vos->vec, vos->sco,
857                                                V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
858                 {
859                         tot++;
860                 }
861                 else {
862                         vos->sco[0] = IS_CLIPPED;
863                 }
864         }
865
866         if (tot) {
867                 int col_pack_prev = 0;
868
869 #if 0
870                 bglMats mats; /* ZBuffer depth vars */
871                 double ux, uy, uz;
872                 float depth;
873
874                 if (v3d->zbuf)
875                         bgl_get_mats(&mats);
876 #endif
877                 if (rv3d->rflag & RV3D_CLIPPING) {
878                         ED_view3d_clipping_disable();
879                 }
880
881                 glMatrixMode(GL_PROJECTION);
882                 glPushMatrix();
883                 glMatrixMode(GL_MODELVIEW);
884                 glPushMatrix();
885                 wmOrtho2_region_ui(ar);
886                 glLoadIdentity();
887                 
888                 if (depth_write) {
889                         if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
890                 }
891                 else {
892                         glDepthMask(0);
893                 }
894                 
895                 for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) {
896                         if (vos->sco[0] != IS_CLIPPED) {
897                                 if (col_pack_prev != vos->col.pack) {
898                                         glColor3ubv(vos->col.ub);
899                                         col_pack_prev = vos->col.pack;
900                                 }
901
902                                 ((vos->flag & V3D_CACHE_TEXT_ASCII) ?
903                                  BLF_draw_default_ascii :
904                                  BLF_draw_default
905                                  )((float)(vos->sco[0] + vos->xoffs),
906                                    (float)(vos->sco[1]),
907                                    (depth_write) ? 0.0f : 2.0f,
908                                    vos->str,
909                                    vos->str_len);
910                         }
911                 }
912
913                 if (depth_write) {
914                         if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
915                 }
916                 else {
917                         glDepthMask(1);
918                 }
919                 
920                 glMatrixMode(GL_PROJECTION);
921                 glPopMatrix();
922                 glMatrixMode(GL_MODELVIEW);
923                 glPopMatrix();
924
925                 if (rv3d->rflag & RV3D_CLIPPING) {
926                         ED_view3d_clipping_enable();
927                 }
928         }
929
930         g_v3d_strings[g_v3d_string_level] = NULL;
931
932         if (g_v3d_string_level == 0) {
933                 if (g_v3d_strings_arena) {
934                         BLI_memarena_free(g_v3d_strings_arena);
935                         g_v3d_strings_arena = NULL;
936                 }
937         }
938
939         g_v3d_string_level--;
940 }
941
942 /* ******************** primitive drawing ******************* */
943
944 /* draws a cube given the scaling of the cube, assuming that
945  * all required matrices have been set (used for drawing empties)
946  */
947 static void drawcube_size(float size)
948 {
949         glBegin(GL_LINE_STRIP);
950         glVertex3f(-size, -size, -size); glVertex3f(-size, -size, size);
951         glVertex3f(-size, size, size); glVertex3f(-size, size, -size);
952
953         glVertex3f(-size, -size, -size); glVertex3f(size, -size, -size);
954         glVertex3f(size, -size, size); glVertex3f(size, size, size);
955
956         glVertex3f(size, size, -size); glVertex3f(size, -size, -size);
957         glEnd();
958
959         glBegin(GL_LINE_STRIP);
960         glVertex3f(-size, -size, size); glVertex3f(size, -size, size);
961         glEnd();
962
963         glBegin(GL_LINE_STRIP);
964         glVertex3f(-size, size, size); glVertex3f(size, size, size);
965         glEnd();
966
967         glBegin(GL_LINE_STRIP);
968         glVertex3f(-size, size, -size); glVertex3f(size, size, -size);
969         glEnd();
970 }
971
972 /* this is an unused (old) cube-drawing function based on a given size */
973 #if 0
974 static void drawcube_size(const float size[3])
975 {
976
977         glPushMatrix();
978         glScalef(size[0],  size[1],  size[2]);
979         
980
981         glBegin(GL_LINE_STRIP);
982         glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
983         glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[6]);
984         glVertex3fv(cube[7]); glVertex3fv(cube[4]);
985         glEnd();
986
987         glBegin(GL_LINE_STRIP);
988         glVertex3fv(cube[1]); glVertex3fv(cube[5]);
989         glEnd();
990
991         glBegin(GL_LINE_STRIP);
992         glVertex3fv(cube[2]); glVertex3fv(cube[6]);
993         glEnd();
994
995         glBegin(GL_LINE_STRIP);
996         glVertex3fv(cube[3]); glVertex3fv(cube[7]);
997         glEnd();
998         
999         glPopMatrix();
1000 }
1001 #endif
1002
1003 static void drawshadbuflimits(Lamp *la, float mat[4][4])
1004 {
1005         float sta[3], end[3], lavec[3];
1006
1007         negate_v3_v3(lavec, mat[2]);
1008         normalize_v3(lavec);
1009
1010         madd_v3_v3v3fl(sta, mat[3], lavec, la->clipsta);
1011         madd_v3_v3v3fl(end, mat[3], lavec, la->clipend);
1012
1013         glBegin(GL_LINE_STRIP);
1014         glVertex3fv(sta);
1015         glVertex3fv(end);
1016         glEnd();
1017
1018         glPointSize(3.0);
1019         bglBegin(GL_POINTS);
1020         bglVertex3fv(sta);
1021         bglVertex3fv(end);
1022         bglEnd();
1023         glPointSize(1.0);
1024 }
1025
1026 static void spotvolume(float lvec[3], float vvec[3], const float inp)
1027 {
1028         /* camera is at 0,0,0 */
1029         float temp[3], plane[3], mat1[3][3], mat2[3][3], mat3[3][3], mat4[3][3], q[4], co, si, angle;
1030
1031         normalize_v3(lvec);
1032         normalize_v3(vvec);             /* is this the correct vector ? */
1033
1034         cross_v3_v3v3(temp, vvec, lvec);      /* equation for a plane through vvec and lvec */
1035         cross_v3_v3v3(plane, lvec, temp);     /* a plane perpendicular to this, parallel with lvec */
1036
1037         /* vectors are exactly aligned, use the X axis, this is arbitrary */
1038         if (normalize_v3(plane) == 0.0f)
1039                 plane[1] = 1.0f;
1040
1041         /* now we've got two equations: one of a cone and one of a plane, but we have
1042          * three unknowns. We remove one unknown by rotating the plane to z=0 (the plane normal) */
1043
1044         /* rotate around cross product vector of (0,0,1) and plane normal, dot product degrees */
1045         /* according definition, we derive cross product is (plane[1],-plane[0],0), en cos = plane[2]);*/
1046
1047         /* translating this comment to english didnt really help me understanding the math! :-) (ton) */
1048         
1049         q[1] =  plane[1];
1050         q[2] = -plane[0];
1051         q[3] =  0;
1052         normalize_v3(&q[1]);
1053
1054         angle = saacos(plane[2]) / 2.0f;
1055         co = cosf(angle);
1056         si = sqrtf(1 - co * co);
1057
1058         q[0] =  co;
1059         q[1] *= si;
1060         q[2] *= si;
1061         q[3] =  0;
1062
1063         quat_to_mat3(mat1, q);
1064
1065         /* rotate lamp vector now over acos(inp) degrees */
1066         copy_v3_v3(vvec, lvec);
1067
1068         unit_m3(mat2);
1069         co = inp;
1070         si = sqrtf(1.0f - inp * inp);
1071
1072         mat2[0][0] =  co;
1073         mat2[1][0] = -si;
1074         mat2[0][1] =  si;
1075         mat2[1][1] =  co;
1076         mul_m3_m3m3(mat3, mat2, mat1);
1077
1078         mat2[1][0] =  si;
1079         mat2[0][1] = -si;
1080         mul_m3_m3m3(mat4, mat2, mat1);
1081         transpose_m3(mat1);
1082
1083         mul_m3_m3m3(mat2, mat1, mat3);
1084         mul_m3_v3(mat2, lvec);
1085         mul_m3_m3m3(mat2, mat1, mat4);
1086         mul_m3_v3(mat2, vvec);
1087
1088         return;
1089 }
1090
1091 static void draw_spot_cone(Lamp *la, float x, float z)
1092 {
1093         z = fabsf(z);
1094
1095         glBegin(GL_TRIANGLE_FAN);
1096         glVertex3f(0.0f, 0.0f, -x);
1097
1098         if (la->mode & LA_SQUARE) {
1099                 glVertex3f(z, z, 0);
1100                 glVertex3f(-z, z, 0);
1101                 glVertex3f(-z, -z, 0);
1102                 glVertex3f(z, -z, 0);
1103                 glVertex3f(z, z, 0);
1104         }
1105         else {
1106                 float angle;
1107                 int a;
1108
1109                 for (a = 0; a < 33; a++) {
1110                         angle = a * M_PI * 2 / (33 - 1);
1111                         glVertex3f(z * cosf(angle), z * sinf(angle), 0);
1112                 }
1113         }
1114
1115         glEnd();
1116 }
1117
1118 static void draw_transp_spot_volume(Lamp *la, float x, float z)
1119 {
1120         glEnable(GL_CULL_FACE);
1121         glEnable(GL_BLEND);
1122         glDepthMask(0);
1123
1124         /* draw backside darkening */
1125         glCullFace(GL_FRONT);
1126
1127         glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
1128         glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
1129
1130         draw_spot_cone(la, x, z);
1131
1132         /* draw front side lighting */
1133         glCullFace(GL_BACK);
1134
1135         glBlendFunc(GL_ONE, GL_ONE);
1136         glColor4f(0.2f, 0.2f, 0.2f, 1.0f);
1137
1138         draw_spot_cone(la, x, z);
1139
1140         /* restore state */
1141         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1142         glDisable(GL_BLEND);
1143         glDepthMask(1);
1144         glDisable(GL_CULL_FACE);
1145         glCullFace(GL_BACK);
1146 }
1147
1148 #ifdef WITH_GAMEENGINE
1149 static void draw_transp_sun_volume(Lamp *la)
1150 {
1151         float box[8][3];
1152
1153         /* construct box */
1154         box[0][0] = box[1][0] = box[2][0] = box[3][0] = -la->shadow_frustum_size;
1155         box[4][0] = box[5][0] = box[6][0] = box[7][0] = +la->shadow_frustum_size;
1156         box[0][1] = box[1][1] = box[4][1] = box[5][1] = -la->shadow_frustum_size;
1157         box[2][1] = box[3][1] = box[6][1] = box[7][1] = +la->shadow_frustum_size;
1158         box[0][2] = box[3][2] = box[4][2] = box[7][2] = -la->clipend;
1159         box[1][2] = box[2][2] = box[5][2] = box[6][2] = -la->clipsta;
1160
1161         /* draw edges */
1162         draw_box(box, false);
1163
1164         /* draw faces */
1165         glEnable(GL_CULL_FACE);
1166         glEnable(GL_BLEND);
1167         glDepthMask(0);
1168
1169         /* draw backside darkening */
1170         glCullFace(GL_FRONT);
1171
1172         glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
1173         glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
1174
1175         draw_box(box, true);
1176
1177         /* draw front side lighting */
1178         glCullFace(GL_BACK);
1179
1180         glBlendFunc(GL_ONE, GL_ONE);
1181         glColor4f(0.2f, 0.2f, 0.2f, 1.0f);
1182
1183         draw_box(box, true);
1184
1185         /* restore state */
1186         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1187         glDisable(GL_BLEND);
1188         glDepthMask(1);
1189         glDisable(GL_CULL_FACE);
1190         glCullFace(GL_BACK);
1191 }
1192 #endif
1193
1194 static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
1195                      const char dt, const short dflag, const unsigned char ob_wire_col[4], const bool is_obact)
1196 {
1197         Object *ob = base->object;
1198         const float pixsize = ED_view3d_pixel_size(rv3d, ob->obmat[3]);
1199         Lamp *la = ob->data;
1200         float vec[3], lvec[3], vvec[3], circrad, x, y, z;
1201         float lampsize;
1202         float imat[4][4];
1203
1204         unsigned char curcol[4];
1205         unsigned char col[4];
1206         /* cone can't be drawn for duplicated lamps, because duplilist would be freed */
1207         /* the moment of view3d_draw_transp() call */
1208         const bool is_view = (rv3d->persp == RV3D_CAMOB && v3d->camera == base->object);
1209         const bool drawcone = ((dt > OB_WIRE) &&
1210                                !(G.f & G_PICKSEL) &&
1211                                (la->type == LA_SPOT) &&
1212                                (la->mode & LA_SHOW_CONE) &&
1213                                !(base->flag & OB_FROMDUPLI) &&
1214                                !is_view);
1215
1216 #ifdef WITH_GAMEENGINE
1217         const bool drawshadowbox = (
1218                 (rv3d->rflag & RV3D_IS_GAME_ENGINE) &&
1219                 (dt > OB_WIRE) &&
1220                 !(G.f & G_PICKSEL) &&
1221                 (la->type == LA_SUN) &&
1222                 ((la->mode & LA_SHAD_BUF) || 
1223                 (la->mode & LA_SHAD_RAY)) &&
1224                 (la->mode & LA_SHOW_SHADOW_BOX) &&
1225                 !(base->flag & OB_FROMDUPLI) &&
1226                 !is_view);
1227 #else
1228         const bool drawshadowbox = false;
1229 #endif
1230
1231         if ((drawcone || drawshadowbox) && !v3d->transp) {
1232                 /* in this case we need to draw delayed */
1233                 ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag);
1234                 return;
1235         }
1236         
1237         /* we first draw only the screen aligned & fixed scale stuff */
1238         glPushMatrix();
1239         glLoadMatrixf(rv3d->viewmat);
1240
1241         /* lets calculate the scale: */
1242         lampsize = pixsize * ((float)U.obcenter_dia * 0.5f);
1243
1244         /* and view aligned matrix: */
1245         copy_m4_m4(imat, rv3d->viewinv);
1246         normalize_v3(imat[0]);
1247         normalize_v3(imat[1]);
1248
1249         /* lamp center */
1250         copy_v3_v3(vec, ob->obmat[3]);
1251
1252         if ((dflag & DRAW_CONSTCOLOR) == 0) {
1253                 /* for AA effects */
1254                 curcol[0] = ob_wire_col[0];
1255                 curcol[1] = ob_wire_col[1];
1256                 curcol[2] = ob_wire_col[2];
1257                 curcol[3] = 154;
1258                 glColor4ubv(curcol);
1259         }
1260
1261         if (lampsize > 0.0f) {
1262
1263                 if ((dflag & DRAW_CONSTCOLOR) == 0) {
1264                         if (ob->id.us > 1) {
1265                                 if (is_obact || (ob->flag & SELECT)) {
1266                                         glColor4ub(0x88, 0xFF, 0xFF, 155);
1267                                 }
1268                                 else {
1269                                         glColor4ub(0x77, 0xCC, 0xCC, 155);
1270                                 }
1271                         }
1272                 }
1273                 
1274                 /* Inner Circle */
1275                 glEnable(GL_BLEND);
1276                 drawcircball(GL_LINE_LOOP, vec, lampsize, imat);
1277                 glDisable(GL_BLEND);
1278                 drawcircball(GL_POLYGON, vec, lampsize, imat);
1279                 
1280                 /* restore */
1281                 if ((dflag & DRAW_CONSTCOLOR) == 0) {
1282                         if (ob->id.us > 1)
1283                                 glColor4ubv(curcol);
1284                 }
1285
1286                 /* Outer circle */
1287                 circrad = 3.0f * lampsize;
1288                 setlinestyle(3);
1289
1290                 drawcircball(GL_LINE_LOOP, vec, circrad, imat);
1291
1292                 /* draw dashed outer circle if shadow is on. remember some lamps can't have certain shadows! */
1293                 if (la->type != LA_HEMI) {
1294                         if ((la->mode & LA_SHAD_RAY) || ((la->mode & LA_SHAD_BUF) && (la->type == LA_SPOT))) {
1295                                 drawcircball(GL_LINE_LOOP, vec, circrad + 3.0f * pixsize, imat);
1296                         }
1297                 }
1298         }
1299         else {
1300                 setlinestyle(3);
1301                 circrad = 0.0f;
1302         }
1303         
1304         /* draw the pretty sun rays */
1305         if (la->type == LA_SUN) {
1306                 float v1[3], v2[3], mat[3][3];
1307                 short axis;
1308                 
1309                 /* setup a 45 degree rotation matrix */
1310                 axis_angle_normalized_to_mat3_ex(mat, imat[2], M_SQRT1_2, M_SQRT1_2);
1311
1312                 /* vectors */
1313                 mul_v3_v3fl(v1, imat[0], circrad * 1.2f);
1314                 mul_v3_v3fl(v2, imat[0], circrad * 2.5f);
1315                 
1316                 /* center */
1317                 glTranslatef(vec[0], vec[1], vec[2]);
1318                 
1319                 setlinestyle(3);
1320                 
1321                 glBegin(GL_LINES);
1322                 for (axis = 0; axis < 8; axis++) {
1323                         glVertex3fv(v1);
1324                         glVertex3fv(v2);
1325                         mul_m3_v3(mat, v1);
1326                         mul_m3_v3(mat, v2);
1327                 }
1328                 glEnd();
1329                 
1330                 glTranslatef(-vec[0], -vec[1], -vec[2]);
1331
1332         }
1333         
1334         if (la->type == LA_LOCAL) {
1335                 if (la->mode & LA_SPHERE) {
1336                         drawcircball(GL_LINE_LOOP, vec, la->dist, imat);
1337                 }
1338         }
1339         
1340         glPopMatrix();  /* back in object space */
1341         zero_v3(vec);
1342         
1343         if (is_view) {
1344                 /* skip drawing extra info */
1345         }
1346         else if ((la->type == LA_SPOT) || (la->type == LA_YF_PHOTON)) {
1347
1348                 copy_v3_fl3(lvec, 0.0f, 0.0f, 1.0f);
1349                 copy_v3_fl3(vvec, rv3d->persmat[0][2], rv3d->persmat[1][2], rv3d->persmat[2][2]);
1350                 mul_transposed_mat3_m4_v3(ob->obmat, vvec);
1351
1352                 x = -la->dist;
1353                 y = cosf(la->spotsize * 0.5f);
1354                 z = x * sqrtf(1.0f - y * y);
1355
1356                 spotvolume(lvec, vvec, y);
1357                 mul_v3_fl(lvec, x);
1358                 mul_v3_fl(vvec, x);
1359
1360                 /* draw the angled sides of the cone */
1361                 glBegin(GL_LINE_STRIP);
1362                 glVertex3fv(vvec);
1363                 glVertex3fv(vec);
1364                 glVertex3fv(lvec);
1365                 glEnd();
1366                 
1367                 x *= y;
1368
1369                 /* draw the circle/square at the end of the cone */
1370                 glTranslatef(0.0, 0.0, x);
1371                 if (la->mode & LA_SQUARE) {
1372                         float tvec[3];
1373                         float z_abs = fabsf(z);
1374
1375                         tvec[0] = tvec[1] = z_abs;
1376                         tvec[2] = 0.0;
1377
1378                         glBegin(GL_LINE_LOOP);
1379                         glVertex3fv(tvec);
1380                         tvec[1] = -z_abs; /* neg */
1381                         glVertex3fv(tvec);
1382                         tvec[0] = -z_abs; /* neg */
1383                         glVertex3fv(tvec);
1384                         tvec[1] = z_abs; /* pos */
1385                         glVertex3fv(tvec);
1386                         glEnd();
1387                 }
1388                 else {
1389                         circ(0.0, 0.0, fabsf(z));
1390                 }
1391
1392                 /* draw the circle/square representing spotbl */
1393                 if (la->type == LA_SPOT) {
1394                         float spotblcirc = fabsf(z) * (1.0f - pow2f(la->spotblend));
1395                         /* hide line if it is zero size or overlaps with outer border,
1396                          * previously it adjusted to always to show it but that seems
1397                          * confusing because it doesn't show the actual blend size */
1398                         if (spotblcirc != 0 && spotblcirc != fabsf(z))
1399                                 circ(0.0, 0.0, spotblcirc);
1400                 }
1401
1402                 if (drawcone)
1403                         draw_transp_spot_volume(la, x, z);
1404
1405                 /* draw clip start, useful for wide cones where its not obvious where the start is */
1406                 glTranslatef(0.0, 0.0, -x);  /* reverse translation above */
1407                 if (la->type == LA_SPOT && (la->mode & LA_SHAD_BUF)) {
1408                         float lvec_clip[3];
1409                         float vvec_clip[3];
1410                         float clipsta_fac = la->clipsta / -x;
1411
1412                         interp_v3_v3v3(lvec_clip, vec, lvec, clipsta_fac);
1413                         interp_v3_v3v3(vvec_clip, vec, vvec, clipsta_fac);
1414
1415                         glBegin(GL_LINE_STRIP);
1416                         glVertex3fv(lvec_clip);
1417                         glVertex3fv(vvec_clip);
1418                         glEnd();
1419                 }
1420                 /* Else, draw spot direction (using distance as end limit, same as for Area lamp). */
1421                 else {
1422                         glBegin(GL_LINE_STRIP);
1423                         glVertex3f(0.0, 0.0, -circrad);
1424                         glVertex3f(0.0, 0.0, -la->dist);
1425                         glEnd();
1426                 }
1427         }
1428         else if (ELEM(la->type, LA_HEMI, LA_SUN)) {
1429                 
1430                 /* draw the line from the circle along the dist */
1431                 glBegin(GL_LINE_STRIP);
1432                 vec[2] = -circrad;
1433                 glVertex3fv(vec);
1434                 vec[2] = -la->dist;
1435                 glVertex3fv(vec);
1436                 glEnd();
1437                 
1438                 if (la->type == LA_HEMI) {
1439                         /* draw the hemisphere curves */
1440                         short axis, steps, dir;
1441                         float outdist, zdist, mul;
1442                         zero_v3(vec);
1443                         outdist = 0.14; mul = 1.4; dir = 1;
1444                         
1445                         setlinestyle(4);
1446                         /* loop over the 4 compass points, and draw each arc as a LINE_STRIP */
1447                         for (axis = 0; axis < 4; axis++) {
1448                                 float v[3] = {0.0, 0.0, 0.0};
1449                                 zdist = 0.02;
1450                                 
1451                                 glBegin(GL_LINE_STRIP);
1452                                 
1453                                 for (steps = 0; steps < 6; steps++) {
1454                                         if (axis == 0 || axis == 1) {       /* x axis up, x axis down */
1455                                                 /* make the arcs start at the edge of the energy circle */
1456                                                 if (steps == 0) v[0] = dir * circrad;
1457                                                 else v[0] = v[0] + dir * (steps * outdist);
1458                                         }
1459                                         else if (axis == 2 || axis == 3) {      /* y axis up, y axis down */
1460                                                 /* make the arcs start at the edge of the energy circle */
1461                                                 v[1] = (steps == 0) ? (dir * circrad) : (v[1] + dir * (steps * outdist));
1462                                         }
1463
1464                                         v[2] = v[2] - steps * zdist;
1465                                         
1466                                         glVertex3fv(v);
1467                                         
1468                                         zdist = zdist * mul;
1469                                 }
1470                                 
1471                                 glEnd();
1472                                 /* flip the direction */
1473                                 dir = -dir;
1474                         }
1475                 }
1476
1477 #ifdef WITH_GAMEENGINE
1478                 if (drawshadowbox) {
1479                         draw_transp_sun_volume(la);
1480                 }
1481 #endif
1482
1483         }
1484         else if (la->type == LA_AREA) {
1485                 setlinestyle(3);
1486                 if (la->area_shape == LA_AREA_SQUARE)
1487                         fdrawbox(-la->area_size * 0.5f, -la->area_size * 0.5f, la->area_size * 0.5f, la->area_size * 0.5f);
1488                 else if (la->area_shape == LA_AREA_RECT)
1489                         fdrawbox(-la->area_size * 0.5f, -la->area_sizey * 0.5f, la->area_size * 0.5f, la->area_sizey * 0.5f);
1490
1491                 glBegin(GL_LINE_STRIP);
1492                 glVertex3f(0.0, 0.0, -circrad);
1493                 glVertex3f(0.0, 0.0, -la->dist);
1494                 glEnd();
1495         }
1496         
1497         /* and back to viewspace */
1498         glPushMatrix();
1499         glLoadMatrixf(rv3d->viewmat);
1500         copy_v3_v3(vec, ob->obmat[3]);
1501
1502         setlinestyle(0);
1503         
1504         if ((la->type == LA_SPOT) && (la->mode & LA_SHAD_BUF) && (is_view == false)) {
1505                 drawshadbuflimits(la, ob->obmat);
1506         }
1507         
1508         if ((dflag & DRAW_CONSTCOLOR) == 0) {
1509                 UI_GetThemeColor4ubv(TH_LAMP, col);
1510                 glColor4ubv(col);
1511         }
1512
1513         glEnable(GL_BLEND);
1514         
1515         if (vec[2] > 0) vec[2] -= circrad;
1516         else vec[2] += circrad;
1517         
1518         glBegin(GL_LINE_STRIP);
1519         glVertex3fv(vec);
1520         vec[2] = 0;
1521         glVertex3fv(vec);
1522         glEnd();
1523         
1524         glPointSize(2.0);
1525         glBegin(GL_POINTS);
1526         glVertex3fv(vec);
1527         glEnd();
1528         glPointSize(1.0);
1529         
1530         glDisable(GL_BLEND);
1531         
1532         if ((dflag & DRAW_CONSTCOLOR) == 0) {
1533                 /* restore for drawing extra stuff */
1534                 glColor3ubv(ob_wire_col);
1535         }
1536         /* and finally back to org object space! */
1537         glPopMatrix();
1538 }
1539
1540 static void draw_limit_line(float sta, float end, const short dflag, unsigned int col)
1541 {
1542         glBegin(GL_LINES);
1543         glVertex3f(0.0, 0.0, -sta);
1544         glVertex3f(0.0, 0.0, -end);
1545         glEnd();
1546
1547         if (!(dflag & DRAW_PICKING)) {
1548                 glPointSize(3.0);
1549                 glBegin(GL_POINTS);
1550                 if ((dflag & DRAW_CONSTCOLOR) == 0) {
1551                         cpack(col);
1552                 }
1553                 glVertex3f(0.0, 0.0, -sta);
1554                 glVertex3f(0.0, 0.0, -end);
1555                 glEnd();
1556                 glPointSize(1.0);
1557         }
1558 }
1559
1560
1561 /* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */
1562 /* qdn: now also enabled for Blender to set focus point for defocus composite node */
1563 static void draw_focus_cross(float dist, float size)
1564 {
1565         glBegin(GL_LINES);
1566         glVertex3f(-size, 0.0f, -dist);
1567         glVertex3f(size, 0.0f, -dist);
1568         glVertex3f(0.0f, -size, -dist);
1569         glVertex3f(0.0f, size, -dist);
1570         glEnd();
1571 }
1572
1573 #ifdef VIEW3D_CAMERA_BORDER_HACK
1574 unsigned char view3d_camera_border_hack_col[3];
1575 bool view3d_camera_border_hack_test = false;
1576 #endif
1577
1578 /* ****************** draw clip data *************** */
1579
1580 static void draw_bundle_sphere(void)
1581 {
1582         static GLuint displist = 0;
1583
1584         if (displist == 0) {
1585                 GLUquadricObj *qobj;
1586
1587                 displist = glGenLists(1);
1588                 glNewList(displist, GL_COMPILE);
1589
1590                 qobj = gluNewQuadric();
1591                 gluQuadricDrawStyle(qobj, GLU_FILL);
1592                 glShadeModel(GL_SMOOTH);
1593                 gluSphere(qobj, 0.05, 8, 8);
1594                 glShadeModel(GL_FLAT);
1595                 gluDeleteQuadric(qobj);
1596
1597                 glEndList();
1598         }
1599
1600         glCallList(displist);
1601 }
1602
1603 static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D *v3d,
1604                                                 MovieClip *clip, MovieTrackingObject *tracking_object,
1605                                                 const short dflag, const unsigned char ob_wire_col[4],
1606                                                 int *global_track_index, bool draw_selected)
1607 {
1608         MovieTracking *tracking = &clip->tracking;
1609         MovieTrackingTrack *track;
1610         float mat[4][4], imat[4][4];
1611         unsigned char col_unsel[4], col_sel[4];
1612         int tracknr = *global_track_index;
1613         ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object);
1614         float camera_size[3];
1615
1616         UI_GetThemeColor4ubv(TH_TEXT, col_unsel);
1617         UI_GetThemeColor4ubv(TH_SELECT, col_sel);
1618
1619         BKE_tracking_get_camera_object_matrix(scene, base->object, mat);
1620
1621         /* we're compensating camera size for bundles size,
1622          * to make it so bundles are always displayed with the same size */
1623         copy_v3_v3(camera_size, base->object->size);
1624         if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0)
1625                 mul_v3_fl(camera_size, tracking_object->scale);
1626
1627         glPushMatrix();
1628
1629         if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
1630                 /* current ogl matrix is translated in camera space, bundles should
1631                  * be rendered in world space, so camera matrix should be "removed"
1632                  * from current ogl matrix */
1633                 invert_m4_m4(imat, base->object->obmat);
1634
1635                 glMultMatrixf(imat);
1636                 glMultMatrixf(mat);
1637         }
1638         else {
1639                 float obmat[4][4];
1640                 int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra);
1641
1642                 BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, obmat);
1643
1644                 invert_m4_m4(imat, obmat);
1645                 glMultMatrixf(imat);
1646         }
1647
1648         for (track = tracksbase->first; track; track = track->next) {
1649                 bool selected = TRACK_SELECTED(track);
1650
1651                 if (draw_selected && !selected)
1652                         continue;
1653
1654                 if ((track->flag & TRACK_HAS_BUNDLE) == 0)
1655                         continue;
1656
1657                 if (dflag & DRAW_PICKING)
1658                         GPU_select_load_id(base->selcol + (tracknr << 16));
1659
1660                 glPushMatrix();
1661                 glTranslatef(track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
1662                 glScalef(v3d->bundle_size / 0.05f / camera_size[0],
1663                          v3d->bundle_size / 0.05f / camera_size[1],
1664                          v3d->bundle_size / 0.05f / camera_size[2]);
1665
1666                 if (v3d->drawtype == OB_WIRE) {
1667                         glDisable(GL_LIGHTING);
1668
1669                         if ((dflag & DRAW_CONSTCOLOR) == 0) {
1670                                 if (selected && (track->flag & TRACK_CUSTOMCOLOR) == 0) {
1671                                         glColor3ubv(ob_wire_col);
1672                                 }
1673                                 else {
1674                                         glColor3fv(track->color);
1675                                 }
1676                         }
1677
1678                         drawaxes(0.05f, v3d->bundle_drawtype);
1679
1680                         glEnable(GL_LIGHTING);
1681                 }
1682                 else if (v3d->drawtype > OB_WIRE) {
1683                         if (v3d->bundle_drawtype == OB_EMPTY_SPHERE) {
1684                                 /* selection outline */
1685                                 if (selected) {
1686                                         if ((dflag & DRAW_CONSTCOLOR) == 0) {
1687                                                 glColor3ubv(ob_wire_col);
1688                                         }
1689
1690                                         glLineWidth(2.0f);
1691                                         glDisable(GL_LIGHTING);
1692                                         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1693
1694                                         draw_bundle_sphere();
1695
1696                                         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1697                                         glEnable(GL_LIGHTING);
1698                                         glLineWidth(1.0f);
1699                                 }
1700
1701                                 if ((dflag & DRAW_CONSTCOLOR) == 0) {
1702                                         if (track->flag & TRACK_CUSTOMCOLOR) glColor3fv(track->color);
1703                                         else UI_ThemeColor(TH_BUNDLE_SOLID);
1704                                 }
1705
1706                                 draw_bundle_sphere();
1707                         }
1708                         else {
1709                                 glDisable(GL_LIGHTING);
1710
1711                                 if ((dflag & DRAW_CONSTCOLOR) == 0) {
1712                                         if (selected) {
1713                                                 glColor3ubv(ob_wire_col);
1714                                         }
1715                                         else {
1716                                                 if (track->flag & TRACK_CUSTOMCOLOR) glColor3fv(track->color);
1717                                                 else UI_ThemeColor(TH_WIRE);
1718                                         }
1719                                 }
1720
1721                                 drawaxes(0.05f, v3d->bundle_drawtype);
1722
1723                                 glEnable(GL_LIGHTING);
1724                         }
1725                 }
1726
1727                 glPopMatrix();
1728
1729                 if ((dflag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLENAME)) {
1730                         float pos[3];
1731
1732                         mul_v3_m4v3(pos, mat, track->bundle_pos);
1733                         view3d_cached_text_draw_add(pos,
1734                                                     track->name, strlen(track->name),
1735                                                     10, V3D_CACHE_TEXT_GLOBALSPACE,
1736                                                     selected ? col_sel : col_unsel);
1737                 }
1738
1739                 tracknr++;
1740         }
1741
1742         if ((dflag & DRAW_PICKING) == 0) {
1743                 if ((v3d->flag2 & V3D_SHOW_CAMERAPATH) && (tracking_object->flag & TRACKING_OBJECT_CAMERA)) {
1744                         MovieTrackingReconstruction *reconstruction;
1745                         reconstruction = BKE_tracking_object_get_reconstruction(tracking, tracking_object);
1746
1747                         if (reconstruction->camnr) {
1748                                 MovieReconstructedCamera *camera = reconstruction->cameras;
1749                                 int a = 0;
1750
1751                                 glDisable(GL_LIGHTING);
1752                                 UI_ThemeColor(TH_CAMERA_PATH);
1753                                 glLineWidth(2.0f);
1754
1755                                 glBegin(GL_LINE_STRIP);
1756                                 for (a = 0; a < reconstruction->camnr; a++, camera++) {
1757                                         glVertex3fv(camera->mat[3]);
1758                                 }
1759                                 glEnd();
1760
1761                                 glLineWidth(1.0f);
1762                                 glEnable(GL_LIGHTING);
1763                         }
1764                 }
1765         }
1766
1767         glPopMatrix();
1768
1769         *global_track_index = tracknr;
1770 }
1771
1772 static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip,
1773                                          const short dflag, const unsigned char ob_wire_col[4],
1774                                          const bool draw_selected)
1775 {
1776         MovieTracking *tracking = &clip->tracking;
1777         MovieTrackingObject *tracking_object;
1778         int global_track_index = 1;
1779
1780         if ((v3d->flag2 & V3D_SHOW_RECONSTRUCTION) == 0)
1781                 return;
1782
1783         if (v3d->flag2 & V3D_RENDER_OVERRIDE)
1784                 return;
1785
1786         glEnable(GL_LIGHTING);
1787         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
1788         glEnable(GL_COLOR_MATERIAL);
1789         glShadeModel(GL_SMOOTH);
1790
1791         tracking_object = tracking->objects.first;
1792         while (tracking_object) {
1793                 draw_viewport_object_reconstruction(scene, base, v3d, clip, tracking_object,
1794                                                     dflag, ob_wire_col, &global_track_index, draw_selected);
1795
1796                 tracking_object = tracking_object->next;
1797         }
1798
1799         /* restore */
1800         glShadeModel(GL_FLAT);
1801         glDisable(GL_COLOR_MATERIAL);
1802         glDisable(GL_LIGHTING);
1803
1804         if ((dflag & DRAW_CONSTCOLOR) == 0) {
1805                 glColor3ubv(ob_wire_col);
1806         }
1807
1808         if (dflag & DRAW_PICKING)
1809                 GPU_select_load_id(base->selcol);
1810 }
1811
1812 static void drawcamera_volume(float near_plane[4][3], float far_plane[4][3], const GLenum mode)
1813 {
1814         glBegin(mode);
1815         glVertex3fv(near_plane[0]);
1816         glVertex3fv(far_plane[0]);
1817         glVertex3fv(far_plane[1]);
1818         glVertex3fv(near_plane[1]);
1819         glEnd();
1820
1821         glBegin(mode);
1822         glVertex3fv(near_plane[1]);
1823         glVertex3fv(far_plane[1]);
1824         glVertex3fv(far_plane[2]);
1825         glVertex3fv(near_plane[2]);
1826         glEnd();
1827
1828         glBegin(mode);
1829         glVertex3fv(near_plane[2]);
1830         glVertex3fv(near_plane[1]);
1831         glVertex3fv(far_plane[1]);
1832         glVertex3fv(far_plane[2]);
1833         glEnd();
1834
1835         glBegin(mode);
1836         glVertex3fv(far_plane[0]);
1837         glVertex3fv(near_plane[0]);
1838         glVertex3fv(near_plane[3]);
1839         glVertex3fv(far_plane[3]);
1840         glEnd();
1841 }
1842
1843 /* camera frame */
1844 static void drawcamera_frame(float vec[4][3], const GLenum mode)
1845 {
1846         glBegin(mode);
1847         glVertex3fv(vec[0]);
1848         glVertex3fv(vec[1]);
1849         glVertex3fv(vec[2]);
1850         glVertex3fv(vec[3]);
1851         glEnd();
1852 }
1853
1854 /* center point to camera frame */
1855 static void drawcamera_framelines(float vec[4][3], float origin[3])
1856 {
1857         glBegin(GL_LINE_STRIP);
1858         glVertex3fv(vec[1]);
1859         glVertex3fv(origin);
1860         glVertex3fv(vec[0]);
1861         glVertex3fv(vec[3]);
1862         glVertex3fv(origin);
1863         glVertex3fv(vec[2]);
1864         glEnd();
1865 }
1866
1867 static bool drawcamera_is_stereo3d(Scene *scene, View3D *v3d, Object *ob)
1868 {
1869         return (ob == v3d->camera) &&
1870                 (scene->r.scemode & R_MULTIVIEW) != 0 &&
1871                 (v3d->stereo3d_flag);
1872 }
1873
1874 static void drawcamera_stereo3d(
1875         Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const Camera *cam,
1876         float vec[4][3], float drawsize, const float scale[3])
1877 {
1878         int i, j;
1879         float obmat[4][4];
1880         float vec_lr[2][4][3];
1881         const float fac = (cam->stereo.pivot == CAM_S3D_PIVOT_CENTER) ? 2.0f : 1.0f;
1882         float origin[2][3] = {{0}};
1883         float tvec[3];
1884         const Camera *cam_lr[2];
1885         const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
1886
1887         const bool is_stereo3d_cameras = (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS) && (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D);
1888         const bool is_stereo3d_plane = (v3d->stereo3d_flag & V3D_S3D_DISPPLANE) && (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D);
1889         const bool is_stereo3d_volume = (v3d->stereo3d_flag & V3D_S3D_DISPVOLUME);
1890
1891         zero_v3(tvec);
1892
1893         glPushMatrix();
1894
1895         for (i = 0; i < 2; i++) {
1896                 ob = BKE_camera_multiview_render(scene, ob, names[i]);
1897                 cam_lr[i] = ob->data;
1898
1899                 glLoadMatrixf(rv3d->viewmat);
1900                 BKE_camera_multiview_model_matrix(&scene->r, ob, names[i], obmat);
1901                 glMultMatrixf(obmat);
1902
1903                 copy_m3_m3(vec_lr[i], vec);
1904                 copy_v3_v3(vec_lr[i][3], vec[3]);
1905
1906                 if (cam->stereo.convergence_mode == CAM_S3D_OFFAXIS) {
1907                         const float shift_x =
1908                                 ((BKE_camera_multiview_shift_x(&scene->r, ob, names[i]) - cam->shiftx) *
1909                                  (drawsize * scale[0] * fac));
1910
1911                         for (j = 0; j < 4; j++) {
1912                                 vec_lr[i][j][0] += shift_x;
1913                         }
1914                 }
1915
1916                 if (is_stereo3d_cameras) {
1917                         /* camera frame */
1918                         drawcamera_frame(vec_lr[i], GL_LINE_LOOP);
1919
1920                         /* center point to camera frame */
1921                         drawcamera_framelines(vec_lr[i], tvec);
1922                 }
1923
1924                 /* connecting line */
1925                 mul_m4_v3(obmat, origin[i]);
1926
1927                 /* convergence plane */
1928                 if (is_stereo3d_plane || is_stereo3d_volume) {
1929                         for (j = 0; j < 4; j++) {
1930                                 mul_m4_v3(obmat, vec_lr[i][j]);
1931                         }
1932                 }
1933         }
1934
1935
1936         /* the remaining drawing takes place in the view space */
1937         glLoadMatrixf(rv3d->viewmat);
1938
1939         if (is_stereo3d_cameras) {
1940                 /* draw connecting lines */
1941                 glPushAttrib(GL_ENABLE_BIT);
1942
1943                 glLineStipple(2, 0xAAAA);
1944                 glEnable(GL_LINE_STIPPLE);
1945
1946                 glBegin(GL_LINES);
1947                 glVertex3fv(origin[0]);
1948                 glVertex3fv(origin[1]);
1949                 glEnd();
1950                 glPopAttrib();
1951         }
1952
1953         /* draw convergence plane*/
1954         if (is_stereo3d_plane) {
1955                 float axis_center[3], screen_center[3];
1956                 float world_plane[4][3];
1957                 float local_plane[4][3];
1958                 float offset;
1959
1960                 mid_v3_v3v3(axis_center, origin[0], origin[1]);
1961
1962                 for (i = 0; i < 4; i++) {
1963                         mid_v3_v3v3(world_plane[i], vec_lr[0][i], vec_lr[1][i]);
1964                         sub_v3_v3v3(local_plane[i], world_plane[i], axis_center);
1965                 }
1966
1967                 mid_v3_v3v3(screen_center, world_plane[0], world_plane[2]);
1968                 offset = cam->stereo.convergence_distance / len_v3v3(screen_center, axis_center);
1969
1970                 for (i = 0; i < 4; i++) {
1971                         mul_v3_fl(local_plane[i], offset);
1972                         add_v3_v3(local_plane[i], axis_center);
1973                 }
1974
1975                 glColor3f(0.0f, 0.0f, 0.0f);
1976
1977                 /* camera frame */
1978                 drawcamera_frame(local_plane, GL_LINE_LOOP);
1979
1980                 if (v3d->stereo3d_convergence_alpha > 0.0f) {
1981                         glEnable(GL_BLEND);
1982                         glDepthMask(0);  /* disable write in zbuffer, needed for nice transp */
1983
1984                         glColor4f(0.0f, 0.0f, 0.0f, v3d->stereo3d_convergence_alpha);
1985
1986                         drawcamera_frame(local_plane, GL_QUADS);
1987
1988                         glDisable(GL_BLEND);
1989                         glDepthMask(1);  /* restore write in zbuffer */
1990                 }
1991         }
1992
1993         /* draw convergence plane*/
1994         if (is_stereo3d_volume) {
1995                 float screen_center[3];
1996                 float near_plane[4][3], far_plane[4][3];
1997                 float offset;
1998                 int j;
1999
2000                 for (i = 0; i < 2; i++) {
2001                         mid_v3_v3v3(screen_center, vec_lr[i][0], vec_lr[i][2]);
2002
2003                         offset = len_v3v3(screen_center, origin[i]);
2004
2005                         for (j = 0; j < 4; j++) {
2006                                 sub_v3_v3v3(near_plane[j], vec_lr[i][j], origin[i]);
2007                                 mul_v3_fl(near_plane[j], cam_lr[i]->clipsta / offset);
2008                                 add_v3_v3(near_plane[j], origin[i]);
2009
2010                                 sub_v3_v3v3(far_plane[j], vec_lr[i][j], origin[i]);
2011                                 mul_v3_fl(far_plane[j], cam_lr[i]->clipend / offset);
2012                                 add_v3_v3(far_plane[j], origin[i]);
2013                         }
2014
2015                         /* camera frame */
2016                         glColor3f(0.0f, 0.0f, 0.0f);
2017
2018                         drawcamera_frame(near_plane, GL_LINE_LOOP);
2019                         drawcamera_frame(far_plane, GL_LINE_LOOP);
2020                         drawcamera_volume(near_plane, far_plane, GL_LINE_LOOP);
2021
2022                         if (v3d->stereo3d_volume_alpha > 0.0f) {
2023                                 glEnable(GL_BLEND);
2024                                 glDepthMask(0);  /* disable write in zbuffer, needed for nice transp */
2025
2026                                 if (i == 0)
2027                                         glColor4f(0.0f, 1.0f, 1.0f, v3d->stereo3d_volume_alpha);
2028                                 else
2029                                         glColor4f(1.0f, 0.0f, 0.0f, v3d->stereo3d_volume_alpha);
2030
2031                                 drawcamera_frame(near_plane, GL_QUADS);
2032                                 drawcamera_frame(far_plane, GL_QUADS);
2033                                 drawcamera_volume(near_plane, far_plane, GL_QUADS);
2034
2035                                 glDisable(GL_BLEND);
2036                                 glDepthMask(1);  /* restore write in zbuffer */
2037                         }
2038                 }
2039         }
2040
2041         glPopMatrix();
2042 }
2043
2044 /* flag similar to draw_object() */
2045 static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
2046                        const short dflag, const unsigned char ob_wire_col[4])
2047 {
2048         /* a standing up pyramid with (0,0,0) as top */
2049         Camera *cam;
2050         Object *ob = base->object;
2051         float tvec[3];
2052         float vec[4][3], asp[2], shift[2], scale[3];
2053         int i;
2054         float drawsize;
2055         const bool is_view = (rv3d->persp == RV3D_CAMOB && ob == v3d->camera);
2056         MovieClip *clip = BKE_object_movieclip_get(scene, base->object, false);
2057
2058         const bool is_stereo3d = drawcamera_is_stereo3d(scene, v3d, ob);
2059         const bool is_stereo3d_cameras = (ob == scene->camera) &&
2060                                          (scene->r.scemode & R_MULTIVIEW) &&
2061                                          (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) &&
2062                                          (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS);
2063
2064         /* draw data for movie clip set as active for scene */
2065         if (clip) {
2066                 draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_wire_col, false);
2067                 draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_wire_col, true);
2068         }
2069
2070 #ifdef VIEW3D_CAMERA_BORDER_HACK
2071         if (is_view && !(G.f & G_PICKSEL)) {
2072                 if ((dflag & DRAW_CONSTCOLOR) == 0) {
2073                         view3d_camera_border_hack_col[0] = ob_wire_col[0];
2074                         view3d_camera_border_hack_col[1] = ob_wire_col[1];
2075                         view3d_camera_border_hack_col[2] = ob_wire_col[2];
2076                 }
2077                 else {
2078                         float col[4];
2079                         glGetFloatv(GL_CURRENT_COLOR, col);
2080                         rgb_float_to_uchar(view3d_camera_border_hack_col, col);
2081                 }
2082                 view3d_camera_border_hack_test = true;
2083                 return;
2084         }
2085 #endif
2086
2087         cam = ob->data;
2088
2089         scale[0] = 1.0f / len_v3(ob->obmat[0]);
2090         scale[1] = 1.0f / len_v3(ob->obmat[1]);
2091         scale[2] = 1.0f / len_v3(ob->obmat[2]);
2092
2093         BKE_camera_view_frame_ex(scene, cam, cam->drawsize, is_view, scale,
2094                                  asp, shift, &drawsize, vec);
2095
2096         glDisable(GL_LIGHTING);
2097         glDisable(GL_CULL_FACE);
2098
2099         /* camera frame */
2100         if (!is_stereo3d_cameras)
2101                 drawcamera_frame(vec, GL_LINE_LOOP);
2102
2103         if (is_view)
2104                 return;
2105
2106         zero_v3(tvec);
2107
2108         /* center point to camera frame */
2109         if (!is_stereo3d_cameras)
2110                 drawcamera_framelines(vec, tvec);
2111
2112         /* arrow on top */
2113         tvec[2] = vec[1][2]; /* copy the depth */
2114
2115         /* draw an outline arrow for inactive cameras and filled
2116          * for active cameras. We actually draw both outline+filled
2117          * for active cameras so the wire can be seen side-on */
2118         for (i = 0; i < 2; i++) {
2119                 if (i == 0) glBegin(GL_LINE_LOOP);
2120                 else if (i == 1 && (ob == v3d->camera)) glBegin(GL_TRIANGLES);
2121                 else break;
2122
2123                 tvec[0] = shift[0] + ((-0.7f * drawsize) * scale[0]);
2124                 tvec[1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]);
2125                 glVertex3fv(tvec); /* left */
2126                 
2127                 tvec[0] = shift[0] + ((0.7f * drawsize) * scale[0]);
2128                 glVertex3fv(tvec); /* right */
2129                 
2130                 tvec[0] = shift[0];
2131                 tvec[1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]);
2132                 glVertex3fv(tvec); /* top */
2133
2134                 glEnd();
2135         }
2136
2137         if ((dflag & DRAW_SCENESET) == 0) {
2138                 if (cam->flag & (CAM_SHOWLIMITS | CAM_SHOWMIST)) {
2139                         float nobmat[4][4];
2140
2141                         /* draw in normalized object matrix space */
2142                         copy_m4_m4(nobmat, ob->obmat);
2143                         normalize_m4(nobmat);
2144
2145                         glPushMatrix();
2146                         glLoadMatrixf(rv3d->viewmat);
2147                         glMultMatrixf(nobmat);
2148
2149                         if (cam->flag & CAM_SHOWLIMITS) {
2150                                 draw_limit_line(cam->clipsta, cam->clipend, dflag, 0x77FFFF);
2151                                 /* qdn: was yafray only, now also enabled for Blender to be used with defocus composite node */
2152                                 draw_focus_cross(BKE_camera_object_dof_distance(ob), cam->drawsize);
2153                         }
2154
2155                         if (cam->flag & CAM_SHOWMIST) {
2156                                 World *world = scene->world;
2157                                 if (world) {
2158                                         draw_limit_line(world->miststa, world->miststa + world->mistdist, dflag, 0xFFFFFF);
2159                                 }
2160                         }
2161                         glPopMatrix();
2162                 }
2163         }
2164
2165         /* stereo cameras drawing */
2166         if (is_stereo3d) {
2167                 drawcamera_stereo3d(scene, v3d, rv3d, ob, cam, vec, drawsize, scale);
2168         }
2169 }
2170
2171 /* flag similar to draw_object() */
2172 static void drawspeaker(Scene *UNUSED(scene), View3D *UNUSED(v3d), RegionView3D *UNUSED(rv3d),
2173                         Object *UNUSED(ob), int UNUSED(flag))
2174 {
2175         float vec[3];
2176         int i, j;
2177
2178         glEnable(GL_BLEND);
2179
2180         for (j = 0; j < 3; j++) {
2181                 vec[2] = 0.25f * j - 0.125f;
2182
2183                 glBegin(GL_LINE_LOOP);
2184                 for (i = 0; i < 16; i++) {
2185                         vec[0] = cosf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
2186                         vec[1] = sinf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
2187                         glVertex3fv(vec);
2188                 }
2189                 glEnd();
2190         }
2191
2192         for (j = 0; j < 4; j++) {
2193                 vec[0] = (((j + 1) % 2) * (j - 1)) * 0.5f;
2194                 vec[1] = ((j % 2) * (j - 2)) * 0.5f;
2195                 glBegin(GL_LINE_STRIP);
2196                 for (i = 0; i < 3; i++) {
2197                         if (i == 1) {
2198                                 vec[0] *= 0.5f;
2199                                 vec[1] *= 0.5f;
2200                         }
2201
2202                         vec[2] = 0.25f * i - 0.125f;
2203                         glVertex3fv(vec);
2204                 }
2205                 glEnd();
2206         }
2207
2208         glDisable(GL_BLEND);
2209 }
2210
2211 static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short sel)
2212 {
2213         BPoint *bp = lt->def;
2214         const float *co = dl ? dl->verts : NULL;
2215         int u, v, w;
2216
2217         const int color = sel ? TH_VERTEX_SELECT : TH_VERTEX;
2218         UI_ThemeColor(color);
2219
2220         glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
2221         bglBegin(GL_POINTS);
2222
2223         for (w = 0; w < lt->pntsw; w++) {
2224                 int wxt = (w == 0 || w == lt->pntsw - 1);
2225                 for (v = 0; v < lt->pntsv; v++) {
2226                         int vxt = (v == 0 || v == lt->pntsv - 1);
2227                         for (u = 0; u < lt->pntsu; u++, bp++, co += 3) {
2228                                 int uxt = (u == 0 || u == lt->pntsu - 1);
2229                                 if (!(lt->flag & LT_OUTSIDE) || uxt || vxt || wxt) {
2230                                         if (bp->hide == 0) {
2231                                                 /* check for active BPoint and ensure selected */
2232                                                 if ((bp == actbp) && (bp->f1 & SELECT)) {
2233                                                         UI_ThemeColor(TH_ACTIVE_VERT);
2234                                                         bglVertex3fv(dl ? co : bp->vec);
2235                                                         UI_ThemeColor(color);
2236                                                 }
2237                                                 else if ((bp->f1 & SELECT) == sel) {
2238                                                         bglVertex3fv(dl ? co : bp->vec);
2239                                                 }
2240                                         }
2241                                 }
2242                         }
2243                 }
2244         }
2245         
2246         bglEnd();
2247         glPointSize(1.0);
2248 }
2249
2250 static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int actdef_wcol)
2251 {
2252         int index = ((w * lt->pntsv + v) * lt->pntsu) + u;
2253
2254         if (actdef_wcol) {
2255                 float col[3];
2256                 MDeformWeight *mdw = defvert_find_index(lt->dvert + index, actdef_wcol - 1);
2257                 
2258                 weight_to_rgb(col, mdw ? mdw->weight : 0.0f);
2259                 glColor3fv(col);
2260
2261         }
2262         
2263         if (dl) {
2264                 glVertex3fv(&dl->verts[index * 3]);
2265         }
2266         else {
2267                 glVertex3fv(lt->def[index].vec);
2268         }
2269 }
2270
2271 #ifdef SEQUENCER_DAG_WORKAROUND
2272 static void ensure_curve_cache(Scene *scene, Object *object)
2273 {
2274         bool need_recalc = object->curve_cache == NULL;
2275         /* Render thread might have freed the curve cache if the
2276          * object is not visible. If the object is also used for
2277          * particles duplication, then render thread might have
2278          * also created curve_cache with only bevel and path
2279          * filled in.
2280          *
2281          * So check for curve_cache != NULL is not fully correct
2282          * here, we also need to check whether display list is
2283          * empty or not.
2284          *
2285          * The trick below tries to optimize calls to displist
2286          * creation for cases curve is empty. Meaning, if the curve
2287          * is empty (without splines) bevel list would also be empty.
2288          * And the thing is, render thread always leaves bevel list
2289          * in a proper state. So if bevel list is here and display
2290          * list is not we need to make display list.
2291          */
2292         if (need_recalc == false) {
2293                 need_recalc = object->curve_cache->disp.first == NULL &&
2294                               object->curve_cache->bev.first != NULL;
2295         }
2296         if (need_recalc) {
2297                 switch (object->type) {
2298                         case OB_CURVE:
2299                         case OB_SURF:
2300                         case OB_FONT:
2301                                 BKE_displist_make_curveTypes(scene, object, false);
2302                                 break;
2303                         case OB_MBALL:
2304                                 BKE_displist_make_mball(G.main->eval_ctx, scene, object);
2305                                 break;
2306                         case OB_LATTICE:
2307                                 BKE_lattice_modifiers_calc(scene, object);
2308                                 break;
2309                 }
2310         }
2311 }
2312 #endif
2313
2314 /* lattice color is hardcoded, now also shows weightgroup values in edit mode */
2315 static void drawlattice(View3D *v3d, Object *ob)
2316 {
2317         Lattice *lt = ob->data;
2318         DispList *dl;
2319         int u, v, w;
2320         int actdef_wcol = 0;
2321         const bool is_edit = (lt->editlatt != NULL);
2322
2323         dl = BKE_displist_find(&ob->curve_cache->disp, DL_VERTS);
2324         
2325         if (is_edit) {
2326                 lt = lt->editlatt->latt;
2327
2328                 UI_ThemeColor(TH_WIRE_EDIT);
2329                 
2330                 if (ob->defbase.first && lt->dvert) {
2331                         actdef_wcol = ob->actdef;
2332                         glShadeModel(GL_SMOOTH);
2333                 }
2334         }
2335         
2336         glBegin(GL_LINES);
2337         for (w = 0; w < lt->pntsw; w++) {
2338                 int wxt = (w == 0 || w == lt->pntsw - 1);
2339                 for (v = 0; v < lt->pntsv; v++) {
2340                         int vxt = (v == 0 || v == lt->pntsv - 1);
2341                         for (u = 0; u < lt->pntsu; u++) {
2342                                 int uxt = (u == 0 || u == lt->pntsu - 1);
2343
2344                                 if (w && ((uxt || vxt) || !(lt->flag & LT_OUTSIDE))) {
2345                                         drawlattice__point(lt, dl, u, v, w - 1, actdef_wcol);
2346                                         drawlattice__point(lt, dl, u, v, w, actdef_wcol);
2347                                 }
2348                                 if (v && ((uxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
2349                                         drawlattice__point(lt, dl, u, v - 1, w, actdef_wcol);
2350                                         drawlattice__point(lt, dl, u, v, w, actdef_wcol);
2351                                 }
2352                                 if (u && ((vxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
2353                                         drawlattice__point(lt, dl, u - 1, v, w, actdef_wcol);
2354                                         drawlattice__point(lt, dl, u, v, w, actdef_wcol);
2355                                 }
2356                         }
2357                 }
2358         }
2359         glEnd();
2360         
2361         /* restoration for weight colors */
2362         if (actdef_wcol)
2363                 glShadeModel(GL_FLAT);
2364
2365         if (is_edit) {
2366                 BPoint *actbp = BKE_lattice_active_point_get(lt);
2367
2368                 if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
2369                 
2370                 lattice_draw_verts(lt, dl, actbp, 0);
2371                 lattice_draw_verts(lt, dl, actbp, 1);
2372                 
2373                 if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
2374         }
2375 }
2376
2377 /* ***************** ******************** */
2378
2379 /*  draw callback */
2380
2381 typedef struct drawDMVertSel_userData {
2382         MVert *mvert;
2383         int active;
2384         unsigned char *col[3];  /* (base, sel, act) */
2385         char sel_prev;
2386 } drawDMVertSel_userData;
2387
2388 static void drawSelectedVertices__mapFunc(void *userData, int index, const float co[3],
2389                                           const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
2390 {
2391         drawDMVertSel_userData *data = userData;
2392         MVert *mv = &data->mvert[index];
2393
2394         if (!(mv->flag & ME_HIDE)) {
2395                 const char sel = (index == data->active) ? 2 : (mv->flag & SELECT);
2396                 if (sel != data->sel_prev) {
2397                         glColor3ubv(data->col[sel]);
2398                         data->sel_prev = sel;
2399                 }
2400
2401                 glVertex3fv(co);
2402         }
2403 }
2404
2405 static void drawSelectedVertices(DerivedMesh *dm, Mesh *me)
2406 {
2407         drawDMVertSel_userData data;
2408
2409         /* TODO define selected color */
2410         unsigned char base_col[3] = {0x0, 0x0, 0x0};
2411         unsigned char sel_col[3] = {0xd8, 0xb8, 0x0};
2412         unsigned char act_col[3] = {0xff, 0xff, 0xff};
2413
2414         data.mvert = me->mvert;
2415         data.active = BKE_mesh_mselect_active_get(me, ME_VSEL);
2416         data.sel_prev = 0xff;
2417
2418         data.col[0] = base_col;
2419         data.col[1] = sel_col;
2420         data.col[2] = act_col;
2421
2422         glBegin(GL_POINTS);
2423         dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data, DM_FOREACH_NOP);
2424         glEnd();
2425 }
2426
2427 /* ************** DRAW MESH ****************** */
2428
2429 /* First section is all the "simple" draw routines,
2430  * ones that just pass some sort of primitive to GL,
2431  * with perhaps various options to control lighting,
2432  * color, etc.
2433  *
2434  * These routines should not have user interface related
2435  * logic!!!
2436  */
2437
2438 static void calcDrawDMNormalScale(Object *ob, drawDMNormal_userData *data)
2439 {
2440         float obmat[3][3];
2441
2442         copy_m3_m4(obmat, ob->obmat);
2443
2444         data->uniform_scale = is_uniform_scaled_m3(obmat);
2445
2446         if (!data->uniform_scale) {
2447                 /* inverted matrix */
2448                 invert_m3_m3(data->imat, obmat);
2449
2450                 /* transposed inverted matrix */
2451                 transpose_m3_m3(data->tmat, data->imat);
2452         }
2453 }
2454
2455 static void draw_dm_face_normals__mapFunc(void *userData, int index, const float cent[3], const float no[3])
2456 {
2457         drawDMNormal_userData *data = userData;
2458         BMFace *efa = BM_face_at_index(data->bm, index);
2459         float n[3];
2460
2461         if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
2462                 if (!data->uniform_scale) {
2463                         mul_v3_m3v3(n, data->tmat, no);
2464                         normalize_v3(n);
2465                         mul_m3_v3(data->imat, n);
2466                 }
2467                 else {
2468                         copy_v3_v3(n, no);
2469                 }
2470
2471                 glVertex3fv(cent);
2472                 glVertex3f(cent[0] + n[0] * data->normalsize,
2473                            cent[1] + n[1] * data->normalsize,
2474                            cent[2] + n[2] * data->normalsize);
2475         }
2476 }
2477
2478 static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
2479 {
2480         drawDMNormal_userData data;
2481
2482         data.bm = em->bm;
2483         data.normalsize = scene->toolsettings->normalsize;
2484
2485         calcDrawDMNormalScale(ob, &data);
2486
2487         glBegin(GL_LINES);
2488         dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
2489         glEnd();
2490 }
2491
2492 static void draw_dm_face_centers__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
2493 {
2494         drawBMSelect_userData *data = userData;
2495         BMFace *efa = BM_face_at_index(data->bm, index);
2496         
2497         if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) &&
2498             (BM_elem_flag_test(efa, BM_ELEM_SELECT) == data->select))
2499         {
2500                 bglVertex3fv(cent);
2501         }
2502 }
2503 static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, bool select)
2504 {
2505         drawBMSelect_userData data = {em->bm, select};
2506
2507         bglBegin(GL_POINTS);
2508         dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, &data, DM_FOREACH_NOP);
2509         bglEnd();
2510 }
2511
2512 static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3])
2513 {
2514         drawDMNormal_userData *data = userData;
2515         BMVert *eve = BM_vert_at_index(data->bm, index);
2516
2517         if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
2518                 float no[3], n[3];
2519
2520                 if (no_f) {
2521                         copy_v3_v3(no, no_f);
2522                 }
2523                 else {
2524                         normal_short_to_float_v3(no, no_s);
2525                 }
2526
2527                 if (!data->uniform_scale) {
2528                         mul_v3_m3v3(n, data->tmat, no);
2529                         normalize_v3(n);
2530                         mul_m3_v3(data->imat, n);
2531                 }
2532                 else {
2533                         copy_v3_v3(n, no);
2534                 }
2535
2536                 glVertex3fv(co);
2537                 glVertex3f(co[0] + n[0] * data->normalsize,
2538                            co[1] + n[1] * data->normalsize,
2539                            co[2] + n[2] * data->normalsize);
2540         }
2541 }
2542
2543 static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
2544 {
2545         drawDMNormal_userData data;
2546
2547         data.bm = em->bm;
2548         data.normalsize = scene->toolsettings->normalsize;
2549
2550         calcDrawDMNormalScale(ob, &data);
2551
2552         glBegin(GL_LINES);
2553         dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
2554         glEnd();
2555 }
2556
2557 /* Draw verts with color set based on selection */
2558 static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3],
2559                                    const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
2560 {
2561         drawDMVerts_userData *data = userData;
2562         BMVert *eve = BM_vert_at_index(data->bm, index);
2563
2564         if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) {
2565                 /* skin nodes: draw a red circle around the root node(s) */
2566                 if (data->cd_vskin_offset != -1) {
2567                         const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, data->cd_vskin_offset);
2568                         if (vs->flag & MVERT_SKIN_ROOT) {
2569                                 float radius = (vs->radius[0] + vs->radius[1]) * 0.5f;
2570                                 bglEnd();
2571                         
2572                                 glColor4ubv(data->th_skin_root);
2573                                 drawcircball(GL_LINES, co, radius, data->imat);
2574
2575                                 glColor4ubv(data->sel ? data->th_vertex_select : data->th_vertex);
2576                                 bglBegin(GL_POINTS);
2577                         }
2578                 }
2579
2580                 /* draw active larger - need to stop/start point drawing for this :/ */
2581                 if (eve == data->eve_act) {
2582                         glColor4ubv(data->th_editmesh_active);
2583                         
2584                         bglEnd();
2585                         
2586                         glPointSize(data->th_vertex_size);
2587                         bglBegin(GL_POINTS);
2588                         bglVertex3fv(co);
2589                         bglEnd();
2590
2591                         glColor4ubv(data->sel ? data->th_vertex_select : data->th_vertex);
2592                         glPointSize(data->th_vertex_size);
2593                         bglBegin(GL_POINTS);
2594                 }
2595                 else {
2596                         bglVertex3fv(co);
2597                 }
2598         }
2599 }
2600
2601 static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVert *eve_act,
2602                           RegionView3D *rv3d)
2603 {
2604         drawDMVerts_userData data;
2605         data.sel = sel;
2606         data.eve_act = eve_act;
2607         data.bm = em->bm;
2608
2609         /* Cache theme values */
2610         UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, data.th_editmesh_active);
2611         UI_GetThemeColor4ubv(TH_VERTEX_SELECT, data.th_vertex_select);
2612         UI_GetThemeColor4ubv(TH_VERTEX, data.th_vertex);
2613         UI_GetThemeColor4ubv(TH_SKIN_ROOT, data.th_skin_root);
2614         data.th_vertex_size = UI_GetThemeValuef(TH_VERTEX_SIZE);
2615
2616         /* For skin root drawing */
2617         data.cd_vskin_offset = CustomData_get_offset(&em->bm->vdata, CD_MVERT_SKIN);
2618         /* view-aligned matrix */
2619         mul_m4_m4m4(data.imat, rv3d->viewmat, em->ob->obmat);
2620         invert_m4(data.imat);
2621
2622         bglBegin(GL_POINTS);
2623         dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data, DM_FOREACH_NOP);
2624         bglEnd();
2625 }
2626
2627 /* Draw edges with color set based on selection */
2628 static DMDrawOption draw_dm_edges_sel__setDrawOptions(void *userData, int index)
2629 {
2630         BMEdge *eed;
2631         drawDMEdgesSel_userData *data = userData;
2632         unsigned char *col;
2633
2634         eed = BM_edge_at_index(data->bm, index);
2635
2636         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
2637                 if (eed == data->eed_act) {
2638                         glColor4ubv(data->actCol);
2639                 }
2640                 else {
2641                         if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
2642                                 col = data->selCol;
2643                         }
2644                         else {
2645                                 col = data->baseCol;
2646                         }
2647                         /* no alpha, this is used so a transparent color can disable drawing unselected edges in editmode */
2648                         if (col[3] == 0)
2649                                 return DM_DRAW_OPTION_SKIP;
2650                         
2651                         glColor4ubv(col);
2652                 }
2653                 return DM_DRAW_OPTION_NORMAL;
2654         }
2655         else {
2656                 return DM_DRAW_OPTION_SKIP;
2657         }
2658 }
2659 static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
2660                               unsigned char *selCol, unsigned char *actCol, BMEdge *eed_act)
2661 {
2662         drawDMEdgesSel_userData data;
2663         
2664         data.baseCol = baseCol;
2665         data.selCol = selCol;
2666         data.actCol = actCol;
2667         data.bm = em->bm;
2668         data.eed_act = eed_act;
2669         dm->drawMappedEdges(dm, draw_dm_edges_sel__setDrawOptions, &data);
2670 }
2671
2672 /* Draw edges */
2673 static DMDrawOption draw_dm_edges__setDrawOptions(void *userData, int index)
2674 {
2675         if (BM_elem_flag_test(BM_edge_at_index(userData, index), BM_ELEM_HIDDEN))
2676                 return DM_DRAW_OPTION_SKIP;
2677         else
2678                 return DM_DRAW_OPTION_NORMAL;
2679 }
2680
2681 static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm)
2682 {
2683         dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em->bm);
2684 }
2685
2686 /* Draw edges with color interpolated based on selection */
2687 static DMDrawOption draw_dm_edges_sel_interp__setDrawOptions(void *userData, int index)
2688 {
2689         drawDMEdgesSelInterp_userData *data = userData;
2690         if (BM_elem_flag_test(BM_edge_at_index(data->bm, index), BM_ELEM_HIDDEN))
2691                 return DM_DRAW_OPTION_SKIP;
2692         else
2693                 return DM_DRAW_OPTION_NORMAL;
2694 }
2695 static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int index, float t)
2696 {
2697         drawDMEdgesSelInterp_userData *data = userData;
2698         BMEdge *eed = BM_edge_at_index(data->bm, index);
2699         unsigned char **cols = userData;
2700         unsigned int col0_id = (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT)) ? 2 : 1;
2701         unsigned int col1_id = (BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)) ? 2 : 1;
2702         unsigned char *col0 = cols[col0_id];
2703         unsigned char *col1 = cols[col1_id];
2704         unsigned char *col_pt;
2705
2706         if (col0_id == col1_id) {
2707                 col_pt = col0;
2708         }
2709         else if (t == 0.0f) {
2710                 col_pt = col0;
2711         }
2712         else if (t == 1.0f) {
2713                 col_pt = col1;
2714         }
2715         else {
2716                 unsigned char  col_blend[4];
2717                 interp_v4_v4v4_uchar(col_blend, col0, col1, t);
2718                 glColor4ubv(col_blend);
2719                 data->lastCol = NULL;
2720                 return;
2721         }
2722
2723         if (data->lastCol != col_pt) {
2724                 data->lastCol = col_pt;
2725                 glColor4ubv(col_pt);
2726         }
2727 }
2728
2729 static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
2730 {
2731         drawDMEdgesSelInterp_userData data;
2732         data.bm = em->bm;
2733         data.baseCol = baseCol;
2734         data.selCol = selCol;
2735         data.lastCol = NULL;
2736
2737         dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, &data);
2738 }
2739
2740 static void bm_color_from_weight(float col[3], BMVert *vert, drawDMEdgesWeightInterp_userData *data)
2741 {
2742         MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(vert, data->cd_dvert_offset);
2743         float weight = defvert_find_weight(dvert, data->vgroup_index);
2744
2745         if ((weight == 0.0f) &&
2746             ((data->weight_user == OB_DRAW_GROUPUSER_ACTIVE) ||
2747              ((data->weight_user == OB_DRAW_GROUPUSER_ALL) && defvert_is_weight_zero(dvert, data->defgroup_tot))))
2748         {
2749                 copy_v3_v3(col, data->alert_color);
2750         }
2751         else {
2752                 weight_to_rgb(col, weight);
2753         }
2754 }
2755
2756 static void draw_dm_edges_nop_interp__setDrawInterpOptions(void *UNUSED(userData), int UNUSED(index), float UNUSED(t))
2757 {
2758         /* pass */
2759 }
2760
2761 static void draw_dm_edges_weight_interp__setDrawInterpOptions(void *userData, int index, float t)
2762 {
2763         drawDMEdgesWeightInterp_userData *data = userData;
2764         BMEdge *eed = BM_edge_at_index(data->bm, index);
2765         float col[3];
2766
2767         if (t == 0.0f) {
2768                 bm_color_from_weight(col, eed->v1, data);
2769         }
2770         else if (t == 1.0f) {
2771                 bm_color_from_weight(col, eed->v2, data);
2772         }
2773         else {
2774                 float col_v1[3];
2775                 float col_v2[3];
2776
2777                 bm_color_from_weight(col_v1, eed->v1, data);
2778                 bm_color_from_weight(col_v2, eed->v2, data);
2779                 interp_v3_v3v3(col, col_v1, col_v2, t);
2780         }
2781
2782         glColor3fv(col);
2783 }
2784
2785 static void draw_dm_edges_weight_interp(BMEditMesh *em, DerivedMesh *dm, const char weight_user)
2786 {
2787         drawDMEdgesWeightInterp_userData data;
2788         Object *ob = em->ob;
2789
2790         data.bm = em->bm;
2791         data.cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
2792         data.defgroup_tot = BLI_listbase_count(&ob->defbase);
2793         data.vgroup_index = ob->actdef - 1;
2794         data.weight_user = weight_user;
2795         UI_GetThemeColor3fv(TH_VERTEX_UNREFERENCED, data.alert_color);
2796
2797         if ((data.vgroup_index != -1) && (data.cd_dvert_offset != -1)) {
2798                 glEnable(GL_BLEND);
2799                 dm->drawMappedEdgesInterp(
2800                         dm,
2801                         draw_dm_edges_sel_interp__setDrawOptions,
2802                         draw_dm_edges_weight_interp__setDrawInterpOptions,
2803                         &data);
2804                 glDisable(GL_BLEND);
2805         }
2806         else {
2807                 float col[3];
2808
2809                 if (data.weight_user == OB_DRAW_GROUPUSER_NONE) {
2810                         weight_to_rgb(col, 0.0f);
2811                 }
2812                 else {
2813                         copy_v3_v3(col, data.alert_color);
2814                 }
2815                 glColor3fv(col);
2816
2817                 dm->drawMappedEdgesInterp(
2818                         dm,
2819                         draw_dm_edges_sel_interp__setDrawOptions,
2820                         draw_dm_edges_nop_interp__setDrawInterpOptions,
2821                         &data);
2822         }
2823
2824 }
2825
2826 static bool draw_dm_edges_weight_check(Mesh *me, View3D *v3d)
2827 {
2828         if (me->drawflag & ME_DRAWEIGHT) {
2829                 if ((v3d->drawtype == OB_WIRE) ||
2830                     (v3d->flag2 & V3D_SOLID_MATCAP) ||
2831                     ((v3d->flag2 & V3D_OCCLUDE_WIRE) && (v3d->drawtype > OB_WIRE)))
2832                 {
2833                         return true;
2834                 }
2835         }
2836
2837         return false;
2838 }
2839
2840 /* Draw only seam edges */
2841 static DMDrawOption draw_dm_edges_seams__setDrawOptions(void *userData, int index)
2842 {
2843         BMEdge *eed = BM_edge_at_index(userData, index);
2844
2845         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_elem_flag_test(eed, BM_ELEM_SEAM))
2846                 return DM_DRAW_OPTION_NORMAL;
2847         else
2848                 return DM_DRAW_OPTION_SKIP;
2849 }
2850
2851 static void draw_dm_edges_seams(BMEditMesh *em, DerivedMesh *dm)
2852 {
2853         dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, em->bm);
2854 }
2855
2856 /* Draw only sharp edges */
2857 static DMDrawOption draw_dm_edges_sharp__setDrawOptions(void *userData, int index)
2858 {
2859         BMEdge *eed = BM_edge_at_index(userData, index);
2860
2861         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && !BM_elem_flag_test(eed, BM_ELEM_SMOOTH))
2862                 return DM_DRAW_OPTION_NORMAL;
2863         else
2864                 return DM_DRAW_OPTION_SKIP;
2865 }
2866
2867 static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm)
2868 {
2869         dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em->bm);
2870 }
2871
2872 #ifdef WITH_FREESTYLE
2873
2874 static int draw_dm_test_freestyle_edge_mark(BMesh *bm, BMEdge *eed)
2875 {
2876         FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, eed->head.data, CD_FREESTYLE_EDGE);
2877         if (!fed)
2878                 return 0;
2879         return (fed->flag & FREESTYLE_EDGE_MARK) != 0;
2880 }
2881
2882 /* Draw only Freestyle feature edges */
2883 static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int index)
2884 {
2885         BMEdge *eed = BM_edge_at_index(userData, index);
2886
2887         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && draw_dm_test_freestyle_edge_mark(userData, eed))
2888                 return DM_DRAW_OPTION_NORMAL;
2889         else
2890                 return DM_DRAW_OPTION_SKIP;
2891 }
2892
2893 static void draw_dm_edges_freestyle(BMEditMesh *em, DerivedMesh *dm)
2894 {
2895         dm->drawMappedEdges(dm, draw_dm_edges_freestyle__setDrawOptions, em->bm);
2896 }
2897
2898 static int draw_dm_test_freestyle_face_mark(BMesh *bm, BMFace *efa)
2899 {
2900         FreestyleFace *ffa = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_FREESTYLE_FACE);
2901         if (!ffa)
2902                 return 0;
2903         return (ffa->flag & FREESTYLE_FACE_MARK) != 0;
2904 }
2905
2906 #endif
2907
2908 /* Draw loop normals. */
2909 static void draw_dm_loop_normals__mapFunc(void *userData, int vertex_index, int face_index,
2910                                           const float co[3], const float no[3])
2911 {
2912         if (no) {
2913                 const drawDMNormal_userData *data = userData;
2914                 const BMVert *eve = BM_vert_at_index(data->bm, vertex_index);
2915                 const BMFace *efa = BM_face_at_index(data->bm, face_index);
2916                 float vec[3];
2917
2918                 if (!(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) || BM_elem_flag_test(efa, BM_ELEM_HIDDEN))) {
2919                         if (!data->uniform_scale) {
2920                                 mul_v3_m3v3(vec, (float(*)[3])data->tmat, no);
2921                                 normalize_v3(vec);
2922                                 mul_m3_v3((float(*)[3])data->imat, vec);
2923                         }
2924                         else {
2925                                 copy_v3_v3(vec, no);
2926                         }
2927                         mul_v3_fl(vec, data->normalsize);
2928                         add_v3_v3(vec, co);
2929                         glVertex3fv(co);
2930                         glVertex3fv(vec);
2931                 }
2932         }
2933 }
2934
2935 static void draw_dm_loop_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
2936 {
2937         drawDMNormal_userData data;
2938
2939         data.bm = em->bm;
2940         data.normalsize = scene->toolsettings->normalsize;
2941
2942         calcDrawDMNormalScale(ob, &data);
2943
2944         glBegin(GL_LINES);
2945         dm->foreachMappedLoop(dm, draw_dm_loop_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
2946         glEnd();
2947 }
2948
2949 /* Draw faces with color set based on selection
2950  * return 2 for the active face so it renders with stipple enabled */
2951 static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index)
2952 {
2953         drawDMFacesSel_userData *data = userData;
2954         BMFace *efa = BM_face_at_index(data->bm, index);
2955         unsigned char *col;
2956         
2957         if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
2958                 if (efa == data->efa_act) {
2959                         glColor4ubv(data->cols[2]);
2960                         return DM_DRAW_OPTION_STIPPLE;
2961                 }
2962                 else {
2963 #ifdef WITH_FREESTYLE
2964                         col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0];
2965 #else
2966                         col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0];
2967 #endif
2968                         if (col[3] == 0)
2969                                 return DM_DRAW_OPTION_SKIP;
2970                         glColor4ubv(col);
2971                         return DM_DRAW_OPTION_NORMAL;
2972                 }
2973         }
2974         return DM_DRAW_OPTION_SKIP;
2975 }
2976
2977 static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index)
2978 {
2979
2980         drawDMFacesSel_userData *data = userData;
2981         int i;
2982         BMFace *efa;
2983         BMFace *next_efa;
2984
2985         unsigned char *col, *next_col;
2986
2987         if (!data->orig_index_mf_to_mpoly)
2988                 return 0;
2989
2990         i = DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, index);
2991         efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL;
2992         i = DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, next_index);
2993         next_efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL;
2994
2995         if (ELEM(NULL, efa, next_efa))
2996                 return 0;
2997
2998         if (efa == next_efa)
2999                 return 1;
3000
3001         if (efa == data->efa_act || next_efa == data->efa_act)
3002                 return 0;
3003
3004 #ifdef WITH_FREESTYLE
3005         col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0];
3006         next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0];
3007 #else
3008         col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0];
3009         next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : 0];
3010 #endif
3011
3012         if (col[3] == 0 || next_col[3] == 0)
3013                 return 0;
3014
3015         return col == next_col;
3016 }
3017
3018 /* also draws the active face */
3019 #ifdef WITH_FREESTYLE
3020 static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
3021                               unsigned char *selCol, unsigned char *actCol, unsigned char *markCol, BMFace *efa_act)
3022 #else
3023 static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
3024                               unsigned char *selCol, unsigned char *actCol, BMFace *efa_act)
3025 #endif
3026 {
3027         drawDMFacesSel_userData data;
3028         data.dm = dm;
3029         data.cols[0] = baseCol;
3030         data.bm = em->bm;
3031         data.cols[1] = selCol;
3032         data.cols[2] = actCol;
3033 #ifdef WITH_FREESTYLE
3034         data.cols[3] = markCol;
3035 #endif
3036         data.efa_act = efa_act;
3037         /* double lookup */
3038         data.orig_index_mf_to_mpoly = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
3039         data.orig_index_mp_to_orig  = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
3040         if ((data.orig_index_mf_to_mpoly && data.orig_index_mp_to_orig) == false) {
3041                 data.orig_index_mf_to_mpoly = data.orig_index_mp_to_orig = NULL;
3042         }
3043
3044         dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, GPU_enable_material, draw_dm_faces_sel__compareDrawOptions, &data, 0);
3045 }
3046
3047 static DMDrawOption draw_dm_creases__setDrawOptions(void *userData, int index)
3048 {
3049         drawDMLayer_userData *data = userData;
3050         BMesh *bm = data->bm;
3051         BMEdge *eed = BM_edge_at_index(bm, index);
3052         
3053         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
3054                 const float crease = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset);
3055                 if (crease != 0.0f) {
3056                         UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_CREASE, crease);
3057                         return DM_DRAW_OPTION_NORMAL;
3058                 }
3059         }
3060         return DM_DRAW_OPTION_SKIP;
3061 }
3062 static void draw_dm_creases(BMEditMesh *em, DerivedMesh *dm)
3063 {
3064         drawDMLayer_userData data;
3065
3066         data.bm = em->bm;
3067         data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
3068
3069         if (data.cd_layer_offset != -1) {
3070                 glLineWidth(3.0);
3071                 dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, &data);
3072                 glLineWidth(1.0);
3073         }
3074 }
3075
3076 static DMDrawOption draw_dm_bweights__setDrawOptions(void *userData, int index)
3077 {
3078         drawDMLayer_userData *data = userData;
3079         BMesh *bm = data->bm;
3080         BMEdge *eed = BM_edge_at_index(bm, index);
3081
3082         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
3083                 const float bweight = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset);
3084                 if (bweight != 0.0f) {
3085                         UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_SELECT, bweight);
3086                         return DM_DRAW_OPTION_NORMAL;
3087                 }
3088         }
3089         return DM_DRAW_OPTION_SKIP;
3090 }
3091 static void draw_dm_bweights__mapFunc(void *userData, int index, const float co[3],
3092                                       const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
3093 {
3094         drawDMLayer_userData *data = userData;
3095         BMesh *bm = data->bm;
3096         BMVert *eve = BM_vert_at_index(bm, index);
3097
3098         if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
3099                 const float bweight = BM_ELEM_CD_GET_FLOAT(eve, data->cd_layer_offset);
3100                 if (bweight != 0.0f) {
3101                         UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_SELECT, bweight);
3102                         bglVertex3fv(co);
3103                 }
3104         }
3105 }
3106 static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm)
3107 {
3108         ToolSettings *ts = scene->toolsettings;
3109
3110         if (ts->selectmode & SCE_SELECT_VERTEX) {
3111                 drawDMLayer_userData data;
3112
3113                 data.bm = em->bm;
3114                 data.cd_layer_offset = CustomData_get_offset(&em->bm->vdata, CD_BWEIGHT);
3115
3116                 if (data.cd_layer_offset != -1) {
3117                         glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2);
3118                         bglBegin(GL_POINTS);
3119                         dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &data, DM_FOREACH_NOP);
3120                         bglEnd();
3121                 }
3122         }
3123         else {
3124                 drawDMLayer_userData data;
3125
3126                 data.bm = em->bm;
3127                 data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
3128
3129                 if (data.cd_layer_offset != -1) {
3130                         glLineWidth(3.0);
3131                         dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, &data);
3132                         glLineWidth(1.0);
3133                 }
3134         }
3135 }
3136
3137 static int draw_dm_override_material_color(int UNUSED(nr), void *UNUSED(attribs))
3138 {
3139         return 1;
3140 }
3141
3142 /* Second section of routines: Combine first sets to form fancy
3143  * drawing routines (for example rendering twice to get overlays).
3144  *