e752d3a034379d30b9f8539c9b7705d6db142a8c
[blender.git] / source / blender / editors / space_view3d / drawobject.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file \ingroup spview3d
21  */
22
23 #include "DNA_mesh_types.h"
24 #include "DNA_scene_types.h"
25 #include "DNA_object_types.h"
26
27 #include "BLI_math.h"
28
29 #include "BKE_DerivedMesh.h"
30 #include "BKE_global.h"
31
32 #include "BKE_editmesh.h"
33
34 #include "DEG_depsgraph.h"
35 #include "DEG_depsgraph_query.h"
36
37 #include "GPU_draw.h"
38 #include "GPU_shader.h"
39 #include "GPU_immediate.h"
40 #include "GPU_batch.h"
41 #include "GPU_matrix.h"
42 #include "GPU_state.h"
43 #include "GPU_framebuffer.h"
44
45 #include "ED_mesh.h"
46
47 #include "UI_resources.h"
48
49 #include "view3d_intern.h"  /* bad level include */
50
51 #include "../../draw/intern/draw_cache_impl.h"  /* bad level include (temporary) */
52
53 int view3d_effective_drawtype(const struct View3D *v3d)
54 {
55         if (v3d->shading.type == OB_RENDER) {
56                 return v3d->shading.prev_type;
57         }
58         return v3d->shading.type;
59 }
60
61 static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
62 {
63         if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0)
64                 return false;
65
66         if (G.f & G_FLAG_BACKBUFSEL)
67                 return false;
68
69         /* if its drawing textures with zbuf sel, then don't draw dots */
70         if (dt == OB_TEXTURE && vd->shading.type == OB_TEXTURE)
71                 return false;
72
73         return true;
74 }
75
76 /* OpenGL Circle Drawing - Tables for Optimized Drawing Speed */
77 /* 32 values of sin function (still same result!) */
78 #define CIRCLE_RESOL 32
79
80 static const float sinval[CIRCLE_RESOL] = {
81         0.00000000,
82         0.20129852,
83         0.39435585,
84         0.57126821,
85         0.72479278,
86         0.84864425,
87         0.93775213,
88         0.98846832,
89         0.99871650,
90         0.96807711,
91         0.89780453,
92         0.79077573,
93         0.65137248,
94         0.48530196,
95         0.29936312,
96         0.10116832,
97         -0.10116832,
98         -0.29936312,
99         -0.48530196,
100         -0.65137248,
101         -0.79077573,
102         -0.89780453,
103         -0.96807711,
104         -0.99871650,
105         -0.98846832,
106         -0.93775213,
107         -0.84864425,
108         -0.72479278,
109         -0.57126821,
110         -0.39435585,
111         -0.20129852,
112         0.00000000,
113 };
114
115 /* 32 values of cos function (still same result!) */
116 static const float cosval[CIRCLE_RESOL] = {
117         1.00000000,
118         0.97952994,
119         0.91895781,
120         0.82076344,
121         0.68896691,
122         0.52896401,
123         0.34730525,
124         0.15142777,
125         -0.05064916,
126         -0.25065253,
127         -0.44039415,
128         -0.61210598,
129         -0.75875812,
130         -0.87434661,
131         -0.95413925,
132         -0.99486932,
133         -0.99486932,
134         -0.95413925,
135         -0.87434661,
136         -0.75875812,
137         -0.61210598,
138         -0.44039415,
139         -0.25065253,
140         -0.05064916,
141         0.15142777,
142         0.34730525,
143         0.52896401,
144         0.68896691,
145         0.82076344,
146         0.91895781,
147         0.97952994,
148         1.00000000,
149 };
150
151 static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, const float tmat[4][4])
152 {
153         float vx[3], vy[3];
154         float *viter = (float *)verts;
155
156         mul_v3_v3fl(vx, tmat[0], rad);
157         mul_v3_v3fl(vy, tmat[1], rad);
158
159         for (unsigned int a = 0; a < CIRCLE_RESOL; a++, viter += 3) {
160                 viter[0] = cent[0] + sinval[a] * vx[0] + cosval[a] * vy[0];
161                 viter[1] = cent[1] + sinval[a] * vx[1] + cosval[a] * vy[1];
162                 viter[2] = cent[2] + sinval[a] * vx[2] + cosval[a] * vy[2];
163         }
164 }
165
166 void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned pos)
167 {
168         float verts[CIRCLE_RESOL][3];
169
170         circball_array_fill(verts, cent, rad, tmat);
171
172         immBegin(GPU_PRIM_LINE_LOOP, CIRCLE_RESOL);
173         for (int i = 0; i < CIRCLE_RESOL; ++i) {
174                 immVertex3fv(pos, verts[i]);
175         }
176         immEnd();
177 }
178
179 #ifdef VIEW3D_CAMERA_BORDER_HACK
180 unsigned char view3d_camera_border_hack_col[3];
181 bool view3d_camera_border_hack_test = false;
182 #endif
183
184 /* ***************** BACKBUF SEL (BBS) ********* */
185
186 /** See #DRW_shgroup_world_clip_planes_from_rv3d, same function for draw manager. */
187 static void bbs_world_clip_planes_from_rv3d(GPUBatch *batch, const float world_clip_planes[6][4])
188 {
189         GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
190 }
191
192 static void bbs_mesh_verts(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
193 {
194         GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE));
195
196         const eGPUShaderConfig shader_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
197         GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, shader_cfg);
198         GPU_batch_uniform_1ui(batch, "offset", offset);
199         if (world_clip_planes != NULL) {
200                 bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
201         }
202         GPU_batch_draw(batch);
203 }
204
205 static void bbs_mesh_wire(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
206 {
207         GPU_line_width(1.0f);
208         glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
209
210         const eGPUShaderConfig shader_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
211         GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, shader_cfg);
212         GPU_batch_uniform_1ui(batch, "offset", offset);
213         if (world_clip_planes != NULL) {
214                 bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
215         }
216         GPU_batch_draw(batch);
217
218         glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
219 }
220
221 /* two options, facecolors or black */
222 static void bbs_mesh_face(GPUBatch *batch, const bool use_select, const float world_clip_planes[6][4])
223 {
224         if (use_select) {
225                 const eGPUShaderConfig shader_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
226                 GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, shader_cfg);
227                 GPU_batch_uniform_1ui(batch, "offset", 1);
228                 if (world_clip_planes != NULL) {
229                         bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
230                 }
231                 GPU_batch_draw(batch);
232         }
233         else {
234                 const eGPUShaderConfig shader_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
235                 GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_UNIFORM_SELECT_ID, shader_cfg);
236                 GPU_batch_uniform_1ui(batch, "id", 0);
237                 if (world_clip_planes != NULL) {
238                         bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
239                 }
240                 GPU_batch_draw(batch);
241         }
242 }
243
244 static void bbs_mesh_face_dot(GPUBatch *batch, const float world_clip_planes[6][4])
245 {
246         const eGPUShaderConfig shader_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
247         GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, shader_cfg);
248         GPU_batch_uniform_1ui(batch, "offset", 1);
249         if (world_clip_planes != NULL) {
250                 bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
251         }
252         GPU_batch_draw(batch);
253 }
254
255 static void bbs_mesh_solid_verts(
256         Depsgraph *UNUSED(depsgraph), Scene *UNUSED(scene), Object *ob, const float world_clip_planes[6][4])
257 {
258         Mesh *me = ob->data;
259
260         GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
261         GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
262         DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
263
264         /* Only draw faces to mask out verts, we don't want their selection ID's. */
265         bbs_mesh_face(geom_faces, false, world_clip_planes);
266         bbs_mesh_verts(geom_verts, 1, world_clip_planes);
267
268         bm_vertoffs = me->totvert + 1;
269 }
270
271 static void bbs_mesh_solid_faces(Scene *UNUSED(scene), Object *ob, const float world_clip_planes[6][4])
272 {
273         Mesh *me = ob->data;
274         Mesh *me_orig = DEG_get_original_object(ob)->data;
275
276         const bool use_hide = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL);
277         GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
278         DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, use_hide);
279
280         bbs_mesh_face(geom_faces, true, world_clip_planes);
281 }
282
283 void draw_object_backbufsel(
284         Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob,
285         short select_mode)
286 {
287         ToolSettings *ts = scene->toolsettings;
288         if (select_mode == -1) {
289                 select_mode = ts->selectmode;
290         }
291
292         GPU_matrix_mul(ob->obmat);
293         GPU_depth_test(true);
294
295         const float (*world_clip_planes)[4] = NULL;
296         if (rv3d->rflag & RV3D_CLIPPING) {
297                 world_clip_planes = rv3d->clip;
298         }
299
300         switch (ob->type) {
301                 case OB_MESH:
302                         if (ob->mode & OB_MODE_EDIT) {
303                                 Mesh *me = ob->data;
304                                 BMEditMesh *em = me->edit_btmesh;
305                                 const bool draw_facedot = check_ob_drawface_dot(scene, v3d, ob->dt);
306                                 const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0;
307
308                                 BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
309
310                                 GPUBatch *geom_faces, *geom_edges, *geom_verts, *geom_facedots;
311                                 geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
312                                 if (select_mode & SCE_SELECT_EDGE) {
313                                         geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me);
314                                 }
315                                 if (select_mode & SCE_SELECT_VERTEX) {
316                                         geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
317                                 }
318                                 if (draw_facedot) {
319                                         geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me);
320                                 }
321                                 DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
322
323                                 bbs_mesh_face(geom_faces, use_faceselect, world_clip_planes);
324
325                                 if (use_faceselect && draw_facedot) {
326                                         bbs_mesh_face_dot(geom_facedots, world_clip_planes);
327                                 }
328
329                                 if (select_mode & SCE_SELECT_FACE)
330                                         bm_solidoffs = 1 + em->bm->totface;
331                                 else {
332                                         bm_solidoffs = 1;
333                                 }
334
335                                 ED_view3d_polygon_offset(rv3d, 1.0);
336
337                                 /* we draw edges if edge select mode */
338                                 if (select_mode & SCE_SELECT_EDGE) {
339                                         bbs_mesh_wire(geom_edges, bm_solidoffs, world_clip_planes);
340                                         bm_wireoffs = bm_solidoffs + em->bm->totedge;
341                                 }
342                                 else {
343                                         /* `bm_vertoffs` is calculated from `bm_wireoffs`. (otherwise see T53512) */
344                                         bm_wireoffs = bm_solidoffs;
345                                 }
346
347                                 ED_view3d_polygon_offset(rv3d, 1.1);
348
349                                 /* we draw verts if vert select mode. */
350                                 if (select_mode & SCE_SELECT_VERTEX) {
351                                         bbs_mesh_verts(geom_verts, bm_wireoffs, world_clip_planes);
352                                         bm_vertoffs = bm_wireoffs + em->bm->totvert;
353                                 }
354                                 else {
355                                         bm_vertoffs = bm_wireoffs;
356                                 }
357
358                                 ED_view3d_polygon_offset(rv3d, 0.0);
359                         }
360                         else {
361                                 Mesh *me = DEG_get_original_object(ob)->data;
362                                 if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) &&
363                                     /* currently vertex select supports weight paint and vertex paint*/
364                                     ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT)))
365                                 {
366                                         bbs_mesh_solid_verts(depsgraph, scene, ob, world_clip_planes);
367                                 }
368                                 else {
369                                         bbs_mesh_solid_faces(scene, ob, world_clip_planes);
370                                 }
371                         }
372                         break;
373                 case OB_CURVE:
374                 case OB_SURF:
375                         break;
376         }
377
378         GPU_matrix_set(rv3d->viewmat);
379 }
380
381
382 void ED_draw_object_facemap(
383         Depsgraph *depsgraph, Object *ob, const float col[4], const int facemap)
384 {
385         /* happens on undo */
386         if (ob->type != OB_MESH || !ob->data) {
387                 return;
388         }
389
390         Mesh *me = ob->data;
391         {
392                 Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
393                 if (ob_eval->runtime.mesh_eval) {
394                         me = ob_eval->runtime.mesh_eval;
395                 }
396         }
397
398         glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
399
400         /* Just to create the data to pass to immediate mode, grr! */
401         const int *facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
402         if (facemap_data) {
403                 GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
404                 GPU_blend(true);
405
406                 const MVert *mvert = me->mvert;
407                 const MPoly *mpoly = me->mpoly;
408                 const MLoop *mloop = me->mloop;
409
410                 int mpoly_len = me->totpoly;
411                 int mloop_len = me->totloop;
412
413                 facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
414
415                 /* use gawain immediate mode fore now */
416                 const int looptris_len = poly_to_tri_count(mpoly_len, mloop_len);
417                 const int vbo_len_capacity = looptris_len * 3;
418                 int vbo_len_used = 0;
419
420                 GPUVertFormat format_pos = { 0 };
421                 const uint pos_id = GPU_vertformat_attr_add(&format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
422
423                 GPUVertBuf *vbo_pos = GPU_vertbuf_create_with_format(&format_pos);
424                 GPU_vertbuf_data_alloc(vbo_pos, vbo_len_capacity);
425
426                 GPUVertBufRaw pos_step;
427                 GPU_vertbuf_attr_get_raw_data(vbo_pos, pos_id, &pos_step);
428
429                 const MPoly *mp;
430                 int i;
431                 if (me->runtime.looptris.array) {
432                         MLoopTri *mlt = me->runtime.looptris.array;
433                         for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) {
434                                 if (facemap_data[i] == facemap) {
435                                         for (int j = 2; j < mp->totloop; j++) {
436                                                 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[0]].v].co);
437                                                 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[1]].v].co);
438                                                 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[2]].v].co);
439                                                 vbo_len_used += 3;
440                                                 mlt++;
441                                         }
442                                 }
443                                 else {
444                                         mlt += mp->totloop - 2;
445                                 }
446                         }
447                 }
448                 else {
449                         /* No tessellation data, fan-fill. */
450                         for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) {
451                                 if (facemap_data[i] == facemap) {
452                                         const MLoop *ml_start = &mloop[mp->loopstart];
453                                         const MLoop *ml_a = ml_start + 1;
454                                         const MLoop *ml_b = ml_start + 2;
455                                         for (int j = 2; j < mp->totloop; j++) {
456                                                 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_start->v].co);
457                                                 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_a->v].co);
458                                                 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_b->v].co);
459                                                 vbo_len_used += 3;
460
461                                                 ml_a++;
462                                                 ml_b++;
463                                         }
464                                 }
465                         }
466                 }
467
468                 if (vbo_len_capacity != vbo_len_used) {
469                         GPU_vertbuf_data_resize(vbo_pos, vbo_len_used);
470                 }
471
472                 GPUBatch *draw_batch = GPU_batch_create(GPU_PRIM_TRIS, vbo_pos, NULL);
473                 GPU_batch_program_set_builtin(draw_batch, GPU_SHADER_3D_UNIFORM_COLOR);
474                 GPU_batch_uniform_4fv(draw_batch, "color", col);
475                 GPU_batch_draw(draw_batch);
476                 GPU_batch_discard(draw_batch);
477                 GPU_vertbuf_discard(vbo_pos);
478
479                 GPU_blend(false);
480         }
481 }