volmdlr_tools.features.extractors package#
Feature extractors for identifying specific features in BRep models.
Submodules#
volmdlr_tools.features.extractors.core module#
Module for the base feature extractor class.
- class volmdlr_tools.features.extractors.core.FeatureExtractor(aag: AttributedAdjacencyGraph, name: str = '')#
Bases:
DessiaObjectBase class for feature extractors.
- is_not_entire_shape(new_feature_faces: list[TopoDS_Shape], new_feature_indices: list[int]) bool#
Validate whether the recognized feature is a subset of the entire CAD model.
This method ensures that the newly identified feature does not encompass the entire model, which would indicate that the feature recognition failed to isolate a distinct feature. The method compares the size of the feature to the total number of faces in the AAG.
- Parameters:
new_feature_faces – A list of faces belonging to the newly recognized feature.
new_feature_indices – A list of indices for the faces in the recognized feature.
- Returns:
Returns True if the recognized feature is smaller than the entire CAD model, indicating successful isolation of a distinct feature.
- perform() bool#
Perform the feature extraction.
- class volmdlr_tools.features.extractors.core.InnerFeaturesExtractor(aag: AttributedAdjacencyGraph, max_number_feature_faces: float = 20, name: str = '')#
Bases:
FeatureExtractorBase class for inner features extractors.
This class provides a base implementation for extracting inner features from a CAD model. Subclasses must implement the is_invalid_base_neighbor and recognize methods.
Inner features are features that are inside a shape’s face, connected to its inner wires.
- Parameters:
aag – The Attributed Adjacency Graph (AAG) representation of the CAD model.
name (str) – The name of the Extractor.
- Returns:
The Extractor.
- Return type:
- extract() list[list[int]]#
Recognize feature faces in BRep model.
The method first identifies seed faces by finding inner wires (loops of edges inside a face). Each seed is checked for convexity/smoothness based on the angle between adjacent faces. If the inner wire is convex or smooth, the method propagates to neighboring faces, ensuring the identified feature doesn’t exceed the maximum allowable number of faces (max_number_feature_faces).
The algorithm proceeds as follows: 1. For each inner wire in a seed face, find adjacent faces through common edges and check whether the adjacency
relationships between each pair of faces are classified as convex.
Propagate through adjacent faces to form a feature, ensuring the feature is valid.
Return the recognized features as collections of faces and their corresponding indices.
Note: This method accumulates all valid feature faces. The post-processing step (e.g., _collect_cavities) should handle grouping by connected components.
- get_features_faces(nodes: list[int]) list[Face]#
Get features faces for a set of nodes.
- is_angle_type_valid(angle_validator: callable, face_index: int, wire: TopoDS_Shape) bool#
Check whether the edges of a wire are of a given type, based on the angles between adjacent faces.
This method iterates over the edges of a given wire (which can represent part of a face) and evaluates the type of the edges based on the angles between the current face and its neighboring faces. If all angles are of the given type, the method returns True, indicating that the wire forms a feature boundary of the given type.
- Parameters:
angle_validator – A function that validates the angle type.
face_index – The index of the face being evaluated for the angle type.
wire – The wire (loop of edges) to check for the angle type.
- Returns:
Returns True if all edges in the wire are of the given type; otherwise, False.
- is_concave_through(face_index: int, wire: TopoDS_Shape) bool#
Check whether the edges of a wire are concave, based on the angles between adjacent faces.
This method iterates over the edges of a given wire (which can represent part of a face) and evaluates the concavity of the edges based on the angles between the current face and its neighboring faces. If all angles are concave, the method returns True, indicating that the wire forms a concave feature boundary.
- Parameters:
face_index – The index of the face being evaluated for concavity.
wire – The wire (loop of edges) to check for concavity.
- Returns:
Returns True if all edges in the wire are concave; otherwise, False.
- is_convex_through(face_index: int, wire: TopoDS_Shape) bool#
Check whether the edges of a wire are convex, based on the angles between adjacent faces.
This method iterates over the edges of a given wire (which can represent part of a face) and evaluates the convexity of the edges based on the angles between the current face and its neighboring faces. If all angles are convex, the method returns True, indicating that the wire forms a convex feature boundary.
- Parameters:
face_index – The index of the face being evaluated for convexity.
wire – The wire (loop of edges) to check for convexity.
- Returns:
Returns True if all edges in the wire are convex; otherwise, False.
- is_feature_valid(new_feature_faces: list[TopoDS_Shape], new_feature_indices: list[int], seed_face_id: int) bool#
Check if the feature is valid.
- is_invalid_base_neighbor(start_id: int, neighbor_id: int) bool#
Check if the base neighbor is invalid.
- propagate(start_id: int, seed_neighbors_ids: list[int], feature_faces: list[TopoDS_Shape], feature_indices: list[int], is_ok: bool = True) bool#
Propagates through the AAG starting from a seed face, identifying adjacent faces that form a feature.
This method is a recursive traversal that collects neighboring faces into a feature. For each seed face, the method checks whether its adjacent faces meet the necessary geometric conditions (e.g., sharing common edges on the outer wire and having convexity in the adjacent angles).
The propagation continues until no more valid adjacent faces can be added to the feature, or the maximum allowable number of faces is reached.
- Parameters:
start_id – The index of the starting face for the propagation.
seed_neighbors_ids – List of neighboring face indices to be evaluated.
feature_faces – A list to collect faces that are part of the recognized feature.
feature_indices – A list to collect indices of faces that form the feature.
is_ok – (optional) A flag indicating whether the feature remains valid throughout propagation (default is True).
- Returns:
Returns True if the propagation is successful and the feature remains valid.
volmdlr_tools.features.extractors.blend module#
A module for recognition of fillets in a BRep model.
- class volmdlr_tools.features.extractors.blend.BlendExtractor(aag: AttributedAdjacencyGraph, max_radius: float | None = None)#
Bases:
FeatureExtractorExtract blend/fillet features from AAG.
A class for recognizing and analyzing blends in a geometric model using an adjacency attribute graph (AAG). Supports recognition of edge-based and vertex-based blends.
- calculate_chain_length(feature: list[int]) float#
Compute the total length of a blend chain based on the blend candidate attributes of each face.
The total length is the sum of the lengths of each blend face in the chain, as stored in their blend candidate attributes.
- Parameters:
feature – A list of face IDs representing the blend chain.
- Returns:
The computed total length of the blend chain.
- compute_blend_length(edges_indices: list[int]) float#
Compute the total length of the blend chain.
- Parameters:
edges_indices – A list of edges indexes from the blend chain.
- Returns:
The sum of the lengths of all edges in edges_indices list.
- display_result() dict#
Implementation of a tag for displays.
- dye_blending_faces(color: tuple = (0, 1, 1)) None#
Change the colors of blending faces.
- Parameters:
color – Derired color
- find_cross_edges(face_id: int, smooth_edges_ids: list[int], spring_edges_ids: list[int], candidate_radius: float) tuple#
Identify and return cross edges on a given face, based on curvature evaluation and a specified candidate radius.
Cross edges are those that satisfy certain curvature conditions compared to the provided radius and are not in the excluded categories (smooth or spring edges).
The method evaluates curvature at the midpoint of each remaining edge, which is smooth but is not a spring edge.
The edge is classified as a cross edge if its curvature-derived radius matches the candidate radius within a tolerance threshold — it curves around the blend.
The edge is classified as a junction instead if the blend does not curve along it at all. The blend runs along such an edge rather than across it, continuing into whatever lies beyond, so the edge marks no end of the blend.
- Parameters:
face_id – The index or ID of the face for which to find cross edges.
smooth_edges_ids – A list of edge IDs that represent “smooth” edges to be excluded.
spring_edges_ids – A list of edge IDs that represent “spring” edges to be excluded.
candidate_radius – The target radius value used to compare the curvature of the edges.
- Returns:
cross_edges: A list of edge objects that qualify as cross edges based on the curvature evaluation.
cross_edges_ids: A list of IDs corresponding to the cross edges.
junction_edges_ids: A list of IDs of the edges the blend runs along.
- Raises:
Issues a warning if the curvature cannot be evaluated along the edge.
- find_smooth_edges() tuple[list[TopoDS_Shape], list[int]]#
Find all smooth edges across all faces in the adjacency attribute graph (AAG).
- Returns:
A tuple containing the list of all smooth edges and their corresponding indices.
- find_smooth_edges_for_face(face_id: int) tuple[list[TopoDS_Shape], list[int]]#
Find smooth edges for a given face based on adjacent faces in the graph.
- Parameters:
face_id – The ID of the face to analyze.
- Returns:
A tuple containing the list of smooth edges and their corresponding indices.
- find_spring_edges(face_id: int, smooth_edge_ids: TColStd_PackedMapOfInteger) tuple[list[TopoDS_Shape], list[int], bool, float, list[float]]#
Find the spring edges for a given face, considering the smooth edge indices.
- Parameters:
face_id – The ID of the face to analyze.
smooth_edge_ids – The indices of the smooth edges.
- Returns:
A tuple containing the spring edges, their indices, whether it’s a candidate blend, the candidate radius, and the per-spring-edge candidate radii.
- find_terminating_edges(face_id: int, smooth_edges_ids: list[int], spring_edges_ids: list[int], cross_edges_ids: list[int]) tuple[list[TopoDS_Shape], list[int], list[TopoDS_Shape], list[int]]#
Identify terminating and seam edges of a given face.
A terminating edge is one that does not belong to any of the provided exclusion lists AND crosses to a real neighbour face — i.e. bounds the blend against another face. A wire edge with no external neighbour through this face is a seam of the underlying periodic surface (a torus fillet’s meridian, for example): topologically it is an internal artifact of the parameter domain, not a boundary against another face, so it goes into the seam set instead of the terminating one — leaving a full-round fillet with the clean
2 spring / 0 cross / 0 termsignature its Euler condition expects, while still exposing the seam through the AAG for consumers that need to detect a closed / loop blend (e.g. profile extraction and the full-round Euler condition).- Parameters:
face_id – The index or ID of the face for which to find terminating edges.
smooth_edges_ids – A list of edge IDs that represent “smooth” edges to be excluded.
spring_edges_ids – A list of edge IDs that represent “spring” edges to be excluded.
cross_edges_ids – A list of edge IDs that represent “cross” edges to be excluded.
- Returns:
(terminating_edges, terminating_edges_ids, seam_edges, seam_edges_ids).
- get_blending_chains_faces() list[list[Face]]#
Return a list containing all identified faces grouped by connectivity and radius.
- get_blending_faces() list[Face]#
Return a list containing all identified faces.
- get_chains(r_dev_perc: float = 5.0) list[BlendChain]#
Identify and return chains of blend faces.
Chains are grouped by their fillet radii and cross-edge length. The method first extracts connected components from the adjacency graph based on recognized blend candidates. It then distributes faces into groups based on their fillet radii and evaluates connected components within each group. Afterward, it normalizes these chains by removing any dangling vertex blends.
- Parameters:
r_dev_perc – The allowed percentage deviation when comparing fillet radii. This value controls the tolerance for how close radii need to be considered part of the same chain. A typical default value is 5.0%.
- Returns:
A list of BlendChain objects, each containing faces, properties, and spring edges.
- property ids: list[int]#
Return the ids of blend faces.
- Returns:
Ids of blend faces.
- perform() None#
Execute the blend recognition process over all faces in the adjacency attribute graph (AAG).
- property shape: Shape#
Return the shape.
- terminating_edges_to_cross_edges() None#
Convert terminating edges to cross edges if the terminating edges connect blend candidate faces.
- class volmdlr_tools.features.extractors.blend.RecognizeBlends(aag: AttributedAdjacencyGraph, max_radius: float = 0.5)#
Bases:
BlendExtractorDeprecated: Use BlendExtractor instead.
This class is maintained for backward compatibility and will be removed in version 1.0.0. Please update your code to use BlendExtractor.
volmdlr_tools.features.extractors.cavity module#
Module for recognizing geometric features, specifically cavities and pockets, in a B-Rep CAD model.
This module operates on a CAD model’s Attributed Adjacency Graph (AAG), an extension of B-Rep that encodes adjacency information and feature semantics. The main class, CavityExtractor, provides methods to traverse the AAG and recognize features like cavities and pockets, leveraging graph algorithms and geometric queries.
- class volmdlr_tools.features.extractors.cavity.CavityExtractor(aag: AttributedAdjacencyGraph, max_number_feature_faces: int = 100, name: str = '')#
Bases:
InnerFeaturesExtractorExtract cavity and pocket features from AAG.
A class for recognizing cavities and pockets in a CAD model using an Attributed Adjacency Graph (AAG). The AAG is traversed to find “seed” faces that are part of these features. From the seeds, the algorithm propagates to identify connected faces that share specific geometric characteristics such as convexity of edges and angles.
- Parameters:
aag (AttributedAdjacencyGraph) – The Attributed Adjacency Graph (AAG) representation of the CAD model
max_number_feature_faces (int) – Maximum allowable number of faces in a recognized feature (used to filter overly large features), defaults to 20
- display_result() dict#
Implementation of a tag for displays.
- find_seeds() list[int]#
Find potential seed faces in the CAD model that can be used to start the feature recognition process.
This method scans the faces in the Attributed Adjacency Graph (AAG) to locate candidate seed faces. For a cavity, a seed face is typically a face with inner wires, where the neighboring faces, adjacent to this seed face through the inner wires, have a convex relationship with respect to the seed face.
- Returns:
A list of face indices that are valid seed candidates for further feature recognition.
- get_cavities() list[Cavity]#
Return a list containing all identified cavities with their base faces.
- property ids_pockets: list[list[int]]#
Return the ids of blend faces.
- Returns:
Ids of blend faces.
- is_angle_valid(seed_id: int, neighbor_id: int) bool#
Check if the angle is valid.
- is_feature_valid(new_feature_faces: list[TopoDS_Shape], new_feature_indices: list[int], seed_face_neighbors: list[int]) bool#
Check if the feature is valid.
- is_invalid_base_neighbor(start_id: int, neighbor_id: int) bool#
Check if the base neighbor is invalid.
- is_seed_valid(face_index: int, wire: TopoDS_Shape) bool#
Check if the seed node is valid.
- perform() bool#
Perform the cavity feature extraction.
- recognize_cavities() None#
Recognize cavity features in the CAD model by analyzing the Attributed Adjacency Graph (AAG).
(Under construction)
- property shape: Shape#
Return the shape.
- class volmdlr_tools.features.extractors.cavity.RecognizeCavities(aag: AttributedAdjacencyGraph)#
Bases:
CavityExtractorDeprecated: Use CavityExtractor instead.
This class is maintained for backward compatibility and will be removed in version 1.0.0. Please update your code to use CavityExtractor.
volmdlr_tools.features.extractors.sharp_edge module#
A module for sharp edges identification.
- class volmdlr_tools.features.extractors.sharp_edge.SharpEdgeExtractor(aag: AttributedAdjacencyGraph, name: str = '')#
Bases:
FeatureExtractorExtract sharp edge features from AAG.
A class for recognizing and analyzing sharp edges in a geometric model using an adjacency attribute graph. Sharp edges are identified by analyzing convex angles between adjacent faces along linear edges.
- display_result() dict#
Implementation of a tag for displays.
- get_edges_shapes() list[Edge]#
Return a list containing all identified edges shapes.
- property ids: list[int]#
Return the ids of sharp edges.
- Returns:
Ids of sharp edges.
- perform() None#
Perform sharp edge identification and cache the result.
- property shape: Shape#
Return the shape.
- class volmdlr_tools.features.extractors.sharp_edge.SharpEdgeRecognizer(aag: AttributedAdjacencyGraph, name: str = '')#
Bases:
SharpEdgeExtractorDeprecated: Use SharpEdgeExtractor instead.
This class is maintained for backward compatibility and will be removed in version 1.0.0. Please update your code to use SharpEdgeExtractor.
volmdlr_tools.features.extractors.deformation module#
volmdlr_tools.features.extractors.sheet_metal module#
Sheet-metal feature extractors.
- class volmdlr_tools.features.extractors.sheet_metal.DeformationExtractor(sheet_metal: SheetMetalShape, name: str = '')#
Bases:
FeatureExtractorExtractor for recognizing deformation features in a B-Rep CAD model.
- static get_entire_set_center_of_mass(deformation_set: list[int], aag_side: AttributedAdjacencyGraph) ndarray#
Compute the center of mass for an entire deformation set by averaging face centers.
- Parameters:
deformation_set – List of node indices in the deformation set.
aag_side – The AAG representation of one side.
- Returns:
The averaged center of mass as a numpy array.
- perform() bool#
Perform deformation recognition by matching deformations from both sides of the sheet metal.
- Returns:
True if found any deformation matches. False otherwise.
- class volmdlr_tools.features.extractors.sheet_metal.RegionDeformationExtractor(sheet_metal: SheetMetalShape, name: str = '')#
Bases:
DeformationExtractorDeformation extractor driving the region-based helper on both sides.
Reuses the wire-based extractor’s pairing plumbing (mutual-nearest matching, gravity centers, feature construction) over region-based candidates.
- MAX_PAIR_FACE_RATIO = 3.0#
- perform() bool#
Run region-based extraction on both sides, pair the pooled results, classify per pair.
Emboss-like and cutout-like regions are pooled per side before pairing: the free-boundary class is a per-side observation that the two sides can disagree on (a region may fade into a cutout rim on one side only), and pairing within a class would then silently drop the deformation. The class is decided from the matched pair instead: FlangedCutout only when both sides touch a free boundary, Emboss otherwise.
- Returns:
True if any deformation pair was found, False otherwise.
- class volmdlr_tools.features.extractors.sheet_metal.SheetMetalFeatureClassifier(aag: AttributedAdjacencyGraph)#
Bases:
objectClassifier for sheet metal features using thickness face chains.
This class implements the classification logic from Yang Yang et al. (2021), using the Characteristics Matrix approach with rule-based pattern matching.
Classification uses three rule tables: - CUT_RULES: For cut features (Slot, Notch, CornerRelief) - COMPOSITE_RULES: For bend/composite features (Bend, Jog, Lance, Clip) - DEFORM_RULES: For deform features (Emboss)
- classify(tfc_group: TFCGroup) Feature#
Classify a thickness face chain group into a specific feature type.
Uses the Characteristics Matrix approach from Yang Yang et al. (2021): 1. Extract properties from the TFC group 2. Match against rules in order of priority 3. Return first matching feature type or UnknownFeature
- class volmdlr_tools.features.extractors.sheet_metal.SheetMetalFeatureExtractor(sheet_metal: SheetMetalShape, name: str = '')#
Bases:
FeatureExtractorExtractor for sheet metal features using Yang Yang et al. (2021) algorithm.
This extractor orchestrates the feature extraction process: 1. Extracts sub-chains from ThicknessFaceChains 2. Delegates classification to SheetMetalFeatureClassifier
Responsibilities: - Extraction: Get sub-chains using three methods (binary, concavity, convexity) - Orchestration: Use classifier for feature identification
The classifier handles all pattern matching and feature creation logic.
- CURL_ANGLE_THRESHOLD = 1.5707963267948966#
- MIN_FACES_FOR_MIRRORING = 5#
- NUM_FACES_CURL = 3#
- NUM_FACES_HEM = 5#
- extract_all_bendings(chain: ThicknessFaceChain) list[Bend]#
Extract all bend features from a thickness face chain.
Identifies fan-shaped faces and pairs, creating Bend features for each. Bends with angle > 90° are labeled as “Curl”.
- Parameters:
chain (ThicknessFaceChain) – The thickness face chain to extract bends from
- Returns:
List of Bend features
- Return type:
list[Bend]
- extract_boundary_features() list#
Extract and classify features from boundary thickness face chains.
- Returns:
List of classified boundary features
- Return type:
list[Feature]
- extract_internal_features() list#
Extract and classify features from internal thickness face chains.
- Returns:
List of classified internal features
- Return type:
list[Feature]
- static get_connected_concave_subchains(fan_shaped_faces_subchains: list[ThicknessFaceChain], concave_subchains: list[ThicknessFaceChain], main_chain: ThicknessFaceChain) list[TFCGroup]#
Group fan-shaped face subchains with their connected concave subchains.
For each fan-shaped face subchain, finds adjacent concave subchains of equal length and groups them together. Unpaired subchains are returned as single-element groups.
- Parameters:
fan_shaped_faces_subchains (list[ThicknessFaceChain]) – Subchains containing fan-shaped faces
concave_subchains (list[ThicknessFaceChain]) – All concave subchains from the main chain
main_chain (ThicknessFaceChain) – The parent thickness face chain
- Returns:
List of TFCGroup objects
- Return type:
list[TFCGroup]
- get_external_subchains_groups() list[TFCGroup]#
Extract and group subchains from the boundary thickness face chain.
Combines fan-shaped face subchains with connected concave subchains, and adds convex/concave subchains as individual groups.
- Returns:
List of TFCGroup objects representing boundary feature candidates
- Return type:
list[TFCGroup]
- get_internal_subchains_groups() list[TFCGroup]#
Extract and group subchains from internal thickness face chains.
- Returns:
List of TFCGroup objects representing internal feature candidates
- Return type:
list[TFCGroup]
- get_mirror_internal_subchains(internal_chains: list[ThicknessFaceChain]) list[TFCGroup]#
Group internal thickness face chains into mirror pairs or individual groups.
Chains with < 5 faces are always treated as individual groups. Chains with >= 5 faces are paired if their neighbors intersect (indicating mirror relationship). Unpaired chains are added as individual groups.
- Parameters:
internal_chains – List of internal thickness face chains
- Returns:
List of chain groups (pairs or singles)
- property internal_features: list[Feature]#
Get the internal features extracted from the sheet metal.
- perform() bool#
Perform feature extraction using Yang Yang algorithm.
Extracts sub-chains from boundary and internal thickness face chains and classifies features using the classifier.
- Returns:
True if any features were found
- Return type:
bool
volmdlr_tools.features.extractors.feature_classifier module#
volmdlr_tools.features.extractors.ribs module#
Rib feature extractor.
Recognizes rib features (thin protruding walls) in a BRep model, following the recognition half (§4.2) of Lai et al. (2017), Recognition and decomposition of rib features in thin-shell plastic parts for finite element analysis.
The extractor works directly against the existing
AttributedAdjacencyGraph (AAG): the paper’s
bespoke “Edge AAG” / “Face AAG” databases map onto the AAG’s edge angle
classification (convex/concave/smooth) and node attributes (surface type,
plane normal, wires).
Recognition is built up incrementally (see the rib-extractor plan):
Implemented: end-face-pair detection (Rules 2, 4, 5, 6), shell/base collection (union of both ends, so faces touching only one end are kept), fillet (blend) pass-over, and rib-structure (junction) grouping of connected segments.
A rib (a protrusion) is told apart from a depression (slot/pocket) of the same thickness by two checks: the material-side test (material lies between the two end faces, not void) and the directly-opposing test (the faces face each other).
Pending: Rule 3 (inner-loop convexity), and ribs whose shell is fully split with no spanning face (the paper’s virtual-face / different-height cases).
- class volmdlr_tools.features.extractors.ribs.RibExtractor(aag: AttributedAdjacencyGraph, max_thickness: float | None = None, blend_max_radius: float | None = None, pair_finder: Literal['edge_driven', 'face_pair', 'nearly_planar'] = 'edge_driven', name: str = '')#
Bases:
FeatureExtractorRecognize rib features on a BRep model from its AAG.
A rib is a thin protruding wall: two opposing end faces a thin gap apart, standing on the surrounding part walls and capped by a shell. By default the end-face pairs are found edge-driven (Lai et al. §4.2.1) — see
perform()for the pipeline and__init__for thepair_finderselector.All constructor parameters are documented on
__init__.- property applied_max_thickness: float#
The wall-thickness threshold recognition actually used.
Equal to
max_thickness(or its scale-aware default) unless the default was tightened to the part’s measured wall population — see_tighten_max_thickness(). Report this, notmax_thickness.
- perform() bool#
Recognize ribs and store them in
self._result.End-face pairs come from the finder the constructor flags select — by default
_find_end_face_pairs_edge_driven(), which derives each wall’s two sides from matched parallel boundary edges of a host face and admits nearly-planar sides, not only true planes.For each pair, collect the shell faces that join the two ends through convex edges and the base faces that meet them through concave edges. Pairs that are fragments of the same physical wall (coplanar sides split by the modeller) are then merged into one candidate before each candidate is materialized into a
Rib. A pair with no connecting shell face is not a rib and is dropped.- Returns:
True once recognition has run (idempotent).
- property rib_structures: list[RibStructure]#
Return rib structures: groups of >=2 segments connected at junctions.
volmdlr_tools.features.extractors.rib_edge_pairs module#
Edge-driven rib pair finding (Lai et al. 2017, §4.2.1-4.2.2).
The paper derives a rib’s two end faces from a host face crossed by the wall: parallel boundary edges of the host are matched at minimum distance, and the faces adjacent across the matched edges are the wall’s two sides. This module holds the pure geometry (no extractor state): boundary-edge extraction, parallel grouping, and minimum-distance matching. Deriving end faces and applying the rib rules stays in RibExtractor.
Deriving pairs this way collapses the candidate space from every anti-parallel
face pair on the part to those bound by an actual host face, and puts material
between the two sides by construction rather than by a ray test. Benchmarked on
the A-Pillar reference part at equal recognition quality and appreciably faster
than the face-pair search, which is why pair_finder="edge_driven" is the
RibExtractor default; the
face-pair finders remain available via the other pair_finder names. See the
CHANGELOG for the measured figures behind that comparison.
- class volmdlr_tools.features.extractors.rib_edge_pairs.BoundaryEdge(start: Point3D, end: Point3D, neighbor_node: int, direction: Vector3D, length: float)#
Bases:
objectOne boundary edge of a host face, with the face adjacent across it.
Positions describe the edge’s chord, not its curve: a subdivided curved edge is represented as several BoundaryEdge instances, one per sub-chord.
- direction: Vector3D#
Unit vector along the chord, from
starttoend.
- end: Point3D#
Chord end point.
- length: float#
Chord length (straight-line, so a lower bound on the arc length).
- neighbor_node: int#
AAG node index of the face on the other side of this edge.
- start: Point3D#
Chord start point.
- volmdlr_tools.features.extractors.rib_edge_pairs.boundary_edges(aag: AttributedAdjacencyGraph, node: int, subdivide: bool = False) list[BoundaryEdge]#
Return the face’s boundary edges as chords, each with its adjacent face.
The adjacent face comes from the AAG’s cached edge adjacency (
get_edge_index+get_common_edge_indices) — the AAG is the owner of edge->face knowledge, and the lookup is O(1) per edge instead of a TopoDS identity scan over every neighbor’s edges. Edges with a degenerate chord (closed or seam edges) or with no identified neighbor (free boundaries, edges unknown to the AAG) are dropped: they cannot span a rib wall.With
subdivide=Trueopen curved edges are split into local chord segments (_edge_sample_points()) so matching compares local directions instead of end-to-end chords — what recovers walls whose crossing edges twist together. Subdivision is offered as a separate pass rather than the default because segment matching is not a superset of whole-chord matching: mutual-nearest is winner-take-all per edge, and short arc segments parallel to a straight edge can steal its single best slot from the true wall partner (measured on eft_sensor_mount: 4 walls lost). The caller unions the pairs of both passes instead.
- volmdlr_tools.features.extractors.rib_edge_pairs.match_parallel_edges(edges: list[BoundaryEdge], max_distance: float) list[tuple[BoundaryEdge, BoundaryEdge, float]]#
Match each boundary edge with its NEAREST parallel, overlapping partner.
Nearest-partner matching is what makes the pairing safe: a wall’s two crossing edges are closer to each other than to any other parallel edge on the host face, so a pair spanning two walls plus the gap between them never forms (the paper’s minimum-distance rule). Pairs are returned once (symmetric duplicates removed) and only when their separation is within
max_distanceand their spans overlap.
Module contents#
Feature extractors.
- class volmdlr_tools.features.extractors.BlendExtractor(aag: AttributedAdjacencyGraph, max_radius: float | None = None)#
Bases:
FeatureExtractorExtract blend/fillet features from AAG.
A class for recognizing and analyzing blends in a geometric model using an adjacency attribute graph (AAG). Supports recognition of edge-based and vertex-based blends.
- calculate_chain_length(feature: list[int]) float#
Compute the total length of a blend chain based on the blend candidate attributes of each face.
The total length is the sum of the lengths of each blend face in the chain, as stored in their blend candidate attributes.
- Parameters:
feature – A list of face IDs representing the blend chain.
- Returns:
The computed total length of the blend chain.
- compute_blend_length(edges_indices: list[int]) float#
Compute the total length of the blend chain.
- Parameters:
edges_indices – A list of edges indexes from the blend chain.
- Returns:
The sum of the lengths of all edges in edges_indices list.
- display_result() dict#
Implementation of a tag for displays.
- dye_blending_faces(color: tuple = (0, 1, 1)) None#
Change the colors of blending faces.
- Parameters:
color – Derired color
- find_cross_edges(face_id: int, smooth_edges_ids: list[int], spring_edges_ids: list[int], candidate_radius: float) tuple#
Identify and return cross edges on a given face, based on curvature evaluation and a specified candidate radius.
Cross edges are those that satisfy certain curvature conditions compared to the provided radius and are not in the excluded categories (smooth or spring edges).
The method evaluates curvature at the midpoint of each remaining edge, which is smooth but is not a spring edge.
The edge is classified as a cross edge if its curvature-derived radius matches the candidate radius within a tolerance threshold — it curves around the blend.
The edge is classified as a junction instead if the blend does not curve along it at all. The blend runs along such an edge rather than across it, continuing into whatever lies beyond, so the edge marks no end of the blend.
- Parameters:
face_id – The index or ID of the face for which to find cross edges.
smooth_edges_ids – A list of edge IDs that represent “smooth” edges to be excluded.
spring_edges_ids – A list of edge IDs that represent “spring” edges to be excluded.
candidate_radius – The target radius value used to compare the curvature of the edges.
- Returns:
cross_edges: A list of edge objects that qualify as cross edges based on the curvature evaluation.
cross_edges_ids: A list of IDs corresponding to the cross edges.
junction_edges_ids: A list of IDs of the edges the blend runs along.
- Raises:
Issues a warning if the curvature cannot be evaluated along the edge.
- find_smooth_edges() tuple[list[TopoDS_Shape], list[int]]#
Find all smooth edges across all faces in the adjacency attribute graph (AAG).
- Returns:
A tuple containing the list of all smooth edges and their corresponding indices.
- find_smooth_edges_for_face(face_id: int) tuple[list[TopoDS_Shape], list[int]]#
Find smooth edges for a given face based on adjacent faces in the graph.
- Parameters:
face_id – The ID of the face to analyze.
- Returns:
A tuple containing the list of smooth edges and their corresponding indices.
- find_spring_edges(face_id: int, smooth_edge_ids: TColStd_PackedMapOfInteger) tuple[list[TopoDS_Shape], list[int], bool, float, list[float]]#
Find the spring edges for a given face, considering the smooth edge indices.
- Parameters:
face_id – The ID of the face to analyze.
smooth_edge_ids – The indices of the smooth edges.
- Returns:
A tuple containing the spring edges, their indices, whether it’s a candidate blend, the candidate radius, and the per-spring-edge candidate radii.
- find_terminating_edges(face_id: int, smooth_edges_ids: list[int], spring_edges_ids: list[int], cross_edges_ids: list[int]) tuple[list[TopoDS_Shape], list[int], list[TopoDS_Shape], list[int]]#
Identify terminating and seam edges of a given face.
A terminating edge is one that does not belong to any of the provided exclusion lists AND crosses to a real neighbour face — i.e. bounds the blend against another face. A wire edge with no external neighbour through this face is a seam of the underlying periodic surface (a torus fillet’s meridian, for example): topologically it is an internal artifact of the parameter domain, not a boundary against another face, so it goes into the seam set instead of the terminating one — leaving a full-round fillet with the clean
2 spring / 0 cross / 0 termsignature its Euler condition expects, while still exposing the seam through the AAG for consumers that need to detect a closed / loop blend (e.g. profile extraction and the full-round Euler condition).- Parameters:
face_id – The index or ID of the face for which to find terminating edges.
smooth_edges_ids – A list of edge IDs that represent “smooth” edges to be excluded.
spring_edges_ids – A list of edge IDs that represent “spring” edges to be excluded.
cross_edges_ids – A list of edge IDs that represent “cross” edges to be excluded.
- Returns:
(terminating_edges, terminating_edges_ids, seam_edges, seam_edges_ids).
- get_blending_chains_faces() list[list[Face]]#
Return a list containing all identified faces grouped by connectivity and radius.
- get_blending_faces() list[Face]#
Return a list containing all identified faces.
- get_chains(r_dev_perc: float = 5.0) list[BlendChain]#
Identify and return chains of blend faces.
Chains are grouped by their fillet radii and cross-edge length. The method first extracts connected components from the adjacency graph based on recognized blend candidates. It then distributes faces into groups based on their fillet radii and evaluates connected components within each group. Afterward, it normalizes these chains by removing any dangling vertex blends.
- Parameters:
r_dev_perc – The allowed percentage deviation when comparing fillet radii. This value controls the tolerance for how close radii need to be considered part of the same chain. A typical default value is 5.0%.
- Returns:
A list of BlendChain objects, each containing faces, properties, and spring edges.
- property ids: list[int]#
Return the ids of blend faces.
- Returns:
Ids of blend faces.
- perform() None#
Execute the blend recognition process over all faces in the adjacency attribute graph (AAG).
- property shape: Shape#
Return the shape.
- terminating_edges_to_cross_edges() None#
Convert terminating edges to cross edges if the terminating edges connect blend candidate faces.
- class volmdlr_tools.features.extractors.CavityExtractor(aag: AttributedAdjacencyGraph, max_number_feature_faces: int = 100, name: str = '')#
Bases:
InnerFeaturesExtractorExtract cavity and pocket features from AAG.
A class for recognizing cavities and pockets in a CAD model using an Attributed Adjacency Graph (AAG). The AAG is traversed to find “seed” faces that are part of these features. From the seeds, the algorithm propagates to identify connected faces that share specific geometric characteristics such as convexity of edges and angles.
- Parameters:
aag (AttributedAdjacencyGraph) – The Attributed Adjacency Graph (AAG) representation of the CAD model
max_number_feature_faces (int) – Maximum allowable number of faces in a recognized feature (used to filter overly large features), defaults to 20
- display_result() dict#
Implementation of a tag for displays.
- find_seeds() list[int]#
Find potential seed faces in the CAD model that can be used to start the feature recognition process.
This method scans the faces in the Attributed Adjacency Graph (AAG) to locate candidate seed faces. For a cavity, a seed face is typically a face with inner wires, where the neighboring faces, adjacent to this seed face through the inner wires, have a convex relationship with respect to the seed face.
- Returns:
A list of face indices that are valid seed candidates for further feature recognition.
- get_cavities() list[Cavity]#
Return a list containing all identified cavities with their base faces.
- property ids_pockets: list[list[int]]#
Return the ids of blend faces.
- Returns:
Ids of blend faces.
- is_angle_valid(seed_id: int, neighbor_id: int) bool#
Check if the angle is valid.
- is_feature_valid(new_feature_faces: list[TopoDS_Shape], new_feature_indices: list[int], seed_face_neighbors: list[int]) bool#
Check if the feature is valid.
- is_invalid_base_neighbor(start_id: int, neighbor_id: int) bool#
Check if the base neighbor is invalid.
- is_seed_valid(face_index: int, wire: TopoDS_Shape) bool#
Check if the seed node is valid.
- perform() bool#
Perform the cavity feature extraction.
- recognize_cavities() None#
Recognize cavity features in the CAD model by analyzing the Attributed Adjacency Graph (AAG).
(Under construction)
- property shape: Shape#
Return the shape.
- class volmdlr_tools.features.extractors.ChamferExtractor(aag: AttributedAdjacencyGraph, convex_only: bool = True, max_offset_ratio: float = 0.5, min_angle_degrees: float = 5.0, name: str = '')#
Bases:
FeatureExtractorExtract chamfer features from an Attributed Adjacency Graph.
A chamfer is a flat angled face (planar or conical) that replaces a sharp edge between two “under” faces. The extractor identifies candidate faces, filters them, builds chains of adjacent chamfers, resolves conflicts when a face is both a chamfer and an under-face, and produces Chamfer and ChamferChain feature objects.
- Parameters:
aag – The Attributed Adjacency Graph to analyze.
convex_only – If True, only detect convex chamfers. Default True.
max_offset_ratio – Maximum ratio of chamfer offset to model diagonal. Default 0.5.
min_angle_degrees – Minimum angle between under-faces in degrees. Default 5.0.
name – Optional name.
- get_chains() list[ChamferChain]#
Return ChamferChain feature objects.
- Returns:
List of ChamferChain instances.
- get_chamfers() list[Chamfer]#
Return Chamfer feature objects for all confirmed chamfer faces.
- Returns:
List of Chamfer instances.
- property ids: list[int]#
Return the face IDs of confirmed chamfer faces.
- perform() None#
Execute the full chamfer recognition pipeline.
- property shape: Shape#
Return the shape being analyzed.
- class volmdlr_tools.features.extractors.CoaxialFeatureExtractorMixin#
Bases:
ABCMixin providing common infrastructure for extracting coaxial features.
This mixin encapsulates the seed-based extraction pattern used by: - ConeExtractor (cones - internal countersinks or external tapers) - TorusExtractor (tori - internal fillets or external rounds)
Supports both EXTERNAL and INTERNAL extraction modes: - EXTERNAL: Extract features with outward-pointing normals (bosses, shafts).
Propagates through CONVEX/SMOOTH edges.
- INTERNAL: Extract features with inward-pointing normals (bores, fillets).
Propagates through CONCAVE/SMOOTH edges.
Subclasses must implement abstract methods for surface-specific logic: - Surface type detection - Property extraction - Property matching for neighbor validation - Mode-aware surface validation
Attributes expected on the class using this mixin: - aag: AttributedAdjacencyGraph - linear_tolerance: float - angular_tolerance: float
- abstract property extraction_mode: ExtractionMode#
Return the extraction mode (INTERNAL or EXTERNAL).
- Returns:
ExtractionMode enum value.
- abstract property surface_type_name: str#
Return the OCP surface type string.
- Returns:
Surface type string (e.g., ‘ConicalSurface’, ‘ToroidalSurface’).
- class volmdlr_tools.features.extractors.ConeExtractor(aag: AttributedAdjacencyGraph, max_semi_angle: float = 1.5707963267948966, linear_tolerance: float = 0.0001, angular_tolerance: float = 0.0175, extraction_mode: ExtractionMode = ExtractionMode.EXTERNAL, name: str = '')#
Bases:
CoaxialFeatureExtractorMixin,FeatureExtractorExtract conical features from an Attributed Adjacency Graph (AAG).
This class recognizes cones by identifying conical faces and propagating to collect all coaxial conical neighbors with the same semi-angle through appropriate edges.
Supports both extraction modes: - EXTERNAL (default): Extract tapered bosses, chamfers (surface normal points away from axis).
Propagates through CONVEX/SMOOTH edges.
- INTERNAL: Extract countersinks, bore chamfers (surface normal points toward axis).
Propagates through CONCAVE/SMOOTH edges.
Key differences from CylinderExtractor: - Surface type: ConicalSurface - Property matching: Same semi-angle (NOT radius - cones taper!)
- Parameters:
aag – The Attributed Adjacency Graph (AAG) representation of the CAD model.
max_semi_angle – Maximum semi-angle in radians (default: 90 degrees).
linear_tolerance – Tolerance for position comparisons.
angular_tolerance – Tolerance for angle comparisons (radians).
extraction_mode – Whether to extract EXTERNAL or INTERNAL cones.
name – Name for the extractor instance.
- property extraction_mode: ExtractionMode#
Return the extraction mode (INTERNAL or EXTERNAL).
- get_cones() list[Cone]#
Create Cone objects from extracted face groups.
- Returns:
List of Cone feature objects.
- property ids_cones: list[list[int]]#
Return the face IDs of identified cones.
- Returns:
List of face ID lists, one per cone.
- perform() bool#
Perform cone feature extraction for the configured extraction mode.
- Returns:
True if extraction completed successfully.
- property surface_type_name: str#
Return the OCP surface type string for cones.
- class volmdlr_tools.features.extractors.CylinderExtractor(aag: AttributedAdjacencyGraph, max_radius: float = inf, linear_tolerance: float = 0.0001, angular_tolerance: float = 0.0175, extraction_mode: ExtractionMode = ExtractionMode.EXTERNAL, name: str = '')#
Bases:
FeatureExtractorExtract cylindrical features from an Attributed Adjacency Graph (AAG).
This class recognizes cylinders by identifying cylindrical faces and propagating to collect all coaxial cylindrical neighbors through appropriate edges.
Supports both extraction modes: - EXTERNAL (default): Extract bosses, shafts, pins (surface normal points away from axis).
Propagates through CONVEX/SMOOTH edges.
- INTERNAL: Extract bores, holes (surface normal points toward axis).
Propagates through CONCAVE/SMOOTH edges.
- Parameters:
aag – The Attributed Adjacency Graph (AAG) representation of the CAD model.
max_radius – Maximum radius for cylinder recognition (filters large cylinders).
linear_tolerance – Tolerance for radius and position comparisons.
angular_tolerance – Tolerance for axis direction comparisons (radians).
extraction_mode – Whether to extract EXTERNAL or INTERNAL cylinders.
name – Name for the extractor instance.
- get_cylinders() list[Cylinder]#
Create Cylinder objects from extracted face groups.
- Returns:
List of Cylinder feature objects.
- property ids_cylinders: list[list[int]]#
Return the face IDs of identified cylinders.
- Returns:
List of face ID lists, one per cylinder.
- perform() bool#
Perform the cylinder feature extraction.
Main entry point for cylinder recognition. Iterates through faces, identifies cylindrical seed faces, propagates to collect coaxial neighbors, validates angular coverage, and processes floating isolations.
- Returns:
True if extraction completed successfully.
- class volmdlr_tools.features.extractors.DeformationExtractor(sheet_metal: SheetMetalShape, name: str = '')#
Bases:
FeatureExtractorExtractor for recognizing deformation features in a B-Rep CAD model.
- static get_entire_set_center_of_mass(deformation_set: list[int], aag_side: AttributedAdjacencyGraph) ndarray#
Compute the center of mass for an entire deformation set by averaging face centers.
- Parameters:
deformation_set – List of node indices in the deformation set.
aag_side – The AAG representation of one side.
- Returns:
The averaged center of mass as a numpy array.
- perform() bool#
Perform deformation recognition by matching deformations from both sides of the sheet metal.
- Returns:
True if found any deformation matches. False otherwise.
- class volmdlr_tools.features.extractors.ExtractionMode(*values)#
Bases:
str,EnumMode for coaxial feature extraction.
Controls whether to extract internal (bores, fillets) or external (bosses, shafts) coaxial features.
- Attributes:
- EXTERNAL: Extract external features (bosses, shafts, external rounded edges).
Surface normal points away from axis. Propagates through CONVEX edges.
- INTERNAL: Extract internal features (bores, holes, internal fillets).
Surface normal points toward axis. Propagates through CONCAVE edges.
- EXTERNAL = 'external'#
- INTERNAL = 'internal'#
- class volmdlr_tools.features.extractors.HoleExtractor(aag: AttributedAdjacencyGraph, linear_tolerance: float = 0.0001, angular_tolerance: float = 0.0175, name: str = '')#
Bases:
FeatureExtractorExtract hole features from an Attributed Adjacency Graph (AAG).
This class recognizes holes by grouping coaxial cylindrical/conical faces, building connected components, merging vertex-sharing fragments from intersecting holes, and splitting non-monotonic radius profiles.
Key differences from CavityExtractor: - Seed type: Coaxial face groups (vs. faces with inner wires) - Propagation: Through coaxial groups + neighbor intersection (vs. outer wire neighbors) - Validation: Angular coverage per radius level (vs. connected components)
- Parameters:
aag – The Attributed Adjacency Graph (AAG) representation of the CAD model.
linear_tolerance – Tolerance for radius and position comparisons.
angular_tolerance – Tolerance for axis direction comparisons (radians).
name (str) – Name for the extractor instance.
- get_holes() list[Hole]#
Create Hole objects from extracted face groups.
- Returns:
List of Hole feature objects.
- property ids_holes: list[list[int]]#
Return the face IDs of identified holes.
- Returns:
List of face ID lists, one per hole.
- perform() bool#
Perform the hole feature extraction.
Main entry point for hole recognition. Groups coaxial cylindrical faces, finds connected components (merging vertex-sharing fragments from intersecting holes), splits non-monotonic radius profiles into separate holes, and adds ending faces.
- Returns:
True if extraction completed successfully.
- class volmdlr_tools.features.extractors.InteractingFeatureExtractor(aag: AttributedAdjacencyGraph, max_radius: float | None = None, name: str = '')#
Bases:
FeatureExtractorExtract interacting machining features using Sunil et al. (2010) algorithm.
- property befgs: list[BEFG]#
Return the filtered list of Base Extended Feature Graphs.
- property blend_extractor: BlendExtractor | None#
Return the underlying BlendExtractor (for radius / kind / vexity inspection).
- property blend_node_ids: set[int]#
Return AAG node ids that BlendExtractor recognized as blend faces.
- property feature_nodes: set[int]#
Return the set of face indices that are part of features.
- property hierarchy: FeatureHierarchy#
Return the parent/child
FeatureHierarchyoverresult.Built lazily on first access and cached. Use this for any non-trivial traversal (leaf-first removal order, ancestor walks, etc.); iterate
interactionsdirectly only when you need the raw edge list.
- property interactions: list[tuple[int, int]]#
Return parent-child interactions as
(parent_idx, child_idx)tuples intoresult.
- perform() bool#
Perform the interacting feature extraction.
Idempotent: repeat calls return without re-running the pipeline.
- Returns:
True if extraction was successful.
- property shape: Shape#
Return the shape.
- property stock_faces: set[int]#
Return the face indices identified as stock (raw material) faces.
Stock faces are removed from the graph before feature extraction, so no extracted feature ever contains them. Inspect this set when a face is unexpectedly absent from every feature.
- class volmdlr_tools.features.extractors.IsolatedFeatureExtractor(aag: AttributedAdjacencyGraph)#
Bases:
objectExtractor for isolated features given seed faces.
Takes seed face(s) as input and identifies the isolated feature component that lies “inside” the seeds.
The algorithm: 1. Check separability: removing seeds must increase connected components 2. Extract contours: outer edges (boundary) and inner edges (feature candidates boundaries) 3. Find forbidden neighbors: faces adjacent to seeds via outer edges 4. Select valid component: not intersecting forbidden, adjacent to inner edges
- check_inner_boundary_inclusion(inner_edge_sets: list[set[int]], component: set[int]) bool#
Check if component covers at least one complete inner contour.
Based on asiAlgo_RecognizeIsolated::checkInnerBoundaryInclusion (lines 249-304).
- Parameters:
inner_edge_sets – List of inner edge index sets.
component – Set of face indices in the component.
- Returns:
True if component covers at least one inner contour.
- extract_contours(seeds: list[int]) tuple[set[int], list[set[int]]]#
Extract outer and inner edge contours from seed faces.
Dispatches to single or multi-seed implementation.
- Parameters:
seeds – List of seed face indices.
- Returns:
Tuple of (outer_edge_indices, list of inner_edge_index_sets).
- extract_contours_multi_seed(seeds: list[int]) tuple[set[int], list[set[int]]]#
Extract contours for multiple seed faces.
Based on asiAlgo_RecognizeIsolated::extractContours multibase case (lines 322-408). Uses naked edges analysis to find outer/inner boundaries.
- Parameters:
seeds – List of seed face indices.
- Returns:
Tuple of (outer_edge_indices, list of inner_edge_index_sets).
- extract_contours_single_seed(seed_id: int) tuple[set[int], list[set[int]]]#
Extract contours for a single seed face.
Based on asiAlgo_RecognizeIsolated::getFaceEdges (lines 204-245).
- Parameters:
seed_id – The seed face index.
- Returns:
Tuple of (outer_edge_indices, list of inner_edge_index_sets).
- get_boundary_wires_from_seeds(seeds: list[int]) list | None#
Get boundary wires from multiple seed faces, sorted by length (longest first).
Builds a shell from the seed faces and finds naked (open) edges, then connects them into wires. The longest wire is the outer boundary, the rest are inner boundaries (holes/features).
- Parameters:
seeds – List of seed face indices.
- Returns:
List of (wire, length) tuples sorted by length descending, or None if < 2 wires.
- get_components_if_separable(seeds: list[int]) list[set[int]] | None#
Get connected components after removing seeds, if separable.
Based on asiAlgo_RecognizeIsolated lines 110-124.
- Parameters:
seeds – List of seed face indices.
- Returns:
List of components if separable, None otherwise.
- get_edge_vertices(edge_idx: int) set[tuple]#
Extract vertex coordinates from an edge by index.
- Parameters:
edge_idx – Edge index in the AAG (0-based).
- Returns:
Set of (x, y, z) coordinate tuples (rounded to 6 decimals).
- get_face_wires(seed_id: int) tuple#
Get outer and inner wires from a single face.
- Parameters:
seed_id – The seed face index.
- Returns:
Tuple of (outer_wire, list of inner_wires).
- get_forbidden_neighbors(seeds: list[int], outer_edges: set[int]) set[int]#
Get faces adjacent to seeds through outer edges (forbidden for feature).
Based on asiAlgo_RecognizeIsolated lines 140-149.
- Parameters:
seeds – List of seed face indices.
outer_edges – Set of outer edge indices.
- Returns:
Set of forbidden face indices.
- get_inner_wires(seeds: list[int]) list#
Get cached inner wires for the given seeds.
For multi-seed cases, inner wires are the shorter boundary wires (everything except the longest/outer wire).
- Parameters:
seeds – List of seed face indices.
- Returns:
List of inner TopoDS_Wire objects.
- static get_wire_vertices(wire: TopoDS_Wire) set[tuple]#
Extract vertex coordinates from a wire.
- Parameters:
wire – TopoDS_Wire to extract vertices from.
- Returns:
Set of (x, y, z) coordinate tuples (rounded to 6 decimals).
- recognize(seeds: list[int]) set[int] | None#
Recognize isolated feature from seeds.
- Parameters:
seeds – List of seed face indices.
- Returns:
Set of feature face indices, or None if no valid feature.
- class volmdlr_tools.features.extractors.RegionDeformationExtractor(sheet_metal: SheetMetalShape, name: str = '')#
Bases:
DeformationExtractorDeformation extractor driving the region-based helper on both sides.
Reuses the wire-based extractor’s pairing plumbing (mutual-nearest matching, gravity centers, feature construction) over region-based candidates.
- MAX_PAIR_FACE_RATIO = 3.0#
- perform() bool#
Run region-based extraction on both sides, pair the pooled results, classify per pair.
Emboss-like and cutout-like regions are pooled per side before pairing: the free-boundary class is a per-side observation that the two sides can disagree on (a region may fade into a cutout rim on one side only), and pairing within a class would then silently drop the deformation. The class is decided from the matched pair instead: FlangedCutout only when both sides touch a free boundary, Emboss otherwise.
- Returns:
True if any deformation pair was found, False otherwise.
- class volmdlr_tools.features.extractors.RevolutionFacesExtractor(aag: AttributedAdjacencyGraph, extract_internal: bool = True, extract_external: bool = True, max_radius: float = inf, max_semi_angle: float = 1.5707963267948966, max_major_radius: float = inf, max_minor_radius: float = inf, linear_tolerance: float = 0.0001, angular_tolerance: float = 0.0175, name: str = '')#
Bases:
FeatureExtractorExtract all revolution surface features (cylinders, cones, tori) from a CAD model.
This extractor combines CylinderExtractor, ConeExtractor, and TorusExtractor to extract all revolution-based features in a single operation. It supports extracting internal, external, or both feature types.
Features are categorized as: - Internal: Bores (cylinders), countersinks (cones), fillets (tori) - External: Bosses (cylinders), chamfers (cones), rounded edges (tori)
- Parameters:
aag – The Attributed Adjacency Graph (AAG) representation of the CAD model.
extract_internal – Whether to extract internal features (default: True).
extract_external – Whether to extract external features (default: True).
max_radius – Maximum radius for cylinder recognition.
max_semi_angle – Maximum semi-angle in radians for cone recognition.
max_major_radius – Maximum major radius for torus recognition.
max_minor_radius – Maximum minor radius for torus recognition.
linear_tolerance – Tolerance for radius and position comparisons.
angular_tolerance – Tolerance for axis direction comparisons (radians).
name – Name for the extractor instance.
- property cones: list[Cone]#
Get all extracted cone features.
- Returns:
List of Cone features (both internal and external if both modes enabled).
- property cylinders: list[Cylinder]#
Get all extracted cylinder features.
- Returns:
List of Cylinder features (both internal and external if both modes enabled).
- property external_features: list[Feature]#
Get all external features (bosses, chamfers, rounded edges).
- Returns:
List of all external features.
- property internal_features: list[Feature]#
Get all internal features (bores, countersinks, fillets).
- Returns:
List of all internal features.
- perform() bool#
Perform the revolution features extraction.
Runs CylinderExtractor, ConeExtractor, and TorusExtractor for each enabled extraction mode (internal and/or external).
- Returns:
True if extraction completed successfully.
- class volmdlr_tools.features.extractors.RibExtractor(aag: AttributedAdjacencyGraph, max_thickness: float | None = None, blend_max_radius: float | None = None, pair_finder: Literal['edge_driven', 'face_pair', 'nearly_planar'] = 'edge_driven', name: str = '')#
Bases:
FeatureExtractorRecognize rib features on a BRep model from its AAG.
A rib is a thin protruding wall: two opposing end faces a thin gap apart, standing on the surrounding part walls and capped by a shell. By default the end-face pairs are found edge-driven (Lai et al. §4.2.1) — see
perform()for the pipeline and__init__for thepair_finderselector.All constructor parameters are documented on
__init__.- property applied_max_thickness: float#
The wall-thickness threshold recognition actually used.
Equal to
max_thickness(or its scale-aware default) unless the default was tightened to the part’s measured wall population — see_tighten_max_thickness(). Report this, notmax_thickness.
- perform() bool#
Recognize ribs and store them in
self._result.End-face pairs come from the finder the constructor flags select — by default
_find_end_face_pairs_edge_driven(), which derives each wall’s two sides from matched parallel boundary edges of a host face and admits nearly-planar sides, not only true planes.For each pair, collect the shell faces that join the two ends through convex edges and the base faces that meet them through concave edges. Pairs that are fragments of the same physical wall (coplanar sides split by the modeller) are then merged into one candidate before each candidate is materialized into a
Rib. A pair with no connecting shell face is not a rib and is dropped.- Returns:
True once recognition has run (idempotent).
- property rib_structures: list[RibStructure]#
Return rib structures: groups of >=2 segments connected at junctions.
- class volmdlr_tools.features.extractors.SharpEdgeExtractor(aag: AttributedAdjacencyGraph, name: str = '')#
Bases:
FeatureExtractorExtract sharp edge features from AAG.
A class for recognizing and analyzing sharp edges in a geometric model using an adjacency attribute graph. Sharp edges are identified by analyzing convex angles between adjacent faces along linear edges.
- display_result() dict#
Implementation of a tag for displays.
- get_edges_shapes() list[Edge]#
Return a list containing all identified edges shapes.
- property ids: list[int]#
Return the ids of sharp edges.
- Returns:
Ids of sharp edges.
- perform() None#
Perform sharp edge identification and cache the result.
- property shape: Shape#
Return the shape.
- class volmdlr_tools.features.extractors.SplitAdjacencyExtractor(aag: AttributedAdjacencyGraph, name: str = '')#
Bases:
FeatureExtractorExtract material addition features detected via the split adjacency pattern.
Seed pairs classified as CUT (predominantly convex dihedral angles) are discarded — cuts are handled by
InteractingFeatureExtractor.- Algorithm:
Find seed pairs: faces sharing N >= 2 edges in the AAG.
For each seed pair, remove seeds and find connected components.
Select the N-1 smallest-distance vertex pairs between adjacent common edges (N common edges always yield N-1 features).
Components containing those vertices are features.
Drop features whose angles indicate a cut.
- find_seed_pairs() list[tuple[int, int]]#
Find face pairs exhibiting the split adjacency pattern.
- Returns:
List of (face1_idx, face2_idx) tuples identifying seed pairs.
- perform() bool#
Execute the split adjacency feature extraction and classification.
For each detected ADDITION candidate, run
ExtrusionShapeRecognizeron its shell. Confirmed shapes becomeExtrusion; the rest stay asUnknownFeaturetagged withheuristic_source="split_adjacency"for later study. Both carryseed_nodesso downstream consumers can trace back to the originating split adjacency.- Returns:
True if at least one ADDITION feature was detected.
- select_feature_components(components: list[set[int]], seed_pair: tuple[int, int]) list[set[int]]#
Select graph components that represent manufacturing features.
After removing seed faces, the AAG splits into multiple components. A component is a feature when it contains at least one of the feature-marker vertices.
- Parameters:
components – Connected components from the AAG after seed removal.
seed_pair – Tuple of (face1_idx, face2_idx) identifying the seed faces.
- Returns:
List of sets of face indices, each set forming a distinct feature.
- class volmdlr_tools.features.extractors.TorusExtractor(aag: AttributedAdjacencyGraph, max_major_radius: float = inf, max_minor_radius: float = inf, linear_tolerance: float = 0.0001, angular_tolerance: float = 0.0175, extraction_mode: ExtractionMode = ExtractionMode.EXTERNAL, name: str = '')#
Bases:
CoaxialFeatureExtractorMixin,FeatureExtractorExtract toroidal features from an Attributed Adjacency Graph (AAG).
This class recognizes tori by identifying toroidal faces and propagating to collect all coaxial toroidal neighbors with the same radii through appropriate edges.
Supports both extraction modes: - EXTERNAL (default): Extract rounded edges, torus protrusions (surface normal points outward).
Propagates through CONVEX/SMOOTH edges.
- INTERNAL: Extract internal fillets (surface normal points inward).
Propagates through CONCAVE/SMOOTH edges.
Key differences from CylinderExtractor: - Surface type: ToroidalSurface - Property matching: Same major AND minor radii (both must match) - Geometry: Has two radii parameters
- Parameters:
aag – The Attributed Adjacency Graph (AAG) representation of the CAD model.
max_major_radius – Maximum major radius for torus recognition.
max_minor_radius – Maximum minor radius for torus recognition.
linear_tolerance – Tolerance for radius and position comparisons.
angular_tolerance – Tolerance for axis direction comparisons (radians).
extraction_mode – Whether to extract EXTERNAL or INTERNAL tori.
name – Name for the extractor instance.
- property extraction_mode: ExtractionMode#
Return the extraction mode (INTERNAL or EXTERNAL).
- get_tori() list[Torus]#
Create Torus objects from extracted face groups.
- Returns:
List of Torus feature objects.
- property ids_tori: list[list[int]]#
Return the face IDs of identified tori.
- Returns:
List of face ID lists, one per torus.
- perform() bool#
Perform torus feature extraction for the configured extraction mode.
- Returns:
True if extraction completed successfully.
- property surface_type_name: str#
Return the OCP surface type string for tori.