diff options
author | Hans Goudey <h.goudey@me.com> | 2021-03-15 05:10:46 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2021-03-15 05:10:46 +0300 |
commit | 3a45f35d7e8defd9b294056d4456b9aeca6e9208 (patch) | |
tree | 3631efb042759b4850832e5d06e47c8a784ebdbf | |
parent | 29e71774fef5a03d0e273ff83dcf679f5ebf1c3a (diff) |
Add plane primitive node
-rw-r--r-- | release/scripts/startup/nodeitems_builtins.py | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.cc | 1 | ||||
-rw-r--r-- | source/blender/nodes/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/nodes/NOD_geometry.h | 1 | ||||
-rw-r--r-- | source/blender/nodes/NOD_static_types.h | 1 | ||||
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_plane.cc | 162 |
7 files changed, 169 insertions, 3 deletions
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 0925445942e..cd894343e97 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -527,9 +527,8 @@ geometry_node_categories = [ NodeItem("GeometryNodeMeshIcoSphere"), NodeItem("GeometryNodeMeshCylinder"), NodeItem("GeometryNodeMeshCone"), - NodeItem("GeometryNodeMeshLine") - # NodeItem("GeometryNodeMeshPlane"), - # NodeItem("GeometryNodeMeshGrid"), + NodeItem("GeometryNodeMeshLine"), + NodeItem("GeometryNodeMeshPlane"), ]), GeometryNodeCategory("GEO_POINT", "Point", items=[ NodeItem("GeometryNodePointDistribute"), diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 15fc52e7cc3..6d50deae072 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -1381,6 +1381,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree, #define GEO_NODE_MESH_PRIMITIVE_ICO_SPHERE 1036 #define GEO_NODE_MESH_PRIMITIVE_CONE 1037 #define GEO_NODE_MESH_PRIMITIVE_LINE 1038 +#define GEO_NODE_MESH_PRIMITIVE_PLANE 1039 /** \} */ diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 2874c5c3a96..0b8c0ffcc2b 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -4812,6 +4812,7 @@ static void registerGeometryNodes() register_node_type_geo_mesh_primitive_cylinder(); register_node_type_geo_mesh_primitive_ico_sphere(); register_node_type_geo_mesh_primitive_line(); + register_node_type_geo_mesh_primitive_plane(); register_node_type_geo_mesh_primitive_uv_sphere(); register_node_type_geo_object_info(); register_node_type_geo_point_distribute(); diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 697647e7b2d..30184e1dee7 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -166,6 +166,7 @@ set(SRC geometry/nodes/node_geo_mesh_primitive_cone.cc geometry/nodes/node_geo_mesh_primitive_cube.cc geometry/nodes/node_geo_mesh_primitive_cylinder.cc + geometry/nodes/node_geo_mesh_primitive_plane.cc geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc geometry/nodes/node_geo_mesh_primitive_line.cc geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h index 8ecda078b46..86d3861c5ba 100644 --- a/source/blender/nodes/NOD_geometry.h +++ b/source/blender/nodes/NOD_geometry.h @@ -47,6 +47,7 @@ void register_node_type_geo_join_geometry(void); void register_node_type_geo_mesh_primitive_circle(void); void register_node_type_geo_mesh_primitive_cone(void); void register_node_type_geo_mesh_primitive_cube(void); +void register_node_type_geo_mesh_primitive_plane(void); void register_node_type_geo_mesh_primitive_cylinder(void); void register_node_type_geo_mesh_primitive_ico_sphere(void); void register_node_type_geo_mesh_primitive_line(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 50f45859d1a..eac9ae695c7 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -308,6 +308,7 @@ DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CYLINDER, def_geo_mesh_cylinder, " DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_ICO_SPHERE, 0, "MESH_PRIMITIVE_ICO_SPHERE", MeshIcoSphere, "Ico Sphere", "") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CONE, def_geo_mesh_cone, "MESH_PRIMITIVE_CONE", MeshCone, "Cone", "") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_LINE, def_geo_mesh_line, "MESH_PRIMITIVE_LINE", MeshLine, "Line", "") +DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_PLANE, 0, "MESH_PRIMITIVE_PLANE", MeshPlane, "Plane", "") /* undefine macros */ #undef DefNode diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_plane.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_plane.cc new file mode 100644 index 00000000000..df7ee046e58 --- /dev/null +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_plane.cc @@ -0,0 +1,162 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "BLI_map.hh" +#include "BLI_math_matrix.h" + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" + +#include "BKE_mesh.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "node_geometry_util.hh" + +static bNodeSocketTemplate geo_node_mesh_primitive_plane_in[] = { + {SOCK_FLOAT, N_("Size"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE}, + {SOCK_INT, N_("Vertices X"), 10, 0.0f, 0.0f, 0.0f, 2, 1000}, + {SOCK_INT, N_("Vertices Y"), 10, 0.0f, 0.0f, 0.0f, 2, 1000}, + {SOCK_VECTOR, N_("Location"), 0.0f, 0.0f, 0.0f, 1.0f, -FLT_MAX, FLT_MAX, PROP_TRANSLATION}, + {SOCK_VECTOR, N_("Rotation"), 0.0f, 0.0f, 0.0f, 1.0f, -FLT_MAX, FLT_MAX, PROP_EULER}, + {-1, ""}, +}; + +static bNodeSocketTemplate geo_node_mesh_primitive_plane_out[] = { + {SOCK_GEOMETRY, N_("Geometry")}, + {-1, ""}, +}; + +namespace blender::nodes { + +static Mesh *create_plane_mesh(const int verts_x, const int verts_y, const float size) +{ + const int edges_x = verts_x - 1; + const int edges_y = verts_y - 1; + Mesh *mesh = BKE_mesh_new_nomain(verts_x * verts_y, + edges_x * verts_y + edges_y * verts_x, + 0, + edges_x * edges_y * 4, + edges_x * edges_y); + MutableSpan<MVert> verts = MutableSpan<MVert>(mesh->mvert, mesh->totvert); + MutableSpan<MLoop> loops = MutableSpan<MLoop>(mesh->mloop, mesh->totloop); + MutableSpan<MEdge> edges = MutableSpan<MEdge>(mesh->medge, mesh->totedge); + MutableSpan<MPoly> polys = MutableSpan<MPoly>(mesh->mpoly, mesh->totpoly); + + const float dx = size * 2.0f / (edges_x); + const float dy = size * 2.0f / (edges_y); + + { + float x = -size; + for (const int x_index : IndexRange(verts_x)) { + float y = -size; + for (const int y_index : IndexRange(verts_y)) { + copy_v3_v3(verts[x_index * verts_y + y_index].co, float3(x, y, 0.0f)); + y += dy; + } + x += dx; + } + } + + /* Point all vertex normals in the up direction. */ + short up_normal[3] = {0, 0, SHRT_MAX}; + for (MVert &vert : verts) { + copy_v3_v3_short(vert.no, up_normal); + } + + /* Build the horizontal edges in the X direction. */ + const int y_edges_start = 0; + int edge_index = 0; + for (const int x : IndexRange(verts_x)) { + for (const int y : IndexRange(edges_y)) { + const int vert_index = x * verts_y + y; + MEdge &edge = edges[edge_index++]; + edge.v1 = vert_index; + edge.v2 = vert_index + 1; + } + } + + /* Build the vertical edges in the Y direction. */ + const int x_edges_start = edge_index; + for (const int y : IndexRange(verts_y)) { + for (const int x : IndexRange(edges_x)) { + const int vert_index = x * verts_y + y; + MEdge &edge = edges[edge_index++]; + edge.v1 = vert_index; + edge.v2 = vert_index + verts_y; + } + } + + int loop_index = 0; + int poly_index = 0; + for (const int x : IndexRange(edges_x)) { + for (const int y : IndexRange(edges_y)) { + MPoly &poly = polys[poly_index++]; + poly.loopstart = loop_index; + poly.totloop = 4; + const int vert_index = x * verts_y + y; + + MLoop &loop_a = loops[loop_index++]; + loop_a.v = vert_index; + loop_a.e = x_edges_start + edges_x * y + x; + MLoop &loop_b = loops[loop_index++]; + loop_b.v = vert_index + verts_y; + loop_b.e = y_edges_start + edges_y * (x + 1) + y; + MLoop &loop_c = loops[loop_index++]; + loop_c.v = vert_index + verts_y + 1; + loop_c.e = x_edges_start + edges_x * (y + 1) + x; + MLoop &loop_d = loops[loop_index++]; + loop_d.v = vert_index + 1; + loop_d.e = y_edges_start + edges_y * x + y; + } + } + + return mesh; +} + +static void geo_node_mesh_primitive_plane_exec(GeoNodeExecParams params) +{ + const float size = params.extract_input<float>("Size"); + const int verts_x = params.extract_input<int>("Vertices X"); + const int verts_y = params.extract_input<int>("Vertices Y"); + const float3 location = params.extract_input<float3>("Location"); + const float3 rotation = params.extract_input<float3>("Rotation"); + if (verts_x < 2 || verts_y < 2) { + params.set_output("Geometry", GeometrySet()); + return; + } + + Mesh *mesh = create_plane_mesh(verts_x, verts_y, size); + BLI_assert(BKE_mesh_is_valid(mesh)); + + transform_mesh(mesh, location, rotation, float3(1)); + + params.set_output("Geometry", GeometrySet::create_with_mesh(mesh)); +} + +} // namespace blender::nodes + +void register_node_type_geo_mesh_primitive_plane() +{ + static bNodeType ntype; + + geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_PLANE, "Plane", NODE_CLASS_GEOMETRY, 0); + node_type_socket_templates( + &ntype, geo_node_mesh_primitive_plane_in, geo_node_mesh_primitive_plane_out); + ntype.geometry_node_execute = blender::nodes::geo_node_mesh_primitive_plane_exec; + nodeRegisterType(&ntype); +} |