45 ubos.append(std::make_unique<CurvesInfosBuf>());
64 const float vert[4] = {0.0f, 0.0f, 0.0f, 0.0f};
74 if (drw_data ==
nullptr) {
78 drw_data->
curves_module = MEM_new<CurvesModule>(
"CurvesModule");
89 MEM_delete(curves_module);
92void CurvesModule::dispatch(
const int curve_count,
PassSimple::Sub &pass)
98 int strands_start = 0;
99 while (strands_start < curve_count) {
100 int batch_strands_len = std::min(
int64_t(curve_count - strands_start), max_strands_per_call);
101 pass.push_constant(
"curves_start", strands_start);
102 pass.push_constant(
"curves_count", batch_strands_len);
104 strands_start += batch_strands_len;
109 const int point_count,
114 int element_count = is_ribbon ? (point_count + curve_count) : (point_count - curve_count);
116 element_count += curve_count;
124 pass.
bind_ssbo(
"indirection_buf", indirection_buf);
127 dispatch(curve_count, pass);
129 return indirection_buf;
133 const bool has_bezier,
135 const bool has_nurbs,
136 const bool has_cyclic,
137 const int curve_count,
150 const char *pass_name =
nullptr;
152 switch (shader_type) {
154 pass_name =
"Position";
157 pass_name =
"Float Attribute";
160 pass_name =
"Float2 Attribute";
163 pass_name =
"Float3 Attribute";
166 pass_name =
"Float4 Attribute";
169 pass_name =
"Length-Intercept Attributes";
180 switch (shader_type) {
215 dispatch(curve_count, sub);
228 dispatch(curve_count, sub);
237 sub.
bind_ssbo(
"handles_positions_right_buf",
245 dispatch(curve_count, sub);
260 dispatch(curve_count, sub);
268 const int curve_count,
287 dispatch(curve_count, pass);
292 bool is_curve_length =
false,
293 bool is_curve_intercept =
false)
303 if (gpu_attr->is_hair_length ==
true) {
304 if (gpu_attr->is_hair_length == is_curve_length) {
308 else if (gpu_attr->is_hair_intercept ==
true) {
309 if (gpu_attr->is_hair_intercept == is_curve_intercept) {
313 else if (gpu_attr->name ==
name) {
333 module.transient_buffers.clear();
336 module.refine.init();
356 std::optional<StringRef>
name;
370 const bool is_point_domain)
384template<
typename PassT>
388 const int face_per_segment,
391 const std::optional<StringRef> uv_name)
396 sub_ps.bind_texture(
"u",
module.dummy_vbo);
397 sub_ps.bind_texture(
"au",
module.dummy_vbo);
398 sub_ps.bind_texture(
"a",
module.dummy_vbo);
399 sub_ps.bind_texture(
"c",
module.dummy_vbo);
400 sub_ps.bind_texture(
"ac",
module.dummy_vbo);
401 sub_ps.bind_texture(
"l",
module.dummy_vbo);
402 sub_ps.bind_texture(
"i",
module.dummy_vbo);
407 sub_ps.bind_texture(attr->input_name,
module.dummy_vbo);
433 char sampler_name[32];
443 if (
name == uv_name) {
456 if (
name == uv_name) {
466 ((face_per_segment + 1) * 2 + 1);
470 sub_ps.bind_ubo(
"drw_curves", curves_infos);
472 sub_ps.bind_texture(
"curves_indirection_buf", indirection_buf);
478 const int face_per_segment,
481 const std::optional<StringRef> active_uv_name)
484 sub_ps,
module, cache, face_per_segment, gpu_material, indirection_buf, active_uv_name);
489 CurvesEvalCache &cache,
490 const int face_per_segment,
493 const std::optional<StringRef> active_uv_name)
496 sub_ps,
module, cache, face_per_segment, gpu_material, indirection_buf, active_uv_name);
499template<
typename PassT>
503 const char *&r_error,
518 bool unused_error =
false;
519 return curves_cache.
batch_get(0, 0, face_per_segment,
false, unused_error);
528 module, curves, face_per_segment);
531 curves_id.
geometry.wrap().attributes());
534 sub_ps,
module, curves_cache, face_per_segment, gpu_material, indirection_buf, uv_name);
544 "Error: Curves object contains too many points. "
545 "Reduce curve resolution or curve count to fix this issue.\n");
553 const char *&r_error,
562 const char *&r_error,
Low-level operations for curves.
#define LISTBASE_FOREACH(type, var, list)
MINLINE uint divide_ceil_u(uint a, uint b)
@ SCE_HAIR_SHAPE_CYLINDER
void DRW_submission_end()
void DRW_submission_start()
T & DRW_object_get_data_for_drawing(const Object &object)
int GPU_max_work_group_count(int index)
ListBase GPU_material_attributes(const GPUMaterial *material)
@ GPU_BARRIER_SHADER_STORAGE
void GPU_memory_barrier(GPUBarrier barrier)
void GPU_vertbuf_use(blender::gpu::VertBuf *)
void GPU_vertbuf_attr_fill(blender::gpu::VertBuf *, uint a_idx, const void *data)
blender::gpu::VertBuf * GPU_vertbuf_create_with_format_ex(const GPUVertFormat &format, GPUUsageType usage)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
@ GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
IndexRange index_range() const
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
bool has_cyclic_curve() const
int evaluated_points_num() const
void submit(PassSimple &pass, View &view)
void shader_set(gpu::Shader *shader)
void specialize_constant(gpu::Shader *shader, const char *name, const float &data)
PassBase< DrawCommandBufType > & sub(const char *name)
void barrier(GPUBarrier type)
void push_constant(const char *name, const float &data)
void bind_ssbo(const char *name, gpu::StorageBuf *buffer)
detail::PassBase< command::DrawCommandBuf > Sub
static VertBufPtr device_only(uint size)
#define CURVES_PER_THREADGROUP
#define EVALUATED_ATTR_SLOT
#define POINTS_BY_CURVES_SLOT
#define EVALUATED_POS_RAD_SLOT
#define EVALUATED_TIME_SLOT
#define EVALUATED_POINT_SLOT
#define CURVES_LENGTH_SLOT
#define CURVE_CYCLIC_SLOT
#define POINT_POSITIONS_SLOT
#define CURVE_RESOLUTION_SLOT
blender::gpu::Shader * DRW_shader_curves_refine_get(blender::draw::CurvesEvalShader type)
blender::gpu::Shader * DRW_shader_curves_topology_get()
struct @021025263243242147216143265077100330027142264337::@225245033123204053237120173316075113304004012000 batch
static void error(const char *str)
void DRW_curves_module_free(draw::CurvesModule *module)
void curves_bind_resources(PassMain::Sub &sub_ps, CurvesModule &module, CurvesEvalCache &cache, const int face_per_segment, GPUMaterial *gpu_material, gpu::VertBufPtr &indirection_buf, const std::optional< StringRef > active_uv_name)
static int attribute_index_in_material(const GPUMaterial *gpu_material, const StringRef name, bool is_curve_length=false, bool is_curve_intercept=false)
CurvesEvalCache & curves_get_eval_cache(Curves &curves_id)
void DRW_curves_init(DRWData *drw_data=nullptr)
static std::optional< StringRef > get_first_uv_name(const bke::AttributeAccessor &attributes)
gpu::Batch * curves_sub_pass_setup(PassMain::Sub &ps, const Scene *scene, Object *ob, const char *&r_error, GPUMaterial *gpu_material=nullptr)
gpu::VertBuf * curves_pos_buffer_get(Object *object)
void DRW_curves_update(draw::Manager &manager)
void drw_curves_get_attribute_sampler_name(const StringRef layer_name, char r_sampler_name[32])
void DRW_curves_begin_sync(DRWData *drw_data)
static bool set_attribute_type(const GPUMaterial *gpu_material, const StringRef name, CurvesInfosBuf &curves_infos, const bool is_point_domain)
gpu::Batch * curves_sub_pass_setup_implementation(PassT &sub_ps, const Scene *scene, Object *ob, const char *&r_error, GPUMaterial *gpu_material=nullptr)
@ CURVES_EVAL_LENGTH_INTERCEPT
UniformBuffer< CurvesInfos > CurvesInfosBuf
void curves_bind_resources_implementation(PassT &sub_ps, CurvesModule &module, CurvesEvalCache &cache, const int face_per_segment, GPUMaterial *gpu_material, gpu::VertBufPtr &indirection_buf, const std::optional< StringRef > uv_name)
std::unique_ptr< gpu::VertBuf, gpu::VertBufDeleter > VertBufPtr
MatBase< float, 4, 4 > float4x4
ListBaseWrapperTemplate< ListBase, T > ListBaseWrapper
static struct PyModuleDef module
uint half_cylinder_face_count
uint4 is_point_attribute[DRW_ATTRIBUTE_PER_CURVES_MAX]
blender::draw::CurvesModule * curves_module
gpu::VertBufPtr curves_cyclic_buf
gpu::VertBufPtr evaluated_time_buf
gpu::VertBufPtr evaluated_attributes_buf[GPU_MAX_ATTR]
gpu::VertBufPtr curves_resolution_buf
gpu::VertBufPtr curves_length_buf
std::array< bool, GPU_MAX_ATTR > attributes_point_domain
gpu::VertBufPtr curves_type_buf
gpu::VertBufPtr bezier_offsets_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]
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
gpu::VertBufPtr basis_cache_offset_buf
gpu::VertBufPtr basis_cache_buf
void evaluate_curve_attribute(bool has_catmull, bool has_bezier, bool has_poly, bool has_nurbs, bool has_cyclic, int curve_count, CurvesEvalCache &cache, CurvesEvalShader shader_type, gpu::VertBufPtr input_buf, gpu::VertBufPtr &output_buf, gpu::VertBuf *input2_buf=nullptr, float4x4 transform=float4x4::identity())
Vector< gpu::VertBufPtr > transient_buffers
gpu::VertBufPtr evaluate_topology_indirection(const int curve_count, const int point_count, CurvesEvalCache &cache, bool is_ribbon, bool has_cyclic)
void evaluate_curve_length_intercept(bool has_cyclic, int curve_count, CurvesEvalCache &cache)