rev |
line source |
nuclear@0
|
1 /*
|
nuclear@0
|
2 ---------------------------------------------------------------------------
|
nuclear@0
|
3 Open Asset Import Library (assimp)
|
nuclear@0
|
4 ---------------------------------------------------------------------------
|
nuclear@0
|
5
|
nuclear@0
|
6 Copyright (c) 2006-2012, assimp team
|
nuclear@0
|
7
|
nuclear@0
|
8 All rights reserved.
|
nuclear@0
|
9
|
nuclear@0
|
10 Redistribution and use of this software in source and binary forms,
|
nuclear@0
|
11 with or without modification, are permitted provided that the following
|
nuclear@0
|
12 conditions are met:
|
nuclear@0
|
13
|
nuclear@0
|
14 * Redistributions of source code must retain the above
|
nuclear@0
|
15 copyright notice, this list of conditions and the
|
nuclear@0
|
16 following disclaimer.
|
nuclear@0
|
17
|
nuclear@0
|
18 * Redistributions in binary form must reproduce the above
|
nuclear@0
|
19 copyright notice, this list of conditions and the
|
nuclear@0
|
20 following disclaimer in the documentation and/or other
|
nuclear@0
|
21 materials provided with the distribution.
|
nuclear@0
|
22
|
nuclear@0
|
23 * Neither the name of the assimp team, nor the names of its
|
nuclear@0
|
24 contributors may be used to endorse or promote products
|
nuclear@0
|
25 derived from this software without specific prior
|
nuclear@0
|
26 written permission of the assimp team.
|
nuclear@0
|
27
|
nuclear@0
|
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
nuclear@0
|
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
nuclear@0
|
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
nuclear@0
|
31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
nuclear@0
|
32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
nuclear@0
|
33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
nuclear@0
|
34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
nuclear@0
|
35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
nuclear@0
|
36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
nuclear@0
|
37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
nuclear@0
|
38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
nuclear@0
|
39 ---------------------------------------------------------------------------
|
nuclear@0
|
40 */
|
nuclear@0
|
41
|
nuclear@0
|
42 /** @file Exporter.cpp
|
nuclear@0
|
43
|
nuclear@0
|
44 Assimp export interface. While it's public interface bears many similarities
|
nuclear@0
|
45 to the import interface (in fact, it is largely symmetric), the internal
|
nuclear@0
|
46 implementations differs a lot. Exporters are considered stateless and are
|
nuclear@0
|
47 simple callbacks which we maintain in a global list along with their
|
nuclear@0
|
48 description strings.
|
nuclear@0
|
49
|
nuclear@0
|
50 Here we implement only the C++ interface (Assimp::Exporter).
|
nuclear@0
|
51 */
|
nuclear@0
|
52
|
nuclear@0
|
53 #include "AssimpPCH.h"
|
nuclear@0
|
54
|
nuclear@0
|
55 #ifndef ASSIMP_BUILD_NO_EXPORT
|
nuclear@0
|
56
|
nuclear@0
|
57 #include "DefaultIOSystem.h"
|
nuclear@0
|
58 #include "BlobIOSystem.h"
|
nuclear@0
|
59 #include "SceneCombiner.h"
|
nuclear@0
|
60 #include "BaseProcess.h"
|
nuclear@0
|
61 #include "Importer.h" // need this for GetPostProcessingStepInstanceList()
|
nuclear@0
|
62
|
nuclear@0
|
63 #include "MakeVerboseFormat.h"
|
nuclear@0
|
64 #include "ConvertToLHProcess.h"
|
nuclear@0
|
65
|
nuclear@0
|
66 namespace Assimp {
|
nuclear@0
|
67
|
nuclear@0
|
68 // PostStepRegistry.cpp
|
nuclear@0
|
69 void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
|
nuclear@0
|
70
|
nuclear@0
|
71 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
72 // Exporter worker function prototypes. Should not be necessary to #ifndef them, it's just a prototype
|
nuclear@0
|
73 void ExportSceneCollada(const char*,IOSystem*, const aiScene*);
|
nuclear@0
|
74 void ExportSceneObj(const char*,IOSystem*, const aiScene*);
|
nuclear@0
|
75 void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
|
nuclear@0
|
76 void ExportScenePly(const char*,IOSystem*, const aiScene*);
|
nuclear@0
|
77 void ExportScene3DS(const char*, IOSystem*, const aiScene*) {}
|
nuclear@0
|
78
|
nuclear@0
|
79 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
80 // global array of all export formats which Assimp supports in its current build
|
nuclear@0
|
81 Exporter::ExportFormatEntry gExporters[] =
|
nuclear@0
|
82 {
|
nuclear@0
|
83 #ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
|
nuclear@0
|
84 Exporter::ExportFormatEntry( "collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada),
|
nuclear@0
|
85 #endif
|
nuclear@0
|
86
|
nuclear@0
|
87 #ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
|
nuclear@0
|
88 Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj,
|
nuclear@0
|
89 aiProcess_GenNormals | aiProcess_PreTransformVertices),
|
nuclear@0
|
90 #endif
|
nuclear@0
|
91
|
nuclear@0
|
92 #ifndef ASSIMP_BUILD_NO_STL_EXPORTER
|
nuclear@0
|
93 Exporter::ExportFormatEntry( "stl", "Stereolithography", "stl" , &ExportSceneSTL,
|
nuclear@0
|
94 aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
|
nuclear@0
|
95 ),
|
nuclear@0
|
96 #endif
|
nuclear@0
|
97
|
nuclear@0
|
98 #ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
|
nuclear@0
|
99 Exporter::ExportFormatEntry( "ply", "Stanford Polygon Library", "ply" , &ExportScenePly,
|
nuclear@0
|
100 aiProcess_PreTransformVertices
|
nuclear@0
|
101 ),
|
nuclear@0
|
102 #endif
|
nuclear@0
|
103
|
nuclear@0
|
104 //#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
nuclear@0
|
105 // ExportFormatEntry( "3ds", "Autodesk 3DS (legacy format)", "3ds" , &ExportScene3DS),
|
nuclear@0
|
106 //#endif
|
nuclear@0
|
107 };
|
nuclear@0
|
108
|
nuclear@0
|
109 #define ASSIMP_NUM_EXPORTERS (sizeof(gExporters)/sizeof(gExporters[0]))
|
nuclear@0
|
110
|
nuclear@0
|
111
|
nuclear@0
|
112 class ExporterPimpl {
|
nuclear@0
|
113 public:
|
nuclear@0
|
114
|
nuclear@0
|
115 ExporterPimpl()
|
nuclear@0
|
116 : blob()
|
nuclear@0
|
117 , mIOSystem(new Assimp::DefaultIOSystem())
|
nuclear@0
|
118 , mIsDefaultIOHandler(true)
|
nuclear@0
|
119 {
|
nuclear@0
|
120 GetPostProcessingStepInstanceList(mPostProcessingSteps);
|
nuclear@0
|
121
|
nuclear@0
|
122 // grab all builtin exporters
|
nuclear@0
|
123 mExporters.resize(ASSIMP_NUM_EXPORTERS);
|
nuclear@0
|
124 std::copy(gExporters,gExporters+ASSIMP_NUM_EXPORTERS,mExporters.begin());
|
nuclear@0
|
125 }
|
nuclear@0
|
126
|
nuclear@0
|
127 ~ExporterPimpl()
|
nuclear@0
|
128 {
|
nuclear@0
|
129 delete blob;
|
nuclear@0
|
130
|
nuclear@0
|
131 // Delete all post-processing plug-ins
|
nuclear@0
|
132 for( unsigned int a = 0; a < mPostProcessingSteps.size(); a++) {
|
nuclear@0
|
133 delete mPostProcessingSteps[a];
|
nuclear@0
|
134 }
|
nuclear@0
|
135 }
|
nuclear@0
|
136
|
nuclear@0
|
137 public:
|
nuclear@0
|
138
|
nuclear@0
|
139 aiExportDataBlob* blob;
|
nuclear@0
|
140 boost::shared_ptr< Assimp::IOSystem > mIOSystem;
|
nuclear@0
|
141 bool mIsDefaultIOHandler;
|
nuclear@0
|
142
|
nuclear@0
|
143 /** Post processing steps we can apply at the imported data. */
|
nuclear@0
|
144 std::vector< BaseProcess* > mPostProcessingSteps;
|
nuclear@0
|
145
|
nuclear@0
|
146 /** Last fatal export error */
|
nuclear@0
|
147 std::string mError;
|
nuclear@0
|
148
|
nuclear@0
|
149 /** Exporters, this includes those registered using #Assimp::Exporter::RegisterExporter */
|
nuclear@0
|
150 std::vector<Exporter::ExportFormatEntry> mExporters;
|
nuclear@0
|
151 };
|
nuclear@0
|
152
|
nuclear@0
|
153
|
nuclear@0
|
154 } // end of namespace Assimp
|
nuclear@0
|
155
|
nuclear@0
|
156
|
nuclear@0
|
157
|
nuclear@0
|
158
|
nuclear@0
|
159
|
nuclear@0
|
160 using namespace Assimp;
|
nuclear@0
|
161
|
nuclear@0
|
162
|
nuclear@0
|
163 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
164 Exporter :: Exporter()
|
nuclear@0
|
165 : pimpl(new ExporterPimpl())
|
nuclear@0
|
166 {
|
nuclear@0
|
167 }
|
nuclear@0
|
168
|
nuclear@0
|
169
|
nuclear@0
|
170 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
171 Exporter :: ~Exporter()
|
nuclear@0
|
172 {
|
nuclear@0
|
173 FreeBlob();
|
nuclear@0
|
174 }
|
nuclear@0
|
175
|
nuclear@0
|
176
|
nuclear@0
|
177 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
178 void Exporter :: SetIOHandler( IOSystem* pIOHandler)
|
nuclear@0
|
179 {
|
nuclear@0
|
180 pimpl->mIsDefaultIOHandler = !pIOHandler;
|
nuclear@0
|
181 pimpl->mIOSystem.reset(pIOHandler);
|
nuclear@0
|
182 }
|
nuclear@0
|
183
|
nuclear@0
|
184
|
nuclear@0
|
185 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
186 IOSystem* Exporter :: GetIOHandler() const
|
nuclear@0
|
187 {
|
nuclear@0
|
188 return pimpl->mIOSystem.get();
|
nuclear@0
|
189 }
|
nuclear@0
|
190
|
nuclear@0
|
191
|
nuclear@0
|
192 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
193 bool Exporter :: IsDefaultIOHandler() const
|
nuclear@0
|
194 {
|
nuclear@0
|
195 return pimpl->mIsDefaultIOHandler;
|
nuclear@0
|
196 }
|
nuclear@0
|
197
|
nuclear@0
|
198
|
nuclear@0
|
199 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
200 const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing )
|
nuclear@0
|
201 {
|
nuclear@0
|
202 if (pimpl->blob) {
|
nuclear@0
|
203 delete pimpl->blob;
|
nuclear@0
|
204 pimpl->blob = NULL;
|
nuclear@0
|
205 }
|
nuclear@0
|
206
|
nuclear@0
|
207
|
nuclear@0
|
208 boost::shared_ptr<IOSystem> old = pimpl->mIOSystem;
|
nuclear@0
|
209
|
nuclear@0
|
210 BlobIOSystem* blobio = new BlobIOSystem();
|
nuclear@0
|
211 pimpl->mIOSystem = boost::shared_ptr<IOSystem>( blobio );
|
nuclear@0
|
212
|
nuclear@0
|
213 if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName())) {
|
nuclear@0
|
214 pimpl->mIOSystem = old;
|
nuclear@0
|
215 return NULL;
|
nuclear@0
|
216 }
|
nuclear@0
|
217
|
nuclear@0
|
218 pimpl->blob = blobio->GetBlobChain();
|
nuclear@0
|
219 pimpl->mIOSystem = old;
|
nuclear@0
|
220
|
nuclear@0
|
221 return pimpl->blob;
|
nuclear@0
|
222 }
|
nuclear@0
|
223
|
nuclear@0
|
224
|
nuclear@0
|
225 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
226 aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing )
|
nuclear@0
|
227 {
|
nuclear@0
|
228 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
229
|
nuclear@0
|
230 pimpl->mError = "";
|
nuclear@0
|
231 for (size_t i = 0; i < pimpl->mExporters.size(); ++i) {
|
nuclear@0
|
232 const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i];
|
nuclear@0
|
233 if (!strcmp(exp.mDescription.id,pFormatId)) {
|
nuclear@0
|
234
|
nuclear@0
|
235 try {
|
nuclear@0
|
236
|
nuclear@0
|
237 // Always create a full copy of the scene. We might optimize this one day,
|
nuclear@0
|
238 // but for now it is the most pragmatic way.
|
nuclear@0
|
239 aiScene* scenecopy_tmp;
|
nuclear@0
|
240 SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
|
nuclear@0
|
241
|
nuclear@0
|
242 std::auto_ptr<aiScene> scenecopy(scenecopy_tmp);
|
nuclear@0
|
243 const ScenePrivateData* const priv = ScenePriv(pScene);
|
nuclear@0
|
244
|
nuclear@0
|
245 // steps that are not idempotent, i.e. we might need to run them again, usually to get back to the
|
nuclear@0
|
246 // original state before the step was applied first. When checking which steps we don't need
|
nuclear@0
|
247 // to run, those are excluded.
|
nuclear@0
|
248 const unsigned int nonIdempotentSteps = aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_MakeLeftHanded;
|
nuclear@0
|
249
|
nuclear@0
|
250 // Erase all pp steps that were already applied to this scene
|
nuclear@0
|
251 unsigned int pp = (exp.mEnforcePP | pPreprocessing) & ~(priv
|
nuclear@0
|
252 ? (priv->mPPStepsApplied & ~nonIdempotentSteps)
|
nuclear@0
|
253 : 0u);
|
nuclear@0
|
254
|
nuclear@0
|
255 // If no extra postprocessing was specified, and we obtained this scene from an
|
nuclear@0
|
256 // Assimp importer, apply the reverse steps automatically.
|
nuclear@0
|
257 if (!pPreprocessing && priv) {
|
nuclear@0
|
258 pp |= (nonIdempotentSteps & priv->mPPStepsApplied);
|
nuclear@0
|
259 }
|
nuclear@0
|
260
|
nuclear@0
|
261 // If the input scene is not in verbose format, but there is at least postprocessing step that relies on it,
|
nuclear@0
|
262 // we need to run the MakeVerboseFormat step first.
|
nuclear@0
|
263 if (scenecopy->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
|
nuclear@0
|
264
|
nuclear@0
|
265 bool verbosify = false;
|
nuclear@0
|
266 for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
nuclear@0
|
267 BaseProcess* const p = pimpl->mPostProcessingSteps[a];
|
nuclear@0
|
268
|
nuclear@0
|
269 if (p->IsActive(pp) && p->RequireVerboseFormat()) {
|
nuclear@0
|
270 verbosify = true;
|
nuclear@0
|
271 break;
|
nuclear@0
|
272 }
|
nuclear@0
|
273 }
|
nuclear@0
|
274
|
nuclear@0
|
275 if (verbosify || (exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) {
|
nuclear@0
|
276 DefaultLogger::get()->debug("export: Scene data not in verbose format, applying MakeVerboseFormat step first");
|
nuclear@0
|
277
|
nuclear@0
|
278 MakeVerboseFormatProcess proc;
|
nuclear@0
|
279 proc.Execute(scenecopy.get());
|
nuclear@0
|
280 }
|
nuclear@0
|
281 }
|
nuclear@0
|
282
|
nuclear@0
|
283 if (pp) {
|
nuclear@0
|
284 // the three 'conversion' steps need to be executed first because all other steps rely on the standard data layout
|
nuclear@0
|
285 {
|
nuclear@0
|
286 FlipWindingOrderProcess step;
|
nuclear@0
|
287 if (step.IsActive(pp)) {
|
nuclear@0
|
288 step.Execute(scenecopy.get());
|
nuclear@0
|
289 }
|
nuclear@0
|
290 }
|
nuclear@0
|
291
|
nuclear@0
|
292 {
|
nuclear@0
|
293 FlipUVsProcess step;
|
nuclear@0
|
294 if (step.IsActive(pp)) {
|
nuclear@0
|
295 step.Execute(scenecopy.get());
|
nuclear@0
|
296 }
|
nuclear@0
|
297 }
|
nuclear@0
|
298
|
nuclear@0
|
299 {
|
nuclear@0
|
300 MakeLeftHandedProcess step;
|
nuclear@0
|
301 if (step.IsActive(pp)) {
|
nuclear@0
|
302 step.Execute(scenecopy.get());
|
nuclear@0
|
303 }
|
nuclear@0
|
304 }
|
nuclear@0
|
305
|
nuclear@0
|
306 // dispatch other processes
|
nuclear@0
|
307 for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
nuclear@0
|
308 BaseProcess* const p = pimpl->mPostProcessingSteps[a];
|
nuclear@0
|
309
|
nuclear@0
|
310 if (p->IsActive(pp)
|
nuclear@0
|
311 && !dynamic_cast<FlipUVsProcess*>(p)
|
nuclear@0
|
312 && !dynamic_cast<FlipWindingOrderProcess*>(p)
|
nuclear@0
|
313 && !dynamic_cast<MakeLeftHandedProcess*>(p)) {
|
nuclear@0
|
314
|
nuclear@0
|
315 p->Execute(scenecopy.get());
|
nuclear@0
|
316 }
|
nuclear@0
|
317 }
|
nuclear@0
|
318 ScenePrivateData* const privOut = ScenePriv(scenecopy.get());
|
nuclear@0
|
319 ai_assert(privOut);
|
nuclear@0
|
320
|
nuclear@0
|
321 privOut->mPPStepsApplied |= pp;
|
nuclear@0
|
322 }
|
nuclear@0
|
323
|
nuclear@0
|
324 exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get());
|
nuclear@0
|
325 }
|
nuclear@0
|
326 catch (DeadlyExportError& err) {
|
nuclear@0
|
327 pimpl->mError = err.what();
|
nuclear@0
|
328 return AI_FAILURE;
|
nuclear@0
|
329 }
|
nuclear@0
|
330 return AI_SUCCESS;
|
nuclear@0
|
331 }
|
nuclear@0
|
332 }
|
nuclear@0
|
333
|
nuclear@0
|
334 pimpl->mError = std::string("Found no exporter to handle this file format: ") + pFormatId;
|
nuclear@0
|
335 ASSIMP_END_EXCEPTION_REGION(aiReturn);
|
nuclear@0
|
336 return AI_FAILURE;
|
nuclear@0
|
337 }
|
nuclear@0
|
338
|
nuclear@0
|
339
|
nuclear@0
|
340 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
341 const char* Exporter :: GetErrorString() const
|
nuclear@0
|
342 {
|
nuclear@0
|
343 return pimpl->mError.c_str();
|
nuclear@0
|
344 }
|
nuclear@0
|
345
|
nuclear@0
|
346
|
nuclear@0
|
347 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
348 void Exporter :: FreeBlob( )
|
nuclear@0
|
349 {
|
nuclear@0
|
350 delete pimpl->blob;
|
nuclear@0
|
351 pimpl->blob = NULL;
|
nuclear@0
|
352
|
nuclear@0
|
353 pimpl->mError = "";
|
nuclear@0
|
354 }
|
nuclear@0
|
355
|
nuclear@0
|
356
|
nuclear@0
|
357 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
358 const aiExportDataBlob* Exporter :: GetBlob() const
|
nuclear@0
|
359 {
|
nuclear@0
|
360 return pimpl->blob;
|
nuclear@0
|
361 }
|
nuclear@0
|
362
|
nuclear@0
|
363
|
nuclear@0
|
364 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
365 const aiExportDataBlob* Exporter :: GetOrphanedBlob() const
|
nuclear@0
|
366 {
|
nuclear@0
|
367 const aiExportDataBlob* tmp = pimpl->blob;
|
nuclear@0
|
368 pimpl->blob = NULL;
|
nuclear@0
|
369 return tmp;
|
nuclear@0
|
370 }
|
nuclear@0
|
371
|
nuclear@0
|
372
|
nuclear@0
|
373 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
374 size_t Exporter :: GetExportFormatCount() const
|
nuclear@0
|
375 {
|
nuclear@0
|
376 return pimpl->mExporters.size();
|
nuclear@0
|
377 }
|
nuclear@0
|
378
|
nuclear@0
|
379 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
380 const aiExportFormatDesc* Exporter :: GetExportFormatDescription( size_t pIndex ) const
|
nuclear@0
|
381 {
|
nuclear@0
|
382 if (pIndex >= GetExportFormatCount()) {
|
nuclear@0
|
383 return NULL;
|
nuclear@0
|
384 }
|
nuclear@0
|
385
|
nuclear@0
|
386 return &pimpl->mExporters[pIndex].mDescription;
|
nuclear@0
|
387 }
|
nuclear@0
|
388
|
nuclear@0
|
389 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
390 aiReturn Exporter :: RegisterExporter(const ExportFormatEntry& desc)
|
nuclear@0
|
391 {
|
nuclear@0
|
392 BOOST_FOREACH(const ExportFormatEntry& e, pimpl->mExporters) {
|
nuclear@0
|
393 if (!strcmp(e.mDescription.id,desc.mDescription.id)) {
|
nuclear@0
|
394 return aiReturn_FAILURE;
|
nuclear@0
|
395 }
|
nuclear@0
|
396 }
|
nuclear@0
|
397
|
nuclear@0
|
398 pimpl->mExporters.push_back(desc);
|
nuclear@0
|
399 return aiReturn_SUCCESS;
|
nuclear@0
|
400 }
|
nuclear@0
|
401
|
nuclear@0
|
402
|
nuclear@0
|
403 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
404 void Exporter :: UnregisterExporter(const char* id)
|
nuclear@0
|
405 {
|
nuclear@0
|
406 for(std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin(); it != pimpl->mExporters.end(); ++it) {
|
nuclear@0
|
407 if (!strcmp((*it).mDescription.id,id)) {
|
nuclear@0
|
408 pimpl->mExporters.erase(it);
|
nuclear@0
|
409 break;
|
nuclear@0
|
410 }
|
nuclear@0
|
411 }
|
nuclear@0
|
412 }
|
nuclear@0
|
413
|
nuclear@0
|
414 #endif // !ASSIMP_BUILD_NO_EXPORT
|