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