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