Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Filaire

Standard cable assets generator for Physical AI.

CI Python 3.10+ License: MIT

Filaire generates cables of standard types (power cords, USB, Ethernet, HDMI, audio, microphone, speaker wire, sensor, ribbon and coiled handset cords, DC barrel and Micro-USB) with their real connectors, male and female, or with cut or stripped ends, and exports them to OpenUSD as physics-ready assets: a chain of rigid segments with UsdPhysics joints whose springs come from the cable's bending and torsional stiffness. Every connector comes with the receptacle it plugs into (device port, inlet, wall socket, panel connector, or the female end of an extension), derived from the plug so that the two always mate. The assets are checked in MuJoCo (dropped on the ground, sagging like a beam, plugged in at the right and wrong angles) and in Blender, where an add-on sets the rigid bodies and joints up by itself when a file is imported. Every file passes OpenUSD's own validators.

It is built for Physical AI: robots that route, plug and unplug cables are trained and tested in simulation, and they need many different cables with exact ground truth, not one capsule chain. Everything can run on CPU. Filaire belongs to a series with Granulaire (granular assets), Maillage (textiles) and Quincaillerie (fasteners, cells and holders), and follows the same approach: distributions instead of one shape, measured outputs, honest limits.

Cables generated by Filaire, rendered in Blender

One cable of each of the 14 presets, with its usual ends (left: power cords C13 and C7, DC barrel, USB-C, USB-A to C, USB-A to Micro-B, Ethernet; right: HDMI, 3.5 mm jack, XLR microphone cable, speaker wire, M12 sensor cable, IDC ribbon, coiled handset cord), imported from the OpenUSD files into Blender and rendered with Cycles.

What it does

  • Generates N cables of a preset, 1 m long by default (--length for another length, or the preset's retail lengths), lying straight, as a slack random curve or coiled on the floor.
  • Puts on each end, independently, a connector plug, a receptacle on a cable (the female end of an extension or a coupler), a clean cut or a stripped end with the cores out: 17 connector families, 28 end variants, any of them on any cable.
  • Models the cable as a Kirchhoff rod: rigid segments of 1.5 cable widths, joints with twist and bending springs G·J / L and E·I / L computed from the cross-section (round, figure-8 zip cord, flat ribbon; coiled cords as a helical spring), real masses.
  • Derives every receptacle from its plug, layer by layer, with a clearance; the keying (any angle, reversible, one orientation) is found from the geometry and checked against the standard.
  • Exports OpenUSD: one rigid body per segment and per connector, each with one visual mesh (so every DCC imports one object per body), mass, centre of mass and inertia, convex collision parts, joints with drives, PhysX attributes for Isaac Sim, a variant set per end (all the end variants of a cable in one asset), a MateFrame on each connector with its insertion axis, depth, clearance, keying and contact gender; and a sockets.usdc file with the fixed receptacles. --no-physics writes visual assets only. Every file passes the OpenUSD validators (UsdValidation).
  • Checks the assets in MuJoCo (filaire sim-test), read back from the files: drop on the ground, cantilever sag against beam theory, coil extension against spring theory, insertion at 0°, 90° and 180°.
  • A Blender add-on (filaire blender-addon): rigid bodies and constraints set up on every USD import, and the same drop check in Blender (filaire blender-test).

Installation

From PyPI:

pip install "filaire[render,sim]"

From a clone, for development:

python -m venv .venv && source .venv/bin/activate
pip install -e ".[render,sim]"      # add ",dev" for tests and linting

Requires Python 3.10+. Dependencies: NumPy, SciPy, Shapely 2.1+ and the OpenUSD bindings (usd-core); matplotlib for the previews, MuJoCo for the checks. The Blender checks need Blender as a Python module (pip install -e ".[blender]", Python 3.13 only) or a Blender executable.

Usage

filaire list                                         # presets
filaire ends                                         # every end variant
filaire generate --preset usb_c                      # 6 cables, 1 m each
filaire generate --preset ethernet --length 3 --layout coil
filaire generate --preset power_c13 --end-a c13_plug --end-b stripped
filaire generate --preset usb_c --end-a usb_c_plug --end-b usb_c_inline   # an extension cord
filaire generate --preset hdmi --length preset --count 12 --seed 4        # retail lengths
filaire generate --preset audio_jack --color "#c0392b" --modulus 45
filaire preview output/usb_c                         # top view (matplotlib)
filaire connectors --out connectors.png              # plug faces and receptacles
filaire generate --preset hdmi --no-physics          # visual assets only
filaire sim-test output/usb_c                        # MuJoCo checks
filaire blender-test output/usb_c                    # the drop check in Blender (add-on)
filaire blender-addon                                # filaire_physics.zip, for Blender 4.4+

python -m filaire ... works too. From Python:

from filaire import generate_scene, write_outputs

cables = generate_scene("usb_c", count=6, seed=1)  # 1 m, ends drawn from the preset
write_outputs(cables, "output")  # -> output/usb_c/

# 2.5 m power cords coiled on the floor, C13 on one end and a stripped end on the other
cords = generate_scene(
    "power_c13", count=4, length=2.5, layout="coil", ends={"a": "c13_plug", "b": "stripped"}
)
write_outputs(cords, "output")

Options of filaire generate

Option Default Effect
--preset usb_c cable type (table below)
--count N, --seed S 6, 1 number of cables, random seed; same options and seed give the same cables
--length L 1 length in m of every cable; preset draws the preset's retail lengths (± tolerance)
--end-a V, --end-b V preset's draw end variant of each end, independently: any filaire ends entry, on any cable
--layout preset's draw straight, slack (random smooth curve) or coil (flat spiral on the floor)
--color "#rrggbb" preset's draw jacket colour of every cable
--modulus E preset's draw effective Young's modulus of the cable in MPa (sets the stiffness)
--max-segments N 400 upper bound on the rigid segments per cable (longer segments beyond it)
--no-physics visual assets only: no rigid bodies, colliders, joints, physics scene or ground
--no-vary-… turn one random aspect off, the others unchanged: layout, ends, color, stiffness, density, length

Each random aspect has its own stream: turning one off or forcing it leaves the others as they were (same layouts with plain colours, same colours with other ends…).

Presets

Category Preset Cross-section End A End B (default draw)
Power power_c13 round Ø6.4 mm, 3 cores C13 CEE 7/7 plug, C14 (extension), stripped
power_c7 figure-8, 2 × Ø3.4 mm C7 Europlug, stripped
dc_barrel figure-8, 2 × Ø2.4 mm DC plug 5.5 × 2.1, 5.5 × 2.5 or 4.0 × 1.7 stripped, cut, DC jack (extension)
Data usb_c round Ø4.0 mm USB-C plug USB-C plug, USB-C receptacle (extension)
usb_a_to_c round Ø3.8 mm USB-A plug USB-C plug
usb_micro round Ø3.5 mm USB-A plug Micro-B plug
ethernet round Ø6.0 mm, 4 pairs RJ45 plug RJ45 plug, RJ45 coupler
hdmi round Ø7.0 mm HDMI plug HDMI plug, HDMI receptacle (extension)
Audio audio_jack round Ø3.5 mm 3.5 mm plug 3.5 mm plug, 3.5 mm socket (extension)
xlr_mic round Ø6.0 mm XLR3 female XLR3 male
speaker_wire figure-8, 2 × Ø3.2 mm stripped, cut stripped, cut
Industrial m12_sensor round Ø5.0 mm, PUR M12 female stripped, cut
ribbon_idc flat, 10 × 1.27 mm IDC socket 2 × 5 IDC socket, cut
Telephone coiled_handset coil Ø8.5 mm of Ø2.8 mm wire RJ9 plug RJ9 plug

Every cable also carries cut and stripped variants on both ends, and any other variant forced with --end-a / --end-b. Diameters, densities (8–90 g/m) and moduli (20–300 MPa, drawn per cable) are realistic orders of magnitude, not measurements of a specific product.

The 14 presets, one cable each

Each preset with its usual ends (the first variant of each end), 40 cm long (25 cm for the ribbon and the coiled cord), rendered in Blender.

Connectors

Every plug on its cable, 15 mm in front of its receptacle

The 17 connector families: each plug on a short piece of its cable, 15 mm in front of the fixed receptacle derived from it (sockets.usdc), rendered in Blender.

Family Cable side (plug) Contacts Receptacle on a cable Fixed receptacle Keying Depth
usb_c USB-C plug male USB-C receptacle USB-C port reversible 6.65 mm
usb_a USB-A plug male USB-A port keyed 12 mm
usb_micro Micro-B plug male Micro-B port keyed 5.6 mm
hdmi_a HDMI plug male HDMI receptacle HDMI port keyed 9.5 mm
rj45 RJ45 plug male RJ45 coupler RJ45 jack keyed 14 mm
rj9 RJ9 plug male RJ9 handset jack keyed 10 mm
jack35 3.5 mm plug male 3.5 mm socket 3.5 mm socket none 15 mm
c13 C13 connector female C14 plug C14 inlet keyed 13 mm
c7 C7 connector female C8 inlet reversible 10 mm
cee77 CEE 7/7 plug male wall socket (simplified) reversible 34 mm
cee716 Europlug male Europlug socket (simplified) reversible 25 mm
xlr3 XLR3 female female XLR3 male XLR3 male (panel) keyed 11 mm
m12a M12 A-coded female female M12 male (panel) keyed 8 mm
idc10 IDC socket 2 × 5 female box header 2 × 5 keyed 6 mm
dc5521, dc5525, dc4017 DC plug 5.5 × 2.1, 5.5 × 2.5, 4.0 × 1.7 mm male DC jack DC jack none 9.5 mm

Gender and role are kept apart. Gender is the contact gender of the standard; role is geometric: the plug enters, the receptacle receives. An IEC C13 has female contacts but enters the C14 inlet; an XLR3 female enters the shell of the male. filaire:contactGender and filaire:role say both.

The receptacle is derived from the plug. Each plug is described by its cross-sections, layer by layer from the tip (a CEE 7/7 plug: two pins, then the round face that enters the socket's recess). In each layer, the receptacle's solid is its outline minus the plug's cross-section grown by the clearance (0.05–0.3 mm). The plug's holes become the receptacle's pins or tongue, the plug's key becomes the keyway, and the two always mate. The keying is then found by turning the plug in 15° steps and testing for overlap, and a test checks it against the standard's.

The same test answers which plug goes into which receptacle across families (fits(plug, angle, socket=other)). For the DC barrels it gives the real behaviour: the derived jacks get a centre pin from the plug's bore, so a 5.5 × 2.5 mm plug goes loosely onto a 5.5 × 2.1 mm jack, while a 5.5 × 2.1 mm plug is stopped by the thicker pin of a 5.5 × 2.5 mm jack.

Plug faces and the receptacles derived from them

filaire connectors: the plug seen from its tip (left) and the fixed receptacle seen from the front (right): opening in dark, pins and tongues in light grey.

Dimensions come from published figures where they could be found (USB-C receptacle opening and insertion length, HDMI plug and receptacle, RJ45 and RJ9 widths and heights, 3.5 mm diameter and length, CEE 7 pins and recess depth, IEC 60320 pin spacing, Micro-B receptacle opening, DC barrel diameters and the 4.0 × 1.7 mm barrel length); the others (XLR, M12, IDC, C13 face, Micro-B chamfers, 5.5 mm barrel length, inner cavities, overmolds) are approximate and marked so in connectors.py, each with its sources. The standards themselves were not consulted. Connectors are simplified: no latches that move, no threads, no contacts inside the holes, no logos.

Outputs (per preset, under output/<preset>/)

File Content
filaire_<preset>.usdc the cables (OpenUSD, Blender: File > Import > USD)
sockets.usdc one fixed receptacle per connector family used by the cables
cables.csv per cable: layout, length, ends, colour, modulus, densities, stiffness, segments, masses
summary.json counts by layout, end and colour; length, mass, stiffness and segment ranges
sheet.png top view (filaire preview)
sim_test/sim_test.json MuJoCo report (filaire sim-test)
sim_test/blender_setup.json, sim_test/blender_naive.json Blender reports and their scenes (filaire blender-test)

OpenUSD layout

Z up, metres, kilograms, /World the default prim.

/World
  /PhysicsScene                  gravity
  /Looks, /PhysicsMaterials      UsdPreviewSurface materials; friction and restitution
  /Cables/<cable>                Xform, PhysicsArticulationRootAPI, filaire:* attributes,
                                 variant sets "end_a" and "end_b"
    /Segments/seg_000 …          rigid bodies (RigidBodyAPI, MassAPI, PhysxRigidBodyAPI), x along the cable
      /Visual                    ONE mesh: the piece of tube this segment carries
      /Collision                 Capsule along x (round, coiled) or Cube (flat, figure-8), purpose guide
    /Joints/joint_000 …          PhysicsJoint: translations locked (coiled: transX free),
                                 drives rotX (twist), rotY, rotZ (bending) [, transX (coil)]
    /End_A, /End_B               filled by the selected variant:
      /Body                      rigid body of the connector or stripped end
        /Visual                  ONE mesh, a GeomSubset per material (shell, body, cores, copper)
        /Collision/hull_00 …     convex parts (MeshCollisionAPI convexHull, purpose guide)
        /MateFrame               origin on the mating plane, +Z = insertion direction
      /Attach                    PhysicsFixedJoint to the end segment
  /Ground                        collision box, its top face at z = 0

Each rigid body has exactly one visual mesh, as in Quincaillerie: Blender and other DCCs import one object per body, so a rigid body set on it moves the whole part. Each segment spans the chord between its two joints, so neighbouring segments meet exactly at their joint even on a tight curve. Every collider carries PhysxCollisionAPI offsets and every body PhysxRigidBodyAPI iterations, read by Isaac Sim and ignored elsewhere.

Without physics (--no-physics, write_outputs(…, physics=False)): each cable is one mesh, /World/Cables/<cable>/Visual, each end a Body with its Visual and MateFrame; no rigid bodies, colliders, joints, physics materials, physics scene or ground. The filaire:* attributes stay.

OpenUSD compliance. filaire.validate.validate(file) runs every validator of OpenUSD's UsdValidation registry (composition, stage metadata, geometry and subsets, material bindings, shaders, UsdPhysics bodies, colliders, joints and articulations) on each end variant of each cable; the tests and CI require no error and no warning, with and without physics.

Selecting a variant (end_b = "usb_c_inline", "cut"…) swaps the end, its collision parts and its joint. Angular drives use UsdPhysics units (stiffness per degree); the same values per radian and the rod's stiffness are kept as engine-neutral attributes:

Attribute (on the cable) Content
filaire:bendingStiffness E·I about the width axis and about the height axis (N·m²)
filaire:torsionalStiffness G·J (N·m²)
filaire:jointStiffness per joint: twist, bend y, bend z (N·m/rad)
filaire:youngsModulus, filaire:shearModulus, filaire:linearDensity material (Pa, kg/m)
filaire:segmentLength, filaire:segmentCount, filaire:restShape discretisation; rest shape is straight
filaire:dampingTime joint damping = stiffness × 0.01 s
filaire:coil:*, filaire:axialStiffness coiled cords: coil diameter, pitch, turns, wire length; spring k (N/m)
filaire:length, filaire:layout, filaire:profile, filaire:jacket, … what the cable is
Attribute (on a MateFrame) Content
filaire:connector, filaire:name, filaire:standard family and name (usb_c, "USB-C plug")
filaire:role, filaire:mount, filaire:contactGender plug / receptacle, cable / panel, male / female
filaire:insertionDepth, filaire:clearance, filaire:keying for insertion tasks (m)

Physics model

  • Rod. The cable is a chain of N rigid segments (length ≈ 1.5 cable widths, at most 400 per cable). Consecutive segments share a joint at their common end point with three rotational springs: twist G·J / L, bending E·I_y / L and E·I_z / L, the discrete Kirchhoff rod. E·I and G·J come from the cross-section (polygon second moments, so a flat ribbon is a hundred times softer across its thickness than across its width) and an effective modulus drawn per cable; G = E / (2 (1 + ν)), ν = 0.45. The rest shape is straight; the authored pose (slack, coiled) is a deformed state.
  • Coiled cords are modelled along their axis, as a helical spring seen as a rod (Wahl's close-coiled formulas): bending 2 E I p / (π D (2 + ν)), twist E I p / (π D), and an axial spring 4 G J / (π D³ n) shared by free transX joints. The coil itself is in the visual mesh.
  • Masses from the linear density; connectors from the volume of their parts and an effective density; inertia tensors from the meshes.

Blender

Blender's USD importer reads geometry and materials but ignores UsdPhysics: imported as is, a cable is a heap of loose tube pieces and its connectors fall off (see the comparison below). The add-on, adapted from Quincaillerie's, sets the physics up once and for all:

  1. filaire blender-addon writes filaire_physics.zip.
  2. In Blender (4.4 or later): Edit > Preferences > Get Extensions > Install from Disk, pick the zip.
  3. File > Import > Universal Scene Description, as usual: every segment and connector gets its rigid body, every joint its constraint. Press Play.

On import it moves each body's origin to its centre of mass (Blender uses the origin as centre of mass), makes its collision shape a compound of the USD shapes (capsules, boxes and convex hulls rebuilt from the file), sets mass, friction and small collision margins, turns the cable joints into Generic Spring constraints with the USD drives' stiffness and damping (translations locked; a coiled cord's axial spring kept) and the connectors' fixed joints into Fixed constraints, and runs the rigid body world at 4000 substeps per second for the light segments. The same file runs as a script (blender -b -P filaire_physics.py -- file.usdc) without installing.

Bullet takes a spring's rest position from the first frame, so in Blender a cable keeps the shape it was generated in (coiled, slack) as its rest shape, where the file and MuJoCo say straight: a coiled cable stays coiled.

MuJoCo checks

filaire sim-test output/<preset> reads the OpenUSD files back (not the generator's objects) and runs, on CPU:

Check What Pass when
drop the first cables, with their selected ends, lifted 1 cm and dropped for 3 s in their authored layout finite, ground penetration below half the cable radius after the impact, all bodies slower than 5 cm/s at the end
sag a sample of the cable clamped at one end, sagging ≈ 10 % of its length under its own weight; E·I read back from the joint drives tip deflection within 5 % of w L⁴ / (8 E I)
coil coiled cords: the coil hanging from its top extension within 5 % of W / (2 k)
insertion each plug pushed along its axis (5 N max) into the fixed receptacle and the receptacle on a cable, at 0°, 90° and 180° goes fully in at the angles its keying allows, stopped before 60 % of the depth at the others

For speed, the drop test simulates the cable with at most 60 links (groups of segments merged, springs in series, same E·I) and without the twist hinge: in generalised coordinates a chain's mass matrix is dense and a step costs the cube of its joints. Each joint gets an armature (added inertia) and critical damping so that stiff, light links stay stable with a 1 ms step; neither changes a static equilibrium, which is what the sag and coil checks compare.

Five cables dropped onto a bar on the floor, simulated in MuJoCo

Power cord, Cat 6, USB-C, 3.5 mm jack and M12 sensor cable (70 cm), steeply tilted and dropped together onto a bar: one end hits first, the cables fold over the bar and over each other, connectors attached, and come to rest. Simulated in MuJoCo from the OpenUSD files (rest shape straight, 60 links per cable, 0.5 ms step), rendered in Blender: scripts/drop_gif.py.

Results

filaire generate --preset <p> --count 3 (1 m cables, seed 1) then filaire sim-test output/<p> --cables 3, MuJoCo 3.17, one CPU core:

Preset Segments E·I (N·m²) Mass with ends (g) Drop (max speed, penetration) Stiffness check Insertion
power_c13 104 0.0049–0.0073 119–187 3/3 (0.004 m/s, 0.10 mm) sag −0.8 % C13 panel + inline, CEE 7/7 ✓
power_c7 98 0.00066–0.00098 49–67 3/3 (0.002 m/s, 0.06 mm) sag −0.8 % C7, Europlug ✓
dc_barrel 139 0.00016–0.00026 30–33 3/3 (0.012 m/s, 0.09 mm) sag −0.8 % three DC jacks ✓
usb_c 167 0.00050–0.00080 46–50 3/3 (0.013 m/s, 0.18 mm) sag −0.8 % USB-C panel + inline ✓
usb_a_to_c 175 0.00041–0.00065 43–46 3/3 (0.004 m/s, 0.18 mm) sag −0.8 % USB-A, USB-C ✓
usb_micro 190 0.00029–0.00051 38–40 3/3 (0.004 m/s, 0.10 mm) sag −0.8 % USB-A, Micro-B ✓
ethernet 111 0.0050–0.0072 61–70 3/3 (0.005 m/s, 0.07 mm) sag −0.8 % RJ45 panel + inline ✓
hdmi 95 0.0094–0.0139 99–107 3/3 (0.005 m/s, 0.09 mm) sag −0.8 % HDMI panel + inline ✓
audio_jack 190 0.00022–0.00036 20–22 3/3 (0.003 m/s, 0.13 mm) sag −0.8 % 3.5 mm panel + inline ✓
xlr_mic 111 0.0013–0.0022 147–151 3/3 (0.007 m/s, 0.06 mm) sag −0.8 % XLR3 panel + inline ✓
speaker_wire 104 0.00042–0.00067 52–55 3/3 (0.024 m/s, 0.07 mm) sag −0.8 % (stripped / cut ends)
m12_sensor 133 0.0015–0.0023 65–68 3/3 (0.004 m/s, 0.03 mm) sag −0.8 % M12 ✓
ribbon_idc 52 0.00011–0.00017 14–16 3/3 (0.007 m/s, 0.06 mm) sag −0.8 % IDC ✓
coiled_handset 59 (coil) 130–139 3/3 (0.004 m/s, 0.07 mm) coil −0.0 % RJ9 ✓

Every keyed connector was stopped at 90° and 180° (at most 12 % of its depth, the IDC socket's flat face entering a little before its key meets the header), every reversible one went in at 180°, the 3.5 mm jack at every angle, like the DC barrels. The sag is 0.8 % under the linear beam formula for every cable: the geometric nonlinearity of a 10 % deflection, the same for all since the sample length is scaled to the stiffness. Generation takes 1–4 s per preset (3 cables), the checks 15–30 s (a minute for the coiled cords).

Blender checks

filaire blender-test output/<preset> builds, for each tested cable, a scene that references the cable file, keeps that cable (with its selected ends), lifts it 2 cm and drops it on the ground, then simulates it in Blender (Bullet) through the add-on, in its own process:

Check Pass when
joints hold the two bodies of every joint meet within 0.5 mm at its anchor, the connectors' fixed joints included
at rest on the ground no point more than 0.5 mm under the ground, every body slower than 5 cm/s after 1.5 s

--mode naive imports the same scene the way one would by hand (File > Import > USD, every mesh an active rigid body, the ground passive) and reports how far neighbouring pieces drift apart.

filaire generate --preset <p> --count 2 (1 m cables, seed 1), then filaire blender-test output/<p> --cables 2 and --mode naive on the first cable, Blender 5.2 (bpy), one CPU core:

Preset Through the add-on Bodies Widest joint gap (mm) Lowest point (mm) Rigid bodies by hand: pieces drifted apart (mm) Time per cable (s)
power_c13 2/2 106 0.005 −0.09 145 18
power_c7 2/2 100 0.006 +0.02 180 17
dc_barrel 2/2 141 0.009 +0.05 174 30
usb_c 2/2 169 0.005 +0.04 58 42
usb_a_to_c 2/2 177 0.005 +0.04 32 44
usb_micro 2/2 192 0.006 +0.04 35 47
ethernet 2/2 113 0.005 +0.01 40 21
hdmi 2/2 97 0.002 +0.03 40 16
audio_jack 2/2 192 0.006 +0.04 162 48
xlr_mic 2/2 113 0.008 −0.03 1634 21
speaker_wire 2/2 105 < 0.001 +0.05 10 18
m12_sensor 2/2 135 0.007 +0.02 818 25
ribbon_idc 2/2 54 < 0.001 −0.05 1240 7
coiled_handset 2/2 61 0.104 (axial spring) −0.10 2193 10

Through the add-on every cable holds together and comes to rest (a coiled cord's joints stretch along its axial spring, by design). Set up by hand, the pieces are independent: they spread over the floor, and where a heavy connector or a coil's overlapping pieces push on them, they are thrown metres away. The checks found a real defect of the first beta: on tight curves the rigid segments, as long as the arc they stand for, overlapped their neighbours by up to 0.4 mm at the joints; each segment now spans the chord between its joints.

Limits

  • Not calibrated. Moduli and densities are orders of magnitude; no cable's E·I was measured. The sag check proves the export is consistent with the model, not that the model matches a real cable.
  • Approximate connectors. See Connectors: simplified outlines, no moving latches, threads or contacts; several dimensions not from a source.
  • Elastic, straight rest shape. No plastic set (a real cable keeps its coils), no initial tension in coiled cords, no knots.
  • Isaac Sim not tested here. The files follow the standard UsdPhysics schemas (rigid bodies, D6 joints with drives, articulation root, convex hulls) and carry PhysX attributes; they are checked in MuJoCo and Blender but have not been loaded in Isaac Sim / PhysX (no NVIDIA GPU), where drive units and articulation behaviour may need adjusting.
  • Rest shape differs in Blender. See Blender: Bullet's springs rest in the first frame's pose, the generated one.
  • Visual per segment. Each segment carries its piece of tube, so a simulated cable shows small creases at the joints when it bends.

Roadmap

  1. Calibration against measured bending stiffness (three-point bending or cantilever tests) for a few real cables per preset.
  2. Plastic set and pre-coiled rest shapes; tied bundles and hanks.
  3. A PhysX test in Isaac Sim, and MJCF export with MuJoCo's cable plugin.
  4. More connectors (Schuko and French sockets with their earth contacts, D-sub with its screws, DisplayPort, M8) and snap-fit latches.
  5. Insertion tasks: forces, misalignment tolerances, success labels.

Development

The project follows GitHub Flow:

  1. main is always releasable and protected: changes reach it only through pull requests, nobody pushes to it directly.
  2. Every change starts on a short-lived branch from main, named after its type: feat/<name>, fix/<name>, docs/<name>, ci/<name>, …
  3. Push the branch and open a pull request into main; CI runs on it.
  4. Merge when CI is green, then delete the branch.

Releasing is a change like any other: on a chore/release-X.Y.Z branch, bump version in pyproject.toml and move the Unreleased entries of CHANGELOG.md under the new version; merge the pull request, then tag vX.Y.Z on main. The release workflow builds the packages and attaches them to the GitHub release.

A versioned pre-push hook refuses direct pushes to main. Enable it once per clone with git config core.hooksPath .githooks (emergency override: ALLOW_MAIN_PUSH=1 git push).

The README images are made by scripts/: make_logo.py (logo), readme_images.py (Blender renders through bpy of every preset and every connector family, connector sheet, GitHub social preview docs/images/social_preview.png, to upload in the repository's Settings > General > Social preview), drop_gif.py (the MuJoCo drop animation).

Continuous integration

Workflow When What
ci.yml every push to main, every pull request ruff check and ruff format --check; pytest on Python 3.10–3.13 (Linux) and 3.12 (macOS, Windows); a command-line smoke test with the OpenUSD validators; the MuJoCo checks of every preset; the Blender checks of every preset through the add-on (with the bpy module, Python 3.13), and for comparison the same with rigid bodies set by hand; reports kept as run artifacts; build the wheel and sdist, twine check, install the wheel in a clean environment.
release.yml a pushed tag v* checks the tag matches the version in pyproject.toml, tests, builds, then creates the GitHub release with the packages and the Blender add-on attached and the notes taken from CHANGELOG.md. Versions with a, b or rc are marked as pre-releases.
Dependabot monthly pull requests to update the GitHub Actions and the Python dependencies.

License

MIT © 2026 Daniel Régis Sarmento Caon

The logo is drawn from DejaVu Sans Bold outlines (Bitstream Vera license), converted to paths, so it displays without the font installed.


Filaire is part of Primvaria, physics-ready variability for Physical AI, in OpenUSD: pip install primvaria installs the whole suite.

Metadata

Release files for filaire 0.2.0b1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for filaire 0.2.0b1
File Size Uploaded Provenance Actions
filaire-0.2.0b1.tar.gz 104.1 kB With provenance Details for filaire-0.2.0b1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for filaire 0.2.0b1
File Interpreter ABI Platform Actions
filaire-0.2.0b1-py3-none-any.whl Python 3 none any Details for filaire-0.2.0b1-py3-none-any.whl

Total release size: 186.5 kB

Release files / filaire-0.2.0b1.tar.gz

Download URL filaire-0.2.0b1.tar.gz
Size 104.1 kB
Tags Source
SHA-256 checksum
How to use checksums
a1f60e8c8054a73a74cf76610480427d459d210837412f4bee3c72a886920c68
BLAKE2b-256 checksum
How to use checksums
381c88e921f7c9e06d099738849ce5094d32b33da5637db00b3462a91f67da88
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Release files / filaire-0.2.0b1-py3-none-any.whl

Download URL filaire-0.2.0b1-py3-none-any.whl
Size 82.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
25240601b4d655342230a0943698dff44e52633e4cf5934796466f124283b2cc
BLAKE2b-256 checksum
How to use checksums
c3dec9b1bf32cfb02a42eec94e0a5d4f0d708f38eae6f28b4914a34ee542f82a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Security for filaire 0.2.0b1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for filaire-0.2.0b1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page