Differential D14365 Diff 59272 source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc
Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc
| Show All 13 Lines | |||||
| namespace blender::draw { | namespace blender::draw { | ||||
| /* ---------------------------------------------------------------------- */ | /* ---------------------------------------------------------------------- */ | ||||
| /** \name Extract Edit UV Data / Flags | /** \name Extract Edit UV Data / Flags | ||||
| * \{ */ | * \{ */ | ||||
| struct MeshExtract_EditUVData_Data { | struct MeshExtract_EditUVData_Data { | ||||
| EditLoopData *vbo_data; | EditLoopData *vbo_data; | ||||
| int cd_ofs; | BMUVOffsets offsets; | ||||
| }; | }; | ||||
| static void extract_edituv_data_init_common(const MeshRenderData *mr, | static void extract_edituv_data_init_common(const MeshRenderData *mr, | ||||
| GPUVertBuf *vbo, | GPUVertBuf *vbo, | ||||
| MeshExtract_EditUVData_Data *data, | MeshExtract_EditUVData_Data *data, | ||||
| uint loop_len) | uint loop_len) | ||||
| { | { | ||||
| static GPUVertFormat format = {0}; | static GPUVertFormat format = {0}; | ||||
| if (format.attr_len == 0) { | if (format.attr_len == 0) { | ||||
| /* WARNING: Adjust #EditLoopData struct accordingly. */ | /* WARNING: Adjust #EditLoopData struct accordingly. */ | ||||
| GPU_vertformat_attr_add(&format, "data", GPU_COMP_U8, 4, GPU_FETCH_INT); | GPU_vertformat_attr_add(&format, "data", GPU_COMP_U8, 4, GPU_FETCH_INT); | ||||
| GPU_vertformat_alias_add(&format, "flag"); | GPU_vertformat_alias_add(&format, "flag"); | ||||
| } | } | ||||
| GPU_vertbuf_init_with_format(vbo, &format); | GPU_vertbuf_init_with_format(vbo, &format); | ||||
| GPU_vertbuf_data_alloc(vbo, loop_len); | GPU_vertbuf_data_alloc(vbo, loop_len); | ||||
| CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata; | |||||
| data->vbo_data = (EditLoopData *)GPU_vertbuf_get_data(vbo); | data->vbo_data = (EditLoopData *)GPU_vertbuf_get_data(vbo); | ||||
| data->cd_ofs = CustomData_get_offset(cd_ldata, CD_MLOOPUV); | data->offsets = BM_uv_map_get_offsets(mr->bm); | ||||
| } | } | ||||
| static void extract_edituv_data_init(const MeshRenderData *mr, | static void extract_edituv_data_init(const MeshRenderData *mr, | ||||
| MeshBatchCache * /*cache*/, | MeshBatchCache * /*cache*/, | ||||
| void *buf, | void *buf, | ||||
| void *tls_data) | void *tls_data) | ||||
| { | { | ||||
| GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf); | GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf); | ||||
| MeshExtract_EditUVData_Data *data = static_cast<MeshExtract_EditUVData_Data *>(tls_data); | MeshExtract_EditUVData_Data *data = static_cast<MeshExtract_EditUVData_Data *>(tls_data); | ||||
| extract_edituv_data_init_common(mr, vbo, data, mr->loop_len); | extract_edituv_data_init_common(mr, vbo, data, mr->loop_len); | ||||
| } | } | ||||
| static void extract_edituv_data_iter_poly_bm(const MeshRenderData *mr, | static void extract_edituv_data_iter_poly_bm(const MeshRenderData *mr, | ||||
| const BMFace *f, | const BMFace *f, | ||||
| const int /*f_index*/, | const int /*f_index*/, | ||||
| void *_data) | void *_data) | ||||
| { | { | ||||
| 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); | ||||
| MeshExtract_EditUVData_Data *data = static_cast<MeshExtract_EditUVData_Data *>(_data); | MeshExtract_EditUVData_Data *data = static_cast<MeshExtract_EditUVData_Data *>(_data); | ||||
| EditLoopData *eldata = &data->vbo_data[l_index]; | EditLoopData *eldata = &data->vbo_data[l_index]; | ||||
| memset(eldata, 0x0, sizeof(*eldata)); | memset(eldata, 0x0, sizeof(*eldata)); | ||||
| mesh_render_data_loop_flag(mr, l_iter, data->cd_ofs, eldata); | mesh_render_data_loop_flag(mr, l_iter, data->offsets, eldata); | ||||
| mesh_render_data_face_flag(mr, f, data->cd_ofs, eldata); | mesh_render_data_face_flag(mr, f, data->offsets, eldata); | ||||
| mesh_render_data_loop_edge_flag(mr, l_iter, data->cd_ofs, eldata); | mesh_render_data_loop_edge_flag(mr, l_iter, data->offsets, eldata); | ||||
| } while ((l_iter = l_iter->next) != l_first); | } while ((l_iter = l_iter->next) != l_first); | ||||
| } | } | ||||
| static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr, | static void extract_edituv_data_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_EditUVData_Data *data = static_cast<MeshExtract_EditUVData_Data *>(_data); | MeshExtract_EditUVData_Data *data = static_cast<MeshExtract_EditUVData_Data *>(_data); | ||||
| const MLoop *mloop = mr->mloop; | const MLoop *mloop = mr->mloop; | ||||
| 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) { | ||||
| const MLoop *ml = &mloop[ml_index]; | const MLoop *ml = &mloop[ml_index]; | ||||
| EditLoopData *eldata = &data->vbo_data[ml_index]; | EditLoopData *eldata = &data->vbo_data[ml_index]; | ||||
| memset(eldata, 0x0, sizeof(*eldata)); | memset(eldata, 0x0, sizeof(*eldata)); | ||||
| BMFace *efa = bm_original_face_get(mr, mp_index); | BMFace *efa = bm_original_face_get(mr, mp_index); | ||||
| if (efa) { | if (efa) { | ||||
| BMEdge *eed = bm_original_edge_get(mr, ml->e); | BMEdge *eed = bm_original_edge_get(mr, ml->e); | ||||
| BMVert *eve = bm_original_vert_get(mr, ml->v); | BMVert *eve = bm_original_vert_get(mr, ml->v); | ||||
| if (eed && eve) { | if (eed && eve) { | ||||
| /* Loop on an edge endpoint. */ | /* Loop on an edge endpoint. */ | ||||
| BMLoop *l = BM_face_edge_share_loop(efa, eed); | BMLoop *l = BM_face_edge_share_loop(efa, eed); | ||||
| mesh_render_data_loop_flag(mr, l, data->cd_ofs, eldata); | mesh_render_data_loop_flag(mr, l, data->offsets, eldata); | ||||
| mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, eldata); | mesh_render_data_loop_edge_flag(mr, l, data->offsets, eldata); | ||||
| } | } | ||||
| else { | else { | ||||
| if (eed == nullptr) { | if (eed == nullptr) { | ||||
| /* Find if the loop's vert is not part of an edit edge. | /* Find if the loop's vert is not part of an edit edge. | ||||
| * For this, we check if the previous loop was on an edge. */ | * For this, we check if the previous loop was on an edge. */ | ||||
| const int ml_index_last = mp->loopstart + mp->totloop - 1; | const int ml_index_last = mp->loopstart + mp->totloop - 1; | ||||
| const int l_prev = (ml_index == mp->loopstart) ? ml_index_last : (ml_index - 1); | const int l_prev = (ml_index == mp->loopstart) ? ml_index_last : (ml_index - 1); | ||||
| const MLoop *ml_prev = &mr->mloop[l_prev]; | const MLoop *ml_prev = &mr->mloop[l_prev]; | ||||
| eed = bm_original_edge_get(mr, ml_prev->e); | eed = bm_original_edge_get(mr, ml_prev->e); | ||||
| } | } | ||||
| if (eed) { | if (eed) { | ||||
| /* Mapped points on an edge between two edit verts. */ | /* Mapped points on an edge between two edit verts. */ | ||||
| BMLoop *l = BM_face_edge_share_loop(efa, eed); | BMLoop *l = BM_face_edge_share_loop(efa, eed); | ||||
| mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, eldata); | mesh_render_data_loop_edge_flag(mr, l, data->offsets, eldata); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void extract_edituv_data_init_subdiv(const DRWSubdivCache *subdiv_cache, | static void extract_edituv_data_init_subdiv(const DRWSubdivCache *subdiv_cache, | ||||
| const MeshRenderData *mr, | const MeshRenderData *mr, | ||||
| Show All 24 Lines | for (uint i = start_loop_idx; i < end_loop_idx; i++) { | ||||
| EditLoopData *edit_loop_data = &data->vbo_data[i]; | EditLoopData *edit_loop_data = &data->vbo_data[i]; | ||||
| memset(edit_loop_data, 0, sizeof(EditLoopData)); | memset(edit_loop_data, 0, sizeof(EditLoopData)); | ||||
| if (vert_origindex != -1 && edge_origindex != -1) { | if (vert_origindex != -1 && edge_origindex != -1) { | ||||
| BMEdge *eed = BM_edge_at_index(mr->bm, edge_origindex); | BMEdge *eed = BM_edge_at_index(mr->bm, edge_origindex); | ||||
| /* Loop on an edge endpoint. */ | /* Loop on an edge endpoint. */ | ||||
| BMLoop *l = BM_face_edge_share_loop(const_cast<BMFace *>(coarse_quad), eed); | BMLoop *l = BM_face_edge_share_loop(const_cast<BMFace *>(coarse_quad), eed); | ||||
| mesh_render_data_loop_flag(mr, l, data->cd_ofs, edit_loop_data); | mesh_render_data_loop_flag(mr, l, data->offsets, edit_loop_data); | ||||
| mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, edit_loop_data); | mesh_render_data_loop_edge_flag(mr, l, data->offsets, edit_loop_data); | ||||
| } | } | ||||
| else { | else { | ||||
| if (edge_origindex == -1) { | if (edge_origindex == -1) { | ||||
| /* Find if the loop's vert is not part of an edit edge. | /* Find if the loop's vert is not part of an edit edge. | ||||
| * For this, we check if the previous loop was on an edge. */ | * For this, we check if the previous loop was on an edge. */ | ||||
| const uint loop_index_last = (i == start_loop_idx) ? end_loop_idx - 1 : i - 1; | const uint loop_index_last = (i == start_loop_idx) ? end_loop_idx - 1 : i - 1; | ||||
| edge_origindex = subdiv_loop_edge_index[loop_index_last]; | edge_origindex = subdiv_loop_edge_index[loop_index_last]; | ||||
| } | } | ||||
| if (edge_origindex != -1) { | if (edge_origindex != -1) { | ||||
| /* Mapped points on an edge between two edit verts. */ | /* Mapped points on an edge between two edit verts. */ | ||||
| BMEdge *eed = BM_edge_at_index(mr->bm, edge_origindex); | BMEdge *eed = BM_edge_at_index(mr->bm, edge_origindex); | ||||
| BMLoop *l = BM_face_edge_share_loop(const_cast<BMFace *>(coarse_quad), eed); | BMLoop *l = BM_face_edge_share_loop(const_cast<BMFace *>(coarse_quad), eed); | ||||
| mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, edit_loop_data); | mesh_render_data_loop_edge_flag(mr, l, data->offsets, edit_loop_data); | ||||
| } | } | ||||
| } | } | ||||
| mesh_render_data_face_flag(mr, coarse_quad, data->cd_ofs, edit_loop_data); | mesh_render_data_face_flag(mr, coarse_quad, data->offsets, edit_loop_data); | ||||
| } | } | ||||
| } | } | ||||
| static void extract_edituv_data_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache, | static void extract_edituv_data_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache, | ||||
| const MeshRenderData *mr, | const MeshRenderData *mr, | ||||
| void *_data, | void *_data, | ||||
| uint subdiv_quad_index, | uint subdiv_quad_index, | ||||
| const MPoly *coarse_quad) | const MPoly *coarse_quad) | ||||
| Show All 27 Lines | |||||