[Bf-blender-cvs] [aa48e1cd663] geometry-nodes-level-set-nodes: Geometry Nodes: Level Set Nodes (WIP)

Hans Goudey noreply at git.blender.org
Fri Aug 13 22:09:26 CEST 2021


Commit: aa48e1cd66305cddf1383663a2efee7e637e6d7d
Author: Hans Goudey
Date:   Sun Aug 1 00:58:30 2021 -0400
Branches: geometry-nodes-level-set-nodes
https://developer.blender.org/rBaa48e1cd66305cddf1383663a2efee7e637e6d7d

Geometry Nodes: Level Set Nodes (WIP)

Level sets are representations of all of the input values where a
function's output is the same. If you imagine a "position to density"
function, the corresponding level set describes a 3D surface. Disrete
Level Sets have some benefits over meshes because they always describe
a manifold shape, which makes some operations simpler. In particular,
Boolean (CSG) operations become quite straightforward. In a procedural
context, they also have the benefit of easily change-able resolution.

The OpenVDB library comes with a set of tools that getting useful
functionality out of this data structure relatively simple. This patch
adds initial versions of three level set nodes:

* **Mesh to Level Set**: Like the "Mesh to Volume" node, but creates a level set instead
** Currently the grid name is hardcoded to `level_set`
** Currently only voxel size input is available
* **Level Set Boolean**: Provides the union, difference, and intersect operations.
** The existing Boolean node should be renamed to "Mesh Boolean"
** Missing is resampling of the second input level set for a transformation.
* **Level Set Filter**: Provides "Grow", "Shrink", and "Smooth" operations.
** There are some other filters provided in the OpenVDB toolkit,
   I'm still trying to figure out their use cases though.

This patch is meant to show some possibility and give anyone interested
the chance to test. Another issue is that Blender doesn't have the ability
to display level sets at the moment, which is the idea behind this task: T88599

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

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

M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/BKE_volume.h
M	source/blender/blenkernel/intern/geometry_set.cc
M	source/blender/blenkernel/intern/node.cc
M	source/blender/blenkernel/intern/volume.cc
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/modifiers/intern/MOD_mesh_to_volume.cc
M	source/blender/modifiers/intern/MOD_volume_displace.cc
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_level_set_boolean.cc
A	source/blender/nodes/geometry/nodes/node_geo_level_set_filter.cc
A	source/blender/nodes/geometry/nodes/node_geo_mesh_to_level_set.cc
M	source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
M	source/blender/nodes/geometry/nodes/node_geo_transform.cc

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

diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 09820291222..a9c3d41df3f 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -594,6 +594,9 @@ geometry_node_categories = [
     GeometryNodeCategory("GEO_VOLUME", "Volume", items=[
         NodeItem("GeometryNodePointsToVolume"),
         NodeItem("GeometryNodeVolumeToMesh"),
+        NodeItem("GeometryNodeMeshToLevelSet"),
+        NodeItem("GeometryNodeLevelSetBoolean"),
+        NodeItem("GeometryNodeLevelSetFilter"),
     ]),
     GeometryNodeCategory("GEO_GROUP", "Group", items=node_group_items),
     GeometryNodeCategory("GEO_LAYOUT", "Layout", items=[
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 42e9ce82278..9ab3f2246c7 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -292,6 +292,8 @@ struct GeometrySet {
       PointCloud *pointcloud, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
   static GeometrySet create_with_curve(
       CurveEval *curve, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+  static GeometrySet create_with_volume(
+      Volume *volume, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
 
   /* Utility methods for access. */
   bool has_mesh() const;
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index cecb3118038..6dae272b2d0 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1466,6 +1466,9 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
 #define GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL 1070
 #define GEO_NODE_CURVE_TRIM 1071
 #define GEO_NODE_CURVE_SET_HANDLES 1072
+#define GEO_NODE_MESH_TO_LEVEL_SET 1073
+#define GEO_NODE_LEVEL_SET_BOOLEAN 1074
+#define GEO_NODE_LEVEL_SET_FILTER 1075
 
 /** \} */
 
diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index d9333996632..b53903af491 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -89,6 +89,7 @@ const VolumeGrid *BKE_volume_grid_get_for_read(const struct Volume *volume, int
 VolumeGrid *BKE_volume_grid_get_for_write(struct Volume *volume, int grid_index);
 const VolumeGrid *BKE_volume_grid_active_get_for_read(const struct Volume *volume);
 const VolumeGrid *BKE_volume_grid_find_for_read(const struct Volume *volume, const char *name);
+const VolumeGrid *BKE_volume_grid_find_for_write(struct Volume *volume, const char *name);
 
 /* Grid
  *
@@ -167,6 +168,10 @@ bool BKE_volume_min_max(const Volume *volume, blender::float3 &r_min, blender::f
 #    include <openvdb/openvdb.h>
 #    include <openvdb/points/PointDataGrid.h>
 
+VolumeGrid *BKE_volume_grid_add_vdb(struct Volume *volume,
+                                    const char *name,
+                                    openvdb::FloatGrid::Ptr vdb_grid);
+
 bool BKE_volume_grid_bounds(openvdb::GridBase::ConstPtr grid,
                             blender::float3 &r_min,
                             blender::float3 &r_max);
@@ -178,8 +183,7 @@ openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_metadata(const struct Vo
 openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_read(const struct Volume *volume,
                                                              const struct VolumeGrid *grid);
 openvdb::GridBase::Ptr BKE_volume_grid_openvdb_for_write(const struct Volume *volume,
-                                                         struct VolumeGrid *grid,
-                                                         const bool clear);
+                                                         struct VolumeGrid *grid);
 
 VolumeGridType BKE_volume_grid_type_openvdb(const openvdb::GridBase &grid);
 
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index 07b4e715ea9..ec0ecc492dd 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -309,6 +309,15 @@ GeometrySet GeometrySet::create_with_curve(CurveEval *curve, GeometryOwnershipTy
   return geometry_set;
 }
 
+/* Create a new geometry set that only contains the given volume. */
+GeometrySet GeometrySet::create_with_volume(Volume *volume, GeometryOwnershipType ownership)
+{
+  GeometrySet geometry_set;
+  VolumeComponent &component = geometry_set.get_component_for_write<VolumeComponent>();
+  component.replace(volume, ownership);
+  return geometry_set;
+}
+
 /* Clear the existing mesh and replace it with the given one. */
 void GeometrySet::replace_mesh(Mesh *mesh, GeometryOwnershipType ownership)
 {
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 9888e23a7bd..cc55627d78f 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -5158,6 +5158,8 @@ static void registerGeometryNodes()
   register_node_type_geo_input_material();
   register_node_type_geo_is_viewport();
   register_node_type_geo_join_geometry();
+  register_node_type_geo_level_set_boolean();
+  register_node_type_geo_level_set_filter();
   register_node_type_geo_material_assign();
   register_node_type_geo_material_replace();
   register_node_type_geo_mesh_primitive_circle();
@@ -5170,6 +5172,7 @@ static void registerGeometryNodes()
   register_node_type_geo_mesh_primitive_uv_sphere();
   register_node_type_geo_mesh_subdivide();
   register_node_type_geo_mesh_to_curve();
+  register_node_type_geo_mesh_to_level_set();
   register_node_type_geo_object_info();
   register_node_type_geo_point_distribute();
   register_node_type_geo_point_instance();
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index b28d17df814..8cdabce579f 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -1238,6 +1238,19 @@ const VolumeGrid *BKE_volume_grid_find_for_read(const Volume *volume, const char
   return nullptr;
 }
 
+const VolumeGrid *BKE_volume_grid_find_for_write(struct Volume *volume, const char *name)
+{
+  int num_grids = BKE_volume_num_grids(volume);
+  for (int i = 0; i < num_grids; i++) {
+    const VolumeGrid *grid = BKE_volume_grid_get_for_read(volume, i);
+    if (STREQ(BKE_volume_grid_name(grid), name)) {
+      return grid;
+    }
+  }
+
+  return nullptr;
+}
+
 /* Grid Loading */
 
 bool BKE_volume_grid_load(const Volume *volume, const VolumeGrid *grid)
@@ -1452,6 +1465,24 @@ VolumeGrid *BKE_volume_grid_add(Volume *volume, const char *name, VolumeGridType
 #endif
 }
 
+VolumeGrid *BKE_volume_grid_add_vdb(Volume *volume,
+                                    const char *name,
+                                    openvdb::FloatGrid::Ptr vdb_grid)
+{
+#ifdef WITH_OPENVDB
+  VolumeGridVector &grids = *volume->runtime.grids;
+  BLI_assert(BKE_volume_grid_find_for_read(volume, name) == nullptr);
+  BLI_assert(BKE_volume_grid_type_openvdb(*vdb_grid) != VOLUME_GRID_UNKNOWN);
+
+  vdb_grid->setName(name);
+  grids.emplace_back(vdb_grid);
+  return &grids.back();
+#else
+  UNUSED_VARS(volume, name, type);
+  return nullptr;
+#endif
+}
+
 void BKE_volume_grid_remove(Volume *volume, VolumeGrid *grid)
 {
 #ifdef WITH_OPENVDB
@@ -1541,18 +1572,11 @@ openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_read(const Volume *volum
   return grid->grid();
 }
 
-openvdb::GridBase::Ptr BKE_volume_grid_openvdb_for_write(const Volume *volume,
-                                                         VolumeGrid *grid,
-                                                         const bool clear)
+openvdb::GridBase::Ptr BKE_volume_grid_openvdb_for_write(const Volume *volume, VolumeGrid *grid)
 {
   const char *volume_name = volume->id.name + 2;
-  if (clear) {
-    grid->clear_reference(volume_name);
-  }
-  else {
-    VolumeGridVector &grids = *volume->runtime.grids;
-    grid->duplicate_reference(volume_name, grids.filepath);
-  }
+  VolumeGridVector &grids = *volume->runtime.grids;
+  grid->duplicate_reference(volume_name, grids.filepath);
 
   return grid->grid();
 }
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 5152098f57a..34788583f9b 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1307,6 +1307,16 @@ typedef struct NodeGeometryVolumeToMesh {
   uint8_t resolution_mode;
 } NodeGeometryVolumeToMesh;
 
+typedef struct NodeGeometryLevelSetBoolean {
+  /* GeometryNodeBooleanOperation */
+  uint8_t operation;
+} NodeGeometryLevelSetBoolean;
+
+typedef struct NodeGeometryLevelSetFilter {
+  /* GeometryNodeFilterOperation */
+  uint8_t operation;
+} NodeGeometryLevelSetFilter;
+
 typedef struct NodeAttributeCombineXYZ {
   /* GeometryNodeAttributeInputMode. */
   uint8_t input_type_x;
@@ -1973,6 +1983,15 @@ typedef enum GeometryNodeCurveInterpolateMode {
   GEO_NODE_CURVE_INTERPOLATE_LENGTH = 1,
 } GeometryNodeCurveInterpolateMode;
 
+typedef enum GeometryNodeFilterOperation {
+  GEO_NODE_LEVEL_SET_FILTER_GAUSSIAN = 0,
+  GEO_NODE_LEVEL_SET_FILTER_OFFSET = 1,
+  GEO_NODE_LEVEL_SET_FILTER_MEDIAN = 2,
+  GEO_NODE_LEVEL_SET_FILTER_MEAN = 3,
+  GEO_NODE_LEVEL_SET_FILTER_MEAN_CURVATURE = 4,
+  GEO_NODE_LEVEL_SET_FILTER_LAPLACIAN = 5,
+} GeometryNodeFilterOperation;
+
 typedef enum GeometryNodeAttributeTransferMapMode {
   GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED = 0,
   GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST = 1,
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 3d4256db335..5bad80ad8e6 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -9845,6 +9845,67 @@ static void def_geo_volume_to_mesh(StructRNA *srna)
   RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
 }
 
+static void def_geo_level_set_boolean(StructRNA *srna)
+{
+  PropertyRNA *prop;
+
+  static EnumPropertyItem operation_items[] = {
+      {GEO_NO

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list