The toolbars in Rhino underwent a rigorous rewrite between versions 3 and 4. Among other new features, Rhino 4 toolbar buttons support images with alpha channels. Earlier versions of Rhino only contained a one-bit transparency mask (yes-or-no, transparent-or-opaque).
Alpha channel blending allows a better integration of icons into the workspace. This wiki page provides information about how alpha channeled icons work, how you can change existing icons, and how to make new icons that look like the default set. There is also some good information in the Microsoft web site about this.
All pixel images are stored in (usually a combination of) channels. The most famous combination is the RGB (Red-Green-Blue) mix. An RGB image contains three channels. Each controls a specific property of every pixel, namely the amount of red, green and blue that goes into making the final color.
Grayscale images contain only one channel, which controls the amount of white for every pixel.
In an RGBA (Red-Green-Blue-Alpha) image, there are four channels. The alpha channel controls the level of transparency per pixel. Since this level can have 256 different values (0 equals completely transparent, 255 equals completely opaque, and the between values equal a partial transparency), we can now use varying levels of transparency per pixel in toolbar icons:
|Here is an image with a binary alpha channel. Pixels are either completely opaque or completely transparent. No middle ground. Binary alpha channels do not mix well into variable backgrounds. This is why anti-aliasing is impossible with 1-bit alpha channels.|
|The same icon with a smooth alpha channel (256 different levels of transparency).|
|Note: These partially transparent pixels typically only occur along the edges of the image. This is called anti-aliasing. In anti-aliasing, 8-bit alpha channels provide enough blending range to make icons that work well on any background.|
|Note: Properly aligned vertical and horizontal lines look exactly the same whether they have anti-aliasing or not. Alpha-channels are an additional feature to be used when applicable. They do not replace existent functionality. In other words, images with alpha channels can behave exactly the same as images without alpha channels, but not the other way around.|
Anti-aliasing is more than just a few semi-transparent pixels near shape edges. Since there is plenty of reading material available on this topic on the web, I will only briefly dive into it.
Anti-aliasing is an intelligent way of adding sub-pixel detail to images. Instead of finding the object in the dominant drawing for any given pixel, all objects are sampled and combined based on their relative dominance. For every pixel in the image, the amount of overlap with every object is measured. The color of that pixel becomes the weighted average of the colors of all overlapping objects.
Note: Applications who render anti-aliased geometry onto the screen use a method like this, but downsizing a pixel image (downsampling) has the same effect.
I'd love to type a thousands words on the subject right now, but I think I'll get out cheap by using an example:
|Here are two images representing two manifestations of the same drawing. The first image is a screenshot of the program used to draw the image. It shows the on-screen rendering of vector objects. All the shapes are defined by line and bezier segments in a continuous space (i.e. not gridded such as pixel-images). The second image shows the anti-aliased pixel bitmap extracted from the vector-drawing. Both images are blended with a pink background.|
The size of the extracted image is 24×24 pixels. Since this information was available when the vector drawing was made, the vector shapes have neatly aligned to a 24×24 grid. Let's look closer at column #4.
The only object which overlaps this column is the black outline of the box. Eleven pixels in column #4 are not overlapped by any object and are left completely transparent. Nine pixels are completely overlapped by the outline and inherit the color of the outline without modification. None of these pixels contain any anti-aliasing. It is the four pixels at the top and bottom of the outline shape which are interesting right now. They are only partly obscured by the outline shape and as a result, the color of these pixels is not 100% black. The amount of transparency in these pixels is directly linked to their amount of overlap. Actually, only the top pixel (column:4 row:8) has a notable blending. The overlap in the other three pixels is so all-or-nothing that the blending is hardly visible. This is not an accident. Anti-aliasing is all fine and dandy, but it works by averaging pixels. This means that an anti-aliased line is always more fuzzy than an aliased (or pixelated) line. Anti-aliasing is a bit like a jack-hammer in this respect. It's a useful tool but you don't necessarily want to use it to change a light bulb. If you do, you'll end up with the following:
|Here, the vector objects have moved half a pixel left and upwards. You can see that there are many more pixels partly obscured by the black outline and no pixels at all which are completely obscured. The resulting 24×24 icon lacks all the crisp features of its aligned brother.|
The lessons so far:
|This table shows the difference between anti-aliased and pixelated lines at different tilting angles. It becomes clear that low angles (near 0° or 90°) result in extreme fuzziness of anti-aliased lines.|
To change an existing icon into something a little different (for example, you've written a script in which you would like to add to a button), there are three things you can do:
Changing the icon image
This is the simplest method of changing icons. You do not need any software besides Rhino. It is ideal for adding pixelated geometry such as texts, arrows, or simple lines (0°, 45° or 90°).
Note: If you have access to a good pixel editor you could technically use a whole range of tools and filters (blurring, hue changes, contrast adjustments, to name a few) on the small icon images. You'll have to extract the icon from the button onto the hard-drive and edit it separately though. Rhino only provides the most basic drawing tools.
First, copy the button you want to change to a new location and then open the button editor using Shift+RMB. Let's assume that we've written a new command alias to create a box by picking a base edge and a point on the opposite edge. To create a new button for this, we need to copy the regular box button and change the way it works. Open the button editor by Shift+RMB and you'll see the following dialog:
I've already updated the text fields in the button editor to cater to our new tool, but the icon is still unchanged. We have to open the Rhino Bitmap Editor if we want to fiddle with the pixels:
Now we can change pixels in the image. We need to highlight one edge (i.e. make it 2 pixels wide and white), mark it off by point objects (4×4 pixel blocks with a black outline and creamy white center) and add a point object on the opposite edge. Like so:
Other examples of pixelated geometry are arrows and texts. You can easily add these to existing buttons. Use the following table of pixel-rules to make your icons compliant with the default ones:
Changing the base image
To help with the creation of anti-aliased icons, all images have been rendered to large bitmaps as well. All the icon images are available as full-color, full-alpha png images. You can use these base images to add anti-aliased geometry to icons. Since base images are much larger than actual icons, anything drawn into the base image is downsampled several times and automatically anti-aliased. For this job you'll need a separate pixel-editor such as Photoshop, PaintShop, or anything else which exceeds Microsoft Paint. In this case, I used JASC PaintShop Pro, but the method is fairly general.
First, you need to load the base image into the editor and apply the alpha channel (some editors will load the alpha automatically). You will see something like this:
|Note that the image displayed here is only 384×384 pixels large. The original base images are twice this size, i.e. base images are 32 times larger than the icons. I have also enabled the display of the pixel-grid (the dotted black lines). If you look closely at the image you'll notice that it is pixelated. This makes it easier to post-process the image.|
Now imagine we have a command (or a macro or alias or whatever) which applies a green glass material to an object and we use this command more than 261 times a day. It would be nice to have a button that runs the command for us, and it would be even nicer to have a neat icon to accompany it. Obviously this icon needs to be a green, transparent something. Since we've used the box icon before, we'll use it again here.
To make the box icon transparent and green, we cannot use the simple method of changing individual pixels. First, the transitions between the sides of the box are anti-aliased, so we have to manually invent all those new blending colors. This is not impossible to do, it's just boring. After we've changed the image hue, we also need to make it transparent. A good illusion of transparency is to highlight some occluded faces and to darken others. This is also tedious to do on a per-pixel basis. If you have a good pixel-editor, these adjustments are peanuts:
|I applied new colors to the faces using the paint bucket tool. Then I copied the two vertical faces of the box onto the opposite sides using the magicwand selection tool, changed their colors (to white and black respectively) and made them very translucent. These faces should be behind the box, but we can draw them on top of the box using such trickery. You can see that the image conveys a strong sense of transparency.|
My edited image has collected a few extra layers on the way and before I can put the image into Rhino, I need to combine all superimposed layers and turn it into a small icon (say, 24×24 pixels). If you need to merge (combine) layers, make sure you do not simply flatten the image. Flattening typically destroys existing alpha channels. JASC PaintShop Pro provides several merging modes. Merge Visible is the one we need:
After the image has merged into a single layer including an alpha-channel (provided this was necessary), the drawing has to be downsampled to the size of the icon.
Note: Many high-end pixel editors provide more ways than one to deal with transparent pixels. The most common modes are alpha channels and mask-layers. The difference between the two is that alpha channels contain the transparency information in the color of the pixels itself. Mask-layers simply use a separate grayscale image to control the transparency. If you're having problems saving *.png files with proper transparency information, try switching between these modes.
Be sure to use a good sampling algorithm when resizing the image (for example, bicubic, bilinear or lances). If you're using an unsuitable algorithm, your icon will end up looking fuzzy or pixelated:
Changing the vector drawing
Sometimes, we make so many changes to an icon that adjusting the base or icon image is not an effective approach. In that case (or even if you need to create a new icon from scratch), you're better off using a vector editor to fiddle with the vector objects that make the icon. All the Rhino 4 icons were drawn in Xara, but you can also use Illustrator or any other illustration package. The source files (each containing many related icons) are available for download from this wiki page.
When creating new icons first find one which resembles your goal. It is possible that no existing icons looks anything like what you're after, but those cases are rare. Let's assume we once more need the box icon:
The vector source images have been layered to ease the alignment and export tasks. In Xara, layers can reside either in the background or the foreground. Layers in the background (Guides and Background) are not included when Xara converts the vector drawing to a pixel image. The only object in the Background layer is the green square behind the icon. This square is used to preserve the alignment and positioning of the foreground objects with respect to the pixel-grid. It is not important yet.
The Guides layer contains a set of infinite lines that mark the boundaries of all icon areas (the red, dotted lines). For now, it can be ignored also.
The Obj_Base layer contains all the objects that make up our icon, in this case, the blue faces and the black outline.
The Pixelgrid layer contains a red grid which corresponds with the pixels of a 24×24 icon. You can use this grid to align your objects. Also, the Xara file has a predefined grid (just like Rhino) which has been preset at half-pixel intervals. This means you can easily snap to pixel-centers and pixel-borders. Using Xara's illustration tools, you can quickly adjust the vector objects to make new icons:
|I dragged a few control points around to new grid locations, made two copies, and changed a few colors. Adjusting the icon took less than one minute.|
Once you are happy with the new image, create an icon file that Rhino understands. Depending on which application you are using, you can use one of the following methods:
Save the icon directly
If your vector illustration program delivers good anti-aliasing on a small scale, you can simply save the vector objects directly to a 24×24 *.png file:
|In Xara, this method works well, especially with properly aligned vectors. Xara's internal renderer automatically snaps certain objects to the pixelgrid, so crispness is easy to attain. The left pane shows the image as it will be saved. The icon itself is only 17 pixels wide and 22 pixels high, but it needs to be positioned in the center of the square icon area. Hence the need for a background rectangle.|
Creating a base image
If saving images at small sizes does not give you satisfactory results, you can take the long way round and create a base image. You'll have to downsample it separately in a pixel editor, as we discussed in the previous paragraph. This image should be large enough to fit a whole number of times around the icon. I recommend using nice round (from a computer point of view) numbers such as 16, 24 or 32. Starting from an icon size of 24, a few multiplication factors with resulting base dimensions and downsampling factors (the number of base pixels that will go into creating a single icon pixel) are:
I also recommend turning off anti-aliasing when creating base images. It serves no purpose and only gets in the way of post-processing operations.
When creating your own icons, you should stick to the Rhino native style. There is not a tight set of rules for icons, but a few general pointers do exist:
|Color definition (R,G,B)||Use|
|255,255,255||Brightest areas of regular objects|
|242,242,242||Normal areas of regular objects|
|197,197,197||Dark areas of regular objects|
|83,83,83||Extra dark areas of regular objects|
|200,212,255||Brightest areas of emphasized objects|
|110,142,255||Normal areas of emphasized objects|
|45,80,200||Dark areas of emphasized objects|
|0,32,136||Extra dark areas of emphasized objects|
|255,235,116||Brightest areas of selected objects|
|255,218,0||Normal areas of selected objects|
|175,90,0||Dark areas of selected objects|
|118,60,0||Extra dark areas of selected objects|
Note! Exporting vector images from Xara to Illustrator is not a one-to-one translation. Many advanced features (gradient progressions, blending modes) are missing in the Illustrator files.