asset_importer_rs_post_process/
lib.rs1pub mod error;
7pub mod helper;
8pub mod steps;
9
10pub use asset_importer_rs_core::AiPostProcessSteps;
12pub use asset_importer_rs_scene::AiScene;
13pub use error::AiPostProcessError;
14
15use asset_importer_rs_core::AiPostProcess;
16use bytemuck;
17use enumflags2::BitFlags;
18
19#[cfg(feature = "calc-tangent-spaces")]
21pub use steps::CalcTangentSpaces;
22#[cfg(feature = "find-degenerates")]
23pub use steps::FindDegenerates;
24#[cfg(feature = "find-invalid-data")]
25pub use steps::FindInvalidData;
26#[cfg(feature = "gen-normals")]
27pub use steps::GenNormals;
28#[cfg(feature = "gen-smooth-normals")]
29pub use steps::GenSmoothNormals;
30#[cfg(feature = "join-identical-vertices")]
31pub use steps::JoinIdenticalVertices;
32#[cfg(feature = "optimize-graph")]
33pub use steps::OptimizeGraph;
34#[cfg(feature = "optimize-meshes")]
35pub use steps::OptimizeMeshes;
36#[cfg(feature = "remove-redundant-materials")]
37pub use steps::RemoveRedundantMaterials;
38#[cfg(feature = "triangulate")]
39pub use steps::Triangulate;
40#[cfg(feature = "validate-data-structure")]
41pub use steps::ValidateDataStructure;
42
43#[cfg(feature = "debone")]
45pub use steps::Debone;
46#[cfg(feature = "drop-normals")]
47pub use steps::DropNormals;
48#[cfg(feature = "embed-textures")]
49pub use steps::EmbedTextures;
50#[cfg(feature = "find-instances")]
51pub use steps::FindInstances;
52#[cfg(feature = "fix-infacing-normals")]
53pub use steps::FixInfacingNormals;
54#[cfg(feature = "flip-uvs")]
55pub use steps::FlipUVs;
56#[cfg(feature = "flip-winding-order")]
57pub use steps::FlipWindingOrder;
58#[cfg(feature = "force-gen-normals")]
59pub use steps::ForceGenNormals;
60#[cfg(feature = "gen-bounding-boxes")]
61pub use steps::GenBoundingBoxes;
62#[cfg(feature = "gen-uv-coords")]
63pub use steps::GenUVCoords;
64#[cfg(feature = "global-scale")]
65pub use steps::GlobalScale;
66#[cfg(feature = "improve-cache-locality")]
67pub use steps::ImproveCacheLocality;
68#[cfg(feature = "limit-bone-weights")]
69pub use steps::LimitBoneWeights;
70#[cfg(feature = "make-left-handed")]
71pub use steps::MakeLeftHanded;
72#[cfg(feature = "populate-armature-data")]
73pub use steps::PopulateArmatureData;
74#[cfg(feature = "pre-transform-vertices")]
75pub use steps::PreTransformVertices;
76#[cfg(feature = "remove-component")]
77pub use steps::RemoveComponent;
78#[cfg(feature = "sort-by-p-type")]
79pub use steps::SortByPType;
80#[cfg(feature = "split-by-bone-count")]
81pub use steps::SplitByBoneCount;
82#[cfg(feature = "split-large-meshes")]
83pub use steps::SplitLargeMeshes;
84#[cfg(feature = "transform-uv-coords")]
85pub use steps::TransformUVCoords;
86
87type AiPostProcessDyn = dyn AiPostProcess<Error = AiPostProcessError>;
88
89pub struct PostProcess {
90 processors: Vec<Box<AiPostProcessDyn>>,
91}
92
93impl PostProcess {
94 pub fn new(processors: Vec<Box<AiPostProcessDyn>>) -> Self {
95 Self { processors }
96 }
97
98 pub fn process(
99 &mut self,
100 scene: &mut AiScene,
101 steps: BitFlags<AiPostProcessSteps>,
102 ) -> Result<(), AiPostProcessError> {
103 for processor in self.processors.iter_mut() {
104 if processor.prepare(steps) {
105 processor.process(scene)?;
106 }
107 }
108 Ok(())
109 }
110}
111
112pub struct AiPostProcesserWrapper<T: AiPostProcess>
113where
114 T::Error: Into<AiPostProcessError>,
115{
116 inner: T,
117}
118
119impl<T: AiPostProcess> AiPostProcesserWrapper<T>
120where
121 T::Error: Into<AiPostProcessError>,
122{
123 pub fn new(inner: T) -> Self {
124 Self { inner }
125 }
126
127 pub fn into_inner(self) -> T {
128 self.inner
129 }
130
131 pub fn inner(&self) -> &T {
132 &self.inner
133 }
134
135 pub fn inner_mut(&mut self) -> &mut T {
136 &mut self.inner
137 }
138}
139
140impl<T: AiPostProcess> AiPostProcess for AiPostProcesserWrapper<T>
141where
142 T::Error: Into<AiPostProcessError>,
143{
144 type Error = AiPostProcessError;
145
146 fn prepare(&mut self, steps: BitFlags<AiPostProcessSteps>) -> bool {
147 self.inner.prepare(steps)
148 }
149
150 fn process(&self, scene: &mut AiScene) -> Result<(), Self::Error> {
151 self.inner.process(scene).map_err(Into::into)
152 }
153}
154pub struct AiPostProcesser;
155
156impl AiPostProcesser {
157 pub fn post_process() -> PostProcess {
158 PostProcess::new(vec![
159 #[cfg(feature = "calc-tangent-spaces")]
160 Box::new(AiPostProcesserWrapper::new(CalcTangentSpaces)),
161 #[cfg(feature = "find-degenerates")]
162 Box::new(AiPostProcesserWrapper::new(FindDegenerates)),
163 #[cfg(feature = "find-invalid-data")]
164 Box::new(AiPostProcesserWrapper::new(FindInvalidData)),
165 #[cfg(feature = "gen-normals")]
166 Box::new(AiPostProcesserWrapper::new(GenNormals::default())),
167 #[cfg(feature = "gen-smooth-normals")]
168 Box::new(AiPostProcesserWrapper::new(GenSmoothNormals::default())),
169 #[cfg(feature = "join-identical-vertices")]
170 Box::new(AiPostProcesserWrapper::new(JoinIdenticalVertices)),
171 #[cfg(feature = "optimize-graph")]
172 Box::new(AiPostProcesserWrapper::new(OptimizeGraph)),
173 #[cfg(feature = "optimize-meshes")]
174 Box::new(AiPostProcesserWrapper::new(OptimizeMeshes)),
175 #[cfg(feature = "remove-redundant-materials")]
176 Box::new(AiPostProcesserWrapper::new(RemoveRedundantMaterials)),
177 #[cfg(feature = "triangulate")]
178 Box::new(AiPostProcesserWrapper::new(Triangulate)),
179 #[cfg(feature = "validate-data-structure")]
180 Box::new(AiPostProcesserWrapper::new(ValidateDataStructure)),
181 #[cfg(feature = "debone")]
182 Box::new(AiPostProcesserWrapper::new(Debone)),
183 #[cfg(feature = "drop-normals")]
184 Box::new(AiPostProcesserWrapper::new(DropNormals)),
185 #[cfg(feature = "embed-textures")]
186 Box::new(AiPostProcesserWrapper::new(EmbedTextures)),
187 #[cfg(feature = "find-instances")]
188 Box::new(AiPostProcesserWrapper::new(FindInstances)),
189 #[cfg(feature = "fix-infacing-normals")]
190 Box::new(AiPostProcesserWrapper::new(FixInfacingNormals)),
191 #[cfg(feature = "flip-uvs")]
192 Box::new(AiPostProcesserWrapper::new(FlipUVs::default())),
193 #[cfg(feature = "flip-winding-order")]
194 Box::new(AiPostProcesserWrapper::new(FlipWindingOrder)),
195 #[cfg(feature = "force-gen-normals")]
196 Box::new(AiPostProcesserWrapper::new(ForceGenNormals)),
197 #[cfg(feature = "gen-bounding-boxes")]
198 Box::new(AiPostProcesserWrapper::new(GenBoundingBoxes)),
199 #[cfg(feature = "gen-uv-coords")]
200 Box::new(AiPostProcesserWrapper::new(GenUVCoords)),
201 #[cfg(feature = "global-scale")]
202 Box::new(AiPostProcesserWrapper::new(GlobalScale)),
203 #[cfg(feature = "improve-cache-locality")]
204 Box::new(AiPostProcesserWrapper::new(ImproveCacheLocality)),
205 #[cfg(feature = "limit-bone-weights")]
206 Box::new(AiPostProcesserWrapper::new(LimitBoneWeights)),
207 #[cfg(feature = "make-left-handed")]
208 Box::new(AiPostProcesserWrapper::new(MakeLeftHanded)),
209 #[cfg(feature = "populate-armature-data")]
210 Box::new(AiPostProcesserWrapper::new(PopulateArmatureData)),
211 #[cfg(feature = "pre-transform-vertices")]
212 Box::new(AiPostProcesserWrapper::new(PreTransformVertices)),
213 #[cfg(feature = "remove-component")]
214 Box::new(AiPostProcesserWrapper::new(RemoveComponent)),
215 #[cfg(feature = "sort-by-p-type")]
216 Box::new(AiPostProcesserWrapper::new(SortByPType)),
217 #[cfg(feature = "split-by-bone-count")]
218 Box::new(AiPostProcesserWrapper::new(SplitByBoneCount)),
219 #[cfg(feature = "split-large-meshes")]
220 Box::new(AiPostProcesserWrapper::new(SplitLargeMeshes)),
221 #[cfg(feature = "transform-uv-coords")]
222 Box::new(AiPostProcesserWrapper::new(TransformUVCoords)),
223 ])
224 }
225}