volmdlr_tools.features package#
The features package provides tools for feature recognition and extraction from BRep models.
Subpackages#
- volmdlr_tools.features.extractors package
- Submodules
- volmdlr_tools.features.extractors.core module
FeatureExtractorInnerFeaturesExtractorInnerFeaturesExtractor.extract()InnerFeaturesExtractor.get_features_faces()InnerFeaturesExtractor.is_angle_type_valid()InnerFeaturesExtractor.is_concave_through()InnerFeaturesExtractor.is_convex_through()InnerFeaturesExtractor.is_feature_valid()InnerFeaturesExtractor.is_invalid_base_neighbor()InnerFeaturesExtractor.propagate()
- volmdlr_tools.features.extractors.blend module
BlendExtractorBlendExtractor.calculate_chain_length()BlendExtractor.compute_blend_length()BlendExtractor.display_result()BlendExtractor.dye_blending_faces()BlendExtractor.find_cross_edges()BlendExtractor.find_smooth_edges()BlendExtractor.find_smooth_edges_for_face()BlendExtractor.find_spring_edges()BlendExtractor.find_terminating_edges()BlendExtractor.get_blend()BlendExtractor.get_blending_chains_faces()BlendExtractor.get_blending_faces()BlendExtractor.get_blends()BlendExtractor.get_chains()BlendExtractor.idsBlendExtractor.perform()BlendExtractor.shapeBlendExtractor.terminating_edges_to_cross_edges()
RecognizeBlends
- volmdlr_tools.features.extractors.cavity module
CavityExtractorCavityExtractor.display_result()CavityExtractor.find_seeds()CavityExtractor.get_cavities()CavityExtractor.ids_pocketsCavityExtractor.is_angle_valid()CavityExtractor.is_feature_valid()CavityExtractor.is_invalid_base_neighbor()CavityExtractor.is_seed_valid()CavityExtractor.perform()CavityExtractor.recognize_cavities()CavityExtractor.shape
RecognizeCavities
- volmdlr_tools.features.extractors.sharp_edge module
- volmdlr_tools.features.extractors.deformation module
- volmdlr_tools.features.extractors.sheet_metal module
DeformationExtractorRegionDeformationExtractorSheetMetalFeatureClassifierSheetMetalFeatureExtractorSheetMetalFeatureExtractor.CURL_ANGLE_THRESHOLDSheetMetalFeatureExtractor.MIN_FACES_FOR_MIRRORINGSheetMetalFeatureExtractor.NUM_FACES_CURLSheetMetalFeatureExtractor.NUM_FACES_HEMSheetMetalFeatureExtractor.boundary_featuresSheetMetalFeatureExtractor.extract_all_bendings()SheetMetalFeatureExtractor.extract_boundary_features()SheetMetalFeatureExtractor.extract_internal_features()SheetMetalFeatureExtractor.get_connected_concave_subchains()SheetMetalFeatureExtractor.get_external_subchains_groups()SheetMetalFeatureExtractor.get_internal_subchains_groups()SheetMetalFeatureExtractor.get_mirror_internal_subchains()SheetMetalFeatureExtractor.internal_featuresSheetMetalFeatureExtractor.perform()
- volmdlr_tools.features.extractors.feature_classifier module
- volmdlr_tools.features.extractors.ribs module
- volmdlr_tools.features.extractors.rib_edge_pairs module
- Module contents
BlendExtractorBlendExtractor.calculate_chain_length()BlendExtractor.compute_blend_length()BlendExtractor.display_result()BlendExtractor.dye_blending_faces()BlendExtractor.find_cross_edges()BlendExtractor.find_smooth_edges()BlendExtractor.find_smooth_edges_for_face()BlendExtractor.find_spring_edges()BlendExtractor.find_terminating_edges()BlendExtractor.get_blend()BlendExtractor.get_blending_chains_faces()BlendExtractor.get_blending_faces()BlendExtractor.get_blends()BlendExtractor.get_chains()BlendExtractor.idsBlendExtractor.perform()BlendExtractor.shapeBlendExtractor.terminating_edges_to_cross_edges()
CavityExtractorCavityExtractor.display_result()CavityExtractor.find_seeds()CavityExtractor.get_cavities()CavityExtractor.ids_pocketsCavityExtractor.is_angle_valid()CavityExtractor.is_feature_valid()CavityExtractor.is_invalid_base_neighbor()CavityExtractor.is_seed_valid()CavityExtractor.perform()CavityExtractor.recognize_cavities()CavityExtractor.shape
ChamferExtractorCoaxialFeatureExtractorMixinConeExtractorCylinderExtractorDeformationExtractorExtractionModeHoleExtractorInteractingFeatureExtractorInteractingFeatureExtractor.befgsInteractingFeatureExtractor.blend_extractorInteractingFeatureExtractor.blend_node_idsInteractingFeatureExtractor.feature_nodesInteractingFeatureExtractor.hierarchyInteractingFeatureExtractor.hole_featuresInteractingFeatureExtractor.interactionsInteractingFeatureExtractor.perform()InteractingFeatureExtractor.resultInteractingFeatureExtractor.shapeInteractingFeatureExtractor.stock_faces
IsolatedFeatureExtractorIsolatedFeatureExtractor.check_inner_boundary_inclusion()IsolatedFeatureExtractor.extract_contours()IsolatedFeatureExtractor.extract_contours_multi_seed()IsolatedFeatureExtractor.extract_contours_single_seed()IsolatedFeatureExtractor.get_boundary_wires_from_seeds()IsolatedFeatureExtractor.get_components_if_separable()IsolatedFeatureExtractor.get_edge_vertices()IsolatedFeatureExtractor.get_face_wires()IsolatedFeatureExtractor.get_forbidden_neighbors()IsolatedFeatureExtractor.get_inner_wires()IsolatedFeatureExtractor.get_wire_vertices()IsolatedFeatureExtractor.recognize()
RegionDeformationExtractorRevolutionFacesExtractorRibExtractorSharpEdgeExtractorSplitAdjacencyExtractorTorusExtractor
- volmdlr_tools.features.feature_types package
- Subpackages
- volmdlr_tools.features.feature_types.sheet_metal package
- Submodules
- volmdlr_tools.features.feature_types.sheet_metal.bends module
- volmdlr_tools.features.feature_types.sheet_metal.corners module
- volmdlr_tools.features.feature_types.sheet_metal.jogs module
- volmdlr_tools.features.feature_types.sheet_metal.notches module
- volmdlr_tools.features.feature_types.sheet_metal.reliefs module
- volmdlr_tools.features.feature_types.sheet_metal.lances module
- volmdlr_tools.features.feature_types.sheet_metal.louvres module
- volmdlr_tools.features.feature_types.sheet_metal.deformations module
- volmdlr_tools.features.feature_types.sheet_metal.unknown module
- Module contents
- volmdlr_tools.features.feature_types.sheet_metal package
- Submodules
- volmdlr_tools.features.feature_types.core module
- volmdlr_tools.features.feature_types.blends module
- volmdlr_tools.features.feature_types.cavities module
- volmdlr_tools.features.feature_types.sharp_edges module
- volmdlr_tools.features.feature_types.ribs module
- Module contents
BlendBlendChainBlindSlotBlindStepCavityChamferChamferAttributeChamferChainCounterboreHoleCounterdrillHoleCountersinkHoleCylinderExtrusionExtrusionParametersFeatureFeatureCategoryHoleHole.access_directionHole.axisHole.categoryHole.depthHole.diameterHole.entry_blend_radiusHole.extrusion_heightHole.face_type_countsHole.feature_typeHole.floor_blend_radiusHole.from_faces_and_nodes()Hole.is_blindHole.locationHole.originHole.radiusHole.revolution_frameHole.revolution_profileHole.revolved_solid()Hole.set_cached_properties()Hole.topology
MultiRadiusHoleOpenPocketOpenSlotPocketRectangularCavityRevolutionFeatureRibRibStructureRoundCavityRoundHoleSharpEdgeSlotSlottedCavitySquareCavityStepSteppedHoleTaperHoleThroughSlotTorusUnknownFeature
- Subpackages
- volmdlr_tools.features.classification package
- Submodules
- volmdlr_tools.features.classification.registry module
- volmdlr_tools.features.classification.matcher module
- volmdlr_tools.features.classification.rules module
CompositeFeatureRuleCompositeFeatureRule.boundary_subchainsCompositeFeatureRule.d1_greater_d2CompositeFeatureRule.descriptionCompositeFeatureRule.fan_shaped_facesCompositeFeatureRule.fan_shaped_pairsCompositeFeatureRule.feature_classCompositeFeatureRule.internal_chainsCompositeFeatureRule.nameCompositeFeatureRule.opposite_normalsCompositeFeatureRule.share_common_face
CutFeatureRuleCutFeatureRule.all_angles_concaveCutFeatureRule.cylindrical_surfacesCutFeatureRule.descriptionCutFeatureRule.different_radius_valuesCutFeatureRule.feature_classCutFeatureRule.is_fsf_neighborCutFeatureRule.nameCutFeatureRule.parallel_planar_pairsCutFeatureRule.planar_surfacesCutFeatureRule.total_facesCutFeatureRule.type_of_chain
DeformFeatureRule
- Module contents
CompositeFeatureRuleCompositeFeatureRule.boundary_subchainsCompositeFeatureRule.d1_greater_d2CompositeFeatureRule.descriptionCompositeFeatureRule.fan_shaped_facesCompositeFeatureRule.fan_shaped_pairsCompositeFeatureRule.feature_classCompositeFeatureRule.internal_chainsCompositeFeatureRule.nameCompositeFeatureRule.opposite_normalsCompositeFeatureRule.share_common_face
CutFeatureRuleCutFeatureRule.all_angles_concaveCutFeatureRule.cylindrical_surfacesCutFeatureRule.descriptionCutFeatureRule.different_radius_valuesCutFeatureRule.feature_classCutFeatureRule.is_fsf_neighborCutFeatureRule.nameCutFeatureRule.parallel_planar_pairsCutFeatureRule.planar_surfacesCutFeatureRule.total_facesCutFeatureRule.type_of_chain
DeformFeatureRuleFeatureRuleRegistryRuleMatcher
- volmdlr_tools.features.measurements package
- volmdlr_tools.features.reverse_engineering package
- Compute engines
BlendClassificationClassifiedProfileProfileExtractorProfileModeVentingblends_drawn_on_profile()classify_blends()classify_profile_wire()classify_venting()clearance_for()compute_access_direction()compute_axis()compute_depth()compute_sweep_axis()compute_sweep_length()extract_profile()profile_frame()profile_origin()sweep_is_prismatic()synthesize_entry_face()venting_and_clearance()
- Profile extraction and shape recognition
- Compute engines
Submodules#
volmdlr_tools.features.core module#
Feature recognition module.
- class volmdlr_tools.features.core.FeatureProcessor(shape: Shell | Solid, aag: AttributedAdjacencyGraph | None = None, name: str = '')#
Bases:
DessiaObjectProcessor/orchestrator for feature recognition and manipulation.
Features extracted through this class are managed internally and should not exist outside of this context. All feature access and manipulation happens through methods on this class.
This class acts as the single source of truth for all extracted features and provides a clean API for feature recognition, querying, filtering, and manipulation operations.
- property blend_chains: list[BlendChain]#
Get extracted blend chains.
- Returns:
Tuple of BlendChain objects (immutable)
- property blends: list[Blend]#
Get extracted blend features.
- Returns:
Tuple of Blend objects (immutable)
- property cavities: list[Cavity]#
Get extracted cavity features.
- Returns:
Tuple of Cavity objects (immutable)
- property chamfer_chains: list[ChamferChain]#
Get extracted chamfer chains.
- Returns:
List of ChamferChain objects
- clear_all_features() None#
Clear all features from the registry.
- clear_features(feature_types: list[type[Feature]] | None = None) None#
Clear extracted features.
- Parameters:
feature_types – Optional feature classes to clear (e.g., Bend, Cavity). If None, clears all features.
- property corner: list[Corner]#
Get extracted corner features.
- Returns:
Tuple of Corner objects (immutable)
- property corner_reliefs: list[CornerRelief]#
Get extracted corner relief features.
- Returns:
List of CornerRelief objects.
- property embosses: list[Emboss]#
Get extracted emboss features.
- Returns:
Tuple of Emboss objects (immutable)
- extract_all(blend_max_radius: float | None = None) None#
Recognize all available features for the shape.
- Parameters:
blend_max_radius – Maximum radius for blend recognition, in the model’s own length units; omitted, a fraction of the model’s own size.
- extract_blends(max_radius: float | None = None) None#
Recognize blend features and store them internally.
- Parameters:
max_radius – The maximum radius for blend recognition, in the model’s own length units. Omitted, it is taken as a fraction of the model’s own size, so the same call recognizes the fillets of a part modelled in millimetres and of one modelled in metres.
- extract_cavities() None#
Recognize cavity features and store them internally.
- extract_chamfers(convex_only: bool = True, max_offset_ratio: float = 0.5, min_angle_degrees: float = 5.0) None#
Recognize chamfer features and store them internally.
- Parameters:
convex_only – If True, only detect convex chamfers. Default True.
max_offset_ratio – Maximum ratio of chamfer offset to model diagonal.
min_angle_degrees – Minimum angle between under-faces in degrees.
- extract_deformations(extractor_class: type[DeformationExtractor] = <class 'volmdlr_tools.features.extractors.sheet_metal.region_deformation.RegionDeformationExtractor'>) None#
Recognize deformation features (embosses, flanged cutouts) and store them internally.
- Parameters:
extractor_class – The extractor driving the recognition. Defaults to the region-based extractor, which also finds deformations merged with cutout rims or the sheet boundary; pass
DeformationExtractorfor the wire-seeded one.- Raises:
ValueError – If the shape is not a sheet metal.
- extract_interacting_features() None#
Extract interacting machining features using the Sunil et al. (2010) algorithm.
- extract_lances() None#
Recognize lance features and store them internally.
- Raises:
ValueError – If the shape is not a sheet metal.
- extract_ribs(max_thickness: float | None = None, blend_max_radius: float | None = None, pair_finder: str = 'edge_driven') None#
Recognize rib features (and rib structures) and store them internally.
Not part of
extract_all()— rib recognition walks the whole AAG and is markedly slower than the other extractors, so it is opt-in. Until it is called,ribsandrib_structuresare empty.- Parameters:
max_thickness – Maximum wall thickness for a rib, in the model’s units. When omitted it defaults to a fraction of the model’s bounding-box diagonal, so the threshold is unit-agnostic; pass an explicit value to constrain recognition to a known wall thickness.
blend_max_radius – Maximum fillet radius recognized as a blend and passed over when collecting a rib’s shell and base faces. When omitted it defaults to a fraction of the bounding-box diagonal, for the same unit-agnostic reason as
max_thickness.pair_finder – Which candidate end-face pair finder the
RibExtractorruns —"edge_driven"(default),"face_pair", or the experimental"nearly_planar"that also admits nearly-planar BSpline/Offset end faces. Same names and defaults asRibExtractoritself.
- Raises:
ValueError – If
pair_finderis not one of the three names.
- extract_sharp_edges() None#
Recognize sharp edge features and store them internally.
- extract_sheet_metal_features() None#
Recognize sheet metal features and store them internally by type.
- Raises:
ValueError – If the shape is not a sheet metal.
- features_volume_model(features: list[Feature]) VolumeModel#
Display features alongside the original shape in a VolumeModel.
- filter_blend_chains(min_radius: float | None = None, max_radius: float | None = None, min_length: float | None = None, max_length: float | None = None) list[BlendChain]#
Filter blend chains based on criteria.
- Parameters:
min_radius – Minimum chain radius
max_radius – Maximum chain radius
min_length – Minimum chain length
max_length – Maximum chain length
- Returns:
Filtered list of blend chains
- filter_blends(min_radius: float | None = None, max_radius: float | None = None, blend_type: str | None = None, confirmed_only: bool = False) list[Blend]#
Filter blends based on criteria.
- Parameters:
min_radius – Minimum blend radius
max_radius – Maximum blend radius
blend_type – type of blend to filter (as string name)
confirmed_only – If True, only return confirmed blends
- Returns:
Filtered list of blends
- filter_by_category(category: str, location: str | None = None) list#
Filter features by category and optionally by location.
- Parameters:
category (str) – Feature category (“cut”, “forming”, “blend”, “cavity”, “unknown”)
location (Optional[str]) – Optional location filter (“boundary”, “internal”)
- Returns:
List of features matching the criteria
- Return type:
list
- filter_by_location(location: str) list#
Filter all features by location.
- Parameters:
location (str) – Location filter (“boundary” or “internal”)
- Returns:
List of features at the specified location
- Return type:
list
- filter_cavities(min_depth: float | None = None, max_depth: float | None = None) list[Cavity]#
Filter cavities based on depth criteria.
- Parameters:
min_depth – Minimum cavity depth
max_depth – Maximum cavity depth
- Returns:
Filtered list of cavities
- get_cut_features(location: str | None = None) list#
Get all cut features (slots, notches, corner reliefs, clips).
- Parameters:
location (Optional[str]) – Optional location filter (“boundary”, “internal”)
- Returns:
List of cut features
- Return type:
list
- get_feature_count() dict[str, int]#
Get count of all extracted features.
- Returns:
Dictionary mapping feature class names to counts
- get_forming_features(location: str | None = None) list#
Get all forming features (bends, jogs).
- Parameters:
location (Optional[str]) – Optional location filter (“boundary”, “internal”)
- Returns:
List of forming features
- Return type:
list
- has_features(feature_type: type[Feature] | None = None) bool#
Check if any features have been extracted.
- Parameters:
feature_type (Optional[type[Feature]]) – Optional feature class to check (e.g., Bend, Jog). If None, checks if any features exist.
- Returns:
True if features exist, False otherwise
- Return type:
bool
- property holes: tuple[Hole, ...]#
Get extracted hole features.
- Returns:
Tuple of Hole objects (immutable)
- property is_sheet_metal: bool#
Check if the shape is a sheet metal.
- Returns:
True if shape is sheet metal, False otherwise
- property lances: list[Lance]#
Get extracted lance features.
- Returns:
Tuple of Lance objects (immutable)
- property louvre: list[Louvre]#
Get extracted louvre features.
- Returns:
Tuple of Louvre objects (immutable)
- property notches: list[Notch]#
Get extracted notch features.
- Returns:
Tuple of Notch objects (immutable)
- plot_features_graph(features_to_highlight: list[Feature] | None = None, show_labels: bool = True)#
Plot the AAG with features highlighted.
- Parameters:
features_to_highlight – Optional list of features to highlight in the graph. If None, highlights all extracted features.
show_labels – Whether to show node labels.
- Returns:
Matplotlib figure or graph visualization object.
- property pockets: tuple[Pocket, ...]#
Get extracted pocket features.
- Returns:
Tuple of Pocket objects (including OpenPocket, immutable)
- post_process_unknown_features(internal_features: list[Feature]) list[Feature]#
Reclassify unknown internal features adjacent to multiple blends as CutoutWithBendInternal.
- property rib_max_thickness: float | None#
The wall-thickness threshold rib recognition actually applied.
Differs from the
max_thicknesspassed toextract_ribs()when the scale-aware default was tightened to the part’s measured walls. None untilextract_ribs()has run.
- property rib_structures: list[RibStructure]#
Get extracted rib structures (groups of segments meeting at junctions).
Empty until
extract_ribs()is called.
- property ribs: list[Rib]#
Get extracted rib segments. Empty until
extract_ribs()is called.
- property sharp_edges: list[Edge, ...]#
Get extracted sharp edge features.
- Returns:
Tuple of Edge objects (immutable)
- property sheet_metal: SheetMetalShape | None#
The recognized sheet-metal shape, or None when the shape is not a sheet metal.
Use it to drive an extractor directly (e.g.
DeformationExtractor(sheet_metal=...)); recognition runs once and is cached.
- show_cavities() dict#
Implementation of a tag for displays.
- show_features(feature_type: type[Feature] | None = None) dict#
Implementation of a tag for displays.
- property slots: tuple[Slot, ...]#
Get extracted slot features.
- Returns:
Tuple of Slot objects (including all subtypes, immutable)
- property steps: tuple[Step, ...]#
Get extracted step features.
- Returns:
Tuple of Step objects (including BlindStep, immutable)
- to_markdown() str#
Return a markdown summary of extracted features.
Includes feature counts, category breakdown (cut/forming with boundary/internal split), and classification summary statistics.
- Returns:
Markdown-formatted string
- Return type:
str
- property unknown_features: list[UnknownFeature]#
Get extracted unknown features.
- Returns:
List of UnknownFeature objects (immutable)
- view(feature_type: type[Feature] | None = None) None#
Open the recognized features, colored, in the local DocModel viewer.
Developer-workstation convenience (interactive side effect, no return value) kept out of
show_features()so the@cad_viewplatform contract stays “return babylon display data”.- Parameters:
feature_type – Same selection as
show_features().- Raises:
ValueError – If
feature_typeis not among the extracted types.
- class volmdlr_tools.features.core.FeaturesRecognizer(*args, **kwargs)#
Bases:
FeatureProcessorBackward compatibility alias for FeatureProcessor.
- . deprecated:: v1.0.0
Use FeatureProcessor instead. This alias will be removed in version 1.0.0.
- blends_recognition(max_radius: float)#
Deprecated method for backward compatibility.
- . deprecated:: v1.0.0
Use extract_blends() instead.
- cavities_recognition()#
Deprecated method for backward compatibility.
Deprecated since version v1.0.0: Use extract_cavities() instead.
- cavitivies_recognition()#
Deprecated alias for cavities_recognition() (legacy misspelling).
- emboss_recognition()#
Deprecated method for backward compatibility.
- . deprecated:: v1.0.0
Use extract_embosses() instead.
- sharp_edges_recognition()#
Deprecated method for backward compatibility.
- . deprecated:: v1.0.0
Use extract_sharp_edges() instead.
volmdlr_tools.features.constants module#
Constants for feature extraction and processing.
This module defines constants used throughout the feature extraction system. Using Enums instead of plain strings provides: - Type safety and IDE autocompletion - Protection against typos - Clear grouping of related values
- class volmdlr_tools.features.constants.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.constants.FeatureCategory(*values)#
Bases:
str,EnumHigh-level category of manufacturing features.
- Variables:
CUT – Material removal features (slots, notches, holes).
ADDITION – Material addition features (bosses, shafts, extrusions).
FORMING – Deformation features (bends, jogs).
BLEND – Fillet/chamfer features.
CAVITY – Pocket/cavity features.
UNKNOWN – Unclassified features.
- ADDITION = 'addition'#
- BLEND = 'blend'#
- CAVITY = 'cavity'#
- CUT = 'cut'#
- FORMING = 'forming'#
- UNKNOWN = 'unknown'#
- class volmdlr_tools.features.constants.FeatureLocation(*values)#
Bases:
str,EnumLocation of features on sheet metal parts.
- Variables:
BOUNDARY – Features on the outer boundary of the sheet metal.
INTERNAL – Features in the internal area of the sheet metal.
- BOUNDARY = 'boundary'#
- INTERNAL = 'internal'#
- class volmdlr_tools.features.constants.FeatureType(*values)#
Bases:
str,EnumSpecific kind of manufacturing feature.
Declared on each
Featurefamily viafeature_type = FeatureType.X. Acts as a serialisable type tag so downstream code (defeaturing, reverse-engineering, UI) can branch withoutisinstancechecks. Subclasses that are sub-variants of a kind (e.g.RoundHoleunderHOLE) inherit their parent’s value.- BEND = 'bend'#
- BLEND = 'blend'#
- BLEND_CHAIN = 'blend_chain'#
- BLIND_HOLE = 'blind_hole'#
- BLIND_SLOT = 'blind_slot'#
- BLIND_STEP = 'blind_step'#
- CAVITY = 'cavity'#
- CHAMFER = 'chamfer'#
- CHAMFER_CHAIN = 'chamfer_chain'#
- CONE = 'cone'#
- CORNER = 'corner'#
- COUNTERBORE = 'counterbore'#
- COUNTERDRILL = 'counterdrill'#
- COUNTERSINK = 'countersink'#
- CURL = 'curl'#
- CYLINDER = 'cylinder'#
- EMBOSS = 'emboss'#
- EXTRUSION = 'extrusion'#
- FLANGED_CUTOUT = 'flanged_cutout'#
- HEM = 'hem'#
- HOLE = 'hole'#
- JOG = 'jog'#
- LANCE = 'lance'#
- LOUVRE = 'louvre'#
- NOTCH = 'notch'#
- OPEN_POCKET = 'open_pocket'#
- OPEN_SLOT = 'open_slot'#
- PASSAGE = 'passage'#
- POCKET = 'pocket'#
- RELIEF = 'relief'#
- RIB = 'rib'#
- RIB_STRUCTURE = 'rib_structure'#
- ROUND_CAVITY = 'round_cavity'#
- SLOT = 'slot'#
- SQUARE_CAVITY = 'square_cavity'#
- STEP = 'step'#
- STEPPED_HOLE = 'stepped_hole'#
- TAPER_HOLE = 'taper_hole'#
- THROUGH_HOLE = 'through_hole'#
- THROUGH_SLOT = 'through_slot'#
- TORUS = 'torus'#
- UNKNOWN = 'unknown'#
- is_hole() bool#
Verify is feature type if a kind of Hole.
volmdlr_tools.features.pattern_matcher module#
Pattern Matcher Module.
- class volmdlr_tools.features.pattern_matcher.GraphMatcher(G1: Graph, G2: Graph, node_match=None, edge_match=None, min_similarity: float = 0.8)#
Bases:
GraphMatcherOverride nx GraphMatcher class.
- class volmdlr_tools.features.pattern_matcher.PatternMatcher(graph_assembly: GraphAssembly, angular_tol: float = 1e-06, min_similarity: float = 1.0, min_face_signature_similarity: float = 1.0, name: str = '')#
Bases:
DessiaObjectA class for finding geometric patterns within a graph assembly structure.
This class provides functionality to search for specific subgraph patterns within a larger graph assembly, particularly focusing on solid geometries and their face relationships.
- Parameters:
graph_assembly – The graph assembly structure to search for patterns within.
angular_tol – Angular tol parameter in radians.
name – A descriptive name for the pattern matcher instance, defaults to ‘’
- EXACT_MATCH_SIMILARITY = 1.0#
- find_matches_from_multiple_patterns(patterns: list[AttributedAdjacencyGraph]) list[list[int]]#
Find patterns matches within a graph assembly structure for a list of different patterns.
- find_pattern_matches(pattern_graph: AttributedAdjacencyGraph) list[Shell]#
Find all occurrences of a pattern graph within the assembly’s solid nodes.
This method searches through all solid nodes in the graph assembly, extracts their associated adjacency graphs (AAG), and identifies subgraphs that match the given pattern using isomorphism detection.
- Parameters:
pattern_graph – The pattern graph to search for.
exact – If true, only return subgraphs that match the pattern graph.
If False, approximate solutions may be accepted. :returns: A list of matches, where each match is a list of Face objects
corresponding to the nodes in the pattern.
- matrix_similarity_verification(pattern_graph: AttributedAdjacencyGraph, target_graph: AttributedAdjacencyGraph) set#
Verify the similarity between two adjacency matrices.
- static row_similarity_scipy(sig1_batch, sig2_batch)#
Use scipy’s optimized distance computation.
- volmdlr_tools.features.pattern_matcher.prepare_graph(graph: AttributedAdjacencyGraph, tolerance: float = 1.0, n_bins: int = 150, n_points: int = 10000) None#
Prepare a pattern graph for matching.
It calculates all nodes degree and adds a node attribute with its value.
volmdlr_tools.features.spring_pattern_matcher module#
Spring Pattern Matcher Module.
- class volmdlr_tools.features.spring_pattern_matcher.SpringPatternMatcher(graph_assembly: GraphAssembly, angular_tol: float = 1e-06, min_similiraty: float = 1.0, name: str = '')#
Bases:
PatternMatcherA pattern matcher for identifying spring-like geometric patterns in 3D models.
This class extends FacePatternMatcher to specifically identify patterns that resemble specific springs by analyzing face relationships, distances, and plane parallelism.
- Parameters:
(list[int]) (NO_VISIT_COUNT_INDEXES) – Indexes that should not be counted during visits (11, 23).
- NO_VISIT_COUNT_INDEXES = (0, 1)#
- static cluster_points_kmeans(points: ndarray, points_per_group: int = 4) tuple[ndarray, ndarray, list[ndarray]]#
Cluster 3D points into groups of specified sizes using K-means.
- Parameters:
points – Numpy array of shape (n, 3) containing 3D coordinates.
points_per_group – Number of points per cluster (default 4)
- Returns:
labels: cluster labels for each point centroids: cluster centers groups: list of point groups
- get_springs(pattern_graph: AttributedAdjacencyGraph) list[Compound]#
Extract springs from a pattern graph by identifying patterns, clustering them, and building spring compounds.
- Parameters:
pattern_graph – The faces graph containing pattern data from which springs are to be extracted.
- Returns:
A list of spring compounds constructed from the patterns in the graph.
volmdlr_tools.features.edge_lines module#
This module provides functionality for finding specific patterns in attributed adjacency graphs.
Particularly useful for analyzing geometric structures with angular relationships between faces.
- class volmdlr_tools.features.edge_lines.EdgeLines(aag: AttributedAdjacencyGraph, angle_tolerance: float = 5, name: str = '')#
Bases:
SharpEdgeExtractorIdentifies border edges formed by faces meeting at approximately 90 degrees.
This class analyzes angular relationships between adjacent faces in a 3D model to detect sharp, convex edges. Edges are classified as sharp if the angle between the connected faces is close to 90 degrees, within a given tolerance.
- perform() None#
Detect and cache sharp convex edges formed at approximately 90 degrees.
Iterates through edges in the model, evaluates the angle between adjacent faces, and marks edges as sharp if the angle is convex and near 90 degrees.
volmdlr_tools.features.geometry_helpers module#
Shared geometry helpers for the feature pipeline.
Public home for predicates and accessors that the extractor layer, the feature-type layer, and the reverse-engineering engines all need. Each helper either reads cached attributes on the AAG (fast path) or performs a single OCP query — never both.
Engines, reversers, and extractors should import from here rather than defining their own copies; the previous duplication caused drift between the AAG-cached fast path and the BRepAdaptor-rebuilding slow path.
- class volmdlr_tools.features.geometry_helpers.ShapeRayCaster(shape: TopoDS_Shape, tolerance: float = 1e-06)#
Bases:
objectCasts rays against a BRep shape, loading the intersector once.
BRepIntCurveSurface_Interrebuilds the shape’s search structures on everyInit(shape, ...)call; loading the shape once and re-initializing only the ray curve makes repeated casts against the same shape cheap. The intersector works on the infinite line, so backward hits (negative parameter) and the near-zero self-hit on a start face lying on the shape are discarded viaminimum_parameter.- first_hit_distance(origin: Point3D, direction: Vector3D, minimum_parameter: float, maximum_parameter: float | None = None) float | None#
Return the distance of the closest hit within the parameter window, or None.
- hits(origin: Point3D, direction: Vector3D, minimum_parameter: float, maximum_parameter: float | None = None) list[tuple[float, TopoDS_Face]]#
Return every
(distance, face)the ray hits within the parameter window.- Parameters:
origin – Ray origin.
direction – Ray direction (any length; normalized internally so parameters are metric distances).
minimum_parameter – Reject hits at or below this distance — the self-hit cutoff when the origin lies on the shape itself.
maximum_parameter – Optional far cutoff.
- Returns:
Unordered
(distance, face)pairs; empty when nothing is hit.
- volmdlr_tools.features.geometry_helpers.axial_extent(faces: Iterable, direction: Vector3D) float#
Return how far a set of faces reaches along direction.
The span the faces themselves occupy, measured along the direction given — the distance between the first and last of them a plane sweeping that way would touch.
A box drawn around the faces is not a stand-in for this. A box has an orientation of its own, chosen to fit what it encloses, and where that differs from direction the box reaches further along it than its contents do. Measuring the faces in a frame that direction itself defines has no such freedom left in it.
- Parameters:
faces – Faces to measure, as volmdlr faces or their underlying shapes.
direction – Unit vector to measure along. Its sign does not matter.
- Returns:
The length of the span, or
0.0when no faces were given.
- volmdlr_tools.features.geometry_helpers.bbox_diagonal(shape: Shape) float#
Return the bounding-box diagonal of a shape — the model’s overall size.
The unit-agnostic scale reference used by scale-aware defaults (rib max-thickness fraction, measurement ray cutoffs): a fraction of the diagonal means the same thing on a millimetre fixture and a metre-scale part.
- volmdlr_tools.features.geometry_helpers.get_interior_point_and_normal(aag: AttributedAdjacencyGraph, node: int) tuple[Point3D, Vector3D] | None#
Return a representative interior point and the outward normal there.
Works for any surface type. The normal honours the face’s
TopAbs_REVERSEDorientation so it points out of the material (matchingget_plane_normal()); for planar faces it short-circuits to the cached plane normal. Point and normal are sampled at the same parametric location, so they stay mutually consistent. ReturnsNonewhen no strictly interior sample exists or the surface normal is undefined there.
- volmdlr_tools.features.geometry_helpers.get_interior_points(aag: AttributedAdjacencyGraph, node: int) list[Point3D]#
Return representative points within a face, never an empty list.
The boundary-accepting instance of
interior_point_candidates()(projection-based containment, 10x10 grid) that the rib samplers use; see that function for the ladder and the best-effort caveat on the result.
- volmdlr_tools.features.geometry_helpers.get_outer_wire_edges(aag: AttributedAdjacencyGraph, face_id: int) list#
Return
TopoDS_Edgeobjects of face_id’s outer wire, in order.
- volmdlr_tools.features.geometry_helpers.get_plane_normal(aag: AttributedAdjacencyGraph, face_id: int) Vector3D#
Return the outward normal of a planar face as a gp_Dir.
Honours the face’s
TopAbs_REVERSEDorientation so the returned direction points out of the material rather than along the surface’s canonical axis. Uses the AAG node’s cachedplane_normalwhen available (populated for planar faces during AAG construction); falls back to a one-shotBRepAdaptor_Surfacebuild otherwise.
- volmdlr_tools.features.geometry_helpers.grid_interior_points(ocp_face: TopoDS_Face, grid_size: int) Generator[Point3D, Any, None]#
Yield points of a UV grid that land inside the face’s trimmed area.
The grid spans the 0.05-0.95 parametric range — inset from the edges so samples do not cling to the boundary — and is
grid_sizeper axis, so the cost isgrid_size ** 2point classifications. On a heavily trimmed face most samples fall outside and few are yielded; on a sliver, none are, so callers must handle an empty result.- Parameters:
ocp_face – The face to sample.
grid_size – Samples per parametric axis.
- Returns:
Generator of points inside the face; possibly empty.
- volmdlr_tools.features.geometry_helpers.interior_point_candidates(ocp_face: TopoDS_Face, containment: Callable[[gp_Pnt, TopoDS_Face], bool], grid_fractions: Sequence[float]) list[Point3D]#
Return representative points within a face, never an empty list.
The cheapest-first sampling ladder shared by the lenient and strict interior samplers — the containment predicate and grid density are the caller’s, because they are tuned pairs (the interacting-features accessibility filter was tuned with strict containment on a 9x9 grid; the rib samplers with boundary-accepting containment on a 10x10 grid):
the centre of mass — one point;
failing that, the UV mid-point — one point;
failing that, the
grid_fractionsxgrid_fractionsUV grid — every sample that passes containment.
If even the grid comes up empty (a sliver, or a face whose trimmed area excludes its whole parametric interior) the centre of mass is returned as a best effort. That point is known NOT to pass containment — it already failed step 1 — so treat the result as “a place to sample from”, not as a guaranteed-interior point.
- Parameters:
ocp_face – The face to sample.
containment – Predicate deciding whether a sampled point counts as inside the face (e.g.
is_point_strictly_inside()oris_point_on_or_inside_face()).grid_fractions – Parametric fractions of the UV range sampled per axis in the grid rung.
- Returns:
Points accepted by containment, or the best-effort centre.
- volmdlr_tools.features.geometry_helpers.is_axis_parallel(direction: gp_Dir, axis: Vector3D, tolerance: float = 1e-06) bool#
Return True if direction is parallel (or anti-parallel) to axis.
Uses
abs(direction · axis) > 1 - toleranceso the test is direction- agnostic — a face whose normal points opposite to axis still counts as parallel. axis is expected to be unit-length.
- volmdlr_tools.features.geometry_helpers.is_nearly_planar_face(aag: AttributedAdjacencyGraph, node: int, angular_tol: float = 0.08726646259971647) bool#
Return True if the face is flat enough to stand in for a planar end face.
True planes pass immediately. BSpline/Offset faces pass when no two sampled normals differ by more than
angular_tol(radians) across a UV grid — the “almost flat” gate that makes a single representative normal meaningful. Any other surface type returns False.The dot products are signed on purpose. A single face’s normal field is continuous, so a sign flip means the surface folded back on itself, not that it is flat: taking
abswould score a U-curled face as perfectly planar. Samples are compared pairwise rather than against the first one, soangular_tolbounds the true spread instead of twice it.
- volmdlr_tools.features.geometry_helpers.is_planar_face(aag: AttributedAdjacencyGraph, face_id: int) bool#
Return True if the face’s surface is a plane.
Reads the AAG node’s pre-computed
surface_typeattribute set during AAG construction; avoids the redundantBRepAdaptor_Surfacebuild on every call.
- volmdlr_tools.features.geometry_helpers.is_planar_perpendicular_to_axis(aag: AttributedAdjacencyGraph, face_id: int, axis: Vector3D, tolerance: float = 1e-06) bool#
Return True if face face_id is planar with normal parallel to axis.
Combination of
is_planar_face()andis_axis_parallel(). Equivalent to “the face’s plane is perpendicular to axis”.
- volmdlr_tools.features.geometry_helpers.is_point_on_or_inside_face(point: gp_Pnt, face: TopoDS_Face, tol: float = 1e-06) bool#
Check if a point lies within a face’s trimmed area, boundary included.
Unlike
is_point_strictly_inside(), the point does not have to lie exactly on the surface: it is first projected onto the underlying surface and rejected if that projection is farther thantol, then classified in UV space. Points on the trimming boundary count as inside — callers sampling a parametric grid rely on that, since a sample can land exactly on an edge.- Parameters:
point – The 3D point to classify.
face – The face to classify against.
tol – Maximum allowed point-to-surface projection distance. This bounds how far off the surface the point may sit; it does NOT widen the boundary margin, which uses a fixed 1e-7 UV tolerance.
- Returns:
True when the point projects onto the surface within
toland classifies asTopAbs_INorTopAbs_ON.
- volmdlr_tools.features.geometry_helpers.is_point_strictly_inside(point: gp_Pnt, face: TopoDS_Face, tol: float = 1e-06) bool#
Check if a point is strictly inside a face — boundary points are excluded.
The point must already lie on the face’s surface;
tolis the classifier’s own tolerance. Useis_point_on_or_inside_face()when the point may sit slightly off the surface, or when a point exactly on the boundary should count.- Parameters:
point – The 3D point to classify.
face – The face to classify against.
tol – Classification tolerance passed to
BRepClass_FaceClassifier.
- Returns:
True when the point classifies as
TopAbs_IN.
- volmdlr_tools.features.geometry_helpers.point_and_normal_on_face(aag: AttributedAdjacencyGraph, node: int, near_point: Point3D, pull_toward: Point3D, offset_distance: float) tuple[Point3D, Vector3D] | None#
Return a strictly interior point of the face near near_point, with the outward normal there.
Moves near_point by offset_distance toward pull_toward (a point interior to the face), re-projects onto the surface, requires strict interiority, and evaluates the outward normal at that exact UV — per-sample local normals, so curved and nearly-planar faces are handled correctly. Retries with halved offsets when the projection lands outside the trimmed face (short or narrow faces). Complements
get_interior_point_and_normal(), which picks some interior point; this one picks an interior point near a location the caller chose.- Parameters:
aag – The model’s attributed adjacency graph.
node – AAG face index.
near_point – Anchor location, typically on or near the face’s boundary.
pull_toward – A point interior to the face; sets the offset direction.
offset_distance – How far to move from near_point toward pull_toward.
- Returns:
(point, outward_normal)sampled at the same UV, or None when no retry produces a strictly interior projection or the normal is undefined.
- volmdlr_tools.features.geometry_helpers.projected_uv_if_strictly_inside(point: gp_Pnt, face: TopoDS_Face, classifier_tolerance: float = 1e-07) tuple[float, float] | None#
Project point onto the face’s surface; return the UV only if strictly inside.
Unlike
is_point_on_or_inside_face(), boundary points (TopAbs_ON) are rejected and the projection distance is not bounded — the caller may pass a point that sits well off the surface (e.g. offset along a chord of a curved face) and wants the nearest on-surface parameter. Returning the UV lets the caller evaluate the surface point and normal there without projecting twice.- Parameters:
point – The 3D point to project.
face – The face whose trimmed area must strictly contain the projection.
classifier_tolerance – UV tolerance for
BRepClass_FaceClassifier.
- Returns:
The
(u, v)of the projection, or None when the projection fails or lands on/outside the trimming boundary.
- volmdlr_tools.features.geometry_helpers.sample_edge_points(edge: TopoDS_Shape, count: int, start_fraction: float = 0.0, end_fraction: float = 1.0) list[Point3D]#
Sample
countpoints along an edge at equal parameter fractions.Fractions are of the edge’s raw parameter range, not arc length, so on splines and conics the spacing is not metrically uniform (use
GCPnts_QuasiUniformAbscissawhen uniform spacing matters). Narrow the[start_fraction, end_fraction]window to skip the edge’s ends — e.g.(0.15, 0.85)avoids corner junctions when the samples seed measurements near, but not on, the edge’s vertices.- Parameters:
edge – The edge to sample (
TopoDS_Edgeor a shape downcastable to one).count – Number of points to return.
start_fraction – Parameter fraction of the first sample (0 = edge start).
end_fraction – Parameter fraction of the last sample (1 = edge end).
- Returns:
The sampled points, ordered along the parameter range.
Module contents#
Feature extraction module.
- class volmdlr_tools.features.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.CavityAnatomy(_roles: dict[int, CavityFaceRole])#
Bases:
objectAnatomical classification of cavity faces.
This class holds the result of classifying cavity faces by their role according to the cavity face nomenclature.
- property all_face_ids: list[int]#
Return all face IDs in the cavity.
- property blend_face_ids: list[int]#
Return all blend face IDs.
- property entry_blend_ids: list[int]#
Return entry blend face IDs.
- property entry_face_ids: list[int]#
Return entry face IDs.
- property floor_blend_ids: list[int]#
Return floor blend face IDs.
- property floor_face_ids: list[int]#
Return floor face IDs.
- classmethod from_classified(entry_face_ids: list[int], wall_face_ids: list[int] | None = None, floor_face_ids: list[int] | None = None, entry_blend_ids: list[int] | None = None, floor_blend_ids: list[int] | None = None, wall_blend_ids: list[int] | None = None) CavityAnatomy#
Create a CavityAnatomy from classified face ID lists.
- Parameters:
entry_face_ids – Entry face IDs.
wall_face_ids – Wall face IDs.
floor_face_ids – Floor face IDs.
entry_blend_ids – Entry blend face IDs.
floor_blend_ids – Floor blend face IDs.
wall_blend_ids – Wall blend face IDs.
- Returns:
CavityAnatomy instance.
- get_ids(role: CavityFaceRole) list[int]#
Return face IDs with the given role.
- property structural_face_ids: list[int]#
Return only structural (non-blend) face IDs.
- property wall_blend_ids: list[int]#
Return wall blend face IDs.
- property wall_face_ids: list[int]#
Return wall face IDs.
- class volmdlr_tools.features.CavityDefinition(profile: Wire | None, depth: float, axis: Vector3D, origin: Point3D, access_direction: Vector3D | None = None, anatomy: CavityAnatomy | None = None, blends: list[Blend] = <factory>, wall_blends_from_profile: bool = False, feature_type: FeatureType = FeatureType.POCKET, parent_index: int | None = None, inner_profiles: list[Wire] = <factory>, classified_profile: ClassifiedProfile | None = None, profile_blend_ids: tuple[int, ...]=(), venting: Venting | None = None, clearance: float = 0.0)#
Bases:
objectParametric definition of a reverse-engineered cavity.
This class holds all the parameters needed to recreate the cavity: - Profile: The 3D profile Wire. - Depth: The extrusion depth - Axis: The extrusion direction - Blends: Fillet information
- access_direction: Vector3D | None = None#
- anatomy: CavityAnatomy | None = None#
- axis: Vector3D#
- classified_profile: ClassifiedProfile | None = None#
- clearance: float = 0.0#
- depth: float#
- property entry_fillet_radius: float | None#
Return the entry fillet radius, or None if no entry blend.
- faces_to_defeature() list[int]#
Return face IDs to pass to ComplexFeatureRemover for this cavity.
Excludes entry faces (surrounding stock) because they must not be removed during defeaturing — they are the faces that close the pocket opening on the original stock surface.
- feature_type: FeatureType = 'pocket'#
- property floor_fillet_radius: float | None#
Return the floor fillet radius, or None if no floor blend.
- property has_entry_blend: bool#
Check if the cavity has an entry blend.
- property has_floor_blend: bool#
Check if the cavity has a floor blend.
- inner_profiles: list[Wire]#
- property is_revolved: bool#
False: a cavity is rebuilt by sweeping its profile, never by revolving one.
Declared so every definition answers the question, rather than leaving each consumer to guess at the answer for the one class that does not.
- origin: Point3D#
- parent_index: int | None = None#
- profile: Wire | None#
- profile_blend_ids: tuple[int, ...] = ()#
- wall_blends_from_profile: bool = False#
- class volmdlr_tools.features.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.CavityFaceRole(*values)#
Bases:
EnumClassification of face roles within a cavity.
- ENTRY = 1#
- ENTRY_BLEND = 4#
- FLOOR = 3#
- FLOOR_BLEND = 5#
- UNKNOWN = 7#
- WALL = 2#
- WALL_BLEND = 6#
- class volmdlr_tools.features.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.FeatureProcessor(shape: Shell | Solid, aag: AttributedAdjacencyGraph | None = None, name: str = '')#
Bases:
DessiaObjectProcessor/orchestrator for feature recognition and manipulation.
Features extracted through this class are managed internally and should not exist outside of this context. All feature access and manipulation happens through methods on this class.
This class acts as the single source of truth for all extracted features and provides a clean API for feature recognition, querying, filtering, and manipulation operations.
- property blend_chains: list[BlendChain]#
Get extracted blend chains.
- Returns:
Tuple of BlendChain objects (immutable)
- property blends: list[Blend]#
Get extracted blend features.
- Returns:
Tuple of Blend objects (immutable)
- property cavities: list[Cavity]#
Get extracted cavity features.
- Returns:
Tuple of Cavity objects (immutable)
- property chamfer_chains: list[ChamferChain]#
Get extracted chamfer chains.
- Returns:
List of ChamferChain objects
- clear_all_features() None#
Clear all features from the registry.
- clear_features(feature_types: list[type[Feature]] | None = None) None#
Clear extracted features.
- Parameters:
feature_types – Optional feature classes to clear (e.g., Bend, Cavity). If None, clears all features.
- property corner: list[Corner]#
Get extracted corner features.
- Returns:
Tuple of Corner objects (immutable)
- property corner_reliefs: list[CornerRelief]#
Get extracted corner relief features.
- Returns:
List of CornerRelief objects.
- property embosses: list[Emboss]#
Get extracted emboss features.
- Returns:
Tuple of Emboss objects (immutable)
- extract_all(blend_max_radius: float | None = None) None#
Recognize all available features for the shape.
- Parameters:
blend_max_radius – Maximum radius for blend recognition, in the model’s own length units; omitted, a fraction of the model’s own size.
- extract_blends(max_radius: float | None = None) None#
Recognize blend features and store them internally.
- Parameters:
max_radius – The maximum radius for blend recognition, in the model’s own length units. Omitted, it is taken as a fraction of the model’s own size, so the same call recognizes the fillets of a part modelled in millimetres and of one modelled in metres.
- extract_cavities() None#
Recognize cavity features and store them internally.
- extract_chamfers(convex_only: bool = True, max_offset_ratio: float = 0.5, min_angle_degrees: float = 5.0) None#
Recognize chamfer features and store them internally.
- Parameters:
convex_only – If True, only detect convex chamfers. Default True.
max_offset_ratio – Maximum ratio of chamfer offset to model diagonal.
min_angle_degrees – Minimum angle between under-faces in degrees.
- extract_deformations(extractor_class: type[DeformationExtractor] = <class 'volmdlr_tools.features.extractors.sheet_metal.region_deformation.RegionDeformationExtractor'>) None#
Recognize deformation features (embosses, flanged cutouts) and store them internally.
- Parameters:
extractor_class – The extractor driving the recognition. Defaults to the region-based extractor, which also finds deformations merged with cutout rims or the sheet boundary; pass
DeformationExtractorfor the wire-seeded one.- Raises:
ValueError – If the shape is not a sheet metal.
- extract_interacting_features() None#
Extract interacting machining features using the Sunil et al. (2010) algorithm.
- extract_lances() None#
Recognize lance features and store them internally.
- Raises:
ValueError – If the shape is not a sheet metal.
- extract_ribs(max_thickness: float | None = None, blend_max_radius: float | None = None, pair_finder: str = 'edge_driven') None#
Recognize rib features (and rib structures) and store them internally.
Not part of
extract_all()— rib recognition walks the whole AAG and is markedly slower than the other extractors, so it is opt-in. Until it is called,ribsandrib_structuresare empty.- Parameters:
max_thickness – Maximum wall thickness for a rib, in the model’s units. When omitted it defaults to a fraction of the model’s bounding-box diagonal, so the threshold is unit-agnostic; pass an explicit value to constrain recognition to a known wall thickness.
blend_max_radius – Maximum fillet radius recognized as a blend and passed over when collecting a rib’s shell and base faces. When omitted it defaults to a fraction of the bounding-box diagonal, for the same unit-agnostic reason as
max_thickness.pair_finder – Which candidate end-face pair finder the
RibExtractorruns —"edge_driven"(default),"face_pair", or the experimental"nearly_planar"that also admits nearly-planar BSpline/Offset end faces. Same names and defaults asRibExtractoritself.
- Raises:
ValueError – If
pair_finderis not one of the three names.
- extract_sharp_edges() None#
Recognize sharp edge features and store them internally.
- extract_sheet_metal_features() None#
Recognize sheet metal features and store them internally by type.
- Raises:
ValueError – If the shape is not a sheet metal.
- features_volume_model(features: list[Feature]) VolumeModel#
Display features alongside the original shape in a VolumeModel.
- filter_blend_chains(min_radius: float | None = None, max_radius: float | None = None, min_length: float | None = None, max_length: float | None = None) list[BlendChain]#
Filter blend chains based on criteria.
- Parameters:
min_radius – Minimum chain radius
max_radius – Maximum chain radius
min_length – Minimum chain length
max_length – Maximum chain length
- Returns:
Filtered list of blend chains
- filter_blends(min_radius: float | None = None, max_radius: float | None = None, blend_type: str | None = None, confirmed_only: bool = False) list[Blend]#
Filter blends based on criteria.
- Parameters:
min_radius – Minimum blend radius
max_radius – Maximum blend radius
blend_type – type of blend to filter (as string name)
confirmed_only – If True, only return confirmed blends
- Returns:
Filtered list of blends
- filter_by_category(category: str, location: str | None = None) list#
Filter features by category and optionally by location.
- Parameters:
category (str) – Feature category (“cut”, “forming”, “blend”, “cavity”, “unknown”)
location (Optional[str]) – Optional location filter (“boundary”, “internal”)
- Returns:
List of features matching the criteria
- Return type:
list
- filter_by_location(location: str) list#
Filter all features by location.
- Parameters:
location (str) – Location filter (“boundary” or “internal”)
- Returns:
List of features at the specified location
- Return type:
list
- filter_cavities(min_depth: float | None = None, max_depth: float | None = None) list[Cavity]#
Filter cavities based on depth criteria.
- Parameters:
min_depth – Minimum cavity depth
max_depth – Maximum cavity depth
- Returns:
Filtered list of cavities
- get_cut_features(location: str | None = None) list#
Get all cut features (slots, notches, corner reliefs, clips).
- Parameters:
location (Optional[str]) – Optional location filter (“boundary”, “internal”)
- Returns:
List of cut features
- Return type:
list
- get_feature_count() dict[str, int]#
Get count of all extracted features.
- Returns:
Dictionary mapping feature class names to counts
- get_forming_features(location: str | None = None) list#
Get all forming features (bends, jogs).
- Parameters:
location (Optional[str]) – Optional location filter (“boundary”, “internal”)
- Returns:
List of forming features
- Return type:
list
- has_features(feature_type: type[Feature] | None = None) bool#
Check if any features have been extracted.
- Parameters:
feature_type (Optional[type[Feature]]) – Optional feature class to check (e.g., Bend, Jog). If None, checks if any features exist.
- Returns:
True if features exist, False otherwise
- Return type:
bool
- property holes: tuple[Hole, ...]#
Get extracted hole features.
- Returns:
Tuple of Hole objects (immutable)
- property is_sheet_metal: bool#
Check if the shape is a sheet metal.
- Returns:
True if shape is sheet metal, False otherwise
- property lances: list[Lance]#
Get extracted lance features.
- Returns:
Tuple of Lance objects (immutable)
- property louvre: list[Louvre]#
Get extracted louvre features.
- Returns:
Tuple of Louvre objects (immutable)
- property notches: list[Notch]#
Get extracted notch features.
- Returns:
Tuple of Notch objects (immutable)
- plot_features_graph(features_to_highlight: list[Feature] | None = None, show_labels: bool = True)#
Plot the AAG with features highlighted.
- Parameters:
features_to_highlight – Optional list of features to highlight in the graph. If None, highlights all extracted features.
show_labels – Whether to show node labels.
- Returns:
Matplotlib figure or graph visualization object.
- property pockets: tuple[Pocket, ...]#
Get extracted pocket features.
- Returns:
Tuple of Pocket objects (including OpenPocket, immutable)
- post_process_unknown_features(internal_features: list[Feature]) list[Feature]#
Reclassify unknown internal features adjacent to multiple blends as CutoutWithBendInternal.
- property rib_max_thickness: float | None#
The wall-thickness threshold rib recognition actually applied.
Differs from the
max_thicknesspassed toextract_ribs()when the scale-aware default was tightened to the part’s measured walls. None untilextract_ribs()has run.
- property rib_structures: list[RibStructure]#
Get extracted rib structures (groups of segments meeting at junctions).
Empty until
extract_ribs()is called.
- property ribs: list[Rib]#
Get extracted rib segments. Empty until
extract_ribs()is called.
- property sharp_edges: list[Edge, ...]#
Get extracted sharp edge features.
- Returns:
Tuple of Edge objects (immutable)
- property sheet_metal: SheetMetalShape | None#
The recognized sheet-metal shape, or None when the shape is not a sheet metal.
Use it to drive an extractor directly (e.g.
DeformationExtractor(sheet_metal=...)); recognition runs once and is cached.
- show_cavities() dict#
Implementation of a tag for displays.
- show_features(feature_type: type[Feature] | None = None) dict#
Implementation of a tag for displays.
- property slots: tuple[Slot, ...]#
Get extracted slot features.
- Returns:
Tuple of Slot objects (including all subtypes, immutable)
- property steps: tuple[Step, ...]#
Get extracted step features.
- Returns:
Tuple of Step objects (including BlindStep, immutable)
- to_markdown() str#
Return a markdown summary of extracted features.
Includes feature counts, category breakdown (cut/forming with boundary/internal split), and classification summary statistics.
- Returns:
Markdown-formatted string
- Return type:
str
- property unknown_features: list[UnknownFeature]#
Get extracted unknown features.
- Returns:
List of UnknownFeature objects (immutable)
- view(feature_type: type[Feature] | None = None) None#
Open the recognized features, colored, in the local DocModel viewer.
Developer-workstation convenience (interactive side effect, no return value) kept out of
show_features()so the@cad_viewplatform contract stays “return babylon display data”.- Parameters:
feature_type – Same selection as
show_features().- Raises:
ValueError – If
feature_typeis not among the extracted types.
- class volmdlr_tools.features.FeaturesRecognizer(*args, **kwargs)#
Bases:
FeatureProcessorBackward compatibility alias for FeatureProcessor.
- . deprecated:: v1.0.0
Use FeatureProcessor instead. This alias will be removed in version 1.0.0.
- blends_recognition(max_radius: float)#
Deprecated method for backward compatibility.
- . deprecated:: v1.0.0
Use extract_blends() instead.
- cavities_recognition()#
Deprecated method for backward compatibility.
Deprecated since version v1.0.0: Use extract_cavities() instead.
- cavitivies_recognition()#
Deprecated alias for cavities_recognition() (legacy misspelling).
- emboss_recognition()#
Deprecated method for backward compatibility.
- . deprecated:: v1.0.0
Use extract_embosses() instead.
- sharp_edges_recognition()#
Deprecated method for backward compatibility.
- . deprecated:: v1.0.0
Use extract_sharp_edges() instead.
- class volmdlr_tools.features.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.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.
- class volmdlr_tools.features.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.
- class volmdlr_tools.features.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.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.