com.jmex.subdivision
Class SubdivisionButterfly

java.lang.Object
  extended by com.jmex.subdivision.Subdivision
      extended by com.jmex.subdivision.SubdivisionButterfly

public class SubdivisionButterfly
extends Subdivision

Subdivison according to the Butterfly scheme introduced by Dyn, Gregory and Levin in ['A butterfly subdivision scheme for surface interpolation with tension control', ACM Transactions on graphics 9, 2 (1990), pp. 160-169]

Other papers used during implementetion:
'SIGGRAPH 2000 Course Notes', Denis Zorin et al. (http://mrl.nyu.edu/~dzorin/sig00course/) mainly pp. 69-75 (Contains faulty coefficients on extraordinary crease rule)
'Interpolating Subdivision for Meshes with Arbitrary Topology', Denis Zorin, Peter Schröder, Wim Sweldens. Computer Graphics, Ann. Conf. Series, vol. 30, pp. 189-192, 1996.
'Sharpen&Bend: Recovering curved sharp edges in triangle meshes produced by feature-insensitive sampling', M. Attene, B. Falcidieno, J. Rossignac and M. Spagnuolo. (contains the corrected coefficients, which I had to correct again to get it right. Where it says 'K=degree(V)+1' it should be 'K=degree(V)-1', I think... it works for me)

The SIGGRAPH 2000 Course Notes contains detailed descriptions of other subdivison schemes if anyone feels the urge to implement another one,hint, hint. Be sure to contact me if that's the case.
Among others: Catmull-Clark, Loop

Usage:
TriMesh mesh = {some trimesh};
Subdivision subdivision = new SubdivisionButterfly(mesh.getBatch(0)); // prepare for subdivision
subdivision.subdivide(); // subdivide
subdivision.apply(); // Applies the new subdivided buffers to the batch
subdivision.computeNormals(); // calculate new normals


Or you can use it without giving it a batch:

Subdivision subdivision = new SubdivisionButterfly();
subdivision.setVertexBuffer(batch.getVertexBuffer());
subdivision.setIndexBuffer(batch.getIndexBuffer());
subdivision.addToBufferList(batch.getTextureBuffer(0), Subdivision.BufferType.TEXTUREBUFFER);
subdivision.addToBufferList(batch.getTextureBuffer(1), Subdivision.BufferType.TEXTUREBUFFER);
subdivision.addToBufferList(batch.getColorBuffer(), Subdivision.BufferType.COLORBUFFER);
subdivision.subdivide(); // subdivide
subdivision.apply(mesh.getBatch(0)); // Applies the new subdivided buffers to the batch
subdivision.computeNormals(mesh.getBatch(0)); // calculate new normals


Handles triangular faces only

Author:
Tobias Andersson (tobbe.a removethisoryourclientgoesape gmail.com)

Nested Class Summary
 class SubdivisionButterfly.Edge
          Inner helper class for SubdivisonBatch to keep track of the edges
static class SubdivisionButterfly.Location
          Whether the vertex is interior or lies on a boundary
static class SubdivisionButterfly.Rule
          Which rule to use when splitting a certain Edge
See Page 73-75 in SIGGRAPH 2000 Course Notes, Denis Zorin, et al.
 class SubdivisionButterfly.Triangle
          Inner helper class for SubdivisonBatch to keep track of the triangles
static class SubdivisionButterfly.Valence
          Regular: Valence==6 for interior vertices, Valence==4 for boundary/crease vertices Extraordinary: Everything else
static class SubdivisionButterfly.VertexType
          Helper class to calculate which Rule to use when splitting an Edge whose vertices have Location and Valence Call: VertexType.getRule(valence1, location1, valence2, location2);
 
Nested classes/interfaces inherited from class com.jmex.subdivision.Subdivision
Subdivision.BufferType, Subdivision.SubdivisionBuffer
 
Field Summary
protected  java.util.ArrayList<SubdivisionButterfly.Edge> edges
           
protected  java.util.ArrayList<SubdivisionButterfly.Triangle> triangles
           
protected  java.util.ArrayList<SubdivisionButterfly.Edge>[] vertexEdgeMap
           
(package private)  SubdivisionButterfly.Location[] vertexLocation
          Maps vertex indices to the enum Location
(package private)  SubdivisionButterfly.Valence[] vertexValence
          Maps vertex indices to the enum Valence
 
Fields inherited from class com.jmex.subdivision.Subdivision
buffers, indexBuffer, newBuffers, newIndexBuffer, newVertexBuffer, vertexBuffer
 
Constructor Summary
SubdivisionButterfly()
          Constructor
SubdivisionButterfly(java.nio.FloatBuffer vertexBuffer, java.nio.IntBuffer indexBuffer)
           
SubdivisionButterfly(TriMesh mesh)
           
 
Method Summary
protected  boolean doSubdivide()
          Do the actual subdivision.
1.
 boolean prepare()
          Prepare the structures needed for subdividing
 
Methods inherited from class com.jmex.subdivision.Subdivision
addToBufferList, addToBufferList, apply, apply, clearBufferList, computeNormals, computeNormals, getBatch, getIndexBuffer, getVertexBuffer, getVertexCount, isValid, removeBuffer, setBatch, setIndexBuffer, setVertexBuffer, subdivide, unsetBatch
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

edges

protected java.util.ArrayList<SubdivisionButterfly.Edge> edges

triangles

protected java.util.ArrayList<SubdivisionButterfly.Triangle> triangles

vertexEdgeMap

protected java.util.ArrayList<SubdivisionButterfly.Edge>[] vertexEdgeMap

vertexLocation

SubdivisionButterfly.Location[] vertexLocation
Maps vertex indices to the enum Location


vertexValence

SubdivisionButterfly.Valence[] vertexValence
Maps vertex indices to the enum Valence

Constructor Detail

SubdivisionButterfly

public SubdivisionButterfly()
Constructor


SubdivisionButterfly

public SubdivisionButterfly(java.nio.FloatBuffer vertexBuffer,
                            java.nio.IntBuffer indexBuffer)
Parameters:
vertexBuffer -
indexBuffer -

SubdivisionButterfly

public SubdivisionButterfly(TriMesh mesh)
Parameters:
mesh - The TriMesh that is to be subdivided
Method Detail

prepare

public boolean prepare()
Prepare the structures needed for subdividing

Specified by:
prepare in class Subdivision
Returns:
true always :)

doSubdivide

protected boolean doSubdivide()
Do the actual subdivision.
1. Set up the new buffers
2. Split all edges and interpolate all buffers according to the Butterfly scheme 3. Construct new triangles

Specified by:
doSubdivide in class Subdivision
Returns:
true always :)