#include <maya/MIOStream.h>
#include <maya/MGlobal.h>
#include <maya/MDagPath.h>
#include <maya/MIntArray.h>
#include <maya/MFnSet.h>
#include <maya/MItDependencyGraph.h>
#include <maya/MPlug.h>
#include <maya/MItMeshPolygon.h>
#include "polyX3DWriter.h"
#define DEFAULT_COLOR "0.2 0.2 0.2"
#define DIFFUSE_COLOR "0 0 0"
#define SHININESS "0.8"
#define SPECULAR_COLOR "0.5 0.5 0.5"
#define COORDINATE_FLAG 0x0001
#define NORMAL_FLAG 0x0010
#define TEXTURE_FLAG 0x0100
#define COLOR_FLAG 0x1000
#define INITIAL_TAB_COUNT 2
polyX3DWriter::polyX3DWriter(const MDagPath& dagPath, MStatus& status):
polyWriter(dagPath, status),
fTagFlags(0),
fInitialTabCount(INITIAL_TAB_COUNT)
{
}
polyX3DWriter::~polyX3DWriter()
{
}
MStatus polyX3DWriter::extractGeometry()
{
if (MStatus::kFailure == polyWriter::extractGeometry()) {
return MStatus::kFailure;
}
if (MStatus::kFailure == fMesh->getUVs(fUArray, fVArray, &fCurrentUVSetName)) {
MGlobal::displayError("MFnMesh::getUVs");
return MStatus::kFailure;
}
return MStatus::kSuccess;
}
MStatus polyX3DWriter::writeToFile(ostream& os)
{
MGlobal::displayInfo("Exporting " + fMesh->partialPathName());
unsigned int setCount = fPolygonSets.length();
if (0 == setCount) {
return MStatus::kFailure;
} else if (1 == setCount) {
if (MStatus::kFailure == outputSets(os)) {
return MStatus::kFailure;
}
} else {
outputTabs(os, INITIAL_TAB_COUNT);
fInitialTabCount++;
os << "<Group DEF=\"" << fMesh->partialPathName() << "\">\n";
if (MStatus::kFailure == outputSets(os)) {
return MStatus::kFailure;
}
outputTabs(os, INITIAL_TAB_COUNT);
os << "</Group>\n";
}
return MStatus::kSuccess;
}
MStatus polyX3DWriter::outputSingleSet (ostream& os, MString setName, MIntArray faces, MString textureName) {
if (0 == fPolygonSets.length()) {
return MStatus::kFailure;
} else if (1 == fPolygonSets.length()) {
setName = fMesh->partialPathName();
} else {
setName = fMesh->partialPathName() + "_" + setName;
}
return outputX3DShapeTag (os, setName, faces, textureName, fInitialTabCount);
}
MStatus polyX3DWriter::outputX3DShapeTag(ostream & os,
const MString shapeName,
const MIntArray& faces,
const MString textureName,
const unsigned int tabCount)
{
outputTabs(os, tabCount);
os << "<Shape DEF=\"" << shapeName << "\">\n";
if (MStatus::kFailure == outputX3DAppearanceTag(os, textureName, tabCount + 1)) {
return MStatus::kFailure;
}
if (MStatus::kFailure == outputX3DIndexedFaceSetTag(os, faces, textureName, tabCount + 1)) {
return MStatus::kFailure;
}
outputTabs(os, tabCount);
os << "</Shape>\n";
return MStatus::kSuccess;
}
MStatus polyX3DWriter::outputX3DAppearanceTag(ostream & os,
const MString textureName,
const unsigned int tabCount)
{
outputTabs(os, tabCount);
if (textureName == MString("")) {
os << "<Appearance><Material/></Appearance>\n";
} else {
os << "<Appearance>\n";
outputTabs(os, tabCount + 1);
os << "<ImageTexture url=\"" << textureName << "\"/>\n";
outputTabs(os, tabCount + 1);
os << "<Material diffuseColor=\"" << DIFFUSE_COLOR
<< "\" shininess=\"" << SHININESS
<< "\" specularColor=\"" << SPECULAR_COLOR
<< "\"/>\n";
outputTabs(os, tabCount);
os << "</Appearance>\n";
}
return MStatus::kSuccess;
}
MStatus polyX3DWriter::outputX3DIndexedFaceSetTag(ostream & os,
const MIntArray& faces,
const MString textureName,
const unsigned int tabCount)
{
outputTabs(os, tabCount);
os << "<IndexedFaceSet coordIndex=\"";
unsigned int faceCount = faces.length();
if (0 == faceCount) {
return MStatus::kFailure;
}
MStatus status;
unsigned int i, j, indexCount;
MIntArray indexList;
for (i = 0; i < faceCount; i++) {
indexCount = fMesh->polygonVertexCount(faces[i], &status);
if (MStatus::kFailure == status) {
MGlobal::displayError("MFnMesh::polygonVertexCount");
return MStatus::kFailure;
}
status = fMesh->getPolygonVertices (faces[i], indexList);
if (MStatus::kFailure == status) {
MGlobal::displayError("MFnMesh::getPolygonVertices");
return MStatus::kFailure;
}
for (j = 0; j < indexCount; j++) {
os << indexList[j] << " ";
}
os << "-1 ";
}
os << "\" normalPerVertex=\"true\" normalIndex=\"";
for (i = 0; i < faceCount; i++) {
status == fMesh->getFaceNormalIds (faces[i], indexList);
if (MStatus::kFailure == status) {
MGlobal::displayError("MFnMesh::getFaceNormalIds");
return MStatus::kFailure;
}
indexCount = indexList.length();
for (j = 0; j < indexCount; j++) {
os << indexList[j] << " ";
}
os << "-1 ";
}
os << "\" ";
if (textureName == MString("")) {
os << "colorPerVertex=\"true\" ";
os << "colorIndex=\"";
int colorIndex = 0;
for (i = 0; i < faceCount; i++) {
indexCount = fMesh->polygonVertexCount(faces[i], &status);
if (MStatus::kFailure == status) {
MGlobal::displayError("MFnMesh::polygonVertexCount");
return MStatus::kFailure;
}
for (j = 0; j < indexCount; j++) {
if (MStatus::kFailure == fMesh->getFaceVertexColorIndex(faces[i], j, colorIndex)) {
MGlobal::displayError("MFnMesh::getFaceVertexColorIndex");
return MStatus::kFailure;
}
os << colorIndex << " ";
}
os << "-1 ";
}
os << "\">\n";
if (MStatus::kFailure == outputX3DColorTag(os, tabCount + 1)) {
return MStatus::kFailure;
}
} else {
os << " texCoordIndex=\"";
for (i = 0; i < faceCount; i++) {
indexCount = fMesh->polygonVertexCount(faces[i], &status);
if (MStatus::kFailure == status) {
MGlobal::displayError("MFnMesh::polygonVertexCount");
return MStatus::kFailure;
}
for (j = 0; j < indexCount; j++) {
int uvID;
status = fMesh->getPolygonUVid(faces[i], j, uvID, &fCurrentUVSetName);
if (MStatus::kFailure == status) {
MGlobal::displayError("MFnMesh::getPolygonUVid");
return MStatus::kFailure;
}
os << uvID << " ";
}
os << "-1 ";
}
os << "\">\n";
if (MStatus::kFailure == outputX3DTextureCoordinateTag(os, tabCount + 1)) {
return MStatus::kFailure;
}
}
if (MStatus::kFailure == outputX3DCoordinateTag(os, tabCount + 1)
|| MStatus::kFailure == outputX3DNormalTag(os, tabCount + 1)) {
return MStatus::kFailure;
}
outputTabs(os, tabCount);
os << "</IndexedFaceSet>\n";
return MStatus::kSuccess;
}
MStatus polyX3DWriter::outputX3DCoordinateTag(ostream & os,
const unsigned int tabCount)
{
unsigned int vertexCount = fVertexArray.length();
if (0 == vertexCount) {
return MStatus::kFailure;
}
outputTabs(os, tabCount);
if (fTagFlags & COORDINATE_FLAG) {
os << "<Coordinate USE=\"" << fMesh->partialPathName() << "_coordinates";
} else {
fTagFlags |= COORDINATE_FLAG;
os << "<Coordinate DEF=\"" << fMesh->partialPathName() << "_coordinates\" point=\"";
unsigned int i;
for (i = 0; i < vertexCount; i++) {
os << fVertexArray[i].x << " "
<< fVertexArray[i].y << " "
<< fVertexArray[i].z << ", ";
}
}
os << "\"/>\n";
return MStatus::kSuccess;
}
MStatus polyX3DWriter::outputX3DNormalTag(ostream & os,
const unsigned int tabCount)
{
unsigned int normalCount = fNormalArray.length();
if (0 == normalCount) {
return MStatus::kFailure;
}
outputTabs(os, tabCount);
if (fTagFlags & NORMAL_FLAG) {
os << "<Normal USE=\"" << fMesh->partialPathName() << "_normals";
} else {
fTagFlags |= NORMAL_FLAG;
os << "<Normal DEF=\"" << fMesh->partialPathName() << "_normals\" vector=\"";
unsigned int i;
for (i = 0; i < normalCount; i++) {
os << fNormalArray[i].x << " "
<< fNormalArray[i].y << " "
<< fNormalArray[i].z << ", ";
}
}
os << "\"/>\n";
return MStatus::kSuccess;
}
MStatus polyX3DWriter::outputX3DTextureCoordinateTag(ostream & os,
const unsigned int tabCount)
{
unsigned int uvCount = fUArray.length();
if (0 == uvCount) {
return MStatus::kFailure;
}
outputTabs(os, tabCount);
if (fTagFlags & TEXTURE_FLAG) {
os << "<TextureCoordinate USE=\"" << fMesh->partialPathName() << "_texCoordinates";
} else {
fTagFlags |= TEXTURE_FLAG;
os << "<TextureCoordinate DEF=\"" << fMesh->partialPathName() << "_texCoordinates\" point=\"";
unsigned int i;
for (i = 0; i < uvCount; i++) {
os << fUArray[i] << " " << fVArray[i] << ", ";
}
}
os << "\"/>\n";
return MStatus::kSuccess;
}
MStatus polyX3DWriter::outputX3DColorTag(ostream & os,
const unsigned int tabCount)
{
unsigned int colorCount = fColorArray.length();
if (0 == colorCount) {
return MStatus::kFailure;
}
outputTabs(os, tabCount);
if (fTagFlags & COLOR_FLAG) {
os << "<Color USE=\"" << fMesh->partialPathName() << "_colors";
} else {
fTagFlags |= COLOR_FLAG;
os << "<Color DEF=\"" << fMesh->partialPathName() << "_colors\" color=\"";
unsigned int i;
for (i = 0; i < colorCount; i++) {
if (-1 != fColorArray[i].r) {
os << fColorArray[i].r << " "
<< fColorArray[i].g << " "
<< fColorArray[i].b << ", ";
} else {
os << DEFAULT_COLOR << ", ";
}
}
}
os << "\"/>\n";
return MStatus::kSuccess;
}