circuit-json-to-tscircuit 0.0.87 → 0.0.89
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.
- package/dist/{chunk-DZP2ZWBQ.js → chunk-GVGY3ZZN.js} +256 -29
- package/dist/cli/main.js +5 -2
- package/dist/lib/index.js +1 -1
- package/lib/generate-board-cad-models-tsx/converter-types.ts +25 -0
- package/lib/generate-board-cad-models-tsx/format-point-prop.ts +7 -0
- package/lib/generate-board-cad-models-tsx/generate-cad-model-group-tsx.ts +43 -0
- package/lib/generate-board-cad-models-tsx/generate-cad-model-tsx.ts +56 -0
- package/lib/generate-board-cad-models-tsx/get-cad-model-groups.ts +54 -0
- package/lib/generate-board-cad-models-tsx/get-cad-model-origin-position.ts +13 -0
- package/lib/generate-board-cad-models-tsx/get-cad-model-placement.ts +46 -0
- package/lib/generate-board-cad-models-tsx/get-cad-model-url.ts +26 -0
- package/lib/generate-board-cad-models-tsx/get-model-url-with-format-hint.ts +10 -0
- package/lib/generate-board-cad-models-tsx.ts +22 -0
- package/lib/generate-footprint-tsx/convert-notes.ts +3 -0
- package/lib/get-board-using-template.ts +7 -1
- package/package.json +4 -1
- package/tests/__snapshots__/pcb-note-rounded-corners-comparison.snap.svg +8 -0
- package/tests/board-bottom-cad-model-rotation.test.ts +70 -0
- package/tests/fixtures/create-ti-evm-cad-model-loss-repro.ts +58 -0
- package/tests/fixtures/create-ti-evm-cad-model-visual-repro.ts +45 -0
- package/tests/fixtures/expect-ti-evm-3d-snapshot.ts +221 -0
- package/tests/fixtures/ti-evms/README.md +6 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/0.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/1.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/10.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/11.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/12.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/13.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/14.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/15.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/2.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/3.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/4.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/5.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/6.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/7.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/8.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/dp83825evm/9.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/drv8307evm/0.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/drv8307evm/1.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/drv8307evm/2.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/drv8307evm/3.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/drv8307evm/4.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/drv8307evm/5.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/0.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/1.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/10.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/11.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/12.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/13.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/14.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/15.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/16.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/17.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/18.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/19.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/2.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/20.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/21.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/22.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/23.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/24.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/25.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/26.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/27.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/28.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/29.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/3.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/30.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/31.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/32.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/33.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/34.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/35.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/36.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/37.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/38.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/39.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/4.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/40.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/41.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/42.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/43.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/44.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/45.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/5.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/6.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/7.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/8.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm251772evm-pd/9.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/0.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/1.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/10.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/11.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/12.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/13.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/14.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/15.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/16.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/17.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/2.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/3.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/4.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/5.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/6.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/7.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/8.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lm5155evm-fly/9.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/0.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/1.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/10.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/11.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/12.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/13.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/14.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/15.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/16.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/17.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/18.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/19.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/2.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/20.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/21.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/22.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/23.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/24.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/25.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/26.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/27.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/28.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/3.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/4.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/5.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/6.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/7.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/8.step.gz +0 -0
- package/tests/fixtures/ti-evms/cad-models/lmg342x-bb-evm/9.step.gz +0 -0
- package/tests/fixtures/ti-evms/dp83825evm-cad.circuit.json.gz +0 -0
- package/tests/fixtures/ti-evms/drv8307evm-cad.circuit.json.gz +0 -0
- package/tests/fixtures/ti-evms/lm251772evm-pd-cad.circuit.json.gz +0 -0
- package/tests/fixtures/ti-evms/lm5155evm-fly-cad.circuit.json.gz +0 -0
- package/tests/fixtures/ti-evms/lmg342x-bb-evm-cad.circuit.json.gz +0 -0
- package/tests/pcb-note-rounded-corners.test.tsx +63 -0
- package/tests/ti-evms/__snapshots__/ti-dp83825evm-cad-model-loss-generated-bottom-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-dp83825evm-cad-model-loss-generated-top-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-dp83825evm-cad-model-loss-source-bottom-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-dp83825evm-cad-model-loss-source-top-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-drv8307evm-cad-model-loss-generated-bottom-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-drv8307evm-cad-model-loss-generated-top-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-drv8307evm-cad-model-loss-source-bottom-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-drv8307evm-cad-model-loss-source-top-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-lm251772evm-pd-cad-model-loss-generated-bottom-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-lm251772evm-pd-cad-model-loss-generated-top-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-lm251772evm-pd-cad-model-loss-source-bottom-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-lm251772evm-pd-cad-model-loss-source-top-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-lm5155evm-fly-cad-model-loss-generated-bottom-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-lm5155evm-fly-cad-model-loss-generated-top-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-lm5155evm-fly-cad-model-loss-source-bottom-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-lm5155evm-fly-cad-model-loss-source-top-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-lmg342x-bb-evm-cad-model-loss-generated-bottom-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-lmg342x-bb-evm-cad-model-loss-generated-top-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-lmg342x-bb-evm-cad-model-loss-source-bottom-3d.snap.png +0 -0
- package/tests/ti-evms/__snapshots__/ti-lmg342x-bb-evm-cad-model-loss-source-top-3d.snap.png +0 -0
- package/tests/ti-evms/ti-dp83825evm-cad-model-loss.test.tsx +23 -0
- package/tests/ti-evms/ti-drv8307evm-cad-model-loss.test.tsx +23 -0
- package/tests/ti-evms/ti-lm251772evm-pd-cad-model-loss.test.tsx +23 -0
- package/tests/ti-evms/ti-lm5155evm-fly-cad-model-loss.test.tsx +23 -0
- package/tests/ti-evms/ti-lmg342x-bb-evm-cad-model-loss.test.tsx +23 -0
|
@@ -140,6 +140,222 @@ var getRuntimeNetNamesBySourcePortId = ({
|
|
|
140
140
|
return result;
|
|
141
141
|
};
|
|
142
142
|
|
|
143
|
+
// lib/generate-board-cad-models-tsx/format-point-prop.ts
|
|
144
|
+
function formatPointProp(point) {
|
|
145
|
+
return `{ x: ${point.x}, y: ${point.y}, z: ${point.z} }`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// lib/generate-board-cad-models-tsx/get-cad-model-origin-position.ts
|
|
149
|
+
function getCadModelOriginPosition(cadComponent) {
|
|
150
|
+
if (cadComponent.model_origin_position !== void 0) {
|
|
151
|
+
return cadComponent.model_origin_position;
|
|
152
|
+
}
|
|
153
|
+
if (cadComponent.model_origin_alignment === "unknown") {
|
|
154
|
+
return { x: 0, y: 0, z: 0 };
|
|
155
|
+
}
|
|
156
|
+
return void 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// lib/generate-board-cad-models-tsx/get-cad-model-placement.ts
|
|
160
|
+
function getCadModelPlacement({
|
|
161
|
+
cadComponent,
|
|
162
|
+
parentPlacement,
|
|
163
|
+
pcbBoard
|
|
164
|
+
}) {
|
|
165
|
+
const cadModelCcwRotationDegrees = cadComponent.rotation ?? {
|
|
166
|
+
x: 0,
|
|
167
|
+
y: 0,
|
|
168
|
+
z: 0
|
|
169
|
+
};
|
|
170
|
+
const boardSurfaceZ = pcbBoard.thickness / 2;
|
|
171
|
+
let positionOffsetZ = cadComponent.position.z - boardSurfaceZ;
|
|
172
|
+
let ccwRotationOffsetDegrees = {
|
|
173
|
+
x: cadModelCcwRotationDegrees.x,
|
|
174
|
+
y: cadModelCcwRotationDegrees.y,
|
|
175
|
+
z: cadModelCcwRotationDegrees.z - parentPlacement.ccwRotationDegrees
|
|
176
|
+
};
|
|
177
|
+
if (parentPlacement.layer === "bottom") {
|
|
178
|
+
positionOffsetZ = cadComponent.position.z + boardSurfaceZ;
|
|
179
|
+
ccwRotationOffsetDegrees = {
|
|
180
|
+
x: cadModelCcwRotationDegrees.x,
|
|
181
|
+
y: cadModelCcwRotationDegrees.y - 180,
|
|
182
|
+
z: cadModelCcwRotationDegrees.z + parentPlacement.ccwRotationDegrees
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
positionOffset: {
|
|
187
|
+
x: cadComponent.position.x - parentPlacement.center.x,
|
|
188
|
+
y: cadComponent.position.y - parentPlacement.center.y,
|
|
189
|
+
z: positionOffsetZ
|
|
190
|
+
},
|
|
191
|
+
ccwRotationOffsetDegrees
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// lib/generate-board-cad-models-tsx/get-cad-model-url.ts
|
|
196
|
+
function getCadModelUrl(cadComponent) {
|
|
197
|
+
if (cadComponent.model_glb_url) {
|
|
198
|
+
return { format: "glb", url: cadComponent.model_glb_url };
|
|
199
|
+
}
|
|
200
|
+
if (cadComponent.model_gltf_url) {
|
|
201
|
+
return { format: "gltf", url: cadComponent.model_gltf_url };
|
|
202
|
+
}
|
|
203
|
+
if (cadComponent.model_obj_url) {
|
|
204
|
+
return { format: "obj", url: cadComponent.model_obj_url };
|
|
205
|
+
}
|
|
206
|
+
if (cadComponent.model_step_url) {
|
|
207
|
+
return { format: "step", url: cadComponent.model_step_url };
|
|
208
|
+
}
|
|
209
|
+
if (cadComponent.model_stl_url) {
|
|
210
|
+
return { format: "stl", url: cadComponent.model_stl_url };
|
|
211
|
+
}
|
|
212
|
+
if (cadComponent.model_wrl_url) {
|
|
213
|
+
return { format: "wrl", url: cadComponent.model_wrl_url };
|
|
214
|
+
}
|
|
215
|
+
return void 0;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// lib/generate-board-cad-models-tsx/get-model-url-with-format-hint.ts
|
|
219
|
+
function getModelUrlWithFormatHint({
|
|
220
|
+
format,
|
|
221
|
+
url
|
|
222
|
+
}) {
|
|
223
|
+
const pathWithoutQuery = url.split(/[?#]/u)[0] ?? "";
|
|
224
|
+
if (pathWithoutQuery.toLowerCase().endsWith(`.${format}`)) return url;
|
|
225
|
+
return `${url}#ext=${format}`;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// lib/generate-board-cad-models-tsx/generate-cad-model-tsx.ts
|
|
229
|
+
function generateCadModelTsx({
|
|
230
|
+
cadComponent,
|
|
231
|
+
parentPlacement,
|
|
232
|
+
pcbBoard
|
|
233
|
+
}) {
|
|
234
|
+
const modelUrl = getCadModelUrl(cadComponent);
|
|
235
|
+
if (!modelUrl) return void 0;
|
|
236
|
+
const placement = getCadModelPlacement({
|
|
237
|
+
cadComponent,
|
|
238
|
+
parentPlacement,
|
|
239
|
+
pcbBoard
|
|
240
|
+
});
|
|
241
|
+
const attributes = [
|
|
242
|
+
`modelUrl={${JSON.stringify(getModelUrlWithFormatHint(modelUrl))}}`,
|
|
243
|
+
`positionOffset={${formatPointProp(placement.positionOffset)}}`,
|
|
244
|
+
`rotationOffset={${formatPointProp(placement.ccwRotationOffsetDegrees)}}`
|
|
245
|
+
];
|
|
246
|
+
if (cadComponent.model_unit_to_mm_scale_factor !== void 0) {
|
|
247
|
+
attributes.push(
|
|
248
|
+
`modelUnitToMmScale={${cadComponent.model_unit_to_mm_scale_factor}}`
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
if (cadComponent.model_board_normal_direction !== void 0) {
|
|
252
|
+
attributes.push(
|
|
253
|
+
`modelBoardNormalDirection={${JSON.stringify(cadComponent.model_board_normal_direction)}}`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
const modelOriginPosition = getCadModelOriginPosition(cadComponent);
|
|
257
|
+
if (modelOriginPosition !== void 0) {
|
|
258
|
+
attributes.push(
|
|
259
|
+
`modelOriginPosition={${formatPointProp(modelOriginPosition)}}`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
if (cadComponent.size !== void 0) {
|
|
263
|
+
attributes.push(`size={${formatPointProp(cadComponent.size)}}`);
|
|
264
|
+
}
|
|
265
|
+
if (cadComponent.show_as_translucent_model === true) {
|
|
266
|
+
attributes.push("showAsTranslucentModel");
|
|
267
|
+
}
|
|
268
|
+
return `<cadmodel ${attributes.join(" ")} />`;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// lib/generate-board-cad-models-tsx/generate-cad-model-group-tsx.ts
|
|
272
|
+
function generateCadModelGroupTsx({
|
|
273
|
+
cadModelGroup,
|
|
274
|
+
groupIndex,
|
|
275
|
+
pcbBoard
|
|
276
|
+
}) {
|
|
277
|
+
const { cadComponents, parentPlacement } = cadModelGroup;
|
|
278
|
+
const modelElements = cadComponents.flatMap((cadComponent) => {
|
|
279
|
+
const modelElement = generateCadModelTsx({
|
|
280
|
+
cadComponent,
|
|
281
|
+
parentPlacement,
|
|
282
|
+
pcbBoard
|
|
283
|
+
});
|
|
284
|
+
return modelElement ? [modelElement] : [];
|
|
285
|
+
});
|
|
286
|
+
if (modelElements.length === 0) return void 0;
|
|
287
|
+
let cadModelTsx = modelElements[0];
|
|
288
|
+
if (modelElements.length > 1) {
|
|
289
|
+
cadModelTsx = `<cadassembly>${modelElements.join("\n")}</cadassembly>`;
|
|
290
|
+
}
|
|
291
|
+
if (!cadModelTsx) return void 0;
|
|
292
|
+
const attributes = [
|
|
293
|
+
`name={${JSON.stringify(`ImportedCadModel${groupIndex + 1}`)}}`,
|
|
294
|
+
`pcbX={${parentPlacement.center.x}}`,
|
|
295
|
+
`pcbY={${parentPlacement.center.y}}`,
|
|
296
|
+
`pcbRotation="${parentPlacement.ccwRotationDegrees}deg"`,
|
|
297
|
+
`layer="${parentPlacement.layer}"`,
|
|
298
|
+
"noSchematicRepresentation",
|
|
299
|
+
"obstructsWithinBounds={false}",
|
|
300
|
+
"footprint={<footprint />}",
|
|
301
|
+
`cadModel={${cadModelTsx}}`
|
|
302
|
+
];
|
|
303
|
+
return `<chip ${attributes.join(" ")} />`;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// lib/generate-board-cad-models-tsx/get-cad-model-groups.ts
|
|
307
|
+
function getCadModelGroups(circuitJson) {
|
|
308
|
+
const pcbComponentById = /* @__PURE__ */ new Map();
|
|
309
|
+
for (const element of circuitJson) {
|
|
310
|
+
if (element.type === "pcb_component") {
|
|
311
|
+
pcbComponentById.set(element.pcb_component_id, element);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
const cadModelGroupByKey = /* @__PURE__ */ new Map();
|
|
315
|
+
for (const element of circuitJson) {
|
|
316
|
+
if (element.type !== "cad_component" || !getCadModelUrl(element)) continue;
|
|
317
|
+
const pcbComponent = element.pcb_component_id ? pcbComponentById.get(element.pcb_component_id) : void 0;
|
|
318
|
+
const layer = (element.layer ?? pcbComponent?.layer) === "bottom" ? "bottom" : "top";
|
|
319
|
+
let parentPlacement = {
|
|
320
|
+
center: element.position,
|
|
321
|
+
ccwRotationDegrees: 0,
|
|
322
|
+
layer
|
|
323
|
+
};
|
|
324
|
+
let cadModelGroupKey = element.cad_component_id;
|
|
325
|
+
if (pcbComponent !== void 0) {
|
|
326
|
+
parentPlacement = {
|
|
327
|
+
center: pcbComponent.center,
|
|
328
|
+
ccwRotationDegrees: pcbComponent.rotation,
|
|
329
|
+
layer
|
|
330
|
+
};
|
|
331
|
+
cadModelGroupKey = `${pcbComponent.pcb_component_id}:${layer}`;
|
|
332
|
+
}
|
|
333
|
+
const cadModelGroup = cadModelGroupByKey.get(cadModelGroupKey) ?? {
|
|
334
|
+
cadComponents: [],
|
|
335
|
+
parentPlacement
|
|
336
|
+
};
|
|
337
|
+
cadModelGroup.cadComponents.push(element);
|
|
338
|
+
cadModelGroupByKey.set(cadModelGroupKey, cadModelGroup);
|
|
339
|
+
}
|
|
340
|
+
return [...cadModelGroupByKey.values()];
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// lib/generate-board-cad-models-tsx.ts
|
|
344
|
+
function generateBoardCadModelsTsx({
|
|
345
|
+
circuitJson,
|
|
346
|
+
pcbBoard
|
|
347
|
+
}) {
|
|
348
|
+
if (!pcbBoard) return [];
|
|
349
|
+
return getCadModelGroups(circuitJson).flatMap((cadModelGroup, groupIndex) => {
|
|
350
|
+
const cadModelGroupTsx = generateCadModelGroupTsx({
|
|
351
|
+
cadModelGroup,
|
|
352
|
+
groupIndex,
|
|
353
|
+
pcbBoard
|
|
354
|
+
});
|
|
355
|
+
return cadModelGroupTsx ? [cadModelGroupTsx] : [];
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
|
|
143
359
|
// lib/generate-board-nets-tsx.ts
|
|
144
360
|
var generateBoardNetsTsx = (context) => {
|
|
145
361
|
const runtimeNetNames = new Set(context.runtimeNetNameBySourceNetId.values());
|
|
@@ -150,6 +366,38 @@ var generateBoardNetsTsx = (context) => {
|
|
|
150
366
|
});
|
|
151
367
|
};
|
|
152
368
|
|
|
369
|
+
// lib/generate-board-schematic-sheet-tsx.ts
|
|
370
|
+
import { mmStr } from "@tscircuit/mm";
|
|
371
|
+
var DEFAULT_SHEET_DIMENSIONS_MM = {
|
|
372
|
+
a4: { width: 297, height: 210 },
|
|
373
|
+
ansi_b: { width: 431.8, height: 279.4 }
|
|
374
|
+
};
|
|
375
|
+
var generateBoardSchematicSheetTsx = ({
|
|
376
|
+
circuitJson,
|
|
377
|
+
schematicElements
|
|
378
|
+
}) => {
|
|
379
|
+
const sheet = circuitJson.find(
|
|
380
|
+
(element) => element.type === "schematic_sheet"
|
|
381
|
+
);
|
|
382
|
+
if (!sheet) return schematicElements.join("\n");
|
|
383
|
+
const attrs = [];
|
|
384
|
+
if (sheet.name) attrs.push(`name={${JSON.stringify(sheet.name)}}`);
|
|
385
|
+
if (sheet.sheet_index !== void 0) {
|
|
386
|
+
attrs.push(`sheetIndex={${sheet.sheet_index}}`);
|
|
387
|
+
}
|
|
388
|
+
if (sheet.sheet_size) {
|
|
389
|
+
attrs.push(`sheetSize="${sheet.sheet_size === "a4" ? "A4" : "ANSI_B"}"`);
|
|
390
|
+
}
|
|
391
|
+
const defaultDimensions = DEFAULT_SHEET_DIMENSIONS_MM[sheet.sheet_size ?? "a4"];
|
|
392
|
+
const sheetWidth = sheet.sheet_width ?? defaultDimensions.width;
|
|
393
|
+
const sheetHeight = sheet.sheet_height ?? defaultDimensions.height;
|
|
394
|
+
attrs.push(`sheetWidth="${mmStr(sheetWidth)}"`);
|
|
395
|
+
attrs.push(`sheetHeight="${mmStr(sheetHeight)}"`);
|
|
396
|
+
return `<schematicsheet ${attrs.join(" ")}>
|
|
397
|
+
${schematicElements.join("\n")}
|
|
398
|
+
</schematicsheet>`;
|
|
399
|
+
};
|
|
400
|
+
|
|
153
401
|
// lib/generate-board-schematic-tsx/convert-primitives.ts
|
|
154
402
|
import { schematic_text } from "circuit-json";
|
|
155
403
|
|
|
@@ -1253,35 +1501,6 @@ var generateBoardSchematicElements = (circuitJson) => {
|
|
|
1253
1501
|
];
|
|
1254
1502
|
};
|
|
1255
1503
|
|
|
1256
|
-
// lib/generate-board-schematic-sheet-tsx.ts
|
|
1257
|
-
import { mmStr } from "@tscircuit/mm";
|
|
1258
|
-
var generateBoardSchematicSheetTsx = ({
|
|
1259
|
-
circuitJson,
|
|
1260
|
-
schematicElements
|
|
1261
|
-
}) => {
|
|
1262
|
-
const sheet = circuitJson.find(
|
|
1263
|
-
(element) => element.type === "schematic_sheet"
|
|
1264
|
-
);
|
|
1265
|
-
if (!sheet) return schematicElements.join("\n");
|
|
1266
|
-
const attrs = [];
|
|
1267
|
-
if (sheet.name) attrs.push(`name={${JSON.stringify(sheet.name)}}`);
|
|
1268
|
-
if (sheet.sheet_index !== void 0) {
|
|
1269
|
-
attrs.push(`sheetIndex={${sheet.sheet_index}}`);
|
|
1270
|
-
}
|
|
1271
|
-
if (sheet.sheet_size) {
|
|
1272
|
-
attrs.push(`sheetSize="${sheet.sheet_size === "a4" ? "A4" : "ANSI_B"}"`);
|
|
1273
|
-
}
|
|
1274
|
-
if (sheet.sheet_width !== void 0) {
|
|
1275
|
-
attrs.push(`sheetWidth="${mmStr(sheet.sheet_width)}"`);
|
|
1276
|
-
}
|
|
1277
|
-
if (sheet.sheet_height !== void 0) {
|
|
1278
|
-
attrs.push(`sheetHeight="${mmStr(sheet.sheet_height)}"`);
|
|
1279
|
-
}
|
|
1280
|
-
return `<schematicsheet ${attrs.join(" ")}>
|
|
1281
|
-
${schematicElements.join("\n")}
|
|
1282
|
-
</schematicsheet>`;
|
|
1283
|
-
};
|
|
1284
|
-
|
|
1285
1504
|
// lib/generate-copper-pours-tsx.ts
|
|
1286
1505
|
import { su as su6 } from "@tscircuit/soup-util";
|
|
1287
1506
|
|
|
@@ -1924,6 +2143,9 @@ var convertNotes = (circuitJson) => {
|
|
|
1924
2143
|
if (noteRect.color !== void 0) {
|
|
1925
2144
|
attrs.push(`color="${noteRect.color}"`);
|
|
1926
2145
|
}
|
|
2146
|
+
if (noteRect.corner_radius !== void 0) {
|
|
2147
|
+
attrs.push(`cornerRadius={${noteRect.corner_radius}}`);
|
|
2148
|
+
}
|
|
1927
2149
|
elementStrings.push(`<pcbnoterect ${attrs.join(" ")} />`);
|
|
1928
2150
|
}
|
|
1929
2151
|
for (const notePath of notePaths) {
|
|
@@ -2393,6 +2615,10 @@ var getBoardUsingTemplate = ({
|
|
|
2393
2615
|
const footprintTsx = generateFootprintTsx(circuitJson, context);
|
|
2394
2616
|
const copperPoursTsx = generateCopperPoursTsx(circuitJson, context);
|
|
2395
2617
|
const boardNetsTsx = generateBoardNetsTsx(context);
|
|
2618
|
+
const boardCadModelsTsx = generateBoardCadModelsTsx({
|
|
2619
|
+
circuitJson,
|
|
2620
|
+
pcbBoard
|
|
2621
|
+
});
|
|
2396
2622
|
const schematicElements = generateBoardSchematicElements(circuitJson);
|
|
2397
2623
|
const schematicSheetTsx = generateBoardSchematicSheetTsx({
|
|
2398
2624
|
circuitJson,
|
|
@@ -2402,6 +2628,7 @@ var getBoardUsingTemplate = ({
|
|
|
2402
2628
|
...boardNetsTsx,
|
|
2403
2629
|
footprintTsx ? `<chip name="${context.pcbChipName}" noSchematicRepresentation footprint={${footprintTsx}} />` : "",
|
|
2404
2630
|
...copperPoursTsx,
|
|
2631
|
+
...boardCadModelsTsx,
|
|
2405
2632
|
schematicSheetTsx
|
|
2406
2633
|
].filter(Boolean).join("\n");
|
|
2407
2634
|
return `
|
package/dist/cli/main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
convertCircuitJsonToTscircuit
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-GVGY3ZZN.js";
|
|
5
5
|
|
|
6
6
|
// cli/main.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -16,7 +16,7 @@ var package_default = {
|
|
|
16
16
|
"./cli": "./dist/cli/main.js"
|
|
17
17
|
},
|
|
18
18
|
type: "module",
|
|
19
|
-
version: "0.0.
|
|
19
|
+
version: "0.0.88",
|
|
20
20
|
repository: {
|
|
21
21
|
type: "git",
|
|
22
22
|
url: "https://github.com/tscircuit/circuit-json-to-tscircuit.git"
|
|
@@ -38,9 +38,12 @@ var package_default = {
|
|
|
38
38
|
"@types/react-dom": "18",
|
|
39
39
|
"bun-match-svg": "^0.0.15",
|
|
40
40
|
"circuit-json": "^0.0.521",
|
|
41
|
+
"circuit-json-to-gltf": "0.0.151",
|
|
41
42
|
"circuit-to-svg": "https://pkg.pr.new/tscircuit/circuit-to-svg@738ef1d",
|
|
42
43
|
commander: "^13.1.0",
|
|
44
|
+
"fast-png": "8.0.0",
|
|
43
45
|
prettier: "^3.9.5",
|
|
46
|
+
poppygl: "0.0.34",
|
|
44
47
|
"schematic-symbols": "0.0.248",
|
|
45
48
|
shiki: "^4.3.1",
|
|
46
49
|
"stack-svgs": "^0.0.1",
|
package/dist/lib/index.js
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CadComponent, PcbComponent } from "circuit-json"
|
|
2
|
+
|
|
3
|
+
export interface CadModelUrl {
|
|
4
|
+
format: "glb" | "gltf" | "obj" | "step" | "stl" | "wrl"
|
|
5
|
+
url: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface CadModelParentPlacement {
|
|
9
|
+
center: { x: number; y: number }
|
|
10
|
+
ccwRotationDegrees: number
|
|
11
|
+
layer: "bottom" | "top"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface CadModelGroup {
|
|
15
|
+
cadComponents: CadComponent[]
|
|
16
|
+
parentPlacement: CadModelParentPlacement
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface CadModelPlacement {
|
|
20
|
+
positionOffset: { x: number; y: number; z: number }
|
|
21
|
+
ccwRotationOffsetDegrees: { x: number; y: number; z: number }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type CadModelGroupKey = string
|
|
25
|
+
export type PcbComponentId = PcbComponent["pcb_component_id"]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { PcbBoard } from "circuit-json"
|
|
2
|
+
import type { CadModelGroup } from "./converter-types"
|
|
3
|
+
import { generateCadModelTsx } from "./generate-cad-model-tsx"
|
|
4
|
+
|
|
5
|
+
export function generateCadModelGroupTsx({
|
|
6
|
+
cadModelGroup,
|
|
7
|
+
groupIndex,
|
|
8
|
+
pcbBoard,
|
|
9
|
+
}: {
|
|
10
|
+
cadModelGroup: CadModelGroup
|
|
11
|
+
groupIndex: number
|
|
12
|
+
pcbBoard: PcbBoard
|
|
13
|
+
}): string | undefined {
|
|
14
|
+
const { cadComponents, parentPlacement } = cadModelGroup
|
|
15
|
+
const modelElements = cadComponents.flatMap((cadComponent) => {
|
|
16
|
+
const modelElement = generateCadModelTsx({
|
|
17
|
+
cadComponent,
|
|
18
|
+
parentPlacement,
|
|
19
|
+
pcbBoard,
|
|
20
|
+
})
|
|
21
|
+
return modelElement ? [modelElement] : []
|
|
22
|
+
})
|
|
23
|
+
if (modelElements.length === 0) return undefined
|
|
24
|
+
|
|
25
|
+
let cadModelTsx = modelElements[0]
|
|
26
|
+
if (modelElements.length > 1) {
|
|
27
|
+
cadModelTsx = `<cadassembly>${modelElements.join("\n")}</cadassembly>`
|
|
28
|
+
}
|
|
29
|
+
if (!cadModelTsx) return undefined
|
|
30
|
+
|
|
31
|
+
const attributes = [
|
|
32
|
+
`name={${JSON.stringify(`ImportedCadModel${groupIndex + 1}`)}}`,
|
|
33
|
+
`pcbX={${parentPlacement.center.x}}`,
|
|
34
|
+
`pcbY={${parentPlacement.center.y}}`,
|
|
35
|
+
`pcbRotation="${parentPlacement.ccwRotationDegrees}deg"`,
|
|
36
|
+
`layer="${parentPlacement.layer}"`,
|
|
37
|
+
"noSchematicRepresentation",
|
|
38
|
+
"obstructsWithinBounds={false}",
|
|
39
|
+
"footprint={<footprint />}",
|
|
40
|
+
`cadModel={${cadModelTsx}}`,
|
|
41
|
+
]
|
|
42
|
+
return `<chip ${attributes.join(" ")} />`
|
|
43
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { CadComponent, PcbBoard } from "circuit-json"
|
|
2
|
+
import type { CadModelParentPlacement } from "./converter-types"
|
|
3
|
+
import { formatPointProp } from "./format-point-prop"
|
|
4
|
+
import { getCadModelOriginPosition } from "./get-cad-model-origin-position"
|
|
5
|
+
import { getCadModelPlacement } from "./get-cad-model-placement"
|
|
6
|
+
import { getCadModelUrl } from "./get-cad-model-url"
|
|
7
|
+
import { getModelUrlWithFormatHint } from "./get-model-url-with-format-hint"
|
|
8
|
+
|
|
9
|
+
export function generateCadModelTsx({
|
|
10
|
+
cadComponent,
|
|
11
|
+
parentPlacement,
|
|
12
|
+
pcbBoard,
|
|
13
|
+
}: {
|
|
14
|
+
cadComponent: CadComponent
|
|
15
|
+
parentPlacement: CadModelParentPlacement
|
|
16
|
+
pcbBoard: PcbBoard
|
|
17
|
+
}): string | undefined {
|
|
18
|
+
const modelUrl = getCadModelUrl(cadComponent)
|
|
19
|
+
if (!modelUrl) return undefined
|
|
20
|
+
|
|
21
|
+
const placement = getCadModelPlacement({
|
|
22
|
+
cadComponent,
|
|
23
|
+
parentPlacement,
|
|
24
|
+
pcbBoard,
|
|
25
|
+
})
|
|
26
|
+
const attributes = [
|
|
27
|
+
`modelUrl={${JSON.stringify(getModelUrlWithFormatHint(modelUrl))}}`,
|
|
28
|
+
`positionOffset={${formatPointProp(placement.positionOffset)}}`,
|
|
29
|
+
`rotationOffset={${formatPointProp(placement.ccwRotationOffsetDegrees)}}`,
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
if (cadComponent.model_unit_to_mm_scale_factor !== undefined) {
|
|
33
|
+
attributes.push(
|
|
34
|
+
`modelUnitToMmScale={${cadComponent.model_unit_to_mm_scale_factor}}`,
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
if (cadComponent.model_board_normal_direction !== undefined) {
|
|
38
|
+
attributes.push(
|
|
39
|
+
`modelBoardNormalDirection={${JSON.stringify(cadComponent.model_board_normal_direction)}}`,
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
const modelOriginPosition = getCadModelOriginPosition(cadComponent)
|
|
43
|
+
if (modelOriginPosition !== undefined) {
|
|
44
|
+
attributes.push(
|
|
45
|
+
`modelOriginPosition={${formatPointProp(modelOriginPosition)}}`,
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
if (cadComponent.size !== undefined) {
|
|
49
|
+
attributes.push(`size={${formatPointProp(cadComponent.size)}}`)
|
|
50
|
+
}
|
|
51
|
+
if (cadComponent.show_as_translucent_model === true) {
|
|
52
|
+
attributes.push("showAsTranslucentModel")
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return `<cadmodel ${attributes.join(" ")} />`
|
|
56
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { AnyCircuitElement, PcbComponent } from "circuit-json"
|
|
2
|
+
import type {
|
|
3
|
+
CadModelGroup,
|
|
4
|
+
CadModelGroupKey,
|
|
5
|
+
CadModelParentPlacement,
|
|
6
|
+
PcbComponentId,
|
|
7
|
+
} from "./converter-types"
|
|
8
|
+
import { getCadModelUrl } from "./get-cad-model-url"
|
|
9
|
+
|
|
10
|
+
export function getCadModelGroups(
|
|
11
|
+
circuitJson: AnyCircuitElement[],
|
|
12
|
+
): CadModelGroup[] {
|
|
13
|
+
const pcbComponentById = new Map<PcbComponentId, PcbComponent>()
|
|
14
|
+
for (const element of circuitJson) {
|
|
15
|
+
if (element.type === "pcb_component") {
|
|
16
|
+
pcbComponentById.set(element.pcb_component_id, element)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const cadModelGroupByKey = new Map<CadModelGroupKey, CadModelGroup>()
|
|
21
|
+
for (const element of circuitJson) {
|
|
22
|
+
if (element.type !== "cad_component" || !getCadModelUrl(element)) continue
|
|
23
|
+
|
|
24
|
+
const pcbComponent = element.pcb_component_id
|
|
25
|
+
? pcbComponentById.get(element.pcb_component_id)
|
|
26
|
+
: undefined
|
|
27
|
+
const layer =
|
|
28
|
+
(element.layer ?? pcbComponent?.layer) === "bottom" ? "bottom" : "top"
|
|
29
|
+
let parentPlacement: CadModelParentPlacement = {
|
|
30
|
+
center: element.position,
|
|
31
|
+
ccwRotationDegrees: 0,
|
|
32
|
+
layer,
|
|
33
|
+
}
|
|
34
|
+
let cadModelGroupKey: CadModelGroupKey = element.cad_component_id
|
|
35
|
+
|
|
36
|
+
if (pcbComponent !== undefined) {
|
|
37
|
+
parentPlacement = {
|
|
38
|
+
center: pcbComponent.center,
|
|
39
|
+
ccwRotationDegrees: pcbComponent.rotation,
|
|
40
|
+
layer,
|
|
41
|
+
}
|
|
42
|
+
cadModelGroupKey = `${pcbComponent.pcb_component_id}:${layer}`
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const cadModelGroup = cadModelGroupByKey.get(cadModelGroupKey) ?? {
|
|
46
|
+
cadComponents: [],
|
|
47
|
+
parentPlacement,
|
|
48
|
+
}
|
|
49
|
+
cadModelGroup.cadComponents.push(element)
|
|
50
|
+
cadModelGroupByKey.set(cadModelGroupKey, cadModelGroup)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return [...cadModelGroupByKey.values()]
|
|
54
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CadComponent } from "circuit-json"
|
|
2
|
+
|
|
3
|
+
export function getCadModelOriginPosition(
|
|
4
|
+
cadComponent: CadComponent,
|
|
5
|
+
): { x: number; y: number; z: number } | undefined {
|
|
6
|
+
if (cadComponent.model_origin_position !== undefined) {
|
|
7
|
+
return cadComponent.model_origin_position
|
|
8
|
+
}
|
|
9
|
+
if (cadComponent.model_origin_alignment === "unknown") {
|
|
10
|
+
return { x: 0, y: 0, z: 0 }
|
|
11
|
+
}
|
|
12
|
+
return undefined
|
|
13
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { CadComponent, PcbBoard } from "circuit-json"
|
|
2
|
+
import type {
|
|
3
|
+
CadModelParentPlacement,
|
|
4
|
+
CadModelPlacement,
|
|
5
|
+
} from "./converter-types"
|
|
6
|
+
|
|
7
|
+
export function getCadModelPlacement({
|
|
8
|
+
cadComponent,
|
|
9
|
+
parentPlacement,
|
|
10
|
+
pcbBoard,
|
|
11
|
+
}: {
|
|
12
|
+
cadComponent: CadComponent
|
|
13
|
+
parentPlacement: CadModelParentPlacement
|
|
14
|
+
pcbBoard: PcbBoard
|
|
15
|
+
}): CadModelPlacement {
|
|
16
|
+
const cadModelCcwRotationDegrees = cadComponent.rotation ?? {
|
|
17
|
+
x: 0,
|
|
18
|
+
y: 0,
|
|
19
|
+
z: 0,
|
|
20
|
+
}
|
|
21
|
+
const boardSurfaceZ = pcbBoard.thickness / 2
|
|
22
|
+
let positionOffsetZ = cadComponent.position.z - boardSurfaceZ
|
|
23
|
+
let ccwRotationOffsetDegrees = {
|
|
24
|
+
x: cadModelCcwRotationDegrees.x,
|
|
25
|
+
y: cadModelCcwRotationDegrees.y,
|
|
26
|
+
z: cadModelCcwRotationDegrees.z - parentPlacement.ccwRotationDegrees,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (parentPlacement.layer === "bottom") {
|
|
30
|
+
positionOffsetZ = cadComponent.position.z + boardSurfaceZ
|
|
31
|
+
ccwRotationOffsetDegrees = {
|
|
32
|
+
x: cadModelCcwRotationDegrees.x,
|
|
33
|
+
y: cadModelCcwRotationDegrees.y - 180,
|
|
34
|
+
z: cadModelCcwRotationDegrees.z + parentPlacement.ccwRotationDegrees,
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
positionOffset: {
|
|
40
|
+
x: cadComponent.position.x - parentPlacement.center.x,
|
|
41
|
+
y: cadComponent.position.y - parentPlacement.center.y,
|
|
42
|
+
z: positionOffsetZ,
|
|
43
|
+
},
|
|
44
|
+
ccwRotationOffsetDegrees,
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CadComponent } from "circuit-json"
|
|
2
|
+
import type { CadModelUrl } from "./converter-types"
|
|
3
|
+
|
|
4
|
+
export function getCadModelUrl(
|
|
5
|
+
cadComponent: CadComponent,
|
|
6
|
+
): CadModelUrl | undefined {
|
|
7
|
+
if (cadComponent.model_glb_url) {
|
|
8
|
+
return { format: "glb", url: cadComponent.model_glb_url }
|
|
9
|
+
}
|
|
10
|
+
if (cadComponent.model_gltf_url) {
|
|
11
|
+
return { format: "gltf", url: cadComponent.model_gltf_url }
|
|
12
|
+
}
|
|
13
|
+
if (cadComponent.model_obj_url) {
|
|
14
|
+
return { format: "obj", url: cadComponent.model_obj_url }
|
|
15
|
+
}
|
|
16
|
+
if (cadComponent.model_step_url) {
|
|
17
|
+
return { format: "step", url: cadComponent.model_step_url }
|
|
18
|
+
}
|
|
19
|
+
if (cadComponent.model_stl_url) {
|
|
20
|
+
return { format: "stl", url: cadComponent.model_stl_url }
|
|
21
|
+
}
|
|
22
|
+
if (cadComponent.model_wrl_url) {
|
|
23
|
+
return { format: "wrl", url: cadComponent.model_wrl_url }
|
|
24
|
+
}
|
|
25
|
+
return undefined
|
|
26
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CadModelUrl } from "./converter-types"
|
|
2
|
+
|
|
3
|
+
export function getModelUrlWithFormatHint({
|
|
4
|
+
format,
|
|
5
|
+
url,
|
|
6
|
+
}: CadModelUrl): string {
|
|
7
|
+
const pathWithoutQuery = url.split(/[?#]/u)[0] ?? ""
|
|
8
|
+
if (pathWithoutQuery.toLowerCase().endsWith(`.${format}`)) return url
|
|
9
|
+
return `${url}#ext=${format}`
|
|
10
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AnyCircuitElement, PcbBoard } from "circuit-json"
|
|
2
|
+
import { generateCadModelGroupTsx } from "./generate-board-cad-models-tsx/generate-cad-model-group-tsx"
|
|
3
|
+
import { getCadModelGroups } from "./generate-board-cad-models-tsx/get-cad-model-groups"
|
|
4
|
+
|
|
5
|
+
export function generateBoardCadModelsTsx({
|
|
6
|
+
circuitJson,
|
|
7
|
+
pcbBoard,
|
|
8
|
+
}: {
|
|
9
|
+
circuitJson: AnyCircuitElement[]
|
|
10
|
+
pcbBoard: PcbBoard | undefined
|
|
11
|
+
}): string[] {
|
|
12
|
+
if (!pcbBoard) return []
|
|
13
|
+
|
|
14
|
+
return getCadModelGroups(circuitJson).flatMap((cadModelGroup, groupIndex) => {
|
|
15
|
+
const cadModelGroupTsx = generateCadModelGroupTsx({
|
|
16
|
+
cadModelGroup,
|
|
17
|
+
groupIndex,
|
|
18
|
+
pcbBoard,
|
|
19
|
+
})
|
|
20
|
+
return cadModelGroupTsx ? [cadModelGroupTsx] : []
|
|
21
|
+
})
|
|
22
|
+
}
|
|
@@ -42,6 +42,9 @@ export const convertNotes: FootprintElementConverter = (circuitJson) => {
|
|
|
42
42
|
if (noteRect.color !== undefined) {
|
|
43
43
|
attrs.push(`color="${noteRect.color}"`)
|
|
44
44
|
}
|
|
45
|
+
if (noteRect.corner_radius !== undefined) {
|
|
46
|
+
attrs.push(`cornerRadius={${noteRect.corner_radius}}`)
|
|
47
|
+
}
|
|
45
48
|
|
|
46
49
|
elementStrings.push(`<pcbnoterect ${attrs.join(" ")} />`)
|
|
47
50
|
}
|