Mayaからほしいデータを抽出してみる。
Maya5のOpen Mayaで私がほしいパラメーターを抽出するプログラムを書いてみました。
参考にしたのはここら辺
http://www.robthebloke.org/index.html
http://svn.hermitworksentertainment.com/maya2q3/browser/trunk/maya2q3/x42.cpp?rev=114
画像はテスト用に作ったものですが、あまりにも出来が悪いのでワイヤーフレームで。
抽出しているパラメータは
スキニングする前の頂点の座標、法線、uv座標、
マテリアル、テクスチャー、
階層、ボーン、頂点の重み、ボーンの割り当てられ方、
などです。
アニメーションもほしいですが今回は見送り。
#define _BOOL int #include <stdlib.h> #include <iostream> #include <string> #include <vector> using namespace std; #define REQUIRE_IOSTREAM #include <maya/MStatus.h> #include <maya/MObject.h> #include <maya/MString.h> #include <maya/MArgList.h> #include <maya/MGlobal.h> #include <maya/MSelectionList.h> #include <maya/MItSelectionList.h> #include <maya/MItSurfaceCV.h> #include <maya/MItMeshVertex.h> #include <maya/MPoint.h> #include <maya/MFnMesh.h> #include <maya/MFnTransform.h> #include <maya/MFnIkJoint.h> #include <maya/MVector.h> #include <maya/MMatrix.h> #include <maya/MQuaternion.h> #include <maya/MDagPath.h> #include <maya/MFileIO.h> #include <maya/MLibrary.h> #include <maya/MIOStream.h> #include <maya/MPointArray.h> #include <maya/MFloatArray.h> #include <maya/MPlug.h> #include <maya/MPlugArray.h> #include <maya/MItDependencyNodes.h> #include <maya/MFnLambertShader.h> #include <maya/MItMeshPolygon.h> #include <maya/MFnSkinCluster.h> #include <maya/MFnMatrixData.h> #include <maya/MItGeometry.h> #include <maya/MDagPathArray.h> #include <math.h> void PrintColor(MFnDependencyNode & node, const char * name, int depth) { string space(depth, ' '); MPlug p; MString r = name; MString g = name; MString b = name; MString a = name; r += "R"; g += "G"; b += "B"; a += "A"; MColor color; p = node.findPlug(r.asChar()); p.getValue(color.r); p = node.findPlug(g.asChar()); p.getValue(color.g); p = node.findPlug(b.asChar()); p.getValue(color.b); p = node.findPlug(a.asChar()); p.getValue(color.a); p = node.findPlug(name); MString texname; MPlugArray plugs; p.connectedTo(plugs,true,false); for(int i=0;i!=plugs.length();++i) { if(plugs[i].node().apiType() == MFn::kFileTexture) { MFnDependencyNode fnDep(plugs[i].node()); { MPlug mp; mp = fnDep.findPlug("fileTextureName"); mp.getValue(texname); } break; } } if( name == string("color") && color.r < 0.01f && color.g < 0.01f && color.b < 0.01f) { color.r = color.g = color.b = 0.5f; } cout << space << name << " " << color.r << " " << color.g << " " << color.b << " " << color.a << " " << texname.asChar() << endl; } void PrintMesh(MObject obj, int depth) { MStatus stat; string space(depth, ' '); MFnDependencyNode node(obj); MFnMesh mesh(obj); unsigned int i, isz; unsigned int j, jsz; unsigned int k, ksz; MObject vtxobj = obj; { MPlug mp; MPlugArray mpa; mp = node.findPlug("inMesh"); mp.connectedTo(mpa, true, false); isz = mpa.length(); for(i = 0 ; i < (1 < isz ? 1 : isz) ; i++) { MFnDependencyNode node(mpa[i].node()); cout << space << " " << node.typeName().asChar() << " : " << node.name().asChar() << endl; if(node.typeName() == "skinCluster") { MFnSkinCluster skinC(mpa[i].node()); skinC.findPlug( "input" ).elementByLogicalIndex( skinC.indexForOutputShape( obj ) ) .child( 0 ).getValue( vtxobj ); } } } MFnMesh smesh(vtxobj); // MPointArray vertices; smesh.getPoints(vertices); cout << space << "vertex size = " << vertices.length() << endl; isz = vertices.length(); //for(i = 0 ; i < isz ; i++) for(i = 0 ; i < 1 ; i++) { cout << space << " (" << vertices[i].x << ", " << vertices[i].y << ", " << vertices[i].z << ", " << vertices[i].w << ")" << endl; //cout << space << " " << // vertices[i].x << " " << // vertices[i].y << " " << // vertices[i].z << " " << // vertices[i].w << "" << endl; } // MFloatVectorArray normals; smesh.getNormals(normals); cout << space << "normal size = " << normals.length() << endl; isz = normals.length(); //for(i = 0 ; i < isz ; i++) for(i = 0 ; i < 1 ; i++) { cout << space << " (" << normals[i].x << ", " << normals[i].y << ", " << normals[i].z << ")" << endl; } // MStringArray uvsets; vector<MFloatArray> us; vector<MFloatArray> vs; smesh.getUVSetNames(uvsets); cout << space << "uvset size = " << uvsets.length() << endl; isz = uvsets.length(); us.resize((size_t)isz); vs.resize((size_t)isz); for(i = 0 ; i < isz ; i++) { smesh.getUVs(us[i], vs[i], &uvsets[i]); jsz = us[i].length(); cout << space << " " << uvsets[i].asChar() << " size = " << jsz << endl; //for(j = 0 ; j < jsz ; j++) for(j = 0 ; j < 1 ; j++) { cout << space << " (" << us[i][j] << ", " << vs[i][j] << ")" << endl; } } // MItMeshPolygon ipol(vtxobj); int uvindex; isz = uvsets.length(); cout << space << "polygon size = " << mesh.numPolygons() << endl; while(!ipol.isDone()) { jsz = (unsigned int)ipol.polygonVertexCount(); cout << space << " polygon vertex size = " << jsz << endl; //for(j = 0 ; j < jsz ; j++) for(j = 0 ; j < 1 ; j++) { cout << space << " vertex index = " << ipol.vertexIndex(j) << " ,normal index = " << ipol.normalIndex(j);// << endl; for(i = 0 ; i < isz ; i++) { ipol.getUVIndex(j, uvindex, &uvsets[i]); cout << " ,uv index" << i << " = " << uvindex; } cout << endl; } // ipol.next(); //一枚だけ表示 break; } // isz = mesh.parentCount(); //isz = smesh.parentCount(); //間違っていたかな? cout << space << "parent count = " << isz << endl; for(i = 0 ; i < isz ; i++) { MObjectArray shaders; MIntArray indices; //smesh.getConnectedShaders(i, //ここも間違っていた // shaders, indices); mesh.getConnectedShaders(i, shaders, indices); jsz = shaders.length(); cout << space << " shader size = " << jsz << endl; for(j = 0 ; j < jsz ; j++) { MPlug mp; MPlugArray mpa; MFnDependencyNode node(shaders[j]); mp = node.findPlug("surfaceShader"); mp.connectedTo(mpa, true, false); ksz = mpa.length(); for(k = 0 ; k < ksz ; k++) { MFnDependencyNode node(mpa[k].node()); cout << space << " Connections " << node.object().apiTypeStr() << " " << node.typeName().asChar() << " " << node.name().asChar() << endl; switch(node.object().apiType()) { case MFn::kPhong: { MFnLambertShader node(node.object()); PrintColor(node, "ambientColor", depth + 3); PrintColor(node, "color", depth + 3); PrintColor(node, "speqularColor", depth + 3); PrintColor(node, "incandescence", depth + 3); PrintColor(node, "transparency", depth + 3); } break; case MFn::kLambert: { MFnLambertShader node(node.object()); PrintColor(node, "ambientColor", depth + 3); PrintColor(node, "color", depth + 3); PrintColor(node, "incandescence", depth + 3); PrintColor(node, "transparency", depth + 3); } break; } } } jsz = indices.length(); cout << space << " indices size = " << jsz << endl; //for(j = 0 ; j < jsz ; j++) for(j = 0 ; j < 1 ; j++) { cout << space << " index = " << indices[j] << endl; } } // { MPlug mp; MPlugArray mpa; mp = node.findPlug("inMesh"); mp.connectedTo(mpa, true, false); isz = mpa.length(); for(i = 0 ; i < isz ; i++) { MFnDependencyNode node(mpa[i].node()); cout << space << " " << node.typeName().asChar() << " : " << node.name().asChar() << endl; if(node.typeName() == "skinCluster") { MFnSkinCluster skinC(mpa[i].node()); MDagPathArray dpa; //* { MPlugArray mpa; skinC.getConnections( mpa ); unsigned int i, isz; isz = mpa.length(); for(i = 0 ; i < isz ; i++) { cout << space << " skinplug = " << mpa[i].name().asChar() << endl; } } //*/ jsz = skinC.influenceObjects(dpa, &stat); ksz = skinC.numOutputConnections(); for(k = 0 ; k < ksz ; k++) { unsigned int index; index = skinC.indexForOutputConnection(k); MDagPath dp; skinC.getPathAtIndex(index, dp); MItGeometry gi(dp); cout << space << " skin = " << dp.partialPathName().asChar() << ", point size = " << gi.count() << ", influence size = " << jsz << endl; for(j = 0 ; j < jsz ; j++) //for(j = 0 ; j < 1 ; j++) { cout << space << " " << dpa[j].partialPathName().asChar() << endl; } { //bindPreMatrix MObject objtobind; skinC.findPlug( "geomMatrix" ).getValue( objtobind ); MFnMatrixData mat(objtobind); MMatrix ma = mat.matrix(); MPlug mp = skinC.findPlug("bindPreMatrix", &stat); //MPlug mp = skinC.findPlug("matrix", &stat); cout << space << " " << mp.name().asChar() << endl; //for(j = 0 ; j < jsz ; j++) for(j = 0 ; j < 1 ; j++) { MPlug mp2 = mp.elementByLogicalIndex( skinC.indexForInfluenceObject( dpa[j], NULL ), &stat); cout << space << " " << mp2.name().asChar() << endl; MObject obj; mp2.getValue(obj); MFnMatrixData mat(obj); MMatrix m = ma * mat.matrix(); m = m.inverse(); cout << space << " (" << m[0][0] << " " << m[0][1] << " " << m[0][2] << " " << m[0][3] << endl << space << " " << m[1][0] << " " << m[1][1] << " " << m[1][2] << " " << m[1][3] << endl << space << " " << m[2][0] << " " << m[2][1] << " " << m[2][2] << " " << m[2][3] << endl << space << " " << m[3][0] << " " << m[3][1] << " " << m[3][2] << " " << m[3][3] << ")" << endl; //cout << space << " " // << m[3][0] << "\t" << m[3][1] << "\t" << m[3][2] << "\t" << m[3][3] << "" << endl; } } while(!gi.isDone()) { MObject cp = gi.component(); MFloatArray ws; unsigned int l, lsz; skinC.getWeights(dp, cp, ws, lsz); if(lsz != 0 && //gi.index() == k && !gi.isDone()) { unsigned int wnum = 0; float outw[256] = {1.0f, 0.0f}; unsigned int outinf[256] = {0}; for(l = 0 ; l < lsz ; l++) { if(ws[l] > 0.001f ) { if(wnum != 0) { outw[0] -= ws[l]; outw[wnum] = ws[l]; } outinf[wnum] = l; wnum++; } } cout << space << " weight size = " << wnum << " index = " << gi.index() << endl; for(l = 0 ; l < wnum ; l++) { cout << space << " (" << outinf[l] << ", " << outw[l] << ")" << endl; } } gi.next(); //break; } } } } } } void PrintTransformMesh(MObject obj, int depth) { string space(depth, ' '); MFnDependencyNode node(obj); cout << space << node.typeName().asChar() << " : " << node.name().asChar() << endl; if(node.typeName() == MString("mesh")) { PrintMesh(obj, depth + 1); } if(node.typeName() == MString("transform") || node.typeName() == MString("joint") ) { MFnTransform trans(obj); MMatrix m = trans.transformation().asMatrix(); cout << space << " (" << m[0][0] << " " << m[0][1] << " " << m[0][2] << " " << m[0][3] << endl << space << " " << m[1][0] << " " << m[1][1] << " " << m[1][2] << " " << m[1][3] << endl << space << " " << m[2][0] << " " << m[2][1] << " " << m[2][2] << " " << m[2][3] << endl << space << " " << m[3][0] << " " << m[3][1] << " " << m[3][2] << " " << m[3][3] << ")" << endl; { unsigned int i, isz; MObject obj; isz = trans.childCount(); for(i = 0 ; i < isz ; i++) { obj = trans.child(i); MFnDependencyNode node(obj); PrintTransformMesh(obj, depth + 1); } } } } void MakeTestProc1(int argc, char **argv) { MStatus stat; { //MString fname("scenes/bamboogun_forx.mb"); MString fname("scenes/mario4.mb"); stat = MFileIO::open(fname, "mayaBinary", true); if(stat) { } else { cout << "failed in open." << endl; return; } } { MSelectionList selList; //selList.add("group5"); selList.add("group6"); unsigned int i, isz; isz = selList.length(); for(i = 0 ; i < isz ; i++) { MObject obj; selList.getDependNode(i, obj); PrintTransformMesh(obj, 0); } } }