[Bf-blender-cvs] [8ddfdfd2b2a] master: Geometry Nodes: Handle multiple grids in the volume to mesh node

Hans Goudey noreply at git.blender.org
Tue Oct 26 18:25:59 CEST 2021


Commit: 8ddfdfd2b2a52f746312246aa3099ab0df8544a0
Author: Hans Goudey
Date:   Tue Oct 26 11:25:44 2021 -0500
Branches: master
https://developer.blender.org/rB8ddfdfd2b2a52f746312246aa3099ab0df8544a0

Geometry Nodes: Handle multiple grids in the volume to mesh node

In future use cases, a volume can contain many grids that represent the
density information. In this case, it's better if the volume to mesh node
creates a mesh based on all of the grids in the volume.

This is also a benefit to share-ability, since one doesn't have to
specify the grid name in the node. Instead, in the future we can have
a way to split particular grids into separate volumes, if only one
grid should be considered.

The code changes are relatively simple:
 - Move the old volume to mesh node to the legacy folder.
 - Run the volume to mesh node on all instance geometry, like elsewhere.
 - Make the blenkernel's volume to mesh API a bit more specific.

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

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

M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/BKE_volume.h
M	source/blender/blenkernel/BKE_volume_to_mesh.hh
M	source/blender/blenkernel/intern/node.cc
M	source/blender/blenkernel/intern/volume.cc
M	source/blender/blenkernel/intern/volume_to_mesh.cc
M	source/blender/blenloader/intern/versioning_290.c
M	source/blender/blenloader/intern/versioning_300.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/legacy/node_geo_volume_to_mesh.cc
M	source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc

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

diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 546f8c9e2ab..22fae8111fd 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -760,6 +760,7 @@ geometry_node_categories = [
     ]),
     GeometryNodeCategory("GEO_VOLUME", "Volume", items=[
         NodeItem("GeometryNodeLegacyPointsToVolume", poll=geometry_nodes_legacy_poll),
+        NodeItem("GeometryNodeLegacyVolumeToMesh", poll=geometry_nodes_legacy_poll),
 
         NodeItem("GeometryNodeVolumeToMesh"),
     ]),
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index c868eb414f7..8daa96164ef 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1442,7 +1442,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
 #define GEO_NODE_COLLECTION_INFO 1023
 #define GEO_NODE_IS_VIEWPORT 1024
 #define GEO_NODE_LEGACY_ATTRIBUTE_PROXIMITY 1025
-#define GEO_NODE_VOLUME_TO_MESH 1026
+#define GEO_NODE_LEGACY_VOLUME_TO_MESH 1026
 #define GEO_NODE_LEGACY_ATTRIBUTE_COMBINE_XYZ 1027
 #define GEO_NODE_LEGACY_ATTRIBUTE_SEPARATE_XYZ 1028
 #define GEO_NODE_SUBDIVIDE_MESH 1029
@@ -1548,6 +1548,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
 #define GEO_NODE_CURVE_TO_POINTS 1130
 #define GEO_NODE_INSTANCES_TO_POINTS 1131
 #define GEO_NODE_IMAGE_TEXTURE 1132
+#define GEO_NODE_VOLUME_TO_MESH 1133
 
 /** \} */
 
diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index 5fe0d54c2cf..601e0cf26a9 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -160,6 +160,7 @@ bool BKE_volume_save(const struct Volume *volume,
 #ifdef __cplusplus
 #  include "BLI_float3.hh"
 #  include "BLI_float4x4.hh"
+#  include "BLI_string_ref.hh"
 
 bool BKE_volume_min_max(const Volume *volume, blender::float3 &r_min, blender::float3 &r_max);
 
@@ -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(Volume &volume,
+                                    blender::StringRef name,
+                                    openvdb::GridBase::Ptr vdb_grid);
+
 bool BKE_volume_grid_bounds(openvdb::GridBase::ConstPtr grid,
                             blender::float3 &r_min,
                             blender::float3 &r_max);
diff --git a/source/blender/blenkernel/BKE_volume_to_mesh.hh b/source/blender/blenkernel/BKE_volume_to_mesh.hh
index 1f6e89636c4..9532da8c23c 100644
--- a/source/blender/blenkernel/BKE_volume_to_mesh.hh
+++ b/source/blender/blenkernel/BKE_volume_to_mesh.hh
@@ -14,6 +14,8 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#include "BLI_span.hh"
+
 #include "DNA_modifier_types.h"
 
 #ifdef WITH_OPENVDB
@@ -33,10 +35,40 @@ struct VolumeToMeshResolution {
 };
 
 #ifdef WITH_OPENVDB
+
+/**
+ * The result of converting a volume grid to mesh data, in the format used by the OpenVDB API.
+ */
+struct OpenVDBMeshData {
+  std::vector<openvdb::Vec3s> verts;
+  std::vector<openvdb::Vec3I> tris;
+  std::vector<openvdb::Vec4I> quads;
+  bool is_empty() const
+  {
+    return verts.empty();
+  }
+};
+
 struct Mesh *volume_to_mesh(const openvdb::GridBase &grid,
                             const VolumeToMeshResolution &resolution,
                             const float threshold,
                             const float adaptivity);
+
+struct OpenVDBMeshData volume_to_mesh_data(const openvdb::GridBase &grid,
+                                           const VolumeToMeshResolution &resolution,
+                                           const float threshold,
+                                           const float adaptivity);
+
+void fill_mesh_from_openvdb_data(const Span<openvdb::Vec3s> vdb_verts,
+                                 const Span<openvdb::Vec3I> vdb_tris,
+                                 const Span<openvdb::Vec4I> vdb_quads,
+                                 const int vert_offset,
+                                 const int poly_offset,
+                                 const int loop_offset,
+                                 MutableSpan<MVert> verts,
+                                 MutableSpan<MPoly> polys,
+                                 MutableSpan<MLoop> loops);
+
 #endif
 
 }  // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index fb2110d7e53..8494c51a66e 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -5753,6 +5753,7 @@ static void registerGeometryNodes()
   register_node_type_geo_legacy_select_by_handle_type();
   register_node_type_geo_legacy_select_by_material();
   register_node_type_geo_legacy_subdivision_surface();
+  register_node_type_geo_legacy_volume_to_mesh();
 
   register_node_type_geo_align_rotation_to_vector();
   register_node_type_geo_attribute_capture();
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 7e7a40d8e9b..a72b5268e1d 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -36,6 +36,7 @@
 #include "BLI_math.h"
 #include "BLI_path_util.h"
 #include "BLI_string.h"
+#include "BLI_string_ref.hh"
 #include "BLI_task.hh"
 #include "BLI_utildefines.h"
 
@@ -71,6 +72,7 @@ static CLG_LogRef LOG = {"bke.volume"};
 using blender::float3;
 using blender::float4x4;
 using blender::IndexRange;
+using blender::StringRef;
 
 #ifdef WITH_OPENVDB
 #  include <atomic>
@@ -1451,6 +1453,21 @@ VolumeGrid *BKE_volume_grid_add(Volume *volume, const char *name, VolumeGridType
 #endif
 }
 
+#ifdef WITH_OPENVDB
+VolumeGrid *BKE_volume_grid_add_vdb(Volume &volume,
+                                    const StringRef name,
+                                    openvdb::GridBase::Ptr vdb_grid)
+{
+  VolumeGridVector &grids = *volume.runtime.grids;
+  BLI_assert(BKE_volume_grid_find_for_read(&volume, name.data()) == 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();
+}
+#endif
+
 void BKE_volume_grid_remove(Volume *volume, VolumeGrid *grid)
 {
 #ifdef WITH_OPENVDB
diff --git a/source/blender/blenkernel/intern/volume_to_mesh.cc b/source/blender/blenkernel/intern/volume_to_mesh.cc
index e9d6eea4614..6e465b2fdf0 100644
--- a/source/blender/blenkernel/intern/volume_to_mesh.cc
+++ b/source/blender/blenkernel/intern/volume_to_mesh.cc
@@ -121,46 +121,66 @@ struct VolumeToMeshOp {
   }
 };
 
-static Mesh *new_mesh_from_openvdb_data(Span<openvdb::Vec3s> verts,
-                                        Span<openvdb::Vec3I> tris,
-                                        Span<openvdb::Vec4I> quads)
+/**
+ * Convert mesh data from the format provided by OpenVDB into Blender's #Mesh data structure.
+ * This can be used to add mesh data from a grid into an existing mesh rather than merging multiple
+ * meshes later on.
+ */
+void fill_mesh_from_openvdb_data(const Span<openvdb::Vec3s> vdb_verts,
+                                 const Span<openvdb::Vec3I> vdb_tris,
+                                 const Span<openvdb::Vec4I> vdb_quads,
+                                 const int vert_offset,
+                                 const int poly_offset,
+                                 const int loop_offset,
+                                 MutableSpan<MVert> verts,
+                                 MutableSpan<MPoly> polys,
+                                 MutableSpan<MLoop> loops)
 {
-  const int tot_loops = 3 * tris.size() + 4 * quads.size();
-  const int tot_polys = tris.size() + quads.size();
-
-  Mesh *mesh = BKE_mesh_new_nomain(verts.size(), 0, 0, tot_loops, tot_polys);
-
   /* Write vertices. */
-  for (const int i : verts.index_range()) {
-    const blender::float3 co = blender::float3(verts[i].asV());
-    copy_v3_v3(mesh->mvert[i].co, co);
+  for (const int i : vdb_verts.index_range()) {
+    const blender::float3 co = blender::float3(vdb_verts[i].asV());
+    copy_v3_v3(verts[vert_offset + i].co, co);
   }
 
   /* Write triangles. */
-  for (const int i : tris.index_range()) {
-    mesh->mpoly[i].loopstart = 3 * i;
-    mesh->mpoly[i].totloop = 3;
+  for (const int i : vdb_tris.index_range()) {
+    polys[poly_offset + i].loopstart = loop_offset + 3 * i;
+    polys[poly_offset + i].totloop = 3;
     for (int j = 0; j < 3; j++) {
       /* Reverse vertex order to get correct normals. */
-      mesh->mloop[3 * i + j].v = tris[i][2 - j];
+      loops[loop_offset + 3 * i + j].v = vert_offset + vdb_tris[i][2 - j];
     }
   }
 
   /* Write quads. */
-  const int poly_offset = tris.size();
-  const int loop_offset = tris.size() * 3;
-  for (const int i : quads.index_range()) {
-    mesh->mpoly[poly_offset + i].loopstart = loop_offset + 4 * i;
-    mesh->mpoly[poly_offset + i].totloop = 4;
+  const int quad_offset = poly_offset + vdb_tris.size();
+  const int quad_loop_offset = loop_offset + vdb_tris.size() * 3;
+  for (const int i : vdb_quads.index_range()) {
+    polys[quad_offset + i].loopstart = quad_loop_offset + 4 * i;
+    polys[quad_offset + i].totloop = 4;
     for (int j = 0; j < 4; j++) {
       /* Reverse vertex order to get correct normals. */
-      mesh->mloop[loop_offset + 4 * i + j].v = quads[i][3 - j];
+      loops[quad_loop_offset + 4 * i + j].v = vert_offset + vdb_quads[i][3 - j];
     }
   }
+}
 
-  BKE_mesh_calc_edges(mesh, false, false);
-  BKE_mesh_normals_tag_dirty(mesh);
-  return mesh;
+/**
+ * Convert an OpenVDB volume grid to corresponding mesh data: vertex positions and quad and
+ * triangle indices.
+ */
+bke::OpenVDBMeshData volume_to_mesh_data(const openvdb::GridBase &grid,
+                                         const VolumeToMeshResolution &resolution,
+                                         const float threshold,
+                                         const float adaptivity)
+{
+  const VolumeGridType grid_type = BKE_volume_grid_type_openvdb(grid);
+
+  Volume

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list