Skip to content

Latest commit

 

History

History
233 lines (160 loc) · 8.82 KB

hmesh_description.md

File metadata and controls

233 lines (160 loc) · 8.82 KB

Description of HMesh

The half-edge data structure modelized by HMesh 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

An half-edge is modelized by the Java interface HEdge

A vertex is modelized by the Java interface HVertex

Streams on each collection are provided by HMesh:

   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 consists of a cycle of HEdge forming a polygon boundary. Each HEdge connects two HVertex

HFace provides getters on its HEdge and on its HVertex:

   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 also provides a getter on its adjacent neighbors:

   HFace face = ...
   
   // Get the sequence of adjacent faces
   Sequence<HFace> neighbors = face.neighbors();

HEdge

An HEdge modelizes an oriented link between 2 HVertex. 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:

   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 modelizes a vertex. A HVertex is both the tail of several HEdge and the head of several others HEdge

   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 a half-edge)
   Sequence<HVertex> neighbors = vertex.neighbors();

Sequence

Some of the getters of HFace, HEdge and HVertex are returning a Sequence. A Sequence is a kind of simplified stream providing several basic streaming operations:

   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)) {
      ...
   }
   
   // Tell if a vertex is a neighbor of a half-edge's head
   boolean isNeighbor = edge.outgoingEdges().anyMatch(e -> e.head() == vertex);

Topological operations on HMesh

Several topological operations are provided by HMesh:

  • Splitting a face into two parts
   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);
  • Merging two faces
   HMesh mesh = ...
   HFace face1 = ...
   HFace face2 = ...
   
   // Merge 2 adjacent faces
   boolean success = mesh.mergeFaces(face1, face2);
  • Splitting an edge by inserting a new vertex
   HMesh mesh = ...
   HEdge edge = ...
   
   // Split a half-edge (and its opposite) and return the newly vertex
   HVertex vertex = mesh.splitEdge(edge);
  • Collapsing an edge
   HMesh mesh = ...
   HEdge edge = ...
   
   // Collapse a half-edge (and its opposite) by merging its head and its tail
   boolean success = mesh.collapseEdge(edge);
  • Removing a vertex
   HMesh mesh = ...
   HVertex vertex = ...
   
   // Remove a vertex
   boolean success = mesh.removeVertex(vertex);

Data association with a HMesh

Faces, half-edges and vertices of a HMesh 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:

   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:

   // 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:

   // Create a set of data associated with the mesh's faces
   HData<HFace, Color> faceColors = mesh.createFaceData();

These sets of data (HData for Java objects, HDData for double values, HIData for integer values, HBData 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

An HMesh is always consistent during its lifetime whatever operations performed on it:

  • HMesh never contains orphan HVertex or HEdge: an HEdge is always connecting 2 HVertex. A HVertex is always the origin and the end of several HEdge
  • An HEdge is always associated with an opposite/twin HEdge. The relationship is always symmetric : edge.opposite().opposite() == edge
  • An HEdge is always part of one and only one polygonal cycle
  • All HEdge of a polygonal cycle are always distinct
  • No collapsed faces: each HFace always contains a cycle of at least 3 half-edges