Interspace Filling (inter-part)#
Watertight plugs for the sub-fist pockets between the parts of an assembly.
Interspace Filling (inter-part)#
volmdlr_tools.meshes.cavity_filling also seals the pockets between parts: the interstices
of an assembly that an operator fist cannot reach. Where the intra-part pipeline (see the
Cavity Filling page) plugs the openings of one part, interspace filling produces watertight
plugs for the inaccessible volume between several parts — the gap under a duct, the channel
between a housing and its bracket, the labyrinth behind two stacked panels.

Quick start#
On DocModels (one group per file/DocModel, the business unit for the fist rule):
from volmdlr.assembly import DocModel
from volmdlr_tools.meshes.cavity_filling import InterspaceParameters, fill_interspace, print_inter_reports
doc_models = [DocModel.from_step(path) for path in ("housing.stp", "duct.stp", "bracket.stp")]
parameters = InterspaceParameters(fist_diameter=0.080) # lengths in meters
collection, reports = fill_interspace(doc_models, parameters, parallel_workers=4)
print_inter_reports(reports)
The same call accepts VolumeModels of Mesh3D — e.g. one CAD Import workflow output per
file, each model being one group — bare Mesh3D elements (single-mesh groups), or any mix of
the three:
collection, reports = fill_interspace([traverse_vm, hvac_vm, env_vm], parameters)
On raw part dicts (any meshes, no DocModel needed):
from volmdlr_tools.meshes.cavity_filling import InterspaceParameters, fill_interspace_parts
parts = [
{"identifier": "housing", "vertices": vertices_a, "triangles": triangles_a},
{"identifier": "duct", "vertices": vertices_b, "triangles": triangles_b},
]
collection, reports = fill_interspace_parts(parts, InterspaceParameters())
Patches come back as the same Patch/PatchCollection models as intra filling, with
patch_type = "inter" and source_part_ids naming the two parts each plug is attributed to.
Intra first#
Run intra filling first and merge its patches into each part’s mesh before calling interspace filling: the intra plugs become matter, so designed openings already sealed at the part level are never re-detected as inter-part pockets, and pockets that leak through a part’s own holes are closed before the between-parts analysis runs.
What it does#
Parts closer than a fist are grouped into proximity clusters, and each cluster is analyzed on a
voxel lattice (pitch = fist_diameter / 16 by default). The pockets — the free space the fist
can never reach — are detected, judged, and each genuine one is sealed by a closed, watertight
surface of the pocket volume itself: no boundary, hence no possible hole, even on labyrinthine
interstices. The plug sits flush against both walls, bulges across every opening, and blocks the
fist by definition — it is the region the fist cannot reach.
Each detected pocket is judged before sealing; the drops are reported per cluster:
Verdict |
Meaning |
Reported as |
|---|---|---|
contact |
too tight to matter (below |
|
single-part |
bounded by one part only: intra territory, never an inter patch |
|
sealed shell |
hollow interior of a closed part: no mouth, nothing to seal |
|
concave wedge |
mostly open boundary (fillet along a crease, not a passage) |
|
genuine pocket |
everything else: sealed |
|

Plugs smaller than minimum_patch_area are dropped as slivers; each surviving plug is
attributed to the two parts it hugs, and its gap width is encoded in the patch name:
ipatch_012|g34mm|housing+duct|inter.
On a full vehicle-zone assembly (three groups, millions of triangles, intra plugs merged first), the 80 mm fist detects the inter-group pockets and seals them with a few dozen watertight blobs in about a minute.
Parameters#
All lengths are in meters. InterspaceParameters is a dessia Model, usable directly in
platform forms.
Field |
Default |
Role |
|---|---|---|
|
0.080 |
The metric criterion: pockets this fist cannot reach are sealed |
|
|
Lattice pitch; |
|
0.005 |
Pockets with a narrower widest gap are unusable contacts, dropped |
|
0.0004 |
Plugs below this area are slivers, dropped |
|
0.7 |
Pockets whose boundary is more open than this are concave wedges, dropped |
|
40e6 |
Memory budget: larger cluster grids get a coarser lattice, not a crash |
|
|
Participating DocModel names for |
|
|
|
Reports#
One report dict per proximity cluster; print_inter_reports renders one line per cluster plus
aggregate totals: pockets, patches, sealed, dropped_contact, dropped_open,
dropped_single_part, dropped_sliver, the grid shape, the resolved voxel_size and per-stage
timings.
Guarantees and limitations#
A plug is watertight by construction (closed surface) and blocks the fist by definition — it is the inaccessible volume itself, not a fitted membrane.
Detection resolution is the lattice pitch: gaps thinner than ~2 voxels may register as contacts; lower
voxel_sizefor finer assemblies (at cubic memory cost, bounded bymax_grid_voxels).Plug geometry is lattice-born: flush against walls within one voxel, smoothed but not exact CAD offsets. For openings within a single part, use the intra pipeline — its patches ride the actual CAD rims.
granularity="group"applies the fist rule between named groups only; self-pockets of a group (between its own meshes) are intentionally out of scope there.