Blog

DesignScript and C#

As we prepare for the imminent release of the Our Graph UI, we'd like to share some more information with you about how to do various things. Top of our request list has been a quick intro to how to use other C# libraries from within DesignScript.

The good news, it's really easy :)

As an example -- right now, the DesignScript libraries don't have an easy way of reading an image and using the values for laying out objects. C# has some pretty good libraries for reading in images, so lets see what we would need to do to wrap those libraries in and use them from DesignScript.

The first thing to do is to create a bit of C# that wraps the call, the code below is what we want:

using System;
using System.Drawing;

public class ImageTools : IDisposable
{
  private Bitmap img;

  public ImageTools(string path) {
  img = new Bitmap(path);
}

  public double GetBrightness(double xFraction, double yFraction) {
    //Compute the location of the pixel we want to look at
    int x = (int) (xFraction*(img.Width-1));
    int y = (int) (yFraction*(img.Height-1));
    Color col = img.GetPixel(x, y);
    return col.GetBrightness();
  }

  public void Dispose() {
    try { img.Dispose(); }
    catch (Exception) { }
  }
}


This is probably pretty self-explanatory to C# developers. There's a class holding a reference to an image, that's constructed from a path. Then a method which can be used to get brightness value.

It will work without the implementation of IDisposable, but it's good to play nice with C#, and as the image references are fairly expensive it's best to release them when we're done. DesignScript's garbage collector will automatically call the dispose mechanism, so there's no need to worry about anything further.

Then just hit compile in your favourite C# editor (I use Visual Studio, the free express products work fine, so does the open source SharpDevelop, as does the command line C# compiler). This produces a DLL.

Using your new DLL from DesignScript is even easier; import it, and you're good to go.

import("c:\\Temp\\ImageLib.dll");

reader = ImageTools.ImageTools("c:\\temp\\adsk.jpg");
Print(reader.GetBrightness(0.5,0.5));

Or from the new DesignScript Studio Graph UI:

Then drag the node onto the canvas and wire it up:

You get all benefits of the DesignScript Virtual Machine and execution engine for free. For example, replication just works and fits naturally into the DesignScript language. We can use this to create a slightly silly shading device and using it to display the Autodesk logo.

import("ProtoGeometry.dll");
import("c:\\Temp\\ImageLib.dll");

wcs = CoordinateSystem.WCS;

count = 50;

reader = ImageTools.ImageTools("c:\\temp\\adsk.jpg");
field = reader.GetBrightness((0..1..#count)<1>, (0..1..#count)<2>);
field = field*90;

coords = wcs.Translate((0..250..#count)<1>, (0..250..#count)<2>, 0);
coords = coords.Rotate(field, wcs.XAxis);
coords = coords.SetVisibility(false);

cyls = Cylinder.ByRadiusHeight(coords, 2, 1);

It's worth noting that this interop between DesignScript and C# is how ProtoGeometry, and as such all of our geometry libraries, work. As such it's received quite a lot of testing and use. It's ready for you to use too with a couple of limitations.

  • The implementation currently doesn't support Namespaces properly. This means if we tried to return a Color object, it would conflict with the ProtoGeometry Color object. This will be solved soon :)
  • It currently supports C#, VB.NET. Managed C++ and IronPython should probably work. If you want to use native C++ you need to create a wrapper for it. This will be solved, but please don't hold your breath.

If either of these two or any other issues cause you problems - please do let us know.

Email me when people comment –

You need to be a member of DesignScript to add comments!