From BlenderWiki

Jump to: navigation, search
Note: This is an archived version of the Blender Developer Wiki. The current and active wiki is available on wiki.blender.org.

GSoC Final Report: NURBS Modernization

This summer I worked on improving Blender's support for NURBS surfaces. I have two goals for this document. I hope to describe my additions well enough so that interested parties can decide if they want to use them and/or suggest additional features that are necessary for them to become useful. I would also like to dispel some of the mystery surrounding NURBS surfaces so that newcomers to NURBS modeling can determine what it has to offer them.

What are NURBS surfaces?

You can think of a NURBS surface as an infinitely stretchable and infinitely smooth sheet that can be tugged into many different shapes using a grid of "control points." Alternatively, you can think of a NURBS surface as what would happen if you took a low-resolution rectangular mesh of the control points points and subdivided it infinitely many times until it was perfectly smooth (by "rectangular" I mean that you *could* lay them out in a rectangle if you wanted to, not that are situated in an actual flat rectangle). Below are some examples from the 2.4 manual. The black mesh represents the NURBS surface and the pink+yellow mesh represents the grid of control points.

Surface.
Tube.
Sphere.
Donut.

This is well and good, but what if we want to do more than make a virtual bumpy cloth or perfect sphere (i.e. shapes that are easily made by tugging on control points)? What if we want to poke a hole in the NURBS surface or mate its edges with something else? This is where things get tricky. You might imagine adding lots of control points and stretching it into the right shape, but this turns out to be so difficult that it really isn't worth the trouble. The answer is to use trim curves. Trim curves are closed 2D curves in the UV map of the NURBS surface that cut away parts of the surface. You can see an extreme example of this below (the polygons are due to the fact that the trimmed NURBS curve had just been converted into a mesh).

NURBS 2014 complex meshing.png

It is still cumbersome to specify trim curves directly, so commercial NURBS packages typically hide away these details and simply allow users to apply booleans to NURBS surfaces. By repeatedly taking the intersection/union/difference between simple shapes or by using them to "slice" one another into pieces, very complex surfaces can be built with ease.

Blender does not have the capability to perform booleans on NURBS. Until this GSoC, it didn't even have the ability to display, edit, and import NURBS surfaces that had been constructed using these techniques. Booleans and "slicing" both depend on trim curves, and Blender didn't have the ability to display trim curves. This made it impractical to use Blender as part of a NURBS modeling pipeline. Now that the problem has been fixed, hopefully Blender will be able to find use in NURBS-heavy modeling workflows.

Why use NURBS surfaces?

People tend to fall into two camps: either they find NURBS surfaces to be completely useless or they find them to be 100% crucial to their workflow. To understand this (and to understand which category you fall into) you must understand the advantages and disadvantages.

Disadvantages: Blender does not yet support enough NURBS modeling tools to be anywhere close to a 1-stop solution. Beyond that, NURBS models tend to be less compatible than meshes (they come apart at the edges when animated, different programs approximate the same NURBS curve differently, etc). So far they have been too slow and difficult to support on the GPU for them to be competitive with polygon meshes for real time 3D applications (in fact, they are usually implemented by automatically converting to polygon meshes).

Advantage: Infinite Smoothness While polygons can approximate smooth surfaces well enough for most computer graphics applications, they have less success when it comes to precisely describing physical objects. In the real world you cannot simply apply a shader and "set smooth normals" in order to make an object look smoother than it is. How many polygons would be required to describe a crankshaft and engine precisely enough that one could be assured of a good fit after sending the separate models away for manufacture? Enough to be cumbersome. How many polygons would be required to describe a swoop in the roof of a building precisely enough to chop the model into hundreds of pieces to order windows and frames that would fit together with sub-mm tolerance? Far too many. NURBS performance (in terms of both accuracy and CPU power required for display&edit) does not degrade in these situations. It should come as no surprise that NURBS surfaces are the preferred modeling tool of industrial designers and engineers.

Advantage: Control over Derivatives NURBS surfaces were originally designed by automotive manufacturers to describe curved car bodies (Pierre Bézier worked at Renault, for example). One of the key requirements was precise control over the degree of continuity between different parts of the car's surface. Simply aligning curved surfaces so that they had continuously varying normals was not enough. Many subtle effects -- the creation or elimination of visible "seams," the manner in which reflections flowed across surfaces and boundaries, etc -- depended on control over higher derivatives. NURBS surfaces are able to provide such control.

Specific GSoC Deliverables

Trim Curve Support

NURBS surfaces with trim curves can now be displayed and edited. Both mask (boolean AND) and subtraction (boolean SUB) trim curves are supported and they can overlap without issue. They are implemented in a backwards-compatible manner that degrades gracefully (older versions of blender just display them as solid NURBS surfaces). Blender files containing old NURBS surfaces can be loaded without issue. See below for examples and downloads.

Spiral Cut NURBS text cut into surface
Spiral_cut.zip NURBScut.zip

Rhino Import

Using the OpenNURBS library from McNeel (the Rhino company), .3dm files can now be imported. In fact, the two example .zip links above each contain a Rhino file that was imported in order to create the .blend file. The Rhino importer supports more than just NURBS surfaces from Rhino. Polygonal surfaces, curves, linked duplicate objects, and layers are all imported correctly.

Unfortunately, due to the complexity of the Rhino format there will likely be a "long-tail" of import-related bugs and missing features. I intend to support the Rhino Importer until it is usable for most peoples' needs.

Spiral Cut Spiral Cut
Rhino scene before import NURBS_NMO.zip

Analytical Normals, N-Gon Meshing

I did not settle for computing normals from the polygonal tessellation of NURBS meshes. Geometry-derived normals caused minor artifacts when importing cyclic surfaces and major artifacts near trim curves. Analytical normals solve those problems.

Support for N-Gon tessellation allows for higher-quality meshes to be generated from NURBS surfaces right from the start.

Spiral Cut Spiral Cut Spiral Cut
Geometry-derived Normals Analytical Normals Geometry-derived Normals
NURBS floatingverts.png New mesher hole.png New mesher donut.png
Geometry-derived Normals Analytical Normals Analytical Normals
Nurbs surf pt.png Nurbs surf d.png
Verification of Analytical Eval Mathematica Notebook

UX Improvements

The old NURBS tools had a number of frustrating ambiguities, omissions, and annoyances. NURBS control meshes didn't support loop-select, despite the fact that this is one of the most common operations used during extrusion modeling. Two different fields in the UI claimed to hold the weight of a vertex. The control mesh was drawn using thick lines and without Z-test, making for very frustrating editing of any curve that overlaps itself. The 'U' and 'V' directions of NURBS curves needed to be distinguished in order to tweak properties but the control mesh used purple and yellow lines rather than following blender's mnemonic of red=x,u, green=y,v, blue=z, so it was very difficult to tell what one was doing without painstaking trial and error. Default surfaces were created upside-down (U axis along Y axis, V axis along X axis). The default NURBS surface was a variety that is mathematically interesting ("uniform") but unintuitive to work with. The list goes on. Smoothing over these issues makes it much less frustrating to work with NURBS surfaces in blender.

NURBS draw sel spiral old.png Screen Shot 2014-08-22 at 5.14.14 AM.png

UV Editor

NURBS surfaces are literally defined as a mapping from UV space into 3D space. It only makes sense that they have a UV editor! More concretely, the UV editor allows you to interact directly with trim curves. You can create them, delete them, duplicate them, drag their control points around individually or in groups, change their boolean operation, and use all the fun selection and transform tools you are used to in other parts of blender (circle, lasso, border select and translate/rotate/scale/etc for BOTH trims and knots). Since NURBS surfaces are invariant under translation and scaling of their knot vectors, they should be easy to fit to imported textures. Just select all and translate/scale! They don't render with materials for some reason so this feature is slightly pointless until we get that sorted out but don't worry, we're working on it :)

NURBS uvedit.png

Tutorial: Swiss Cheese

Step 0: Select the "UV Editing" window layout. Press "T" in the 3D view to hide the toolshelf and/or "N" in the UV editor to show the properties panel.

NURBS tut seluv.png

Step 1: Shift-A in the 3d view, add a NURBS surface

NURBS tut 1.png

Step 2: Tab to enter edit mode.

NURBS tut 2.png

Step 3: Left-click to position the UV cursor inside the UV domain of the UV surface

NURBS tut 3.png

Step 4: Shift-A in the UV view to add a circular trim curve

NURBS tut 4.png

Step 5: Shift-D and then drag to duplicate the trim. Use 's' to scale, 'r' to rotate, etc to add variety to the holes

NURBS tut 5.png

Voilà. A delicious infinitely-thin slice of gray swiss cheese!

Special Thanks

Thanks to Sergey and Ton for putting up with my never-ending quest to push projects closer and closer to deadlines. Thanks to my roommates and family for putting up with my strange hours and increased antisocial behavior. Thanks to Les Piegl and Wayne Tiller for writing both the book I used as my major reference *and* the most useful academic papers detailing trim algorithms (evidently they wrote these at the same time). Thanks to Claas, Pedro, Andrei, and everyone else who took the time to email and reassure me that my efforts were appreciated :) Also, thanks to McNeel and associates for open-sourcing the import/export code for their fantastic (but alas, not free) modeling program Rhino!