1/*
2Open Asset Import Library (assimp)
3----------------------------------------------------------------------
4
5Copyright (c) 2006-2017, assimp team
6
7All rights reserved.
8
9Redistribution and use of this software in source and binary forms,
10with or without modification, are permitted provided that the
11following conditions are met:
12
13* Redistributions of source code must retain the above
14 copyright notice, this list of conditions and the
15 following disclaimer.
16
17* Redistributions in binary form must reproduce the above
18 copyright notice, this list of conditions and the
19 following disclaimer in the documentation and/or other
20 materials provided with the distribution.
21
22* Neither the name of the assimp team, nor the names of its
23 contributors may be used to endorse or promote products
24 derived from this software without specific prior
25 written permission of the assimp team.
26
27THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39----------------------------------------------------------------------
40*/
41
42/** @file Base class of all import post processing steps */
43#ifndef INCLUDED_AI_BASEPROCESS_H
44#define INCLUDED_AI_BASEPROCESS_H
45
46#include <map>
47#include "GenericProperty.h"
48
49struct aiScene;
50
51namespace Assimp {
52
53class Importer;
54
55// ---------------------------------------------------------------------------
56/** Helper class to allow post-processing steps to interact with each other.
57 *
58 * The class maintains a simple property list that can be used by pp-steps
59 * to provide additional information to other steps. This is primarily
60 * intended for cross-step optimizations.
61 */
62class SharedPostProcessInfo
63{
64public:
65
66 struct Base
67 {
68 virtual ~Base()
69 {}
70 };
71
72 //! Represents data that is allocated on the heap, thus needs to be deleted
73 template <typename T>
74 struct THeapData : public Base
75 {
76 explicit THeapData(T* in)
77 : data (in)
78 {}
79
80 ~THeapData()
81 {
82 delete data;
83 }
84 T* data;
85 };
86
87 //! Represents static, by-value data not allocated on the heap
88 template <typename T>
89 struct TStaticData : public Base
90 {
91 explicit TStaticData(T in)
92 : data (in)
93 {}
94
95 ~TStaticData()
96 {}
97
98 T data;
99 };
100
101 // some typedefs for cleaner code
102 typedef unsigned int KeyType;
103 typedef std::map<KeyType, Base*> PropertyMap;
104
105public:
106
107 //! Destructor
108 ~SharedPostProcessInfo()
109 {
110 Clean();
111 }
112
113 //! Remove all stored properties from the table
114 void Clean()
115 {
116 // invoke the virtual destructor for all stored properties
117 for (PropertyMap::iterator it = pmap.begin(), end = pmap.end();
118 it != end; ++it)
119 {
120 delete (*it).second;
121 }
122 pmap.clear();
123 }
124
125 //! Add a heap property to the list
126 template <typename T>
127 void AddProperty( const char* name, T* in ){
128 AddProperty(name,(Base*)new THeapData<T>(in));
129 }
130
131 //! Add a static by-value property to the list
132 template <typename T>
133 void AddProperty( const char* name, T in ){
134 AddProperty(name,(Base*)new TStaticData<T>(in));
135 }
136
137
138 //! Get a heap property
139 template <typename T>
140 bool GetProperty( const char* name, T*& out ) const
141 {
142 THeapData<T>* t = (THeapData<T>*)GetPropertyInternal(name);
143 if(!t)
144 {
145 out = NULL;
146 return false;
147 }
148 out = t->data;
149 return true;
150 }
151
152 //! Get a static, by-value property
153 template <typename T>
154 bool GetProperty( const char* name, T& out ) const
155 {
156 TStaticData<T>* t = (TStaticData<T>*)GetPropertyInternal(name);
157 if(!t)return false;
158 out = t->data;
159 return true;
160 }
161
162 //! Remove a property of a specific type
163 void RemoveProperty( const char* name) {
164 SetGenericPropertyPtr<Base>(pmap,name,NULL);
165 }
166
167private:
168
169 void AddProperty( const char* name, Base* data) {
170 SetGenericPropertyPtr<Base>(pmap,name,data);
171 }
172
173 Base* GetPropertyInternal( const char* name) const {
174 return GetGenericProperty<Base*>(pmap,name,NULL);
175 }
176
177private:
178
179 //! Map of all stored properties
180 PropertyMap pmap;
181};
182
183#if 0
184
185// ---------------------------------------------------------------------------
186/** @brief Represents a dependency table for a postprocessing steps.
187 *
188 * For future use.
189 */
190 struct PPDependencyTable
191 {
192 unsigned int execute_me_before_these;
193 unsigned int execute_me_after_these;
194 unsigned int only_if_these_are_not_specified;
195 unsigned int mutually_exclusive_with;
196 };
197
198#endif
199
200
201#define AI_SPP_SPATIAL_SORT "$Spat"
202
203// ---------------------------------------------------------------------------
204/** The BaseProcess defines a common interface for all post processing steps.
205 * A post processing step is run after a successful import if the caller
206 * specified the corresponding flag when calling ReadFile().
207 * Enum #aiPostProcessSteps defines which flags are available.
208 * After a successful import the Importer iterates over its internal array
209 * of processes and calls IsActive() on each process to evaluate if the step
210 * should be executed. If the function returns true, the class' Execute()
211 * function is called subsequently.
212 */
213class ASSIMP_API_WINONLY BaseProcess
214{
215 friend class Importer;
216
217public:
218
219 /** Constructor to be privately used by Importer */
220 BaseProcess();
221
222 /** Destructor, private as well */
223 virtual ~BaseProcess();
224
225public:
226
227 // -------------------------------------------------------------------
228 /** Returns whether the processing step is present in the given flag.
229 * @param pFlags The processing flags the importer was called with. A
230 * bitwise combination of #aiPostProcessSteps.
231 * @return true if the process is present in this flag fields,
232 * false if not.
233 */
234 virtual bool IsActive( unsigned int pFlags) const = 0;
235
236 // -------------------------------------------------------------------
237 /** Check whether this step expects its input vertex data to be
238 * in verbose format. */
239 virtual bool RequireVerboseFormat() const;
240
241 // -------------------------------------------------------------------
242 /** Executes the post processing step on the given imported data.
243 * The function deletes the scene if the postprocess step fails (
244 * the object pointer will be set to NULL).
245 * @param pImp Importer instance (pImp->mScene must be valid)
246 */
247 void ExecuteOnScene( Importer* pImp);
248
249 // -------------------------------------------------------------------
250 /** Called prior to ExecuteOnScene().
251 * The function is a request to the process to update its configuration
252 * basing on the Importer's configuration property list.
253 */
254 virtual void SetupProperties(const Importer* pImp);
255
256 // -------------------------------------------------------------------
257 /** Executes the post processing step on the given imported data.
258 * A process should throw an ImportErrorException* if it fails.
259 * This method must be implemented by deriving classes.
260 * @param pScene The imported data to work at.
261 */
262 virtual void Execute( aiScene* pScene) = 0;
263
264
265 // -------------------------------------------------------------------
266 /** Assign a new SharedPostProcessInfo to the step. This object
267 * allows multiple postprocess steps to share data.
268 * @param sh May be NULL
269 */
270 inline void SetSharedData(SharedPostProcessInfo* sh) {
271 shared = sh;
272 }
273
274 // -------------------------------------------------------------------
275 /** Get the shared data that is assigned to the step.
276 */
277 inline SharedPostProcessInfo* GetSharedData() {
278 return shared;
279 }
280
281protected:
282
283 /** See the doc of #SharedPostProcessInfo for more details */
284 SharedPostProcessInfo* shared;
285
286 /** Currently active progress handler */
287 ProgressHandler* progress;
288};
289
290
291} // end of namespace Assimp
292
293#endif // AI_BASEPROCESS_H_INC
294