From 1e832832fcc25a7b4ce9dfb84622619ebfc42ce9 Mon Sep 17 00:00:00 2001 From: Falk David Date: Mon, 13 Feb 2023 17:34:16 +0100 Subject: [PATCH 1/4] Curves: Use deformed points in overlay (crazyspace) --- source/blender/blenkernel/BKE_crazyspace.hh | 1 + .../blender/blenkernel/intern/crazyspace.cc | 10 ++- .../draw/intern/draw_cache_impl_curves.cc | 89 +++++++++---------- 3 files changed, 52 insertions(+), 48 deletions(-) diff --git a/source/blender/blenkernel/BKE_crazyspace.hh b/source/blender/blenkernel/BKE_crazyspace.hh index 5f206bcefb2..36b15dcb590 100644 --- a/source/blender/blenkernel/BKE_crazyspace.hh +++ b/source/blender/blenkernel/BKE_crazyspace.hh @@ -46,6 +46,7 @@ struct GeometryDeformation { * function either retrieves the deformation data from the evaluated object, or falls back to * returning the original data. */ +GeometryDeformation get_evaluated_curves_deformation(const Object *ob_eval, const Object &ob_orig); GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph, const Object &ob_orig); diff --git a/source/blender/blenkernel/intern/crazyspace.cc b/source/blender/blenkernel/intern/crazyspace.cc index d56aeeb7940..703454fef1c 100644 --- a/source/blender/blenkernel/intern/crazyspace.cc +++ b/source/blender/blenkernel/intern/crazyspace.cc @@ -596,7 +596,7 @@ void BKE_crazyspace_api_eval_clear(Object *object) namespace blender::bke::crazyspace { -GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph, +GeometryDeformation get_evaluated_curves_deformation(const Object *ob_eval, const Object &ob_orig) { BLI_assert(ob_orig.type == OB_CURVES); @@ -608,7 +608,6 @@ GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph, /* Use the undeformed positions by default. */ deformation.positions = curves_orig.positions(); - const Object *ob_eval = DEG_get_evaluated_object(&depsgraph, const_cast(&ob_orig)); if (ob_eval == nullptr) { return deformation; } @@ -653,4 +652,11 @@ GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph, return deformation; } +GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph, + const Object &ob_orig) +{ + const Object *ob_eval = DEG_get_evaluated_object(&depsgraph, const_cast(&ob_orig)); + return get_evaluated_curves_deformation(ob_eval, ob_orig); +} + } // namespace blender::bke::crazyspace diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index 22e1eb3ece5..2a18b77ee88 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -25,6 +25,7 @@ #include "DEG_depsgraph_query.h" +#include "BKE_crazyspace.hh" #include "BKE_curves.hh" #include "BKE_geometry_set.hh" @@ -74,6 +75,8 @@ struct CurvesBatchCache { std::mutex render_mutex; }; +using namespace blender; + static bool curves_batch_cache_valid(const Curves &curves) { const CurvesBatchCache *cache = static_cast(curves.batch_cache); @@ -231,13 +234,11 @@ struct PositionAndParameter { }; static void curves_batch_cache_fill_segments_proc_pos( - const Curves &curves_id, + const bke::CurvesGeometry &curves, MutableSpan posTime_data, MutableSpan hairLength_data) { - using namespace blender; /* TODO: use hair radius layer if available. */ - const bke::CurvesGeometry &curves = curves_id.geometry.wrap(); const OffsetIndices points_by_curve = curves.points_by_curve(); const Span positions = curves.positions(); @@ -270,7 +271,7 @@ static void curves_batch_cache_fill_segments_proc_pos( }); } -static void curves_batch_cache_ensure_procedural_pos(const Curves &curves, +static void curves_batch_cache_ensure_procedural_pos(const bke::CurvesGeometry &curves, CurvesEvalCache &cache, GPUMaterial * /*gpu_material*/) { @@ -301,12 +302,11 @@ static void curves_batch_cache_ensure_procedural_pos(const Curves &curves, } } -static void curves_batch_cache_ensure_edit_points_pos(const Curves &curves_id, - CurvesBatchCache &cache) +static void curves_batch_cache_ensure_edit_points_pos( + const bke::CurvesGeometry &curves, + const bke::crazyspace::GeometryDeformation &deformation, + CurvesBatchCache &cache) { - using namespace blender; - const bke::CurvesGeometry &curves = curves_id.geometry.wrap(); - static GPUVertFormat format_pos = {0}; static uint pos; if (format_pos.attr_len == 0) { @@ -315,17 +315,13 @@ static void curves_batch_cache_ensure_edit_points_pos(const Curves &curves_id, GPU_vertbuf_init_with_format(cache.edit_points_pos, &format_pos); GPU_vertbuf_data_alloc(cache.edit_points_pos, curves.points_num()); - - Span positions = curves.positions(); - GPU_vertbuf_attr_fill(cache.edit_points_pos, pos, positions.data()); + GPU_vertbuf_attr_fill(cache.edit_points_pos, pos, deformation.positions.data()); } -static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id, +static void curves_batch_cache_ensure_edit_points_data(const bke::CurvesGeometry &curves, + const eAttrDomain selection_domain, CurvesBatchCache &cache) { - using namespace blender; - const bke::CurvesGeometry &curves = curves_id.geometry.wrap(); - static GPUVertFormat format_data = {0}; static uint color; if (format_data.attr_len == 0) { @@ -338,8 +334,8 @@ static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id, const OffsetIndices points_by_curve = curves.points_by_curve(); const VArray selection = curves.attributes().lookup_or_default( - ".selection", eAttrDomain(curves_id.selection_domain), true); - switch (curves_id.selection_domain) { + ".selection", selection_domain, true); + switch (selection_domain) { case ATTR_DOMAIN_POINT: for (const int point_i : selection.index_range()) { const float point_selection = selection[point_i] ? 1.0f : 0.0f; @@ -355,14 +351,14 @@ static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id, } } break; + default: + break; } } -static void curves_batch_cache_ensure_edit_lines(const Curves &curves_id, CurvesBatchCache &cache) +static void curves_batch_cache_ensure_edit_lines(const bke::CurvesGeometry &curves, + CurvesBatchCache &cache) { - using namespace blender; - const bke::CurvesGeometry &curves = curves_id.geometry.wrap(); - const int vert_len = curves.points_num(); const int curve_len = curves.curves_num(); const int index_len = vert_len + curve_len; @@ -413,7 +409,6 @@ static void curves_batch_ensure_attribute(const Curves &curves, const int subdiv, const int index) { - using namespace blender; GPU_VERTBUF_DISCARD_SAFE(cache.proc_attributes_buf[index]); char sampler_name[32]; @@ -458,11 +453,10 @@ static void curves_batch_ensure_attribute(const Curves &curves, } } -static void curves_batch_cache_fill_strands_data(const Curves &curves_id, +static void curves_batch_cache_fill_strands_data(const bke::CurvesGeometry &curves, GPUVertBufRaw &data_step, GPUVertBufRaw &seg_step) { - const blender::bke::CurvesGeometry &curves = curves_id.geometry.wrap(); const blender::OffsetIndices points_by_curve = curves.points_by_curve(); for (const int i : IndexRange(curves.curves_num())) { @@ -473,7 +467,7 @@ static void curves_batch_cache_fill_strands_data(const Curves &curves_id, } } -static void curves_batch_cache_ensure_procedural_strand_data(Curves &curves, +static void curves_batch_cache_ensure_procedural_strand_data(const bke::CurvesGeometry &curves, CurvesEvalCache &cache) { GPUVertBufRaw data_step, seg_step; @@ -513,15 +507,12 @@ static void curves_batch_cache_ensure_procedural_final_points(CurvesEvalCache &c cache.final[subdiv].strands_res * cache.strands_len); } -static void curves_batch_cache_fill_segments_indices(const Curves &curves, +static void curves_batch_cache_fill_segments_indices(const bke::CurvesGeometry &curves, const int res, GPUIndexBufBuilder &elb) { - const int curves_num = curves.geometry.curve_num; - uint curr_point = 0; - - for ([[maybe_unused]] const int i : IndexRange(curves_num)) { + for ([[maybe_unused]] const int i : IndexRange(curves.curves_num())) { for (int k = 0; k < res; k++) { GPU_indexbuf_add_generic_vert(&elb, curr_point++); } @@ -529,7 +520,7 @@ static void curves_batch_cache_fill_segments_indices(const Curves &curves, } } -static void curves_batch_cache_ensure_procedural_indices(Curves &curves, +static void curves_batch_cache_ensure_procedural_indices(const bke::CurvesGeometry &curves, CurvesEvalCache &cache, const int thickness_res, const int subdiv) @@ -624,15 +615,16 @@ static bool curves_ensure_attributes(const Curves &curves, return need_tf_update; } -bool curves_ensure_procedural_data(Curves *curves, +bool curves_ensure_procedural_data(Curves *curves_id, CurvesEvalCache **r_hair_cache, GPUMaterial *gpu_material, const int subdiv, const int thickness_res) { + bke::CurvesGeometry &curves = curves_id->geometry.wrap(); bool need_ft_update = false; - CurvesBatchCache &cache = curves_batch_cache_get(*curves); + CurvesBatchCache &cache = curves_batch_cache_get(*curves_id); *r_hair_cache = &cache.curves_cache; const int steps = 3; /* TODO: don't hard-code? */ @@ -640,14 +632,14 @@ bool curves_ensure_procedural_data(Curves *curves, /* Refreshed on combing and simulation. */ if ((*r_hair_cache)->proc_point_buf == nullptr) { - ensure_seg_pt_count(*curves, cache.curves_cache); - curves_batch_cache_ensure_procedural_pos(*curves, cache.curves_cache, gpu_material); + ensure_seg_pt_count(*curves_id, cache.curves_cache); + curves_batch_cache_ensure_procedural_pos(curves, cache.curves_cache, gpu_material); need_ft_update = true; } /* Refreshed if active layer or custom data changes. */ if ((*r_hair_cache)->proc_strand_buf == nullptr) { - curves_batch_cache_ensure_procedural_strand_data(*curves, cache.curves_cache); + curves_batch_cache_ensure_procedural_strand_data(curves, cache.curves_cache); } /* Refreshed only on subdiv count change. */ @@ -657,10 +649,10 @@ bool curves_ensure_procedural_data(Curves *curves, } if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] == nullptr) { curves_batch_cache_ensure_procedural_indices( - *curves, cache.curves_cache, thickness_res, subdiv); + curves, cache.curves_cache, thickness_res, subdiv); } - need_ft_update |= curves_ensure_attributes(*curves, cache, gpu_material, subdiv); + need_ft_update |= curves_ensure_attributes(*curves_id, cache, gpu_material, subdiv); return need_ft_update; } @@ -747,11 +739,15 @@ GPUVertBuf **DRW_curves_texture_for_evaluated_attribute(Curves *curves, void DRW_curves_batch_cache_create_requested(Object *ob) { - Curves *curves = static_cast(ob->data); - Object *orig = DEG_get_original_object(ob); - Curves *curves_orig = static_cast(orig->data); + Curves *curves_id = static_cast(ob->data); + Object *ob_orig = DEG_get_original_object(ob); + Curves *curves_orig_id = static_cast(ob_orig->data); - CurvesBatchCache &cache = curves_batch_cache_get(*curves); + CurvesBatchCache &cache = curves_batch_cache_get(*curves_id); + bke::CurvesGeometry &curves_orig = curves_orig_id->geometry.wrap(); + + const bke::crazyspace::GeometryDeformation deformation = + bke::crazyspace::get_evaluated_curves_deformation(ob, *ob_orig); if (DRW_batch_requested(cache.edit_points, GPU_PRIM_POINTS)) { DRW_vbo_request(cache.edit_points, &cache.edit_points_pos); @@ -763,12 +759,13 @@ void DRW_curves_batch_cache_create_requested(Object *ob) DRW_vbo_request(cache.edit_lines, &cache.edit_points_data); } if (DRW_vbo_requested(cache.edit_points_pos)) { - curves_batch_cache_ensure_edit_points_pos(*curves_orig, cache); + curves_batch_cache_ensure_edit_points_pos(curves_orig, deformation, cache); } if (DRW_vbo_requested(cache.edit_points_data)) { - curves_batch_cache_ensure_edit_points_data(*curves_orig, cache); + curves_batch_cache_ensure_edit_points_data( + curves_orig, eAttrDomain(curves_id->selection_domain), cache); } if (DRW_ibo_requested(cache.edit_lines_ibo)) { - curves_batch_cache_ensure_edit_lines(*curves_orig, cache); + curves_batch_cache_ensure_edit_lines(curves_orig, cache); } } -- 2.30.2 From 66b6d2c0cb1ff0d21a815bd7d862ea932c18e4e9 Mon Sep 17 00:00:00 2001 From: Falk David Date: Mon, 13 Feb 2023 19:23:35 +0100 Subject: [PATCH 2/4] Cleanup --- .../draw/intern/draw_cache_impl_curves.cc | 181 +++++++++--------- 1 file changed, 93 insertions(+), 88 deletions(-) diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index 2a18b77ee88..b71b8ec1408 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -41,11 +41,9 @@ #include "draw_curves_private.h" /* own include */ #include "draw_shader.h" -using blender::ColorGeometry4f; -using blender::float3; using blender::IndexRange; -using blender::MutableSpan; -using blender::Span; + +namespace blender::draw { /* ---------------------------------------------------------------------- */ /* Curves GPUBatch Cache */ @@ -75,8 +73,6 @@ struct CurvesBatchCache { std::mutex render_mutex; }; -using namespace blender; - static bool curves_batch_cache_valid(const Curves &curves) { const CurvesBatchCache *cache = static_cast(curves.batch_cache); @@ -153,70 +149,12 @@ static void curves_batch_cache_clear(Curves &curves) curves_batch_cache_clear_edit_data(cache); } -void DRW_curves_batch_cache_validate(Curves *curves) -{ - if (!curves_batch_cache_valid(*curves)) { - curves_batch_cache_clear(*curves); - curves_batch_cache_init(*curves); - } -} - static CurvesBatchCache &curves_batch_cache_get(Curves &curves) { DRW_curves_batch_cache_validate(&curves); return *static_cast(curves.batch_cache); } -void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode) -{ - CurvesBatchCache *cache = static_cast(curves->batch_cache); - if (cache == nullptr) { - return; - } - switch (mode) { - case BKE_CURVES_BATCH_DIRTY_ALL: - cache->is_dirty = true; - break; - default: - BLI_assert_unreachable(); - } -} - -void DRW_curves_batch_cache_free(Curves *curves) -{ - curves_batch_cache_clear(*curves); - MEM_delete(static_cast(curves->batch_cache)); - curves->batch_cache = nullptr; -} - -void DRW_curves_batch_cache_free_old(Curves *curves, int ctime) -{ - CurvesBatchCache *cache = static_cast(curves->batch_cache); - if (cache == nullptr) { - return; - } - - bool do_discard = false; - - for (const int i : IndexRange(MAX_HAIR_SUBDIV)) { - CurvesEvalFinalCache &final_cache = cache->curves_cache.final[i]; - - if (drw_attributes_overlap(&final_cache.attr_used_over_time, &final_cache.attr_used)) { - final_cache.last_attr_matching_time = ctime; - } - - if (ctime - final_cache.last_attr_matching_time > U.vbotimeout) { - do_discard = true; - } - - drw_attributes_clear(&final_cache.attr_used_over_time); - } - - if (do_discard) { - curves_discard_attributes(cache->curves_cache); - } -} - static void ensure_seg_pt_count(const Curves &curves, CurvesEvalCache &curves_cache) { if (curves_cache.proc_point_buf != nullptr) { @@ -302,10 +240,9 @@ static void curves_batch_cache_ensure_procedural_pos(const bke::CurvesGeometry & } } -static void curves_batch_cache_ensure_edit_points_pos( - const bke::CurvesGeometry &curves, - const bke::crazyspace::GeometryDeformation &deformation, - CurvesBatchCache &cache) +static void curves_batch_cache_ensure_edit_points_pos(const bke::CurvesGeometry &curves, + Span deformed_positions, + CurvesBatchCache &cache) { static GPUVertFormat format_pos = {0}; static uint pos; @@ -315,7 +252,7 @@ static void curves_batch_cache_ensure_edit_points_pos( GPU_vertbuf_init_with_format(cache.edit_points_pos, &format_pos); GPU_vertbuf_data_alloc(cache.edit_points_pos, curves.points_num()); - GPU_vertbuf_attr_fill(cache.edit_points_pos, pos, deformation.positions.data()); + GPU_vertbuf_attr_fill(cache.edit_points_pos, pos, deformed_positions.data()); } static void curves_batch_cache_ensure_edit_points_data(const bke::CurvesGeometry &curves, @@ -657,23 +594,6 @@ bool curves_ensure_procedural_data(Curves *curves_id, return need_ft_update; } -int DRW_curves_material_count_get(Curves *curves) -{ - return max_ii(1, curves->totcol); -} - -GPUBatch *DRW_curves_batch_cache_get_edit_points(Curves *curves) -{ - CurvesBatchCache &cache = curves_batch_cache_get(*curves); - return DRW_batch_request(&cache.edit_points); -} - -GPUBatch *DRW_curves_batch_cache_get_edit_lines(Curves *curves) -{ - CurvesBatchCache &cache = curves_batch_cache_get(*curves); - return DRW_batch_request(&cache.edit_lines); -} - static void request_attribute(Curves &curves, const char *name) { CurvesBatchCache &cache = curves_batch_cache_get(curves); @@ -701,10 +621,94 @@ static void request_attribute(Curves &curves, const char *name) drw_attributes_merge(&final_cache.attr_used, &attributes, cache.render_mutex); } +} // namespace blender::draw + +void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode) +{ + using namespace blender::draw; + CurvesBatchCache *cache = static_cast(curves->batch_cache); + if (cache == nullptr) { + return; + } + switch (mode) { + case BKE_CURVES_BATCH_DIRTY_ALL: + cache->is_dirty = true; + break; + default: + BLI_assert_unreachable(); + } +} + +void DRW_curves_batch_cache_validate(Curves *curves) +{ + using namespace blender::draw; + if (!curves_batch_cache_valid(*curves)) { + curves_batch_cache_clear(*curves); + curves_batch_cache_init(*curves); + } +} + +void DRW_curves_batch_cache_free(Curves *curves) +{ + using namespace blender::draw; + curves_batch_cache_clear(*curves); + MEM_delete(static_cast(curves->batch_cache)); + curves->batch_cache = nullptr; +} + +void DRW_curves_batch_cache_free_old(Curves *curves, int ctime) +{ + using namespace blender::draw; + CurvesBatchCache *cache = static_cast(curves->batch_cache); + if (cache == nullptr) { + return; + } + + bool do_discard = false; + + for (const int i : IndexRange(MAX_HAIR_SUBDIV)) { + CurvesEvalFinalCache &final_cache = cache->curves_cache.final[i]; + + if (drw_attributes_overlap(&final_cache.attr_used_over_time, &final_cache.attr_used)) { + final_cache.last_attr_matching_time = ctime; + } + + if (ctime - final_cache.last_attr_matching_time > U.vbotimeout) { + do_discard = true; + } + + drw_attributes_clear(&final_cache.attr_used_over_time); + } + + if (do_discard) { + curves_discard_attributes(cache->curves_cache); + } +} + +int DRW_curves_material_count_get(Curves *curves) +{ + return max_ii(1, curves->totcol); +} + +GPUBatch *DRW_curves_batch_cache_get_edit_points(Curves *curves) +{ + using namespace blender::draw; + CurvesBatchCache &cache = curves_batch_cache_get(*curves); + return DRW_batch_request(&cache.edit_points); +} + +GPUBatch *DRW_curves_batch_cache_get_edit_lines(Curves *curves) +{ + using namespace blender::draw; + CurvesBatchCache &cache = curves_batch_cache_get(*curves); + return DRW_batch_request(&cache.edit_lines); +} + GPUVertBuf **DRW_curves_texture_for_evaluated_attribute(Curves *curves, const char *name, bool *r_is_point_domain) { + using namespace blender::draw; CurvesBatchCache &cache = curves_batch_cache_get(*curves); const DRWContextState *draw_ctx = DRW_context_state_get(); const Scene *scene = draw_ctx->scene; @@ -739,11 +743,12 @@ GPUVertBuf **DRW_curves_texture_for_evaluated_attribute(Curves *curves, void DRW_curves_batch_cache_create_requested(Object *ob) { + using namespace blender; Curves *curves_id = static_cast(ob->data); Object *ob_orig = DEG_get_original_object(ob); Curves *curves_orig_id = static_cast(ob_orig->data); - CurvesBatchCache &cache = curves_batch_cache_get(*curves_id); + draw::CurvesBatchCache &cache = draw::curves_batch_cache_get(*curves_id); bke::CurvesGeometry &curves_orig = curves_orig_id->geometry.wrap(); const bke::crazyspace::GeometryDeformation deformation = @@ -759,7 +764,7 @@ void DRW_curves_batch_cache_create_requested(Object *ob) DRW_vbo_request(cache.edit_lines, &cache.edit_points_data); } if (DRW_vbo_requested(cache.edit_points_pos)) { - curves_batch_cache_ensure_edit_points_pos(curves_orig, deformation, cache); + curves_batch_cache_ensure_edit_points_pos(curves_orig, deformation.positions, cache); } if (DRW_vbo_requested(cache.edit_points_data)) { curves_batch_cache_ensure_edit_points_data( -- 2.30.2 From 2418400a3eb59bbd5dd72224ae1e07d8289e2a74 Mon Sep 17 00:00:00 2001 From: Falk David Date: Mon, 13 Feb 2023 19:33:12 +0100 Subject: [PATCH 3/4] Fix linker error --- .../draw/intern/draw_cache_impl_curves.cc | 101 +++++++++--------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index b71b8ec1408..f1b91dbb374 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -316,14 +316,6 @@ static void curves_batch_cache_ensure_edit_lines(const bke::CurvesGeometry &curv GPU_indexbuf_build_in_place(&elb, cache.edit_lines_ibo); } -void drw_curves_get_attribute_sampler_name(const char *layer_name, char r_sampler_name[32]) -{ - char attr_safe_name[GPU_MAX_SAFE_ATTR_NAME]; - GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME); - /* Attributes use auto-name. */ - BLI_snprintf(r_sampler_name, 32, "a%s", attr_safe_name); -} - static void curves_batch_cache_ensure_procedural_final_attr(CurvesEvalCache &cache, const GPUVertFormat *format, const int subdiv, @@ -552,48 +544,6 @@ static bool curves_ensure_attributes(const Curves &curves, return need_tf_update; } -bool curves_ensure_procedural_data(Curves *curves_id, - CurvesEvalCache **r_hair_cache, - GPUMaterial *gpu_material, - const int subdiv, - const int thickness_res) -{ - bke::CurvesGeometry &curves = curves_id->geometry.wrap(); - bool need_ft_update = false; - - CurvesBatchCache &cache = curves_batch_cache_get(*curves_id); - *r_hair_cache = &cache.curves_cache; - - const int steps = 3; /* TODO: don't hard-code? */ - (*r_hair_cache)->final[subdiv].strands_res = 1 << (steps + subdiv); - - /* Refreshed on combing and simulation. */ - if ((*r_hair_cache)->proc_point_buf == nullptr) { - ensure_seg_pt_count(*curves_id, cache.curves_cache); - curves_batch_cache_ensure_procedural_pos(curves, cache.curves_cache, gpu_material); - need_ft_update = true; - } - - /* Refreshed if active layer or custom data changes. */ - if ((*r_hair_cache)->proc_strand_buf == nullptr) { - curves_batch_cache_ensure_procedural_strand_data(curves, cache.curves_cache); - } - - /* Refreshed only on subdiv count change. */ - if ((*r_hair_cache)->final[subdiv].proc_buf == nullptr) { - curves_batch_cache_ensure_procedural_final_points(cache.curves_cache, subdiv); - need_ft_update = true; - } - if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] == nullptr) { - curves_batch_cache_ensure_procedural_indices( - curves, cache.curves_cache, thickness_res, subdiv); - } - - need_ft_update |= curves_ensure_attributes(*curves_id, cache, gpu_material, subdiv); - - return need_ft_update; -} - static void request_attribute(Curves &curves, const char *name) { CurvesBatchCache &cache = curves_batch_cache_get(curves); @@ -623,6 +573,57 @@ static void request_attribute(Curves &curves, const char *name) } // namespace blender::draw +void drw_curves_get_attribute_sampler_name(const char *layer_name, char r_sampler_name[32]) +{ + char attr_safe_name[GPU_MAX_SAFE_ATTR_NAME]; + GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME); + /* Attributes use auto-name. */ + BLI_snprintf(r_sampler_name, 32, "a%s", attr_safe_name); +} + +bool curves_ensure_procedural_data(Curves *curves_id, + CurvesEvalCache **r_hair_cache, + GPUMaterial *gpu_material, + const int subdiv, + const int thickness_res) +{ + using namespace blender; + bke::CurvesGeometry &curves = curves_id->geometry.wrap(); + bool need_ft_update = false; + + draw::CurvesBatchCache &cache = draw::curves_batch_cache_get(*curves_id); + *r_hair_cache = &cache.curves_cache; + + const int steps = 3; /* TODO: don't hard-code? */ + (*r_hair_cache)->final[subdiv].strands_res = 1 << (steps + subdiv); + + /* Refreshed on combing and simulation. */ + if ((*r_hair_cache)->proc_point_buf == nullptr) { + draw::ensure_seg_pt_count(*curves_id, cache.curves_cache); + draw::curves_batch_cache_ensure_procedural_pos(curves, cache.curves_cache, gpu_material); + need_ft_update = true; + } + + /* Refreshed if active layer or custom data changes. */ + if ((*r_hair_cache)->proc_strand_buf == nullptr) { + draw::curves_batch_cache_ensure_procedural_strand_data(curves, cache.curves_cache); + } + + /* Refreshed only on subdiv count change. */ + if ((*r_hair_cache)->final[subdiv].proc_buf == nullptr) { + draw::curves_batch_cache_ensure_procedural_final_points(cache.curves_cache, subdiv); + need_ft_update = true; + } + if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] == nullptr) { + draw::curves_batch_cache_ensure_procedural_indices( + curves, cache.curves_cache, thickness_res, subdiv); + } + + need_ft_update |= draw::curves_ensure_attributes(*curves_id, cache, gpu_material, subdiv); + + return need_ft_update; +} + void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode) { using namespace blender::draw; -- 2.30.2 From c88db3057633dc517ae2312e6c7a04beab0b7366 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 14 Feb 2023 16:31:09 +0100 Subject: [PATCH 4/4] Null pointer check --- source/blender/draw/intern/draw_cache_impl_curves.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index f1b91dbb374..07d7f795a62 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -747,6 +747,9 @@ void DRW_curves_batch_cache_create_requested(Object *ob) using namespace blender; Curves *curves_id = static_cast(ob->data); Object *ob_orig = DEG_get_original_object(ob); + if (ob_orig == nullptr) { + return; + } Curves *curves_orig_id = static_cast(ob_orig->data); draw::CurvesBatchCache &cache = draw::curves_batch_cache_get(*curves_id); -- 2.30.2