A shell is an entire connected set of faces and/or wires. If any two faces or wires in the same body touch, they must be connected and are part of the same shell. Faces are connected together along common edges or at common vertices; wires are connected to faces at vertices.
A lump may contain multiple shells. Each shell can contain wires, sheet faces, and faces that bound a solid region. Because a lump represents a single connected set of points, if a single lump has multiple shells, the shells must bound a single, solid region. A lump with multiple shells would have a single peripheral shell and one or more interior voids. The figures below depict a body with one lump and either one or two shells. In the first figure, a solid region is connected to interior (green) and exterior (gold) sheet regions. These nine faces constitute a single shell because all the faces are connected. In the second figure, a solid region has an interior void. Because the two sets of faces bounding this solid region are not connected, there are two shells: one containing the faces that bound the periphery of the solid region (blue) and one containing the faces that bound the void region within the solid (green). The third figure is similar to the second figure, except the interior void has collapsed to a single face. This body also has two shells: one representing the periphery of the solid (blue) and one representing the infinitely thin void in the interior (green). The fourth figure depicts a cellular solid; that is, a solid with interior partitions. All of the faces are connected; therefore, there is only one shell. Faces can also be connected by wires. The fifth figure is very similar to the second figure except the faces bounding the exterior of the solid region are connected to the faces bounding the interior of the solid region by a wire. Because all of the faces and wires are connected, this is a single shell. The sixth figure depicts two solid regions connected by a wire. Again, because all of the faces and wires are connected, this is a single shell. If the wire were not present in this last case, the body would consist of two lumps, each containing one shell.
The shell concept allows a lump to have multiple disconnected boundaries, which supports a lump having interior voids. Thus, a shell is analogous to a loop, which allows a face to have multiple disconnected boundaries, which supports a face having interior holes.
Types of Shells
The most common type of shell bounds a solid region. It typically consists of complete, finite, single-sided faces. (Single-sided faces have material on only one side of them. They separate what is inside the solid region from what is outside the solid region.) When faces meet along an edge, their insides and outsides must be consistent. Such a shell is said to be complete. A complete shell is one which enables a point in space to be unambiguously classified with respect to the object; that is, if it is inside, outside or on the boundary of the object. Each of the shells depicted in the first six figures are complete shells. The solid depicted in the figure below contains one complete shell that separates the inside from the outside of the solid.
Peripheral and Void Shell
A complete shell divides the whole of space into one finite region and one infinite one. If the finite region is inside the bounding faces, the shell is a peripheral shell; otherwise the shell represents a finite void in an object and is a void shell. Each of the models depicted in the first six figures contains one peripheral shell. The models depicted in the second and third figures also contain a void shell. The model in the figure below contains a void; however, there is only one shell, which is a peripheral shell.
Open Shell or Incomplete Shell
A free edge is an edge that is used once to bound a face. A face is counted twice if it passes right through the edge, appearing on both sides of the edge; it is counted once if the edge lies on the boundary of the face, so that the face is on only one side of the edge. If a shell contains a free edge, then the shell is open. If all the faces are double-sided and all exterior or all interior, then the shell is a double-sided sheet. (A double-sided face has either material or void on both sides of the face.) If a free edge lies on a single-sided face, or if a face is not completely bounded by its edges, then points in space cannot be classified unambiguously as inside or outside the shell and the shell is described as incompletely-bounded, or incomplete. The shell depicted in the figure below has incompletely-bounded faces; therefore, it is incomplete.
Bodies containing incomplete shells may only participate in modeling operations in regions where their shells are well-defined. Even then, some configurations give rise to ambiguous results and, therefore, are disallowed.
If more than two faces meet along an edge, the edge is said to be non-manifold. Normally, if one collects together every face at a vertex that can be reached from a given face by crossing one or more edges starting or ending at the vertex, the collection contains all of the faces that meet at that vertex. If this is not the case, the vertex is said to be non-manifold. One or more wires may be attached to a vertex that is already on the boundary of one or more faces. This again makes the vertex non-manifold. A shell that contains a non-manifold edge or vertex is itself said to be non-manifold.
For these more complex shells, the test for whether they are complete or incomplete is correspondingly more complex. Points in space close to single-sided faces are inside or outside according to which side of the face they are on. Points close to double-sided faces or wire edges are inside or outside, according to whether the face or wire is interior or exterior. Any other point is classified the same as another already classified point, if they can be joined by a continuous path that does not cross any face. If every point in space can be classified unambiguously in this way, then the shell is complete; otherwise, it is incomplete. Any shell which contains a single-sided face with a free edge is automatically incomplete.
The concept of a shell is implemented in the SHELL class. The SHELL class is derived from the ENTITY class; therefore, SHELLs are part of the persistent model and inherit all of the Model Management capabilities of the ENTITY class. Each instance of a SHELL contains a pointer to its parent LUMP, a pointer to the next SHELL in a singly-linked list of SHELLs owned by its LUMP, a pointer to the first FACE in a singly-linked list of FACEs owned by the SHELL, a pointer to the first WIRE in a singly-linked list of WIREs owned by the SHELL, and a pointer to a hierarchy of child SUBSHELLs. A FACE or WIRE must be contained either in the SHELL itself or in exactly one of its SUBSHELLs.
Some of the most commonly used SHELL methods are listed below.
SHELL::lump() Returns a pointer to the owning LUMP, if there is one. SHELL::owner() Returns a pointer to the owning LUMP, if there is one. SHELL::next() Returns a pointer to the next SHELL of the owning LUMP, if there is one. SHELL::subshell() Returns a pointer to the first SUBSHELL owned directly by this SHELL, if there is one. SHELL::face() Returns a pointer to the first FACE in a complete list of all FACEs owned by this SHELL;
that is, it pretends no SUBSHELLs exist.
SHELL::face_list() Returns a pointer to the first FACE owned directly by this SHELL;
that is, it takes SUBSHELLs into account.
SHELL::wire() Returns a pointer to the first WIRE in a complete list of all WIREs owned by this SHELL;
that is, it pretends no SUBSHELLs exist.
SHELL::wire_list() Returns a pointer to the first WIRE owned directly by this SHELL;
that is, it takes SUBSHELLs into account.
ACIS has multiple API functions to obtain the bounding box of a SHELL. Each has the name api_get_entity_box. The Direct Interface function to obtain the bounding box of a SHELLis get_shell_box(SHELL*, ...). These functions are preferred over SHELL::bound because the bound member function will return a NULL box if it has not been calculated. The global functions will calculate the box if it has not been calculated.