Blender  V2.93
node_geo_mesh_primitive_grid.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_FLOAT, N_("Size X"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE},
29  {SOCK_FLOAT, N_("Size Y"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE},
30  {SOCK_INT, N_("Vertices X"), 3, 0.0f, 0.0f, 0.0f, 2, 1000},
31  {SOCK_INT, N_("Vertices Y"), 3, 0.0f, 0.0f, 0.0f, 2, 1000},
32  {-1, ""},
33 };
34 
36  {SOCK_GEOMETRY, N_("Geometry")},
37  {-1, ""},
38 };
39 
40 namespace blender::nodes {
41 
42 static void calculate_uvs(
43  Mesh *mesh, Span<MVert> verts, Span<MLoop> loops, const float size_x, const float size_y)
44 {
45  MeshComponent mesh_component;
47  OutputAttributePtr uv_attribute = mesh_component.attribute_try_get_for_output(
48  "uv_map", ATTR_DOMAIN_CORNER, CD_PROP_FLOAT2, nullptr);
49  MutableSpan<float2> uvs = uv_attribute->get_span_for_write_only<float2>();
50 
51  const float dx = (size_x == 0.0f) ? 0.0f : 1.0f / size_x;
52  const float dy = (size_y == 0.0f) ? 0.0f : 1.0f / size_y;
53  for (const int i : loops.index_range()) {
54  const float3 &co = verts[loops[i].v].co;
55  uvs[i].x = (co.x + size_x * 0.5f) * dx;
56  uvs[i].y = (co.y + size_y * 0.5f) * dy;
57  }
58 
59  uv_attribute.apply_span_and_save();
60 }
61 
62 static Mesh *create_grid_mesh(const int verts_x,
63  const int verts_y,
64  const float size_x,
65  const float size_y)
66 {
67  BLI_assert(verts_x > 1 && verts_y > 1);
68  const int edges_x = verts_x - 1;
69  const int edges_y = verts_y - 1;
70  Mesh *mesh = BKE_mesh_new_nomain(verts_x * verts_y,
71  edges_x * verts_y + edges_y * verts_x,
72  0,
73  edges_x * edges_y * 4,
74  edges_x * edges_y);
79 
80  {
81  const float dx = size_x / edges_x;
82  const float dy = size_y / edges_y;
83  float x = -size_x * 0.5;
84  for (const int x_index : IndexRange(verts_x)) {
85  float y = -size_y * 0.5;
86  for (const int y_index : IndexRange(verts_y)) {
87  const int vert_index = x_index * verts_y + y_index;
88  verts[vert_index].co[0] = x;
89  verts[vert_index].co[1] = y;
90  verts[vert_index].co[2] = 0.0f;
91  y += dy;
92  }
93  x += dx;
94  }
95  }
96 
97  /* Point all vertex normals in the up direction. */
98  const short up_normal[3] = {0, 0, SHRT_MAX};
99  for (MVert &vert : verts) {
100  copy_v3_v3_short(vert.no, up_normal);
101  }
102 
103  /* Build the horizontal edges in the X direction. */
104  const int y_edges_start = 0;
105  int edge_index = 0;
106  for (const int x : IndexRange(verts_x)) {
107  for (const int y : IndexRange(edges_y)) {
108  const int vert_index = x * verts_y + y;
109  MEdge &edge = edges[edge_index++];
110  edge.v1 = vert_index;
111  edge.v2 = vert_index + 1;
112  edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
113  }
114  }
115 
116  /* Build the vertical edges in the Y direction. */
117  const int x_edges_start = edge_index;
118  for (const int y : IndexRange(verts_y)) {
119  for (const int x : IndexRange(edges_x)) {
120  const int vert_index = x * verts_y + y;
121  MEdge &edge = edges[edge_index++];
122  edge.v1 = vert_index;
123  edge.v2 = vert_index + verts_y;
124  edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
125  }
126  }
127 
128  int loop_index = 0;
129  int poly_index = 0;
130  for (const int x : IndexRange(edges_x)) {
131  for (const int y : IndexRange(edges_y)) {
132  MPoly &poly = polys[poly_index++];
133  poly.loopstart = loop_index;
134  poly.totloop = 4;
135  const int vert_index = x * verts_y + y;
136 
137  MLoop &loop_a = loops[loop_index++];
138  loop_a.v = vert_index;
139  loop_a.e = x_edges_start + edges_x * y + x;
140  MLoop &loop_b = loops[loop_index++];
141  loop_b.v = vert_index + verts_y;
142  loop_b.e = y_edges_start + edges_y * (x + 1) + y;
143  MLoop &loop_c = loops[loop_index++];
144  loop_c.v = vert_index + verts_y + 1;
145  loop_c.e = x_edges_start + edges_x * (y + 1) + x;
146  MLoop &loop_d = loops[loop_index++];
147  loop_d.v = vert_index + 1;
148  loop_d.e = y_edges_start + edges_y * x + y;
149  }
150  }
151 
152  calculate_uvs(mesh, verts, loops, size_x, size_y);
153 
154  return mesh;
155 }
156 
158 {
159  const float size_x = params.extract_input<float>("Size X");
160  const float size_y = params.extract_input<float>("Size Y");
161  const int verts_x = params.extract_input<int>("Vertices X");
162  const int verts_y = params.extract_input<int>("Vertices Y");
163  if (verts_x < 2 || verts_y < 2) {
164  params.set_output("Geometry", GeometrySet());
165  return;
166  }
167 
168  Mesh *mesh = create_grid_mesh(verts_x, verts_y, size_x, size_y);
170 
171  params.set_output("Geometry", GeometrySet::create_with_mesh(mesh));
172 }
173 
174 } // namespace blender::nodes
175 
177 {
178  static bNodeType ntype;
179 
184  nodeRegisterType(&ntype);
185 }
@ ATTR_DOMAIN_CORNER
Definition: BKE_attribute.h:45
bool BKE_mesh_is_valid(struct Mesh *me)
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 node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
Definition: node.cc:4527
#define NODE_CLASS_GEOMETRY
Definition: BKE_node.h:359
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1298
#define BLI_assert(a)
Definition: BLI_assert.h:58
MINLINE void copy_v3_v3_short(short r[3], const short a[3])
#define N_(msgid)
@ CD_PROP_FLOAT2
@ ME_EDGEDRAW
@ ME_EDGERENDER
@ SOCK_INT
@ SOCK_FLOAT
@ SOCK_GEOMETRY
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner Anti Mix RGB Hue Separate TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC Boolean Random Edge Subdivision Point Object Attribute Attribute Attribute Color Attribute Attribute Vector Point Attribute Sample Collection Attribute Attribute Combine Attribute GEO_NODE_MESH_PRIMITIVE_GRID
@ PROP_DISTANCE
Definition: RNA_types.h:135
OutputAttributePtr attribute_try_get_for_output(const blender::StringRef attribute_name, const AttributeDomain domain, const CustomDataType data_type, const void *default_value=nullptr)
void replace(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
constexpr IndexRange index_range() const
Definition: BLI_span.hh:414
fn::GMutableSpan get_span_for_write_only()
static float verts[][3]
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
static void geo_node_mesh_primitive_grid_exec(GeoNodeExecParams params)
static void calculate_uvs(Mesh *mesh, const bool top_is_point, const bool bottom_is_point, const int verts_num, const GeometryNodeMeshCircleFillType fill_type)
static Mesh * create_grid_mesh(const int verts_x, const int verts_y, const float size_x, const float size_y)
static bNodeSocketTemplate geo_node_mesh_primitive_grid_out[]
void register_node_type_geo_mesh_primitive_grid()
static bNodeSocketTemplate geo_node_mesh_primitive_grid_in[]
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
static GeometrySet create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
unsigned int v1
unsigned int v2
unsigned int e
unsigned int v
struct MEdge * medge
struct MVert * mvert
int totedge
int totvert
struct MLoop * mloop
int totpoly
int totloop
struct MPoly * mpoly
Compact definition of a node socket.
Definition: BKE_node.h:95
Defines a node type.
Definition: BKE_node.h:221
NodeGeometryExecFunction geometry_node_execute
Definition: BKE_node.h:327