Feature: Globe Box
Purpose
Printable 3D models of a small Earth globe rendered from the GDEM data on the shared /datasets volume: the globe (100 mm diameter at sea level) is split into two hollow hemisphere halves divided at the equator, and a third piece — a hollow twist-lock cylinder — joins the two halves. Each piece is an STL file that loads into a slicer (OrcaSlicer, PrusaSlicer) and prints on a 3D printer.
Requirements
scripts/globe-box-build.shmust render the piece set intodataflow.out/box/from the ETOPO 2022 source tiles (/datasets/dataset-etopo-2022/, read-only).- The globe is 100 mm in diameter at sea level: the sea-level sphere has radius
radius_mm = 50; land elevation maps to relief above sea level (relief_mm, default 4), and with--oceans-flat(the standard build) water-covered cells are clamped to sea level. - The piece set is exactly three STL files plus a manifest:
globe-north.stl— the northern hemisphere half (lat 0..90).globe-south.stl— the southern hemisphere half (lat -90..0).twist-lock.stl— the hollow cylinder that joins the halves.
- Each half is a hollow shell: the outer surface is the globe surface with elevation relief; the inner surface is a sphere of radius
radius_mm - wall_mm(wall_mmdefault 3), except near the rim where it is a cylindrical socket (bore) of radiussocket_radius_mmfor a depthsocket_depth_mm(default 12). - Each half must have a flat rim (annulus) at z = 0 that sits against the printer bed; the STL’s z = 0 is the rim plane.
- Each half must be a watertight solid (every edge shared by exactly two triangles), so slicers accept it.
- The relief must be continuous across the seam: the two halves sample the same elevation grid at the equator, so the rim rings match.
- Twist-lock cylinder: a hollow tube whose outer surface mates with the inner surface of the two halves’ sockets (radius
socket_radius_mmminusclearance_mm, default 0.2). It is entirely internal: a plain tube of length 2 xcylinder_socket_length_mmwith no protruding band (band_width_mm, default 0), so the two hemispheres’ rims meet at the equator. A positiveband_width_mminstead gives the ring a knurled band of radiusradius_mm + relief_mm + 2that stays outside at the seam as a grip. - The twist-lock is a bayonet: 3 pins on the cylinder near each end, at 0/120/240 degrees, engage L-shaped grooves cut into the inner surface of each half’s socket. Insert the cylinder into one half with the pins aligned to the groove entrances, slide the other half over the far end, then twist the two hemispheres in OPPOSITE directions by
twist_degrees(default 30) to lock both halves at once; the ring stays put (held by its friction fit), so two hands (one per hemisphere) lock and unlock the globe with a natural motion. - The two halves’ grooves are generated with the same handedness in their own STL frames (both -twist; the south half is assembled rotated 180 degrees about the x axis, which reverses its azimuth), so in the assembled globe the two halves’ grooves turn in OPPOSITE directions. The north half’s groove pattern is offset +2 x
twist_degreesin its STL frame, so the north starts 2 x twist degrees west of the south; the opposite-direction twists bring both halves to the same rotation, so the relief seam is aligned when locked. - The underside of each half may carry an engraved (recessed) label; z = 0 must stay the lowest plane.
- Output format: binary STL, millimeters.
scripts/globe-box-build.sh --checkmust validate every generated piece (watertight, flat rim at z = 0, expected bounds, positive signed volume, mating geometry) without rebuilding.- The build must write
dataflow.out/box/manifest.json: parameters, piece list with bounds and sizes, and provenance (dataset, script, timestamp, git commit). scripts/globe-box-assemble.shmust build an assembled web model: the three pieces rebuilt at coarse sampling and merged into one grouped Wavefront OBJ (dataflow.out/box/globe-assembled.obj, groupsglobe-north,globe-south,twist-lock) plusassemble.json. The assembled pose puts the north rim at z = +band_width/2 and the south rim at z = -band_width/2 (the south half rotated 180 degrees about x), with the ring spanning the seam — so with the default band width 0 the rims meet at z = 0 and the ring is entirely inside.- The site must include an
assemble.htmlpage with an interactive 3D view of the assembled model (drag to rotate, scroll to zoom), following themodel-render-printframe-page pattern (three.js, grouped OBJ). - Derived output (
dataflow.out/box/) is generated and must not be edited by hand.
Behavior
- Running the script recreates the piece set deterministically from the source tiles and the given parameters.
- Re-running the script overwrites existing pieces.
Dependencies
- Tool-gated: GDAL 3.8+ and Python 3 with the
osgeoandnumpymodules, plus the ETOPO source tiles under/datasetson the owning host. - Dataset
etopo-2022maintained by themodel-elevation-earthproject.