Skip to main content

Parametric print-in-place piano hinge for clamshell cases, in build123d

Project description

pip-hinge

A parametric print-in-place piano hinge in build123d, designed for clamshell cases.

Four inputs:

from pip_hinge import HingeParams, Knuckle, make_hinge

hinge = make_hinge(HingeParams(
    case_h        = 10,             # case wall height (mm)
    hinge_length  = 60,             # total hinge length along the axis (mm)
    stations      = 6,              # alternating cs/ps tab count (even, ≥ 2)
    knuckle       = Knuckle.FULL,   # FULL = "bump on top", no ramp needed
))

make_hinge() returns a 2-body Compound: the cylinder-side leaf (with bored knuckle tabs) and the pin-side leaf (with the integral pin).

In context: a flat-open clamshell with HALF knuckle

clamshell with HALF knuckle and corner magnet pockets, flat-open print orientation

Built by examples/clamshell.py — case_h = 10mm, 80 × 50 mm footprint, 60 mm hinge with Knuckle.HALF, plus four 6 × 3 mm corner magnet pockets to latch the case shut. Both halves print as one piece in the orientation shown. The example also emits a bare HALF/FULL variant (no magnets) for reference.

Parameter reference

parameters guide

Cross-section (Panel A) shows the spatial parameters: case_h (wall height), PIVOT_Z_OFFSET (extra lift), mounting_flat (flat past the disc edge), plus the derived Po/Ro/T/W and the pin/bore inset. Top view (Panel B) shows hinge_length, stations, derived clasp_width, and clasp_clearance between meshing tabs.

The two knuckle options

knuckle options

knuckle knuckle diameter ramp gap between case walls (flat-open)
Knuckle.FULL 2 × case_h none — rests on bed 2 × (case_h + mounting_flat)
Knuckle.HALF case_h 45° self-supporting teardrop case_h + 2 × mounting_flat
Knuckle.SMALL max(case_h / 2, 5 mm) ~25° from vertical (smaller knuckle → naturally steeper) max(case_h, 10mm) + 2 × mounting_flat

See docs/clamshell-integration.md for mounting, orientation, multi-hinge layouts, and the closed-vs-open view.

Provenance

This is a port of "Parametric print-in-place hinge. FreeCAD." by r0berts on Printables, licensed CC BY 4.0.

The original is a spreadsheet-driven FreeCAD model. This repository:

  1. Translates the FreeCAD geometry into build123d Python via fcd2b123d.
  2. Reparameterises around four case-designer-facing inputs (case_h, hinge_length, stations, knuckle) with the original dimensional relationships derived under the hood.
  3. Generalises the comb pattern (hardcoded 6 stations in the original) to any even number of stations ≥ 2, and adds an optional Knuckle.HALF mode with a self-supporting teardrop knuckle for cases where a smaller knuckle is wanted.

Per the CC BY 4.0 terms: design and dimensional relationships are r0berts'; modifications are the build123d port, the four-input API, and the configurable station count and ramp.

Quick start

Install from this repo into your own project (until it's on PyPI):

uv pip install git+https://github.com/pzfreo/pip-hinge.git

Then in your build123d code:

from pip_hinge import HingeParams, Knuckle, make_hinge

hinge = make_hinge(HingeParams(
    case_h=10, hinge_length=60, knuckle=Knuckle.FULL,
))
cylinder_side, pin_side = hinge.solids()    # or use _split_hinge_by_side helper

Or to play with it locally:

git clone https://github.com/pzfreo/pip-hinge.git && cd pip-hinge
uv pip install -e .                          # editable install
python examples/clamshell.py                 # writes clamshell_{full,half,small,magnets}.{step,stl}
python examples/hinge_only.py                # writes the bare hinge_{full,half}.{step,stl}

Parameters

The four primary inputs:

Parameter Default Meaning
case_h (required) Case wall height; the hinge's "scale" reference
hinge_length (required) Total hinge length along the axis (Y)
stations 6 Number of alternating cs/ps tabs (even, ≥ 2)
knuckle Knuckle.FULL FULL, HALF, or SMALL — see the option table below

Three small tuneables:

Parameter Default Meaning
mounting_flat 0.5 Flat width past the disc edge for case-wall fusion. Below pivot_clearance (= 0.6 mm) the bare hinge fragments into multiple solids — fine when fused into a case, see docs
pivot_clearance 0.6 Radial pin/bore gap (FDM tolerance)
clasp_clearance None Axial gap between cs and ps tabs. None auto-scales with knuckle diameter Po: 0.2 mm at Po ≤ 5 mm (matches r0berts' original), linear up to 0.4 mm at Po ≥ 10 mm. Pass an explicit value to override

Plus three pin-engagement constants from the original FreeCAD source (pin_cyl_extra, pin_end_offset, pin_short_cyl_factor) — leave at defaults unless deliberately tuning the pin/bore feel.

Validation

make_hinge() raises ValueError for hard geometric problems:

  • non-positive case_h, hinge_length, or mounting_flat
  • stations < 2 or odd
  • bore Ø ≤ pivot_clearance (knuckle too small for the pivot clearance)

And warns (warnings.warn) when:

  • clasp_width = hinge_length / stations drops below ~3 mm (too thin for FDM)

Printing

Lay flat on the bed with the hinge axis along Y (parallel to bed). 0.2 mm layers, fan on, brim recommended. After printing, gently flex the leaves to break the clearance gaps free.

  • FULL prints without any supports at any knuckle size — the knuckle rests on the bed.
  • HALF prints without supports at any case_h: the meshing-side underside meets the knuckle tangentially at 45° and runs to the bed as a self-supporting teardrop, so the disc's downward arc is never left hanging.

How this was built

The build123d code, API design discussions, station-count generalisation, self-supporting ramp, clamshell example, and documentation in this repository were produced through a paired design session with Claude Code (Anthropic's Claude Opus 4.7). I drove the design decisions — what the API should look like, which knuckle geometries to support, what trade-offs to accept — and Claude wrote the code, generated the diagrams, ran the verifications, and opened the PRs. The conversation is the source of truth for why the code looks the way it does; the commit history reflects the steps.

The original FreeCAD geometry from r0berts is unchanged in its dimensional relationships — it was reparameterised, not redesigned. The Claude collaboration is on the build123d port and the case-designer-facing API built on top of it.

License

This work is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0), matching the upstream Printables source. See LICENSE.

When using or redistributing, please credit:

  • r0berts — original FreeCAD design (Printables)
  • Paul Fremantle (pzfreo) — build123d port, four-input parameterisation, station generalisation, and ramp option

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pip_hinge-0.1.0.tar.gz (361.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pip_hinge-0.1.0-py3-none-any.whl (12.3 kB view details)

Uploaded Python 3

File details

Details for the file pip_hinge-0.1.0.tar.gz.

File metadata

  • Download URL: pip_hinge-0.1.0.tar.gz
  • Upload date:
  • Size: 361.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pip_hinge-0.1.0.tar.gz
Algorithm Hash digest
SHA256 eedcf5a048b3530ee5b62870173c1c4ecac4ab86baf9a03fc7a717cbfcf69285
MD5 fec875a7862cb83696d8b7fdf13268a0
BLAKE2b-256 91a428d9825563ed8fb340b0143ac3a357ce8407b93f057b1d2cb798563dedc6

See more details on using hashes here.

Provenance

The following attestation bundles were made for pip_hinge-0.1.0.tar.gz:

Publisher: publish.yml on pzfreo/pip-hinge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pip_hinge-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pip_hinge-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pip_hinge-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 932b91ed98d487f177514b76e96532c19f0524457cbc68ae66ab922112196537
MD5 dec3b01b36da6bb882c689427f627e5a
BLAKE2b-256 02e181fbe255bb06fe3e2ff9646b13a7fc3e4462b2dd743455e5572a596c205f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pip_hinge-0.1.0-py3-none-any.whl:

Publisher: publish.yml on pzfreo/pip-hinge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page