//====================================================================== // // 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(); MColorArray myColorArray = new MColorArray(); MFnDependencyNode node = new MFnDependencyNode(fObj); // Get the current metadata (empty if none yet) Associations newMetadata = new Associations(node.metadata); Channel newChannel = newMetadata.channel("vertex"); // 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); return; } StreamForType <MyStructureClass> newStream = new StreamForType <MyStructureClass>(fStreamName); int indexCount = fMesh.numVertices; Random rndIndexCount = new Random(); // Fill specified stream ranges with random data int m; 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. MyStructureClass myClass = new MyStructureClass(); // int myClass.a = rnd.Next(Int32.MinValue, Int32.MaxValue); // float myClass.b = (float)rnd.NextDouble(); // string string[] randomStrings = new string[] { "banana", "tomatoe", "apple", "pineapple", "apricot", "pepper", "olive", "grapefruit" }; int index = rnd.Next(randomStrings.Length); myClass.c = randomStrings[index]; // bool int randomInt = rnd.Next(0, 2); myClass.d = randomInt == 1 ? true : false; myClass.e = rnd.Next(Int32.MinValue, Int32.MaxValue); myClass.f = rnd.Next(Int32.MinValue, Int32.MaxValue); myClass.xyz[0] = (float)rnd.NextDouble(); myClass.xyz[1] = (float)rnd.NextDouble(); myClass.xyz[2] = (float)rnd.NextDouble(); newStream[m] = myClass; } 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(fObj, newMetadata); fDGModifier.doIt(); Associations meshMetadata = fMesh.metadata; // This code is for debugging only { Channel chn = meshMetadata["vertex"]; Console.WriteLine("Channel : type = {0}, nbStreams = {1}", chn.nameProperty, chn.dataStreamCount); Stream chnStream = chn[fStreamName]; Structure strct = chnStream.structure; var strm = new StreamForType <MyStructureClass>(chnStream); Console.WriteLine("Stream : name = {0}, nbElements = {1}", chnStream.name, chnStream.Count); var tomatoes = strm.Where((KeyValuePair <Index, MyStructureClass> keyvalue) => keyvalue.Value.c == "tomatoe"); foreach (var keyvalue in tomatoes) // foreach (MyStructureClass myClass in strm.Values ) { Console.WriteLine("Vertex #{0}, a = {1}", keyvalue.Key.asString, keyvalue.Value.a.ToString()); Console.WriteLine("Vertex #{0}, b = {1}", keyvalue.Key.asString, keyvalue.Value.b.ToString()); Console.WriteLine("Vertex #{0}, c = {1}", keyvalue.Key.asString, keyvalue.Value.c.ToString()); Console.WriteLine("Vertex #{0}, d = {1}", keyvalue.Key.asString, keyvalue.Value.d.ToString()); Console.WriteLine("Vertex #{0}, e = {1}", keyvalue.Key.asString, keyvalue.Value.e.ToString()); Console.WriteLine("Vertex #{0}, f = {1}", keyvalue.Key.asString, keyvalue.Value.f.ToString()); Console.WriteLine("Vertex #{0}, xyz = {1},{2},{3}", keyvalue.Key.asString, keyvalue.Value.xyz[0].ToString(), keyvalue.Value.xyz[1].ToString(), keyvalue.Value.xyz[2].ToString()); Console.WriteLine("Vertex #{0}, abc = {1},{2}", keyvalue.Key.asString, keyvalue.Value.abc[0], keyvalue.Value.abc[1]); } } }
//====================================================================== // // 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); } }