Poly API は、次の 5 つの主要クラスから構成されています。
MItMeshPolygon を参照してください。
MItMeshEdge を参照してください。
MItMeshVertex と MItMeshFaceVertex を参照してください。
MFnMesh を参照してください。
最初の 4 つのクラスはイテレータで、最後のクラスは関数セットです。ポリゴン イテレータは、主に、コンポーネントごとにメッシュのナビゲートとパーシング処理を行い、コンポーネント固有の情報を取得するために使用します。ポリゴン関数セット MFnMesh は、メッシュ固有データの作成、修正、取得に使用します。
イテレータには、メッシュの修正に使用できるメソッドが含まれていますが、メッシュのナビゲートとコンポーネント固有のデータへのアクセスにのみイテレータを使用するようにしてください。MFnMesh には、その他の操作をメッシュ上で実行するために必要となる、すべてのメソッドがあります。
MItMeshPolygon はポリゴン フェース イテレータです。あるメッシュ オブジェクトに対してこのクラスを初期化すると、フェース ID の順序でメッシュ内のすべてのフェースを反復処理できます。メッシュを参照する DAG パスと特定のコンポーネントへの MObject リファレンスの両方に対してこのクラスを初期化すると、イテレータをエッジや頂点など特定のコンポーネントに隣接するフェースに制限することもできます。
このイテレータは、より迅速にメッシュを調べられるため、メッシュのパーシング処理に便利です。エッジと頂点よりフェースの方が数が少なく、データ取得で重複が少ないからです。フェース イテレータとしての MItMeshPolygon には、主に以下から構成される、フェース固有のデータを取得するメソッドがあります。
MItMeshPolygon は、フェースごとにメッシュを迅速に検索する、またはフェース固有のデータをメッシュから要求する場合に理想的です。このクラスの使用法については、splitUVCmd の例を参照してください。以下は、MItMeshPolygon クラスの使用例です。このサンプル コードでは MItMeshPolygon を使用してメッシュをトラバースして特定のフェースを調べ、そのフェースを構成するエッジを取得しています。
MStatus getFaceEdges( MObject mesh, int faceId, MIntArray faceEdges ) { MStatus status; // Reset the faceEdges array // faceEdges.clear(); // Initialize a face iterator and function set // MItMeshPolygon faceIter( mesh, &status ); MCheckStatus( status, "MItMeshPolygon constructor failed" ); MFnMesh meshFn( mesh, &status ); MCheckStatus( status, "MFnMesh constructor failed" ); // Check to make sure that the faceId passed in is valid // if( faceId >= meshFn.numPolygons() || faceId < 0 ) { cerr << "Invalid faceId.\n"; status = MS::kFailure; } else { // Now parse the mesh for the given face and // return the edges // for( ; !faceIter.isDone(); faceIter.next() ) { // If we find the matching face, retrieve the // edge indices // if( faceIter.index() == faceId ) { faceIter.getEdges( faceEdges ); break; } } } return status; }
MItMeshEdge は、エッジごとにメッシュを反復処理し、エッジ固有のデータを取得します。このエッジ イテレータは、エッジ ID の順序でエッジを反復処理するか、渡されたコンポーネントに隣接するエッジを反復処理します。MltMeshEdge では、以下のタイプのデータを取得できます。
MItMeshEdge は、メッシュをエッジごとに調べ、エッジ固有のデータを取得する場合に最適です。以下のサンプル コードは、このエッジ イテレータの使用例です。この例では、メッシュのそれぞれのエッジが調べられ、開始頂点が収集されて、エッジ ID でインデックス付けされた配列内に保存されます。
MStatus getEdgeStartVertices( MObject mesh, MPointArray& pointArray ) { MStatus status; // Clear the output array // pointArray.clear(); // Initialize our iterator // MItMeshEdge edgeIter( mesh, &status ); MCheckStatus( status, "MItMeshEdge constructor failed" ); // Now parse the mesh // for( ; !edgeIter.isDone(); edgeIter.next() ) { // Retrieve the start vertex of each edge and append it to // our point array. Use the default object coordinate // system for our space // pointArray.append( edgeIter.point(0, MSpace::kObject) ); } return status; }
MItMeshVertex は、頂点 ID の順序で頂点ごとにメッシュを反復処理し、頂点固有のデータを取得します。この頂点イテレータは、2 つのケースに最適で、以下のような頂点固有データを取得できます。
MItMeshFaceVertex イテレータは、フェース ID の順序でフェース頂点ごとにメッシュを調べ、フェース頂点固有のデータを取得します。このフェース頂点イテレータでは、以下のようなデータを取得できます。
MFnMesh には、メッシュ固有データを取得してメッシュを修正するメソッドが複数含まれています。イテレータを使用して特定のコンポーネントを検索し、MFnMesh を使用してそのコンポーネント上で操作を実行します。これについては、splitUVCmd の例で説明します。この例ではメッシュで特定の UV を検索し、MFnMesh を使用して UV を「分割」します。
MFnMesh が提供するメソッドと MItMesh* イテレータは重複する部分がありますが、MFnMesh はメッシュ操作のグローバル ライブラリを表し、イテレータは各コンポーネントまわりを中心としたものです。以下のサンプル コードは、MFnMesh の一部の使用例です。この例では各種データを取得して修正します。このコードはコンパイルできないことに注意してください。
// The argument list contains a "..." to represent a "Fill in // the data you would like here" // MStatus getRandomPolyData( MObject mesh, ... ) { MStatus status; // Initialize a function set to a polygonal mesh // MFnMesh meshFn( mesh, &status ); MCheckStatus( status, "MFnMesh constructor failed" ); // Retrieve topological information // int faceCount = meshFn.numPolygons(); int edgeCount = meshFn.numEdges(); int vertexCount = meshFn.numVertices(); int faceVertexCount = meshFn.polygonVertexCount(); int UVCount = meshFn.numUVs(); MPointArray vertexList; meshFn.getPoints( vertexList ); MFloatArray UArray; MFloatArray VArray; meshFn.getUVs( UArray, VArray ); // Modify topological information // // Add a UV to the UV list – setUV will automatically grow // the UV list, based on the given index // meshFn.setUV( numUVs, 0.0, 0.0 ); // Move vertex 0 to the origin of the world // MPoint origin( 0.0, 0.0. 0.0 ); meshFn.setPoint( 0, origin, MSpace::kWorld ); // Can also work with: // // - Vertex Colors // - Blind data // - etc. // }