circuit-json-to-step 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,48 @@
1
+ import { writeFileSync } from "node:fs"
2
+ import { test, expect } from "bun:test"
3
+ import { circuitJsonToStep } from "../../../lib/index"
4
+ import { importStepWithOcct } from "../../utils/occt/importer"
5
+ import circuitJson from "./repro01.json"
6
+
7
+ test("basics04: convert circuit json with components to STEP", async () => {
8
+ const stepText = await circuitJsonToStep(circuitJson as any, {
9
+ includeComponents: true,
10
+ productName: "TestPCB_with_components",
11
+ })
12
+
13
+ // Verify STEP format
14
+ expect(stepText).toContain("ISO-10303-21")
15
+ expect(stepText).toContain("END-ISO-10303-21")
16
+
17
+ // Verify product structure
18
+ expect(stepText).toContain("TestPCB_with_components")
19
+ expect(stepText).toContain("MANIFOLD_SOLID_BREP")
20
+
21
+ // Verify holes are created
22
+ expect(stepText).toContain("CIRCLE")
23
+ expect(stepText).toContain("CYLINDRICAL_SURFACE")
24
+
25
+ // Verify we have multiple solids (board + components)
26
+ const solidCount = (stepText.match(/MANIFOLD_SOLID_BREP/g) || []).length
27
+ expect(solidCount).toBeGreaterThanOrEqual(1)
28
+
29
+ // Write STEP file to debug-output
30
+ const outputPath = "debug-output/basics04.step"
31
+ writeFileSync(outputPath, stepText)
32
+
33
+ console.log("✓ STEP file with components generated successfully")
34
+ console.log(` - Solids created: ${solidCount}`)
35
+ console.log(` - STEP text length: ${stepText.length} bytes`)
36
+ console.log(` - Output: ${outputPath}`)
37
+
38
+ // Validate STEP file can be imported with occt-import-js
39
+ const occtResult = await importStepWithOcct(stepText)
40
+ expect(occtResult.success).toBe(true)
41
+ expect(occtResult.meshes.length).toBeGreaterThan(0)
42
+
43
+ const [firstMesh] = occtResult.meshes
44
+ expect(firstMesh.attributes.position.array.length).toBeGreaterThan(0)
45
+ expect(firstMesh.index.array.length).toBeGreaterThan(0)
46
+
47
+ console.log("✓ STEP file successfully validated with occt-import-js")
48
+ }, 30000)
@@ -0,0 +1,119 @@
1
+ export type OcctLinearUnit =
2
+ | "millimeter"
3
+ | "centimeter"
4
+ | "meter"
5
+ | "inch"
6
+ | "foot"
7
+
8
+ export type OcctLinearDeflectionType = "bounding_box_ratio" | "absolute_value"
9
+
10
+ export interface OcctImportParams {
11
+ linearUnit?: OcctLinearUnit
12
+ linearDeflectionType?: OcctLinearDeflectionType
13
+ linearDeflection?: number
14
+ angularDeflection?: number
15
+ }
16
+
17
+ export interface OcctImportNode {
18
+ name: string
19
+ meshes: number[]
20
+ children: OcctImportNode[]
21
+ }
22
+
23
+ export interface OcctMeshAttributeData {
24
+ array: number[]
25
+ }
26
+
27
+ export interface OcctMeshAttributes {
28
+ position: OcctMeshAttributeData
29
+ normal?: OcctMeshAttributeData
30
+ }
31
+
32
+ export interface OcctMeshFaceRange {
33
+ first: number
34
+ last: number
35
+ color: [number, number, number] | null
36
+ }
37
+
38
+ export interface OcctMesh {
39
+ name: string
40
+ color?: [number, number, number]
41
+ brep_faces: OcctMeshFaceRange[]
42
+ attributes: OcctMeshAttributes
43
+ index: { array: number[] }
44
+ }
45
+
46
+ export interface OcctImportResult {
47
+ success: boolean
48
+ root: OcctImportNode
49
+ meshes: OcctMesh[]
50
+ }
51
+
52
+ type OcctImport = {
53
+ ReadStepFile(
54
+ content: ArrayBufferView | ArrayBuffer,
55
+ params: OcctImportParams | null,
56
+ ): OcctImportResult
57
+ ReadBrepFile(
58
+ content: ArrayBufferView | ArrayBuffer,
59
+ params: OcctImportParams | null,
60
+ ): OcctImportResult
61
+ ReadIgesFile(
62
+ content: ArrayBufferView | ArrayBuffer,
63
+ params: OcctImportParams | null,
64
+ ): OcctImportResult
65
+ }
66
+
67
+ type OcctImportFactory = () => Promise<OcctImport>
68
+
69
+ let occtInstancePromise: Promise<OcctImport> | undefined
70
+
71
+ async function loadOcct(): Promise<OcctImport> {
72
+ if (!occtInstancePromise) {
73
+ const imported = (await import("occt-import-js")) as any
74
+ const factory = resolveFactory(imported)
75
+ occtInstancePromise = factory()
76
+ }
77
+ return occtInstancePromise
78
+ }
79
+
80
+ function resolveFactory(candidate: unknown): OcctImportFactory {
81
+ if (typeof candidate === "function") {
82
+ return candidate as OcctImportFactory
83
+ }
84
+ if (
85
+ candidate &&
86
+ typeof candidate === "object" &&
87
+ "default" in candidate &&
88
+ typeof (candidate as { default: unknown }).default === "function"
89
+ ) {
90
+ return (candidate as { default: unknown }).default as OcctImportFactory
91
+ }
92
+ throw new Error("Unable to resolve occt-import-js factory export")
93
+ }
94
+
95
+ export type StepInput = string | ArrayBuffer | ArrayBufferView
96
+
97
+ function toUint8Array(input: StepInput): Uint8Array {
98
+ if (typeof input === "string") {
99
+ return new TextEncoder().encode(input)
100
+ }
101
+ if (input instanceof ArrayBuffer) {
102
+ return new Uint8Array(input)
103
+ }
104
+ const view = input as ArrayBufferView
105
+ return new Uint8Array(view.buffer, view.byteOffset, view.byteLength)
106
+ }
107
+
108
+ export async function importStepWithOcct(
109
+ input: StepInput,
110
+ params: OcctImportParams | null = null,
111
+ ): Promise<OcctImportResult> {
112
+ const occt = await loadOcct()
113
+ const data = toUint8Array(input)
114
+ const result = occt.ReadStepFile(data, params)
115
+ if (!result.success) {
116
+ throw new Error("occt-import-js failed to load STEP file")
117
+ }
118
+ return result
119
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Environment setup & latest features
4
+ "lib": ["ESNext"],
5
+ "target": "ESNext",
6
+ "module": "Preserve",
7
+ "moduleDetection": "force",
8
+ "jsx": "react-jsx",
9
+ "allowJs": true,
10
+
11
+ // Bundler mode
12
+ "moduleResolution": "bundler",
13
+ "allowImportingTsExtensions": true,
14
+ "verbatimModuleSyntax": true,
15
+ "noEmit": true,
16
+
17
+ // Best practices
18
+ "strict": true,
19
+ "skipLibCheck": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noUncheckedIndexedAccess": false,
22
+ "noImplicitOverride": true,
23
+
24
+ // Some stricter flags (disabled by default)
25
+ "noUnusedLocals": false,
26
+ "noUnusedParameters": false,
27
+ "noPropertyAccessFromIndexSignature": false
28
+ },
29
+ "exclude": ["circuit-json", "stepts"]
30
+ }