developer:dotnettorhinoscript2


Table of Contents

Passing Arrays from .NET to RhinoScript

.NET

Version: Rhino 4

Question

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 am able to 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 3-D points, which in RhinoScript are really arrays of arrays of doubles. Is there a way to call RhinoScript's AddMesh method from C#?

Answer

Simple data types, such as integers and doubles are easly 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!");
   }
developer/dotnettorhinoscript2.txt · Last modified: 2010/01/26 16:37 (external edit) Driven by DokuWiki Recent changes RSS feed

 © 1997-2010 

McNeel North America Europe Latin AmericaAsia