2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * The Original Code is Copyright (C) 2017 by Blender Foundation.
19 * All rights reserved.
21 * Contributor(s): Blender Foundation, Mike Erwin, Dalai Felinto
23 * ***** END GPL LICENSE BLOCK *****
26 /** \file draw_cache_impl_mesh.c
29 * \brief Mesh API for render engines
32 #include "MEM_guardedalloc.h"
34 #include "BLI_buffer.h"
35 #include "BLI_utildefines.h"
36 #include "BLI_math_vector.h"
37 #include "BLI_math_bits.h"
38 #include "BLI_math_color.h"
39 #include "BLI_string.h"
40 #include "BLI_alloca.h"
41 #include "BLI_edgehash.h"
43 #include "DNA_mesh_types.h"
44 #include "DNA_meshdata_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_space_types.h"
47 #include "DNA_scene_types.h"
49 #include "BKE_customdata.h"
50 #include "BKE_deform.h"
51 #include "BKE_editmesh.h"
52 #include "BKE_editmesh_cache.h"
53 #include "BKE_editmesh_tangent.h"
55 #include "BKE_mesh_tangent.h"
56 #include "BKE_mesh_runtime.h"
57 #include "BKE_object.h"
58 #include "BKE_object_deform.h"
59 #include "BKE_colorband.h"
60 #include "BKE_cdderivedmesh.h"
62 #include "DEG_depsgraph_query.h"
66 #include "GPU_batch.h"
67 #include "GPU_batch_presets.h"
69 #include "GPU_material.h"
71 #include "DRW_render.h"
75 #include "ED_uvedit.h"
77 #include "draw_cache_impl.h" /* own include */
80 static void mesh_batch_cache_clear(Mesh *me);
82 /* Vertex Group Selection and display options */
83 typedef struct DRW_MeshWeightState {
90 /* Set of all selected bones for Multipaint. */
91 bool *defgroup_sel; /* [defgroup_len] */
92 int defgroup_sel_count;
93 } DRW_MeshWeightState;
95 /* DRW_MeshWeightState.flags */
97 DRW_MESH_WEIGHT_STATE_MULTIPAINT = (1 << 0),
98 DRW_MESH_WEIGHT_STATE_AUTO_NORMALIZE = (1 << 1),
101 /* ---------------------------------------------------------------------- */
103 /** \name Mesh/BMesh Interface (direct access to basic data).
106 static int mesh_render_verts_len_get(Mesh *me)
108 return me->edit_btmesh ? me->edit_btmesh->bm->totvert : me->totvert;
111 static int mesh_render_edges_len_get(Mesh *me)
113 return me->edit_btmesh ? me->edit_btmesh->bm->totedge : me->totedge;
116 static int mesh_render_looptri_len_get(Mesh *me)
118 return me->edit_btmesh ? me->edit_btmesh->tottri : poly_to_tri_count(me->totpoly, me->totloop);
121 static int mesh_render_polys_len_get(Mesh *me)
123 return me->edit_btmesh ? me->edit_btmesh->bm->totface : me->totpoly;
126 static int mesh_render_mat_len_get(Mesh *me)
128 return MAX2(1, me->totcol);
131 static int UNUSED_FUNCTION(mesh_render_loops_len_get)(Mesh *me)
133 return me->edit_btmesh ? me->edit_btmesh->bm->totloop : me->totloop;
139 /* ---------------------------------------------------------------------- */
141 /** \name Mesh/BMesh Interface (indirect, partially cached access to complex data).
144 typedef struct EdgeAdjacentPolys {
149 typedef struct EdgeAdjacentVerts {
150 int vert_index[2]; /* -1 if none */
153 typedef struct EdgeDrawAttr {
160 typedef struct MeshRenderData {
172 /* Support for mapped mesh data. */
174 /* Must be set if we want to get mapped data. */
192 /* origindex layers */
199 BMEditMesh *edit_bmesh;
200 struct EditMeshData *edit_data;
208 float (*orco)[3]; /* vertex coordinates normalized to bounding box */
209 bool is_orco_allocated;
213 float (*loop_normals)[3];
215 /* CustomData 'cd' cache for efficient access. */
226 float (**tangent)[4];
233 /* Custom-data offsets (only needed for BMesh access) */
239 #ifdef WITH_FREESTYLE
246 char (*auto_mix)[32];
252 /* for certain cases we need an output loop-data storage (bmesh tangents) */
255 /* grr, special case variable (use in place of 'dm->tangent_mask') */
264 /* Data created on-demand (usually not for bmesh-based data). */
265 EdgeAdjacentPolys *edges_adjacent_polys;
270 float (*poly_normals)[3];
272 char (*vert_color)[3];
273 GPUPackedNormal *poly_normals_pack;
274 GPUPackedNormal *vert_normals_pack;
275 bool *edge_select_bool;
276 bool *edge_visible_bool;
280 MR_DATATYPE_VERT = 1 << 0,
281 MR_DATATYPE_EDGE = 1 << 1,
282 MR_DATATYPE_LOOPTRI = 1 << 2,
283 MR_DATATYPE_LOOP = 1 << 3,
284 MR_DATATYPE_POLY = 1 << 4,
285 MR_DATATYPE_OVERLAY = 1 << 5,
286 MR_DATATYPE_SHADING = 1 << 6,
287 MR_DATATYPE_DVERT = 1 << 7,
288 MR_DATATYPE_LOOPCOL = 1 << 8,
289 MR_DATATYPE_LOOPUV = 1 << 9,
290 MR_DATATYPE_LOOSE_VERT = 1 << 10,
291 MR_DATATYPE_LOOSE_EDGE = 1 << 11,
295 * These functions look like they would be slow but they will typically return true on the first iteration.
296 * Only false when all attached elements are hidden.
298 static bool bm_vert_has_visible_edge(const BMVert *v)
300 const BMEdge *e_iter, *e_first;
302 e_iter = e_first = v->e;
304 if (!BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN)) {
307 } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first);
311 static bool bm_edge_has_visible_face(const BMEdge *e)
313 const BMLoop *l_iter, *l_first;
314 l_iter = l_first = e->l;
316 if (!BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) {
319 } while ((l_iter = l_iter->radial_next) != l_first);
323 /* Return true is all layers in _b_ are inside _a_. */
324 static bool mesh_cd_layers_type_overlap(
325 const uchar av[CD_NUMTYPES], const ushort al[CD_NUMTYPES],
326 const uchar bv[CD_NUMTYPES], const ushort bl[CD_NUMTYPES])
328 for (int i = 0; i < CD_NUMTYPES; ++i) {
329 if ((av[i] & bv[i]) != bv[i]) {
332 if ((al[i] & bl[i]) != bl[i]) {
339 static void mesh_cd_layers_type_merge(
340 uchar av[CD_NUMTYPES], ushort al[CD_NUMTYPES],
341 uchar bv[CD_NUMTYPES], ushort bl[CD_NUMTYPES])
343 for (int i = 0; i < CD_NUMTYPES; ++i) {
349 static void mesh_cd_calc_active_uv_layer(
350 const Mesh *me, ushort cd_lused[CD_NUMTYPES])
352 const CustomData *cd_ldata = (me->edit_btmesh) ? &me->edit_btmesh->bm->ldata : &me->ldata;
354 int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
356 cd_lused[CD_MLOOPUV] |= (1 << layer);
360 static void mesh_cd_calc_active_vcol_layer(
361 const Mesh *me, ushort cd_lused[CD_NUMTYPES])
363 const CustomData *cd_ldata = (me->edit_btmesh) ? &me->edit_btmesh->bm->ldata : &me->ldata;
365 int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL);
367 cd_lused[CD_MLOOPCOL] |= (1 << layer);
371 static void mesh_cd_calc_used_gpu_layers(
372 const Mesh *me, uchar cd_vused[CD_NUMTYPES], ushort cd_lused[CD_NUMTYPES],
373 struct GPUMaterial **gpumat_array, int gpumat_array_len)
375 const CustomData *cd_ldata = (me->edit_btmesh) ? &me->edit_btmesh->bm->ldata : &me->ldata;
377 /* See: DM_vertex_attributes_from_gpu for similar logic */
378 GPUVertexAttribs gattribs = {{{0}}};
380 for (int i = 0; i < gpumat_array_len; i++) {
381 GPUMaterial *gpumat = gpumat_array[i];
383 GPU_material_vertex_attributes(gpumat, &gattribs);
384 for (int j = 0; j < gattribs.totlayer; j++) {
385 const char *name = gattribs.layer[j].name;
386 int type = gattribs.layer[j].type;
389 if (type == CD_AUTO_FROM_NAME) {
390 /* We need to deduct what exact layer is used.
392 * We do it based on the specified name.
394 if (name[0] != '\0') {
395 layer = CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name);
399 layer = CustomData_get_named_layer(cd_ldata, CD_MLOOPCOL, name);
402 #if 0 /* Tangents are always from UV's - this will never happen. */
404 layer = CustomData_get_named_layer(cd_ldata, CD_TANGENT, name);
413 /* Fall back to the UV layer, which matches old behavior. */
422 layer = (name[0] != '\0') ?
423 CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name) :
424 CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
427 cd_lused[CD_MLOOPUV] |= (1 << layer);
434 layer = (name[0] != '\0') ?
435 CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name) :
436 CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
438 /* Only fallback to orco (below) when we have no UV layers, see: T56545 */
439 if (layer == -1 && name[0] != '\0') {
440 layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
444 cd_lused[CD_TANGENT] |= (1 << layer);
447 /* no UV layers at all => requesting orco */
448 cd_lused[CD_TANGENT] |= DM_TANGENT_MASK_ORCO;
449 cd_vused[CD_ORCO] |= 1;
456 layer = (name[0] != '\0') ?
457 CustomData_get_named_layer(cd_ldata, CD_MLOOPCOL, name) :
458 CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL);
461 cd_lused[CD_MLOOPCOL] |= (1 << layer);
467 cd_vused[CD_ORCO] |= 1;
477 static void mesh_render_calc_normals_loop_and_poly(const Mesh *me, const float split_angle, MeshRenderData *rdata)
479 BLI_assert((me->flag & ME_AUTOSMOOTH) != 0);
481 int totloop = me->totloop;
482 int totpoly = me->totpoly;
483 float (*loop_normals)[3] = MEM_mallocN(sizeof(*loop_normals) * totloop, __func__);
484 float (*poly_normals)[3] = MEM_mallocN(sizeof(*poly_normals) * totpoly, __func__);
485 short (*clnors)[2] = CustomData_get_layer(&me->ldata, CD_CUSTOMLOOPNORMAL);
487 BKE_mesh_calc_normals_poly(
488 me->mvert, NULL, me->totvert,
489 me->mloop, me->mpoly, totloop, totpoly, poly_normals, false);
491 BKE_mesh_normals_loop_split(
492 me->mvert, me->totvert, me->medge, me->totedge,
493 me->mloop, loop_normals, totloop, me->mpoly, poly_normals, totpoly,
494 true, split_angle, NULL, clnors, NULL);
496 rdata->loop_len = totloop;
497 rdata->poly_len = totpoly;
498 rdata->loop_normals = loop_normals;
499 rdata->poly_normals = poly_normals;
502 static void mesh_cd_extract_auto_layers_names_and_srgb(
503 Mesh *me, const ushort cd_lused[CD_NUMTYPES],
504 char **r_auto_layers_names, int **r_auto_layers_srgb, int *r_auto_layers_len)
506 const CustomData *cd_ldata = (me->edit_btmesh) ? &me->edit_btmesh->bm->ldata : &me->ldata;
508 int uv_len_used = count_bits_i(cd_lused[CD_MLOOPUV]);
509 int vcol_len_used = count_bits_i(cd_lused[CD_MLOOPCOL]);
510 int uv_len = CustomData_number_of_layers(cd_ldata, CD_MLOOPUV);
511 int vcol_len = CustomData_number_of_layers(cd_ldata, CD_MLOOPCOL);
513 uint auto_names_len = 32 * (uv_len_used + vcol_len_used);
515 /* Allocate max, resize later. */
516 char *auto_names = MEM_callocN(sizeof(char) * auto_names_len, __func__);
517 int *auto_is_srgb = MEM_callocN(sizeof(int) * (uv_len_used + vcol_len_used), __func__);
519 for (int i = 0; i < uv_len; i++) {
520 if ((cd_lused[CD_MLOOPUV] & (1 << i)) != 0) {
521 const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i);
522 uint hash = BLI_ghashutil_strhash_p(name);
523 /* +1 to include '\0' terminator. */
524 auto_ofs += 1 + BLI_snprintf_rlen(auto_names + auto_ofs, auto_names_len - auto_ofs, "ba%u", hash);
528 uint auto_is_srgb_ofs = uv_len_used;
529 for (int i = 0; i < vcol_len; i++) {
530 if ((cd_lused[CD_MLOOPCOL] & (1 << i)) != 0) {
531 const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPCOL, i);
532 /* We only do vcols that are not overridden by a uv layer with same name. */
533 if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, name) == -1) {
534 uint hash = BLI_ghashutil_strhash_p(name);
535 /* +1 to include '\0' terminator. */
536 auto_ofs += 1 + BLI_snprintf_rlen(auto_names + auto_ofs, auto_names_len - auto_ofs, "ba%u", hash);
537 auto_is_srgb[auto_is_srgb_ofs] = true;
543 auto_names = MEM_reallocN(auto_names, sizeof(char) * auto_ofs);
544 auto_is_srgb = MEM_reallocN(auto_is_srgb, sizeof(int) * auto_is_srgb_ofs);
546 *r_auto_layers_names = auto_names;
547 *r_auto_layers_srgb = auto_is_srgb;
548 *r_auto_layers_len = auto_is_srgb_ofs;
552 * TODO(campbell): 'gpumat_array' may include materials linked to the object.
553 * While not default, object materials should be supported.
554 * Although this only impacts the data that's generated, not the materials that display.
556 static MeshRenderData *mesh_render_data_create_ex(
557 Mesh *me, const int types, const uchar cd_vused[CD_NUMTYPES], const ushort cd_lused[CD_NUMTYPES])
559 MeshRenderData *rdata = MEM_callocN(sizeof(*rdata), __func__);
560 rdata->types = types;
561 rdata->mat_len = mesh_render_mat_len_get(me);
563 CustomData_reset(&rdata->cd.output.ldata);
565 const bool is_auto_smooth = (me->flag & ME_AUTOSMOOTH) != 0;
566 const float split_angle = is_auto_smooth ? me->smoothresh : (float)M_PI;
568 if (me->edit_btmesh) {
569 BMEditMesh *embm = me->edit_btmesh;
570 BMesh *bm = embm->bm;
572 rdata->edit_bmesh = embm;
573 rdata->edit_data = me->runtime.edit_data;
575 if (embm->mesh_eval_cage && (embm->mesh_eval_cage->runtime.is_original == false)) {
576 Mesh *me_cage = embm->mesh_eval_cage;
578 rdata->mapped.me_cage = me_cage;
579 if (types & MR_DATATYPE_VERT) {
580 rdata->mapped.vert_len = me_cage->totvert;
582 if (types & MR_DATATYPE_EDGE) {
583 rdata->mapped.edge_len = me_cage->totedge;
585 if (types & MR_DATATYPE_LOOP) {
586 rdata->mapped.loop_len = me_cage->totloop;
588 if (types & MR_DATATYPE_POLY) {
589 rdata->mapped.poly_len = me_cage->totpoly;
591 if (types & MR_DATATYPE_LOOPTRI) {
592 rdata->mapped.tri_len = poly_to_tri_count(me_cage->totpoly, me_cage->totloop);
595 rdata->mapped.v_origindex = CustomData_get_layer(&me_cage->vdata, CD_ORIGINDEX);
596 rdata->mapped.e_origindex = CustomData_get_layer(&me_cage->edata, CD_ORIGINDEX);
597 rdata->mapped.l_origindex = CustomData_get_layer(&me_cage->ldata, CD_ORIGINDEX);
598 rdata->mapped.p_origindex = CustomData_get_layer(&me_cage->pdata, CD_ORIGINDEX);
599 rdata->mapped.supported = (
600 rdata->mapped.v_origindex &&
601 rdata->mapped.e_origindex &&
602 rdata->mapped.p_origindex);
605 int bm_ensure_types = 0;
606 if (types & MR_DATATYPE_VERT) {
607 rdata->vert_len = bm->totvert;
608 bm_ensure_types |= BM_VERT;
610 if (types & MR_DATATYPE_EDGE) {
611 rdata->edge_len = bm->totedge;
612 bm_ensure_types |= BM_EDGE;
614 if (types & MR_DATATYPE_LOOPTRI) {
615 bm_ensure_types |= BM_LOOP;
617 if (types & MR_DATATYPE_LOOP) {
618 int totloop = bm->totloop;
619 if (is_auto_smooth) {
620 rdata->loop_normals = MEM_mallocN(sizeof(*rdata->loop_normals) * totloop, __func__);
621 int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
622 BM_loops_calc_normal_vcos(
623 bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL,
624 cd_loop_clnors_offset, false);
626 rdata->loop_len = totloop;
627 bm_ensure_types |= BM_LOOP;
629 if (types & MR_DATATYPE_POLY) {
630 rdata->poly_len = bm->totface;
631 bm_ensure_types |= BM_FACE;
633 if (types & MR_DATATYPE_OVERLAY) {
634 rdata->efa_act = BM_mesh_active_face_get(bm, false, true);
635 rdata->eed_act = BM_mesh_active_edge_get(bm);
636 rdata->eve_act = BM_mesh_active_vert_get(bm);
637 rdata->cd.offset.crease = CustomData_get_offset(&bm->edata, CD_CREASE);
638 rdata->cd.offset.bweight = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
640 #ifdef WITH_FREESTYLE
641 rdata->cd.offset.freestyle_edge = CustomData_get_offset(&bm->edata, CD_FREESTYLE_EDGE);
642 rdata->cd.offset.freestyle_face = CustomData_get_offset(&bm->pdata, CD_FREESTYLE_FACE);
645 if (types & (MR_DATATYPE_DVERT)) {
646 bm_ensure_types |= BM_VERT;
648 if (rdata->edit_data != NULL) {
649 bm_ensure_types |= BM_VERT;
652 BM_mesh_elem_index_ensure(bm, bm_ensure_types);
653 BM_mesh_elem_table_ensure(bm, bm_ensure_types & ~BM_LOOP);
655 if (types & MR_DATATYPE_LOOPTRI) {
656 /* Edit mode ensures this is valid, no need to calculate. */
657 BLI_assert((bm->totloop == 0) || (embm->looptris != NULL));
658 int tottri = embm->tottri;
659 MLoopTri *mlooptri = MEM_mallocN(sizeof(*rdata->mlooptri) * embm->tottri, __func__);
660 for (int index = 0; index < tottri ; index ++ ) {
661 BMLoop **bmtri = embm->looptris[index];
662 MLoopTri *mtri = &mlooptri[index];
663 mtri->tri[0] = BM_elem_index_get(bmtri[0]);
664 mtri->tri[1] = BM_elem_index_get(bmtri[1]);
665 mtri->tri[2] = BM_elem_index_get(bmtri[2]);
667 rdata->mlooptri = mlooptri;
668 rdata->tri_len = tottri;
671 if (types & MR_DATATYPE_LOOSE_VERT) {
672 BLI_assert(types & MR_DATATYPE_VERT);
673 rdata->loose_vert_len = 0;
676 int *lverts = MEM_mallocN(rdata->vert_len * sizeof(int), __func__);
677 BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
678 for (int i = 0; i < bm->totvert; i++) {
679 const BMVert *eve = BM_vert_at_index(bm, i);
680 if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
682 if (eve->e == NULL || !bm_vert_has_visible_edge(eve)) {
683 lverts[rdata->loose_vert_len++] = i;
687 rdata->loose_verts = MEM_reallocN(lverts, rdata->loose_vert_len * sizeof(int));
690 if (rdata->mapped.supported) {
691 Mesh *me_cage = embm->mesh_eval_cage;
692 rdata->mapped.loose_vert_len = 0;
694 if (rdata->loose_vert_len) {
695 int *lverts = MEM_mallocN(me_cage->totvert * sizeof(int), __func__);
696 const int *v_origindex = rdata->mapped.v_origindex;
697 for (int i = 0; i < me_cage->totvert; i++) {
698 const int v_orig = v_origindex[i];
699 if (v_orig != ORIGINDEX_NONE) {
700 BMVert *eve = BM_vert_at_index(bm, v_orig);
701 if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
703 if (eve->e == NULL || !bm_vert_has_visible_edge(eve)) {
704 lverts[rdata->mapped.loose_vert_len++] = i;
709 rdata->mapped.loose_verts = MEM_reallocN(lverts, rdata->mapped.loose_vert_len * sizeof(int));
714 if (types & MR_DATATYPE_LOOSE_EDGE) {
715 BLI_assert(types & MR_DATATYPE_EDGE);
716 rdata->loose_edge_len = 0;
719 int *ledges = MEM_mallocN(rdata->edge_len * sizeof(int), __func__);
720 BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0);
721 for (int i = 0; i < bm->totedge; i++) {
722 const BMEdge *eed = BM_edge_at_index(bm, i);
723 if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
725 if (eed->l == NULL || !bm_edge_has_visible_face(eed)) {
726 ledges[rdata->loose_edge_len++] = i;
730 rdata->loose_edges = MEM_reallocN(ledges, rdata->loose_edge_len * sizeof(int));
733 if (rdata->mapped.supported) {
734 Mesh *me_cage = embm->mesh_eval_cage;
735 rdata->mapped.loose_edge_len = 0;
737 if (rdata->loose_edge_len) {
738 int *ledges = MEM_mallocN(me_cage->totedge * sizeof(int), __func__);
739 const int *e_origindex = rdata->mapped.e_origindex;
740 for (int i = 0; i < me_cage->totedge; i++) {
741 const int e_orig = e_origindex[i];
742 if (e_orig != ORIGINDEX_NONE) {
743 BMEdge *eed = BM_edge_at_index(bm, e_orig);
744 if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
746 if (eed->l == NULL || !bm_edge_has_visible_face(eed)) {
747 ledges[rdata->mapped.loose_edge_len++] = i;
752 rdata->mapped.loose_edges = MEM_reallocN(ledges, rdata->mapped.loose_edge_len * sizeof(int));
760 if (types & (MR_DATATYPE_VERT)) {
761 rdata->vert_len = me->totvert;
762 rdata->mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
764 if (types & (MR_DATATYPE_EDGE)) {
765 rdata->edge_len = me->totedge;
766 rdata->medge = CustomData_get_layer(&me->edata, CD_MEDGE);
768 if (types & MR_DATATYPE_LOOPTRI) {
769 const int tri_len = rdata->tri_len = poly_to_tri_count(me->totpoly, me->totloop);
770 MLoopTri *mlooptri = MEM_mallocN(sizeof(*mlooptri) * tri_len, __func__);
771 BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mlooptri);
772 rdata->mlooptri = mlooptri;
774 if (types & MR_DATATYPE_LOOP) {
775 rdata->loop_len = me->totloop;
776 rdata->mloop = CustomData_get_layer(&me->ldata, CD_MLOOP);
778 if (is_auto_smooth) {
779 mesh_render_calc_normals_loop_and_poly(me, split_angle, rdata);
782 if (types & MR_DATATYPE_POLY) {
783 rdata->poly_len = me->totpoly;
784 rdata->mpoly = CustomData_get_layer(&me->pdata, CD_MPOLY);
786 if (types & MR_DATATYPE_DVERT) {
787 rdata->vert_len = me->totvert;
788 rdata->dvert = CustomData_get_layer(&me->vdata, CD_MDEFORMVERT);
790 if (types & MR_DATATYPE_LOOPCOL) {
791 rdata->loop_len = me->totloop;
792 rdata->mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
794 if (types & MR_DATATYPE_LOOPUV) {
795 rdata->loop_len = me->totloop;
796 rdata->mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
800 if (types & MR_DATATYPE_SHADING) {
801 CustomData *cd_vdata, *cd_ldata;
803 BLI_assert(cd_vused != NULL && cd_lused != NULL);
805 if (me->edit_btmesh) {
806 BMesh *bm = me->edit_btmesh->bm;
807 cd_vdata = &bm->vdata;
808 cd_ldata = &bm->ldata;
811 cd_vdata = &me->vdata;
812 cd_ldata = &me->ldata;
815 rdata->cd.layers.uv_active = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
816 rdata->cd.layers.vcol_active = CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL);
817 rdata->cd.layers.tangent_active = rdata->cd.layers.uv_active;
819 #define CD_VALIDATE_ACTIVE_LAYER(active_index, used) \
820 if ((active_index != -1) && (used & (1 << active_index)) == 0) { \
824 CD_VALIDATE_ACTIVE_LAYER(rdata->cd.layers.uv_active, cd_lused[CD_MLOOPUV]);
825 CD_VALIDATE_ACTIVE_LAYER(rdata->cd.layers.tangent_active, cd_lused[CD_TANGENT]);
826 CD_VALIDATE_ACTIVE_LAYER(rdata->cd.layers.vcol_active, cd_lused[CD_MLOOPCOL]);
828 #undef CD_VALIDATE_ACTIVE_LAYER
830 rdata->is_orco_allocated = false;
831 if (cd_vused[CD_ORCO] & 1) {
832 rdata->orco = CustomData_get_layer(cd_vdata, CD_ORCO);
833 /* If orco is not available compute it ourselves */
835 rdata->is_orco_allocated = true;
836 if (me->edit_btmesh) {
837 BMesh *bm = me->edit_btmesh->bm;
838 rdata->orco = MEM_mallocN(sizeof(*rdata->orco) * rdata->vert_len, "orco mesh");
839 BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
840 for (int i = 0; i < bm->totvert; i++) {
841 copy_v3_v3(rdata->orco[i], BM_vert_at_index(bm, i)->co);
843 BKE_mesh_orco_verts_transform(me, rdata->orco, rdata->vert_len, 0);
846 rdata->orco = MEM_mallocN(sizeof(*rdata->orco) * rdata->vert_len, "orco mesh");
847 MVert *mvert = rdata->mvert;
848 for (int a = 0; a < rdata->vert_len; a++, mvert++) {
849 copy_v3_v3(rdata->orco[a], mvert->co);
851 BKE_mesh_orco_verts_transform(me, rdata->orco, rdata->vert_len, 0);
859 /* don't access mesh directly, instead use vars taken from BMesh or Mesh */
860 #define me DONT_USE_THIS
861 #ifdef me /* quiet warning */
867 .uv_len = CustomData_number_of_layers(cd_ldata, CD_MLOOPUV),
868 .vcol_len = CustomData_number_of_layers(cd_ldata, CD_MLOOPCOL),
871 rdata->cd.layers.uv_len = count_bits_i(cd_lused[CD_MLOOPUV]);
872 rdata->cd.layers.tangent_len = count_bits_i(cd_lused[CD_TANGENT]);
873 rdata->cd.layers.vcol_len = count_bits_i(cd_lused[CD_MLOOPCOL]);
875 rdata->cd.layers.uv = MEM_mallocN(sizeof(*rdata->cd.layers.uv) * rdata->cd.layers.uv_len, __func__);
876 rdata->cd.layers.vcol = MEM_mallocN(sizeof(*rdata->cd.layers.vcol) * rdata->cd.layers.vcol_len, __func__);
877 rdata->cd.layers.tangent = MEM_mallocN(sizeof(*rdata->cd.layers.tangent) * rdata->cd.layers.tangent_len, __func__);
879 rdata->cd.uuid.uv = MEM_mallocN(sizeof(*rdata->cd.uuid.uv) * rdata->cd.layers.uv_len, __func__);
880 rdata->cd.uuid.vcol = MEM_mallocN(sizeof(*rdata->cd.uuid.vcol) * rdata->cd.layers.vcol_len, __func__);
881 rdata->cd.uuid.tangent = MEM_mallocN(sizeof(*rdata->cd.uuid.tangent) * rdata->cd.layers.tangent_len, __func__);
883 rdata->cd.offset.uv = MEM_mallocN(sizeof(*rdata->cd.offset.uv) * rdata->cd.layers.uv_len, __func__);
884 rdata->cd.offset.vcol = MEM_mallocN(sizeof(*rdata->cd.offset.vcol) * rdata->cd.layers.vcol_len, __func__);
887 rdata->cd.layers.auto_vcol = MEM_callocN(
888 sizeof(*rdata->cd.layers.auto_vcol) * rdata->cd.layers.vcol_len, __func__);
889 rdata->cd.uuid.auto_mix = MEM_mallocN(
890 sizeof(*rdata->cd.uuid.auto_mix) * (rdata->cd.layers.vcol_len + rdata->cd.layers.uv_len), __func__);
893 /* We use a hash to identify each data layer based on its name.
894 * Gawain then search for this name in the current shader and bind if it exists.
895 * NOTE : This is prone to hash collision.
896 * One solution to hash collision would be to format the cd layer name
897 * to a safe glsl var name, but without name clash.
898 * NOTE 2 : Replicate changes to code_generate_vertex_new() in gpu_codegen.c */
899 if (rdata->cd.layers.vcol_len != 0) {
900 for (int i_src = 0, i_dst = 0; i_src < cd_layers_src.vcol_len; i_src++, i_dst++) {
901 if ((cd_lused[CD_MLOOPCOL] & (1 << i_src)) == 0) {
903 if (rdata->cd.layers.vcol_active >= i_src) {
904 rdata->cd.layers.vcol_active--;
908 const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPCOL, i_src);
909 uint hash = BLI_ghashutil_strhash_p(name);
910 BLI_snprintf(rdata->cd.uuid.vcol[i_dst], sizeof(*rdata->cd.uuid.vcol), "c%u", hash);
911 rdata->cd.layers.vcol[i_dst] = CustomData_get_layer_n(cd_ldata, CD_MLOOPCOL, i_src);
912 if (rdata->edit_bmesh) {
913 rdata->cd.offset.vcol[i_dst] = CustomData_get_n_offset(
914 &rdata->edit_bmesh->bm->ldata, CD_MLOOPCOL, i_src);
917 /* Gather number of auto layers. */
918 /* We only do vcols that are not overridden by uvs */
919 if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, name) == -1) {
921 rdata->cd.uuid.auto_mix[rdata->cd.layers.uv_len + i_dst],
922 sizeof(*rdata->cd.uuid.auto_mix), "a%u", hash);
923 rdata->cd.layers.auto_vcol[i_dst] = true;
930 CustomData_free_layers(cd_ldata, CD_TANGENT, rdata->loop_len);
931 CustomData_free_layers(cd_ldata, CD_MLOOPTANGENT, rdata->loop_len);
933 if (rdata->cd.layers.uv_len != 0) {
934 for (int i_src = 0, i_dst = 0; i_src < cd_layers_src.uv_len; i_src++, i_dst++) {
935 if ((cd_lused[CD_MLOOPUV] & (1 << i_src)) == 0) {
937 if (rdata->cd.layers.uv_active >= i_src) {
938 rdata->cd.layers.uv_active--;
942 const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i_src);
943 uint hash = BLI_ghashutil_strhash_p(name);
945 BLI_snprintf(rdata->cd.uuid.uv[i_dst], sizeof(*rdata->cd.uuid.uv), "u%u", hash);
946 rdata->cd.layers.uv[i_dst] = CustomData_get_layer_n(cd_ldata, CD_MLOOPUV, i_src);
947 if (rdata->edit_bmesh) {
948 rdata->cd.offset.uv[i_dst] = CustomData_get_n_offset(
949 &rdata->edit_bmesh->bm->ldata, CD_MLOOPUV, i_src);
951 BLI_snprintf(rdata->cd.uuid.auto_mix[i_dst], sizeof(*rdata->cd.uuid.auto_mix), "a%u", hash);
956 if (rdata->cd.layers.tangent_len != 0) {
958 /* -------------------------------------------------------------------- */
959 /* Pre-calculate tangents into 'rdata->cd.output.ldata' */
961 BLI_assert(!CustomData_has_layer(&rdata->cd.output.ldata, CD_TANGENT));
964 char tangent_names[MAX_MTFACE][MAX_NAME];
965 for (int i_src = 0, i_dst = 0; i_src < cd_layers_src.uv_len; i_src++, i_dst++) {
966 if ((cd_lused[CD_TANGENT] & (1 << i_src)) == 0) {
971 tangent_names[i_dst],
972 CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i_src), MAX_NAME);
976 /* If tangent from orco is requested, decrement tangent_len */
977 int actual_tangent_len = (cd_lused[CD_TANGENT] & DM_TANGENT_MASK_ORCO) ?
978 rdata->cd.layers.tangent_len - 1 : rdata->cd.layers.tangent_len;
979 if (rdata->edit_bmesh) {
980 BMEditMesh *em = rdata->edit_bmesh;
983 if (is_auto_smooth && rdata->loop_normals == NULL) {
984 /* Should we store the previous array of `loop_normals` in somewhere? */
985 rdata->loop_len = bm->totloop;
986 rdata->loop_normals = MEM_mallocN(sizeof(*rdata->loop_normals) * rdata->loop_len, __func__);
987 BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL, -1, false);
990 bool calc_active_tangent = false;
992 BKE_editmesh_loop_tangent_calc(
993 em, calc_active_tangent,
994 tangent_names, actual_tangent_len,
995 rdata->poly_normals, rdata->loop_normals,
997 &rdata->cd.output.ldata, bm->totloop,
998 &rdata->cd.output.tangent_mask);
1003 if (is_auto_smooth && rdata->loop_normals == NULL) {
1004 /* Should we store the previous array of `loop_normals` in CustomData? */
1005 mesh_render_calc_normals_loop_and_poly(me, split_angle, rdata);
1008 bool calc_active_tangent = false;
1010 BKE_mesh_calc_loop_tangent_ex(
1012 me->mpoly, me->totpoly,
1014 rdata->mlooptri, rdata->tri_len,
1016 calc_active_tangent,
1017 tangent_names, actual_tangent_len,
1018 rdata->poly_normals, rdata->loop_normals,
1020 &rdata->cd.output.ldata, me->totloop,
1021 &rdata->cd.output.tangent_mask);
1023 /* If we store tangents in the mesh, set temporary. */
1025 CustomData_set_layer_flag(cd_ldata, CD_TANGENT, CD_FLAG_TEMPORARY);
1028 #define me DONT_USE_THIS
1029 #ifdef me /* quiet warning */
1033 /* End tangent calculation */
1034 /* -------------------------------------------------------------------- */
1036 BLI_assert(CustomData_number_of_layers(&rdata->cd.output.ldata, CD_TANGENT) == rdata->cd.layers.tangent_len);
1039 for (int i_src = 0; i_src < cd_layers_src.uv_len; i_src++, i_dst++) {
1040 if ((cd_lused[CD_TANGENT] & (1 << i_src)) == 0) {
1042 if (rdata->cd.layers.tangent_active >= i_src) {
1043 rdata->cd.layers.tangent_active--;
1047 const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i_src);
1048 uint hash = BLI_ghashutil_strhash_p(name);
1050 BLI_snprintf(rdata->cd.uuid.tangent[i_dst], sizeof(*rdata->cd.uuid.tangent), "t%u", hash);
1052 /* Done adding tangents. */
1054 /* note: BKE_editmesh_loop_tangent_calc calculates 'CD_TANGENT',
1055 * not 'CD_MLOOPTANGENT' (as done below). It's OK, they're compatible. */
1057 /* note: normally we'd use 'i_src' here, but 'i_dst' is in sync with 'rdata->cd.output' */
1058 rdata->cd.layers.tangent[i_dst] = CustomData_get_layer_n(&rdata->cd.output.ldata, CD_TANGENT, i_dst);
1059 if (rdata->tri_len != 0) {
1060 BLI_assert(rdata->cd.layers.tangent[i_dst] != NULL);
1064 if (cd_lused[CD_TANGENT] & DM_TANGENT_MASK_ORCO) {
1065 const char *name = CustomData_get_layer_name(&rdata->cd.output.ldata, CD_TANGENT, i_dst);
1066 uint hash = BLI_ghashutil_strhash_p(name);
1067 BLI_snprintf(rdata->cd.uuid.tangent[i_dst], sizeof(*rdata->cd.uuid.tangent), "t%u", hash);
1069 rdata->cd.layers.tangent[i_dst] = CustomData_get_layer_n(&rdata->cd.output.ldata, CD_TANGENT, i_dst);
1079 /* Warning replace mesh pointer. */
1080 #define MBC_GET_FINAL_MESH(me) \
1081 /* Hack to show the final result. */ \
1082 const bool _use_em_final = ( \
1083 (me)->edit_btmesh && \
1084 (me)->edit_btmesh->mesh_eval_final && \
1085 ((me)->edit_btmesh->mesh_eval_final->runtime.is_original == false)); \
1087 if (_use_em_final) { \
1088 _me_fake = *(me)->edit_btmesh->mesh_eval_final; \
1089 _me_fake.mat = (me)->mat; \
1090 _me_fake.totcol = (me)->totcol; \
1094 static void mesh_render_data_free(MeshRenderData *rdata)
1096 if (rdata->is_orco_allocated) {
1097 MEM_SAFE_FREE(rdata->orco);
1099 MEM_SAFE_FREE(rdata->cd.offset.uv);
1100 MEM_SAFE_FREE(rdata->cd.offset.vcol);
1101 MEM_SAFE_FREE(rdata->cd.uuid.auto_mix);
1102 MEM_SAFE_FREE(rdata->cd.uuid.uv);
1103 MEM_SAFE_FREE(rdata->cd.uuid.vcol);
1104 MEM_SAFE_FREE(rdata->cd.uuid.tangent);
1105 MEM_SAFE_FREE(rdata->cd.layers.uv);
1106 MEM_SAFE_FREE(rdata->cd.layers.vcol);
1107 MEM_SAFE_FREE(rdata->cd.layers.tangent);
1108 MEM_SAFE_FREE(rdata->cd.layers.auto_vcol);
1109 MEM_SAFE_FREE(rdata->loose_verts);
1110 MEM_SAFE_FREE(rdata->loose_edges);
1111 MEM_SAFE_FREE(rdata->edges_adjacent_polys);
1112 MEM_SAFE_FREE(rdata->mlooptri);
1113 MEM_SAFE_FREE(rdata->loop_normals);
1114 MEM_SAFE_FREE(rdata->poly_normals);
1115 MEM_SAFE_FREE(rdata->poly_normals_pack);
1116 MEM_SAFE_FREE(rdata->vert_normals_pack);
1117 MEM_SAFE_FREE(rdata->vert_weight);
1118 MEM_SAFE_FREE(rdata->edge_select_bool);
1119 MEM_SAFE_FREE(rdata->edge_visible_bool);
1120 MEM_SAFE_FREE(rdata->vert_color);
1122 MEM_SAFE_FREE(rdata->mapped.loose_verts);
1123 MEM_SAFE_FREE(rdata->mapped.loose_edges);
1125 CustomData_free(&rdata->cd.output.ldata, rdata->loop_len);
1130 static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
1132 return mesh_render_data_create_ex(me, types, NULL, NULL);
1137 /* ---------------------------------------------------------------------- */
1139 /** \name Accessor Functions
1142 static const char *mesh_render_data_uv_auto_layer_uuid_get(const MeshRenderData *rdata, int layer)
1144 BLI_assert(rdata->types & MR_DATATYPE_SHADING);
1145 return rdata->cd.uuid.auto_mix[layer];
1148 static const char *mesh_render_data_vcol_auto_layer_uuid_get(const MeshRenderData *rdata, int layer)
1150 BLI_assert(rdata->types & MR_DATATYPE_SHADING);
1151 return rdata->cd.uuid.auto_mix[rdata->cd.layers.uv_len + layer];
1154 static const char *mesh_render_data_uv_layer_uuid_get(const MeshRenderData *rdata, int layer)
1156 BLI_assert(rdata->types & MR_DATATYPE_SHADING);
1157 return rdata->cd.uuid.uv[layer];
1160 static const char *mesh_render_data_vcol_layer_uuid_get(const MeshRenderData *rdata, int layer)
1162 BLI_assert(rdata->types & MR_DATATYPE_SHADING);
1163 return rdata->cd.uuid.vcol[layer];
1166 static const char *mesh_render_data_tangent_layer_uuid_get(const MeshRenderData *rdata, int layer)
1168 BLI_assert(rdata->types & MR_DATATYPE_SHADING);
1169 return rdata->cd.uuid.tangent[layer];
1172 static int UNUSED_FUNCTION(mesh_render_data_verts_len_get)(const MeshRenderData *rdata)
1174 BLI_assert(rdata->types & MR_DATATYPE_VERT);
1175 return rdata->vert_len;
1177 static int mesh_render_data_verts_len_get_maybe_mapped(const MeshRenderData *rdata)
1179 BLI_assert(rdata->types & MR_DATATYPE_VERT);
1180 return ((rdata->mapped.use == false) ? rdata->vert_len : rdata->mapped.vert_len);
1183 static int UNUSED_FUNCTION(mesh_render_data_loose_verts_len_get)(const MeshRenderData *rdata)
1185 BLI_assert(rdata->types & MR_DATATYPE_LOOSE_VERT);
1186 return rdata->loose_vert_len;
1188 static int mesh_render_data_loose_verts_len_get_maybe_mapped(const MeshRenderData *rdata)
1190 BLI_assert(rdata->types & MR_DATATYPE_LOOSE_VERT);
1191 return ((rdata->mapped.use == false) ? rdata->loose_vert_len : rdata->mapped.loose_vert_len);
1194 static int UNUSED_FUNCTION(mesh_render_data_edges_len_get)(const MeshRenderData *rdata)
1196 BLI_assert(rdata->types & MR_DATATYPE_EDGE);
1197 return rdata->edge_len;
1199 static int mesh_render_data_edges_len_get_maybe_mapped(const MeshRenderData *rdata)
1201 BLI_assert(rdata->types & MR_DATATYPE_EDGE);
1202 return ((rdata->mapped.use == false) ? rdata->edge_len : rdata->mapped.edge_len);
1205 static int UNUSED_FUNCTION(mesh_render_data_loose_edges_len_get)(const MeshRenderData *rdata)
1207 BLI_assert(rdata->types & MR_DATATYPE_LOOSE_EDGE);
1208 return rdata->loose_edge_len;
1210 static int mesh_render_data_loose_edges_len_get_maybe_mapped(const MeshRenderData *rdata)
1212 BLI_assert(rdata->types & MR_DATATYPE_LOOSE_EDGE);
1213 return ((rdata->mapped.use == false) ? rdata->loose_edge_len : rdata->mapped.loose_edge_len);
1216 static int mesh_render_data_looptri_len_get(const MeshRenderData *rdata)
1218 BLI_assert(rdata->types & MR_DATATYPE_LOOPTRI);
1219 return rdata->tri_len;
1221 static int mesh_render_data_looptri_len_get_maybe_mapped(const MeshRenderData *rdata)
1223 BLI_assert(rdata->types & MR_DATATYPE_LOOPTRI);
1224 return ((rdata->mapped.use == false) ? rdata->tri_len : rdata->mapped.tri_len);
1227 static int UNUSED_FUNCTION(mesh_render_data_mat_len_get)(const MeshRenderData *rdata)
1229 BLI_assert(rdata->types & MR_DATATYPE_POLY);
1230 return rdata->mat_len;
1233 static int mesh_render_data_loops_len_get(const MeshRenderData *rdata)
1235 BLI_assert(rdata->types & MR_DATATYPE_LOOP);
1236 return rdata->loop_len;
1239 static int mesh_render_data_loops_len_get_maybe_mapped(const MeshRenderData *rdata)
1241 BLI_assert(rdata->types & MR_DATATYPE_LOOP);
1242 return ((rdata->mapped.use == false) ? rdata->loop_len : rdata->mapped.loop_len);
1245 static int mesh_render_data_polys_len_get(const MeshRenderData *rdata)
1247 BLI_assert(rdata->types & MR_DATATYPE_POLY);
1248 return rdata->poly_len;
1250 static int mesh_render_data_polys_len_get_maybe_mapped(const MeshRenderData *rdata)
1252 BLI_assert(rdata->types & MR_DATATYPE_POLY);
1253 return ((rdata->mapped.use == false) ? rdata->poly_len : rdata->mapped.poly_len);
1259 /* ---------------------------------------------------------------------- */
1261 /* TODO remove prototype. */
1262 static void mesh_create_edit_facedots(MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor_data_facedots);
1264 /** \name Internal Cache (Lazy Initialization)
1267 /** Ensure #MeshRenderData.poly_normals_pack */
1268 static void mesh_render_data_ensure_poly_normals_pack(MeshRenderData *rdata)
1270 GPUPackedNormal *pnors_pack = rdata->poly_normals_pack;
1271 if (pnors_pack == NULL) {
1272 if (rdata->edit_bmesh) {
1273 BMesh *bm = rdata->edit_bmesh->bm;
1278 pnors_pack = rdata->poly_normals_pack = MEM_mallocN(sizeof(*pnors_pack) * rdata->poly_len, __func__);
1279 if (rdata->edit_data && rdata->edit_data->vertexCos != NULL) {
1280 BKE_editmesh_cache_ensure_poly_normals(rdata->edit_bmesh, rdata->edit_data);
1281 const float (*pnors)[3] = rdata->edit_data->polyNos;
1282 for (i = 0; i < bm->totface; i++) {
1283 pnors_pack[i] = GPU_normal_convert_i10_v3(pnors[i]);
1287 BM_ITER_MESH_INDEX(efa, &fiter, bm, BM_FACES_OF_MESH, i) {
1288 pnors_pack[i] = GPU_normal_convert_i10_v3(efa->no);
1293 float (*pnors)[3] = rdata->poly_normals;
1296 pnors = rdata->poly_normals = MEM_mallocN(sizeof(*pnors) * rdata->poly_len, __func__);
1297 BKE_mesh_calc_normals_poly(
1298 rdata->mvert, NULL, rdata->vert_len,
1299 rdata->mloop, rdata->mpoly, rdata->loop_len, rdata->poly_len, pnors, true);
1302 pnors_pack = rdata->poly_normals_pack = MEM_mallocN(sizeof(*pnors_pack) * rdata->poly_len, __func__);
1303 for (int i = 0; i < rdata->poly_len; i++) {
1304 pnors_pack[i] = GPU_normal_convert_i10_v3(pnors[i]);
1310 /** Ensure #MeshRenderData.vert_normals_pack */
1311 static void mesh_render_data_ensure_vert_normals_pack(MeshRenderData *rdata)
1313 GPUPackedNormal *vnors_pack = rdata->vert_normals_pack;
1314 if (vnors_pack == NULL) {
1315 if (rdata->edit_bmesh) {
1316 BMesh *bm = rdata->edit_bmesh->bm;
1321 vnors_pack = rdata->vert_normals_pack = MEM_mallocN(sizeof(*vnors_pack) * rdata->vert_len, __func__);
1322 BM_ITER_MESH_INDEX(eve, &viter, bm, BM_VERT, i) {
1323 vnors_pack[i] = GPU_normal_convert_i10_v3(eve->no);
1327 /* data from mesh used directly */
1334 /** Ensure #MeshRenderData.vert_color */
1335 static void UNUSED_FUNCTION(mesh_render_data_ensure_vert_color)(MeshRenderData *rdata)
1337 char (*vcol)[3] = rdata->vert_color;
1339 if (rdata->edit_bmesh) {
1340 BMesh *bm = rdata->edit_bmesh->bm;
1341 const int cd_loop_color_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
1342 if (cd_loop_color_offset == -1) {
1346 vcol = rdata->vert_color = MEM_mallocN(sizeof(*vcol) * rdata->loop_len, __func__);
1352 BM_ITER_MESH(efa, &fiter, bm, BM_FACES_OF_MESH) {
1353 BMLoop *l_iter, *l_first;
1354 l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
1356 const MLoopCol *lcol = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_color_offset);
1357 vcol[i][0] = lcol->r;
1358 vcol[i][1] = lcol->g;
1359 vcol[i][2] = lcol->b;
1361 } while ((l_iter = l_iter->next) != l_first);
1363 BLI_assert(i == rdata->loop_len);
1366 if (rdata->mloopcol == NULL) {
1370 vcol = rdata->vert_color = MEM_mallocN(sizeof(*vcol) * rdata->loop_len, __func__);
1372 for (int i = 0; i < rdata->loop_len; i++) {
1373 vcol[i][0] = rdata->mloopcol[i].r;
1374 vcol[i][1] = rdata->mloopcol[i].g;
1375 vcol[i][2] = rdata->mloopcol[i].b;
1382 vcol = rdata->vert_color = MEM_mallocN(sizeof(*vcol) * rdata->loop_len, __func__);
1384 for (int i = 0; i < rdata->loop_len; i++) {
1391 static float evaluate_vertex_weight(const MDeformVert *dvert, const DRW_MeshWeightState *wstate)
1394 bool show_alert_color = false;
1396 if (wstate->flags & DRW_MESH_WEIGHT_STATE_MULTIPAINT) {
1397 /* Multi-Paint feature */
1398 input = BKE_defvert_multipaint_collective_weight(
1399 dvert, wstate->defgroup_len, wstate->defgroup_sel, wstate->defgroup_sel_count,
1400 (wstate->flags & DRW_MESH_WEIGHT_STATE_AUTO_NORMALIZE) != 0);
1402 /* make it black if the selected groups have no weight on a vertex */
1403 if (input == 0.0f) {
1404 show_alert_color = true;
1408 /* default, non tricky behavior */
1409 input = defvert_find_weight(dvert, wstate->defgroup_active);
1411 if (input == 0.0f) {
1412 switch (wstate->alert_mode) {
1413 case OB_DRAW_GROUPUSER_ACTIVE:
1414 show_alert_color = true;
1417 case OB_DRAW_GROUPUSER_ALL:
1418 show_alert_color = defvert_is_weight_zero(dvert, wstate->defgroup_len);
1424 if (show_alert_color) {
1428 CLAMP(input, 0.0f, 1.0f);
1433 /** Ensure #MeshRenderData.vert_weight */
1434 static void mesh_render_data_ensure_vert_weight(MeshRenderData *rdata, const struct DRW_MeshWeightState *wstate)
1436 float *vweight = rdata->vert_weight;
1437 if (vweight == NULL) {
1438 if (wstate->defgroup_active == -1) {
1442 if (rdata->edit_bmesh) {
1443 BMesh *bm = rdata->edit_bmesh->bm;
1444 const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
1445 if (cd_dvert_offset == -1) {
1453 vweight = rdata->vert_weight = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__);
1454 BM_ITER_MESH_INDEX(eve, &viter, bm, BM_VERT, i) {
1455 const MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
1456 vweight[i] = evaluate_vertex_weight(dvert, wstate);
1460 if (rdata->dvert == NULL) {
1464 vweight = rdata->vert_weight = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__);
1465 for (int i = 0; i < rdata->vert_len; i++) {
1466 vweight[i] = evaluate_vertex_weight(&rdata->dvert[i], wstate);
1473 vweight = rdata->vert_weight = MEM_callocN(sizeof(*vweight) * rdata->vert_len, __func__);
1475 if ((wstate->defgroup_active < 0) && (wstate->defgroup_len > 0)) {
1476 copy_vn_fl(vweight, rdata->vert_len, -2.0f);
1478 else if (wstate->alert_mode != OB_DRAW_GROUPUSER_NONE) {
1479 copy_vn_fl(vweight, rdata->vert_len, -1.0f);
1485 /* ---------------------------------------------------------------------- */
1487 /** \name Internal Cache Generation
1490 static uchar mesh_render_data_looptri_flag(MeshRenderData *rdata, const BMFace *efa)
1494 if (efa == rdata->efa_act)
1495 fflag |= VFLAG_FACE_ACTIVE;
1497 if (BM_elem_flag_test(efa, BM_ELEM_SELECT))
1498 fflag |= VFLAG_FACE_SELECTED;
1500 #ifdef WITH_FREESTYLE
1501 if (rdata->cd.offset.freestyle_face != -1) {
1502 const FreestyleFace *ffa = BM_ELEM_CD_GET_VOID_P(efa, rdata->cd.offset.freestyle_face);
1503 if (ffa->flag & FREESTYLE_FACE_MARK) {
1504 fflag |= VFLAG_FACE_FREESTYLE;
1512 static void mesh_render_data_edge_flag(
1513 const MeshRenderData *rdata, const BMEdge *eed,
1514 EdgeDrawAttr *eattr)
1516 eattr->e_flag |= VFLAG_EDGE_EXISTS;
1518 if (eed == rdata->eed_act)
1519 eattr->e_flag |= VFLAG_EDGE_ACTIVE;
1521 if (BM_elem_flag_test(eed, BM_ELEM_SELECT))
1522 eattr->e_flag |= VFLAG_EDGE_SELECTED;
1524 if (BM_elem_flag_test(eed, BM_ELEM_SEAM))
1525 eattr->e_flag |= VFLAG_EDGE_SEAM;
1527 if (!BM_elem_flag_test(eed, BM_ELEM_SMOOTH))
1528 eattr->e_flag |= VFLAG_EDGE_SHARP;
1530 /* Use a byte for value range */
1531 if (rdata->cd.offset.crease != -1) {
1532 float crease = BM_ELEM_CD_GET_FLOAT(eed, rdata->cd.offset.crease);
1534 eattr->crease = (uchar)(crease * 255.0f);
1538 /* Use a byte for value range */
1539 if (rdata->cd.offset.bweight != -1) {
1540 float bweight = BM_ELEM_CD_GET_FLOAT(eed, rdata->cd.offset.bweight);
1542 eattr->bweight = (uchar)(bweight * 255.0f);
1546 #ifdef WITH_FREESTYLE
1547 if (rdata->cd.offset.freestyle_edge != -1) {
1548 const FreestyleEdge *fed = BM_ELEM_CD_GET_VOID_P(eed, rdata->cd.offset.freestyle_edge);
1549 if (fed->flag & FREESTYLE_EDGE_MARK) {
1550 eattr->e_flag |= VFLAG_EDGE_FREESTYLE;
1556 static uchar mesh_render_data_vertex_flag(MeshRenderData *rdata, const BMVert *eve)
1558 uchar vflag = VFLAG_VERTEX_EXISTS;
1560 /* Current vertex */
1561 if (eve == rdata->eve_act)
1562 vflag |= VFLAG_VERTEX_ACTIVE;
1564 if (BM_elem_flag_test(eve, BM_ELEM_SELECT))
1565 vflag |= VFLAG_VERTEX_SELECTED;
1570 static void add_edit_tri(
1571 MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_lnor, GPUVertBuf *vbo_data, GPUIndexBufBuilder *elb,
1572 const uint pos_id, const uint vnor_id, const uint lnor_id, const uint data_id,
1573 const BMLoop **bm_looptri, const int base_vert_idx)
1578 /* Only draw vertices once. */
1580 for (int i = 0; i < 3; ++i) {
1581 if (!BM_elem_flag_test(bm_looptri[i]->v, BM_ELEM_TAG)) {
1582 BM_elem_flag_enable(bm_looptri[i]->v, BM_ELEM_TAG);
1583 GPU_indexbuf_add_generic_vert(elb, base_vert_idx + i);
1589 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
1590 if (rdata->edit_data && rdata->edit_data->vertexCos) {
1591 for (uint i = 0; i < 3; i++) {
1592 int vidx = BM_elem_index_get(bm_looptri[i]->v);
1593 const float *pos = rdata->edit_data->vertexCos[vidx];
1594 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos);
1598 for (uint i = 0; i < 3; i++) {
1599 const float *pos = bm_looptri[i]->v->co;
1600 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos);
1604 for (uint i = 0; i < 3; i++) {
1605 GPUPackedNormal vnor = GPU_normal_convert_i10_v3(bm_looptri[i]->v->no);
1606 GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx + i, &vnor);
1611 float (*lnors)[3] = rdata->loop_normals;
1612 for (uint i = 0; i < 3; i++) {
1613 const float *nor = (lnors) ? lnors[BM_elem_index_get(bm_looptri[i])] : bm_looptri[0]->f->no;
1614 GPUPackedNormal lnor = GPU_normal_convert_i10_v3(nor);
1615 GPU_vertbuf_attr_set(vbo_lnor, lnor_id, base_vert_idx + i, &lnor);
1620 fflag = mesh_render_data_looptri_flag(rdata, bm_looptri[0]->f);
1621 for (uint i = 0; i < 3; i++) {
1622 const int i_next = (i + 1) % 3;
1623 const int i_prev = (i + 2) % 3;
1624 vflag = mesh_render_data_vertex_flag(rdata, bm_looptri[i]->v);
1625 /* Opposite edge to the vertex at 'i'. */
1626 EdgeDrawAttr eattr = {0};
1627 const bool is_edge_real = (bm_looptri[i_next] == bm_looptri[i_prev]->prev);
1629 mesh_render_data_edge_flag(rdata, bm_looptri[i_next]->e, &eattr);
1631 eattr.v_flag = fflag | vflag;
1632 GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr);
1636 static bool add_edit_tri_mapped(
1637 MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_lnor, GPUVertBuf *vbo_data, GPUIndexBufBuilder *elb,
1638 const uint pos_id, const uint vnor_id, const uint lnor_id, const uint data_id,
1639 BMFace *efa, const MLoopTri *mlt, const float (*poly_normals)[3], const float (*loop_normals)[3], const int base_vert_idx)
1641 if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
1645 BMEditMesh *embm = rdata->edit_bmesh;
1646 BMesh *bm = embm->bm;
1647 Mesh *me_cage = embm->mesh_eval_cage;
1649 const MVert *mvert = me_cage->mvert;
1650 const MEdge *medge = me_cage->medge;
1651 const MLoop *mloop = me_cage->mloop;
1653 const int *v_origindex = rdata->mapped.v_origindex;
1654 const int *e_origindex = rdata->mapped.e_origindex;
1657 for (int i = 0; i < 3; ++i) {
1658 const int v_orig = v_origindex[mloop[mlt->tri[i]].v];
1659 if (v_orig == ORIGINDEX_NONE) {
1662 BMVert *v = BM_vert_at_index(bm, v_orig);
1663 if (!BM_elem_flag_test(v, BM_ELEM_TAG)) {
1664 BM_elem_flag_enable(v, BM_ELEM_TAG);
1665 GPU_indexbuf_add_generic_vert(elb, base_vert_idx + i);
1671 for (uint i = 0; i < 3; i++) {
1672 const float *pos = mvert[mloop[mlt->tri[i]].v].co;
1673 GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mvert[mloop[mlt->tri[i]].v].no);
1674 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos);
1675 GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx + i, &vnor);
1680 for (uint i = 0; i < 3; i++) {
1681 const float *nor = loop_normals ? loop_normals[mlt->tri[i]] : poly_normals[mlt->poly];
1682 GPUPackedNormal lnor = GPU_normal_convert_i10_v3(nor);
1683 GPU_vertbuf_attr_set(vbo_lnor, lnor_id, base_vert_idx + i, &lnor);
1688 EdgeDrawAttr eattr[3] = {{0}}; /* Importantly VFLAG_VERTEX_EXISTS is not set. */
1689 uchar fflag = mesh_render_data_looptri_flag(rdata, efa);
1690 for (uint i = 0; i < 3; i++) {
1691 const int i_next = (i + 1) % 3;
1692 const int i_prev = (i + 2) % 3;
1693 const int v_orig = v_origindex[mloop[mlt->tri[i]].v];
1694 if (v_orig != ORIGINDEX_NONE) {
1695 BMVert *v = BM_vert_at_index(bm, v_orig);
1696 eattr[i].v_flag |= mesh_render_data_vertex_flag(rdata, v);
1698 /* Opposite edge to the vertex at 'i'. */
1699 const int e_idx = mloop[mlt->tri[i_next]].e;
1700 const int e_orig = e_origindex[e_idx];
1701 if (e_orig != ORIGINDEX_NONE) {
1702 const MEdge *ed = &medge[e_idx];
1703 const uint tri_edge[2] = {mloop[mlt->tri[i_prev]].v, mloop[mlt->tri[i_next]].v};
1704 const bool is_edge_real = (
1705 ((ed->v1 == tri_edge[0]) && (ed->v2 == tri_edge[1])) ||
1706 ((ed->v1 == tri_edge[1]) && (ed->v2 == tri_edge[0])));
1708 BMEdge *eed = BM_edge_at_index(bm, e_orig);
1709 mesh_render_data_edge_flag(rdata, eed, &eattr[i]);
1710 /* Set vertex selected if both original verts are selected. */
1711 if (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) &&
1712 BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))
1714 eattr[i_next].v_flag |= VFLAG_VERTEX_SELECTED;
1715 eattr[i_prev].v_flag |= VFLAG_VERTEX_SELECTED;
1720 for (uint i = 0; i < 3; i++) {
1721 eattr[i].v_flag |= fflag;
1722 GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr[i]);
1729 static void add_edit_loose_edge(
1730 MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_data,
1731 const uint pos_id, const uint vnor_id, const uint data_id,
1732 const BMEdge *eed, const int base_vert_idx)
1735 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
1736 if (rdata->edit_data && rdata->edit_data->vertexCos) {
1737 for (uint i = 0; i < 2; i++) {
1738 int vidx = BM_elem_index_get((&eed->v1)[i]);
1739 const float *pos = rdata->edit_data->vertexCos[vidx];
1740 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos);
1744 for (int i = 0; i < 2; i++) {
1745 const float *pos = (&eed->v1)[i]->co;
1746 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos);
1750 for (int i = 0; i < 2; i++) {
1751 GPUPackedNormal vnor = GPU_normal_convert_i10_v3((&eed->v1)[i]->no);
1752 GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx + i, &vnor);
1757 EdgeDrawAttr eattr = {0};
1758 mesh_render_data_edge_flag(rdata, eed, &eattr);
1759 for (int i = 0; i < 2; i++) {
1760 eattr.v_flag = mesh_render_data_vertex_flag(rdata, (&eed->v1)[i]);
1761 GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr);
1765 static void add_edit_loose_edge_mapped(
1766 MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_data,
1767 const uint pos_id, const uint vnor_id, const uint data_id,
1768 BMEdge *eed, const MVert *mvert, const MEdge *ed, const int base_vert_idx)
1771 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
1772 for (int i = 0; i < 2; i++) {
1773 const float *pos = mvert[*(&ed->v1 + i)].co;
1774 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos);
1776 GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mvert[*(&ed->v1 + i)].no);
1777 GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx + i, &vnor);
1782 EdgeDrawAttr eattr = {0};
1783 mesh_render_data_edge_flag(rdata, eed, &eattr);
1784 for (int i = 0; i < 2; i++) {
1785 const int v_orig = rdata->mapped.v_origindex[*(&ed->v1 + i)];
1786 eattr.v_flag = (v_orig != ORIGINDEX_NONE) ? mesh_render_data_vertex_flag(rdata, (&eed->v1)[i]) : 0;
1787 GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr);
1792 static void add_edit_loose_vert(
1793 MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_data,
1794 const uint pos_id, const uint vnor_id, const uint data_id,
1795 const BMVert *eve, const int base_vert_idx)
1798 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
1799 if (rdata->edit_data && rdata->edit_data->vertexCos) {
1800 int vidx = BM_elem_index_get(eve);
1801 const float *pos = rdata->edit_data->vertexCos[vidx];
1802 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx, pos);
1805 const float *pos = eve->co;
1806 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx, pos);
1809 GPUPackedNormal vnor = GPU_normal_convert_i10_v3(eve->no);
1810 GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx, &vnor);
1814 uchar vflag[4] = {0, 0, 0, 0};
1815 vflag[0] = mesh_render_data_vertex_flag(rdata, eve);
1816 GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx, vflag);
1819 static void add_edit_loose_vert_mapped(
1820 MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_data,
1821 const uint pos_id, const uint vnor_id, const uint data_id,
1822 const BMVert *eve, const MVert *mv, const int base_vert_idx)
1825 const float *pos = mv->co;
1826 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx, pos);
1828 GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mv->no);
1829 GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx, &vnor);
1833 uchar vflag[4] = {0, 0, 0, 0};
1834 vflag[0] = mesh_render_data_vertex_flag(rdata, eve);
1835 GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx, vflag);
1839 static bool add_edit_facedot(
1840 MeshRenderData *rdata, GPUVertBuf *vbo,
1841 const uint fdot_pos_id, const uint fdot_nor_flag_id,
1842 const int poly, const int base_vert_idx)
1844 BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
1845 float pnor[3], center[3];
1847 if (rdata->edit_bmesh) {
1848 const BMFace *efa = BM_face_at_index(rdata->edit_bmesh->bm, poly);
1849 if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
1852 if (rdata->edit_data && rdata->edit_data->vertexCos) {
1853 copy_v3_v3(center, rdata->edit_data->polyCos[poly]);
1854 copy_v3_v3(pnor, rdata->edit_data->polyNos[poly]);
1857 BM_face_calc_center_median(efa, center);
1858 copy_v3_v3(pnor, efa->no);
1860 selected = (BM_elem_flag_test(efa, BM_ELEM_SELECT) != 0) ? true : false;
1863 MVert *mvert = rdata->mvert;
1864 const MPoly *mpoly = rdata->mpoly + poly;
1865 const MLoop *mloop = rdata->mloop + mpoly->loopstart;
1867 BKE_mesh_calc_poly_center(mpoly, mloop, mvert, center);
1868 BKE_mesh_calc_poly_normal(mpoly, mloop, mvert, pnor);
1870 selected = false; /* No selection if not in edit mode */
1873 GPUPackedNormal nor = GPU_normal_convert_i10_v3(pnor);
1874 nor.w = (selected) ? 1 : 0;
1875 GPU_vertbuf_attr_set(vbo, fdot_nor_flag_id, base_vert_idx, &nor);
1876 GPU_vertbuf_attr_set(vbo, fdot_pos_id, base_vert_idx, center);
1880 static bool add_edit_facedot_mapped(
1881 MeshRenderData *rdata, GPUVertBuf *vbo,
1882 const uint fdot_pos_id, const uint fdot_nor_flag_id,
1883 const int poly, const int base_vert_idx)
1885 BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
1886 float pnor[3], center[3];
1887 const int *p_origindex = rdata->mapped.p_origindex;
1888 const int p_orig = p_origindex[poly];
1889 if (p_orig == ORIGINDEX_NONE) {
1892 BMEditMesh *em = rdata->edit_bmesh;
1893 const BMFace *efa = BM_face_at_index(rdata->edit_bmesh->bm, p_orig);
1894 if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
1898 Mesh *me_cage = em->mesh_eval_cage;
1899 const MVert *mvert = me_cage->mvert;
1900 const MLoop *mloop = me_cage->mloop;
1901 const MPoly *mpoly = me_cage->mpoly;
1903 const MPoly *mp = mpoly + poly;
1904 const MLoop *ml = mloop + mp->loopstart;
1906 BKE_mesh_calc_poly_center(mp, ml, mvert, center);
1907 BKE_mesh_calc_poly_normal(mp, ml, mvert, pnor);
1909 GPUPackedNormal nor = GPU_normal_convert_i10_v3(pnor);
1910 nor.w = (BM_elem_flag_test(efa, BM_ELEM_SELECT) != 0) ? 1 : 0;
1911 GPU_vertbuf_attr_set(vbo, fdot_nor_flag_id, base_vert_idx, &nor);
1912 GPU_vertbuf_attr_set(vbo, fdot_pos_id, base_vert_idx, center);
1919 /* ---------------------------------------------------------------------- */
1921 /** \name Vertex Group Selection
1924 /** Reset the selection structure, deallocating heap memory as appropriate. */
1925 static void drw_mesh_weight_state_clear(struct DRW_MeshWeightState *wstate)
1927 MEM_SAFE_FREE(wstate->defgroup_sel);
1929 memset(wstate, 0, sizeof(*wstate));
1931 wstate->defgroup_active = -1;
1934 /** Copy selection data from one structure to another, including heap memory. */
1935 static void drw_mesh_weight_state_copy(
1936 struct DRW_MeshWeightState *wstate_dst, const struct DRW_MeshWeightState *wstate_src)
1938 MEM_SAFE_FREE(wstate_dst->defgroup_sel);
1940 memcpy(wstate_dst, wstate_src, sizeof(*wstate_dst));
1942 if (wstate_src->defgroup_sel) {
1943 wstate_dst->defgroup_sel = MEM_dupallocN(wstate_src->defgroup_sel);
1947 /** Compare two selection structures. */
1948 static bool drw_mesh_weight_state_compare(const struct DRW_MeshWeightState *a, const struct DRW_MeshWeightState *b)
1950 return a->defgroup_active == b->defgroup_active &&
1951 a->defgroup_len == b->defgroup_len &&
1952 a->flags == b->flags &&
1953 a->alert_mode == b->alert_mode &&
1954 a->defgroup_sel_count == b->defgroup_sel_count &&
1955 ((!a->defgroup_sel && !b->defgroup_sel) ||
1956 (a->defgroup_sel && b->defgroup_sel &&
1957 memcmp(a->defgroup_sel, b->defgroup_sel, a->defgroup_len * sizeof(bool)) == 0));
1960 static void drw_mesh_weight_state_extract(
1961 Object *ob, Mesh *me, const ToolSettings *ts, bool paint_mode,
1962 struct DRW_MeshWeightState *wstate)
1964 /* Extract complete vertex weight group selection state and mode flags. */
1965 memset(wstate, 0, sizeof(*wstate));
1967 wstate->defgroup_active = ob->actdef - 1;
1968 wstate->defgroup_len = BLI_listbase_count(&ob->defbase);
1970 wstate->alert_mode = ts->weightuser;
1972 if (paint_mode && ts->multipaint) {
1973 /* Multipaint needs to know all selected bones, not just the active group.
1974 * This is actually a relatively expensive operation, but caching would be difficult. */
1975 wstate->defgroup_sel = BKE_object_defgroup_selected_get(ob, wstate->defgroup_len, &wstate->defgroup_sel_count);
1977 if (wstate->defgroup_sel_count > 1) {
1978 wstate->flags |= DRW_MESH_WEIGHT_STATE_MULTIPAINT | (ts->auto_normalize ? DRW_MESH_WEIGHT_STATE_AUTO_NORMALIZE : 0);
1980 if (me->editflag & ME_EDIT_MIRROR_X) {
1981 BKE_object_defgroup_mirror_selection(
1982 ob, wstate->defgroup_len, wstate->defgroup_sel, wstate->defgroup_sel, &wstate->defgroup_sel_count);
1985 /* With only one selected bone Multipaint reverts to regular mode. */
1987 wstate->defgroup_sel_count = 0;
1988 MEM_SAFE_FREE(wstate->defgroup_sel);
1995 /* ---------------------------------------------------------------------- */
1997 /** \name Mesh GPUBatch Cache
2000 typedef struct MeshBatchCache {
2001 /* In order buffers: All verts only specified once.
2002 * To be used with a GPUIndexBuf. */
2005 GPUVertBuf *pos_nor;
2006 GPUVertBuf *weights;
2008 GPUVertBuf *loop_pos_nor;
2009 GPUVertBuf *loop_uv_tan;
2010 GPUVertBuf *loop_vcol;
2013 /* Tesselated: (all verts specified for each triangles).
2014 * Indices does not match the CPU data structure's. */
2016 GPUVertBuf *pos_nor;
2017 GPUVertBuf *wireframe_data;
2021 * Data is also tesselated because of barycentric wireframe rendering. */
2023 GPUVertBuf *pos_nor;
2024 GPUVertBuf *pos_nor_ledges;
2025 GPUVertBuf *pos_nor_lverts;
2026 GPUVertBuf *pos_nor_data_facedots;
2028 GPUVertBuf *data_ledges;
2029 GPUVertBuf *data_lverts;
2032 GPUVertBuf *loop_pos;
2033 GPUVertBuf *loop_vert_idx;
2034 GPUVertBuf *loop_edge_idx;
2035 GPUVertBuf *loop_face_idx;
2036 GPUVertBuf *facedots_idx;
2040 * We need different flags and vertex count form edit mesh. */
2042 GPUVertBuf *loop_stretch_angle;
2043 GPUVertBuf *loop_stretch_area;
2044 GPUVertBuf *loop_uv;
2045 GPUVertBuf *loop_data;
2046 GPUVertBuf *facedots_uv;
2047 GPUVertBuf *facedots_data;
2051 * Only need to be updated when topology changes. */
2053 /* Indices to verts. */
2054 GPUIndexBuf *surf_tris;
2055 GPUIndexBuf *edges_lines;
2056 GPUIndexBuf *edges_adj_lines;
2057 GPUIndexBuf *loose_edges_lines;
2058 /* Indices to vloops. */
2059 GPUIndexBuf *loops_tris;
2060 GPUIndexBuf *loops_lines;
2061 /* Contains indices to unique edit vertices to not
2062 * draw the same vert multiple times (because of tesselation). */
2063 GPUIndexBuf *edit_verts_points;
2064 /* Edit mode selection. */
2065 GPUIndexBuf *edit_loops_points; /* verts */
2066 GPUIndexBuf *edit_loops_lines; /* edges */
2067 GPUIndexBuf *edit_loops_tris; /* faces */
2069 GPUIndexBuf *edituv_loops_lines; /* edges & faces */
2073 /* Surfaces / Render */
2075 GPUBatch *surface_weights;
2077 GPUBatch *edit_triangles;
2078 GPUBatch *edit_vertices;
2079 GPUBatch *edit_loose_edges;
2080 GPUBatch *edit_loose_verts;
2081 GPUBatch *edit_triangles_nor;
2082 GPUBatch *edit_triangles_lnor;
2083 GPUBatch *edit_loose_edges_nor;
2084 GPUBatch *edit_facedots;
2086 GPUBatch *edituv_faces_strech_area;
2087 GPUBatch *edituv_faces_strech_angle;
2088 GPUBatch *edituv_faces;
2089 GPUBatch *edituv_edges;
2090 GPUBatch *edituv_verts;
2091 GPUBatch *edituv_facedots;
2092 /* Edit selection */
2093 GPUBatch *edit_selection_verts;
2094 GPUBatch *edit_selection_edges;
2095 GPUBatch *edit_selection_faces;
2096 GPUBatch *edit_selection_facedots;
2097 /* Common display / Other */
2098 GPUBatch *all_verts;
2099 GPUBatch *all_edges;
2100 GPUBatch *loose_edges;
2101 GPUBatch *edge_detection;
2102 GPUBatch *wire_loops; /* Loops around faces. */
2103 GPUBatch *wire_triangles; /* Triangles for object mode wireframe. */
2106 GPUIndexBuf **surf_per_mat_tris;
2107 GPUBatch **surf_per_mat;
2109 /* OLD BATCH METHOD, thoses needs to be ported and added in the structs above. */
2110 GPUBatch *texpaint_uv_loops;
2112 /* arrays of bool uniform names (and value) that will be use to
2113 * set srgb conversion for auto attribs.*/
2114 char *auto_layer_names;
2115 int *auto_layer_is_srgb;
2118 /* settings to determine if cache is invalid */
2119 bool is_maybe_dirty;
2120 bool is_dirty; /* Instantly invalidates cache, skipping mesh check */
2129 struct DRW_MeshWeightState weight_state;
2131 uchar cd_vused[CD_NUMTYPES];
2132 uchar cd_vneeded[CD_NUMTYPES];
2133 ushort cd_lused[CD_NUMTYPES];
2134 ushort cd_lneeded[CD_NUMTYPES];
2136 /* XXX, only keep for as long as sculpt mode uses shaded drawing. */
2137 bool is_sculpt_points_tag;
2139 /* Valid only if edge_detection is up to date. */
2143 /* GPUBatch cache management. */
2145 static bool mesh_batch_cache_valid(Mesh *me)
2147 MeshBatchCache *cache = me->runtime.batch_cache;
2149 if (cache == NULL) {
2153 if (cache->mat_len != mesh_render_mat_len_get(me)) {
2157 if (cache->is_editmode != (me->edit_btmesh != NULL)) {
2161 if (cache->is_dirty) {
2165 if (cache->is_maybe_dirty == false) {
2169 if (cache->is_editmode) {
2172 else if ((cache->vert_len != mesh_render_verts_len_get(me)) ||
2173 (cache->edge_len != mesh_render_edges_len_get(me)) ||
2174 (cache->tri_len != mesh_render_looptri_len_get(me)) ||
2175 (cache->poly_len != mesh_render_polys_len_get(me)) ||
2176 (cache->mat_len != mesh_render_mat_len_get(me)))
2185 static void mesh_batch_cache_init(Mesh *me)
2187 MeshBatchCache *cache = me->runtime.batch_cache;
2190 cache = me->runtime.batch_cache = MEM_callocN(sizeof(*cache), __func__);
2193 memset(cache, 0, sizeof(*cache));
2196 cache->is_editmode = me->edit_btmesh != NULL;
2198 if (cache->is_editmode == false) {
2199 cache->edge_len = mesh_render_edges_len_get(me);
2200 cache->tri_len = mesh_render_looptri_len_get(me);
2201 cache->poly_len = mesh_render_polys_len_get(me);
2202 cache->vert_len = mesh_render_verts_len_get(me);
2205 cache->mat_len = mesh_render_mat_len_get(me);
2206 cache->surf_per_mat_tris = MEM_callocN(sizeof(*cache->surf_per_mat_tris) * cache->mat_len, __func__);
2207 cache->surf_per_mat = MEM_callocN(sizeof(*cache->surf_per_mat) * cache->mat_len, __func__);
2209 cache->is_maybe_dirty = false;
2210 cache->is_dirty = false;
2212 drw_mesh_weight_state_clear(&cache->weight_state);
2215 static MeshBatchCache *mesh_batch_cache_get(Mesh *me)
2217 if (!mesh_batch_cache_valid(me)) {
2218 mesh_batch_cache_clear(me);
2219 mesh_batch_cache_init(me);
2221 return me->runtime.batch_cache;
2224 static void mesh_batch_cache_check_vertex_group(MeshBatchCache *cache, const struct DRW_MeshWeightState *wstate)
2226 if (!drw_mesh_weight_state_compare(&cache->weight_state, wstate)) {
2227 GPU_BATCH_CLEAR_SAFE(cache->batch.surface_weights);
2228 GPU_VERTBUF_DISCARD_SAFE(cache->ordered.weights);
2230 drw_mesh_weight_state_clear(&cache->weight_state);
2234 static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
2236 GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_pos_nor);
2237 GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_uv_tan);
2238 GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_vcol);
2240 // GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_orco);
2242 if (cache->surf_per_mat_tris) {
2243 for (int i = 0; i < cache->mat_len; i++) {
2244 GPU_INDEXBUF_DISCARD_SAFE(cache->surf_per_mat_tris[i]);
2247 MEM_SAFE_FREE(cache->surf_per_mat_tris);
2248 if (cache->surf_per_mat) {
2249 for (int i = 0; i < cache->mat_len; i++) {
2250 GPU_BATCH_DISCARD_SAFE(cache->surf_per_mat[i]);
2253 MEM_SAFE_FREE(cache->surf_per_mat);
2255 MEM_SAFE_FREE(cache->auto_layer_names);
2256 MEM_SAFE_FREE(cache->auto_layer_is_srgb);
2261 static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache)
2263 for (int i = 0; i < sizeof(cache->edituv) / sizeof(void *); ++i) {
2264 GPUVertBuf **vbo = (GPUVertBuf **)&cache->edituv;
2265 GPU_VERTBUF_DISCARD_SAFE(vbo[i]);
2268 GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_lines);
2269 GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_area);
2270 GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_angle);
2271 GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces);
2272 GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_edges);
2273 GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_verts);
2274 GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_facedots);
2276 gpu_batch_presets_unregister(cache->texpaint_uv_loops);
2278 GPU_BATCH_DISCARD_SAFE(cache->texpaint_uv_loops);
2281 void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
2283 MeshBatchCache *cache = me->runtime.batch_cache;
2284 if (cache == NULL) {
2288 case BKE_MESH_BATCH_DIRTY_MAYBE_ALL:
2289 cache->is_maybe_dirty = true;
2291 case BKE_MESH_BATCH_DIRTY_SELECT:
2292 GPU_VERTBUF_DISCARD_SAFE(cache->edit.data);
2293 GPU_VERTBUF_DISCARD_SAFE(cache->edit.data_ledges);
2294 GPU_VERTBUF_DISCARD_SAFE(cache->edit.data_lverts);
2295 GPU_VERTBUF_DISCARD_SAFE(cache->edit.pos_nor_data_facedots);
2296 GPU_BATCH_DISCARD_SAFE(cache->batch.edit_triangles);
2297 GPU_BATCH_DISCARD_SAFE(cache->batch.edit_vertices);
2298 GPU_BATCH_DISCARD_SAFE(cache->batch.edit_loose_verts);
2299 GPU_BATCH_DISCARD_SAFE(cache->batch.edit_loose_edges);
2300 GPU_BATCH_DISCARD_SAFE(cache->batch.edit_facedots);
2301 /* Paint mode selection */
2302 /* TODO only do that in paint mode. */
2303 GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_pos_nor);
2304 GPU_BATCH_DISCARD_SAFE(cache->batch.surface);
2305 GPU_BATCH_DISCARD_SAFE(cache->batch.wire_loops);
2306 if (cache->surf_per_mat) {
2307 for (int i = 0; i < cache->mat_len; i++) {
2308 GPU_BATCH_DISCARD_SAFE(cache->surf_per_mat[i]);
2311 /* Because visible UVs depends on edit mode selection, discard everything. */
2312 mesh_batch_cache_discard_uvedit(cache);
2314 case BKE_MESH_BATCH_DIRTY_ALL:
2315 cache->is_dirty = true;
2317 case BKE_MESH_BATCH_DIRTY_SHADING:
2318 mesh_batch_cache_discard_shaded_tri(cache);
2319 mesh_batch_cache_discard_uvedit(cache);
2321 case BKE_MESH_BATCH_DIRTY_SCULPT_COORDS:
2322 cache->is_sculpt_points_tag = true;
2324 case BKE_MESH_BATCH_DIRTY_UVEDIT_ALL:
2325 mesh_batch_cache_discard_uvedit(cache);
2327 case BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT:
2328 /* For now same as above. */
2329 mesh_batch_cache_discard_uvedit(cache);
2336 static void mesh_batch_cache_clear(Mesh *me)
2338 MeshBatchCache *cache = me->runtime.batch_cache;
2343 for (int i = 0; i < sizeof(cache->ordered) / sizeof(void *); ++i) {
2344 GPUVertBuf **vbo = (GPUVertBuf **)&cache->ordered;
2345 GPU_VERTBUF_DISCARD_SAFE(vbo[i]);
2347 for (int i = 0; i < sizeof(cache->tess) / sizeof(void *); ++i) {
2348 GPUVertBuf **vbo = (GPUVertBuf **)&cache->tess;
2349 GPU_VERTBUF_DISCARD_SAFE(vbo[i]);
2351 for (int i = 0; i < sizeof(cache->edit) / sizeof(void *); ++i) {
2352 GPUVertBuf **vbo = (GPUVertBuf **)&cache->edit;
2353 GPU_VERTBUF_DISCARD_SAFE(vbo[i]);
2355 for (int i = 0; i < sizeof(cache->ibo) / sizeof(void *); ++i) {
2356 GPUIndexBuf **ibo = (GPUIndexBuf **)&cache->ibo;
2357 GPU_INDEXBUF_DISCARD_SAFE(ibo[i]);
2359 for (int i = 0; i < sizeof(cache->batch) / sizeof(void *); ++i) {
2360 GPUBatch **batch = (GPUBatch **)&cache->batch;
2361 GPU_BATCH_DISCARD_SAFE(batch[i]);
2364 mesh_batch_cache_discard_shaded_tri(cache);
2366 mesh_batch_cache_discard_uvedit(cache);
2368 drw_mesh_weight_state_clear(&cache->weight_state);
2371 void DRW_mesh_batch_cache_free(Mesh *me)
2373 mesh_batch_cache_clear(me);
2374 MEM_SAFE_FREE(me->runtime.batch_cache);
2377 /* GPUBatch cache usage. */
2379 static void mesh_create_pos_and_nor_tess(MeshRenderData *rdata, GPUVertBuf *vbo, bool use_hide)
2381 static GPUVertFormat format = { 0 };
2382 static struct { uint pos, nor; } attr_id;
2383 if (format.attr_len == 0) {
2384 attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
2385 attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
2386 GPU_vertformat_triple_load(&format);
2389 GPU_vertbuf_init_with_format(vbo, &format);
2391 const int tri_len = mesh_render_data_looptri_len_get_maybe_mapped(rdata);
2392 const int vbo_len_capacity = tri_len * 3;
2393 int vbo_len_used = 0;
2394 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2396 GPUVertBufRaw pos_step, nor_step;
2397 GPU_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step);
2398 GPU_vertbuf_attr_get_raw_data(vbo, attr_id.nor, &nor_step);
2400 if (rdata->mapped.use == false) {
2401 float (*lnors)[3] = rdata->loop_normals;
2402 if (rdata->edit_bmesh) {
2403 GPUPackedNormal *pnors_pack, *vnors_pack;
2405 if (lnors == NULL) {
2406 mesh_render_data_ensure_poly_normals_pack(rdata);
2407 mesh_render_data_ensure_vert_normals_pack(rdata);
2409 pnors_pack = rdata->poly_normals_pack;
2410 vnors_pack = rdata->vert_normals_pack;
2413 for (int i = 0; i < tri_len; i++) {
2414 const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
2415 const BMFace *bm_face = bm_looptri[0]->f;
2417 /* use_hide always for edit-mode */
2418 if (BM_elem_flag_test(bm_face, BM_ELEM_HIDDEN)) {
2423 for (uint t = 0; t < 3; t++) {
2424 const float *nor = lnors[BM_elem_index_get(bm_looptri[t])];
2425 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor);
2428 else if (BM_elem_flag_test(bm_face, BM_ELEM_SMOOTH)) {
2429 for (uint t = 0; t < 3; t++) {
2430 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = vnors_pack[BM_elem_index_get(bm_looptri[t]->v)];
2434 const GPUPackedNormal *snor_pack = &pnors_pack[BM_elem_index_get(bm_face)];
2435 for (uint t = 0; t < 3; t++) {
2436 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *snor_pack;
2440 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
2441 if (rdata->edit_data && rdata->edit_data->vertexCos) {
2442 for (uint t = 0; t < 3; t++) {
2443 int vidx = BM_elem_index_get(bm_looptri[t]->v);
2444 const float *pos = rdata->edit_data->vertexCos[vidx];
2445 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), pos);
2449 for (uint t = 0; t < 3; t++) {
2450 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), bm_looptri[t]->v->co);
2456 if (lnors == NULL) {
2457 /* Use normals from vertex. */
2458 mesh_render_data_ensure_poly_normals_pack(rdata);
2461 for (int i = 0; i < tri_len; i++) {
2462 const MLoopTri *mlt = &rdata->mlooptri[i];
2463 const MPoly *mp = &rdata->mpoly[mlt->poly];
2465 if (use_hide && (mp->flag & ME_HIDE)) {
2469 const uint vtri[3] = {
2470 rdata->mloop[mlt->tri[0]].v,
2471 rdata->mloop[mlt->tri[1]].v,
2472 rdata->mloop[mlt->tri[2]].v,
2476 for (uint t = 0; t < 3; t++) {
2477 const float *nor = lnors[mlt->tri[t]];
2478 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor);
2481 else if (mp->flag & ME_SMOOTH) {
2482 for (uint t = 0; t < 3; t++) {
2483 const MVert *mv = &rdata->mvert[vtri[t]];
2484 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_s3(mv->no);
2488 const GPUPackedNormal *pnors_pack = &rdata->poly_normals_pack[mlt->poly];
2489 for (uint t = 0; t < 3; t++) {
2490 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *pnors_pack;
2494 for (uint t = 0; t < 3; t++) {
2495 const MVert *mv = &rdata->mvert[vtri[t]];
2496 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mv->co);
2502 /* Note: mapped doesn't support lnors yet. */
2503 BMesh *bm = rdata->edit_bmesh->bm;
2504 Mesh *me_cage = rdata->mapped.me_cage;
2506 /* TODO(campbell): unlike non-mapped modes we don't generate these on demand, just use if they exist.
2507 * this seems like a low priority TODO since mapped meshes typically
2508 * use the final mesh evaluated mesh for showing faces. */
2509 const float (*lnors)[3] = CustomData_get_layer(&me_cage->ldata, CD_NORMAL);
2511 /* TODO(campbell): this is quite an expensive operation for something
2512 * that's not used unless 'normal' display option is enabled. */
2513 if (!CustomData_has_layer(&me_cage->pdata, CD_NORMAL)) {
2514 /* TODO(campbell): this is quite an expensive operation for something
2515 * that's not used unless 'normal' display option is enabled. */
2516 BKE_mesh_ensure_normals_for_display(me_cage);
2518 const float (*polynors)[3] = CustomData_get_layer(&me_cage->pdata, CD_NORMAL);
2520 const MVert *mvert = rdata->mapped.me_cage->mvert;
2521 const MLoop *mloop = rdata->mapped.me_cage->mloop;
2522 const MPoly *mpoly = rdata->mapped.me_cage->mpoly;
2524 const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me_cage);
2525 for (int i = 0; i < tri_len; i++) {
2526 const MLoopTri *mlt = &mlooptri[i];
2527 const int p_orig = rdata->mapped.p_origindex[mlt->poly];
2528 if (p_orig != ORIGINDEX_NONE) {
2529 /* Assume 'use_hide' */
2530 BMFace *efa = BM_face_at_index(bm, p_orig);
2531 if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
2532 const MPoly *mp = &mpoly[mlt->poly];
2533 const uint vtri[3] = {
2534 mloop[mlt->tri[0]].v,
2535 mloop[mlt->tri[1]].v,
2536 mloop[mlt->tri[2]].v,
2540 for (uint t = 0; t < 3; t++) {
2541 const float *nor = lnors[mlt->tri[t]];
2542 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor);
2545 else if (mp->flag & ME_SMOOTH) {
2546 for (uint t = 0; t < 3; t++) {
2547 const MVert *mv = &mvert[vtri[t]];
2548 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_s3(mv->no);
2552 /* we don't have cached 'rdata->poly_normals_pack'. */
2553 const GPUPackedNormal pnor = GPU_normal_convert_i10_v3(polynors[mlt->poly]);
2554 for (uint t = 0; t < 3; t++) {
2555 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = pnor;
2559 for (uint t = 0; t < 3; t++) {
2560 const MVert *mv = &mvert[vtri[t]];
2561 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mv->co);
2568 vbo_len_used = GPU_vertbuf_raw_used(&pos_step);
2569 BLI_assert(vbo_len_used == GPU_vertbuf_raw_used(&nor_step));
2571 if (vbo_len_capacity != vbo_len_used) {
2572 GPU_vertbuf_data_resize(vbo, vbo_len_used);
2576 BLI_INLINE void mesh_edit_add_select_index(GPUVertBufRaw *buf, GPUVertCompType comp, uint index)
2578 /* We don't need to sanitize the value because the elements
2579 * with these undefined values will never get drawn. */
2582 *((uint *)GPU_vertbuf_raw_step(buf)) = index;
2585 *((ushort *)GPU_vertbuf_raw_step(buf)) = (ushort)index;
2588 *((uchar *)GPU_vertbuf_raw_step(buf)) = (uchar)index;
2596 #define SELECT_COMP_FORMAT(el_len) (el_len > 0xFF ? (el_len > 0xFFFF ? GPU_COMP_U32 : GPU_COMP_U16) : GPU_COMP_U8)
2598 static void mesh_create_edit_select_id(
2599 MeshRenderData *rdata,
2600 GPUVertBuf *vbo_pos, GPUVertBuf *vbo_verts, GPUVertBuf *vbo_edges, GPUVertBuf *vbo_faces)
2602 const int vert_len = mesh_render_data_verts_len_get_maybe_mapped(rdata);
2603 const int edge_len = mesh_render_data_edges_len_get_maybe_mapped(rdata);
2604 const int poly_len = mesh_render_data_polys_len_get_maybe_mapped(rdata);
2605 const int lvert_len = mesh_render_data_loose_verts_len_get_maybe_mapped(rdata);
2606 const int ledge_len = mesh_render_data_loose_edges_len_get_maybe_mapped(rdata);
2607 const int loop_len = mesh_render_data_loops_len_get_maybe_mapped(rdata);
2608 const int tot_loop_len = loop_len + ledge_len * 2 + lvert_len;
2610 /* Choose the most compact vertex format. */
2611 GPUVertCompType vert_comp = SELECT_COMP_FORMAT(vert_len);
2612 GPUVertCompType edge_comp = SELECT_COMP_FORMAT(edge_len);
2613 GPUVertCompType face_comp = SELECT_COMP_FORMAT(poly_len);
2615 GPUVertFormat format_vert = { 0 }, format_edge = { 0 }, format_face = { 0 }, format_pos = { 0 };
2616 struct { uint vert, edge, face, pos; } attr_id;
2617 attr_id.vert = GPU_vertformat_attr_add(&format_vert, "color", vert_comp, 1, GPU_FETCH_INT);
2618 attr_id.edge = GPU_vertformat_attr_add(&format_edge, "color", edge_comp, 1, GPU_FETCH_INT);
2619 attr_id.face = GPU_vertformat_attr_add(&format_face, "color", face_comp, 1, GPU_FETCH_INT);
2620 attr_id.pos = GPU_vertformat_attr_add(&format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
2622 GPUVertBufRaw raw_verts, raw_edges, raw_faces, raw_pos;
2623 if (DRW_TEST_ASSIGN_VBO(vbo_pos)) {
2624 GPU_vertbuf_init_with_format(vbo_pos, &format_pos);
2625 GPU_vertbuf_data_alloc(vbo_pos, tot_loop_len);
2626 GPU_vertbuf_attr_get_raw_data(vbo_pos, attr_id.pos, &raw_pos);
2628 if (DRW_TEST_ASSIGN_VBO(vbo_verts)) {
2629 GPU_vertbuf_init_with_format(vbo_verts, &format_vert);
2630 GPU_vertbuf_data_alloc(vbo_verts, tot_loop_len);
2631 GPU_vertbuf_attr_get_raw_data(vbo_verts, attr_id.vert, &raw_verts);
2633 if (DRW_TEST_ASSIGN_VBO(vbo_edges)) {
2634 GPU_vertbuf_init_with_format(vbo_edges, &format_edge);
2635 GPU_vertbuf_data_alloc(vbo_edges, tot_loop_len);
2636 GPU_vertbuf_attr_get_raw_data(vbo_edges, attr_id.edge, &raw_edges);
2638 if (DRW_TEST_ASSIGN_VBO(vbo_faces)) {
2639 GPU_vertbuf_init_with_format(vbo_faces, &format_face);
2640 GPU_vertbuf_data_alloc(vbo_faces, tot_loop_len);
2641 GPU_vertbuf_attr_get_raw_data(vbo_faces, attr_id.face, &raw_faces);
2644 if (rdata->edit_bmesh && rdata->mapped.use == false) {
2645 BMesh *bm = rdata->edit_bmesh->bm;
2646 BMIter iter_efa, iter_loop, iter_edge, iter_vert;
2653 BM_ITER_MESH (efa, &iter_efa, bm, BM_FACES_OF_MESH) {
2654 int fidx = BM_elem_index_get(efa);
2655 BM_ITER_ELEM (loop, &iter_loop, efa, BM_LOOPS_OF_FACE) {
2657 copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), loop->v->co);
2660 int vidx = BM_elem_index_get(loop->v);
2661 mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
2664 int eidx = BM_elem_index_get(loop->e);
2665 mesh_edit_add_select_index(&raw_edges, edge_comp, eidx);
2668 mesh_edit_add_select_index(&raw_faces, face_comp, fidx);
2673 BM_ITER_MESH (eed, &iter_edge, bm, BM_EDGES_OF_MESH) {
2674 if (eed->l != NULL) {
2677 BM_ITER_ELEM (eve, &iter_vert, eed, BM_VERTS_OF_EDGE) {
2679 copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), eve->co);
2682 int vidx = BM_elem_index_get(eve);
2683 mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
2686 int eidx = BM_elem_index_get(eed);
2687 mesh_edit_add_select_index(&raw_edges, edge_comp, eidx);
2692 BM_ITER_MESH (eve, &iter_vert, bm, BM_VERTS_OF_MESH) {
2693 if (eve->e != NULL) {
2697 copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), eve->co);
2700 int vidx = BM_elem_index_get(eve);
2701 mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
2705 else if (rdata->mapped.use == true) {
2706 const MPoly *mpoly = rdata->mapped.me_cage->mpoly;
2707 const MEdge *medge = rdata->mapped.me_cage->medge;
2708 const MVert *mvert = rdata->mapped.me_cage->mvert;
2709 const MLoop *mloop = rdata->mapped.me_cage->mloop;
2710 BMesh *bm = rdata->edit_bmesh->bm;
2712 const int *v_origindex = rdata->mapped.v_origindex;
2713 const int *e_origindex = rdata->mapped.e_origindex;
2714 const int *p_origindex = rdata->mapped.p_origindex;
2717 for (int poly = 0; poly < poly_len; poly++, mpoly++) {
2718 const MLoop *l = &mloop[mpoly->loopstart];
2719 int fidx = p_origindex[poly];
2720 for (int i = 0; i < mpoly->totloop; i++, l++) {
2722 copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert[l->v].co);
2725 int vidx = v_origindex[l->v];
2726 mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
2729 int eidx = e_origindex[l->e];
2730 mesh_edit_add_select_index(&raw_edges, edge_comp, eidx);
2733 mesh_edit_add_select_index(&raw_faces, face_comp, fidx);
2738 for (int e = 0; e < edge_len; e++, medge++) {
2739 int eidx = e_origindex[e];
2740 if (eidx != ORIGINDEX_NONE && (medge->flag & ME_LOOSEEDGE)) {
2741 for (int i = 0; i < 2; ++i) {
2742 int vidx = (i == 0) ? medge->v1 : medge->v2;
2744 copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert[vidx].co);
2747 mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
2750 mesh_edit_add_select_index(&raw_edges, edge_comp, eidx);
2756 for (int v = 0; v < vert_len; v++, mvert++) {
2757 int vidx = v_origindex[v];
2758 if (vidx != ORIGINDEX_NONE) {
2759 BMVert *eve = BM_vert_at_index(bm, vidx);
2760 if (eve->e == NULL) {
2762 copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert->co);
2765 mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
2772 const MPoly *mpoly = rdata->mpoly;
2773 const MVert *mvert = rdata->mvert;
2774 const MLoop *mloop = rdata->mloop;
2776 const int *v_origindex = CustomData_get_layer(&rdata->me->vdata, CD_ORIGINDEX);
2777 const int *e_origindex = CustomData_get_layer(&rdata->me->edata, CD_ORIGINDEX);
2778 const int *p_origindex = CustomData_get_layer(&rdata->me->pdata, CD_ORIGINDEX);
2781 for (int poly = 0; poly < poly_len; poly++, mpoly++) {
2782 const MLoop *l = &mloop[mpoly->loopstart];
2783 int fidx = p_origindex ? p_origindex[poly] : poly;
2784 for (int i = 0; i < mpoly->totloop; i++, l++) {
2786 copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert[l->v].co);
2789 int vidx = v_origindex ? v_origindex[l->v] : l->v;
2790 mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
2793 int eidx = e_origindex ? e_origindex[l->e] : l->e;
2794 mesh_edit_add_select_index(&raw_edges, edge_comp, eidx);
2797 mesh_edit_add_select_index(&raw_faces, face_comp, fidx);
2801 /* TODO(fclem): Until we find a way to detect
2802 * loose verts easily outside of edit mode, this
2803 * will remain disabled. */
2806 for (int e = 0; e < edge_len; e++, medge++) {
2807 int eidx = e_origindex[e];
2808 if (eidx != ORIGINDEX_NONE && (medge->flag & ME_LOOSEEDGE)) {
2809 for (int i = 0; i < 2; ++i) {
2810 int vidx = (i == 0) ? medge->v1 : medge->v2;
2812 copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert[vidx].co);
2815 mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
2818 mesh_edit_add_select_index(&raw_edges, edge_comp, eidx);
2824 for (int v = 0; v < vert_len; v++, mvert++) {
2825 int vidx = v_origindex[v];
2826 if (vidx != ORIGINDEX_NONE) {
2827 MVert *eve = BM_vert_at_index(bm, vidx);
2828 if (eve->e == NULL) {
2830 copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert->co);
2833 mesh_edit_add_select_index(&raw_verts, vert_comp, vidx);
2843 /* TODO: We could use gl_PrimitiveID as index instead of using another VBO. */
2844 static void mesh_create_edit_facedots_select_id(
2845 MeshRenderData *rdata,
2848 const int poly_len = mesh_render_data_polys_len_get_maybe_mapped(rdata);
2850 GPUVertCompType comp = SELECT_COMP_FORMAT(poly_len);
2852 GPUVertFormat format = { 0 };
2853 struct { uint idx; } attr_id;
2854 attr_id.idx = GPU_vertformat_attr_add(&format, "color", comp, 1, GPU_FETCH_INT);
2856 GPUVertBufRaw idx_step;
2857 GPU_vertbuf_init_with_format(vbo, &format);
2858 GPU_vertbuf_data_alloc(vbo, poly_len);
2859 GPU_vertbuf_attr_get_raw_data(vbo, attr_id.idx, &idx_step);
2861 /* Keep in sync with mesh_create_edit_facedots(). */
2862 if (rdata->mapped.use == false) {
2863 if (rdata->edit_bmesh) {
2864 for (int poly = 0; poly < poly_len; poly++) {
2865 const BMFace *efa = BM_face_at_index(rdata->edit_bmesh->bm, poly);
2866 if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
2867 mesh_edit_add_select_index(&idx_step, comp, poly);