Apart from a few primitive surface types such as spheres, cones, planes and cylinders, Rhino supports three kinds of freeform surface types, the most useful of which is the NURBS surface. Similar to curves, all possible surface shapes can be represented by a NURBS surface, and this is the default fall-back in Rhino. It is also by far the most useful surface definition and the one we will be focusing on.

- Sphere Primitive [plane, radius]
- Cylinder Primitive [plane, radius, height]
- Plane Primitive [plane, width, height]
- Cone Primitive [plane, radius, height]

NURBS surfaces are very similar to NURBS curves. The same algorithms are used to calculate shape, normals, tangents, curvatures and other properties, but there are some distinct differences. For example, curves have tangent vectors and normal planes, whereas surfaces have normal vectors and tangent planes.This means that curves lack orientation while surfaces lack direction. In the case of NURBS surfaces, there are in fact two directions implied by the geometry, because NURBS surfaces are rectangular grids of {u} and {v} curves. And even though these directions are often arbitrary, we end up using them anyway because they make life so much easier for us.

You can think of NURBS surfaces as a grid of NURBS curves that go in two directions. The shape of a NURBS surface is defined by a number of control points and the degree of that surface in the u and v directions. NURBS surfaces are efficient for storing and representing free-form surfaces with a high degree of accuracy.

**Surface Domain**
A surface domain is defined as the range of (u,v) parameters that evaluate into a
3-D point on that surface. The domain in each dimension (u or v) is usually
described as two real numbers (u_min to u_max) and (v_min to v_max) Changing
a surface domain is referred to as reparameterizing the surface.

In Grasshopper, it is often useful to reparameterize NURBS surfaces so that the u and v domains both range from 0 to 1. This allows us to easily evaluate and operate on the surface.

Evaluating parameters at equal intervals in the 2-D parameter rectangle does not necessarily translate into equal intervals in 3-D space.

**Surface evaluation**
Evaluating a surface at a parameter that is within the surface domain results in a
point that is on the surface. Keep in mind that the middle of the domain (mid-u,
mid-v) might not necessarily evaluate to the middle point of the 3D surface. Also, evaluating u- and v-values that are outside the surface domain will not give a
useful result.

**Normal Vectors and Tangent Planes**
The tangent plane to a surface at a given point is the plane that touches the
surface at that point. The z-direction of the tangent plane represents the normal
direction of the surface at that point.

Grasshopper handles NURBS surfaces similarly to the way that Rhino does because it is built on the same core of operations needed to generate the surface. However, because Grasshopper is displaying the surface on top of the Rhino viewport (which is why you can’t really select any of the geometry created through Grasshopper in the viewport until you bake the results into the scene) some of the mesh settings are slightly lower in order to keep the speed of the Grasshopper results fairly high. You may notice some faceting in your surface meshes, but this is to be expected and is only a result of Grasshopper’s drawing settings. Any baked geometry will still use the higher mesh settings.

In the previous section, we explained that NURBS surfaces contain their own coordinate space desfined by u and v domains. This means that two dimensional geometry that is defined by x and y coordinates can be mapped onto the uv space of a surface. The geometry will stretch and change in response to the curvature of the surface. This is different from simply projecting 2d geometry onto a surface, where vectors are drawn from the 2d geometry in a specified direction until they intersect with the surface.

You can think of projecting as geometry casting a shadow onto a surface, and mapping as geometry being stretched over a surface.

- Mapped geometry defined by uv coordinates
- Projecting geometry onto a surface

Just as 2d geometry can be projected onto the uv space of a surface, 3d geometry that is contained by a box can be mapped to a corresponding twisted box on a surface patch. This operation is called box morphing and is useful for populating curved surfaces with three dimensional geometric components.

To array twisted boxes on a surface, the surface domain must be divided to create a grid of surface patches. The twisted boxes are created by drawing normal vectors at the corners of each patch to the desired height and creating a box defined by the end points of those vectors and the corner points of the patch.

Example files that accompany this section: http://grasshopperprimer.com/appendix/A-2/1_gh-files.html

In this example, we will use the box morph component to populate a NURBS surface with a geometric component.

- NURBS surface populated with component.
- Original component in reference box.
- Surface divided into patches.
- Twisted boxes arrayed on surface.

You should see a grid of twisted boxes populating your referenced surface. Change the U and V count sliders to change the number of boxes, and use the height slider to adjust their height.

You should now see your geometry populating your surface.