Version: Rhino 4
I have a standalone C# application that automates Rhino by creating a Rhino4.Application object and then obtaining a reference to the RhinoScript COM object. I can perform simple operations, such as scripting commands via the Command method and adding lines via the AddLine method. But I am unable to use any RhinoScript method where I need to pass in an array of 3D points, which in RhinoScript are really arrays of arrays of doubles. Is there a way to call RhinoScript's AddMesh method from C#?
Simple data types, such as integers and doubles are easily marshalled between .NET and COM because their values can be easily converted to the Object .NET data type. Array are a little more difficult to deal with, but not impossible. The .NET array classes have a ToArray member that will copy the elements of the array to a new Object array. A .NET Object array will marshall to COM as a SafeArray.
The following example demonstrates how to call RhinoScript's AddMesh method from a standalone application:
C#
static void Main(string[] args) { //Create Rhino application object Console.Write("Creating Rhino object..."); Rhino4.Application objRhino = new Rhino4.Application(); if (objRhino == null) { Console.WriteLine("failed."); return; } else { Console.WriteLine("succeeded."); } //Retrieve RhinoScript object Console.Write("Retrieving RhinoScript object..."); RhinoScript4.IRhinoScript objRhinoScript = null; int count = 0; System.Threading.Thread.Sleep(500); while (count < 10) { object obj = objRhino.GetScriptObject(); if (obj != null) { objRhinoScript = (RhinoScript4.IRhinoScript)obj; if (objRhinoScript != null) break; } System.Threading.Thread.Sleep(500); count++; } if (objRhinoScript == null) { Console.WriteLine("failed."); return; } else { Console.WriteLine("succeeded."); } //Create mesh data Console.Write("Adding mesh object..."); //Mesh vertices ArrayList vertices = new ArrayList(); ArrayList v0 = new ArrayList(); v0.Add(0.0); v0.Add(0.0); v0.Add(0.0); vertices.Add(v0.ToArray()); ArrayList v1 = new ArrayList(); v1.Add(10.0); v1.Add(0.0); v1.Add(0.0); vertices.Add(v1.ToArray()); ArrayList v2 = new ArrayList(); v2.Add(10.0); v2.Add(10.0); v2.Add(0.0); vertices.Add(v2.ToArray()); ArrayList v3 = new ArrayList(); v3.Add(0.0); v3.Add(10.0); v3.Add(0.0); vertices.Add(v3.ToArray()); //Mesh faces ArrayList faces = new ArrayList(); ArrayList f0 = new ArrayList(); f0.Add(0); f0.Add(1); f0.Add(2); f0.Add(3); faces.Add(f0.ToArray()); //Mesh normals ArrayList normals = new ArrayList(); ArrayList n0 = new ArrayList(); n0.Add(0.0); n0.Add(0.0); n0.Add(1.0); normals.Add(n0.ToArray()); ArrayList n1 = new ArrayList(); n1.Add(0.0); n1.Add(0.0); n1.Add(1.0); normals.Add(n1.ToArray()); ArrayList n2 = new ArrayList(); n2.Add(0.0); n2.Add(0.0); n2.Add(1.0); normals.Add(n2.ToArray()); ArrayList n3 = new ArrayList(); n3.Add(0.0); n3.Add(0.0); n3.Add(1.0); normals.Add(n3.ToArray()); //Texture coordinates ArrayList textures = new ArrayList(); ArrayList t0 = new ArrayList(); t0.Add(0.0); t0.Add(0.0); textures.Add(t0.ToArray()); ArrayList t1 = new ArrayList(); t1.Add(1.0); t1.Add(0.0); textures.Add(t1.ToArray()); ArrayList t2 = new ArrayList(); t2.Add(1.0); t2.Add(1.0); textures.Add(t2.ToArray()); ArrayList t3 = new ArrayList(); t3.Add(0.0); t3.Add(0.1); textures.Add(t3.ToArray()); //Vertex colors ArrayList colors = new ArrayList(); colors.Add(0); colors.Add(0); colors.Add(0); colors.Add(0); //Call AddMesh //If you want to pass in everything, then do this: object obj_uuid_str = objRhinoScript.AddMesh( vertices.ToArray(), faces.ToArray(), normals.ToArray(), textures.ToArray(), colors.ToArray() ); //If you do not want to pass in optional argument, //then pass "System.Reflection.Missing.Value". object obj_uuid_str = objRhinoScript.AddMesh( vertices.ToArray(), faces.ToArray(), System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value ); Console.WriteLine(obj_uuid_str.ToString()); //Save the file Console.WriteLine("Saving test file."); objRhinoScript.Command("_-Save c:\\test.3dm", 0); Console.WriteLine("Done!"); }