Coverage Report

Created: 2025-08-28 06:38

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