> ## Documentation Index
> Fetch the complete documentation index at: https://docs.opengeometry.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Boundary Representation (BREP)

> Understanding the BREP data structure in OpenGeometry

Boundary Representation (BREP) is the core data structure used in OpenGeometry to represent geometric entities. It describes 3D objects by defining their boundaries through vertices, edges, and faces.

## What is BREP?

BREP is a method of representing shapes by explicitly defining their boundaries. Instead of storing a solid as a filled volume, BREP stores:

* **Vertices** - Points in 3D space
* **Edges** - Connectivity between vertices
* **Faces** - Surfaces bounded by edges (with explicit boundary loops)

This representation is:

* **Exact** - Preserves geometric precision
* **Topology-aware** - Maintains relationships between elements
* **Efficient** - Avoids redundant storage of shared vertices/edges

## Why BREP?

OpenGeometry uses BREP because it:

1. **Supports complex operations** - Boolean operations, offsetting, and extrusion work naturally on boundaries
2. **Maintains precision** - No approximation errors from voxelization or tessellation
3. **Industry standard** - Compatible with CAD file formats like STEP, IGES, and Parasolid
4. **Flexible** - Can represent wireframes, surfaces, and solids with the same structure

## BREP Body Types

OpenGeometry can represent different types of geometric bodies:

* **Solid body** - Has volume (e.g., cube, sphere)
* **Shell body** - Has surface but no volume (e.g., car body)
* **Sheet body** - Has 2D surface (e.g., flat plate)
* **Wireframe body** - Has only edges (e.g., line drawing)
* **Point body** - Single vertex in space

## Data Structure

The BREP structure is defined in the Rust core (`main/opengeometry/src/brep/mod.rs` in this repo):

```rust theme={null}
pub struct Brep {
    pub id: Uuid,
    pub vertices: Vec<Vertex>,
    pub halfedges: Vec<HalfEdge>,
    pub edges: Vec<Edge>,
    pub loops: Vec<Loop>,
    pub faces: Vec<Face>,
    pub wires: Vec<Wire>,
    pub shells: Vec<Shell>,
}
```

<Note>
  IDs (`u32`) in the BREP are array indices. For example, `brep.vertices[vertex_id as usize]` is the
  vertex with id `vertex_id`.
</Note>

### Core Components

#### Vertex

Defined in `main/opengeometry/src/brep/vertex.rs`, a vertex represents a point in 3D space and may
reference an outgoing half-edge for topology traversal:

```rust theme={null}
pub struct Vertex {
    pub id: u32,
    pub position: Vector3,
    pub outgoing_halfedge: Option<u32>,
}
```

**Example:**

```rust theme={null}
let v = Vertex::new(0, Vector3::new(1.0, 2.0, 3.0));
```

#### HalfEdge

Defined in `main/opengeometry/src/brep/halfedge.rs`, a half-edge is the directed topology primitive.
Half-edges are the basis for efficient adjacency queries, loop traversal, and hidden line removal.

```rust theme={null}
pub struct HalfEdge {
    pub id: u32,
    pub from: u32,
    pub to: u32,
    pub twin: Option<u32>,
    pub next: Option<u32>,
    pub prev: Option<u32>,
    pub edge: u32,
    pub face: Option<u32>,
    pub loop_ref: Option<u32>,
    pub wire_ref: Option<u32>,
}
```

Key links:

* `twin` points to the opposite half-edge (when the underlying edge is shared).
* `next` and `prev` walk the boundary of a face loop (or a closed wire).

#### Edge

Defined in `main/opengeometry/src/brep/edge.rs`, an edge is an undirected edge that points at one
or two half-edges:

```rust theme={null}
pub struct Edge {
    pub id: u32,
    pub halfedge: u32,
    pub twin_halfedge: Option<u32>,
}
```

The endpoints of an edge come from its referenced half-edge(s).

#### Face

Defined in `main/opengeometry/src/brep/face.rs`, a face is bounded by an outer loop and zero or
more inner loops (holes):

```rust theme={null}
pub struct Face {
    pub id: u32,
    pub normal: Vector3,
    pub outer_loop: u32,
    pub inner_loops: Vec<u32>,
    pub shell_ref: Option<u32>,
}
```

**Example:**

```rust theme={null}
let face = Face::new(0, Vector3::new(0.0, 0.0, 1.0), 0, Vec::new(), None);
```

#### Loop

Defined in `main/opengeometry/src/brep/loop.rs`, a loop is a face boundary (outer boundary or an
inner hole) represented by a half-edge cycle:

```rust theme={null}
pub struct Loop {
    pub id: u32,
    pub halfedge: u32,
    pub face: u32,
    pub is_hole: bool,
}
```

#### Wire

Defined in `main/opengeometry/src/brep/wire.rs`, a wire is an (optionally closed) polyline stored as
a list of half-edges:

```rust theme={null}
pub struct Wire {
    pub id: u32,
    pub halfedges: Vec<u32>,
    pub is_closed: bool,
}
```

#### Shell

Defined in `main/opengeometry/src/brep/shell.rs`, a shell groups faces and can be marked as open or
closed:

```rust theme={null}
pub struct Shell {
    pub id: u32,
    pub faces: Vec<u32>,
    pub is_closed: bool,
}
```

## BREP Operations

The `Brep` struct provides several utility methods. Most callers should construct BReps through
`BrepBuilder` (see below) and treat the resulting BRep as an immutable kernel output.

### Querying Geometry

```rust theme={null}
// Get count of elements
let vertex_count = brep.get_vertex_count();
let halfedge_count = brep.get_halfedge_count();
let edge_count = brep.get_edge_count();
let loop_count = brep.get_loop_count();
let face_count = brep.get_face_count();
let wire_count = brep.get_wire_count();
let shell_count = brep.get_shell_count();

// Get vertices for a specific face
let vertices: Vec<Vector3> = brep.get_vertices_by_face_id(0);

// Get all vertices as flat array
let all_vertices: Vec<Vector3> = brep.get_flattened_vertices();

// Get a flat triangle buffer (x, y, z triples)
let triangle_buffer: Vec<f64> = brep.get_triangle_vertex_buffer();

// Get a flat outline buffer (line segments)
let outline_buffer: Vec<f64> = brep.get_outline_vertex_buffer();
```

### Handling Holes

Faces can contain holes (inner loops):

```rust theme={null}
// Get face with holes
let (face_vertices, hole_vertices) = brep.get_vertices_and_holes_by_face_id(0);
// face_vertices: outer boundary
// hole_vertices: Vec of hole boundaries
```

If you need to build or modify topology, use `BrepBuilder` (below). You can also clear all geometry
with `brep.clear()`.

## Example: building a BREP with `BrepBuilder`

`BrepBuilder` creates consistent half-edge/edge/loop links and validates topology on `build()`:

```rust theme={null}
use openmaths::Vector3;
use opengeometry::brep::BrepBuilder;
use uuid::Uuid;

let mut builder = BrepBuilder::new(Uuid::new_v4());

// Add vertices
builder.add_vertices(&[
    Vector3::new(0.0, 0.0, 0.0),
    Vector3::new(1.0, 0.0, 0.0),
    Vector3::new(1.0, 0.0, 1.0),
    Vector3::new(0.0, 0.0, 1.0),
]);

// Add a quad face using vertex indices (the builder creates loops, half-edges, and edges).
builder.add_face(&[0, 1, 2, 3], &[])?;

let brep = builder.build()?;
```

## Serialization

BREP structures are serializable via `serde`:

```rust theme={null}
// Serialize to JSON
let json = serde_json::to_string(&brep)?;

// Deserialize from JSON
let brep: Brep = serde_json::from_str(&json)?;
```

This enables passing BREP data between Rust and JavaScript via WASM.

## Topology Validation

`BrepBuilder::build()` calls `brep.validate_topology()` before returning. Exporters can also validate
topology (depending on the export config).

Valid BREP structures should maintain:

* **Vertex references** - All referenced vertex IDs exist in vertex list
* **Half-edge symmetry** - `twin`, `next`, and `prev` links are consistent
* **Manifold edges** - An edge has at most two incident faces

## References

The BREP implementation is based on:

* [Boundary Representation (Wikipedia)](https://en.wikipedia.org/wiki/Boundary_representation)
* [Doubly Connected Edge List](https://en.wikipedia.org/wiki/Doubly_connected_edge_list)
* [CMU Graphics Lectures](https://15462.courses.cs.cmu.edu/spring2021content/lectures/11_meshes/11_meshes_slides.pdf)

## Next Steps

<CardGroup cols={2}>
  <Card title="Architecture" icon="diagram-project" href="/OpenGeometry/concepts/architecture">
    Understand how BREP fits in the system architecture
  </Card>

  <Card title="Primitives and Shapes" icon="shapes" href="/OpenGeometry/concepts/primitives-and-shapes">
    Explore the available 2D and 3D primitives you can create
  </Card>
</CardGroup>
