generated from tscircuit/template-api-fake
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from tscircuit/debug-scaling-issue
fix scaling issue of dsn-converter
- Loading branch information
Showing
8 changed files
with
400 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import type { AnyCircuitElement } from "@tscircuit/soup" | ||
import fs from "node:fs" | ||
import path from "node:path" | ||
|
||
function formatNumber(num: number) { | ||
return typeof num === "number" ? Number(num.toFixed(1)) : "N/A" | ||
} | ||
|
||
function formatPoint(x: number, y: number) { | ||
return `(${formatNumber(x)}, ${formatNumber(y)})` | ||
} | ||
|
||
function convertCircuitJsonToMarkdown(circuitJson: any, title?: string) { | ||
let markdown = title ? `# ${title}\n\n` : "# Circuit Component Analysis\n\n" | ||
|
||
// Source Components | ||
const sourceComponents = circuitJson.filter( | ||
(item: AnyCircuitElement) => item.type === "source_component", | ||
) | ||
if (sourceComponents.length > 0) { | ||
markdown += "## Source Components\n" | ||
markdown += "| ID | Name | Type |\n" | ||
markdown += "|----|------|------|\n" | ||
for (const comp of sourceComponents) { | ||
const shortId = comp.source_component_id.split(":").pop() | ||
markdown += `| ${shortId} | ${comp.name} | ${comp.ftype} |\n` | ||
} | ||
markdown += "\n" | ||
} | ||
|
||
// PCB Ports | ||
const ports = circuitJson.filter( | ||
(item: AnyCircuitElement) => item.type === "pcb_port", | ||
) | ||
if (ports.length > 0) { | ||
markdown += "## PCB Ports\n" | ||
markdown += "| ID | Position (x,y) |\n" | ||
markdown += "|-----|---------------|\n" | ||
for (const port of ports) { | ||
const shortId = port.pcb_port_id.split("-").slice(-2).join("-") | ||
markdown += `| ${shortId} | ${formatPoint(port.x, port.y)} |\n` | ||
} | ||
markdown += "\n" | ||
} | ||
|
||
// SMT Pads | ||
const pads = circuitJson.filter( | ||
(item: AnyCircuitElement) => item.type === "pcb_smtpad", | ||
) | ||
if (pads.length > 0) { | ||
markdown += "## SMT Pads\n" | ||
markdown += "| Component | Position (x,y) | Size (w×h) |\n" | ||
markdown += "|-----------|---------------|-------------|\n" | ||
for (const pad of pads) { | ||
const shortId = pad.pcb_smtpad_id.split("_").slice(-3).join("-") | ||
markdown += `| ${shortId} | ${formatPoint(pad.x, pad.y)} | ${formatNumber(pad.width)} × ${formatNumber(pad.height)} |\n` | ||
} | ||
markdown += "\n" | ||
} | ||
|
||
// Traces | ||
const traces = circuitJson.filter( | ||
(item: AnyCircuitElement) => item.type === "pcb_trace", | ||
) | ||
if (traces.length > 0) { | ||
markdown += "## Trace Route Points\n" | ||
markdown += "| Point | Position (x,y) | Width |\n" | ||
markdown += "|-------|---------------|--------|\n" | ||
for (const trace of traces) { | ||
for (const [index, point] of trace.route.entries()) { | ||
if (point.route_type === "wire") { | ||
markdown += `| ${index + 1} | ${formatPoint(point.x, point.y)} | ${formatNumber(point.width)} |\n` | ||
} | ||
} | ||
} | ||
} | ||
|
||
return markdown | ||
} | ||
|
||
export function circuitJsonToMarkdownTable( | ||
circuitJson: AnyCircuitElement[], | ||
outputPath: string, | ||
title?: string, | ||
) { | ||
try { | ||
const markdown = convertCircuitJsonToMarkdown(circuitJson, title) | ||
// Resolve the output path relative to the current file's directory | ||
const resolvedOutputPath = path.resolve(__dirname, outputPath) | ||
console.log(`Resolved output path: ${resolvedOutputPath}`) | ||
fs.writeFileSync(resolvedOutputPath, markdown) | ||
console.log(`Circuit JSON has been written to ${resolvedOutputPath}`) | ||
return markdown | ||
} catch (error) { | ||
console.error("Error processing circuit JSON:", error) | ||
throw error | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import fs from "node:fs" | ||
import path from "node:path" | ||
|
||
function formatNumber(num: number) { | ||
// Format number to 2 decimal places and remove trailing zeros | ||
return parseFloat(num.toFixed(2)).toString() | ||
} | ||
|
||
function extractWirePathPoints(sesContent: string) { | ||
const wirePathRegex = /path\s+([A-Za-z.]+)\s+([0-9.]+)\s+([\d.-\s]+)/g | ||
const paths = [] | ||
|
||
let match: RegExpExecArray | null | ||
while (true) { | ||
match = wirePathRegex.exec(sesContent) | ||
if (match === null) break | ||
const layer = match[1] | ||
const width = match[2] | ||
const coordinates = match[3].trim().split(/\s+/) | ||
|
||
const points = [] | ||
for (let i = 0; i < coordinates.length; i += 2) { | ||
points.push({ | ||
x: parseFloat(coordinates[i]), | ||
y: parseFloat(coordinates[i + 1]), | ||
}) | ||
} | ||
|
||
paths.push({ | ||
layer, | ||
width, | ||
points, | ||
}) | ||
} | ||
|
||
return paths | ||
} | ||
|
||
function generateMarkdownTable(paths: any, title?: string) { | ||
let markdown = title ? `# ${title}\n\n` : "# Wire Path Points Analysis\n\n" | ||
|
||
for (const [index, path] of paths.entries()) { | ||
markdown += `## Wire Path ${index + 1}\n` | ||
markdown += `- Layer: ${path.layer}\n` | ||
markdown += `- Width: ${path.width}mm\n\n` | ||
|
||
// Fixed width columns with padding | ||
markdown += "| Point # | X (μm) | Y (μm) |\n" | ||
markdown += "|---------|--------------|--------------||\n" | ||
|
||
for (const [pointIndex, point] of path.points.entries()) { | ||
const formattedX = formatNumber(point.x).padStart(12, " ") | ||
const formattedY = formatNumber(point.y).padStart(12, " ") | ||
markdown += `| ${(pointIndex + 1).toString().padStart(2)} |${formattedX}|${formattedY}|\n` | ||
} | ||
|
||
markdown += "\n" | ||
} | ||
|
||
return markdown | ||
} | ||
|
||
export function analyzeWirePaths( | ||
sesContent: string, | ||
outputPath: string, | ||
title?: string, | ||
) { | ||
try { | ||
const paths = extractWirePathPoints(sesContent) | ||
const markdown = generateMarkdownTable(paths, title) | ||
const resolvedOutputPath = path.resolve(__dirname, outputPath) | ||
fs.writeFileSync(resolvedOutputPath, markdown) | ||
console.log(`Wire path analysis has been written to ${resolvedOutputPath}`) | ||
|
||
return paths | ||
} catch (error) { | ||
console.error("Error processing file:", error) | ||
throw error | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import fs from "node:fs" | ||
import path from "node:path" | ||
|
||
function formatNumber(num: number) { | ||
return parseFloat(num.toFixed(2)).toString().padStart(8, " ") | ||
} | ||
|
||
function convertRouteJsonToMarkdown(routeJson: any, title?: string) { | ||
let markdown = title ? `# ${title}\n\n` : "# Simple Route JSON Analysis\n\n" | ||
|
||
// Basic Information | ||
markdown += "## General Information\n" | ||
markdown += `- Minimum Trace Width: ${routeJson.minTraceWidth}mm\n` | ||
markdown += `- Layer Count: ${routeJson.layerCount}\n\n` | ||
|
||
// Bounds Information | ||
markdown += "## Board Bounds\n" | ||
markdown += "| Dimension | Min (mm) | Max (mm) |\n" | ||
markdown += "|-----------|----------|----------|\n" | ||
markdown += `| X |${formatNumber(routeJson.bounds.minX)}|${formatNumber(routeJson.bounds.maxX)}|\n` | ||
markdown += `| Y |${formatNumber(routeJson.bounds.minY)}|${formatNumber(routeJson.bounds.maxY)}|\n\n` | ||
|
||
// Obstacles | ||
markdown += "## Obstacles\n" | ||
markdown += | ||
"| Type | Layer | X (mm) | Y (mm) | Width (mm) | Height (mm) | Connected To |\n" | ||
markdown += | ||
"|-------|--------|---------|---------|------------|-------------|-------------|\n" | ||
|
||
for (const obstacle of routeJson.obstacles) { | ||
markdown += `| ${obstacle.type} | ${obstacle.layers.join(", ")} |` | ||
markdown += `${formatNumber(obstacle.center.x)}|${formatNumber(obstacle.center.y)}|` | ||
markdown += `${formatNumber(obstacle.width)}|${formatNumber(obstacle.height)}|` | ||
markdown += ` ${obstacle.connectedTo.map((conn: any) => `\n- ${conn}`).join("")} |\n` | ||
} | ||
markdown += "\n" | ||
|
||
// Connections | ||
markdown += "## Connections\n" | ||
for (const [index, connection] of routeJson.connections.entries()) { | ||
markdown += `### Connection ${index + 1}: ${connection.name}\n` | ||
markdown += "| Point | X (mm) | Y (mm) | Layer | Port ID |\n" | ||
markdown += "|--------|---------|---------|--------|----------|\n" | ||
|
||
for (const [pointIndex, point] of connection.pointsToConnect.entries()) { | ||
markdown += `| ${pointIndex + 1} |` | ||
markdown += `${formatNumber(point.x)}|${formatNumber(point.y)}|` | ||
markdown += ` ${point.layer} | ${point.pcb_port_id} |\n` | ||
} | ||
markdown += "\n" | ||
} | ||
|
||
return markdown | ||
} | ||
|
||
export function saveRouteAnalysis( | ||
routeJson: any, | ||
outputPath: string, | ||
title?: string, | ||
) { | ||
try { | ||
const markdown = convertRouteJsonToMarkdown(routeJson, title) | ||
// Resolve the output path relative to the current file's directory | ||
const resolvedOutputPath = path.resolve(__dirname, outputPath) | ||
fs.writeFileSync(resolvedOutputPath, markdown) | ||
console.log(`Route analysis has been written to ${resolvedOutputPath}`) | ||
return markdown | ||
} catch (error) { | ||
console.error("Error processing route JSON:", error) | ||
throw error | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
tests/routes/_fake/__snapshots__/run-autorouter-passing-circuit-json.snap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.