| sidebar_position | 1 | |||||
|---|---|---|---|---|---|---|
| title | Shells | |||||
| sidebar_label | Intro Shells | |||||
| description | Learn how to create shells | |||||
| tags |
|
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import BitByBitRenderCanvas from '@site/src/components/BitByBitRenderCanvas';
Shells are fundamental geometric constructs in OCCT that represent connected collections of faces. Think of a shell as the "skin" of a 3D object - it defines the boundary between the interior and exterior of a shape but doesn't necessarily enclose a volume. Shells are particularly useful for creating complex surfaces, modeling thin-walled objects, or as intermediate steps toward creating solid geometries.
A shell is essentially a collection of faces that are sewn together along their common edges. Unlike individual faces that exist independently, shells maintain topological connections between faces, creating a unified surface structure. This connectivity is crucial for many geometric operations and enables OCCT to understand the relationship between adjacent surfaces.
Shells can be either open (like a curved sheet of paper) or closed (like a complete sphere surface). Closed shells that properly enclose a volume can be converted into solid geometries, making them valuable intermediate representations in 3D modeling workflows.
The process of creating shells involves "sewing" faces together by identifying and connecting their common edges. OCCT's sewing algorithm automatically detects edges that are geometrically coincident within a specified tolerance and merges them into shared boundaries. This process ensures topological consistency and creates the connected face structure that defines a shell.
:::important Face Order and Direction When creating shells, the first face in the collection often dictates how other face normals and orientations behave during the sewing process. OCCT uses the orientation of the first face as a reference to determine the consistent orientation for the entire shell. This is particularly important when creating closed shells that will be converted to solids, as inconsistent face orientations can prevent successful solid creation. :::
This first example demonstrates the fundamental concept of shell creation by sewing two square faces together. We create two identical square faces, position one of them to share an edge with the first, and then sew them together to form a simple shell.
sizeface1face2rotatedFace2translatedFace2facesshellsize5face1size000010face2size000010rotatedFace2face200190translatedFace2rotatedFace2DIVIDEsize2DIVIDEsize20facesface1translatedFace2shellfaces0.0000001shell","version":"0.20.7","type":"blockly"}} title="Creating shells by sewing two square faces" /> {\n // Define the size for both square faces\n const size = 5;\n\n // Create first square face at origin\n const face1Options = new SquareDto();\n face1Options.size = size;\n face1Options.center = [0, 0, 0] as Point3;\n face1Options.direction = [0, 1, 0] as Vector3; // Y-up orientation\n\n const face1 = await face.createSquareFace(face1Options);\n\n // Create second square face (initially identical to first)\n const face2Options = new SquareDto();\n face2Options.size = size;\n face2Options.center = [0, 0, 0] as Point3;\n face2Options.direction = [0, 1, 0] as Vector3;\n\n const face2 = await face.createSquareFace(face2Options);\n\n // Rotate the second face 90 degrees around Z-axis to create perpendicular orientation\n const rotateOptions = new RotateDto();\n rotateOptions.shape = face2;\n rotateOptions.axis = [0, 0, 1] as Vector3; // Z-axis\n rotateOptions.angle = 90; // 90 degrees\n\n const rotatedFace2 = await transforms.rotate(rotateOptions);\n\n // Translate the rotated face to share an edge with the first face\n const translateOptions = new TranslateDto();\n translateOptions.shape = rotatedFace2;\n translateOptions.translation = [size / 2, size / 2, 0] as Vector3;\n\n const translatedFace2 = await transforms.translate(translateOptions);\n\n // Create array of faces to sew together\n const faces = [face1, translatedFace2];\n\n // Sew the faces together to create a shell\n const sewOptions = new SewDto(faces);\n sewOptions.tolerance = 1e-7; // Very tight tolerance for precise sewing\n\n const resultShell = await shell.sewFaces(sewOptions);\n\n // Verify that we created a shell (not just individual faces)\n const shapeType = await shape.getShapeType({ shape: resultShell });\n console.log('Shell shape type:', shapeType); // Should output \"shell\"\n\n // Draw the resulting shell\n bitbybit.draw.drawAnyAsync({\n entity: resultShell\n });\n}\n\n// Execute the function\nstart();","version":"0.20.7","type":"typescript"}} title="Creating shells by sewing two square faces" />The workflow demonstrates several key concepts:
- Face Creation: Two identical square faces are created with the same dimensions and orientation.
- Geometric Transformation: The second face is rotated 90 degrees and then translated to position it perpendicular to the first face, sharing a common edge.
- Sewing Process: The
sewFacesoperation identifies the shared edge and creates topological connections between the faces. - Validation: The
getShapeTypefunction confirms that the result is indeed a shell rather than separate faces.
This simple example shows how shells maintain the relationship between connected faces, creating a unified geometric entity that can be used in further operations.
This more sophisticated example demonstrates how to create a complex shell from multiple faces that form a closed surface, which can then be converted into a solid. We'll construct a cylindrical shape by creating circular faces and an extruded cylindrical surface, then sew them together to form a closed shell.
:::note Alternative Construction Methods While this cylindrical solid can be constructed in Bitbybit using the simple solid cylinder command, this example is created for demonstration purposes to show the face-based shell construction process. Understanding face-based construction is valuable for creating complex custom geometries that cannot be easily generated using primitive solid operations. :::
radiusheightcircleWireextrusionVectorcylindricalSurfacebottomFacetopFacefacesshellsolidradius5height5circleWireradius000010extrusionVector0height0cylindricalSurfacecircleWireextrusionVectorbottomFacecircleWireTRUEtopFacebottomFaceextrusionVectorfacestopFacecylindricalSurfacebottomFaceshellfaces1e-7solidshellsolid","version":"0.20.7","type":"blockly"}} title="Creating closed shells and converting to solids" /> {\n // Define geometric parameters\n const radius = 5;\n const height = 5;\n\n // Step 1: Create base circle wire\n const circleOptions = new CircleDto();\n circleOptions.radius = radius;\n circleOptions.center = [0, 0, 0] as Point3;\n circleOptions.direction = [0, 1, 0] as Vector3; // Y-up orientation\n\n const circleWire = await wire.createCircleWire(circleOptions);\n\n // Step 2: Create extrusion vector for cylindrical surface\n const extrusionVector: Vector3 = [0, height, 0];\n\n // Step 3: Create cylindrical surface by extruding the circle wire\n const extrudeOptions = new ExtrudeDto();\n extrudeOptions.shape = circleWire;\n extrudeOptions.direction = extrusionVector;\n\n const cylindricalSurface = await operations.extrude(extrudeOptions);\n\n // Step 4: Create bottom face from the circle wire\n const bottomFaceOptions = new FaceFromWireDto();\n bottomFaceOptions.shape = circleWire;\n bottomFaceOptions.planar = true; // Ensure flat circular face\n\n const bottomFace = await face.createFaceFromWire(bottomFaceOptions);\n\n // Step 5: Create top face by translating bottom face\n const translateOptions = new TranslateDto();\n translateOptions.shape = bottomFace;\n translateOptions.translation = extrusionVector;\n\n const topFace = await transforms.translate(translateOptions);\n\n // Step 6: Collect all faces that will form the closed shell\n const faces = [topFace, cylindricalSurface, bottomFace];\n\n // Step 7: Sew faces together to create a closed shell\n const sewOptions = new SewDto(faces);\n sewOptions.tolerance = 1e-7; // High precision for closed shell\n\n const closedShell = await shell.sewFaces(sewOptions);\n\n // Step 8: Convert closed shell to solid\n const solidOptions = new ShapeDto();\n solidOptions.shape = closedShell;\n\n const cylinderSolid = await solid.fromClosedShell(solidOptions);\n\n // Step 9: Verify the shape types\n const shellType = await shape.getShapeType({ shape: closedShell });\n const solidType = await shape.getShapeType({ shape: cylinderSolid });\n\n console.log('Shell type:', shellType); // Should output \"shell\"\n console.log('Solid type:', solidType); // Should output \"solid\"\n\n // Step 10: Draw the final solid\n bitbybit.draw.drawAnyAsync({\n entity: cylinderSolid\n });\n}\n\n// Execute the function\nstart();","version":"0.20.7","type":"typescript"}} title="Creating closed shells and converting to solids" />This advanced example demonstrates several sophisticated concepts:
-
Base Geometry Creation: We start by creating a circular wire that serves as the foundation for our cylindrical shape.
-
Surface Generation: The circular wire is extruded to create the cylindrical surface that will form the sides of our shape.
-
End Cap Creation: Two circular faces are created - one at the bottom (from the original circle wire) and one at the top (by translating the bottom face upward).
-
Shell Assembly: All three faces (bottom, top, and cylindrical surface) are sewn together using the
sewFacesoperation to create a closed shell. -
Solid Conversion: The closed shell is converted into a solid using
fromClosedShell, which validates that the shell properly encloses a volume.
Topological Validity: By creating shells first and then converting to solids, we ensure that the resulting geometry has proper topological relationships between faces, edges, and vertices.
Error Detection: If the shell is not properly closed or has topological issues, the fromClosedShell operation will fail.
Geometric Flexibility: This approach allows for complex surface creation that might be difficult to achieve with direct solid modeling operations.
Intermediate Inspection: You can examine and validate the shell before converting it to a solid, making debugging easier in complex workflows.
:::tip Performance Advantage Making geometry from faces is usually way faster than performing boolean operations such as union or difference. When designing complex geometries, it pays to think in terms of faces and shell construction rather than relying heavily on boolean operations. This face-based approach not only provides better performance but also gives you more precise control over the final geometry and better error handling for invalid operations. :::
This tutorial demonstrates how shells serve as a crucial intermediate representation in OCCT, bridging the gap between individual faces and complete solid geometries while providing powerful tools for surface-based modeling.