~ubuntu-branches/ubuntu/wily/opencollada/wily-proposed

« back to all changes in this revision

Viewing changes to COLLADAMaya/src/COLLADAMayaDocumentExporter.cpp

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2015-05-14 17:23:27 UTC
  • Revision ID: package-import@ubuntu.com-20150514172327-f862u8envms01fra
Tags: upstream-0.1.0~20140703.ddf8f47+dfsg1
ImportĀ upstreamĀ versionĀ 0.1.0~20140703.ddf8f47+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (c) 2008-2009 NetAllied Systems GmbH
 
3
 
 
4
        This file is part of COLLADAMaya.
 
5
 
 
6
    Portions of the code are:
 
7
    Copyright (c) 2005-2007 Feeling Software Inc.
 
8
    Copyright (c) 2005-2007 Sony Computer Entertainment America
 
9
    Copyright (c) 2004-2005 Alias Systems Corp.
 
10
 
 
11
    Licensed under the MIT Open Source License,
 
12
    for details please see LICENSE file or the website
 
13
    http://www.opensource.org/licenses/mit-license.php
 
14
*/
 
15
 
 
16
#include "COLLADAMayaStableHeaders.h"
 
17
#include "COLLADAMayaDocumentExporter.h"
 
18
#include "COLLADAMayaSceneGraph.h"
 
19
#include "COLLADAMayaGeometryExporter.h"
 
20
#include "COLLADAMayaVisualSceneExporter.h"
 
21
#include "COLLADAMayaEffectExporter.h"
 
22
#include "COLLADAMayaImageExporter.h"
 
23
#include "COLLADAMayaMaterialExporter.h"
 
24
#include "COLLADAMayaAnimationExporter.h"
 
25
#include "COLLADAMayaAnimationClipExporter.h"
 
26
#include "COLLADAMayaAnimationSampleCache.h"
 
27
#include "COLLADAMayaControllerExporter.h"
 
28
#include "COLLADAMayaLightExporter.h"
 
29
#include "COLLADAMayaCameraExporter.h"
 
30
#include "COLLADAMayaDagHelper.h"
 
31
#include "COLLADAMayaShaderHelper.h"
 
32
#include "COLLADAMayaConversion.h"
 
33
#include "COLLADAMayaExportOptions.h"
 
34
#include "COLLADAMayaSyntax.h"
 
35
#include "COLLADAMayaReferenceManager.h"
 
36
 
 
37
#include "COLLADASWAsset.h"
 
38
#include "COLLADASWScene.h"
 
39
#include "COLLADASWConstants.h"
 
40
 
 
41
#include <maya/MFileIO.h>
 
42
#include <maya/MFnAttribute.h>
 
43
 
 
44
 
 
45
namespace COLLADAMaya
 
46
{
 
47
 
 
48
    //---------------------------------------------------------------
 
49
    DocumentExporter::DocumentExporter ( const NativeString& fileName )
 
50
        : mStreamWriter ( fileName, ExportOptions::doublePrecision () )
 
51
            , mFileName ( fileName )
 
52
            , mSceneGraph ( NULL )
 
53
            , mIsImport ( true )
 
54
            , mAnimationCache ( NULL )
 
55
            , mMaterialExporter ( NULL )
 
56
            , mEffectExporter ( NULL )
 
57
            , mImageExporter ( NULL )
 
58
            , mGeometryExporter ( NULL )
 
59
            , mVisualSceneExporter ( NULL )
 
60
            , mAnimationExporter ( NULL )
 
61
            , mAnimationClipExporter ( NULL )
 
62
            , mControllerExporter ( NULL )
 
63
            , mLightExporter ( NULL )
 
64
            , mCameraExporter ( NULL )
 
65
            , mSceneId ( "MayaScene" )
 
66
            , mDigitTolerance (FLOAT_TOLERANCE)
 
67
    {
 
68
        if ( ExportOptions::doublePrecision () )
 
69
        {
 
70
            mDigitTolerance = DOUBLE_TOLERANCE;
 
71
        }
 
72
    }
 
73
 
 
74
    //---------------------------------------------------------------
 
75
    DocumentExporter::~DocumentExporter()
 
76
    {
 
77
        releaseLibraries(); // The libraries should already have been released
 
78
    }
 
79
 
 
80
    //---------------------------------------------------------------
 
81
    // Create the parsing libraries: we want access to the libraries only during import/export time.
 
82
    void DocumentExporter::createLibraries()
 
83
    {
 
84
        releaseLibraries();
 
85
        
 
86
        // Get the sceneID (assign a name to the scene)
 
87
        MString sceneName;
 
88
        MGlobal::executeCommand ( MString ( "file -q -ns" ), sceneName );
 
89
        if ( sceneName.length() != 0 ) mSceneId = sceneName.asChar();
 
90
 
 
91
        // Initialize the reference manager
 
92
        ReferenceManager::getInstance()->initialize ();
 
93
 
 
94
        // Create the cache for the animations
 
95
        mAnimationCache = new AnimationSampleCache();
 
96
 
 
97
        // Create the basic elements
 
98
        mSceneGraph = new SceneGraph ( this );
 
99
        mMaterialExporter = new MaterialExporter ( &mStreamWriter, this );
 
100
        mEffectExporter = new EffectExporter ( &mStreamWriter, this );
 
101
        mImageExporter = new ImageExporter ( &mStreamWriter );
 
102
        mGeometryExporter = new GeometryExporter ( &mStreamWriter, this );
 
103
        mVisualSceneExporter = new VisualSceneExporter ( &mStreamWriter, this, mSceneId );
 
104
        mAnimationExporter = new AnimationExporter ( &mStreamWriter, this );
 
105
        mAnimationClipExporter = new AnimationClipExporter ( &mStreamWriter );
 
106
        mControllerExporter = new ControllerExporter ( &mStreamWriter, this );
 
107
        mLightExporter = new LightExporter ( &mStreamWriter, this );
 
108
        mCameraExporter = new CameraExporter ( &mStreamWriter, this );
 
109
    }
 
110
 
 
111
    //---------------------------------------------------------------
 
112
    void DocumentExporter::releaseLibraries()
 
113
    {
 
114
        delete mAnimationCache;
 
115
        delete mSceneGraph;
 
116
        delete mMaterialExporter;
 
117
        delete mEffectExporter;
 
118
        delete mImageExporter;
 
119
        delete mGeometryExporter;
 
120
        delete mVisualSceneExporter;
 
121
        delete mAnimationExporter;
 
122
        delete mAnimationClipExporter;
 
123
        delete mControllerExporter;
 
124
        delete mLightExporter;
 
125
        delete mCameraExporter;
 
126
    }
 
127
 
 
128
 
 
129
    //---------------------------------------------------------------
 
130
    void DocumentExporter::exportCurrentScene ( bool selectionOnly )
 
131
    {
 
132
        mIsImport = false;
 
133
 
 
134
        // Create the import/export library helpers.
 
135
        createLibraries();
 
136
 
 
137
        mStreamWriter.startDocument();
 
138
 
 
139
        // Build the scene graph
 
140
        if ( mSceneGraph->create ( selectionOnly ) )
 
141
        {
 
142
            // Export the asset of the document.
 
143
            exportAsset();
 
144
 
 
145
            if ( !ExportOptions::exportMaterialsOnly () )
 
146
            {
 
147
                // Start by caching the expressions that will be sampled
 
148
                mSceneGraph->sampleAnimationExpressions();
 
149
 
 
150
                // Export the lights.
 
151
                mLightExporter->exportLights();
 
152
 
 
153
                // Export the cameras.
 
154
                mCameraExporter->exportCameras();
 
155
 
 
156
                // Export the material URLs and get the material list
 
157
                MaterialMap* materialMap = mMaterialExporter->exportMaterials();
 
158
 
 
159
                // Export the effects (materials)
 
160
                const ImageMap* imageMap = mEffectExporter->exportEffects ( materialMap );
 
161
 
 
162
                // Export the images
 
163
                mImageExporter->exportImages ( imageMap );
 
164
 
 
165
                // Export the controllers. Must be done before the geometries, to decide, which
 
166
                // geometries have to be exported (for example, if the controller need an invisible 
 
167
                // geometry, we also have to export it).
 
168
                mControllerExporter->exportControllers();
 
169
 
 
170
                // Export the geometries
 
171
                mGeometryExporter->exportGeometries();
 
172
 
 
173
                // Export the visual scene
 
174
                bool visualSceneExported = mVisualSceneExporter->exportVisualScenes();
 
175
 
 
176
                // Export the animations
 
177
                const AnimationClipList* animationClips = mAnimationExporter->exportAnimations();
 
178
 
 
179
                // Export the animation clips
 
180
                mAnimationClipExporter->exportAnimationClips ( animationClips );
 
181
 
 
182
                // Export the scene
 
183
                if ( visualSceneExported ) exportScene();
 
184
            }
 
185
            else
 
186
            {
 
187
                // Export the material URLs and get the material list
 
188
                MaterialMap* materialMap = mMaterialExporter->exportMaterials();
 
189
 
 
190
                // Export the effects (materials)
 
191
                const ImageMap* imageMap = mEffectExporter->exportEffects ( materialMap );
 
192
 
 
193
                // Export the images
 
194
                mImageExporter->exportImages ( imageMap );
 
195
            }
 
196
        }
 
197
 
 
198
        mStreamWriter.endDocument();
 
199
    }
 
200
 
 
201
    //---------------------------------------------------------------
 
202
    void DocumentExporter::exportAsset()
 
203
    {
 
204
        COLLADASW::Asset asset ( &mStreamWriter );
 
205
 
 
206
        // Add contributor information
 
207
        // Set the author
 
208
        char* userName = getenv ( USERNAME );
 
209
 
 
210
        if ( !userName || *userName == 0 ) 
 
211
                {
 
212
                        userName = getenv ( USER );
 
213
                }
 
214
        if ( userName && *userName != 0 ) 
 
215
                {
 
216
                        asset.getContributor().mAuthor = NativeString( userName ).toUtf8String();
 
217
                }
 
218
 
 
219
        // Source is the scene we have exported from
 
220
        String currentScene = MFileIO::currentFile().asChar();
 
221
        if ( currentScene.size() > 0 )
 
222
        {
 
223
            COLLADASW::URI sourceFileUri ( COLLADASW::URI::nativePathToUri ( currentScene ) );
 
224
            if ( sourceFileUri.getScheme ().empty () )
 
225
                sourceFileUri.setScheme ( COLLADASW::URI::SCHEME_FILE );
 
226
            asset.getContributor().mSourceData = sourceFileUri.getURIString();
 
227
        }
 
228
 
 
229
        asset.getContributor().mAuthoringTool = AUTHORING_TOOL_NAME + MGlobal::mayaVersion().asChar();
 
230
 
 
231
        // comments
 
232
        MString optstr = MString ( "\n\t\t\tColladaMaya export options: " )
 
233
            + "\n\t\t\tbakeTransforms=" + ExportOptions::bakeTransforms() 
 
234
            + ";relativePaths=" + ExportOptions::relativePaths() 
 
235
            + ";copyTextures=" + ExportOptions::copyTextures() 
 
236
            + ";exportTriangles=" + ExportOptions::exportTriangles() 
 
237
            + ";exportCgfxFileReferences=" + ExportOptions::exportCgfxFileReferences() 
 
238
            + ";\n\t\t\tisSampling=" + ExportOptions::isSampling() 
 
239
            + ";curveConstrainSampling=" + ExportOptions::curveConstrainSampling()
 
240
            + ";removeStaticCurves=" + ExportOptions::removeStaticCurves() 
 
241
            + ";exportPolygonMeshes=" + ExportOptions::exportPolygonMeshes() 
 
242
            + ";exportLights=" + ExportOptions::exportLights() 
 
243
            + ";\n\t\t\texportCameras=" + ExportOptions::exportCameras() 
 
244
            + ";exportJointsAndSkin=" + ExportOptions::exportJointsAndSkin() 
 
245
            + ";exportAnimations=" + ExportOptions::exportAnimations()
 
246
            + ";exportInvisibleNodes=" + ExportOptions::exportInvisibleNodes()
 
247
            + ";exportDefaultCameras=" + ExportOptions::exportDefaultCameras()
 
248
            + ";\n\t\t\texportTexCoords=" + ExportOptions::exportTexCoords()
 
249
            + ";exportNormals=" + ExportOptions::exportNormals() 
 
250
            + ";exportNormalsPerVertex=" + ExportOptions::exportNormalsPerVertex() 
 
251
            + ";exportVertexColors=" + ExportOptions::exportVertexColors()
 
252
            + ";exportVertexColorsPerVertex=" + ExportOptions::exportVertexColorsPerVertex()
 
253
            + ";\n\t\t\texportTexTangents=" + ExportOptions::exportTexTangents() 
 
254
            + ";exportTangents=" + ExportOptions::exportTangents() 
 
255
            + ";exportReferencedMaterials=" + ExportOptions::exportReferencedMaterials() 
 
256
            + ";exportMaterialsOnly=" + ExportOptions::exportMaterialsOnly() 
 
257
            + ";\n\t\t\texportXRefs=" + ExportOptions::exportXRefs() 
 
258
            + ";dereferenceXRefs=" + ExportOptions::dereferenceXRefs() 
 
259
            + ";exportCameraAsLookat=" + ExportOptions::exportCameraAsLookat() 
 
260
            + ";cameraXFov=" + ExportOptions::cameraXFov() 
 
261
            + ";cameraYFov=" + ExportOptions::cameraYFov() 
 
262
            + ";doublePrecision=" + ExportOptions::doublePrecision () + "\n\t\t";
 
263
        asset.getContributor().mComments = optstr.asChar();
 
264
 
 
265
        // Up axis
 
266
        if ( MGlobal::isYAxisUp() ) 
 
267
            asset.setUpAxisType ( COLLADASW::Asset::Y_UP );
 
268
        else if ( MGlobal::isZAxisUp() ) 
 
269
            asset.setUpAxisType ( COLLADASW::Asset::Z_UP );
 
270
 
 
271
        // Retrieve the linear unit name
 
272
        MString mayaLinearUnitName;
 
273
        MGlobal::executeCommand ( "currentUnit -q -linear -fullName;", mayaLinearUnitName );
 
274
        String linearUnitName = mayaLinearUnitName.asChar();
 
275
 
 
276
        // Get the UI unit type (internal units are centimeter, collada want
 
277
        // a number relative to meters).
 
278
        // All transform components with units will be in maya's internal units
 
279
        // (radians for rotations and centimeters for translations).
 
280
        MDistance testDistance ( 1.0f, MDistance::uiUnit() );
 
281
 
 
282
        // Get the conversion factor relative to meters for the collada document.
 
283
        // For example, 1.0 for the name "meter"; 1000 for the name "kilometer";
 
284
        // 0.3048 for the name "foot".
 
285
        double colladaConversionFactor = ( float ) testDistance.as ( MDistance::kMeters );
 
286
        float colladaUnitFactor = float ( 1.0 / colladaConversionFactor );
 
287
        asset.setUnit ( linearUnitName, colladaConversionFactor );
 
288
 
 
289
        // Asset heraus schreiben
 
290
        asset.add();
 
291
    }
 
292
 
 
293
    //---------------------------------------------------------------
 
294
    void DocumentExporter::exportScene()
 
295
    {
 
296
        COLLADASW::Scene scene ( &mStreamWriter, COLLADASW::URI ( EMPTY_STRING, VISUAL_SCENE_NODE_ID ) );
 
297
        scene.add();
 
298
    }
 
299
 
 
300
    //---------------------------------------------------------------
 
301
    void DocumentExporter::endExport()
 
302
    {
 
303
        // Write out the scene parameters
 
304
        //  CDOC->SetStartTime((float) AnimationHelper::AnimationStartTime().as(MTime::kSeconds));
 
305
        //  CDOC->SetEndTime((float) AnimationHelper::AnimationEndTime().as(MTime::kSeconds));
 
306
    }
 
307
 
 
308
    //---------------------------
 
309
    String DocumentExporter::mayaNameToColladaName ( const MString& str, bool removeNamespace )
 
310
    {
 
311
        // Replace characters that are supported in Maya,
 
312
        // but not supported in collada names
 
313
        if ( str == 0 ) return EMPTY_STRING;
 
314
 
 
315
        // NathanM: Strip off namespace prefixes
 
316
        // TODO: Should really be exposed as an option in the Exporter
 
317
        MString mayaName;
 
318
        if ( removeNamespace )
 
319
        {
 
320
            int prefixIndex = str.rindex ( ':' );
 
321
            mayaName = ( prefixIndex < 0 ) ? str : str.substring ( prefixIndex + 1, str.length() );
 
322
        }
 
323
        else mayaName = str;
 
324
 
 
325
        const char* c = mayaName.asChar();
 
326
        uint length = mayaName.length();
 
327
        char* buffer = new char[length+1];
 
328
 
 
329
        // Replace offending characters by some that are supported within xml:
 
330
        // ':', '|' are replaced by '_'.
 
331
        // Ideally, these should be encoded as '%3A' for ':', etc. and decoded at import time.
 
332
        //
 
333
        for ( uint i = 0; i < length; ++i )
 
334
        {
 
335
            char d = c[i];
 
336
 
 
337
            if ( d == '|' || d == ':' || d == '/' || d == '\\' || d == '(' || d == ')' || d == '[' || d == ']' )
 
338
                d = '_';
 
339
 
 
340
            buffer[i] = d;
 
341
        }
 
342
        buffer[length] = '\0';
 
343
 
 
344
        MString mayaReturnString ( buffer );
 
345
        delete buffer;
 
346
 
 
347
        return COLLADABU::Utils::checkNCName( mayaReturnString.asChar() );
 
348
    }
 
349
 
 
350
    //---------------------------
 
351
    String DocumentExporter::dagPathToColladaId ( const MDagPath& dagPath )
 
352
    {
 
353
        // Make an unique COLLADA Id from a dagPath.
 
354
        // We are free to use anything we want for Ids. For now use
 
355
        // a honking unique name for readability - but in future we
 
356
        // could just use an incrementing integer
 
357
        return mayaNameToColladaName ( dagPath.partialPathName(), false );
 
358
    }
 
359
 
 
360
    //---------------------------
 
361
    String DocumentExporter::dagPathToColladaName ( const MDagPath& dagPath )
 
362
    {
 
363
        // Get a COLLADA suitable node name from a DAG path
 
364
        // For import/export symmetry, this should be exactly the
 
365
        // Maya node name. If we include any more of the path, we'll
 
366
        // get viral node names after repeated import/export.
 
367
        MFnDependencyNode node ( dagPath.node() );
 
368
        return mayaNameToColladaName ( node.name(), true );
 
369
    }
 
370
 
 
371
    //---------------------------
 
372
    SceneGraph* DocumentExporter::getSceneGraph()
 
373
    {
 
374
        return mSceneGraph;
 
375
    }
 
376
 
 
377
    //---------------------------
 
378
    const SceneGraph* DocumentExporter::getSceneGraph() const
 
379
    {
 
380
        return mSceneGraph;
 
381
    }
 
382
 
 
383
    //---------------------------
 
384
    const String& DocumentExporter::getFilename() const
 
385
    {
 
386
        return mFileName;
 
387
    }
 
388
 
 
389
    //---------------------------
 
390
    COLLADASW::StreamWriter* DocumentExporter::getStreamWriter()
 
391
    {
 
392
        return &mStreamWriter;
 
393
    }
 
394
 
 
395
    //---------------------------
 
396
    AnimationSampleCache* DocumentExporter::getAnimationCache()
 
397
    {
 
398
        return mAnimationCache;
 
399
    }
 
400
 
 
401
    //---------------------------
 
402
    MaterialExporter* DocumentExporter::getMaterialExporter()
 
403
    {
 
404
        return mMaterialExporter;
 
405
    }
 
406
 
 
407
    //---------------------------
 
408
    EffectExporter* DocumentExporter::getEffectExporter()
 
409
    {
 
410
        return mEffectExporter;
 
411
    }
 
412
 
 
413
    //---------------------------
 
414
    ImageExporter* DocumentExporter::getImageExporter()
 
415
    {
 
416
        return mImageExporter;
 
417
    }
 
418
 
 
419
    //---------------------------
 
420
    GeometryExporter* DocumentExporter::getGeometryExporter()
 
421
    {
 
422
        return mGeometryExporter;
 
423
    }
 
424
 
 
425
    //---------------------------
 
426
    VisualSceneExporter* DocumentExporter::getVisualSceneExporter()
 
427
    {
 
428
        return mVisualSceneExporter;
 
429
    }
 
430
 
 
431
    //---------------------------
 
432
    AnimationExporter* DocumentExporter::getAnimationExporter()
 
433
    {
 
434
        return mAnimationExporter;
 
435
    }
 
436
 
 
437
    //---------------------------
 
438
    AnimationClipExporter* DocumentExporter::getAnimationClipExporter()
 
439
    {
 
440
        return mAnimationClipExporter;
 
441
    }
 
442
 
 
443
    //---------------------------
 
444
    ControllerExporter* DocumentExporter::getControllerExporter()
 
445
    {
 
446
        return mControllerExporter;
 
447
    }
 
448
 
 
449
    //---------------------------
 
450
    LightExporter* DocumentExporter::getLightExporter()
 
451
    {
 
452
        return mLightExporter;
 
453
    }
 
454
 
 
455
    //---------------------------
 
456
    CameraExporter* DocumentExporter::getCameraExporter()
 
457
    {
 
458
        return mCameraExporter;
 
459
    }
 
460
 
 
461
    //---------------------------
 
462
    const String& DocumentExporter::getSceneID()
 
463
    {
 
464
        return mSceneId;
 
465
    }
 
466
 
 
467
    //---------------------------
 
468
    const bool DocumentExporter::getExportSelectedOnly () const
 
469
    {
 
470
        return getSceneGraph ()->getExportSelectedOnly ();
 
471
    }
 
472
 
 
473
//     // --------------------------------------
 
474
//     void DocumentExporter::exportExtraData ( 
 
475
//         const MObject& node, 
 
476
//         const char* key, 
 
477
//         const char* secondKey /*= 0*/, 
 
478
//         COLLADASW::BaseExtraTechnique* baseExtraTechnique /*= 0*/ )
 
479
//     {
 
480
//         MStatus status;
 
481
//         MFnDependencyNode dependencyNode ( node, &status );
 
482
//         if ( status != MStatus::kSuccess ) return;
 
483
// 
 
484
//         MPlug colladaPlug = dependencyNode.findPlug ( COLLADAFW::ExtraKeys::BASEKEY, &status );
 
485
//         if ( status == MStatus::kSuccess ) 
 
486
//         {
 
487
//             if ( !colladaPlug.isCompound () ) 
 
488
//             {
 
489
//                 std::cerr << "There exist another attribute with the name \"COLLADA\". No extra tag preservation possible!" << endl;
 
490
//                 return;
 
491
//             }
 
492
// 
 
493
//             // Flag, if the extra source was opened.
 
494
//             bool closeExtraSource = false;
 
495
//             COLLADASW::Extra extraSource ( &mStreamWriter );
 
496
// 
 
497
//             size_t numChildren = colladaPlug.numChildren ();
 
498
//             for ( uint i=0; i<numChildren; ++i )
 
499
//             {
 
500
//                 MPlug childPlug = colladaPlug.child ( i, &status );
 
501
//                 if ( status != MStatus::kSuccess ) continue;
 
502
// 
 
503
//                 // Get the collada attribute.
 
504
//                 MFnAttribute pathAttribute ( childPlug.attribute() );
 
505
//                 String pathAttributeName = pathAttribute.name().asChar ();
 
506
//                 if ( !COLLADABU::Utils::equals ( pathAttributeName, key ) ) continue;
 
507
// 
 
508
//                 if ( exportExtraData ( childPlug, pathAttributeName, baseExtraTechnique, extraSource, secondKey ) )
 
509
//                     closeExtraSource = true;
 
510
//             }
 
511
// 
 
512
//             // Close the extra source tag, if it is open.
 
513
//             if ( closeExtraSource ) 
 
514
//                 extraSource.closeExtra();
 
515
//         }
 
516
//     }
 
517
// 
 
518
//     // --------------------------------------
 
519
//     bool DocumentExporter::exportExtraData ( 
 
520
//         const MPlug& childPlug, 
 
521
//         const String& parentAttributeName, 
 
522
//         COLLADASW::BaseExtraTechnique* baseExtraTechnique, 
 
523
//         COLLADASW::Extra& extraSource, 
 
524
//         const char* secondKey /*= 0*/ )
 
525
//     {
 
526
//         MStatus status;
 
527
//         bool closeExtraSource = false; 
 
528
// 
 
529
//         // Get the profile name of the child attribute.
 
530
//         size_t numExtraChildren = childPlug.numChildren ();
 
531
//         for ( uint i=0; i<numExtraChildren; ++i )
 
532
//         {
 
533
//             // Get the extra plug.
 
534
//             MPlug extraPlug = childPlug.child ( i, &status );
 
535
//             if ( status != MStatus::kSuccess ) continue;
 
536
//             MFnAttribute extraAttribute ( extraPlug.attribute() );
 
537
// 
 
538
//             // Check if we have an extra tag of an physical index element (primitive element, 
 
539
//             // surface, sampler2d or texture). In this case, the current attribute is a compound
 
540
//             // attribute and holds for every index a child element.
 
541
//             if ( extraPlug.isCompound () )
 
542
//             {
 
543
//                 // TODO Recursive call for the child plugs.
 
544
//                 String attributeName = extraAttribute.name ().asChar ();
 
545
//                 if ( !COLLADABU::Utils::equals ( attributeName, secondKey ) ) continue;
 
546
//                 if ( exportExtraData ( extraPlug, attributeName, baseExtraTechnique, extraSource, secondKey ) )
 
547
//                     closeExtraSource = true;
 
548
//                 continue;
 
549
//             }
 
550
// 
 
551
//             if ( secondKey )
 
552
//             {
 
553
//                 // Get the physical index of the element.
 
554
//                 String physicalIndexStr = parentAttributeName.substr ( parentAttributeName.length ()-1 );
 
555
//                 unsigned int physicalIndex = atoi ( physicalIndexStr.c_str () );
 
556
//             }
 
557
// 
 
558
//             // The attribute with the collada profile name.
 
559
//             // The profile name has always the path attribute name in front.
 
560
//             String profileName = extraAttribute.name ().asChar ();
 
561
//             profileName = profileName.substr ( parentAttributeName.length () + 1 );
 
562
// 
 
563
//             // The attribute value.
 
564
//             MString mAttributeValue;
 
565
//             status = extraPlug.getValue ( mAttributeValue );
 
566
//             if ( status != MStatus::kSuccess || mAttributeValue == 0 ) continue;
 
567
// 
 
568
//             // Convert the attributeValue back to collada.
 
569
//             String source = mAttributeValue.asChar ();
 
570
//             COLLADABU::Utils::stringFindAndReplace ( source, "\\\"", "\"" );
 
571
//             String encodedSource = COLLADABU::URI::uriDecode ( source );
 
572
// 
 
573
//             // If a baseExtraTechnique element is given, use this to write the extra data.
 
574
//             if ( baseExtraTechnique )
 
575
//                 baseExtraTechnique->addExtraTechniqueTextblock ( profileName, encodedSource );
 
576
//             else
 
577
//             {
 
578
//                 // Open the extra source tag, if neccessary.
 
579
//                 if ( !closeExtraSource ) 
 
580
//                 {
 
581
//                     extraSource.openExtra();
 
582
//                     closeExtraSource = true;
 
583
//                 }
 
584
//                 // Create the extra attribute.
 
585
//                 COLLADASW::Technique techniqueSource ( &mStreamWriter );
 
586
//                 techniqueSource.openTechnique ( profileName );
 
587
//                 techniqueSource.addValue ( encodedSource );
 
588
//                 techniqueSource.closeTechnique();
 
589
//             }
 
590
//         }
 
591
// 
 
592
//         return closeExtraSource;
 
593
//     }
 
594
}