diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-02-14 16:49:11 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-02-14 16:49:11 +0300 |
commit | 15141ec19ae54a0f087405e1d0ddba899daf886d (patch) | |
tree | 8db9c88e2a1f834f235d25489cef7de5eb451e26 /source | |
parent | 06a492cfdc78049adff6923636faa5d13b90cc57 (diff) | |
parent | 993839ce85137ac37a978f49ae894703a39dbf6a (diff) |
Merge remote-tracking branch 'origin/blender-v3.1-release'
Diffstat (limited to 'source')
10 files changed, 315 insertions, 166 deletions
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h index 8f2e8ebdf01..aaec47b4dce 100644 --- a/source/blender/draw/intern/draw_cache_extract.h +++ b/source/blender/draw/intern/draw_cache_extract.h @@ -8,6 +8,7 @@ #pragma once struct DRWSubdivCache; +struct MeshRenderData; struct TaskGraph; #include "DNA_customdata_types.h" @@ -332,7 +333,7 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph, void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache, MeshBufferCache *mbc, struct DRWSubdivCache *subdiv_cache, - const struct ToolSettings *ts); + struct MeshRenderData *mr); #ifdef __cplusplus } diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc index 09d6c06f7df..738a9029167 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc @@ -776,7 +776,7 @@ static void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph, static void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache, MeshBufferCache *mbc, DRWSubdivCache *subdiv_cache, - const ToolSettings *ts) + MeshRenderData *mr) { /* Create an array containing all the extractors that needs to be executed. */ ExtractorRunDatas extractors; @@ -832,10 +832,7 @@ static void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache, return; } - MeshRenderData mr; - memset(&mr, 0, sizeof(MeshRenderData)); - draw_subdiv_init_mesh_render_data(subdiv_cache, &mr, ts); - mesh_render_data_update_loose_geom(&mr, mbc, MR_ITER_LEDGE | MR_ITER_LVERT, MR_DATA_LOOSE_GEOM); + mesh_render_data_update_loose_geom(mr, mbc, MR_ITER_LEDGE | MR_ITER_LVERT, MR_DATA_LOOSE_GEOM); void *data_stack = MEM_mallocN(extractors.data_size_total(), __func__); uint32_t data_offset = 0; @@ -844,17 +841,17 @@ static void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache, void *buffer = mesh_extract_buffer_get(extractor, mbuflist); void *data = POINTER_OFFSET(data_stack, data_offset); - extractor->init_subdiv(subdiv_cache, &mr, cache, buffer, data); + extractor->init_subdiv(subdiv_cache, mr, cache, buffer, data); if (extractor->iter_subdiv_mesh || extractor->iter_subdiv_bm) { int *subdiv_loop_poly_index = subdiv_cache->subdiv_loop_poly_index; - if (subdiv_cache->bm) { + if (mr->extract_type == MR_EXTRACT_BMESH) { for (uint i = 0; i < subdiv_cache->num_subdiv_quads; i++) { /* Multiply by 4 to have the start index of the quad's loop, as subdiv_loop_poly_index is * based on the subdivision loops. */ const int poly_origindex = subdiv_loop_poly_index[i * 4]; - const BMFace *efa = bm_original_face_get(&mr, poly_origindex); - extractor->iter_subdiv_bm(subdiv_cache, &mr, data, i, efa); + const BMFace *efa = BM_face_at_index(mr->bm, poly_origindex); + extractor->iter_subdiv_bm(subdiv_cache, mr, data, i, efa); } } else { @@ -862,18 +859,18 @@ static void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache, /* Multiply by 4 to have the start index of the quad's loop, as subdiv_loop_poly_index is * based on the subdivision loops. */ const int poly_origindex = subdiv_loop_poly_index[i * 4]; - const MPoly *mp = &mr.mpoly[poly_origindex]; - extractor->iter_subdiv_mesh(subdiv_cache, &mr, data, i, mp); + const MPoly *mp = &mr->mpoly[poly_origindex]; + extractor->iter_subdiv_mesh(subdiv_cache, mr, data, i, mp); } } } if (extractor->iter_loose_geom_subdiv) { - extractor->iter_loose_geom_subdiv(subdiv_cache, &mr, &mbc->loose_geom, buffer, data); + extractor->iter_loose_geom_subdiv(subdiv_cache, mr, &mbc->loose_geom, buffer, data); } if (extractor->finish_subdiv) { - extractor->finish_subdiv(subdiv_cache, &mr, cache, buffer, data); + extractor->finish_subdiv(subdiv_cache, mr, cache, buffer, data); } } MEM_freeN(data_stack); @@ -921,9 +918,9 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph, void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache, MeshBufferCache *mbc, DRWSubdivCache *subdiv_cache, - const ToolSettings *ts) + MeshRenderData *mr) { - blender::draw::mesh_buffer_cache_create_requested_subdiv(cache, mbc, subdiv_cache, ts); + blender::draw::mesh_buffer_cache_create_requested_subdiv(cache, mbc, subdiv_cache, mr); } } // extern "C" diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 2d78a3f2b6f..8833a354c21 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -2062,7 +2062,20 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, } if (do_subdivision) { - DRW_create_subdivision(scene, ob, me, cache, &cache->final, ts); + DRW_create_subdivision(scene, + ob, + me, + cache, + &cache->final, + is_editmode, + is_paint_mode, + is_mode_active, + ob->obmat, + true, + false, + use_subsurf_fdots, + ts, + use_hide); } else { /* The subsurf modifier may have been recently removed, or another modifier was added after it, diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index f79b2fb8c1b..3c1c8ffd4fc 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -552,7 +552,6 @@ void draw_subdiv_cache_free(DRWSubdivCache *cache) GPU_VERTBUF_DISCARD_SAFE(cache->extra_coarse_face_data); MEM_SAFE_FREE(cache->subdiv_loop_subdiv_vert_index); MEM_SAFE_FREE(cache->subdiv_loop_poly_index); - MEM_SAFE_FREE(cache->point_indices); MEM_SAFE_FREE(cache->subdiv_polygon_offset); GPU_VERTBUF_DISCARD_SAFE(cache->subdiv_vertex_face_adjacency_offsets); GPU_VERTBUF_DISCARD_SAFE(cache->subdiv_vertex_face_adjacency); @@ -593,7 +592,9 @@ void draw_subdiv_cache_free(DRWSubdivCache *cache) SUBDIV_COARSE_FACE_FLAG_ACTIVE) \ << SUBDIV_COARSE_FACE_FLAG_OFFSET) -static void draw_subdiv_cache_update_extra_coarse_face_data(DRWSubdivCache *cache, Mesh *mesh) +static void draw_subdiv_cache_update_extra_coarse_face_data(DRWSubdivCache *cache, + Mesh *mesh, + MeshRenderData *mr) { if (cache->extra_coarse_face_data == nullptr) { cache->extra_coarse_face_data = GPU_vertbuf_calloc(); @@ -602,12 +603,14 @@ static void draw_subdiv_cache_update_extra_coarse_face_data(DRWSubdivCache *cach GPU_vertformat_attr_add(&format, "data", GPU_COMP_U32, 1, GPU_FETCH_INT); } GPU_vertbuf_init_with_format_ex(cache->extra_coarse_face_data, &format, GPU_USAGE_DYNAMIC); - GPU_vertbuf_data_alloc(cache->extra_coarse_face_data, mesh->totpoly); + GPU_vertbuf_data_alloc(cache->extra_coarse_face_data, + mr->extract_type == MR_EXTRACT_BMESH ? cache->bm->totface : + mesh->totpoly); } uint32_t *flags_data = (uint32_t *)(GPU_vertbuf_get_data(cache->extra_coarse_face_data)); - if (cache->bm) { + if (mr->extract_type == MR_EXTRACT_BMESH) { BMesh *bm = cache->bm; BMFace *f; BMIter iter; @@ -622,13 +625,34 @@ static void draw_subdiv_cache_update_extra_coarse_face_data(DRWSubdivCache *cach if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { flag |= SUBDIV_COARSE_FACE_FLAG_SELECT; } - if (f == bm->act_face) { + if (f == mr->efa_act) { flag |= SUBDIV_COARSE_FACE_FLAG_ACTIVE; } const int loopstart = BM_elem_index_get(f->l_first); flags_data[index] = (uint)(loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET); } } + else if (mr->extract_type == MR_EXTRACT_MAPPED) { + for (int i = 0; i < mesh->totpoly; i++) { + BMFace *f = bm_original_face_get(mr, i); + uint32_t flag = 0; + + if (f) { + if (BM_elem_flag_test(f, BM_ELEM_SMOOTH)) { + flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH; + } + if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { + flag |= SUBDIV_COARSE_FACE_FLAG_SELECT; + } + if (f == mr->efa_act) { + flag |= SUBDIV_COARSE_FACE_FLAG_ACTIVE; + } + const int loopstart = BM_elem_index_get(f->l_first); + flag = (uint)(loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET); + } + flags_data[i] = flag; + } + } else { for (int i = 0; i < mesh->totpoly; i++) { uint32_t flag = 0; @@ -669,6 +693,7 @@ static DRWSubdivCache *mesh_batch_cache_ensure_subdiv_cache(MeshBatchCache *mbc) struct DRWCacheBuildingContext { const Mesh *coarse_mesh; + const Subdiv *subdiv; const SubdivToMeshSettings *settings; DRWSubdivCache *cache; @@ -679,7 +704,6 @@ struct DRWCacheBuildingContext { int *subdiv_loop_subdiv_vert_index; int *subdiv_loop_edge_index; int *subdiv_loop_poly_index; - int *point_indices; /* Temporary buffers used during traversal. */ int *vert_origindex_map; @@ -737,20 +761,12 @@ static bool draw_subdiv_topology_info_cb(const SubdivForeachContext *foreach_con cache->subdiv_loop_poly_index = static_cast<int *>( MEM_mallocN(cache->num_subdiv_loops * sizeof(int), "subdiv_loop_poly_index")); - const int num_coarse_vertices = ctx->coarse_mesh->totvert; - cache->point_indices = static_cast<int *>( - MEM_mallocN(num_coarse_vertices * sizeof(int), "point_indices")); - for (int i = 0; i < num_coarse_vertices; i++) { - cache->point_indices[i] = -1; - } - /* Initialize context pointers and temporary buffers. */ ctx->patch_coords = (CompressedPatchCoord *)GPU_vertbuf_get_data(cache->patch_coords); ctx->subdiv_loop_vert_index = (int *)GPU_vertbuf_get_data(cache->verts_orig_index); ctx->subdiv_loop_edge_index = (int *)GPU_vertbuf_get_data(cache->edges_orig_index); ctx->subdiv_loop_subdiv_vert_index = cache->subdiv_loop_subdiv_vert_index; ctx->subdiv_loop_poly_index = cache->subdiv_loop_poly_index; - ctx->point_indices = cache->point_indices; ctx->v_origindex = static_cast<int *>( CustomData_get_layer(&ctx->coarse_mesh->vdata, CD_ORIGINDEX)); @@ -839,17 +855,6 @@ static void draw_subdiv_loop_cb(const SubdivForeachContext *foreach_context, int coarse_vertex_index = ctx->vert_origindex_map[subdiv_vertex_index]; - if (coarse_vertex_index != -1) { - if (ctx->v_origindex) { - coarse_vertex_index = ctx->v_origindex[coarse_vertex_index]; - } - - /* Double check as vorigindex may have modified the index. */ - if (coarse_vertex_index != -1) { - ctx->point_indices[coarse_vertex_index] = subdiv_loop_index; - } - } - ctx->subdiv_loop_subdiv_vert_index[subdiv_loop_index] = subdiv_vertex_index; /* For now index the subdiv_edge_index, it will be replaced by the actual coarse edge index * at the end of the traversal as some edges are only then traversed. */ @@ -1012,7 +1017,6 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache, cache->face_ptex_offset_buffer = draw_subdiv_build_origindex_buffer(cache->face_ptex_offset, mesh_eval->totpoly + 1); cache->num_coarse_poly = mesh_eval->totpoly; - cache->point_indices = cache_building_context.point_indices; build_vertex_face_adjacency_maps(cache); @@ -1085,7 +1089,7 @@ static void draw_subdiv_init_ubo_storage(const DRWSubdivCache *cache, ubo->max_patch_face = cache->gpu_patch_map.max_patch_face; ubo->max_depth = cache->gpu_patch_map.max_depth; ubo->patches_are_triangular = cache->gpu_patch_map.patches_are_triangular; - ubo->coarse_poly_count = cache->num_coarse_poly; + ubo->coarse_poly_count = cache->bm ? cache->bm->totface : cache->num_coarse_poly; ubo->optimal_display = cache->optimal_display; ubo->num_subdiv_loops = cache->num_subdiv_loops; ubo->edge_loose_offset = cache->num_subdiv_loops * 2; @@ -1649,50 +1653,6 @@ void draw_subdiv_build_edituv_stretch_angle_buffer(const DRWSubdivCache *cache, /* -------------------------------------------------------------------- */ -void draw_subdiv_init_mesh_render_data(DRWSubdivCache *cache, - MeshRenderData *mr, - const ToolSettings *toolsettings) -{ - Mesh *mesh = cache->mesh; - - /* Setup required data for loose geometry. */ - mr->me = mesh; - mr->medge = mesh->medge; - mr->mvert = mesh->mvert; - mr->mpoly = mesh->mpoly; - mr->mloop = mesh->mloop; - mr->vert_normals = BKE_mesh_vertex_normals_ensure(mesh); - mr->vert_len = mesh->totvert; - mr->edge_len = mesh->totedge; - mr->poly_len = mesh->totpoly; - mr->loop_len = mesh->totloop; - mr->extract_type = MR_EXTRACT_MESH; - mr->toolsettings = toolsettings; - mr->v_origindex = static_cast<int *>(CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX)); - mr->e_origindex = static_cast<int *>(CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX)); - mr->p_origindex = static_cast<int *>(CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX)); - - /* MeshRenderData is only used for generating edit mode data here. */ - if (!cache->bm) { - return; - } - - BMesh *bm = cache->bm; - BM_mesh_elem_table_ensure(bm, BM_EDGE | BM_FACE | BM_VERT); - - mr->bm = bm; - mr->eed_act = BM_mesh_active_edge_get(bm); - mr->efa_act = BM_mesh_active_face_get(bm, false, true); - mr->eve_act = BM_mesh_active_vert_get(bm); - mr->edge_crease_ofs = CustomData_get_offset(&bm->edata, CD_CREASE); - mr->vert_crease_ofs = CustomData_get_offset(&bm->vdata, CD_CREASE); - mr->bweight_ofs = CustomData_get_offset(&bm->edata, CD_BWEIGHT); -#ifdef WITH_FREESTYLE - mr->freestyle_edge_ofs = CustomData_get_offset(&bm->edata, CD_FREESTYLE_EDGE); - mr->freestyle_face_ofs = CustomData_get_offset(&bm->pdata, CD_FREESTYLE_FACE); -#endif -} - /** * For material assignments we want indices for triangles that share a common material to be laid * out contiguously in memory. To achieve this, we sort the indices based on which material the @@ -1796,7 +1756,15 @@ static bool draw_subdiv_create_requested_buffers(const Scene *scene, Mesh *mesh, struct MeshBatchCache *batch_cache, MeshBufferCache *mbc, - const ToolSettings *toolsettings, + const bool is_editmode, + const bool is_paint_mode, + const bool is_mode_active, + const float obmat[4][4], + const bool do_final, + const bool do_uvedit, + const bool use_subsurf_fdots, + const ToolSettings *ts, + const bool use_hide, OpenSubdiv_EvaluatorCache *evaluator_cache) { SubsurfModifierData *smd = BKE_object_get_last_subsurf_modifier(ob); @@ -1849,9 +1817,14 @@ static bool draw_subdiv_create_requested_buffers(const Scene *scene, draw_subdiv_cache_ensure_mat_offsets(draw_cache, mesh_eval, batch_cache->mat_len); } - draw_subdiv_cache_update_extra_coarse_face_data(draw_cache, mesh_eval); + MeshRenderData *mr = mesh_render_data_create( + ob, mesh, is_editmode, is_paint_mode, is_mode_active, obmat, do_final, do_uvedit, ts); + + draw_subdiv_cache_update_extra_coarse_face_data(draw_cache, mesh_eval, mr); + + mesh_buffer_cache_create_requested_subdiv(batch_cache, mbc, draw_cache, mr); - mesh_buffer_cache_create_requested_subdiv(batch_cache, mbc, draw_cache, toolsettings); + mesh_render_data_free(mr); return true; } @@ -1863,7 +1836,15 @@ void DRW_create_subdivision(const Scene *scene, Mesh *mesh, struct MeshBatchCache *batch_cache, MeshBufferCache *mbc, - const ToolSettings *toolsettings) + const bool is_editmode, + const bool is_paint_mode, + const bool is_mode_active, + const float obmat[4][4], + const bool do_final, + const bool do_uvedit, + const bool use_subsurf_fdots, + const ToolSettings *ts, + const bool use_hide) { if (g_evaluator_cache == nullptr) { g_evaluator_cache = openSubdiv_createEvaluatorCache(OPENSUBDIV_EVALUATOR_GLSL_COMPUTE); @@ -1875,8 +1856,21 @@ void DRW_create_subdivision(const Scene *scene, const double begin_time = PIL_check_seconds_timer(); #endif - if (!draw_subdiv_create_requested_buffers( - scene, ob, mesh, batch_cache, mbc, toolsettings, g_evaluator_cache)) { + if (!draw_subdiv_create_requested_buffers(scene, + ob, + mesh, + batch_cache, + mbc, + is_editmode, + is_paint_mode, + is_mode_active, + obmat, + do_final, + do_uvedit, + use_subsurf_fdots, + ts, + use_hide, + g_evaluator_cache)) { return; } diff --git a/source/blender/draw/intern/draw_subdivision.h b/source/blender/draw/intern/draw_subdivision.h index 74db85f2c94..394482c0862 100644 --- a/source/blender/draw/intern/draw_subdivision.h +++ b/source/blender/draw/intern/draw_subdivision.h @@ -128,7 +128,17 @@ void DRW_create_subdivision(const struct Scene *scene, struct Mesh *mesh, struct MeshBatchCache *batch_cache, struct MeshBufferCache *mbc, - const struct ToolSettings *toolsettings); + const bool is_editmode, + const bool is_paint_mode, + const bool is_mode_active, + const float obmat[4][4], + const bool do_final, + const bool do_uvedit, + const bool use_subsurf_fdots, + const ToolSettings *ts, + const bool use_hide); + +void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, struct MeshBufferCache *cache); void DRW_subdiv_cache_free(struct Subdiv *subdiv); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc index e5dd3798fc6..bf34d961281 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc @@ -147,16 +147,55 @@ static void extract_points_init_subdiv(const DRWSubdivCache *subdiv_cache, void *data) { GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(data); - /* Copy the points as the data upload will free them. */ - elb->data = (uint *)MEM_dupallocN(subdiv_cache->point_indices); - elb->index_len = mr->vert_len; - elb->index_min = 0; - elb->index_max = subdiv_cache->num_subdiv_loops + mr->loop_loose_len; - elb->prim_type = GPU_PRIM_POINTS; + GPU_indexbuf_init( + elb, GPU_PRIM_POINTS, mr->vert_len, subdiv_cache->num_subdiv_loops + mr->loop_loose_len); +} + +static void extract_points_iter_subdiv_common(GPUIndexBufBuilder *elb, + const MeshRenderData *mr, + const DRWSubdivCache *subdiv_cache, + uint subdiv_quad_index) +{ + int *subdiv_loop_vert_index = (int *)GPU_vertbuf_get_data(subdiv_cache->verts_orig_index); + uint start_loop_idx = subdiv_quad_index * 4; + uint end_loop_idx = (subdiv_quad_index + 1) * 4; + for (uint i = start_loop_idx; i < end_loop_idx; i++) { + int coarse_vertex_index = subdiv_loop_vert_index[i]; + + if (coarse_vertex_index == -1) { + continue; + } + + if (mr->v_origindex && mr->v_origindex[coarse_vertex_index] == -1) { + continue; + } + + GPU_indexbuf_set_point_vert(elb, coarse_vertex_index, i); + } +} + +static void extract_points_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache, + const MeshRenderData *mr, + void *_data, + uint subdiv_quad_index, + const BMFace *UNUSED(coarse_quad)) +{ + GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data); + extract_points_iter_subdiv_common(elb, mr, subdiv_cache, subdiv_quad_index); +} + +static void extract_points_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache, + const MeshRenderData *mr, + void *_data, + uint subdiv_quad_index, + const MPoly *UNUSED(coarse_quad)) +{ + GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data); + extract_points_iter_subdiv_common(elb, mr, subdiv_cache, subdiv_quad_index); } static void extract_points_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache, - const MeshRenderData *UNUSED(mr), + const MeshRenderData *mr, const MeshExtractLooseGeom *loose_geom, void *UNUSED(buffer), void *data) @@ -167,28 +206,38 @@ static void extract_points_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache, } GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(data); - - const Mesh *coarse_mesh = subdiv_cache->mesh; - const MEdge *coarse_edges = coarse_mesh->medge; - uint offset = subdiv_cache->num_subdiv_loops; - for (int i = 0; i < loose_geom->edge_len; i++) { - const MEdge *loose_edge = &coarse_edges[loose_geom->edges[i]]; - if (elb->data[loose_edge->v1] == -1u) { - GPU_indexbuf_set_point_vert(elb, loose_edge->v1, offset); + if (mr->extract_type == MR_EXTRACT_MESH) { + const Mesh *coarse_mesh = subdiv_cache->mesh; + const MEdge *coarse_edges = coarse_mesh->medge; + + for (int i = 0; i < loose_geom->edge_len; i++) { + const MEdge *loose_edge = &coarse_edges[loose_geom->edges[i]]; + vert_set_mesh(elb, mr, loose_edge->v1, offset); + vert_set_mesh(elb, mr, loose_edge->v2, offset + 1); + offset += 2; } - if (elb->data[loose_edge->v2] == -1u) { - GPU_indexbuf_set_point_vert(elb, loose_edge->v2, offset + 1); + + for (int i = 0; i < loose_geom->vert_len; i++) { + vert_set_mesh(elb, mr, loose_geom->verts[i], offset); + offset += 1; } - offset += 2; } + else { + BMesh *bm = mr->bm; + for (int i = 0; i < loose_geom->edge_len; i++) { + const BMEdge *loose_edge = BM_edge_at_index(bm, loose_geom->edges[i]); + vert_set_bm(elb, loose_edge->v1, offset); + vert_set_bm(elb, loose_edge->v2, offset + 1); + offset += 2; + } - for (int i = 0; i < loose_geom->vert_len; i++) { - if (elb->data[loose_geom->verts[i]] == -1u) { - GPU_indexbuf_set_point_vert(elb, loose_geom->verts[i], offset); + for (int i = 0; i < loose_geom->vert_len; i++) { + const BMVert *loose_vert = BM_vert_at_index(bm, loose_geom->verts[i]); + vert_set_bm(elb, loose_vert, offset); + offset += 1; } - offset += 1; } } @@ -216,6 +265,8 @@ constexpr MeshExtract create_extractor_points() extractor.task_reduce = extract_points_task_reduce; extractor.finish = extract_points_finish; extractor.init_subdiv = extract_points_init_subdiv; + extractor.iter_subdiv_bm = extract_points_iter_subdiv_bm; + extractor.iter_subdiv_mesh = extract_points_iter_subdiv_mesh; extractor.iter_loose_geom_subdiv = extract_points_loose_geom_subdiv; extractor.finish_subdiv = extract_points_finish_subdiv; extractor.use_threading = true; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc index e17cef8a1e3..b777b67b984 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc @@ -272,21 +272,24 @@ static void extract_edit_data_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache, memset(edit_loop_data, 0, sizeof(EditLoopData)); if (vert_origindex != -1) { - const BMVert *eve = bm_original_vert_get(mr, vert_origindex); + const BMVert *eve = mr->v_origindex ? bm_original_vert_get(mr, vert_origindex) : + BM_vert_at_index(mr->bm, vert_origindex); if (eve) { mesh_render_data_vert_flag(mr, eve, edit_loop_data); } } if (edge_origindex != -1) { - const BMEdge *eed = bm_original_edge_get(mr, edge_origindex); - if (eed) { - mesh_render_data_edge_flag(mr, eed, edit_loop_data); - } + /* NOTE: #subdiv_loop_edge_index already has the origindex layer baked in. */ + const BMEdge *eed = BM_edge_at_index(mr->bm, edge_origindex); + mesh_render_data_edge_flag(mr, eed, edit_loop_data); } - /* The -1 parameter is for edit_uvs, which we don't do here. */ - mesh_render_data_face_flag(mr, coarse_quad, -1, edit_loop_data); + /* coarse_quad can be null when called by the mesh iteration below. */ + if (coarse_quad) { + /* The -1 parameter is for edit_uvs, which we don't do here. */ + mesh_render_data_face_flag(mr, coarse_quad, -1, edit_loop_data); + } } } @@ -317,7 +320,9 @@ static void extract_edit_data_loose_geom_subdiv(const DRWSubdivCache *subdiv_cac const int offset = subdiv_cache->num_subdiv_loops + ledge_index * 2; EditLoopData *data = &vbo_data[offset]; memset(data, 0, sizeof(EditLoopData)); - BMEdge *eed = bm_original_edge_get(mr, loose_geom->edges[ledge_index]); + const int edge_index = loose_geom->edges[ledge_index]; + BMEdge *eed = mr->e_origindex ? bm_original_edge_get(mr, edge_index) : + BM_edge_at_index(mr->bm, edge_index); mesh_render_data_edge_flag(mr, eed, &data[0]); data[1] = data[0]; mesh_render_data_vert_flag(mr, eed->v1, &data[0]); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc index e8f4167c177..2dfd2cd43dc 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc @@ -143,7 +143,7 @@ static void extract_edituv_data_iter_subdiv_bm(const DRWSubdivCache *subdiv_cach memset(edit_loop_data, 0, sizeof(EditLoopData)); if (vert_origindex != -1 && edge_origindex != -1) { - BMEdge *eed = bm_original_edge_get(mr, edge_origindex); + BMEdge *eed = BM_edge_at_index(mr->bm, edge_origindex); /* Loop on an edge endpoint. */ 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); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc index 30c6de966fe..6e2cb8ad3e3 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc @@ -249,9 +249,6 @@ static void extract_pos_nor_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache } GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer); - const Mesh *coarse_mesh = subdiv_cache->mesh; - const MEdge *coarse_edges = coarse_mesh->medge; - const MVert *coarse_verts = coarse_mesh->mvert; uint offset = subdiv_cache->num_subdiv_loops; /* TODO(@kevindietrich): replace this when compressed normals are supported. */ @@ -261,38 +258,75 @@ static void extract_pos_nor_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache float flag; }; - SubdivPosNorLoop edge_data[2]; - for (int i = 0; i < loose_geom->edge_len; i++) { - const MEdge *loose_edge = &coarse_edges[loose_geom->edges[i]]; - const MVert *loose_vert1 = &coarse_verts[loose_edge->v1]; - const MVert *loose_vert2 = &coarse_verts[loose_edge->v2]; + if (mr->extract_type == MR_EXTRACT_MESH) { + const Mesh *coarse_mesh = subdiv_cache->mesh; + const MEdge *coarse_edges = coarse_mesh->medge; + const MVert *coarse_verts = coarse_mesh->mvert; - copy_v3_v3(edge_data[0].pos, loose_vert1->co); - copy_v3_v3(edge_data[0].nor, mr->vert_normals[loose_edge->v1]); - edge_data[0].flag = 0.0f; + SubdivPosNorLoop edge_data[2]; + memset(&edge_data, 0, sizeof(SubdivPosNorLoop) * 2); + for (int i = 0; i < loose_geom->edge_len; i++) { + const MEdge *loose_edge = &coarse_edges[loose_geom->edges[i]]; + const MVert *loose_vert1 = &coarse_verts[loose_edge->v1]; + const MVert *loose_vert2 = &coarse_verts[loose_edge->v2]; - copy_v3_v3(edge_data[1].pos, loose_vert2->co); - copy_v3_v3(edge_data[1].nor, mr->vert_normals[loose_edge->v2]); - edge_data[1].flag = 0.0f; + copy_v3_v3(edge_data[0].pos, loose_vert1->co); + copy_v3_v3(edge_data[1].pos, loose_vert2->co); - GPU_vertbuf_update_sub( - vbo, offset * sizeof(SubdivPosNorLoop), sizeof(SubdivPosNorLoop) * 2, &edge_data); + GPU_vertbuf_update_sub( + vbo, offset * sizeof(SubdivPosNorLoop), sizeof(SubdivPosNorLoop) * 2, &edge_data); - offset += 2; + offset += 2; + } + + SubdivPosNorLoop vert_data; + memset(&vert_data, 0, sizeof(SubdivPosNorLoop)); + for (int i = 0; i < loose_geom->vert_len; i++) { + const MVert *loose_vertex = &coarse_verts[loose_geom->verts[i]]; + + copy_v3_v3(vert_data.pos, loose_vertex->co); + + GPU_vertbuf_update_sub( + vbo, offset * sizeof(SubdivPosNorLoop), sizeof(SubdivPosNorLoop), &vert_data); + + offset += 1; + } } + else { + BMesh *bm = subdiv_cache->bm; - SubdivPosNorLoop vert_data; - vert_data.flag = 0.0f; - for (int i = 0; i < loose_geom->vert_len; i++) { - const MVert *loose_vertex = &coarse_verts[loose_geom->verts[i]]; + SubdivPosNorLoop edge_data[2]; + memset(&edge_data, 0, sizeof(SubdivPosNorLoop) * 2); + for (int i = 0; i < loose_geom->edge_len; i++) { + const BMEdge *loose_edge = BM_edge_at_index(bm, loose_geom->edges[i]); + const BMVert *loose_vert1 = loose_edge->v1; + const BMVert *loose_vert2 = loose_edge->v2; - copy_v3_v3(vert_data.pos, loose_vertex->co); - copy_v3_v3(vert_data.nor, mr->vert_normals[loose_geom->verts[i]]); + copy_v3_v3(edge_data[0].pos, loose_vert1->co); + copy_v3_v3(edge_data[0].nor, loose_vert1->no); - GPU_vertbuf_update_sub( - vbo, offset * sizeof(SubdivPosNorLoop), sizeof(SubdivPosNorLoop), &vert_data); + copy_v3_v3(edge_data[1].pos, loose_vert2->co); + copy_v3_v3(edge_data[1].nor, loose_vert2->no); - offset += 1; + GPU_vertbuf_update_sub( + vbo, offset * sizeof(SubdivPosNorLoop), sizeof(SubdivPosNorLoop) * 2, &edge_data); + + offset += 2; + } + + SubdivPosNorLoop vert_data; + memset(&vert_data, 0, sizeof(SubdivPosNorLoop)); + for (int i = 0; i < loose_geom->vert_len; i++) { + const BMVert *loose_vertex = BM_vert_at_index(bm, loose_geom->verts[i]); + + copy_v3_v3(vert_data.pos, loose_vertex->co); + copy_v3_v3(vert_data.nor, loose_vertex->no); + + GPU_vertbuf_update_sub( + vbo, offset * sizeof(SubdivPosNorLoop), sizeof(SubdivPosNorLoop), &vert_data); + + offset += 1; + } } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc index 6db08e76ead..0dcf59005bd 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc @@ -190,13 +190,28 @@ static void extract_vert_idx_init_subdiv(const DRWSubdivCache *subdiv_cache, GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf); /* Each element points to an element in the ibo.points. */ draw_subdiv_init_origindex_buffer(vbo, - subdiv_cache->subdiv_loop_subdiv_vert_index, + (int *)GPU_vertbuf_get_data(subdiv_cache->verts_orig_index), subdiv_cache->num_subdiv_loops, mr->loop_loose_len); + + if (!mr->v_origindex) { + return; + } + + /* Remap the vertex indices to those pointed by the origin indices layer. At this point, the + * VBO data is a copy of #verts_orig_index which contains the coarse vertices indices, so + * the memory can both be accessed for lookup and immediately overwritten. */ + int *vbo_data = static_cast<int *>(GPU_vertbuf_get_data(vbo)); + for (int i = 0; i < subdiv_cache->num_subdiv_loops; i++) { + if (vbo_data[i] == -1) { + continue; + } + vbo_data[i] = mr->v_origindex[vbo_data[i]]; + } } static void extract_vert_idx_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache, - const MeshRenderData *UNUSED(mr), + const MeshRenderData *mr, const MeshExtractLooseGeom *loose_geom, void *buffer, void *UNUSED(data)) @@ -208,20 +223,37 @@ static void extract_vert_idx_loose_geom_subdiv(const DRWSubdivCache *subdiv_cach GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer); uint *vert_idx_data = (uint *)GPU_vertbuf_get_data(vbo); - const Mesh *coarse_mesh = subdiv_cache->mesh; - const MEdge *coarse_edges = coarse_mesh->medge; uint offset = subdiv_cache->num_subdiv_loops; - for (int i = 0; i < loose_geom->edge_len; i++) { - const MEdge *loose_edge = &coarse_edges[loose_geom->edges[i]]; - vert_idx_data[offset] = loose_edge->v1; - vert_idx_data[offset + 1] = loose_edge->v2; - offset += 2; + if (mr->extract_type == MR_EXTRACT_MESH) { + const Mesh *coarse_mesh = subdiv_cache->mesh; + const MEdge *coarse_edges = coarse_mesh->medge; + for (int i = 0; i < loose_geom->edge_len; i++) { + const MEdge *loose_edge = &coarse_edges[loose_geom->edges[i]]; + vert_idx_data[offset] = loose_edge->v1; + vert_idx_data[offset + 1] = loose_edge->v2; + offset += 2; + } + + for (int i = 0; i < loose_geom->vert_len; i++) { + vert_idx_data[offset] = loose_geom->verts[i]; + offset += 1; + } } - - for (int i = 0; i < loose_geom->vert_len; i++) { - vert_idx_data[offset] = loose_geom->verts[i]; - offset += 1; + else { + BMesh *bm = mr->bm; + for (int i = 0; i < loose_geom->edge_len; i++) { + const BMEdge *loose_edge = BM_edge_at_index(bm, loose_geom->edges[i]); + vert_idx_data[offset] = BM_elem_index_get(loose_edge->v1); + vert_idx_data[offset + 1] = BM_elem_index_get(loose_edge->v2); + offset += 2; + } + + for (int i = 0; i < loose_geom->vert_len; i++) { + const BMVert *loose_vert = BM_vert_at_index(bm, loose_geom->verts[i]); + vert_idx_data[offset] = BM_elem_index_get(loose_vert); + offset += 1; + } } } @@ -262,7 +294,7 @@ static void extract_edge_idx_loose_geom_subdiv(const DRWSubdivCache *subdiv_cach } static void extract_poly_idx_init_subdiv(const DRWSubdivCache *subdiv_cache, - const MeshRenderData *UNUSED(mr), + const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *buf, void *UNUSED(data)) @@ -270,6 +302,18 @@ static void extract_poly_idx_init_subdiv(const DRWSubdivCache *subdiv_cache, GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf); draw_subdiv_init_origindex_buffer( vbo, subdiv_cache->subdiv_loop_poly_index, subdiv_cache->num_subdiv_loops, 0); + + if (!mr->p_origindex) { + return; + } + + /* Remap the polygon indices to those pointed by the origin indices layer. At this point, the + * VBO data is a copy of #subdiv_loop_poly_index which contains the coarse polygon indices, so + * the memory can both be accessed for lookup and immediately overwritten. */ + int *vbo_data = static_cast<int *>(GPU_vertbuf_get_data(vbo)); + for (int i = 0; i < subdiv_cache->num_subdiv_loops; i++) { + vbo_data[i] = mr->p_origindex[vbo_data[i]]; + } } constexpr MeshExtract create_extractor_poly_idx() |