133 static uint pos_id, selection_id;
141 *r_selection_id = selection_id;
142 return &edit_point_format;
149 if (cache ==
nullptr) {
167 cache = MEM_new<ParticleBatchCache>(__func__);
190 if (cache ==
nullptr) {
247 MEM_delete(batch_cache);
253 for (
const auto &particle :
parent) {
256 for (
const auto &particle :
children) {
265 return {{
edit->pathcache,
edit->totcached}, {}};
270 if (
psys->pathcache && display_parent) {
274 if (
psys->childcache) {
282 if (!points_by_curve_storage_.is_empty()) {
283 return points_by_curve_storage_.as_span();
287 points_by_curve_storage_.append(total);
289 total += strand.
size();
290 points_by_curve_storage_.append(total);
292 return points_by_curve_storage_.as_span();
297 if (additional_subdivision_ == 0) {
301 if (!evaluated_points_by_curve_storage_.is_empty()) {
302 return evaluated_points_by_curve_storage_.as_span();
307 evaluated_points_by_curve_storage_.append(total);
310 total += (
size > 1) ?
size * segment_multiplier : 1;
311 evaluated_points_by_curve_storage_.append(total);
313 return evaluated_points_by_curve_storage_.as_span();
317 const int num_path_cache_keys,
320 for (
int i = 0;
i < num_path_cache_keys;
i++) {
334 if (hair_cache->
pos !=
nullptr && hair_cache->
indices !=
nullptr) {
342 if (edit !=
nullptr && edit->
pathcache !=
nullptr) {
371 const int num_uv_layers,
372 const int parent_index,
376 if (psmd ==
nullptr) {
391 const MFace *mfaces =
static_cast<const MFace *
>(
395 "A mesh with polygons should always have a generated 'CD_MFACE' layer!");
399 for (
int j = 0; j < num_uv_layers; j++) {
407 const int num_col_layers,
408 const int parent_index,
412 if (psmd ==
nullptr) {
427 const MFace *mfaces =
static_cast<const MFace *
>(
431 "A mesh with polygons should always have a generated 'CD_MFACE' layer!");
435 for (
int j = 0; j < num_col_layers; j++) {
445 const int num_uv_layers,
446 const int child_index,
450 if (psmd ==
nullptr) {
460 const MFace *mfaces =
static_cast<const MFace *
>(
463 for (
int j = 0; j < num_uv_layers; j++) {
471 const int num_col_layers,
472 const int child_index,
476 if (psmd ==
nullptr) {
486 const MFace *mfaces =
static_cast<const MFace *
>(
489 for (
int j = 0; j < num_col_layers; j++) {
498 const bool is_simple,
499 const int num_uv_layers,
500 const int parent_index,
501 const int child_index,
503 float (**r_parent_uvs)[2],
506 if (psmd ==
nullptr) {
510 if (r_parent_uvs[parent_index] !=
nullptr) {
511 *r_uv = r_parent_uvs[parent_index];
520 if (child_index == -1) {
523 r_parent_uvs[parent_index] = *r_uv;
532 else if (!r_parent_uvs[psys->
child[child_index].
parent]) {
533 r_parent_uvs[psys->
child[child_index].
parent] = *r_uv;
541 const bool is_simple,
542 const int num_col_layers,
543 const int parent_index,
544 const int child_index,
546 MCol **r_parent_mcol,
549 if (psmd ==
nullptr) {
553 if (r_parent_mcol[parent_index] !=
nullptr) {
554 *r_mcol = r_parent_mcol[parent_index];
563 if (child_index == -1) {
566 r_parent_mcol[parent_index] = *r_mcol;
575 else if (!r_parent_mcol[psys->
child[child_index].
parent]) {
576 r_parent_mcol[psys->
child[child_index].
parent] = *r_mcol;
591 const int global_offset,
592 const int start_index,
593 const int num_path_keys,
594 const int num_uv_layers,
595 const int num_col_layers,
600 float (***r_parent_uvs)[2],
601 MCol ***r_parent_mcol,
608 if (is_simple && *r_parent_uvs ==
nullptr) {
610 *r_parent_uvs =
static_cast<float (**)[2]
>(
613 if (is_simple && *r_parent_mcol ==
nullptr) {
614 *r_parent_mcol =
static_cast<MCol **
>(
617 int curr_point = start_index;
618 for (
int i = 0;
i < num_path_keys;
i++) {
624 float (*uv)[2] =
nullptr;
625 MCol *mcol =
nullptr;
644 for (
int j = 0; j < path->
segments; j++) {
649 sub_v3_v3v3(tangent, path[j + 1].co, path[j - 1].co);
654 if (psmd !=
nullptr) {
655 for (
int k = 0; k < num_uv_layers; k++) {
662 for (
int k = 0; k < num_col_layers; k++) {
676 int global_index =
i + global_offset;
681 if (psmd !=
nullptr) {
682 for (
int k = 0; k < num_uv_layers; k++) {
689 for (
int k = 0; k < num_col_layers; k++) {
714 float edit_key_seg_t = 1.0f / (part->
totkey - 1);
719 float interp = t / edit_key_seg_t;
722 float s1 = hkeys[index].
weight;
723 float s2 = hkeys[index + 1].
weight;
724 return s1 +
interp * (s2 - s1);
731 const int start_index,
732 const int num_path_keys,
736 int curr_point = start_index;
737 for (
int i = 0;
i < num_path_keys;
i++) {
742 for (
int j = 0; j <= path->
segments; j++) {
749 seg_data->
selection = (weight < 1.0f) ? weight : 1.0f;
769 if (hair_cache->
pos !=
nullptr && hair_cache->
indices !=
nullptr) {
781 uint *uv_id =
nullptr;
782 uint *col_id =
nullptr;
783 int num_uv_layers = 0;
784 int num_col_layers = 0;
787 const MTFace **mtfaces =
nullptr;
788 const MCol **mcols =
nullptr;
789 float (**parent_uvs)[2] =
nullptr;
790 MCol **parent_mcol =
nullptr;
792 if (psmd !=
nullptr) {
816 for (
int i = 0;
i < num_uv_layers;
i++) {
826 if (
i == active_uv) {
831 for (
int i = 0;
i < num_col_layers;
i++) {
839 &
format, uuid, blender::gpu::VertAttrType::UNORM_16_16_16_16);
841 if (
i == active_col) {
853 if (num_uv_layers || num_col_layers) {
856 mtfaces =
static_cast<const MTFace **
>(
857 MEM_mallocN(
sizeof(*mtfaces) * num_uv_layers,
"Faces UV layers"));
858 for (
int i = 0;
i < num_uv_layers;
i++) {
863 if (num_col_layers) {
864 mcols =
static_cast<const MCol **
>(
865 MEM_mallocN(
sizeof(*mcols) * num_col_layers,
"Color layers"));
866 for (
int i = 0;
i < num_col_layers;
i++) {
873 if (edit !=
nullptr && edit->
pathcache !=
nullptr) {
939 if (parent_uvs !=
nullptr) {
946 if (parent_mcol !=
nullptr) {
955 if (num_col_layers) {
958 if (psmd !=
nullptr) {
968 if (point_cache->
pos !=
nullptr) {
987 static uint pos_id, rot_id, val_id;
1028 if (curr_point != psys->
totpart) {
1039 if (edit->
psys ==
nullptr) {
1072 if (edit !=
nullptr) {
1081 const int additional_subdivision)
1134 if (hair_cache->
pos !=
nullptr && hair_cache->
indices !=
nullptr) {
1145 uint pos_id, selection_id;
1154 if (edit !=
nullptr && edit->
pathcache !=
nullptr) {
1189 for (
int point_index = 0; point_index < edit->
totpoint; point_index++) {
1206 uint pos_id, selection_id;
1212 int global_key_index = 0;
1213 for (
int point_index = 0; point_index < edit->
totpoint; point_index++) {
1218 for (
int key_index = 0; key_index < point->
totkey - 1; key_index++) {
1249 for (
int point_index = 0; point_index < edit->
totpoint; point_index++) {
1264 uint pos_id, selection_id;
1270 int global_point_index = 0;
1271 for (
int point_index = 0; point_index < edit->
totpoint; point_index++) {
1281 global_point_index++;
1306 if (particle.
num < face_count_legacy) {
1313 return particle.
num;
1324 std::swap(
col[0],
col[2]);
1328template<
typename ParticleDataT>
1333 return float4(0, 0, 0, 1);
1341template<
typename ParticleDataT>
1355 std::optional<StringRef>
name;
1383template<
typename InputT,
typename OutputT, eCustomDataType data_type>
1409 int curve_index = 0;
1445 bool &r_is_point_domain)
1447 using namespace bke;
1449 r_is_point_domain =
false;
1451 const AttributeAccessor attributes = mesh.
attributes();
1453 auto meta_data = attributes.lookup_meta_data(
name);
1455 if (meta_data->data_type == AttrType::ColorByte) {
1458 if (meta_data->data_type == AttrType::Float2) {
1473 char sampler_name[32];
1508 if (
name.is_empty()) {
1529 for (
const int i :
attr_used.index_range()) {
1564 float radius = 1.0f - time;
1566 radius =
powf(radius, 1.0f + shape);
1569 radius =
powf(radius, 1.0f / (1.0f - shape));
1571 return (radius * (root - tip)) + tip;
1597 const float hair_rad_shape = part.
shape;
1598 const float hair_rad_root = part.rad_root * part.rad_scale * 0.5f;
1599 const float hair_rad_tip = part.rad_tip * part.rad_scale * 0.5f;
1606 points_pos[
i] = point.co;
1607 points_rad[
i] = (hair_close_tip && (j == strand.index_range().last())) ?
1610 hair_rad_shape, hair_rad_root, hair_rad_tip, point.time);
1619 module.evaluate_positions(true,
1626 std::move(points_pos_buf),
1627 std::move(points_rad_buf),
1628 evaluated_pos_rad_buf,
1635 module.evaluate_curve_length_intercept(false, src.curves_num(), *this);
1640 int face_per_segment)
1642 const bool is_ribbon = face_per_segment < 2;
1646 if (indirection_buf) {
1647 return indirection_buf;
1653 return indirection_buf;
1658 indirection_buf =
module.evaluate_topology_indirection(
1659 src.curves_num(), src.evaluated_points_num(), *this, is_ribbon, false);
1661 return indirection_buf;
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer_n(const CustomData *data, eCustomDataType type, int n)
int CustomData_get_named_layer(const CustomData *data, eCustomDataType type, blender::StringRef name)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
const char * CustomData_get_layer_name(const CustomData *data, eCustomDataType type, int n)
int CustomData_get_active_layer(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
void BKE_mesh_tessface_ensure(Mesh *mesh)
struct ParticleSystemModifierData * psys_get_modifier(struct Object *ob, struct ParticleSystem *psys)
struct ParticleSystem * psys_orig_get(struct ParticleSystem *psys)
void psys_cache_edit_paths(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra, bool use_render_params)
bool psys_in_edit_mode(struct Depsgraph *depsgraph, const struct ParticleSystem *psys)
void psys_interpolate_uvs(const struct MTFace *tface, int quad, const float w[4], float r_uv[2])
void psys_sim_data_free(struct ParticleSimulationData *sim)
@ BKE_PARTICLE_BATCH_DIRTY_ALL
void psys_interpolate_mcol(const struct MCol *mcol, int quad, const float w[4], struct MCol *mc)
void psys_sim_data_init(struct ParticleSimulationData *sim)
bool psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, bool always)
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
#define LISTBASE_FOREACH(type, var, list)
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
ATTR_WARN_UNUSED_RESULT const size_t num
#define SNPRINTF_UTF8(dst, format,...)
float DEG_get_ctime(const Depsgraph *graph)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
T * DEG_get_original(T *id)
Object groups, one object can be in many groups at once.
struct ParticleSystem ParticleSystem
void PE_update_object(Depsgraph *depsgraph, Scene *scene, Object *ob, int useflag)
PTCacheEdit * PE_create_current(Depsgraph *depsgraph, Scene *scene, Object *ob)
#define GPU_batch_create(primitive_type, vertex_buf, index_buf)
#define GPU_BATCH_DISCARD_SAFE(batch)
#define GPU_INDEXBUF_DISCARD_SAFE(elem)
void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder *)
blender::gpu::IndexBuf * GPU_indexbuf_build(GPUIndexBufBuilder *)
void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder *, uint v)
void GPU_indexbuf_init_ex(GPUIndexBufBuilder *, GPUPrimType, uint index_len, uint vertex_len)
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)
void GPU_vertbuf_data_resize(blender::gpu::VertBuf &verts, uint v_len)
blender::gpu::VertBuf * GPU_vertbuf_create_with_format_ex(const GPUVertFormat &format, GPUUsageType usage)
static blender::gpu::VertBuf * GPU_vertbuf_create_with_format(const GPUVertFormat &format)
void GPU_vertbuf_attr_set(blender::gpu::VertBuf *, uint a_idx, uint v_idx, const void *data)
#define GPU_VERTBUF_DISCARD_SAFE(verts)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
@ GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY
BLI_INLINE void IMB_colormanagement_rec709_to_scene_linear(float scene_linear[3], const float rec709[3])
Read Guarded memory(de)allocation.
BMesh const char void * data
BPy_StructRNA * depsgraph
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr IndexRange index_range() const
constexpr bool is_empty() const
constexpr Span slice(int64_t start, int64_t size) const
constexpr const T * data() const
constexpr int64_t size() const
static VArray from_single(T value, const int64_t size)
void append(const T &value)
void reserve(const int64_t min_capacity)
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
bool contains(StringRef attribute_id) const
static VertBufPtr device_only(uint size)
static VertBufPtr from_varray(const VArray< T > &array)
static VertBufPtr from_size(const int size, GPUUsageType usage=GPU_USAGE_STATIC)
static VertBufPtr from_span(const Span< T > data)
Utilities for rendering attributes.
const DRWContext * DRW_context_get()
struct @021025263243242147216143265077100330027142264337::@240232116316110053135047106323056371161236243121 attr_id
ccl_device_inline uint particle_index(KernelGlobals kg, const int particle)
void * MEM_mallocN(size_t len, const char *str)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
ccl_device_inline float interp(const float a, const float b, const float t)
MINLINE unsigned short unit_float_to_ushort_clamp(float val)
float BLI_color_from_srgb_table[256]
void drw_particle_update_ptcache(Object *object_eval, ParticleSystem *psys)
void drw_attributes_add_request(VectorSet< std::string > *attrs, const StringRef name)
static void count_cache_segment_keys(ParticleCacheKey **pathcache, const int num_path_cache_keys, ParticleHairCache *hair_cache)
static float4 particle_mcol_convert(const MCol &mcol)
void DRW_particle_batch_cache_free(ParticleSystem *psys)
CurvesEvalCache & hair_particle_get_eval_cache(ParticleDrawSource &src)
blender::gpu::Batch * DRW_particles_batch_cache_get_edit_inner_points(Object *object, ParticleSystem *psys, PTCacheEdit *edit)
ParticleDrawSource drw_particle_get_hair_source(Object *object, ParticleSystem *psys, ModifierData *md, PTCacheEdit *edit, const int additional_subdivision)
blender::gpu::Batch * DRW_particles_batch_cache_get_edit_tip_points(Object *object, ParticleSystem *psys, PTCacheEdit *edit)
static void drw_particle_update_ptcache_edit(Object *object_eval, ParticleSystem *psys, PTCacheEdit *edit)
static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, ParticleSystem *psys, ModifierData *md, ParticleHairCache *hair_cache)
static int particle_batch_cache_fill_segments_edit(const PTCacheEdit *, const ParticleData *particle, ParticleCacheKey **path_cache, const int start_index, const int num_path_keys, GPUIndexBufBuilder *elb, GPUVertBufRaw *attr_step)
static bool particle_batch_cache_valid(ParticleSystem *psys)
static void particle_batch_cache_ensure_edit_tip_pos(PTCacheEdit *edit, ParticleBatchCache *cache)
@ PARTICLE_SOURCE_CHILDREN
blender::gpu::Batch * DRW_particles_batch_cache_get_edit_strands(Object *object, ParticleSystem *psys, PTCacheEdit *edit, bool use_weight)
static void particle_batch_cache_ensure_edit_pos_and_seg(PTCacheEdit *edit, ParticleSystem *psys, ModifierData *, ParticleHairCache *hair_cache, bool use_weight)
static void particle_calculate_uvs(ParticleSystem *psys, ParticleSystemModifierData *psmd, const bool is_simple, const int num_uv_layers, const int parent_index, const int child_index, const MTFace **mtfaces, float(**r_parent_uvs)[2], float(**r_uv)[2])
static void ensure_edit_inner_points_count(const PTCacheEdit *edit, ParticleBatchCache *cache)
blender::gpu::Batch * DRW_particles_batch_cache_get_dots(Object *object, ParticleSystem *psys)
static std::optional< StringRef > get_first_uv_name(const bke::AttributeAccessor &attributes)
static void particle_batch_cache_clear(ParticleSystem *psys)
Span< T > span_from_custom_data_layer(const Mesh &mesh, const eCustomDataType type, const StringRef name)
static void particle_interpolate_children_uvs(ParticleSystem *psys, ParticleSystemModifierData *psmd, const int num_uv_layers, const int child_index, const MTFace **mtfaces, float(*r_uv)[2])
static void particle_pack_mcol(MCol *mcol, ushort r_scol[3])
static int particle_mface_index(const ParticleData &particle, int face_count_legacy)
static void particle_batch_cache_ensure_edit_inner_pos(PTCacheEdit *edit, ParticleBatchCache *cache)
void drw_curves_get_attribute_sampler_name(const StringRef layer_name, char r_sampler_name[32])
static void particle_batch_cache_clear_point(ParticlePointCache *point_cache)
static void particle_batch_cache_ensure_pos(Object *object, ParticleSystem *psys, ParticlePointCache *point_cache)
bool drw_attributes_overlap(const VectorSet< std::string > *a, const VectorSet< std::string > *b)
static float particle_key_weight(const ParticleData *particle, int strand, float t)
static void particle_calculate_parent_mcol(ParticleSystem *psys, ParticleSystemModifierData *psmd, const int num_col_layers, const int parent_index, const MCol **mcols, MCol *r_mcol)
static gpu::VertBufPtr ensure_curve_attribute(ParticleDrawSource &src, const Mesh &mesh, const StringRef name, bool &r_is_point_domain)
static void particle_calculate_mcol(ParticleSystem *psys, ParticleSystemModifierData *psmd, const bool is_simple, const int num_col_layers, const int parent_index, const int child_index, const MCol **mcols, MCol **r_parent_mcol, MCol **r_mcol)
static gpu::VertBufPtr interpolate_face_corner_attribute_to_curve(ParticleDrawSource &src, const StringRef name)
static void particle_batch_cache_init(ParticleSystem *psys)
void DRW_particle_batch_cache_dirty_tag(ParticleSystem *psys, int mode)
static ParticleBatchCache * particle_batch_cache_get(ParticleSystem *psys)
static void particle_interpolate_children_mcol(ParticleSystem *psys, ParticleSystemModifierData *psmd, const int num_col_layers, const int child_index, const MCol **mcols, MCol *r_mcol)
static int particle_batch_cache_fill_segments(ParticleSystem *psys, ParticleSystemModifierData *psmd, ParticleCacheKey **path_cache, const ParticleSource particle_source, const int global_offset, const int start_index, const int num_path_keys, const int num_uv_layers, const int num_col_layers, const MTFace **mtfaces, const MCol **mcols, uint *uv_id, uint *col_id, float(***r_parent_uvs)[2], MCol ***r_parent_mcol, GPUIndexBufBuilder *elb, HairAttributeID *attr_id, ParticleHairCache *hair_cache)
void drw_attributes_merge(VectorSet< std::string > *dst, const VectorSet< std::string > *src)
blender::gpu::Batch * DRW_particles_batch_cache_get_hair(Object *object, ParticleSystem *psys, ModifierData *md)
static float hair_shape_radius(float shape, float root, float tip, float time)
static void ensure_seg_pt_count(PTCacheEdit *edit, ParticleSystem *psys, ParticleHairCache *hair_cache)
static void ensure_edit_tip_points_count(const PTCacheEdit *edit, ParticleBatchCache *cache)
static const GPUVertFormat * edit_points_vert_format_get(uint *r_pos_id, uint *r_selection_id)
static void particle_batch_cache_clear_hair(ParticleHairCache *hair_cache)
static void particle_calculate_parent_uvs(ParticleSystem *psys, ParticleSystemModifierData *psmd, const int num_uv_layers, const int parent_index, const MTFace **mtfaces, float(*r_uv)[2])
std::unique_ptr< gpu::VertBuf, gpu::VertBufDeleter > VertBufPtr
T clamp(const T &a, const T &min, const T &max)
T interpolate(const T &a, const T &b, const FactorT &t)
bool assign_if_different(T &old_value, T new_value)
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
VecBase< float, 2 > float2
VecBase< float, 3 > float3
static bool is_child(const Object *ob, const Object *parent)
static struct PyModuleDef module
char * active_color_attribute
struct PTCacheEditKey * keys
struct ParticleCacheKey ** pathcache
PTCacheEditPoint * points
struct ParticleSystem * psys
struct Depsgraph * depsgraph
struct ParticleSystemModifierData * psmd
struct ParticleSystem * psys
struct ParticleSystem * psys
struct ParticleCacheKey ** childcache
struct ParticleCacheKey ** pathcache
gpu::VertBufPtr curves_cyclic_buf
gpu::VertBufPtr evaluated_time_buf
gpu::VertBufPtr curves_resolution_buf
gpu::VertBufPtr indirection_ribbon_buf
gpu::VertBufPtr curves_length_buf
std::array< bool, GPU_MAX_ATTR > attributes_point_domain
gpu::VertBufPtr curves_type_buf
void ensure_common(const bke::CurvesGeometry &curves)
gpu::VertBufPtr indirection_cylinder_buf
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
VectorSet< std::string > attr_used
void ensure_attribute(struct CurvesModule &module, const bke::CurvesGeometry &curves, StringRef name, int index)
gpu::Batch * edit_inner_points
ParticleHairCache edit_hair
gpu::Batch * edit_strands
gpu::VertBuf * edit_inner_pos
gpu::VertBuf * edit_tip_pos
gpu::Batch * edit_tip_points
OffsetIndices< int > evaluated_points_by_curve()
int evaluated_points_num()
ParticleSpans particles_get()
OffsetIndices< int > points_by_curve()
blender::gpu::VertBuf * pos
blender::gpu::IndexBuf * indices
Vector< int > evaluated_points_by_curve_storage
CurvesEvalCache eval_cache
blender::gpu::Batch * hairs
Vector< int > points_by_curve_storage
blender::gpu::Batch * proc_hairs[MAX_THICKRES]
blender::gpu::VertBuf * proc_buf
void foreach_strand(FunctionRef< void(Span< ParticleCacheKey >)> callback)
Span< ParticleCacheKey * > parent
Span< ParticleCacheKey * > children