af44c8ca9982e609a0f70469094e508f9b39addd
[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_subsurf.h"
78 #include "BKE_unit.h"
79 #include "BKE_tracking.h"
80
81 #include "BKE_editmesh.h"
82
83 #include "IMB_imbuf.h"
84 #include "IMB_imbuf_types.h"
85
86 #include "BIF_gl.h"
87 #include "BIF_glutil.h"
88
89 #include "GPU_draw.h"
90 #include "GPU_extensions.h"
91 #include "GPU_select.h"
92 #include "GPU_simple_shader.h"
93
94 #include "ED_mesh.h"
95 #include "ED_particle.h"
96 #include "ED_screen.h"
97 #include "ED_sculpt.h"
98 #include "ED_types.h"
99
100 #include "UI_resources.h"
101 #include "UI_interface_icons.h"
102
103 #include "WM_api.h"
104 #include "BLF_api.h"
105
106 #include "view3d_intern.h"  /* bad level include */
107
108 /* Workaround for sequencer scene render mode.
109  *
110  * Strips doesn't use DAG to update objects or so, which
111  * might lead to situations when object is drawing without
112  * curve cache ready.
113  *
114  * Ideally we don't want to evaluate objects from drawing,
115  * but it'll require some major sequencer re-design. So
116  * for now just fallback to legacy behavior with calling
117  * display ist creating from draw().
118  */
119 #define SEQUENCER_DAG_WORKAROUND
120
121 typedef enum eWireDrawMode {
122         OBDRAW_WIRE_OFF = 0,
123         OBDRAW_WIRE_ON = 1,
124         OBDRAW_WIRE_ON_DEPTH = 2
125 } eWireDrawMode;
126
127 typedef struct drawDMVerts_userData {
128         BMesh *bm;
129
130         BMVert *eve_act;
131         char sel;
132
133         /* cached theme values */
134         unsigned char th_editmesh_active[4];
135         unsigned char th_vertex_select[4];
136         unsigned char th_vertex[4];
137         unsigned char th_skin_root[4];
138         float th_vertex_size;
139
140         /* for skin node drawing */
141         int cd_vskin_offset;
142         float imat[4][4];
143 } drawDMVerts_userData;
144
145 typedef struct drawDMEdgesSel_userData {
146         BMesh *bm;
147
148         unsigned char *baseCol, *selCol, *actCol;
149         BMEdge *eed_act;
150 } drawDMEdgesSel_userData;
151
152 typedef struct drawDMEdgesSelInterp_userData {
153         BMesh *bm;
154
155         unsigned char *baseCol, *selCol;
156         unsigned char *lastCol;
157 } drawDMEdgesSelInterp_userData;
158
159 typedef struct drawDMEdgesWeightInterp_userData {
160         BMesh *bm;
161
162         int cd_dvert_offset;
163         int defgroup_tot;
164         int vgroup_index;
165         char weight_user;
166         float alert_color[3];
167
168 } drawDMEdgesWeightInterp_userData;
169
170 typedef struct drawDMFacesSel_userData {
171 #ifdef WITH_FREESTYLE
172         unsigned char *cols[4];
173 #else
174         unsigned char *cols[3];
175 #endif
176
177         DerivedMesh *dm;
178         BMesh *bm;
179
180         BMFace *efa_act;
181         const int *orig_index_mp_to_orig;
182 } drawDMFacesSel_userData;
183
184 typedef struct drawDMNormal_userData {
185         BMesh *bm;
186         int uniform_scale;
187         float normalsize;
188         float tmat[3][3];
189         float imat[3][3];
190 } drawDMNormal_userData;
191
192 typedef struct drawMVertOffset_userData {
193         MVert *mvert;
194         int offset;
195 } drawMVertOffset_userData;
196
197 typedef struct drawDMLayer_userData {
198         BMesh *bm;
199         int cd_layer_offset;
200 } drawDMLayer_userData;
201
202 typedef struct drawBMOffset_userData {
203         BMesh *bm;
204         int offset;
205 } drawBMOffset_userData;
206
207 typedef struct drawBMSelect_userData {
208         BMesh *bm;
209         bool select;
210 } drawBMSelect_userData;
211
212 static void draw_bounding_volume(Object *ob, char type);
213
214 static void drawcube_size(float size);
215 static void drawcircle_size(float size);
216 static void draw_empty_sphere(float size);
217 static void draw_empty_cone(float size);
218 static void draw_box(float vec[8][3], bool solid);
219
220 static void ob_wire_color_blend_theme_id(const unsigned char ob_wire_col[4], const int theme_id, float fac)
221 {
222         float col_wire[3], col_bg[3], col[3];
223
224         rgb_uchar_to_float(col_wire, ob_wire_col);
225
226         UI_GetThemeColor3fv(theme_id, col_bg);
227         interp_v3_v3v3(col, col_bg, col_wire, fac);
228         glColor3fv(col);
229 }
230
231 /* this condition has been made more complex since editmode can draw textures */
232 bool check_object_draw_texture(Scene *scene, View3D *v3d, const char drawtype)
233 {
234         /* texture and material draw modes */
235         if (ELEM(v3d->drawtype, OB_TEXTURE, OB_MATERIAL) && drawtype > OB_SOLID) {
236                 return true;
237         }
238
239         /* textured solid */
240         if ((v3d->drawtype == OB_SOLID) &&
241             (v3d->flag2 & V3D_SOLID_TEX) &&
242             (BKE_scene_use_new_shading_nodes(scene) == false))
243         {
244                 return true;
245         }
246         
247         if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) {
248                 return true;
249         }
250         
251         return false;
252 }
253
254 static bool check_object_draw_editweight(Mesh *me, DerivedMesh *finalDM)
255 {
256         if (me->drawflag & ME_DRAWEIGHT) {
257                 /* editmesh handles its own weight drawing */
258                 if (finalDM->type != DM_TYPE_EDITBMESH) {
259                         return true;
260                 }
261         }
262
263         return false;
264 }
265
266 static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
267 {
268         if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0)
269                 return false;
270
271         if (G.f & G_BACKBUFSEL)
272                 return false;
273
274         if ((vd->flag & V3D_ZBUF_SELECT) == 0)
275                 return true;
276
277         /* if its drawing textures with zbuf sel, then don't draw dots */
278         if (dt == OB_TEXTURE && vd->drawtype == OB_TEXTURE)
279                 return false;
280
281         if ((vd->drawtype >= OB_SOLID) && (vd->flag2 & V3D_SOLID_TEX))
282                 return false;
283
284         return true;
285 }
286
287 /* ************************ */
288
289 /* check for glsl drawing */
290
291 bool draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
292 {
293         if (G.f & G_PICKSEL)
294                 return false;
295         if (!check_object_draw_texture(scene, v3d, dt))
296                 return false;
297         if (ob == OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
298                 return false;
299         
300         if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)
301                 return true;
302         
303         if (v3d->drawtype == OB_TEXTURE)
304                 return (scene->gm.matmode == GAME_MAT_GLSL && !BKE_scene_use_new_shading_nodes(scene));
305         else if (v3d->drawtype == OB_MATERIAL && dt > OB_SOLID)
306                 return true;
307         else
308                 return false;
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_uchar(vos->col.ub, 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         glScale3fv(size);
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;
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                 glTranslate3fv(vec);
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) {
1347                 float x, y, z, z_abs;
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                 x *= y;
1361
1362                 z_abs = fabsf(z);
1363
1364                 if (la->mode & LA_SQUARE) {
1365                         /* draw pyramid */
1366                         const float vertices[5][3] = {
1367                             /* 5 of vertex coords of pyramid */
1368                             {0.0f, 0.0f, 0.0f},
1369                             {z_abs, z_abs, x},
1370                             {-z_abs, -z_abs, x},
1371                             {z_abs, -z_abs, x},
1372                             {-z_abs, z_abs, x},
1373                         };
1374                         const unsigned char indices[] = {
1375                             0, 1, 3,
1376                             0, 3, 2,
1377                             0, 2, 4,
1378                             0, 1, 4,
1379                         };
1380
1381                         /* Draw call:
1382                          * activate and specify pointer to vertex array */
1383                         glEnableClientState(GL_VERTEX_ARRAY);
1384                         glVertexPointer(3, GL_FLOAT, 0, vertices);
1385                         /* draw the pyramid */
1386                         glDrawElements(GL_LINE_STRIP, 12, GL_UNSIGNED_BYTE, indices);
1387
1388                         /* deactivate vertex arrays after drawing */
1389                         glDisableClientState(GL_VERTEX_ARRAY);
1390
1391                         glTranslatef(0.0f, 0.0f, x);
1392
1393                         /* draw the square representing spotbl */
1394                         if (la->type == LA_SPOT) {
1395                                 float blend = z_abs * (1.0f - pow2f(la->spotblend));
1396
1397                                 /* hide line if it is zero size or overlaps with outer border,
1398                                  * previously it adjusted to always to show it but that seems
1399                                  * confusing because it doesn't show the actual blend size */
1400                                 if (blend != 0.0f && blend != z_abs) {
1401                                         fdrawbox(blend, -blend, -blend, blend);
1402                                 }
1403                         }
1404                 }
1405                 else {
1406
1407                         /* draw the angled sides of the cone */
1408                         glBegin(GL_LINE_STRIP);
1409                         glVertex3fv(vvec);
1410                         glVertex3fv(vec);
1411                         glVertex3fv(lvec);
1412                         glEnd();
1413
1414                         /* draw the circle at the end of the cone */
1415                         glTranslatef(0.0f, 0.0f, x);
1416                         circ(0.0f, 0.0f, z_abs);
1417
1418                         /* draw the circle representing spotbl */
1419                         if (la->type == LA_SPOT) {
1420                                 float blend = z_abs * (1.0f - pow2f(la->spotblend));
1421
1422                                 /* hide line if it is zero size or overlaps with outer border,
1423                                 * previously it adjusted to always to show it but that seems
1424                                 * confusing because it doesn't show the actual blend size */
1425                                 if (blend != 0.0f && blend != z_abs) {
1426                                         circ(0.0f, 0.0f, blend);
1427                                 }
1428                         }
1429                 }
1430
1431                 if (drawcone)
1432                         draw_transp_spot_volume(la, x, z);
1433
1434                 /* draw clip start, useful for wide cones where its not obvious where the start is */
1435                 glTranslatef(0.0, 0.0, -x);  /* reverse translation above */
1436                 if (la->type == LA_SPOT && (la->mode & LA_SHAD_BUF)) {
1437                         float lvec_clip[3];
1438                         float vvec_clip[3];
1439                         float clipsta_fac = la->clipsta / -x;
1440
1441                         interp_v3_v3v3(lvec_clip, vec, lvec, clipsta_fac);
1442                         interp_v3_v3v3(vvec_clip, vec, vvec, clipsta_fac);
1443
1444                         glBegin(GL_LINE_STRIP);
1445                         glVertex3fv(lvec_clip);
1446                         glVertex3fv(vvec_clip);
1447                         glEnd();
1448                 }
1449                 /* Else, draw spot direction (using distance as end limit, same as for Area lamp). */
1450                 else {
1451                         glBegin(GL_LINE_STRIP);
1452                         glVertex3f(0.0, 0.0, -circrad);
1453                         glVertex3f(0.0, 0.0, -la->dist);
1454                         glEnd();
1455                 }
1456         }
1457         else if (ELEM(la->type, LA_HEMI, LA_SUN)) {
1458                 
1459                 /* draw the line from the circle along the dist */
1460                 glBegin(GL_LINE_STRIP);
1461                 vec[2] = -circrad;
1462                 glVertex3fv(vec);
1463                 vec[2] = -la->dist;
1464                 glVertex3fv(vec);
1465                 glEnd();
1466                 
1467                 if (la->type == LA_HEMI) {
1468                         /* draw the hemisphere curves */
1469                         short axis, steps, dir;
1470                         float outdist, zdist, mul;
1471                         zero_v3(vec);
1472                         outdist = 0.14; mul = 1.4; dir = 1;
1473                         
1474                         setlinestyle(4);
1475                         /* loop over the 4 compass points, and draw each arc as a LINE_STRIP */
1476                         for (axis = 0; axis < 4; axis++) {
1477                                 float v[3] = {0.0, 0.0, 0.0};
1478                                 zdist = 0.02;
1479                                 
1480                                 glBegin(GL_LINE_STRIP);
1481                                 
1482                                 for (steps = 0; steps < 6; steps++) {
1483                                         if (axis == 0 || axis == 1) {       /* x axis up, x axis down */
1484                                                 /* make the arcs start at the edge of the energy circle */
1485                                                 if (steps == 0) v[0] = dir * circrad;
1486                                                 else v[0] = v[0] + dir * (steps * outdist);
1487                                         }
1488                                         else if (axis == 2 || axis == 3) {      /* y axis up, y axis down */
1489                                                 /* make the arcs start at the edge of the energy circle */
1490                                                 v[1] = (steps == 0) ? (dir * circrad) : (v[1] + dir * (steps * outdist));
1491                                         }
1492
1493                                         v[2] = v[2] - steps * zdist;
1494                                         
1495                                         glVertex3fv(v);
1496                                         
1497                                         zdist = zdist * mul;
1498                                 }
1499                                 
1500                                 glEnd();
1501                                 /* flip the direction */
1502                                 dir = -dir;
1503                         }
1504                 }
1505
1506 #ifdef WITH_GAMEENGINE
1507                 if (drawshadowbox) {
1508                         draw_transp_sun_volume(la);
1509                 }
1510 #endif
1511
1512         }
1513         else if (la->type == LA_AREA) {
1514                 setlinestyle(3);
1515                 if (la->area_shape == LA_AREA_SQUARE)
1516                         fdrawbox(-la->area_size * 0.5f, -la->area_size * 0.5f, la->area_size * 0.5f, la->area_size * 0.5f);
1517                 else if (la->area_shape == LA_AREA_RECT)
1518                         fdrawbox(-la->area_size * 0.5f, -la->area_sizey * 0.5f, la->area_size * 0.5f, la->area_sizey * 0.5f);
1519
1520                 glBegin(GL_LINE_STRIP);
1521                 glVertex3f(0.0, 0.0, -circrad);
1522                 glVertex3f(0.0, 0.0, -la->dist);
1523                 glEnd();
1524         }
1525         
1526         /* and back to viewspace */
1527         glPushMatrix();
1528         glLoadMatrixf(rv3d->viewmat);
1529         copy_v3_v3(vec, ob->obmat[3]);
1530
1531         setlinestyle(0);
1532         
1533         if ((la->type == LA_SPOT) && (la->mode & LA_SHAD_BUF) && (is_view == false)) {
1534                 drawshadbuflimits(la, ob->obmat);
1535         }
1536         
1537         if ((dflag & DRAW_CONSTCOLOR) == 0) {
1538                 UI_GetThemeColor4ubv(TH_LAMP, col);
1539                 glColor4ubv(col);
1540         }
1541
1542         glEnable(GL_BLEND);
1543         
1544         if (vec[2] > 0) vec[2] -= circrad;
1545         else vec[2] += circrad;
1546         
1547         glBegin(GL_LINE_STRIP);
1548         glVertex3fv(vec);
1549         vec[2] = 0;
1550         glVertex3fv(vec);
1551         glEnd();
1552         
1553         glPointSize(2.0);
1554         glBegin(GL_POINTS);
1555         glVertex3fv(vec);
1556         glEnd();
1557         glPointSize(1.0);
1558         
1559         glDisable(GL_BLEND);
1560         
1561         if ((dflag & DRAW_CONSTCOLOR) == 0) {
1562                 /* restore for drawing extra stuff */
1563                 glColor3ubv(ob_wire_col);
1564         }
1565         /* and finally back to org object space! */
1566         glPopMatrix();
1567 }
1568
1569 static void draw_limit_line(float sta, float end, const short dflag, const unsigned char col[3])
1570 {
1571         glBegin(GL_LINES);
1572         glVertex3f(0.0, 0.0, -sta);
1573         glVertex3f(0.0, 0.0, -end);
1574         glEnd();
1575
1576         if (!(dflag & DRAW_PICKING)) {
1577                 glPointSize(3.0);
1578                 glBegin(GL_POINTS);
1579                 if ((dflag & DRAW_CONSTCOLOR) == 0) {
1580                         glColor3ubv(col);
1581                 }
1582                 glVertex3f(0.0, 0.0, -sta);
1583                 glVertex3f(0.0, 0.0, -end);
1584                 glEnd();
1585                 glPointSize(1.0);
1586         }
1587 }
1588
1589
1590 /* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */
1591 /* qdn: now also enabled for Blender to set focus point for defocus composite node */
1592 static void draw_focus_cross(float dist, float size)
1593 {
1594         glBegin(GL_LINES);
1595         glVertex3f(-size, 0.0f, -dist);
1596         glVertex3f(size, 0.0f, -dist);
1597         glVertex3f(0.0f, -size, -dist);
1598         glVertex3f(0.0f, size, -dist);
1599         glEnd();
1600 }
1601
1602 #ifdef VIEW3D_CAMERA_BORDER_HACK
1603 unsigned char view3d_camera_border_hack_col[3];
1604 bool view3d_camera_border_hack_test = false;
1605 #endif
1606
1607 /* ****************** draw clip data *************** */
1608
1609 static void draw_bundle_sphere(void)
1610 {
1611         static GLuint displist = 0;
1612
1613         if (displist == 0) {
1614                 GLUquadricObj *qobj;
1615
1616                 displist = glGenLists(1);
1617                 glNewList(displist, GL_COMPILE);
1618
1619                 qobj = gluNewQuadric();
1620                 gluQuadricDrawStyle(qobj, GLU_FILL);
1621                 glShadeModel(GL_SMOOTH);
1622                 gluSphere(qobj, 0.05, 8, 8);
1623                 glShadeModel(GL_FLAT);
1624                 gluDeleteQuadric(qobj);
1625
1626                 glEndList();
1627         }
1628
1629         glCallList(displist);
1630 }
1631
1632 static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D *v3d,
1633                                                 MovieClip *clip, MovieTrackingObject *tracking_object,
1634                                                 const short dflag, const unsigned char ob_wire_col[4],
1635                                                 int *global_track_index, bool draw_selected)
1636 {
1637         MovieTracking *tracking = &clip->tracking;
1638         MovieTrackingTrack *track;
1639         float mat[4][4], imat[4][4];
1640         unsigned char col_unsel[4], col_sel[4];
1641         int tracknr = *global_track_index;
1642         ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object);
1643         float camera_size[3];
1644
1645         UI_GetThemeColor4ubv(TH_TEXT, col_unsel);
1646         UI_GetThemeColor4ubv(TH_SELECT, col_sel);
1647
1648         BKE_tracking_get_camera_object_matrix(scene, base->object, mat);
1649
1650         /* we're compensating camera size for bundles size,
1651          * to make it so bundles are always displayed with the same size */
1652         copy_v3_v3(camera_size, base->object->size);
1653         if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0)
1654                 mul_v3_fl(camera_size, tracking_object->scale);
1655
1656         glPushMatrix();
1657
1658         if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
1659                 /* current ogl matrix is translated in camera space, bundles should
1660                  * be rendered in world space, so camera matrix should be "removed"
1661                  * from current ogl matrix */
1662                 invert_m4_m4(imat, base->object->obmat);
1663
1664                 glMultMatrixf(imat);
1665                 glMultMatrixf(mat);
1666         }
1667         else {
1668                 float obmat[4][4];
1669                 int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra);
1670
1671                 BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, obmat);
1672
1673                 invert_m4_m4(imat, obmat);
1674                 glMultMatrixf(imat);
1675         }
1676
1677         for (track = tracksbase->first; track; track = track->next) {
1678                 bool selected = TRACK_SELECTED(track);
1679
1680                 if (draw_selected && !selected)
1681                         continue;
1682
1683                 if ((track->flag & TRACK_HAS_BUNDLE) == 0)
1684                         continue;
1685
1686                 if (dflag & DRAW_PICKING)
1687                         GPU_select_load_id(base->selcol + (tracknr << 16));
1688
1689                 glPushMatrix();
1690                 glTranslate3fv(track->bundle_pos);
1691                 glScalef(v3d->bundle_size / 0.05f / camera_size[0],
1692                          v3d->bundle_size / 0.05f / camera_size[1],
1693                          v3d->bundle_size / 0.05f / camera_size[2]);
1694
1695                 if (v3d->drawtype == OB_WIRE) {
1696                         if ((dflag & DRAW_CONSTCOLOR) == 0) {
1697                                 if (selected && (track->flag & TRACK_CUSTOMCOLOR) == 0) {
1698                                         glColor3ubv(ob_wire_col);
1699                                 }
1700                                 else {
1701                                         glColor3fv(track->color);
1702                                 }
1703                         }
1704
1705                         drawaxes(0.05f, v3d->bundle_drawtype);
1706                 }
1707                 else if (v3d->drawtype > OB_WIRE) {
1708                         if (v3d->bundle_drawtype == OB_EMPTY_SPHERE) {
1709                                 /* selection outline */
1710                                 if (selected) {
1711                                         if ((dflag & DRAW_CONSTCOLOR) == 0) {
1712                                                 glColor3ubv(ob_wire_col);
1713                                         }
1714
1715                                         glLineWidth(2.0f);
1716                                         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1717
1718                                         draw_bundle_sphere();
1719
1720                                         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1721                                         glLineWidth(1.0f);
1722                                 }
1723
1724                                 if ((dflag & DRAW_CONSTCOLOR) == 0) {
1725                                         if (track->flag & TRACK_CUSTOMCOLOR) glColor3fv(track->color);
1726                                         else UI_ThemeColor(TH_BUNDLE_SOLID);
1727                                 }
1728
1729                                 draw_bundle_sphere();
1730                         }
1731                         else {
1732                                 if ((dflag & DRAW_CONSTCOLOR) == 0) {
1733                                         if (selected) {
1734                                                 glColor3ubv(ob_wire_col);
1735                                         }
1736                                         else {
1737                                                 if (track->flag & TRACK_CUSTOMCOLOR) glColor3fv(track->color);
1738                                                 else UI_ThemeColor(TH_WIRE);
1739                                         }
1740                                 }
1741
1742                                 drawaxes(0.05f, v3d->bundle_drawtype);
1743                         }
1744                 }
1745
1746                 glPopMatrix();
1747
1748                 if ((dflag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLENAME)) {
1749                         float pos[3];
1750
1751                         mul_v3_m4v3(pos, mat, track->bundle_pos);
1752                         view3d_cached_text_draw_add(pos,
1753                                                     track->name, strlen(track->name),
1754                                                     10, V3D_CACHE_TEXT_GLOBALSPACE,
1755                                                     selected ? col_sel : col_unsel);
1756                 }
1757
1758                 tracknr++;
1759         }
1760
1761         if ((dflag & DRAW_PICKING) == 0) {
1762                 if ((v3d->flag2 & V3D_SHOW_CAMERAPATH) && (tracking_object->flag & TRACKING_OBJECT_CAMERA)) {
1763                         MovieTrackingReconstruction *reconstruction;
1764                         reconstruction = BKE_tracking_object_get_reconstruction(tracking, tracking_object);
1765
1766                         if (reconstruction->camnr) {
1767                                 MovieReconstructedCamera *camera = reconstruction->cameras;
1768                                 int a = 0;
1769
1770                                 UI_ThemeColor(TH_CAMERA_PATH);
1771                                 glLineWidth(2.0f);
1772
1773                                 glBegin(GL_LINE_STRIP);
1774                                 for (a = 0; a < reconstruction->camnr; a++, camera++) {
1775                                         glVertex3fv(camera->mat[3]);
1776                                 }
1777                                 glEnd();
1778
1779                                 glLineWidth(1.0f);
1780                         }
1781                 }
1782         }
1783
1784         glPopMatrix();
1785
1786         *global_track_index = tracknr;
1787 }
1788
1789 static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip,
1790                                          const short dflag, const unsigned char ob_wire_col[4],
1791                                          const bool draw_selected)
1792 {
1793         MovieTracking *tracking = &clip->tracking;
1794         MovieTrackingObject *tracking_object;
1795         int global_track_index = 1;
1796
1797         if ((v3d->flag2 & V3D_SHOW_RECONSTRUCTION) == 0)
1798                 return;
1799
1800         if (v3d->flag2 & V3D_RENDER_OVERRIDE)
1801                 return;
1802
1803         GPU_simple_shader_colors(NULL, NULL, 0, 1.0f);
1804         GPU_simple_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
1805
1806         glShadeModel(GL_SMOOTH);
1807
1808         tracking_object = tracking->objects.first;
1809         while (tracking_object) {
1810                 draw_viewport_object_reconstruction(scene, base, v3d, clip, tracking_object,
1811                                                     dflag, ob_wire_col, &global_track_index, draw_selected);
1812
1813                 tracking_object = tracking_object->next;
1814         }
1815
1816         /* restore */
1817         glShadeModel(GL_FLAT);
1818         GPU_simple_shader_bind(GPU_SHADER_USE_COLOR);
1819
1820         if ((dflag & DRAW_CONSTCOLOR) == 0) {
1821                 glColor3ubv(ob_wire_col);
1822         }
1823
1824         if (dflag & DRAW_PICKING)
1825                 GPU_select_load_id(base->selcol);
1826 }
1827
1828 static void drawcamera_volume(float near_plane[4][3], float far_plane[4][3], const GLenum mode)
1829 {
1830         glBegin(mode);
1831         glVertex3fv(near_plane[0]);
1832         glVertex3fv(far_plane[0]);
1833         glVertex3fv(far_plane[1]);
1834         glVertex3fv(near_plane[1]);
1835         glEnd();
1836
1837         glBegin(mode);
1838         glVertex3fv(near_plane[1]);
1839         glVertex3fv(far_plane[1]);
1840         glVertex3fv(far_plane[2]);
1841         glVertex3fv(near_plane[2]);
1842         glEnd();
1843
1844         glBegin(mode);
1845         glVertex3fv(near_plane[2]);
1846         glVertex3fv(near_plane[1]);
1847         glVertex3fv(far_plane[1]);
1848         glVertex3fv(far_plane[2]);
1849         glEnd();
1850
1851         glBegin(mode);
1852         glVertex3fv(far_plane[0]);
1853         glVertex3fv(near_plane[0]);
1854         glVertex3fv(near_plane[3]);
1855         glVertex3fv(far_plane[3]);
1856         glEnd();
1857 }
1858
1859 /* camera frame */
1860 static void drawcamera_frame(float vec[4][3], const GLenum mode)
1861 {
1862         glBegin(mode);
1863         glVertex3fv(vec[0]);
1864         glVertex3fv(vec[1]);
1865         glVertex3fv(vec[2]);
1866         glVertex3fv(vec[3]);
1867         glEnd();
1868 }
1869
1870 /* center point to camera frame */
1871 static void drawcamera_framelines(float vec[4][3], float origin[3])
1872 {
1873         glBegin(GL_LINE_STRIP);
1874         glVertex3fv(vec[1]);
1875         glVertex3fv(origin);
1876         glVertex3fv(vec[0]);
1877         glVertex3fv(vec[3]);
1878         glVertex3fv(origin);
1879         glVertex3fv(vec[2]);
1880         glEnd();
1881 }
1882
1883 static bool drawcamera_is_stereo3d(Scene *scene, View3D *v3d, Object *ob)
1884 {
1885         return (ob == v3d->camera) &&
1886                 (scene->r.scemode & R_MULTIVIEW) != 0 &&
1887                 (v3d->stereo3d_flag);
1888 }
1889
1890 static void drawcamera_stereo3d(
1891         Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const Camera *cam,
1892         float vec[4][3], float drawsize, const float scale[3])
1893 {
1894         int i;
1895         float obmat[4][4];
1896         float vec_lr[2][4][3];
1897         const float fac = (cam->stereo.pivot == CAM_S3D_PIVOT_CENTER) ? 2.0f : 1.0f;
1898         float origin[2][3] = {{0}};
1899         float tvec[3];
1900         const Camera *cam_lr[2];
1901         const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
1902
1903         const bool is_stereo3d_cameras = (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS) && (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D);
1904         const bool is_stereo3d_plane = (v3d->stereo3d_flag & V3D_S3D_DISPPLANE) && (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D);
1905         const bool is_stereo3d_volume = (v3d->stereo3d_flag & V3D_S3D_DISPVOLUME);
1906
1907         zero_v3(tvec);
1908
1909         glPushMatrix();
1910
1911         for (i = 0; i < 2; i++) {
1912                 ob = BKE_camera_multiview_render(scene, ob, names[i]);
1913                 cam_lr[i] = ob->data;
1914
1915                 glLoadMatrixf(rv3d->viewmat);
1916                 BKE_camera_multiview_model_matrix(&scene->r, ob, names[i], obmat);
1917                 glMultMatrixf(obmat);
1918
1919                 copy_m3_m3(vec_lr[i], vec);
1920                 copy_v3_v3(vec_lr[i][3], vec[3]);
1921
1922                 if (cam->stereo.convergence_mode == CAM_S3D_OFFAXIS) {
1923                         const float shift_x =
1924                                 ((BKE_camera_multiview_shift_x(&scene->r, ob, names[i]) - cam->shiftx) *
1925                                  (drawsize * scale[0] * fac));
1926
1927                         for (int j = 0; j < 4; j++) {
1928                                 vec_lr[i][j][0] += shift_x;
1929                         }
1930                 }
1931
1932                 if (is_stereo3d_cameras) {
1933                         /* camera frame */
1934                         drawcamera_frame(vec_lr[i], GL_LINE_LOOP);
1935
1936                         /* center point to camera frame */
1937                         drawcamera_framelines(vec_lr[i], tvec);
1938                 }
1939
1940                 /* connecting line */
1941                 mul_m4_v3(obmat, origin[i]);
1942
1943                 /* convergence plane */
1944                 if (is_stereo3d_plane || is_stereo3d_volume) {
1945                         for (int j = 0; j < 4; j++) {
1946                                 mul_m4_v3(obmat, vec_lr[i][j]);
1947                         }
1948                 }
1949         }
1950
1951
1952         /* the remaining drawing takes place in the view space */
1953         glLoadMatrixf(rv3d->viewmat);
1954
1955         if (is_stereo3d_cameras) {
1956                 /* draw connecting lines */
1957                 glPushAttrib(GL_ENABLE_BIT);
1958
1959                 glLineStipple(2, 0xAAAA);
1960                 glEnable(GL_LINE_STIPPLE);
1961
1962                 glBegin(GL_LINES);
1963                 glVertex3fv(origin[0]);
1964                 glVertex3fv(origin[1]);
1965                 glEnd();
1966                 glPopAttrib();
1967         }
1968
1969         /* draw convergence plane*/
1970         if (is_stereo3d_plane) {
1971                 float axis_center[3], screen_center[3];
1972                 float world_plane[4][3];
1973                 float local_plane[4][3];
1974                 float offset;
1975
1976                 mid_v3_v3v3(axis_center, origin[0], origin[1]);
1977
1978                 for (i = 0; i < 4; i++) {
1979                         mid_v3_v3v3(world_plane[i], vec_lr[0][i], vec_lr[1][i]);
1980                         sub_v3_v3v3(local_plane[i], world_plane[i], axis_center);
1981                 }
1982
1983                 mid_v3_v3v3(screen_center, world_plane[0], world_plane[2]);
1984                 offset = cam->stereo.convergence_distance / len_v3v3(screen_center, axis_center);
1985
1986                 for (i = 0; i < 4; i++) {
1987                         mul_v3_fl(local_plane[i], offset);
1988                         add_v3_v3(local_plane[i], axis_center);
1989                 }
1990
1991                 glColor3f(0.0f, 0.0f, 0.0f);
1992
1993                 /* camera frame */
1994                 drawcamera_frame(local_plane, GL_LINE_LOOP);
1995
1996                 if (v3d->stereo3d_convergence_alpha > 0.0f) {
1997                         glEnable(GL_BLEND);
1998                         glDepthMask(0);  /* disable write in zbuffer, needed for nice transp */
1999
2000                         glColor4f(0.0f, 0.0f, 0.0f, v3d->stereo3d_convergence_alpha);
2001
2002                         drawcamera_frame(local_plane, GL_QUADS);
2003
2004                         glDisable(GL_BLEND);
2005                         glDepthMask(1);  /* restore write in zbuffer */
2006                 }
2007         }
2008
2009         /* draw convergence plane*/
2010         if (is_stereo3d_volume) {
2011                 float screen_center[3];
2012                 float near_plane[4][3], far_plane[4][3];
2013                 float offset;
2014                 int j;
2015
2016                 for (i = 0; i < 2; i++) {
2017                         mid_v3_v3v3(screen_center, vec_lr[i][0], vec_lr[i][2]);
2018
2019                         offset = len_v3v3(screen_center, origin[i]);
2020
2021                         for (j = 0; j < 4; j++) {
2022                                 sub_v3_v3v3(near_plane[j], vec_lr[i][j], origin[i]);
2023                                 mul_v3_fl(near_plane[j], cam_lr[i]->clipsta / offset);
2024                                 add_v3_v3(near_plane[j], origin[i]);
2025
2026                                 sub_v3_v3v3(far_plane[j], vec_lr[i][j], origin[i]);
2027                                 mul_v3_fl(far_plane[j], cam_lr[i]->clipend / offset);
2028                                 add_v3_v3(far_plane[j], origin[i]);
2029                         }
2030
2031                         /* camera frame */
2032                         glColor3f(0.0f, 0.0f, 0.0f);
2033
2034                         drawcamera_frame(near_plane, GL_LINE_LOOP);
2035                         drawcamera_frame(far_plane, GL_LINE_LOOP);
2036                         drawcamera_volume(near_plane, far_plane, GL_LINE_LOOP);
2037
2038                         if (v3d->stereo3d_volume_alpha > 0.0f) {
2039                                 glEnable(GL_BLEND);
2040                                 glDepthMask(0);  /* disable write in zbuffer, needed for nice transp */
2041
2042                                 if (i == 0)
2043                                         glColor4f(0.0f, 1.0f, 1.0f, v3d->stereo3d_volume_alpha);
2044                                 else
2045                                         glColor4f(1.0f, 0.0f, 0.0f, v3d->stereo3d_volume_alpha);
2046
2047                                 drawcamera_frame(near_plane, GL_QUADS);
2048                                 drawcamera_frame(far_plane, GL_QUADS);
2049                                 drawcamera_volume(near_plane, far_plane, GL_QUADS);
2050
2051                                 glDisable(GL_BLEND);
2052                                 glDepthMask(1);  /* restore write in zbuffer */
2053                         }
2054                 }
2055         }
2056
2057         glPopMatrix();
2058 }
2059
2060 /* flag similar to draw_object() */
2061 static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
2062                        const short dflag, const unsigned char ob_wire_col[4])
2063 {
2064         /* a standing up pyramid with (0,0,0) as top */
2065         Camera *cam;
2066         Object *ob = base->object;
2067         float tvec[3];
2068         float vec[4][3], asp[2], shift[2], scale[3];
2069         int i;
2070         float drawsize;
2071         MovieClip *clip = BKE_object_movieclip_get(scene, base->object, false);
2072
2073         const bool is_active = (ob == v3d->camera);
2074         const bool is_view = (rv3d->persp == RV3D_CAMOB && is_active);
2075         const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0;
2076         const bool is_stereo3d = drawcamera_is_stereo3d(scene, v3d, ob);
2077         const bool is_stereo3d_view = (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D);
2078         const bool is_stereo3d_cameras = (ob == scene->camera) &&
2079                                          is_multiview &&
2080                                          is_stereo3d_view &&
2081                                          (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS);
2082         const bool is_selection_camera_stereo = (G.f & G_PICKSEL) &&
2083                                                 is_view && is_multiview &&
2084                                                 is_stereo3d_view;
2085
2086         /* draw data for movie clip set as active for scene */
2087         if (clip) {
2088                 draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_wire_col, false);
2089                 draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_wire_col, true);
2090         }
2091
2092 #ifdef VIEW3D_CAMERA_BORDER_HACK
2093         if (is_view && !(G.f & G_PICKSEL)) {
2094                 if ((dflag & DRAW_CONSTCOLOR) == 0) {
2095                         view3d_camera_border_hack_col[0] = ob_wire_col[0];
2096                         view3d_camera_border_hack_col[1] = ob_wire_col[1];
2097                         view3d_camera_border_hack_col[2] = ob_wire_col[2];
2098                 }
2099                 else {
2100                         float col[4];
2101                         glGetFloatv(GL_CURRENT_COLOR, col);
2102                         rgb_float_to_uchar(view3d_camera_border_hack_col, col);
2103                 }
2104                 view3d_camera_border_hack_test = true;
2105                 return;
2106         }
2107 #endif
2108
2109         cam = ob->data;
2110
2111         /* BKE_camera_multiview_model_matrix already accounts for scale, don't do it here */
2112         if (is_selection_camera_stereo) {
2113                 scale[0] = 1.0f;
2114                 scale[1] = 1.0f;
2115                 scale[2] = 1.0f;
2116         }
2117         else {
2118                 scale[0] = 1.0f / len_v3(ob->obmat[0]);
2119                 scale[1] = 1.0f / len_v3(ob->obmat[1]);
2120                 scale[2] = 1.0f / len_v3(ob->obmat[2]);
2121         }
2122
2123         BKE_camera_view_frame_ex(scene, cam, cam->drawsize, is_view, scale,
2124                                  asp, shift, &drawsize, vec);
2125
2126         glDisable(GL_CULL_FACE);
2127
2128         /* camera frame */
2129         if (!is_stereo3d_cameras) {
2130                 /* make sure selection uses the same matrix for camera as the one used while viewing */
2131                 if (is_selection_camera_stereo) {
2132                         float obmat[4][4];
2133                         bool is_left = v3d->multiview_eye == STEREO_LEFT_ID;
2134
2135                         glPushMatrix();
2136                         glLoadMatrixf(rv3d->viewmat);
2137                         BKE_camera_multiview_model_matrix(&scene->r, ob, is_left ? STEREO_LEFT_NAME : STEREO_RIGHT_NAME, obmat);
2138                         glMultMatrixf(obmat);
2139
2140                         drawcamera_frame(vec, GL_LINE_LOOP);
2141                         glPopMatrix();
2142                 }
2143                 else {
2144                         drawcamera_frame(vec, GL_LINE_LOOP);
2145                 }
2146         }
2147
2148         if (is_view)
2149                 return;
2150
2151         zero_v3(tvec);
2152
2153         /* center point to camera frame */
2154         if (!is_stereo3d_cameras)
2155                 drawcamera_framelines(vec, tvec);
2156
2157         /* arrow on top */
2158         tvec[2] = vec[1][2]; /* copy the depth */
2159
2160         /* draw an outline arrow for inactive cameras and filled
2161          * for active cameras. We actually draw both outline+filled
2162          * for active cameras so the wire can be seen side-on */
2163         for (i = 0; i < 2; i++) {
2164                 if (i == 0) glBegin(GL_LINE_LOOP);
2165                 else if (i == 1 && is_active) glBegin(GL_TRIANGLES);
2166                 else break;
2167
2168                 tvec[0] = shift[0] + ((-0.7f * drawsize) * scale[0]);
2169                 tvec[1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]);
2170                 glVertex3fv(tvec); /* left */
2171                 
2172                 tvec[0] = shift[0] + ((0.7f * drawsize) * scale[0]);
2173                 glVertex3fv(tvec); /* right */
2174                 
2175                 tvec[0] = shift[0];
2176                 tvec[1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]);
2177                 glVertex3fv(tvec); /* top */
2178
2179                 glEnd();
2180         }
2181
2182         if ((dflag & DRAW_SCENESET) == 0) {
2183                 if (cam->flag & (CAM_SHOWLIMITS | CAM_SHOWMIST)) {
2184                         float nobmat[4][4];
2185
2186                         /* draw in normalized object matrix space */
2187                         copy_m4_m4(nobmat, ob->obmat);
2188                         normalize_m4(nobmat);
2189
2190                         glPushMatrix();
2191                         glLoadMatrixf(rv3d->viewmat);
2192                         glMultMatrixf(nobmat);
2193
2194                         if (cam->flag & CAM_SHOWLIMITS) {
2195                                 const unsigned char col[3] = {128, 128, 60}, col_hi[3] = {255, 255, 120};
2196
2197                                 draw_limit_line(cam->clipsta, cam->clipend, dflag, (is_active ? col_hi : col));
2198                                 /* qdn: was yafray only, now also enabled for Blender to be used with defocus composite node */
2199                                 draw_focus_cross(BKE_camera_object_dof_distance(ob), cam->drawsize);
2200                         }
2201
2202                         if (cam->flag & CAM_SHOWMIST) {
2203                                 World *world = scene->world;
2204                                 const unsigned char col[3] = {128, 128, 128}, col_hi[3] = {255, 255, 255};
2205
2206                                 if (world) {
2207                                         draw_limit_line(world->miststa, world->miststa + world->mistdist,
2208                                                         dflag, (is_active ? col_hi : col));
2209                                 }
2210                         }
2211                         glPopMatrix();
2212                 }
2213         }
2214
2215         /* stereo cameras drawing */
2216         if (is_stereo3d) {
2217                 drawcamera_stereo3d(scene, v3d, rv3d, ob, cam, vec, drawsize, scale);
2218         }
2219 }
2220
2221 /* flag similar to draw_object() */
2222 static void drawspeaker(Scene *UNUSED(scene), View3D *UNUSED(v3d), RegionView3D *UNUSED(rv3d),
2223                         Object *UNUSED(ob), int UNUSED(flag))
2224 {
2225         float vec[3];
2226         int i, j;
2227
2228         glEnable(GL_BLEND);
2229
2230         for (j = 0; j < 3; j++) {
2231                 vec[2] = 0.25f * j - 0.125f;
2232
2233                 glBegin(GL_LINE_LOOP);
2234                 for (i = 0; i < 16; i++) {
2235                         vec[0] = cosf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
2236                         vec[1] = sinf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
2237                         glVertex3fv(vec);
2238                 }
2239                 glEnd();
2240         }
2241
2242         for (j = 0; j < 4; j++) {
2243                 vec[0] = (((j + 1) % 2) * (j - 1)) * 0.5f;
2244                 vec[1] = ((j % 2) * (j - 2)) * 0.5f;
2245                 glBegin(GL_LINE_STRIP);
2246                 for (i = 0; i < 3; i++) {
2247                         if (i == 1) {
2248                                 vec[0] *= 0.5f;
2249                                 vec[1] *= 0.5f;
2250                         }
2251
2252                         vec[2] = 0.25f * i - 0.125f;
2253                         glVertex3fv(vec);
2254                 }
2255                 glEnd();
2256         }
2257
2258         glDisable(GL_BLEND);
2259 }
2260
2261 static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short sel)
2262 {
2263         BPoint *bp = lt->def;
2264         const float *co = dl ? dl->verts : NULL;
2265         int u, v, w;
2266
2267         const int color = sel ? TH_VERTEX_SELECT : TH_VERTEX;
2268         UI_ThemeColor(color);
2269
2270         glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
2271         bglBegin(GL_POINTS);
2272
2273         for (w = 0; w < lt->pntsw; w++) {
2274                 int wxt = (w == 0 || w == lt->pntsw - 1);
2275                 for (v = 0; v < lt->pntsv; v++) {
2276                         int vxt = (v == 0 || v == lt->pntsv - 1);
2277                         for (u = 0; u < lt->pntsu; u++, bp++, co += 3) {
2278                                 int uxt = (u == 0 || u == lt->pntsu - 1);
2279                                 if (!(lt->flag & LT_OUTSIDE) || uxt || vxt || wxt) {
2280                                         if (bp->hide == 0) {
2281                                                 /* check for active BPoint and ensure selected */
2282                                                 if ((bp == actbp) && (bp->f1 & SELECT)) {
2283                                                         UI_ThemeColor(TH_ACTIVE_VERT);
2284                                                         bglVertex3fv(dl ? co : bp->vec);
2285                                                         UI_ThemeColor(color);
2286                                                 }
2287                                                 else if ((bp->f1 & SELECT) == sel) {
2288                                                         bglVertex3fv(dl ? co : bp->vec);
2289                                                 }
2290                                         }
2291                                 }
2292                         }
2293                 }
2294         }
2295         
2296         bglEnd();
2297         glPointSize(1.0);
2298 }
2299
2300 static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int actdef_wcol)
2301 {
2302         int index = ((w * lt->pntsv + v) * lt->pntsu) + u;
2303
2304         if (actdef_wcol) {
2305                 float col[3];
2306                 MDeformWeight *mdw = defvert_find_index(lt->dvert + index, actdef_wcol - 1);
2307                 
2308                 weight_to_rgb(col, mdw ? mdw->weight : 0.0f);
2309                 glColor3fv(col);
2310
2311         }
2312         
2313         if (dl) {
2314                 glVertex3fv(&dl->verts[index * 3]);
2315         }
2316         else {
2317                 glVertex3fv(lt->def[index].vec);
2318         }
2319 }
2320
2321 #ifdef SEQUENCER_DAG_WORKAROUND
2322 static void ensure_curve_cache(Scene *scene, Object *object)
2323 {
2324         bool need_recalc = object->curve_cache == NULL;
2325         /* Render thread might have freed the curve cache if the
2326          * object is not visible. If the object is also used for
2327          * particles duplication, then render thread might have
2328          * also created curve_cache with only bevel and path
2329          * filled in.
2330          *
2331          * So check for curve_cache != NULL is not fully correct
2332          * here, we also need to check whether display list is
2333          * empty or not.
2334          *
2335          * The trick below tries to optimize calls to displist
2336          * creation for cases curve is empty. Meaning, if the curve
2337          * is empty (without splines) bevel list would also be empty.
2338          * And the thing is, render thread always leaves bevel list
2339          * in a proper state. So if bevel list is here and display
2340          * list is not we need to make display list.
2341          */
2342         if (need_recalc == false) {
2343                 need_recalc = object->curve_cache->disp.first == NULL &&
2344                               object->curve_cache->bev.first != NULL;
2345         }
2346         if (need_recalc) {
2347                 switch (object->type) {
2348                         case OB_CURVE:
2349                         case OB_SURF:
2350                         case OB_FONT:
2351                                 BKE_displist_make_curveTypes(scene, object, false);
2352                                 break;
2353                         case OB_MBALL:
2354                                 BKE_displist_make_mball(G.main->eval_ctx, scene, object);
2355                                 break;
2356                         case OB_LATTICE:
2357                                 BKE_lattice_modifiers_calc(scene, object);
2358                                 break;
2359                 }
2360         }
2361 }
2362 #endif
2363
2364 /* lattice color is hardcoded, now also shows weightgroup values in edit mode */
2365 static void drawlattice(View3D *v3d, Object *ob)
2366 {
2367         Lattice *lt = ob->data;
2368         DispList *dl;
2369         int u, v, w;
2370         int actdef_wcol = 0;
2371         const bool is_edit = (lt->editlatt != NULL);
2372
2373         dl = BKE_displist_find(&ob->curve_cache->disp, DL_VERTS);
2374         
2375         if (is_edit) {
2376                 lt = lt->editlatt->latt;
2377
2378                 UI_ThemeColor(TH_WIRE_EDIT);
2379                 
2380                 if (ob->defbase.first && lt->dvert) {
2381                         actdef_wcol = ob->actdef;
2382                         glShadeModel(GL_SMOOTH);
2383                 }
2384         }
2385         
2386         glBegin(GL_LINES);
2387         for (w = 0; w < lt->pntsw; w++) {
2388                 int wxt = (w == 0 || w == lt->pntsw - 1);
2389                 for (v = 0; v < lt->pntsv; v++) {
2390                         int vxt = (v == 0 || v == lt->pntsv - 1);
2391                         for (u = 0; u < lt->pntsu; u++) {
2392                                 int uxt = (u == 0 || u == lt->pntsu - 1);
2393
2394                                 if (w && ((uxt || vxt) || !(lt->flag & LT_OUTSIDE))) {
2395                                         drawlattice__point(lt, dl, u, v, w - 1, actdef_wcol);
2396                                         drawlattice__point(lt, dl, u, v, w, actdef_wcol);
2397                                 }
2398                                 if (v && ((uxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
2399                                         drawlattice__point(lt, dl, u, v - 1, w, actdef_wcol);
2400                                         drawlattice__point(lt, dl, u, v, w, actdef_wcol);
2401                                 }
2402                                 if (u && ((vxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
2403                                         drawlattice__point(lt, dl, u - 1, v, w, actdef_wcol);
2404                                         drawlattice__point(lt, dl, u, v, w, actdef_wcol);
2405                                 }
2406                         }
2407                 }
2408         }
2409         glEnd();
2410         
2411         /* restoration for weight colors */
2412         if (actdef_wcol)
2413                 glShadeModel(GL_FLAT);
2414
2415         if (is_edit) {
2416                 BPoint *actbp = BKE_lattice_active_point_get(lt);
2417
2418                 if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
2419                 
2420                 lattice_draw_verts(lt, dl, actbp, 0);
2421                 lattice_draw_verts(lt, dl, actbp, 1);
2422                 
2423                 if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
2424         }
2425 }
2426
2427 /* ***************** ******************** */
2428
2429 /*  draw callback */
2430
2431 typedef struct drawDMVertSel_userData {
2432         MVert *mvert;
2433         int active;
2434         unsigned char *col[3];  /* (base, sel, act) */
2435         char sel_prev;
2436 } drawDMVertSel_userData;
2437
2438 static void drawSelectedVertices__mapFunc(void *userData, int index, const float co[3],
2439                                           const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
2440 {
2441         drawDMVertSel_userData *data = userData;
2442         MVert *mv = &data->mvert[index];
2443
2444         if (!(mv->flag & ME_HIDE)) {
2445                 const char sel = (index == data->active) ? 2 : (mv->flag & SELECT);
2446                 if (sel != data->sel_prev) {
2447                         glColor3ubv(data->col[sel]);
2448                         data->sel_prev = sel;
2449                 }
2450
2451                 glVertex3fv(co);
2452         }
2453 }
2454
2455 static void drawSelectedVertices(DerivedMesh *dm, Mesh *me)
2456 {
2457         drawDMVertSel_userData data;
2458
2459         /* TODO define selected color */
2460         unsigned char base_col[3] = {0x0, 0x0, 0x0};
2461         unsigned char sel_col[3] = {0xd8, 0xb8, 0x0};
2462         unsigned char act_col[3] = {0xff, 0xff, 0xff};
2463
2464         data.mvert = me->mvert;
2465         data.active = BKE_mesh_mselect_active_get(me, ME_VSEL);
2466         data.sel_prev = 0xff;
2467
2468         data.col[0] = base_col;
2469         data.col[1] = sel_col;
2470         data.col[2] = act_col;
2471
2472         glBegin(GL_POINTS);
2473         dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data, DM_FOREACH_NOP);
2474         glEnd();
2475 }
2476
2477 /* ************** DRAW MESH ****************** */
2478
2479 /* First section is all the "simple" draw routines,
2480  * ones that just pass some sort of primitive to GL,
2481  * with perhaps various options to control lighting,
2482  * color, etc.
2483  *
2484  * These routines should not have user interface related
2485  * logic!!!
2486  */
2487
2488 static void calcDrawDMNormalScale(Object *ob, drawDMNormal_userData *data)
2489 {
2490         float obmat[3][3];
2491
2492         copy_m3_m4(obmat, ob->obmat);
2493
2494         data->uniform_scale = is_uniform_scaled_m3(obmat);
2495
2496         if (!data->uniform_scale) {
2497                 /* inverted matrix */
2498                 invert_m3_m3(data->imat, obmat);
2499
2500                 /* transposed inverted matrix */
2501                 transpose_m3_m3(data->tmat, data->imat);
2502         }
2503 }
2504
2505 static void draw_dm_face_normals__mapFunc(void *userData, int index, const float cent[3], const float no[3])
2506 {
2507         drawDMNormal_userData *data = userData;
2508         BMFace *efa = BM_face_at_index(data->bm, index);
2509         float n[3];
2510
2511         if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
2512                 if (!data->uniform_scale) {
2513                         mul_v3_m3v3(n, data->tmat, no);
2514                         normalize_v3(n);
2515                         mul_m3_v3(data->imat, n);
2516                 }
2517                 else {
2518                         copy_v3_v3(n, no);
2519                 }
2520
2521                 glVertex3fv(cent);
2522                 glVertex3f(cent[0] + n[0] * data->normalsize,
2523                            cent[1] + n[1] * data->normalsize,
2524                            cent[2] + n[2] * data->normalsize);
2525         }
2526 }
2527
2528 static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
2529 {
2530         drawDMNormal_userData data;
2531
2532         data.bm = em->bm;
2533         data.normalsize = scene->toolsettings->normalsize;
2534
2535         calcDrawDMNormalScale(ob, &data);
2536
2537         glBegin(GL_LINES);
2538         dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
2539         glEnd();
2540 }
2541
2542 static void draw_dm_face_centers__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
2543 {
2544         drawBMSelect_userData *data = userData;
2545         BMFace *efa = BM_face_at_index(data->bm, index);
2546         
2547         if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) &&
2548             (BM_elem_flag_test(efa, BM_ELEM_SELECT) == data->select))
2549         {
2550                 bglVertex3fv(cent);
2551         }
2552 }
2553 static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, bool select)
2554 {
2555         drawBMSelect_userData data = {em->bm, select};
2556
2557         bglBegin(GL_POINTS);
2558         dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, &data, DM_FOREACH_NOP);
2559         bglEnd();
2560 }
2561
2562 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])
2563 {
2564         drawDMNormal_userData *data = userData;
2565         BMVert *eve = BM_vert_at_index(data->bm, index);
2566
2567         if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
2568                 float no[3], n[3];
2569
2570                 if (no_f) {
2571                         copy_v3_v3(no, no_f);
2572                 }
2573                 else {
2574                         normal_short_to_float_v3(no, no_s);
2575                 }
2576
2577                 if (!data->uniform_scale) {
2578                         mul_v3_m3v3(n, data->tmat, no);
2579                         normalize_v3(n);
2580                         mul_m3_v3(data->imat, n);
2581                 }
2582                 else {
2583                         copy_v3_v3(n, no);
2584                 }
2585
2586                 glVertex3fv(co);
2587                 glVertex3f(co[0] + n[0] * data->normalsize,
2588                            co[1] + n[1] * data->normalsize,
2589                            co[2] + n[2] * data->normalsize);
2590         }
2591 }
2592
2593 static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
2594 {
2595         drawDMNormal_userData data;
2596
2597         data.bm = em->bm;
2598         data.normalsize = scene->toolsettings->normalsize;
2599
2600         calcDrawDMNormalScale(ob, &data);
2601
2602         glBegin(GL_LINES);
2603         dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
2604         glEnd();
2605 }
2606
2607 /* Draw verts with color set based on selection */
2608 static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3],
2609                                    const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
2610 {
2611         drawDMVerts_userData *data = userData;
2612         BMVert *eve = BM_vert_at_index(data->bm, index);
2613
2614         if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) {
2615                 /* skin nodes: draw a red circle around the root node(s) */
2616                 if (data->cd_vskin_offset != -1) {
2617                         const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, data->cd_vskin_offset);
2618                         if (vs->flag & MVERT_SKIN_ROOT) {
2619                                 float radius = (vs->radius[0] + vs->radius[1]) * 0.5f;
2620                                 bglEnd();
2621                         
2622                                 glColor4ubv(data->th_skin_root);
2623                                 drawcircball(GL_LINES, co, radius, data->imat);
2624
2625                                 glColor4ubv(data->sel ? data->th_vertex_select : data->th_vertex);
2626                                 bglBegin(GL_POINTS);
2627                         }
2628                 }
2629
2630                 /* draw active larger - need to stop/start point drawing for this :/ */
2631                 if (eve == data->eve_act) {
2632                         glColor4ubv(data->th_editmesh_active);
2633                         
2634                         bglEnd();
2635                         
2636                         glPointSize(data->th_vertex_size);
2637                         bglBegin(GL_POINTS);
2638                         bglVertex3fv(co);
2639                         bglEnd();
2640
2641                         glColor4ubv(data->sel ? data->th_vertex_select : data->th_vertex);
2642                         glPointSize(data->th_vertex_size);
2643                         bglBegin(GL_POINTS);
2644                 }
2645                 else {
2646                         bglVertex3fv(co);
2647                 }
2648         }
2649 }
2650
2651 static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVert *eve_act,
2652                           RegionView3D *rv3d)
2653 {
2654         drawDMVerts_userData data;
2655         data.sel = sel;
2656         data.eve_act = eve_act;
2657         data.bm = em->bm;
2658
2659         /* Cache theme values */
2660         UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, data.th_editmesh_active);
2661         UI_GetThemeColor4ubv(TH_VERTEX_SELECT, data.th_vertex_select);
2662         UI_GetThemeColor4ubv(TH_VERTEX, data.th_vertex);
2663         UI_GetThemeColor4ubv(TH_SKIN_ROOT, data.th_skin_root);
2664         data.th_vertex_size = UI_GetThemeValuef(TH_VERTEX_SIZE);
2665
2666         /* For skin root drawing */
2667         data.cd_vskin_offset = CustomData_get_offset(&em->bm->vdata, CD_MVERT_SKIN);
2668         /* view-aligned matrix */
2669         mul_m4_m4m4(data.imat, rv3d->viewmat, em->ob->obmat);
2670         invert_m4(data.imat);
2671
2672         bglBegin(GL_POINTS);
2673         dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data, DM_FOREACH_NOP);
2674         bglEnd();
2675 }
2676
2677 /* Draw edges with color set based on selection */
2678 static DMDrawOption draw_dm_edges_sel__setDrawOptions(void *userData, int index)
2679 {
2680         BMEdge *eed;
2681         drawDMEdgesSel_userData *data = userData;
2682         unsigned char *col;
2683
2684         eed = BM_edge_at_index(data->bm, index);
2685
2686         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
2687                 if (eed == data->eed_act) {
2688                         glColor4ubv(data->actCol);
2689                 }
2690                 else {
2691                         if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
2692                                 col = data->selCol;
2693                         }
2694                         else {
2695                                 col = data->baseCol;
2696                         }
2697                         /* no alpha, this is used so a transparent color can disable drawing unselected edges in editmode */
2698                         if (col[3] == 0)
2699                                 return DM_DRAW_OPTION_SKIP;
2700                         
2701                         glColor4ubv(col);
2702                 }
2703                 return DM_DRAW_OPTION_NORMAL;
2704         }
2705         else {
2706                 return DM_DRAW_OPTION_SKIP;
2707         }
2708 }
2709 static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
2710                               unsigned char *selCol, unsigned char *actCol, BMEdge *eed_act)
2711 {
2712         drawDMEdgesSel_userData data;
2713         
2714         data.baseCol = baseCol;
2715         data.selCol = selCol;
2716         data.actCol = actCol;
2717         data.bm = em->bm;
2718         data.eed_act = eed_act;
2719         dm->drawMappedEdges(dm, draw_dm_edges_sel__setDrawOptions, &data);
2720 }
2721
2722 /* Draw edges */
2723 static DMDrawOption draw_dm_edges__setDrawOptions(void *userData, int index)
2724 {
2725         if (BM_elem_flag_test(BM_edge_at_index(userData, index), BM_ELEM_HIDDEN))
2726                 return DM_DRAW_OPTION_SKIP;
2727         else
2728                 return DM_DRAW_OPTION_NORMAL;
2729 }
2730
2731 static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm)
2732 {
2733         dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em->bm);
2734 }
2735
2736 /* Draw edges with color interpolated based on selection */
2737 static DMDrawOption draw_dm_edges_sel_interp__setDrawOptions(void *userData, int index)
2738 {
2739         drawDMEdgesSelInterp_userData *data = userData;
2740         if (BM_elem_flag_test(BM_edge_at_index(data->bm, index), BM_ELEM_HIDDEN))
2741                 return DM_DRAW_OPTION_SKIP;
2742         else
2743                 return DM_DRAW_OPTION_NORMAL;
2744 }
2745 static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int index, float t)
2746 {
2747         drawDMEdgesSelInterp_userData *data = userData;
2748         BMEdge *eed = BM_edge_at_index(data->bm, index);
2749         unsigned char **cols = userData;
2750         unsigned int col0_id = (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT)) ? 2 : 1;
2751         unsigned int col1_id = (BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)) ? 2 : 1;
2752         unsigned char *col0 = cols[col0_id];
2753         unsigned char *col1 = cols[col1_id];
2754         unsigned char *col_pt;
2755
2756         if (col0_id == col1_id) {
2757                 col_pt = col0;
2758         }
2759         else if (t == 0.0f) {
2760                 col_pt = col0;
2761         }
2762         else if (t == 1.0f) {
2763                 col_pt = col1;
2764         }
2765         else {
2766                 unsigned char  col_blend[4];
2767                 interp_v4_v4v4_uchar(col_blend, col0, col1, t);
2768                 glColor4ubv(col_blend);
2769                 data->lastCol = NULL;
2770                 return;
2771         }
2772
2773         if (data->lastCol != col_pt) {
2774                 data->lastCol = col_pt;
2775                 glColor4ubv(col_pt);
2776         }
2777 }
2778
2779 static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
2780 {
2781         drawDMEdgesSelInterp_userData data;
2782         data.bm = em->bm;
2783         data.baseCol = baseCol;
2784         data.selCol = selCol;
2785         data.lastCol = NULL;
2786
2787         dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, &data);
2788 }
2789
2790 static void bm_color_from_weight(float col[3], BMVert *vert, drawDMEdgesWeightInterp_userData *data)
2791 {
2792         MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(vert, data->cd_dvert_offset);
2793         float weight = defvert_find_weight(dvert, data->vgroup_index);
2794
2795         if ((weight == 0.0f) &&
2796             ((data->weight_user == OB_DRAW_GROUPUSER_ACTIVE) ||
2797              ((data->weight_user == OB_DRAW_GROUPUSER_ALL) && defvert_is_weight_zero(dvert, data->defgroup_tot))))
2798         {
2799                 copy_v3_v3(col, data->alert_color);
2800         }
2801         else {
2802                 weight_to_rgb(col, weight);
2803         }
2804 }
2805
2806 static void draw_dm_edges_nop_interp__setDrawInterpOptions(void *UNUSED(userData), int UNUSED(index), float UNUSED(t))
2807 {
2808         /* pass */
2809 }
2810
2811 static void draw_dm_edges_weight_interp__setDrawInterpOptions(void *userData, int index, float t)
2812 {
2813         drawDMEdgesWeightInterp_userData *data = userData;
2814         BMEdge *eed = BM_edge_at_index(data->bm, index);
2815         float col[3];
2816
2817         if (t == 0.0f) {
2818                 bm_color_from_weight(col, eed->v1, data);
2819         }
2820         else if (t == 1.0f) {
2821                 bm_color_from_weight(col, eed->v2, data);
2822         }
2823         else {
2824                 float col_v1[3];
2825                 float col_v2[3];
2826
2827                 bm_color_from_weight(col_v1, eed->v1, data);
2828                 bm_color_from_weight(col_v2, eed->v2, data);
2829                 interp_v3_v3v3(col, col_v1, col_v2, t);
2830         }
2831
2832         glColor3fv(col);
2833 }
2834
2835 static void draw_dm_edges_weight_interp(BMEditMesh *em, DerivedMesh *dm, const char weight_user)
2836 {
2837         drawDMEdgesWeightInterp_userData data;
2838         Object *ob = em->ob;
2839
2840         data.bm = em->bm;
2841         data.cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
2842         data.defgroup_tot = BLI_listbase_count(&ob->defbase);
2843         data.vgroup_index = ob->actdef - 1;
2844         data.weight_user = weight_user;
2845         UI_GetThemeColor3fv(TH_VERTEX_UNREFERENCED, data.alert_color);
2846
2847         if ((data.vgroup_index != -1) && (data.cd_dvert_offset != -1)) {
2848                 glEnable(GL_BLEND);
2849                 dm->drawMappedEdgesInterp(
2850                         dm,
2851                         draw_dm_edges_sel_interp__setDrawOptions,
2852                         draw_dm_edges_weight_interp__setDrawInterpOptions,
2853                         &data);
2854                 glDisable(GL_BLEND);
2855         }
2856         else {
2857                 float col[3];
2858
2859                 if (data.weight_user == OB_DRAW_GROUPUSER_NONE) {
2860                         weight_to_rgb(col, 0.0f);
2861                 }
2862                 else {
2863                         copy_v3_v3(col, data.alert_color);
2864                 }
2865                 glColor3fv(col);
2866
2867                 dm->drawMappedEdgesInterp(
2868                         dm,
2869                         draw_dm_edges_sel_interp__setDrawOptions,
2870                         draw_dm_edges_nop_interp__setDrawInterpOptions,
2871                         &data);
2872         }
2873
2874 }
2875
2876 static bool draw_dm_edges_weight_check(Mesh *me, View3D *v3d)
2877 {
2878         if (me->drawflag & ME_DRAWEIGHT) {
2879                 if ((v3d->drawtype == OB_WIRE) ||
2880                     (v3d->flag2 & V3D_SOLID_MATCAP) ||
2881                     ((v3d->flag2 & V3D_OCCLUDE_WIRE) && (v3d->drawtype > OB_WIRE)))
2882                 {
2883                         return true;
2884                 }
2885         }
2886
2887         return false;
2888 }
2889
2890 /* Draw only seam edges */
2891 static DMDrawOption draw_dm_edges_seams__setDrawOptions(void *userData, int index)
2892 {
2893         BMEdge *eed = BM_edge_at_index(userData, index);
2894
2895         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_elem_flag_test(eed, BM_ELEM_SEAM))
2896                 return DM_DRAW_OPTION_NORMAL;
2897         else
2898                 return DM_DRAW_OPTION_SKIP;
2899 }
2900
2901 static void draw_dm_edges_seams(BMEditMesh *em, DerivedMesh *dm)
2902 {
2903         dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, em->bm);
2904 }
2905
2906 /* Draw only sharp edges */
2907 static DMDrawOption draw_dm_edges_sharp__setDrawOptions(void *userData, int index)
2908 {
2909         BMEdge *eed = BM_edge_at_index(userData, index);
2910
2911         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && !BM_elem_flag_test(eed, BM_ELEM_SMOOTH))
2912                 return DM_DRAW_OPTION_NORMAL;
2913         else
2914                 return DM_DRAW_OPTION_SKIP;
2915 }
2916
2917 static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm)
2918 {
2919         dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em->bm);
2920 }
2921
2922 #ifdef WITH_FREESTYLE
2923
2924 static int draw_dm_test_freestyle_edge_mark(BMesh *bm, BMEdge *eed)
2925 {
2926         FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, eed->head.data, CD_FREESTYLE_EDGE);
2927         if (!fed)
2928                 return 0;
2929         return (fed->flag & FREESTYLE_EDGE_MARK) != 0;
2930 }
2931
2932 /* Draw only Freestyle feature edges */
2933 static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int index)
2934 {
2935         BMEdge *eed = BM_edge_at_index(userData, index);
2936
2937         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && draw_dm_test_freestyle_edge_mark(userData, eed))
2938                 return DM_DRAW_OPTION_NORMAL;
2939         else
2940                 return DM_DRAW_OPTION_SKIP;
2941 }
2942
2943 static void draw_dm_edges_freestyle(BMEditMesh *em, DerivedMesh *dm)
2944 {
2945         dm->drawMappedEdges(dm, draw_dm_edges_freestyle__setDrawOptions, em->bm);
2946 }
2947
2948 static int draw_dm_test_freestyle_face_mark(BMesh *bm, BMFace *efa)
2949 {
2950         FreestyleFace *ffa = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_FREESTYLE_FACE);
2951         if (!ffa)
2952                 return 0;
2953         return (ffa->flag & FREESTYLE_FACE_MARK) != 0;
2954 }
2955
2956 #endif
2957
2958 /* Draw loop normals. */
2959 static void draw_dm_loop_normals__mapFunc(void *userData, int vertex_index, int face_index,
2960                                           const float co[3], const float no[3])
2961 {
2962         if (no) {
2963                 const drawDMNormal_userData *data = userData;
2964                 const BMVert *eve = BM_vert_at_index(data->bm, vertex_index);
2965                 const BMFace *efa = BM_face_at_index(data->bm, face_index);
2966                 float vec[3];
2967
2968                 if (!(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) || BM_elem_flag_test(efa, BM_ELEM_HIDDEN))) {
2969                         if (!data->uniform_scale) {
2970                                 mul_v3_m3v3(vec, (float(*)[3])data->tmat, no);
2971                                 normalize_v3(vec);
2972                                 mul_m3_v3((float(*)[3])data->imat, vec);
2973                         }
2974                         else {
2975                                 copy_v3_v3(vec, no);
2976                         }
2977                         mul_v3_fl(vec, data->normalsize);
2978                         add_v3_v3(vec, co);
2979                         glVertex3fv(co);
2980                         glVertex3fv(vec);
2981                 }
2982         }
2983 }
2984
2985 static void draw_dm_loop_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
2986 {
2987         drawDMNormal_userData data;
2988
2989         data.bm = em->bm;
2990         data.normalsize = scene->toolsettings->normalsize;
2991
2992         calcDrawDMNormalScale(ob, &data);
2993
2994         glBegin(GL_LINES);
2995         dm->foreachMappedLoop(dm, draw_dm_loop_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
2996         glEnd();
2997 }
2998
2999 /* Draw faces with color set based on selection
3000  * return 2 for the active face so it renders with stipple enabled */
3001 static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index)
3002 {
3003         drawDMFacesSel_userData *data = userData;
3004         BMFace *efa = BM_face_at_index(data->bm, index);
3005         unsigned char *col;
3006         
3007         if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
3008                 if (efa == data->efa_act) {
3009                         glColor4ubv(data->cols[2]);
3010                         return DM_DRAW_OPTION_STIPPLE;
3011                 }
3012                 else {
3013 #ifdef WITH_FREESTYLE
3014                         col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0];
3015 #else
3016                         col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0];
3017 #endif
3018                         if (col[3] == 0)
3019                                 return DM_DRAW_OPTION_SKIP;
3020                         glColor4ubv(col);
3021                         return DM_DRAW_OPTION_NORMAL;
3022                 }
3023         }
3024         return DM_DRAW_OPTION_SKIP;
3025 }
3026
3027 static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index)
3028 {
3029
3030         drawDMFacesSel_userData *data = userData;
3031         int i;
3032         BMFace *efa;
3033         BMFace *next_efa;
3034
3035         unsigned char *col, *next_col;
3036
3037         i = data->orig_index_mp_to_orig ? data->orig_index_mp_to_orig[index] : index;
3038         efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL;
3039         i = data->orig_index_mp_to_orig ? data->orig_index_mp_to_orig[next_index] : next_index;
3040         next_efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL;
3041
3042         if (ELEM(NULL, efa, next_efa))
3043                 return 0;
3044
3045         if (efa == next_efa)
3046                 return 1;
3047
3048         if (efa == data->efa_act || next_efa == data->efa_act)
3049                 return 0;
3050
3051 #ifdef WITH_FREESTYLE
3052         col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0];
3053         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];
3054 #else
3055         col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0];
3056         next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : 0];
3057 #endif
3058
3059         if (col[3] == 0 || next_col[3] == 0)
3060                 return 0;
3061
3062         return col == next_col;
3063 }
3064
3065 /* also draws the active face */
3066 #ifdef WITH_FREESTYLE
3067 static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
3068                               unsigned char *selCol, unsigned char *actCol, unsigned char *markCol, BMFace *efa_act)
3069 #else
3070 static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
3071                               unsigned char *selCol, unsigned char *actCol, BMFace *efa_act)
3072 #endif
3073 {
3074         drawDMFacesSel_userData data;
3075         data.dm = dm;
3076         data.cols[0] = baseCol;
3077         data.bm = em->bm;
3078         data.cols[1] = selCol;
3079         data.cols[2] = actCol;
3080 #ifdef WITH_FREESTYLE
3081         data.cols[3] = markCol;
3082 #endif
3083         data.efa_act = efa_act;
3084         /* double lookup */
3085         data.orig_index_mp_to_orig  = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
3086
3087         dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, NULL, draw_dm_faces_sel__compareDrawOptions, &data, DM_DRAW_SKIP_HIDDEN);
3088 }
3089
3090 static DMDrawOption draw_dm_creases__setDrawOptions(void *userData, int index)
3091 {
3092         drawDMLayer_userData *data = userData;
3093         BMesh *bm = data->bm;
3094         BMEdge *eed = BM_edge_at_index(bm, index);
3095         
3096         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
3097                 const float crease = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset);
3098                 if (crease != 0.0f) {
3099                         UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_CREASE, crease);
3100                         return DM_DRAW_OPTION_NORMAL;
3101                 }
3102         }
3103         return DM_DRAW_OPTION_SKIP;
3104 }
3105 static void draw_dm_creases(BMEditMesh *em, DerivedMesh *dm)
3106 {
3107         drawDMLayer_userData data;
3108
3109         data.bm = em->bm;
3110         data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
3111
3112         if (data.cd_layer_offset != -1) {
3113                 glLineWidth(3.0);
3114                 dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, &data);
3115                 glLineWidth(1.0);
3116         }
3117 }
3118
3119 static DMDrawOption draw_dm_bweights__setDrawOptions(void *userData, int index)
3120 {
3121         drawDMLayer_userData *data = userData;
3122         BMesh *bm = data->bm;
3123         BMEdge *eed = BM_edge_at_index(bm, index);
3124
3125         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
3126                 const float bweight = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset);
3127                 if (bweight != 0.0f) {
3128                         UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_SELECT, bweight);
3129                         return DM_DRAW_OPTION_NORMAL;
3130                 }