@tscircuit/core 0.0.718 → 0.0.719

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 (3) hide show
  1. package/dist/index.d.ts +286 -138
  2. package/dist/index.js +150 -33
  3. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -11,6 +11,8 @@ __export(components_exports, {
11
11
  Board: () => Board,
12
12
  Breakout: () => Breakout,
13
13
  BreakoutPoint: () => BreakoutPoint,
14
+ CadAssembly: () => CadAssembly,
15
+ CadModel: () => CadModel,
14
16
  Capacitor: () => Capacitor,
15
17
  Chip: () => Chip,
16
18
  Constraint: () => Constraint3,
@@ -69,8 +71,8 @@ __export(components_exports, {
69
71
  import { fp } from "@tscircuit/footprinter";
70
72
  import {
71
73
  pcb_manual_edit_conflict_warning,
72
- point3,
73
- rotation,
74
+ point3 as point32,
75
+ rotation as rotation2,
74
76
  schematic_manual_edit_conflict_warning
75
77
  } from "circuit-json";
76
78
  import Debug4 from "debug";
@@ -699,10 +701,10 @@ var PrimitiveComponent2 = class extends Renderable {
699
701
  */
700
702
  computePcbPropsTransform() {
701
703
  const { _parsedProps: props } = this;
702
- const rotation4 = this._getPcbRotationBeforeLayout() ?? 0;
704
+ const rotation5 = this._getPcbRotationBeforeLayout() ?? 0;
703
705
  const matrix = compose(
704
706
  translate(props.pcbX ?? 0, props.pcbY ?? 0),
705
- rotate(rotation4 * Math.PI / 180)
707
+ rotate(rotation5 * Math.PI / 180)
706
708
  );
707
709
  return matrix;
708
710
  }
@@ -716,12 +718,12 @@ var PrimitiveComponent2 = class extends Renderable {
716
718
  _computePcbGlobalTransformBeforeLayout() {
717
719
  const manualPlacement = this.getSubcircuit()._getPcbManualPlacementForComponent(this);
718
720
  if (manualPlacement && this.props.pcbX === void 0 && this.props.pcbY === void 0) {
719
- const rotation4 = this._getPcbRotationBeforeLayout() ?? 0;
721
+ const rotation5 = this._getPcbRotationBeforeLayout() ?? 0;
720
722
  return compose(
721
723
  this.parent?._computePcbGlobalTransformBeforeLayout() ?? identity(),
722
724
  compose(
723
725
  translate(manualPlacement.x, manualPlacement.y),
724
- rotate(rotation4 * Math.PI / 180)
726
+ rotate(rotation5 * Math.PI / 180)
725
727
  )
726
728
  );
727
729
  }
@@ -3761,7 +3763,7 @@ import {
3761
3763
  isValidElement
3762
3764
  } from "react";
3763
3765
  import { symbols as symbols2 } from "schematic-symbols";
3764
- import { z as z8 } from "zod";
3766
+ import { z as z9 } from "zod";
3765
3767
 
3766
3768
  // lib/components/primitive-components/Footprint.ts
3767
3769
  import { footprintProps } from "@tscircuit/props";
@@ -3973,6 +3975,101 @@ var Footprint = class extends PrimitiveComponent2 {
3973
3975
  }
3974
3976
  };
3975
3977
 
3978
+ // lib/components/primitive-components/CadModel.ts
3979
+ import { cadmodelProps, point3 } from "@tscircuit/props";
3980
+ import { z as z7 } from "zod";
3981
+ var rotation = z7.union([z7.number(), z7.string()]);
3982
+ var rotation3 = z7.object({ x: rotation, y: rotation, z: rotation });
3983
+ var CadModel = class extends PrimitiveComponent2 {
3984
+ get config() {
3985
+ return {
3986
+ componentName: "CadModel",
3987
+ zodProps: cadmodelProps
3988
+ };
3989
+ }
3990
+ doInitialCadModelRender() {
3991
+ const parent = this._findParentWithPcbComponent();
3992
+ if (!parent) return;
3993
+ if (!parent.pcb_component_id) return;
3994
+ const { db } = this.root;
3995
+ const { boardThickness = 0 } = this.root?._getBoard() ?? {};
3996
+ const bounds = parent._getPcbCircuitJsonBounds();
3997
+ const pcb_component = db.pcb_component.get(parent.pcb_component_id);
3998
+ const props = this._parsedProps;
3999
+ if (!props || typeof props.modelUrl !== "string") return;
4000
+ const rotationOffset = rotation3.parse({ x: 0, y: 0, z: 0 });
4001
+ if (typeof props.rotationOffset === "number") {
4002
+ rotationOffset.z = Number(props.rotationOffset);
4003
+ } else if (typeof props.rotationOffset === "object") {
4004
+ const parsed = rotation3.parse(props.rotationOffset);
4005
+ rotationOffset.x = Number(parsed.x);
4006
+ rotationOffset.y = Number(parsed.y);
4007
+ rotationOffset.z = Number(parsed.z);
4008
+ }
4009
+ const positionOffset = point3.parse({
4010
+ x: props.pcbX ?? 0,
4011
+ y: props.pcbY ?? 0,
4012
+ z: props.pcbZ ?? 0,
4013
+ ...typeof props.positionOffset === "object" ? props.positionOffset : {}
4014
+ });
4015
+ const layer = parent.props.layer === "bottom" ? "bottom" : "top";
4016
+ const ext = new URL(props.modelUrl).pathname.split(".").pop()?.toLowerCase();
4017
+ const urlProps = {};
4018
+ if (ext === "stl")
4019
+ urlProps.model_stl_url = this._addCachebustToModelUrl(props.modelUrl);
4020
+ else if (ext === "obj")
4021
+ urlProps.model_obj_url = this._addCachebustToModelUrl(props.modelUrl);
4022
+ else if (ext === "gltf")
4023
+ urlProps.model_gltf_url = this._addCachebustToModelUrl(props.modelUrl);
4024
+ else if (ext === "glb")
4025
+ urlProps.model_glb_url = this._addCachebustToModelUrl(props.modelUrl);
4026
+ else if (ext === "step" || ext === "stp")
4027
+ urlProps.model_step_url = this._addCachebustToModelUrl(props.modelUrl);
4028
+ else if (ext === "wrl" || ext === "vrml")
4029
+ urlProps.model_wrl_url = this._addCachebustToModelUrl(props.modelUrl);
4030
+ else urlProps.model_stl_url = this._addCachebustToModelUrl(props.modelUrl);
4031
+ const cad = db.cad_component.insert({
4032
+ position: {
4033
+ x: bounds.center.x + Number(positionOffset.x),
4034
+ y: bounds.center.y + Number(positionOffset.y),
4035
+ z: (layer === "bottom" ? -boardThickness / 2 : boardThickness / 2) + Number(positionOffset.z)
4036
+ },
4037
+ rotation: {
4038
+ x: Number(rotationOffset.x),
4039
+ y: (layer === "top" ? 0 : 180) + Number(rotationOffset.y),
4040
+ z: layer === "bottom" ? -((pcb_component?.rotation ?? 0) + Number(rotationOffset.z)) + 180 : (pcb_component?.rotation ?? 0) + Number(rotationOffset.z)
4041
+ },
4042
+ pcb_component_id: parent.pcb_component_id,
4043
+ source_component_id: parent.source_component_id,
4044
+ model_unit_to_mm_scale_factor: typeof props.modelUnitToMmScale === "number" ? props.modelUnitToMmScale : void 0,
4045
+ ...urlProps
4046
+ });
4047
+ this.cad_component_id = cad.cad_component_id;
4048
+ }
4049
+ _findParentWithPcbComponent() {
4050
+ let p = this.parent;
4051
+ while (p && !p.pcb_component_id) p = p.parent;
4052
+ return p;
4053
+ }
4054
+ _addCachebustToModelUrl(url) {
4055
+ if (!url || !url.includes("modelcdn.tscircuit.com")) return url;
4056
+ const origin = this.root?.getClientOrigin() ?? "";
4057
+ return `${url}${url.includes("?") ? "&" : "?"}cachebust_origin=${encodeURIComponent(origin)}`;
4058
+ }
4059
+ };
4060
+
4061
+ // lib/components/primitive-components/CadAssembly.ts
4062
+ import { cadassemblyProps } from "@tscircuit/props";
4063
+ var CadAssembly = class extends PrimitiveComponent2 {
4064
+ isPrimitiveContainer = true;
4065
+ get config() {
4066
+ return {
4067
+ componentName: "CadAssembly",
4068
+ zodProps: cadassemblyProps
4069
+ };
4070
+ }
4071
+ };
4072
+
3976
4073
  // lib/utils/schematic/getNumericSchPinStyle.ts
3977
4074
  var getNumericSchPinStyle = (pinStyles, pinLabels) => {
3978
4075
  if (!pinStyles) return void 0;
@@ -4388,12 +4485,12 @@ var getObstaclesFromRoute = (route, source_trace_id, { viaDiameter = 0.5 } = {})
4388
4485
 
4389
4486
  // lib/utils/obstacles/generateApproximatingRects.ts
4390
4487
  function generateApproximatingRects(rotatedRect, numRects = 4) {
4391
- const { center, width, height, rotation: rotation4 } = rotatedRect;
4488
+ const { center, width, height, rotation: rotation5 } = rotatedRect;
4392
4489
  const rects = [];
4393
- const angleRad = rotation4 * Math.PI / 180;
4490
+ const angleRad = rotation5 * Math.PI / 180;
4394
4491
  const cosAngle = Math.cos(angleRad);
4395
4492
  const sinAngle = Math.sin(angleRad);
4396
- const normalizedRotation = (rotation4 % 360 + 360) % 360;
4493
+ const normalizedRotation = (rotation5 % 360 + 360) % 360;
4397
4494
  const sliceAlongWidth = height <= width ? normalizedRotation >= 45 && normalizedRotation < 135 || normalizedRotation >= 225 && normalizedRotation < 315 : normalizedRotation >= 135 && normalizedRotation < 225 || normalizedRotation >= 315 || normalizedRotation < 45;
4398
4495
  if (sliceAlongWidth) {
4399
4496
  const sliceWidth = width / numRects;
@@ -6705,13 +6802,6 @@ function NormalComponent_doInitialPcbFootprintStringRender(component, queueAsync
6705
6802
  });
6706
6803
  return;
6707
6804
  }
6708
- if (isReactElement(footprint)) {
6709
- if (component.reactSubtrees.some((rs) => rs.element === footprint)) return;
6710
- const subtree = component._renderReactSubtree(footprint);
6711
- component.reactSubtrees.push(subtree);
6712
- component.add(subtree.component);
6713
- return;
6714
- }
6715
6805
  if (!isReactElement(footprint) && footprint.componentName === "Footprint") {
6716
6806
  component.add(footprint);
6717
6807
  }
@@ -6719,10 +6809,10 @@ function NormalComponent_doInitialPcbFootprintStringRender(component, queueAsync
6719
6809
 
6720
6810
  // lib/components/base-components/NormalComponent/NormalComponent.ts
6721
6811
  var debug3 = Debug4("tscircuit:core");
6722
- var rotation3 = z8.object({
6723
- x: rotation,
6724
- y: rotation,
6725
- z: rotation
6812
+ var rotation32 = z9.object({
6813
+ x: rotation2,
6814
+ y: rotation2,
6815
+ z: rotation2
6726
6816
  });
6727
6817
  var NormalComponent2 = class extends PrimitiveComponent2 {
6728
6818
  reactSubtrees = [];
@@ -6737,6 +6827,7 @@ var NormalComponent2 = class extends PrimitiveComponent2 {
6737
6827
  };
6738
6828
  _asyncSupplierPartNumbers;
6739
6829
  _asyncFootprintCadModel;
6830
+ _isCadModelChild;
6740
6831
  pcb_missing_footprint_error_id;
6741
6832
  _hasStartedFootprintUrlLoad = false;
6742
6833
  _invalidPinLabelMessages = [];
@@ -7250,15 +7341,38 @@ var NormalComponent2 = class extends PrimitiveComponent2 {
7250
7341
  this.doInitialPcbComponentSizeCalculation();
7251
7342
  }
7252
7343
  _renderReactSubtree(element) {
7344
+ const component = createInstanceFromReactElement(element);
7253
7345
  return {
7254
7346
  element,
7255
- component: createInstanceFromReactElement(element)
7347
+ component
7256
7348
  };
7257
7349
  }
7258
7350
  doInitialInitializePortsFromChildren() {
7259
7351
  this.initPorts();
7260
7352
  }
7261
7353
  doInitialReactSubtreesRender() {
7354
+ const fpElm = this.props.footprint;
7355
+ if (isValidElement(fpElm)) {
7356
+ const hasFootprintChild = this.children.some(
7357
+ (c) => c.componentName === "Footprint"
7358
+ );
7359
+ if (!hasFootprintChild) {
7360
+ this.add(fpElm);
7361
+ }
7362
+ }
7363
+ const cmElm = this.props.cadModel;
7364
+ if (isValidElement(cmElm)) {
7365
+ this._isCadModelChild = true;
7366
+ const hasCadAssemblyChild = this.children.some(
7367
+ (c) => c.componentName === "CadAssembly"
7368
+ );
7369
+ const hasCadModelChild = this.children.some(
7370
+ (c) => c.componentName === "CadModel"
7371
+ );
7372
+ if (!hasCadAssemblyChild && !hasCadModelChild) {
7373
+ this.add(cmElm);
7374
+ }
7375
+ }
7262
7376
  }
7263
7377
  doInitialPcbFootprintStringRender() {
7264
7378
  NormalComponent_doInitialPcbFootprintStringRender(
@@ -7470,6 +7584,7 @@ var NormalComponent2 = class extends PrimitiveComponent2 {
7470
7584
  return dimensions;
7471
7585
  }
7472
7586
  doInitialCadModelRender() {
7587
+ if (this._isCadModelChild) return;
7473
7588
  const { db } = this.root;
7474
7589
  const { boardThickness = 0 } = this.root?._getBoard() ?? {};
7475
7590
  const cadModelProp = this._parsedProps.cadModel;
@@ -7483,13 +7598,13 @@ var NormalComponent2 = class extends PrimitiveComponent2 {
7483
7598
  if (typeof cadModel === "string") {
7484
7599
  throw new Error("String cadModel not yet implemented");
7485
7600
  }
7486
- const rotationOffset = rotation3.parse({
7601
+ const rotationOffset = rotation32.parse({
7487
7602
  x: 0,
7488
7603
  y: 0,
7489
7604
  z: typeof cadModel?.rotationOffset === "number" ? cadModel.rotationOffset : 0,
7490
7605
  ...typeof cadModel?.rotationOffset === "object" ? cadModel.rotationOffset ?? {} : {}
7491
7606
  });
7492
- const positionOffset = point3.parse({
7607
+ const positionOffset = point32.parse({
7493
7608
  x: 0,
7494
7609
  y: 0,
7495
7610
  z: 0,
@@ -12939,18 +13054,18 @@ var PowerSource = class extends NormalComponent2 {
12939
13054
  };
12940
13055
 
12941
13056
  // lib/components/normal-components/VoltageSource.ts
12942
- import { frequency, rotation as rotation2, voltage } from "circuit-json";
13057
+ import { frequency, rotation as rotation4, voltage } from "circuit-json";
12943
13058
  import {
12944
13059
  commonComponentProps
12945
13060
  } from "@tscircuit/props";
12946
- import { z as z12 } from "zod";
13061
+ import { z as z13 } from "zod";
12947
13062
  var voltageSourceProps = commonComponentProps.extend({
12948
13063
  voltage: voltage.optional(),
12949
13064
  frequency: frequency.optional(),
12950
13065
  peakToPeakVoltage: voltage.optional(),
12951
- waveShape: z12.enum(["sinewave", "square", "triangle", "sawtooth"]).optional(),
12952
- phase: rotation2.optional(),
12953
- dutyCycle: z12.number().optional()
13066
+ waveShape: z13.enum(["sinewave", "square", "triangle", "sawtooth"]).optional(),
13067
+ phase: rotation4.optional(),
13068
+ dutyCycle: z13.number().optional()
12954
13069
  });
12955
13070
  var VoltageSource = class extends NormalComponent2 {
12956
13071
  get config() {
@@ -14794,7 +14909,7 @@ import { identity as identity6 } from "transformation-matrix";
14794
14909
  var package_default = {
14795
14910
  name: "@tscircuit/core",
14796
14911
  type: "module",
14797
- version: "0.0.717",
14912
+ version: "0.0.718",
14798
14913
  types: "dist/index.d.ts",
14799
14914
  main: "dist/index.js",
14800
14915
  module: "dist/index.js",
@@ -14833,11 +14948,11 @@ var package_default = {
14833
14948
  "@tscircuit/matchpack": "^0.0.16",
14834
14949
  "@tscircuit/math-utils": "^0.0.21",
14835
14950
  "@tscircuit/miniflex": "^0.0.4",
14836
- "@tscircuit/props": "0.0.315",
14951
+ "@tscircuit/props": "0.0.319",
14837
14952
  "@tscircuit/schematic-autolayout": "^0.0.6",
14838
14953
  "@tscircuit/schematic-match-adapt": "^0.0.16",
14839
14954
  "@tscircuit/schematic-trace-solver": "^0.0.36",
14840
- "@tscircuit/simple-3d-svg": "^0.0.38",
14955
+ "@tscircuit/simple-3d-svg": "^0.0.41",
14841
14956
  "@types/bun": "^1.2.16",
14842
14957
  "@types/debug": "^4.1.12",
14843
14958
  "@types/react": "^19.1.8",
@@ -14850,7 +14965,7 @@ var package_default = {
14850
14965
  "circuit-json": "^0.0.250",
14851
14966
  "circuit-json-to-bpc": "^0.0.13",
14852
14967
  "circuit-json-to-connectivity-map": "^0.0.22",
14853
- "circuit-json-to-simple-3d": "^0.0.6",
14968
+ "circuit-json-to-simple-3d": "^0.0.8",
14854
14969
  "circuit-to-svg": "^0.0.189",
14855
14970
  concurrently: "^9.1.2",
14856
14971
  "connectivity-map": "^1.0.0",
@@ -15301,6 +15416,8 @@ export {
15301
15416
  Board,
15302
15417
  Breakout,
15303
15418
  BreakoutPoint,
15419
+ CadAssembly,
15420
+ CadModel,
15304
15421
  Capacitor,
15305
15422
  Chip,
15306
15423
  Circuit,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.718",
4
+ "version": "0.0.719",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -40,11 +40,11 @@
40
40
  "@tscircuit/matchpack": "^0.0.16",
41
41
  "@tscircuit/math-utils": "^0.0.21",
42
42
  "@tscircuit/miniflex": "^0.0.4",
43
- "@tscircuit/props": "0.0.315",
43
+ "@tscircuit/props": "0.0.319",
44
44
  "@tscircuit/schematic-autolayout": "^0.0.6",
45
45
  "@tscircuit/schematic-match-adapt": "^0.0.16",
46
46
  "@tscircuit/schematic-trace-solver": "^0.0.36",
47
- "@tscircuit/simple-3d-svg": "^0.0.38",
47
+ "@tscircuit/simple-3d-svg": "^0.0.41",
48
48
  "@types/bun": "^1.2.16",
49
49
  "@types/debug": "^4.1.12",
50
50
  "@types/react": "^19.1.8",
@@ -57,7 +57,7 @@
57
57
  "circuit-json": "^0.0.250",
58
58
  "circuit-json-to-bpc": "^0.0.13",
59
59
  "circuit-json-to-connectivity-map": "^0.0.22",
60
- "circuit-json-to-simple-3d": "^0.0.6",
60
+ "circuit-json-to-simple-3d": "^0.0.8",
61
61
  "circuit-to-svg": "^0.0.189",
62
62
  "concurrently": "^9.1.2",
63
63
  "connectivity-map": "^1.0.0",