61#include "RNA_prototypes.hh"
114 return unique_curves;
118 const bool check_editable,
119 const bool check_surface,
120 const bool check_edit_mode)
126 if (check_editable) {
138 if (check_edit_mode) {
194 if (possible_mface_indices.
size() == 1) {
195 return possible_mface_indices.
first();
199 float best_distance_sq =
FLT_MAX;
200 for (
const int possible_mface_i : possible_mface_indices) {
201 const MFace &possible_mface = mface[possible_mface_i];
206 positions[possible_mface.
v1],
207 positions[possible_mface.
v2],
208 positions[possible_mface.
v3]);
210 if (distance_sq < best_distance_sq) {
211 best_distance_sq = distance_sq;
212 mface_i = possible_mface_i;
216 if (possible_mface.
v4) {
220 positions[possible_mface.
v1],
221 positions[possible_mface.
v3],
222 positions[possible_mface.
v4]);
224 if (distance_sq < best_distance_sq) {
225 best_distance_sq = distance_sq;
226 mface_i = possible_mface_i;
242 float mface_positions_su[4][3];
251 mface_weights, positions[mface.
v1], positions[mface.
v2], positions[mface.
v3], position);
252 mface_weights[3] = 0.0f;
254 return mface_weights;
260 bool *r_could_not_convert_some_curves)
267 if (curves_id.
surface ==
nullptr) {
274 Mesh &surface_me = *
static_cast<Mesh *
>(surface_ob.
data);
281 const Span<int> tri_faces = surface_me.corner_tri_faces();
284 *r_could_not_convert_some_curves =
true;
290 curves.curves_range(),
GrainSize(4096), memory, [&](
const int curve_i) {
291 return points_by_curve[curve_i].
size() > 1;
294 const int hair_num = multi_point_curves.
size();
303 particle_system = psys;
307 if (particle_system ==
nullptr) {
310 particle_system = psmd.
psys;
333 for (
const int mface_i : mface_to_poly_map.
index_range()) {
334 const int face_i = mface_to_poly_map[mface_i];
335 poly_to_mface_map[face_i].append(mface_i);
342 const Span<float3> positions = surface_me.vert_positions();
344 multi_point_curves.
foreach_index([&](
const int curve_i,
const int new_hair_i) {
345 const IndexRange points = points_by_curve[curve_i];
347 const float3 &root_pos_cu = positions_cu[points.
first()];
356 const int tri_i = nearest.
index;
357 const int face_i = tri_faces[tri_i];
360 positions, mfaces, poly_to_mface_map[face_i], root_pos_su);
361 const MFace &mface = mfaces[mface_i];
366 const int num_keys = points.
size();
373 particle.
num = mface_i;
381 hair_to_surface_mat.
location() = root_pos_su;
385 const float3 &key_pos_cu = positions_cu[points[key_i]];
389 HairKey &key = hair_keys[key_i];
391 const float key_fac = key_i /
float(hair_keys.
size() - 1);
392 key.
time = 100.0f * key_fac;
393 key.
weight = 1.0f - key_fac;
411 bool could_not_convert_some_curves =
false;
417 if (curves_ob != &active_object) {
423 if (could_not_convert_some_curves) {
426 "Some curves could not be converted because they were not attached to the surface");
438 ot->name =
"Convert Curves to Particle System";
439 ot->idname =
"CURVES_OT_convert_to_particle_system";
440 ot->description =
"Add a new or update an existing hair particle system on the surface object";
466 if (transfer_parents) {
467 for (
const int parent_i : parents_cache.
index_range()) {
468 const int segments = parents_cache[parent_i]->segments;
472 parents_to_transfer.
append(parent_i);
473 curve_offsets.
append(points_num);
474 points_num += segments + 1;
477 for (
const int child_i : children_cache.
index_range()) {
478 const int segments = children_cache[child_i]->segments;
482 children_to_transfer.
append(child_i);
483 curve_offsets.
append(points_num);
484 points_num += segments + 1;
486 const int curves_num = parents_to_transfer.
size() + children_to_transfer.
size();
487 curve_offsets.
append(points_num);
490 curves.offsets_for_write().copy_from(curve_offsets);
492 const float4x4 &object_to_world_mat =
object.object_to_world();
500 const int curve_index_offset) {
502 for (const int i : range) {
503 const int hair_i = indices_to_transfer[i];
504 const int curve_i = i + curve_index_offset;
505 const IndexRange points = points_by_curve[curve_i];
506 const Span<ParticleCacheKey> keys{hair_cache[hair_i], points.size()};
507 for (const int key_i : keys.index_range()) {
508 const float3 key_pos_wo = keys[key_i].co;
509 positions[points[key_i]] = math::transform_point(world_to_object_mat, key_pos_wo);
515 if (transfer_parents) {
516 copy_hair_to_curves(parents_cache, parents_to_transfer, 0);
518 copy_hair_to_curves(children_cache, children_to_transfer, parents_to_transfer.size());
520 curves.update_curve_types();
521 curves.tag_topology_changed();
534 if (psys_orig ==
nullptr) {
537 if (psys_orig ==
nullptr) {
550 psys_eval = psmd->
psys;
573 ot->name =
"Convert Particle System to Curves";
574 ot->idname =
"CURVES_OT_convert_from_particle_system";
575 ot->description =
"Add a new curves object based on the current state of the particle system";
599 const Mesh &surface_mesh = *
static_cast<const Mesh *
>(surface_ob.
data);
600 const Span<float3> surface_positions = surface_mesh.vert_positions();
601 const Span<int> corner_verts = surface_mesh.corner_verts();
602 const Span<int3> surface_corner_tris = surface_mesh.corner_tris();
616 switch (attach_mode) {
623 for (const int curve_i : curves_range) {
624 const IndexRange points = points_by_curve[curve_i];
625 const int first_point_i = points.first();
626 const float3 old_first_point_pos_cu = positions_cu[first_point_i];
627 const float3 old_first_point_pos_su = math::transform_point(transforms.curves_to_surface,
628 old_first_point_pos_cu);
630 BVHTreeNearest nearest;
632 nearest.dist_sq = FLT_MAX;
633 BLI_bvhtree_find_nearest(surface_bvh.tree,
634 old_first_point_pos_su,
636 surface_bvh.nearest_callback,
638 const int tri_index = nearest.index;
639 if (tri_index == -1) {
643 const float3 new_first_point_pos_su = nearest.co;
644 const float3 new_first_point_pos_cu = math::transform_point(transforms.surface_to_curves,
645 new_first_point_pos_su);
646 const float3 pos_diff_cu = new_first_point_pos_cu - old_first_point_pos_cu;
648 for (float3 &pos_cu : positions_cu.slice(points)) {
649 pos_cu += pos_diff_cu;
652 if (!surface_uv_map.is_empty()) {
653 const int3 &tri = surface_corner_tris[tri_index];
654 const float3 bary_coords = bke::mesh_surface_sample::compute_bary_coord_in_triangle(
655 surface_positions, corner_verts, tri, new_first_point_pos_su);
656 const float2 uv = bke::mesh_surface_sample::sample_corner_attribute_with_bary_coords(
657 bary_coords, tri, surface_uv_map);
658 surface_uv_coords[curve_i] = uv;
666 *r_missing_uvs =
true;
670 ReverseUVSampler reverse_uv_sampler{surface_uv_map, surface_corner_tris};
673 for (const int curve_i : curves_range) {
674 const IndexRange points = points_by_curve[curve_i];
675 const int first_point_i = points.first();
676 const float3 old_first_point_pos_cu = positions_cu[first_point_i];
678 const float2 uv = surface_uv_coords[curve_i];
679 ReverseUVSampler::Result lookup_result = reverse_uv_sampler.sample(uv);
680 if (lookup_result.type != ReverseUVSampler::ResultType::Ok) {
681 *r_invalid_uvs = true;
685 const int3 &tri = surface_corner_tris[lookup_result.tri_index];
686 const float3 &bary_coords = lookup_result.bary_weights;
688 const float3 &p0_su = surface_positions[corner_verts[tri[0]]];
689 const float3 &p1_su = surface_positions[corner_verts[tri[1]]];
690 const float3 &p2_su = surface_positions[corner_verts[tri[2]]];
692 float3 new_first_point_pos_su;
693 interp_v3_v3v3v3(new_first_point_pos_su, p0_su, p1_su, p2_su, bary_coords);
694 const float3 new_first_point_pos_cu = math::transform_point(transforms.surface_to_curves,
695 new_first_point_pos_su);
697 const float3 pos_diff_cu = new_first_point_pos_cu - old_first_point_pos_cu;
698 for (float3 &pos_cu : positions_cu.slice(points)) {
699 pos_cu += pos_diff_cu;
707 curves.tag_positions_changed();
715 bool found_invalid_uvs =
false;
716 bool found_missing_uvs =
false;
722 Curves &curves_id = *
static_cast<Curves *
>(curves_ob->data);
723 if (curves_id.
surface ==
nullptr) {
730 *curves_ob, *curves_id.
surface, attach_mode, &found_invalid_uvs, &found_missing_uvs);
734 if (found_missing_uvs) {
737 "Curves do not have attachment information that can be used for deformation");
739 if (found_invalid_uvs) {
755 ot->name =
"Snap Curves to Surface";
756 ot->idname =
"CURVES_OT_snap_curves_to_surface";
757 ot->description =
"Move curves so that the first point is exactly on the surface mesh";
760 ot->exec = snap_curves_to_surface_exec;
765 {
int(AttachMode::Nearest),
769 "Find the closest point on the surface for the root point of every curve and move the root "
771 {
int(AttachMode::Deform),
775 "Re-attach curves to a deformed surface using the existing attachment information. This "
776 "only works when the topology of the surface mesh has not changed"},
777 {0,
nullptr, 0,
nullptr,
nullptr},
783 int(AttachMode::Nearest),
785 "How to find the point on the surface to attach to");
799 curves_id->selection_domain = char(domain);
803 if (
curves.points_num() == 0) {
812 std::string active_attribute;
816 active_attribute = layer->
name;
819 if (
const GVArray src = *attributes.
lookup(selection_name, domain)) {
820 const CPPType &type = src.type();
822 src.materialize(dst);
824 attributes.
remove(selection_name);
825 if (!attributes.
add(selection_name,
834 if (!active_attribute.empty()) {
855 ot->name =
"Set Select Mode";
856 ot->idname = __func__;
857 ot->description =
"Change the mode used for selection masking in curves sculpt mode";
871 return std::any_of(curves_ids.
begin(), curves_ids.
end(), [](
const Curves *curves_id) {
872 return has_anything_selected(curves_id->geometry.wrap());
886 for (
Curves *curves_id : unique_curves) {
901 ot->name =
"(De)select All";
902 ot->idname =
"CURVES_OT_select_all";
903 ot->description =
"(De)select all control points";
920 for (
Curves *curves_id : unique_curves) {
923 const int domain_size =
curves.attributes().domain_size(selection_domain);
927 curves, selection_domain,
seed, probability, memory)
933 if (!was_anything_selected) {
958 ot->name =
"Select Random";
959 ot->idname = __func__;
960 ot->description =
"Randomizes existing selection or create new random selection";
974 "Source of randomness",
983 "Chance of every point or curve being included in the selection",
994 for (
Curves *curves_id : unique_curves) {
999 curves, amount_start, amount_end,
true, memory);
1004 if (!was_anything_selected) {
1011 if (
selection.span.type().is<
float>()) {
1039 ot->name =
"Select Ends";
1040 ot->idname = __func__;
1041 ot->description =
"Select end points of curves";
1055 "Number of points to select from the front",
1064 "Number of points to select from the back",
1072 for (
Curves *curves_id : unique_curves) {
1086 ot->name =
"Select Linked";
1087 ot->idname = __func__;
1088 ot->description =
"Select all points in curves with any point selection";
1099 for (
Curves *curves_id : unique_curves) {
1113 ot->name =
"Select More";
1114 ot->idname = __func__;
1115 ot->description =
"Grow the selection by one point";
1126 for (
Curves *curves_id : unique_curves) {
1140 ot->name =
"Select Less";
1141 ot->idname = __func__;
1142 ot->description =
"Shrink the selection by one point";
1155 if (
object ==
nullptr) {
1171 Mesh &new_surface_mesh = *
static_cast<Mesh *
>(new_surface_ob.
data);
1179 Object &curves_ob = *selected_ob;
1183 if (new_uv_map_name !=
nullptr) {
1199 curves_id.
surface = &new_surface_ob;
1229 ot->name =
"Set Curves Surface Object";
1230 ot->idname = __func__;
1232 "Use the active object as surface for selected curves objects and set it as the parent";
1259 ot->name =
"Delete";
1260 ot->idname = __func__;
1261 ot->description =
"Remove selected control points or curves";
1297 ot->name =
"Duplicate";
1298 ot->idname = __func__;
1299 ot->description =
"Copy selected points or curves";
1320 curves.attributes_for_write().remove(
"tilt");
1326 curves.tag_normals_changed();
1337 ot->name =
"Clear Tilt";
1338 ot->idname = __func__;
1339 ot->description =
"Clear the tilt of selected control points";
1364 [&](
const int i) { cyclic.
span[i] = !cyclic.
span[i]; });
1367 if (!cyclic.
span.as_span().contains(
true)) {
1368 attributes.
remove(
"cyclic");
1371 curves.calculate_bezier_auto_handles();
1383 ot->name =
"Toggle Cyclic";
1384 ot->idname = __func__;
1385 ot->description =
"Make active curve closed/opened loop";
1409 options.convert_bezier_handles_to_poly_points = use_handles;
1410 options.convert_bezier_handles_to_catmull_rom_points = use_handles;
1411 options.keep_bezier_shape_as_nurbs = use_handles;
1412 options.keep_catmull_rom_shape_as_nurbs = use_handles;
1426 ot->name =
"Set Curve Type";
1427 ot->idname = __func__;
1428 ot->description =
"Set type of selected curves";
1442 "Take handle information into account in the conversion");
1469 ot->name =
"Switch Direction";
1470 ot->idname = __func__;
1471 ot->description =
"Reverse the direction of the selected curves";
1487 const int points_num =
curves.points_num();
1495 points_selection.
to_bools(points_selection_span);
1497 Array<int> segment_cuts(points_num, number_cuts);
1501 for (const int curve_i : range) {
1502 const IndexRange points = points_by_curve[curve_i];
1503 if (points.size() <= 1) {
1506 for (const int point_i : points.drop_back(1)) {
1507 if (!points_selection_span[point_i] || !points_selection_span[point_i + 1]) {
1508 segment_cuts[point_i] = 0;
1512 if (!points_selection_span[points.last()] || !points_selection_span[points.first()]) {
1513 segment_cuts[points.last()] = 0;
1531 ot->name =
"Subdivide";
1532 ot->idname = __func__;
1533 ot->description =
"Subdivide selected curve segments";
1541 prop =
RNA_def_int(
ot->srna,
"number_cuts", 1, 1, 1000,
"Number of Cuts",
"", 1, 10);
1552 const int new_points_num = new_curves.
points_num();
1553 const int new_curves_num = new_curves.
curves_num();
1573 dst_curves = std::move(joined_curves_id->geometry.wrap());
1599 curves.cyclic_for_write().fill(
true);
1602 curves.resolution_for_write().fill(12);
1605 positions[0] =
float3(-radius, 0, 0);
1606 positions[1] =
float3(0, radius, 0);
1607 positions[2] =
float3(radius, 0, 0);
1608 positions[3] =
float3(0, -radius, 0);
1611 curves.handle_positions_left_for_write();
1612 curves.handle_positions_right_for_write();
1614 curves.calculate_bezier_auto_handles();
1622 Curves *active_curves_id =
static_cast<Curves *
>(
object->data);
1636 ot->name =
"Add Circle";
1637 ot->idname = __func__;
1638 ot->description =
"Add new circle curve";
1662 curves.resolution_for_write().fill(12);
1668 left_handles[0] =
float3(-1.5f, -0.5, 0) * radius;
1669 positions[0] =
float3(-1.0f, 0, 0) * radius;
1670 right_handles[0] =
float3(-0.5f, 0.5f, 0) * radius;
1672 left_handles[1] =
float3(0, 0, 0) * radius;
1673 positions[1] =
float3(1.0f, 0, 0) * radius;
1674 right_handles[1] =
float3(2.0f, 0, 0) * radius;
1682 Curves *active_curves_id =
static_cast<Curves *
>(
object->data);
1696 ot->name =
"Add Bezier";
1697 ot->idname = __func__;
1698 ot->description =
"Add new bezier curve";
1730 for (const int point_i : range) {
1731 if (selection_left[point_i] || selection[point_i]) {
1732 handle_types_left[point_i] = int8_t(dst_handle_type);
1734 if (selection_right[point_i] || selection[point_i]) {
1735 handle_types_right[point_i] = int8_t(dst_handle_type);
1740 curves.calculate_bezier_auto_handles();
1741 curves.tag_topology_changed();
1753 ot->name =
"Set Handle Type";
1754 ot->idname = __func__;
1755 ot->description =
"Set the handle type for bezier curves";
1803 "Make copies of selected elements and move them",
1812 "Extrude Curve and Move",
1813 "Extrude curve and move result",
void BKE_attributes_active_set(AttributeOwner &owner, const char *name)
struct CustomDataLayer * BKE_attributes_active_get(AttributeOwner &owner)
void free_bvhtree_from_mesh(BVHTreeFromMesh *data)
BVHTree * BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data, const Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
@ BVHTREE_FROM_CORNER_TRIS
#define CTX_DATA_BEGIN(C, Type, instance, member)
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Object * CTX_data_edit_object(const bContext *C)
Main * CTX_data_main(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
Low-level operations for curves.
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
bool BKE_id_is_editable(const Main *bmain, const ID *id)
void BKE_mesh_tessface_calc(Mesh *mesh)
General operations, lookup, etc. for blender objects.
void BKE_object_apply_mat4(Object *ob, const float mat[4][4], bool use_compat, bool use_parent)
Object * BKE_object_add(Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name) ATTR_NONNULL(1
struct ModifierData * object_add_particle_system(struct Main *bmain, const struct Scene *scene, struct Object *ob, const char *name)
void psys_mat_hair_to_object(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4])
void psys_free_particles(struct ParticleSystem *psys)
void psys_changed_type(struct Object *ob, struct ParticleSystem *psys)
struct ParticleSystem * psys_get_current(struct Object *ob)
void BKE_report(ReportList *reports, eReportType type, const char *message)
#define BLI_assert_unreachable()
int BLI_bvhtree_find_nearest(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
A KD-tree for nearest neighbor search.
#define LISTBASE_FOREACH(type, var, list)
void interp_weights_tri_v3(float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3])
void closest_on_tri_to_point_v3(float r[3], const float p[3], const float v1[3], const float v2[3], const float v3[3])
void interp_weights_poly_v3(float w[], float v[][3], int n, const float co[3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define BLI_SCOPED_DEFER(function_to_defer)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ eModifierType_ParticleSystem
Object is a sort of wrapper for general info.
@ OB_MODIFIER_FLAG_ADD_REST_POSITION
bool ED_operator_object_active_editable_ex(bContext *C, const Object *ob)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
BPy_StructRNA * depsgraph
static unsigned long seed
VecBase< float, 3 > float3
static AttributeOwner from_id(ID *id)
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
constexpr int64_t first() const
constexpr int64_t size() const
constexpr int64_t size() const
constexpr T * data() const
constexpr IndexRange index_range() const
constexpr const T & first() const
constexpr int64_t size() const
constexpr const T * end() const
constexpr IndexRange index_range() const
constexpr const T * begin() const
constexpr bool is_empty() const
static VArray ForSpan(Span< T > values)
void add_new(const Key &key)
void append(const T &value)
GAttributeReader lookup(const StringRef attribute_id) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
int domain_size(const AttrDomain domain) const
void tag_topology_changed()
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
bool remove(const StringRef attribute_id)
bool add(const StringRef attribute_id, const AttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer)
void to_bools(MutableSpan< bool > r_bools) const
void foreach_index(Fn &&fn) const
IndexRange index_range() const
CCL_NAMESPACE_BEGIN struct Options options
static int select_linked_exec(bContext *C, wmOperator *)
static int delete_exec(bContext *C, wmOperator *op)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
static int select_all_exec(bContext *C, wmOperator *op)
eCustomDataType cpp_type_to_custom_data_type(const CPPType &type)
Curves * curves_new_nomain(int points_num, int curves_num)
static int exec(bContext *C, wmOperator *op)
static CurvesGeometry generate_bezier_primitive(const float radius)
static CurvesGeometry generate_circle_primitive(const float radius)
static int exec(bContext *C, wmOperator *op)
static int exec(bContext *C, wmOperator *)
static int curves_convert_from_particle_system_exec(bContext *C, wmOperator *)
static bke::CurvesGeometry particles_to_curves(Object &object, ParticleSystem &psys)
static bool curves_convert_from_particle_system_poll(bContext *C)
static float4 compute_mface_weights_for_position(const Span< float3 > positions, const MFace &mface, const float3 &position)
static int curves_convert_to_particle_system_exec(bContext *C, wmOperator *op)
static int find_mface_for_root_position(const Span< float3 > positions, const MFace *mface, const Span< int > possible_mface_indices, const float3 &root_pos)
static void try_convert_single_object(Object &curves_ob, Main &bmain, Scene &scene, bool *r_could_not_convert_some_curves)
static int exec(bContext *C, wmOperator *op)
static int delete_exec(bContext *C, wmOperator *)
static int delete_exec(bContext *C, wmOperator *)
static int exec(bContext *C, wmOperator *)
static int exec(bContext *C, wmOperator *op)
static int curves_set_selection_domain_exec(bContext *C, wmOperator *op)
static void snap_curves_to_surface_exec_object(Object &curves_ob, const Object &surface_ob, const AttachMode attach_mode, bool *r_invalid_uvs, bool *r_missing_uvs)
static int snap_curves_to_surface_exec(bContext *C, wmOperator *op)
static int exec(bContext *C, wmOperator *op)
static int surface_set_exec(bContext *C, wmOperator *op)
static bool surface_set_poll(bContext *C)
static int exec(bContext *C, wmOperator *)
static void CURVES_OT_surface_set(wmOperatorType *ot)
void select_linked(bke::CurvesGeometry &curves, const IndexMask &curves_mask)
void operatormacros_curves()
bool remove_selection(bke::CurvesGeometry &curves, const bke::AttrDomain selection_domain)
static void CURVES_OT_convert_from_particle_system(wmOperatorType *ot)
void keymap_curves(wmKeyConfig *keyconf)
void CURVES_OT_draw(wmOperatorType *ot)
static bool has_anything_selected(const Span< Curves * > curves_ids)
static int select_ends_exec(bContext *C, wmOperator *op)
static void CURVES_OT_select_less(wmOperatorType *ot)
static void CURVES_OT_convert_to_particle_system(wmOperatorType *ot)
static void CURVES_OT_select_random(wmOperatorType *ot)
IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves, IndexMaskMemory &memory)
static void CURVES_OT_select_ends(wmOperatorType *ot)
void select_all(bke::CurvesGeometry &curves, const IndexMask &mask, const bke::AttrDomain selection_domain, int action)
void operatortypes_curves()
static bool editable_curves_point_domain_poll(bContext *C)
void duplicate_curves(bke::CurvesGeometry &curves, const IndexMask &mask)
static void CURVES_OT_add_bezier(wmOperatorType *ot)
void duplicate_points(bke::CurvesGeometry &curves, const IndexMask &mask)
static void CURVES_OT_select_linked(wmOperatorType *ot)
VectorSet< Curves * > get_unique_editable_curves(const bContext &C)
static int select_less_exec(bContext *C, wmOperator *)
static int select_linked_exec(bContext *C, wmOperator *)
bool editable_curves_poll(bContext *C)
void select_adjacent(bke::CurvesGeometry &curves, const IndexMask &curves_mask, const bool deselect)
static void CURVES_OT_handle_type_set(wmOperatorType *ot)
static void CURVES_OT_subdivide(wmOperatorType *ot)
void foreach_selection_attribute_writer(bke::CurvesGeometry &curves, bke::AttrDomain selection_domain, blender::FunctionRef< void(bke::GSpanAttributeWriter &selection)> fn)
static int select_random_exec(bContext *C, wmOperator *op)
static void CURVES_OT_select_more(wmOperatorType *ot)
static void CURVES_OT_select_all(wmOperatorType *ot)
static void CURVES_OT_switch_direction(wmOperatorType *ot)
void fill_selection_false(GMutableSpan selection)
bool object_has_editable_curves(const Main &bmain, const Object &object)
static void select_random_ui(bContext *, wmOperator *op)
bool editable_curves_in_edit_mode_poll(bContext *C)
static int select_all_exec(bContext *C, wmOperator *op)
static void CURVES_OT_tilt_clear(wmOperatorType *ot)
static void CURVES_OT_duplicate(wmOperatorType *ot)
void fill_selection_true(GMutableSpan selection)
static bool curves_poll_impl(bContext *C, const bool check_editable, const bool check_surface, const bool check_edit_mode)
Span< StringRef > get_curves_selection_attribute_names(const bke::CurvesGeometry &curves)
static void CURVES_OT_curve_type_set(wmOperatorType *ot)
static void CURVES_OT_cyclic_toggle(wmOperatorType *ot)
static void CURVES_OT_delete(wmOperatorType *ot)
static void CURVES_OT_snap_curves_to_surface(wmOperatorType *ot)
void ensure_surface_deformation_node_exists(bContext &C, Object &curves_ob)
static void append_primitive_curve(bContext *C, Curves &curves_id, CurvesGeometry new_curves, wmOperator &op)
IndexMask end_points(const bke::CurvesGeometry &curves, const IndexMask &curves_mask, const int amount_start, const int amount_end, const bool inverted, IndexMaskMemory &memory)
bool curves_with_surface_poll(bContext *C)
static void select_ends_ui(bContext *, wmOperator *op)
bke::GSpanAttributeWriter ensure_selection_attribute(bke::CurvesGeometry &curves, bke::AttrDomain selection_domain, eCustomDataType create_type, StringRef attribute_name)
static int select_more_exec(bContext *C, wmOperator *)
void CURVES_OT_attribute_set(wmOperatorType *ot)
bool curves_poll(bContext *C)
IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, IndexMaskMemory &memory)
void CURVES_OT_extrude(wmOperatorType *ot)
IndexMask random_mask(const bke::CurvesGeometry &curves, const IndexMask &mask, const bke::AttrDomain selection_domain, const uint32_t random_seed, const float probability, IndexMaskMemory &memory)
static void CURVES_OT_set_selection_domain(wmOperatorType *ot)
static void CURVES_OT_add_circle(wmOperatorType *ot)
bool editable_curves_with_surface_poll(bContext *C)
void add_unit_props_radius(wmOperatorType *ot)
bool parent_set(ReportList *reports, const bContext *C, Scene *scene, Object *const ob, Object *const par, int partype, bool xmirror, bool keep_transform, const int vert_par[3])
Object * context_active_object(const bContext *C)
void add_generic_props(wmOperatorType *ot, bool do_editmode)
void add_generic_get_opts(bContext *C, wmOperator *op, char view_align_axis, float r_loc[3], float r_rot[3], float r_scale[3], bool *r_enter_editmode, unsigned short *r_local_view_bits, bool *r_is_view_aligned)
std::optional< TransformGeometryErrors > transform_geometry(bke::GeometrySet &geometry, const float4x4 &transform)
bke::GeometrySet join_geometries(Span< bke::GeometrySet > geometries, const bke::AttributeFilter &attribute_filter, const std::optional< Span< bke::GeometryComponent::Type > > &component_types_to_join=std::nullopt)
bke::CurvesGeometry subdivide_curves(const bke::CurvesGeometry &src_curves, const IndexMask &selection, const VArray< int > &cuts, const bke::AttributeFilter &attribute_filter={})
bke::CurvesGeometry convert_curves(const bke::CurvesGeometry &src_curves, const IndexMask &selection, CurveType dst_type, const bke::AttributeFilter &attribute_filter, const ConvertCurvesOptions &options={})
void masked_fill(MutableSpan< T > data, const T &value, const IndexMask &mask)
EulerXYZBase< float > EulerXYZ
CartesianBasis invert(const CartesianBasis &basis)
MatT from_loc_rot_scale(const typename MatT::loc_type &location, const RotationT &rotation, const VecBase< typename MatT::base_type, ScaleDim > &scale)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
VecBase< float, 2 > float2
VecBase< float, 3 > float3
static void exec(void *data, int, bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
GPU_SHADER_INTERFACE_INFO(overlay_edit_curve_handle_iface, "vert").flat(Type pos vertex_in(1, Type::UINT, "data") .vertex_out(overlay_edit_curve_handle_iface) .geometry_layout(PrimitiveIn Frequency::GEOMETRY storage_buf(1, Qualifier::READ, "uint", "data[]", Frequency::GEOMETRY) .push_constant(Type Frequency::GEOMETRY selection[]
static int select_random_exec(bContext *C, wmOperator *op)
static int select_more_exec(bContext *C, wmOperator *)
static int select_less_exec(bContext *C, wmOperator *)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
int RNA_int_get(PointerRNA *ptr, const char *name)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
const EnumPropertyItem rna_enum_attribute_curves_domain_items[]
const EnumPropertyItem rna_enum_curves_handle_type_items[]
const EnumPropertyItem rna_enum_curves_type_items[]
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
BVHTree_NearestPointCallback nearest_callback
struct ParticleSystem * psys
struct ParticleCacheKey ** childcache
struct ParticleCacheKey ** pathcache
const c_style_mat & ptr() const
static GeometrySet from_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Curves * get_curves_for_write()
MutableVArraySpan< T > span
bool(* poll)(struct bContext *)
struct ReportList * reports
void WM_main_add_notifier(uint type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
void WM_operator_properties_select_all(wmOperatorType *ot)
wmOperatorTypeMacro * WM_operatortype_macro_define(wmOperatorType *ot, const char *idname)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
wmOperatorType * WM_operatortype_append_macro(const char *idname, const char *name, const char *description, int flag)
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *)