diff options
author | Lukas Stockner <lukas.stockner@freenet.de> | 2022-10-30 00:41:21 +0300 |
---|---|---|
committer | Lukas Stockner <lukas.stockner@freenet.de> | 2022-10-30 01:14:59 +0300 |
commit | bc37e8d8399eef686b71341aa90eced9bc117786 (patch) | |
tree | 92e4af388150209df9bc44e2cba6f2f303aa7baf /source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc | |
parent | 552abb838c76d44a0d7d1226b59a1ab381e88386 (diff) | |
parent | d1d2f002c7caaf4ab457ec27bbc44666d7aac624 (diff) |
Merge remote-tracking branch 'origin/master' into principled-v2
Diffstat (limited to 'source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc')
-rw-r--r-- | source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc | 161 |
1 files changed, 92 insertions, 69 deletions
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc index 77cbb5efa12..f606701ed09 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc @@ -14,9 +14,11 @@ #include "BLI_math.h" #include "BLI_task.h" +#include "BKE_attribute.hh" #include "BKE_editmesh.h" #include "BKE_editmesh_cache.h" #include "BKE_mesh.h" +#include "BKE_mesh_runtime.h" #include "GPU_batch.h" @@ -228,10 +230,10 @@ static void mesh_render_data_polys_sorted_build(MeshRenderData *mr, MeshBufferCa } } else { - const MPoly *mp = &mr->mpoly[0]; - for (int i = 0; i < mr->poly_len; i++, mp++) { - if (!(mr->use_hide && (mp->flag & ME_HIDE))) { - const int mat = min_ii(mp->mat_nr, mat_last); + for (int i = 0; i < mr->poly_len; i++) { + if (!(mr->use_hide && mr->hide_poly && mr->hide_poly[i])) { + const MPoly *mp = &mr->mpoly[i]; + const int mat = min_ii(mr->material_indices ? mr->material_indices[i] : 0, mat_last); tri_first_index[i] = mat_tri_offs[mat]; mat_tri_offs[mat] += mp->totloop - 2; } @@ -269,8 +271,8 @@ static void mesh_render_data_mat_tri_len_mesh_range_fn(void *__restrict userdata int *mat_tri_len = static_cast<int *>(tls->userdata_chunk); const MPoly *mp = &mr->mpoly[iter]; - if (!(mr->use_hide && (mp->flag & ME_HIDE))) { - int mat = min_ii(mp->mat_nr, mr->mat_len - 1); + if (!(mr->use_hide && mr->hide_poly && mr->hide_poly[iter])) { + int mat = min_ii(mr->material_indices ? mr->material_indices[iter] : 0, mr->mat_len - 1); mat_tri_len[mat] += mp->totloop - 2; } } @@ -328,28 +330,10 @@ void mesh_render_data_update_looptris(MeshRenderData *mr, const eMRIterType iter_type, const eMRDataType data_flag) { - Mesh *me = mr->me; if (mr->extract_type != MR_EXTRACT_BMESH) { /* Mesh */ if ((iter_type & MR_ITER_LOOPTRI) || (data_flag & MR_DATA_LOOPTRI)) { - /* NOTE(campbell): It's possible to skip allocating tessellation, - * the tessellation can be calculated as part of the iterator, see: P2188. - * The overall advantage is small (around 1%), so keep this as-is. */ - mr->mlooptri = static_cast<MLoopTri *>( - MEM_mallocN(sizeof(*mr->mlooptri) * mr->tri_len, "MR_DATATYPE_LOOPTRI")); - if (mr->poly_normals != nullptr) { - BKE_mesh_recalc_looptri_with_normals(me->mloop, - me->mpoly, - me->mvert, - me->totloop, - me->totpoly, - mr->mlooptri, - mr->poly_normals); - } - else { - BKE_mesh_recalc_looptri( - me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mr->mlooptri); - } + mr->mlooptri = BKE_mesh_runtime_looptri_ensure(mr->me); } } else { @@ -365,7 +349,7 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_ { Mesh *me = mr->me; const bool is_auto_smooth = (me->flag & ME_AUTOSMOOTH) != 0; - const float split_angle = is_auto_smooth ? me->smoothresh : (float)M_PI; + const float split_angle = is_auto_smooth ? me->smoothresh : float(M_PI); if (mr->extract_type != MR_EXTRACT_BMESH) { /* Mesh */ @@ -378,15 +362,15 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_ MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__)); short(*clnors)[2] = static_cast<short(*)[2]>( CustomData_get_layer(&mr->me->ldata, CD_CUSTOMLOOPNORMAL)); - BKE_mesh_normals_loop_split(mr->me->mvert, + BKE_mesh_normals_loop_split(mr->mvert, mr->vert_normals, mr->vert_len, - mr->me->medge, + mr->medge, mr->edge_len, - mr->me->mloop, + mr->mloop, mr->loop_normals, mr->loop_len, - mr->me->mpoly, + mr->mpoly, mr->poly_normals, mr->poly_len, is_auto_smooth, @@ -431,6 +415,30 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_ } } +static void retrieve_active_attribute_names(MeshRenderData &mr, + const Object &object, + const Mesh &mesh) +{ + const Mesh *mesh_final = editmesh_final_or_this(&object, &mesh); + const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(mesh_final); + const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(mesh_final); + + /* Necessary because which attributes are active/default is stored in #CustomData. */ + Mesh me_query = blender::dna::shallow_zero_initialize(); + BKE_id_attribute_copy_domains_temp( + ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id); + + mr.active_color_name = nullptr; + mr.default_color_name = nullptr; + + if (const CustomDataLayer *active = BKE_id_attributes_active_color_get(&me_query.id)) { + mr.active_color_name = active->name; + } + if (const CustomDataLayer *render = BKE_id_attributes_render_color_get(&me_query.id)) { + mr.default_color_name = render->name; + } +} + MeshRenderData *mesh_render_data_create(Object *object, Mesh *me, const bool is_editmode, @@ -455,7 +463,7 @@ MeshRenderData *mesh_render_data_create(Object *object, mr->bm = me->edit_mesh->bm; mr->edit_bmesh = me->edit_mesh; mr->me = (do_final) ? editmesh_eval_final : editmesh_eval_cage; - mr->edit_data = is_mode_active ? mr->me->runtime.edit_data : nullptr; + mr->edit_data = is_mode_active ? mr->me->runtime->edit_data : nullptr; if (mr->edit_data) { EditMeshData *emd = mr->edit_data; @@ -470,17 +478,6 @@ MeshRenderData *mesh_render_data_create(Object *object, mr->bm_poly_centers = mr->edit_data->polyCos; } - /* A subdivision wrapper may be created in edit mode when X-ray is turned on to ensure that the - * topology seen by the user matches the one used for the selection routines. This wrapper - * seemingly takes precedence over the MDATA one, however the mesh we use for rendering is not - * the subdivided one, but the one where the MDATA wrapper would have been added. So consider - * the subdivision wrapper as well for the `has_mdata` case. */ - bool has_mdata = is_mode_active && ELEM(mr->me->runtime.wrapper_type, - ME_WRAPPER_TYPE_MDATA, - ME_WRAPPER_TYPE_SUBD); - bool use_mapped = is_mode_active && - (has_mdata && !do_uvedit && mr->me && !mr->me->runtime.is_original); - int bm_ensure_types = BM_VERT | BM_EDGE | BM_LOOP | BM_FACE; BM_mesh_elem_index_ensure(mr->bm, bm_ensure_types); @@ -499,43 +496,51 @@ MeshRenderData *mesh_render_data_create(Object *object, mr->freestyle_face_ofs = CustomData_get_offset(&mr->bm->pdata, CD_FREESTYLE_FACE); #endif - if (use_mapped) { - mr->v_origindex = static_cast<const int *>( - CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX)); - mr->e_origindex = static_cast<const int *>( - CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX)); - mr->p_origindex = static_cast<const int *>( - CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX)); - - use_mapped = (mr->v_origindex || mr->e_origindex || mr->p_origindex); + /* Use bmesh directly when the object is in edit mode unchanged by any modifiers. + * For non-final UVs, always use original bmesh since the UV editor does not support + * using the cage mesh with deformed coordinates. */ + if ((is_mode_active && mr->me->runtime->is_original_bmesh && + mr->me->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) || + (do_uvedit && !do_final)) { + mr->extract_type = MR_EXTRACT_BMESH; } - - mr->extract_type = use_mapped ? MR_EXTRACT_MAPPED : MR_EXTRACT_BMESH; - - /* Seems like the mesh_eval_final do not have the right origin indices. - * Force not mapped in this case. */ - if (use_mapped && do_final && editmesh_eval_final != editmesh_eval_cage) { - // mr->edit_bmesh = nullptr; + else { mr->extract_type = MR_EXTRACT_MESH; + + /* Use mapping from final to original mesh when the object is in edit mode. */ + if (is_mode_active && do_final) { + mr->v_origindex = static_cast<const int *>( + CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX)); + mr->e_origindex = static_cast<const int *>( + CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX)); + mr->p_origindex = static_cast<const int *>( + CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX)); + } + else { + mr->v_origindex = nullptr; + mr->e_origindex = nullptr; + mr->p_origindex = nullptr; + } } } else { mr->me = me; mr->edit_bmesh = nullptr; + mr->extract_type = MR_EXTRACT_MESH; - bool use_mapped = is_paint_mode && mr->me && !mr->me->runtime.is_original; - if (use_mapped) { + if (is_paint_mode && mr->me) { mr->v_origindex = static_cast<const int *>( CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX)); mr->e_origindex = static_cast<const int *>( CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX)); mr->p_origindex = static_cast<const int *>( CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX)); - - use_mapped = (mr->v_origindex || mr->e_origindex || mr->p_origindex); } - - mr->extract_type = use_mapped ? MR_EXTRACT_MAPPED : MR_EXTRACT_MESH; + else { + mr->v_origindex = nullptr; + mr->e_origindex = nullptr; + mr->p_origindex = nullptr; + } } if (mr->extract_type != MR_EXTRACT_BMESH) { @@ -546,14 +551,31 @@ MeshRenderData *mesh_render_data_create(Object *object, mr->poly_len = mr->me->totpoly; mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len); - mr->mvert = static_cast<MVert *>(CustomData_get_layer(&mr->me->vdata, CD_MVERT)); - mr->medge = static_cast<MEdge *>(CustomData_get_layer(&mr->me->edata, CD_MEDGE)); - mr->mloop = static_cast<MLoop *>(CustomData_get_layer(&mr->me->ldata, CD_MLOOP)); - mr->mpoly = static_cast<MPoly *>(CustomData_get_layer(&mr->me->pdata, CD_MPOLY)); + mr->mvert = BKE_mesh_verts(mr->me); + mr->medge = BKE_mesh_edges(mr->me); + mr->mpoly = BKE_mesh_polys(mr->me); + mr->mloop = BKE_mesh_loops(mr->me); mr->v_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX)); mr->e_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX)); mr->p_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX)); + + mr->material_indices = static_cast<const int *>( + CustomData_get_layer_named(&me->pdata, CD_PROP_INT32, "material_index")); + + mr->hide_vert = static_cast<const bool *>( + CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".hide_vert")); + mr->hide_edge = static_cast<const bool *>( + CustomData_get_layer_named(&me->edata, CD_PROP_BOOL, ".hide_edge")); + mr->hide_poly = static_cast<const bool *>( + CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".hide_poly")); + + mr->select_vert = static_cast<const bool *>( + CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".select_vert")); + mr->select_edge = static_cast<const bool *>( + CustomData_get_layer_named(&me->edata, CD_PROP_BOOL, ".select_edge")); + mr->select_poly = static_cast<const bool *>( + CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".select_poly")); } else { /* #BMesh */ @@ -566,12 +588,13 @@ MeshRenderData *mesh_render_data_create(Object *object, mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len); } + retrieve_active_attribute_names(*mr, *object, *me); + return mr; } void mesh_render_data_free(MeshRenderData *mr) { - MEM_SAFE_FREE(mr->mlooptri); MEM_SAFE_FREE(mr->loop_normals); /* Loose geometry are owned by #MeshBufferCache. */ |