Yeti – public release

posted by on 2011.05.29, under Programming, Projects

Yeti is now available for download from yeti3d.com. It is still a proof-of-concept more than a parametric modelling environment, but there is enough going on that others may find it useful – particularly for setting the underlying geometry of models.

The latest version allows the generation of custom objects (shown in the video above). The geometry remains really limited – points, straight lines and circles – until I sort out how arrays of data will work.

Yeti is written in C# and I made the source available at bitbucket in case anyone is curious about how it goes together or wants to make it better.

HTML5 & WebGL

posted by on 2011.05.16, under Programming

Innovation comes from funny places. In 2005 Apple introduced the Dashboard; a largely impractical application that overlaid the desktop with little Widgets reminding you of the time, weather, and stock-market prices. The most redeeming feature of the Dashboard was that when you added a new Widget to the Dashboard it made the screen ripple like it was made from water and, since not all computers at the time were powerful enough to do this, the Dashboard’s rippling became an unofficial performance benchmark. Despite the frivolous nature of Dashboard, the Widgets have an important legacy (other than being a precursor of the iPhone apps).

Dashboard Widgets are made up of HTML, CSS, and Javascript – the same stuff websites are made from. Except Apple added one extra word to the Widgets vocabulary: canvas. This little, propitiatory, modification of the HTML language allowed Widget designers to write Javascript code that drew shapes in the Widget – much like Processing.  Three years later, in 2008, and HTML standard was updated to standardise the drawing of drop-shadows across browsers (a big deal if you are a webdesigner) and to include the canvas tag as part of the official HTML standard (a big deal if you are an architect). Now in 2011, ‘canvas’ has been extended to allow the drawing of 3d shapes with WebGL.

What is WebGL?

Prior to WebGL the only practical way of drawing 3d objects in a web-browser was through a plugin like Flash or Java (not the same as Javascript). Plugins are slow because the when the plugin code decides to draw a line, it must ask the plugin, which must ask the webbrowser, which must ask the operating system, which must ask several other layers of the computer, to draw the line onscreen. This journey through the grapevine is inevitably slow. WebGL skips these layers by allowing Javascript access to the GPU, meaning WebGL can send data straight to your videocard to be rendered. WebGL also has the advantage that it is native to the browser, so users don’t need to download or install any additional plugins to view 3d content – currently only the latest versions of Chrome and Firefox support WebGL, but all browsers (except possibly IE) will support it in the coming months.

Why WebGL is important to CAD

It is inevitable that in the near future CAD models will be able to be viewed in a browser using WebGL. There are already some early examples of this happening with PythonOCC/WebGL which exports 3d models to WebGl; the Surface Explorer, which draws doubly curved surfaces from equations; and most beautifully in the Google Body Explorer, which allows you to interact with a rather complex 3d model of the body. And I have it on good authority that at least one major CAD manufacturer is making a ‘dropbox for CAD files and project data.’

With 3d models now viewable on the internet, the critical question becomes how much interaction will be enabled. Will you be able to view associated model data? Will you be able to modify a model? Will you be able to generate a model? Will the browser become your preferred way of designing?  Some early applications like CloudSCAD, 3dTin, Shapesmith (shown above) and TinkerCAD, would say ‘yes’ to all of the above. There are some advantages to this approach:

  1. Users don’t have to download software and updates can be made instantly.
  2. Theoretically the application is cross platform and cross device.
  3. Users can use less powerful computers to do more complex tasks by offloading the work onto the server. The server might be able to do the rendering or object population, the server could also load a really large model while giving the user a simplified version of the area they are working on. It is also a better use of resources to have one server constantly working hard rather than every user intermittently working their computer hard.
  4. Live connections to other databases. A few years ago I helped start ProductSpec, and it has always been on the roadmap to have the Productspec database linked to CAD models so that as manufactures change product data, this is reflected, in realtime, within the model.
  5. All of the associated advantages of cloud computing: less piracy, more payment granularity, online storage/backup ect.

However even with the examples of early WebGL CAD software and all the advantages listed above, I am still not entirely convinced we will be designing with WebGL in the future. For one thing CAD manufactures, who have a lot invested in large code bases, are going to be slow making the switch. There may be a new generation of companies that develop WebGL applications but (at least initially) they are going to look underdeveloped compared to their desktop rivals. Secondly, as painful as C++ development can be, writing a CAD program in Javascript is simply sadistic – there are problems with browsers being consistent, there are performance issues, there are security issues. Instead I think WebGL is going to spark a new generation of software, which are more interactive than a printed drawing and less featured than a full fledged CAD package.

It is interesting to see that the next iteration of architectural representation isn’t emerging from the past 20 years of discourse flowing out of architectural theorists and philosophers, but it comes from a technology Apple developed to add a bit of bling to the desktop.

Threading Grasshopper

posted by on 2011.05.07, under Programming

An alternative title might be Why CAD software hasn’t gotten any faster in the last three years. Simply, most CAD software is written to take advantage of only one processor, leaving the other three processors in your shiny new Quad-core i7 idle. The solution to the multi-processor problem is threading. Programming threads can seem daunting, I put them off until I had to create one for Yeti to, of all things, check for updates in the background without hanging up the interface. To my surprise I found threading in modern programming languages almost elegant. Naturally I was curious about whether threads can be used in Grasshopper, and whether they give any performance increase. It turns out threads can be used in Grasshopper, and that they significantly increase performance  - on my shiny new Quad-core i7 I get an almost 200% improvement. This post is the third part of a series on Optimising Grasshopper (following on from part one and part two). In this post I will explain a fairly ninja technique for breaking C# nodes down into multiple threads to be processed in parallel by all the processors on your computer.

What are threads?

Roughly speaking, a thread is a list of tasks for the processor in your computer to execute. All programs and scripts get compiled into a thread of tasks, which are then feed through the processor in linear order to produce the desired outcome. Conceptually this could be thought of as a chain of grasshopper nodes being evaluated one at a time by the processor.

One processor works on the graph while the other three sit idle

Threads get interesting when you have more than one processor, like on the Quad-core Intel processor, which has four processors sitting in parallel. With a multi-processor computer, you can have each processor working on a separate thread. So the Quad-core processor can work through four threads simultaneously (it can actually work through more due to some processor magic but that is getting a little technical). The difficulty with a multi-processor computer is that the processors can not ‘talk’ to each-other, so (as shown above) a thread can only go through one processor at a time. This essentially means that if one of the processors on the Quad-core processor gets a really long thread of tasks, it cannot ask the neighboring processors to help out with some of the tasks, even if they are sitting idle. This is why sometimes you will be updating a really complex model in Grasshopper, and see the processors only working at 25% – there is only one thread going through the processors so only one of the four processors is actually working.

Multi-threading

Since the processor can not break a single thread into multipul strands, we have to break the tread up for the processor. Essentially rather than giving the processor one long thread of tasks, we can break the tasks up into little bundles of work, and generate a thread of tasks for each bundle. That way we can send a single thread of tasks as multipul threads and get each processor to work on a little part by itself.

By splitting the thread up, it can be sent to more than one processor

Multi-threading in Grasshopper

To test threading in Grasshopper I decided to recreate the Project-point-to-surface node in Grasshopper. The full node can be downloaded from Parametric Model. The critical line of code in the node comes within this for-loop:

for(int i = 0; i < total; i++)
{
  if(p[i] is Point3d)
  {
    int tempI = i;
    Point3d tempP = (Point3d) p[i];
    taskInfo task = new taskInfo(tempI, tempP);
    System.Threading.ThreadPool.QueueUserWorkItem(pntToSrf, task);
  } else done--;
}

Essentially this loop works its way through every point passed to the node. It then adds the point and the point’s index to a taskInfo object – a custom object created to store the information about the point being projected to the surface. The point is then projected onto the surface by calling the pntToSrf function and passing the taskInfo object in this line:

    System.Threading.ThreadPool.QueueUserWorkItem(pntToSrf, task);

Basically this line of code calls the pntToSrf function, but rather than calling it on the main thread (as you would do in a singally threaded application), it sends the function to the ThreadPool where a manager runs it on the next available thread. The ThreadPool has many different threads running through each processor in parallel, so the manager will send the pntToSrf function to whatever processor is not doing any work, which utilises the power each processor.

A couple of tricky things happen inside the thread, like the arrays are locked whenever data is written to them, to prevent the threads sending data into the array simultaneously:

lock(locker)
{
  outP[index] = myPoint;
  outUVP[index] = uvPoint;
  outD[index] = myDis;
  done--;
}

Finally, since the threads are executing co-currently to the main thread, we have to pause the main thread until the other threads have finished processing before returning the data from the node. For simplicity sake I have used a really naive method of waiting, which loops until the right number of tasks are done.

while(done > 1)
{
  System.Threading.Thread.Sleep(2);
}

And that is it.

In terms of performance, on my quad-core computer, the normal Grasshopper srfCP node can project 1,000,000 points onto a sphere in 10.0 seconds. Compared to both Digital Project and GC, this is remarkably fast, although it is nothing like the performance of Open Cascade. The same task performed with my threaded srfCP node takes 4.5 seconds, which is roughly a 2X improvement over the non-threaded version. You will notice using four cores does not result in a straight up 4X improvement, this is in part because some processor power is used to manage the threads, and partly because aspects of the code still happen in serial.

Native types in Grasshopper

outP = new GH_Point[total];
outUVP = new GH_Point[total];
outD = new GH_Number[total];

Some keen eyes would have picked up that the C# node is returning an array of GH_point’s rather than an array of point3d’s. When a C# node returns a point3d, this is automatically converted by Grasshopper into a GH_Point (allowing it to be baked ect.). This conversion is computationally expensive, presumably because Grasshopper is checking the data is valid. To avoid this performance hit, we can sidestep the conversion by giving Grasshopper the data back in its native format, a GH_Point. The other native Grasshopper formats can be found under Grasshopper.Kernal.Data. Similarly if the inputs to a node are of a specific type, Grasshopper does an automatic conversion. By asking for the inputs as a System.Object this conversion can be avoided.

A word to the eager

While multi-threading offers significant speed improvements, it is not without downsides. It can be challenging and frustrating to debug threaded code since interactions between threads can throw unforeseen errors from bugs that are invisible in the Grasshopper IDE. These errors will often crash Rhino: save frequently. Furthermore, not all functions in Rhino 4 are thread safe. So if you use the unsafe function of  plane-brep intersection in different threads, you will  either crash Rhino or end up with strange results. Rhino 5 addresses some of the thread safety issues and once it moves to .Net4.0 there will be access to even easier threading functions. For now take this post as an explanation for why CAD software hasn’t gotten any faster in the last three years, but expect to see significant performance increases in the near future once CAD finally catches up to processor developments.

For more information about multi-threading I recommended Joseph Albahari’s excellent tutorial on C# threading.