42 if (curves_ !=
nullptr) {
52 if (curves_ !=
nullptr) {
56 if (curve_for_render_ !=
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_;
147 return curve_for_render_;
158 const OffsetIndices points_by_curve = curves.points_by_curve();
159 const OffsetIndices evaluated_points_by_curve = curves.evaluated_points_by_curve();
161 const VArray<int> resolutions = curves.resolution();
170 const Span<float3> evaluated_normals = curves.evaluated_normals();
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);
235 return curves.adapt_domain<
float3>(
241 if (domain == AttrDomain::Point) {
245 if (domain == AttrDomain::Curve) {
246 return curves.adapt_domain<
float3>(
262 curves.ensure_evaluated_lengths();
266 curves.curves_num(), [&curves, cyclic = std::move(cyclic)](
int64_t index) {
267 return curves.evaluated_length_total_for_curve(index, cyclic[index]);
270 if (domain == AttrDomain::Curve) {
274 if (domain == AttrDomain::Point) {
275 return curves.adapt_domain<
float>(std::move(lengths), AttrDomain::Curve, AttrDomain::Point);
281CurveLengthFieldInput::CurveLengthFieldInput()
327 curves.tag_topology_changed();
365 if (curves ==
nullptr) {
370 if (vertex_group_index < 0) {
379 const int vertex_group_index)
const
394 if (curves ==
nullptr) {
399 if (vertex_group_index < 0) {
412 if (curves ==
nullptr) {
415 const std::string name = attribute_id;
420 &curves->vertex_group_names, name.c_str(), &index, &group))
426 if (curves->deform_verts().is_empty()) {
439 if (curves ==
nullptr) {
447 const auto get_fn = [&]() {
452 if (iter.is_stopped()) {
480 [](
const void *owner) ->
int {
493 [](
const void *owner) ->
int {
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});
684 if (owner ==
nullptr) {
692 return curves.curves_num();
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)
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
void update_curve_types()
void tag_normals_changed()
void tag_topology_changed()
GVArray adapt_domain(const GVArray &varray, AttrDomain from, AttrDomain to) const
void tag_positions_changed()
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
DEGForeachIDComponentCallback callback
draw_view in_light_buf[] float
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
const struct Curves * curve_eval
struct EditFont * editfont
GVArray(* adapt_domain)(const void *owner, const GVArray &varray, AttrDomain from_domain, AttrDomain to_domain)
bool(* domain_supported)(const void *owner, AttrDomain domain)
int(* domain_size)(const void *owner, AttrDomain domain)