Skip to main content

fbx_dom/
owned_document.rs

1//! Eager-owned snapshot produced by [`From<Document>`]: typed `Vec`s of meshes, materials, animation,
2//! etc., plus catch-all buckets for unclassified rows.
3//!
4//! ## `From<Document>` behavior
5//!
6//! Iterates every object in document order via [`crate::object::Objects`], converts each to
7//! [`OwnedObject`], then [`ClassifiedFbxObject::try_from`]. Successful variants append to the
8//! matching typed list; failures go to [`OwnedDocument::unknown_objects`] (or geometry/node/deformer
9//! “unknown kind” variants when `type_name` matches but `class_name` is unsupported).
10//!
11//! **Note:** This conversion does **not** retain the full [`Document`] connection graph on
12//! [`OwnedDocument`] itself; each [`OwnedObject`] still carries its own outgoing `OO` / `OP` / `PP`
13//! lists copied at materialization time.
14
15use crate::Document;
16use crate::object::OwnedObject;
17use crate::objects::ClassifiedFbxObject;
18use crate::objects::{
19    AnimationCurve, AnimationCurveNode, AnimationLayer, AnimationStack, BlendShape,
20    BlendShapeChannel, Camera, CameraSwitcher, Cluster, LayeredTexture, Light, LimbNode,
21    LineGeometry, Material, MeshGeometry, Model, NullNode, OwnedGlobalSettings, ShapeGeometry,
22    Skin, Texture, Video,
23};
24
25/// Fully owned FBX DOM view: header, definitions, globals, connection graph, and typed object rows.
26#[derive(Debug, Default, PartialEq)]
27pub struct OwnedDocument {
28    pub fbx_version: u32,
29    pub creator: String,
30    pub creation_date: [u32; 7],
31    pub global_settings: OwnedGlobalSettings,
32
33    pub models: Vec<Model>,
34    pub mesh_geometries: Vec<MeshGeometry>,
35    pub line_geometries: Vec<LineGeometry>,
36    pub shape_geometries: Vec<ShapeGeometry>,
37    pub unknown_geometries: Vec<OwnedObject>,
38
39    pub cameras: Vec<Camera>,
40    pub camera_switchers: Vec<CameraSwitcher>,
41    pub lights: Vec<Light>,
42    pub null_nodes: Vec<NullNode>,
43    pub limb_nodes: Vec<LimbNode>,
44    pub unknown_node_attributes: Vec<OwnedObject>,
45
46    pub materials: Vec<Material>,
47    pub textures: Vec<Texture>,
48    pub layered_textures: Vec<LayeredTexture>,
49    pub videos: Vec<Video>,
50    pub clusters: Vec<Cluster>,
51    pub skins: Vec<Skin>,
52    pub blend_shapes: Vec<BlendShape>,
53    pub blend_shape_channels: Vec<BlendShapeChannel>,
54    pub unknown_deformers: Vec<OwnedObject>,
55    pub animation_stacks: Vec<AnimationStack>,
56    pub animation_layers: Vec<AnimationLayer>,
57    pub animation_curves: Vec<AnimationCurve>,
58    pub animation_curve_nodes: Vec<AnimationCurveNode>,
59    pub unknown_objects: Vec<OwnedObject>,
60}
61
62impl From<Document> for OwnedDocument {
63    /// Classifies every `Objects` row; header and [`crate::objects::OwnedGlobalSettings`] are copied;
64    /// connection maps are only preserved per-[`OwnedObject`], not on this struct.
65    fn from(document: Document) -> Self {
66        let mut models = Vec::new();
67        let mut mesh_geometries = Vec::new();
68        let mut line_geometries = Vec::new();
69        let mut shape_geometries = Vec::new();
70        let mut unknown_geometries = Vec::new();
71        let mut cameras = Vec::new();
72        let mut camera_switchers = Vec::new();
73        let mut lights = Vec::new();
74        let mut null_nodes = Vec::new();
75        let mut limb_nodes = Vec::new();
76        let mut unknown_node_attributes = Vec::new();
77        let mut materials = Vec::new();
78        let mut textures = Vec::new();
79        let mut layered_textures = Vec::new();
80        let mut videos = Vec::new();
81        let mut clusters = Vec::new();
82        let mut skins = Vec::new();
83        let mut blend_shapes = Vec::new();
84        let mut blend_shape_channels = Vec::new();
85        let mut unknown_deformers = Vec::new();
86        let mut animation_stacks = Vec::new();
87        let mut animation_layers = Vec::new();
88        let mut animation_curves = Vec::new();
89        let mut animation_curve_nodes = Vec::new();
90        let mut unknown_objects = Vec::new();
91
92        for object in document.objects().flatten() {
93            let owned: OwnedObject = object.into();
94            let classified = match ClassifiedFbxObject::try_from(owned) {
95                Ok(v) => v,
96                Err(e) => {
97                    unknown_objects.push(e.object);
98                    continue;
99                }
100            };
101            match classified {
102                ClassifiedFbxObject::Model(v) => models.push(v),
103                ClassifiedFbxObject::MeshGeometry(v) => mesh_geometries.push(v),
104                ClassifiedFbxObject::LineGeometry(v) => line_geometries.push(v),
105                ClassifiedFbxObject::ShapeGeometry(v) => shape_geometries.push(v),
106                ClassifiedFbxObject::UnknownGeometry(v) => unknown_geometries.push(v),
107                ClassifiedFbxObject::Camera(v) => cameras.push(v),
108                ClassifiedFbxObject::CameraSwitcher(v) => camera_switchers.push(v),
109                ClassifiedFbxObject::Light(v) => lights.push(v),
110                ClassifiedFbxObject::NullNode(v) => null_nodes.push(v),
111                ClassifiedFbxObject::LimbNode(v) => limb_nodes.push(v),
112                ClassifiedFbxObject::UnknownNodeAttribute(v) => unknown_node_attributes.push(v),
113                ClassifiedFbxObject::Material(v) => materials.push(v),
114                ClassifiedFbxObject::Texture(v) => textures.push(v),
115                ClassifiedFbxObject::LayeredTexture(v) => layered_textures.push(v),
116                ClassifiedFbxObject::Video(v) => videos.push(v),
117                ClassifiedFbxObject::Cluster(v) => clusters.push(v),
118                ClassifiedFbxObject::Skin(v) => skins.push(v),
119                ClassifiedFbxObject::BlendShape(v) => blend_shapes.push(v),
120                ClassifiedFbxObject::BlendShapeChannel(v) => blend_shape_channels.push(v),
121                ClassifiedFbxObject::UnknownDeformer(v) => unknown_deformers.push(v),
122                ClassifiedFbxObject::AnimationStack(v) => animation_stacks.push(v),
123                ClassifiedFbxObject::AnimationLayer(v) => animation_layers.push(v),
124                ClassifiedFbxObject::AnimationCurve(v) => animation_curves.push(v),
125                ClassifiedFbxObject::AnimationCurveNode(v) => animation_curve_nodes.push(v),
126                ClassifiedFbxObject::Unknown(v) => unknown_objects.push(v),
127            }
128        }
129
130        let global_settings = document.global_settings().into();
131        Self {
132            fbx_version: document.fbx_version,
133            creator: document.creator,
134            creation_date: document.creation_date,
135            global_settings,
136            models,
137            mesh_geometries,
138            line_geometries,
139            shape_geometries,
140            unknown_geometries,
141            cameras,
142            camera_switchers,
143            lights,
144            null_nodes,
145            limb_nodes,
146            unknown_node_attributes,
147            materials,
148            textures,
149            layered_textures,
150            videos,
151            clusters,
152            skins,
153            blend_shapes,
154            blend_shape_channels,
155            unknown_deformers,
156            animation_stacks,
157            animation_layers,
158            animation_curves,
159            animation_curve_nodes,
160            unknown_objects,
161        }
162    }
163}