volmdlr_tools.shapes package#
Shape recognition and abstraction classes for CAD models.
Subpackages#
- volmdlr_tools.shapes.recognizers package
- Submodules
- volmdlr_tools.shapes.recognizers.sheet_metal module
SheetMetalRecognizerSheetMetalRecognizer.main_face_group_1SheetMetalRecognizer.main_face_group_2SheetMetalRecognizer.main_facesSheetMetalRecognizer.opposite_face_idSheetMetalRecognizer.perform()SheetMetalRecognizer.resultSheetMetalRecognizer.seed_face_idSheetMetalRecognizer.sheet_metalSheetMetalRecognizer.thickness_faces
- volmdlr_tools.shapes.recognizers.swept_shape module
- Module contents
SheetMetalRecognizerSheetMetalRecognizer.main_face_group_1SheetMetalRecognizer.main_face_group_2SheetMetalRecognizer.main_facesSheetMetalRecognizer.opposite_face_idSheetMetalRecognizer.perform()SheetMetalRecognizer.resultSheetMetalRecognizer.seed_face_idSheetMetalRecognizer.sheet_metalSheetMetalRecognizer.thickness_faces
SweptShapeRecognizer
- volmdlr_tools.shapes.utils package
Submodules#
volmdlr_tools.shapes.base module#
Base classes for shape recognition and abstractions.
This module defines the base classes that all recognized shapes should inherit from, establishing a common interface for shape classification and feature extraction.
- class volmdlr_tools.shapes.base.RecognizedShape(shape: Shape, aag: AttributedAdjacencyGraph, name: str = '')#
Bases:
DessiaObject,ABCBase class for all recognized shape abstractions.
A RecognizedShape represents a classified geometric shape that knows how to extract its own features based on its Attributed Adjacency Graph (AAG).
This class establishes the interface that all shape abstractions should follow: - Hold reference to the original volmdlr shape - Hold reference to the AAG for topological analysis - Implement validation logic - Implement feature extraction logic
- abstractmethod extract_features() dict#
Extract all relevant features for this shape type.
This method should return a dictionary containing all the key features and parameters that characterize this shape type.
- Returns:
Dictionary of features (structure depends on shape type)
- get_aag() AttributedAdjacencyGraph#
Get the AttributedAdjacencyGraph.
- Returns:
The AAG used for topological analysis
- get_shape() Shape#
Get the underlying volmdlr shape.
- Returns:
The original volmdlr shape
- abstractmethod validate() bool#
Validate that this shape matches expected structure.
This method should check that the classified shape has the correct topological structure for its type (e.g., sheet metal has two sides separated by thickness faces).
- Returns:
True if valid, False otherwise
volmdlr_tools.shapes.sheet_metal module#
Sheet metal shape abstraction.
This module defines the SheetMetalShape class, which represents a classified sheet metal part and knows how to extract sheet-metal-specific features like thickness, sides, and contours.
- class volmdlr_tools.shapes.sheet_metal.FanShapedFace(face_id: int, inner_circular_edge: Any, inner_circular_edge_index: int, outer_circular_edge: Any, outer_circular_edge_index: int, thickness_edges: list[Any], arc_center: Any, normal: Any, angle: float)#
Bases:
objectRepresents a fan-shaped thickness face.
A fan-shaped face is planar and has: - Two concentric circular edges (inner and outer radius) - Two straight thickness edges connecting them
- can_pair_with(other: FanShapedFace, aag: AttributedAdjacencyGraph) bool#
Check if this fan-shaped face can be paired with another.
According to Yang Yang et al., for faces fi and fj to be partners: 1. Face normals must be in opposite directions 2. Line connecting arc centers must be parallel to normals 3. Larger circular edges should be geometrically identical 4. Smaller circular edges should be geometrically identical
- Parameters:
other – Another fan-shaped face to check pairing with
aag – The AttributedAdjacencyGraph for accessing face data
- Returns:
True if faces can be paired
- opposite_normal(other: FanShapedFace) bool#
Verify that two faces have the same but opposite normal vector.
- Parameters:
other – other FanShapedFace.
- Returns:
True if normals are opposite, False otherwise.
Verify that two faces have the same common face.
- Parameters:
other – other FanShapedFace.
aag – AttributedAdjacencyGraph containing corresponding faces.
- Returns:
True if common face was found, False otherwise.
- class volmdlr_tools.shapes.sheet_metal.SheetMetalShape(shape: Shape, aag: AttributedAdjacencyGraph, main_face_group_1: list[int], main_face_group_2: list[int], thickness_faces: list[int], thickness_components: list[set[int]] | list[ThicknessFaceChain], seed_face_id: int, opposite_face_id: int, name: str = '')#
Bases:
RecognizedShapeSheet metal shape abstraction.
Represents a classified sheet metal part and knows how to extract sheet-metal-specific features like thickness, sides, and contours.
This class is the result of SheetMetalRecognizer.recognize() and contains all the information needed to query features and parameters of the sheet metal.
- property boundary_chain: ThicknessFaceChain#
Get the boundary thickness face chain object.
Returns the ThicknessFaceChain classified as boundary based on range values.
- Returns:
Boundary ThicknessFaceChain or None if not found.
- extract_features() dict#
Extract all sheet metal features at once.
- Returns:
Dictionary containing all extracted features
- get_boundary_thickness_shell() Shell | None#
Get boundary thickness facecc chain as a single Shell.
Creates a shell from all boundary thickness faces (outer boundary faces). Uses the cached boundary_thickness_face_chain property.
- Returns:
Shell containing all boundary thickness faces, or None if creation fails
- get_internal_thickness_shells() list[Shell]#
Get internal thickness faces as a list of Shells.
Creates a shell for each connected component of internal thickness faces (faces around holes, cutouts, and other internal features). Uses the cached internal_thickness_faces property.
- Returns:
List of shells, one for each internal thickness component
- get_side_1_aag() AttributedAdjacencyGraph | None#
Create AAG for side 1 from its shell.
- Returns:
AttributedAdjacencyGraph for side 1, or None if creation fails
- get_side_1_areas() dict[int, float]#
Get areas for all faces in side 1.
- Returns:
Dictionary mapping face IDs to their areas
- get_side_1_contours() dict#
Get contours for side 1.
Uses cached contours if available, otherwise computes and caches them.
- Returns:
Dictionary containing outer and inner contours
- get_side_1_shell() Shell | None#
Get side 1 as a Shell.
- Returns:
Shell containing all faces from side 1, or None if creation fails
- get_side_1_total_area() float#
Get total area of side 1.
Sums the areas of all faces in side 1.
- Returns:
Total area of side 1
- Return type:
float
- get_side_2_aag() AttributedAdjacencyGraph | None#
Create AAG for side 2 from its shell.
- Returns:
AttributedAdjacencyGraph for side 2, or None if creation fails
- get_side_2_areas() dict[int, float]#
Get areas for all faces in side 2.
- Returns:
Dictionary mapping face IDs to their areas
- get_side_2_contours() dict#
Get contours for side 2.
Uses cached contours if available, otherwise computes and caches them.
- Returns:
Dictionary containing outer and inner contours
- get_side_2_shell() Shell | None#
Get side 2 as a Shell.
- Returns:
Shell containing all faces from side 2, or None if creation fails
- get_side_2_total_area() float#
Get total area of side 2.
Sums the areas of all faces in side 2.
- Returns:
Total area of side 2
- Return type:
float
- get_thickness() float | None#
Calculate sheet metal thickness.
The rigorous method identifies boundary thickness faces (those connected to the outer contour) and measures the length of edges shared between them, which represents the actual sheet metal thickness. Falls back to seed-opposite distance if needed.
- Returns:
Thickness value or None if calculation fails
- get_thickness_aag() AttributedAdjacencyGraph | None#
Create AAG for thickness faces.
- Returns:
AttributedAdjacencyGraph for thickness faces, or None if creation fails
- get_thickness_faces_areas() dict[int, float]#
Get areas for all thickness faces.
- Returns:
Dictionary mapping face IDs to their areas
- get_thickness_faces_compound() Compound | None#
Get thickness faces as a Compound of shells.
Creates a compound containing the boundary thickness shell and all internal thickness shells.
- Returns:
Compound of shells, or None if creation fails
- property internal_chains: list[ThicknessFaceChain]#
Get all internal thickness face chain objects.
Returns list of ThicknessFaceChain objects classified as internal based on range values.
- Returns:
List of internal ThicknessFaceChain objects
- property main_faces: list[int]#
Get all main face IDs from both sides.
Combines face IDs from main_face_group_1 and main_face_group_2.
- Returns:
List of all main face IDs
- Return type:
list[int]
- validate() bool#
Validate sheet metal structure.
Checks that removing thickness faces creates exactly two connected components (the two main sides).
- Returns:
True if valid sheet metal structure, False otherwise
- static validate_sheet_metal_structure(aag: AttributedAdjacencyGraph, thickness_faces: list[int], main_faces: list[int]) bool#
Validate sheet metal structure (static validation logic).
Checks that removing thickness faces creates exactly two connected components (the two main sides).
- Parameters:
aag – The attributed adjacency graph
thickness_faces – List of thickness face IDs
main_faces – List of main face IDs
- Returns:
True if valid sheet metal structure, False otherwise
- class volmdlr_tools.shapes.sheet_metal.TFCGroup(thickness_face_chains: list[ThicknessFaceChain], name: str = '')#
Bases:
DessiaObjectGroup of ThicknessFaceChain objects for feature analysis.
A TFCGroup represents a collection of ThicknessFaceChain objects that are grouped together for feature recognition and property extraction. This class provides methods to aggregate fan-shaped faces, count parallel planar pairs, and extract properties for matching against feature classification rules (cut features, composite features, etc.).
- extract_composite_feature_properties() dict[str, Any]#
Extract properties for matching against composite feature rules.
Properties correspond to Table 2 from Yang Yang et al. (2021): - internal_chains: Number of internal thickness face chains - boundary_subchains: Number of boundary sub-chains - fan_shaped_faces: Number of fan-shaped faces - fan_shaped_pairs: Number of fan-shaped face pairs - share_common_face: Do fan-shaped pairs share a common face? - opposite_normals: Are normals in opposite directions? - d1_greater_d2: Is flat part width > deformed part width?
- Returns:
Dictionary of properties
- Return type:
dict[str, Any]
- extract_cut_feature_properties() dict[str, Any]#
Extract properties for matching against cut feature rules.
Properties correspond to Table 1 from Yang Yang et al. (2021): - type_of_chain: “Closed” or “Open” - total_faces: Total number of faces in chain - cylindrical_surfaces: Count of cylindrical faces - different_radius_values: Number of distinct radii in cylindrical faces - planar_surfaces: Count of planar faces - parallel_planar_pairs: Number of parallel planar face pairs
- Returns:
Dictionary of properties
- Return type:
dict
- get_fan_shaped_faces() list[FanShapedFace]#
Get all fan-shaped faces from all thickness face chains in the group.
Aggregates fan-shaped faces from each ThicknessFaceChain in the group.
- Returns:
List of all FanShapedFace objects from all chains
- Return type:
list[FanShapedFace]
- get_fan_shaped_pairs() list[tuple[FanShapedFace, FanShapedFace]]#
Get all fan-shaped face pairs from the group.
If the group contains only one ThicknessFaceChain, returns pairs from that chain. Otherwise, aggregates all fan-shaped faces from all chains and pairs them according to the pairing criteria (opposite normals, common face, etc.).
- Returns:
List of tuples containing paired FanShapedFace objects
- Return type:
list[tuple[FanShapedFace, FanShapedFace]]
- property parallel_count: tuple[int, set[float]]#
Get the count of parallel planar pairs and their distances.
Returns a tuple containing: - The number of parallel planar face pairs - A set of distances between parallel pairs
- Returns:
Tuple of (pair_count, distances_set)
- Return type:
tuple[int, set[float]]
- class volmdlr_tools.shapes.sheet_metal.ThicknessFaceChain(face_ids: list[int], aag: AttributedAdjacencyGraph, is_closed: bool | None = True, is_internal_chain: bool | None = False, is_fsf_neighbor: bool | None = False, name: str | None = None)#
Bases:
DessiaObjectBase class representing a chain of thickness faces.
A thickness face chain is a group of connected thickness faces. According to Yang Yang et al. (2021), thickness face chains are the fundamental building blocks for sheet metal feature recognition.
- property adjacency_map: dict[int, list[int]]#
Get adjacency relationships between faces in the chain.
- Returns:
Dictionary mapping face_id -> list of adjacent face_ids in chain
- all_angles_concave() bool#
Check if all angles between consecutive faces are concave.
- Returns:
True if all angles are concave
- Return type:
bool
- all_angles_convex() bool#
Check if all angles between consecutive faces are convex.
- Returns:
True if all angles are convex
- Return type:
bool
- property angles: dict#
Extract angle data between consecutive faces.
- Returns:
Dictionary mapping (face_id1, face_id2) -> angle data
- Return type:
dict
- binary_pattern_contains(pattern: list[int]) bool#
Check if binary pattern contains the given pattern as a subsequence.
- Parameters:
pattern (list[int]) – Pattern to find (e.g., [0, 1])
- Returns:
True if pattern is found
- Return type:
bool
- static extract_deform_feature_properties(termination_criterion: int, inner_loop_shape: str) dict#
Extract properties for matching against deform feature rules.
Properties correspond to Table 3 from Yang Yang et al. (2021): - has_interconnected_faces: Are faces interconnected? - termination_criterion: Which criterion terminated extraction (1 or 2) - inner_loop_shape: Shape of the inner loop (e.g., “Circular”, “Rectangular”)
- Parameters:
termination_criterion (int) – Termination criterion used (1 or 2)
inner_loop_shape (str) – Shape of the inner loop
- Returns:
Dictionary of properties
- Return type:
dict
- extract_fsf_subchains() list[ThicknessFaceChain]#
Extract feature sub-chains from binary representation of fan-shaped faces.
According to Yang Yang et al. (Section 3.2.1), the binary matrix encodes fan-shaped face pairs where: - 0 = starting face of a pair - 1 = partner face of that pair
- Returns:
List of sub-chains, where each sub-chain contains all face IDs (including non-fan-shaped faces) between the start and end
- Return type:
list[list[int]]
- property fan_shaped_faces_paths: dict[tuple[int, int], tuple[list[int], list[int]]]#
Get the fan-shaped faces paths dictionary.
Returns a copy of the paths dictionary to prevent external modification.
- Returns:
Dictionary mapping face ID tuples to path tuples (shortest_path, longest_path)
- Return type:
dict[tuple[int, int], tuple[list[int], list[int]]]
- property fsf_binary_representation: list[list[int]]#
Generate binary representation matrices for fan shaped faces.
According to Yang Yang et al., the algorithm: 1. For each fan-shaped pair, find faces between them in both directions 2. Keep the shorter list for each pair 3. Select the longest of these shorter lists (ensures not starting in middle) 4. Create second list from remaining faces by traversing in opposite direction 5. Assign binary values: 0 for starting face, 1 for partner face
The binary patterns are used to classify bend/jog/lance features. Example patterns from paper (Fig. 6): - Matrix 1: [0 0 0 1 1 1 1] (contains pairs 1, 2, 3, 4) - Matrix 2: [0 0 1 1 0 1] (contains remaining pairs)
- Returns:
List of binary matrices (typically 2, one for each direction)
- get_concave_subchains() list[ThicknessFaceChain]#
Extract sub-chains with concave angles using the concavity method.
According to Yang Yang et al. (Section 3.2.2), concave angles indicate features like slots, notches, and corner reliefs. This method identifies consecutive faces connected by concave angles.
- Returns:
List of ThicknessFaceChain sub-chains with concave angles
- Return type:
list[ThicknessFaceChain]
- get_convex_subchains() list[list[int]]#
Extract clip sub-chains using the convexity method.
- Example from paper:
fi – fj – fk Where fj is a clip if both angles (fi-fj and fj-fk) are convex and within the range (π/2, π).
- Returns:
List of clip sub-chains, where each sub-chain contains a single face ID
- Return type:
list[list[int]]
- get_fan_shaped_faces() list[FanShapedFace]#
Identify all fan-shaped faces in the chain.
According to Yang Yang et al., a fan-shaped thickness face: - Must be planar - Must have two concentric circular edges - Must have two thickness edges - Solid angles between edges must be < 180°
- Returns:
List of FanShapedFace objects
- get_fan_shaped_faces_path(key: tuple[int, int]) tuple[list[int], list[int]]#
Get the fan-shaped faces path for a given key.
- Parameters:
key (tuple[int, int]) – Tuple of (start_face_id, end_face_id) identifying the path
- Returns:
Tuple containing (shortest_path, longest_path) as lists of face IDs
- Return type:
tuple[list]
- Raises:
KeyError – If no path exists for the given key
- get_fan_shaped_pairs(max_angle: float = 3.141592653589793) list[tuple[FanShapedFace, FanShapedFace]]#
Identify pairs of fan-shaped faces.
According to Yang Yang et al., fan-shaped faces form pairs that represent bend features. The pairing algorithm checks: 1. Normals in opposite directions 2. Arc centers connected by line parallel to normals 3. Circular edges are geometrically identical
- Returns:
List of (face1, face2) pairs
- get_main_fan_shaped_pair_lists() tuple[list[int], list[int]]#
Get the two main lists of fan-shaped faces for binary representation.
According to Yang Yang et al.: 1. For each pair, find the shorter path between them 2. Select the longest of these shorter paths (ensures not starting in middle) 3. Create second list from remaining faces in opposite direction
- Returns:
Tuple of (first_list, second_list) of face IDs
- get_range_values() tuple[float, float, float]#
Calculate range values for the chain.
Returns (X_range, Y_range, Z_range) where: X_range = X_max - X_min for all faces in chain
Used to classify boundary vs internal chains.
- Returns:
Tuple of (x_range, y_range, z_range)
- has_binary_pattern(pattern: list[int]) bool#
Check if binary pattern matches exactly.
- Parameters:
pattern (list[int]) – Pattern to match (e.g., [0, 1] for bend)
- Returns:
True if pattern matches
- Return type:
bool
- is_open_ended() bool#
Check if chain is open (not closed).
- Returns:
True if open
- Return type:
bool
- is_single_face() bool#
Check if chain contains only a single face.
- Returns:
True if only one face
- Return type:
bool
- is_small(max_faces: int = 3) bool#
Check if chain is small (few faces).
- Parameters:
max_faces (int) – Maximum number of faces to be considered small
- Returns:
True if face count <= max_faces
- Return type:
bool
- set_fan_shaped_faces(faces: list[FanShapedFace]) None#
Set the fan-shaped faces for this chain.
- Parameters:
faces (list[FanShapedFace]) – List of FanShapedFace objects
- Returns:
None
- Return type:
None
- set_fan_shaped_faces_path(key: tuple[int, int], value: tuple[list[int], list[int]]) None#
Set the fan-shaped faces path for a given key.
- Parameters:
key (tuple[int, int]) – Tuple of (start_face_id, end_face_id) identifying the path
value (tuple[list[int], list[int]]) – Tuple containing (shortest_path, longest_path) as lists of face IDs
- Returns:
None
- Return type:
None
- set_fan_shaped_pairs(face_pairs: list[tuple[FanShapedFace, FanShapedFace]]) None#
Set the fan-shaped face pairs for this chain.
- Parameters:
face_pairs (list[tuple[FanShapedFace, FanShapedFace]]) – List of tuples containing paired FanShapedFace objects
- Returns:
None
- Return type:
None
- property thickness: float | None#
Get thickness value for validating fan-shaped faces.
Calculates thickness by finding the length of common edges between neighboring faces in the chain. Returns the first non-zero edge length found.
- Returns:
Thickness value or None if calculation fails
- Return type:
Optional[float]
- property thickness_shell: Shell#
Get the thickness shell for this chain.
Creates a Shell object from all faces in the chain. Caches the result for subsequent calls.
- Returns:
Shell containing all faces in the chain
- Return type:
shapes.Shell
- verify_fan_shaped_pair_order(face1: FanShapedFace, face2: FanShapedFace) tuple[FanShapedFace, FanShapedFace]#
Verify and correct the order of fan-shaped face pairs.
Computes paths between the two faces and ensures they are ordered correctly based on their position in the chain. Stores the paths for later use.
- Parameters:
face1 (FanShapedFace) – First fan-shaped face
face2 (FanShapedFace) – Second fan-shaped face
- Returns:
Tuple of (ordered_face1, ordered_face2)
- Return type:
tuple[FanShapedFace, FanShapedFace]
- volmdlr_tools.shapes.sheet_metal.are_faces_parallel(face1: Face, face2: Face, tolerance: float = 1e-06) bool#
Check if two faces are parallel.
Two faces are considered parallel if the vector connecting their centers is parallel to the normal of the first face (i.e., the dot product is approximately ±1).
- Parameters:
face1 – First face to check
face2 – Second face to check
tolerance – Tolerance for parallel checks
- Returns:
True if faces are parallel, False otherwise
- Return type:
bool
- volmdlr_tools.shapes.sheet_metal.get_face_normal(face: Shape) Vector3D#
Extract normal vector from a planar face.
- Parameters:
face – Face object to extract normal from
- Returns:
Normal vector as tuple (x, y, z) or None if extraction fails
- Return type:
Optional[tuple[float, float, float]]
- volmdlr_tools.shapes.sheet_metal.order_nodes_by_graph(nodes: list[int], subgraph: Graph) list[int]#
Orders a list of nodes according to their connectivity in the graph.
Works for both open paths and closed cycles.
- Parameters:
nodes (list) – List of nodes to order
subgraph (networkx.Graph) – The graph containing the nodes
- Returns:
Ordered list of nodes following the graph structure
- Return type:
list
volmdlr_tools.shapes.bearing module#
Module dedicated to identifying bearings within an assembly.
- class volmdlr_tools.shapes.bearing.Bearing(primitives: list[Shape], graph_assembly_repeating_elements_ids: list[int], graph_assembly_rings_ids: list[int], name: str = '')#
Bases:
CompoundBearing class.
- class volmdlr_tools.shapes.bearing.BearingFinder(graph_assembly: GraphAssembly)#
Bases:
objectClass to identify bearings within an assembly graph.
- find_bearings(number_elements_define_bearing: int = 5) list[list[int]]#
Find all bearings in the assembly.
- Returns:
list[list[str]]: List of bearing groups, where each group contains node IDs
of components that form a bearing.
Module contents#
Shape recognition and abstractions.