42 if (curves_ !=
nullptr) {
52 if (curves_ !=
nullptr) {
56 if (curve_for_render_ !=
nullptr) {
58 BLI_assert(curve_for_render_->editfont ==
nullptr && curve_for_render_->editnurb ==
nullptr);
60 curve_for_render_ =
nullptr;
69 return curves_ !=
nullptr;
77 ownership_ = ownership;
105 return curves_ ==
nullptr;
127 curves_->geometry.wrap().count_memory(memory);
133 if (curves_ ==
nullptr) {
136 if (curve_for_render_ !=
nullptr) {
137 return curve_for_render_;
139 std::lock_guard
lock{curve_for_render_mutex_};
140 if (curve_for_render_ !=
nullptr) {
141 return curve_for_render_;
145 curve_for_render_->curve_eval = curves_;
147 return curve_for_render_;
175 Vector<float3> nurbs_tangents;
177 for (const int i_curve : range) {
178 const IndexRange points = points_by_curve[i_curve];
179 const IndexRange evaluated_points = evaluated_points_by_curve[i_curve];
181 MutableSpan<float3> curve_normals = results.as_mutable_span().slice(points);
183 switch (types[i_curve]) {
184 case CURVE_TYPE_CATMULL_ROM: {
185 const Span<float3> normals = evaluated_normals.slice(evaluated_points);
186 const int resolution = resolutions[i_curve];
187 for (const int i : IndexRange(points.size())) {
188 curve_normals[i] = normals[resolution * i];
192 case CURVE_TYPE_POLY:
193 curve_normals.copy_from(evaluated_normals.slice(evaluated_points));
195 case CURVE_TYPE_BEZIER: {
196 const Span<float3> normals = evaluated_normals.slice(evaluated_points);
197 curve_normals.first() = normals.first();
198 const Span<int> offsets = curves.bezier_evaluated_offsets_for_curve(i_curve);
199 for (const int i : IndexRange(points.size()).drop_front(1)) {
200 curve_normals[i] = normals[offsets[i]];
204 case CURVE_TYPE_NURBS: {
207 nurbs_tangents.clear();
208 nurbs_tangents.resize(points.size());
209 const bool cyclic = curves_cyclic[i_curve];
210 const Span<float3> curve_positions = positions.slice(points);
211 curves::poly::calculate_tangents(curve_positions, cyclic, nurbs_tangents);
212 switch (NormalMode(normal_modes[i_curve])) {
213 case NORMAL_MODE_Z_UP:
214 curves::poly::calculate_normals_z_up(nurbs_tangents, curve_normals);
216 case NORMAL_MODE_MINIMUM_TWIST:
217 curves::poly::calculate_normals_minimum(nurbs_tangents, cyclic, curve_normals);
219 case NORMAL_MODE_FREE:
220 custom_normals.materialize(points, curve_normals);
262 curves.ensure_evaluated_lengths();
267 return curves.evaluated_length_total_for_curve(index, cyclic[index]);
320 curves.tag_topology_changed();
326 curves.update_curve_types();
327 curves.tag_topology_changed();
333 curves.tag_positions_changed();
339 curves.tag_radii_changed();
345 curves.tag_normals_changed();
370 if (vertex_group_index < 0) {
379 const int vertex_group_index)
const
399 if (vertex_group_index < 0) {
415 const std::string name = attribute_id;
420 &
curves->vertex_group_names, name.c_str(), &index, &group))
426 if (
curves->deform_verts().is_empty()) {
447 const auto get_fn = [&]() {
474 return &
curves.curve_data;
478 return &
curves.curve_data;
480 [](
const void *owner) ->
int {
482 return curves.curves_num();
487 return &
curves.point_data;
491 return &
curves.point_data;
493 [](
const void *owner) ->
int {
495 return curves.points_num();
540 static auto handle_type_clamp = mf::build::SI1_SO<int8_t, int8_t>(
541 "Handle Type Validate",
545 mf::build::exec_presets::AllSpanOrSingle());
569 static const auto nurbs_order_clamp = mf::build::SI1_SO<int8_t, int8_t>(
570 "NURBS Order Validate",
571 [](
int8_t value) {
return std::max<int8_t>(value, 1); },
572 mf::build::exec_presets::AllSpanOrSingle());
573 static int nurbs_order_default = 4;
581 &nurbs_order_default);
583 static const auto normal_mode_clamp = mf::build::SI1_SO<int8_t, int8_t>(
584 "Normal Mode Validate",
588 mf::build::exec_presets::AllSpanOrSingle());
604 static const auto knots_mode_clamp = mf::build::SI1_SO<int8_t, int8_t>(
605 "Knots Mode Validate",
609 mf::build::exec_presets::AllSpanOrSingle());
618 static const auto curve_type_clamp = mf::build::SI1_SO<int8_t, int8_t>(
619 "Curve Type Validate",
623 mf::build::exec_presets::AllSpanOrSingle());
632 static const auto resolution_clamp = mf::build::SI1_SO<int, int>(
633 "Resolution Validate",
634 [](
int value) {
return std::max<int>(value, 1); },
635 mf::build::exec_presets::AllSpanOrSingle());
636 static int resolution_default = 12;
644 &resolution_default);
673 {&vertex_groups, &curve_custom_data, &point_custom_data});
683 fn.domain_size = [](
const void *owner,
const AttrDomain domain) {
684 if (owner ==
nullptr) {
690 return curves.points_num();
692 return curves.curves_num();
697 fn.domain_supported = [](
const void * ,
const AttrDomain domain) {
700 fn.adapt_domain = [](
const void *owner,
704 if (owner ==
nullptr) {
708 return curves.adapt_domain(varray, from_domain, to_domain);
struct Curves * BKE_curves_copy_for_eval(const struct Curves *curves_src)
Low-level operations for curves.
void BKE_id_free(Main *bmain, void *idv)
void * BKE_id_new_nomain(short type, const char *name)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Enumerations for DNA_ID.h.
@ NORMAL_MODE_MINIMUM_TWIST
@ NURBS_KNOT_MODE_ENDPOINT_BEZIER
constexpr bool is_empty() const
static VArray ForContainer(ContainerT container)
static VArray ForSingle(T value, const int64_t size)
static VArray ForSpan(Span< T > values)
static VArray ForFunc(const int64_t size, GetFunc get_func)
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
void ensure_owns_direct_data() override
const Curve * get_curve_for_render() const
void count_memory(MemoryCounter &memory) const override
void replace(Curves *curve, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
const Curves * get() const
GeometryComponentPtr copy() const override
bool is_empty() const final
std::optional< AttributeAccessor > attributes() const final
std::optional< MutableAttributeAccessor > attributes_for_write() final
bool owns_direct_data() const override
GAttributeWriter try_get_for_write(void *owner, const StringRef attribute_id) const final
void foreach_domain(const FunctionRef< void(AttrDomain)> callback) const final
GAttributeReader get_for_vertex_group_index(const CurvesGeometry &curves, const Span< MDeformVert > dverts, const int vertex_group_index) const
GAttributeReader try_get_for_read(const void *owner, const StringRef attribute_id) const final
bool foreach_attribute(const void *owner, FunctionRef< void(const AttributeIter &)> fn) const final
bool try_delete(void *owner, const StringRef attribute_id) const final
GeometryComponent(Type type)
draw_view in_light_buf[] float
static float normals[][3]
void MEM_freeN(void *vmemh)
AttributeAccessorFunctions accessor_functions_for_providers()
bool attribute_name_is_anonymous(const StringRef name)
static const AttributeAccessorFunctions & get_curves_accessor_functions_ref()
ImplicitSharingPtr< GeometryComponent > GeometryComponentPtr
static void tag_component_topology_changed(void *owner)
static void tag_component_normals_changed(void *owner)
static Array< float3 > curve_normal_point_domain(const CurvesGeometry &curves)
static void tag_component_positions_changed(void *owner)
void remove_defgroup_index(MutableSpan< MDeformVert > dverts, int defgroup_index)
static AttributeAccessorFunctions get_curves_accessor_functions()
VArray< float3 > curve_normals_varray(const CurvesGeometry &curves, AttrDomain domain)
static void tag_component_radii_changed(void *owner)
static void tag_component_curve_types_changed(void *owner)
static VArray< float > construct_curve_length_gvarray(const CurvesGeometry &curves, const AttrDomain domain)
static ComponentAttributeProviders create_attribute_providers_for_curve()
VMutableArray< float > varray_for_mutable_deform_verts(MutableSpan< MDeformVert > dverts, int defgroup_index)
VArray< float > varray_for_deform_verts(Span< MDeformVert > dverts, int defgroup_index)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< float, 3 > float3
unsigned __int64 uint64_t