forked from blender/blender
WIP: uv-simple-select #1
@ -46,6 +46,7 @@ struct GeometryDeformation {
|
|||||||
* function either retrieves the deformation data from the evaluated object, or falls back to
|
* function either retrieves the deformation data from the evaluated object, or falls back to
|
||||||
* returning the original data.
|
* 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,
|
GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
|
||||||
const Object &ob_orig);
|
const Object &ob_orig);
|
||||||
|
|
||||||
|
@ -596,7 +596,7 @@ void BKE_crazyspace_api_eval_clear(Object *object)
|
|||||||
|
|
||||||
namespace blender::bke::crazyspace {
|
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)
|
const Object &ob_orig)
|
||||||
{
|
{
|
||||||
BLI_assert(ob_orig.type == OB_CURVES);
|
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. */
|
/* Use the undeformed positions by default. */
|
||||||
deformation.positions = curves_orig.positions();
|
deformation.positions = curves_orig.positions();
|
||||||
|
|
||||||
const Object *ob_eval = DEG_get_evaluated_object(&depsgraph, const_cast<Object *>(&ob_orig));
|
|
||||||
if (ob_eval == nullptr) {
|
if (ob_eval == nullptr) {
|
||||||
return deformation;
|
return deformation;
|
||||||
}
|
}
|
||||||
@ -653,4 +652,11 @@ GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
|
|||||||
return deformation;
|
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<Object *>(&ob_orig));
|
||||||
|
return get_evaluated_curves_deformation(ob_eval, ob_orig);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blender::bke::crazyspace
|
} // namespace blender::bke::crazyspace
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "DEG_depsgraph_query.h"
|
#include "DEG_depsgraph_query.h"
|
||||||
|
|
||||||
|
#include "BKE_crazyspace.hh"
|
||||||
#include "BKE_curves.hh"
|
#include "BKE_curves.hh"
|
||||||
#include "BKE_geometry_set.hh"
|
#include "BKE_geometry_set.hh"
|
||||||
|
|
||||||
@ -40,11 +41,9 @@
|
|||||||
#include "draw_curves_private.hh" /* own include */
|
#include "draw_curves_private.hh" /* own include */
|
||||||
#include "draw_shader.h"
|
#include "draw_shader.h"
|
||||||
|
|
||||||
using blender::ColorGeometry4f;
|
|
||||||
using blender::float3;
|
|
||||||
using blender::IndexRange;
|
using blender::IndexRange;
|
||||||
using blender::MutableSpan;
|
|
||||||
using blender::Span;
|
namespace blender::draw {
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
/* Curves GPUBatch Cache */
|
/* Curves GPUBatch Cache */
|
||||||
@ -150,70 +149,12 @@ static void curves_batch_cache_clear(Curves &curves)
|
|||||||
curves_batch_cache_clear_edit_data(cache);
|
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)
|
static CurvesBatchCache &curves_batch_cache_get(Curves &curves)
|
||||||
{
|
{
|
||||||
DRW_curves_batch_cache_validate(&curves);
|
DRW_curves_batch_cache_validate(&curves);
|
||||||
return *static_cast<CurvesBatchCache *>(curves.batch_cache);
|
return *static_cast<CurvesBatchCache *>(curves.batch_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode)
|
|
||||||
{
|
|
||||||
CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(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<CurvesBatchCache *>(curves->batch_cache));
|
|
||||||
curves->batch_cache = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DRW_curves_batch_cache_free_old(Curves *curves, int ctime)
|
|
||||||
{
|
|
||||||
CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(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)
|
static void ensure_seg_pt_count(const Curves &curves, CurvesEvalCache &curves_cache)
|
||||||
{
|
{
|
||||||
if (curves_cache.proc_point_buf != nullptr) {
|
if (curves_cache.proc_point_buf != nullptr) {
|
||||||
@ -231,13 +172,11 @@ struct PositionAndParameter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void curves_batch_cache_fill_segments_proc_pos(
|
static void curves_batch_cache_fill_segments_proc_pos(
|
||||||
const Curves &curves_id,
|
const bke::CurvesGeometry &curves,
|
||||||
MutableSpan<PositionAndParameter> posTime_data,
|
MutableSpan<PositionAndParameter> posTime_data,
|
||||||
MutableSpan<float> hairLength_data)
|
MutableSpan<float> hairLength_data)
|
||||||
{
|
{
|
||||||
using namespace blender;
|
|
||||||
/* TODO: use hair radius layer if available. */
|
/* 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 OffsetIndices points_by_curve = curves.points_by_curve();
|
||||||
const Span<float3> positions = curves.positions();
|
const Span<float3> positions = curves.positions();
|
||||||
|
|
||||||
@ -270,7 +209,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,
|
CurvesEvalCache &cache,
|
||||||
GPUMaterial * /*gpu_material*/)
|
GPUMaterial * /*gpu_material*/)
|
||||||
{
|
{
|
||||||
@ -301,12 +240,10 @@ static void curves_batch_cache_ensure_procedural_pos(const Curves &curves,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void curves_batch_cache_ensure_edit_points_pos(const Curves &curves_id,
|
static void curves_batch_cache_ensure_edit_points_pos(const bke::CurvesGeometry &curves,
|
||||||
|
Span<float3> deformed_positions,
|
||||||
CurvesBatchCache &cache)
|
CurvesBatchCache &cache)
|
||||||
{
|
{
|
||||||
using namespace blender;
|
|
||||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
|
||||||
|
|
||||||
static GPUVertFormat format_pos = {0};
|
static GPUVertFormat format_pos = {0};
|
||||||
static uint pos;
|
static uint pos;
|
||||||
if (format_pos.attr_len == 0) {
|
if (format_pos.attr_len == 0) {
|
||||||
@ -315,17 +252,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_init_with_format(cache.edit_points_pos, &format_pos);
|
||||||
GPU_vertbuf_data_alloc(cache.edit_points_pos, curves.points_num());
|
GPU_vertbuf_data_alloc(cache.edit_points_pos, curves.points_num());
|
||||||
|
GPU_vertbuf_attr_fill(cache.edit_points_pos, pos, deformed_positions.data());
|
||||||
Span<float3> positions = curves.positions();
|
|
||||||
GPU_vertbuf_attr_fill(cache.edit_points_pos, pos, 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)
|
CurvesBatchCache &cache)
|
||||||
{
|
{
|
||||||
using namespace blender;
|
|
||||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
|
||||||
|
|
||||||
static GPUVertFormat format_data = {0};
|
static GPUVertFormat format_data = {0};
|
||||||
static uint color;
|
static uint color;
|
||||||
if (format_data.attr_len == 0) {
|
if (format_data.attr_len == 0) {
|
||||||
@ -338,8 +271,8 @@ static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id,
|
|||||||
const OffsetIndices points_by_curve = curves.points_by_curve();
|
const OffsetIndices points_by_curve = curves.points_by_curve();
|
||||||
|
|
||||||
const VArray<bool> selection = curves.attributes().lookup_or_default<bool>(
|
const VArray<bool> selection = curves.attributes().lookup_or_default<bool>(
|
||||||
".selection", eAttrDomain(curves_id.selection_domain), true);
|
".selection", selection_domain, true);
|
||||||
switch (curves_id.selection_domain) {
|
switch (selection_domain) {
|
||||||
case ATTR_DOMAIN_POINT:
|
case ATTR_DOMAIN_POINT:
|
||||||
for (const int point_i : selection.index_range()) {
|
for (const int point_i : selection.index_range()) {
|
||||||
const float point_selection = selection[point_i] ? 1.0f : 0.0f;
|
const float point_selection = selection[point_i] ? 1.0f : 0.0f;
|
||||||
@ -355,14 +288,14 @@ static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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 vert_len = curves.points_num();
|
||||||
const int curve_len = curves.curves_num();
|
const int curve_len = curves.curves_num();
|
||||||
const int index_len = vert_len + curve_len;
|
const int index_len = vert_len + curve_len;
|
||||||
@ -383,14 +316,6 @@ static void curves_batch_cache_ensure_edit_lines(const Curves &curves_id, Curves
|
|||||||
GPU_indexbuf_build_in_place(&elb, cache.edit_lines_ibo);
|
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,
|
static void curves_batch_cache_ensure_procedural_final_attr(CurvesEvalCache &cache,
|
||||||
const GPUVertFormat *format,
|
const GPUVertFormat *format,
|
||||||
const int subdiv,
|
const int subdiv,
|
||||||
@ -413,7 +338,6 @@ static void curves_batch_ensure_attribute(const Curves &curves,
|
|||||||
const int subdiv,
|
const int subdiv,
|
||||||
const int index)
|
const int index)
|
||||||
{
|
{
|
||||||
using namespace blender;
|
|
||||||
GPU_VERTBUF_DISCARD_SAFE(cache.proc_attributes_buf[index]);
|
GPU_VERTBUF_DISCARD_SAFE(cache.proc_attributes_buf[index]);
|
||||||
|
|
||||||
char sampler_name[32];
|
char sampler_name[32];
|
||||||
@ -458,11 +382,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 &data_step,
|
||||||
GPUVertBufRaw &seg_step)
|
GPUVertBufRaw &seg_step)
|
||||||
{
|
{
|
||||||
const blender::bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
|
||||||
const blender::OffsetIndices points_by_curve = curves.points_by_curve();
|
const blender::OffsetIndices points_by_curve = curves.points_by_curve();
|
||||||
|
|
||||||
for (const int i : IndexRange(curves.curves_num())) {
|
for (const int i : IndexRange(curves.curves_num())) {
|
||||||
@ -473,7 +396,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)
|
CurvesEvalCache &cache)
|
||||||
{
|
{
|
||||||
GPUVertBufRaw data_step, seg_step;
|
GPUVertBufRaw data_step, seg_step;
|
||||||
@ -513,15 +436,12 @@ static void curves_batch_cache_ensure_procedural_final_points(CurvesEvalCache &c
|
|||||||
cache.final[subdiv].strands_res * cache.strands_len);
|
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,
|
const int res,
|
||||||
GPUIndexBufBuilder &elb)
|
GPUIndexBufBuilder &elb)
|
||||||
{
|
{
|
||||||
const int curves_num = curves.geometry.curve_num;
|
|
||||||
|
|
||||||
uint curr_point = 0;
|
uint curr_point = 0;
|
||||||
|
for ([[maybe_unused]] const int i : IndexRange(curves.curves_num())) {
|
||||||
for ([[maybe_unused]] const int i : IndexRange(curves_num)) {
|
|
||||||
for (int k = 0; k < res; k++) {
|
for (int k = 0; k < res; k++) {
|
||||||
GPU_indexbuf_add_generic_vert(&elb, curr_point++);
|
GPU_indexbuf_add_generic_vert(&elb, curr_point++);
|
||||||
}
|
}
|
||||||
@ -529,7 +449,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,
|
CurvesEvalCache &cache,
|
||||||
const int thickness_res,
|
const int thickness_res,
|
||||||
const int subdiv)
|
const int subdiv)
|
||||||
@ -624,64 +544,6 @@ static bool curves_ensure_attributes(const Curves &curves,
|
|||||||
return need_tf_update;
|
return need_tf_update;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool curves_ensure_procedural_data(Curves *curves,
|
|
||||||
CurvesEvalCache **r_hair_cache,
|
|
||||||
GPUMaterial *gpu_material,
|
|
||||||
const int subdiv,
|
|
||||||
const int thickness_res)
|
|
||||||
{
|
|
||||||
bool need_ft_update = false;
|
|
||||||
|
|
||||||
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
|
||||||
*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, 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, cache, gpu_material, subdiv);
|
|
||||||
|
|
||||||
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)
|
static void request_attribute(Curves &curves, const char *name)
|
||||||
{
|
{
|
||||||
CurvesBatchCache &cache = curves_batch_cache_get(curves);
|
CurvesBatchCache &cache = curves_batch_cache_get(curves);
|
||||||
@ -709,10 +571,145 @@ static void request_attribute(Curves &curves, const char *name)
|
|||||||
drw_attributes_merge(&final_cache.attr_used, &attributes, cache.render_mutex);
|
drw_attributes_merge(&final_cache.attr_used, &attributes, cache.render_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // 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;
|
||||||
|
CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(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<CurvesBatchCache *>(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<CurvesBatchCache *>(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,
|
GPUVertBuf **DRW_curves_texture_for_evaluated_attribute(Curves *curves,
|
||||||
const char *name,
|
const char *name,
|
||||||
bool *r_is_point_domain)
|
bool *r_is_point_domain)
|
||||||
{
|
{
|
||||||
|
using namespace blender::draw;
|
||||||
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
||||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||||
const Scene *scene = draw_ctx->scene;
|
const Scene *scene = draw_ctx->scene;
|
||||||
@ -747,11 +744,19 @@ GPUVertBuf **DRW_curves_texture_for_evaluated_attribute(Curves *curves,
|
|||||||
|
|
||||||
void DRW_curves_batch_cache_create_requested(Object *ob)
|
void DRW_curves_batch_cache_create_requested(Object *ob)
|
||||||
{
|
{
|
||||||
Curves *curves = static_cast<Curves *>(ob->data);
|
using namespace blender;
|
||||||
Object *orig = DEG_get_original_object(ob);
|
Curves *curves_id = static_cast<Curves *>(ob->data);
|
||||||
Curves *curves_orig = static_cast<Curves *>(orig->data);
|
Object *ob_orig = DEG_get_original_object(ob);
|
||||||
|
if (ob_orig == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Curves *curves_orig_id = static_cast<Curves *>(ob_orig->data);
|
||||||
|
|
||||||
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
draw::CurvesBatchCache &cache = draw::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)) {
|
if (DRW_batch_requested(cache.edit_points, GPU_PRIM_POINTS)) {
|
||||||
DRW_vbo_request(cache.edit_points, &cache.edit_points_pos);
|
DRW_vbo_request(cache.edit_points, &cache.edit_points_pos);
|
||||||
@ -763,12 +768,13 @@ void DRW_curves_batch_cache_create_requested(Object *ob)
|
|||||||
DRW_vbo_request(cache.edit_lines, &cache.edit_points_data);
|
DRW_vbo_request(cache.edit_lines, &cache.edit_points_data);
|
||||||
}
|
}
|
||||||
if (DRW_vbo_requested(cache.edit_points_pos)) {
|
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.positions, cache);
|
||||||
}
|
}
|
||||||
if (DRW_vbo_requested(cache.edit_points_data)) {
|
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)) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user