Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
first upload src / docs / examples
  • Loading branch information
pierre-b-geom authored Aug 5, 2018
1 parent 274ba4c commit bc97b43
Show file tree
Hide file tree
Showing 74 changed files with 9,820 additions and 0 deletions.
Binary file added docs/edges.dia
Binary file not shown.
Binary file added docs/edges.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/face_description.dia
Binary file not shown.
Binary file added docs/face_description.dia~
Binary file not shown.
Binary file added docs/face_description.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
221 changes: 221 additions & 0 deletions docs/hmesh_description.md
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
149 changes: 149 additions & 0 deletions docs/hmesh_uses.md
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 added docs/mesh.dia
Binary file not shown.
Binary file added docs/mesh.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/polygons.dia
Binary file not shown.
Binary file added docs/polygons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/polygons_coords.dia
Binary file not shown.
Binary file added docs/polygons_coords.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit bc97b43

Please sign in to comment.