use anyhow::Result;
use crate::sdf;
use crate::usd::{Attribute, Relationship, SchemaBase, Stage};
use super::tokens as tok;
use super::{Purpose, Visibility};
pub trait Imageable: SchemaBase {
fn visibility_attr(&self) -> Attribute {
self.prim().attribute(tok::A_VISIBILITY)
}
fn create_visibility_attr(&self) -> Result<Attribute> {
Ok(self
.prim()
.create_attribute(tok::A_VISIBILITY, "token")?
.set_custom(false)?)
}
fn purpose_attr(&self) -> Attribute {
self.prim().attribute(tok::A_PURPOSE)
}
fn create_purpose_attr(&self) -> Result<Attribute> {
Ok(self
.prim()
.create_attribute(tok::A_PURPOSE, "token")?
.set_custom(false)?
.set_variability(sdf::Variability::Uniform)?)
}
fn proxy_prim_rel(&self) -> Relationship {
self.prim().relationship(tok::REL_PROXY_PRIM)
}
fn compute_visibility(&self) -> Result<Visibility> {
let stage = self.stage();
let mut cur = self.path().clone();
loop {
if direct_token(stage, &cur, tok::A_VISIBILITY)?
.as_deref()
.and_then(Visibility::from_token)
.unwrap_or_default()
== Visibility::Invisible
{
return Ok(Visibility::Invisible);
}
match cur.parent() {
Some(p) => cur = p,
None => return Ok(Visibility::Inherited),
}
}
}
fn compute_purpose(&self) -> Result<Purpose> {
let stage = self.stage();
let mut cur = self.path().clone();
loop {
if let Some(token) = direct_token(stage, &cur, tok::A_PURPOSE)? {
return Ok(Purpose::from_token(&token).unwrap_or_default());
}
match cur.parent() {
Some(p) => cur = p,
None => return Ok(Purpose::Default),
}
}
}
}
fn direct_token(stage: &Stage, prim: &sdf::Path, name: &str) -> Result<Option<String>> {
let attr = prim.append_property(name)?;
Ok(match stage.field::<sdf::Value>(attr, sdf::FieldKey::Default)? {
Some(sdf::Value::Token(s)) | Some(sdf::Value::String(s)) => Some(s),
_ => None,
})
}