Coverage Report

Created: 2024-08-02 07:04

/src/assimp/code/AssetLib/X/XFileExporter.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
Open Asset Import Library (assimp)
3
----------------------------------------------------------------------
4
5
Copyright (c) 2006-2024, 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
@author: Richard Steffen, 2014
41
----------------------------------------------------------------------
42
*/
43
44
45
#ifndef ASSIMP_BUILD_NO_EXPORT
46
#ifndef ASSIMP_BUILD_NO_X_EXPORTER
47
48
#include "AssetLib/X/XFileExporter.h"
49
#include "PostProcessing/ConvertToLHProcess.h"
50
51
#include <assimp/Bitmap.h>
52
#include <assimp/BaseImporter.h>
53
#include <assimp/fast_atof.h>
54
#include <assimp/SceneCombiner.h>
55
#include <assimp/DefaultIOSystem.h>
56
#include <assimp/Exceptional.h>
57
#include <assimp/IOSystem.hpp>
58
#include <assimp/scene.h>
59
#include <assimp/light.h>
60
61
#include <ctime>
62
#include <set>
63
#include <memory>
64
65
using namespace Assimp;
66
67
namespace Assimp
68
{
69
70
// ------------------------------------------------------------------------------------------------
71
// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
72
void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
73
0
{
74
0
    std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
75
0
    std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));
76
77
    // create/copy Properties
78
0
    ExportProperties props(*pProperties);
79
80
    // set standard properties if not set
81
0
    if (!props.HasPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT)) props.SetPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT, false);
82
83
    // invoke the exporter
84
0
    XFileExporter iDoTheExportThing( pScene, pIOSystem, path, file, &props);
85
86
0
    if (iDoTheExportThing.mOutput.fail()) {
87
0
        throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
88
0
    }
89
90
    // we're still here - export successfully completed. Write result to the given IOSYstem
91
0
    std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
92
0
    if (outfile == nullptr) {
93
0
        throw DeadlyExportError("could not open output .x file: " + std::string(pFile));
94
0
    }
95
96
    // XXX maybe use a small wrapper around IOStream that behaves like std::stringstream in order to avoid the extra copy.
97
0
    outfile->Write( iDoTheExportThing.mOutput.str().c_str(), static_cast<size_t>(iDoTheExportThing.mOutput.tellp()),1);
98
0
}
99
100
} // end of namespace Assimp
101
102
103
// ------------------------------------------------------------------------------------------------
104
// Constructor for a specific scene to export
105
XFileExporter::XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file, const ExportProperties* pProperties)
106
        : mProperties(pProperties),
107
        mIOSystem(pIOSystem),
108
        mPath(path),
109
        mFile(file),
110
        mScene(pScene),
111
        mSceneOwned(false),
112
        endstr("\n")
113
0
{
114
    // make sure that all formatting happens using the standard, C locale and not the user's current locale
115
0
    mOutput.imbue( std::locale("C") );
116
0
    mOutput.precision(ASSIMP_AI_REAL_TEXT_PRECISION);
117
118
    // start writing
119
0
    WriteFile();
120
0
}
121
122
// ------------------------------------------------------------------------------------------------
123
// Destructor
124
XFileExporter::~XFileExporter()
125
0
{
126
0
    if(mSceneOwned) {
127
0
        delete mScene;
128
0
    }
129
0
}
130
131
// ------------------------------------------------------------------------------------------------
132
// Starts writing the contents
133
void XFileExporter::WriteFile()
134
0
{
135
    // note, that all realnumber values must be comma separated in x files
136
0
    mOutput.setf(std::ios::fixed);
137
0
    mOutput.precision(ASSIMP_AI_REAL_TEXT_PRECISION); // precision for ai_real
138
139
    // entry of writing the file
140
0
    WriteHeader();
141
142
0
    mOutput << startstr << "Frame DXCC_ROOT {" << endstr;
143
0
    PushTag();
144
145
0
    aiMatrix4x4 I; // identity
146
0
    WriteFrameTransform(I);
147
148
0
    WriteNode(mScene->mRootNode);
149
0
    PopTag();
150
151
0
    mOutput << startstr << "}" << endstr;
152
153
0
}
154
155
// ------------------------------------------------------------------------------------------------
156
// Writes the asset header
157
void XFileExporter::WriteHeader()
158
0
{
159
0
    if (mProperties->GetPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT) == true)
160
0
        mOutput << startstr << "xof 0303txt 0064" << endstr;
161
0
    else
162
0
        mOutput << startstr << "xof 0303txt 0032" << endstr;
163
0
    mOutput << endstr;
164
0
    mOutput << startstr << "template Frame {" << endstr;
165
0
    PushTag();
166
0
    mOutput << startstr << "<3d82ab46-62da-11cf-ab39-0020af71e433>" << endstr;
167
0
    mOutput << startstr << "[...]" << endstr;
168
0
    PopTag();
169
0
    mOutput << startstr << "}" << endstr;
170
0
    mOutput << endstr;
171
0
    mOutput << startstr << "template Matrix4x4 {" << endstr;
172
0
    PushTag();
173
0
    mOutput << startstr << "<f6f23f45-7686-11cf-8f52-0040333594a3>" << endstr;
174
0
    mOutput << startstr << "array FLOAT matrix[16];" << endstr;
175
0
    PopTag();
176
0
    mOutput << startstr << "}" << endstr;
177
0
    mOutput << endstr;
178
0
    mOutput << startstr << "template FrameTransformMatrix {" << endstr;
179
0
    PushTag();
180
0
    mOutput << startstr << "<f6f23f41-7686-11cf-8f52-0040333594a3>" << endstr;
181
0
    mOutput << startstr << "Matrix4x4 frameMatrix;" << endstr;
182
0
    PopTag();
183
0
    mOutput << startstr << "}" << endstr;
184
0
    mOutput << endstr;
185
0
    mOutput << startstr << "template Vector {" << endstr;
186
0
    PushTag();
187
0
    mOutput << startstr << "<3d82ab5e-62da-11cf-ab39-0020af71e433>" << endstr;
188
0
    mOutput << startstr << "FLOAT x;" << endstr;
189
0
    mOutput << startstr << "FLOAT y;" << endstr;
190
0
    mOutput << startstr << "FLOAT z;" << endstr;
191
0
    PopTag();
192
0
    mOutput << startstr << "}" << endstr;
193
0
    mOutput << endstr;
194
0
    mOutput << startstr << "template MeshFace {" << endstr;
195
0
    PushTag();
196
0
    mOutput << startstr << "<3d82ab5f-62da-11cf-ab39-0020af71e433>" << endstr;
197
0
    mOutput << startstr << "DWORD nFaceVertexIndices;" << endstr;
198
0
    mOutput << startstr << "array DWORD faceVertexIndices[nFaceVertexIndices];" << endstr;
199
0
    PopTag();
200
0
    mOutput << startstr << "}" << endstr;
201
0
    mOutput << endstr;
202
0
    mOutput << startstr << "template Mesh {" << endstr;
203
0
    PushTag();
204
0
    mOutput << startstr << "<3d82ab44-62da-11cf-ab39-0020af71e433>" << endstr;
205
0
    mOutput << startstr << "DWORD nVertices;" << endstr;
206
0
    mOutput << startstr << "array Vector vertices[nVertices];" << endstr;
207
0
    mOutput << startstr << "DWORD nFaces;" << endstr;
208
0
    mOutput << startstr << "array MeshFace faces[nFaces];" << endstr;
209
0
    mOutput << startstr << "[...]" << endstr;
210
0
    PopTag();
211
0
    mOutput << startstr << "}" << endstr;
212
0
    mOutput << endstr;
213
0
    mOutput << startstr << "template MeshNormals {" << endstr;
214
0
    PushTag();
215
0
    mOutput << startstr << "<f6f23f43-7686-11cf-8f52-0040333594a3>" << endstr;
216
0
    mOutput << startstr << "DWORD nNormals;" << endstr;
217
0
    mOutput << startstr << "array Vector normals[nNormals];" << endstr;
218
0
    mOutput << startstr << "DWORD nFaceNormals;" << endstr;
219
0
    mOutput << startstr << "array MeshFace faceNormals[nFaceNormals];" << endstr;
220
0
    PopTag();
221
0
    mOutput << startstr << "}" << endstr;
222
0
    mOutput << endstr;
223
0
    mOutput << startstr << "template Coords2d {" << endstr;
224
0
    PushTag();
225
0
    mOutput << startstr << "<f6f23f44-7686-11cf-8f52-0040333594a3>" << endstr;
226
0
    mOutput << startstr << "FLOAT u;" << endstr;
227
0
    mOutput << startstr << "FLOAT v;" << endstr;
228
0
    PopTag();
229
0
    mOutput << startstr << "}" << endstr;
230
0
    mOutput << endstr;
231
0
    mOutput << startstr << "template MeshTextureCoords {" << endstr;
232
0
    PushTag();
233
0
    mOutput << startstr << "<f6f23f40-7686-11cf-8f52-0040333594a3>" << endstr;
234
0
    mOutput << startstr << "DWORD nTextureCoords;" << endstr;
235
0
    mOutput << startstr << "array Coords2d textureCoords[nTextureCoords];" << endstr;
236
0
    PopTag();
237
0
    mOutput << startstr << "}" << endstr;
238
0
    mOutput << endstr;
239
0
    mOutput << startstr << "template ColorRGBA {" << endstr;
240
0
    PushTag();
241
0
    mOutput << startstr << "<35ff44e0-6c7c-11cf-8f52-0040333594a3>" << endstr;
242
0
    mOutput << startstr << "FLOAT red;" << endstr;
243
0
    mOutput << startstr << "FLOAT green;" << endstr;
244
0
    mOutput << startstr << "FLOAT blue;" << endstr;
245
0
    mOutput << startstr << "FLOAT alpha;" << endstr;
246
0
    PopTag();
247
0
    mOutput << startstr << "}" << endstr;
248
0
    mOutput << endstr;
249
0
    mOutput << startstr << "template IndexedColor {" << endstr;
250
0
    PushTag();
251
0
    mOutput << startstr << "<1630b820-7842-11cf-8f52-0040333594a3>" << endstr;
252
0
    mOutput << startstr << "DWORD index;" << endstr;
253
0
    mOutput << startstr << "ColorRGBA indexColor;" << endstr;
254
0
    PopTag();
255
0
    mOutput << startstr << "}" << endstr;
256
0
    mOutput << endstr;
257
0
    mOutput << startstr << "template MeshVertexColors {" << endstr;
258
0
    PushTag();
259
0
    mOutput << startstr << "<1630b821-7842-11cf-8f52-0040333594a3>" << endstr;
260
0
    mOutput << startstr << "DWORD nVertexColors;" << endstr;
261
0
    mOutput << startstr << "array IndexedColor vertexColors[nVertexColors];" << endstr;
262
0
    PopTag();
263
0
    mOutput << startstr << "}" << endstr;
264
0
    mOutput << endstr;
265
0
    mOutput << startstr << "template VertexElement {" << endstr;
266
0
    PushTag();
267
0
    mOutput << startstr << "<f752461c-1e23-48f6-b9f8-8350850f336f>" << endstr;
268
0
    mOutput << startstr << "DWORD Type;" << endstr;
269
0
    mOutput << startstr << "DWORD Method;" << endstr;
270
0
    mOutput << startstr << "DWORD Usage;" << endstr;
271
0
    mOutput << startstr << "DWORD UsageIndex;" << endstr;
272
0
    PopTag();
273
0
    mOutput << startstr << "}" << endstr;
274
0
    mOutput << endstr;
275
0
    mOutput << startstr << "template DeclData {" << endstr;
276
0
    PushTag();
277
0
    mOutput << startstr << "<bf22e553-292c-4781-9fea-62bd554bdd93>" << endstr;
278
0
    mOutput << startstr << "DWORD nElements;" << endstr;
279
0
    mOutput << startstr << "array VertexElement Elements[nElements];" << endstr;
280
0
    mOutput << startstr << "DWORD nDWords;" << endstr;
281
0
    mOutput << startstr << "array DWORD data[nDWords];" << endstr;
282
0
    PopTag();
283
0
    mOutput << startstr << "}" << endstr;
284
0
    mOutput << endstr;
285
0
}
286
287
288
// Writes the material setup
289
void XFileExporter::WriteFrameTransform(aiMatrix4x4& m)
290
0
{
291
0
    mOutput << startstr << "FrameTransformMatrix {" << endstr << " ";
292
0
    PushTag();
293
0
    mOutput << startstr << m.a1 << ", " << m.b1 << ", " << m.c1 << ", " << m.d1 << "," << endstr;
294
0
    mOutput << startstr << m.a2 << ", " << m.b2 << ", " << m.c2 << ", " << m.d2 << "," << endstr;
295
0
    mOutput << startstr << m.a3 << ", " << m.b3 << ", " << m.c3 << ", " << m.d3 << "," << endstr;
296
0
    mOutput << startstr << m.a4 << ", " << m.b4 << ", " << m.c4 << ", " << m.d4 << ";;" << endstr;
297
0
    PopTag();
298
0
    mOutput << startstr << "}" << endstr << endstr;
299
0
}
300
301
302
// ------------------------------------------------------------------------------------------------
303
// Recursively writes the given node
304
void XFileExporter::WriteNode( aiNode* pNode)
305
0
{
306
0
    if (pNode->mName.length==0)
307
0
    {
308
0
        std::stringstream ss;
309
0
        ss << "Node_" << pNode;
310
0
        pNode->mName.Set(ss.str());
311
0
    }
312
0
    mOutput << startstr << "Frame " << toXFileString(pNode->mName) << " {" << endstr;
313
314
0
    PushTag();
315
316
0
    aiMatrix4x4 m = pNode->mTransformation;
317
318
0
    WriteFrameTransform(m);
319
320
0
    for (size_t i = 0; i < pNode->mNumMeshes; ++i)
321
0
        WriteMesh(mScene->mMeshes[pNode->mMeshes[i]]);
322
323
    // recursive call the Nodes
324
0
    for (size_t i = 0; i < pNode->mNumChildren; ++i)
325
0
        WriteNode(pNode->mChildren[i]);
326
327
0
    PopTag();
328
329
0
    mOutput << startstr << "}" << endstr << endstr;
330
0
}
331
332
void XFileExporter::WriteMesh(aiMesh* mesh)
333
0
{
334
0
    mOutput << startstr << "Mesh " << toXFileString(mesh->mName) << "_mShape" << " {" << endstr;
335
336
0
    PushTag();
337
338
    // write all the vertices
339
0
    mOutput << startstr << mesh->mNumVertices << ";" << endstr;
340
0
    for (size_t a = 0; a < mesh->mNumVertices; a++)
341
0
    {
342
0
        aiVector3D &v = mesh->mVertices[a];
343
0
        mOutput << startstr << v[0] << ";"<< v[1] << ";" << v[2] << ";";
344
0
        if (a < mesh->mNumVertices - 1)
345
0
            mOutput << "," << endstr;
346
0
        else
347
0
            mOutput << ";" << endstr;
348
0
    }
349
350
    // write all the faces
351
0
    mOutput << startstr << mesh->mNumFaces << ";" << endstr;
352
0
    for( size_t a = 0; a < mesh->mNumFaces; ++a )
353
0
    {
354
0
        const aiFace& face = mesh->mFaces[a];
355
0
        mOutput << startstr << face.mNumIndices << ";";
356
        // must be counter clockwise triangle
357
        //for(int b = face.mNumIndices - 1; b >= 0 ; --b)
358
0
        for(size_t b = 0; b < face.mNumIndices ; ++b)
359
0
        {
360
0
            mOutput << face.mIndices[b];
361
            //if (b > 0)
362
0
            if (b<face.mNumIndices-1)
363
0
                mOutput << ",";
364
0
            else
365
0
                mOutput << ";";
366
0
        }
367
368
0
        if (a < mesh->mNumFaces - 1)
369
0
            mOutput << "," << endstr;
370
0
        else
371
0
            mOutput << ";" << endstr;
372
0
    }
373
374
0
    mOutput << endstr;
375
376
0
    if (mesh->HasTextureCoords(0))
377
0
    {
378
0
        const aiMaterial* mat = mScene->mMaterials[mesh->mMaterialIndex];
379
0
        aiString relpath;
380
0
        mat->Get(_AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0, relpath);
381
382
0
        mOutput << startstr << "MeshMaterialList {" << endstr;
383
0
        PushTag();
384
0
        mOutput << startstr << "1;" << endstr; // number of materials
385
0
        mOutput << startstr << mesh->mNumFaces << ";" << endstr; // number of faces
386
0
        mOutput << startstr;
387
0
        for( size_t a = 0; a < mesh->mNumFaces; ++a )
388
0
        {
389
0
            mOutput << "0"; // the material index
390
0
            if (a < mesh->mNumFaces - 1)
391
0
                mOutput << ", ";
392
0
            else
393
0
                mOutput << ";" << endstr;
394
0
        }
395
0
        mOutput << startstr << "Material {" << endstr;
396
0
        PushTag();
397
0
        mOutput << startstr << "1.0; 1.0; 1.0; 1.000000;;" << endstr;
398
0
        mOutput << startstr << "1.000000;" << endstr; // power
399
0
        mOutput << startstr << "0.000000; 0.000000; 0.000000;;" << endstr; // specularity
400
0
        mOutput << startstr << "0.000000; 0.000000; 0.000000;;" << endstr; // emission
401
0
        mOutput << startstr << "TextureFilename { \"";
402
403
0
        writePath(relpath);
404
405
0
        mOutput << "\"; }" << endstr;
406
0
        PopTag();
407
0
        mOutput << startstr << "}" << endstr;
408
0
        PopTag();
409
0
        mOutput << startstr << "}" << endstr;
410
0
    }
411
412
    // write normals (every vertex has one)
413
0
    if (mesh->HasNormals())
414
0
    {
415
0
        mOutput << endstr << startstr << "MeshNormals {" << endstr;
416
0
        mOutput << startstr << mesh->mNumVertices << ";" << endstr;
417
0
        for (size_t a = 0; a < mesh->mNumVertices; a++)
418
0
        {
419
0
            aiVector3D &v = mesh->mNormals[a];
420
            // because we have a LHS and also changed wth winding, we need to invert the normals again
421
0
            mOutput << startstr << -v[0] << ";"<< -v[1] << ";" << -v[2] << ";";
422
0
            if (a < mesh->mNumVertices - 1)
423
0
                mOutput << "," << endstr;
424
0
            else
425
0
                mOutput << ";" << endstr;
426
0
        }
427
428
0
        mOutput << startstr << mesh->mNumFaces << ";" << endstr;
429
0
        for (size_t a = 0; a < mesh->mNumFaces; a++)
430
0
        {
431
0
            const aiFace& face = mesh->mFaces[a];
432
0
            mOutput << startstr << face.mNumIndices << ";";
433
434
            //for(int b = face.mNumIndices-1; b >= 0 ; --b)
435
0
            for(size_t b = 0; b < face.mNumIndices ; ++b)
436
0
            {
437
0
                mOutput << face.mIndices[b];
438
                //if (b > 0)
439
0
                if (b<face.mNumIndices-1)
440
0
                    mOutput << ",";
441
0
                else
442
0
                    mOutput << ";";
443
0
            }
444
445
0
            if (a < mesh->mNumFaces-1)
446
0
                mOutput << "," << endstr;
447
0
            else
448
0
                mOutput << ";" << endstr;
449
0
        }
450
0
        mOutput << startstr << "}" << endstr;
451
0
    }
452
453
    // write texture UVs if available
454
0
    if (mesh->HasTextureCoords(0))
455
0
    {
456
0
        mOutput << endstr << startstr << "MeshTextureCoords {"  << endstr;
457
0
        mOutput << startstr << mesh->mNumVertices << ";" << endstr;
458
0
        for (size_t a = 0; a < mesh->mNumVertices; a++)
459
        //for (int a = (int)mesh->mNumVertices-1; a >=0 ; a--)
460
0
        {
461
0
            aiVector3D& uv = mesh->mTextureCoords[0][a]; // uv of first uv layer for the vertex
462
0
            mOutput << startstr << uv.x << ";" << uv.y;
463
0
            if (a < mesh->mNumVertices-1)
464
            //if (a >0 )
465
0
                mOutput << ";," << endstr;
466
0
            else
467
0
                mOutput << ";;" << endstr;
468
0
        }
469
0
        mOutput << startstr << "}" << endstr;
470
0
    }
471
472
    // write color channel if available
473
0
    if (mesh->HasVertexColors(0))
474
0
    {
475
0
        mOutput << endstr << startstr << "MeshVertexColors {"  << endstr;
476
0
        mOutput << startstr << mesh->mNumVertices << ";" << endstr;
477
0
        for (size_t a = 0; a < mesh->mNumVertices; a++)
478
0
        {
479
0
            aiColor4D& mColors = mesh->mColors[0][a]; // color of first vertex color set for the vertex
480
0
            mOutput << startstr << a << ";" << mColors.r << ";" << mColors.g << ";" << mColors.b << ";" << mColors.a << ";;";
481
0
            if (a < mesh->mNumVertices-1)
482
0
                mOutput << "," << endstr;
483
0
            else
484
0
                mOutput << ";" << endstr;
485
0
        }
486
0
        mOutput << startstr << "}" << endstr;
487
0
    }
488
    /*
489
    else
490
    {
491
        mOutput << endstr << startstr << "MeshVertexColors {"  << endstr;
492
        mOutput << startstr << mesh->mNumVertices << ";" << endstr;
493
        for (size_t a = 0; a < mesh->mNumVertices; a++)
494
        {
495
            aiColor4D* mColors = mesh->mColors[a];
496
            mOutput << startstr << a << ";0.500000;0.000000;0.000000;0.500000;;";
497
            if (a < mesh->mNumVertices-1)
498
                mOutput << "," << endstr;
499
            else
500
                mOutput << ";" << endstr;
501
        }
502
        mOutput << startstr << "}" << endstr;
503
    }
504
    */
505
0
    PopTag();
506
0
    mOutput << startstr << "}" << endstr << endstr;
507
508
0
}
509
510
std::string XFileExporter::toXFileString(aiString &name)
511
0
{
512
0
    std::string pref = ""; // node name prefix to prevent unexpected start of string
513
0
    std::string str = pref + std::string(name.C_Str());
514
0
    for (int i=0; i < (int) str.length(); ++i)
515
0
    {
516
0
        if ((str[i] >= '0' && str[i] <= '9') || // 0-9
517
0
            (str[i] >= 'A' && str[i] <= 'Z') || // A-Z
518
0
            (str[i] >= 'a' && str[i] <= 'z')) // a-z
519
0
            continue;
520
0
        str[i] = '_';
521
0
    }
522
0
    return str;
523
0
}
524
525
void XFileExporter::writePath(const aiString &path)
526
0
{
527
0
    std::string str = std::string(path.C_Str());
528
0
    BaseImporter::ConvertUTF8toISO8859_1(str);
529
530
0
    while( str.find( "\\\\") != std::string::npos)
531
0
        str.replace( str.find( "\\\\"), 2, "\\");
532
533
0
    while (str.find('\\') != std::string::npos)
534
0
        str.replace(str.find('\\'), 1, "/");
535
536
0
    mOutput << str;
537
538
0
}
539
540
#endif
541
#endif