From 615c7a04e4a85284a6f1ede7bc1ee328b064e308 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Thu, 22 Jun 2023 18:48:40 +0200 Subject: [PATCH 1/6] Single Color implementation --- source/blender/draw/CMakeLists.txt | 2 + .../engines/workbench/workbench_engine.cc | 27 ++- source/blender/draw/intern/draw_sculpt.cc | 177 ++++++++++++++++++ source/blender/draw/intern/draw_sculpt.hh | 23 +++ 4 files changed, 226 insertions(+), 3 deletions(-) create mode 100644 source/blender/draw/intern/draw_sculpt.cc create mode 100644 source/blender/draw/intern/draw_sculpt.hh diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index b1406ada8cb..81a4e0b6837 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -100,6 +100,7 @@ set(SRC intern/draw_pbvh.cc intern/draw_pointcloud.cc intern/draw_resource.cc + intern/draw_sculpt.cc intern/draw_select_buffer.c intern/draw_shader.cc intern/draw_texture_pool.cc @@ -261,6 +262,7 @@ set(SRC intern/draw_pass.hh intern/draw_pbvh.h intern/draw_resource.hh + intern/draw_sculpt.hh intern/draw_shader.h intern/draw_shader_shared.h intern/draw_state.h diff --git a/source/blender/draw/engines/workbench/workbench_engine.cc b/source/blender/draw/engines/workbench/workbench_engine.cc index 04fd5a94cb5..529dfd3b37f 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.cc +++ b/source/blender/draw/engines/workbench/workbench_engine.cc @@ -15,6 +15,8 @@ #include "ED_view3d.h" #include "GPU_capabilities.h" +#include "draw_sculpt.hh" + #include "workbench_private.hh" #include "workbench_engine.h" /* Own include. */ @@ -128,6 +130,7 @@ class Instance { * when switching from eevee to workbench). */ if (ob_ref.object->sculpt && ob_ref.object->sculpt->pbvh) { + /* TODO(Miguel Pozo): Could this me moved to sculpt_batches_get()? */ BKE_pbvh_is_drawing_set(ob_ref.object->sculpt->pbvh, object_state.sculpt_pbvh); } @@ -207,9 +210,27 @@ class Instance { bool has_transparent_material = false; if (object_state.sculpt_pbvh) { -#if 0 /* TODO(@pragma37): */ - workbench_cache_sculpt_populate(wpd, ob, object_state.color_type); -#endif + if (!object_state.use_per_material_batches) { + bool use_color = object_state.color_type == V3D_SHADING_VERTEX_COLOR; + bool use_uv = object_state.color_type == V3D_SHADING_TEXTURE_COLOR; + + Material mat = get_material(ob_ref, object_state.color_type); + has_transparent_material = has_transparent_material || mat.is_transparent(); + + for (SculptBatch &batch : + sculpt_batches_get(ob_ref.object, false, false, false, use_color, use_uv)) + { + draw_mesh(ob_ref, + mat, + batch.batch, + handle, + object_state.image_paint_override, + object_state.override_sampler_state); + } + } + else { + /* TODO */ + } } else { if (object_state.use_per_material_batches) { diff --git a/source/blender/draw/intern/draw_sculpt.cc b/source/blender/draw/intern/draw_sculpt.cc new file mode 100644 index 00000000000..49ca6c3378f --- /dev/null +++ b/source/blender/draw/intern/draw_sculpt.cc @@ -0,0 +1,177 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup draw + */ + +#include "draw_sculpt.hh" + +#include "draw_pbvh.h" + +#include "BKE_paint.h" +#include "BKE_pbvh.h" +#include "DRW_pbvh.hh" + +namespace blender::draw { + +struct SculptCallbackData { + bool use_wire; + bool fast_mode; + + PBVHAttrReq *attrs; + int attrs_len; + + Vector batches; +}; + +static void sculpt_draw_cb(SculptCallbackData *data, + PBVHBatches *batches, + PBVH_GPU_Args *pbvh_draw_args) +{ + if (!batches) { + return; + } + + SculptBatch batch = {}; + + int primcount; + if (data->use_wire) { + batch.batch = DRW_pbvh_lines_get( + batches, data->attrs, data->attrs_len, pbvh_draw_args, &primcount, data->fast_mode); + } + else { + batch.batch = DRW_pbvh_tris_get( + batches, data->attrs, data->attrs_len, pbvh_draw_args, &primcount, data->fast_mode); + } + + batch.material_slot = drw_pbvh_material_index_get(batches); + + data->batches.append(batch); +} + +static Vector sculpt_batches_get_ex( + Object *ob, bool use_wire, bool use_materials, PBVHAttrReq *attrs, int attrs_len) +{ + /* PBVH should always exist for non-empty meshes, created by depsgraph eval. */ + PBVH *pbvh = ob->sculpt ? ob->sculpt->pbvh : nullptr; + if (!pbvh) { + return {}; + } + + /* TODO(Miguel Pozo): Don't use global context. */ + const DRWContextState *drwctx = DRW_context_state_get(); + RegionView3D *rv3d = drwctx->rv3d; + const bool navigating = rv3d && (rv3d->rflag & RV3D_NAVIGATING); + + Paint *paint = nullptr; + if (drwctx->evil_C != nullptr) { + paint = BKE_paint_get_active_from_context(drwctx->evil_C); + } + + /* Frustum planes to show only visible PBVH nodes. */ + float4 draw_planes[6]; + PBVHFrustumPlanes draw_frustum = {reinterpret_cast(draw_planes), 6}; + float4 update_planes[6]; + PBVHFrustumPlanes update_frustum = {reinterpret_cast(update_planes), 6}; + + /* TODO: take into account partial redraw for clipping planes. */ + DRW_view_frustum_planes_get(DRW_view_default_get(), draw_frustum.planes); + /* Transform clipping planes to object space. Transforming a plane with a + * 4x4 matrix is done by multiplying with the transpose inverse. + * The inverse cancels out here since we transform by inverse(obmat). */ + float4x4 tmat = math::transpose(float4x4(ob->object_to_world)); + for (int i : IndexRange(6)) { + draw_planes[i] = tmat * draw_planes[i]; + update_planes[i] = draw_planes[i]; + } + + if (paint && (paint->flags & PAINT_SCULPT_DELAY_UPDATES)) { + if (navigating) { + BKE_pbvh_get_frustum_planes(pbvh, &update_frustum); + } + else { + BKE_pbvh_set_frustum_planes(pbvh, &update_frustum); + } + } + + /* Fast mode to show low poly multires while navigating. */ + bool fast_mode = false; + if (paint && (paint->flags & PAINT_FAST_NAVIGATE)) { + fast_mode = navigating; + } + + /* Update draw buffers only for visible nodes while painting. + * But do update them otherwise so navigating stays smooth. */ + bool update_only_visible = rv3d && !(rv3d->rflag & RV3D_PAINTING); + if (paint && (paint->flags & PAINT_SCULPT_DELAY_UPDATES)) { + update_only_visible = true; + } + + Mesh *mesh = static_cast(ob->data); + BKE_pbvh_update_normals(pbvh, mesh->runtime->subdiv_ccg); + + SculptCallbackData data; + data.use_wire = use_wire; + data.fast_mode = fast_mode; + data.attrs = attrs; + data.attrs_len = attrs_len; + + BKE_pbvh_draw_cb(pbvh, + update_only_visible, + &update_frustum, + &draw_frustum, + (void (*)(void *, PBVHBatches *, PBVH_GPU_Args *))sculpt_draw_cb, + &data, + use_materials, + attrs, + attrs_len); + + return data.batches; +} + +Vector sculpt_batches_get( + Object *ob, bool use_wire, bool use_mask, bool use_fset, bool use_color, bool use_uv) +{ + PBVHAttrReq attrs[16] = {0}; + int attrs_len = 0; + + /* NOTE: these are NOT #eCustomDataType, they are extended values, ASAN may warn about this. */ + attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_CO_TYPE; + attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_NO_TYPE; + + if (use_mask) { + attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_MASK_TYPE; + } + + if (use_fset) { + attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_FSET_TYPE; + } + + Mesh *me = BKE_object_get_original_mesh(ob); + + if (use_color) { + const CustomDataLayer *layer = BKE_id_attributes_color_find(&me->id, + me->active_color_attribute); + if (layer) { + attrs[attrs_len].type = eCustomDataType(layer->type); + attrs[attrs_len].domain = BKE_id_attribute_domain(&me->id, layer); + STRNCPY(attrs[attrs_len].name, layer->name); + attrs_len++; + } + } + + if (use_uv) { + int layer_i = CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2); + if (layer_i != -1) { + CustomDataLayer *layer = me->ldata.layers + layer_i; + attrs[attrs_len].type = CD_PROP_FLOAT2; + attrs[attrs_len].domain = ATTR_DOMAIN_CORNER; + STRNCPY(attrs[attrs_len].name, layer->name); + attrs_len++; + } + } + + return sculpt_batches_get_ex(ob, use_wire, false, attrs, attrs_len); +} + +} // namespace blender::draw diff --git a/source/blender/draw/intern/draw_sculpt.hh b/source/blender/draw/intern/draw_sculpt.hh new file mode 100644 index 00000000000..1f0a1fa699b --- /dev/null +++ b/source/blender/draw/intern/draw_sculpt.hh @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup draw + */ + +#pragma once + +#include "draw_manager.hh" + +namespace blender::draw { + +struct SculptBatch { + GPUBatch *batch; + int material_slot; +}; + +enum class SculptBatchFeature { WIRE, MASK, FSET, VERTEX_COLOR, UV }; + +Vector sculpt_batches_get( + Object *ob, bool use_wire, bool use_mask, bool use_fset, bool use_color, bool use_uv); + +} // namespace blender::draw -- 2.30.2 From 441b8c5897261590a225a2de2689dcff08712a70 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Thu, 22 Jun 2023 20:39:45 +0200 Subject: [PATCH 2/6] Multi material support --- .../engines/workbench/workbench_engine.cc | 161 ++++++++++-------- source/blender/draw/intern/draw_sculpt.cc | 69 ++++++-- source/blender/draw/intern/draw_sculpt.hh | 16 +- 3 files changed, 158 insertions(+), 88 deletions(-) diff --git a/source/blender/draw/engines/workbench/workbench_engine.cc b/source/blender/draw/engines/workbench/workbench_engine.cc index 529dfd3b37f..12f0ad68bbe 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.cc +++ b/source/blender/draw/engines/workbench/workbench_engine.cc @@ -183,7 +183,10 @@ class Instance { return; } - if (ELEM(ob->type, OB_MESH, OB_POINTCLOUD)) { + if (object_state.sculpt_pbvh) { + sculpt_sync(manager, ob_ref, object_state); + } + else if (ELEM(ob->type, OB_MESH, OB_POINTCLOUD)) { mesh_sync(manager, ob_ref, object_state); } else if (ob->type == OB_CURVES) { @@ -209,90 +212,65 @@ class Instance { ResourceHandle handle = manager.resource_handle(ob_ref); bool has_transparent_material = false; - if (object_state.sculpt_pbvh) { - if (!object_state.use_per_material_batches) { - bool use_color = object_state.color_type == V3D_SHADING_VERTEX_COLOR; - bool use_uv = object_state.color_type == V3D_SHADING_TEXTURE_COLOR; + if (object_state.use_per_material_batches) { + const int material_count = DRW_cache_object_material_count_get(ob_ref.object); - Material mat = get_material(ob_ref, object_state.color_type); - has_transparent_material = has_transparent_material || mat.is_transparent(); - - for (SculptBatch &batch : - sculpt_batches_get(ob_ref.object, false, false, false, use_color, use_uv)) - { - draw_mesh(ob_ref, - mat, - batch.batch, - handle, - object_state.image_paint_override, - object_state.override_sampler_state); - } + GPUBatch **batches; + if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) { + batches = DRW_cache_mesh_surface_texpaint_get(ob_ref.object); } else { - /* TODO */ + batches = DRW_cache_object_surface_material_get( + ob_ref.object, get_dummy_gpu_materials(material_count), material_count); + } + + if (batches) { + for (auto i : IndexRange(material_count)) { + if (batches[i] == nullptr) { + continue; + } + + Material mat = get_material(ob_ref, object_state.color_type, i); + has_transparent_material = has_transparent_material || mat.is_transparent(); + + ::Image *image = nullptr; + ImageUser *iuser = nullptr; + GPUSamplerState sampler_state = GPUSamplerState::default_sampler(); + if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) { + get_material_image(ob_ref.object, i + 1, image, iuser, sampler_state); + } + + draw_mesh(ob_ref, mat, batches[i], handle, image, sampler_state, iuser); + } } } else { - if (object_state.use_per_material_batches) { - const int material_count = DRW_cache_object_material_count_get(ob_ref.object); - - GPUBatch **batches; - if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) { - batches = DRW_cache_mesh_surface_texpaint_get(ob_ref.object); + GPUBatch *batch; + if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) { + batch = DRW_cache_mesh_surface_texpaint_single_get(ob_ref.object); + } + else if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) { + if (ob_ref.object->mode & OB_MODE_VERTEX_PAINT) { + batch = DRW_cache_mesh_surface_vertpaint_get(ob_ref.object); } else { - batches = DRW_cache_object_surface_material_get( - ob_ref.object, get_dummy_gpu_materials(material_count), material_count); - } - - if (batches) { - for (auto i : IndexRange(material_count)) { - if (batches[i] == nullptr) { - continue; - } - - Material mat = get_material(ob_ref, object_state.color_type, i); - has_transparent_material = has_transparent_material || mat.is_transparent(); - - ::Image *image = nullptr; - ImageUser *iuser = nullptr; - GPUSamplerState sampler_state = GPUSamplerState::default_sampler(); - if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) { - get_material_image(ob_ref.object, i + 1, image, iuser, sampler_state); - } - - draw_mesh(ob_ref, mat, batches[i], handle, image, sampler_state, iuser); - } + batch = DRW_cache_mesh_surface_sculptcolors_get(ob_ref.object); } } else { - GPUBatch *batch; - if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) { - batch = DRW_cache_mesh_surface_texpaint_single_get(ob_ref.object); - } - else if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) { - if (ob_ref.object->mode & OB_MODE_VERTEX_PAINT) { - batch = DRW_cache_mesh_surface_vertpaint_get(ob_ref.object); - } - else { - batch = DRW_cache_mesh_surface_sculptcolors_get(ob_ref.object); - } - } - else { - batch = DRW_cache_object_surface_get(ob_ref.object); - } + batch = DRW_cache_object_surface_get(ob_ref.object); + } - if (batch) { - Material mat = get_material(ob_ref, object_state.color_type); - has_transparent_material = has_transparent_material || mat.is_transparent(); + if (batch) { + Material mat = get_material(ob_ref, object_state.color_type); + has_transparent_material = has_transparent_material || mat.is_transparent(); - draw_mesh(ob_ref, - mat, - batch, - handle, - object_state.image_paint_override, - object_state.override_sampler_state); - } + draw_mesh(ob_ref, + mat, + batch, + handle, + object_state.image_paint_override, + object_state.override_sampler_state); } } @@ -341,6 +319,45 @@ class Instance { } } + void sculpt_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state) + { + ResourceHandle handle = manager.resource_handle(ob_ref); + + if (object_state.use_per_material_batches) { + const int material_count = DRW_cache_object_material_count_get(ob_ref.object); + for (SculptBatch &batch : sculpt_batches_per_material_get( + ob_ref.object, {get_dummy_gpu_materials(material_count), material_count})) + { + Material mat = get_material(ob_ref, object_state.color_type, batch.material_slot); + draw_mesh(ob_ref, + mat, + batch.batch, + handle, + object_state.image_paint_override, + object_state.override_sampler_state); + } + } + else { + Material mat = get_material(ob_ref, object_state.color_type); + SculptBatchFeature features = SCULPT_BATCH_DEFAULT; + if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) { + features = SCULPT_BATCH_VERTEX_COLOR; + } + else if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) { + features = SCULPT_BATCH_UV; + } + + for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, features)) { + draw_mesh(ob_ref, + mat, + batch.batch, + handle, + object_state.image_paint_override, + object_state.override_sampler_state); + } + } + } + void draw(Manager &manager, GPUTexture *depth_tx, GPUTexture *color_tx) { view.sync(DRW_view_default_get()); diff --git a/source/blender/draw/intern/draw_sculpt.cc b/source/blender/draw/intern/draw_sculpt.cc index 49ca6c3378f..616630f0caf 100644 --- a/source/blender/draw/intern/draw_sculpt.cc +++ b/source/blender/draw/intern/draw_sculpt.cc @@ -6,6 +6,7 @@ #include "draw_sculpt.hh" +#include "draw_attributes.hh" #include "draw_pbvh.h" #include "BKE_paint.h" @@ -129,8 +130,7 @@ static Vector sculpt_batches_get_ex( return data.batches; } -Vector sculpt_batches_get( - Object *ob, bool use_wire, bool use_mask, bool use_fset, bool use_color, bool use_uv) +Vector sculpt_batches_get(Object *ob, SculptBatchFeature features) { PBVHAttrReq attrs[16] = {0}; int attrs_len = 0; @@ -139,31 +139,31 @@ Vector sculpt_batches_get( attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_CO_TYPE; attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_NO_TYPE; - if (use_mask) { + if (features & SCULPT_BATCH_MASK) { attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_MASK_TYPE; } - if (use_fset) { + if (features & SCULPT_BATCH_FSET) { attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_FSET_TYPE; } - Mesh *me = BKE_object_get_original_mesh(ob); + Mesh *mesh = BKE_object_get_original_mesh(ob); - if (use_color) { - const CustomDataLayer *layer = BKE_id_attributes_color_find(&me->id, - me->active_color_attribute); + if (features & SCULPT_BATCH_VERTEX_COLOR) { + const CustomDataLayer *layer = BKE_id_attributes_color_find(&mesh->id, + mesh->active_color_attribute); if (layer) { attrs[attrs_len].type = eCustomDataType(layer->type); - attrs[attrs_len].domain = BKE_id_attribute_domain(&me->id, layer); + attrs[attrs_len].domain = BKE_id_attribute_domain(&mesh->id, layer); STRNCPY(attrs[attrs_len].name, layer->name); attrs_len++; } } - if (use_uv) { - int layer_i = CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2); + if (features & SCULPT_BATCH_UV) { + int layer_i = CustomData_get_active_layer_index(&mesh->ldata, CD_PROP_FLOAT2); if (layer_i != -1) { - CustomDataLayer *layer = me->ldata.layers + layer_i; + CustomDataLayer *layer = mesh->ldata.layers + layer_i; attrs[attrs_len].type = CD_PROP_FLOAT2; attrs[attrs_len].domain = ATTR_DOMAIN_CORNER; STRNCPY(attrs[attrs_len].name, layer->name); @@ -171,7 +171,50 @@ Vector sculpt_batches_get( } } - return sculpt_batches_get_ex(ob, use_wire, false, attrs, attrs_len); + return sculpt_batches_get_ex(ob, features & SCULPT_BATCH_WIREFRAME, false, attrs, attrs_len); +} + +Vector sculpt_batches_per_material_get(Object *ob, + MutableSpan materials) +{ + BLI_assert(ob->type == OB_MESH); + Mesh *mesh = (Mesh *)ob->data; + + DRW_Attributes draw_attrs; + DRW_MeshCDMask cd_needed; + + DRW_mesh_get_attributes(ob, mesh, materials.data(), materials.size(), &draw_attrs, &cd_needed); + + PBVHAttrReq attrs[16] = {0}; + int attrs_len = 0; + + /* NOTE: these are NOT #eCustomDataType, they are extended values, ASAN may warn about this. */ + attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_CO_TYPE; + attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_NO_TYPE; + + for (int i = 0; i < draw_attrs.num_requests; i++) { + DRW_AttributeRequest *req = draw_attrs.requests + i; + attrs[attrs_len].type = req->cd_type; + attrs[attrs_len].domain = req->domain; + STRNCPY(attrs[attrs_len].name, req->attribute_name); + attrs_len++; + } + + /* UV maps are not in attribute requests. */ + for (uint i = 0; i < 32; i++) { + if (cd_needed.uv & (1 << i)) { + int layer_i = CustomData_get_layer_index_n(&mesh->ldata, CD_PROP_FLOAT2, i); + CustomDataLayer *layer = layer_i != -1 ? mesh->ldata.layers + layer_i : nullptr; + if (layer) { + attrs[attrs_len].type = CD_PROP_FLOAT2; + attrs[attrs_len].domain = ATTR_DOMAIN_CORNER; + STRNCPY(attrs[attrs_len].name, layer->name); + attrs_len++; + } + } + } + + return sculpt_batches_get_ex(ob, false, true, attrs, attrs_len); } } // namespace blender::draw diff --git a/source/blender/draw/intern/draw_sculpt.hh b/source/blender/draw/intern/draw_sculpt.hh index 1f0a1fa699b..e407e196d40 100644 --- a/source/blender/draw/intern/draw_sculpt.hh +++ b/source/blender/draw/intern/draw_sculpt.hh @@ -15,9 +15,19 @@ struct SculptBatch { int material_slot; }; -enum class SculptBatchFeature { WIRE, MASK, FSET, VERTEX_COLOR, UV }; +enum SculptBatchFeature { + SCULPT_BATCH_DEFAULT = 0, + SCULPT_BATCH_WIREFRAME = 1 << 0, + SCULPT_BATCH_MASK = 1 << 1, + SCULPT_BATCH_FSET = 1 << 2, + SCULPT_BATCH_VERTEX_COLOR = 1 << 3, + SCULPT_BATCH_UV = 1 << 4 +}; +ENUM_OPERATORS(SculptBatchFeature, SCULPT_BATCH_UV); -Vector sculpt_batches_get( - Object *ob, bool use_wire, bool use_mask, bool use_fset, bool use_color, bool use_uv); +Vector sculpt_batches_get(Object *ob, SculptBatchFeature features); + +Vector sculpt_batches_per_material_get(Object *ob, + MutableSpan materials); } // namespace blender::draw -- 2.30.2 From 2e6409371efe700affc7175a8b466104ddca7760 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Fri, 23 Jun 2023 20:35:00 +0200 Subject: [PATCH 3/6] Code Style --- source/blender/draw/intern/draw_sculpt.cc | 14 +++++++------- source/blender/draw/intern/draw_sculpt.hh | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/draw/intern/draw_sculpt.cc b/source/blender/draw/intern/draw_sculpt.cc index 616630f0caf..e45149bee7c 100644 --- a/source/blender/draw/intern/draw_sculpt.cc +++ b/source/blender/draw/intern/draw_sculpt.cc @@ -136,15 +136,15 @@ Vector sculpt_batches_get(Object *ob, SculptBatchFeature features) int attrs_len = 0; /* NOTE: these are NOT #eCustomDataType, they are extended values, ASAN may warn about this. */ - attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_CO_TYPE; - attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_NO_TYPE; + attrs[attrs_len++].type = eCustomDataType(CD_PBVH_CO_TYPE); + attrs[attrs_len++].type = eCustomDataType(CD_PBVH_NO_TYPE); if (features & SCULPT_BATCH_MASK) { - attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_MASK_TYPE; + attrs[attrs_len++].type = eCustomDataType(CD_PBVH_MASK_TYPE); } - if (features & SCULPT_BATCH_FSET) { - attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_FSET_TYPE; + if (features & SCULPT_BATCH_FACE_SET) { + attrs[attrs_len++].type = eCustomDataType(CD_PBVH_FSET_TYPE); } Mesh *mesh = BKE_object_get_original_mesh(ob); @@ -189,8 +189,8 @@ Vector sculpt_batches_per_material_get(Object *ob, int attrs_len = 0; /* NOTE: these are NOT #eCustomDataType, they are extended values, ASAN may warn about this. */ - attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_CO_TYPE; - attrs[attrs_len++].type = (eCustomDataType)CD_PBVH_NO_TYPE; + attrs[attrs_len++].type = eCustomDataType(CD_PBVH_CO_TYPE); + attrs[attrs_len++].type = eCustomDataType(CD_PBVH_NO_TYPE); for (int i = 0; i < draw_attrs.num_requests; i++) { DRW_AttributeRequest *req = draw_attrs.requests + i; diff --git a/source/blender/draw/intern/draw_sculpt.hh b/source/blender/draw/intern/draw_sculpt.hh index e407e196d40..7617733f35d 100644 --- a/source/blender/draw/intern/draw_sculpt.hh +++ b/source/blender/draw/intern/draw_sculpt.hh @@ -19,7 +19,7 @@ enum SculptBatchFeature { SCULPT_BATCH_DEFAULT = 0, SCULPT_BATCH_WIREFRAME = 1 << 0, SCULPT_BATCH_MASK = 1 << 1, - SCULPT_BATCH_FSET = 1 << 2, + SCULPT_BATCH_FACE_SET = 1 << 2, SCULPT_BATCH_VERTEX_COLOR = 1 << 3, SCULPT_BATCH_UV = 1 << 4 }; -- 2.30.2 From fe3d0dad6de566c08323034c57a111d217ced4e2 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Fri, 23 Jun 2023 20:36:14 +0200 Subject: [PATCH 4/6] Debug Draw --- .../engines/workbench/workbench_engine.cc | 8 ++++++++ source/blender/draw/intern/draw_sculpt.cc | 19 +++++++++++++++++++ source/blender/draw/intern/draw_sculpt.hh | 4 ++++ 3 files changed, 31 insertions(+) diff --git a/source/blender/draw/engines/workbench/workbench_engine.cc b/source/blender/draw/engines/workbench/workbench_engine.cc index 12f0ad68bbe..16fb7aadd57 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.cc +++ b/source/blender/draw/engines/workbench/workbench_engine.cc @@ -329,6 +329,10 @@ class Instance { ob_ref.object, {get_dummy_gpu_materials(material_count), material_count})) { Material mat = get_material(ob_ref, object_state.color_type, batch.material_slot); + if (SCULPT_DEBUG_DRAW) { + mat.base_color = batch.debug_color(); + } + draw_mesh(ob_ref, mat, batch.batch, @@ -348,6 +352,10 @@ class Instance { } for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, features)) { + if (SCULPT_DEBUG_DRAW) { + mat.base_color = batch.debug_color(); + } + draw_mesh(ob_ref, mat, batch.batch, diff --git a/source/blender/draw/intern/draw_sculpt.cc b/source/blender/draw/intern/draw_sculpt.cc index e45149bee7c..bc985f22d00 100644 --- a/source/blender/draw/intern/draw_sculpt.cc +++ b/source/blender/draw/intern/draw_sculpt.cc @@ -15,6 +15,23 @@ namespace blender::draw { +float3 SculptBatch::debug_color() +{ + static float3 colors[9] = { + {1.0f, 0.2f, 0.2f}, + {0.2f, 1.0f, 0.2f}, + {0.2f, 0.2f, 1.0f}, + {1.0f, 1.0f, 0.2f}, + {0.2f, 1.0f, 1.0f}, + {1.0f, 0.2f, 1.0f}, + {1.0f, 0.7f, 0.2f}, + {0.2f, 1.0f, 0.7f}, + {0.7f, 0.2f, 1.0f}, + }; + + return colors[debug_index % 9]; +} + struct SculptCallbackData { bool use_wire; bool fast_mode; @@ -46,6 +63,8 @@ static void sculpt_draw_cb(SculptCallbackData *data, } batch.material_slot = drw_pbvh_material_index_get(batches); + /** NOTE: This doesn't match the index used in DRW_sculpt_debug_cb (debug_node_nr). */ + batch.debug_index = data->batches.size(); data->batches.append(batch); } diff --git a/source/blender/draw/intern/draw_sculpt.hh b/source/blender/draw/intern/draw_sculpt.hh index 7617733f35d..edc565ce558 100644 --- a/source/blender/draw/intern/draw_sculpt.hh +++ b/source/blender/draw/intern/draw_sculpt.hh @@ -10,9 +10,13 @@ namespace blender::draw { +#define SCULPT_DEBUG_DRAW (G.debug_value == 889) + struct SculptBatch { GPUBatch *batch; int material_slot; + int debug_index; + float3 debug_color(); }; enum SculptBatchFeature { -- 2.30.2 From c8fe28e031f4752a3da4bff059483ee08e596197 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Fri, 23 Jun 2023 20:36:28 +0200 Subject: [PATCH 5/6] Disable Frustum Culling --- source/blender/draw/engines/workbench/workbench_engine.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/engines/workbench/workbench_engine.cc b/source/blender/draw/engines/workbench/workbench_engine.cc index 16fb7aadd57..0f0ae56d1ba 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.cc +++ b/source/blender/draw/engines/workbench/workbench_engine.cc @@ -321,7 +321,8 @@ class Instance { void sculpt_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state) { - ResourceHandle handle = manager.resource_handle(ob_ref); + /* Disable frustum culling for sculpt meshes. */ + ResourceHandle handle = manager.resource_handle(float4x4(ob_ref.object->object_to_world)); if (object_state.use_per_material_batches) { const int material_count = DRW_cache_object_material_count_get(ob_ref.object); -- 2.30.2 From ad9f99933710e1f33710d65a8fa399f9b4bea6df Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Mon, 26 Jun 2023 11:52:32 +0200 Subject: [PATCH 6/6] Cleanup comment --- source/blender/draw/intern/draw_sculpt.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/draw/intern/draw_sculpt.cc b/source/blender/draw/intern/draw_sculpt.cc index bc985f22d00..e5bf30d44c3 100644 --- a/source/blender/draw/intern/draw_sculpt.cc +++ b/source/blender/draw/intern/draw_sculpt.cc @@ -63,7 +63,6 @@ static void sculpt_draw_cb(SculptCallbackData *data, } batch.material_slot = drw_pbvh_material_index_get(batches); - /** NOTE: This doesn't match the index used in DRW_sculpt_debug_cb (debug_node_nr). */ batch.debug_index = data->batches.size(); data->batches.append(batch); -- 2.30.2