Package org.jmol.util
Class MeshCapper
- java.lang.Object
-
- org.jmol.util.MeshCapper
-
public class MeshCapper extends java.lang.ObjectA class to properly cap a convoluted, closed slice of an isosurface inspired by: Computational Geometry: Algorithms and Applications Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf Springer-Verlag, Berlin Heidelberg 1997 Chapter 3. Polygon Triangulation Thanks given to Olaf Hall-Holt for pointing me to this reference. Extensively modified: - quaternion transform from 3D plane to XY plane for best precision - using directional edges -- no angle measurements necessary - continuous splitting off of triangles - independent dynamic monotonic regions created and processed as one stream - no need for vertex typing - no push/pop stacks INPUT: stream of [a b] ordered-vertex edges such that triangle a-b-c is interior if (ab.cross.ac).dot.planeNormal > 0 (right-hand rule; counter-clockwise edge flow) Bob Hanson - Jan 11, 2015- Author:
- Bob Hanson, hansonr@stolaf.edu
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private classMeshCapper.CapVertexA class to provide linked vertices for MeshCapper
-
Field Summary
Fields Modifier and Type Field Description private static intASCENDERprivate java.util.Map<java.lang.Integer,MeshCapper.CapVertex>capMapinitialization onlyprivate static intDESCENDERprivate booleandumpingfor debuggingprivate static intLASTprivate javajs.util.Lst<MeshCapper.CapVertex[]>lstRegionsdynamic region processing.private javajs.util.Lst<int[]>lstTrianglesprivate intnPointsprivate intnRegionsinformational onlyprivate intnTrianglesinformational onlyprivate MeshSlicerslicersource of edges; consumer of trianglesprivate javajs.util.Lst<MeshCapper.CapVertex>vertices
-
Constructor Summary
Constructors Constructor Description MeshCapper()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description (package private) voidaddEdge(int ipt1, int ipt2, int thisSet)Input method from MeshSlicer.private MeshCapper.CapVertexaddPoint(int thisSet, int i)The MeshSlicer class manages all introduction of vertices; we must pass on to it the subset of vertices from the original Jmol isosurface being capped.private voidaddTriangle(MeshCapper.CapVertex v0, MeshCapper.CapVertex v1, MeshCapper.CapVertex v2, java.lang.String note)Add the triangle and remove v1 from the chain.private booleancheckWinding(MeshCapper.CapVertex v0, MeshCapper.CapVertex v1, MeshCapper.CapVertex v2)Check for CCW winding.(package private) voidclear()private static voidclearV(MeshCapper.CapVertex v)(package private) voidcreateCap(javajs.util.V3 norm)Entry point when finished generating edges.private voiddrawTriangle(int index, MeshCapper.CapVertex v0, MeshCapper.CapVertex v1, MeshCapper.CapVertex v2, java.lang.String color)for debuggingprivate javajs.util.T3getInputPoint(MeshCapper.CapVertex v)for debuggingprivate MeshCapper.CapVertexgetLastPoint(MeshCapper.CapVertex v)Find the lowest ascender or descender above scan line bounding the region for this point.private booleanisEdge(int i, int j)private voidnewRegion(MeshCapper.CapVertex v)Add a new region to the list of regions.private voidoutputTriangle(int ipt1, int ipt2, int ipt3)Export triangle to MeshSlicerprivate MeshCapper.CapVertexprocess(MeshCapper.CapVertex v)Handle the point; mark as processed.private voidprocessMonotonic(MeshCapper.CapVertex v, boolean isDescending)Process a standard monotonic region, cleaving off as many triangles as possible.private MeshCapper.CapVertexprocessSplit(MeshCapper.CapVertex v, MeshCapper.CapVertex last)Process what M3O refer to as a "split" vertex, which we handle differently here, cloning the "helper" point and the "split" point, creating a new region if necessary, and then swapping pointers.MeshCapperset(MeshSlicer slicer)private MeshCapper.CapVertex[]test(MeshCapper.CapVertex[] vs)int[][]triangulateFaces(int[][] faces, javajs.util.P3[] vertices, int[][] faceTriangles)generic entry for a set of facesint[][]triangulatePolygon(javajs.util.P3[] points, int nPoints)generic entry for a polygon
-
-
-
Field Detail
-
slicer
private MeshSlicer slicer
source of edges; consumer of triangles
-
dumping
private boolean dumping
for debugging
-
capMap
private java.util.Map<java.lang.Integer,MeshCapper.CapVertex> capMap
initialization only
-
vertices
private javajs.util.Lst<MeshCapper.CapVertex> vertices
-
lstRegions
private javajs.util.Lst<MeshCapper.CapVertex[]> lstRegions
dynamic region processing. These are just [DESCENDER, ASCENDER, LAST] for each region
-
DESCENDER
private static final int DESCENDER
- See Also:
- Constant Field Values
-
ASCENDER
private static final int ASCENDER
- See Also:
- Constant Field Values
-
LAST
private static final int LAST
- See Also:
- Constant Field Values
-
nTriangles
private int nTriangles
informational only
-
nRegions
private int nRegions
informational only
-
lstTriangles
private javajs.util.Lst<int[]> lstTriangles
-
nPoints
private int nPoints
-
-
Method Detail
-
set
public MeshCapper set(MeshSlicer slicer)
- Parameters:
slicer-- Returns:
- this
-
clear
void clear()
-
triangulateFaces
public int[][] triangulateFaces(int[][] faces, javajs.util.P3[] vertices, int[][] faceTriangles)generic entry for a set of faces- Parameters:
faces- array of pointers into pointsvertices-faceTriangles-- Returns:
- array of triangles [a b c mask]
-
triangulatePolygon
public int[][] triangulatePolygon(javajs.util.P3[] points, int nPoints)generic entry for a polygon- Parameters:
points-nPoints- number of points or -1- Returns:
- int[][i j k mask]
-
addEdge
void addEdge(int ipt1, int ipt2, int thisSet)Input method from MeshSlicer. Pointers are into MeshSlicer.m.vs[]- Parameters:
ipt1-ipt2-thisSet-
-
addPoint
private MeshCapper.CapVertex addPoint(int thisSet, int i)
The MeshSlicer class manages all introduction of vertices; we must pass on to it the subset of vertices from the original Jmol isosurface being capped.- Parameters:
thisSet-i-- Returns:
- a CapVertex pointing to this new point in the isosurface or one we already have
-
getInputPoint
private javajs.util.T3 getInputPoint(MeshCapper.CapVertex v)
for debugging- Parameters:
v-- Returns:
- external point or test point
-
outputTriangle
private void outputTriangle(int ipt1, int ipt2, int ipt3)Export triangle to MeshSlicer- Parameters:
ipt1-ipt2-ipt3-
-
isEdge
private boolean isEdge(int i, int j)
-
test
private MeshCapper.CapVertex[] test(MeshCapper.CapVertex[] vs)
-
createCap
void createCap(javajs.util.V3 norm)
Entry point when finished generating edges.- Parameters:
norm-
-
process
private MeshCapper.CapVertex process(MeshCapper.CapVertex v)
Handle the point; mark as processed.- Parameters:
v-- Returns:
- next point to process
-
clearV
private static void clearV(MeshCapper.CapVertex v)
-
processMonotonic
private void processMonotonic(MeshCapper.CapVertex v, boolean isDescending)
Process a standard monotonic region, cleaving off as many triangles as possible.- Parameters:
v-isDescending-
-
processSplit
private MeshCapper.CapVertex processSplit(MeshCapper.CapVertex v, MeshCapper.CapVertex last)
Process what M3O refer to as a "split" vertex, which we handle differently here, cloning the "helper" point and the "split" point, creating a new region if necessary, and then swapping pointers.- Parameters:
v-last- "helper" or left edge- Returns:
- new point clone of this
-
newRegion
private void newRegion(MeshCapper.CapVertex v)
Add a new region to the list of regions.- Parameters:
v-
-
getLastPoint
private MeshCapper.CapVertex getLastPoint(MeshCapper.CapVertex v)
Find the lowest ascender or descender above scan line bounding the region for this point. In the case of a region that consists of a single edge with descender above ascender, this will return the ascender. In the case where there are two independent regions, it is possible for the lowest to be missed, but to no import. [This is MOST confusing in the M3O book.]- Parameters:
v-- Returns:
- pt
-
checkWinding
private boolean checkWinding(MeshCapper.CapVertex v0, MeshCapper.CapVertex v1, MeshCapper.CapVertex v2)
Check for CCW winding.- Parameters:
v0-v1-v2-- Returns:
- true if properly wound -- (v1-v0).cross.(v2-v0).dot.norm > 0
-
addTriangle
private void addTriangle(MeshCapper.CapVertex v0, MeshCapper.CapVertex v1, MeshCapper.CapVertex v2, java.lang.String note)
Add the triangle and remove v1 from the chain.- Parameters:
v0-v1-v2-note-
-
drawTriangle
private void drawTriangle(int index, MeshCapper.CapVertex v0, MeshCapper.CapVertex v1, MeshCapper.CapVertex v2, java.lang.String color)for debugging- Parameters:
index-v0-v1-v2-color-
-
-