Differential D14365 Diff 59272 source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
| /* SPDX-License-Identifier: GPL-2.0-or-later | /* SPDX-License-Identifier: GPL-2.0-or-later | ||||
| * Copyright 2021 Blender Foundation. All rights reserved. */ | * Copyright 2021 Blender Foundation. All rights reserved. */ | ||||
| /** \file | /** \file | ||||
| * \ingroup draw | * \ingroup draw | ||||
| */ | */ | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BLI_math_vector_types.hh" | |||||
| #include "extract_mesh.hh" | #include "extract_mesh.hh" | ||||
| #include "draw_subdivision.h" | #include "draw_subdivision.h" | ||||
| namespace blender::draw { | namespace blender::draw { | ||||
| /* ---------------------------------------------------------------------- */ | /* ---------------------------------------------------------------------- */ | ||||
| /** \name Extract Edit UV angle stretch | /** \name Extract Edit UV angle stretch | ||||
| * \{ */ | * \{ */ | ||||
| struct UVStretchAngle { | struct UVStretchAngle { | ||||
| int16_t angle; | int16_t angle; | ||||
| int16_t uv_angles[2]; | int16_t uv_angles[2]; | ||||
| }; | }; | ||||
| struct MeshExtract_StretchAngle_Data { | struct MeshExtract_StretchAngle_Data { | ||||
| UVStretchAngle *vbo_data; | UVStretchAngle *vbo_data; | ||||
| const MLoopUV *luv; | const float2 *uv; | ||||
| float auv[2][2], last_auv[2]; | float auv[2][2], last_auv[2]; | ||||
| float av[2][3], last_av[3]; | float av[2][3], last_av[3]; | ||||
| int cd_ofs; | int cd_ofs; | ||||
| }; | }; | ||||
| static void compute_normalize_edge_vectors(float auv[2][2], | static void compute_normalize_edge_vectors(float auv[2][2], | ||||
| float av[2][3], | float av[2][3], | ||||
| const float uv[2], | const float uv[2], | ||||
| ▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | static void extract_edituv_stretch_angle_init(const MeshRenderData *mr, | ||||
| GPU_vertbuf_init_with_format(vbo, &format); | GPU_vertbuf_init_with_format(vbo, &format); | ||||
| GPU_vertbuf_data_alloc(vbo, mr->loop_len); | GPU_vertbuf_data_alloc(vbo, mr->loop_len); | ||||
| MeshExtract_StretchAngle_Data *data = static_cast<MeshExtract_StretchAngle_Data *>(tls_data); | MeshExtract_StretchAngle_Data *data = static_cast<MeshExtract_StretchAngle_Data *>(tls_data); | ||||
| data->vbo_data = (UVStretchAngle *)GPU_vertbuf_get_data(vbo); | data->vbo_data = (UVStretchAngle *)GPU_vertbuf_get_data(vbo); | ||||
| /* Special iterator needed to save about half of the computing cost. */ | /* Special iterator needed to save about half of the computing cost. */ | ||||
| if (mr->extract_type == MR_EXTRACT_BMESH) { | if (mr->extract_type == MR_EXTRACT_BMESH) { | ||||
| data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_MLOOPUV); | data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_PROP_FLOAT2); | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_assert(mr->extract_type == MR_EXTRACT_MESH); | BLI_assert(mr->extract_type == MR_EXTRACT_MESH); | ||||
| data->luv = (const MLoopUV *)CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV); | data->uv = (const float2 *)CustomData_get_layer(&mr->me->ldata, CD_PROP_FLOAT2); | ||||
| } | } | ||||
| } | } | ||||
| static void extract_edituv_stretch_angle_iter_poly_bm(const MeshRenderData *mr, | static void extract_edituv_stretch_angle_iter_poly_bm(const MeshRenderData *mr, | ||||
| const BMFace *f, | const BMFace *f, | ||||
| const int /*f_index*/, | const int /*f_index*/, | ||||
| void *_data) | void *_data) | ||||
| { | { | ||||
| MeshExtract_StretchAngle_Data *data = static_cast<MeshExtract_StretchAngle_Data *>(_data); | MeshExtract_StretchAngle_Data *data = static_cast<MeshExtract_StretchAngle_Data *>(_data); | ||||
| float(*auv)[2] = data->auv, *last_auv = data->last_auv; | float(*auv)[2] = data->auv, *last_auv = data->last_auv; | ||||
| float(*av)[3] = data->av, *last_av = data->last_av; | float(*av)[3] = data->av, *last_av = data->last_av; | ||||
| BMLoop *l_iter, *l_first; | BMLoop *l_iter, *l_first; | ||||
| l_iter = l_first = BM_FACE_FIRST_LOOP(f); | l_iter = l_first = BM_FACE_FIRST_LOOP(f); | ||||
| do { | do { | ||||
| const int l_index = BM_elem_index_get(l_iter); | const int l_index = BM_elem_index_get(l_iter); | ||||
| const MLoopUV *luv, *luv_next; | const float(*luv)[2], (*luv_next)[2]; | ||||
| BMLoop *l_next = l_iter->next; | BMLoop *l_next = l_iter->next; | ||||
| if (l_iter == BM_FACE_FIRST_LOOP(f)) { | if (l_iter == BM_FACE_FIRST_LOOP(f)) { | ||||
| /* First loop in face. */ | /* First loop in face. */ | ||||
| BMLoop *l_tmp = l_iter->prev; | BMLoop *l_tmp = l_iter->prev; | ||||
| BMLoop *l_next_tmp = l_iter; | BMLoop *l_next_tmp = l_iter; | ||||
| luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_tmp, data->cd_ofs); | luv = BM_ELEM_CD_GET_FLOAT2_P(l_tmp, data->cd_ofs); | ||||
| luv_next = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_next_tmp, data->cd_ofs); | luv_next = BM_ELEM_CD_GET_FLOAT2_P(l_next_tmp, data->cd_ofs); | ||||
| compute_normalize_edge_vectors(auv, | compute_normalize_edge_vectors(auv, | ||||
| av, | av, | ||||
| luv->uv, | *luv, | ||||
| luv_next->uv, | *luv_next, | ||||
| bm_vert_co_get(mr, l_tmp->v), | bm_vert_co_get(mr, l_tmp->v), | ||||
| bm_vert_co_get(mr, l_next_tmp->v)); | bm_vert_co_get(mr, l_next_tmp->v)); | ||||
| /* Save last edge. */ | /* Save last edge. */ | ||||
| copy_v2_v2(last_auv, auv[1]); | copy_v2_v2(last_auv, auv[1]); | ||||
| copy_v3_v3(last_av, av[1]); | copy_v3_v3(last_av, av[1]); | ||||
| } | } | ||||
| if (l_next == BM_FACE_FIRST_LOOP(f)) { | if (l_next == BM_FACE_FIRST_LOOP(f)) { | ||||
| /* Move previous edge. */ | /* Move previous edge. */ | ||||
| copy_v2_v2(auv[0], auv[1]); | copy_v2_v2(auv[0], auv[1]); | ||||
| copy_v3_v3(av[0], av[1]); | copy_v3_v3(av[0], av[1]); | ||||
| /* Copy already calculated last edge. */ | /* Copy already calculated last edge. */ | ||||
| copy_v2_v2(auv[1], last_auv); | copy_v2_v2(auv[1], last_auv); | ||||
| copy_v3_v3(av[1], last_av); | copy_v3_v3(av[1], last_av); | ||||
| } | } | ||||
| else { | else { | ||||
| luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, data->cd_ofs); | luv = BM_ELEM_CD_GET_FLOAT2_P(l_iter, data->cd_ofs); | ||||
| luv_next = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_next, data->cd_ofs); | luv_next = BM_ELEM_CD_GET_FLOAT2_P(l_next, data->cd_ofs); | ||||
| compute_normalize_edge_vectors(auv, | compute_normalize_edge_vectors( | ||||
| av, | auv, av, *luv, *luv_next, bm_vert_co_get(mr, l_iter->v), bm_vert_co_get(mr, l_next->v)); | ||||
| luv->uv, | |||||
| luv_next->uv, | |||||
| bm_vert_co_get(mr, l_iter->v), | |||||
| bm_vert_co_get(mr, l_next->v)); | |||||
| } | } | ||||
| edituv_get_edituv_stretch_angle(auv, av, &data->vbo_data[l_index]); | edituv_get_edituv_stretch_angle(auv, av, &data->vbo_data[l_index]); | ||||
| } while ((l_iter = l_iter->next) != l_first); | } while ((l_iter = l_iter->next) != l_first); | ||||
| } | } | ||||
| static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr, | static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr, | ||||
| const MPoly *mp, | const MPoly *mp, | ||||
| const int /*mp_index*/, | const int /*mp_index*/, | ||||
| void *_data) | void *_data) | ||||
| { | { | ||||
| MeshExtract_StretchAngle_Data *data = static_cast<MeshExtract_StretchAngle_Data *>(_data); | MeshExtract_StretchAngle_Data *data = static_cast<MeshExtract_StretchAngle_Data *>(_data); | ||||
| const int ml_index_end = mp->loopstart + mp->totloop; | const int ml_index_end = mp->loopstart + mp->totloop; | ||||
| for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) { | for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) { | ||||
| float(*auv)[2] = data->auv, *last_auv = data->last_auv; | float(*auv)[2] = data->auv, *last_auv = data->last_auv; | ||||
| float(*av)[3] = data->av, *last_av = data->last_av; | float(*av)[3] = data->av, *last_av = data->last_av; | ||||
| int l_next = ml_index + 1; | int l_next = ml_index + 1; | ||||
| if (ml_index == mp->loopstart) { | if (ml_index == mp->loopstart) { | ||||
| /* First loop in face. */ | /* First loop in face. */ | ||||
| const int ml_index_last = ml_index_end - 1; | const int ml_index_last = ml_index_end - 1; | ||||
| const int l_next_tmp = mp->loopstart; | const int l_next_tmp = mp->loopstart; | ||||
| compute_normalize_edge_vectors(auv, | compute_normalize_edge_vectors(auv, | ||||
| av, | av, | ||||
| data->luv[ml_index_last].uv, | data->uv[ml_index_last], | ||||
| data->luv[l_next_tmp].uv, | data->uv[l_next_tmp], | ||||
| mr->vert_positions[mr->mloop[ml_index_last].v], | mr->vert_positions[mr->mloop[ml_index_last].v], | ||||
| mr->vert_positions[mr->mloop[l_next_tmp].v]); | mr->vert_positions[mr->mloop[l_next_tmp].v]); | ||||
| /* Save last edge. */ | /* Save last edge. */ | ||||
| copy_v2_v2(last_auv, auv[1]); | copy_v2_v2(last_auv, auv[1]); | ||||
| copy_v3_v3(last_av, av[1]); | copy_v3_v3(last_av, av[1]); | ||||
| } | } | ||||
| if (l_next == ml_index_end) { | if (l_next == ml_index_end) { | ||||
| l_next = mp->loopstart; | l_next = mp->loopstart; | ||||
| /* Move previous edge. */ | /* Move previous edge. */ | ||||
| copy_v2_v2(auv[0], auv[1]); | copy_v2_v2(auv[0], auv[1]); | ||||
| copy_v3_v3(av[0], av[1]); | copy_v3_v3(av[0], av[1]); | ||||
| /* Copy already calculated last edge. */ | /* Copy already calculated last edge. */ | ||||
| copy_v2_v2(auv[1], last_auv); | copy_v2_v2(auv[1], last_auv); | ||||
| copy_v3_v3(av[1], last_av); | copy_v3_v3(av[1], last_av); | ||||
| } | } | ||||
| else { | else { | ||||
| compute_normalize_edge_vectors(auv, | compute_normalize_edge_vectors(auv, | ||||
| av, | av, | ||||
| data->luv[ml_index].uv, | data->uv[ml_index], | ||||
| data->luv[l_next].uv, | data->uv[l_next], | ||||
| mr->vert_positions[mr->mloop[ml_index].v], | mr->vert_positions[mr->mloop[ml_index].v], | ||||
| mr->vert_positions[mr->mloop[l_next].v]); | mr->vert_positions[mr->mloop[l_next].v]); | ||||
| } | } | ||||
| edituv_get_edituv_stretch_angle(auv, av, &data->vbo_data[ml_index]); | edituv_get_edituv_stretch_angle(auv, av, &data->vbo_data[ml_index]); | ||||
| } | } | ||||
| } | } | ||||
| static GPUVertFormat *get_edituv_stretch_angle_format_subdiv() | static GPUVertFormat *get_edituv_stretch_angle_format_subdiv() | ||||
| Show All 38 Lines | static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache *subdiv_cache, | ||||
| /* UVs are stored contiguously so we need to compute the offset in the UVs buffer for the active | /* UVs are stored contiguously so we need to compute the offset in the UVs buffer for the active | ||||
| * UV layer. */ | * UV layer. */ | ||||
| CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_MESH) ? &mr->me->ldata : &mr->bm->ldata; | CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_MESH) ? &mr->me->ldata : &mr->bm->ldata; | ||||
| uint32_t uv_layers = cache->cd_used.uv; | uint32_t uv_layers = cache->cd_used.uv; | ||||
| /* HACK to fix T68857 */ | /* HACK to fix T68857 */ | ||||
| if (mr->extract_type == MR_EXTRACT_BMESH && cache->cd_used.edit_uv == 1) { | if (mr->extract_type == MR_EXTRACT_BMESH && cache->cd_used.edit_uv == 1) { | ||||
| int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV); | int layer = CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2); | ||||
| if (layer != -1) { | if (layer != -1) { | ||||
| uv_layers |= (1 << layer); | uv_layers |= (1 << layer); | ||||
| } | } | ||||
| } | } | ||||
| int uvs_offset = 0; | int uvs_offset = 0; | ||||
| for (int i = 0; i < MAX_MTFACE; i++) { | for (int i = 0; i < MAX_MTFACE; i++) { | ||||
| if (uv_layers & (1 << i)) { | if (uv_layers & (1 << i)) { | ||||
| if (i == CustomData_get_active_layer(cd_ldata, CD_MLOOPUV)) { | if (i == CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2)) { | ||||
| break; | break; | ||||
| } | } | ||||
| uvs_offset += 1; | uvs_offset += 1; | ||||
| } | } | ||||
| } | } | ||||
| /* The data is at `offset * num loops`, and we have 2 values per index. */ | /* The data is at `offset * num loops`, and we have 2 values per index. */ | ||||
| Show All 30 Lines | |||||