32 .supported_type({GeometryComponent::Type::Curve, GeometryComponent::Type::GreasePencil})
39 .make_available([](
bNode &node) {
47 .make_available([](
bNode &node) {
55 const bNode *node =
b.node_or_null();
56 if (node !=
nullptr) {
83 for (const int i : range) {
84 rotations[i] = math::to_quaternion(
85 math::from_orthonormal_axes<float4x4>(normals[i], tangents[i]));
98 if (iter.
domain != AttrDomain::Curve) {
107 point_attributes.
add(iter.
name,
142 pointcloud->attributes_for_write());
165 if (!pointcloud_by_layer.
is_empty()) {
167 for (
PointCloud *pointcloud : pointcloud_by_layer) {
203 std::optional<std::string> rotation_anonymous_id =
204 params.get_output_anonymous_attribute_id_if_needed(
"Rotation");
205 const bool need_tangent_and_normal = bool(rotation_anonymous_id);
206 std::optional<std::string> tangent_anonymous_id =
207 params.get_output_anonymous_attribute_id_if_needed(
"Tangent", need_tangent_and_normal);
208 std::optional<std::string> normal_anonymous_id =
209 params.get_output_anonymous_attribute_id_if_needed(
"Normal", need_tangent_and_normal);
212 resample_attributes.
tangent_id = tangent_anonymous_id;
213 resample_attributes.
normal_id = normal_anonymous_id;
222 src_curves_id->geometry.wrap(),
226 resample_attributes);
228 dst_curves, attribute_filter, resample_attributes, rotation_anonymous_id);
229 geometry.replace_pointcloud(pointcloud);
233 for (
const int layer_index : grease_pencil->layers().index_range()) {
235 grease_pencil->layer(layer_index));
236 if (drawing ==
nullptr) {
244 resample_attributes);
246 dst_curves, attribute_filter, resample_attributes, rotation_anonymous_id);
261 src_curves_id->geometry.wrap(),
265 resample_attributes);
267 dst_curves, attribute_filter, resample_attributes, rotation_anonymous_id);
268 geometry.replace_pointcloud(pointcloud);
272 for (
const int layer_index : grease_pencil->layers().index_range()) {
274 grease_pencil->layer(layer_index));
275 if (drawing ==
nullptr) {
283 resample_attributes);
285 dst_curves, attribute_filter, resample_attributes, rotation_anonymous_id);
299 src_curves_id->geometry.wrap(),
302 resample_attributes);
304 dst_curves, attribute_filter, resample_attributes, rotation_anonymous_id);
305 geometry.replace_pointcloud(pointcloud);
310 for (
const int layer_index : grease_pencil->layers().index_range()) {
312 grease_pencil->layer(layer_index));
313 if (drawing ==
nullptr) {
320 resample_attributes);
322 dst_curves, attribute_filter, resample_attributes, rotation_anonymous_id);
334 params.set_output(
"Points", std::move(geometry_set));
344 "Create points from the curve's evaluated points, based on the resolution attribute for "
345 "NURBS and Bézier splines"},
350 "Sample each spline by evenly distributing the specified number of points"},
355 "Sample each spline by splitting it into segments with the specified length"},
356 {0,
nullptr, 0,
nullptr,
nullptr},
362 "How to generate points from the input curve",
373 ntype.
ui_name =
"Curve to Points";
374 ntype.
ui_description =
"Generate a point cloud by sampling positions along curves";
CustomData interface, see also DNA_customdata_types.h.
Low-level operations for grease pencil.
#define NODE_STORAGE_FUNCS(StorageT)
#define NODE_CLASS_GEOMETRY
#define GEO_NODE_CURVE_TO_POINTS
General operations for point clouds.
GeometryNodeCurveResampleMode
@ GEO_NODE_CURVE_RESAMPLE_LENGTH
@ GEO_NODE_CURVE_RESAMPLE_EVALUATED
@ GEO_NODE_CURVE_RESAMPLE_COUNT
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_storage_enum_accessors(member)
BMesh const char void * data
constexpr int64_t size() const
constexpr bool is_empty() const
bool is_builtin(const StringRef attribute_id) const
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
GAttributeReader lookup(const StringRef attribute_id) const
GAttributeReader get() const
AttributeAccessor attributes() const
void replace(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
int add_reference(const InstanceReference &reference)
void add_instance(int instance_handle, const float4x4 &transform)
bke::MutableAttributeAccessor attributes_for_write()
bool add(const StringRef attribute_id, const AttrDomain domain, const AttrType data_type, const AttributeInit &initializer)
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, AttrType data_type)
const bke::CurvesGeometry & strokes() const
static void remember_deformed_positions_if_necessary(GeometrySet &geometry)
static float normals[][3]
float length(VecOp< float, D >) RET
void * MEM_callocN(size_t len, const char *str)
void node_register_type(bNodeType &ntype)
void copy_attributes(const AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, MutableAttributeAccessor dst_attributes)
PointCloud * pointcloud_new_no_attributes(int totpoint)
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
GField make_constant_field(const CPPType &type, const void *value)
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)
void foreach_real_geometry(bke::GeometrySet &geometry, FunctionRef< void(bke::GeometrySet &geometry_set)> fn)
CurvesGeometry resample_to_count(const CurvesGeometry &src_curves, const IndexMask &selection, const VArray< int > &counts, const ResampleCurvesOutputAttributeIDs &output_ids={})
CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, const IndexMask &selection, const ResampleCurvesOutputAttributeIDs &output_ids={})
CurvesGeometry resample_to_length(const CurvesGeometry &src_curves, const IndexMask &selection, const VArray< float > &sample_lengths, const ResampleCurvesOutputAttributeIDs &output_ids={}, bool keep_last_segment=false)
QuaternionBase< float > Quaternion
static void node_register()
static PointCloud * curves_to_points(const bke::CurvesGeometry &curves, const AttributeFilter &attribute_filter, const geometry::ResampleCurvesOutputAttributeIDs &resample_attributes, const std::optional< StringRef > &rotation_id)
static void node_geo_exec(GeoNodeExecParams params)
static void node_declare(NodeDeclarationBuilder &b)
static void copy_curve_domain_attributes(const AttributeAccessor curve_attributes, const AttributeFilter &attribute_filter, MutableAttributeAccessor point_attributes)
static void node_init(bNodeTree *, bNode *node)
static void fill_rotation_attribute(const Span< float3 > tangents, const Span< float3 > normals, MutableSpan< math::Quaternion > rotations)
static void layer_pointclouds_to_instances(const Span< PointCloud * > pointcloud_by_layer, const AttributeFilter &attribute_filter, GeometrySet &geometry)
static void node_rna(StructRNA *srna)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
PropertyRNA * RNA_def_node_enum(StructRNA *srna, const char *identifier, const char *ui_name, const char *ui_description, const EnumPropertyItem *static_items, const EnumRNAAccessors accessors, std::optional< int > default_value, const EnumPropertyItemFunc item_func, const bool allow_animation)
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
std::optional< std::string > rotation_id
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
void node_free_standard_storage(bNode *node)
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
static GeometrySet from_instances(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
static GeometrySet from_pointcloud(PointCloud *pointcloud, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
static MatBase identity()
bool allow_skip(const StringRef name) const
std::string ui_description
void(* initfunc)(bNodeTree *ntree, bNode *node)
NodeGeometryExecFunction geometry_node_execute
const char * enum_name_legacy
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeDeclareFunction declare
std::optional< std::string > tangent_id
std::optional< std::string > normal_id
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)