artofillusion.object
Class TriangleMesh

java.lang.Object
  extended by artofillusion.object.Object3D
      extended by artofillusion.object.TriangleMesh
All Implemented Interfaces:
FacetedMesh, Mesh

public class TriangleMesh
extends Object3D
implements FacetedMesh

The TriangleMesh class represents an aritrary surface defined by a mesh of triangular faces. Depending on the selected smoothing method, the surface may simply consist of the triangular faces, or it may be a smooth subdivision surface which either interpolates or approximates the vertices of the control mesh.


Nested Class Summary
 class TriangleMesh.Edge
          An edge is defined by the two vertices which it connects, and the two faces it is adjacent to.
 class TriangleMesh.Face
          A face is defined by its three vertices and three edges.
static class TriangleMesh.TriangleMeshKeyframe
          This class represents a pose of a TriangleMesh.
 class TriangleMesh.Vertex
          A vertex specifies a position vector, the number of edges which share the vertex, and the "first" edge.
 
Field Summary
 
Fields inherited from class artofillusion.object.Object3D
APPROXIMATELY, CANT_CONVERT, EXACTLY
 
Fields inherited from interface artofillusion.object.Mesh
APPROXIMATING, INTERPOLATING, NO_SMOOTHING, SMOOTH_SHADING
 
Constructor Summary
TriangleMesh(java.io.DataInputStream in, Scene theScene)
          The following two methods are used for reading and writing files.
TriangleMesh(TriangleMesh.Vertex[] v, int[][] faces)
           
TriangleMesh(Vec3[] v, int[][] faces)
          The constructor takes three arguments.
 
Method Summary
 void applyPoseKeyframe(Keyframe k)
          Modify this object based on a pose keyframe.
 void autosmoothMeshEdges(double angle)
          Automatically select smoothness values for all edges in the mesh.
 boolean canConvertToActor()
          Allow TriangleMeshes to be converted to Actors.
 int canConvertToTriangleMesh()
          Tells whether the object can be converted to a TriangleMesh.
 TriangleMesh convertToTriangleMesh(double tol)
          Get a more finely subdivided version of this mesh.
 void copyObject(Object3D obj)
          Make this object exactly like another one.
 MeshViewer createMeshViewer(MeshEditController controller, RowContainer options)
          Get a MeshViewer which can be used for viewing this mesh.
 Object3D duplicate()
          Create a duplicate of this object.
 void edit(EditingWindow parent, ObjectInfo info, java.lang.Runnable cb)
          Display a window in which the user can edit this object.
 void editGesture(EditingWindow parent, ObjectInfo info, java.lang.Runnable cb, ObjectInfo realObject)
          Edit an object which represents a gesture for an Actor object.
 int[][] findBoundaryEdges()
          Calculate a set of array representing the boundaries of this mesh.
 BoundingBox getBounds()
          Get the bounding box for the mesh.
 TriangleMesh getDisplacedMesh(double tol, double time)
          Create a new triangle mesh by applying the displacement map of the texture assigned to this object.
 TriangleMesh.Edge[] getEdges()
           
 int getFaceCount()
          Get the number of faces in this mesh.
 TriangleMesh.Face[] getFaces()
           
 int getFaceVertexCount(int faceIndex)
          Get the number of vertices in a particular face.
 int getFaceVertexIndex(int faceIndex, int vertexIndex)
          Get the index of a particular vertex in a particular face.
 Vec3[] getNormals()
          Get an array of normal vectors.
 Object3D getPosableObject()
          TriangleMeshes cannot be keyframed directly, since any change to mesh topology would cause all keyframes to become invalid.
 Keyframe getPoseKeyframe()
          Return a Keyframe which describes the current pose of this object.
 Property[] getProperties()
          Get a list of editable properties defined by this object.
 java.lang.Object getPropertyValue(int index)
          Get the value of one of this object's editable properties.
 RenderingMesh getRenderingMesh(double tol, boolean interactive, ObjectInfo info)
          Objects which can be rendered as part of a scene should override this method to return a RenderingMesh which describes the appearance of the object.
 Skeleton getSkeleton()
          Get the skeleton for this object.
 int getSmoothingMethod()
          Get the smoothing method being used for this mesh.
 TriangleMesh.Vertex getVertex(int i)
           
 Vec3[] getVertexPositions()
          Get a list of the positions of all vertices which define the mesh.
 MeshVertex[] getVertices()
          These methods return the lists of vertices, edges, and faces for the mesh.
 WireframeMesh getWireframeMesh()
          Every object should override this method to return a WireframeMesh.
 boolean isClosed()
          Tells whether the object is closed.
 boolean isEditable()
          If the object can be edited by the user, isEditable() should be overridden to return true.
 void makeRightSideOut()
          If necessary, reorder the points in each face so that the normals will be properly oriented.
static TriangleMesh optimizeMesh(TriangleMesh mesh)
          Return a new mesh which is an "optimized" version of the input mesh.
 void reverseNormals()
          Reorder the vertices in each face, so as to reverse all of the normal vectors.
 void setMaterial(Material mat, MaterialMapping map)
          When setting the material, we need to clear the caches.
 void setParameterValue(TextureParameter param, ParameterValue val)
          When setting texture parameters, we need to clear the caches.
 void setParameterValues(ParameterValue[] val)
          When setting texture parameters, we need to clear the caches.
 void setPropertyValue(int index, java.lang.Object value)
          Set the value of one of this object's editable properties.
 void setShape(TriangleMesh.Vertex[] v, int[][] faces)
          This method rebuilds the mesh based on new lists of vertices and faces.
 void setSize(double xsize, double ysize, double zsize)
          Resize the object.
 void setSkeleton(Skeleton s)
          Set the skeleton for this object.
 void setSmoothingMethod(int method)
          Set the smoothing method.
 void setTexture(Texture tex, TextureMapping mapping)
          When setting the texture, we need to clear the caches.
 void setVertexPositions(Vec3[] v)
          Set the positions for all the vertices of the mesh.
static TriangleMesh subdivideButterfly(TriangleMesh mesh, boolean[] refineEdge, double tol)
          This method subdivides the mesh using interpolating (modified Butterfly) subdivision, and returns a new TriangleMesh which approximates the limit surface to within the specified tolerance.
static TriangleMesh subdivideEdges(TriangleMesh mesh, boolean[] splitEdge, double tol)
          Subdivide all or part of the mesh using the mesh's defined smoothing method (linear, approximating, or interpolating).
static TriangleMesh subdivideFaces(TriangleMesh mesh, boolean[] split)
          This method splits each selected face into three faces, and returns the subdivided mesh.
static TriangleMesh subdivideLinear(TriangleMesh mesh, boolean[] split)
          This method subdivides each selected edge once, placing a new vertex in the midpoint of the edge, and returns the subdivided mesh.
static TriangleMesh subdivideLoop(TriangleMesh mesh, boolean[] refineEdge, double tol)
          This method subdivides the mesh using approximating (Loop) subdivision, and returns a new TriangleMesh which approximates the limit surface to within the specified tolerance.
 TriangleMesh subdivideToLimit(double tol)
          Create a new triangle mesh by subdividing this one until no edge is longer than the specified tolerance.
 void writeToFile(java.io.DataOutputStream out, Scene theScene)
          The following method writes the object's data to an output stream.
 
Methods inherited from class artofillusion.object.Object3D
canSetMaterial, canSetTexture, configurePoseTrack, copyTextureAndMaterial, editKeyframe, getAverageParameterValues, getMaterial, getMaterialMapping, getParameters, getParameterValue, getParameterValues, getTexture, getTextureMapping, readParameterValue, renderObject, sceneChanged, setParameters
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface artofillusion.object.Mesh
getParameters, getParameterValues
 

Constructor Detail

TriangleMesh

public TriangleMesh(Vec3[] v,
                    int[][] faces)
The constructor takes three arguments. v[] is an array containing the vertices. faces[][] is an N by 3 array containing the indices of the vertices which define each face. The vertices for each face must be listed in order, such that they go counter-clockwise when viewed from the outside of the mesh. All faces must have a consistent vertex order, such that the object has a well defined outer surface. This is true even if the mesh does not form a closed surface. It is an error to call the constructor with a faces[][] array which does not meet this condition, and the results are undefined. norm[] contains the normal vector at each vertex. If any element of norm[] is null, flat shading will be used around that vertex.


TriangleMesh

public TriangleMesh(TriangleMesh.Vertex[] v,
                    int[][] faces)

TriangleMesh

public TriangleMesh(java.io.DataInputStream in,
                    Scene theScene)
             throws java.io.IOException,
                    java.io.InvalidObjectException
The following two methods are used for reading and writing files. The first is a constructor which reads the necessary data from an input stream. The other writes the object's representation to an output stream.

Throws:
java.io.IOException
java.io.InvalidObjectException
Method Detail

duplicate

public Object3D duplicate()
Create a duplicate of this object.

Specified by:
duplicate in interface Mesh
Specified by:
duplicate in class Object3D

copyObject

public void copyObject(Object3D obj)
Make this object exactly like another one.

Specified by:
copyObject in interface Mesh
Specified by:
copyObject in class Object3D

getBounds

public BoundingBox getBounds()
Get the bounding box for the mesh. This is always the bounding box for the unsmoothed control mesh. If the smoothing method is set to approximating, the final surface may not actually touch the sides of this box. If the smoothing method is set to interpolating, the final surface may actually extend outside this box.

Specified by:
getBounds in interface Mesh
Specified by:
getBounds in class Object3D

getVertices

public MeshVertex[] getVertices()
These methods return the lists of vertices, edges, and faces for the mesh.

Specified by:
getVertices in interface Mesh

getVertex

public TriangleMesh.Vertex getVertex(int i)

getEdges

public TriangleMesh.Edge[] getEdges()

getFaces

public TriangleMesh.Face[] getFaces()

getSmoothingMethod

public int getSmoothingMethod()
Get the smoothing method being used for this mesh.


getVertexPositions

public Vec3[] getVertexPositions()
Get a list of the positions of all vertices which define the mesh.

Specified by:
getVertexPositions in interface Mesh

setVertexPositions

public void setVertexPositions(Vec3[] v)
Set the positions for all the vertices of the mesh.

Specified by:
setVertexPositions in interface Mesh

setSmoothingMethod

public void setSmoothingMethod(int method)
Set the smoothing method.


setShape

public void setShape(TriangleMesh.Vertex[] v,
                     int[][] faces)
This method rebuilds the mesh based on new lists of vertices and faces. The smoothness values for all edges are lost in the process.


isClosed

public boolean isClosed()
Description copied from class: Object3D
Tells whether the object is closed. For curves, this means it has no endpoints. For surface, it means the surface has no boundary.

Overrides:
isClosed in class Object3D

setSize

public void setSize(double xsize,
                    double ysize,
                    double zsize)
Description copied from class: Object3D
Resize the object. This should be interpreted such that, if setSize() is followed by a call to getBounds(), the dimensions of the BoundingBox will exactly match the dimensions specified in setSize().

Specified by:
setSize in class Object3D

findBoundaryEdges

public int[][] findBoundaryEdges()
Calculate a set of array representing the boundaries of this mesh. There is one array for each distinct boundary, containing the indices of the edges which form that boundary.


isEditable

public boolean isEditable()
Description copied from class: Object3D
If the object can be edited by the user, isEditable() should be overridden to return true. edit() should then create a window and allow the user to edit the object.

Overrides:
isEditable in class Object3D

edit

public void edit(EditingWindow parent,
                 ObjectInfo info,
                 java.lang.Runnable cb)
Description copied from class: Object3D
Display a window in which the user can edit this object.

Overrides:
edit in class Object3D
Parameters:
parent - the window from which this command is being invoked
info - the ObjectInfo corresponding to this object
cb - a callback which will be executed when editing is complete. If the user cancels the operation, it will not be called.

editGesture

public void editGesture(EditingWindow parent,
                        ObjectInfo info,
                        java.lang.Runnable cb,
                        ObjectInfo realObject)
Description copied from class: Object3D
Edit an object which represents a gesture for an Actor object. realObject specifies the object in the scene which this is a gesture for.

Overrides:
editGesture in class Object3D

createMeshViewer

public MeshViewer createMeshViewer(MeshEditController controller,
                                   RowContainer options)
Get a MeshViewer which can be used for viewing this mesh.

Specified by:
createMeshViewer in interface Mesh

canConvertToTriangleMesh

public int canConvertToTriangleMesh()
Description copied from class: Object3D
Tells whether the object can be converted to a TriangleMesh. It should return one of the following values: CANT_CONVERT: The object cannot be converted to a TriangleMesh. EXACTLY: The object can be represented exactly by a TriangleMesh. APPROXIMATELY: The object can be converted to a TriangleMesh. However, the resulting mesh will not be exactly the same shape as the original object. If a class overrides this method, it must also override convertToTriangleMesh().

Overrides:
canConvertToTriangleMesh in class Object3D

convertToTriangleMesh

public TriangleMesh convertToTriangleMesh(double tol)
Get a more finely subdivided version of this mesh.

Overrides:
convertToTriangleMesh in class Object3D

getWireframeMesh

public WireframeMesh getWireframeMesh()
Description copied from class: Object3D
Every object should override this method to return a WireframeMesh. This will be used for drawing the object in wireframe mode, and also for drawing "nonrenderable" objects in other rendering modes.

Specified by:
getWireframeMesh in class Object3D

getRenderingMesh

public RenderingMesh getRenderingMesh(double tol,
                                      boolean interactive,
                                      ObjectInfo info)
Description copied from class: Object3D
Objects which can be rendered as part of a scene should override this method to return a RenderingMesh which describes the appearance of the object. All points on the RenderingMesh should be within a distance tol of the true surface. The interactive flag tells whether the resulting Mesh will be rendered in interactive mode. When interactive is set to true, the RenderingMesh should be cached for future use, so that it may be rendered repeatedly without needing to be regenerated.

The ObjectInfo contains additional information which may affect how the object is rendered, such as it location in the scene, texture parameters, etc.

Objects which cannot be rendered directly (lights, cameras, curves, etc.) do not need to override this method.

Overrides:
getRenderingMesh in class Object3D

setTexture

public void setTexture(Texture tex,
                       TextureMapping mapping)
When setting the texture, we need to clear the caches.

Overrides:
setTexture in class Object3D

setMaterial

public void setMaterial(Material mat,
                        MaterialMapping map)
When setting the material, we need to clear the caches.

Overrides:
setMaterial in class Object3D

setParameterValues

public void setParameterValues(ParameterValue[] val)
When setting texture parameters, we need to clear the caches.

Overrides:
setParameterValues in class Object3D

setParameterValue

public void setParameterValue(TextureParameter param,
                              ParameterValue val)
When setting texture parameters, we need to clear the caches.

Overrides:
setParameterValue in class Object3D

getSkeleton

public Skeleton getSkeleton()
Get the skeleton for this object.

Specified by:
getSkeleton in interface Mesh
Overrides:
getSkeleton in class Object3D

setSkeleton

public void setSkeleton(Skeleton s)
Set the skeleton for this object.

Specified by:
setSkeleton in interface Mesh

subdivideEdges

public static TriangleMesh subdivideEdges(TriangleMesh mesh,
                                          boolean[] splitEdge,
                                          double tol)
Subdivide all or part of the mesh using the mesh's defined smoothing method (linear, approximating, or interpolating).

Parameters:
mesh - the mesh to subdivide
splitEdge - a flag for each edge, specifying which ones should be split. If this is null, every edge will be split.
tol - the error tolerance. Edges will be repeatedly subdivided until every point on the subdivided mesh is within this distance of the limit surface. If this is equal to Double.MAX_VALUE, each edge will be subdivided exactly once.
Returns:
the subdivided mesh

subdivideLinear

public static TriangleMesh subdivideLinear(TriangleMesh mesh,
                                           boolean[] split)
This method subdivides each selected edge once, placing a new vertex in the midpoint of the edge, and returns the subdivided mesh.

Parameters:
mesh - the mesh to subdivide
split - a flag for each edge, specifying which ones should be split. If this is null, every edge will be split.
Returns:
the subdivided mesh

subdivideLoop

public static TriangleMesh subdivideLoop(TriangleMesh mesh,
                                         boolean[] refineEdge,
                                         double tol)
This method subdivides the mesh using approximating (Loop) subdivision, and returns a new TriangleMesh which approximates the limit surface to within the specified tolerance. The subdivision coefficients are taken (with a few minor changes) from Hoppe et al. "Piecewise Smooth Surface Reconstruction." SIGGRAPH Proceedings, 1994, p. 295. The algorithm for creating semi-smooth points and creases is original.

Parameters:
mesh - the mesh to subdivide
refineEdge - a flag for each edge, specifying which ones should be split. If this is null, every edge will be split.
tol - the error tolerance. Edges will be repeatedly subdivided until every point on the subdivided mesh is within this distance of the limit surface. If this is equal to Double.MAX_VALUE, each edge will be subdivided exactly once.
Returns:
the subdivided mesh

subdivideButterfly

public static TriangleMesh subdivideButterfly(TriangleMesh mesh,
                                              boolean[] refineEdge,
                                              double tol)
This method subdivides the mesh using interpolating (modified Butterfly) subdivision, and returns a new TriangleMesh which approximates the limit surface to within the specified tolerance. The subdivision coefficients are taken from Zorin et al. "Interpolating Subdivision for Meshes with Arbitrary Topology." 1996. The algorithm for creating semi-smooth points and creases is original.

Parameters:
mesh - the mesh to subdivide
refineEdge - a flag for each edge, specifying which ones should be split. If this is null, every edge will be split.
tol - the error tolerance. Edges will be repeatedly subdivided until every point on the subdivided mesh is within this distance of the limit surface. If this is equal to Double.MAX_VALUE, each edge will be subdivided exactly once.
Returns:
the subdivided mesh

subdivideFaces

public static TriangleMesh subdivideFaces(TriangleMesh mesh,
                                          boolean[] split)
This method splits each selected face into three faces, and returns the subdivided mesh. split is a boolean array specifying which faces to split.


subdivideToLimit

public TriangleMesh subdivideToLimit(double tol)
Create a new triangle mesh by subdividing this one until no edge is longer than the specified tolerance.


getDisplacedMesh

public TriangleMesh getDisplacedMesh(double tol,
                                     double time)
Create a new triangle mesh by applying the displacement map of the texture assigned to this object.


makeRightSideOut

public void makeRightSideOut()
If necessary, reorder the points in each face so that the normals will be properly oriented.


reverseNormals

public void reverseNormals()
Reorder the vertices in each face, so as to reverse all of the normal vectors.


getNormals

public Vec3[] getNormals()
Get an array of normal vectors. This calculates a single normal for each vertex, ignoring smoothness values.

Specified by:
getNormals in interface Mesh

getFaceCount

public int getFaceCount()
Description copied from interface: FacetedMesh
Get the number of faces in this mesh.

Specified by:
getFaceCount in interface FacetedMesh

getFaceVertexCount

public int getFaceVertexCount(int faceIndex)
Description copied from interface: FacetedMesh
Get the number of vertices in a particular face.

Specified by:
getFaceVertexCount in interface FacetedMesh
Parameters:
faceIndex - the index of the face

getFaceVertexIndex

public int getFaceVertexIndex(int faceIndex,
                              int vertexIndex)
Description copied from interface: FacetedMesh
Get the index of a particular vertex in a particular face.

Specified by:
getFaceVertexIndex in interface FacetedMesh
Parameters:
faceIndex - the index of the face
vertexIndex - the index of the vertex within the face (between 0 and getFaceVertexCount(face)-1 inclusive)
Returns:
the index of the corresponding vertex in the list returned by getVertices()

optimizeMesh

public static TriangleMesh optimizeMesh(TriangleMesh mesh)
Return a new mesh which is an "optimized" version of the input mesh. This is done by rearranging edges to eliminate very small angles, or vertices where many edges come together. The resulting mesh will generally produce a better looking surface after smoothing is applied to it.


autosmoothMeshEdges

public void autosmoothMeshEdges(double angle)
Automatically select smoothness values for all edges in the mesh. This is done based on the angle between the two faces sharing the edge. If it is greater than the specified cutoff, the edge smoothness is set to 0. Otherwise, it is set to 1.

Parameters:
angle - the cutoff angle, in radians

writeToFile

public void writeToFile(java.io.DataOutputStream out,
                        Scene theScene)
                 throws java.io.IOException
Description copied from class: Object3D
The following method writes the object's data to an output stream. Subclasses should override this method, but also call super.writeToFile() to save information about materials, etc. In addition to this method, every Object3D must include a constructor with the signature public Classname(DataInputStream in, Scene theScene) throws IOException, InvalidObjectException which reconstructs the object by reading its data from an input stream. This constructor, similarly, should call the overridden constructor to read information about materials, etc.

Overrides:
writeToFile in class Object3D
Throws:
java.io.IOException

getProperties

public Property[] getProperties()
Description copied from class: Object3D
Get a list of editable properties defined by this object.

Overrides:
getProperties in class Object3D

getPropertyValue

public java.lang.Object getPropertyValue(int index)
Description copied from class: Object3D
Get the value of one of this object's editable properties.

Overrides:
getPropertyValue in class Object3D
Parameters:
index - the index of the property to get

setPropertyValue

public void setPropertyValue(int index,
                             java.lang.Object value)
Description copied from class: Object3D
Set the value of one of this object's editable properties.

Overrides:
setPropertyValue in class Object3D
Parameters:
index - the index of the property to set
value - the value to set for the property

getPoseKeyframe

public Keyframe getPoseKeyframe()
Return a Keyframe which describes the current pose of this object.

Specified by:
getPoseKeyframe in class Object3D

applyPoseKeyframe

public void applyPoseKeyframe(Keyframe k)
Modify this object based on a pose keyframe.

Specified by:
applyPoseKeyframe in class Object3D

canConvertToActor

public boolean canConvertToActor()
Allow TriangleMeshes to be converted to Actors.

Overrides:
canConvertToActor in class Object3D

getPosableObject

public Object3D getPosableObject()
TriangleMeshes cannot be keyframed directly, since any change to mesh topology would cause all keyframes to become invalid. Return an actor for this mesh.

Overrides:
getPosableObject in class Object3D


Copyright © 1999-2011 by Peter Eastman.