-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
74 changed files
with
9,820 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
## Description of [HMesh](../src/hgeom/hmesh/elements/HMesh.java) | ||
|
||
The half-edge data structure modelized by [HMesh](../src/hgeom/hmesh/elements/HMesh.java) is composed of a collection of faces, a collection of half-edges and a collection of vertices. | ||
|
||
A face is modelized by the Java interface [HFace](../src/hgeom/hmesh/elements/HFace.java) | ||
|
||
An half-edge is modelized by the Java interface [HEdge](../src/hgeom/hmesh/elements/HEdge.java) | ||
|
||
A vertex is modelized by the Java interface [HVertex](../src/hgeom/hmesh/elements/HVertex.java) | ||
|
||
Streams on each collection are provided by [HMesh](../src/hgeom/hmesh/elements/HMesh.java): | ||
|
||
```Java | ||
HMesh mesh = ... | ||
|
||
// Get streams over the collections of faces, half-edges and vertices | ||
Stream<HFace> faces = mesh.faces(); | ||
Stream<HEdge> edges = mesh.edges(); | ||
Stream<HFace> vertices = mesh.vertices(); | ||
``` | ||
|
||
### HFace | ||
|
||
A [HFace](../src/hgeom/hmesh/elements/HFace.java) consists of a cycle of [HEdge](../src/hgeom/hmesh/elements/HEdge.java) forming a polygon boundary. Each [HEdge](../src/hgeom/hmesh/elements/HEdge.java) connects two [HVertex](../src/hgeom/hmesh/elements/HVertex.java) | ||
|
||
<p align="center"> | ||
<img src="face_description.png"> | ||
</p> | ||
|
||
[HFace](../src/hgeom/hmesh/elements/HFace.java) provides getters on its [HEdge](../src/hgeom/hmesh/elements/HEdge.java) and on its [HVertex](../src/hgeom/hmesh/elements/HVertex.java): | ||
|
||
```Java | ||
HFace face = ... | ||
|
||
// Get the sequence of half-edges forming the face / polygon's boundary | ||
Sequence<HEdge> edges = face.edges(); | ||
|
||
// Get the sequence of vertices on the face / polygon's boundary | ||
Sequence<HVertice> vertices = face.vertices(); | ||
``` | ||
[HFace](../src/hgeom/hmesh/elements/HFace.java) also provides a getter on its adjacent neighbors: | ||
|
||
```Java | ||
HFace face = ... | ||
|
||
// Get the sequence of adjacent faces | ||
Sequence<HFace> neighbors = face.neighbors(); | ||
``` | ||
|
||
### HEdge | ||
|
||
An [HEdge](../src/hgeom/hmesh/elements/HEdge.java) modelizes an oriented link between 2 [HVertex](../src/hgeom/hmesh/elements/HVertex.java). It is an element of a cycle forming the boundary of a polygon. It always has a twin / opposite half-edge | ||
|
||
Various getters are provided by [HEdge](../src/hgeom/hmesh/elements/HEdge.java): | ||
|
||
```Java | ||
HEdge edge = ... | ||
|
||
// Get the face to which the half-edge belongs | ||
HFace face = edge.face(); | ||
|
||
// Get the vertex the edge points at | ||
HVertex head = edge.head(); | ||
|
||
// Get the vertex the edge starts from | ||
HVertex tail = edge.tail(); | ||
|
||
// Get the next edge on the edge's cycle | ||
HEdge next = edge.next(); | ||
|
||
// Get the previous edge on the edge's cycle | ||
HEdge previous = edge.previous(); | ||
|
||
// Get the opposite / twin half-edge | ||
HEdge opposite = edge.opposite(); | ||
|
||
// Get the cycle the edge is part of | ||
Sequence<HEdge> cycle = edge.cycle(); | ||
|
||
// Get all edges going out of the edge's head | ||
Sequence<HEdge> outgoingEdges = edge.outgoingEdges() | ||
|
||
// Get all edges starting from the edge's tail | ||
Sequence<HEdge> incomingEdges = edge.incomingEdges() | ||
``` | ||
### HVertex | ||
|
||
An [HVertex](../src/hgeom/hmesh/elements/HVertex.java) modelizes a vertex. A [HVertex](../src/hgeom/hmesh/elements/HVertex.java) is both the tail of several [HEdge](../src/hgeom/hmesh/elements/HEdge.java) and the head of several others [HEdge](../src/hgeom/hmesh/elements/HEdge.java) | ||
|
||
```Java | ||
HVertex vertex = ... | ||
|
||
// Get one of the half-edge pointing at the vertex | ||
HEdge edge = vertex.edge(); | ||
|
||
// Get all half-edges going out of the vertex | ||
Sequence<HEdge> outgoingEdges = vertex.outgoingEdges() | ||
|
||
// Get all half-edges pointing at the vertex | ||
Sequence<HEdge> incomingEdges = vertex.incomingEdges() | ||
|
||
// Get all vertices neighbors of the vertex (in connection via an half-edge) | ||
Sequence<HVertex> neighbors = vertex.neighbors(); | ||
``` | ||
|
||
### Sequence | ||
|
||
Some of the getters of HFace, HEdge and HVertex are returning a [Sequence](../src/hgeom/hmesh/sequence/Sequence.java). A [Sequence](../src/hgeom/hmesh/sequence/Sequence.java) is a kind of simplified stream providing several basic streaming operations: | ||
|
||
```Java | ||
HVertex vertex = ... | ||
HEdge edge = ... | ||
|
||
// Collect all vertex neighbors whose degree is 5 into a list | ||
List<HVertex> neighbors = vertex.neighbors(). | ||
filter(v -> v.degree() == 5).toList(); | ||
|
||
// Iterate on the vertices of a cycle | ||
for (HVertex vertex : edge.cycle().map(HEdge::head)) { | ||
... | ||
} | ||
|
||
``` | ||
|
||
|
||
### Topological operations on [HMesh](../src/hgeom/hmesh/elements/HMesh.java) | ||
|
||
Several topological operations are provided by [HMesh](../src/hgeom/hmesh/elements/HMesh.java): | ||
|
||
- Splitting a face into two parts: | ||
|
||
```Java | ||
HMesh mesh = ... | ||
HFace face = ... | ||
HVertex vertex1 = ... | ||
HVertex vertex2 = ... | ||
|
||
// Split a face along the line formed by 2 of its vertices | ||
Optional<HFace> newFace = mesh.splitFace(face, vertex1, vertex2); | ||
``` | ||
|
||
- Splitting a half-edge by inserting a new vertex: | ||
|
||
```Java | ||
HMesh mesh = ... | ||
HEdge edge = ... | ||
|
||
// Split a edge and return the newly vertex | ||
HVertex vertex = mesh.splitEdge(edge); | ||
``` | ||
|
||
- Removing a vertex: | ||
|
||
```Java | ||
HMesh mesh = ... | ||
HVertex vertex = ... | ||
|
||
// Remove a vertex | ||
boolean success = mesh.removeVertex(vertex); | ||
``` | ||
|
||
- Merging two faces: | ||
|
||
```Java | ||
HMesh mesh = ... | ||
HFace face1 = ... | ||
HFace face2 = ... | ||
|
||
// Merge 2 adjacent faces | ||
boolean success = mesh.mergeFaces(face1, face2); | ||
``` | ||
|
||
### Data association with a [HMesh](../src/hgeom/hmesh/elements/HMesh.java) | ||
|
||
Faces, half-edges and vertices of a [HMesh](../src/hgeom/hmesh/elements/HMesh.java) can be associated with data. HMesh provides several methods to do that | ||
|
||
For instance, to associate a double value to each of the vertices of a [HMesh](../src/hgeom/hmesh/elements/HMesh.java): | ||
|
||
```Java | ||
HMesh mesh = ... | ||
|
||
// Create a collection of double values associated with the mesh's vertices | ||
HDData<HVertex> vertexDoubleValues = mesh.createVertexDoubleData(); | ||
|
||
// Associate a value to a vertex | ||
HVertex vertex = ... | ||
vertexDoubleValues.set(vertex, 2.3); | ||
|
||
// Get the value associated to a vertex | ||
double value = vertexDoubleValues.get(vertex); | ||
|
||
// set all double values associated with the mesh's vertices using a function | ||
// to compute the values | ||
vertexDoubleValues.setAll(v -> { | ||
... | ||
}); | ||
``` | ||
|
||
Or to associate boolean values to the collection of edges: | ||
|
||
```Java | ||
// Create a set of boolean values associated with the mesh's half-edges | ||
HBData<HEdge> edgeFlags = mesh.createEdgeBooleanData(); | ||
``` | ||
|
||
Or to associate Java objects to the collection of faces: | ||
|
||
```Java | ||
// Create a set of data associated with the mesh's faces | ||
HData<HFace, Color> faceColors = mesh.createFaceData(); | ||
``` | ||
|
||
These sets of data ([HData](../src/hgeom/hmesh/data/HData.java) for Java objects, [HDData](../src/hgeom/hmesh/data/HDData.java) for double values, [HIData](../src/hgeom/hmesh/data/HIData.java) for integer values, [HBData](../src/hgeom/hmesh/data/HBData.java) for boolean values) are synchronized with their associated mesh and are updated whenever a topological change occurs. For instance, if a vertex is removed from the mesh, all values attached to this vertex will automatically be removed from all sets of data | ||
|
||
### Consistency of [HMesh](../src/hgeom/hmesh/elements/HMesh.java) | ||
An [HMesh](../src/hgeom/hmesh/elements/HMesh.java) is always consistent during its lifetime whatever operations performed on it: | ||
|
||
- [HMesh](../src/hgeom/hmesh/elements/HMesh.java) does not contain orphan [HVertex](../src/hgeom/hmesh/elements/HVertex.java) or [HEdge](../src/hgeom/hmesh/elements/HEdge.java): an [HEdge](../src/hgeom/hmesh/elements/HEdge.java) is always connecting 2 [HVertex](../src/hgeom/hmesh/elements/HVertex.java). A [HVertex](../src/hgeom/hmesh/elements/HVertex.java) is always the origin and the end of several [HEdge](../src/hgeom/hmesh/elements/HEdge.java) | ||
- An [HEdge](../src/hgeom/hmesh/elements/HEdge.java) is always associated with an opposite/twin [HEdge](../src/hgeom/hmesh/elements/HEdge.java). The relationship is always symmetric : edge.opposite().opposite() == edge | ||
- An [HEdge](../src/hgeom/hmesh/elements/HEdge.java) is always part of one and only one polygonal cycle | ||
- All [HEdge](../src/hgeom/hmesh/elements/HEdge.java) of a polygonal cycle are always distinct |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
## Examples of uses of [HMesh](../src/hgeom/hmesh/elements/HMesh.java) | ||
|
||
#### 1. A function creating a [HMesh](../src/hgeom/hmesh/elements/HMesh.java) from a list of polygons | ||
|
||
```Java | ||
public static HMesh createHMesh(List<int[]> faces) { | ||
return new FaceSource(faces).toHMesh().orElseThrow(IllegalStateException::new); | ||
} | ||
``` | ||
|
||
#### 2. A function creating a [HMesh2D](../src/hgeom/hmesh/elements/HMesh2D.java) from a list of polygons and an array of 2D vertex coordinates | ||
|
||
```Java | ||
public static HMesh2D createHMesh2D(int[][] faces, double[][] vertexCoords) { | ||
|
||
// Create face source | ||
FaceSource faceSource = new FaceSource(faces); | ||
|
||
// Create vertex coordinates source | ||
Coord2DSource coord2DSource = new Coord2DSource(vertexCoords); | ||
|
||
// Build the half-edge data structure from the faces and the coordinates | ||
return faceSource.toHMesh(coord2DSource).orElseThrow(IllegalStateException::new); | ||
} | ||
``` | ||
|
||
#### 3. Assign values to polygons according to values attached to their vertices | ||
|
||
```Java | ||
// The polygons as arrays of indices to vertices: | ||
int[][] faces = ...; | ||
|
||
// The values attached to the vertices | ||
double[] vertexValues = ... | ||
|
||
// Create a faces source | ||
FaceSource faceSource = new FaceSource(faces); | ||
|
||
// Create a converter to HMesh | ||
ToHMeshConverter converter = new ToHMeshConverter(); | ||
|
||
// Build the half-edge data structure from the faces | ||
HConversion<HMesh> conversion = converter.convert(faceSource) | ||
.orElseThrow(RuntimeException::new); | ||
|
||
// Get the created half-edge data structure | ||
HMesh mesh = conversion.mesh(); | ||
|
||
// Map the original vertex weights to the half-edge data structure's vertices | ||
HDData<HVertex> meshVertexValues = conversion.meshVertexDoubleData(i -> vertexValues[i]); | ||
|
||
// Create a data collection for the half-edge data structure's faces | ||
HDData<HFace> meshFaceValues = mesh.createFaceDoubleData(); | ||
|
||
// Set each face value as the sum of the values associated to the vertices on its border | ||
meshFaceValues.setAll(f -> { | ||
double sum = 0; | ||
|
||
// Compute the sum of the value assigned to the vertices of the face border | ||
for (HVertex v : f.vertices()) { | ||
sum += meshVertexValues.get(v); | ||
} | ||
|
||
// Assign the computed value to the face | ||
return sum; | ||
}); | ||
``` | ||
|
||
#### 4. Assign values to vertices according to values attached to surrounding polygons | ||
|
||
```Java | ||
// The polygons as arrays of indices to vertices: | ||
int[][] faces = ...; | ||
|
||
// The values attached to the polygons | ||
double[] faceValues = ... | ||
|
||
// Create a faces source | ||
FaceSource faceSource = new FaceSource(faces); | ||
|
||
// Create a converter to HMesh | ||
ToHMeshConverter converter = new ToHMeshConverter(); | ||
|
||
// Build the half-edge data structure from the faces | ||
HConversion<HMesh> conversion = converter.convert(faceSource) | ||
.orElseThrow(RuntimeException::new); | ||
|
||
// Get the created half-edge data structure | ||
HMesh mesh = conversion.mesh(); | ||
|
||
// Map the original face values to the half-edge data structure's faces | ||
HDData<HFace> meshFaceValues = conversion.meshFaceDoubleData(i -> faceValues[i]); | ||
|
||
// Create a data collection for the half-edge data structure's vertices | ||
HDData<HVertex> meshVertexValues = mesh.createVertexDoubleData(); | ||
|
||
// Set each vertex value as the average of the values associated to its neighboring polygons | ||
meshVertexValues.setAll(vertex -> { | ||
double mean = 0; | ||
int count = 0; | ||
|
||
// Iterate on all the polygons connected to the vertex | ||
for (HFace face : vertex.outgoingEdges().map(HEdge::face)) { | ||
mean += meshFaceValues.get(face); | ||
count += 1; | ||
} | ||
|
||
// A vertex always connected to several faces, so count > 0 | ||
return mean / count; | ||
}); | ||
``` | ||
|
||
#### 5. Remove from a polygonal mesh all vertices whose associated value is superior to a limit | ||
|
||
```Java | ||
// The polygons as arrays of indices to vertices: | ||
int[][] faces = ...; | ||
|
||
// The values attached to the vertices | ||
int[] vertexValues = ... | ||
|
||
// The limit | ||
int limit = ... | ||
|
||
// Create a faces source | ||
FaceSource faceSource = new FaceSource(faces); | ||
|
||
// Create a converter to HMesh | ||
ToHMeshConverter converter = new ToHMeshConverter(); | ||
|
||
// Build the half-edge data structure from the facessources | ||
HConversion<HMesh> conversion = converter.convert(faceSource) | ||
.orElseThrow(RuntimeException::new); | ||
|
||
// Get the created half-edge data structure | ||
HMesh mesh = conversion.mesh(); | ||
|
||
// Map the original vertex weights to the half-edge data structure's vertices | ||
HIData<HVertex> meshVertexValues = conversion.meshVertexIntData(i -> vertexValues[i]); | ||
|
||
// Get the vertices associated with a value > limit | ||
List<HVertex> verticesToRemove = mesh.vertices() | ||
.filter(v -> meshVertexValues.get(v) > limit) | ||
.collect(Collectors.toList()); | ||
|
||
for (HVertex vertex : verticesToRemove) { | ||
mesh.removeVertex(vertex); | ||
} | ||
``` |
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.