[Bf-blender-cvs] [8242567574f] geometry-nodes-level-set-nodes: Initial support for instances and multiple grids in the volume to mesh node

Hans Goudey noreply at git.blender.org
Thu Sep 2 20:59:33 CEST 2021


Commit: 8242567574fa5a1b828696155116bfefc303e599
Author: Hans Goudey
Date:   Thu Sep 2 13:59:27 2021 -0500
Branches: geometry-nodes-level-set-nodes
https://developer.blender.org/rB8242567574fa5a1b828696155116bfefc303e599

Initial support for instances and multiple grids in the volume to mesh node

Non-identity transforms do not work properly yet,
and there are other internal TODOs

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

M	source/blender/blenkernel/BKE_volume_to_mesh.hh
M	source/blender/blenkernel/intern/volume_to_mesh.cc
M	source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc

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

diff --git a/source/blender/blenkernel/BKE_volume_to_mesh.hh b/source/blender/blenkernel/BKE_volume_to_mesh.hh
index 1f6e89636c4..5798ba91cab 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,37 @@ struct VolumeToMeshResolution {
 };
 
 #ifdef WITH_OPENVDB
+
+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/volume_to_mesh.cc b/source/blender/blenkernel/intern/volume_to_mesh.cc
index e9d6eea4614..cd9f0f11ee4 100644
--- a/source/blender/blenkernel/intern/volume_to_mesh.cc
+++ b/source/blender/blenkernel/intern/volume_to_mesh.cc
@@ -121,46 +121,57 @@ struct VolumeToMeshOp {
   }
 };
 
-static Mesh *new_mesh_from_openvdb_data(Span<openvdb::Vec3s> verts,
-                                        Span<openvdb::Vec3I> tris,
-                                        Span<openvdb::Vec4I> quads)
+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;
+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);
+
+  VolumeToMeshOp to_mesh_op{grid, resolution, threshold, adaptivity};
+  if (!BKE_volume_grid_type_operation(grid_type, to_mesh_op)) {
+    return {};
+  }
+  return {std::move(to_mesh_op.verts), std::move(to_mesh_op.tris), std::move(to_mesh_op.quads)};
 }
 
 Mesh *volume_to_mesh(const openvdb::GridBase &grid,
@@ -168,14 +179,27 @@ Mesh *volume_to_mesh(const openvdb::GridBase &grid,
                      const float threshold,
                      const float adaptivity)
 {
-  const VolumeGridType grid_type = BKE_volume_grid_type_openvdb(grid);
+  const bke::OpenVDBMeshData mesh_data = volume_to_mesh_data(
+      grid, resolution, threshold, adaptivity);
+
+  const int tot_loops = 3 * mesh_data.tris.size() + 4 * mesh_data.quads.size();
+  const int tot_polys = mesh_data.tris.size() + mesh_data.quads.size();
+  Mesh *mesh = BKE_mesh_new_nomain(mesh_data.verts.size(), 0, 0, tot_loops, tot_polys);
+
+  fill_mesh_from_openvdb_data(mesh_data.verts,
+                              mesh_data.tris,
+                              mesh_data.quads,
+                              0,
+                              0,
+                              0,
+                              {mesh->mvert, mesh->totvert},
+                              {mesh->mpoly, mesh->totpoly},
+                              {mesh->mloop, mesh->totloop});
 
-  VolumeToMeshOp to_mesh_op{grid, resolution, threshold, adaptivity};
-  if (!BKE_volume_grid_type_operation(grid_type, to_mesh_op)) {
-    return nullptr;
-  }
+  BKE_mesh_calc_edges(mesh, false, false);
+  BKE_mesh_normals_tag_dirty(mesh);
 
-  return new_mesh_from_openvdb_data(to_mesh_op.verts, to_mesh_op.tris, to_mesh_op.quads);
+  return mesh;
 }
 
 #endif /* WITH_OPENVDB */
diff --git a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
index 6d5eb2a28d1..f6370bfe0eb 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
@@ -40,7 +40,6 @@ namespace blender::nodes {
 static void geo_node_volume_to_mesh_declare(NodeDeclarationBuilder &b)
 {
   b.add_input<decl::Geometry>("Geometry");
-  b.add_input<decl::String>("Density");
   b.add_input<decl::Float>("Voxel Size").default_value(0.3f).min(0.01f).subtype(PROP_DISTANCE);
   b.add_input<decl::Float>("Voxel Amount").default_value(64.0f).min(0.0f);
   b.add_input<decl::Float>("Threshold").default_value(0.1f).min(0.0f);
@@ -60,11 +59,6 @@ static void geo_node_volume_to_mesh_init(bNodeTree *UNUSED(ntree), bNode *node)
   NodeGeometryVolumeToMesh *data = (NodeGeometryVolumeToMesh *)MEM_callocN(
       sizeof(NodeGeometryVolumeToMesh), __func__);
   data->resolution_mode = VOLUME_TO_MESH_RESOLUTION_MODE_GRID;
-
-  bNodeSocket *grid_socket = nodeFindSocket(node, SOCK_IN, "Density");
-  bNodeSocketValueString *grid_socket_value = (bNodeSocketValueString *)grid_socket->default_value;
-  STRNCPY(grid_socket_value->value, "density");
-
   node->storage = data;
 }
 
@@ -82,77 +76,138 @@ static void geo_node_volume_to_mesh_update(bNodeTree *UNUSED(ntree), bNode *node
 
 #ifdef WITH_OPENVDB
 
-static void create_mesh_from_volume(GeometrySet &geometry_set_in,
-                                    GeometrySet &geometry_set_out,
-                                    GeoNodeExecParams &params)
-{
-  if (!geometry_set_in.has<VolumeComponent>()) {
-    return;
-  }
-
-  SCOPED_TIMER(__func__);
+struct GridInstanceInfo {
+  openvdb::GridBase::ConstPtr grid;
+  Span<float4x4> transforms;
+};
 
+static bke::VolumeToMeshResolution get_resolution_param(const GeoNodeExecParams &params)
+{
   const NodeGeometryVolumeToMesh &storage =
       *(const NodeGeometryVolumeToMesh *)params.node().storage;
 
   bke::VolumeToMeshResolution resolution;
   resolution.mode = (VolumeToMeshResolutionMode)storage.resolution_mode;
   if (resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT) {
-    resolution.settings.voxel_amount = params.get_input<float>("Voxel Amount");
-    if (resolution.settings.voxel_amount <= 0.0f) {
-      return;
-    }
+    resolution.settings.voxel_amount = std::max(params.get_input<float>("Voxel Amount"), 0.0f);
   }
   else if (resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE) {
-    resolution.settings.voxel_size = params.get_input<float>("Voxel Size");
-    if (resolution.settings.voxel_size <= 0.0f) {
-      return;
-    }
+    resolution.settings.voxel_size = std::max(params.get_input<float>("Voxel Size"), 0.0f);
   }
 
-  const VolumeComponent *component = geometry_set_in.get_component_for_read<VolumeComponent>();
-  const Volume *volume = component->get_for_read();
-  if (volume == nullptr) {
-    return;
-  }
-
-  const Main *bmain = DEG_get_bmain(params.depsgraph());
-  BKE_volume_load(volume, bmain);
+  return resolution;
+}
 
-  const std::string grid_name = params.get_input<std::string>("Densi

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list