Looping through the Grasshopper canvas

Loops in programming are very powerful. Oftentimes, we want to repeat the same piece of code several times, maybe with some slight changes each time.

Grasshopper, being a visual programming interface, tries to be a little simpler and easier to grasp than the regular horror of text-based programming. One of the key losses that comes from this simplicity is the inability to natively perform loops – we cannot use the output of one component as an input for a component upstream.

Trying to perform a recursive calculation in Grasshopper produces a recursion error
This is bad!

Hoopsnake

Hoopsnake gets around this problem using an approach similar to the way that Excel deals with the problem – what it calls circular references. But while a good solution in certain cases, Hoopsnake isn’t always easy to grasp and can be clumsy to set up in larger canvases – highlighting possibly why Grasshopper has removed the ability in the first place.

David Rutten’s permutation component

An alternative solution was created by David Rutten in this post, and looks at creating loops by cycling through values in the number slider component.

Say you have a few sliders in your canvas. Rutten’s component looks for all sliders. When the slider is changed, the canvas recalculates, as always happens in Grasshopper. The component listens for when all calculations have finished, then it changes the value of one of the sliders. This of course triggers another recalculation. The component listens again for calculations to finish, and changes the slider again. It cleverly repeats this cycle until it has gone through every value in the slider. If the component has found multiple sliders, it will run through every combination of these slider values. So if you have two sliders with integer values of 0-10, the canvas will recalculate 121 times (i.e. 11 x 11).

A component created by David Rutten that cycles through all possible permutations of a number slider in Grasshopper

The curse of dimensionality

Nowadays, Grasshopper is being used for much larger projects than ever envisaged when it was first created. GH documents are likely to have many dozens of sliders. If we have 20 sliders each with just 11 possible settings, Rutten’s component will force the recalculation 11^20 times – i.e. 672 billion billion times! (This concept of small numbers multiplying up very quickly is something referred to as the curse of dimensionality and is a big challenge when designing computational algorithms on large data sets.)

Mostapha’s modification

Perhaps in recognition to the Curse of Dimensionality, or simply the need that you might not want to involve every slider in your canvas in your recursion, Mostapha Roudsari has created a modified version of Rutten’s component. You can find it as part of his example files for his Honeybee plugin. (Jump to example 6, “Parametric grid-based analysis” and look for the component called “runItAll”.)

The key change in this component is that there is now an input called “mySliders”. Instead of running through all sliders like Rutton’s solution, this component will only cycle through those sliders connected to “mySliders”. While very powerful, this creates an initially surprising behaviour since, visually, it looks like the action to change a slider flows backwards along the wire!

The runItAll component created by Mostapha Roudsari, which allows a user to cycle through selected number sliders in Grasshopper

If no wires are connected, then the component resorts to Rutten’s component’s behaviour of modifying the values of all sliders in the canvas. This is still useful when you want to modify all sliders without spending time connecting them up.

My token improvement

This component has proven very useful for my own parametric studies, and I have been using it a lot. By using it a lot though, I have made a lot of mistakes. I’ve found it’s all too easy to accidentally run it and realise you’ve connected the wrong sliders, and find that you’ve asked Grasshopper to run a billion permutations, which GH diligently makes a happy start with. The only solution is to kill Grasshopper and reload.

I have added a message box that fires when you press the start button. This tells you the name of the connected sliders that the component will cycle through, and will calculate the number of permutations. You are then free to proceed or cancel.

jr-grasshopper-permutations

You can download this component as a UserObject here:


Next steps

This component has proven to be very useful in parametric studies. For example, if you are looking at optimal depth of window shading to control glare from the sun, you might set the depth of the shading with a slider. You can then set up a run where the glare values are automatically calculated for different shading depths.

Using a slider is quite limited however. What if you want to explore values of 0, 0.5 and 1 only? It is not possible to create a slider containing these three values. One solution is to connect a slider to a ListItem component (below) but this is quite a clumsy solution that takes time to set up and modify.

grasshopper-list-item

I have been looking at different components that can be modified remotely. For example, is it possible to use the Num component to hold modified values instead of the slider component? In a couple of recent posts, we have been looking at the ways that data is programatically stored within Grasshopper components. (Short answer – it’s possible to access, but not easy or obvious how to do it!)

grasshopper-persistent-data-access

Eventually, I want to be able to have a component where input values can be modified within a range. We don’t necessarily need to do an orthogonal grid of values like the recursive slider solution provides. If we are doing a parametric study, there are numerous other ways of choosing which discrete values we want to select as a sample within our ranges. This is a whole field called design of experiements which I am beginning to touch upon.

Appendix: BatchRun source code

private void RunScript(List<System.Object> mySliders, bool startme)
  {
    if (!startme)
      return;

    if (_running)
      return;


    _run = true;

    _mySliders = mySliders;

    GrasshopperDocument.SolutionEnd += OnSolutionEnd;
    Print(_rtnmessage);
  }

  // <Custom additional code> 
  private bool _run = false;
  private bool _running = false;
  private List<System.Object> _mySliders;
  private string _rtnmessage;

  private void OnSolutionEnd(object sender, GH_SolutionEventArgs e)
  {
    // Unregister the event, we don't want to get called again.
    e.Document.SolutionEnd -= OnSolutionEnd;

    // If we're not supposed to run, abort now.
    if (!_run)
      return;

    //throw new System.ArgumentException("Parameter cannot be null", "something weird");

    // If we're already running, abort now.
    if (_running)
      return;

    // Reset run and running states.
    _run = false;
    _running = true;

    try
    {
      // Find the Guid for connected slides
      List<System.Guid> guids = new List<System.Guid>(); //empty list for guids
      Grasshopper.Kernel.IGH_Param selSlidersInput = Component.Params.Input[0]; //ref for input where sliders are connected to this component
      IList<Grasshopper.Kernel.IGH_Param> sources = selSlidersInput.Sources; //list of things connected on this input
      bool isAnythingConnected = sources.Any(); //is there actually anything connected?

      if (isAnythingConnected) { //if something's connected,
        foreach (var source in sources) //for each of these connected things:
        {
          IGH_DocumentObject component = source.Attributes.GetTopLevel.DocObject; //for this connected thing, bring it into the code in a way where we can access its properties
          Grasshopper.Kernel.Special.GH_NumberSlider mySlider = component as Grasshopper.Kernel.Special.GH_NumberSlider; //...then cast (?) it as a slider
          if (mySlider == null) //of course, if the thing isn't a slider, the cast doesn't work, so we get null. let's filter out the nulls
            continue;
          guids.Add(mySlider.InstanceGuid); //things left over are sliders and are connected to our input. save this guid.
          //we now have a list of guids of sliders connected to our input, saved in list var 'mySlider'
        }
      }

      // Find all sliders.
      List<Grasshopper.Kernel.Special.GH_NumberSlider> sliders = new List<Grasshopper.Kernel.Special.GH_NumberSlider>();
      foreach (IGH_DocumentObject docObject in GrasshopperDocument.Objects)
      {
        Grasshopper.Kernel.Special.GH_NumberSlider slider = docObject as Grasshopper.Kernel.Special.GH_NumberSlider;
        if (slider != null)
        {
          // check if the slider is in the selected list
          if (isAnythingConnected)
          {
            if (guids.Contains(slider.InstanceGuid)) sliders.Add(slider);
          }
          else sliders.Add(slider);
        }
      }
      if (sliders.Count == 0)
      {
        System.Windows.Forms.MessageBox.Show("No sliders could be found", "<harsh buzzing sound>", MessageBoxButtons.OK);
        return;
      }

      //we now have all sliders
      //ask the user to give a sanity check
      int totalLoops = 1;
      string message = null;
      foreach(Grasshopper.Kernel.Special.GH_NumberSlider slider in sliders)
      {
        totalLoops *= (slider.TickCount + 1);
        message += slider.ImpliedNickName;
        message += "\n";
      }
      if (System.Windows.Forms.MessageBox.Show(sliders.Count + " slider(s) connected:\n" + message + "\n" + totalLoops.ToString() + " iterations will be done. Continue?", "Start?", MessageBoxButtons.YesNo) == DialogResult.No) return;



      // Set all sliders back to zero.
      //GH_Document.EnableSolutions = false;
      foreach (Grasshopper.Kernel.Special.GH_NumberSlider slider in sliders)
        slider.TickValue = 0;

      // Start a giant loop in which we'll permutate our way across all slider layouts.
      while (true)
      {
        int idx = 0;
        if (!MoveToNextPermutation(ref idx, sliders))
          break;

        // We've just got a new valid permutation. Solve the new solution.
        e.Document.NewSolution(false);
        Rhino.RhinoDoc.ActiveDoc.Views.Redraw();
      }
    }
    catch {
      _rtnmessage = "something went wrong!";
    }
    finally {
      // Always make sure that _running is switched off.
      _running = false;
    }
  }

  private bool MoveToNextPermutation(ref int index, List<Grasshopper.Kernel.Special.GH_NumberSlider> sliders)
  {
    if (index >= sliders.Count)
      return false;

    Grasshopper.Kernel.Special.GH_NumberSlider slider = sliders[index];
    if (slider.TickValue < slider.TickCount)
    {
      // Increment the slider.
      slider.TickValue++;
      return true;
    }
    else
    {
      // The current slider is already at the maximum value. Reset it back to zero.
      slider.TickValue = 0;

      // Move on to the next slider.
      index++;

      // If we've run out of sliders to modify, we're done permutatin'
      if (index >= sliders.Count)
        return false;

      return MoveToNextPermutation(ref index, sliders);
    }
  }

Update: Another solution for modifying sliders

Anders Deleuran has created an alternative way of remotely modifying slider values. His method is similar, but looks for sliders based upon their name. It is written in Python. You can download the file from the Grasshopper forum.

anders-grasshopper-loop

Radiation analysis in Ladybug for Grasshopper: Example file

How to set up an incredibly simple solar radiation analysis in Grasshopper using the Ladybug plugin. Read this post if you need to install Ladybug.

This example creates a simple shoebox that receives radiation from a sky. It is coloured according to how much radiation it receives across its surface. It is also partly shaded by a shading object (another shoebox) so you can see how to set up shading objects, and see the effect on your measurement objects.

Just follow the picture below! You can also download this GH file with the link at the bottom.

ladybug-radiation-example-grasshopper

Click the image for full size.

You should get something like the image below. Notice how the context geometry (coloured red at the right) provides shading on the left hand block, producing blue (shaded) results in its shadow.

radiation-analysis-example-ladybug

Download example file

I presented at CIBSE Technical Symposium 2015

Last week I presented a software tool I have been developing in collaboration with Smart Space at BuroHappold called SmartBuildingAnalyser. CIBSE Technical Symposium is a meeting of academic and industrial developments which aim to look at the latest advances in tools and methodologies for the many aspects of building environmental design. This year, the conference was held at UCL in London.

James Ramsden presenting SmartBuildingAnalyser at CIBSE Technical Symposium 2015

Presentation abstract

The paper and presentation set out the problem of the complexity and contradictions that arise as we try to design the ‘perfect’ building. I attempted to argue that, since there is no such thing as a perfect building, trade-offs are inevitable, and that the best way to get the best combination of trade-offs is to have a better understanding of how different options perform. Currently the tools available for ‘optioneering’ are not powerful enough to generate this data for a wide range of options in a reasonable amount of time.

SmartBuildingAnalyser is a collection of components currently under development for Grasshopper that help to leverage the power of Grasshopper for the specific task of streamlining the parametric building design and analysis process. In the presentation, I showed how these components generated options for a number of projects in BuroHappold to expose how the sensitivity of building performance with respect to the changing of certain design parameters.

Many of the posts on this site, especially the ‘hints and tips’ style posts on Grasshopper, were written as part of the various pieces of development towards SBA. I’m still a fair way off a public release of SBA, but it’s well on its way, and hopefully the presentation will have generated enough interest to provide the links necessary for further work.

How did it go?

I have given a small number of presentations before as part of my work, mostly internal to BuroHappold but most notably to COLEB in ETH, Zurich last year. The CIBSE presentation was, by quite a margin, the most significant and impactful presentation I have given to date – I was fortunate to have an enthusiastic and prolific audience of perhaps 50 delegates. While it was rather intimidating when waiting to give my speech, I needn’t have worried – the audience were receptive and were keen to pass on their feedback and discussion points later on in the day. (Thank you to everyone who did this – your feedback and insights are very valuable to me!)

Every experience like this is a learning process, and especially at this CIBSE event where most participants aren’t programmers of any description, it’s good practice to learn to explain my work in an accessible way. One key failing is that I didn’t quite explain where in the design process my tool lies. The gap in software I have identified is in the transition between concept and detailed design stages. I am not trying to compete with ‘architect’ conceptual tools such as Sefaira or Vasari, nor have I developed a tool that provides the level of detail (and associated time cost) of detailing that comes with Dynamo, but I am aiming for the space between, where the design has progressed to the point where engineering questions are being asked of a building where the form is still still subject to a significant amount of uncertainty.

Download paper and presentation

I have uploaded the paper to academia.edu.

The full presentation with videos is available from this site here.

Video game control for Grasshopper

Using a combination of the keyboard reader and the camera control components for Grasshopper, it is possible to create a rather cool video-game-like keyboard control for walking around your Rhino/Grasshopper file.

Make sure you have installed the keyboard reader. Then click the link below to download the example Grasshopper file. This uses WASD controls, though you can remap the controls as you please.

Access persistent data in Grasshopper in C#

How to access the persistent data property of Grasshopper components in C#.

Say for example you want to read the value of ‘2’ which is saved internally within a ‘Num’ component.

grasshopper-persistent-data-access

We can look up the Num class and access the property from here quite easily. But what if we want to do it a bit more generically, so we can access the persistent data within any component?

We can do this by accessing the GH_PersistentParam(T) class. But because this class is in a different namespace/class hierarchy to the IGH_Param class (where we would normally be working to access component properties) it takes a little bit of work to manoeuvre data without Grasshopper having a small fit. (Read here for a forum post where David Rutten explains the class hierarchy behind Grasshopper.)

Two similar solutions I’ve produced today are:

var param2 = Component.Params.Input[0].Sources[0] as Grasshopper.Kernel.GH_PersistentParam<Grasshopper.Kernel.Types.GH_Number>;
A = param2.PersistentData[0];

…and the one-line alternative:

A = ((Grasshopper.Kernel.GH_PersistentParam<Grasshopper.Kernel.Types.GH_Number>) Component.Params.Input[0].Sources[0]).PersistentData[0];

This is a great simplification of the problem – it will only looks at the 1st component connected to the 1st input. And since PersistentData returns as GH_Structure, rather than dealing with data trees, it is easiest just to use square bracket notation to retrieve the first item (which is valid if we only have one item in our persistent data, as in this example).

How to access GH_Param

Today we have a special guest post from my colleague and friend Fraser Greenroyd. Fraser is the team’s resident computer scientist, and as such he is subject to the daily brunt of my programming woes. Here he recounts one of the many challenges we face in another day of beating Grasshopper into submission…

How often do you think “this won’t take more than a few minutes to figure out” and then spend far longer solving the problem? For me, that happens on an almost daily basis in my work with James, and today was no exception. Starting with a simple “before you sit down” question, James and I spent an hour traversing the inheritance of Grasshopper to solve one problem – accessing the DataMapping property of any plugged in component.

To begin with, James had created a C# component that read the component plugged into the inputs and checked if it was a ‘Num’ component. From there, he was able to output the DataMapping type, but the code doing this limited the functionality to only the ‘Num’ component. Useless for any other type.

It was recognised that, as multiple components shared similar data members, the chances of them inheriting from a single class were high, but knowing which class was, to begin with, tricky. This was compounded by the fact that I am a Computer Scientist, I’ve been programming for years and am used to reading and digesting well written SDKs but it appears the Grasshopper SDK is not well written. But never-the-less, James took me to the beginning steps and from there we began a journey up and down the inheritance tree until we stumbled upon GH_Param – a class housing such members as the Description, DataMapping and VolatileData.  Further up the tree, this inherited from the GH_DocumentObject class which meant access to this generic class should be possible from the bottom level of a component.

grasshopper-param-access-graft

Our goal – seems simple, no?

The majority of the hour we spent on this was looking at the SDK and figuring out where we needed to be on the inheritance tree. The minority was the actual nice bit – coding. Our initial development, which was based on James’ first piece of code for the ‘Num’ component gave us a bit of a headache when the GH_Param<T> didn’t like the type we supplied. Unfortunately, the not so well written documentation did not reveal what type we needed but through some trial and error we found it to be the IGH_Goo type.

If you’re a developer, you’ll know only too well the scent of victory drawing ever closer as you change lines here and there, and the sheer frustration when it won’t compile, or doesn’t provide the output you expect. For James and I, we reached this point when the code compiled but the output wasn’t the correct DataMapping for the component plugged in. Thankfully, this did not last long as, not being a Grasshopper developer, it transpired I had forgotten to make use of the ‘sources’ of the inputs.

The final code, included in this post does not do credit to the journey we went on. From an original 30 lines of code, James was able to condense what we needed into two lines (I would have condensed it into one but that’s another story). The source code supplied here allows you to access the DataMapping variable for the first component plugged into the input side of a component, but can be easily extended using lists to include all components plugged in OR, with some clever use of the GH_DocumentObject any component on the canvas (but whether that would be useful is up for debate).

However, if you take just one thing away from this post let it be this – if you ever have to write SDK documentation, for the sanity of those using it write it properly and write it well!

Grasshopper.Kernel.IGH_Param param = Component.Params.Input[0].Sources[0];
A = param.DataMapping;

or
A = ((Grasshopper.Kernal.IGH_Param)Component.Params.Input[0].Sources[0]).DataMapping;

How to explode a mesh in Grasshopper

Exploding a mesh is a key skill in handling meshes. Knowing the different ways is a good way of demonstrating you understand how to manipulate meshes. You might need to redefine some faces in your mesh, or you might want to colour a mesh face-by-face.

What does it mean to explode a mesh? It essentially means taking each face of the mesh, and making it a separate mesh in its own right. So a single mesh with 100 faces will become 100 meshes with one face.

There are broadly three ways of exploding a mesh, depending on what you want to do, your ability level, and the wider task you are trying to achieve. Let’s say we want to explode the mesh below.

Rhino mesh grid

Starting with the easiest…

Method 1: Use MeshEdit

Use the Explode component in the MeshEdit collection of components:

Grasshopper explode mesh with MeshEdit component

Notice how we feed a single mesh into the left, and a list comes out the other end.

This method is dependent upon MeshEdit being installed on the computer that the Grasshopper file is being used on. In cases where you can’t rely on this, for example in team working or when sharing files with clients, you might want to try…

Method 2: Use native Grasshopper components

Use this slightly clunkier method which grafts mesh data to create multiple meshes. The two components are ‘Construct Mesh’ and ‘Deconstruct Mesh’. Take care of the grafts and flattens. You could always turn these into a cluster for tidiness.

Explode Grasshopper mesh with native Grasshopper components

Method 3: Use C#

If you are writing C# and want to merge the mesh explode into a script for efficiency, or you just want to show off your Grasshopper Geek credentials, you can use the following method:

  List<Mesh> Explode(Mesh m)
  {
    var rtnlist = new List<Mesh>();

    for (int f = 0; f < m.Faces.Count; f++)
    {
      var newmesh = new Mesh();
      newmesh.Vertices.Add(m.Vertices[m.Faces[f].A]);
      newmesh.Vertices.Add(m.Vertices[m.Faces[f].B]);
      newmesh.Vertices.Add(m.Vertices[m.Faces[f].C]);
      if(m.Faces[f].IsQuad) newmesh.Vertices.Add(m.Vertices[m.Faces[f].D]);

      if(m.Faces[f].IsTriangle) newmesh.Faces.AddFace(0, 1, 2);
      if(m.Faces[f].IsQuad) newmesh.Faces.AddFace(0, 1, 2, 3);

      rtnlist.Add(newmesh);
    }

    return rtnlist;
  }

 

…which you can easily call with:

    M = Explode(m);

 

This gives a nice, tidy component:

Explode mesh in Grasshopper C# component

Learning to manipulate meshes in C# is a great skill to have, and I recommend you get into it. Recently, I have used C# to turn curves into data-light meshes, and to turn curves into roads suitable for mapping.

Whichever method you’ve chosen, if you bake the result, you should end up with something like this:

Exploded Rhino grid mesh

Grasshopper without wires: Transmit data to any component

The philosophy of data in Grasshopper is quite simple: data flows from left to right, and it flows along the wires. That is, until you break it.

Based upon a slider permutation component created by David Rutten, and modified by Mostapha Roudsari, I have created a component that can transmit numbers to any component in your canvas, even when there is no wire connection.

grasshopper-transmit-data

The value is entered in the bottom left. The component then looks for any ‘Num’ components, and send the value to them. If there are multiple components, it will find them and update them accordingly.

grasshopper-transmit-data-2

By default, if nothing is connected to that ‘input’ input, the component will update all Nums. If you only want to update certain components, connect these to ‘input’.

grasshopper-transmit-data-3

The component can potentially be created to work with any component. By finding the class of any component in Grasshopper, we can interact programmatically with it.

The component is written in the C# component and can be opened and edited directly within Grasshopper.

Download


Source code

    List<System.Guid> guids = new List<System.Guid>(); //connected components

    Grasshopper.Kernel.IGH_Param selNumsInput = Component.Params.Input[0];
    IList<Grasshopper.Kernel.IGH_Param> sources = selNumsInput.Sources;
    bool isAnythingConnected = sources.Any();

    if(isAnythingConnected && (bool) startme)
    {
      foreach (var source in sources)
      {
        IGH_DocumentObject component = source.Attributes.GetTopLevel.DocObject;

        //check if valid number
        bool validNumber = true;
        Grasshopper.Kernel.Parameters.Param_Number myNum = component as Grasshopper.Kernel.Parameters.Param_Number;
        if(myNum == null) validNumber = false; //check if it's a num component
        else if(myNum.DataType == Grasshopper.Kernel.GH_ParamData.remote) validNumber = false; //check if free
        if (validNumber)
        {
          guids.Add(myNum.InstanceGuid); //a list of free num component GUIDs
        }
      }


    }

    //this loop can probably be merged with the above, unless I'm missing something...
    List<Grasshopper.Kernel.Parameters.Param_Number> nums = new List<Grasshopper.Kernel.Parameters.Param_Number>();
    foreach (IGH_DocumentObject docObject in GrasshopperDocument.Objects) //for every GH component in document
    {
      Grasshopper.Kernel.Parameters.Param_Number num = docObject as Grasshopper.Kernel.Parameters.Param_Number; //try convert to num
      if(num != null) //if that component is a num
      {
        if(isAnythingConnected) //...and nums are connected to this C# component
        {
          if(guids.Contains(num.InstanceGuid)) nums.Add(num); //...then if that num is connected, add to 'nums'
        }
        else if (num.DataType != GH_ParamData.remote)
        {
          nums.Add(num); //else add all free num components
        }

      }
    }

    //nums is the list of all the components we want to update.

    Grasshopper.Kernel.Types.GH_Number ghnum = new Grasshopper.Kernel.Types.GH_Number(val);
    foreach (Grasshopper.Kernel.Parameters.Param_Number obj in nums)
    {
      if((bool) startme)
      {
        obj.PersistentData.Clear();
        obj.PersistentData.Append(ghnum);
        obj.ExpireSolution(true);
      }
    }

    A = nums;

Getting started with Amazon S3: A replacement for Dropbox

Dropbox is amazing. The ability to have files saved in the cloud, yet with the ease of use that comes with having them saved locally, is quite revolutionary. I could never imagine going back to the dark era of saving directly to the C drive, a time when one misplaced swing of your hard drive head could render your entire digital life erased forever.

But that’s not to say that Dropbox, or any of their rival clones like Google Drive or OneDrive, have to be the way forward. Many of these services use Amazon S3, Amazon’s famous web storage service, part of Amazon Web Services. If you’re here, you probably already have your own reasons for investigating S3, but for me it was a combination of cost (see below), wanting to learn more about how S3 works, and basically cutting out the middleman.

This guide will help you in getting started with Amazon S3: what S3 is, what it costs, and what you might do with it.

What is S3?

Think of S3 as a web app where you can store and access files online. Amazon explain the process in their words here.

When you have registered for AWS, you can access the full suite of AWS apps on their dashboard. The number of things you can do with AWS is quite bewildering, but for now let’s focus on S3.

Amazon Web Services AWS dashboard

Creating your first bucket

Within S3, you store files within top level folders called ‘buckets’. We need to create a bucket to store files in. This bucket name must be globally unique – i.e. no other bucket in the world can have the same name as yours. The reason for this is that we can choose to access our bucket with a URL, which of course must also be unique. It’s convention to start the bucket name with the organisation or website we represent.

Click ‘create bucket’ in the top left. Then give your bucket a name. You can’t change the name later, so give it something sensible.

Create new bucket for Amazon S3 dialog box

You also need to choose a region. This is the data centre that Amazon will use to store your data. There are two factors influencing your choice:

  • Price: Different regions have slightly different prices, and you might want to choose a cheaper region.
  • Distance: Generally speaking, the closer the server is to you, the faster it will be. If you are using S3 for public access (e.g. downloading files from your website) you may choose to use a region that is closer to where most of your visitors come from, rather than where you personally live.

For personal storage, Ireland was an obvious choice for me. It is close to England, and is among the cheapest.

Adding files to our bucket

Once we’ve created our bucket, we can open it and start adding files to it.

List of buckets in Amazon S3

Once inside, click ‘upload’ and add some files. When you’re finished, you should see them in your bucket!

Uploaded file in Amazon S3 screenshot

Downloading files from our bucket

Downloading files is equally simple. Just right-click on any file and click open. (You may need to enable pop-ups in your browser for this to work.) Files like .txt and .pdf will open in your browser. Otherwise, it will download. You can also just use the ‘download’ option in the right-click menu.

Right click file to open in Amazon S3

What does S3 cost?

The short answer – S3 is cheap. The average domestic user is unlikely to spend more than a few dollars each month.

Calculating the price is difficult though. Whereas Dropbox uses a flat price (currently £7.99 per month in the UK for Dropbox Pro), S3 uses a pay-as-you-go system where you pay only for what you use. You pay both for storage and for transferring data.

The different components that contribute to your S3 bill are:

  • Storage: approx. $0.03 per GB per month
  • Uploading files: approx. $0.005 per 1000 items*
  • Downloading files: approx. $0.004 per 10,000 files* PLUS $0.09 per GB (first GB free)

So, if you are storing 20GB, and each month you download 2GB consisting of 1000 files, as well as uploading/updating 200 files, you will pay (20GB * $0.03) + ($0.005 * 200 / 1000) + ((2GB – 1GB) * $0.09) + ($0.004 * 1000 / 10000) = $0.6914. These prices don’t include tax, so when we add tax of 20% (or equivalent in your country) the total is $0.83 per month.

Amazon provide a calculator to give more detailed estimated bills here. In the example above, we would enter the data as:

Estimated cost calculator example Amazon S3

Interestingly, Dropbox and other companies do offer as much as 1TB in their offers. To store 1TB with S3 would cost $30, much more than £7.99 (about $12). Costs do come down a little for large customers, but I can only assume that the 1TB is being promoted as a kind of loss-leader.

Free tier: Amazon’s introductory offer

As an added bonus, Amazon are offering 12 months of limited free service on all of AWS, including S3. Everything included in this deal is called the free tier. Among other benefits, the free tier offers:

  • 5GB free storage
  • First 2000 uploads (PUT requests) per month free
  • First 20000 downloads (GET requests) per month free

 

Read more here about the free tier.

So what can I use S3 for?

As we can see, the S3 interface is functional but very basic. In itself, it is not intended to compete with highly polished solutions like Dropbox, but with the right approach it can be a very powerful approach to handling files. Some things that you might use it for include:

S3 for personal backup

Save all of your important files to your S3 bucket. By default, your bucket is set on ‘private’ mode, so anything you upload will be secure and only accessible by you.

S3 for sharing public images and documents

You can use S3 to host images and documents for websites, or otherwise provide an alternative to FTP. Every item you upload to S3 will get its own web address. You can find this address by looking at a file’s properties in the web interface:

Amazon S3 file properties and URL

If you copy the link on the right into your browser, it should open the document.

BUT, remember the permission settings? By default, if anyone other than you tries to view this link, they will get an ‘access denied’ error in their browser.

So what we do is to change the permission so that anyone can view the image. In the properties window again, find the ‘permissions’ tab:

Add custom permissions in Amazon S3

With the above settings, you should now be able to open the file from any web connection in the world, like this one.

But be careful with this setting! It exposes your file to the world, so don’t make the mistake that many have made and use it for sensitive information. See the next item if you want controlled sharing.

Sharing files with specific people

You can set permissions to any email address, assuming the owner of that email address has also signed up for AWS with that email address. In the permissions drop down box, you can type in the email address. If that doesn’t work, you can ask the other person for their account number.

Add custom permissions Amazon S3

Other cool stuff you can try with S3

 

 

Conclusion

We’ve seen how easy it is to create an Amazon S3 account and to upload and download files from it. But the current process still feels very manual – it lacks the streamlined set-and-forget syncing ability of Dropbox.

Over the next week I will be trying different solutions to see whether a full, convenient alternative to Dropbox is possible with S3. At the moment I am transferring data from Dropbox and OneDrive with MultCloud, so let’s see how it goes!

Add a message box to Grasshopper

A great thing about being able to use C# code in Grasshopper is the ability to access other C# libraries and functions that we wouldn’t normally think of when using Grasshopper.

The message box is a good example of this, and can be a very simple and useful way of interacting with your user.

We can add a message box with a single line of C# in the C# component.

    if(System.Windows.Forms.MessageBox.Show("If you're happy and you know it, clap your hands",
      "Are you sure?", MessageBoxButtons.OKCancel) == DialogResult.OK)
      A = "clap clap";

This gives us something like this:

grasshopper-message-box

Another nice thing about message boxes is, like in ‘regular’ C# programming, we can also get a response from the message box. If I hit ‘OK’, the output A changes:

grasshopper-message-box-2

This happens because we selected MessageBoxButtons.OKCancel. We then said that if the response is equal to DialogResult.OK then we should output ‘clap clap’ to A.

Creating our own message box

The basic structure to construct our own message box is:

System.Windows.Forms.MessageBox.Show("text","title", MessageBoxButtons.OKCancel);

We can choose a range of standard message boxes. When we create our message box, we can choose from one of 6 button combinations:

message-box-buttons

We can then respond to whatever button the user presses by writing an if statement corresponding to each of the buttons we have chosen:

message-box-buttons-2

So if we want the code to respond to the user’s choice, we will end up with something of the form:

    if(System.Windows.Forms.MessageBox.Show("text","title",MessageBoxButtons.OKCancel) 
      == DialogResult.OK)
      DoSomething();

Creating an input box

It is even possible to create an input box (i.e. a message box with a space for the user to type something), though it is slightly hacky and doesn’t look so good. It’s hacky because it’s technically not implemented for C#, and we are using the flexibility of .NET to access a library that was intended to be used with VB.

The class you need is in the VisualBasic namespace:

    if(Microsoft.VisualBasic.Interaction.InputBox("If you're happy and you know it...", 
      "What are you gonna do?", "enter response here", 100, 100) == "clap your hands")
      A = "clap clap";

…and as you’d expect, if you type “clap your hands”, we will get a response in A:

grasshopper-input-box

Thanks to this forum post for the input box code