[Bf-blender-cvs] [f8c52590c0f] geometry-nodes: Geometry Nodes: new Subdivision Surface node

Léo Depoix noreply at git.blender.org
Sat Oct 31 10:53:58 CET 2020


Commit: f8c52590c0f928a31d005942508b446358057794
Author: Léo Depoix
Date:   Sat Oct 31 10:51:09 2020 +0100
Branches: geometry-nodes
https://developer.blender.org/rBf8c52590c0f928a31d005942508b446358057794

Geometry Nodes: new Subdivision Surface node

This node is similar to the subdivision surface modifier. It subdivides
the mesh component of a geometry. The options have the same meaning
as in the modifier.

Differential Revision: https://developer.blender.org/D9364

===================================================================

M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.c
M	source/blender/editors/space_node/CMakeLists.txt
M	source/blender/editors/space_node/drawnode.c
M	source/blender/nodes/CMakeLists.txt
M	source/blender/nodes/NOD_geometry.h
M	source/blender/nodes/NOD_static_types.h
A	source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc

===================================================================

diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 7f661da3774..4d53ca8a228 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -490,7 +490,8 @@ geometry_node_categories = [
         NodeItem("GeometryNodeEdgeSplit"),
         NodeItem("GeometryNodeTransform"),
         NodeItem("GeometryNodeBoolean"),
-    ]),    
+        NodeItem("GeometryNodeSubdivisionSurface"),
+    ]),
     GeometryNodeCategory("GEO_SCATTERING", "Scattering", items=[
         NodeItem("GeometryNodePointDistribute"),
         NodeItem("GeometryNodePointInstance"),
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 857d73cee46..839047036ce 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1346,6 +1346,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
 #define GEO_NODE_BOOLEAN 1003
 #define GEO_NODE_POINT_DISTRIBUTE 1004
 #define GEO_NODE_POINT_INSTANCE 1005
+#define GEO_NODE_SUBDIVISION_SURFACE 1006
 
 /** \} */
 
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 5f6ceb026c0..1976461432a 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -4682,6 +4682,7 @@ static void registerGeometryNodes(void)
   register_node_type_geo_triangulate();
   register_node_type_geo_edge_split();
   register_node_type_geo_transform();
+  register_node_type_geo_subdivision_surface();
   register_node_type_geo_boolean();
   register_node_type_geo_point_distribute();
   register_node_type_geo_point_instance();
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index fc831bf8490..0c970eb7c7b 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -72,5 +72,8 @@ if(WITH_OPENIMAGEDENOISE)
   add_definitions(-DWITH_OPENIMAGEDENOISE)
 endif()
 
+if(WITH_OPENSUBDIV)
+  add_definitions(-DWITH_OPENSUBDIV)
+endif()
 
 blender_add_lib(bf_editor_space_node "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 90b873a2744..51486e398c2 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -3145,12 +3145,26 @@ static void node_geometry_buts_boolean_math(uiLayout *layout, bContext *UNUSED(C
   uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
 }
 
+static void node_geometry_buts_subdivision_surface(uiLayout *layout,
+                                                   bContext *UNUSED(C),
+                                                   PointerRNA *UNUSED(ptr))
+{
+#ifndef WITH_OPENSUBDIV
+  uiItemL(layout, IFACE_("Disabled, built without OpenSubdiv"), ICON_ERROR);
+#else
+  UNUSED_VARS(layout);
+#endif
+}
+
 static void node_geometry_set_butfunc(bNodeType *ntype)
 {
   switch (ntype->type) {
     case GEO_NODE_BOOLEAN:
       ntype->draw_buttons = node_geometry_buts_boolean_math;
       break;
+    case GEO_NODE_SUBDIVISION_SURFACE:
+      ntype->draw_buttons = node_geometry_buts_subdivision_surface;
+      break;
   }
 }
 
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 0e1abab0ed9..9b9af437e4b 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -141,6 +141,7 @@ set(SRC
   geometry/nodes/node_geo_common.cc
   geometry/nodes/node_geo_boolean.cc
   geometry/nodes/node_geo_edge_split.cc
+  geometry/nodes/node_geo_subdivision_surface.cc
   geometry/nodes/node_geo_point_distribute.cc
   geometry/nodes/node_geo_point_instance.cc
   geometry/nodes/node_geo_transform.cc
@@ -338,9 +339,12 @@ if(WITH_COMPOSITOR)
   add_definitions(-DWITH_COMPOSITOR)
 endif()
 
-
 if(WITH_FREESTYLE)
   add_definitions(-DWITH_FREESTYLE)
 endif()
 
+if(WITH_OPENSUBDIV)
+  add_definitions(-DWITH_OPENSUBDIV)
+endif()
+
 blender_add_lib(bf_nodes "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index 56cc1cc11e8..5a38947a2ca 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -29,6 +29,7 @@ void register_node_type_geo_group(void);
 void register_node_type_geo_boolean(void);
 void register_node_type_geo_edge_split(void);
 void register_node_type_geo_transform(void);
+void register_node_type_geo_subdivision_surface(void);
 void register_node_type_geo_triangulate(void);
 void register_node_type_geo_point_distribute(void);
 void register_node_type_geo_point_instance(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index f2689759e1b..4bc99d0de08 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -269,6 +269,7 @@ DefNode(FunctionNode, FN_NODE_RANDOM_FLOAT, 0,                  "RANDOM_FLOAT",
 DefNode(GeometryNode, GEO_NODE_TRIANGULATE, 0, "TRIANGULATE", Triangulate, "Triangulate", "")
 DefNode(GeometryNode, GEO_NODE_EDGE_SPLIT, 0, "EDGE_SPLIT", EdgeSplit, "Edge Split", "")
 DefNode(GeometryNode, GEO_NODE_TRANSFORM, 0, "TRANSFORM", Transform, "Transform", "")
+DefNode(GeometryNode, GEO_NODE_SUBDIVISION_SURFACE, 0, "SUBDIVISION_SURFACE", SubdivisionSurface, "Subdivision Surface", "")
 DefNode(GeometryNode, GEO_NODE_BOOLEAN, def_geo_boolean, "BOOLEAN", Boolean, "Boolean", "")
 DefNode(GeometryNode, GEO_NODE_POINT_DISTRIBUTE, 0, "POINT_DISTRIBUTE", PointDistribute, "Point Distribute", "")
 DefNode(GeometryNode, GEO_NODE_POINT_INSTANCE, 0, "POINT_INSTANCE", PointInstance, "Point Instance", "")
diff --git a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
new file mode 100644
index 00000000000..0bc0f444c40
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
@@ -0,0 +1,121 @@
+/*
+ * 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 "MEM_guardedalloc.h"
+
+#include "BKE_subdiv.h"
+#include "BKE_subdiv_mesh.h"
+
+#include "node_geometry_util.hh"
+
+static bNodeSocketTemplate geo_node_subdivision_surface_in[] = {
+    {SOCK_GEOMETRY, N_("Geometry")},
+    {SOCK_INT, N_("Level"), 1, 0, 0, 0, 0, 6},
+    {SOCK_BOOLEAN, N_("Simple")},
+    {SOCK_BOOLEAN, N_("Optimal Display")},
+    {SOCK_BOOLEAN, N_("Use Creases")},
+    {SOCK_BOOLEAN, N_("Boundary Smooth")},
+    {SOCK_BOOLEAN, N_("Smooth UVs")},
+    {-1, ""},
+};
+
+static bNodeSocketTemplate geo_node_subdivision_surface_out[] = {
+    {SOCK_GEOMETRY, N_("Geometry")},
+    {-1, ""},
+};
+
+namespace blender::nodes {
+static void geo_subdivision_surface_exec(bNode *UNUSED(node),
+                                         GeoNodeInputs inputs,
+                                         GeoNodeOutputs outputs)
+{
+  GeometryPtr geometry = inputs.extract<GeometryPtr>("Geometry");
+
+  if (!geometry.has_value() || !geometry->has_mesh()) {
+    outputs.set("Geometry", geometry);
+    return;
+  }
+
+#ifndef WITH_OPENSUBDIV
+  /* Return input geometry if Blender is build without OpenSubdiv. */
+  outputs.set("Geometry", std::move(geometry));
+  return;
+#else
+  const int subdiv_level = clamp_i(inputs.extract<int>("Level"), 0, 30);
+  const bool is_simple = inputs.extract<bool>("Simple");
+  const bool use_optimal_display = inputs.extract<bool>("Optimal Display");
+  const bool use_crease = inputs.extract<bool>("Use Creases");
+  const bool boundary_smooth = inputs.extract<bool>("Boundary Smooth");
+  const bool smooth_uvs = inputs.extract<bool>("Smooth UVs");
+
+  const Mesh *mesh_in = geometry->get_mesh_for_read();
+
+  /* Only process subdivion if level is greater than 0. */
+  if (subdiv_level == 0) {
+    outputs.set("Geometry", std::move(geometry));
+    return;
+  }
+
+  /* Mesh settings init. */
+  SubdivToMeshSettings mesh_settings;
+  mesh_settings.resolution = (1 << subdiv_level) + 1;
+  mesh_settings.use_optimal_display = use_optimal_display;
+
+  /* Subdivision settings init. */
+  SubdivSettings subdiv_settings;
+  subdiv_settings.is_simple = is_simple;
+  subdiv_settings.is_adaptive = false;
+  subdiv_settings.use_creases = use_crease;
+  subdiv_settings.level = subdiv_level;
+
+  subdiv_settings.vtx_boundary_interpolation = BKE_subdiv_vtx_boundary_interpolation_from_subsurf(
+      boundary_smooth);
+  subdiv_settings.fvar_linear_interpolation = BKE_subdiv_fvar_interpolation_from_uv_smooth(
+      smooth_uvs);
+
+  /* Apply subdiv to mesh. */
+  Subdiv *subdiv = BKE_subdiv_update_from_mesh(nullptr, &subdiv_settings, mesh_in);
+
+  /* In case of bad topology, skip to input mesh. */
+  if (subdiv == NULL) {
+    outputs.set("Geometry", std::move(geometry));
+    return;
+  }
+
+  Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh_in);
+
+  make_geometry_mutable(geometry);
+
+  geometry->replace_mesh(mesh_out);
+
+  // BKE_subdiv_stats_print(&subdiv->stats);
+  BKE_subdiv_free(subdiv);
+
+  outputs.set("Geometry", std::move(geometry));
+#endif
+}
+}  // namespace blender::nodes
+
+void register_node_type_geo_subdivision_surface()
+{
+  static bNodeType ntype;
+
+  geo_node_type_base(&ntype, GEO_NODE_SUBDIVISION_SURFACE, "Subdivision Surface", 0, 0);
+  node_type_socket_templates(
+      &ntype, geo_node_subdivision_surface_in, geo_node_subdivision_surface_out);
+  ntype.geome

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list