smpl_core/common/
vertex_offsets.rs

1use crate::codec::codec::SmplCodec;
2use log::info;
3use ndarray as nd;
4use ndarray_npy::NpzReader;
5use smpl_utils::io::FileLoader;
6use std::io::{Read, Seek};
7/// Component for free vertex deformation of the SMPL template defined in T-Pose
8#[derive(Clone)]
9pub struct VertexOffsets {
10    pub offsets: nd::Array2<f32>,
11    pub strength: f32,
12}
13impl VertexOffsets {
14    pub fn new(offsets: nd::Array2<f32>) -> Self {
15        Self { offsets, strength: 1.0 }
16    }
17    #[allow(clippy::cast_possible_truncation)]
18    fn new_from_npz_reader<R: Read + Seek>(npz: &mut NpzReader<R>) -> Self {
19        info!("NPZ keys - {:?}", npz.names().unwrap());
20        let offsets: nd::Array2<f64> = npz.by_name("vertexOffsets").unwrap();
21        let offsets = offsets.mapv(|x| x as f32);
22        Self { offsets, strength: 1.0 }
23    }
24    #[cfg(not(target_arch = "wasm32"))]
25    /// # Panics
26    /// Will panic if the file cannot be read
27    pub fn new_from_npz(npz_path: &str) -> Self {
28        let mut npz = NpzReader::new(std::fs::File::open(npz_path).unwrap()).unwrap();
29        Self::new_from_npz_reader(&mut npz)
30    }
31    /// # Panics
32    /// Will panic if the file cannot be read
33    pub async fn new_from_npz_async(npz_path: &str) -> Self {
34        let reader = FileLoader::open(npz_path).await;
35        let mut npz = NpzReader::new(reader).unwrap();
36        Self::new_from_npz_reader(&mut npz)
37    }
38    /// Create a new ``VertexOffsets`` component from a ``SmplCodec``
39    pub fn new_from_smpl_codec(codec: &SmplCodec) -> Option<Self> {
40        codec.vertex_offsets.as_ref().map(|offsets| Self {
41            offsets: offsets.clone(),
42            strength: 1.0,
43        })
44    }
45    /// Create a new ``VertexOffsets`` component from a ``.smpl`` file
46    pub fn new_from_smpl_file(path: &str) -> Option<Self> {
47        let codec = SmplCodec::from_file(path);
48        Self::new_from_smpl_codec(&codec)
49    }
50}