The Loop subdivision algorithm was used to subdivide the input geometry [1]. Subdivision surfaces let artists create smooth shapes from polygonal meshes. Subdivision surfaces are a more flexible alternative to NURBS since polygonal meshes can be created easier and animated better. For more information see OpenSubdiv.
Adaptive subdivision was implemented using a simple curvature metric [2]. Triangles with low curvature are on nearly flat surfaces. Subdividing further will do little to improve the rendered result. Therefore computation time and memory can be saved by only subdividing triangles above a certain curvature threshold which is set by the user. See differences in mesh density using standard and adaptive subdivision surfaces below (shown in Blender viewport).
Subdiv Iterations: None
Curvature Threshold: None
Render Time: 16s
Subdiv Iterations: 1
Curvature Threshold: None
Render Time: 1m 5s
Subdiv Iterations: 1
Curvature Threshold: 0.5
Render Time: 1m 1s
Subdiv Iterations: 1
Curvature Threshold: 1
Render Time: 56s
Subdiv Iterations: 1
Curvature Threshold: 2
Render Time: 50s
Subdiv Iterations: 2
Curvature Threshold: None
Render Time: 4m 5s
Subdiv Iterations: 2
Curvature Threshold: 0.5
Render Time: 4m 8s
Subdiv Iterations: 2
Curvature Threshold: 1
Render Time: 3m 34s
Subdiv Iterations: 2
Curvature Threshold: 2
Render Time: 2m 47s
Subdiv Iterations: 3
Curvature Threshold: None
Render Time: 16m 27s
Here is a complete scene rendered with a subdivision mesh along with other objects in the scene.
[1] Loop Subdivision Explanation: http://www.holmes3d.net/graphics/subdivision
[2] Simple Curvature Metric: https://computergraphics.stackexchange.com/a/1719
[3] OpenSubdiv: http://graphics.pixar.com/opensubdiv/docs/subdivision_surfaces.html
[4] Subdivision Surfaces in Blender: https://docs.blender.org/manual/en/latest/modeling/modifiers/generate/subdivision_surface.html
[5] OpenMesh: https://www.graphics.rwth-aachen.de/software/openmesh/