Blender  V3.3
node_geo_mesh_primitive_line.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include "DNA_mesh_types.h"
4 #include "DNA_meshdata_types.h"
5 
6 #include "BLI_task.hh"
7 
8 #include "BKE_material.h"
9 #include "BKE_mesh.h"
10 
11 #include "UI_interface.h"
12 #include "UI_resources.h"
13 
15 
16 #include "node_geometry_util.hh"
17 
19 
21 
23 {
24  b.add_input<decl::Int>(N_("Count"))
25  .default_value(10)
26  .min(1)
27  .max(10000)
28  .description(N_("Number of vertices on the line"));
29  b.add_input<decl::Float>(N_("Resolution"))
30  .default_value(1.0f)
31  .min(0.1f)
32  .subtype(PROP_DISTANCE)
33  .description(N_("Length of each individual edge"));
34  b.add_input<decl::Vector>(N_("Start Location"))
35  .subtype(PROP_TRANSLATION)
36  .description(N_("Position of the first vertex"));
37  b.add_input<decl::Vector>(N_("Offset"))
38  .default_value({0.0f, 0.0f, 1.0f})
39  .subtype(PROP_TRANSLATION)
40  .description(N_(
41  "In offset mode, the distance between each socket on each axis. In end points mode, the "
42  "position of the final vertex"));
43  b.add_output<decl::Geometry>(N_("Mesh"));
44 }
45 
46 static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
47 {
48  uiLayoutSetPropSep(layout, true);
49  uiLayoutSetPropDecorate(layout, false);
50  uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
52  uiItemR(layout, ptr, "count_mode", 0, "", ICON_NONE);
53  }
54 }
55 
57 {
58  NodeGeometryMeshLine *node_storage = MEM_cnew<NodeGeometryMeshLine>(__func__);
59 
60  node_storage->mode = GEO_NODE_MESH_LINE_MODE_OFFSET;
62 
63  node->storage = node_storage;
64 }
65 
67 {
68  bNodeSocket *count_socket = (bNodeSocket *)node->inputs.first;
69  bNodeSocket *resolution_socket = count_socket->next;
70  bNodeSocket *start_socket = resolution_socket->next;
71  bNodeSocket *end_and_offset_socket = start_socket->next;
72 
73  const NodeGeometryMeshLine &storage = node_storage(*node);
76  storage.count_mode;
77 
78  node_sock_label(end_and_offset_socket,
79  (mode == GEO_NODE_MESH_LINE_MODE_END_POINTS) ? N_("End Location") :
80  N_("Offset"));
81 
83  resolution_socket,
87  count_socket,
89  count_mode == GEO_NODE_MESH_LINE_COUNT_TOTAL);
90 }
91 
93 {
94  const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
95  if (params.in_out() == SOCK_OUT) {
97  return;
98  }
99  else if (params.node_tree().typeinfo->validate_link(
100  static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
101  params.add_item(IFACE_("Count"), [](LinkSearchOpParams &params) {
102  bNode &node = params.add_node("GeometryNodeMeshLine");
103  node_storage(node).mode = GEO_NODE_MESH_LINE_MODE_OFFSET;
104  params.connect_available_socket(node, "Count");
105  });
106  params.add_item(IFACE_("Resolution"), [](LinkSearchOpParams &params) {
107  bNode &node = params.add_node("GeometryNodeMeshLine");
108  node_storage(node).mode = GEO_NODE_MESH_LINE_MODE_OFFSET;
109  node_storage(node).count_mode = GEO_NODE_MESH_LINE_COUNT_RESOLUTION;
110  params.connect_available_socket(node, "Resolution");
111  });
112  params.add_item(IFACE_("Start Location"), [](LinkSearchOpParams &params) {
113  bNode &node = params.add_node("GeometryNodeMeshLine");
114  params.connect_available_socket(node, "Start Location");
115  });
116  params.add_item(IFACE_("Offset"), [](LinkSearchOpParams &params) {
117  bNode &node = params.add_node("GeometryNodeMeshLine");
118  params.connect_available_socket(node, "Offset");
119  });
120  /* The last socket is reused in end points mode. */
121  params.add_item(IFACE_("End Location"), [](LinkSearchOpParams &params) {
122  bNode &node = params.add_node("GeometryNodeMeshLine");
123  node_storage(node).mode = GEO_NODE_MESH_LINE_MODE_END_POINTS;
124  params.connect_available_socket(node, "Offset");
125  });
126  }
127 }
128 
130 {
131  const NodeGeometryMeshLine &storage = node_storage(params.node());
134  storage.count_mode;
135 
136  Mesh *mesh = nullptr;
137  const float3 start = params.extract_input<float3>("Start Location");
139  /* The label switches to "End Location", but the same socket is used. */
140  const float3 end = params.extract_input<float3>("Offset");
141  const float3 total_delta = end - start;
142 
143  if (count_mode == GEO_NODE_MESH_LINE_COUNT_RESOLUTION) {
144  /* Don't allow asymptotic count increase for low resolution values. */
145  const float resolution = std::max(params.extract_input<float>("Resolution"), 0.0001f);
146  const int count = math::length(total_delta) / resolution + 1;
147  const float3 delta = math::normalize(total_delta) * resolution;
148  mesh = create_line_mesh(start, delta, count);
149  }
150  else if (count_mode == GEO_NODE_MESH_LINE_COUNT_TOTAL) {
151  const int count = params.extract_input<int>("Count");
152  if (count == 1) {
153  mesh = create_line_mesh(start, float3(0), count);
154  }
155  else {
156  const float3 delta = total_delta / (float)(count - 1);
157  mesh = create_line_mesh(start, delta, count);
158  }
159  }
160  }
161  else if (mode == GEO_NODE_MESH_LINE_MODE_OFFSET) {
162  const float3 delta = params.extract_input<float3>("Offset");
163  const int count = params.extract_input<int>("Count");
164  mesh = create_line_mesh(start, delta, count);
165  }
166 
167  params.set_output("Mesh", GeometrySet::create_with_mesh(mesh));
168 }
169 
170 } // namespace blender::nodes::node_geo_mesh_primitive_line_cc
171 
172 namespace blender::nodes {
173 
174 Mesh *create_line_mesh(const float3 start, const float3 delta, const int count)
175 {
176  if (count < 1) {
177  return nullptr;
178  }
179 
180  Mesh *mesh = BKE_mesh_new_nomain(count, count - 1, 0, 0, 0);
184 
186  1024 < count,
187  [&]() {
188  threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
189  for (const int i : range) {
190  copy_v3_v3(verts[i].co, start + delta * i);
191  }
192  });
193  },
194  [&]() {
195  threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
196  for (const int i : range) {
197  edges[i].v1 = i;
198  edges[i].v2 = i + 1;
199  edges[i].flag |= ME_LOOSEEDGE;
200  }
201  });
202  });
203 
204  return mesh;
205 }
206 
207 } // namespace blender::nodes
208 
210 {
212 
213  static bNodeType ntype;
214 
220  &ntype, "NodeGeometryMeshLine", node_free_standard_storage, node_copy_standard_storage);
224  nodeRegisterType(&ntype);
225 }
typedef float(TangentPoint)[2]
General operations, lookup, etc. for materials.
void BKE_id_material_eval_ensure_default_slot(struct ID *id)
Definition: material.c:784
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
Definition: mesh.cc:991
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4443
#define NODE_STORAGE_FUNCS(StorageT)
Definition: BKE_node.h:1563
void nodeSetSocketAvailability(struct bNodeTree *ntree, struct bNodeSocket *sock, bool is_available)
Definition: node.cc:3664
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4390
#define NODE_CLASS_GEOMETRY
Definition: BKE_node.h:359
#define GEO_NODE_MESH_PRIMITIVE_LINE
Definition: BKE_node.h:1397
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
Definition: node.cc:4426
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
#define UNUSED(x)
#define IFACE_(msgid)
GeometryNodeMeshLineCountMode
@ GEO_NODE_MESH_LINE_COUNT_RESOLUTION
@ GEO_NODE_MESH_LINE_COUNT_TOTAL
@ SOCK_OUT
GeometryNodeMeshLineMode
@ GEO_NODE_MESH_LINE_MODE_END_POINTS
@ GEO_NODE_MESH_LINE_MODE_OFFSET
eNodeSocketDatatype
@ SOCK_FLOAT
@ PROP_DISTANCE
Definition: RNA_types.h:149
@ PROP_TRANSLATION
Definition: RNA_types.h:154
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
Span< SocketDeclarationPtr > outputs() const
OperationNode * node
bNodeTree * ntree
static float verts[][3]
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
int count
T length(const vec_base< T, Size > &a)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
static void node_update(bNodeTree *ntree, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
Mesh * create_line_mesh(const float3 start, const float3 delta, int count)
void search_link_ops_for_declarations(GatherLinkSearchOpParams &params, Span< SocketDeclarationPtr > declarations)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
Definition: BLI_task.hh:51
void parallel_invoke(Functions &&...functions)
Definition: BLI_task.hh:99
vec_base< float, 3 > float3
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
Definition: node.cc:1082
void register_node_type_geo_mesh_primitive_line()
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
void node_sock_label(bNodeSocket *sock, const char *name)
Definition: node_util.c:76
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:55
void node_free_standard_storage(bNode *node)
Definition: node_util.c:43
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
static GeometrySet create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
struct MEdge * medge
struct MVert * mvert
int totedge
int totvert
struct bNodeSocket * next
Defines a node type.
Definition: BKE_node.h:226
NodeGeometryExecFunction geometry_node_execute
Definition: BKE_node.h:316
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition: BKE_node.h:335
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:244
NodeDeclareFunction declare
Definition: BKE_node.h:324
float max
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480