Area of a mesh face in C# in Grasshopper

Another quick script for handing meshes – this time to find the area of a mesh face.

This script is in C# and can be easily used with the C# component in Grasshopper. Copy the script into the ‘custom additional code’ section. It is written as a method, so you can easily call it. In the ‘RunScript’ section, call the method with something like:

double area = Area(3, myMesh)

This will return the area of the third face in the mesh called myMesh.

The method itself to calculate the area of a mesh face is below. Of course, you can use this method in any C# application, not just Grasshopper – you’ll just need to modify the code to fit whatever data structure your mesh uses.

  double Area(int meshfaceindex, Mesh m)
  {
    //get points into a nice, concise format
    Point3d[] pts = new Point3d[4];
    pts[0] = m.Vertices[m.Faces[meshfaceindex].A];
    pts[1] = m.Vertices[m.Faces[meshfaceindex].B];
    pts[2] = m.Vertices[m.Faces[meshfaceindex].C];
    if(m.Faces[meshfaceindex].IsQuad) pts[3] = m.Vertices[m.Faces[meshfaceindex].D];

    //calculate areas of triangles
    double a = pts[0].DistanceTo(pts[1]);
    double b = pts[1].DistanceTo(pts[2]);
    double c = pts[2].DistanceTo(pts[0]);
    double p = 0.5 * (a + b + c);
    double area1 = Math.Sqrt(p * (p - a) * (p - b) * (p - c));

    //if quad, calc area of second triangle
    double area2 = 0;
    if(m.Faces[meshfaceindex].IsQuad)
    {
      a = pts[0].DistanceTo(pts[2]);
      b = pts[2].DistanceTo(pts[3]);
      c = pts[3].DistanceTo(pts[0]);
      p = 0.5 * (a + b + c);
      area2 = Math.Sqrt(p * (p - a) * (p - b) * (p - c));
    }

    return area1 + area2;
  }

This script is based upon Heron’s Formula, which calculates the area of a triangle based upon knowing its three lengths. The script also calculates the area for quads. It does this by dividing the quad into two triangles.

mesh-area

How to colour a mesh using the C# component in Grasshopper

In this post, we saw how you can apply colours to a mesh using Grasshopper components.

Sometimes we would rather use C# code – in certain cases it can be a lot faster than clicking around the Grasshopper canvas, and it can give us a lot more control. How can we apply colour to a mesh using C#?

How coloured meshes work in Grasshopper

If we understand the mesh structure in Grasshopper, we know that meshes are defined by nodes and faces. We create a list of nodes, and then ‘join them up’ into faces of 3 or 4 nodes.

When we colour a mesh in Grasshopper, we do not colour the faces themselves. Instead, we set each node to a colour. So, if we have a simple mesh of one face and four nodes, we must define four colours, one for each node.

We can set the same colour to every node to get a uniform colour. But a nice thing that we can do is set different colours to each node. Rhino will automatically render the mesh with smooth colour gradients – nice!

As an aside, if you want one uniform colour per face, as in the second example here, we must again explode the mesh into multiple meshes, one per face. Alternatively, instead of exploding, you could duplicate the nodes at points where faces of different colours meet.

An example

Let’s say you want to create a mesh with a 3-colour gradient of red, yellow and green, as below:

Grasshopper mesh 3 colour gradient

We can create this with a mesh of 2 faces and 6 nodes. Create a C# component within Grasshopper with default input/outputs, and copy the code below:

    //declare an empty mesh
    var mesh = new Mesh();

    //create vertices
    mesh.Vertices.Add(0, 0, 0);
    mesh.Vertices.Add(5, 0, 0);
    mesh.Vertices.Add(5, 2, 0);
    mesh.Vertices.Add(0, 2, 0);
    mesh.Vertices.Add(10, 0, 0);
    mesh.Vertices.Add(10, 2, 0);

    //create colour list. The vertex [i] is coloured by the value at VertexColors[i]
    //the VertexColors list MUST be the same length as the vertices list
    mesh.VertexColors.Add(Color.Red);
    mesh.VertexColors.Add(Color.Yellow);
    mesh.VertexColors.Add(Color.Yellow);
    mesh.VertexColors.Add(Color.Red);
    mesh.VertexColors.Add(Color.Green);
    mesh.VertexColors.Add(Color.Green);

    //create faces using vertex indices
    mesh.Faces.AddFace(0, 1, 2, 3);
    mesh.Faces.AddFace(1, 4, 5, 2);

    //return mesh
    A = mesh;

A few notes

The colours are saved as a list in VertexColors. Note that this list must either be completely empty (if you are not interested in colouring your mesh) or it should be exactly the same length as the Vertices list. Fail to do this, and your mesh will have a nasty habit of disappearing with no word of warning!

Since VertexColors is a list, once you have added colours, you can edit them in the usual way with VertexColors[i] where i is some index number. But, like a list, you cannot add a new colour using VertexColors[i] – you must use the VertexColors.Add() method.

Colours are normally defined using RGB values, for example:

Mesh.VertexColors.Add(255,0,0);

But a useful shortcut if you don’t know/can’t be bothered to look up colour codes is to use shortcuts like Color.Red instead of RGB values.

FastMesh for Grasshopper: A cluster to make fast, light meshes from curves

Creating a mesh from a curve can be challenging in Grasshopper. Most ways of doing it involve creating a surface and then meshing that surface. And once the mesh is made, it often has inconsistent face densities, with unusual points of high point density.

bad_mesh

The mathematics behind these methds are fine for the general case (any closed curve in any alignment), but in cases where we have a planar polyline (i.e. no curved segments, such as a room or building outline) and where this curve lies in the XY plane, we can use a highly optimised algorithm.

FastMesh is my attempt. Simply connect a polyline (or list of polylines) and it will mesh those curves – without the heavy operation of creating intermediary surfaces. I have attempted to ensure that points are distributed evenly in a grid-like pattern (so it is suitable for creating analysis meshes for tools like Honeybee), and you can optionally control the distance between points by inputting a distance into ‘s’. If you leave ‘s’ blank (or set it to 0) it will create a mesh with a minimum number of faces, creating extremely light meshes, for example in creating buildings with Elk.

good_mesh

The principle of my method is that it generates a collection of mesh points, and removes any mesh points that don’t lie inside the curve. It then performs a Delaunay Triangulation on remaining points. For concave shapes, triangles will be formed that fall outside the curve, which are removed.

Grasshopper: Front and Centre for aligning legends to the Rhino Viewport

Grasshopper is a great way of creating legends and graphs beside your model, but how do you display them? You can use multiple viewports, but this is clumsy to set up. You could use Ladybug’s approach of keeping the legend close to your geometry in 3D space, but this means you have to move the viewport to inspect the legend.

legend1

Front and Centre is a Grasshopper cluster which moves legends or any other geometry directly in front of the camera. Add a timer and the legend automatically follows the camera. It intelligently scales the geometry to fit within the screen, and you can customise the location by modifying a centre point.

legend2

To use, connect the legend or geometry you wish to display to ‘Geo’. Optionally, you can add a point to define the centre of your screen to ‘pt’. Both these should be located somewhere in the plane Z=0.

frontandcentre

A simple timer example for the Grasshopper C# component

grasshopper-timer

Create a simple timer in Grasshopper using the built-in C# component with this example script.

What this does

Set runtimer to true. The component will build a list of the current time and date, once per second.

When runtimer is set to false, the timer is turned off and the list is displayed.

Code

  private void RunScript(bool runtimer, bool reset, ref object A)
  {
    if(runtimer) Example.TurnOnTimer();
    if(!runtimer) Example.TurnOffTimer();
    A = rtnlist;
  }

  // <Custom additional code> 

  public static List<string> rtnlist = new List<string>();

  public class Example
  {
    public static System.Timers.Timer aTimer = new System.Timers.Timer(1000);

    public static void TurnOnTimer()
    {
      rtnlist.Clear();
      aTimer.Elapsed += OnTimedEvent;
      aTimer.Enabled = true;
    }

    public static void TurnOffTimer()
    {
      aTimer.Elapsed -= OnTimedEvent;
      aTimer.Enabled = false;
    }

    private static void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
    {
      rtnlist.Add(e.SignalTime.ToString());
    }
  }

Download

You can download the above code as a Grasshopper user object here


Further information

MSDN guide: timers in C#

Grasshopper timer using Python

If you are looking to add a timer to a Python component without using the timer component, have a look at Anders Deleuran’s code here.

Set the Rhino camera with Grasshopper and C#

Setting the camera in Rhino can be a bit fiddly. Often, dragging and orbiting doesn’t give you the camera view you need. It is possible to manually set the camera using the ViewportProperties command, but even this often isn’t ideal.

However, it is surprisingly easy to set the Rhino camera with a few lines of C# code in Grasshopper. The key part is understanding how the Rhino camera works. The camera location is defined by a Point3d. In order to get the view direction, a second point is used, called the target. So if you want to ‘look around’, keep the camera location constant, and move the target. If you want to orbit around an object, keep the target the same and move the camera location. If you want to ‘walk’ (like in Sketchup) then you need to move the location and the target together.

To use the code below, create a C# component in Grasshopper. Copy the script below into the component. The snippet gets the camera in the selected Rhino viewport.

Get camera

private void RunScript(bool getcamera)
{
    //get current viewport    
    vp = doc.Views.ActiveView.ActiveViewport;
    //save camera location and camera target
    loc = vp.CameraLocation;
    tar = vp.CameraTarget;
}
// <custom additional code>

Rhino.Display.RhinoViewport vp; //used to get and set rhino camera properties
Point3d tar;
Point3d loc;

…and this one sets the viewport. You’ll need to set two Point3d inputs called loc and tar to take the user’s desired camera location and target points.

Set camera

private void RunScript(Point3d loc, Point3d tar)
{
    //get current viewport    
    vp = Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.ActiveViewport;
    //set new camera
    vp.SetCameraLocations(tar, loc);
}
// <custom additional code>

Rhino.Display.RhinoViewport vp; //used to get and set rhino camera properties

These examples are of course very simple, but you don’t have to stop here. Once you’ve got the gist of it, this approach reveals not only the ability to manipulate the view but it allows a huge range of creativity. For example, I rendered OpenStreetMap data in Grasshopper and manipulated the camera to follow a road.

You can download the Grasshopper file to set the camera along a curve like the above video from here.

Vastly improve Grasshopper component performance by NOT using data types??

Scripting components in Grasshopper can be a great way to get extra power and functionality for those comfortable with C# or VB. It can also be a much tidier way of doing certain tasks than using components, such as using mathematical formulae on a list of values.

Calculating the minimum value in a list of numbers is a great example of this – difficult to do using Grasshopper but dead easy with a few lines of script. The algorithm is simple – look through every item in the list, keeping track of the smallest item found. When we are at the end of the list, simply return this smallest value.

To implement this in Grasshopper, we can use the C# component. We’d start by specifying the input data types by right-clicking on the input, selecting ‘list’ and selecting ‘double’.

GH_component_right_click

Then we’d go into the component and add our code.

  private void RunScript(List<double> x, ref object A)
  {

    double minsofar = x[0];

    foreach(double val in x)
    {
      minsofar = Math.Min(val, minsofar);
    }

    A = minsofar;

  }

This works fine and gives the expected result.

But try and run this code for quite a large list, say 100000 items. This takes around a second to compute. Not an especially long time, but for such a simple calculation it still adds a noticeable lag to the canvas. I just accepted it for what it was, thinking maybe that’s simply how long it actually takes to run a bit of code.

One day, I was writing another simple component and was feeling especially lazy. I couldn’t be bothered to do the right-clicking malarkey, and decided to just cast the data types in the Grasshopper component itself. Again, there was a large list going into the component, but to my surprise it calculated in mere milliseconds. Investigating further, I found that this speed difference occurs time and time again, and can be easily demonstrated:

GH_double_cast

Here, we have a list of 100000 numbers (a series of doubles) and we’re trying to find the smallest value among them. (Of course, with an ascending series it’s going to be the first value, but the algorithm doesn’t know that.) The code for the first C# component is:

    double minsofar = x[0];

    foreach(double val in x)
    {
      minsofar = Math.Min(val, minsofar);
    }

    A = minsofar;

This is the same as before – we have set the input data type (called x) as double, and assumed that x is a double in the code. This consistently takes 1.2s to calculate on my laptop.

The code for the second C# component is:

    double minsofar = (double) x[0];

    foreach(object val in x)
    {
      minsofar = Math.Min((double) val, minsofar);
    }

    A = minsofar;

The only difference here is that we don’t tell the component input to expect a particular data type – we leave it set as ‘object’. (We still have to tell it it’s going to be a list.) Then, in the code, whenever we want to do something with this list that can only be applied as numbers, we cast the item in the list we are looking at as a double, e.g. x[0] becomes (double)x[0].

The difference this makes is astonishing – we go from a calculation time of 1.2s to a tiny 7 milliseconds.

Why this is I don’t know. Whether it works for other data types I am still investigating, and it would be great to hear if this technique is repeated elsewhere in different scenarios.

In the meantime, the lesson is clear: if you are looking to optimise your canvas as much as possible, it is worth trying to cast your variables inside your component instead.

Download the example file:

Using Generics in C#

When we write a method in C#, we often want to specify an input and a return for it. Since C# is a strongly typed language, it likes to know exactly what data type these inputs and returns are.

Let’s take an example, which takes a 2D array of data and returns a specified row as a list:

public List<string> GetRowOf2dArray(string[,] array, int rowNo)
{
    List<string> rtnlist = new List<string>();
    for (int i = 0; i < array.GetLength(0); i++)
    {
        rtnlist.Add(array[i, rowNo]);
    }
    return rtnlist;
}

This is all well and good if we only want to use strings. But what happens if, later on, we want to use the function with a list of doubles?

We might decide to create a copy of the method:

public List<double> GetRowOf2dArray(double[,] array, int rowNo)
{
    List<double> rtnlist = new List<double>();
    for (int i = 0; i < array.GetLength(0); i++)
    {
        rtnlist.Add(array[i, rowNo]);
    }
    return rtnlist;
}

Now, at the interface level, we can extract a row whether we have a matrix of doubles or of strings, and return them in the correct data type.

string[,] branchPaths = new string[5, 5];
for (int i = 0; i < branchPaths.GetLength(0); i++)
{
    for (int j = 0; j < branchPaths.GetLength(1); j++)
    {
        branchPaths[i, j] = "I am cell " + i.ToString() + ", " + j.ToString() + ".";
    }
}

var rtnList = new List<string>();
rtnList = tst.GetRowOf2dArray(branchPaths, 0);

But, we’re already running into problems. We basically had to copy and paste the GetRow…() method above, which is already bad practice. What if we want to change something, or we find there’s a bug? We’d have to make the change in every copy of GetRow…(). And what if we want to use the method with yet another data type, such as an array of integers? We’d have to keep copying and pasting for every data type.

One way around this is instead to write the method using objects as the type. Since all types inherit from the object type, we can write the method once and cast the specific data types. A very simple example is:

public bool IsEqual(object v1, object v2)
{
    if (v1 == v2) return true;
    else return false;
}

double a = 2;
double b = 3;
bool areTheyEqual = IsEqual(a, b); //returns false

However, this gives a lot of problems, which are explained in more depth here. Basically, using objects means that we lose performance due to casting, and we lose control since all data types can be casted to and from objects. What we want is a way to create a method suitable for multiple data types, but where we still can feel safe that the user won’t break our method with a strange data type.

Generics

This is solved with generics. As well as feeding in parameters to our methods, we can also tell the method what kind of data type we want to use it with.

This will already be familiar if you have worked with lists:

List<double> myList = new List<double>();

myList.Add(1.5);
myList.Add(5.232);

The bit in the angle brackets is the type – we can’t create a list without telling it what kind of data the list will contain. By writing <double>, we are saying that every item in the list will be a double. And if we wanted to create a list of strings, we don’t need to call a different method or different class, but we can still do it by calling the same class by specifying the type as string.

In short, using generics allows you to write your method once for a wide range of data types.

Back to the matrix example – in our class:

public List<T> GetRowOf2dArray<T>(T[,] array, int rowNo)
{
    List<T> rtnlist = new List<T>();
    for (int i = 0; i < array.GetLength(0); i++)
    {
         rtnlist.Add(array[i, rowNo]);
    }
    return rtnlist;
}

int[,] branchPaths = new int[5, 5];
for (int i = 0; i < branchPaths.GetLength(0); i++)
{
    for (int j = 0; j < branchPaths.GetLength(1); j++)
    {
        branchPaths[i, j] = i*100 + j;
    }
}

var rtnList = new List<int>();
rtnList = tst.GetRowOf2dArray<int>(branchPaths, 2);

T is the placeholder for the type. When the user calls the method, T will hold a data type, such as string or int. In this example, both an input (T[,]) and the return type (List<T>) have data types that must be carried by the user. The place where the user specifies the data type carried by T is in GetRowOf2dArray<T>. So when the user calls the method, they only need to specify T once. T can then be used wherever necessary throughout the method.

References

MSDN – An introduction to C# generics
MSDN – Generics (C# programming guide)

Changing input names for custom C# Grasshopper components

Edit input names of a GH component

The two components above look similar but are actually the same. What’s the difference? When a single item is connected to the first input, saving is enabled in the bottom input. When a list is connected to the first input, saving is disabled.

When we are writing custom Grasshopper components in C# in Visual Studio, this is very easy. All we do is, somewhere within the SolveInstance method, modify the input properties to change the name, then manually add some code to allow for our desired saving behaviour.

protected override void SolveInstance(IGH_DataAccess DA)
{
   if(Input0.Count == 1)
   {
       Params.Input[6].NickName = "save";
       Params.Input[6].Name = "Save";
   }
   else if (Input0.Count > 1)
   {
       Params.Input[6].NickName = "----";
       Params.Input[6].Name = "Save (Disabled)";
   }
}

In fact, by going to

Params.Input[i].something

where i is the index of the input we are interested in, we can access lots of interesting properties and methods to bring new interesting behaviour to our Grasshopper components. We can even do the same to our outputs with Params.Output[i].

And it’s not just limited to the parameter inputs and outputs either. By using

this.something

we can browse the properties and methods which affect the whole component. For example, we can add a warning to our component by adding the line below to our SolveInstance code:

this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "You did a booboo.");

Custom error message on a Grasshopper component

Keyboard reader for Grasshopper

A prototype way of interacting with Grasshopper with the keyboard. Press any character key on the keyboard to send true/false values to Grasshopper.

It uses the Global Mouse and Keyboard Hook classes by George Mamaladze to intercept key up/down events. I have written two components that turns these key events into true/false commands – if a key is raised, ‘false’ is sent, and if pressed, ‘true’ is sent.

Keyboard reader with 6 pre-filled keys
Keyboard reader with 6 pre-filled keys

In the component above, 6 keys have been hard-coded. (I have been using this as part of video game-like WASD camera control in Rhino.) The component below accepts any character (and possibly any key on the keyboard if you’re lucky enough to find the correct character code for each key.)

Keyboard reader with any letter of the keyboard
Keyboard reader with any letter of the keyboard

Install

To install, download the file at the bottom of this page. Unzip and copy the two files (one GHA and one DLL) into your Grasshopper components folder. To use, set up as in the images above, and remember to attach a timer with a short interval. You may need to unblock the file within Windows if you are having problems. (Right click each of the two files in Windows Explorer, click Properties, and click Unblock.)


Source code

The source code of the Grasshopper components is available at GitHub.

The classes for interacting with the keyboard must (at least for the moment) be downloaded separately, and are available here.