37 if (curve_ !=
nullptr) {
38 new_component->curve_ =
new CurveEval(*curve_);
47 if (curve_ !=
nullptr) {
57 return curve_ !=
nullptr;
65 ownership_ = ownership;
93 return curve_ ==
nullptr;
119 struct PointIndices {
128 const int index_in_spline = index - offsets[
spline_index];
144 const int splines_len =
curve.splines().
size();
149 for (
const int i_spline :
IndexRange(splines_len)) {
150 const int spline_offset = offsets[i_spline];
151 const int spline_point_len = offsets[i_spline + 1] - spline_offset;
152 for (
const int i_point :
IndexRange(spline_point_len)) {
153 const T value = old_values[spline_offset + i_point];
154 mixer.mix_in(i_spline, value);
173 const int splines_len =
curve.splines().
size();
179 for (
const int i_spline :
IndexRange(splines_len)) {
180 const int spline_offset = offsets[i_spline];
181 const int spline_point_len = offsets[i_spline + 1] - spline_offset;
183 for (
const int i_point :
IndexRange(spline_point_len)) {
184 if (!old_values[spline_offset + i_point]) {
185 r_values[i_spline] =
false;
196 using T = decltype(dummy);
197 if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
198 Array<T> values(curve.splines().size());
199 adapt_curve_domain_point_to_spline_impl<T>(curve, varray.typed<T>(), values);
200 new_varray = VArray<T>::ForContainer(std::move(values));
221 original_varray_(
std::move(original_varray)),
222 original_data_(original_varray_.typed<
T>()),
223 offsets_(
std::move(offsets))
230 return original_data_[
indices.spline_index];
235 const int total_num = offsets_.
last();
245 for (
const int dst_index :
mask) {
256 T *dst = r_span.data();
257 const int total_num = offsets_.
last();
267 for (
const int dst_index :
mask) {
281 using T = decltype(dummy);
283 Array<int> offsets = curve.control_point_offsets();
284 new_varray = VArray<T>::template For<VArray_For_SplineToPoint<T>>(std::move(varray),
303 if (from_domain == to_domain) {
330 const AsReadAttribute as_read_attribute_;
331 const AsWriteAttribute as_write_attribute_;
337 const AsReadAttribute as_read_attribute,
338 const AsWriteAttribute as_write_attribute)
345 as_read_attribute_(as_read_attribute),
346 as_write_attribute_(as_write_attribute)
353 if (
curve ==
nullptr) {
356 return as_read_attribute_(*
curve);
365 if (
curve ==
nullptr) {
381 bool exists(
const void *owner)
const final
384 return !
curve->splines().is_empty();
391 return bezier_spline->resolution();
394 return nurb_spline->resolution();
402 bezier_spline->set_resolution(
std::max(resolution, 1));
405 nurb_spline->set_resolution(
std::max(resolution, 1));
422 return spline->is_cyclic();
427 if (spline->is_cyclic() != value) {
428 spline->set_cyclic(value);
429 spline->mark_cache_invalid();
464 const int total_num = offsets.
last();
472 if (
src.is_empty()) {
482 for (
const int dst_index :
mask) {
488 const int index_in_spline = dst_index - offsets[
spline_index];
490 if (
src.is_empty()) {
491 r_span[dst_index] =
T();
494 r_span[dst_index] =
src[index_in_spline];
509 T *dst = r_span.
data();
510 const int total_num = offsets.
last();
517 if (
src.is_empty()) {
527 for (
const int dst_index :
mask) {
533 const int index_in_spline = dst_index - offsets[
spline_index];
535 if (
src.is_empty()) {
536 new (dst + dst_index)
T();
539 new (dst + dst_index)
T(
src[index_in_spline]);
549 switch (initializer.
type) {
560 total_num += spline->size();
584 if (!
splines.
first()->attributes.create_by_move(attribute_id, data_type, source_data)) {
592 for (
const int i :
splines.index_range()) {
593 if (!
splines[i]->attributes.create(attribute_id, data_type)) {
627 if (
curve ==
nullptr) {
632 bool layer_freed =
false;
634 layer_freed = spline->attributes.remove(attribute_id);
721 return splines_[
indices.spline_index]->positions()[
indices.point_index];
746 spans[i] = splines_[i]->positions();
776 offsets_(
std::move(offsets)),
888 const bool stored_in_custom_data)
905 if (
curve ==
nullptr) {
909 if (!this->
exists(owner)) {
920 for (
const int i :
splines.index_range()) {
933 if (
curve ==
nullptr) {
937 if (!this->
exists(owner)) {
941 std::function<
void()> tag_modified_fn;
954 std::move(tag_modified_fn)};
959 for (
const int i :
splines.index_range()) {
968 if (
deletable_ == DeletableEnum::NonDeletable) {
984 bool exists(
const void *owner)
const final
987 if (
curve ==
nullptr) {
997 if (!
curve->splines().first()->attributes.get_for_read(
name_)) {
1002 bool has_point =
false;
1004 if (spline->size() != 0) {
1030 [](const
Spline &spline) {
return spline.positions(); },
1031 [](
Spline &spline) {
return spline.positions(); },
1032 [](
Spline &spline) { spline.mark_cache_invalid(); },
1040 if (
curve ==
nullptr) {
1050 auto tag_modified_fn = [
curve]() {
1053 curve->mark_cache_invalid();
1058 std::move(offsets)),
1083 if (
curve ==
nullptr) {
1101 if (
curve ==
nullptr) {
1109 auto tag_modified_fn = [
curve]() {
curve->mark_cache_invalid(); };
1113 curve->splines(), std::move(offsets), is_right_),
1131 if (
curve ==
nullptr) {
1172 std::optional<GSpan> first_span =
splines[0]->attributes.get_for_read(attribute_id);
1176 spans.
append(*first_span);
1178 std::optional<GSpan> span =
splines[i]->attributes.get_for_read(attribute_id);
1186 if (span->type() != spans.
last().type()) {
1195 if (spans.
size() == 1) {
1202 using T = decltype(dummy);
1204 for (
const int i :
splines.index_range()) {
1205 Span<T> span = spans[i].typed<
T>();
1227 std::optional<GMutableSpan> first_span =
splines[0]->attributes.get_for_write(attribute_id);
1231 spans.
append(*first_span);
1233 std::optional<GMutableSpan> span =
splines[i]->attributes.get_for_write(attribute_id);
1241 if (span->type() != spans.
last().type()) {
1250 if (spans.
size() == 1) {
1257 using T = decltype(dummy);
1259 for (
const int i :
splines.index_range()) {
1260 data[i] = spans[i].typed<
T>();
1298 curve->assert_valid_point_attributes();
1313 return ((1ULL << data_type) & supported_types_mask) != 0;
1344 return curve ? &
curve->attributes.data :
nullptr;
1346 [](
const void *owner) ->
const CustomData * {
1348 return curve ? &
curve->attributes.data :
nullptr;
1350 [](
const void *owner) ->
int {
1357 spline_custom_data_access);
1367 [](
const Spline &spline) {
1369 return span ? span->typed<
int>() :
Span<int>();
1382 [](
const Spline &spline) {
return spline.
radii(); },
1391 [](
const Spline &spline) {
return spline.
tilts(); },
1399 {&position, &
id, &radius, &tilt, &handles_start, &handles_end, &resolution, &cyclic},
1400 {&spline_custom_data, &point_custom_data});
1409 attribute_accessor_functions::accessor_functions_for_providers<providers>();
1411 if (owner ==
nullptr) {
1419 return curve_eval.
splines().size();
1431 if (owner ==
nullptr) {
@ GEO_COMPONENT_TYPE_CURVE
std::unique_ptr< Spline > SplinePtr
#define BLI_assert_unreachable()
static uint8 component(Color32 c, uint i)
Enumerations for DNA_ID.h.
#define CD_MASK_PROP_COLOR
#define CD_MASK_PROP_FLOAT3
#define CD_MASK_PROP_FLOAT2
#define CD_MASK_PROP_BOOL
#define CD_MASK_PROP_INT32
#define CD_MASK_PROP_FLOAT
#define CD_MASK_PROP_INT8
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
blender::Span< blender::float3 > handle_positions_right() const
blender::Span< blender::float3 > handle_positions_left() const
void mark_cache_invalid() final
GeometryComponent * copy() const override
void ensure_owns_direct_data() override
void replace(CurveEval *curve, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
bool is_empty() const final
const CurveEval * get_for_read() const
std::optional< blender::bke::AttributeAccessor > attributes() const final
CurveEval * get_for_write()
bool owns_direct_data() const override
std::optional< blender::bke::MutableAttributeAccessor > attributes_for_write() final
virtual blender::MutableSpan< blender::float3 > positions()=0
virtual blender::MutableSpan< float > tilts()=0
blender::bke::CustomDataAttributes attributes
virtual blender::MutableSpan< float > radii()=0
virtual void mark_cache_invalid()=0
const T & last(const int64_t n=0) const
IndexRange index_range() const
Span< T > as_span() const
void fill(const T &value) const
const CPPType & type() const
static GVArray ForSpan(GSpan span)
void set_all(const void *src)
static GVMutableArray ForSpan(GMutableSpan span)
constexpr int64_t size() const
constexpr void fill(const T &value)
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr void copy_from(Span< T > values)
constexpr IndexRange index_range() const
constexpr T * data() const
constexpr const T * data() const
constexpr const T & last(const int64_t n=0) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr const T * end() const
constexpr const T * begin() const
void append(const T &value)
const T & last(const int64_t n=0) const
void reserve(const int64_t min_capacity)
bool exists(const void *owner) const final
GVArray try_get_for_read(const void *owner) const override
BezierHandleAttributeProvider(const bool is_right)
bool try_create(void *UNUSED(owner), const AttributeInit &UNUSED(initializer)) const final
GAttributeWriter try_get_for_write(void *owner) const override
bool try_delete(void *UNUSED(owner)) const final
const WritableEnum writable_
const CreatableEnum createable_
const eAttrDomain domain_
const DeletableEnum deletable_
bool stored_in_custom_data_
GAttributeWriter try_get_for_write(void *owner) const override
bool exists(const void *owner) const final
void(*)(Spline &spline) UpdateOnWrite
BuiltinPointAttributeProvider(std::string attribute_name, const CreatableEnum creatable, const DeletableEnum deletable, const GetSpan get_span, const GetMutableSpan get_mutable_span, const UpdateOnWrite update_on_write, const bool stored_in_custom_data)
bool try_create(void *owner, const AttributeInit &initializer) const final
const UpdateOnWrite update_on_write_
GVArray try_get_for_read(const void *owner) const override
const GetMutableSpan get_mutable_span_
bool try_delete(void *owner) const final
bool exists(const void *owner) const final
GAttributeWriter try_get_for_write(void *owner) const final
BuiltinSplineAttributeProvider(std::string attribute_name, const eCustomDataType attribute_type, const WritableEnum writable, const AsReadAttribute as_read_attribute, const AsWriteAttribute as_write_attribute)
GVArray try_get_for_read(const void *owner) const final
bool try_create(void *UNUSED(owner), const AttributeInit &UNUSED(initializer)) const final
bool try_delete(void *UNUSED(owner)) const final
std::optional< blender::GSpan > get_for_read(const AttributeIDRef &attribute_id) const
std::optional< blender::GMutableSpan > get_for_write(const AttributeIDRef &attribute_id)
GAttributeReader try_get_for_read(const void *owner, const AttributeIDRef &attribute_id) const final
bool try_delete(void *owner, const AttributeIDRef &attribute_id) const final
bool foreach_attribute(const void *owner, const AttributeForeachCallback callback) const final
void foreach_domain(const FunctionRef< void(eAttrDomain)> callback) const final
bool type_is_supported(eCustomDataType data_type) const
GAttributeWriter try_get_for_write(void *owner, const AttributeIDRef &attribute_id) const final
bool try_create(void *owner, const AttributeIDRef &attribute_id, const eAttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer) const final
PositionAttributeProvider()
GAttributeWriter try_get_for_write(void *owner) const final
void materialize(const IndexMask mask, MutableSpan< float3 > r_span) const final
void set(const int64_t index, float3 value) final
void set_all(Span< float3 > src) final
static Array< Span< float3 > > get_handle_spans(Span< SplinePtr > splines, const bool is_right)
void materialize_to_uninitialized(const IndexMask mask, MutableSpan< float3 > r_span) const final
float3 get(const int64_t index) const final
VArrayImpl_For_BezierHandles(MutableSpan< SplinePtr > splines, Array< int > offsets, const bool is_right)
void set_all(Span< T > src) final
T get(const int64_t index) const final
void materialize_to_uninitialized(const IndexMask mask, MutableSpan< T > r_span) const final
void materialize(const IndexMask mask, MutableSpan< T > r_span) const final
VArrayImpl_For_SplinePoints(Array< MutableSpan< T >> data, Array< int > offsets)
void set(const int64_t index, T value) final
void set(const int64_t index, float3 value) final
float3 get(const int64_t index) const final
void materialize(const IndexMask mask, MutableSpan< float3 > r_span) const final
Array< Span< float3 > > get_position_spans() const
void materialize_to_uninitialized(const IndexMask mask, MutableSpan< float3 > r_span) const final
VArrayImpl_For_SplinePosition(MutableSpan< SplinePtr > splines, Array< int > offsets)
void set_all(Span< float3 > src) final
void materialize(const IndexMask mask, MutableSpan< T > r_span) const final
VArray_For_SplineToPoint(GVArray original_varray, Array< int > offsets)
T get(const int64_t index) const final
void materialize_to_uninitialized(const IndexMask mask, MutableSpan< T > r_span) const final
DEGForeachIDComponentCallback callback
SyclQueue void void * src
SyclQueue void void size_t num_bytes void
static GVArray adapt_curve_attribute_domain(const CurveEval &curve, const GVArray &varray, const eAttrDomain from_domain, const eAttrDomain to_domain)
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_gpu_kernel_postfix int ccl_global int * indices
void(* MEM_freeN)(void *vmemh)
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
typename DefaultMixerStruct< T >::type DefaultMixer
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
const blender::CPPType * custom_data_type_to_cpp_type(const eCustomDataType type)
static int get_spline_resolution(const SplinePtr &spline)
static bool get_cyclic_value(const SplinePtr &spline)
static bool remove_point_attribute(CurveEval *curve, const AttributeIDRef &attribute_id)
static bool create_point_attribute(CurveEval *curve, const AttributeIDRef &attribute_id, const AttributeInit &initializer, const eCustomDataType data_type)
static GVMutableArray make_cyclic_write_attribute(CurveEval &curve)
static void point_attribute_materialize(Span< Span< T >> data, Span< int > offsets, const IndexMask mask, MutableSpan< T > r_span)
static void set_spline_resolution(SplinePtr &spline, const int resolution)
static void adapt_curve_domain_point_to_spline_impl(const CurveEval &curve, const VArray< T > &old_values, MutableSpan< T > r_values)
VArray< T > point_data_varray(Array< MutableSpan< T >> spans, Array< int > offsets)
static void set_cyclic_value(SplinePtr &spline, const bool value)
static GVArray adapt_curve_domain_spline_to_point(const CurveEval &curve, GVArray varray)
static ComponentAttributeProviders create_attribute_providers_for_curve()
VMutableArray< T > point_data_varray_mutable(Array< MutableSpan< T >> spans, Array< int > offsets)
static GVArray make_resolution_read_attribute(const CurveEval &curve)
static GVArray make_cyclic_read_attribute(const CurveEval &curve)
static GVMutableArray make_resolution_write_attribute(CurveEval &curve)
static AttributeAccessorFunctions get_curve_accessor_functions()
static PointIndices lookup_point_indices(Span< int > offsets, const int index)
static void point_attribute_materialize_to_uninitialized(Span< Span< T >> data, Span< int > offsets, const IndexMask mask, MutableSpan< T > r_span)
static const AttributeAccessorFunctions & get_curve_accessor_functions_ref()
static GVArray varray_from_initializer(const AttributeInit &initializer, const eCustomDataType data_type, const Span< SplinePtr > splines)
eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type)
static GVArray adapt_curve_domain_point_to_spline(const CurveEval &curve, GVArray varray)
vec_base< float, 3 > float3
void uninitialized_fill_n(T *dst, int64_t n, const T &value)
void uninitialized_copy_n(const T *src, int64_t n, T *dst)
static void update(bNodeTree *ntree)
unsigned __int64 uint64_t
blender::Span< SplinePtr > splines() const
blender::bke::MutableAttributeAccessor attributes_for_write()
int total_control_point_num() const
bool(* domain_supported)(const void *owner, eAttrDomain domain)
GVArray(* adapt_domain)(const void *owner, const GVArray &varray, eAttrDomain from_domain, eAttrDomain to_domain)
int(* domain_size)(const void *owner, eAttrDomain domain)