diff options
Diffstat (limited to 'source/blender/nodes/geometry/nodes/node_geo_transform.cc')
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_transform.cc | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_transform.cc index 4fe61dff72d..251fa0866ad 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc @@ -14,11 +14,19 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#ifdef WITH_OPENVDB +# include <openvdb/openvdb.h> +#endif + #include "BLI_math_matrix.h" #include "DNA_pointcloud_types.h" +#include "DNA_volume_types.h" #include "BKE_mesh.h" +#include "BKE_volume.h" + +#include "DEG_depsgraph_query.h" #include "node_geometry_util.hh" @@ -116,6 +124,43 @@ static void transform_instances(InstancesComponent &instances, } } +static void transform_volume(Volume *volume, + const float3 translation, + const float3 rotation, + const float3 scale, + GeoNodeExecParams ¶ms) +{ +#ifdef WITH_OPENVDB + /* Scaling an axis to zero is not supported for volumes. */ + const float3 limited_scale = { + (scale.x == 0.0f) ? FLT_EPSILON : scale.x, + (scale.y == 0.0f) ? FLT_EPSILON : scale.y, + (scale.z == 0.0f) ? FLT_EPSILON : scale.z, + }; + + Main *bmain = DEG_get_bmain(params.depsgraph()); + BKE_volume_load(volume, bmain); + + float matrix[4][4]; + loc_eul_size_to_mat4(matrix, translation, rotation, limited_scale); + + openvdb::Mat4s vdb_matrix; + memcpy(vdb_matrix.asPointer(), matrix, sizeof(float[4][4])); + openvdb::Mat4d vdb_matrix_d{vdb_matrix}; + + const int num_grids = BKE_volume_num_grids(volume); + for (const int i : IndexRange(num_grids)) { + VolumeGrid *volume_grid = BKE_volume_grid_get(volume, i); + + openvdb::GridBase::Ptr grid = BKE_volume_grid_openvdb_for_write(volume, volume_grid, false); + openvdb::math::Transform &grid_transform = grid->transform(); + grid_transform.postMult(vdb_matrix_d); + } +#else + UNUSED_VARS(volume, translation, rotation, scale, params); +#endif +} + static void geo_node_transform_exec(GeoNodeExecParams params) { GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); @@ -138,6 +183,11 @@ static void geo_node_transform_exec(GeoNodeExecParams params) transform_instances(instances, translation, rotation, scale); } + if (geometry_set.has_volume()) { + Volume *volume = geometry_set.get_volume_for_write(); + transform_volume(volume, translation, rotation, scale, params); + } + params.set_output("Geometry", std::move(geometry_set)); } } // namespace blender::nodes |