use anyhow::Result;
use crate::sdf;
use crate::usd::{Attribute, Prim, SchemaBase, SchemaKind, Stage};
use super::tokens as tok;
use super::{impl_geom_schema, Boundable, Gprim, Imageable, PointBased, Xformable};
use crate::schemas::common::get_typed;
#[derive(Clone, derive_more::Deref)]
pub struct Points(Prim);
impl Points {
pub fn define(stage: &Stage, path: impl Into<sdf::Path>) -> Result<Self> {
Ok(Self(stage.define_prim(path)?.set_type_name(tok::T_POINTS)?))
}
pub fn get(stage: &Stage, path: impl Into<sdf::Path>) -> Result<Option<Self>> {
get_typed(stage, path, tok::T_POINTS).map(|o| o.map(Self))
}
pub fn widths_attr(&self) -> Attribute {
self.attribute(tok::A_WIDTHS)
}
pub fn create_widths_attr(&self) -> Result<Attribute> {
Ok(self.create_attribute(tok::A_WIDTHS, "float[]")?.set_custom(false)?)
}
pub fn ids_attr(&self) -> Attribute {
self.attribute(tok::A_IDS)
}
pub fn create_ids_attr(&self) -> Result<Attribute> {
Ok(self.create_attribute(tok::A_IDS, "int64[]")?.set_custom(false)?)
}
}
impl_geom_schema!(pointbased Points);
#[derive(Clone, derive_more::Deref)]
pub struct TetMesh(Prim);
impl TetMesh {
pub fn define(stage: &Stage, path: impl Into<sdf::Path>) -> Result<Self> {
Ok(Self(stage.define_prim(path)?.set_type_name(tok::T_TET_MESH)?))
}
pub fn get(stage: &Stage, path: impl Into<sdf::Path>) -> Result<Option<Self>> {
get_typed(stage, path, tok::T_TET_MESH).map(|o| o.map(Self))
}
pub fn tet_vertex_indices_attr(&self) -> Attribute {
self.attribute(tok::A_TET_VERTEX_INDICES)
}
pub fn create_tet_vertex_indices_attr(&self) -> Result<Attribute> {
Ok(self
.create_attribute(tok::A_TET_VERTEX_INDICES, "int4[]")?
.set_custom(false)?)
}
pub fn surface_face_vertex_indices_attr(&self) -> Attribute {
self.attribute(tok::A_SURFACE_FACE_VERTEX_INDICES)
}
pub fn create_surface_face_vertex_indices_attr(&self) -> Result<Attribute> {
Ok(self
.create_attribute(tok::A_SURFACE_FACE_VERTEX_INDICES, "int3[]")?
.set_custom(false)?)
}
}
impl_geom_schema!(pointbased TetMesh);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn points_widths_and_ids() -> Result<()> {
let stage = Stage::builder().in_memory("anon.usda")?;
let p = Points::define(&stage, "/Cloud")?;
p.create_points_attr()?.set(sdf::Value::Vec3fVec(vec![
[0.0_f32, 0.0, 0.0].into(),
[1.0, 0.0, 0.0].into(),
]))?;
p.create_widths_attr()?.set(sdf::Value::FloatVec(vec![0.1, 0.1]))?;
p.create_ids_attr()?.set(sdf::Value::Int64Vec(vec![10, 20]))?;
let p = Points::get(&stage, "/Cloud")?.expect("Points");
assert_eq!(p.widths_attr().get()?, Some(sdf::Value::FloatVec(vec![0.1, 0.1])));
assert_eq!(p.ids_attr().get()?, Some(sdf::Value::Int64Vec(vec![10, 20])));
Ok(())
}
#[test]
fn tet_mesh_indices() -> Result<()> {
let stage = Stage::builder().in_memory("anon.usda")?;
let t = TetMesh::define(&stage, "/Soft")?;
t.create_tet_vertex_indices_attr()?
.set(sdf::Value::Vec4iVec(vec![[0_i32, 1, 2, 3].into()]))?;
let t = TetMesh::get(&stage, "/Soft")?.expect("TetMesh");
assert_eq!(
t.tet_vertex_indices_attr().get()?,
Some(sdf::Value::Vec4iVec(vec![[0_i32, 1, 2, 3].into()]))
);
assert!(t.surface_face_vertex_indices_attr().get::<sdf::Value>()?.is_none());
Ok(())
}
}