56#include "RNA_prototypes.hh"
109 return unique_curves;
113 const bool check_editable,
114 const bool check_surface,
115 const bool check_edit_mode)
121 if (check_editable) {
133 if (check_edit_mode) {
189 if (possible_mface_indices.
size() == 1) {
190 return possible_mface_indices.
first();
194 float best_distance_sq =
FLT_MAX;
195 for (
const int possible_mface_i : possible_mface_indices) {
196 const MFace &possible_mface = mface[possible_mface_i];
201 positions[possible_mface.
v1],
202 positions[possible_mface.
v2],
203 positions[possible_mface.
v3]);
205 if (distance_sq < best_distance_sq) {
206 best_distance_sq = distance_sq;
207 mface_i = possible_mface_i;
211 if (possible_mface.
v4) {
215 positions[possible_mface.
v1],
216 positions[possible_mface.
v3],
217 positions[possible_mface.
v4]);
219 if (distance_sq < best_distance_sq) {
220 best_distance_sq = distance_sq;
221 mface_i = possible_mface_i;
237 float mface_positions_su[4][3];
246 mface_weights, positions[mface.
v1], positions[mface.
v2], positions[mface.
v3], position);
247 mface_weights[3] = 0.0f;
249 return mface_weights;
255 bool *r_could_not_convert_some_curves)
262 if (curves_id.
surface ==
nullptr) {
269 Mesh &surface_me = *
static_cast<Mesh *
>(surface_ob.
data);
274 const Span<int> tri_faces = surface_me.corner_tri_faces();
277 *r_could_not_convert_some_curves =
true;
283 curves.curves_range(),
GrainSize(4096), memory, [&](
const int curve_i) {
284 return points_by_curve[curve_i].
size() > 1;
287 const int hair_num = multi_point_curves.
size();
296 particle_system = psys;
300 if (particle_system ==
nullptr) {
303 particle_system = psmd.
psys;
325 for (
const int mface_i : mface_to_poly_map.
index_range()) {
326 const int face_i = mface_to_poly_map[mface_i];
327 poly_to_mface_map[face_i].append(mface_i);
334 const Span<float3> positions = surface_me.vert_positions();
336 multi_point_curves.
foreach_index([&](
const int curve_i,
const int new_hair_i) {
337 const IndexRange points = points_by_curve[curve_i];
339 const float3 &root_pos_cu = positions_cu[points.
first()];
348 const int tri_i = nearest.
index;
349 const int face_i = tri_faces[tri_i];
352 positions, mfaces, poly_to_mface_map[face_i], root_pos_su);
353 const MFace &mface = mfaces[mface_i];
358 const int num_keys = points.
size();
364 particle.
num = mface_i;
372 hair_to_surface_mat.
location() = root_pos_su;
376 const float3 &key_pos_cu = positions_cu[points[key_i]];
380 HairKey &key = hair_keys[key_i];
382 const float key_fac = key_i /
float(hair_keys.
size() - 1);
383 key.
time = 100.0f * key_fac;
384 key.
weight = 1.0f - key_fac;
402 bool could_not_convert_some_curves =
false;
408 if (curves_ob != &active_object) {
414 if (could_not_convert_some_curves) {
417 "Some curves could not be converted because they were not attached to the surface");
429 ot->name =
"Convert Curves to Particle System";
430 ot->idname =
"CURVES_OT_convert_to_particle_system";
431 ot->description =
"Add a new or update an existing hair particle system on the surface object";
457 if (transfer_parents) {
458 for (
const int parent_i : parents_cache.
index_range()) {
459 const int segments = parents_cache[parent_i]->segments;
463 parents_to_transfer.
append(parent_i);
464 curve_offsets.
append(points_num);
465 points_num += segments + 1;
468 for (
const int child_i : children_cache.
index_range()) {
469 const int segments = children_cache[child_i]->segments;
473 children_to_transfer.
append(child_i);
474 curve_offsets.
append(points_num);
475 points_num += segments + 1;
477 const int curves_num = parents_to_transfer.
size() + children_to_transfer.
size();
478 curve_offsets.
append(points_num);
481 curves.offsets_for_write().copy_from(curve_offsets);
483 const float4x4 &object_to_world_mat =
object.object_to_world();
491 const int curve_index_offset) {
493 for (const int i : range) {
494 const int hair_i = indices_to_transfer[i];
495 const int curve_i = i + curve_index_offset;
496 const IndexRange points = points_by_curve[curve_i];
497 const Span<ParticleCacheKey> keys{hair_cache[hair_i], points.size()};
498 for (const int key_i : keys.index_range()) {
499 const float3 key_pos_wo = keys[key_i].co;
500 positions[points[key_i]] = math::transform_point(world_to_object_mat, key_pos_wo);
506 if (transfer_parents) {
507 copy_hair_to_curves(parents_cache, parents_to_transfer, 0);
509 copy_hair_to_curves(children_cache, children_to_transfer, parents_to_transfer.size());
511 curves.update_curve_types();
512 curves.tag_topology_changed();
525 if (psys_orig ==
nullptr) {
528 if (psys_orig ==
nullptr) {
541 psys_eval = psmd->
psys;
564 ot->name =
"Convert Particle System to Curves";
565 ot->idname =
"CURVES_OT_convert_from_particle_system";
566 ot->description =
"Add a new curves object based on the current state of the particle system";
590 const Mesh &surface_mesh = *
static_cast<const Mesh *
>(surface_ob.
data);
591 const Span<float3> surface_positions = surface_mesh.vert_positions();
592 const Span<int> corner_verts = surface_mesh.corner_verts();
593 const Span<int3> surface_corner_tris = surface_mesh.corner_tris();
607 switch (attach_mode) {
612 for (const int curve_i : curves_range) {
613 const IndexRange points = points_by_curve[curve_i];
614 const int first_point_i = points.first();
615 const float3 old_first_point_pos_cu = positions_cu[first_point_i];
616 const float3 old_first_point_pos_su = math::transform_point(transforms.curves_to_surface,
617 old_first_point_pos_cu);
619 BVHTreeNearest nearest;
621 nearest.dist_sq = FLT_MAX;
622 BLI_bvhtree_find_nearest(surface_bvh.tree,
623 old_first_point_pos_su,
625 surface_bvh.nearest_callback,
627 const int tri_index = nearest.index;
628 if (tri_index == -1) {
632 const float3 new_first_point_pos_su = nearest.co;
633 const float3 new_first_point_pos_cu = math::transform_point(transforms.surface_to_curves,
634 new_first_point_pos_su);
635 const float3 pos_diff_cu = new_first_point_pos_cu - old_first_point_pos_cu;
637 for (float3 &pos_cu : positions_cu.slice(points)) {
638 pos_cu += pos_diff_cu;
641 if (!surface_uv_map.is_empty()) {
642 const int3 &tri = surface_corner_tris[tri_index];
643 const float3 bary_coords = bke::mesh_surface_sample::compute_bary_coord_in_triangle(
644 surface_positions, corner_verts, tri, new_first_point_pos_su);
645 const float2 uv = bke::mesh_surface_sample::sample_corner_attribute_with_bary_coords(
646 bary_coords, tri, surface_uv_map);
647 surface_uv_coords[curve_i] = uv;
655 *r_missing_uvs =
true;
659 ReverseUVSampler reverse_uv_sampler{surface_uv_map, surface_corner_tris};
662 for (const int curve_i : curves_range) {
663 const IndexRange points = points_by_curve[curve_i];
664 const int first_point_i = points.first();
665 const float3 old_first_point_pos_cu = positions_cu[first_point_i];
667 const float2 uv = surface_uv_coords[curve_i];
668 ReverseUVSampler::Result lookup_result = reverse_uv_sampler.sample(uv);
669 if (lookup_result.type != ReverseUVSampler::ResultType::Ok) {
670 *r_invalid_uvs = true;
674 const int3 &tri = surface_corner_tris[lookup_result.tri_index];
675 const float3 &bary_coords = lookup_result.bary_weights;
677 const float3 &p0_su = surface_positions[corner_verts[tri[0]]];
678 const float3 &p1_su = surface_positions[corner_verts[tri[1]]];
679 const float3 &p2_su = surface_positions[corner_verts[tri[2]]];
681 float3 new_first_point_pos_su;
682 interp_v3_v3v3v3(new_first_point_pos_su, p0_su, p1_su, p2_su, bary_coords);
683 const float3 new_first_point_pos_cu = math::transform_point(transforms.surface_to_curves,
684 new_first_point_pos_su);
686 const float3 pos_diff_cu = new_first_point_pos_cu - old_first_point_pos_cu;
687 for (float3 &pos_cu : positions_cu.slice(points)) {
688 pos_cu += pos_diff_cu;
696 curves.tag_positions_changed();
704 bool found_invalid_uvs =
false;
705 bool found_missing_uvs =
false;
711 Curves &curves_id = *
static_cast<Curves *
>(curves_ob->data);
712 if (curves_id.
surface ==
nullptr) {
719 *curves_ob, *curves_id.
surface, attach_mode, &found_invalid_uvs, &found_missing_uvs);
723 if (found_missing_uvs) {
726 "Curves do not have attachment information that can be used for deformation");
728 if (found_invalid_uvs) {
744 ot->name =
"Snap Curves to Surface";
745 ot->idname =
"CURVES_OT_snap_curves_to_surface";
746 ot->description =
"Move curves so that the first point is exactly on the surface mesh";
749 ot->exec = snap_curves_to_surface_exec;
754 {int(AttachMode::Nearest),
758 "Find the closest point on the surface for the root point of every curve and move the root "
760 {int(AttachMode::Deform),
764 "Re-attach curves to a deformed surface using the existing attachment information. This "
765 "only works when the topology of the surface mesh has not changed"},
766 {0,
nullptr, 0,
nullptr,
nullptr},
772 int(AttachMode::Nearest),
774 "How to find the point on the surface to attach to");
788 curves_id->selection_domain = char(domain);
804 if (
const GVArray src = *attributes.
lookup(selection_name, domain)) {
805 const CPPType &type = src.type();
807 src.materialize(dst);
809 attributes.
remove(selection_name);
810 if (!attributes.
add(selection_name,
819 if (!active_attribute.empty()) {
840 ot->name =
"Set Select Mode";
841 ot->idname = __func__;
842 ot->description =
"Change the mode used for selection masking in curves sculpt mode";
856 return std::any_of(curves_ids.
begin(), curves_ids.
end(), [](
const Curves *curves_id) {
857 return has_anything_selected(curves_id->geometry.wrap());
871 for (
Curves *curves_id : unique_curves) {
886 ot->name =
"(De)select All";
887 ot->idname =
"CURVES_OT_select_all";
888 ot->description =
"(De)select all control points";
905 for (
Curves *curves_id : unique_curves) {
908 const int domain_size =
curves.attributes().domain_size(selection_domain);
911 const IndexMask inv_random_elements = random_mask(domain_size,
seed, probability, memory)
917 if (!was_anything_selected) {
942 ot->name =
"Select Random";
943 ot->idname = __func__;
944 ot->description =
"Randomizes existing selection or create new random selection";
958 "Source of randomness",
967 "Chance of every point or curve being included in the selection",
978 for (
Curves *curves_id : unique_curves) {
983 curves, amount_start, amount_end,
true, memory);
988 if (!was_anything_selected) {
1016 col->use_property_decorate_set(
false);
1023 ot->name =
"Select Ends";
1024 ot->idname = __func__;
1025 ot->description =
"Select end points of curves";
1039 "Number of points to select from the front",
1048 "Number of points to select from the back",
1056 for (
Curves *curves_id : unique_curves) {
1070 ot->name =
"Select Linked";
1071 ot->idname = __func__;
1072 ot->description =
"Select all points in curves with any point selection";
1083 for (
Curves *curves_id : unique_curves) {
1097 ot->name =
"Select More";
1098 ot->idname = __func__;
1099 ot->description =
"Grow the selection by one point";
1110 for (
Curves *curves_id : unique_curves) {
1124 ot->name =
"Select Less";
1125 ot->idname = __func__;
1126 ot->description =
"Shrink the selection by one point";
1140 for (
Curves *curves_id : unique_curves) {
1150 curves.calculate_bezier_auto_handles();
1164 ot->idname = __func__;
1165 ot->description =
"Split selected points";
1178 if (
object ==
nullptr) {
1194 Mesh &new_surface_mesh = *
static_cast<Mesh *
>(new_surface_ob.
data);
1202 Object &curves_ob = *selected_ob;
1206 if (new_uv_map_name !=
nullptr) {
1222 curves_id.
surface = &new_surface_ob;
1252 ot->name =
"Set Curves Surface Object";
1253 ot->idname = __func__;
1255 "Use the active object as surface for selected curves objects and set it as the parent";
1282 ot->name =
"Delete";
1283 ot->idname = __func__;
1284 ot->description =
"Remove selected control points or curves";
1320 ot->name =
"Duplicate";
1321 ot->idname = __func__;
1322 ot->description =
"Copy selected points or curves";
1342 if (selection.
size() ==
curves.points_num()) {
1343 curves.attributes_for_write().remove(
"tilt");
1349 curves.tag_normals_changed();
1360 ot->name =
"Clear Tilt";
1361 ot->idname = __func__;
1362 ot->description =
"Clear the tilt of selected control points";
1387 [&](
const int i) { cyclic.
span[
i] = !cyclic.
span[
i]; });
1390 if (!cyclic.
span.contains(
true)) {
1391 attributes.
remove(
"cyclic");
1394 curves.calculate_bezier_auto_handles();
1406 ot->name =
"Toggle Cyclic";
1407 ot->idname = __func__;
1408 ot->description =
"Make active curve closed/opened loop";
1432 options.convert_bezier_handles_to_poly_points = use_handles;
1433 options.convert_bezier_handles_to_catmull_rom_points = use_handles;
1434 options.keep_bezier_shape_as_nurbs = use_handles;
1435 options.keep_catmull_rom_shape_as_nurbs = use_handles;
1449 ot->name =
"Set Curve Type";
1450 ot->idname = __func__;
1451 ot->description =
"Set type of selected curves";
1465 "Take handle information into account in the conversion");
1480 curves.reverse_curves(selection);
1492 ot->name =
"Switch Direction";
1493 ot->idname = __func__;
1494 ot->description =
"Reverse the direction of the selected curves";
1510 const int points_num =
curves.points_num();
1518 points_selection.
to_bools(points_selection_span);
1520 Array<int> segment_cuts(points_num, number_cuts);
1524 for (const int curve_i : range) {
1525 const IndexRange points = points_by_curve[curve_i];
1526 if (points.size() <= 1) {
1529 for (const int point_i : points.drop_back(1)) {
1530 if (!points_selection_span[point_i] || !points_selection_span[point_i + 1]) {
1531 segment_cuts[point_i] = 0;
1535 if (!points_selection_span[points.last()] || !points_selection_span[points.first()]) {
1536 segment_cuts[points.last()] = 0;
1554 ot->name =
"Subdivide";
1555 ot->idname = __func__;
1556 ot->description =
"Subdivide selected curve segments";
1564 prop =
RNA_def_int(
ot->srna,
"number_cuts", 1, 1, 1000,
"Number of Cuts",
"", 1, 10);
1575 const int new_points_num = new_curves.
points_num();
1576 const int new_curves_num = new_curves.
curves_num();
1596 dst_curves = std::move(joined_curves_id->geometry.wrap());
1622 curves.cyclic_for_write().fill(
true);
1625 curves.resolution_for_write().fill(12);
1628 positions[0] =
float3(-radius, 0, 0);
1629 positions[1] =
float3(0, radius, 0);
1630 positions[2] =
float3(radius, 0, 0);
1631 positions[3] =
float3(0, -radius, 0);
1634 curves.handle_positions_left_for_write();
1635 curves.handle_positions_right_for_write();
1637 curves.calculate_bezier_auto_handles();
1645 Curves *active_curves_id =
static_cast<Curves *
>(
object->data);
1659 ot->name =
"Add Circle";
1660 ot->idname = __func__;
1661 ot->description =
"Add new circle curve";
1685 curves.resolution_for_write().fill(12);
1691 left_handles[0] =
float3(-1.5f, -0.5, 0) * radius;
1692 positions[0] =
float3(-1.0f, 0, 0) * radius;
1693 right_handles[0] =
float3(-0.5f, 0.5f, 0) * radius;
1695 left_handles[1] =
float3(0, 0, 0) * radius;
1696 positions[1] =
float3(1.0f, 0, 0) * radius;
1697 right_handles[1] =
float3(2.0f, 0, 0) * radius;
1705 Curves *active_curves_id =
static_cast<Curves *
>(
object->data);
1719 ot->name =
"Add Bézier";
1720 ot->idname = __func__;
1721 ot->description =
"Add new Bézier curve";
1738 auto new_handle_type = [&](
const int8_t handle_type) {
1771 for (const int point_i : range) {
1772 if (selection_left[point_i] || selection[point_i]) {
1773 handle_types_left[point_i] = new_handle_type(handle_types_left[point_i]);
1775 if (selection_right[point_i] || selection[point_i]) {
1776 handle_types_right[point_i] = new_handle_type(handle_types_right[point_i]);
1781 curves.calculate_bezier_auto_handles();
1782 curves.tag_topology_changed();
1797 "The location is automatically calculated to be smooth"},
1802 "The location is calculated to point to the next/previous control point"},
1807 "The location is constrained to point in the opposite direction as the other handle"},
1812 "The handle can be moved anywhere, and does not influence the point's other handle"},
1814 "TOGGLE_FREE_ALIGN",
1816 "Toggle Free/Align",
1817 "Replace Free handles with Align, and all Align with Free handles"},
1818 {0,
nullptr, 0,
nullptr,
nullptr},
1823 ot->name =
"Set Handle Type";
1824 ot->idname = __func__;
1825 ot->description =
"Set the handle type for bezier curves";
1881 "Make copies of selected elements and move them",
1889 "Extrude Curve and Move",
1890 "Extrude curve and move result",
std::optional< blender::StringRefNull > BKE_attributes_active_name_get(AttributeOwner &owner)
void BKE_attributes_active_set(AttributeOwner &owner, blender::StringRef name)
#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)
View3D * CTX_wm_view3d(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)
#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])
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)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ 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)
BMesh const char void * data
BPy_StructRNA * depsgraph
static unsigned long seed
static AttributeOwner from_id(ID *id)
GMutableSpan take_back(const int64_t n) const
GMutableSpan drop_back(const int64_t n) const
const CPPType & type() const
MutableSpan< T > typed() const
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 from_span(Span< T > values)
void add_new(const Key &key)
void append(const T &value)
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
GAttributeReader lookup(const StringRef attribute_id) const
int domain_size(const AttrDomain domain) const
void tag_topology_changed()
bool add(const StringRef attribute_id, const AttrDomain domain, const AttrType data_type, const AttributeInit &initializer)
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
bool remove(const StringRef attribute_id)
IndexMask complement(const IndexMask &universe, IndexMaskMemory &memory) const
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 wmOperatorStatus duplicate_exec(bContext *C, wmOperator *op)
static wmOperatorStatus select_linked_exec(bContext *C, wmOperator *)
static wmOperatorStatus delete_exec(bContext *C, wmOperator *op)
VecBase< float, 3 > float3
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
static wmOperatorStatus select_all_exec(bContext *C, wmOperator *op)
AttrType cpp_type_to_attribute_type(const CPPType &type)
Curves * curves_new_nomain(int points_num, int curves_num)
static wmOperatorStatus exec(bContext *C, wmOperator *op)
static CurvesGeometry generate_bezier_primitive(const float radius)
static CurvesGeometry generate_circle_primitive(const float radius)
static wmOperatorStatus exec(bContext *C, wmOperator *op)
static wmOperatorStatus exec(bContext *C, wmOperator *)
static wmOperatorStatus 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 find_mface_for_root_position(const Span< float3 > positions, const MFace *mface, const Span< int > possible_mface_indices, const float3 &root_pos)
static wmOperatorStatus curves_convert_to_particle_system_exec(bContext *C, wmOperator *op)
static void try_convert_single_object(Object &curves_ob, Main &bmain, Scene &scene, bool *r_could_not_convert_some_curves)
static wmOperatorStatus exec(bContext *C, wmOperator *op)
static wmOperatorStatus delete_exec(bContext *C, wmOperator *)
static wmOperatorStatus duplicate_exec(bContext *C, wmOperator *)
static wmOperatorStatus exec(bContext *C, wmOperator *)
static wmOperatorStatus exec(bContext *C, wmOperator *op)
static wmOperatorStatus curves_set_selection_domain_exec(bContext *C, wmOperator *op)
static wmOperatorStatus snap_curves_to_surface_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 wmOperatorStatus split_exec(bContext *C, wmOperator *)
static wmOperatorStatus exec(bContext *C, wmOperator *op)
static wmOperatorStatus surface_set_exec(bContext *C, wmOperator *op)
static bool surface_set_poll(bContext *C)
static wmOperatorStatus exec(bContext *C, wmOperator *)
static void CURVES_OT_surface_set(wmOperatorType *ot)
void select_linked(bke::CurvesGeometry &curves, const IndexMask &curves_mask)
const EnumPropertyItem rna_enum_set_handle_type_items[]
void operatormacros_curves()
static wmOperatorStatus select_linked_exec(bContext *C, wmOperator *)
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 void CURVES_OT_select_less(wmOperatorType *ot)
IndexMask retrieve_all_selected_points(const bke::CurvesGeometry &curves, const int handle_display, IndexMaskMemory &memory)
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)
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 void CURVES_OT_select_more(wmOperatorType *ot)
static void CURVES_OT_select_all(wmOperatorType *ot)
static void CURVES_OT_switch_direction(wmOperatorType *ot)
bke::CurvesGeometry split_points(const bke::CurvesGeometry &curves, const IndexMask &points_to_split)
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)
void ED_curves_pentool_modal_keymap(wmKeyConfig *keyconf)
bool editable_curves_in_edit_mode_poll(bContext *C)
static void CURVES_OT_split(wmOperatorType *ot)
static void CURVES_OT_tilt_clear(wmOperatorType *ot)
static void CURVES_OT_duplicate(wmOperatorType *ot)
static wmOperatorStatus select_all_exec(bContext *C, wmOperator *op)
static wmOperatorStatus select_more_exec(bContext *C, wmOperator *)
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 wmOperatorStatus select_random_exec(bContext *C, wmOperator *op)
static void CURVES_OT_cyclic_toggle(wmOperatorType *ot)
void ED_operatortypes_curves_pen()
static wmOperatorStatus select_ends_exec(bContext *C, wmOperator *op)
static void CURVES_OT_delete(wmOperatorType *ot)
static void CURVES_OT_snap_curves_to_surface(wmOperatorType *ot)
static wmOperatorStatus select_less_exec(bContext *C, wmOperator *)
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)
void CURVES_OT_separate(wmOperatorType *ot)
void CURVES_OT_attribute_set(wmOperatorType *ot)
bool curves_poll(bContext *C)
bke::GSpanAttributeWriter ensure_selection_attribute(bke::CurvesGeometry &curves, bke::AttrDomain selection_domain, bke::AttrType create_type, StringRef attribute_name)
IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, IndexMaskMemory &memory)
void CURVES_OT_extrude(wmOperatorType *ot)
void CURVES_OT_select_linked_pick(wmOperatorType *ot)
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)
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, bool allow_merging_instance_references=true)
std::optional< TransformGeometryErrors > transform_geometry(bke::GeometrySet &geometry, const float4x4 &transform)
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)
static wmOperatorStatus select_random_exec(bContext *C, wmOperator *op)
static wmOperatorStatus select_less_exec(bContext *C, wmOperator *)
static wmOperatorStatus select_more_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_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)
struct ParticleSystem * psys
struct ParticleCacheKey ** childcache
struct ParticleCacheKey ** pathcache
const c_style_mat & ptr() const
BVHTree_NearestPointCallback nearest_callback
static GeometrySet from_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Curves * get_curves_for_write()
MutableVArraySpan< T > span
uiLayout & column(bool align)
void use_property_split_set(bool value)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
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)
wmOperatorStatus WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *)