Merge remote-tracking branch 'origin/blender-v3.1-release'

This commit is contained in:
Kévin Dietrich
2022-02-14 14:49:11 +01:00
10 changed files with 318 additions and 169 deletions

View File

@@ -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
}

View File

@@ -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"

View File

@@ -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,

View File

@@ -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);
mesh_buffer_cache_create_requested_subdiv(batch_cache, mbc, draw_cache, toolsettings);
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_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;
}

View File

@@ -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);

View File

@@ -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 (elb->data[loose_edge->v2] == -1u) {
GPU_indexbuf_set_point_vert(elb, loose_edge->v2, offset + 1);
}
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->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->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;
}
for (int i = 0; i < loose_geom->vert_len; i++) {
vert_set_mesh(elb, mr, loose_geom->verts[i], offset);
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_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++) {
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;

View File

@@ -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]);

View File

@@ -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);

View File

@@ -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;
}
}
}

View File

@@ -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()