Merge branch 'master' into blender2.8
[blender.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_context.h"
58 #include "BKE_curve.h"
59 #include "BKE_DerivedMesh.h"
60 #include "BKE_deform.h"
61 #include "BKE_displist.h"
62 #include "BKE_font.h"
63 #include "BKE_global.h"
64 #include "BKE_image.h"
65 #include "BKE_key.h"
66 #include "BKE_layer.h"
67 #include "BKE_lattice.h"
68 #include "BKE_main.h"
69 #include "BKE_mesh.h"
70 #include "BKE_material.h"
71 #include "BKE_mball.h"
72 #include "BKE_modifier.h"
73 #include "BKE_movieclip.h"
74 #include "BKE_object.h"
75 #include "BKE_paint.h"
76 #include "BKE_particle.h"
77 #include "BKE_pointcache.h"
78 #include "BKE_scene.h"
79 #include "BKE_subsurf.h"
80 #include "BKE_unit.h"
81 #include "BKE_tracking.h"
82
83 #include "BKE_editmesh.h"
84
85 #include "DEG_depsgraph.h"
86 #include "DEG_depsgraph_query.h"
87
88 #include "IMB_imbuf.h"
89 #include "IMB_imbuf_types.h"
90
91 #include "BIF_gl.h"
92 #include "BIF_glutil.h"
93
94 #include "GPU_draw.h"
95 #include "GPU_select.h"
96 #include "GPU_basic_shader.h"
97 #include "GPU_shader.h"
98 #include "GPU_immediate.h"
99 #include "GPU_immediate_util.h"
100 #include "GPU_batch.h"
101 #include "GPU_matrix.h"
102
103 #include "ED_mesh.h"
104 #include "ED_particle.h"
105 #include "ED_screen.h"
106 #include "ED_sculpt.h"
107 #include "ED_types.h"
108
109 #include "UI_resources.h"
110 #include "UI_interface_icons.h"
111
112 #include "WM_api.h"
113 #include "BLF_api.h"
114
115 #include "view3d_intern.h"  /* bad level include */
116
117 #include "../../draw/intern/draw_cache_impl.h"  /* bad level include (temporary) */
118
119 int view3d_effective_drawtype(const struct View3D *v3d)
120 {
121         if (v3d->drawtype == OB_RENDER) {
122                 return v3d->prev_drawtype;
123         }
124         return v3d->drawtype;
125 }
126
127 static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
128 {
129         if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0)
130                 return false;
131
132         if (G.f & G_BACKBUFSEL)
133                 return false;
134
135         if ((vd->flag & V3D_ZBUF_SELECT) == 0)
136                 return true;
137
138         /* if its drawing textures with zbuf sel, then don't draw dots */
139         if (dt == OB_TEXTURE && vd->drawtype == OB_TEXTURE)
140                 return false;
141
142         if ((vd->drawtype >= OB_SOLID) && (vd->flag2 & V3D_SOLID_TEX))
143                 return false;
144
145         return true;
146 }
147
148 /* ----------------- OpenGL Circle Drawing - Tables for Optimized Drawing Speed ------------------ */
149 /* 32 values of sin function (still same result!) */
150 #define CIRCLE_RESOL 32
151
152 static const float sinval[CIRCLE_RESOL] = {
153         0.00000000,
154         0.20129852,
155         0.39435585,
156         0.57126821,
157         0.72479278,
158         0.84864425,
159         0.93775213,
160         0.98846832,
161         0.99871650,
162         0.96807711,
163         0.89780453,
164         0.79077573,
165         0.65137248,
166         0.48530196,
167         0.29936312,
168         0.10116832,
169         -0.10116832,
170         -0.29936312,
171         -0.48530196,
172         -0.65137248,
173         -0.79077573,
174         -0.89780453,
175         -0.96807711,
176         -0.99871650,
177         -0.98846832,
178         -0.93775213,
179         -0.84864425,
180         -0.72479278,
181         -0.57126821,
182         -0.39435585,
183         -0.20129852,
184         0.00000000
185 };
186
187 /* 32 values of cos function (still same result!) */
188 static const float cosval[CIRCLE_RESOL] = {
189         1.00000000,
190         0.97952994,
191         0.91895781,
192         0.82076344,
193         0.68896691,
194         0.52896401,
195         0.34730525,
196         0.15142777,
197         -0.05064916,
198         -0.25065253,
199         -0.44039415,
200         -0.61210598,
201         -0.75875812,
202         -0.87434661,
203         -0.95413925,
204         -0.99486932,
205         -0.99486932,
206         -0.95413925,
207         -0.87434661,
208         -0.75875812,
209         -0.61210598,
210         -0.44039415,
211         -0.25065253,
212         -0.05064916,
213         0.15142777,
214         0.34730525,
215         0.52896401,
216         0.68896691,
217         0.82076344,
218         0.91895781,
219         0.97952994,
220         1.00000000
221 };
222
223 static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, const float tmat[4][4])
224 {
225         float vx[3], vy[3];
226         float *viter = (float *)verts;
227
228         mul_v3_v3fl(vx, tmat[0], rad);
229         mul_v3_v3fl(vy, tmat[1], rad);
230
231         for (unsigned int a = 0; a < CIRCLE_RESOL; a++, viter += 3) {
232                 viter[0] = cent[0] + sinval[a] * vx[0] + cosval[a] * vy[0];
233                 viter[1] = cent[1] + sinval[a] * vx[1] + cosval[a] * vy[1];
234                 viter[2] = cent[2] + sinval[a] * vx[2] + cosval[a] * vy[2];
235         }
236 }
237
238 void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned pos)
239 {
240         float verts[CIRCLE_RESOL][3];
241
242         circball_array_fill(verts, cent, rad, tmat);
243
244         immBegin(GWN_PRIM_LINE_LOOP, CIRCLE_RESOL);
245         for (int i = 0; i < CIRCLE_RESOL; ++i) {
246                 immVertex3fv(pos, verts[i]);
247         }
248         immEnd();
249 }
250
251 #ifdef VIEW3D_CAMERA_BORDER_HACK
252 unsigned char view3d_camera_border_hack_col[3];
253 bool view3d_camera_border_hack_test = false;
254 #endif
255
256 /* ***************** BACKBUF SEL (BBS) ********* */
257
258 #ifdef USE_MESH_DM_SELECT
259 static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, const float co[3],
260                                            const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
261 {
262         drawMVertOffset_userData *data = userData;
263         MVert *mv = &data->mvert[index];
264
265         if (!(mv->flag & ME_HIDE)) {
266                 int selcol;
267                 GPU_select_index_get(data->offset + index, &selcol);
268                 immAttrib1u(data->col, selcol);
269                 immVertex3fv(data->pos, co);
270         }
271 }
272
273 static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset)
274 {
275         drawMVertOffset_userData data;
276         Mesh *me = ob->data;
277         MVert *mvert = me->mvert;
278         data.mvert = mvert;
279         data.offset = offset;
280
281         const int imm_len = dm->getNumVerts(dm);
282
283         if (imm_len == 0) return;
284
285         Gwn_VertFormat *format = immVertexFormat();
286         data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
287         data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
288
289         immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
290
291         glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
292
293         immBeginAtMost(GWN_PRIM_POINTS, imm_len);
294         dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data, DM_FOREACH_NOP);
295         immEnd();
296
297         immUnbindProgram();
298 }
299 #else
300 static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *UNUSED(dm), int offset)
301 {
302         Mesh *me = ob->data;
303         Gwn_Batch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset);
304         GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
305         GWN_batch_draw(batch);
306 }
307 #endif
308
309 #ifdef USE_MESH_DM_SELECT
310 static void bbs_mesh_verts__mapFunc(void *userData, int index, const float co[3],
311                                     const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
312 {
313         drawBMOffset_userData *data = userData;
314         BMVert *eve = BM_vert_at_index(data->bm, index);
315
316         if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
317                 int selcol;
318                 GPU_select_index_get(data->offset + index, &selcol);
319                 immAttrib1u(data->col, selcol);
320                 immVertex3fv(data->pos, co);
321         }
322 }
323 static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset)
324 {
325         drawBMOffset_userData data;
326         data.bm = em->bm;
327         data.offset = offset;
328         Gwn_VertFormat *format = immVertexFormat();
329         data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
330         data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
331
332         immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
333
334         glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
335
336         immBeginAtMost(GWN_PRIM_POINTS, em->bm->totvert);
337         dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, &data, DM_FOREACH_NOP);
338         immEnd();
339
340         immUnbindProgram();
341 }
342 #else
343 static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *UNUSED(dm), int offset)
344 {
345         glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
346
347         Mesh *me = em->ob->data;
348         Gwn_Batch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset);
349         GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
350         GWN_batch_draw(batch);
351 }
352 #endif
353
354 #ifdef USE_MESH_DM_SELECT
355 static void bbs_mesh_wire__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3])
356 {
357         drawBMOffset_userData *data = userData;
358         BMEdge *eed = BM_edge_at_index(data->bm, index);
359
360         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
361                 int selcol;
362                 GPU_select_index_get(data->offset + index, &selcol);
363                 immAttrib1u(data->col, selcol);
364                 immVertex3fv(data->pos, v0co);
365                 immVertex3fv(data->pos, v1co);
366         }
367 }
368
369 static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset)
370 {
371         drawBMOffset_userData data;
372         data.bm = em->bm;
373         data.offset = offset;
374
375         Gwn_VertFormat *format = immVertexFormat();
376
377         const int imm_len = dm->getNumEdges(dm) * 2;
378
379         if (imm_len == 0) return;
380
381         data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
382         data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
383
384         immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
385
386         glLineWidth(1.0f);
387
388         immBeginAtMost(GWN_PRIM_LINES, imm_len);
389         dm->foreachMappedEdge(dm, bbs_mesh_wire__mapFunc, &data);
390         immEnd();
391
392         immUnbindProgram();
393 }
394 #else
395 static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *UNUSED(dm), int offset)
396 {
397         glLineWidth(1.0f);
398
399         Mesh *me = em->ob->data;
400         Gwn_Batch *batch = DRW_mesh_batch_cache_get_edges_with_select_id(me, offset);
401         GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
402         GWN_batch_draw(batch);
403 }
404 #endif
405
406 #ifdef USE_MESH_DM_SELECT
407 static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *dm, const bool use_select)
408 {
409         UNUSED_VARS(dm);
410
411         drawBMOffset_userData data;
412         data.bm = em->bm;
413
414         const int tri_len = em->tottri;
415         const int imm_len = tri_len * 3;
416         const char hflag_skip = use_select ? BM_ELEM_HIDDEN : (BM_ELEM_HIDDEN | BM_ELEM_SELECT);
417
418         if (imm_len == 0) return;
419
420         Gwn_VertFormat *format = immVertexFormat();
421         data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
422         data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
423
424         immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
425
426         immBeginAtMost(GWN_PRIM_TRIS, imm_len);
427
428         if (use_select == false) {
429                 int selcol;
430                 GPU_select_index_get(0, &selcol);
431                 immAttrib1u(data.col, selcol);
432         }
433
434         int index = 0;
435         while (index < tri_len) {
436                 const BMFace *f = em->looptris[index][0]->f;
437                 const int ntris = f->len - 2;
438                 if (!BM_elem_flag_test(f, hflag_skip)) {
439                         if (use_select) {
440                                 int selcol;
441                                 GPU_select_index_get(BM_elem_index_get(f) + 1, &selcol);
442                                 immAttrib1u(data.col, selcol);
443                         }
444                         for (int t = 0; t < ntris; t++) {
445                                 immVertex3fv(data.pos, em->looptris[index][0]->v->co);
446                                 immVertex3fv(data.pos, em->looptris[index][1]->v->co);
447                                 immVertex3fv(data.pos, em->looptris[index][2]->v->co);
448                                 index++;
449                         }
450                 }
451                 else {
452                         index += ntris;
453                 }
454         }
455         immEnd();
456
457         immUnbindProgram();
458 }
459 #else
460 static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *UNUSED(dm), const bool use_select)
461 {
462         Mesh *me = em->ob->data;
463         Gwn_Batch *batch;
464
465         if (use_select) {
466                 batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1);
467                 GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
468                 GWN_batch_draw(batch);
469         }
470         else {
471                 int selcol;
472                 GPU_select_index_get(0, &selcol);
473                 batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true);
474                 GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32);
475                 GWN_batch_uniform_1ui(batch, "color", selcol);
476                 GWN_batch_draw(batch);
477         }
478 }
479 #endif
480
481 #ifdef USE_MESH_DM_SELECT
482 static void bbs_mesh_solid__drawCenter(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
483 {
484         drawBMOffset_userData *data = (drawBMOffset_userData *)userData;
485         BMFace *efa = BM_face_at_index(userData, index);
486
487         if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
488                 int selcol;
489                 GPU_select_index_get(index + 1, &selcol);
490                 immAttrib1u(data->col, selcol);
491                 immVertex3fv(data->pos, cent);
492         }
493 }
494
495 static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *dm)
496 {
497         drawBMOffset_userData data; /* don't use offset */
498         data.bm = em->bm;
499         Gwn_VertFormat *format = immVertexFormat();
500         data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
501         data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U32, 1, GWN_FETCH_INT);
502
503         immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32);
504
505         glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE));
506
507         immBeginAtMost(GWN_PRIM_POINTS, em->bm->totface);
508         dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, &data, DM_FOREACH_NOP);
509         immEnd();
510
511         immUnbindProgram();
512 }
513 #else
514 static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *UNUSED(dm))
515 {
516         Mesh *me = em->ob->data;
517         Gwn_Batch *batch = DRW_mesh_batch_cache_get_facedots_with_select_id(me, 1);
518         GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
519         GWN_batch_draw(batch);
520 }
521 #endif
522
523 /* two options, facecolors or black */
524 static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d,
525                               Object *ob, DerivedMesh *dm, bool use_faceselect)
526 {
527         if (use_faceselect) {
528                 bbs_mesh_face(em, dm, true);
529
530                 if (check_ob_drawface_dot(scene, v3d, ob->dt)) {
531                         bbs_mesh_face_dot(em, dm);
532                 }
533         }
534         else {
535                 bbs_mesh_face(em, dm, false);
536         }
537 }
538
539 #ifdef USE_MESH_DM_SELECT
540 /* must have called GPU_framebuffer_index_set beforehand */
541 static DMDrawOption bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index)
542 {
543         Mesh *me = userData;
544
545         if (!(me->mpoly[index].flag & ME_HIDE)) {
546                 return DM_DRAW_OPTION_NORMAL;
547         }
548         else {
549                 return DM_DRAW_OPTION_SKIP;
550         }
551 }
552
553 static void bbs_mesh_solid_verts(Depsgraph *depsgraph, Scene *scene, Object *ob)
554 {
555         Mesh *me = ob->data;
556         DerivedMesh *dm = mesh_get_derived_final(depsgraph, scene, ob, scene->customdata_mask);
557
558         DM_update_materials(dm, ob);
559
560         /* Only draw faces to mask out verts, we don't want their selection ID's. */
561         const int G_f_orig = G.f;
562         G.f &= ~G_BACKBUFSEL;
563
564         dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, NULL, NULL, me, DM_DRAW_SKIP_HIDDEN);
565
566         G.f |= (G_f_orig & G_BACKBUFSEL);
567
568         bbs_obmode_mesh_verts(ob, dm, 1);
569         bm_vertoffs = me->totvert + 1;
570         dm->release(dm);
571 }
572 #else
573 static void bbs_mesh_solid_verts(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(scene), Object *ob)
574 {
575         Mesh *me = ob->data;
576
577         /* Only draw faces to mask out verts, we don't want their selection ID's. */
578         const int G_f_orig = G.f;
579         G.f &= ~G_BACKBUFSEL;
580
581         {
582                 int selcol;
583                 Gwn_Batch *batch;
584                 GPU_select_index_get(0, &selcol);
585                 batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true);
586                 GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32);
587                 GWN_batch_uniform_1ui(batch, "color", selcol);
588                 GWN_batch_draw(batch);
589         }
590
591         G.f |= (G_f_orig & G_BACKBUFSEL);
592
593         bbs_obmode_mesh_verts(ob, NULL, 1);
594         bm_vertoffs = me->totvert + 1;
595 }
596 #endif
597
598 static void bbs_mesh_solid_faces(Scene *UNUSED(scene), Object *ob)
599 {
600         Mesh *me = ob->data;
601         Gwn_Batch *batch;
602         if ((me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
603                 batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1);
604         }
605         else {
606                 batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, false, 1);
607         }
608         GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
609         GWN_batch_draw(batch);
610 }
611
612 void draw_object_backbufsel(
613         Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob,
614         short select_mode)
615 {
616         ToolSettings *ts = scene->toolsettings;
617         if (select_mode == -1) {
618                 select_mode = ts->selectmode;
619         }
620
621         gpuMultMatrix(ob->obmat);
622
623         glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT);
624         glEnable(GL_DEPTH_TEST);
625
626         switch (ob->type) {
627                 case OB_MESH:
628                         if (ob->mode & OB_MODE_EDIT) {
629                                 Mesh *me = ob->data;
630                                 BMEditMesh *em = me->edit_btmesh;
631
632                                 DerivedMesh *dm = editbmesh_get_derived_cage(depsgraph, scene, ob, em, CD_MASK_BAREMESH);
633
634                                 BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
635
636                                 DM_update_materials(dm, ob);
637
638                                 bbs_mesh_solid_EM(em, scene, v3d, ob, dm, (select_mode & SCE_SELECT_FACE) != 0);
639                                 if (select_mode & SCE_SELECT_FACE)
640                                         bm_solidoffs = 1 + em->bm->totface;
641                                 else {
642                                         bm_solidoffs = 1;
643                                 }
644
645                                 ED_view3d_polygon_offset(rv3d, 1.0);
646
647                                 /* we draw edges if edge select mode */
648                                 if (select_mode & SCE_SELECT_EDGE) {
649                                         bbs_mesh_wire(em, dm, bm_solidoffs);
650                                         bm_wireoffs = bm_solidoffs + em->bm->totedge;
651                                 }
652                                 else {
653                                         /* `bm_vertoffs` is calculated from `bm_wireoffs`. (otherwise see T53512) */
654                                         bm_wireoffs = bm_solidoffs;
655                                 }
656
657                                 /* we draw verts if vert select mode. */
658                                 if (select_mode & SCE_SELECT_VERTEX) {
659                                         bbs_mesh_verts(em, dm, bm_wireoffs);
660                                         bm_vertoffs = bm_wireoffs + em->bm->totvert;
661                                 }
662                                 else {
663                                         bm_vertoffs = bm_wireoffs;
664                                 }
665
666                                 ED_view3d_polygon_offset(rv3d, 0.0);
667
668                                 dm->release(dm);
669                         }
670                         else {
671                                 Mesh *me = ob->data;
672                                 if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) &&
673                                     /* currently vertex select supports weight paint and vertex paint*/
674                                     ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT)))
675                                 {
676                                         bbs_mesh_solid_verts(depsgraph, scene, ob);
677                                 }
678                                 else {
679                                         bbs_mesh_solid_faces(scene, ob);
680                                 }
681                         }
682                         break;
683                 case OB_CURVE:
684                 case OB_SURF:
685                         break;
686         }
687
688         gpuLoadMatrix(rv3d->viewmat);
689 }
690
691
692 void ED_draw_object_facemap(
693         Depsgraph *depsgraph, Scene *scene, Object *ob, const float col[4], const int facemap)
694 {
695         DerivedMesh *dm = NULL;
696
697         /* happens on undo */
698         if (ob->type != OB_MESH || !ob->data)
699                 return;
700
701         /* Temporary, happens on undo, would resolve but will eventually move away from DM. */
702         if (ob->derivedFinal == NULL) {
703                 return;
704         }
705
706         dm = mesh_get_derived_final(depsgraph, scene, ob, CD_MASK_BAREMESH);
707         if (!dm || !CustomData_has_layer(&dm->polyData, CD_FACEMAP))
708                 return;
709
710
711         glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
712
713 #if 0
714         DM_update_materials(dm, ob);
715
716         /* add polygon offset so we draw above the original surface */
717         glPolygonOffset(1.0, 1.0);
718
719         GPU_facemap_setup(dm);
720
721         glColor4fv(col);
722
723         gpuPushAttrib(GL_ENABLE_BIT);
724         glEnable(GL_BLEND);
725         glDisable(GL_LIGHTING);
726
727         /* always draw using backface culling */
728         glEnable(GL_CULL_FACE);
729         glCullFace(GL_BACK);
730
731         if (dm->drawObject->facemapindices) {
732                 glDrawElements(GL_TRIANGLES, dm->drawObject->facemap_count[facemap] * 3, GL_UNSIGNED_INT,
733                                (int *)NULL + dm->drawObject->facemap_start[facemap] * 3);
734         }
735         gpuPopAttrib();
736
737         GPU_buffers_unbind();
738
739         glPolygonOffset(0.0, 0.0);
740
741 #else
742
743         /* Just to create the data to pass to immediate mode, grr! */
744         Mesh *me = ob->data;
745         const int *facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
746         if (facemap_data) {
747                 Gwn_VertFormat *format = immVertexFormat();
748                 unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
749
750                 immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
751                 immUniformColor4fv(col);
752
753                 /* XXX, alpha isn't working yet, not sure why. */
754                 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
755                 glEnable(GL_BLEND);
756
757                 MVert *mvert;
758
759                 MPoly *mpoly;
760                 int    mpoly_len;
761
762                 MLoop *mloop;
763                 int    mloop_len;
764
765                 if (dm && CustomData_has_layer(&dm->polyData, CD_FACEMAP)) {
766                         mvert = dm->getVertArray(dm);
767                         mpoly = dm->getPolyArray(dm);
768                         mloop = dm->getLoopArray(dm);
769
770                         mpoly_len = dm->getNumPolys(dm);
771                         mloop_len = dm->getNumLoops(dm);
772
773                         facemap_data = CustomData_get_layer(&dm->polyData, CD_FACEMAP);
774                 }
775                 else {
776                         mvert = me->mvert;
777                         mpoly = me->mpoly;
778                         mloop = me->mloop;
779
780                         mpoly_len = me->totpoly;
781                         mloop_len = me->totloop;
782
783                         facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
784                 }
785
786                 /* use gawain immediate mode fore now */
787                 const int looptris_len = poly_to_tri_count(mpoly_len, mloop_len);
788                 immBeginAtMost(GWN_PRIM_TRIS, looptris_len * 3);
789
790                 MPoly *mp;
791                 int i;
792                 for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) {
793                         if (facemap_data[i] == facemap) {
794                                 /* Weak, fan-fill, use until we have derived-mesh replaced. */
795                                 const MLoop *ml_start = &mloop[mp->loopstart];
796                                 const MLoop *ml_a = ml_start + 1;
797                                 const MLoop *ml_b = ml_start + 2;
798                                 for (int j = 2; j < mp->totloop; j++) {
799                                         immVertex3fv(pos, mvert[ml_start->v].co);
800                                         immVertex3fv(pos, mvert[ml_a->v].co);
801                                         immVertex3fv(pos, mvert[ml_b->v].co);
802
803                                         ml_a++;
804                                         ml_b++;
805                                 }
806                         }
807                 }
808                 immEnd();
809
810                 immUnbindProgram();
811
812                 glDisable(GL_BLEND);
813         }
814 #endif
815
816         dm->release(dm);
817 }
818