Globe-Box Approach (Printable Earth)
This document captures how model-render-print-box turns the GDEM data on the shared /datasets volume into STL models that load into a slicer and print on a 3D printer. It is a decision log; mark each option decided with a date and reason.
Goal
A small desk globe, 100 mm in diameter at sea level, that prints as two halves divided at the equator plus a third piece — a hollow twist-lock cylinder that joins the halves. The Earth’s surface comes from the ETOPO 2022 dataset (/datasets/dataset-etopo-2022/, 15-arcsecond GeoTIFF tiles, read-only). The set is three STL files that: - load into OrcaSlicer / PrusaSlicer (binary STL, millimeters, watertight), - print on a common FDM printer (each half’s rim is a flat annulus that sits on the bed, dome up), - assemble into a sphere whose hemispheres meet at the equator with an aligned relief seam, locked by twisting the two hemispheres in opposite directions (the ring is entirely inside).
Source data
ETOPO 2022— global relief model combining land elevation and seafloor bathymetry at 15-arcsecond (~450 m) resolution, as 350 GeoTIFF tiles.- Maintained and versioned by the
model-elevation-earthproject; the manifest is/datasets/manifest.yml(etopo-2022). - Read-only consumption: this project never writes to
/datasets; derived pieces go indataflow.out/box/.
Candidate approaches
- Two hemisphere halves + twist-lock cylinder — CHOSEN (decided 2026-08-27)
- The globe is split at the equator into a northern half (lat 0..90) and a southern half (lat -90..0). Each half is a hollow shell: the outer surface is the sphere at radius
radius_mm + relief, the inner surface is a sphere atradius_mm - wall_mmwith a cylindrical socket (bore) at the rim of radiussocket_radius_mmforsocket_depth_mm. The rim is a flat annulus at z = 0 that sits on the print bed. - The third piece is a hollow cylinder whose outer surface mates with the halves’ sockets. It is entirely INTERNAL: a plain tube spanning the two sockets, with no protruding band, so the hemispheres’ rims meet at the equator (decided 2026-08-31). Locking is done by twisting the two hemispheres, so the ring needs no grip.
- Bayonet lock: 3 pins on the cylinder near each end, at 0/120/240 degrees, engage L-shaped grooves cut into the socket bores. Insert the cylinder into one half (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(30) — both pin sets ride into both halves’ grooves at once, and the ring stays put (held by its friction fit). Two hands, one on each hemisphere, lock and unlock the globe (the natural two-hand motion). - The two halves’ grooves are generated with the SAME handedness in their own STL frames (both -twist); the south half’s assembly flip (180 deg about x) reverses its azimuth, so in the assembled globe the north grooves turn -twist and the south +twist — OPPOSITE handedness, which is what an opposite-direction two-hand twist needs.
- The north half’s groove pattern (axial channels AND circumferential grooves) is rotated +2 x
twist_degrees(60) in its STL frame, so at insertion the north relief starts 2 x twist degrees WEST of the south half’s. Twisting north +30 and south -30 (opposite directions) brings both halves to the same rotation, so the relief seam is aligned when locked (decided 2026-08-31). - History: without the offset, an opposite-direction twist locked the halves 2 x
twist_degrees(60 deg) apart and offset the relief seam (measured ~50 deg); a same-direction twist aligned them but felt unnatural. The offset gives the natural two-hand motion AND an aligned seam.
- The globe is split at the equator into a northern half (lat 0..90) and a southern half (lat -90..0). Each half is a hollow shell: the outer surface is the sphere at radius
- Threaded halves — rejected (decided 2026-08-27)
- The two halves screw together directly on a thread at the rim. Simple to print, but the halves rotate many turns relative to each other during assembly, so the relief seam ends up at an arbitrary longitude unless the thread pitch is engineered for exact alignment; the bayonet avoids that with a fixed 30-degree stop.
- Full solid globe / stacked rings — deferred (decided 2026-08-27)
- Prints a solid sphere or concentric rings; heavier, larger than the bed at useful sizes, and the task asks for two halves plus a twist-lock.
Geometry (per piece)
radius_mm(default 50): the sea-level sphere radius; the globe is 100 mm in diameter at sea level.relief_mm(default 4): land elevation mapped over the global ETOPO range. The standard build uses flat oceans (--oceans-flat): water cells clamp to sea level, so the ocean surface is exactly the sea-level sphere (decided 2026-08-27, matchingmodel-render-print).wall_mm(default 3): shell wall; the inner sphere radius isradius_mm - wall_mm.socket_radius_mm(default 43) andsocket_depth_mm(default 13): the cylindrical bore at each half’s rim that receives the cylinder. The socket radius is smaller than the inner sphere radius, so the cavity opens out above the socket (the ledge is hidden inside the globe).- Twist-lock cylinder: outer radius
socket_radius_mm - clearance_mm(clearance 0.2 for FDM, reduced from 0.3 on 2026-08-27 after the first prints: the fit was good and a 85.6 mm OD cylinder tightened the join without changing the hemispheres), wall 2.5 mm, and a total length of 2 xcylinder_socket_length_mm(24 mm) — a plain tube with NO band (band_width_mm0, set 2026-08-31: the ring is entirely inside the two sockets, so the hemispheres’ rims meet at the equator). With a positiveband_width_mmthe ring instead carries a knurled band of radiusradius_mm + relief_mm + 1.5that stays outside at the seam as a grip. - Pins:
pin_count(3) at 0/120/240 degrees,pin_height_mm(1.6), radius 2 mm, axial length 4 mm, sittingpin_distance_from_end_mm(3) from each cylinder end so they land at the groove depth when seated. - Grooves: axial channel
groove_width_degrees(7) wide andaxial_channel_depth_mm(9) deep from the rim, then a circumferential groove ofgroove_axial_width_mm(4.5) turningtwist_degrees(30).
Pellucidar liners
Two more pieces (decided 2026-09-16): a liner for each half, carrying a map of Pellucidar, the inner surface of Burroughs’ hollow Earth.
- The map is the ETOPO elevation inverted. Burroughs’ rule is that Pellucidar’s continents mirror the surface world’s oceans and its seas mirror its continents, so the build negates the sampled elevation and runs it through the same mapping as the globe, with flat seas. Our deepest ocean (about 8700 m) becomes Pellucidar’s highest land; our dry land becomes its flat sea. Its amplitude is
liner_relief_mm(2, half the globe’s, because the map is cut into a downward-facing surface). - It is a bowl, not a disc. The liner’s outer surface is a sphere of
liner_outer_radius_mm(the half’s inner sphere lessliner_clearance_mm, 0.4) and its map surface isliner_wall_mm(1.6) less, displaced inward by the relief — land rises toward the hollow centre, which is “up” for anyone standing inside Pellucidar. It prints rim-down like the halves. - The rim is the seat, and it has to catch. The cavity’s only entry is the socket bore (86 mm across), while the cavity opens out to 90.3 mm at the ledge just above it (z = 13). A liner that simply hugged the inner sphere would be 1.8 mm per side too wide to go in, and anything narrow enough to pass falls straight through onto the twist-lock ring. So the rim is
liner_rim_radius_mm= socket radius + 0.6 (87.2 mm across): it flexes ~0.6 mm per side as it passes the bore and springs out over the ledge, where it seats. The seated liner’s lowest point is z = 13, which is 1.0 mm clear of the ring’s end face (z = 12) — it clears the ring rather than resting on it. - The rim relief is faded. The map surface is
r * cos(polar), so relief appearing faster than the sphere rises drags the surface below the rim plane: on the real ETOPO data, without a fade, the lowest face of the printed liner sat 0.32 mm below the rim, so the bowl would not sit flat on the bed. The relief is therefore faded in overliner_rim_fade_degrees(4) above the rim, which keeps the rim plane the lowest face (verified in the build and guarded by a test that fails without the fade). - A polar tunnel (
liner_tunnel_diameter_mm, 2.0) pierces each liner on its axis. It is the polar opening of Pellucidar in the stories, and it also keeps the vent working: the air in the central cavity escapes through the liner’s tunnel, along the 0.4 mm gap between liner and shell, and out of the half’s pole vent. It is sized to match that vent (2.0 mm), so the passage is 2 mm the whole way rather than necking down inside. - The two liners are one world. The south liner samples mirrored longitude exactly like the south half, so the pair form one continuous Pellucidar in the assembled globe. The equatorial band (|latitude| below about 21 degrees) is left uncovered: that is where the socket is, and the ring and sockets occupy it.
South half mirroring
- The south half is generated in the same print orientation as the north (rim at z = 0, dome up) but samples mirrored longitude: the relief at STL longitude lon is the ETOPO elevation at geographic longitude -lon. When the printed south half is flipped over for assembly (rotated 180 degrees about the x axis), its surface shows the true relief, and the two halves’ rim rings carry the same relief at every longitude — the seam is continuous.
- The grooves of the two halves are generated with the SAME handedness in their own STL frames (both -twist); the south half’s assembly flip reverses its azimuth, so in the assembled globe the two halves’ grooves turn in OPPOSITE directions (north -twist, south +twist). Locking is a two-handed twist: turn the hemispheres in opposite directions (the natural two-hand motion) and the ring stays put (held by its friction fit). The north half’s groove pattern is offset +2 x twist in its STL frame, so the north starts 2 x twist west of the south and the opposite twists bring the halves to the same rotation — the seam is aligned when locked (decided 2026-08-31). Verified in
tests/04-globe-box-math.sh.
Print and assembly notes
- Each half prints rim-down: the flat rim annulus sits on the bed and the dome rises, so no supports are needed under the shell (the dome is self-supporting; the interior cavity is open at the rim).
- The cylinder prints on one of its flat end faces, or lying on its side with light supports for the pins.
- Each liner prints rim-down like the halves, but its map is on the concave underside, so the map is cut into an overhanging surface: keep the relief shallow (
liner_relief_mm2) and expect a slightly rougher finish there than on the outer globe. - Assembly: push the cylinder into one half with the pins aligned to the groove entrances (the entrances are visible at the rim), slide the other half over the far end until the rims meet at the equator, then twist the hemispheres in OPPOSITE directions 30 degrees each (the ring stays put — held by its friction fit). To disassemble, twist the halves back and pull them apart. Seat a liner first (or last): squeeze its rim slightly and push it up past the socket bore until it springs out over the ledge; it hangs there, clear of the ring, and comes out with a firm pull.
- Because the ring is entirely internal, the assembled globe is a clean sphere: the hemispheres’ rims meet at the equator with no visible band.
- Each half has a 2 mm vent hole on its pole axis (decided 2026-09-16, widened from 1 mm the same day): the pole cap is replaced by a bore through the 3 mm shell, so the hollow interior is open to the outside. Pushing the two halves together otherwise compresses the trapped air (the ring seals the socket), which pushes the halves apart and makes the last few millimetres of the join springy; the vents let the air escape. The hole is built, not booleaned: the dome stops at the latitude ring whose radius equals the vent radius, the inner sphere stops at the matching rim, and a short cylinder wall joins the two rims, so the shell stays watertight.
tests/04-globe-box-math.shproves the opening by casting rays along the pole axis: zero material crossings with the vent, exactly two withpole_hole_diameter_mm = 0. - Because the north half starts 2 x twist west of the south and the opposite twists bring both to the same rotation, the relief seam is aligned when locked (see the mechanism note under Candidate approaches).
- Clearances are sized for a 0.4 mm nozzle; expect to tune
clearance_mm,pin_height_mm, andgroove_depth_mmafter the first print (tracked inTODO.md).