Blender V4.3
node_geo_curve_to_mesh.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BKE_curves.hh"
6
9#include "BKE_instances.hh"
10
11#include "UI_resources.hh"
12
14#include "GEO_randomize.hh"
15
16#include "node_geometry_util.hh"
17
19
21{
22 b.add_input<decl::Geometry>("Curve").supported_type(
24 b.add_input<decl::Geometry>("Profile Curve")
25 .only_realized_data()
26 .supported_type(GeometryComponent::Type::Curve);
27 b.add_input<decl::Bool>("Fill Caps")
28 .description(
29 "If the profile spline is cyclic, fill the ends of the generated mesh with N-gons");
30 b.add_output<decl::Geometry>("Mesh").propagate_all();
31}
32
34 const GeometrySet &profile_set,
35 const bool fill_caps,
36 const AttributeFilter &attribute_filter)
37{
38 Mesh *mesh;
39 if (profile_set.has_curves()) {
40 const Curves *profile_curves = profile_set.get_curves();
42 curves, profile_curves->geometry.wrap(), fill_caps, attribute_filter);
43 }
44 else {
45 mesh = bke::curve_to_wire_mesh(curves, attribute_filter);
46 }
48 return mesh;
49}
50
51static void grease_pencil_to_mesh(GeometrySet &geometry_set,
52 const GeometrySet &profile_set,
53 const bool fill_caps,
54 const AttributeFilter &attribute_filter)
55{
56 using namespace blender::bke::greasepencil;
57
58 const GreasePencil &grease_pencil = *geometry_set.get_grease_pencil();
59 Array<Mesh *> mesh_by_layer(grease_pencil.layers().size(), nullptr);
60
61 for (const int layer_index : grease_pencil.layers().index_range()) {
62 const Drawing *drawing = grease_pencil.get_eval_drawing(grease_pencil.layer(layer_index));
63 if (drawing == nullptr) {
64 continue;
65 }
66 const bke::CurvesGeometry &curves = drawing->strokes();
67 mesh_by_layer[layer_index] = curve_to_mesh(curves, profile_set, fill_caps, attribute_filter);
68 }
69
70 if (mesh_by_layer.is_empty()) {
71 return;
72 }
73
74 bke::Instances *instances = new bke::Instances();
75 for (Mesh *mesh : mesh_by_layer) {
76 if (!mesh) {
77 /* Add an empty reference so the number of layers and instances match.
78 * This makes it easy to reconstruct the layers afterwards and keep their attributes.
79 * Although in this particular case we don't propagate the attributes. */
80 const int handle = instances->add_reference(bke::InstanceReference());
81 instances->add_instance(handle, float4x4::identity());
82 continue;
83 }
84 GeometrySet temp_set = GeometrySet::from_mesh(mesh);
85 const int handle = instances->add_reference(bke::InstanceReference{temp_set});
86 instances->add_instance(handle, float4x4::identity());
87 }
89 geometry_set.get_grease_pencil()->attributes(),
90 instances->attributes_for_write(),
91 attribute_filter);
92 InstancesComponent &dst_component = geometry_set.get_component_for_write<InstancesComponent>();
94 {GeometrySet::from_instances(dst_component.release()),
96 attribute_filter);
97 dst_component.replace(new_instances.get_component_for_write<InstancesComponent>().release());
98 geometry_set.replace_grease_pencil(nullptr);
99}
100
102{
103 GeometrySet curve_set = params.extract_input<GeometrySet>("Curve");
104 GeometrySet profile_set = params.extract_input<GeometrySet>("Profile Curve");
105 const bool fill_caps = params.extract_input<bool>("Fill Caps");
106
108 const AttributeFilter &attribute_filter = params.get_attribute_filter("Mesh");
109
110 curve_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
111 if (geometry_set.has_curves()) {
112 const Curves &curves = *geometry_set.get_curves();
113 Mesh *mesh = curve_to_mesh(curves.geometry.wrap(), profile_set, fill_caps, attribute_filter);
114 geometry_set.replace_mesh(mesh);
115 }
116 if (geometry_set.has_grease_pencil()) {
117 grease_pencil_to_mesh(geometry_set, profile_set, fill_caps, attribute_filter);
118 }
119 geometry_set.keep_only_during_modify({GeometryComponent::Type::Mesh});
120 });
121
122 params.set_output("Mesh", std::move(curve_set));
123}
124
125static void node_register()
126{
127 static blender::bke::bNodeType ntype;
128
129 geo_node_type_base(&ntype, GEO_NODE_CURVE_TO_MESH, "Curve to Mesh", NODE_CLASS_GEOMETRY);
130 ntype.declare = node_declare;
133}
135
136} // namespace blender::nodes::node_geo_curve_to_mesh_cc
Low-level operations for curves.
Low-level operations for grease pencil.
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:418
#define NOD_REGISTER_NODE(REGISTER_FUNC)
bool is_empty() const
Definition BLI_array.hh:253
static void remember_deformed_positions_if_necessary(GeometrySet &geometry)
void replace(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
const bke::CurvesGeometry & strokes() const
local_group_size(16, 16) .push_constant(Type b
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
Mesh * curve_to_mesh_sweep(const CurvesGeometry &main, const CurvesGeometry &profile, bool fill_caps, const bke::AttributeFilter &attribute_filter={})
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
Mesh * curve_to_wire_mesh(const CurvesGeometry &curve, const bke::AttributeFilter &attribute_filter={})
void debug_randomize_mesh_order(Mesh *mesh)
Definition randomize.cc:220
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)
static void node_declare(NodeDeclarationBuilder &b)
static void grease_pencil_to_mesh(GeometrySet &geometry_set, const GeometrySet &profile_set, const bool fill_caps, const AttributeFilter &attribute_filter)
static Mesh * curve_to_mesh(const bke::CurvesGeometry &curves, const GeometrySet &profile_set, const bool fill_caps, const AttributeFilter &attribute_filter)
static void node_geo_exec(GeoNodeExecParams params)
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
CurvesGeometry geometry
GeometryComponent & get_component_for_write(GeometryComponent::Type component_type)
static GeometrySet from_instances(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
const GreasePencil * get_grease_pencil() const
static GeometrySet from_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void keep_only_during_modify(Span< GeometryComponent::Type > component_types)
const Curves * get_curves() const
static void propagate_attributes_from_layer_to_instances(const AttributeAccessor src_attributes, MutableAttributeAccessor dst_attributes, const AttributeFilter &attribute_filter)
void modify_geometry_sets(ForeachSubGeometryCallback callback)
void replace_grease_pencil(GreasePencil *grease_pencil, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Defines a node type.
Definition BKE_node.hh:218
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:339
NodeDeclareFunction declare
Definition BKE_node.hh:347