[Bf-blender-cvs] [1516f7dcde3] master: Geometry Nodes: Add Mesh To Volume Node

Erik Abrahamsson noreply at git.blender.org
Wed Jun 29 17:58:43 CEST 2022


Commit: 1516f7dcde34a4a31f6f3d04eac5f60310ea32b7
Author: Erik Abrahamsson
Date:   Wed Jun 29 10:56:17 2022 -0500
Branches: master
https://developer.blender.org/rB1516f7dcde34a4a31f6f3d04eac5f60310ea32b7

Geometry Nodes: Add Mesh To Volume Node

This adds a Mesh To Volume Node T86838 based on the existing modifier.
The mesh to volume conversion is implemented in the geometry module,
and shared between the node and the modifier.

Currently the node outputs a grid with the name "density". This may
change in the future depending on the decisions made in T91668.

The original patch was by Kris (@Metricity), further implementation
by Geramy Loveless (@GeramyLoveless), then finished by Erik Abrahamsson
(@erik85).

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

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

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/intern/geometry_set.cc
M	source/blender/blenkernel/intern/node.cc
M	source/blender/geometry/CMakeLists.txt
A	source/blender/geometry/GEO_mesh_to_volume.hh
A	source/blender/geometry/intern/mesh_to_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/nodes/NOD_geometry.h
M	source/blender/nodes/NOD_static_types.h
M	source/blender/nodes/geometry/CMakeLists.txt
A	source/blender/nodes/geometry/nodes/node_geo_mesh_to_volume.cc

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

diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index cddd96ff3cf..5983596dab1 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -113,6 +113,7 @@ def mesh_node_items(context):
     yield NodeItem("GeometryNodeMeshBoolean")
     yield NodeItem("GeometryNodeMeshToCurve")
     yield NodeItem("GeometryNodeMeshToPoints")
+    yield NodeItem("GeometryNodeMeshToVolume")
     yield NodeItem("GeometryNodeSplitEdges")
     yield NodeItem("GeometryNodeSubdivideMesh")
     yield NodeItem("GeometryNodeSubdivisionSurface")
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 8d658c9be15..1d4291473bb 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -411,6 +411,11 @@ struct GeometrySet {
    */
   static GeometrySet create_with_mesh(
       Mesh *mesh, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+  /**
+   * Create a new geometry set that only contains the given volume.
+   */
+  static GeometrySet create_with_volume(
+      Volume *volume, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
   /**
    * Create a new geometry set that only contains the given point cloud.
    */
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 4a84f8fc3c4..bad3e0005b8 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1498,6 +1498,7 @@ struct TexResult;
 #define GEO_NODE_VOLUME_CUBE 1161
 #define GEO_NODE_POINTS 1162
 #define GEO_NODE_FIELD_ON_DOMAIN 1163
+#define GEO_NODE_MESH_TO_VOLUME 1164
 
 /** \} */
 
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index 1a43c4d01b0..70a39acf620 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -322,6 +322,16 @@ GeometrySet GeometrySet::create_with_mesh(Mesh *mesh, GeometryOwnershipType owne
   return geometry_set;
 }
 
+GeometrySet GeometrySet::create_with_volume(Volume *volume, GeometryOwnershipType ownership)
+{
+  GeometrySet geometry_set;
+  if (volume != nullptr) {
+    VolumeComponent &component = geometry_set.get_component_for_write<VolumeComponent>();
+    component.replace(volume, ownership);
+  }
+  return geometry_set;
+}
+
 GeometrySet GeometrySet::create_with_pointcloud(PointCloud *pointcloud,
                                                 GeometryOwnershipType ownership)
 {
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index b6ab1e0174b..244c9ccd048 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -4804,6 +4804,7 @@ static void registerGeometryNodes()
   register_node_type_geo_mesh_subdivide();
   register_node_type_geo_mesh_to_curve();
   register_node_type_geo_mesh_to_points();
+  register_node_type_geo_mesh_to_volume();
   register_node_type_geo_object_info();
   register_node_type_geo_points();
   register_node_type_geo_points_to_vertices();
diff --git a/source/blender/geometry/CMakeLists.txt b/source/blender/geometry/CMakeLists.txt
index 531487a45e2..f0fb5c5c9af 100644
--- a/source/blender/geometry/CMakeLists.txt
+++ b/source/blender/geometry/CMakeLists.txt
@@ -19,6 +19,7 @@ set(SRC
   intern/mesh_merge_by_distance.cc
   intern/mesh_primitive_cuboid.cc
   intern/mesh_to_curve_convert.cc
+  intern/mesh_to_volume.cc
   intern/point_merge_by_distance.cc
   intern/realize_instances.cc
   intern/resample_curves.cc
@@ -29,6 +30,7 @@ set(SRC
   GEO_mesh_merge_by_distance.hh
   GEO_mesh_primitive_cuboid.hh
   GEO_mesh_to_curve.hh
+  GEO_mesh_to_volume.hh
   GEO_point_merge_by_distance.hh
   GEO_realize_instances.hh
   GEO_resample_curves.hh
@@ -41,6 +43,20 @@ set(LIB
   bf_blenlib
 )
 
+if(WITH_OPENVDB)
+  list(APPEND INC
+    ../../../intern/openvdb
+  )
+  list(APPEND INC_SYS
+    ${OPENVDB_INCLUDE_DIRS}
+  )
+  list(APPEND LIB
+    bf_intern_openvdb
+    ${OPENVDB_LIBRARIES}
+  )
+  add_definitions(-DWITH_OPENVDB ${OPENVDB_DEFINITIONS})
+endif()
+
 if(WITH_TBB)
   add_definitions(-DWITH_TBB)
 
diff --git a/source/blender/geometry/GEO_mesh_to_volume.hh b/source/blender/geometry/GEO_mesh_to_volume.hh
new file mode 100644
index 00000000000..384293df336
--- /dev/null
+++ b/source/blender/geometry/GEO_mesh_to_volume.hh
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_float4x4.hh"
+#include "BLI_string_ref.hh"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+
+#pragma once
+
+struct Volume;
+struct VolumeGrid;
+struct Depsgraph;
+
+/** \file
+ * \ingroup geo
+ */
+
+namespace blender::geometry {
+
+struct MeshToVolumeResolution {
+  MeshToVolumeModifierResolutionMode mode;
+  union {
+    float voxel_size;
+    float voxel_amount;
+  } settings;
+};
+
+#ifdef WITH_OPENVDB
+float volume_compute_voxel_size(const Depsgraph *depsgraph,
+                                const float3 &bb_min,
+                                const float3 &bb_max,
+                                const MeshToVolumeResolution resolution,
+                                float exterior_band_width,
+                                const float4x4 &transform);
+/**
+ * Add a new VolumeGrid to the Volume by converting the supplied mesh
+ */
+VolumeGrid *volume_grid_add_from_mesh(Volume *volume,
+                                      const StringRefNull name,
+                                      const Mesh *mesh,
+                                      const float4x4 &mesh_to_volume_space_transform,
+                                      float voxel_size,
+                                      bool fill_volume,
+                                      float exterior_band_width,
+                                      float interior_band_width,
+                                      float density);
+#endif
+}  // namespace blender::geometry
diff --git a/source/blender/geometry/intern/mesh_to_volume.cc b/source/blender/geometry/intern/mesh_to_volume.cc
new file mode 100644
index 00000000000..93a424f9a94
--- /dev/null
+++ b/source/blender/geometry/intern/mesh_to_volume.cc
@@ -0,0 +1,168 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_mesh_runtime.h"
+#include "BKE_volume.h"
+
+#include "GEO_mesh_to_volume.hh"
+
+#ifdef WITH_OPENVDB
+#  include <openvdb/openvdb.h>
+#  include <openvdb/tools/GridTransformer.h>
+#  include <openvdb/tools/VolumeToMesh.h>
+
+namespace blender::geometry {
+
+/* This class follows the MeshDataAdapter interface from openvdb. */
+class OpenVDBMeshAdapter {
+ private:
+  Span<MVert> vertices_;
+  Span<MLoop> loops_;
+  Span<MLoopTri> looptris_;
+  float4x4 transform_;
+
+ public:
+  OpenVDBMeshAdapter(const Mesh &mesh, float4x4 transform);
+  size_t polygonCount() const;
+  size_t pointCount() const;
+  size_t vertexCount(size_t UNUSED(polygon_index)) const;
+  void getIndexSpacePoint(size_t polygon_index, size_t vertex_index, openvdb::Vec3d &pos) const;
+};
+
+OpenVDBMeshAdapter::OpenVDBMeshAdapter(const Mesh &mesh, float4x4 transform)
+    : vertices_(mesh.mvert, mesh.totvert), loops_(mesh.mloop, mesh.totloop), transform_(transform)
+{
+  /* This only updates a cache and can be considered to be logically const. */
+  const MLoopTri *looptris = BKE_mesh_runtime_looptri_ensure(&mesh);
+  const int looptris_len = BKE_mesh_runtime_looptri_len(&mesh);
+  looptris_ = Span(looptris, looptris_len);
+}
+
+size_t OpenVDBMeshAdapter::polygonCount() const
+{
+  return static_cast<size_t>(looptris_.size());
+}
+
+size_t OpenVDBMeshAdapter::pointCount() const
+{
+  return static_cast<size_t>(vertices_.size());
+}
+
+size_t OpenVDBMeshAdapter::vertexCount(size_t UNUSED(polygon_index)) const
+{
+  /* All polygons are triangles. */
+  return 3;
+}
+
+void OpenVDBMeshAdapter::getIndexSpacePoint(size_t polygon_index,
+                                            size_t vertex_index,
+                                            openvdb::Vec3d &pos) const
+{
+  const MLoopTri &looptri = looptris_[polygon_index];
+  const MVert &vertex = vertices_[loops_[looptri.tri[vertex_index]].v];
+  const float3 transformed_co = transform_ * float3(vertex.co);
+  pos = &transformed_co.x;
+}
+
+float volume_compute_voxel_size(const Depsgraph *depsgraph,
+                                const float3 &bb_min,
+                                const float3 &bb_max,
+                                const MeshToVolumeResolution res,
+                                const float exterior_band_width,
+                                const float4x4 &transform)
+{
+  const float volume_simplify = BKE_volume_simplify_factor(depsgraph);
+  if (volume_simplify == 0.0f) {
+    return 0.0f;
+  }
+
+  if (res.mode == MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE) {
+    return res.settings.voxel_size / volume_simplify;
+  }
+  if (res.settings.voxel_amount <= 0) {
+    return 0;
+  }
+  /* Compute the voxel size based on the desired number of voxels and the approximated bounding
+   * box of the volume. */
+  const float diagonal = math::distance(transform * bb_max, transform * bb_min);
+  const float approximate_volume_side_length = diagonal + exterior_band_width * 2.0f;
+  const float voxel_size = approximate_volume_side_length / res.settings.voxel_amount /
+                           volume_simplify;
+  return voxel_size;
+}
+
+static openvdb::FloatGrid::Ptr mesh_to_volume_grid(const Mesh *mesh,
+                                                   const float4x4 &mesh_to_volume_space_transform,
+                                                   const float voxel_size,
+                                                   const bool fill_volume,
+                                                   const float exterior_band_width,
+                                                   const float interior_band_width,
+                                                   const float density)
+{
+  if (voxel_size == 0.0f) {
+    return nullptr;
+  }
+
+  float4x4 mesh_to_index_space_transform;
+  s

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list