Swept Shapes#
Recognize swept profiles (pipes, tubes, extruded channels) from BRep models.
Note
Prerequisites: Attributed Adjacency Graph (AAG)
Swept Shape Recognition#
This module identifies swept shapes (extruded profiles) from BRep models. It recognizes pipes, tubes, and other shapes formed by sweeping a cross-section along a path.
Overview#
A swept shape is characterized by:
Extremity faces: The start and end faces of the sweep
Neutral fiber: The centerline path along which the profile was swept
Section: The cross-sectional profile perpendicular to the sweep path
Smoothness: The neutral fiber has C1 continuity (no sharp corners)
Common examples:
Circular pipes and tubes
Extruded profiles (channels, I-beams)
Cable routing paths
Duct sections
Quick Start#
from volmdlr.model import VolumeModel
from volmdlr_tools.shapes.recognizers import SweptShapeRecognizer
# Load a STEP file
volume_model = VolumeModel.from_step("path/to/pipe.step")
shape = volume_model.primitives[0]
# Recognize swept shape
recognizer = SweptShapeRecognizer(shape=shape)
if recognizer.perform():
# Get sweep properties
neutral_fiber = recognizer.neutral_fiber
section = recognizer.section
radius_info = recognizer.get_radius()
print(f"Neutral fiber length: {neutral_fiber.length()}")
print(f"Outer radius: {radius_info['outer_contour']}")
else:
print("Not a valid swept shape")
Core Class: SweptShapeRecognizer#
The main entry point for swept shape recognition. It analyzes a BRep shape to determine if it’s a swept profile and extracts its geometric properties.
Constructor#
SweptShapeRecognizer(
shape: Union[shapes.Shell, shapes.Solid],
aag: Optional[AttributedAdjacencyGraph] = None,
name: str = ""
)
Parameters:
shape: The BRep shape to analyze (Shell or Solid)aag: (Optional) Pre-computed AttributedAdjacencyGraphname: (Optional) Name for the recognizer instance
Methods#
perform() -> bool#
Execute the recognition algorithm.
recognizer = SweptShapeRecognizer(shape=my_shape)
is_swept = recognizer.perform()
Returns: True if the shape is a valid swept shape, False otherwise.
get_radius() -> dict#
Get the radius information for circular sweeps.
radius_info = recognizer.get_radius()
print(f"Outer radius: {radius_info['outer_contour']}")
print(f"Inner radii: {radius_info['inner_contours']}")
Returns: Dictionary with keys:
outer_contour: Radius of outer contour (orNoneif not circular)inner_contours: List of radii for inner contours (holes)
Properties#
Property |
Type |
Description |
|---|---|---|
|
|
The centerline path of the sweep |
|
|
The cross-sectional profile |
|
|
The input BRep shape |
|
|
The face adjacency graph |
Recognition Algorithm#
The recognition process:
Find extremity candidates: Identify planar or BSpline faces that could be sweep endpoints
Faces with only convex neighbors
At most 1-2 smooth angles depending on neighbor count
Validate extremities: Group candidates into two coplanar groups (start and end faces)
Find shortest path: Compute the graph path between extremity faces
Uses the AAG to find the path through adjacent faces
Path represents the sweep body faces
Validate path: Verify the path represents a valid sweep
All intermediate faces should be smooth-connected
Path should be continuous
Extract properties: Compute neutral fiber and section from validated path
Examples#
Basic Pipe Recognition#
from volmdlr.model import VolumeModel
from volmdlr_tools.shapes.recognizers import SweptShapeRecognizer
# Load pipe model
volume_model = VolumeModel.from_step("pipe.step")
pipe_shape = volume_model.primitives[0]
# Recognize
recognizer = SweptShapeRecognizer(shape=pipe_shape)
if recognizer.perform():
# Get neutral fiber (centerline)
centerline = recognizer.neutral_fiber
print(f"Pipe length: {centerline.length():.2f} mm")
# Get cross-section
section = recognizer.section
print(f"Section area: {section.area():.2f} mm²")
# Get radius for circular pipes
radii = recognizer.get_radius()
if radii['outer_contour']:
outer_r = radii['outer_contour']
inner_r = radii['inner_contours'][0] if radii['inner_contours'] else 0
wall_thickness = outer_r - inner_r
print(f"Wall thickness: {wall_thickness:.2f} mm")
Visualizing Results#
from volmdlr.model import VolumeModel
# After recognition
neutral_fiber = recognizer.neutral_fiber
section = recognizer.section
# Create visualization primitives
prims = [pipe_shape]
if neutral_fiber:
# Display neutral fiber as colored wire
neutral_fiber.color = (1.0, 0.0, 0.0) # Red
prims.append(neutral_fiber)
if section:
# Display section face
section.color = (0.0, 1.0, 0.0) # Green
prims.append(section)
VolumeModel(prims).babylonjs()
Working with Non-Circular Sections#
# For non-circular extruded profiles
recognizer = SweptShapeRecognizer(shape=channel_shape)
if recognizer.perform():
section = recognizer.section
# Get section contour
outer_contour = section.surface2d.outer_contour
# Analyze contour geometry
print(f"Contour perimeter: {outer_contour.length()}")
print(f"Number of edges: {len(outer_contour.primitives)}")
# Check for holes
inner_contours = section.surface2d.inner_contours
print(f"Number of holes: {len(inner_contours)}")
Use Cases#
Pipe Routing Analysis#
def analyze_pipe_routing(shapes):
"""Analyze a collection of pipes for routing information."""
pipe_data = []
for shape in shapes:
recognizer = SweptShapeRecognizer(shape=shape)
if recognizer.perform():
fiber = recognizer.neutral_fiber
radii = recognizer.get_radius()
pipe_data.append({
'length': fiber.length(),
'outer_radius': radii['outer_contour'],
'start_point': fiber.primitives[0].start,
'end_point': fiber.primitives[-1].end,
})
return pipe_data
Cable Tray Identification#
def is_cable_tray(shape):
"""Check if a shape is a cable tray (open channel profile)."""
recognizer = SweptShapeRecognizer(shape=shape)
if not recognizer.perform():
return False
section = recognizer.section
if section is None:
return False
# Cable trays typically have U-shaped open profiles
# Check if section has no inner contours (not a closed tube)
inner_contours = section.surface2d.inner_contours
return len(inner_contours) == 0
Limitations#
Works best with smooth sweeps (C1 continuous neutral fiber)
Extremity faces must be planar or BSpline surfaces
Complex multi-branch sweeps are not supported
Very short sweeps (fewer than 3 faces) may have limited property extraction
See Also#
AAG (Attributed Adjacency Graph) - Understanding the graph representation
Sheet Metal Recognition - Recognition for sheet metal parts
Shape Signatures - Shape comparison using signatures
See Also#
Attributed Adjacency Graph (AAG) - Attributed Adjacency Graph
Sheet Metal Shapes - Sheet metal recognition
Shape Signatures - Shape signatures for comparison