polyX3DExporter/polyExporter.cpp
 
 
 
polyX3DExporter/polyExporter.cpp
//-
// ==========================================================================
// Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk
// license agreement provided at the time of installation or download,
// or which otherwise accompanies this software in either electronic
// or hard copy form.
// ==========================================================================
//+

//
//

//polyExporter.cpp
#include <maya/MStatus.h>
#include <maya/MString.h>
#include <maya/MObject.h>
#include <maya/MGlobal.h>
#include <maya/MItDag.h>
#include <maya/MDagPath.h>
#include <maya/MItSelectionList.h>
#include <maya/MPlug.h>

#include <maya/MIOStream.h>
#include <maya/MFStream.h>

#include "polyExporter.h"
#include "polyWriter.h"


polyExporter::polyExporter()
{
//Summary:  constructor method; does nothing
}


polyExporter::~polyExporter() 
{ 
//Summary:  destructor method; does nothing
//
}


MStatus polyExporter::writer(const MFileObject& file,
                                                         const MString& /*options*/,
                                                         MPxFileTranslator::FileAccessMode mode) 
//Summary:      saves a file of a type supported by this translator by traversing
//                      the all or selected objects (depending on mode) in the current
//                      Maya scene, and writing a representation to the given file
//Args   :      file - object containing the pathname of the file to be written to
//                      options - a string representation of any file options 
//                      mode - the method used to write the file - export, or export active
//                                 are valid values; method will fail for any other values 
//Returns:      MStatus::kSuccess if the export was successful;
//                      MStatus::kFailure otherwise
{
        #if defined (OSMac_)
                char nameBuffer[MAXPATHLEN];
                strcpy (nameBuffer, file.fullName().asChar());
                const MString fileName(nameBuffer);
        #else
                const MString fileName = file.fullName();
        #endif

        ofstream newFile(fileName.asChar(), ios::out);
        if (!newFile) {
                MGlobal::displayError(fileName + ": could not be opened for reading");
                return MS::kFailure;
        }
        newFile.setf(ios::unitbuf);

        writeHeader(newFile);

        //check which objects are to be exported, and invoke the corresponding
        //methods; only 'export all' and 'export selection' are allowed
        //
        if (MPxFileTranslator::kExportAccessMode == mode) {
                if (MStatus::kFailure == exportAll(newFile)) {
                        return MStatus::kFailure;
                }
        } else if (MPxFileTranslator::kExportActiveAccessMode == mode) {
                if (MStatus::kFailure == exportSelection(newFile)) {
                        return MStatus::kFailure;
                }
        } else {
                return MStatus::kFailure;
        }

        writeFooter(newFile);
        newFile.flush();
        newFile.close();

        MGlobal::displayInfo("Export to " + fileName + " successful!");
        return MS::kSuccess;
}


bool polyExporter::haveWriteMethod() const 
//Summary:      returns true if the writer() method of the class is implemented;
//                      false otherwise
//Returns:  true since writer() is implemented in this class
{
        return true;
}


bool polyExporter::haveReadMethod() const 
//Summary:      returns true if the reader() method of the class is implemented;
//                      false otherwise
//Returns:  false since reader() is not implemented in this class
{
        return false;
}


bool polyExporter::canBeOpened() const 
//Summary:      returns true if the translator can open and import files;
//                      false if it can only import files
//Returns:  true
{
        return true;
}


MStatus polyExporter::exportAll(ostream& os) 
//Summary:      finds and outputs all polygonal meshes in the DAG
//Args   :      os - an output stream to write to
//Returns:  MStatus::kSuccess if the method succeeds
//                      MStatus::kFailure if the method fails
{
        MStatus status;

        //create an iterator for only the mesh components of the DAG
        //
        MItDag itDag(MItDag::kDepthFirst, MFn::kMesh, &status);

        if (MStatus::kFailure == status) {
                MGlobal::displayError("MItDag::MItDag");
                return MStatus::kFailure;
        }

        for(;!itDag.isDone();itDag.next()) {
                //get the current DAG path
                //
                MDagPath dagPath;
                if (MStatus::kFailure == itDag.getPath(dagPath)) {
                        MGlobal::displayError("MDagPath::getPath");
                        return MStatus::kFailure;
                }

                MFnDagNode visTester(dagPath);

                //if this node is visible, then process the poly mesh it represents
                //
                if(isVisible(visTester, status) && MStatus::kSuccess == status) {
                        if (MStatus::kFailure == processPolyMesh(dagPath, os)) {
                                return MStatus::kFailure;
                        }
                }
        }
        return MStatus::kSuccess;
}


MStatus polyExporter::exportSelection(ostream& os) 
//Summary:      finds and outputs all selected polygonal meshes in the DAG
//Args   :      os - an output stream to write to
//Returns:  MStatus::kSuccess if the method succeeds
//                      MStatus::kFailure if the method fails
{
        MStatus status;

        //create an iterator for the selected mesh components of the DAG
        //
        MSelectionList selectionList;
        if (MStatus::kFailure == MGlobal::getActiveSelectionList(selectionList)) {
                MGlobal::displayError("MGlobal::getActiveSelectionList");
                return MStatus::kFailure;
        }

        MItSelectionList itSelectionList(selectionList, MFn::kMesh, &status);   
        if (MStatus::kFailure == status) {
                return MStatus::kFailure;
        }

        for (itSelectionList.reset(); !itSelectionList.isDone(); itSelectionList.next()) {
                MDagPath dagPath;

                //get the current dag path and process the poly mesh on it
                //
                if (MStatus::kFailure == itSelectionList.getDagPath(dagPath)) {
                        MGlobal::displayError("MItSelectionList::getDagPath");
                        return MStatus::kFailure;
                }

                if (MStatus::kFailure == processPolyMesh(dagPath, os)) {
                        return MStatus::kFailure;
                }
        }
        return MStatus::kSuccess;
}


MStatus polyExporter::processPolyMesh(const MDagPath dagPath, ostream& os) 
//Summary:      processes the mesh on the given dag path by extracting its geometry
//                      and writing this data to file
//Args   :      dagPath - the current dag path whose poly mesh is to be processed
//                      os - an output stream to write to
//Returns:      MStatus::kSuccess if the polygonal mesh data was processed fully;
//                      MStatus::kFailure otherwise
{
        MStatus status;
        polyWriter* pWriter = createPolyWriter(dagPath, status);
        if (MStatus::kFailure == status) {
                delete pWriter;
                return MStatus::kFailure;
        }
        if (MStatus::kFailure == pWriter->extractGeometry()) {
                delete pWriter;
                return MStatus::kFailure;
        }
        if (MStatus::kFailure == pWriter->writeToFile(os)) {
                delete pWriter;
                return MStatus::kFailure;
        }
        delete pWriter;
        return MStatus::kSuccess;
}


bool polyExporter::isVisible(MFnDagNode & fnDag, MStatus& status) 
//Summary:      determines if the given DAG node is currently visible
//Args   :      fnDag - the DAG node to check
//Returns:      true if the node is visible;            
//                      false otherwise
{
        if(fnDag.isIntermediateObject())
                return false;

        MPlug visPlug = fnDag.findPlug("visibility", &status);
        if (MStatus::kFailure == status) {
                MGlobal::displayError("MPlug::findPlug");
                return false;
        } else {
                bool visible;
                status = visPlug.getValue(visible);
                if (MStatus::kFailure == status) {
                        MGlobal::displayError("MPlug::getValue");
                }
                return visible;
        }
}


void polyExporter::writeHeader(ostream& os) 
//Summary:      outputs information that needs to appear before the main data
//Args   :      os - an output stream to write to
{
        os << "";
}


void polyExporter::writeFooter(ostream& os) 
//Summary:      outputs information that needs to appear after the main data
//Args   :      os - an output stream to write to
{
        os << "";
}