|
IsoSurface Rendering of an AR Representation | |||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--rlaramee.OctreeNode
Description: The Octree is made up of Octree Nodes. In the tree representation, the lower level nodes store data at a higher resolution. Each node is an octant of a parent node.
Internal nodes also have 2 values: the minimum and maximum values of all its decendants [children].
Leaf nodes have 8 data values and a minimum and maximum of those data values. It is the leaf nodes that are rendered.
Each octant is labeled using the convention from page 87 of
Applications of Spacial Data Structures by H. Samet.
Note: it is only the labeling convention taken from H. Samet, not the
numbering. (H. Samet uses a different numbering convention.)
The octants are numbered using the convention from page 233 of
The Visualization Toolkit (first edition) Figure 8-11
This is the same as the cube-vertex numbering and labeling.
start date Fri 30 April 1999
Field Summary | |
private byte |
childNumber
an int uses 4 bytes, 3 too many |
private Cube |
cube
octree node has a cube as a member |
private boolean |
debug
|
private OctreeNode |
parentNode
a pointer is 4 bytes |
private boolean |
processed
has this octree node been processed by the MC algorithm ? |
private OctreeNode |
siblingNode
node to the "right" |
private java.util.Vector |
triangleList
replace this with an array or an ArrayList for more efficiency Note: a cube in the Marching Cubes algorithm can contain no more than 5 triangles. |
Constructor Summary | |
OctreeNode(Cube newCube)
|
Method Summary | |
void |
accumulateUniqueDirections(byte edge,
byte[] uniqueDirections)
This method is called from IsoSurface.computeTriangle() It responsible for aggregating the unique directions to search for octree node neighbors given the edge. |
abstract boolean |
addEdgeVertex(SharedEdgeVertex newSharedVertex)
|
abstract boolean |
addFacialVertex(SharedFacialVertex sv)
|
void |
addNodeFromTop(OctreeNode newNode)
addNodeFromTop() adds a node onto the Octree starting with the root. |
void |
addTriangle(Triangle triangle)
addTriangle() adds a triangle onto the octree node's list |
abstract void |
addTriangleEdge(TriangleEdge triangleEdge)
|
private boolean |
alreadyThere(java.util.Vector vertexList,
TriangleVertex triangleVertex)
|
abstract void |
assembleChainGang()
|
byte |
classifyNode(OctreeNode newNode)
This function identifies which of this node's octants the node being passed belongs to/in. |
private OctreeNode |
createChild(byte childLevel,
byte childOctant)
This is called from OctreeNode.getChild(int, int) Creates a new placeholder child node. |
OctreeNode |
createParent(Octree octree)
This is called from Octree.addNodeFromBottom() Creates a new placeholder parent node. |
void |
deletePreviousSurface()
The method is called from MarchingCubes.execute() It used when using the same octree to render multiple isosurfaces since octree nodes may have triangles left over from prior isosurface computations. |
abstract byte |
deleteTriangles(IsoSurface surface)
|
boolean |
encompassesSurface(float isoValue)
encompassesSurface() is called from MachingCubes.execute() |
boolean |
errorCheck()
The purpose of this function is look for errors in the octree nodes (coordinate and data values) and their corresponding triangles. |
abstract byte |
faceWithMaxChains()
|
private OctreeNode |
findAncestor(byte direction)
|
void |
freeMemory()
This method attempts to free up all the resources a node takes up in order to help out the gargbage collector. |
abstract byte |
generateTriangleFans(IsoSurface surface)
|
abstract OctreeARnode |
getARnode()
|
OctreeNode |
getChild(byte childn)
This version of getChild() is called from OctreeNode.getNext(), OctreeNode.getFaceNeighbor(), Draw3d.renderNode() |
private OctreeNode |
getChild(byte level,
byte childn,
Octree octree)
This method (always) returns a child node. |
byte |
getChildNumber()
|
abstract OctreeNode |
getChildZero()
|
Cube |
getCube()
|
abstract java.util.Vector |
getEdgeVertexList()
|
java.util.Vector |
getEdgeVerticesOfCoarserNeighbor(byte fineEdge,
byte fineOctant,
byte fineToCoarseDir,
OctreeNode coarseNode)
Deprecated. Is this method still being used? |
OctreeNode |
getFaceNeighbor(byte direction)
Locate the face-neighbor of node N , of size greater than or equal to N , in direction D . |
abstract java.util.Vector |
getFacialVertexList()
|
byte |
getLevel()
|
abstract float |
getMaximum()
|
abstract float |
getMinimum()
|
OctreeNode |
getNext(boolean skipBranch)
The getNext() algorithm for an AR octree: |
int |
getNumTriangles()
This method is called from MarchingCubes.processSubDivide() |
OctreeNode |
getParent()
|
short |
getResolution()
|
OctreeNode |
getSibling()
|
OctreeNode |
getSibling(int number)
Deprecated. -use getSibling() instead |
Triangle |
getTriangle(byte n)
Don't forget, getTriangle() may be called for a qualified node that has not actually generated its triangles yet because it has not been traversed. |
java.util.Vector |
getTriangleList()
|
private boolean |
isAdjacent(byte f,
byte o)
P3_____________P2 This is the cube representation /| /| used to write the isAdjacent() / | / | and reflect() methods. |
boolean |
isEqual(OctreeNode otherNode)
Checks to see if 2 OctreeNodes are the same. |
protected boolean |
isLeafNode()
This method identifies a leaf node - a node with no children |
OctreeNode[] |
mapAdjacentChildrenFineToCoarseDir(byte fromFineToCoarseDir)
This method is called from IsoSurfaceAdaptive.processSubdivide() . |
byte[] |
mapDirectionsFromEdge(byte edge)
This is called from OctreeNode.accumulateDirectionsFromEdge() . |
byte[] |
mapDirectionsFromOctant(byte octant,
byte deltaResolution)
Deprecated. -use OctreeNode.mapDirectionsFromEdge() instead |
private byte |
mapOctant(byte octant)
|
abstract byte |
maxChainsPerFace()
|
abstract SharedEdgeVertex |
onCoarseEdge(TriangleVertex fv,
byte octant,
byte direction)
|
abstract SharedFacialVertex |
onCoarseFace(TriangleVertex fv,
byte octant,
byte direction)
|
private void |
p(int n)
called from OctreeNode.reflect() |
private void |
p(java.lang.String bool)
|
abstract void |
print()
Print out a node's private data members. |
private byte |
reflect(byte f,
byte o)
This returns the octant (child number) number of the cube of equal size (not necessarily a brother) that shares the face, f, of a cube in octant o. |
void |
removeNodes()
|
private boolean |
removeTriangles()
This method is called from OctreeNode.subDivide() |
private boolean |
set3pointers(byte octant,
OctreeNode newChildNode,
Octree octree)
This method takes an octree node and sets the parent, childZero and sibling pointers. |
boolean |
set8children(Cube[] childCubes)
|
boolean |
setChild(byte octant,
OctreeNode newChildNode,
Octree octree)
The new child node may take the place of a placeholder node. |
boolean |
setChildNumber(byte n)
|
abstract boolean |
setChildZero(OctreeNode node)
|
void |
setCube(Cube newCube)
|
abstract boolean |
setEdgeVertexList(java.util.Vector newList)
|
abstract boolean |
setFacialVertexList(java.util.Vector newList)
|
void |
setLevel(byte l)
|
abstract boolean |
setMaximum(float max)
|
abstract boolean |
setMinimum(float min)
|
private void |
setParent(OctreeNode parent)
|
void |
setResolution(short res)
|
private boolean |
setSibling(OctreeNode newOctreeNode)
|
void |
setTriangleList(java.util.Vector v)
|
private boolean |
sharedFineEdge(byte coarseEdge,
byte fineEdge,
byte fineOctant,
byte fineDirection)
Deprecated. this method has to be re-evaluated and probably rewritten to handle more than one level of resolution difference. |
Cube[] |
subDivide(OctreeNode[] fourChildren,
byte fromFineToCoarseDir)
The way we are going to collaborate on this is to let the OctreeNode be responsible for identifying which 9 out of the 19 (0-18) possible vertices are shared between the adjacent nodes (because it is the OctreeNode not the cube that can find neighbors). |
private OctreeNode |
traverseChildren()
|
private OctreeNode |
traverseSiblings()
|
abstract boolean |
updateEdgeVertices()
|
boolean |
updateTriangle(byte triangleNumber,
byte vertexNumber,
TriangleVertex newVertex)
|
Methods inherited from class java.lang.Object |
|
Field Detail |
private OctreeNode parentNode
private OctreeNode siblingNode
private Cube cube
private java.util.Vector triangleList
private byte childNumber
private boolean processed
private boolean debug
Constructor Detail |
public OctreeNode(Cube newCube)
Method Detail |
public abstract float getMinimum()
OctreeLeafNode and OctreeInternalNode
classes for the implementation of these methods
public abstract float getMaximum()
public abstract boolean setMinimum(float min)
public abstract boolean setMaximum(float max)
public abstract OctreeNode getChildZero()
public abstract boolean setChildZero(OctreeNode node)
public abstract java.util.Vector getEdgeVertexList()
public abstract boolean setEdgeVertexList(java.util.Vector newList)
public abstract boolean addEdgeVertex(SharedEdgeVertex newSharedVertex)
public abstract java.util.Vector getFacialVertexList()
public abstract boolean setFacialVertexList(java.util.Vector newList)
public abstract boolean addFacialVertex(SharedFacialVertex sv)
public abstract boolean updateEdgeVertices()
public abstract SharedEdgeVertex onCoarseEdge(TriangleVertex fv, byte octant, byte direction)
public abstract SharedFacialVertex onCoarseFace(TriangleVertex fv, byte octant, byte direction)
public abstract void addTriangleEdge(TriangleEdge triangleEdge)
public abstract OctreeARnode getARnode()
public abstract byte deleteTriangles(IsoSurface surface)
public abstract void assembleChainGang()
public abstract byte maxChainsPerFace()
public abstract byte faceWithMaxChains()
public abstract byte generateTriangleFans(IsoSurface surface)
public Cube getCube()
public void setCube(Cube newCube)
newCube
- set this octree node's cube to this newCubepublic short getResolution()
public void setResolution(short res)
the
- resolution of this octree nodepublic java.util.Vector getTriangleList()
public Triangle getTriangle(byte n)
n
- the triangle number to returnpublic void deletePreviousSurface()
public void setTriangleList(java.util.Vector v)
v
- a new vector to hold a list of trianglesprivate boolean removeTriangles()
When a node is subdivided, it's coarser resolution triangles must be removed. The MC algorithm generates a maximum of 5 triangles per cube
public int getNumTriangles()
public byte getLevel()
public void setLevel(byte l)
newLevel
- the level in the octree this node is inpublic byte getChildNumber()
public boolean setChildNumber(byte n)
child
- number a number from 0-7 indicating which
parent node's octant this node is inpublic OctreeNode getParent()
private void setParent(OctreeNode parent)
OctreeNode
- this octree node's parent nodepublic OctreeNode getSibling()
private boolean setSibling(OctreeNode newOctreeNode)
OctreeNode
- this octree node's sibling octree nodepublic java.util.Vector getEdgeVerticesOfCoarserNeighbor(byte fineEdge, byte fineOctant, byte fineToCoarseDir, OctreeNode coarseNode)
fineEdge
- the finer resolution neighboring octree node edgefineOctant
- the octant that the calling finer resolution
octree node neigbor is infineDirection
- the direction in which to look for shared edgecoarseNode
- the coarser resolution neighboring octree nodeprivate boolean alreadyThere(java.util.Vector vertexList, TriangleVertex triangleVertex)
vertexList
- a vector of TriangleVertex objectstriangleVertex
- 1 TriangleVertex objectprivate boolean sharedFineEdge(byte coarseEdge, byte fineEdge, byte fineOctant, byte fineDirection)
Note that it is a finer resolution cube that updates the vertices of coarser resolution neighbors. Distinguishing shared edge intersections is going to depend on the calling octree node's octant and direction.
P3_____e2______P2 This is the cube representation /| /| used write the method. e10| e11| It is the same as the VTK's except y P7______e6____P6/ | for the orientation of the ^ | e3 | e1 y,z axes. | | | | | | e7 | e5 | |---> | P0|_____e0__|___|P1 / x | / | / / | e8 | e9 z |/_____e4_____|/ P4 P5
It is also important to note that this method does not check for facial intersections. We'll give that responsibility to another method in order to make things a little simpler.
coarseEdge
- this octree node edgefineEdge
- the finer resolution octree node's edge
intersectionfineOctant
- the octant that the calling finer resolution
octree node neigbor is infineDirection
- the direction in which to look for shared edgepublic Cube[] subDivide(OctreeNode[] fourChildren, byte fromFineToCoarseDir)
Then, the OctreeNode will pass these 9 values along to the cube in order to finish the actual subDivision algorithm.
Also, we have to remember to delete this nodes triangles if it has to be subdivided because we don't want to render this node's coarser triangles.
fineAdjacentChildren
- the 4 the finer resolution neighboring
children to this node -which is being subdivided.
It is a finer resolution neighbor that made
the request for this node/cube to subdividefromFineToCoarseDir
- the direction from the finer resolution
neighbor to this coarse node public byte[] mapDirectionsFromOctant(byte octant, byte deltaResolution)
For a given octant, an octreeNode only has face neighbors of coarser resolutions in 3 possible directions. For a given octant, an octreeNode may have face neighbors of finer resolutoins in all 6 directions.
One might infer that since both of these neighbors share a common edge, we only have to update a vertex on this common edge for one of the neighbors. However, this reasoning won't work unless both of the neighbors are there and both have triangles.
octant
- the octant an octreeNode belongs indirections
- the directions to inspect neighbors inpublic void accumulateUniqueDirections(byte edge, byte[] uniqueDirections)
edge
- the edge that a triangle vertex lies ondirections
- the directions that abut this edge.public byte[] mapDirectionsFromEdge(byte edge)
For a given edge, an octreeNode only has face neighbors of different resolutions in 2 possible directions. One might infer that since both of these neighbors share a common edge, we only have to update a vertex on this common edge for one of the neighbors. However, this reasoning won't work unless both of the neighbors are there and both have triangles.
octant
- the octant an octreeNode belongs indirections
- the directions to inspect neighbors inpublic OctreeNode[] mapAdjacentChildrenFineToCoarseDir(byte fromFineToCoarseDir)
fromFineToCoarseDirection
- the direction the fine neighbor is
requesting the subdivision fromnode
- the octree node calling this methodpublic void freeMemory()
Use this method with caution.
public void removeNodes()
public OctreeNode getFaceNeighbor(byte direction)
IF such a node does not exist THEN return nullTo understand this method, you have to understand the \ isAdjacent() and reflect() methods. A node calls isAdjacent() until a common ancestor is found, and then calls reflect() down the list of adjacent nodes.
direction
- the direction we're seeking the face-neighbor inprivate OctreeNode findAncestor(byte direction)
direction
- the direction we are seeking our face neighbor
in e.g. LEFT, RIGHT, DOWN, UP, BACK, FRONTprotected boolean isLeafNode()
private boolean isAdjacent(byte f, byte o)
P3_____________P2 This is the cube representation /| /| used to write the isAdjacent() / | / | and reflect() methods. It is y P7____________P6/ | the same as the VTK's except ^ | | | | for the orientation of the | | | | | y,z axes. | | | | | |---> | P0|_________|___|P1 / x | / | / / | / | / z |_____________|/ P4 P5
This method returns TRUE if and only if octant, o, is adjacent to face, f, of o's containing block. For example the right face of a cube is adjacent to it's parent's containing cube if it is in octant 1,2,5, or 6. See pages 86-88 of Application's of Spatial Data Structures by H. Samet. Note orientation of axes on page 86.
a
- face defined in Constant.javaan
- octant numberprivate void p(java.lang.String bool)
string
- a boolean string indicating TRUE or FALSEprivate byte reflect(byte f, byte o)
See pages 86-88 of Applications of Spacial Data by H. Samet. Note orientation of axes on page 86.
a
- face defined in Constant.javaan
- octant numberprivate void p(int n)
n
- a number from 0 to 7public void addNodeFromTop(OctreeNode newNode)
Classify the new node as to which octant it belongs in.
IF we're at the correct resolution (the next finer resolution) THEN set the child and parent pointers (we're done) ELSE Follow child pointer to that octant. Recurse down the tree until we reach the new node's level.
newNode
- a new octree nodepublic byte classifyNode(OctreeNode newNode)
newNode
- an octree nodeprivate byte mapOctant(byte octant)
octant
- an octant ID passed from classifyNode()public boolean encompassesSurface(float isoValue)
We are going to skip the children of nodes when the isovalue is not within the nodes' minimum and maximum. This not as restrictive as processCube() because it has nothing to do with whether a node is leaf node or an internal node.
octreeNode
- the OctreeNode we are deciding onisoValue
- the isosurface value to renderpublic boolean set8children(Cube[] childCubes)
childCubes
- an array of 8 child cubespublic boolean setChild(byte octant, OctreeNode newChildNode, Octree octree)
octant
- the octant it's being added toonewChildNode
- a new child node
optional parameters:
octree
- a reference to the octree so we may add
a pointer to the new node (but only if
it really is a new node and not updating a placeholder node)
This parameter is used *only* from Octree.addNodeFromBottom()private boolean set3pointers(byte octant, OctreeNode newChildNode, Octree octree)
octant
- the octant it's being added toonewChildNode
- a new child nodeoctree
- a reference to the octree so we may add
a pointer to the new node (but only if
it really is a new node and not updating a placeholder node)
This parameter is used *only* from Octree.addNodeFromBottom()private OctreeNode getChild(byte level, byte childn, Octree octree)
level
- level of nodeoctant
- an octant ID passed from classifyNode()octree
- a reference to the octree, needed only by
setChild(int, OctreeNode, Octree)public OctreeNode getChild(byte childn)
childn
- a number from 0-7 indicating which child node
to returnprivate OctreeNode createChild(byte childLevel, byte childOctant)
level
- level of nodeoctant
- an octant ID passed from getChild() public OctreeNode createParent(Octree octree)
octree
- -an optional parameter, a pointer to the octreepublic OctreeNode getNext(boolean skipBranch)
IF the direction is FROMABOVE OR FROM LEFT THEN get next available child IF no children THEN return next sibling IF no children OR siblings THEN return parent node ELSE IF the direction is FROMBELOW THEN traverse siblings IF no siblings are found THEN return the parent node
skipBranch
- is TRUE if we are to skip this octree
node's childrenpublic OctreeNode getSibling(int number)
number
- a number from 0-7 indicating which sibling to returnprivate OctreeNode traverseChildren()
private OctreeNode traverseSiblings()
public boolean isEqual(OctreeNode otherNode)
otherNode
- the other node that may be equal to this onepublic void addTriangle(Triangle triangle)
Remember, the initilization of the triangleList has been postponed until we actually have some triangles, in order to save memory
cube
- a new cubepublic boolean updateTriangle(byte triangleNumber, byte vertexNumber, TriangleVertex newVertex)
triangleNumber
- which triangle from this node's triangleList
to updatevertexNumber
- which vertex from the given triangle to updatetriangleVertex
- the new TriangleVertex to insertpublic boolean errorCheck()
It's called from Octree.errorCheck()
public abstract void print()
|
IsoSurface Rendering of an AR Representation | |||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |