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

« back to all changes in this revision

Viewing changes to COLLADAMaya/src/COLLADAMayaFileTranslator.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 "COLLADAMayaPrerequisites.h"
 
18
#include "COLLADAMayaPlatform.h"
 
19
#include "COLLADAMayaSyntax.h"
 
20
#include "COLLADAMayaVersionInfo.h"
 
21
#include "COLLADAMayaFileTranslator.h"
 
22
#include "COLLADAMayaDocumentExporter.h"
 
23
#include "COLLADAMayaExportOptions.h"
 
24
#include "COLLADAMayaSyntax.h"
 
25
 
 
26
#include "DAE2MADocumentImporter.h"
 
27
 
 
28
// TODO
 
29
#include "COLLADAMayaImportOptions.h"
 
30
 
 
31
#include "COLLADASWException.h"
 
32
 
 
33
#include <time.h>
 
34
 
 
35
#include <maya/MFnPlugin.h>
 
36
#include <maya/MItDependencyNodes.h>
 
37
#include <maya/MFnDependencyNode.h>
 
38
#include <maya/MGlobal.h>
 
39
#include <maya/MFileIO.h>
 
40
#if MAYA_API_VERSION >= 700
 
41
#include <maya/MHWShaderSwatchGenerator.h>
 
42
#endif
 
43
 
 
44
#include <fstream>
 
45
 
 
46
 
 
47
    // This is a nasty bit of hackyness for compilation under Windows. Under Win32 you need
 
48
    // to compile a dll project and change the extension from "dll" to "mll". One additional
 
49
    // thing we have to do is 'export' the initializePlugin and uninitializePlugin functions.
 
50
    // This basically means that when maya loads the dll, it can see the two Functions it needs.
 
51
    // If for some reason your plugin fails to load, it may be this thats causing the problems.
 
52
    // Under linux we simply need to compile it with the -shared flag.
 
53
    //
 
54
#ifdef WIN32
 
55
#define MLL_EXPORT __declspec(dllexport)
 
56
#else
 
57
#define MLL_EXPORT
 
58
#endif
 
59
 
 
60
    //
 
61
    // Description:
 
62
    //  this method is called when the plug-in is loaded into Maya.
 
63
    //  It registers all of the services that this plug-in provides with Maya.
 
64
    //
 
65
    // Arguments:
 
66
    //  obj - a handle to the plug-in object (use MFnPlugin to access it)
 
67
    //
 
68
    MStatus MLL_EXPORT initializePlugin ( MObject obj )
 
69
    {
 
70
        //_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); 
 
71
 
 
72
        MStatus status;
 
73
 
 
74
#ifdef _DEBUG
 
75
        // Activate the error logging
 
76
        MGlobal::startErrorLogging();
 
77
#endif
 
78
        // The default name of this file is OpenMayaErrorLog located in the 
 
79
        // current directory. This can be changed, however, by calling:
 
80
        //MGlobal::setErrorLogPathName("...");
 
81
  
 
82
        std::ostringstream stream; 
 
83
        stream << MAYA_API_VERSION;
 
84
 
 
85
        COLLADAMaya::String revision ( COLLADAMaya::TRANSLATOR_VERSION );
 
86
        revision += "." + COLLADAMaya::CURRENT_REVISION;
 
87
        MFnPlugin plugin ( obj, 
 
88
            COLLADAMaya::TRANSLATOR_VENDOR, 
 
89
            revision.c_str (), 
 
90
            stream.str ().c_str () );
 
91
 
 
92
        // --------------------------------------------------------------
 
93
        // Register the import and the export file translator plug-ins.
 
94
 
 
95
        // Export plug-in
 
96
        status = plugin.registerFileTranslator ( 
 
97
            COLLADAMaya::COLLADA_EXPORTER,
 
98
            "", // pathname of the icon used in file selection dialogs
 
99
            COLLADAMaya::FileTranslator::createExporter, // this class implements the new file type
 
100
            (char*)COLLADAMaya::MEL_EXPORT_OPTS, // name of a MEL script that will be used to display the contents of the options dialog during file open and save
 
101
            NULL ); // defaultOptionsString
 
102
        if ( !status )
 
103
        {
 
104
            status.perror ( "registerFileTranslator" );
 
105
            MGlobal::displayError ( MString ( "Unable to register OpenCOLLADA exporter: " ) + status );
 
106
            return status;
 
107
        }
 
108
 
 
109
        // Import plug-in
 
110
        status = plugin.registerFileTranslator ( 
 
111
            COLLADAMaya::COLLADA_IMPORTER,
 
112
            "",
 
113
            COLLADAMaya::FileTranslator::createImporter,
 
114
            (char*)COLLADAMaya::MEL_IMPORT_OPTS,
 
115
            NULL );
 
116
        if ( !status )
 
117
        {
 
118
            status.perror ( "registerFileTranslator" );
 
119
            MGlobal::displayError ( MString ( "Unable to register OpenCOLLADA importer: " ) + status );
 
120
        }
 
121
 
 
122
        // TODO
 
123
        MString UserClassify("shader/surface/utility");
 
124
 
 
125
#if MAYA_API_VERSION >= 700
 
126
        // Don't initialize swatches in batch mode
 
127
        if (MGlobal::mayaState() != MGlobal::kBatch)
 
128
        {
 
129
         const MString& swatchName = MHWShaderSwatchGenerator::initialize();
 
130
         UserClassify = MString("shader/surface/utility/:swatch/"+swatchName);
 
131
        }
 
132
#endif // MAYA_API_VERSION >= 700
 
133
 
 
134
        return status;
 
135
    }
 
136
 
 
137
 
 
138
    //
 
139
    // Description:
 
140
    //  this method is called when the plug-in is unloaded from Maya. It
 
141
    //  deregisters all of the services that it was providing.
 
142
    //
 
143
    // Arguments:
 
144
    //  obj - a handle to the plug-in object (use MFnPlugin to access it)
 
145
    //
 
146
    MStatus MLL_EXPORT uninitializePlugin ( MObject obj )
 
147
    {
 
148
        MStatus   status;
 
149
        MFnPlugin plugin ( obj );
 
150
 
 
151
        // Add plug-in feature de-registration here
 
152
 
 
153
        // Export plug-in
 
154
        status = plugin.deregisterFileTranslator ( COLLADAMaya::COLLADA_EXPORTER );
 
155
        if ( !status )
 
156
        {
 
157
            status.perror ( "deregisterFileTranslator" );
 
158
            MGlobal::displayError ( MString ( "Unable to unregister OpenCOLLADA exporter: " ) + status );
 
159
            return status;
 
160
        }
 
161
 
 
162
        // Import plug-in
 
163
        status = plugin.deregisterFileTranslator ( COLLADAMaya::COLLADA_IMPORTER );
 
164
        if ( !status )
 
165
        {
 
166
            status.perror ( "deregisterFileTranslator" );
 
167
            MGlobal::displayError ( MString ( "Unable to unregister OpenCOLLADA importer: " ) + status );
 
168
            return status;
 
169
        }
 
170
 
 
171
#if MAYA_API_VERSION >= 800
 
172
        // Disable the shared-reference node options.
 
173
        MGlobal::executeCommand ( "optionVar -iv \"referenceOptionsSharedReference\" 0;" );
 
174
        MGlobal::executeCommand ( "optionVar -iv \"referenceOptionsShareDisplayLayers\" 0;" );
 
175
        MGlobal::executeCommand ( "optionVar -iv \"referenceOptionsShareShaders\" 0;" );
 
176
#endif // MAYA 8.0 and 8.5
 
177
 
 
178
#ifdef _DEBUG
 
179
        // Stop the error logging
 
180
        MGlobal::stopErrorLogging();
 
181
#endif
 
182
 
 
183
        return status;
 
184
    }
 
185
 
 
186
 
 
187
namespace COLLADAMaya
 
188
{
 
189
 
 
190
    const String FileTranslator::ASCII_PATH_EXTENSION = ".ma";
 
191
    const String FileTranslator::ASCII_PATH_EXTENSION_DEBUG = ".opencollada.ma";
 
192
 
 
193
 
 
194
    /************************************************************************/
 
195
    /* Constructor and Destructor of the DaeFileTranslator class                                                                     */
 
196
    /************************************************************************/
 
197
    uint FileTranslator::readDepth = 0;
 
198
 
 
199
    FileTranslator::FileTranslator ( bool _isImporter )
 
200
    {
 
201
        isImporter = _isImporter;
 
202
    }
 
203
 
 
204
    FileTranslator::~FileTranslator()
 
205
    {
 
206
    }
 
207
 
 
208
 
 
209
 
 
210
    // Create a new instance of the translator
 
211
    // These two methods are registered to Maya's plugin module in the above initializePlugin function.
 
212
    void* FileTranslator::createExporter()
 
213
    {
 
214
        return new FileTranslator ( false );
 
215
    }
 
216
 
 
217
    void* FileTranslator::createImporter()
 
218
    {
 
219
        return new FileTranslator ( true );
 
220
    }
 
221
 
 
222
    /************************************************************************/
 
223
    /* The writer() method provides a message through the script editor and
 
224
    /* returns a status to indicate the results.
 
225
    /* In this example, only "export all" and "export selection" options are
 
226
    /* allowed when trying to save data. Other options will result in the
 
227
    /* display of a failure message through the script editor and returns a
 
228
    /* MS:kFailure, which indicates that the file type cannot be understood
 
229
    /* by the translator.
 
230
    /************************************************************************/
 
231
    MStatus FileTranslator::writer ( const MFileObject& file,
 
232
                                     const MString& options,
 
233
                                     MPxFileTranslator::FileAccessMode mode )
 
234
    {
 
235
        MStatus status = MStatus::kFailure;
 
236
 
 
237
        try
 
238
        {
 
239
            // Extract the filename
 
240
#if defined (OSMac_)
 
241
            char nameBuffer[MAXPATHLEN];
 
242
            strcpy ( nameBuffer, file.fullName().asChar() );
 
243
            const MString fileName ( nameBuffer );
 
244
#else
 
245
            const MString fileName = file.fullName();
 
246
#endif // OSMac
 
247
 
 
248
            // TODO Export the referenced files!
 
249
            // Maya forces the write of all the references, on export.
 
250
            // Intentionally skip known reference file paths.
 
251
            for ( MItDependencyNodes it ( MFn::kReference ); !it.isDone(); it.next() )
 
252
            {
 
253
                MObject refNode = it.item();
 
254
                MString refNodeName = MFnDependencyNode ( refNode ).name();
 
255
 
 
256
                MString refNodeFilename;
 
257
                MGlobal::executeCommand ( MString ( "reference -rfn \"" ) + refNodeName + MString ( "\" -q -filename" ),
 
258
                                          refNodeFilename );
 
259
 
 
260
                if ( refNodeFilename == fileName ) return MStatus::kSuccess;
 
261
 
 
262
                if ( ExportOptions::exportXRefs() )
 
263
                {
 
264
                    // TODO Open file export dialog ( !? HOW ?! ) to get a DAE filename 
 
265
                    // to export the referenced file.
 
266
                    
 
267
                }
 
268
            }
 
269
 
 
270
            // Parse the export options
 
271
            ExportOptions::set ( options );
 
272
 
 
273
            // Check, if we should just export the selected Objects
 
274
            exportSelection = mode == MPxFileTranslator::kExportActiveAccessMode;
 
275
 
 
276
            // Do the actual export now
 
277
            status = exportIntoFile ( fileName, exportSelection );
 
278
        }
 
279
        catch ( COLLADASW::StreamWriterException* swException  )
 
280
        {
 
281
            String message = "StreamWriterException: " + swException->getMessage();
 
282
            MGlobal::displayError ( message.c_str() );
 
283
        }
 
284
        catch ( ... )
 
285
        {
 
286
            MGlobal::displayError ( "ColladaMaya has thrown an exception!" );
 
287
        }
 
288
 
 
289
        return status;
 
290
    }
 
291
 
 
292
 
 
293
    /************************************************************************/
 
294
    /* Parses the Maya DAG/DG graphs and writes out a COLLADA document                                                                     */
 
295
    /************************************************************************/
 
296
    MStatus FileTranslator::exportIntoFile ( const MString& filename, const bool selectionOnly )
 
297
    {
 
298
        MStatus status = MS::kSuccess;
 
299
 
 
300
        /** To get the time */
 
301
        clock_t startClock, endClock;
 
302
        startClock = clock();
 
303
 
 
304
        // Actually export the document
 
305
        DocumentExporter documentExporter ( NativeString(filename.asChar()) );
 
306
        documentExporter.exportCurrentScene ( selectionOnly );
 
307
 
 
308
        // Display some closing information.
 
309
        endClock = clock();
 
310
        std::ostringstream stream; 
 
311
        stream << "Time to export into file \"" << filename.asChar() << "\": " << endClock - startClock << std::endl;
 
312
        MString message( stream.str().c_str() );
 
313
        std::cerr << message.asChar() << std::endl;
 
314
 
 
315
        return status;
 
316
    }
 
317
 
 
318
 
 
319
    /************************************************************************/
 
320
    /* The reader() method reads each line of the file and returns a
 
321
    /* MS::kFailure if it cannot be opened by the translator. If a file type
 
322
    /* cannot be recognized by the translator, the method creates a new
 
323
    /* object via MEL to support the data in that file.
 
324
    /************************************************************************/
 
325
    MStatus FileTranslator::reader ( const MFileObject& file,
 
326
                                     const MString& options,
 
327
                                     MPxFileTranslator::FileAccessMode mode )
 
328
    {
 
329
        MStatus status ( MS::kSuccess );
 
330
 
 
331
        try
 
332
        {
 
333
#if MAYA_API_VERSION >= 800
 
334
 
 
335
            if ( mode == MPxFileTranslator::kReferenceAccessMode )
 
336
            {
 
337
                int optionValue;
 
338
                MGlobal::executeCommand ( "optionVar -q \"referenceOptionsSharedReference\";", optionValue );
 
339
 
 
340
                if ( optionValue != 0 )
 
341
                {
 
342
#ifdef WIN32
 
343
                    MessageBox ( NULL, "Maya may now hang. Do disable the reference option named: \"Shared Reference Nodes\".", "POSSIBLE HANG", MB_OK );
 
344
#endif
 
345
                }
 
346
            }
 
347
 
 
348
#endif // Maya 8.0 and 8.5
 
349
 
 
350
 
 
351
#if defined (OSMac_)
 
352
            char nameBuffer[MAXPATHLEN];
 
353
            strcpy ( nameBuffer, file.fullName().asChar() );
 
354
            const MString filename ( nameBuffer );
 
355
#else
 
356
            const MString filename = file.fullName();
 
357
#endif  // OSMac
 
358
 
 
359
            // Process the import options
 
360
            ImportOptions::set ( options, mode );
 
361
            if (ImportOptions::hasError()) status = MStatus::kFailure;
 
362
 
 
363
            // Import the COLLADA DAE file
 
364
                        status = importFromFile ( filename.asChar() );
 
365
        }
 
366
        catch ( COLLADABU::Exception* exception  )
 
367
        {
 
368
            MGlobal::displayError ( exception->getMessage().c_str() );
 
369
        }
 
370
        catch ( ... )
 
371
        {
 
372
            MGlobal::displayError ( "ColladaMaya has thrown an exception!" );
 
373
        }
 
374
 
 
375
        return status;
 
376
    }
 
377
 
 
378
    // ------------------------------
 
379
    MStatus FileTranslator::importFromFile ( const String& importFileName )
 
380
    {
 
381
        MStatus status = MS::kSuccess;
 
382
 
 
383
        // Get the time 
 
384
        clock_t startClock, endClock;
 
385
        startClock = clock();
 
386
 
 
387
        // TODO Ask the user where to save the maya file.
 
388
//         MString command = "fileBrowserDialog -m 0 -fc \"importFromFile\" -ft \"mayaAscii\" -fl \"*.ma\" -an \"Save_import_as\" -om \"SaveAs\"";
 
389
//         MString mayaAsciiFileNameM = MGlobal::executeCommandStringResult ( command );
 
390
//         String mayaAsciiFileName ( mayaAsciiFileNameM.asChar () );
 
391
//         MGlobal::displayInfo ( mayaAsciiFileName.c_str() );
 
392
 
 
393
        // Set the imported file name and path.
 
394
//        COLLADABU::URI mayaAsciiFileURI ( mayaAsciiFileName );
 
395
        COLLADABU::URI mayaAsciiFileURI ( importFileName );
 
396
#ifdef NDEBUG
 
397
        mayaAsciiFileURI.setPathExtension ( ASCII_PATH_EXTENSION );
 
398
#else
 
399
        mayaAsciiFileURI.setPathExtension ( ASCII_PATH_EXTENSION_DEBUG );
 
400
#endif
 
401
        String mayaAsciiFileName = mayaAsciiFileURI.getURIString ();
 
402
                const char* cpMayaAsciiFileName = mayaAsciiFileName.c_str();
 
403
 
 
404
        // Get the current maya version
 
405
        String mayaVersion ( MGlobal::mayaVersion ().asChar () );
 
406
 
 
407
        // We have to change the name on 64 bit machines. 
 
408
        // For example from "2008 x64" to "2008" or from "2008 Extension 2" to "2008".
 
409
        std::vector<String> words;
 
410
        String separator (" ");
 
411
        COLLADABU::Utils::split ( mayaVersion, separator, words );
 
412
        if ( words.size () > 1 ) 
 
413
        {
 
414
            mayaVersion = words[0];
 
415
        }
 
416
 
 
417
        // Actually import the document
 
418
                {
 
419
                        DAE2MA::DocumentImporter documentImporter ( importFileName, mayaAsciiFileURI.getURIString (), mayaVersion.c_str () );
 
420
                        documentImporter.importCurrentScene ();
 
421
                }
 
422
 
 
423
        // Display some closing information.
 
424
        endClock = clock();
 
425
 
 
426
        std::ostringstream stream; 
 
427
        stream << "Time to import into file \"" << mayaAsciiFileName << "\": " << endClock - startClock << std::endl;
 
428
        String message( stream.str() );
 
429
        std::cerr << message << std::endl;
 
430
 
 
431
        // TODO Open the maya ascii file in the maya instance
 
432
                MFileIO::importFile ( cpMayaAsciiFileName );
 
433
                //MFileIO::open ( mayaAsciiFileName.c_str (), "mayaAscii", true ); 
 
434
 
 
435
                //         mayaAsciiFileURI.setPathExtension ( ".opencollada.mb" );
 
436
                //         mayaFileName = mayaAsciiFileURI.getURIString ();
 
437
                //         MFileIO::saveAs ( mayaFileName.c_str () );
 
438
                //         MGlobal::displayInfo ( "File saved as maya binary: " );
 
439
                //         MGlobal::displayInfo ( mayaFileName.c_str () 
 
440
        
 
441
        return status;
 
442
    }
 
443
 
 
444
 
 
445
    /************************************************************************/
 
446
    /* Check the given file to see if it is COLLADA data
 
447
    /************************************************************************/
 
448
    MPxFileTranslator::MFileKind FileTranslator::identifyFile ( 
 
449
        const MFileObject &fileObject,
 
450
        const char *buffer,
 
451
        short size )
 
452
    const
 
453
    {
 
454
        // Just check for the proper extension for now
 
455
        MFileKind rval = kNotMyFileType;
 
456
        int extLocation = fileObject.name().rindex ( '.' );
 
457
 
 
458
        if ( extLocation > 0 )
 
459
        {
 
460
            MString ext = fileObject.name().substring ( extLocation + 1, fileObject.name().length()-1 ).toLowerCase();
 
461
            if ( ext == "dae" || ext == "xml" )
 
462
            {
 
463
                rval = kIsMyFileType;
 
464
            }
 
465
        }
 
466
 
 
467
        return rval;
 
468
    }
 
469
 
 
470
    // Return the default extension for COLLADA files
 
471
    MString FileTranslator::defaultExtension() const
 
472
    {
 
473
        return "dae";
 
474
    }
 
475
 
 
476
        // ------------------------------
 
477
    MString FileTranslator::filter() const
 
478
    {
 
479
        return "*.dae;*.xml";
 
480
    }
 
481
 
 
482
 
 
483
}// namespace COLLADA
 
 
b'\\ No newline at end of file'