Initializing 3D Canvas...

The Brep

1 min read1 page

The Simple Concept

The Boundary Representation

A Brep (Boundary Representation) is the data format used by professional CAD software. Unlike a Mesh, which is an approximation, a Brep is a collection of perfectly mathematical Surfaces (NURBS) joined to form a solid volume.

It represents the exact boundary between the "inside" of an object and the "outside".

Solid Intelligence: A Brep knows which side of a surface is solid material and which is empty air. This allows for perfect calculations of volume, mass, and center of gravity.
3 min read1 page

The Data Structure

The Hierarchy of Topology

A Brep is a complex, nested data structure. To define a Brep, the computer navigates a hierarchy:

  1. Faces: The individual surfaces making up the shell.
  2. Edges: Boundaries where two faces meet.
  3. Vertices: Corners where multiple edges meet.
python
1class BrepVertex:
2 def __init__(self, location: 'Point3d'):
3 self.Location = location # 3D coordinate point
4 self.AdjacentEdges = [] # Edges meeting at this vertex
5
6class BrepEdge:
7 def __init__(self, curve: 'Curve3d'):
8 self.EdgeCurve = curve # 3D parameter space curve
9 self.StartVertex = None # BrepVertex
10 self.EndVertex = None # BrepVertex
11 self.AdjacentFaces = [] # Faces sharing this edge boundary
12
13class BrepFace:
14 def __init__(self, surface: 'NurbsSurface'):
15 self.UnderlyingSurface = surface # Perfect infinite mathematical surface
16 self.Loops = [] # Closed loop boundary curves (trims)
17 self.OuterLoop = None # The primary exterior boundary
18
19class Brep:
20 def __init__(self):
21 self.Faces = [] # List of BrepFace objects
22 self.Edges = [] # List of unique BrepEdge objects
23 self.Vertices = [] # List of unique BrepVertex objects
Brep Faces are underlying NURBS surfaces. See The Surface article for details.
Highlight
2 min read1 page

Translate(vector):

Shifts the entire solid model by the vector.
python
1def Translate(self, vector: 'Vector3d'):
2 """Shifts the entire solid model by a vector."""
3 # To avoid duplicate translation of shared elements (e.g. an edge bordering
4 # two faces moving twice), we transform unique geometric pools once:
5
6 # 1. Shift master corner coordinates once
7 for vertex in self.Vertices:
8 vertex.Location += vector
9
10 # 2. Shift edge 3D curves once
11 for edge in self.Edges:
12 edge.Geometry.Translate(vector)
13
14 # 3. Shift face 3D surfaces once
15 for face in self.Faces:
16 face.Geometry.Translate(vector)

The Shared Topology Trap: Because B-Rep is a shared graph (multiple faces share the same edges and vertices), recursive transformation (moving a face which moves its edges and vertices) would translate shared boundaries multiple times. We prevent this by transforming unique pools of vertices, curves, and surfaces exactly once.

Move X
2.00
Move Y
1.00
2 min read1 page

Scale(factor):

Uniformly scales the Brep by a given factor.
python
1def Scale(self, scale_factor: float, center: 'Point3d' = Point3d(0,0,0)):
2 """Uniformly scales the Brep by a given factor around a center point."""
3 # 1. Create a scaling matrix
4 transform = Transform.Scale(center, scale_factor)
5
6 # 2. Scale all topological vertices
7 for vertex in self.Vertices:
8 vertex.Location = transform * vertex.Location
9
10 # 3. Scale the underlying geometries of faces and edges
11 for face in self.Faces:
12 face.Geometry.Transform(transform)
13
14 for edge in self.Edges:
15 edge.Geometry.Transform(transform)

Scaling a Brep expands its entire mathematical definition. Unlike scaling a mesh, scaling a Brep preserves the perfect mathematical precision of its underlying NURBS surfaces.

Scale Factor
1.50
2 min read1 page

Rotate(angle, axis, center):

Rotates the Brep around a specified axis and center point.
python
1def Rotate(self, angle: float, axis: 'Vector3d', center: 'Point3d'):
2 """Rotates the Brep around a specified axis and center point."""
3 # 1. Create a rotation matrix
4 transform = Transform.Rotation(angle, axis, center)
5
6 # 2. Rotate all topological vertices
7 for vertex in self.Vertices:
8 vertex.Location = transform * vertex.Location
9
10 # 3. Rotate the underlying geometries of faces and edges
11 for face in self.Faces:
12 face.Geometry.Transform(transform)
13
14 for edge in self.Edges:
15 edge.Geometry.Transform(transform)

Rotating a Brep spins all internal NURBS data around an axis. This transformation is applied to every surface, trim curve, and vertex within the topological hierarchy.

Angle (°)
45.00
3 min read1 page

Brep.IsSolid / Valence:

A B-Rep is a valid **solid** when it is fully closed (watertight) and **manifold**. We inspect this by looking at edge valence: the number of adjacent faces sharing each edge.
python
1# Edge valence (number of connected faces) determines B-Rep validity:
2# - Naked Edge (Valence = 1): Boundary of an open surface patch.
3# - Manifold Edge (Valence = 2): Watertight seam where exactly two faces join.
4# - Non-Manifold Edge (Valence >= 3): T-junction where three or more faces intersect.
5
6def ValidateSolid(brep: Brep) -> dict:
7 is_manifold = True
8 naked_edges = []
9 non_manifold_edges = []
10
11 for edge in brep.Edges:
12 valence = len(edge.AdjacentFaces)
13 if valence == 1:
14 naked_edges.append(edge)
15 elif valence >= 3:
16 non_manifold_edges.append(edge)
17 is_manifold = False
18
19 is_solid = is_manifold and len(naked_edges) == 0
20 return {
21 "IsSolid": is_solid,
22 "NakedCount": len(naked_edges),
23 "NonManifoldCount": len(non_manifold_edges)
24 }
Validation Scene
6 min read2 pages

Compute(brep):

Computes volume and mass properties of a closed Brep.
python
1def compute_brep_volume(brep: Brep) -> dict:
2 """Calculates the exact volume and centroid of a closed Brep.
3 Uses Gauss's Divergence Theorem: Volume = 1/3 * sum(integral(F . n dS))
4 where F is the vector field [x, y, z] / 3.
5 """
6 if not brep.IsSolid:
7 raise ValueError("Cannot compute volume of non-watertight Brep.")
8
9 total_volume = 0.0
10 centroid_sum = [0.0, 0.0, 0.0]
11
12 # Tessellate/evaluate each face surface patch to compute integration
13 for face in brep.Faces:
14 # Approximate surface patch as small planar triangles or polygons
15 mesh = face.Tessellate(tolerance=0.01)
16
17 for triangle in mesh.Triangles:
18 # Vertices of the triangle in 3D
19 p0, p1, p2 = triangle.V0, triangle.V1, triangle.V2
20
21 # Signed volume of tetrahedron formed by origin (0,0,0) and the triangle
22 # V = 1/6 * |p0 . (p1 x p2)|
23 cross_x = p1.y * p2.z - p1.z * p2.y
24 cross_y = p1.z * p2.x - p1.x * p2.z
25 cross_z = p1.x * p2.y - p1.y * p2.x
26
27 signed_tetra_vol = (p0.x * cross_x + p0.y * cross_y + p0.z * cross_z) / 6.0
28
29 total_volume += signed_tetra_vol
30
31 # Center of the tetrahedron
32 cx = (p0.x + p1.x + p2.x) / 4.0
33 cy = (p0.y + p1.y + p2.y) / 4.0
34 cz = (p0.z + p1.z + p2.z) / 4.0
35
36 centroid_sum[0] += cx * signed_tetra_vol
37 centroid_sum[1] += cy * signed_tetra_vol
38 centroid_sum[2] += cz * signed_tetra_vol
39
40 # Centroid is volume-weighted average position
41 centroid = [0.0, 0.0, 0.0]
42 if abs(total_volume) > 1e-9:
43 centroid = [
44 centroid_sum[0] / total_volume,
45 centroid_sum[1] / total_volume,
46 centroid_sum[2] / total_volume
47 ]
48
49 return {
50 "volume": abs(total_volume),
51 "centroid": centroid,
52 "is_watertight": True
53 }

For a watertight Brep, you can compute the exact enclosed volume and center of mass. This is a fundamentally different operation from surface area — volume requires a closed solid boundary. Essential for BIM quantity takeoffs, structural dead-load calculations, and CNC machining stock estimation.

Box Size
2.50
3 min read1 page

Deconstruct / Explode:

A Boundary Representation is a complex data structure. "Exploding" a B-Rep simply means breaking its topological links, allowing you to access the individual untrimmed surfaces (Faces), boundary curves (Edges), and corner points (Vertices).
python
1def explode_brep(brep: Brep) -> dict:
2 """Deconstructs a B-Rep into individual face surfaces, boundary edges, and vertices."""
3 extracted_faces = []
4 extracted_edges = []
5 extracted_vertices = []
6
7 # Extract faces (NURBS surfaces with trim loop boundaries)
8 for i, face in enumerate(brep.Faces):
9 face_geometry = face.UnderlyingSurface()
10 extracted_faces.append({
11 "index": i,
12 "surface": face_geometry,
13 "outer_loop": face.OuterLoop
14 })
15
16 # Extract unique edges (3D curves forming face boundaries)
17 for j, edge in enumerate(brep.Edges):
18 edge_curve = edge.EdgeCurve
19 extracted_edges.append({
20 "index": j,
21 "curve": edge_curve,
22 "start_vertex": edge.StartVertex,
23 "end_vertex": edge.EndVertex
24 })
25
26 # Extract unique vertices (3D points at edge endpoints)
27 for k, vertex in enumerate(brep.Vertices):
28 extracted_vertices.append({
29 "index": k,
30 "position": vertex.Location
31 })
32
33 return {
34 "faces": extracted_faces,
35 "edges": extracted_edges,
36 "vertices": extracted_vertices
37 }
Explode Distance
0.00
3 min read1 page

Intersect(Plane):

Intersecting a B-Rep with a mathematical Plane generates a series of 1D curves (contours). This is the exact algorithm used in 3D printing (slicing) and topographic map generation.
python
1def create_contours(brep: Brep, plane_origin: Point3D, plane_normal: Vector3D, step: float, limit_dist: float) -> list[Curve]:
2 """Generates contour curves by intersecting a Brep with parallel planes."""
3 contours = []
4
5 # Calculate spacing along the normal vector direction
6 dir_normalized = plane_normal.Normalize()
7 num_steps = int(limit_dist / step)
8
9 for i in range(num_steps):
10 # Shift plane origin along the normal vector
11 offset_distance = i * step
12 shift_vector = dir_normalized * offset_distance
13 current_origin = plane_origin + shift_vector
14
15 # Define the mathematical intersection plane
16 slice_plane = Plane(current_origin, dir_normalized)
17
18 # Intersect the plane with each face of the B-Rep
19 plane_contours = []
20 for face in brep.Faces:
21 intersection_curves = face.IntersectWithPlane(slice_plane)
22 for curve in intersection_curves:
23 plane_contours.append(curve)
24
25 # Join individual intersection segments into continuous curves
26 joined_curves = Curve.JoinCurves(plane_contours)
27 contours.extend(joined_curves)
28
29 return contours
Slice Spacing
0.50
4 min read1 page

ClosestPoint(Point3d):

Finding the closest point on a Brep is a multi-step process. The computer first finds the closest point on every individual Face, then checks the distance to every Edge.
python
1def find_closest_point_on_brep(brep: Brep, test_point: Point3D) -> dict:
2 """Finds the point on the B-Rep surface boundary closest to the test point.
3 Projects the point onto each individual face and edge boundary.
4 """
5 closest_point = None
6 min_distance = float('inf')
7 source_element_type = None
8 source_element_index = -1
9
10 # 1. Project onto individual B-Rep Faces (surfaces)
11 for i, face in enumerate(brep.Faces):
12 # Projects point onto face UV space, then checks if inside face loops
13 projection_result = face.ProjectPoint(test_point)
14 if projection_result.IsSuccess:
15 projected_pt = projection_result.Point
16 dist = test_point.DistanceTo(projected_pt)
17 if dist < min_distance:
18 min_distance = dist
19 closest_point = projected_pt
20 source_element_type = "Face"
21 source_element_index = i
22
23 # 2. Project onto B-Rep Edges (boundary curves)
24 for j, edge in enumerate(brep.Edges):
25 # Find closest parameter t on edge 3D curve
26 success, t = edge.EdgeCurve.ClosestPoint(test_point)
27 if success:
28 curve_pt = edge.EdgeCurve.PointAt(t)
29 dist = test_point.DistanceTo(curve_pt)
30 if dist < min_distance:
31 min_distance = dist
32 closest_point = curve_pt
33 source_element_type = "Edge"
34 source_element_index = j
35
36 return {
37 "closest_point": closest_point,
38 "distance": min_distance,
39 "element_type": source_element_type,
40 "element_index": source_element_index
41 }
This iterates over all boundary faces to project the point, picking the candidate with the shortest Euclidean distance.
Search Pt X
4.00
Search Pt Y
4.00
3 min read1 page

Flip:

Reverses the orientation of all surfaces within a Brep, turning an object inside-out.
python
1def flip_brep_orientation(brep: Brep) -> Brep:
2 """Reverses the orientation of all faces and boundary curves in a B-Rep.
3 Turns solid inside-out (flipping normal vectors from outward to inward).
4 """
5 # 1. Flip surface normal directions on all faces
6 for face in brep.Faces:
7 # Toggle orientation boolean flag to invert surface normal
8 face.OrientationIsReversed = not face.OrientationIsReversed
9
10 # 2. Reverse 2D trim curves in loops to keep solid-on-left convention
11 for loop in brep.Loops:
12 for trim in loop.Trims:
13 # Reverse start/end points and direction of parameter space curve
14 trim.Reverse()
15
16 # 3. Reverse 3D curves of all edges to remain consistent with trims
17 for edge in brep.Edges:
18 # Flip edge parameter space (start parameter <-> end parameter)
19 edge.EdgeCurve.Reverse()
20
21 return brep

In 3D modeling, a solid is defined as a closed boundary of surfaces where all the surface normals point “outward” into empty space. If the normals point inward, algorithms (like volume calculation or boolean subtractions) will treat the object as a void, or an infinite space with a hole in it.

Brep.Flip() simultaneously reverses the normals of all constituent faces. This is often necessary when creating voids for boolean differences, or fixing imported geometry that came in inverted.

Flip Brep
3 min read1 page

IsPointInside:

Determines if a 3D coordinate falls within the volumetric boundary of a solid Brep.
python
1def CheckPointContainment(brep: Brep, test_point: 'Point3d', tolerance: float = 0.001) -> bool:
2 """Determines if a 3D point is inside a closed Brep solid."""
3 if not brep.IsSolid:
4 raise ValueError("Containment check requires a closed watertight B-Rep solid.")
5
6 # Ray casting method: shoot an arbitrary ray into infinity
7 ray_direction = Vector3d(0, 0, 1) # shoot vertically up
8 intersection_count = 0
9
10 # Count how many times the ray intersects the faces
11 for face in brep.Faces:
12 hits = face.IntersectRay(test_point, ray_direction, tolerance)
13 intersection_count += len(hits)
14
15 # Odd number of intersections means the point is inside the boundary
16 return (intersection_count % 2) == 1

Unlike a mathematical Sphere where checking containment is just distance < radius, a Brep can be an extremely complex, concave shape with holes.

To figure out if a point is inside, the engine performs a “Raycast”. It shoots an invisible line from the point out into infinity, and counts how many times the line intersects the Brep's faces. If the count is Odd (1, 3, 5...), the point is Inside. If the count is Even (0, 2, 4...), the point is Outside. This requires the Brep to be perfectly closed (watertight).

Move Point X
0.00
4 min read1 page

JoinBreps(breps, tolerance):

Stitches adjacent surfaces together into a polysurface.
python
1def join_surfaces_into_brep(surfaces: list[Surface], tolerance: float = 0.001) -> Brep:
2 """Stitches multiple separate surfaces into a single topological B-Rep.
3
4 Pairs up and merges coincident boundary edges within a distance tolerance,
5 converting naked edges into shared topological edges.
6 """
7 brep = Brep()
8
9 # 1. Add all surfaces as B-Rep faces
10 for srf in surfaces:
11 brep.AddFace(srf)
12
13 # 2. Iterate over all naked (unjoined) edge pairs to check for geometric coincidence
14 # Topological stitching connects matching pairs of half-edges.
15 naked_edges = [edge for edge in brep.Edges if edge.IsNaked]
16
17 for i in range(len(naked_edges)):
18 edge_a = naked_edges[i]
19 if not edge_a.IsNaked:
20 continue # Already joined in a previous iteration
21
22 for j in range(i + 1, len(naked_edges)):
23 edge_b = naked_edges[j]
24 if not edge_b.IsNaked:
25 continue
26
27 # Check if the 3D curves of the edges are within tolerance
28 if edge_a.IsCoincidentWith(edge_b, tolerance):
29 # Merge edge_b into edge_a topologically
30 # This updates the B-Rep topology: the two trims now share a single Edge
31 brep.StitchEdges(edge_a, edge_b)
32 break
33
34 # 3. Rebuild B-Rep topology and validate manifold connectivity
35 brep.RebuildTopology()
36 return brep

Joining is the foundational operation for building Breps from individual surfaces. If the edges of adjacent surfaces match within the specified tolerance, they are stitched together.

Join Progress
0.00