diff options
author | Hans Goudey <h.goudey@me.com> | 2021-04-02 22:35:48 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2021-04-02 22:35:48 +0300 |
commit | 46d75052eb08cd904a42882030ca5c8718ee04ee (patch) | |
tree | f87b2f0229b563a41cc0ad86843db21372d178c9 /source | |
parent | e0a07700bfbe3a4d64e65d0d51adb8c44ef105d7 (diff) |
Geometry Nodes: Separate grid primitive X and Y size
Since you can already specify a separate size for X and Y with the
grid node, it makes sense to be able to specify the size separately
for each axis also.
This also avoids some awkward math with a Transform node afterwards
when you want a specific size for each direction.
Versioning (except for animation and drivers) is handled in this commit.
Differential Revision: https://developer.blender.org/D10834
Diffstat (limited to 'source')
3 files changed, 76 insertions, 17 deletions
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 0fcc2fe8f46..3d57d55af2a 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -39,7 +39,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 15 +#define BLENDER_FILE_SUBVERSION 16 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index 0d59845e934..c9f93d35eb3 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -379,6 +379,37 @@ static void seq_update_meta_disp_range(Editing *ed) } } +static void version_node_socket_duplicate(bNodeTree *ntree, + const int node_type, + const char *old_name, + const char *new_name) +{ + /* Duplicate a link going into the original socket. */ + LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { + if (link->tonode->type == node_type) { + bNode *node = link->tonode; + bNodeSocket *dest_socket = nodeFindSocket(node, SOCK_IN, new_name); + BLI_assert(dest_socket); + if (STREQ(link->tosock->name, old_name)) { + nodeAddLink(ntree, link->fromnode, link->fromsock, node, dest_socket); + } + } + } + + /* Duplicate the default value from the old socket and assign it to the new socket. */ + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { + if (node->type == node_type) { + bNodeSocket *source_socket = nodeFindSocket(node, SOCK_IN, old_name); + bNodeSocket *dest_socket = nodeFindSocket(node, SOCK_IN, new_name); + BLI_assert(source_socket && dest_socket); + if (dest_socket->default_value) { + MEM_freeN(dest_socket->default_value); + } + dest_socket->default_value = MEM_dupallocN(source_socket->default_value); + } + } +} + void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) { if (!MAIN_VERSION_ATLEAST(bmain, 290, 1)) { @@ -641,6 +672,20 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) } } + if (!MAIN_VERSION_ATLEAST(bmain, 293, 16)) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + seq_update_meta_disp_range(SEQ_editing_get(scene, false)); + } + + /* Add a separate socket for Grid node X and Y size. */ + FOREACH_NODETREE_BEGIN (bmain, ntree, id) { + if (ntree->type == NTREE_GEOMETRY) { + version_node_socket_duplicate(ntree, GEO_NODE_MESH_PRIMITIVE_GRID, "Size X", "Size Y"); + } + FOREACH_NODETREE_END; + } + } + /** * Versioning code until next subversion bump goes here. * @@ -653,10 +698,6 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) */ { /* Keep this block, even when empty. */ - - LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { - seq_update_meta_disp_range(SEQ_editing_get(scene, false)); - } } } @@ -1939,6 +1980,15 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } } + if (!MAIN_VERSION_ATLEAST(bmain, 293, 16)) { + FOREACH_NODETREE_BEGIN (bmain, ntree, id) { + if (ntree->type == NTREE_GEOMETRY) { + version_node_socket_name(ntree, GEO_NODE_MESH_PRIMITIVE_GRID, "Size", "Size X"); + } + FOREACH_NODETREE_END; + } + } + /** * Versioning code until next subversion bump goes here. * diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc index d87e6e1ec76..17f69886276 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc @@ -28,7 +28,8 @@ #include "node_geometry_util.hh" static bNodeSocketTemplate geo_node_mesh_primitive_grid_in[] = { - {SOCK_FLOAT, N_("Size"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE}, + {SOCK_FLOAT, N_("Size X"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE}, + {SOCK_FLOAT, N_("Size Y"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE}, {SOCK_INT, N_("Vertices X"), 3, 0.0f, 0.0f, 0.0f, 2, 1000}, {SOCK_INT, N_("Vertices Y"), 3, 0.0f, 0.0f, 0.0f, 2, 1000}, {-1, ""}, @@ -41,7 +42,8 @@ static bNodeSocketTemplate geo_node_mesh_primitive_grid_out[] = { namespace blender::nodes { -static void calculate_uvs(Mesh *mesh, Span<MVert> verts, Span<MLoop> loops, const float size) +static void calculate_uvs( + Mesh *mesh, Span<MVert> verts, Span<MLoop> loops, const float size_x, const float size_y) { MeshComponent mesh_component; mesh_component.replace(mesh, GeometryOwnershipType::Editable); @@ -49,17 +51,23 @@ static void calculate_uvs(Mesh *mesh, Span<MVert> verts, Span<MLoop> loops, cons "uv", ATTR_DOMAIN_CORNER, CD_PROP_FLOAT2, nullptr); MutableSpan<float2> uvs = uv_attribute->get_span_for_write_only<float2>(); + const float dx = (size_x == 0.0f) ? 0.0f : 1.0f / size_x; + const float dy = (size_y == 0.0f) ? 0.0f : 1.0f / size_y; for (const int i : loops.index_range()) { const float3 &co = verts[loops[i].v].co; - uvs[i].x = (co.x + (size * 0.5)) / size; - uvs[i].y = (co.y + (size * 0.5)) / size; + uvs[i].x = (co.x + size_x * 0.5f) * dx; + uvs[i].y = (co.y + size_y * 0.5f) * dy; } uv_attribute.apply_span_and_save(); } -static Mesh *create_grid_mesh(const int verts_x, const int verts_y, const float size) +static Mesh *create_grid_mesh(const int verts_x, + const int verts_y, + const float size_x, + const float size_y) { + BLI_assert(verts_x > 1 && verts_y > 1); const int edges_x = verts_x - 1; const int edges_y = verts_y - 1; Mesh *mesh = BKE_mesh_new_nomain(verts_x * verts_y, @@ -73,11 +81,11 @@ static Mesh *create_grid_mesh(const int verts_x, const int verts_y, const float MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly}; { - const float dx = size / edges_x; - const float dy = size / edges_y; - float x = -size * 0.5; + const float dx = size_x / edges_x; + const float dy = size_y / edges_y; + float x = -size_x * 0.5; for (const int x_index : IndexRange(verts_x)) { - float y = -size * 0.5; + float y = -size_y * 0.5; for (const int y_index : IndexRange(verts_y)) { const int vert_index = x_index * verts_y + y_index; verts[vert_index].co[0] = x; @@ -144,14 +152,15 @@ static Mesh *create_grid_mesh(const int verts_x, const int verts_y, const float } } - calculate_uvs(mesh, verts, loops, size); + calculate_uvs(mesh, verts, loops, size_x, size_y); return mesh; } static void geo_node_mesh_primitive_grid_exec(GeoNodeExecParams params) { - const float size = params.extract_input<float>("Size"); + const float size_x = params.extract_input<float>("Size X"); + const float size_y = params.extract_input<float>("Size Y"); const int verts_x = params.extract_input<int>("Vertices X"); const int verts_y = params.extract_input<int>("Vertices Y"); if (verts_x < 2 || verts_y < 2) { @@ -159,7 +168,7 @@ static void geo_node_mesh_primitive_grid_exec(GeoNodeExecParams params) return; } - Mesh *mesh = create_grid_mesh(verts_x, verts_y, size); + Mesh *mesh = create_grid_mesh(verts_x, verts_y, size_x, size_y); BLI_assert(BKE_mesh_is_valid(mesh)); params.set_output("Geometry", GeometrySet::create_with_mesh(mesh)); |