53#define EDIT_CURVES_NURBS_CONTROL_POINT (1u)
54#define EDIT_CURVES_BEZIER_HANDLE (1u << 1)
55#define EDIT_CURVES_ACTIVE_HANDLE (1u << 2)
58#define EDIT_CURVES_BEZIER_KNOT (1u << 3)
59#define EDIT_CURVES_HANDLE_TYPES_SHIFT (4u)
104 return (cache && cache->
is_dirty ==
false);
112 cache = MEM_new<CurvesBatchCache>(__func__);
209 return points_num + bezier_offsets.
total_size() * 2;
225 const bool mark_active,
226 const uint32_t fill_value,
230 const IndexRange points = points_by_curve[curve];
231 bool is_active =
false;
236 data.slice(points).fill(data_value);
249 const int points_num = points_by_curve.
total_size();
255 gpu::VertAttrType::UINT_32);
276 const IndexRange points = points_by_curve[curve];
279 const int point = points[
i];
282 const bool selected = selection[point] || selection_left[point] || selection_right[point];
283 const int bezier_point = bezier_range[
i];
302 const int points_num = positions.
size();
305 "pos", gpu::VertAttrType::SFLOAT_32_32_32);
310 data.take_front(positions.
size()).copy_from(positions);
316 if (handles_left && handles_right) {
340 "selection", gpu::VertAttrType::SFLOAT_32);
342 const int points_num = points_by_curve.
total_size();
349 attribute.materialize(
data.take_front(points_num));
373 const int points_num = points_by_curve.
total_size();
374 const int curves_num = points_by_curve.
size();
375 const int indices_num = points_num + curves_num;
380 for (
const int curve : range) {
381 const IndexRange points = points_by_curve[curve];
384 ibo_data[ibo_range[
i]] = points[
i];
396 const int points_num = points_by_curve.
total_size();
397 const int curves_num = points_by_curve.
size();
398 const int indices_num = points_num + curves_num * 2;
403 for (
const int curve : range) {
404 const IndexRange points = points_by_curve[curve];
407 ibo_data[ibo_range[
i]] = points[
i];
436 const IndexRange points = points_by_curve[curve];
464 const int points_num = points_by_curve.
total_size();
465 const int extra_bezier_segments = bezier_offsets.
total_size();
471 points_num + extra_bezier_segments,
478 lines.
fill(
uint2(std::numeric_limits<uint32_t>::min()));
482 points_by_curve, cyclic, catmull_rom_curves, curve_or_handle_segments);
490 const IndexRange points = points_by_curve[curve];
493 const int point = points[
i];
494 const int bezier_point = bezier_point_range[
i];
495 curve_or_handle_segments[point] =
uint2(handles_left[bezier_point], point);
501 const IndexRange points = points_by_curve[curve];
504 const int point = points[
i];
505 const int bezier_point = bezier_point_range[
i];
506 right_handle_segments[bezier_point] =
uint2(handles_right[bezier_point], point);
530 bool &r_is_point_domain)
551 r_is_point_domain =
false;
563 std::optional<StringRef>
name;
601 char sampler_name[32];
627 format,
name, evaluated_point_count_with_cyclic(curves));
629 module.evaluate_curve_attribute(curves.has_curve_with_type(CURVE_TYPE_CATMULL_ROM),
630 curves.has_curve_with_type(CURVE_TYPE_BEZIER),
631 curves.has_curve_with_type(CURVE_TYPE_POLY),
632 curves.has_curve_with_type(CURVE_TYPE_NURBS),
633 curves.has_cyclic_curve(),
638 this->evaluated_attributes_buf[index]);
656 if (
name.is_empty()) {
712 curves.
runtime->evaluated_offsets_cache.data().all_bezier_offsets.as_span());
735 for (
const BasisCache &cache : nurbs_basis_cache) {
736 basis_cache_offset.
append(cache.invalid ? -1 : basis_cache_packed.
size());
737 if (!cache.invalid) {
738 basis_cache_packed.
extend(cache.start_indices.as_span().cast<uint32_t>());
739 basis_cache_packed.
extend(cache.weights.as_span().cast<uint32_t>());
743 if (basis_cache_packed.
is_empty()) {
744 basis_cache_packed.
append(0);
784 evaluated_point_count_with_cyclic(curves));
786 module.evaluate_positions(curves.has_curve_with_type(CURVE_TYPE_CATMULL_ROM),
787 curves.has_curve_with_type(CURVE_TYPE_BEZIER),
788 curves.has_curve_with_type(CURVE_TYPE_POLY),
789 curves.has_curve_with_type(CURVE_TYPE_NURBS),
790 curves.has_cyclic_curve(),
793 std::move(points_pos_buf),
794 std::move(points_rad_buf),
795 evaluated_pos_rad_buf);
799 evaluated_point_count_with_cyclic(curves));
802 module.evaluate_curve_length_intercept(curves.has_cyclic_curve(), curves.curves_num(), *this);
807 const int face_per_segment)
809 const bool is_ribbon = face_per_segment < 2;
813 if (indirection_buf) {
814 return indirection_buf;
819 indirection_buf =
module.evaluate_topology_indirection(curves.curves_num(),
820 curves.evaluated_points_num(),
823 curves.has_cyclic_curve());
825 return indirection_buf;
829 const int curve_count,
830 const int face_per_segment,
831 const bool use_cyclic,
834 gpu::Batch *&
batch = this->batch[face_per_segment];
843 if (face_per_segment == 0) {
845 segment_count =
int64_t(evaluated_point_count) + curve_count;
847 segment_count += curve_count;
851 segment_count -= (segment_count > 0) ? 1 : 0;
852 vert_per_segment = 1;
855 else if (face_per_segment == 1) {
857 segment_count =
int64_t(evaluated_point_count) + curve_count;
859 segment_count += curve_count;
863 segment_count -= (segment_count > 0) ? 1 : 0;
864 vert_per_segment = 2;
867 else if (face_per_segment >= 2) {
868 segment_count =
int64_t(evaluated_point_count) - curve_count;
870 segment_count += curve_count;
873 vert_per_segment = (face_per_segment + 1) * 2 + 1;
883 if (segment_count > segment_limit) {
884 segment_count = segment_limit;
887 r_over_limit =
false;
889 uint32_t vertex_count = segment_count * vert_per_segment;
902 if (cache ==
nullptr) {
926 MEM_delete(batch_cache);
933 if (cache ==
nullptr) {
937 bool do_discard =
false;
982 bool &r_is_point_domain,
983 bool &r_valid_attribute)
995 r_valid_attribute =
true;
997 r_is_point_domain =
true;
1000 r_is_point_domain =
false;
1004 r_valid_attribute =
false;
1005 r_is_point_domain =
false;
1015 "pos", gpu::VertAttrType::SFLOAT_32_32_32);
1028 if (ob_orig ==
nullptr) {
1036 bool is_edit_data_needed =
false;
1042 is_edit_data_needed =
true;
1049 is_edit_data_needed =
true;
1056 is_edit_data_needed =
true;
1084 if (!is_edit_data_needed) {
1090 const std::array<int, CURVE_TYPES_NUM> type_counts = curves_orig.
curve_type_counts();
1105 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.
#define BLI_assert_unreachable()
#define LISTBASE_FOREACH(type, var, list)
size_t size_t size_t BLI_snprintf_utf8(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.
T & DRW_object_get_data_for_drawing(const Object &object)
#define GPU_BATCH_DISCARD_SAFE(batch)
blender::gpu::Batch * GPU_batch_create_procedural(GPUPrimType primitive_type, int32_t vertex_count)
uint32_t GPU_max_buffer_texture_size()
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)
ListBase GPU_material_attributes(const GPUMaterial *material)
static constexpr int GPU_MAX_ATTR
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
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
IndexRange index_range() const
constexpr int64_t first() const
constexpr IndexRange drop_back(int64_t n) 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 int64_t size() const
constexpr bool contains(const T &value) const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr MutableSpan< NewT > cast() const
constexpr void fill(const T &value) const
constexpr MutableSpan drop_front(const int64_t n) const
constexpr MutableSpan take_front(const int64_t n) const
constexpr T & last(const int64_t n=0) const
constexpr int64_t size() const
void append(const T &value)
void extend(Span< T > array)
Span< T > as_span() const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
bool contains(StringRef attribute_id) const
GAttributeReader lookup(const StringRef attribute_id) const
VArray< int8_t > handle_types_left() const
OffsetIndices< int > points_by_curve() const
VArray< int8_t > handle_types_right() const
void ensure_can_interpolate_to_evaluated() const
bool has_cyclic_curve() const
IndexRange curves_range() const
const std::array< int, CURVE_TYPES_NUM > & curve_type_counts() const
VArray< float > radius() const
std::optional< Span< float > > nurbs_weights() const
VArray< int > resolution() const
int evaluated_points_num() const
std::optional< Span< float3 > > handle_positions_left() const
Span< float3 > positions() const
OffsetIndices< int > evaluated_points_by_curve() const
bool has_curve_with_type(CurveType type) const
std::optional< Span< float3 > > handle_positions_right() const
AttributeAccessor attributes() const
Span< float3 > evaluated_positions() const
VArray< int8_t > curve_types() const
VArray< bool > cyclic() const
VArray< int8_t > nurbs_orders() const
static VertBufPtr device_only(uint size)
static VertBufPtr from_varray(const VArray< T > &array)
static VertBufPtr from_span(const Span< T > data)
void foreach_index(Fn &&fn) 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)
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 create_segments_with_cyclic(const OffsetIndices< int > points_by_curve, const VArray< bool > &cyclic, const IndexMask &selection, MutableSpan< uint2 > lines)
void DRW_curves_batch_cache_validate(Curves *curves)
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)
static gpu::VertBufPtr alloc_evaluated_point_attribute_vbo(const GPUVertFormat &format, const StringRef, int64_t size)
blender::gpu::Batch * DRW_curves_batch_cache_get_edit_points(Curves *curves)
static bool batch_cache_is_dirty(const Curves &curves)
void DRW_curves_batch_cache_free_old(Curves *curves, int ctime)
CurvesEvalCache & curves_get_eval_cache(Curves &curves_id)
static gpu::VertBufPtr ensure_control_point_attribute(const bke::CurvesGeometry &curves, 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 std::optional< StringRef > get_first_uv_name(const bke::AttributeAccessor &attributes)
static void init_batch_cache(Curves &curves)
blender::gpu::Batch * DRW_curves_batch_cache_get_sculpt_curves_cage(Curves *curves)
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_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 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)
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)
static void create_lines_ibo_no_cyclic(const OffsetIndices< int > points_by_curve, gpu::IndexBuf &ibo)
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)
void drw_attributes_merge(VectorSet< std::string > *dst, const VectorSet< std::string > *src)
static IndexRange handle_range_left(const int points_num, const OffsetIndices< int > bezier_offsets)
blender::gpu::VertBufPtr & DRW_curves_texture_for_evaluated_attribute(Curves *curves, StringRef name, bool &r_is_point_domain, bool &r_valid_attribute)
void DRW_curves_batch_cache_free(Curves *curves)
void DRW_curves_batch_cache_create_requested(Object *ob)
static int handles_and_points_num(const int points_num, const OffsetIndices< int > bezier_offsets)
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
static struct PyModuleDef module
CurvesGeometryRuntimeHandle * runtime
blender::draw::CurvesModule * curves_module
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::VertBufPtr curves_cyclic_buf
gpu::VertBufPtr evaluated_time_buf
gpu::VertBufPtr evaluated_attributes_buf[GPU_MAX_ATTR]
void ensure_bezier(const bke::CurvesGeometry &curves)
gpu::VertBufPtr curves_resolution_buf
gpu::VertBufPtr indirection_ribbon_buf
int last_attr_matching_time
std::array< gpu::Batch *, MAX_FACE_PER_SEGMENT > batch
gpu::VertBufPtr curves_length_buf
std::array< bool, GPU_MAX_ATTR > attributes_point_domain
gpu::VertBufPtr curves_type_buf
gpu::VertBufPtr bezier_offsets_buf
void ensure_common(const bke::CurvesGeometry &curves)
void discard_attributes()
gpu::VertBufPtr indirection_cylinder_buf
gpu::VertBufPtr control_weights_buf
gpu::Batch * batch_get(int evaluated_point_count, int curve_count, int face_per_segment, bool use_cyclic, bool &r_over_limit)
gpu::VertBufPtr & indirection_buf_get(CurvesModule &module, const bke::CurvesGeometry &curves, int face_per_segment)
gpu::VertBufPtr evaluated_pos_rad_buf
gpu::VertBufPtr evaluated_points_by_curve_buf
void ensure_attributes(struct CurvesModule &module, const bke::CurvesGeometry &curves, const GPUMaterial *gpu_material)
void ensure_positions(CurvesModule &module, const bke::CurvesGeometry &curves)
gpu::VertBufPtr curve_attributes_buf[GPU_MAX_ATTR]
VectorSet< std::string > attr_used_over_time
gpu::VertBufPtr points_by_curve_buf
gpu::VertBufPtr curves_order_buf
gpu::VertBufPtr handles_positions_right_buf
VectorSet< std::string > attr_used
gpu::VertBufPtr handles_positions_left_buf
void ensure_attribute(struct CurvesModule &module, const bke::CurvesGeometry &curves, StringRef name, int index)
void ensure_nurbs(const bke::CurvesGeometry &curves)
gpu::VertBufPtr basis_cache_offset_buf
gpu::VertBufPtr basis_cache_buf