@tscircuit/3d-viewer 0.0.445 → 0.0.447

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.
Files changed (2) hide show
  1. package/dist/index.js +220 -54
  2. package/package.json +9 -7
package/dist/index.js CHANGED
@@ -15474,7 +15474,8 @@ var source_port = z37.object({
15474
15474
  source_component_id: z37.string().optional(),
15475
15475
  source_group_id: z37.string().optional(),
15476
15476
  subcircuit_id: z37.string().optional(),
15477
- subcircuit_connectivity_map_key: z37.string().optional()
15477
+ subcircuit_connectivity_map_key: z37.string().optional(),
15478
+ must_be_connected: z37.boolean().optional()
15478
15479
  });
15479
15480
  expectTypesMatch(true);
15480
15481
  var source_trace = z38.object({
@@ -16115,8 +16116,7 @@ var pcb_plated_hole_circle = z73.object({
16115
16116
  pcb_component_id: z73.string().optional(),
16116
16117
  pcb_port_id: z73.string().optional(),
16117
16118
  pcb_plated_hole_id: getZodPrefixedIdWithDefault("pcb_plated_hole"),
16118
- soldermask_margin: z73.number().optional(),
16119
- is_covered_with_solder_mask: z73.boolean().optional()
16119
+ soldermask_margin: z73.number().optional()
16120
16120
  });
16121
16121
  var pcb_plated_hole_oval = z73.object({
16122
16122
  type: z73.literal("pcb_plated_hole"),
@@ -16601,7 +16601,8 @@ var pcb_via = z84.object({
16601
16601
  layers: z84.array(layer_ref),
16602
16602
  pcb_trace_id: z84.string().optional(),
16603
16603
  net_is_assignable: z84.boolean().optional(),
16604
- net_assigned: z84.boolean().optional()
16604
+ net_assigned: z84.boolean().optional(),
16605
+ is_tented: z84.boolean().optional()
16605
16606
  }).describe("Defines a via on the PCB");
16606
16607
  expectTypesMatch(true);
16607
16608
  var pcb_board = z85.object({
@@ -17304,7 +17305,8 @@ var cad_component = z125.object({
17304
17305
  model_step_url: z125.string().optional(),
17305
17306
  model_wrl_url: z125.string().optional(),
17306
17307
  model_unit_to_mm_scale_factor: z125.number().optional(),
17307
- model_jscad: z125.any().optional()
17308
+ model_jscad: z125.any().optional(),
17309
+ show_as_translucent_model: z125.boolean().optional()
17308
17310
  }).describe("Defines a component on the PCB");
17309
17311
  expectTypesMatch(true);
17310
17312
  var wave_shape = z126.enum(["sinewave", "square", "triangle", "sawtooth"]);
@@ -17404,18 +17406,48 @@ var simulation_voltage_probe = z130.object({
17404
17406
  ),
17405
17407
  source_component_id: z130.string().optional(),
17406
17408
  name: z130.string().optional(),
17407
- source_port_id: z130.string().optional(),
17408
- source_net_id: z130.string().optional(),
17409
+ signal_input_source_port_id: z130.string().optional(),
17410
+ signal_input_source_net_id: z130.string().optional(),
17411
+ reference_input_source_port_id: z130.string().optional(),
17412
+ reference_input_source_net_id: z130.string().optional(),
17409
17413
  subcircuit_id: z130.string().optional(),
17410
17414
  color: z130.string().optional()
17411
17415
  }).describe(
17412
- "Defines a voltage probe for simulation, connected to a port or a net"
17413
- ).refine(
17414
- (data) => Boolean(data.source_port_id) !== Boolean(data.source_net_id),
17415
- {
17416
- message: "Exactly one of source_port_id or source_net_id must be provided to simulation_voltage_probe"
17416
+ "Defines a voltage probe for simulation. If a reference input is not provided, it measures against ground. If a reference input is provided, it measures the differential voltage between two points."
17417
+ ).superRefine((data, ctx) => {
17418
+ const is_differential = data.reference_input_source_port_id || data.reference_input_source_net_id;
17419
+ if (is_differential) {
17420
+ const has_ports = !!data.signal_input_source_port_id || !!data.reference_input_source_port_id;
17421
+ const has_nets = !!data.signal_input_source_net_id || !!data.reference_input_source_net_id;
17422
+ if (has_ports && has_nets) {
17423
+ ctx.addIssue({
17424
+ code: z130.ZodIssueCode.custom,
17425
+ message: "Cannot mix port and net connections in a differential probe."
17426
+ });
17427
+ } else if (has_ports) {
17428
+ if (!data.signal_input_source_port_id || !data.reference_input_source_port_id) {
17429
+ ctx.addIssue({
17430
+ code: z130.ZodIssueCode.custom,
17431
+ message: "Differential port probe requires both signal_input_source_port_id and reference_input_source_port_id."
17432
+ });
17433
+ }
17434
+ } else if (has_nets) {
17435
+ if (!data.signal_input_source_net_id || !data.reference_input_source_net_id) {
17436
+ ctx.addIssue({
17437
+ code: z130.ZodIssueCode.custom,
17438
+ message: "Differential net probe requires both signal_input_source_net_id and reference_input_source_net_id."
17439
+ });
17440
+ }
17441
+ }
17442
+ } else {
17443
+ if (!!data.signal_input_source_port_id === !!data.signal_input_source_net_id) {
17444
+ ctx.addIssue({
17445
+ code: z130.ZodIssueCode.custom,
17446
+ message: "A voltage probe must have exactly one of signal_input_source_port_id or signal_input_source_net_id."
17447
+ });
17448
+ }
17417
17449
  }
17418
- );
17450
+ });
17419
17451
  expectTypesMatch(true);
17420
17452
  var simulation_unknown_experiment_error = z131.object({
17421
17453
  type: z131.literal("simulation_unknown_experiment_error"),
@@ -27101,38 +27133,65 @@ var LQFP = ({
27101
27133
  )
27102
27134
  ] });
27103
27135
  };
27104
- var getCcwSot723Coords2 = (pn) => {
27105
- if (pn === 1) {
27106
- return { x: 0, y: 0 };
27107
- } else if (pn === 2) {
27108
- return { x: 1, y: -0.4 };
27109
- } else {
27110
- return { x: 1, y: 0.4 };
27111
- }
27112
- };
27113
27136
  var SOT723 = () => {
27114
- const bodyWidth = 0.8;
27137
+ const bodyWidth = 0.85;
27115
27138
  const bodyLength10 = 1.2;
27116
- const bodyHeight = 0.5;
27117
- const leadWidth = 0.32;
27118
- const leadLength = 0.3;
27119
- const leadHeight = 0.1;
27120
- const centerLeadWidth = 0.42;
27139
+ const bodyHeight = 0.38;
27140
+ const straightHeight = bodyHeight * 0.55;
27141
+ const taperOffset = 0.1;
27142
+ const padLength = 0.3;
27143
+ const padThickness = 0.1;
27144
+ const leftPadWidth = 0.2;
27145
+ const rightPadWidth = 0.25;
27146
+ const rightPadCenterX = 0.55;
27147
+ const rightPadCenterY = 0;
27148
+ const leftTopPadCenterX = -0.55;
27149
+ const leftTopPadCenterY = 0.4;
27150
+ const leftBottomPadCenterX = -0.55;
27151
+ const leftBottomPadCenterY = -0.4;
27121
27152
  return /* @__PURE__ */ jsxs(Fragment22, { children: [
27122
- /* @__PURE__ */ jsx5(Rotate, { rotation: [45 * Math.PI, 0, 0], children: /* @__PURE__ */ jsx5(Translate, { center: [0.475, leadHeight / 2, -0.25], children: /* @__PURE__ */ jsx5(Colorize, { color: "grey", children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyWidth, bodyLength10, bodyHeight] }) }) }) }),
27123
- [1, 2, 3].map((pn) => {
27124
- const { x, y } = getCcwSot723Coords2(pn);
27125
- return /* @__PURE__ */ jsx5(Translate, { center: [x, y, 0.05], children: /* @__PURE__ */ jsx5(
27153
+ /* @__PURE__ */ jsx5(Colorize, { color: "#222", children: /* @__PURE__ */ jsxs(Union, { children: [
27154
+ /* @__PURE__ */ jsx5(
27126
27155
  Cuboid,
27127
27156
  {
27128
- size: [
27129
- leadLength,
27130
- pn === 1 ? centerLeadWidth : leadWidth,
27131
- leadHeight
27132
- ]
27157
+ size: [bodyWidth, bodyLength10, straightHeight],
27158
+ center: [0, 0, straightHeight / 2]
27133
27159
  }
27134
- ) }, `lead-${pn}`);
27135
- })
27160
+ ),
27161
+ /* @__PURE__ */ jsxs(Hull, { children: [
27162
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyWidth, bodyLength10, 0.01] }) }),
27163
+ /* @__PURE__ */ jsx5(Translate, { z: bodyHeight, children: /* @__PURE__ */ jsx5(
27164
+ Cuboid,
27165
+ {
27166
+ size: [bodyWidth - taperOffset, bodyLength10 - taperOffset, 0.01]
27167
+ }
27168
+ ) })
27169
+ ] })
27170
+ ] }) }),
27171
+ /* @__PURE__ */ jsx5(
27172
+ Cuboid,
27173
+ {
27174
+ color: "#ccc",
27175
+ size: [padLength, rightPadWidth, padThickness],
27176
+ center: [rightPadCenterX, rightPadCenterY, padThickness / 2]
27177
+ }
27178
+ ),
27179
+ /* @__PURE__ */ jsx5(
27180
+ Cuboid,
27181
+ {
27182
+ color: "#ccc",
27183
+ size: [padLength, leftPadWidth, padThickness],
27184
+ center: [leftTopPadCenterX, leftTopPadCenterY, padThickness / 2]
27185
+ }
27186
+ ),
27187
+ /* @__PURE__ */ jsx5(
27188
+ Cuboid,
27189
+ {
27190
+ color: "#ccc",
27191
+ size: [padLength, leftPadWidth, padThickness],
27192
+ center: [leftBottomPadCenterX, leftBottomPadCenterY, padThickness / 2]
27193
+ }
27194
+ )
27136
27195
  ] });
27137
27196
  };
27138
27197
  var DFN = ({
@@ -27470,6 +27529,79 @@ var MS012 = ({
27470
27529
  )
27471
27530
  ] });
27472
27531
  };
27532
+ var TO220 = () => {
27533
+ const fullLength10 = 20;
27534
+ const bodyLength10 = 9.9;
27535
+ const bodyHeight = 4.5;
27536
+ const zOffset = 1;
27537
+ const padWidth = 9.9;
27538
+ const padLength = 6.5;
27539
+ const padThickness = 1.3;
27540
+ const padHoleDiameter = 3;
27541
+ const prongWidth = 0.81;
27542
+ const prongLength = 16;
27543
+ const prongHeight = 0.5;
27544
+ const prongPitch = 2.7;
27545
+ const bodyWidth = padWidth;
27546
+ const bodyFrontX = fullLength10 - bodyLength10 / 2;
27547
+ const bodyBackX = fullLength10 + bodyLength10 / 2;
27548
+ const prongCenterX = bodyFrontX - prongLength / 2;
27549
+ const padCenterX = bodyBackX + padLength / 2;
27550
+ return /* @__PURE__ */ jsx5(Translate, { center: [0, 0, zOffset], children: /* @__PURE__ */ jsxs(Fragment22, { children: [
27551
+ /* @__PURE__ */ jsxs(Rotate, { rotation: [0, 55, -55], children: [
27552
+ /* @__PURE__ */ jsxs(Subtract, { children: [
27553
+ /* @__PURE__ */ jsx5(
27554
+ Cuboid,
27555
+ {
27556
+ color: "#ccc",
27557
+ size: [padLength + 0.1, padWidth, padThickness],
27558
+ center: [padCenterX, 0, padThickness - 2]
27559
+ }
27560
+ ),
27561
+ /* @__PURE__ */ jsx5(
27562
+ Cylinder,
27563
+ {
27564
+ color: "black",
27565
+ center: [padCenterX, 0, padThickness - 2],
27566
+ radius: padHoleDiameter / 2,
27567
+ height: padThickness * 1.2
27568
+ }
27569
+ )
27570
+ ] }),
27571
+ /* @__PURE__ */ jsx5(Colorize, { color: "#222", children: /* @__PURE__ */ jsx5(
27572
+ ChipBody,
27573
+ {
27574
+ width: bodyWidth,
27575
+ length: bodyLength10,
27576
+ height: bodyHeight,
27577
+ center: { x: fullLength10, y: 0, z: -2.4 },
27578
+ includeNotch: false,
27579
+ straightHeightRatio: 0.3,
27580
+ taperRatio: 0.04,
27581
+ heightAboveSurface: 1
27582
+ }
27583
+ ) })
27584
+ ] }),
27585
+ /* @__PURE__ */ jsx5(Rotate, { rotation: [0, 55, 55], children: Array.from({ length: 3 }).map((_, i) => {
27586
+ const x = prongCenterX;
27587
+ const y = (i - 1) * prongPitch;
27588
+ const z135 = -prongHeight - 0.6;
27589
+ return /* @__PURE__ */ jsxs(Colorize, { color: "gold", children: [
27590
+ /* @__PURE__ */ jsxs(Hull, { children: [
27591
+ /* @__PURE__ */ jsx5(Translate, { center: [bodyFrontX - bodyHeight / 2 + 0.1, y, z135], children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyHeight, prongWidth + 1, prongHeight] }) }),
27592
+ /* @__PURE__ */ jsx5(
27593
+ Translate,
27594
+ {
27595
+ center: [bodyFrontX - bodyHeight / 2 - 1 + 0.1, y, z135],
27596
+ children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyHeight, prongWidth, prongHeight] })
27597
+ }
27598
+ )
27599
+ ] }),
27600
+ /* @__PURE__ */ jsx5(Translate, { center: [x, y, z135], children: /* @__PURE__ */ jsx5(Cuboid, { size: [prongLength + 0.1, prongWidth, prongHeight] }) })
27601
+ ] }, `prong-${i}`);
27602
+ }) })
27603
+ ] }) });
27604
+ };
27473
27605
  var Footprinter3d = ({ footprint }) => {
27474
27606
  const fpJson = fp.string(footprint).json();
27475
27607
  switch (fpJson.fn) {
@@ -27651,6 +27783,8 @@ var Footprinter3d = ({ footprint }) => {
27651
27783
  );
27652
27784
  case "sot723":
27653
27785
  return /* @__PURE__ */ jsx5(SOT723, {});
27786
+ case "to220":
27787
+ return /* @__PURE__ */ jsx5(TO220, {});
27654
27788
  }
27655
27789
  const colorMatch = footprint.match(/_color\(([^)]+)\)/);
27656
27790
  const color = colorMatch ? colorMatch[1] : void 0;
@@ -27714,7 +27848,7 @@ function renderNode(node, colorCtx, renderCtx) {
27714
27848
  }
27715
27849
  if (type === Translate) {
27716
27850
  const off = toVec3(
27717
- props?.offset ?? { x: props?.x, y: props?.y, z: props?.z }
27851
+ props?.offset ?? props?.center ?? { x: props?.x, y: props?.y, z: props?.z }
27718
27852
  );
27719
27853
  const geoms = (children ?? []).flatMap(
27720
27854
  (c) => renderNode(c, colorCtx, renderCtx)
@@ -28136,7 +28270,7 @@ var defaultVisibility = {
28136
28270
  bottomMask: true,
28137
28271
  throughHoleModels: true,
28138
28272
  smtModels: true,
28139
- virtualModels: false,
28273
+ translucentModels: true,
28140
28274
  modelsNotInPosFile: false,
28141
28275
  modelsMarkedDNP: false,
28142
28276
  modelBoundingBoxes: false,
@@ -28287,11 +28421,17 @@ var AnyCadComponent = ({
28287
28421
  }
28288
28422
  );
28289
28423
  }
28290
- if (isThroughHole && !visibility.throughHoleModels) {
28291
- return null;
28292
- }
28293
- if (!isThroughHole && !visibility.smtModels) {
28294
- return null;
28424
+ if (cad_component2.show_as_translucent_model) {
28425
+ if (!visibility.translucentModels) {
28426
+ return null;
28427
+ }
28428
+ } else {
28429
+ if (isThroughHole && !visibility.throughHoleModels) {
28430
+ return null;
28431
+ }
28432
+ if (!isThroughHole && !visibility.smtModels) {
28433
+ return null;
28434
+ }
28295
28435
  }
28296
28436
  return /* @__PURE__ */ jsxs2(Fragment3, { children: [
28297
28437
  modelComponent,
@@ -28324,7 +28464,7 @@ import * as THREE15 from "three";
28324
28464
  // package.json
28325
28465
  var package_default = {
28326
28466
  name: "@tscircuit/3d-viewer",
28327
- version: "0.0.444",
28467
+ version: "0.0.446",
28328
28468
  main: "./dist/index.js",
28329
28469
  module: "./dist/index.js",
28330
28470
  type: "module",
@@ -28372,10 +28512,12 @@ var package_default = {
28372
28512
  "@storybook/blocks": "9.0.0-alpha.17",
28373
28513
  "@storybook/react-vite": "^9.1.5",
28374
28514
  "@tscircuit/circuit-json-util": "^0.0.72",
28375
- "@tscircuit/core": "^0.0.787",
28376
- "@tscircuit/props": "^0.0.364",
28377
- "@tscircuit/checks": "^0.0.85",
28378
- "@tscircuit/math-utils": "^0.0.27",
28515
+ "@tscircuit/core": "^0.0.890",
28516
+ "@tscircuit/props": "^0.0.422",
28517
+ "@tscircuit/checks": "^0.0.87",
28518
+ "@tscircuit/math-utils": "^0.0.29",
28519
+ "@tscircuit/copper-pour-solver": "^0.0.14",
28520
+ "@tscircuit/solver-utils": "^0.0.4",
28379
28521
  "@tscircuit/capacity-autorouter": "^0.0.131",
28380
28522
  "calculate-packing": "^0.0.48",
28381
28523
  "@types/jsdom": "^21.1.7",
@@ -28386,10 +28528,10 @@ var package_default = {
28386
28528
  "@vitejs/plugin-react": "^4.3.4",
28387
28529
  "bun-match-svg": "^0.0.9",
28388
28530
  "bun-types": "1.2.1",
28389
- "circuit-json": "0.0.320",
28531
+ "circuit-json": "0.0.325",
28390
28532
  "circuit-to-svg": "^0.0.179",
28391
28533
  debug: "^4.4.0",
28392
- "jscad-electronics": "^0.0.89",
28534
+ "jscad-electronics": "^0.0.91",
28393
28535
  "jscad-planner": "^0.0.13",
28394
28536
  jsdom: "^26.0.0",
28395
28537
  "manifold-3d": "^3.2.1",
@@ -34140,8 +34282,11 @@ function createGeometryMeshes(geoms) {
34140
34282
  new THREE27.MeshStandardMaterial({
34141
34283
  color: comp.color,
34142
34284
  side: THREE27.DoubleSide,
34143
- flatShading: true
34285
+ flatShading: true,
34144
34286
  // Consistent with board
34287
+ polygonOffset: true,
34288
+ polygonOffsetFactor: -1,
34289
+ polygonOffsetUnits: -1
34145
34290
  })
34146
34291
  );
34147
34292
  mesh.name = comp.key;
@@ -39037,6 +39182,12 @@ function RemoveScrollSideCar(props) {
39037
39182
  if ("touches" in event && moveDirection === "h" && target.type === "range") {
39038
39183
  return false;
39039
39184
  }
39185
+ var selection = window.getSelection();
39186
+ var anchorNode = selection && selection.anchorNode;
39187
+ var isTouchingSelection = anchorNode ? anchorNode === target || anchorNode.contains(target) : false;
39188
+ if (isTouchingSelection) {
39189
+ return false;
39190
+ }
39040
39191
  var canBeScrolledInMainDirection = locationCouldBeScrolled(moveDirection, target);
39041
39192
  if (!canBeScrolledInMainDirection) {
39042
39193
  return true;
@@ -41170,6 +41321,21 @@ var CadViewerInner = (props) => {
41170
41321
  description: "Toggle through-hole components"
41171
41322
  }
41172
41323
  );
41324
+ useRegisteredHotkey(
41325
+ "toggle_translucent_models",
41326
+ () => {
41327
+ const newVisibility = !visibility.translucentModels;
41328
+ setLayerVisibility("translucentModels", newVisibility);
41329
+ showToast(
41330
+ newVisibility ? "Translucent components visible" : "Translucent components hidden",
41331
+ 1500
41332
+ );
41333
+ },
41334
+ {
41335
+ shortcut: "shift+v",
41336
+ description: "Toggle translucent components"
41337
+ }
41338
+ );
41173
41339
  useEffect42(() => {
41174
41340
  if (containerRef.current) {
41175
41341
  registerHotkeyViewer(containerRef.current);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/3d-viewer",
3
- "version": "0.0.445",
3
+ "version": "0.0.447",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",
@@ -48,10 +48,12 @@
48
48
  "@storybook/blocks": "9.0.0-alpha.17",
49
49
  "@storybook/react-vite": "^9.1.5",
50
50
  "@tscircuit/circuit-json-util": "^0.0.72",
51
- "@tscircuit/core": "^0.0.787",
52
- "@tscircuit/props": "^0.0.364",
53
- "@tscircuit/checks": "^0.0.85",
54
- "@tscircuit/math-utils": "^0.0.27",
51
+ "@tscircuit/core": "^0.0.890",
52
+ "@tscircuit/props": "^0.0.422",
53
+ "@tscircuit/checks": "^0.0.87",
54
+ "@tscircuit/math-utils": "^0.0.29",
55
+ "@tscircuit/copper-pour-solver": "^0.0.14",
56
+ "@tscircuit/solver-utils": "^0.0.4",
55
57
  "@tscircuit/capacity-autorouter": "^0.0.131",
56
58
  "calculate-packing": "^0.0.48",
57
59
  "@types/jsdom": "^21.1.7",
@@ -62,10 +64,10 @@
62
64
  "@vitejs/plugin-react": "^4.3.4",
63
65
  "bun-match-svg": "^0.0.9",
64
66
  "bun-types": "1.2.1",
65
- "circuit-json": "0.0.320",
67
+ "circuit-json": "0.0.325",
66
68
  "circuit-to-svg": "^0.0.179",
67
69
  "debug": "^4.4.0",
68
- "jscad-electronics": "^0.0.89",
70
+ "jscad-electronics": "^0.0.91",
69
71
  "jscad-planner": "^0.0.13",
70
72
  "jsdom": "^26.0.0",
71
73
  "manifold-3d": "^3.2.1",