Boundary Representations
Boundary representations (BReps) express solids only via their outer surface characteristics, in the sense that solids are hollow or skin deep with no internal volumetric variation of matter; they are homogenous lumps, where only their boundary shape features are important. This is both a reasonable and practical abstraction for describing physical objects for design, engineering and manufacturing applications.
BReps capture both geometric as well as topological concepts, not unlike those presented in the geometry of meshes section. So the concepts of a face, edge and node are also present here but there are also higher level topological ideas.
Bodies
Bodies are at the top of the BRep hierarchy objects representing solid objects with one exterior shell and zero or more interior shells. Interior shells are used for expressing internal voids or cavities. This allows for solids with no voids such as solid box as well as closed objects with cavities such as a box with a thin wall.
Some software use a slightly different definition for allowing multiply connected domains, that is bodies contains more than one solids which are disconnected. To enable this they introduce the notion of a lump, defined as seen above, such that a body contains one or more lumps.
Rhino does not support bodies so it is not possible to subtract two concentric spheres with different radii and produce a thin wall solid. The best that can be done is to create some connecting geometry between the inner and outer surfaces or group the two spheres.
Shells
A shell is collection of one or more boundary faces that forms a closed and orientable envelope. Shells split space in an exterior and an interior, and vise-versa for shells used for voids. A sphere is a shell with one face, while a cube is shell with six faces. To represent a thin walled object, the outer shell's normals point towards the opposite direction of the interior shell. In both cases the normals point towards the ambient space or against the solid's interior volume.
Rhino's Breps are essentially shells which may not comply with the closure and orientability constraints. This is why they are terms as polysurfaces which may be open or closed. A closed and orientable polysurface is equivalent to a solid body with only the exterior shell defined.
Faces
Faces, in the geometric sense, are just bounded parametric surfaces such as planes and Nurbs surfaces. The boundary may be defined by a parametric domain or a domain curve. Faces require one exterior and zero or more interior loops. Interior loops represent surface holes. For instance a cylinder's cap is plane bounded by a circle while a tube's cap is plane bounded by two circles.
''' Solid Object
'''
solid = Brep.CreateFromBox( BoundingBox(
Point3d( 0.0, 0.0, 0.0 ),
Point3d( 1.0, 1.0, 1.0 ) ) )
''' Enumerating Faces
'''
for index in range( solid.Faces.Count ):
face = solid.Faces[index]
''' Adjacencies
'''
edges = face.AdjacentFaces( )
faces = face.AdjacentFaces( )
''' Boundary
'''
loops = face.Loops
external = face.OuterLoop
''' Geometry
'''
surface = face.UnderlyingSurface( )
Edges
Faces are adjacent with one another via edges which are often domain curves of the supporting surfaces. Edges are not generic curves floating about in space. Instead, it is better to consider them as the result of the intersection between faces, that is the meeting or common interface among faces.
Conceptually, edges have several geometric representations simultaneously: (a) a domain curve for each associated face, and (b) a spatial curve which ought to be the same for all associated faces. For example two intersecting spheres require an edge which is a different domain curve for each sphere and a circle living in ambient space.
''' Solid Object
'''
solid = Brep.CreateFromBox( BoundingBox(
Point3d( 0.0, 0.0, 0.0 ),
Point3d( 1.0, 1.0, 1.0 ) ) )
''' Enumerating Edges
'''
for index in range( solid.Edges.Count ):
edge = solid.Edges[index]
''' Adjacencies
'''
faces = edge.AdjacentFaces( )
''' Boundary
'''
nodes = ( edge.StartVertex,
edge.EndVertex )
''' Geometry
'''
curves = edge.EdgeCurve
Loops
Edges form loops, also known as rings, which bound the faces in the sense of an interior and an exterior. Loops are the 2D analogue of 3D shells, so the notions of closure and orientability are important. Otherwise it is not possible to determine what is filled and what is empty. Loops must not overlap one another, such as intersections between the exterior-interior or the interior-interior. Theoretically, they may have shared points, even though this often leads to problems.
''' Solid Object
'''
solid = Brep.CreateFromBox( BoundingBox(
Point3d( 0.0, 0.0, 0.0 ),
Point3d( 1.0, 1.0, 1.0 ) ) )
''' Enumerating Loops
'''
for index in range( solid.Loops.Count ):
loop = solid.Loops[index]
''' Typology
'''
closure = loop.LoopType
Nodes
Nodes express the boundaries where edges meet. The can be considered as domain parameters of each adjacent face, domain parameters of each adjacent edge and a 3D point simultaneously.
''' Solid Object
'''
solid = Brep.CreateFromBox( BoundingBox(
Point3d( 0.0, 0.0, 0.0 ),
Point3d( 1.0, 1.0, 1.0 ) ) )
''' Enumerating Nodes
'''
for index in range( solid.Vertices.Count ):
node = solid.Vertices[index]
''' Adjacencies
'''
edges = node.EdgeIndices( )
''' Geometry
'''
point = node.Location
Operations
Some typical operations using BReps are presented below. Generally, it is not advisable to edit BReps directly because their dual topology and geometry representation is often fragile. Instead they can be manipulated via Boolean operations. Some common operations nevertheless are presented below.
''' Explode to Trimmed Surfaces
'''
solid = Brep.CreateFromBox( BoundingBox(
Point3d( 0.0, 0.0, 0.0 ),
Point3d( 1.0, 1.0, 1.0 ) ) )
breps = [solid.Faces[index].DuplicateFace( True )
for index in range( solid.Faces.Count )]
''' Explode tp Untrimmed Surfaces
'''
surfaces = [solid.Faces[index].UnderlyingSurface( )
for index in range( solid.Faces.Count )]
''' Brep from Surfaces
'''
a = Brep.CreateFromCornerPoints(
Point3d( 0.0, 0.0, 0.0 ),
Point3d( 1.0, 0.0, 0.0 ),
Point3d( 0.0, 1.0, 0.0 ), 1e-5 )
b = Brep.CreateFromCornerPoints(
Point3d( 0.0, 0.0, 0.0 ),
Point3d( 1.0, 0.0, 0.0 ),
Point3d( 0.0, 0.0, 1.0 ), 1e-5 )
c = Brep.CreateFromCornerPoints(
Point3d( 0.0, 0.0, 0.0 ),
Point3d( 0.0, 1.0, 0.0 ),
Point3d( 0.0, 0.0, 1.0 ), 1e-5 )
d = Brep.CreateFromCornerPoints(
Point3d( 1.0, 0.0, 0.0 ),
Point3d( 0.0, 1.0, 0.0 ),
Point3d( 0.0, 0.0, 1.0 ), 1e-5 )
brep = Brep.MergeBreps( [a, b, c, d], 1e-5 )
''' Splitting with Surface
'''
plane = Brep.CreateFromCornerPoints(
Point3d( 0.0, 0.0, 0.5 ),
Point3d( 1.0, 0.0, 0.5 ),
Point3d( 1.0, 1.0, 0.5 ),
Point3d( 0.0, 1.0, 0.5 ), 1e-5 )
parts = solid.Split( plane, 1e-5 )
''' Surface to Brep
'''
surface = NurbsSurface.CreateExtrusion(
PolylineCurve( [ Point3d( 0.0, 0.0, 0.0 ),
Point3d( 1.0, 0.0, 0.0 ),
Point3d( 1.0, 1.0, 0.0 ),
Point3d( 0.0, 1.0, 0.0 ),
Point3d( 0.0, 0.0, 0.0 )] ),
Vector3d( 1.0, 1.0, 1.0 ) )
extrusion = Brep.CreateFromSurface( surface )
''' Closing Planar Holes
'''
solid = extrusion.CapPlanarHoles( 1e-5 )