fbxcel_dom/v7400/data/mesh/
layer.rs1use std::convert::{TryFrom, TryInto};
4
5use anyhow::{bail, format_err, Error};
6
7use fbxcel::{low::v7400::AttributeValue, tree::v7400::NodeHandle};
8
9pub(crate) use self::common::LayerContentIndex;
10pub use self::{
11 color::LayerElementColorHandle,
12 common::{LayerElementHandle, MappingMode, ReferenceInformation, ReferenceMode},
13 material::LayerElementMaterialHandle,
14 normal::LayerElementNormalHandle,
15 uv::LayerElementUvHandle,
16};
17
18pub mod color;
19mod common;
20pub mod material;
21pub mod normal;
22pub mod uv;
23
24#[derive(Debug, Clone, Copy)]
26pub struct LayerHandle<'a> {
27 node: NodeHandle<'a>,
29}
30
31impl<'a> LayerHandle<'a> {
32 pub(crate) fn new(node: NodeHandle<'a>) -> Self {
34 Self { node }
35 }
36
37 pub fn get_index(&self) -> Result<LayerIndex, Error> {
39 let raw = self
40 .node
41 .attributes()
42 .get(0)
43 .ok_or_else(|| format_err!("Attributes not found for `Layer` element"))?
44 .get_i32_or_type()
45 .map_err(|ty| format_err!("Expected `i32` as layer index, but got {:?}", ty))?;
46 if raw < 0 {
47 bail!(
48 "Expected non-negative integer as layer index, but got {:?}",
49 raw
50 );
51 }
52
53 Ok(LayerIndex::new(raw as u32))
54 }
55
56 pub fn layer_element_entries(&self) -> impl Iterator<Item = LayerElementEntryHandle<'a>> {
58 self.children_by_name("LayerElement")
59 .map(LayerElementEntryHandle::new)
60 }
61}
62
63impl<'a> std::ops::Deref for LayerHandle<'a> {
64 type Target = NodeHandle<'a>;
65
66 fn deref(&self) -> &Self::Target {
67 &self.node
68 }
69}
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
73pub struct LayerIndex(u32);
74
75impl LayerIndex {
76 fn new(v: u32) -> Self {
78 Self(v)
79 }
80
81 pub fn to_u32(self) -> u32 {
83 self.0
84 }
85
86 #[deprecated(since = "0.0.3", note = "Renamed to `to_u32`")]
88 pub fn get_u32(self) -> u32 {
89 self.to_u32()
90 }
91}
92
93#[derive(Debug, Clone, Copy)]
98pub struct LayerElementEntryHandle<'a> {
99 node: NodeHandle<'a>,
101}
102
103impl<'a> LayerElementEntryHandle<'a> {
104 fn new(node: NodeHandle<'a>) -> Self {
106 Self { node }
107 }
108
109 pub fn type_str(&self) -> Result<&'a str, Error> {
111 self.children_by_name("Type")
112 .next()
113 .ok_or_else(|| format_err!("Child node `Type` not found for `LayerElement`"))?
114 .attributes()
115 .get(0)
116 .ok_or_else(|| format_err!("Attributes not found for `Type`"))?
117 .get_string_or_type()
118 .map_err(|ty| format_err!("Expected string but got {:?}", ty))
119 }
120
121 pub fn type_(&self) -> Result<LayerElementType, Error> {
123 self.type_str()?.parse()
124 }
125
126 pub fn typed_index(&self) -> Result<LayerElementIndex, Error> {
128 let raw = self
129 .children_by_name("TypedIndex")
130 .next()
131 .ok_or_else(|| format_err!("Child node `TypedIndex` not found for `LayerElement`"))?
132 .attributes()
133 .get(0)
134 .ok_or_else(|| format_err!("Attributes not found for `TypedIndex`"))?
135 .get_i32_or_type()
136 .map_err(|ty| format_err!("Expected `i32` but got {:?}", ty))?;
137 if raw < 0 {
138 bail!(
139 "Expected non-negative integer as layer element index, but got {:?}",
140 raw
141 );
142 }
143
144 Ok(LayerElementIndex::new(raw as u32))
145 }
146
147 pub fn typed_layer_element(&self) -> Result<TypedLayerElementHandle<'a>, Error> {
149 let geometry_node = self.parent().and_then(|p| p.parent()).ok_or_else(|| {
150 format_err!(
151 "Failed to get parent of parent of `LayerElement` node, \
152 this is not supposed to happen"
153 )
154 })?;
155 let ty = self.type_()?;
156 let index = self.typed_index()?;
157 geometry_node
158 .children_by_name(ty.type_name())
159 .find(|node| {
160 node.attributes()
161 .get(0)
162 .and_then(AttributeValue::get_i32)
163 .map_or(false, |v| v == index.to_u32() as i32)
164 })
165 .ok_or_else(|| {
166 format_err!(
167 "Layer element node not found: type={:?}, index={:?}",
168 ty,
169 index
170 )
171 })
172 .map(|node| TypedLayerElementHandle::new(ty, node))
173 }
174}
175
176impl<'a> std::ops::Deref for LayerElementEntryHandle<'a> {
177 type Target = NodeHandle<'a>;
178
179 fn deref(&self) -> &Self::Target {
180 &self.node
181 }
182}
183
184#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
186pub enum LayerElementType {
187 Color,
189 Material,
191 Normal,
193 Uv,
195}
196
197impl LayerElementType {
198 pub fn type_name(self) -> &'static str {
200 match self {
201 LayerElementType::Color => "LayerElementColor",
202 LayerElementType::Material => "LayerElementMaterial",
203 LayerElementType::Normal => "LayerElementNormal",
204 LayerElementType::Uv => "LayerElementUV",
205 }
206 }
207}
208
209impl TryFrom<&str> for LayerElementType {
210 type Error = Error;
211
212 fn try_from(s: &str) -> Result<Self, Self::Error> {
213 match s {
214 "LayerElementColor" => Ok(LayerElementType::Color),
215 "LayerElementMaterial" => Ok(LayerElementType::Material),
216 "LayerElementNormal" => Ok(LayerElementType::Normal),
217 "LayerElementUV" => Ok(LayerElementType::Uv),
218 _ => Err(format_err!("Unknown layer element type: {:?}", s)),
219 }
220 }
221}
222
223impl std::str::FromStr for LayerElementType {
224 type Err = Error;
225
226 fn from_str(s: &str) -> Result<Self, Self::Err> {
227 s.try_into()
228 }
229}
230
231#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
233pub struct LayerElementIndex(u32);
234
235impl LayerElementIndex {
236 fn new(v: u32) -> Self {
238 Self(v)
239 }
240
241 pub fn to_u32(self) -> u32 {
243 self.0
244 }
245
246 #[deprecated(since = "0.0.3", note = "Renamed to `to_u32`")]
248 pub fn get_u32(self) -> u32 {
249 self.to_u32()
250 }
251}
252
253#[derive(Debug, Clone, Copy)]
255pub enum TypedLayerElementHandle<'a> {
256 Color(LayerElementColorHandle<'a>),
258 Material(LayerElementMaterialHandle<'a>),
260 Normal(LayerElementNormalHandle<'a>),
262 Uv(LayerElementUvHandle<'a>),
264}
265
266impl<'a> TypedLayerElementHandle<'a> {
267 fn new(ty: LayerElementType, node: NodeHandle<'a>) -> Self {
269 let base = LayerElementHandle::new(node);
270 match ty {
271 LayerElementType::Color => {
272 TypedLayerElementHandle::Color(LayerElementColorHandle::new(base))
273 }
274 LayerElementType::Material => {
275 TypedLayerElementHandle::Material(LayerElementMaterialHandle::new(base))
276 }
277 LayerElementType::Normal => {
278 TypedLayerElementHandle::Normal(LayerElementNormalHandle::new(base))
279 }
280 LayerElementType::Uv => TypedLayerElementHandle::Uv(LayerElementUvHandle::new(base)),
281 }
282 }
283}
284
285impl<'a> std::ops::Deref for TypedLayerElementHandle<'a> {
286 type Target = LayerElementHandle<'a>;
287
288 fn deref(&self) -> &Self::Target {
289 match self {
290 TypedLayerElementHandle::Color(v) => v,
291 TypedLayerElementHandle::Normal(v) => v,
292 TypedLayerElementHandle::Material(v) => v,
293 TypedLayerElementHandle::Uv(v) => v,
294 }
295 }
296}