/*
* Copyright (c) 2010, Frederik Vanhoutte This library is free software; you can
* redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version
* 2.1 of the License, or (at your option) any later version.
* http://creativecommons.org/licenses/LGPL/2.1/ This library is distributed in
* the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU Lesser General Public License for more details. You should have
* received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
* Fifth Floor, Boston, MA 02110-1301 USA
*/
package wblut.hemesh;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javolution.util.FastList;
import javolution.util.FastMap;
import wblut.geom.WB_AABB3D;
import wblut.geom.WB_Point3d;
// TODO: Auto-generated Javadoc
/**
* Collection of mesh elements. Contains methods for adding, deleting and
* accessing elements
*
* @author Frederik Vanhoutte (W:Blut)
*
*/
public abstract class HE_MeshStructure {
/** Linked HashMap of vertices. */
protected FastMap<Integer, HE_Vertex> _hashedVertices;
/** Iterator over vertices. */
protected Iterator<HE_Vertex> _vertexItr;
/** Linked HashMap of halfedges. */
protected FastMap<Integer, HE_Halfedge> _hashedHalfedges;
/** Iterator over halfedges. */
protected Iterator<HE_Halfedge> _halfedgeItr;
/** Linked HashMap of edges. */
protected FastMap<Integer, HE_Edge> _hashedEdges;
/** Iterator over edges. */
protected Iterator<HE_Edge> _edgeItr;
/** Static structure key counter. */
protected static int _currentKey;
/** Unique structure key. */
protected final Integer _key;
/**
* Instantiates a new HE_Structure.
*/
protected HE_MeshStructure() {
_key = new Integer(_currentKey);
_currentKey++;
_hashedVertices = new FastMap<Integer, HE_Vertex>();
_hashedHalfedges = new FastMap<Integer, HE_Halfedge>();
_hashedEdges = new FastMap<Integer, HE_Edge>();
_hashedFaces = new FastMap<Integer, HE_Face>();
}
/**
* Get key.
*
* @return key
*/
public Integer key() {
return _key;
}
/**
* Clear entire structure.
*/
public void clear() {
_hashedVertices.clear();
_hashedHalfedges.clear();
_hashedEdges.clear();
_hashedFaces.clear();
}
/**
* Clear vertices.
*/
public final void clearVertices() {
_hashedVertices.clear();
}
/**
* Clear halfedges.
*/
public final void clearHalfedges() {
_hashedHalfedges.clear();
}
/**
* Clear edges.
*/
public final void clearEdges() {
_hashedEdges.clear();
}
/**
* Vertices as array.
*
* @return all vertices as HE_Vertex[]
*/
public final HE_Vertex[] getVerticesAsArray() {
final HE_Vertex[] vertices = new HE_Vertex[numberOfVertices()];
final Collection<HE_Vertex> _vertices = _hashedVertices.values();
final Iterator<HE_Vertex> vitr = _vertices.iterator();
int i = 0;
while (vitr.hasNext()) {
vertices[i] = vitr.next();
i++;
}
return vertices;
}
/**
* Halfedges as array.
*
* @return all halfedges as HE_Halfedge[]
*/
public final HE_Halfedge[] getHalfedgesAsArray() {
final HE_Halfedge[] halfedges = new HE_Halfedge[numberOfHalfedges()];
final Iterator<HE_Halfedge> heItr = _hashedHalfedges.values()
.iterator();
int i = 0;
while (heItr.hasNext()) {
halfedges[i] = heItr.next();
i++;
}
return halfedges;
}
/**
* Edges as array.
*
* @return all edges as HE_Edge[]
*/
public final HE_Edge[] getEdgesAsArray() {
final HE_Edge[] edges = new HE_Edge[numberOfEdges()];
final Iterator<HE_Edge> eItr = _hashedEdges.values().iterator();
int i = 0;
while (eItr.hasNext()) {
edges[i] = eItr.next();
i++;
}
return edges;
}
/**
* Vertices as arrayList.
*
* @return all vertices as FastList<HE_Vertex>
*/
public final List<HE_Vertex> getVerticesAsList() {
final List<HE_Vertex> vertices = new FastList<HE_Vertex>();
final Collection<HE_Vertex> _vertices = _hashedVertices.values();
vertices.addAll(_vertices);
return (vertices);
}
/**
* Halfedges as arrayList.
*
* @return all vertices as FastList<HE_Halfedge>
*/
public final List<HE_Halfedge> getHalfedgesAsList() {
final List<HE_Halfedge> halfedges = new FastList<HE_Halfedge>();
halfedges.addAll(_hashedHalfedges.values());
return (halfedges);
}
/**
* Edges as arrayList.
*
* @return all vertices as FastList<HE_Edge>
*/
public final List<HE_Edge> getEdgesAsList() {
final List<HE_Edge> edges = new FastList<HE_Edge>();
edges.addAll(_hashedEdges.values());
return (edges);
}
/**
* Get vertex.
*
* @param key
* vertex key
* @return vertex
*/
public final HE_Vertex getVertexByKey(final Integer key) {
return _hashedVertices.get(key);
}
/**
* Get halfedge.
*
* @param key
* halfedge key
* @return halfedge
*/
public final HE_Halfedge getHalfedgeByKey(final Integer key) {
return _hashedHalfedges.get(key);
}
/**
* Get edge.
*
* @param key
* edge key
* @return edge
*/
public final HE_Edge getEdgeByKey(final Integer key) {
return _hashedEdges.get(key);
}
/**
* Check if structure contains edge.
*
* @param e
* edge
* @return true, if successful
*/
public final boolean contains(final HE_Edge e) {
if (e == null)
return false;
return _hashedEdges.containsKey(e._key);
}
/**
* Check if structure contains halfedge.
*
* @param he
* halfedge
* @return true, if successful
*/
public final boolean contains(final HE_Halfedge he) {
if (he == null)
return false;
return _hashedHalfedges.containsKey(he._key);
}
/**
* Check if structure contains vertex.
*
* @param v
* vertex
* @return true, if successful
*/
public final boolean contains(final HE_Vertex v) {
if (v == null)
return false;
return _hashedVertices.containsKey(v.key());
}
/**
* Number of edges.
*
* @return the number of edges
*/
public final int numberOfEdges() {
return _hashedEdges.size();
}
/**
* Number of halfedges.
*
* @return the number of halfedges
*/
public final int numberOfHalfedges() {
return _hashedHalfedges.size();
}
/**
* Number of vertices.
*
* @return the number of vertices
*/
public final int numberOfVertices() {
return _hashedVertices.size();
}
/**
* Add the edge.
*
* @param e
* edge to add
*/
public final void add(final HE_Edge e) {
_hashedEdges.put(e.key(), e);
}
/**
* Adds the halfedge.
*
* @param he
* halfedge to add
*/
public final void add(final HE_Halfedge he) {
_hashedHalfedges.put(he.key(), he);
}
/**
* Add the vertex.
*
* @param v
* vertex to add
*/
public final void add(final HE_Vertex v) {
_hashedVertices.put(v.key(), v);
}
/**
* Adds vertices.
*
* @param vertices
* vertices to add as HE_Vertex[]
*/
public final void addVertices(final HE_Vertex[] vertices) {
for (final HE_Vertex vertex : vertices) {
add(vertex);
}
}
/**
* Adds edges.
*
* @param edges
* edges to add as HE_Edge[]
*/
public final void addEdges(final HE_Edge[] edges) {
for (final HE_Edge edge : edges) {
add(edge);
}
}
/**
* Adds halfedges.
*
* @param halfedges
* halfedges to add as HE_Halfedge[]
*/
public final void addHalfedges(final HE_Halfedge[] halfedges) {
for (final HE_Halfedge halfedge : halfedges) {
add(halfedge);
}
}
/**
* Adds vertices.
*
* @param vertices
* vertices to add as FastList<HE_Vertex>
*/
public final void addVertices(final List<HE_Vertex> vertices) {
for (int i = 0; i < vertices.size(); i++) {
add(vertices.get(i));
}
}
/**
* Adds edges.
*
* @param edges
* edges to add as FastList<HE_Edge>
*/
public final void addEdges(final List<HE_Edge> edges) {
for (int i = 0; i < edges.size(); i++) {
add(edges.get(i));
}
}
/**
* Adds halfedges.
*
* @param halfedges
* halfedges to add as FastList<HE_Halfedge>
*/
public final void addHalfedges(final List<HE_Halfedge> halfedges) {
for (int i = 0; i < halfedges.size(); i++) {
add(halfedges.get(i));
}
}
/**
* Removes edge.
*
* @param e
* edge to remove
*/
public void remove(final HE_Edge e) {
_hashedEdges.remove(e._key);
}
/**
* Removes halfedge.
*
* @param he
* halfedge to remove
*/
public void remove(final HE_Halfedge he) {
_hashedHalfedges.remove(he._key);
}
/**
* Removes vertex.
*
* @param v
* vertex to remove
*/
public void remove(final HE_Vertex v) {
_hashedVertices.remove(v.key());
}
/**
* Removes vertices.
*
* @param vertices
* vertices to remove as HE_Vertex[]
*/
public final void removeVertices(final HE_Vertex[] vertices) {
for (final HE_Vertex vertice : vertices) {
remove(vertice);
}
}
/**
* Removes edges.
*
* @param edges
* edges to remove as HE_Edge[]
*/
public final void removeEdges(final HE_Edge[] edges) {
for (final HE_Edge edge : edges) {
remove(edge);
}
}
/**
* Removes halfedges.
*
* @param halfedges
* halfedges to remove as HE_Halfedge[]
*/
public final void removeHalfedges(final HE_Halfedge[] halfedges) {
for (final HE_Halfedge halfedge : halfedges) {
remove(halfedge);
}
}
/**
* Removes vertices.
*
* @param vertices
* vertices to remove as FastList<HE_Vertex>
*/
public final void removeVertices(final List<HE_Vertex> vertices) {
for (int i = 0; i < vertices.size(); i++) {
remove(vertices.get(i));
}
}
/**
* Removes edges.
*
* @param edges
* edges to remove as FastList<HE_Edge>
*/
public final void removeEdges(final List<HE_Edge> edges) {
for (int i = 0; i < edges.size(); i++) {
remove(edges.get(i));
}
}
/**
* Removes halfedges.
*
* @param halfedges
* halfedges to remove as FastList<HE_Halfedge>
*/
public final void removeHalfedges(final List<HE_Halfedge> halfedges) {
for (int i = 0; i < halfedges.size(); i++) {
remove(halfedges.get(i));
}
}
/**
* Replace vertices.
*
* @param vertices
* vertices to replace with as HE_Vertex[]
*/
public final void replaceVertices(final HE_Vertex[] vertices) {
_hashedVertices.clear();
final Collection<HE_Vertex> _vertices = _hashedVertices.values();
_vertices.clear();
for (final HE_Vertex vertice : vertices) {
add(vertice);
}
}
/**
* Replace edges.
*
* @param edges
* edges to replace with as HE_Edge[]
*/
public final void replaceEdges(final HE_Edge[] edges) {
_hashedEdges.clear();
for (final HE_Edge edge : edges) {
add(edge);
}
}
/**
* Replace halfedges.
*
* @param halfedges
* halfedges to replace with as HE_Halfedge[]
*/
public final void replaceHalfedges(final HE_Halfedge[] halfedges) {
_hashedHalfedges.clear();
for (final HE_Halfedge halfedge : halfedges) {
add(halfedge);
}
}
/**
* Replace vertices.
*
* @param vertices
* vertices to replace with as HE_Vertex[]
*/
public final void replaceVertices(final List<HE_Vertex> vertices) {
_hashedVertices.clear();
final Collection<HE_Vertex> _vertices = _hashedVertices.values();
_vertices.clear();
for (int i = 0; i < vertices.size(); i++) {
add(vertices.get(i));
}
}
/**
* Replace edges.
*
* @param edges
* edges to replace with as HE_Edge[]
*/
public final void replaceEdges(final List<HE_Edge> edges) {
_hashedEdges.clear();
for (int i = 0; i < edges.size(); i++) {
add(edges.get(i));
}
}
/**
* Replace halfedges.
*
* @param halfedges
* halfedges to replace with as HE_halfedge[]
*/
public final void replaceHalfedges(final List<HE_Halfedge> halfedges) {
_hashedHalfedges.clear();
for (int i = 0; i < halfedges.size(); i++) {
add(halfedges.get(i));
}
}
/**
* Vertex iterator.
*
* @return vertex iterator
*/
public Iterator<HE_Vertex> vItr() {
return _hashedVertices.values().iterator();
}
/**
* Edge iterator.
*
* @return edge iterator
*/
public Iterator<HE_Edge> eItr() {
return _hashedEdges.values().iterator();
}
/**
* Hslfedge iterator.
*
* @return halfedge iterator
*/
public Iterator<HE_Halfedge> heItr() {
return _hashedHalfedges.values().iterator();
}
/** Linked HashMap of faces. */
protected FastMap<Integer, HE_Face> _hashedFaces;
/** Iterator over faces. */
protected Iterator<HE_Face> _faceItr;
/**
* Clear faces.
*/
public final void clearFaces() {
_hashedFaces.clear();
}
/**
* Faces as array.
*
* @return all faces as HE_Face[]
*/
public final HE_Face[] getFacesAsArray() {
final HE_Face[] faces = new HE_Face[numberOfFaces()];
final Iterator<HE_Face> fItr = _hashedFaces.values().iterator();
int i = 0;
while (fItr.hasNext()) {
faces[i] = fItr.next();
i++;
}
return faces;
}
/**
* Faces as arrayList.
*
* @return all vertices as FastList<HE_Face>
*/
public final List<HE_Face> getFacesAsList() {
final List<HE_Face> faces = new FastList<HE_Face>();
faces.addAll(_hashedFaces.values());
return (faces);
}
/**
* Get face.
*
* @param key
* face key
* @return face
*/
public final HE_Face getFaceByKey(final Integer key) {
return _hashedFaces.get(key);
}
/**
* Check if structure contains face.
*
* @param f
* face
* @return true, if successful
*/
public final boolean contains(final HE_Face f) {
if (f == null)
return false;
return _hashedFaces.containsKey(f._key);
}
/**
* Number of faces.
*
* @return the number of faces
*/
public final int numberOfFaces() {
return _hashedFaces.size();
}
/**
* Add the face.
*
* @param f
* face to add
*/
public final void add(final HE_Face f) {
_hashedFaces.put(f.key(), f);
}
/**
* Adds faces.
*
* @param faces
* faces to add as HE_Face[]
*/
public final void addFaces(final HE_Face[] faces) {
for (final HE_Face face : faces) {
add(face);
}
}
/**
* Adds faces.
*
* @param faces
* faces to add as HE_Face[]
*/
public final void addFaces(final List<HE_Face> faces) {
for (int i = 0; i < faces.size(); i++) {
add(faces.get(i));
}
}
/**
* Removes face.
*
* @param f
* face to remove
*/
public void remove(final HE_Face f) {
_hashedFaces.remove(f._key);
}
/**
* Removes faces.
*
* @param faces
* faces to remove as HE_Face[]
*/
public final void removeFaces(final HE_Face[] faces) {
for (final HE_Face face : faces) {
remove(face);
}
}
/**
* Removes faces.
*
* @param faces
* faces to remove as FastList<HE_Face>
*/
public final void removeFaces(final List<HE_Face> faces) {
for (int i = 0; i < faces.size(); i++) {
remove(faces.get(i));
}
}
/**
* Replace faces.
*
* @param faces
* faces to replace with as HE_Face[]
*/
public final void replaceFaces(final HE_Face[] faces) {
_hashedFaces.clear();
for (final HE_Face face : faces) {
add(face);
}
}
/**
* Replace faces.
*
* @param faces
* faces to replace with as HE_Face[]
*/
public final void replaceFaces(final List<HE_Face> faces) {
_hashedFaces.clear();
for (int i = 0; i < faces.size(); i++) {
add(faces.get(i));
}
}
/**
* Face iterator.
*
* @return face iterator
*/
public Iterator<HE_Face> fItr() {
return _hashedFaces.values().iterator();
}
/**
* Get range of vertex coordinates.
*
* @return array of limit values: min x, min y, min z, max x, max y, max z
*/
public double[] limits() {
final double[] result = new double[6];
for (int i = 0; i < 3; i++) {
result[i] = Double.POSITIVE_INFINITY;
}
for (int i = 3; i < 6; i++) {
result[i] = Double.NEGATIVE_INFINITY;
}
HE_Vertex v;
final Iterator<HE_Vertex> vItr = vItr();
while (vItr.hasNext()) {
v = vItr.next();
result[0] = Math.min(result[0], v.x);
result[1] = Math.min(result[1], v.y);
result[2] = Math.min(result[2], v.z);
result[3] = Math.max(result[3], v.x);
result[4] = Math.max(result[4], v.y);
result[5] = Math.max(result[5], v.z);
}
return result;
}
/**
* Get axis-aligned bounding box surrounding mesh.
*
* @return WB_AABB axis-aligned bounding box
*/
public WB_AABB3D getAABB() {
final double[] result = limits();
final WB_Point3d min = new WB_Point3d(result[0], result[1], result[2]);
final WB_Point3d max = new WB_Point3d(result[3], result[4], result[5]);
return new WB_AABB3D(min, max);
}
}