hapi_rs/
volume.rs

1//! Volume and Heightfield APIs
2use crate::ffi::{raw::HAPI_VolumeTileInfo, VolumeTileInfo};
3use crate::node::HoudiniNode;
4use crate::Result;
5
6/// Volume primitive dimensions returned from [`crate::geometry::Geometry::volume_bounds()`]
7#[derive(Debug, Clone, Default)]
8pub struct VolumeBounds {
9    pub x_min: f32,
10    pub y_min: f32,
11    pub z_min: f32,
12    pub x_max: f32,
13    pub y_max: f32,
14    pub z_max: f32,
15    pub x_center: f32,
16    pub y_center: f32,
17    pub z_center: f32,
18}
19
20pub trait VolumeStorage: Sized + Copy {
21    fn read_tile(
22        node: &HoudiniNode,
23        part: i32,
24        fill: Self,
25        values: &mut [Self],
26        tile: &HAPI_VolumeTileInfo,
27    ) -> Result<()>;
28
29    fn read_voxel(
30        node: &HoudiniNode,
31        part: i32,
32        x: i32,
33        y: i32,
34        z: i32,
35        values: &mut [Self],
36    ) -> Result<()>;
37
38    fn write_tile(
39        node: &HoudiniNode,
40        part: i32,
41        values: &[Self],
42        tile: &HAPI_VolumeTileInfo,
43    ) -> Result<()>;
44
45    fn write_voxel(
46        node: &HoudiniNode,
47        part: i32,
48        x: i32,
49        y: i32,
50        z: i32,
51        values: &[Self],
52    ) -> Result<()>;
53}
54
55impl VolumeStorage for i32 {
56    fn read_tile(
57        node: &HoudiniNode,
58        part: i32,
59        fill_value: Self,
60        values: &mut [Self],
61        info: &HAPI_VolumeTileInfo,
62    ) -> Result<()> {
63        crate::ffi::get_volume_tile_int_data(node, part, fill_value, values, info)
64    }
65
66    fn read_voxel(
67        node: &HoudiniNode,
68        part: i32,
69        x: i32,
70        y: i32,
71        z: i32,
72        values: &mut [Self],
73    ) -> Result<()> {
74        crate::ffi::get_volume_voxel_int(node, part, x, y, z, values)
75    }
76
77    fn write_tile(
78        node: &HoudiniNode,
79        part: i32,
80        values: &[Self],
81        tile: &HAPI_VolumeTileInfo,
82    ) -> Result<()> {
83        crate::ffi::set_volume_tile_int_data(node, part, values, tile)
84    }
85
86    fn write_voxel(
87        node: &HoudiniNode,
88        part: i32,
89        x: i32,
90        y: i32,
91        z: i32,
92        values: &[Self],
93    ) -> Result<()> {
94        crate::ffi::set_volume_voxel_int(node, part, x, y, z, values)
95    }
96}
97
98impl VolumeStorage for f32 {
99    fn read_tile(
100        node: &HoudiniNode,
101        part: i32,
102        fill_value: Self,
103        values: &mut [Self],
104        info: &HAPI_VolumeTileInfo,
105    ) -> Result<()> {
106        crate::ffi::get_volume_tile_float_data(node, part, fill_value, values, info)
107    }
108
109    fn read_voxel(
110        node: &HoudiniNode,
111        part: i32,
112        x: i32,
113        y: i32,
114        z: i32,
115        values: &mut [Self],
116    ) -> Result<()> {
117        crate::ffi::get_volume_voxel_float(node, part, x, y, z, values)
118    }
119
120    fn write_tile(
121        node: &HoudiniNode,
122        part: i32,
123        values: &[Self],
124        tile: &HAPI_VolumeTileInfo,
125    ) -> Result<()> {
126        crate::ffi::set_volume_tile_float_data(node, part, values, tile)
127    }
128
129    fn write_voxel(
130        node: &HoudiniNode,
131        part: i32,
132        x: i32,
133        y: i32,
134        z: i32,
135        values: &[Self],
136    ) -> Result<()> {
137        crate::ffi::set_volume_voxel_float(node, part, x, y, z, values)
138    }
139}
140
141/// Represents a single tile in a volume.
142/// Used with [`crate::geometry::Geometry::foreach_volume_tile`]
143#[derive(Debug)]
144pub struct Tile<'a> {
145    pub info: &'a VolumeTileInfo,
146    pub size: usize,
147    pub index: i32,
148}
149
150pub(crate) fn iterate_tiles(
151    node: &HoudiniNode,
152    part: i32,
153    tile_size: usize,
154    callback: impl Fn(Tile),
155) -> Result<()> {
156    let mut tile = VolumeTileInfo(crate::ffi::get_volume_first_tile_info(node, part)?);
157    let mut tile_num = 0;
158    while tile.is_valid() {
159        callback(Tile {
160            info: &tile,
161            size: tile_size,
162            index: tile_num,
163        });
164        crate::ffi::get_volume_next_tile_info(node, part, &mut tile.0)?;
165        tile_num += 1;
166    }
167    Ok(())
168}