private void create_truncated_icosahedron( ) { num_verts = 60; int idx; for (idx = 0; idx < num_verts; idx++) { FILL(trunc_icosa_vtxArray[idx, 0], trunc_icosa_vtxArray[idx, 1], trunc_icosa_vtxArray[idx, 2]); } num_faces = 32; for (idx = 0; idx < num_faces; idx++) { faceCounts.append(trunc_icosa_faceCountArray[idx]); } for (idx = 0; idx < 180; idx++) { faceConnects.append(trunc_icosa_faceConnectArray[idx]); } }
//====================================================================== // // Do the metadata creation. The metadata will be randomly initialized // based on the channel type and the structure specified. For recognized // components the number of metadata elements will correspond to the count // of components in the selected mesh, otherwise a random number of metadata // elements between 1 and 100 will be created (at consecutive indices). // // The previously existing metadata is preserved for later undo. // override public void doIt(MArgList args) { MArgDatabase argsDb = new MArgDatabase(syntax, args); checkArgs(ref argsDb); clearResult(); uint numNodes = fNodes.length; int i; for (i = 0; i < numNodes; ++i) { // fNodes[i] is the transform not the shape itself MFnDagNode dagNode = new MFnDagNode(fNodes[i]); MObject obj = dagNode.child(0); // obj is the shape, which is where we can add the meta data MFnDependencyNode node = new MFnDependencyNode(obj); // Get the current metadata (empty if none yet) Associations newMetadata = new Associations(node.metadata); Channel newChannel = newMetadata.channel(fChannelType); // Check to see if the requested stream name already exists Stream oldStream = newChannel.dataStream(fStreamName); if (oldStream != null) { string fmt = MStringResource.getString(MetaDataRegisterMStringResources.kCreateMetadataHasStream); string msg = String.Format(fmt, fStreamName); MGlobal.displayError( msg ); continue; } Stream newStream = new Stream(fStructure, fStreamName); string strmName = newStream.name; int indexCount = 0; MFnMesh mesh = null; Random rndIndexCount = new Random(); // Treat the channel type initializations different for meshes if (obj.hasFn(MFn.Type.kMesh)) { mesh = new MFnMesh(obj); // Get mesh-specific channel type parameters if (fChannelType == "face") { indexCount = mesh.numPolygons; } else if (fChannelType == "edge") { indexCount = mesh.numEdges; } else if (fChannelType == "vertex") { indexCount = mesh.numVertices; } else if (fChannelType == "vertexFace") { indexCount = mesh.numFaceVertices; } else { // Set a random number between 1 to 100 indexCount = rndIndexCount.Next(1, 100); } } else { // Create generic channel type information indexCount = rndIndexCount.Next(1, 100); } // Fill specified stream ranges with random data int structureMemberCount = fStructure.memberCount; uint m,n,d; Random rnd = new Random(); for (m = 0; m < indexCount; ++m) { // Walk each structure member and fill with random data // tailored to the member data type. Handle handle = new Handle(fStructure); for (n = 0; n < structureMemberCount; ++n) { handle.setPositionByMemberIndex(n); switch (handle.dataType) { case Member.eDataType.kBoolean: { bool[] data = new bool[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { int randomInt = rnd.Next(0, 2); bool randomBool = randomInt == 1 ? true : false; data[d] = randomBool; } handle.asBooleanArray = data; break; } case Member.eDataType.kDouble: { double[] data = new double[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { // Set a random number between -2000000000.0.0 and 2000000000.0.0 data[d] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; } handle.asDoubleArray = data; break; } case Member.eDataType.kDoubleMatrix4x4: { double[] data = new double[handle.dataLength * 16]; for (d = 0; d < handle.dataLength; ++d) { data[d*16+0] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+1] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+2] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+3] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+4] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+5] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+6] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+7] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+8] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+9] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+10] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+11] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+12] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+13] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+14] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; data[d*16+15] = rnd.NextDouble()*4000000000.0 - 2000000000.0 ; } handle.asDoubleMatrix4x4 = data; break; } case Member.eDataType.kFloat: { float[] data = new float[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { // Set a random number between -2000000.0 and 2000000.0 data[d] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; } handle.asFloatArray = data; break; } case Member.eDataType.kFloatMatrix4x4: { float[] data = new float[handle.dataLength * 16]; for (d = 0; d < handle.dataLength; ++d) { // Set a random number between -2000000.0 and 2000000.0 data[d*16+0] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+1] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+2] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+3] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+4] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+5] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+6] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+7] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+8] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+9] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+10] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+11] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+12] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+13] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+14] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; data[d*16+15] = (float)rnd.NextDouble()*4000000.0f - 2000000.0f ; } handle.asFloatMatrix4x4 = data; break; } case Member.eDataType.kInt8: { sbyte[] data = new sbyte[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (sbyte)rnd.Next(SByte.MinValue, SByte.MaxValue+1); } handle.asInt8Array = data; break; } case Member.eDataType.kInt16: { short[] data = new short[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (short)rnd.Next(Int16.MinValue, Int16.MaxValue+1); } handle.asInt16Array = data; break; } case Member.eDataType.kInt32: { int[] data = new int[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { // rnd.Next returns a number between [arg1,arg2[ // but unfortunately I can't pass Int32.MaxValue+1 here.... data[d] = rnd.Next(Int32.MinValue, Int32.MaxValue); } handle.asInt32Array = data; break; } case Member.eDataType.kInt64: { long[] data = new long[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { // rnd.Next() gives a number between [0,Int32 data[d] = (long)rnd.Next(Int32.MinValue, Int32.MaxValue); if( data[d] >= 0 ) data[d] *= Int64.MaxValue / Int32.MaxValue; else data[d] *= Int64.MinValue / Int32.MinValue; } handle.asInt64Array = data; break; } case Member.eDataType.kUInt8: { byte[] data = new byte[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (byte)rnd.Next(0, Byte.MaxValue + 1); } handle.asUInt8Array = data; break; } case Member.eDataType.kUInt16: { ushort[] data = new ushort[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (ushort)rnd.Next(0, UInt16.MaxValue + 1); } handle.asUInt16Array = data; break; } case Member.eDataType.kUInt32: { uint[] data = new uint[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (uint)rnd.Next(); } handle.asUInt32Array = data; break; } case Member.eDataType.kUInt64: { ulong[] data = new ulong[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = ((ulong)rnd.Next()) * UInt64.MaxValue / UInt32.MaxValue; } handle.asUInt64Array = data; break; } case Member.eDataType.kString: { string[] randomStrings = new string[] { "banana", "tomatoe", "apple", "pineapple", "apricot", "pepper", "olive", "grapefruit" }; string[] data = new string[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { int index = rnd.Next( randomStrings.Length ); data[d] = randomStrings[index]; } handle.asStringArray = data; break; } default: { Debug.Assert(false, "This should never happen"); break; } } } newStream.setElement(new Index(m), handle); } newChannel.setDataStream(newStream); newMetadata.setChannel(newChannel); // Note: the following will not work if "obj" is a shape constructed by a source object // You need to delete the history of the shape before calling this... fDGModifier.setMetadata(obj, newMetadata); fDGModifier.doIt(); // Set the result to the number of actual metadata values set as a // triple value: // (# nodes, # metadata elements, # members per element) // MIntArray theResult = new MIntArray(); theResult.append( (int) fNodes.length ); theResult.append( (int) indexCount ); theResult.append( (int) structureMemberCount ); setResult( theResult ); } }
public void Load(string name) { List <StaticObjectVertex> vertices = GetVertices(); List <uint> indices = GetIndices(); MIntArray polygonIndexCounts = new MIntArray((uint)indices.Count / 3); MIntArray polygonIndices = new MIntArray((uint)indices.Count); MFloatPointArray meshVertices = new MFloatPointArray((uint)vertices.Count); MFloatArray arrayU = new MFloatArray((uint)vertices.Count); MFloatArray arrayV = new MFloatArray((uint)vertices.Count); MFnMesh mesh = new MFnMesh(); MDagPath meshDagPath = new MDagPath(); MDGModifier modifier = new MDGModifier(); MFnSet set = new MFnSet(); for (int i = 0; i < indices.Count / 3; i++) { polygonIndexCounts[i] = 3; } for (int i = 0; i < indices.Count; i++) { polygonIndices[i] = (int)indices[i]; } for (int i = 0; i < vertices.Count; i++) { StaticObjectVertex vertex = vertices[i]; meshVertices[i] = new MFloatPoint(vertex.Position.X, vertex.Position.Y, vertex.Position.Z); arrayU[i] = vertex.UV.X; arrayV[i] = 1 - vertex.UV.Y; } //Assign mesh data mesh.create(vertices.Count, indices.Count / 3, meshVertices, polygonIndexCounts, polygonIndices, arrayU, arrayV, MObject.kNullObj); mesh.getPath(meshDagPath); mesh.assignUVs(polygonIndexCounts, polygonIndices); //Set names mesh.setName(name); MFnTransform transformNode = new MFnTransform(mesh.parent(0)); transformNode.setName("transform_" + name); //Get render partition MFnPartition renderPartition = MayaHelper.FindRenderPartition(); //Create Materials uint startIndex = 0; for (int i = 0; i < this.Submeshes.Count; i++) { MFnDependencyNode dependencyNode = new MFnDependencyNode(); MFnLambertShader lambertShader = new MFnLambertShader(); StaticObjectSubmesh submesh = this.Submeshes[i]; lambertShader.create(true); lambertShader.setName(submesh.Name); lambertShader.color = MaterialProvider.GetMayaColor(i); MObject shadingEngine = dependencyNode.create("shadingEngine", submesh.Name + "_SG"); MObject materialInfo = dependencyNode.create("materialInfo", submesh.Name + "_MaterialInfo"); MPlug partitionPlug = new MFnDependencyNode(shadingEngine).findPlug("partition"); MPlug setsPlug = MayaHelper.FindFirstNotConnectedElement(renderPartition.findPlug("sets")); modifier.connect(partitionPlug, setsPlug); MPlug outColorPlug = lambertShader.findPlug("outColor"); MPlug surfaceShaderPlug = new MFnDependencyNode(shadingEngine).findPlug("surfaceShader"); modifier.connect(outColorPlug, surfaceShaderPlug); MPlug messagePlug = new MFnDependencyNode(shadingEngine).findPlug("message"); MPlug shadingGroupPlug = new MFnDependencyNode(materialInfo).findPlug("shadingGroup"); modifier.connect(messagePlug, shadingGroupPlug); modifier.doIt(); MFnSingleIndexedComponent component = new MFnSingleIndexedComponent(); MObject faceComponent = component.create(MFn.Type.kMeshPolygonComponent); MIntArray groupPolygonIndices = new MIntArray(); uint endIndex = (startIndex + (uint)submesh.Indices.Count) / 3; for (uint j = startIndex / 3; j < endIndex; j++) { groupPolygonIndices.append((int)j); } component.addElements(groupPolygonIndices); set.setObject(shadingEngine); set.addMember(meshDagPath, faceComponent); startIndex += (uint)submesh.Indices.Count; } mesh.updateSurface(); }
//====================================================================== // // Do the metadata creation. The metadata will be randomly initialized // based on the channel type and the structure specified. For recognized // components the number of metadata elements will correspond to the count // of components in the selected mesh, otherwise a random number of metadata // elements between 1 and 100 will be created (at consecutive indices). // // The previously existing metadata is preserved for later undo. // override public void doIt(MArgList args) { MArgDatabase argsDb = new MArgDatabase(syntax, args); checkArgs(ref argsDb); clearResult(); uint numNodes = fNodes.length; int i; for (i = 0; i < numNodes; ++i) { // fNodes[i] is the transform not the shape itself MFnDagNode dagNode = new MFnDagNode(fNodes[i]); MObject obj = dagNode.child(0); // obj is the shape, which is where we can add the meta data MFnDependencyNode node = new MFnDependencyNode(obj); // Get the current metadata (empty if none yet) Associations newMetadata = new Associations(node.metadata); Channel newChannel = newMetadata.channel(fChannelType); // Check to see if the requested stream name already exists Stream oldStream = newChannel.dataStream(fStreamName); if (oldStream != null) { string fmt = MStringResource.getString(MetaDataRegisterMStringResources.kCreateMetadataHasStream); string msg = String.Format(fmt, fStreamName); MGlobal.displayError(msg); continue; } Stream newStream = new Stream(fStructure, fStreamName); string strmName = newStream.name; int indexCount = 0; MFnMesh mesh = null; Random rndIndexCount = new Random(); // Treat the channel type initializations different for meshes if (obj.hasFn(MFn.Type.kMesh)) { mesh = new MFnMesh(obj); // Get mesh-specific channel type parameters if (fChannelType == "face") { indexCount = mesh.numPolygons; } else if (fChannelType == "edge") { indexCount = mesh.numEdges; } else if (fChannelType == "vertex") { indexCount = mesh.numVertices; } else if (fChannelType == "vertexFace") { indexCount = mesh.numFaceVertices; } else { // Set a random number between 1 to 100 indexCount = rndIndexCount.Next(1, 100); } } else { // Create generic channel type information indexCount = rndIndexCount.Next(1, 100); } // Fill specified stream ranges with random data int structureMemberCount = fStructure.memberCount; uint m, n, d; Random rnd = new Random(); for (m = 0; m < indexCount; ++m) { // Walk each structure member and fill with random data // tailored to the member data type. Handle handle = new Handle(fStructure); for (n = 0; n < structureMemberCount; ++n) { handle.setPositionByMemberIndex(n); switch (handle.dataType) { case Member.eDataType.kBoolean: { bool[] data = new bool[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { int randomInt = rnd.Next(0, 2); bool randomBool = randomInt == 1 ? true : false; data[d] = randomBool; } handle.asBooleanArray = data; break; } case Member.eDataType.kDouble: { double[] data = new double[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { // Set a random number between -2000000000.0.0 and 2000000000.0.0 data[d] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; } handle.asDoubleArray = data; break; } case Member.eDataType.kDoubleMatrix4x4: { double[] data = new double[handle.dataLength * 16]; for (d = 0; d < handle.dataLength; ++d) { data[d * 16 + 0] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 1] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 2] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 3] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 4] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 5] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 6] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 7] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 8] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 9] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 10] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 11] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 12] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 13] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 14] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 15] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; } handle.asDoubleMatrix4x4 = data; break; } case Member.eDataType.kFloat: { float[] data = new float[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { // Set a random number between -2000000.0 and 2000000.0 data[d] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; } handle.asFloatArray = data; break; } case Member.eDataType.kFloatMatrix4x4: { float[] data = new float[handle.dataLength * 16]; for (d = 0; d < handle.dataLength; ++d) { // Set a random number between -2000000.0 and 2000000.0 data[d * 16 + 0] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 1] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 2] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 3] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 4] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 5] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 6] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 7] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 8] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 9] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 10] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 11] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 12] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 13] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 14] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 15] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; } handle.asFloatMatrix4x4 = data; break; } case Member.eDataType.kInt8: { sbyte[] data = new sbyte[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (sbyte)rnd.Next(SByte.MinValue, SByte.MaxValue + 1); } handle.asInt8Array = data; break; } case Member.eDataType.kInt16: { short[] data = new short[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (short)rnd.Next(Int16.MinValue, Int16.MaxValue + 1); } handle.asInt16Array = data; break; } case Member.eDataType.kInt32: { int[] data = new int[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { // rnd.Next returns a number between [arg1,arg2[ // but unfortunately I can't pass Int32.MaxValue+1 here.... data[d] = rnd.Next(Int32.MinValue, Int32.MaxValue); } handle.asInt32Array = data; break; } case Member.eDataType.kInt64: { long[] data = new long[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { // rnd.Next() gives a number between [0,Int32 data[d] = (long)rnd.Next(Int32.MinValue, Int32.MaxValue); if (data[d] >= 0) { data[d] *= Int64.MaxValue / Int32.MaxValue; } else { data[d] *= Int64.MinValue / Int32.MinValue; } } handle.asInt64Array = data; break; } case Member.eDataType.kUInt8: { byte[] data = new byte[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (byte)rnd.Next(0, Byte.MaxValue + 1); } handle.asUInt8Array = data; break; } case Member.eDataType.kUInt16: { ushort[] data = new ushort[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (ushort)rnd.Next(0, UInt16.MaxValue + 1); } handle.asUInt16Array = data; break; } case Member.eDataType.kUInt32: { uint[] data = new uint[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (uint)rnd.Next(); } handle.asUInt32Array = data; break; } case Member.eDataType.kUInt64: { ulong[] data = new ulong[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = ((ulong)rnd.Next()) * UInt64.MaxValue / UInt32.MaxValue; } handle.asUInt64Array = data; break; } case Member.eDataType.kString: { string[] randomStrings = new string[] { "banana", "tomatoe", "apple", "pineapple", "apricot", "pepper", "olive", "grapefruit" }; string[] data = new string[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { int index = rnd.Next(randomStrings.Length); data[d] = randomStrings[index]; } handle.asStringArray = data; break; } default: { Debug.Assert(false, "This should never happen"); break; } } } newStream.setElement(new Index(m), handle); } newChannel.setDataStream(newStream); newMetadata.setChannel(newChannel); // Note: the following will not work if "obj" is a shape constructed by a source object // You need to delete the history of the shape before calling this... fDGModifier.setMetadata(obj, newMetadata); fDGModifier.doIt(); // Set the result to the number of actual metadata values set as a // triple value: // (# nodes, # metadata elements, # members per element) // MIntArray theResult = new MIntArray(); theResult.append((int)fNodes.length); theResult.append((int)indexCount); theResult.append((int)structureMemberCount); setResult(theResult); } }
// // Description // // Create circles of vertices starting with // the top pole ending with the bottom pole // public void buildSphere(double rad, int div, MPointArray vertices, MIntArray counts, MIntArray connects, MVectorArray normals, apiMeshGeomUV uvs) { double u = -Math.PI / 2.0; double v = -Math.PI; double u_delta = Math.PI / ((double)div); double v_delta = 2 * Math.PI / ((double)div); MPoint topPole = new MPoint( 0.0, rad, 0.0 ); MPoint botPole = new MPoint( 0.0, -rad, 0.0 ); // Build the vertex and normal table // vertices.append( botPole ); normals.append( botPole.minus(MPoint.origin) ); int i; for ( i=0; i<(div-1); i++ ) { u += u_delta; v = -Math.PI; for ( int j=0; j<div; j++ ) { double x = rad * Math.Cos(u) * Math.Cos(v); double y = rad * Math.Sin(u); double z = rad * Math.Cos(u) * Math.Sin(v) ; MPoint pnt = new MPoint( x, y, z ); vertices.append( pnt ); normals.append( pnt.minus(MPoint.origin) ); v += v_delta; } } vertices.append( topPole ); normals.append( topPole.minus(MPoint.origin) ); // Create the connectivity lists // int vid = 1; int numV = 0; for ( i=0; i<div; i++ ) { for ( int j=0; j<div; j++ ) { if ( i==0 ) { counts.append( 3 ); connects.append( 0 ); connects.append( j+vid ); connects.append( (j==(div-1)) ? vid : j+vid+1 ); } else if ( i==(div-1) ) { counts.append( 3 ); connects.append( j+vid+1-div ); connects.append( vid+1 ); connects.append( j==(div-1) ? vid+1-div : j+vid+2-div ); } else { counts.append( 4 ); connects.append( j + vid+1-div ); connects.append( j + vid+1 ); connects.append( j == (div-1) ? vid+1 : j+vid+2 ); connects.append( j == (div-1) ? vid+1-div : j+vid+2-div ); } numV++; } vid = numV; } // TODO: Define UVs for sphere ... // }
public void Load(string name, SKLFile skl = null) { MIntArray polygonIndexCounts = new MIntArray((uint)this.Indices.Count / 3); MIntArray polygonIndices = new MIntArray((uint)this.Indices.Count); MFloatPointArray vertices = new MFloatPointArray((uint)this.Vertices.Count); MFloatArray arrayU = new MFloatArray((uint)this.Vertices.Count); MFloatArray arrayV = new MFloatArray((uint)this.Vertices.Count); MVectorArray normals = new MVectorArray((uint)this.Vertices.Count); MIntArray normalIndices = new MIntArray((uint)this.Vertices.Count); MFnMesh mesh = new MFnMesh(); MDagPath meshDagPath = new MDagPath(); MDGModifier modifier = new MDGModifier(); MFnSet set = new MFnSet(); for (int i = 0; i < this.Indices.Count / 3; i++) { polygonIndexCounts[i] = 3; } for (int i = 0; i < this.Indices.Count; i++) { polygonIndices[i] = this.Indices[i]; } for (int i = 0; i < this.Vertices.Count; i++) { SKNVertex vertex = this.Vertices[i]; vertices[i] = new MFloatPoint(vertex.Position.X, vertex.Position.Y, vertex.Position.Z); arrayU[i] = vertex.UV.X; arrayV[i] = 1 - vertex.UV.Y; normals[i] = new MVector(vertex.Normal.X, vertex.Normal.Y, vertex.Normal.Z); normalIndices[i] = i; } //Assign mesh data mesh.create(this.Vertices.Count, this.Indices.Count / 3, vertices, polygonIndexCounts, polygonIndices, arrayU, arrayV, MObject.kNullObj); mesh.setVertexNormals(normals, normalIndices); mesh.getPath(meshDagPath); mesh.assignUVs(polygonIndexCounts, polygonIndices); //Set names mesh.setName(name); MFnTransform transformNode = new MFnTransform(mesh.parent(0)); transformNode.setName("transform_" + name); //Get render partition MGlobal.displayInfo("SKNFile:Load - Searching for Render Partition"); MItDependencyNodes itDependencyNodes = new MItDependencyNodes(MFn.Type.kPartition); MFnPartition renderPartition = new MFnPartition(); bool foundRenderPartition = false; for (; !itDependencyNodes.isDone; itDependencyNodes.next()) { renderPartition.setObject(itDependencyNodes.thisNode); MGlobal.displayInfo("SKNFile:Load - Iterating through partition: " + renderPartition.name + " IsRenderPartition: " + renderPartition.isRenderPartition); if (renderPartition.name == "renderPartition" && renderPartition.isRenderPartition) { MGlobal.displayInfo("SKNFile:Load - Found render partition"); foundRenderPartition = true; break; } } //Create Materials for (int i = 0; i < this.Submeshes.Count; i++) { MFnDependencyNode dependencyNode = new MFnDependencyNode(); MFnLambertShader lambertShader = new MFnLambertShader(); SKNSubmesh submesh = this.Submeshes[i]; MObject shader = lambertShader.create(true); lambertShader.setName(submesh.Name); lambertShader.color = MaterialProvider.GetMayaColor(i); MObject shadingEngine = dependencyNode.create("shadingEngine", submesh.Name + "_SG"); MObject materialInfo = dependencyNode.create("materialInfo", submesh.Name + "_MaterialInfo"); if (foundRenderPartition) { MPlug partitionPlug = new MFnDependencyNode(shadingEngine).findPlug("partition"); MPlug setsPlug = MayaHelper.FindFirstNotConnectedElement(renderPartition.findPlug("sets")); modifier.connect(partitionPlug, setsPlug); } else { MGlobal.displayInfo("SKNFile:Load - Couldn't find Render Partition for mesh: " + name + "." + submesh.Name); } MPlug outColorPlug = lambertShader.findPlug("outColor"); MPlug surfaceShaderPlug = new MFnDependencyNode(shadingEngine).findPlug("surfaceShader"); modifier.connect(outColorPlug, surfaceShaderPlug); MPlug messagePlug = new MFnDependencyNode(shadingEngine).findPlug("message"); MPlug shadingGroupPlug = new MFnDependencyNode(materialInfo).findPlug("shadingGroup"); modifier.connect(messagePlug, shadingGroupPlug); modifier.doIt(); MFnSingleIndexedComponent component = new MFnSingleIndexedComponent(); MObject faceComponent = component.create(MFn.Type.kMeshPolygonComponent); MIntArray groupPolygonIndices = new MIntArray(); uint endIndex = (submesh.StartIndex + submesh.IndexCount) / 3; for (uint j = submesh.StartIndex / 3; j < endIndex; j++) { groupPolygonIndices.append((int)j); } component.addElements(groupPolygonIndices); set.setObject(shadingEngine); set.addMember(meshDagPath, faceComponent); } if (skl == null) { mesh.updateSurface(); } else { MFnSkinCluster skinCluster = new MFnSkinCluster(); MSelectionList jointPathsSelectionList = new MSelectionList(); jointPathsSelectionList.add(meshDagPath); for (int i = 0; i < skl.Influences.Count; i++) { short jointIndex = skl.Influences[i]; SKLJoint joint = skl.Joints[jointIndex]; jointPathsSelectionList.add(skl.JointDagPaths[jointIndex]); MGlobal.displayInfo(string.Format("SKNFile:Load:Bind - Added joint [{0}] {1} to binding selection", joint.ID, joint.Name)); } MGlobal.selectCommand(jointPathsSelectionList); MGlobal.executeCommand("skinCluster -mi 4 -tsb -n skinCluster_" + name); MPlug inMeshPlug = mesh.findPlug("inMesh"); MPlugArray inMeshConnections = new MPlugArray(); inMeshPlug.connectedTo(inMeshConnections, true, false); if (inMeshConnections.length == 0) { MGlobal.displayError("SKNFile:Load:Bind - Failed to find the created Skin Cluster"); throw new Exception("SKNFile:Load:Bind - Failed to find the created Skin Cluster"); } MPlug outputGeometryPlug = inMeshConnections[0]; MDagPathArray influencesDagPaths = new MDagPathArray(); skinCluster.setObject(outputGeometryPlug.node); skinCluster.influenceObjects(influencesDagPaths); MIntArray influenceIndices = new MIntArray((uint)skl.Influences.Count); for (int i = 0; i < skl.Influences.Count; i++) { MDagPath influencePath = skl.JointDagPaths[skl.Influences[i]]; for (int j = 0; j < skl.Influences.Count; j++) { if (influencesDagPaths[j].partialPathName == influencePath.partialPathName) { influenceIndices[i] = j; MGlobal.displayInfo("SKNReader:Load:Bind - Added Influence Joint: " + i + " -> " + j); break; } } } MFnSingleIndexedComponent singleIndexedComponent = new MFnSingleIndexedComponent(); MObject vertexComponent = singleIndexedComponent.create(MFn.Type.kMeshVertComponent); MIntArray groupVertexIndices = new MIntArray((uint)this.Vertices.Count); for (int i = 0; i < this.Vertices.Count; i++) { groupVertexIndices[i] = i; } singleIndexedComponent.addElements(groupVertexIndices); MGlobal.executeCommand(string.Format("setAttr {0}.normalizeWeights 0", skinCluster.name)); MDoubleArray weights = new MDoubleArray((uint)(this.Vertices.Count * skl.Influences.Count)); for (int i = 0; i < this.Vertices.Count; i++) { SKNVertex vertex = this.Vertices[i]; for (int j = 0; j < 4; j++) { double weight = vertex.Weights[j]; int influence = vertex.BoneIndices[j]; if (weight != 0) { weights[(i * skl.Influences.Count) + influence] = weight; } } } skinCluster.setWeights(meshDagPath, vertexComponent, influenceIndices, weights, false); MGlobal.executeCommand(string.Format("setAttr {0}.normalizeWeights 1", skinCluster.name)); MGlobal.executeCommand(string.Format("skinPercent -normalize true {0} {1}", skinCluster.name, mesh.name)); mesh.updateSurface(); } }
// // Description // // Constructs a cube // public void buildCube(double cube_size, MPointArray pa, MIntArray faceCounts, MIntArray faceConnects, MVectorArray normals, apiMeshGeomUV uvs) { const int num_faces = 6; const int num_face_connects = 24; const double normal_value = 0.5775; const int uv_count = 14; pa.clear(); faceCounts.clear(); faceConnects.clear(); uvs.reset(); pa.append( new MPoint( -cube_size, -cube_size, -cube_size ) ); pa.append( new MPoint( cube_size, -cube_size, -cube_size ) ); pa.append( new MPoint( cube_size, -cube_size, cube_size ) ); pa.append( new MPoint( -cube_size, -cube_size, cube_size ) ); pa.append( new MPoint( -cube_size, cube_size, -cube_size ) ); pa.append( new MPoint( -cube_size, cube_size, cube_size ) ); pa.append( new MPoint( cube_size, cube_size, cube_size ) ); pa.append( new MPoint( cube_size, cube_size, -cube_size ) ); normals.append( new MVector( -normal_value, -normal_value, -normal_value ) ); normals.append( new MVector( normal_value, -normal_value, -normal_value ) ); normals.append( new MVector( normal_value, -normal_value, normal_value ) ); normals.append( new MVector( -normal_value, -normal_value, normal_value ) ); normals.append( new MVector( -normal_value, normal_value, -normal_value ) ); normals.append( new MVector( -normal_value, normal_value, normal_value ) ); normals.append( new MVector( normal_value, normal_value, normal_value ) ); normals.append( new MVector( normal_value, normal_value, -normal_value ) ); // Define the UVs for the cube. // float[] uv_pts = new float[uv_count*2] { 0.375f, 0.0f, 0.625f, 0.0f, 0.625f, 0.25f, 0.375f, 0.25f, 0.625f, 0.5f, 0.375f, 0.5f, 0.625f, 0.75f, 0.375f, 0.75f, 0.625f, 1.0f, 0.375f, 1.0f, 0.875f, 0.0f, 0.875f, 0.25f, 0.125f, 0.0f, 0.125f, 0.25f }; // UV Face Vertex Id. // int[] uv_fvid = new int[num_face_connects]{ 0, 1, 2, 3, 3, 2, 4, 5, 5, 4, 6, 7, 7, 6, 8, 9, 1, 10, 11, 2, 12, 0, 3, 13 }; int i; for ( i = 0; i < uv_count; i ++ ) { uvs.append_uv( uv_pts[i*2], uv_pts[i*2 + 1] ); } for ( i = 0; i < num_face_connects; i ++ ) { uvs.faceVertexIndex.append( uv_fvid[i] ); } // Set up an array containing the number of vertices // for each of the 6 cube faces (4 vertices per face) // int[] face_counts = new int[num_faces]{ 4, 4, 4, 4, 4, 4 }; for ( i=0; i<num_faces; i++ ) { faceCounts.append( face_counts[i] ); } // Set up and array to assign vertices from pa to each face // int[] face_connects = new int[ num_face_connects ]{ 0, 1, 2, 3, 4, 5, 6, 7, 3, 2, 6, 5, 0, 3, 5, 4, 0, 4, 7, 1, 1, 7, 6, 2 }; for ( i=0; i<num_face_connects; i++ ) { faceConnects.append( face_connects[i] ); } }
// // Description // // This function takes an input surface of type kMeshData and converts // the geometry into this nodes attributes. // Returns false if nothing is connected. // public bool computeInputMesh(MPlug plug, MDataBlock datablock, MPointArray vertices, MIntArray counts, MIntArray connects, MVectorArray normals, apiMeshGeomUV uvs) { // Get the input subdiv // MDataHandle inputData = datablock.inputValue( inputMesh ); MObject surf = inputData.asMesh; // Check if anything is connected // MObject thisObj = thisMObject(); MPlug surfPlug = new MPlug( thisObj, inputMesh ); if ( !surfPlug.isConnected ) { datablock.setClean( plug ); return false; } // Extract the mesh data // MFnMesh surfFn = new MFnMesh(surf); surfFn.getPoints( vertices, MSpace.Space.kObject ); // Check to see if we have UVs to copy. // bool hasUVs = surfFn.numUVsProperty > 0; surfFn.getUVs( uvs.ucoord, uvs.vcoord ); for ( int i=0; i<surfFn.numPolygons; i++ ) { MIntArray polyVerts = new MIntArray(); surfFn.getPolygonVertices( i, polyVerts ); int pvc = (int)polyVerts.length; counts.append( pvc ); int uvId; for ( int v=0; v<pvc; v++ ) { if ( hasUVs ) { surfFn.getPolygonUVid( i, v, out uvId ); uvs.faceVertexIndex.append( uvId ); } connects.append( polyVerts[v] ); } } for ( int n=0; n<(int)vertices.length; n++ ) { MVector normal = new MVector(); surfFn.getVertexNormal( n, normal ); normals.append( normal ); } return true; }
// // Description // // Create circles of vertices starting with // the top pole ending with the bottom pole // public void buildSphere(double rad, int div, MPointArray vertices, MIntArray counts, MIntArray connects, MVectorArray normals, apiMeshGeomUV uvs) { double u = -Math.PI / 2.0; double v = -Math.PI; double u_delta = Math.PI / ((double)div); double v_delta = 2 * Math.PI / ((double)div); MPoint topPole = new MPoint(0.0, rad, 0.0); MPoint botPole = new MPoint(0.0, -rad, 0.0); // Build the vertex and normal table // vertices.append(botPole); normals.append(botPole.minus(MPoint.origin)); int i; for (i = 0; i < (div - 1); i++) { u += u_delta; v = -Math.PI; for (int j = 0; j < div; j++) { double x = rad * Math.Cos(u) * Math.Cos(v); double y = rad * Math.Sin(u); double z = rad * Math.Cos(u) * Math.Sin(v); MPoint pnt = new MPoint(x, y, z); vertices.append(pnt); normals.append(pnt.minus(MPoint.origin)); v += v_delta; } } vertices.append(topPole); normals.append(topPole.minus(MPoint.origin)); // Create the connectivity lists // int vid = 1; int numV = 0; for (i = 0; i < div; i++) { for (int j = 0; j < div; j++) { if (i == 0) { counts.append(3); connects.append(0); connects.append(j + vid); connects.append((j == (div - 1)) ? vid : j + vid + 1); } else if (i == (div - 1)) { counts.append(3); connects.append(j + vid + 1 - div); connects.append(vid + 1); connects.append(j == (div - 1) ? vid + 1 - div : j + vid + 2 - div); } else { counts.append(4); connects.append(j + vid + 1 - div); connects.append(j + vid + 1); connects.append(j == (div - 1) ? vid + 1 : j + vid + 2); connects.append(j == (div - 1) ? vid + 1 - div : j + vid + 2 - div); } numV++; } vid = numV; } // TODO: Define UVs for sphere ... // }
// // Description // // Constructs a cube // public void buildCube(double cube_size, MPointArray pa, MIntArray faceCounts, MIntArray faceConnects, MVectorArray normals, apiMeshGeomUV uvs) { const int num_faces = 6; const int num_face_connects = 24; const double normal_value = 0.5775; const int uv_count = 14; pa.clear(); faceCounts.clear(); faceConnects.clear(); uvs.reset(); pa.append(new MPoint(-cube_size, -cube_size, -cube_size)); pa.append(new MPoint(cube_size, -cube_size, -cube_size)); pa.append(new MPoint(cube_size, -cube_size, cube_size)); pa.append(new MPoint(-cube_size, -cube_size, cube_size)); pa.append(new MPoint(-cube_size, cube_size, -cube_size)); pa.append(new MPoint(-cube_size, cube_size, cube_size)); pa.append(new MPoint(cube_size, cube_size, cube_size)); pa.append(new MPoint(cube_size, cube_size, -cube_size)); normals.append(new MVector(-normal_value, -normal_value, -normal_value)); normals.append(new MVector(normal_value, -normal_value, -normal_value)); normals.append(new MVector(normal_value, -normal_value, normal_value)); normals.append(new MVector(-normal_value, -normal_value, normal_value)); normals.append(new MVector(-normal_value, normal_value, -normal_value)); normals.append(new MVector(-normal_value, normal_value, normal_value)); normals.append(new MVector(normal_value, normal_value, normal_value)); normals.append(new MVector(normal_value, normal_value, -normal_value)); // Define the UVs for the cube. // float[] uv_pts = new float[uv_count * 2] { 0.375f, 0.0f, 0.625f, 0.0f, 0.625f, 0.25f, 0.375f, 0.25f, 0.625f, 0.5f, 0.375f, 0.5f, 0.625f, 0.75f, 0.375f, 0.75f, 0.625f, 1.0f, 0.375f, 1.0f, 0.875f, 0.0f, 0.875f, 0.25f, 0.125f, 0.0f, 0.125f, 0.25f }; // UV Face Vertex Id. // int[] uv_fvid = new int[num_face_connects] { 0, 1, 2, 3, 3, 2, 4, 5, 5, 4, 6, 7, 7, 6, 8, 9, 1, 10, 11, 2, 12, 0, 3, 13 }; int i; for (i = 0; i < uv_count; i++) { uvs.append_uv(uv_pts[i * 2], uv_pts[i * 2 + 1]); } for (i = 0; i < num_face_connects; i++) { uvs.faceVertexIndex.append(uv_fvid[i]); } // Set up an array containing the number of vertices // for each of the 6 cube faces (4 vertices per face) // int[] face_counts = new int[num_faces] { 4, 4, 4, 4, 4, 4 }; for (i = 0; i < num_faces; i++) { faceCounts.append(face_counts[i]); } // Set up and array to assign vertices from pa to each face // int[] face_connects = new int[num_face_connects] { 0, 1, 2, 3, 4, 5, 6, 7, 3, 2, 6, 5, 0, 3, 5, 4, 0, 4, 7, 1, 1, 7, 6, 2 }; for (i = 0; i < num_face_connects; i++) { faceConnects.append(face_connects[i]); } }
// // Description // // This function takes an input surface of type kMeshData and converts // the geometry into this nodes attributes. // Returns false if nothing is connected. // public bool computeInputMesh(MPlug plug, MDataBlock datablock, MPointArray vertices, MIntArray counts, MIntArray connects, MVectorArray normals, apiMeshGeomUV uvs) { // Get the input subdiv // MDataHandle inputData = datablock.inputValue(inputMesh); MObject surf = inputData.asMesh; // Check if anything is connected // MObject thisObj = thisMObject(); MPlug surfPlug = new MPlug(thisObj, inputMesh); if (!surfPlug.isConnected) { datablock.setClean(plug); return(false); } // Extract the mesh data // MFnMesh surfFn = new MFnMesh(surf); surfFn.getPoints(vertices, MSpace.Space.kObject); // Check to see if we have UVs to copy. // bool hasUVs = surfFn.numUVsProperty > 0; surfFn.getUVs(uvs.ucoord, uvs.vcoord); for (int i = 0; i < surfFn.numPolygons; i++) { MIntArray polyVerts = new MIntArray(); surfFn.getPolygonVertices(i, polyVerts); int pvc = (int)polyVerts.length; counts.append(pvc); int uvId; for (int v = 0; v < pvc; v++) { if (hasUVs) { surfFn.getPolygonUVid(i, v, out uvId); uvs.faceVertexIndex.append(uvId); } connects.append(polyVerts[v]); } } for (int n = 0; n < (int)vertices.length; n++) { MVector normal = new MVector(); surfFn.getVertexNormal(n, normal); normals.append(normal); } return(true); }