Some pointless fun with C# and the Grasshopper timer

I made a thing, and it ripples!

It could be sound in an auditorium. It could be waves in water. It could be energy dissipating from an earthquake’s epicentre. But that’s not the point.

What it is is a great demonstration on what you can make with the Grasshopper timer, and bit of C#, and 15 minutes to kill.

In the C# component, there are two regions you can edit: the RunScript section, and the ‘additional code’ section. Data stored in RunScript is volatile – it gets deleted every time the component is run. But data stored in the second region is preserved.

By running a timer on our component, it will be executed repeatedly. We can use this second region to hold information between these executions, allowing us to build up complex and dynamic behaviour in Grasshopper.

Grasshopper component C# timer example

The code within the C# component handles each ‘frame’ of the animation. It maintains the current time (increasing by 1 for each cycle) and uses this time to decide what colour each part of the mesh will be.

  private void RunScript(bool _clap, bool _reset, Mesh _mesh, ref object A)
  {
    
    thetime++;

    //button actions
    if(_clap)
    {
      times.Add(thetime);
    }
    if(_reset)
    {
      times.Clear();
      thetime = 0;
      CalcDistances(_mesh, new Point3d(0, 0, 0));
    }

    //maintain list size to maintain performance
    if(times.Count > 50) times.RemoveAt(0);

    //calculate mesh colours
    _mesh.VertexColors.Clear();
    int i = 0;
    foreach(var v in _mesh.Vertices)
    {
      bool shouldbegreen = false;
      foreach(var time in times)
      {
        if(thetime == (time + (int) (distances[i])))
        {
          shouldbegreen = true;
        }
      }
      if(shouldbegreen)
      {
        _mesh.VertexColors.Add(Color.Green);
        _mesh.Vertices.SetVertex(i, _mesh.Vertices[i].X, _mesh.Vertices[i].Y, 1);
      }
      else
      {
        _mesh.VertexColors.Add(Color.Red);
        _mesh.Vertices.SetVertex(i, _mesh.Vertices[i].X, _mesh.Vertices[i].Y, 0);
      }
      i++;
    }

    //output
    A = _mesh;
  }

  // <Custom additional code> 

  int thetime = 0;
  List<int> times = new List<int>();
  List<double> distances = new List<double>();
  
  //preprocessed here to speed up calculation
  public void CalcDistances(Mesh msh, Point3d pt)
  {
    distances.Clear();
    foreach (var v in msh.Vertices)
    {
      distances.Add(pt.DistanceTo(v));
    }
  }

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.