//- // ========================================================================== // Copyright (C) 1995 - 2005 Alias Systems Corp. and/or its licensors. All // rights reserved. // // The coded instructions, statements, computer programs, and/or related // material (collectively the "Data") in these files are provided by Alias // Systems Corp. ("Alias") and/or its licensors for the exclusive use of the // Customer (as defined in the Alias Software License Agreement that // accompanies this Alias software). Such Customer has the right to use, // modify, and incorporate the Data into other products and to distribute such // products for use by end-users. // // THE DATA IS PROVIDED "AS IS". ALIAS HEREBY DISCLAIMS ALL WARRANTIES // RELATING TO THE DATA, INCLUDING, WITHOUT LIMITATION, ANY AND ALL EXPRESS OR // IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. IN NO EVENT SHALL ALIAS BE LIABLE FOR ANY DAMAGES // WHATSOEVER, WHETHER DIRECT, INDIRECT, SPECIAL, OR PUNITIVE, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, OR IN EQUITY, // ARISING OUT OF ACCESS TO, USE OF, OR RELIANCE UPON THE DATA. // ========================================================================== //+ // // //polyWriter.cpp //General Includes // #include #include #include #include #include #include //Iterator Includes // #include //Header File // #include "polyWriter.h" polyWriter::polyWriter(MDagPath dagPath, MStatus& status) //Summary: Constructor - creates the MDagPath and MFnMesh objects necessary // for extracting the data //Args : dagPath - the dagPath where the mesh is located= // status - will be set to MStatus::kSuccess if the creation of the // MFnMesh is successful; MStatus::kFailure otherwise { fDagPath = new MDagPath(dagPath); fMesh = new MFnMesh(*fDagPath, &status); } polyWriter::~polyWriter() //Summary: Destructor - deletes all constructor created objects { if (NULL != fDagPath) delete fDagPath; if (NULL != fMesh) delete fMesh; } MStatus polyWriter::extractGeometry() //Summary: extracts the main geometry (vertices, vertex colours, vertex normals) // of this polygonal mesh. //Returns: MStatus::kSuccess if the method succeeds // MStatus::kFailure if the method fails { if (MStatus::kFailure == fMesh->getPoints(fVertexArray, MSpace::kWorld)) { MGlobal::displayError("MFnMesh::getPoints"); return MStatus::kFailure; } if (MStatus::kFailure == fMesh->getFaceVertexColors(fColorArray)) { MGlobal::displayError("MFnMesh::getFaceVertexColors"); return MStatus::kFailure; } if (MStatus::kFailure == fMesh->getNormals(fNormalArray, MSpace::kWorld)) { MGlobal::displayError("MFnMesh::getNormals"); return MStatus::kFailure; } if (MStatus::kFailure == fMesh->getCurrentUVSetName(fCurrentUVSetName)) { MGlobal::displayError("MFnMesh::getCurrentUVSetName"); return MStatus::kFailure; } if (MStatus::kFailure == fMesh->getTangents(fTangentArray, MSpace::kWorld, &fCurrentUVSetName)) { MGlobal::displayError("MFnMesh::getTangents"); return MStatus::kFailure; } if (MStatus::kFailure == fMesh->getBinormals(fBinormalArray, MSpace::kWorld, &fCurrentUVSetName)) { MGlobal::displayError("MFnMesh::getBinormals"); return MStatus::kFailure; } //Have to make the path include the shape below it so that //we can determine if the underlying shape node is instanced. //By default, dag paths only include transform nodes. // fDagPath->extendToShape(); //If the shape is instanced then we need to determine which //instance this path refers to. // int instanceNum = 0; if (fDagPath->isInstanced()) instanceNum = fDagPath->instanceNumber(); //Get the connected sets and members - these will be used to determine texturing of different //faces // if (!fMesh->getConnectedSetsAndMembers(instanceNum, fPolygonSets, fPolygonComponents, true)) { MGlobal::displayError("MFnMesh::getConnectedSetsAndMembers"); return MStatus::kFailure; } return MStatus::kSuccess; } void polyWriter::outputTabs(ostream& os, unsigned int tabCount) //Summary: outputs tab spacing //Args : os - an output stream to write to // tabCount - the number of tabs to print //Returns: MStatus::kSuccess if the method succeeds // MStatus::kFailure if the method fails { unsigned int i; for (i = 0; i < tabCount; i++) { os << "\t"; } } MObject polyWriter::findShader(const MObject& setNode) //Summary: finds the shading node for the given shading group set node //Args : setNode - the shading group set node //Returns: the shader node for setNode if found; // MObject::kNullObj otherwise { MFnDependencyNode fnNode(setNode); MPlug shaderPlug = fnNode.findPlug("surfaceShader"); if (!shaderPlug.isNull()) { MPlugArray connectedPlugs; //get all the plugs that are connected as the destination of this //surfaceShader plug so we can find the surface shaderNode // MStatus status; shaderPlug.connectedTo(connectedPlugs, true, false, &status); if (MStatus::kFailure == status) { MGlobal::displayError("MPlug::connectedTo"); return MObject::kNullObj; } if (1 != connectedPlugs.length()) { MGlobal::displayError("Error getting shader for: " + fMesh->partialPathName()); } else { return connectedPlugs[0].node(); } } return MObject::kNullObj; } MStatus polyWriter::outputSets(ostream& os) //Summary: outputs this mesh's sets and each sets face components, and any // associated texture //Args : os - an output stream to write to //Returns: MStatus::kSuccess if set information was outputted // MStatus::kFailure otherwise { MStatus status; //if there is more than one set, the last set simply consists of all //polygons, so we won't include it // unsigned int setCount = fPolygonSets.length(); if (setCount > 1) { setCount--; } MIntArray faces; unsigned int i; for (i = 0; i < setCount; i++ ) { MObject set = fPolygonSets[i]; MObject comp = fPolygonComponents[i]; MFnSet fnSet(set, &status); if (MS::kFailure == status) { MGlobal::displayError("MFnSet::MFnSet"); continue; } //Make sure the set is a polygonal set. If not, continue. MItMeshPolygon itMeshPolygon(*fDagPath, comp, &status); if ((MS::kFailure == status)) { MGlobal::displayError("MItMeshPolygon::MItMeshPolygon"); continue; } //add the current set's face indices to the faces array // faces.setLength(itMeshPolygon.count()); unsigned int j = 0; for (itMeshPolygon.reset(); !itMeshPolygon.isDone(); itMeshPolygon.next()) { faces[j++] = itMeshPolygon.index(); } //Find the texture that is applied to this set. First, get the //shading node connected to the set. Then, if there is an input //attribute called "color", search upstream from it for a texture //file node. // MObject shaderNode = findShader(set); if (MObject::kNullObj == shaderNode) { continue; } MPlug colorPlug = MFnDependencyNode(shaderNode).findPlug("color", &status); if (MS::kFailure == status) { MGlobal::displayError("MFnDependencyNode::findPlug"); continue; } MItDependencyGraph itDG(colorPlug, MFn::kFileTexture, MItDependencyGraph::kUpstream, MItDependencyGraph::kBreadthFirst, MItDependencyGraph::kNodeLevel, &status); if (MS::kFailure == status) { MGlobal::displayError("MItDependencyGraph::MItDependencyGraph"); continue; } //disable automatic pruning so that we can locate a specific plug itDG.disablePruningOnFilter(); //If no texture file node was found, pass in an empty string as the texture filename //so that color information is outputted instead // MString textureName(""); if (itDG.isDone()) { if (MStatus::kFailure == outputSingleSet(os, MString(fnSet.name()), faces, textureName)) { return MStatus::kFailure; } //otherwise retrieve the filename and pass it in to output texture information // } else { MObject textureNode = itDG.thisNode(); MPlug filenamePlug = MFnDependencyNode(textureNode).findPlug("fileTextureName"); filenamePlug.getValue(textureName); if (MStatus::kFailure == outputSingleSet(os, MString(fnSet.name()), faces, textureName)) { return MStatus::kFailure; } } } return MStatus::kSuccess; }