Blender  V2.93
node_geo_mesh_primitive_line.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #include "DNA_mesh_types.h"
18 #include "DNA_meshdata_types.h"
19 
20 #include "BKE_mesh.h"
21 
22 #include "UI_interface.h"
23 #include "UI_resources.h"
24 
25 #include "node_geometry_util.hh"
26 
28  {SOCK_INT, N_("Count"), 10, 0.0f, 0.0f, 0.0f, 1, 10000},
29  {SOCK_FLOAT, N_("Resolution"), 1.0f, 0.0f, 0.0f, 0.0f, 0.01f, FLT_MAX, PROP_DISTANCE},
30  {SOCK_VECTOR,
31  N_("Start Location"),
32  0.0f,
33  0.0f,
34  0.0f,
35  1.0f,
36  -FLT_MAX,
37  FLT_MAX,
39  {SOCK_VECTOR, N_("Offset"), 0.0f, 0.0f, 1.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_TRANSLATION},
40  {-1, ""},
41 };
42 
44  {SOCK_GEOMETRY, N_("Geometry")},
45  {-1, ""},
46 };
47 
49  bContext *UNUSED(C),
50  PointerRNA *ptr)
51 {
52  uiLayoutSetPropSep(layout, true);
53  uiLayoutSetPropDecorate(layout, false);
54  uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
56  uiItemR(layout, ptr, "count_mode", 0, "", ICON_NONE);
57  }
58 }
59 
61 {
63  sizeof(NodeGeometryMeshLine), __func__);
64 
65  node_storage->mode = GEO_NODE_MESH_LINE_MODE_OFFSET;
67 
68  node->storage = node_storage;
69 }
70 
72 {
73  bNodeSocket *count_socket = (bNodeSocket *)node->inputs.first;
74  bNodeSocket *resolution_socket = count_socket->next;
75  bNodeSocket *start_socket = resolution_socket->next;
76  bNodeSocket *end_and_offset_socket = start_socket->next;
77 
78  const NodeGeometryMeshLine &storage = *(const NodeGeometryMeshLine *)node->storage;
79  const GeometryNodeMeshLineMode mode = (const GeometryNodeMeshLineMode)storage.mode;
81  storage.count_mode;
82 
83  node_sock_label(end_and_offset_socket,
84  (mode == GEO_NODE_MESH_LINE_MODE_END_POINTS) ? N_("End Location") :
85  N_("Offset"));
86 
87  nodeSetSocketAvailability(resolution_socket,
90  nodeSetSocketAvailability(count_socket,
92  count_mode == GEO_NODE_MESH_LINE_COUNT_TOTAL);
93 }
94 
95 namespace blender::nodes {
96 
98 {
99  for (const int i : edges.index_range()) {
100  edges[i].v1 = i;
101  edges[i].v2 = i + 1;
102  edges[i].flag |= ME_LOOSEEDGE;
103  }
104 }
105 
106 static Mesh *create_line_mesh(const float3 start, const float3 delta, const int count)
107 {
108  if (count < 1) {
109  return nullptr;
110  }
111 
112  Mesh *mesh = BKE_mesh_new_nomain(count, count - 1, 0, 0, 0);
115 
116  short normal[3];
118 
119  float3 co = start;
120  for (const int i : verts.index_range()) {
121  copy_v3_v3(verts[i].co, co);
122  copy_v3_v3_short(verts[i].no, normal);
123  co += delta;
124  }
125 
126  fill_edge_data(edges);
127 
128  return mesh;
129 }
130 
132 {
133  const NodeGeometryMeshLine &storage = *(const NodeGeometryMeshLine *)params.node().storage;
134  const GeometryNodeMeshLineMode mode = (const GeometryNodeMeshLineMode)storage.mode;
136  storage.count_mode;
137 
138  Mesh *mesh = nullptr;
139  const float3 start = params.extract_input<float3>("Start Location");
141  /* The label switches to "End Location", but the same socket is used. */
142  const float3 end = params.extract_input<float3>("Offset");
143  const float3 total_delta = end - start;
144 
145  if (count_mode == GEO_NODE_MESH_LINE_COUNT_RESOLUTION) {
146  /* Don't allow asymptotic count increase for low resolution values. */
147  const float resolution = std::max(params.extract_input<float>("Resolution"), 0.0001f);
148  const int count = total_delta.length() / resolution + 1;
149  const float3 delta = total_delta.normalized() * resolution;
150  mesh = create_line_mesh(start, delta, count);
151  }
152  else if (count_mode == GEO_NODE_MESH_LINE_COUNT_TOTAL) {
153  const int count = params.extract_input<int>("Count");
154  if (count == 1) {
155  mesh = create_line_mesh(start, float3(0), count);
156  }
157  else {
158  const float3 delta = total_delta / (float)(count - 1);
159  mesh = create_line_mesh(start, delta, count);
160  }
161  }
162  }
163  else if (mode == GEO_NODE_MESH_LINE_MODE_OFFSET) {
164  const float3 delta = params.extract_input<float3>("Offset");
165  const int count = params.extract_input<int>("Count");
166  mesh = create_line_mesh(start, delta, count);
167  }
168 
169  params.set_output("Geometry", GeometrySet::create_with_mesh(mesh));
170 }
171 
172 } // namespace blender::nodes
173 
175 {
176  static bNodeType ntype;
177 
184  &ntype, "NodeGeometryMeshLine", node_free_standard_storage, node_copy_standard_storage);
187  nodeRegisterType(&ntype);
188 }
typedef float(TangentPoint)[2]
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
Definition: mesh.c:877
void nodeSetSocketAvailability(struct bNodeSocket *sock, bool is_available)
Definition: node.cc:3726
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
Definition: node.cc:4527
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4623
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4559
#define NODE_CLASS_GEOMETRY
Definition: BKE_node.h:359
#define GEO_NODE_MESH_PRIMITIVE_LINE
Definition: BKE_node.h:1414
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:4599
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1298
MINLINE void normal_float_to_short_v3(short r[3], const float n[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_v3_short(short r[3], const short a[3])
#define UNUSED(x)
#define N_(msgid)
@ ME_LOOSEEDGE
GeometryNodeMeshLineCountMode
@ GEO_NODE_MESH_LINE_COUNT_RESOLUTION
@ GEO_NODE_MESH_LINE_COUNT_TOTAL
GeometryNodeMeshLineMode
@ GEO_NODE_MESH_LINE_MODE_END_POINTS
@ GEO_NODE_MESH_LINE_MODE_OFFSET
@ SOCK_INT
@ SOCK_VECTOR
@ SOCK_FLOAT
@ SOCK_GEOMETRY
@ PROP_DISTANCE
Definition: RNA_types.h:135
@ PROP_TRANSLATION
Definition: RNA_types.h:140
#define C
Definition: RandGen.cpp:39
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)
constexpr IndexRange index_range() const
Definition: BLI_span.hh:659
OperationNode * node
void * tree
bNodeTree * ntree
static float verts[][3]
IconTextureDrawCall normal
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
int count
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static void fill_edge_data(MutableSpan< MEdge > edges)
static Mesh * create_line_mesh(const float3 start, const float3 delta, const int count)
static void geo_node_mesh_primitive_line_exec(GeoNodeExecParams params)
static void geo_node_mesh_primitive_line_init(bNodeTree *UNUSED(ntree), bNode *node)
static void geo_node_mesh_primitive_line_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
void register_node_type_geo_mesh_primitive_line()
static void geo_node_mesh_primitive_line_update(bNodeTree *UNUSED(tree), bNode *node)
static bNodeSocketTemplate geo_node_mesh_primitive_line_in[]
static bNodeSocketTemplate geo_node_mesh_primitive_line_out[]
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
void node_sock_label(bNodeSocket *sock, const char *name)
Definition: node_util.c:88
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:67
void node_free_standard_storage(bNode *node)
Definition: node_util.c:55
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
static GeometrySet create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
struct MEdge * medge
struct MVert * mvert
int totedge
int totvert
Compact definition of a node socket.
Definition: BKE_node.h:95
struct bNodeSocket * next
Defines a node type.
Definition: BKE_node.h:221
NodeGeometryExecFunction geometry_node_execute
Definition: BKE_node.h:327
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:253
float3 normalized() const
Definition: BLI_float3.hh:160
float max
PointerRNA * ptr
Definition: wm_files.c:3157