dankbuild

Four printable ESP32-S3 bench parts — three come as STL downloads, the fourth only as a browser generator

·Downloads, browser generators and method·Not a build-log

Three STL files you can download from this page. A bench plate that parks a half-size (BB400) solderless breadboard and an ESP32-S3-DevKitC-1 side by side, a fit gauge whose six stepped channels exist to measure the one dimension this repository could not source from an authority, and a jumper-wire comb whose teeth stand on the 2.54 mm breadboard pitch.

Read this before you download. These files have not been printed — not by me, not by anyone I know of. They are geometry that has been checked by code and by nothing else.

What was checked: twenty-six assertions run against the finished solids by tools/print/test-fit.cjs, and an independent re-read of the written STL bytes by tools/print/verify-stl.cjs. What was not checked: a printer. There is no photo of any of them, no measured tolerance, no material or print-time result, and no report from anyone who has used one. This page is a download plus the method behind it. It is not a write-up of something that got made.

What you may do with all of this. Separately from whether the geometry is any good, you are free to use it. The three STL files, the SVG outlines and anything the browser generators on this page hand you are released under CC BY 4.0; the generator code behind them — the .cjs listings linked throughout this page — is MIT.

So: remix a part, print it, sell the print, re-post it on Printables or anywhere else, without asking. The one thing asked in return is that you credit dankbuild.com with a link back to this page, link the licence alongside it, and say that you changed the file if you did.

Both licence files are plain text and open in the tab — LICENSE-CC-BY-4.0.txt carries an attribution line you can paste as it stands, and LICENSE-MIT.txt is the full MIT text. Permission is not a promise the part works: the paragraph above still stands.

You do not have to take the files as they are. All three parts can also be built in this tab, around a number of your own rather than the one this repository picked: see Make a plate sized to the numbers you measured, Re-centre the gauge on a number you already have and Build a comb with the number of teeth you want, further down.

You type a number, the same generator code that produced the STLs above runs in your browser, and it either hands you a file or refuses and says why. Nothing is uploaded and nothing is stored; if JavaScript is off, those controls simply never appear and the downloads are unaffected.

A fourth part has no file above it at all. Build a tray for the loose parts on your bench is an open-top box sized from an inside length and an inside width you type. There is no bench-tray.stl to download, and that is deliberate: any size this page published would be a guess about somebody else's bench, so the generator has no default and refuses, in writing, until you give it both dimensions.

It is the same code path as the three above, and it has been printed exactly as often as they have, which is never.

Everything dimensional below is either a parameter you can read in tools/print/models.cjs or a bounding box that came back from re-reading the binary STL files that this page serves. Where a parameter is marked UNVERIFIED in the generator, this page says so instead of quietly rounding it into a fact.

The bench plate

esp32-bench-plate.stl — 120.3 × 63.1 × 5.6 mm overall, 96 triangles, 4884 bytes. Two bays side by side on one slab, so tugging a jumper wire at one end does not drag the whole arrangement across the desk.

Top-view outline of the bench plate: a wide rectangular bay on the left for a breadboard, a narrow bay on the right for a devkit, a divider between them, and two gaps in the rear wall over the left bay. Isometric render of the bench plate mesh, seen from above and to one side: a flat slab with low walls standing up around a wide bay on the left and a narrow open-ended bay on the right, top faces bright and side walls darker.
Two drawings of the same file, esp32-bench-plate.stl: the flat top view, and an isometric projection of the same mesh. Both were written by verify-stl.cjs out of the STL bytes it had just re-read — they are renders, not photographs, and not pictures of a print, because nothing has been printed. The isometric one shades each facet by its normal so the form reads; the checker's own comment calls that view “genuinely ambiguous about which walls exist and where the openings are”, which is why the top view is still here next to it.

The fit gauge, and the number nobody could source

The header comment in models.cjs is blunt about the problem: the DevKitC-1's board outline could not be obtained from an authority. That claim was re-checked on 2026-08-08 and it needed correcting.

The documentation URL those notes were built on does still return 404, but only because the guide was renamed to a versioned filename and the old path was left dead; the guide that replaced it resolves, and it links a public DXF dimensions source that resolves too. What the DXF does not contain is a dimension callout — it is vector geometry, not a table, so a width still has to be measured, in CAD or in plastic.

This site's hardest rule is that no hardware fact may be invented. So the width parameter stays marked UNVERIFIED in the generator, and the gauge exists to replace it with a reading.

The method behind that decision — how the sourcing check was actually run, why the bay is left open on the axis nobody could confirm, and what each layer of checking catches — is written up separately in measuring a dev board for 3D printing when the size is not published.

Why this page will not tell you the board's width. Searching for the width of an “ESP32 DevKitC” hands you a confident number. That number belongs to a different board in the same family, and copying it across would be exactly the fabricated hardware measurement this site refuses to publish.

The generator carries a placeholder so that it can emit geometry at all, and labels it UNVERIFIED; the only figure quoted below that touches it is the test suite's own line calling it a guess. Six stepped channels are cheaper than a wrong number: print the gauge and the board itself tells you.

esp32-fit-gauge.stl — 83.4 × 109.8 × 5.4 mm overall, 408 triangles, 20484 bytes.

Top-view outline of the fit gauge: six pairs of parallel walls forming channels, arranged two across and three down, each with a group of small ribs beside it. Isometric render of the fit gauge mesh, seen from above and to one side: six pairs of parallel walls standing off one flat base in two columns of three, a row of short ribs beside each pair, top faces bright and side walls darker.
Two drawings of the same file, esp32-fit-gauge.stl: the flat top view, and an isometric projection of the same mesh, both drawn from that file's bytes by verify-stl.cjs — renders, not photographs of a part. The isometric view is where you can see that the walls stand up off one flat base and that every channel is open at both ends. What it cannot show you is which channel is which: the step between neighbours is finer than this drawing resolves at page size, so identify a channel by counting the ribs beside it, never by eye off the picture.

The jumper-wire comb

Concede the obvious first: if what you want is a finished jumper-wire comb, the model repositories have thousands of them, and searching for one is not hard. This one has not been printed by anybody. If a file to send straight to a slicer is the whole job, go and take one of theirs; it is a better answer to that question than this is.

What page one of that search does not hand you is this surface: the number that sets the part, the STL, the source that built it, and a drawing made by a reader that shares no code with the writer, all published beside each other. That is the only thing this page adds. The comb is here because a second part makes that surface worth more than one part did — the same generator, the same checks, a different shape.

jumper-wire-comb.stl — 84.01 × 9.08 × 5.6 mm overall, 396 triangles, 19884 bytes. A flat bar with 32 teeth standing on it, leaving 31 slots. Press a wire into each slot and the bundle comes out spaced the way the holes are spaced.

Top view of the jumper-wire comb: a long, shallow rectangular bar with a single row of thirty-two short dark teeth spaced evenly along it, and a plain pad of bare base at each end. Isometric render of the jumper-wire comb mesh, seen from above and to one side: a long flat slab with a row of small square posts standing up along its length, top faces bright and side faces darker.
Two drawings of the same file, jumper-wire-comb.stl: the flat top view and an isometric projection, both written by verify-stl.cjs out of the finished bytes it had just parsed back off disk. Renders, not photographs — nothing here has been printed. At page size the drawing cannot resolve a 1.27 mm slot from a 1.27 mm tooth, so read the spacing off the numbers below rather than off the picture.

Where the 2.54 mm comes from

Every dimension of this part descends from one published figure: 2.54 mm, which is 0.1 inch exactly — the through-hole lead spacing that DIP packages, 0.1” pin headers and solderless breadboard tie-points are all laid out on.

That is the same pitch this page already cites two sections up as the reason a half-size (BB400) footprint can be stated at all without measuring anybody's breadboard: the 83.5 × 54.5 mm outline follows from the grid, not from a vendor's tooling. It is a defined conversion, not a measurement, so it is the one number on this page that cannot be wrong.

From it, without touching a caliper:

The limit, stated plainly. A 1.27 mm slot is a geometric consequence of the pitch, not a measurement of anything you own. Nothing here has measured the jacket of a jumper wire, and a wire whose insulation is fatter than 1.27 mm will not enter the slot. That is the one thing worth checking against your own wire before you spend filament, and it is the sort of check this page cannot do for you, because this page has no wire and no printer.

The tooth count is a control in this tab. If the comb above is the wrong length for what you are doing, type the count you want into Build a comb with the number of teeth you want, further down this page, and the same jumperComb({ teeth }) in models.cjs runs in your browser instead of on your machine. Running build.cjs yourself does the same thing and is still there if you would rather.

Which numbers are asserted, and which are not

Provenance table: where each number in models.cjs came from — 13 rows, a header plus one row per parameter, including the two still marked UNVERIFIED
Provenance of every parameter in tools/print/models.cjs
ParameterStatus
Breadboard footprint, 83.5 × 54.5 mmStandard BB400 half-size footprint, fixed by 2.54 mm pitch. Bay span asserted by test-fit.cjs.
Breadboard clearance, 0.6 mmDesign choice. Asserted only in the sense that the bay is neither undersized nor sloppy.
Devkit board widthUNVERIFIED in models.cjs — a placeholder, never sourced, never measured. This page does not restate it as a fact about the board. It is the number the gauge exists to measure.
Devkit board lengthUNVERIFIED in models.cjs. Made harmless by leaving the bay open at both ends — test-fit.cjs asserts that openness directly.
Devkit clearance, 0.8 mmDesign choice. The intent is that a full millimetre of error in the unverified width would still leave the bay usable; nothing has tested that, because nothing has been printed.
Devkit bay, 26.2 mmFollows arithmetically from an UNVERIFIED input, so treat it as a guess with a margin. The finished span is asserted by test-fit.cjs; what it is a good span for is not.
Six channel widths, 24.6–26.6 mmAsserted: test-fit.cjs measures each finished channel against its stated width.
Base 2.4 mm, walls 2.0 mm × 3.2 mm, notches 12.0 mmDesign choices, read straight from the parameter block.
Tie-point pitch, 2.54 mmA published standard, and a defined conversion: 0.1 inch exactly, the through-hole lead spacing DIP packages, 0.1” headers and breadboard tie-points share. Not measured here, and not measurable wrongly.
Comb teeth and slots, 1.27 mm eachHalf the pitch, by arithmetic. Asserted: test-fit.cjs scans each finished slot, and verify-stl.cjs re-measures the tooth faces from the encoded bytes. NOT asserted: that any particular jumper wire fits a 1.27 mm slot. No wire has been measured.
Comb tooth count, 32Derived: the largest count whose overall length (84.01 mm) still lies inside the plate's 84.1 mm breadboard bay. Asserted by test-fit.cjs against the plate's own bay, not against a literal.
Comb tooth depth 5.08 mm, height 3.2 mm, base 2.4 mmTwo pitches, and the plate's own wall height and base thickness reused. Design choices with no hardware input.
What the checks actually check — all 26 assertions in full, and why the plate mesh has four four-triangle edges (about 1,100 words)

What the checks actually check

node tools/print/test-fit.cjs takes a scan line across the finished solids at wall height and reports the clear span, the way a caliper would, rather than trusting the arithmetic that produced them. Twenty-six assertions pass:

bench plate
  ok   the breadboard bay is wide enough for a BB400, and not sloppy
  ok   the breadboard bay is DEEP enough, and not sloppy
  ok   the devkit bay holds the board width with the intended clearance
  ok   the devkit bay is OPEN end to end, so an unverified board LENGTH cannot bind
  ok   the rear wall really is notched for cables
  ok   nothing overhangs: every solid sits on the base or on another solid

fit gauge
  ok   every channel measures its stated width
  ok   the ribs never intrude into a channel
  ok   channel widths bracket the nominal 25.4 mm guess in both directions
  ok   the PUBLISHED band is exactly the array the STL on the site was built from

fit gauge, re-centred on a supplied width
  ok   a supplied centre is bracketed in both directions
  ok   the re-centred ladder keeps the 0.4 mm default step, evenly spaced
  ok   every re-centred channel measures its stated width, and no rib intrudes
  ok   the re-centred solid is still a valid, non-interpenetrating mesh
  ok   a re-centred gauge does not disturb the default one

jumper-wire comb
  ok   the teeth stand on exact 2.54 mm tie-point centres
  ok   every slot between two teeth is exactly half the pitch wide
  ok   the teeth are as thick as the slots, so neither member is the weak one
  ok   the default comb lies inside the breadboard bay of the plate on the same page
  ok   bounds() agrees with the meta the generator reported
  ok   nothing overhangs: every tooth stands on the base
  ok   the mesh is valid and no two solids interpenetrate

jumper-wire comb, at a tooth count the caller chose
  ok   a shorter comb keeps the pitch and stays a valid mesh
  ok   the overall size is the tooth count and the pitch, and nothing else
  ok   counts that cannot work are refused, not quietly built
  ok   a comb of another length does not disturb the published one

26 assertion(s) passed

That third assertion is worth reading carefully. It checks the bay against the parameter, not against a real board — it confirms the generator did what the parameter block asked for, which is a different and much weaker claim than "your board will fit". The same measurement pass earned its keep during design: a stray 4 mm term had inflated the devkit bay to 30.2 mm, four millimetres of slop that the arithmetic hid and the scan line caught.

node tools/print/verify-stl.cjs then re-reads the bytes that actually landed on disk with a separate parser, on the principle that a generator validating its own memory says nothing about the file. Run against the three STLs this page serves, it reports 408 triangles for the gauge, 396 for the comb and 96 for the plate, all three sitting exactly on Z=0, with every facet normal agreeing with its winding order.

All six preview images above are that tool's own output — one flat top view and one isometric projection per solid, written to disk in the same pass that did the re-reading — not drawings made by hand.

Every edge, counted. That same pass now also tallies undirected edges: for each edge of each triangle it parsed, it counts how many triangles use that same line. On one closed surface the answer is exactly two, everywhere — an edge used once is a hole in the shell, and an edge used more than twice is several sheets meeting along one line.

The gauge (408 triangles, 612 distinct edges) and the comb (396 triangles, 594 edges) both come back with zero edges that are anything other than twice-used: they are closed meshes. The plate (96 triangles, 140 edges) comes back with zero edges used once and four edges used by four triangles each, so the plate is not one closed surface.

The tool prints that number for every file it reads; it does not assert it, because the number is a property of how the part is built rather than a fault that crept in.

The four build controls further down print the same tally for the part you build, counted the same way out of the same bytes they hand you — and the tray is the one part on this page whose boxes were laid out so that the answer is always zero and zero, which its own section explains.

Why four, and where. The writer in stl.cjs has no boolean operations. A part is a set of axis-aligned boxes that touch but never share volume — a recess here is four walls standing on a slab, not a hole cut out of one — and nothing ever unions those boxes into a single skin.

So wherever two wall boxes meet at a shared corner, the vertical line at that corner is a genuine edge of both boxes, and each box contributes two triangles to it: four in total. The plate has exactly four such corners — two where the left-hand side wall butts into the front and rear walls, and two where the bay divider does the same.

Each of the four lines runs the 3.2 mm wall height, from the top of the 2.4 mm base to the top of the wall, and verify-stl.cjs prints all four sets of coordinates. The gauge and the comb score zero because no two of their boxes ever share an edge line: their solids stand on the base without meeting each other end-on.

What you may see, and what has not been established. A program that inspects meshes when you open a file can be expected to notice this and offer to repair it, and coincident contacts between solids that are meant to be one part are the ordinary case such repairs exist for — so the expectation is that it is handled.

That is an expectation, not a measurement: nothing here has tested any particular program, and none is named. No repair has been applied to the file either — the bytes you download are the bytes the generator wrote, four-triangle edges and all.

Rearranging the boxes does not remove them: with the walls turned so the long sides run the full depth and the end walls sit between them, the count is still four, and giving each corner its own post makes it sixteen. Removing them properly means a boolean union, which this kernel does not have. And nothing on this page has been printed, so this says nothing about how the plate prints.

Downloads

All three are binary STL in millimetres, sitting on Z=0, so they import at the right scale and orientation with nothing to rotate or rescale. That is a statement about placement, not about the mesh: as the edge count above records, the gauge and the comb are closed meshes and the plate is not, so a program that inspects meshes on import may flag the plate and offer to repair it. They are served from this site — the same bytes the repository holds, not a re-export from somewhere else.

The source files this page describes

The five files below — served as plain text — are the entry point that produced the three STLs on this page, the generator it takes its geometry from, the binary-STL writer it requires, and the two checkers that measured the finished solids and re-read the written bytes.

build.cjs is the entry point that ties the other four together: it builds all three solids, runs the mesh check on each, and writes that part's .stl only if the check passed — a part whose check fails prints its problems and leaves no file behind. Read the check narrowly: it says the solids making up a part do not interpenetrate and that the file was written only because that held, and it says nothing about whether the part fits a board, prints cleanly, or is the right shape.

The thinking behind these five files is written up at Generating 3D-Printable Parts From Code — why the kernel has no boolean operations, so a recess here is four walls standing on a plate rather than a hole cut into a block, and the defects that surfaced on both sides of the checks.

Printing them

All three of the files above have a flat bottom, nothing overhangs, and the tallest feature on any of them is 5.6 mm, so as guidance: lay them on the bed as they arrive, and you should not need supports, a raft or a brim. PLA is fine — none of them carries load or heat. 0.2 mm layers, three perimeters and light infill are plenty; these are bench furniture, not machine parts, and there is nothing to gain from a slow profile.

The tray you can build further down is the same in kind and taller: its walls stand straight up off a flat floor, so nothing overhangs there either, but it is 14.4 mm tall rather than 5.6 mm whatever size you ask for, and above the floor it is nothing but wall.

Those are statements about the shape the generator emits, and that is all they are: no version of the tray has been sliced, printed, timed or weighed, so this page has no print advice for it beyond what it has for the others.

The repository README puts the gauge at roughly fifteen minutes. Treat that as a rough estimate with no slicer behind it and no printer behind it either — slice the file and believe your own number.

Print the gauge first. It is the smaller part and it is the one that turns the unverified width parameter into a measured one, after which the generator emits a plate sized to the board rather than to a guess.

Make a plate sized to the numbers you measured — the in-browser generator: one width box, two optional breadboard boxes (about 830 words)

Make a plate sized to the numbers you measured

The gauge exists to replace a guess with a number. This is where the number goes: type the width of the narrowest channel your board settled into without forcing, and the plate is rebuilt around that figure and handed to you as a binary STL.

Only the devkit bay moves with that number — and, with it, the overall plate width. The base and wall thicknesses are untouched, because nothing the gauge measures affects them. The breadboard bay keeps the footprint the generator already carries unless you measure your own breadboard into the two boxes below; give it a length and a width and that bay, the plate's depth and the two cable notches spaced along it all move with your numbers instead.

This is not a second implementation of the geometry, which is the usual way a browser version of a part quietly stops matching the real one. The module the button runs, geometry.js, is generated verbatim from the same models.cjs and stl.cjs listed above, by tools/print/make-web-geometry.cjs.

A test in the repository re-runs that generator and fails if the served copy differs by a single byte, and separately builds the plate at the file's own parameters and requires the result to be byte-identical to the esp32-bench-plate.stl this page serves. The browser and the command line are the same code path, and that is checked rather than claimed.

Everything happens in this tab. The number is read from the box below, used to build an array of bytes in memory, and handed to the browser as a download; it is not sent anywhere, not stored, and no request is made in order to build it.

Before a link appears, the module runs the two functions the command-line build gates on — check(), which rejects degenerate triangles and any pair of solids that share volume, and bounds(), which measures the finished triangles instead of trusting the arithmetic that produced them. If either comes back wrong you get the reason in plain words and no file, the same way build.cjs leaves no file behind when a check fails.

A plate you generate here has not been printed either. It is the same kind of object as the three files above: geometry a computer has checked and a printer has never seen. The generator built the mesh to the number you typed and verified that mesh. What nobody did is print it, put a board in it, or measure the result. If your reading of the gauge is off, the part is off by the same amount, and nothing on this page can tell you so.

Re-centre the gauge on a number you already have — the in-browser generator: one box for a rough width (about 400 words)

Re-centre the gauge on a number you already have

The gauge this page serves as a file brackets a width that came from the generator's placeholder, which is only useful if the board you are measuring happens to sit near it.

If you already have a rough figure — a caliper reading you do not trust to a tenth, a dimension you took off a DXF yourself in a CAD viewer, or the fact that a previous reading landed hard against one end of the published ladder rather than in the middle — type that figure below.

The channels are rebuilt centred on it, keeping the same step between them and the same rib groups counting up so a channel can be told apart from its neighbours without a label. Nothing else about the part changes. The depth does follow the number you ask for, because the rows have to be pitched far enough apart for the widest channel, and the control reports the envelope it measured before it offers you anything.

It runs the same ladder of checks as the plate control above, in the same order, and refuses in the same way.

It has one refusal the plate control does not need: ask for a centre low enough and the bottom of the ladder reaches zero width, which is a part with no channel in it. The mesh check does not object to that — a zero-width channel is still a closed set of triangles — so the module reads the built channel widths back and tells you what the narrowest one came out at instead of handing you the file.

A re-centred gauge has not been printed either. No version of it has. It is the same kind of object as everything else here: a mesh a computer built to the number you gave it and then checked. Whether it tells you anything useful depends entirely on whether the figure you typed was close enough to be worth bracketing, and nothing on this page can tell you that.

Build a comb with the number of teeth you want — the in-browser generator: tooth count is its only parameter (about 560 words)

Build a comb with the number of teeth you want

Length is the comb's only parameter. The file this page serves is as long as the generator will go, because the count was derived by asking how many teeth still fit inside the breadboard bay of the plate at the top of the page — a sensible thing to derive it from, and a completely arbitrary answer to the different question of how many wires you are trying to keep in order.

If you want a short one to sit at the edge of a project box, or a stub to hold the four wires of an I²C run, the number is yours to pick. Type it below and the comb is rebuilt at that count and handed to you as a binary STL.

Only the count changes. The pitch, the tooth and slot widths, the tooth depth, the base and the wall height are all fixed — they come from the plate's own parameters and from the breadboard pitch, and none of them is a function of how many teeth you ask for.

So a comb you build here is the published one made shorter, not a differently proportioned part. The control reports the widths it actually built, read back out of the generator's output, so you can see that for yourself rather than take this paragraph's word for it.

The refusals are the generator's, not this page's. jumperComb() already throws, with a written reason, for a count that is not a whole number, for one below the shortest comb it makes, and for one longer than the bay allows.

The module catches that error and prints its message verbatim, in quotation marks, instead of restating it — which means the ceiling you are told about is the one the function computed, and this page cannot drift away from it.

Past that, a comb runs the same ladder of checks as the plate and gauge controls above, in the same order:

  • check() for degenerate triangles and solids sharing volume,
  • bounds() re-measured off the finished triangles and compared against the width, depth and height the generator said it was making,
  • the part sitting on Z=0,
  • and the finished file's byte length coming out at exactly what binary STL's fixed header and fixed per-triangle record add up to for the triangle count check() reported.

Any one of those failing means a reason and no file.

A comb you generate here has not been printed either. None of them has. And the one thing worth checking before you print — whether the jacket of your wire will enter a slot — does not change with the tooth count, because the slot width is half the pitch at every count. Nothing here has measured a wire. A shorter comb is a shorter comb; it is not a comb that answers a question this page cannot answer.

Build a tray for the loose parts on your bench — the in-browser generator: inside length and inside width, both required (about 860 words)

Build a tray for the loose parts on your bench

An open-top rectangular box, sized from the two numbers that actually matter about a tray: how long the hole in the middle of it is, and how wide. Everything else is fixed — a 2.4 mm floor and 2 mm walls, both taken from the bench plate at the top of this page rather than picked again, and a 12 mm wall height that was simply chosen and is labelled as a choice in models.cjs. Nothing has been measured against that 12 mm: not a header strip, not a screw, not a jumper end.

Why there is no bench-tray.stl to download. The other three parts have a published size because something outside this repository fixes it: the breadboard footprint follows from 2.54 mm tie-point pitch, the gauge's ladder brackets a board width, the comb's tooth count is the longest that still sits in the plate's bay.

A tray has no such anchor. How much loose hardware is on your bench, and how much room you have to put it, are facts about your bench, and this page's whole rule is that it does not invent those. So benchTray() ships with no default size at all: call it without both inside dimensions and it throws, and the control below prints that refusal in the generator's own words instead of quietly building something.

It is generated and checked, and that is the entire claim. No tray has been printed, test-fitted, filled, or held up against a real part.

What happens when you press the button is that geometry is built from your two numbers and then examined by code, in front of you:

  • check() for degenerate triangles and for any pair of solids sharing volume,
  • bounds() re-measured off the finished triangles and compared with the width, depth and height the generator said it was making,
  • the part sitting on Z=0,
  • and the file's byte length matching what binary STL's fixed header and per-triangle record add up to for the triangle count check() reported.

There is one check no other control on this page runs: the built solids are compared against the cavity the generator says it left, on all three axes at once, so a wall standing in the middle of the hole would be caught. check() has no opinion about that — material in the wrong place is still a sound mesh.

The corners are stepped on purpose, and the edge tally is how you can tell. As the edge count above records, the bench plate is not one closed surface: wherever two of its wall boxes meet at a shared corner, the vertical line at that corner is a real edge of both boxes and four triangles land on it.

The tray is laid out so that never happens. Its two end walls run the full width of the base; its two side walls sit between them, inset by the same 2 mm margin the plate uses, so each side wall lands on a face strictly wider than itself — a T-junction rather than a butt joint — and shares no vertex with it.

Five boxes, sixty triangles, ninety distinct edges, none of them shared — so every tray this control builds comes back zero used once, zero used more than twice, at every pair of dimensions. That costs something you can see on the part: a 2 mm ledge of bare base right round the outside, and end walls that stand 2 mm further out at each side than the side walls do.

Both are real, not rendering artefacts, and both show up in the top view the control draws. You do not have to take any of this on trust: the tally printed under your download is counted out of the bytes you were just handed, by a parser that has never seen the generator.

A tray you build here has not been printed. None has. Whether 12 mm is deep enough for what you want to put in it, whether the walls are stiff enough at 2 mm, and whether a 200 mm tray fits your bed are all questions this page cannot answer, because it has no printer, no filament and no bench. What it can tell you is that the geometry closes and that the hole is the size you asked for, and it shows you the count both times.

What this page does not claim


← All electronics build-logs

Back to the top