volmdlr_tools.features.measurements package#

Geometric measurements taken on recognized features. Measurement functions are pure geometry — they quantify a feature without judging it; design-rule checks (material factors, tolerances, verdicts) belong to the caller.

Submodules#

volmdlr_tools.features.measurements.ribs module#

Rib thickness measurements.

Two quantities on a recognized Rib, matching the dimensions of injection-molding rib design rules (b <= e x rib_factor):

  • root thickness (the rule’s b): the wall thickness of the rib itself, measured at the rib’s bottom — just above the junction with the part wall, above the fillet tangency when root fillets exist, so the fillet radius is not part of the value. Ribs are drafted, so the root is the thickest section and the one design rules dimension.

  • wall thickness (the rule’s e): the thickness of each part wall the rib stands on (rib.base_face_nodes), measured by ray casting from the wall face, next to the rib’s attachment, through the solid to the far skin.

Both measurements sample per-location surface normals, so curved and nearly-planar (BSpline) faces are handled correctly. The rule check itself (material factor, tolerance, verdict) is client policy and deliberately NOT part of this module.

class volmdlr_tools.features.measurements.ribs.RibThicknessMeasurement(root_thickness: float | None, root_thickness_samples: list[float], wall_thickness_by_base_node: dict[int, float], end_face_nodes: list[int], note: str = '', rib: Rib | None = None, name: str = '')#

Bases: DessiaObject

The measured thicknesses of one rib: its root (b) and the walls it stands on (e).

Pure measurement record — it carries no verdict. Design rules compare root_thickness against wall_thickness (or the per-face dict, for a stricter aggregation) with their own material factor and tolerance.

The measured rib is identified by its AAG face indexes (end_face_nodes and the keys of wall_thickness_by_base_node); the live Rib object itself is kept only as a convenience for in-process callers and is not serialized — features are managed by their FeatureProcessor and do not round-trip on their own.

Parameters:
  • root_thickness – The rib’s thickness at its root (median of samples), or None when it could not be measured.

  • root_thickness_samples – The individual root ray measurements.

  • wall_thickness_by_base_node – Thickness of each part wall the rib stands on, keyed by AAG face index.

  • end_face_nodes – AAG face indexes of the measured rib’s end faces.

  • note – Non-empty when a fallback was used (e.g. the root could not be sampled and root_thickness echoes the extractor’s whole-wall value).

  • rib – The measured rib feature (in-process convenience, not serialized).

  • name – Optional name.

classmethod from_rib(aag: AttributedAdjacencyGraph, rib: Rib, root_maximum_hit: float | None = None, wall_maximum_hit: float | None = None, ray_caster: ShapeRayCaster | None = None, name: str = '') RibThicknessMeasurement#

Measure a rib’s root and wall thicknesses.

Parameters:
  • aag – The model’s attributed adjacency graph.

  • rib – The rib to measure.

  • root_maximum_hit – Far cutoff for the root rays, in model units; defaults to a few times the rib’s own wall thickness.

  • wall_maximum_hit – Far cutoff for the wall rays; defaults to half the model’s bounding-box diagonal (a wall cannot be thicker).

  • ray_caster – Optional pre-loaded caster over the whole model (ShapeRayCaster(aag.shape.wrapped)); pass one when measuring many ribs so the model is loaded once.

  • name – Optional name for the measurement.

Returns:

The populated measurement.

property wall_thickness: float | None#

Median wall thickness over the attached walls, or None when unmeasured.

The median is the robust default: a rib usually stands on one physical wall split into several faces, and a single face with a grazing ray exit would make a min unrepresentative. Clients wanting a stricter aggregation (e.g. the thinnest attached wall) can aggregate wall_thickness_by_base_node themselves.

volmdlr_tools.features.measurements.ribs.measure_rib_root_thickness(aag: AttributedAdjacencyGraph, rib: Rib, maximum_hit: float | None = None) tuple[float | None, list[float], str]#

Measure the rib’s thickness at its root (the design rules’ b).

For each end face, samples points on its root edges (shared with base faces, or with root fillets when the junction is filleted), lifts them slightly above the root onto the end face, and ray-casts along the local inward normal to the opposite side’s end faces. The result is the median of the samples.

Convention: the value is taken just above the root junction — above the fillet tangency when root fillets exist — so the fillet radius is not part of it, matching how rib design rules dimension b.

Parameters:
  • aag – The model’s attributed adjacency graph.

  • rib – The rib to measure.

  • maximum_hit – Far cutoff for accepted ray hits, in model units; defaults to _ROOT_MAXIMUM_HIT_THICKNESS_FACTOR times the rib’s own wall thickness (a root measurement past a few times the wall is noise).

Returns:

(root_thickness, samples, note). When the root cannot be sampled, root_thickness falls back to rib.thickness and the note says so; the function never raises for a degenerate rib.

volmdlr_tools.features.measurements.ribs.measure_rib_wall_thickness(aag: AttributedAdjacencyGraph, rib: Rib, maximum_hit: float | None = None, ray_caster: ShapeRayCaster | None = None) dict[int, float]#

Measure the thickness of each part wall the rib stands on (the rules’ e).

Samples points on each base face next to the rib attachment (pulled laterally away from the root so the ray does not travel through the rib itself), ray-casts along the inward normal through the solid, and takes a trimmed median per face — robust against rays that exit through an opposing rib on the far skin (gross overestimates of the wall).

Parameters:
  • aag – The model’s attributed adjacency graph.

  • rib – The rib whose attached walls are measured.

  • maximum_hit – Far cutoff for accepted ray hits, in model units; defaults to half the model’s bounding-box diagonal (a wall cannot be thicker than that).

  • ray_caster – Optional pre-loaded caster over the whole model; pass one when measuring many ribs so the model is loaded once.

Returns:

Wall thickness per base face, keyed by AAG face index. Faces yielding no usable ray are absent from the dict; the dict is empty when the rib has no thickness (the sampling offsets and the self-hit cutoff scale with it, and a machine-epsilon cutoff is the documented near-zero-thickness failure mode — see RIB_THICKNESS_SELF_HIT_FRACTION in features.constants).