📄 ogremayamesh.cpp
字号:
MPlugArray srcPlugArray;
ssPlug.connectedTo(srcPlugArray, true, false);
if (srcPlugArray.length() > 0) {
// This object contains a reference to a shader or material.
// Check for known material types and extract material name.
MObject srcNode = srcPlugArray[0].node();
if (srcNode.hasFn(MFn::kPhong)) {
MFnPhongShader fnPhong(srcNode);
MaterialName = fnPhong.name();
}
else if (srcNode.hasFn(MFn::kLambert)) {
MFnLambertShader fnLambert(srcNode);
MaterialName = fnLambert.name();
}
else if (srcNode.hasFn(MFn::kBlinn)) {
MFnBlinnShader fnBlinn(srcNode);
MaterialName = fnBlinn.name();
}
else if (srcNode.hasFn(MFn::kReflect)) {
MFnReflectShader fnReflect(srcNode);
MaterialName = fnReflect.name();
}
}
}
// ===== Done
return MaterialName;
}
// --------------------------------------------------------------------------
/** Retrieve all Maya geometry for a single Maya mesh.
\todo Define materials if requested
\todo Fix normals
*/
// --------------------------------------------------------------------------
MStatus MeshGenerator::_queryMayaGeometry(
MFnMesh &fnMesh,
MeshMayaGeometry &rGeom
) {
cout << "\nMeshGenerator::_queryMayaGeometry\n";
MStatus status = MStatus::kSuccess;
// ===== Identification
rGeom.Name = fnMesh.partialPathName(); // shortest unique name
rGeom.MaterialName = getMaterialName(fnMesh);
// ===== Geometry
// --- Vertices
status = fnMesh.getPoints(rGeom.Vertices, MSpace::kWorld);
if (status == MStatus::kFailure) {
cout << "\t[ERROR] MFnMesh::getPoints() failed\n";
return status;
}
cout << "\tvertices count: " << rGeom.Vertices.length() << '\n';
// --- Vertex normals
status = fnMesh.getNormals(rGeom.FaceVertexNormals);
if (status == MStatus::kFailure) {
cout << "\t[ERROR] MFnMesh::getNormals() failed\n";
return status;
}
// --- Triangular faces
MDagPath dagPath;
fnMesh.getPath(dagPath);
MItMeshPolygon iterPoly(dagPath);
int iPolygon, nPolygons;
nPolygons = fnMesh.numPolygons();
for (iPolygon=0; iPolygon < nPolygons; ++iPolygon)
{
MIntArray ThisPolyTriVertices;
MPointArray ThisPolyPointsUntweaked;
iterPoly.getTriangles(ThisPolyPointsUntweaked, ThisPolyTriVertices, MSpace::kWorld);
_convertObjectToFace(iterPoly, ThisPolyTriVertices, rGeom.TriangleVertexIds);
int iTriangle, nTriangles;
iterPoly.numTriangles(nTriangles);
for (iTriangle=0; iTriangle < nTriangles; ++iTriangle) {
rGeom.TrianglePolygonIds.append(iPolygon);
}
iterPoly.next();
}
// ===== Colours and UVs
// --- Face vertex colours
status = fnMesh.getFaceVertexColors(rGeom.FaceVertexColours);
if (status == MStatus::kFailure) {
cout << "\t[ERROR] MFnMesh::getFaceVertexColors() failed\n";
return status;
}
// Override non-existent colours with semi-transparent white
unsigned int iFaceVertex;
MColor mayaColour;
for (iFaceVertex=0; iFaceVertex < rGeom.FaceVertexColours.length(); ++iFaceVertex) {
mayaColour = rGeom.FaceVertexColours[iFaceVertex];
if ((mayaColour.r) == -1) mayaColour.r = 1;
if ((mayaColour.g) == -1) mayaColour.g = 1;
if ((mayaColour.b) == -1) mayaColour.b = 1;
if ((mayaColour.a) == -1) mayaColour.a = 0.2;
rGeom.FaceVertexColours[iFaceVertex] = mayaColour;
}
// --- UV set names
MStringArray UVSetNames;
status = fnMesh.getUVSetNames(UVSetNames);
if (status == MStatus::kFailure) {
cout << "\t[ERROR] MFnMesh::getUVSetNames() failed\n";
return status;
}
// --- Linked list of UV sets
unsigned int nUVSets = UVSetNames.length();
unsigned int iUVSet;
// Loop over all UV sets
MeshMayaUVSet UVSet;
for (iUVSet = 0; iUVSet < nUVSets; ++iUVSet) {
// Store UV name
UVSet.sName = UVSetNames[iUVSet];
// Retrieve UV coordinates
status = fnMesh.getUVs(UVSet.uArray, UVSet.vArray, &(UVSet.sName));
if (status == MStatus::kFailure) {
return status;
}
// Store UV set
rGeom.UVSets.push_back(UVSet);
}
// ===== Done
return status;
}
// --------------------------------------------------------------------------
/** Parse Maya geometry into MeshGenerator format for further processing.
*/
// --------------------------------------------------------------------------
MStatus MeshGenerator::_parseMayaGeometry(
MFnMesh &fnMesh,
MeshMayaGeometry &MayaGeometry,
MeshFaceVertexVector &FaceVertices,
MeshTriFaceList &TriFaces
) {
cout << "\nMeshGenerator::_parseMayaGeometry\n";
MStatus status;
// --- Determine number of triangles
unsigned int nTris = MayaGeometry.TrianglePolygonIds.length();
if (nTris == 0) {
return MStatus::kFailure;
}
// --- Confirm number of triangle vertices
unsigned int nTriVertices = MayaGeometry.TriangleVertexIds.length();
if (nTriVertices != 3*nTris) {
cout << "\t[ERROR] "<<nTris<<" triangles require "<<(3*nTris)<<" vertices but "<<nTriVertices<<" vertices present!\n";
return MStatus::kFailure;
}
// --- Loop over all triangles
unsigned int iTri;
cout << "\texporting "<<fnMesh.numPolygons()<<" faces as "<<nTris<<" triangles from "<<MayaGeometry.Name.asChar()<<" (material "<<MayaGeometry.MaterialName.asChar()<<")...\n";
for (iTri = 0; iTri < nTris; ++iTri) {
// --- Get polygon index
unsigned int iPoly;
iPoly = MayaGeometry.TrianglePolygonIds[iTri];
// --- Get indices of face-vertices
MIntArray VertexIds;
status = fnMesh.getPolygonVertices(iPoly, VertexIds);
if (status == MStatus::kFailure) {
MGlobal::displayError("MFnMesh::getPolygonVertices()");
return status;
}
// --- Get indices of face-vertex normals
MIntArray NormalIds;
/*if (OPTIONS.exportNormals)*/ {
fnMesh.getFaceNormalIds(iPoly, NormalIds);
if (status == MStatus::kFailure) {
MGlobal::displayError("MFnMesh::getFaceNormalIds()");
return status;
}
}
// --- Loop over all face-vertices
unsigned int iTriVertex;
MeshFaceVertex faceVertices[3];
for (iTriVertex = 0; iTriVertex < 3; ++iTriVertex) {
MeshFaceVertex& FaceVertex = faceVertices[iTriVertex];
// Get polygon vertex id
unsigned int iPolyVertex;
iPolyVertex = MayaGeometry.TriangleVertexIds[3*iTri + iTriVertex];
// Lookup and store face-vertex position
MPoint mayaPoint;
int iVertex = VertexIds[iPolyVertex];
mayaPoint = MayaGeometry.Vertices[iVertex];
MFloatArray* weights = 0;
if(iVertex < MayaGeometry.Weights.size()) {
weights = &MayaGeometry.Weights[iVertex];
}
FaceVertex.vecPosition.x = mayaPoint.x;
FaceVertex.vecPosition.y = mayaPoint.y;
FaceVertex.vecPosition.z = mayaPoint.z;
// Lookup and store face-vertex normal
/*if (OPTIONS.exportNormals)*/ {
MVector mayaNormal;
int iNormal = NormalIds[iPolyVertex];
mayaNormal = MayaGeometry.FaceVertexNormals[iNormal];
FaceVertex.vecNormal.x = mayaNormal.x;
FaceVertex.vecNormal.y = mayaNormal.y;
FaceVertex.vecNormal.z = mayaNormal.z;
}
// Lookup and store face-vertex colour
/*if (OPTIONS.exportColours)*/ {
int iColour;
MColor mayaColour;
status = fnMesh.getFaceVertexColorIndex(iPoly, iPolyVertex, iColour);
mayaColour = MayaGeometry.FaceVertexColours[iColour];
FaceVertex.colour.r = mayaColour.r;
FaceVertex.colour.g = mayaColour.g;
FaceVertex.colour.b = mayaColour.b;
FaceVertex.colour.a = mayaColour.a;
}
// Loop over UV sets
/*if (OPTIONS.exportUVs)*/ {
MeshMayaUVSetList::iterator iterUVSet;
iterUVSet = MayaGeometry.UVSets.begin();
while (iterUVSet != MayaGeometry.UVSets.end()) {
int iUV;
MStatus stat = fnMesh.getPolygonUVid(iPoly, iPolyVertex, iUV, &(iterUVSet->sName));
MeshVertexUV VertexUV;
if(!stat.error()) {
VertexUV.u = iterUVSet->uArray[iUV];
VertexUV.v = 1.0f - iterUVSet->vArray[iUV]; // CJV 2004-01-05: Required for Ogre 0.13
}
else {
VertexUV.u = 0;
VertexUV.v = 0;
}
FaceVertex.listUV.push_back(VertexUV);
++iterUVSet;
}
}
// assign weights
if(weights) {
const float eps = 0.001f;
float acc;
for(int i=weights->length()-1; i>=0; i--) {
acc = 0;
if((*weights)[i] < eps) {
acc += (*weights)[i];
}
else {
VertexBoneAssigment vba;
vba.boneId = i;
vba.weight = (*weights)[i];// + (acc/(float)i);
FaceVertex.boneAssigments.push_front(vba);
}
}
}
}
// OPTIMIZIATION CODE: BEGIN
// Search in the current vertex vector for occurance
int index[3];
for(int i=0; i<3; i++) {
vector<MeshFaceVertex>::iterator it;
vector<MeshFaceVertex>::iterator end = FaceVertices.end();
int j;
for(j=0, it=FaceVertices.begin(); it!=end; ++it, j++) {
if(faceVertices[i] == *it) {
// this vertex is already in vector -> reuse
index[i] = j;
break;
}
}
// if can not be found in vector, insert
if(it==end) {
index[i] = FaceVertices.size();
FaceVertices.push_back(faceVertices[i]);
}
}
// OPTIMIZIATION CODE: END
// --- Define face (three face-vertices)
MeshTriFace TriFace;
TriFace.index0 = (unsigned long)index[0];
TriFace.index1 = (unsigned long)index[1];
TriFace.index2 = (unsigned long)index[2];
TriFaces.push_back(TriFace);
}
return MStatus::kSuccess;
}
// --------------------------------------------------------------------------
/** Determines if a given DAG node is currently visible.
\param fnDag
DAG node to check
\param status
Status code from Maya API
\return True if node is visible, False if node is not visible or if
unable to determine visibility
*/
// --------------------------------------------------------------------------
bool MeshGenerator::_isVisible(MFnDagNode &fnDag, MStatus &status) {
if(fnDag.isIntermediateObject()) {
return false;
}
bool bVisible = false;
MPlug visPlug = fnDag.findPlug("visibility", &status);
if (MStatus::kFailure == status) {
cout << "[WARNING] can not find \"visibility\" plug, returning false\n";
} else {
status = visPlug.getValue(bVisible);
if (MStatus::kFailure == status) {
bVisible = false;
cout << "[WARNING] can not query \"visibility\" plug, returning false\n";
}
}
return bVisible;
}
// --------------------------------------------------------------------------
/** Convert an array of object-relative vertex indices into an array of face-
relative vertex indices. Required because MItMeshPolygon::getTriangle()
returns object-relative vertex indices, whereas many other methods require
face-relative vertex indices.
Adapted from "How do I write a polygon mesh exporter?" at URL
http://www.ewertb.com/maya/api/api_a18.html.
\param iterPoly
Reference to a polygon iterator that is currently at the
polygon of interest
\param objIndices
Reference to array of object-relative indices
\param faceIndices
Reference to array of face-relative indices (output). Indices
are appended to the end of this array. A value of -1 will be
appended if there is no corresponding vertex.
*/
// --------------------------------------------------------------------------
void MeshGenerator::_convertObjectToFace(
MItMeshPolygon &iterPoly,
MIntArray &objIndices,
MIntArray &faceIndices
) {
MIntArray polyIndices;
iterPoly.getVertices(polyIndices);
bool bMatched;
unsigned int iPoly, iObj;
for (iObj=0; iObj < objIndices.length(); ++iObj)
{
bMatched = false;
// iPoly is face-relative vertex index
for (iPoly=0; iPoly < polyIndices.length(); ++iPoly)
{
if (objIndices[iObj] == polyIndices[iPoly]) {
faceIndices.append(iPoly);
bMatched = true;
break;
}
}
// default if no match found
if (!bMatched) {
faceIndices.append(-1);
}
}
}
} // namespace OgreMaya
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -