23 curves.tag_topology_changed();
29 curves.update_curve_types();
30 curves.tag_topology_changed();
36 curves.tag_positions_changed();
42 curves.tag_radii_changed();
48 curves.tag_normals_changed();
54 curves.tag_material_index_changed();
84 return curves.points_num();
86 return curves.curves_num();
94 const int vertex_group_index)
111 if (vertex_group_index < 0) {
126 if (vertex_group_index < 0) {
147 if (
curves->deform_verts().is_empty()) {
166 const auto get_fn = [&]() {
182 static auto attributes = []() {
187 map.
add_new(
"position", std::move(position));
190 map.
add_new(
"radius", std::move(radius));
193 map.
add_new(
"tilt", std::move(tilt));
196 map.
add_new(
"handle_left", std::move(handle_left));
199 map.
add_new(
"handle_right", std::move(handle_right));
201 static auto handle_type_clamp = mf::build::SI1_SO<int8_t, int8_t>(
202 "Handle Type Validate",
206 mf::build::exec_presets::AllSpanOrSingle());
210 map.
add_new(
"handle_type_left", std::move(handle_type_left));
214 map.
add_new(
"handle_type_right", std::move(handle_type_right));
216 static float default_nurbs_weight = 1.0f;
219 map.
add_new(
"nurbs_weight", std::move(nurbs_weight));
221 static const auto nurbs_order_clamp = mf::build::SI1_SO<int8_t, int8_t>(
222 "NURBS Order Validate",
223 [](int8_t value) {
return std::max<int8_t>(value, 1); },
224 mf::build::exec_presets::AllSpanOrSingle());
225 static int nurbs_order_default = 4;
229 map.
add_new(
"nurbs_order", std::move(nurbs_order));
231 static const auto normal_mode_clamp = mf::build::SI1_SO<int8_t, int8_t>(
232 "Normal Mode Validate",
236 mf::build::exec_presets::AllSpanOrSingle());
239 map.
add_new(
"normal_mode", std::move(normal_mode));
242 map.
add_new(
"custom_normal", std::move(custom_normal));
244 static const auto knots_mode_clamp = mf::build::SI1_SO<int8_t, int8_t>(
245 "Knots Mode Validate",
247 return std::clamp<int8_t>(
250 mf::build::exec_presets::AllSpanOrSingle());
253 map.
add_new(
"knots_mode", std::move(knots_mode));
255 static const auto curve_type_clamp = mf::build::SI1_SO<int8_t, int8_t>(
256 "Curve Type Validate",
260 mf::build::exec_presets::AllSpanOrSingle());
263 map.
add_new(
"curve_type", std::move(curve_type));
265 static const auto resolution_clamp = mf::build::SI1_SO<int, int>(
266 "Resolution Validate",
267 [](
int value) {
return std::max<int>(value, 1); },
268 mf::build::exec_presets::AllSpanOrSingle());
269 static int resolution_default = 12;
273 map.
add_new(
"resolution", std::move(resolution));
276 map.
add_new(
"cyclic", std::move(cyclic));
278 static const auto material_index_clamp = mf::build::SI1_SO<int, int>(
279 "Material Index Validate",
282 return std::clamp<int>(value, 0, std::numeric_limits<short>::max());
284 mf::build::exec_presets::AllSpanOrSingle());
287 map.
add_new(
"material_index", std::move(material_index));
299 fn.domain_supported = [](
const void * ,
const AttrDomain domain) {
303 fn.builtin_domain_and_type = [](
const void * ,
304 const StringRef name) -> std::optional<AttributeDomainAndType> {
330 fn.adapt_domain = [](
const void *owner,
335 return curves.adapt_domain(varray, from_domain, to_domain);
337 fn.foreach_attribute = [](
const void *owner,
344 if (!should_continue) {
350 const auto get_fn = [&]() {
392 if (!info->deletable) {
406 fn.add = [](
void *owner,
415 if (info->domain != domain || info->type != type) {
Low-level operations for curves.
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
@ NORMAL_MODE_MINIMUM_TWIST
@ NURBS_KNOT_MODE_ENDPOINT_BEZIER
Object is a sort of wrapper for general info.
void add_new(const Key &key, const Value &value)
constexpr bool is_empty() const
static VArray from_single(T value, const int64_t size)
const AttributeAccessor * accessor
Attribute & add(std::string name, bke::AttrDomain domain, bke::AttrType data_type, Attribute::DataVariant data)
Attribute * lookup(StringRef name)
bool remove(StringRef name)
void foreach_with_stop(FunctionRef< bool(Attribute &)> fn)
AttrDomain domain() const
StringRefNull name() const
AttrType data_type() const
void MEM_freeN(void *vmemh)
static void tag_curve_types_changed(void *owner)
static void tag_topology_changed(void *owner)
static bool foreach_vertex_group(const void *owner, FunctionRef< void(const AttributeIter &)> fn)
static void tag_material_index_changed(void *owner)
static GAttributeWriter try_get_vertex_group_for_write(void *owner, const StringRef attribute_id)
static void tag_normals_changed(void *owner)
static const auto & changed_tags()
static void tag_radii_changed(void *owner)
static void tag_positions_changed(void *owner)
static int get_domain_size(const void *owner, const AttrDomain domain)
static const auto & builtin_attributes()
const AttributeAccessorFunctions & get_attribute_accessor_functions()
static bool try_delete_vertex_group(void *owner, const StringRef name)
static GAttributeReader reader_for_vertex_group_index(const CurvesGeometry &curves, const Span< MDeformVert > dverts, const int vertex_group_index)
static GAttributeReader try_get_vertex_group(const void *owner, const StringRef attribute_id)
static AttributeAccessorFunctions get_curves_accessor_functions()
GAttributeReader attribute_to_reader(const Attribute &attribute, const AttrDomain domain, const int64_t domain_size)
void remove_defgroup_index(MutableSpan< MDeformVert > dverts, int defgroup_index)
Attribute::DataVariant attribute_init_to_data(const bke::AttrType data_type, const int64_t domain_size, const AttributeInit &initializer)
GAttributeWriter attribute_to_writer(void *owner, const Map< StringRef, AttrUpdateOnChange > &changed_tags, const int64_t domain_size, Attribute &attribute)
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)
AttributeValidator validator