app
Adom Fields
Public Made by Adomby adom
Adom Fields: where the current and the heat go on your board.
← Commit history
adom-fields 0.6.2: the board gets the whole pane (panels slide over below 1400 px) and the camera fits the pane's shape
8 files changed
+21−11
Cargo.lock+1−1@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "adom-fields"-version = "0.6.1"+version = "0.6.2" dependencies = [ "clap", "png",
Cargo.toml+1−1@@ -1,6 +1,6 @@ [package] name = "adom-fields"-version = "0.6.1"+version = "0.6.2" edition = "2021" license = "MIT" description = "Adom Fields: where the current and the heat go on your board. Current density, copper heat flow and board temperature from the board file itself, in 3D, for the AI to drive and the human to explore."
bin/adom-fields⋯ 1 unchanged line ⋯
docs/release-0.6.2.mdadded+7@@ -0,0 +1,7 @@+# adom-fields 0.6.2++- **More of the board in a Hydrogen pane.** Below 1400 px wide (a Hydrogen right pane, a laptop) the two side panels slide over the board on demand (the list and the warning buttons in the header) instead of taking 620 px beside it, so the 3D board gets the whole pane.+- **The camera fits the pane's own shape.** Top, bottom and iso views compute the distance from the field of view and the pane's aspect ratio, so a tall narrow pane is no longer limited to the width of a square one and the board fills the view.+- The header buttons say what they open ("Nets, layers and hot parts", "Issues and how it was solved") instead of "(phone)".++Note on 3D parts: adom-fields places each part's STEP exactly as the board binds it. The standing inductor in the 2026-10-07 Fusion buck video was the component page's STEP, not adom-fields: that STEP had its representation frame turned with its geometry, so every OpenCascade reader turned it twice. The page is fixed (john/amplh5030s-150mt 1.1.3) and AI Flow 0.1.60 checks every model with the STEP service before a library uses it.
package.json+1−1@@ -1,7 +1,7 @@ { "slug": "adom-fields", "type": "app",- "version": "0.6.1",+ "version": "0.6.2", "title": "Adom Fields", "brief": "Adom Fields: where the current and the heat go on your board.", "summary": "Current density on the copper, heat flow through the pours and the vias, and the temperature over the board, solved from the board file itself and shown on the board in 3D. The AI does the analysis and drives the view; the human orbits, zooms, hovers for the number under the cursor, and reads the nets by what they carry and the issues by what to fix. A step in Adom's AI Flow: the walkthrough goes into the video.",
page.json+1−1@@ -1,7 +1,7 @@ { "slug": "adom-fields", "type": "app",- "version": "0.6.1",+ "version": "0.6.2", "title": "Adom Fields", "brief": "Adom Fields: where the current and the heat go on your board.", "summary": "Current density on the copper, heat flow through the pours and the vias, and the temperature over the board, solved from the board file itself and shown on the board in 3D. The AI does the analysis and drives the view; the human orbits, zooms, hovers for the number under the cursor, and reads the nets by what they carry and the issues by what to fix. A step in Adom's AI Flow: the walkthrough goes into the video.",
src/ui/app.js+7−4@@ -201,13 +201,16 @@ const NORTH = Math.PI / 2; function fitCamera(which) { if (!board) return;- const R = Math.max(board.widthMm, board.heightMm) * 1.15;+ // fit the board to the pane's own shape: a tall narrow pane is limited by its width, a wide one by its height+ const vf = camera.fov || 0.8, aspect = scene.getEngine().getAspectRatio(camera) || 1;+ const hf = 2 * Math.atan(Math.tan(vf / 2) * aspect);+ const R = Math.max((board.heightMm / 2) / Math.tan(vf / 2), (board.widthMm / 2) / Math.tan(hf / 2)) * 1.06; const home = BAB.Vector3.Zero(); const flipping = (which === 'bottom' && camera.beta < Math.PI / 2) || (which === 'top' && camera.beta > Math.PI / 2); const s = flipping ? 2.6 : 9.0; // the turn-over is quick, everything else is slow- if (which === 'top') goto(NORTH, 0.02, R * 1.05, home, s);- else if (which === 'bottom') goto(NORTH, Math.PI - 0.02, R * 1.05, home, s);- else if (which === 'iso') goto(NORTH - 0.55, 0.95, R * 1.25, home, s);+ if (which === 'top') goto(NORTH, 0.02, R, home, s);+ else if (which === 'bottom') goto(NORTH, Math.PI - 0.02, R, home, s);+ else if (which === 'iso') goto(NORTH - 0.55, 0.95, R * 1.08, home, s); else { tweens = []; tweening = 0; V.goHome(); } } function zoomTo(x, y, fromBelow) {
src/ui/index.html+3−3@@ -72,7 +72,7 @@ body{margin:0;background:var(--bg);color:var(--text-body);font-family:"Satoshi", .dot{width:8px;height:8px;border-radius:50%;background:var(--green);display:inline-block;margin-right:6px} .dot.off{background:var(--red)} /* the phone: one column, the stage full height, the side panels as sheets from the header buttons */-@media(max-width:900px){.app-body{grid-template-columns:minmax(0,1fr)}.side{display:none}.side.is-open{display:flex;position:fixed;inset:44px 0 26px 0;z-index:20}.stage{min-height:0}}+/* a Hydrogen pane or a laptop: the board gets the whole width, the panels slide over it on demand */@media(max-width:1400px){.app-body{grid-template-columns:minmax(0,1fr)}.side{display:none}.side.is-open{display:flex;position:fixed;top:44px;bottom:26px;left:0;width:min(320px,90vw);z-index:20;box-shadow:0 8px 24px rgba(0,0,0,.45)}.side.right.is-open{left:auto;right:0}.stage{min-height:0}}@media(min-width:1401px){#btnNets,#btnIssues{display:none}} </style> </head> <body>@@ -86,8 +86,8 @@ body{margin:0;background:var(--bg);color:var(--text-body);font-family:"Satoshi", <div class="vsep"></div> <div class="subject"><b id="boardName">loading</b><span class="meta" id="boardMeta"></span></div> <div class="actions">- <button class="ibtn" id="btnNets" data-tip="Nets and layers (phone)" aria-pressed="false"><svg viewBox="0 0 24 24"><path d="M4 6h16M4 12h16M4 18h16"/></svg></button>- <button class="ibtn" id="btnIssues" data-tip="Issues (phone)" aria-pressed="false"><svg viewBox="0 0 24 24"><path d="M12 9v4M12 17h.01M10.3 3.9 2.5 17a2 2 0 0 0 1.7 3h15.6a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/></svg></button>+ <button class="ibtn" id="btnNets" data-tip="Nets, layers and hot parts" aria-pressed="false"><svg viewBox="0 0 24 24"><path d="M4 6h16M4 12h16M4 18h16"/></svg></button>+ <button class="ibtn" id="btnIssues" data-tip="Issues and how it was solved" aria-pressed="false"><svg viewBox="0 0 24 24"><path d="M12 9v4M12 17h.01M10.3 3.9 2.5 17a2 2 0 0 0 1.7 3h15.6a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/></svg></button> <button class="ibtn" id="btnParts" data-tip="The parts' 3D bodies over the field: see-through, solid, or off" aria-pressed="false"><svg viewBox="0 0 24 24"><path d="M12 3l8 4.5v9L12 21l-8-4.5v-9z"/><path d="M12 12l8-4.5M12 12v9M12 12L4 7.5"/></svg></button> <button class="ibtn" id="btnLight" data-tip="Light the underside (dark parts)" aria-pressed="false"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg></button> </div>