51#define EDIT_CURVES_NURBS_CONTROL_POINT (1u)
52#define EDIT_CURVES_BEZIER_HANDLE (1u << 1)
53#define EDIT_CURVES_ACTIVE_HANDLE (1u << 2)
56#define EDIT_CURVES_BEZIER_KNOT (1u << 3)
57#define EDIT_CURVES_HANDLE_TYPES_SHIFT (4u)
109 return (cache && cache->
is_dirty ==
false);
117 cache = MEM_new<CurvesBatchCache>(__func__);
209 for (const int i_curve : range) {
210 const IndexRange points = points_by_curve[i_curve];
212 Span<float3> curve_positions = positions.slice(points);
213 MutableSpan<PositionAndParameter> curve_posTime_data = posTime_data.slice(points);
215 float total_len = 0.0f;
216 for (const int i_point : curve_positions.index_range()) {
218 total_len += math::distance(curve_positions[i_point - 1], curve_positions[i_point]);
220 curve_posTime_data[i_point].position = curve_positions[i_point];
221 curve_posTime_data[i_point].parameter = total_len;
223 hairLength_data[i_curve] = total_len;
226 if (total_len > 0.0f) {
227 const float factor = 1.0f / total_len;
229 for (const int i_point : curve_positions.index_range()) {
230 curve_posTime_data[i_point].parameter *= factor;
269 return points_num + bezier_offsets.
total_size() * 2;
285 const bool mark_active,
286 const uint32_t fill_value,
290 const IndexRange points = points_by_curve[curve];
291 bool is_active =
false;
296 data.slice(points).fill(data_value);
309 const int points_num = points_by_curve.
total_size();
336 const IndexRange points = points_by_curve[curve];
339 const int point = points[
i];
342 const bool selected = selection[point] || selection_left[point] || selection_right[point];
343 const int bezier_point = bezier_range[
i];
362 const int points_num = positions.
size();
370 data.take_front(positions.
size()).copy_from(positions);
394 const int points_num = points_by_curve.
total_size();
401 attribute.materialize(
data.take_front(points_num));
427 const int points_num = points_by_curve.
total_size();
428 const int curves_num = points_by_curve.
size();
429 const int indices_num = points_num + curves_num;
434 for (
const int curve : range) {
435 const IndexRange points = points_by_curve[curve];
438 ibo_data[ibo_range[
i]] = points[
i];
450 const int points_num = points_by_curve.
total_size();
451 const int curves_num = points_by_curve.
size();
452 const int indices_num = points_num + curves_num * 2;
457 for (
const int curve : range) {
458 const IndexRange points = points_by_curve[curve];
461 ibo_data[ibo_range[
i]] = points[
i];
487 const int cyclic_segment_offset,
491 const IndexRange points = points_by_curve[curve];
495 const int point = points[
i];
496 curve_lines[
i] =
uint2(point, point + 1);
516 const int curves_num = points_by_curve.
size();
517 const int points_num = points_by_curve.
total_size();
518 const int non_bezier_points_num = points_num - bezier_offsets.
total_size();
519 const int non_bezier_curves_num = curves_num - bezier_curves.
size();
523 lines_num += non_bezier_points_num;
525 lines_num += non_bezier_curves_num;
534 int cyclic_segment_offset = 0;
535 extract_curve_lines(points_by_curve, cyclic, catmull_rom_curves, cyclic_segment_offset, lines);
536 cyclic_segment_offset += catmull_rom_curves.
size();
539 cyclic_segment_offset += catmull_rom_curves.
size();
546 handle_range_left(non_bezier_points_num, bezier_offsets).shift(non_bezier_curves_num));
548 handle_range_right(non_bezier_points_num, bezier_offsets).shift(non_bezier_curves_num));
551 const IndexRange points = points_by_curve[curve];
554 const int point = points[
i];
555 const int bezier_point = bezier_point_range[
i];
556 lines_left[bezier_point] =
uint2(handles_left[bezier_point], point);
557 lines_right[bezier_point] =
uint2(handles_right[bezier_point], point);
585 bool &r_is_point_domain)
602 r_is_point_domain =
false;
617 char sampler_name[32];
691 point_len =
max_ii(1, point_len);
698 const int thickness_res)
707 if (use_strip_prims) {
750 std::optional<bke::AttrDomain> domain;
814 if (layer != -1 && !name.
is_empty() && domain.has_value()) {
819 if (layer != -1 && domain.has_value()) {
840 if (layer != -1 && domain.has_value()) {
861 bool need_tf_update =
false;
870 need_tf_update =
true;
874 return need_tf_update;
898 BLI_snprintf(r_sampler_name, 32,
"a%s", attr_safe_name);
905 const int thickness_res)
908 bool need_ft_update =
false;
929 need_ft_update =
true;
940 need_ft_update =
true;
950 *r_cache = &eval_cache;
951 return need_ft_update;
957 if (cache ==
nullptr) {
981 MEM_delete(batch_cache);
988 if (cache ==
nullptr) {
992 bool do_discard =
false;
1037 bool *r_is_point_domain)
1051 if (request_i == -1) {
1052 *r_is_point_domain =
false;
1056 *r_is_point_domain =
true;
1059 *r_is_point_domain =
false;
1082 if (ob_orig ==
nullptr) {
1090 bool is_edit_data_needed =
false;
1096 is_edit_data_needed =
true;
1103 is_edit_data_needed =
true;
1110 is_edit_data_needed =
true;
1138 if (!is_edit_data_needed) {
1144 const std::array<int, CURVE_TYPES_NUM> type_counts = curves_orig.
curve_type_counts();
1159 points_by_curve, bezier_curves, bezier_point_offset_data);
@ BKE_CURVES_BATCH_DIRTY_ALL
Low-level operations for curves.
Low-level operations for curves.
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_named_layer(const CustomData *data, eCustomDataType type, blender::StringRef name)
const char * CustomData_get_layer_name(const CustomData *data, eCustomDataType type, int n)
int CustomData_get_render_layer(const CustomData *data, eCustomDataType type)
#define BLI_assert_unreachable()
#define LISTBASE_FOREACH(type, var, list)
MINLINE int max_ii(int a, int b)
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
T * DEG_get_original(T *id)
Object is a sort of wrapper for general info.
blender::gpu::Batch * GPU_batch_create_ex(GPUPrimType primitive_type, blender::gpu::VertBuf *vertex_buf, blender::gpu::IndexBuf *index_buf, eGPUBatchFlag owns_flag)
#define GPU_BATCH_DISCARD_SAFE(batch)
eGPUBackendType GPU_backend_get_type()
void GPU_indexbuf_build_in_place_ex(GPUIndexBufBuilder *builder, uint index_min, uint index_max, bool uses_restart_indices, blender::gpu::IndexBuf *elem)
blender::MutableSpan< uint32_t > GPU_indexbuf_get_data(GPUIndexBufBuilder *)
#define GPU_INDEXBUF_DISCARD_SAFE(elem)
void GPU_indexbuf_init(GPUIndexBufBuilder *, GPUPrimType, uint prim_len, uint vertex_len)
blender::gpu::IndexBuf * GPU_indexbuf_build_curves_on_device(GPUPrimType prim_type, uint curves_num, uint verts_per_curve)
ListBase GPU_material_attributes(const GPUMaterial *material)
static constexpr int GPU_MAX_ATTR
void GPU_vertbuf_attr_get_raw_data(blender::gpu::VertBuf *, uint a_idx, GPUVertBufRaw *access)
GPU_INLINE void * GPU_vertbuf_raw_step(GPUVertBufRaw *a)
#define GPU_vertbuf_create_with_format(format)
blender::gpu::VertBuf * GPU_vertbuf_create_with_format_ex(const GPUVertFormat &format, GPUUsageType usage)
#define GPU_vertbuf_init_with_format(verts, format)
#define GPU_VERTBUF_DISCARD_SAFE(verts)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
@ GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY
Read Guarded memory(de)allocation.
BMesh const char void * data
IndexRange index_range() const
constexpr int64_t first() const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr int64_t start() const
constexpr IndexRange index_range() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr MutableSpan< NewT > cast() const
constexpr T & last(const int64_t n=0) const
constexpr int64_t size() const
constexpr bool is_empty() const
bool contains(StringRef attribute_id) const
GAttributeReader lookup(const StringRef attribute_id) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
VArray< int8_t > handle_types_left() const
OffsetIndices< int > points_by_curve() const
VArray< int8_t > handle_types_right() const
IndexRange curves_range() const
const std::array< int, CURVE_TYPES_NUM > & curve_type_counts() const
Span< float3 > handle_positions_left() const
Span< float3 > positions() const
OffsetIndices< int > evaluated_points_by_curve() const
Span< float3 > handle_positions_right() const
AttributeAccessor attributes() const
Span< float3 > evaluated_positions() const
VArray< int8_t > curve_types() const
VArray< bool > cyclic() const
void foreach_index(Fn &&fn) const
IndexRange index_range() const
Utilities for rendering attributes.
#define EDIT_CURVES_ACTIVE_HANDLE
#define EDIT_CURVES_HANDLE_TYPES_SHIFT
#define EDIT_CURVES_BEZIER_KNOT
#define EDIT_CURVES_BEZIER_HANDLE
#define EDIT_CURVES_NURBS_CONTROL_POINT
bool DRW_batch_requested(blender::gpu::Batch *batch, GPUPrimType prim_type)
blender::gpu::Batch * DRW_batch_request(blender::gpu::Batch **batch)
void DRW_vbo_request(blender::gpu::Batch *batch, blender::gpu::VertBuf **vbo)
bool DRW_vbo_requested(blender::gpu::VertBuf *vbo)
void DRW_ibo_request(blender::gpu::Batch *batch, blender::gpu::IndexBuf **ibo)
bool DRW_ibo_requested(blender::gpu::IndexBuf *ibo)
Mesh & DRW_object_get_data_for_drawing(const Object &object)
void gather_group_to_group(const OffsetIndices< int > src_offsets, const OffsetIndices< int > dst_offsets, const IndexMask &selection, const Span< T > src, MutableSpan< T > dst)
BooleanMix booleans_mix_calc(const VArray< bool > &varray, IndexRange range_to_check)
int64_t count_booleans(const VArray< bool > &varray)
GeometryDeformation get_evaluated_curves_deformation(const Object *ob_eval, const Object &ob_orig)
IndexMask indices_for_type(const VArray< int8_t > &types, const std::array< int, CURVE_TYPES_NUM > &type_counts, const CurveType type, const IndexMask &selection, IndexMaskMemory &memory)
void drw_attributes_add_request(VectorSet< std::string > *attrs, const StringRef name)
static void clear_eval_data(CurvesEvalCache &eval_cache)
void DRW_curves_batch_cache_validate(Curves *curves)
static void create_points_position_time_vbo(const bke::CurvesGeometry &curves, CurvesEvalCache &cache)
static void alloc_final_attribute_vbo(CurvesEvalCache &cache, const GPUVertFormat &format, const int index, const char *)
static void request_attribute(Curves &curves, const StringRef name)
static void calc_edit_handles_ibo(const OffsetIndices< int > points_by_curve, const IndexMask &catmull_rom_curves, const IndexMask &poly_curves, const IndexMask &bezier_curves, const IndexMask &nurbs_curves, const OffsetIndices< int > bezier_offsets, const VArray< bool > &cyclic, gpu::IndexBuf &ibo)
blender::gpu::Batch * DRW_curves_batch_cache_get_edit_points(Curves *curves)
static bool batch_cache_is_dirty(const Curves &curves)
static void fill_points_position_time_vbo(const OffsetIndices< int > points_by_curve, const Span< float3 > positions, MutableSpan< PositionAndParameter > posTime_data, MutableSpan< float > hairLength_data)
void DRW_curves_batch_cache_free_old(Curves *curves, int ctime)
static gpu::VertBufPtr ensure_control_point_attribute(const Curves &curves_id, const StringRef name, const GPUVertFormat &format, bool &r_is_point_domain)
static void clear_edit_data(CurvesBatchCache *cache)
static void create_edit_points_selection(const OffsetIndices< int > points_by_curve, const IndexMask &bezier_curves, const OffsetIndices< int > bezier_offsets, const bke::AttributeAccessor attributes, gpu::VertBuf &vbo)
blender::gpu::Batch * DRW_curves_batch_cache_get_edit_curves_handles(Curves *curves)
static void alloc_final_points_vbo(CurvesEvalCache &cache)
static void init_batch_cache(Curves &curves)
blender::gpu::Batch * DRW_curves_batch_cache_get_sculpt_curves_cage(Curves *curves)
void drw_attributes_merge(VectorSet< std::string > *dst, const VectorSet< std::string > *src, Mutex &render_mutex)
static void create_lines_ibo_with_cyclic(const OffsetIndices< int > points_by_curve, const Span< bool > cyclic, gpu::IndexBuf &ibo)
void drw_curves_get_attribute_sampler_name(const StringRef layer_name, char r_sampler_name[32])
static void create_curve_offsets_vbos(const OffsetIndices< int > points_by_curve, CurvesEvalCache &cache)
static void calc_final_indices(const bke::CurvesGeometry &curves, CurvesEvalCache &cache, const int thickness_res)
static void create_edit_points_position_vbo(const bke::CurvesGeometry &curves, const bke::crazyspace::GeometryDeformation &, CurvesBatchCache &cache)
static void clear_batch_cache(Curves &curves)
static CurvesBatchCache & get_batch_cache(Curves &curves)
void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode)
static uint32_t bezier_data_value(int8_t handle_type, bool is_active)
bool drw_attributes_overlap(const VectorSet< std::string > *a, const VectorSet< std::string > *b)
static void create_edit_points_data(const OffsetIndices< int > points_by_curve, const IndexMask &catmull_rom_curves, const IndexMask &poly_curves, const IndexMask &bezier_curves, const IndexMask &nurbs_curves, const OffsetIndices< int > bezier_offsets, const bke::CurvesGeometry &curves, gpu::VertBuf &vbo)
static bool ensure_attributes(const Curves &curves, CurvesBatchCache &cache, const GPUMaterial *gpu_material)
static void create_edit_points_position(const bke::CurvesGeometry &curves, const OffsetIndices< int > points_by_curve, const IndexMask &bezier_curves, const OffsetIndices< int > bezier_offsets, const bke::crazyspace::GeometryDeformation deformation, gpu::VertBuf &vbo)
bool curves_ensure_procedural_data(Curves *curves_id, CurvesEvalCache **r_cache, const GPUMaterial *gpu_material, const int subdiv, const int thickness_res)
static void fill_curve_offsets_vbos(const OffsetIndices< int > points_by_curve, GPUVertBufRaw &data_step, GPUVertBufRaw &seg_step)
static void extract_edit_data(const OffsetIndices< int > points_by_curve, const IndexMask &curve_selection, const VArray< bool > &selection_attr, const bool mark_active, const uint32_t fill_value, MutableSpan< uint32_t > data)
gpu::VertBuf ** DRW_curves_texture_for_evaluated_attribute(Curves *curves, StringRef name, bool *r_is_point_domain)
static void create_lines_ibo_no_cyclic(const OffsetIndices< int > points_by_curve, gpu::IndexBuf &ibo)
static void discard_attributes(CurvesEvalCache &eval_cache)
blender::gpu::Batch * DRW_curves_batch_cache_get_edit_curves_lines(Curves *curves)
static IndexRange handle_range_right(const int points_num, const OffsetIndices< int > bezier_offsets)
static void extract_curve_lines(const OffsetIndices< int > points_by_curve, const VArray< bool > &cyclic, const IndexMask &selection, const int cyclic_segment_offset, MutableSpan< uint2 > lines)
static IndexRange handle_range_left(const int points_num, const OffsetIndices< int > bezier_offsets)
void DRW_curves_batch_cache_free(Curves *curves)
void DRW_curves_batch_cache_create_requested(Object *ob)
static void clear_final_data(CurvesEvalFinalCache &final_cache)
static int handles_and_points_num(const int points_num, const OffsetIndices< int > bezier_offsets)
bool drw_custom_data_match_attribute(const CustomData &custom_data, const StringRef name, int *r_layer_index, eCustomDataType *r_type)
static void ensure_final_attribute(const Curves &curves, const StringRef name, const int index, CurvesEvalCache &cache)
std::unique_ptr< gpu::VertBuf, gpu::VertBufDeleter > VertBufPtr
constexpr uint32_t RESTART_INDEX
OffsetIndices< int > gather_selected_offsets(OffsetIndices< int > src_offsets, const IndexMask &selection, int start_offset, MutableSpan< int > dst_offsets)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< uint32_t, 2 > uint2
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
gpu::IndexBuf * edit_handles_ibo
gpu::VertBuf * edit_points_pos
CurvesEvalCache eval_cache
gpu::Batch * edit_curves_lines
gpu::VertBuf * edit_points_selection
gpu::IndexBuf * edit_curves_lines_ibo
gpu::IndexBuf * sculpt_cage_ibo
gpu::VertBuf * edit_curves_lines_pos
gpu::VertBuf * edit_points_data
gpu::Batch * edit_handles
gpu::VertBuf * proc_strand_seg_buf
CurvesEvalFinalCache final
gpu::VertBuf * proc_length_buf
gpu::VertBuf * proc_attributes_buf[GPU_MAX_ATTR]
gpu::VertBuf * proc_point_buf
std::array< bool, GPU_MAX_ATTR > proc_attributes_point_domain
gpu::VertBuf * proc_strand_buf
VectorSet< std::string > attr_used_over_time
gpu::VertBuf * attributes_buf[GPU_MAX_ATTR]
VectorSet< std::string > attr_used
int last_attr_matching_time