
                        NURBS with Extraordinary Points:
             High-degree, Non-uniform, Rational Subdivision Schemes

  Thomas J. Cashman   Ursula H. Augsdörfer   Neil A. Dodgson   Malcolm A Sabin

                   Auxiliary material: Example implementation


This archive contains an implementation of the subdivision method we describe in
the paper "NURBS with Extraordinary Points: High-degree, Non-uniform, Rational
Subdivision Schemes", which appeared at SIGGRAPH 2009. The implementation has
three parts:
 - libsnurbs, a subdivision library for creating NURBS with extraordinary points
 - snurbs-cl, a very simple command-line interface to the library
 - snurbs-vis, a graphical interface to the library

The source code for these three components is either provided in this archive,
or is available online at <http://www.cl.cam.ac.uk/~tc270/subdnurbs.html> (if
this archive contains only precompiled binaries). The implementation is made
available under a GPL license: see the file COPYING for details.

To understand how to use the library in other projects, snurbs-cl provides a
simple example. To experiment with the surfaces interactively, snurbs-vis is the
most convenient interface. The library is also provided with full documentation,
which can either be built from the source files using "doxygen", or can be
accessed online at <http://www.cl.cam.ac.uk/~tc270/subdnurbs-doc/>.

This README explains:
 - how to use "snurbs-vis"
 - the file format used by "libsnurbs"
 - how to use "snurbs-cl"
 - how to build all three components from the source code


How to use "snurbs-vis"
-----------------------

snurbs-vis uses OpenGL to display the surfaces created by libsnurbs. Load a file
using File->Open, and click and drag in the main viewing area to rotate. To
zoom, either use the mouse wheel or drag vertically whilst holding the right
mouse button. There are several different viewing modes provided on the toolbar
at the top of the viewing area.

To change knot spacings, you must first select a knot interval:
 - Select the option to draw the control mesh (either from the toolbar, or from
   the View menu). The control mesh material is translucent, so this option
   works well after the surface has been subdivided a few times.
 - While the control mesh is displayed the left mouse button still rotates the
   view, but the right mouse button is used to select a knot interval.
   Right-click near an edge of the control mesh to select the knot interval
   across that edge.
 - The viewing area will show the selected knot interval (which appears as a
   strip of quadrilateral faces) in a pink/red colour.
The knot spacing of the selected interval can then be modified using the
"subdivision" toolbar which appears to the left of the main viewing area.


The file format used by "libsnurbs"
-----------------------------------

This implementation uses the Stanford PLY format, with the additional element
"knot_interval" to store non-uniform knot spacing. In the 'ply' subdirectory,
we have included the PLY input files for every surface shown in the paper and
video*, as well as a few additional examples. You can try modifying these files
or subdividing your own, but remember the restriction that each face must be a
quadrilateral (see Section 5.1 of the paper). Of course the objects must also be
2-manifold, and faces must have a consistent orientation (if either condition is
not satisfied, the implementation may not fail gracefully).

Knot intervals are specified in a PLY element called "knot_interval". If there
are no knot intervals specified, then libsnurbs will subdivide uniformly. When
they are supplied, knot interval elements appear at the end of the sample PLY
files. An example from ply/other_examples/cube.ply is

  0 1 1.0
  1 2 1.0
  1 5 1.0

This specifies unit knot intervals for the three strips of quadrilateral faces
that appear on the cube. To try a non-uniform knot spacing, modify one of the
three values at the end of the lines.

* Note that to replicate the same surface as shown in the paper or video, the
library must be passed the correct degree. For example, the surface shown in
Figure 1b can be created using
  snurbs-cl --degree=3 --steps=6 ply/paper/figure_1bc.ply
Whereas the command used to create the surface shown in Figure 1c is
  snurbs-cl --degree=7 --steps=6 ply/paper/figure_1bc.ply


How to use "snurbs-cl"
----------------------

Command-line options include:
  --steps=#        The number of subdivision steps to take
  --degree=#       The degree (must be odd) at which to subdivide
  --outfile=file   Write the result to 'file' instead of standard output
  --help           Display a summary of options

For example:
  snurbs-cl --steps=3 --outfile=subdivided_cube.ply ply/other_examples/cube.ply

To view the surfaces created by snurbs-cl, you can either use snurbs-vis, or you
can use a freely available PLY viewer such as MeshLab
<http://meshlab.sourceforge.net/>.


Building from source
--------------------

To build this implementation from source, you will need to have the following
dependencies installed:
 - a C++ compiler that implements the TR1 standard; particularly the
   <tr1/functional> header (in the case of GCC, which we used, this means
   version 4.2 or higher)
 - Qt 4 (we used version 4.2, but earlier 4.x versions may also work)
 - Boost
In the following instructions, I refer to the directory containing the source
code as $SRCDIR.

First you need to build the dependency "libply", which is provided in the
subdirectory src/libply:
  cd $SRCDIR/src/libply
  ./configure --prefix=$SRCDIR
  make && make install

To build libsnurbs, and the two sample applications snurbs-cl and snurbs-vis:
  cd $SRCDIR
  qmake -recursive
  make

To build the documentation for libsnurbs:
  cd $SRCDIR
  doxygen Doxyfile
(the documentation will then appear in the subdirectory "html")

Then to execute snurbs-vis, either:
  cd $SRCDIR/bin
  LD_LIBRARY_PATH=../lib:$LD_LIBRARY_PATH ./snurbs-vis
or:
  cd $SRCDIR
  export LD_LIBRARY_PATH=$SRCDIR/lib:$LD_LIBRARY_PATH
  ./bin/snurbs-vis
In either case, replace 'vis' with 'cl' to run snurbs-cl instead
