easyeda 0.0.263 → 0.0.265

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/index.d.ts CHANGED
@@ -4867,9 +4867,21 @@ interface Options {
4867
4867
  cadPositionXMm?: number;
4868
4868
  cadPositionYMm?: number;
4869
4869
  cadPositionZMm?: number;
4870
+ cadModelBounds?: {
4871
+ min: {
4872
+ x: number;
4873
+ y: number;
4874
+ z: number;
4875
+ };
4876
+ max: {
4877
+ x: number;
4878
+ y: number;
4879
+ z: number;
4880
+ };
4881
+ };
4870
4882
  showDesignator?: boolean;
4871
4883
  }
4872
- declare const convertEasyEdaJsonToCircuitJson: (easyEdaJson: BetterEasyEdaJson, { useModelCdn, shouldRecenter, cadPositionXMm, cadPositionYMm, cadPositionZMm, showDesignator, }?: Options) => AnyCircuitElement[];
4884
+ declare const convertEasyEdaJsonToCircuitJson: (easyEdaJson: BetterEasyEdaJson, { useModelCdn, shouldRecenter, cadPositionXMm, cadPositionYMm, cadPositionZMm, cadModelBounds, showDesignator, }?: Options) => AnyCircuitElement[];
4873
4885
 
4874
4886
  declare function fetchEasyEDAComponent(jlcpcbPartNumber: string, { fetch, includeModelMetadata, }?: {
4875
4887
  fetch?: typeof globalThis.fetch;
package/dist/index.js CHANGED
@@ -5033,11 +5033,11 @@ function generateArcFromSweep(startX, startY, endX, endY, radius, largeArcFlag,
5033
5033
  const midY = (startY + endY) / 2;
5034
5034
  const dx = endX - startX;
5035
5035
  const dy = endY - startY;
5036
- const distance2 = Math.sqrt(dx * dx + dy * dy);
5037
- if (distance2 === 0 || radius < distance2 / 2) {
5036
+ const distance3 = Math.sqrt(dx * dx + dy * dy);
5037
+ if (distance3 === 0 || radius < distance3 / 2) {
5038
5038
  return [start, end];
5039
5039
  }
5040
- const h = Math.sqrt(radius * radius - distance2 * distance2 / 4);
5040
+ const h = Math.sqrt(radius * radius - distance3 * distance3 / 4);
5041
5041
  const angle = Math.atan2(dy, dx);
5042
5042
  const centerX = midX + h * Math.sin(angle) * (sweepFlag ? -1 : 1);
5043
5043
  const centerY = midY - h * Math.cos(angle) * (sweepFlag ? -1 : 1);
@@ -5073,6 +5073,142 @@ function generateArcFromSweep(startX, startY, endX, endY, radius, largeArcFlag,
5073
5073
  // lib/utils/easyeda-unit-to-mm.ts
5074
5074
  var mil10ToMm = (value) => value * 10 * 0.0254;
5075
5075
 
5076
+ // node_modules/@tscircuit/math-utils/dist/chunk-3WCUPG5S.js
5077
+ var getBoundsCenter = (bounds) => ({
5078
+ x: (bounds.minX + bounds.maxX) / 2,
5079
+ y: (bounds.minY + bounds.maxY) / 2
5080
+ });
5081
+
5082
+ // node_modules/@tscircuit/math-utils/dist/chunk-5N7UJNVK.js
5083
+ var getBoundsFromPoints = (points) => {
5084
+ if (points.length === 0) {
5085
+ return null;
5086
+ }
5087
+ let minX = points[0].x;
5088
+ let minY = points[0].y;
5089
+ let maxX = points[0].x;
5090
+ let maxY = points[0].y;
5091
+ for (let i = 1; i < points.length; i++) {
5092
+ const point2 = points[i];
5093
+ if (point2.x < minX) minX = point2.x;
5094
+ if (point2.y < minY) minY = point2.y;
5095
+ if (point2.x > maxX) maxX = point2.x;
5096
+ if (point2.y > maxY) maxY = point2.y;
5097
+ }
5098
+ return { minX, minY, maxX, maxY };
5099
+ };
5100
+
5101
+ // lib/websafe/get-easyeda-cad-placement-helpers.ts
5102
+ var getCadSvgNode = (easyEdaJson) => {
5103
+ const svgNode = easyEdaJson.packageDetail.dataStr.shape.find(
5104
+ (shape) => shape.type === "SVGNODE" && shape.svgData.attrs?.uuid
5105
+ );
5106
+ return svgNode?.type === "SVGNODE" ? svgNode : null;
5107
+ };
5108
+ var isSvgChildNodeWithAttrs = (childNode) => typeof childNode === "object" && childNode !== null;
5109
+ var getXyBoundsFromModelBounds = (bounds) => ({
5110
+ minX: bounds.min.x,
5111
+ minY: bounds.min.y,
5112
+ maxX: bounds.max.x,
5113
+ maxY: bounds.max.y
5114
+ });
5115
+ var rotateScenePoint = (point2, rotationDeg) => {
5116
+ switch (rotationDeg) {
5117
+ case 0:
5118
+ return point2;
5119
+ case 90:
5120
+ return { x: point2.y, y: -point2.x };
5121
+ case 180:
5122
+ return { x: -point2.x, y: -point2.y };
5123
+ case 270:
5124
+ return { x: -point2.y, y: point2.x };
5125
+ }
5126
+ };
5127
+ var getEasyEdaModelOriginOnBoardMm = ({
5128
+ svgNode,
5129
+ footprintCenterMm
5130
+ }) => {
5131
+ const points = [];
5132
+ for (const childNode of svgNode.svgData.childNodes ?? []) {
5133
+ if (!isSvgChildNodeWithAttrs(childNode)) continue;
5134
+ const rawPoints = childNode.attrs?.points;
5135
+ if (!rawPoints) continue;
5136
+ const values = String(rawPoints).trim().split(/\s+/).map(Number);
5137
+ for (let i = 0; i + 1 < values.length; i += 2) {
5138
+ const x = values[i];
5139
+ const y = values[i + 1];
5140
+ if (Number.isFinite(x) && Number.isFinite(y)) {
5141
+ points.push({ x: mil10ToMm(x), y: mil10ToMm(y) });
5142
+ }
5143
+ }
5144
+ }
5145
+ let modelOriginMm = null;
5146
+ if (points.length > 0) {
5147
+ const bounds = getBoundsFromPoints(points);
5148
+ modelOriginMm = bounds ? getBoundsCenter(bounds) : null;
5149
+ } else {
5150
+ const [originX, originY] = String(svgNode.svgData.attrs?.c_origin ?? "0,0").split(",").map((value) => Number(value.trim()));
5151
+ if (Number.isFinite(originX) && Number.isFinite(originY)) {
5152
+ modelOriginMm = { x: mil10ToMm(originX), y: mil10ToMm(originY) };
5153
+ }
5154
+ }
5155
+ if (!modelOriginMm) return null;
5156
+ return {
5157
+ x: modelOriginMm.x - footprintCenterMm.x,
5158
+ y: footprintCenterMm.y - modelOriginMm.y
5159
+ };
5160
+ };
5161
+ var snapZero = (value) => Math.abs(value) < 1e-6 ? 0 : value;
5162
+ var normalizePoint = (point2) => ({
5163
+ x: snapZero(point2.x),
5164
+ y: snapZero(point2.y)
5165
+ });
5166
+ var getCadModelOffsetMm = (easyEdaJson) => {
5167
+ const svgNode = getCadSvgNode(easyEdaJson);
5168
+ return getCadModelOffsetMmFromBounds(
5169
+ easyEdaJson,
5170
+ easyEdaJson._objMetadata?.bounds
5171
+ );
5172
+ };
5173
+ var getCadModelOffsetMmFromBounds = (easyEdaJson, bounds, {
5174
+ footprintBoundsCenterMm
5175
+ } = {}) => {
5176
+ const svgNode = getCadSvgNode(easyEdaJson);
5177
+ if (!svgNode || !bounds) return null;
5178
+ const [, , rotationZRaw] = String(
5179
+ svgNode.svgData.attrs?.c_rotation ?? "0,0,0"
5180
+ ).split(",").map((value) => Number(value.trim()));
5181
+ const rotationDeg = (rotationZRaw % 360 + 360) % 360;
5182
+ if (![0, 90, 180, 270].includes(rotationDeg)) return null;
5183
+ const modelCenter = getBoundsCenter(getXyBoundsFromModelBounds(bounds));
5184
+ const footprintCenter = easyEdaJson.packageDetail.dataStr.head;
5185
+ const footprintCenterMm = footprintBoundsCenterMm ?? {
5186
+ x: mil10ToMm(footprintCenter.x),
5187
+ y: mil10ToMm(footprintCenter.y)
5188
+ };
5189
+ const targetOriginOnBoardMm = getEasyEdaModelOriginOnBoardMm({
5190
+ svgNode,
5191
+ footprintCenterMm
5192
+ });
5193
+ if (!targetOriginOnBoardMm) return null;
5194
+ const targetOriginInModelFrame = rotateScenePoint(
5195
+ targetOriginOnBoardMm,
5196
+ rotationDeg
5197
+ );
5198
+ return normalizePoint({
5199
+ x: modelCenter.x - targetOriginInModelFrame.x,
5200
+ y: modelCenter.y - targetOriginInModelFrame.y
5201
+ });
5202
+ };
5203
+ var getCadSvgNodeZOffsetMm = (easyEdaJson) => {
5204
+ const svgNode = getCadSvgNode(easyEdaJson);
5205
+ if (!svgNode) return null;
5206
+ const svgNodeZ = Number(svgNode.svgData.attrs?.z ?? 0);
5207
+ if (!Number.isFinite(svgNodeZ)) return null;
5208
+ return mil10ToMm(svgNodeZ);
5209
+ };
5210
+ var getCadSvgNodeModelUuid = (easyEdaJson) => getCadSvgNode(easyEdaJson)?.svgData.attrs?.uuid ?? null;
5211
+
5076
5212
  // lib/utils/normalize-pin-labels.ts
5077
5213
  var normalizePinLabels = (inputPinLabels) => {
5078
5214
  const uniqueInputPinLabels = inputPinLabels.map((labels) => [
@@ -5289,6 +5425,7 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
5289
5425
  cadPositionXMm,
5290
5426
  cadPositionYMm,
5291
5427
  cadPositionZMm,
5428
+ cadModelBounds,
5292
5429
  showDesignator = false
5293
5430
  } = {}) => {
5294
5431
  const resolvedCadPositionZMm = cadPositionZMm ?? getCadPositionZMmFromMetadata(easyEdaJson);
@@ -5427,7 +5564,7 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
5427
5564
  } else if (pad.shape === "ELLIPSE") {
5428
5565
  soupShape = "rect";
5429
5566
  } else if (pad.shape === "OVAL") {
5430
- soupShape = "rect";
5567
+ soupShape = "pill";
5431
5568
  } else if (pad.shape === "POLYGON") {
5432
5569
  soupShape = "polygon";
5433
5570
  }
@@ -5447,12 +5584,17 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
5447
5584
  x: mil2mm(pad.center.x),
5448
5585
  y: mil2mm(pad.center.y)
5449
5586
  },
5450
- ...soupShape === "rect" ? rectSize : soupShape === "polygon" && pad.points ? {
5587
+ ...soupShape === "rect" ? rectSize : soupShape === "pill" ? {
5588
+ ...rectSize,
5589
+ radius: Math.min(rectSize.width, rectSize.height) / 2
5590
+ } : soupShape === "polygon" && pad.points ? {
5451
5591
  points: pad.points.map((p) => ({
5452
5592
  x: milx10(p.x),
5453
5593
  y: milx10(p.y)
5454
5594
  }))
5455
- } : { radius: Math.min(mil2mm(pad.width), mil2mm(pad.height)) / 2 },
5595
+ } : {
5596
+ radius: Math.min(mil2mm(pad.width), mil2mm(pad.height)) / 2
5597
+ },
5456
5598
  layer: "top",
5457
5599
  port_hints: [`pin${pinNumber}`],
5458
5600
  pcb_component_id: "pcb_component_1",
@@ -5641,6 +5783,14 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, {
5641
5783
  if (!cad.model_origin_position) {
5642
5784
  cad.model_origin_position = { x: 0, y: 0, z: 0 };
5643
5785
  }
5786
+ const resolvedCadModelBounds = cadModelBounds ?? easyEdaJson._objMetadata?.bounds;
5787
+ const recenteredCadOffset = resolvedCadModelBounds && getCadModelOffsetMmFromBounds(easyEdaJson, resolvedCadModelBounds, {
5788
+ footprintBoundsCenterMm: bounds.center
5789
+ });
5790
+ if (recenteredCadOffset) {
5791
+ cad.model_origin_position.x = recenteredCadOffset.x;
5792
+ cad.model_origin_position.y = recenteredCadOffset.y;
5793
+ }
5644
5794
  const side = pcb_component2.layer ?? "top";
5645
5795
  const t = DEFAULT_PCB_THICKNESS_MM / 2;
5646
5796
  const attrs = svgNode?.svgData?.attrs ?? {};
@@ -6610,98 +6760,6 @@ function normalizeManufacturerPartNumber(partNumber) {
6610
6760
  return normalized;
6611
6761
  }
6612
6762
 
6613
- // lib/websafe/get-easyeda-cad-placement-helpers.ts
6614
- var milToMm = (mil) => mil * 0.0254;
6615
- var getBoundsCenter = (bounds) => ({
6616
- x: (bounds.min.x + bounds.max.x) / 2,
6617
- y: (bounds.min.y + bounds.max.y) / 2
6618
- });
6619
- var getCadSvgNode = (easyEdaJson) => {
6620
- const svgNode = easyEdaJson.packageDetail.dataStr.shape.find(
6621
- (shape) => shape.type === "SVGNODE" && shape.svgData.attrs?.uuid
6622
- );
6623
- return svgNode?.type === "SVGNODE" ? svgNode : null;
6624
- };
6625
- var parseMil10Value = (value) => Number(String(value).replace("mil", "")) / 10;
6626
- var isZeroishModelCenter = (value) => Math.abs(value) < 1e-6;
6627
- var isZeroishFootprintDelta = (value) => Math.abs(value) < 1e-3;
6628
- var getPadCenter = (easyEdaJson) => {
6629
- const pads = easyEdaJson.packageDetail.dataStr.shape.filter(
6630
- (shape) => shape.type === "PAD"
6631
- );
6632
- if (pads.length === 0) return null;
6633
- const xs = pads.map((pad) => parseMil10Value(pad.center.x));
6634
- const ys = pads.map((pad) => parseMil10Value(pad.center.y));
6635
- return {
6636
- x: (Math.min(...xs) + Math.max(...xs)) / 2,
6637
- y: (Math.min(...ys) + Math.max(...ys)) / 2
6638
- };
6639
- };
6640
- var getRotatedOffsetMm = ({
6641
- bounds,
6642
- rawOffsetMil,
6643
- rotationDeg
6644
- }) => {
6645
- const center = getBoundsCenter(bounds);
6646
- const offsetX = milToMm(rawOffsetMil.x);
6647
- const offsetY = milToMm(rawOffsetMil.y);
6648
- switch (rotationDeg) {
6649
- case 0:
6650
- return { x: center.x + offsetX, y: center.y + offsetY };
6651
- case 90:
6652
- return { x: center.x + offsetY, y: center.y + offsetX };
6653
- case 180:
6654
- return { x: center.x - offsetX, y: center.y - offsetY };
6655
- case 270:
6656
- return { x: center.x - offsetY, y: center.y - offsetX };
6657
- }
6658
- };
6659
- var getCadModelOffsetMm = (easyEdaJson) => {
6660
- const svgNode = getCadSvgNode(easyEdaJson);
6661
- return getCadModelOffsetMmFromBounds(
6662
- easyEdaJson,
6663
- easyEdaJson._objMetadata?.bounds
6664
- );
6665
- };
6666
- var getCadModelOffsetMmFromBounds = (easyEdaJson, bounds) => {
6667
- const svgNode = getCadSvgNode(easyEdaJson);
6668
- if (!svgNode || !bounds) return null;
6669
- const [originX, originY] = String(svgNode.svgData.attrs?.c_origin ?? "0,0").split(",").map((value) => Number(value.trim()));
6670
- if (!Number.isFinite(originX) || !Number.isFinite(originY)) return null;
6671
- const [, , rotationZRaw] = String(
6672
- svgNode.svgData.attrs?.c_rotation ?? "0,0,0"
6673
- ).split(",").map((value) => Number(value.trim()));
6674
- const rotationDeg = (rotationZRaw % 360 + 360) % 360;
6675
- if (![0, 90, 180, 270].includes(rotationDeg)) return null;
6676
- const modelCenter = getBoundsCenter(bounds);
6677
- const footprintCenter = easyEdaJson.packageDetail.dataStr.head;
6678
- const padCenter = getPadCenter(easyEdaJson);
6679
- const padCenterDelta = padCenter ? {
6680
- x: padCenter.x - footprintCenter.x,
6681
- y: padCenter.y - footprintCenter.y
6682
- } : null;
6683
- const rawOffsetMil = {
6684
- x: (originX - footprintCenter.x) * 10,
6685
- y: (originY - footprintCenter.y) * 10
6686
- };
6687
- if (padCenter && padCenterDelta && isZeroishModelCenter(modelCenter.x) && isZeroishModelCenter(modelCenter.y) && isZeroishFootprintDelta(padCenterDelta.x) && isZeroishFootprintDelta(padCenterDelta.y)) {
6688
- return { x: 0, y: 0 };
6689
- }
6690
- return getRotatedOffsetMm({
6691
- bounds,
6692
- rawOffsetMil,
6693
- rotationDeg
6694
- });
6695
- };
6696
- var getCadSvgNodeZOffsetMm = (easyEdaJson) => {
6697
- const svgNode = getCadSvgNode(easyEdaJson);
6698
- if (!svgNode) return null;
6699
- const svgNodeZ = Number(svgNode.svgData.attrs?.z ?? 0);
6700
- if (!Number.isFinite(svgNodeZ)) return null;
6701
- return mil10ToMm(svgNodeZ);
6702
- };
6703
- var getCadSvgNodeModelUuid = (easyEdaJson) => getCadSvgNode(easyEdaJson)?.svgData.attrs?.uuid ?? null;
6704
-
6705
6763
  // lib/websafe/get-easyeda-cad-model-placement.ts
6706
6764
  var placementCache = /* @__PURE__ */ new Map();
6707
6765
  var parseObjBounds2 = (objText) => {
@@ -6852,8 +6910,14 @@ var generateFootprintTsx = (circuitJson, options = {}) => {
6852
6910
  `<smtpad portHints={${JSON.stringify(mapPortHints(smtPad.port_hints, options.portHintsMap))}} pcbX="${mmStr(smtPad.x)}" pcbY="${mmStr(smtPad.y)}" radius="${mmStr(smtPad.radius)}" shape="circle" />`
6853
6911
  );
6854
6912
  } else if (smtPad.shape === "rect") {
6913
+ const cornerRadius = smtPad.corner_radius ?? smtPad.rect_border_radius ?? void 0;
6914
+ const cornerRadiusAttr = cornerRadius !== void 0 ? ` cornerRadius="${mmStr(cornerRadius)}"` : "";
6915
+ elementStrings.push(
6916
+ `<smtpad portHints={${JSON.stringify(smtPad.port_hints)}} pcbX="${mmStr(smtPad.x)}" pcbY="${mmStr(smtPad.y)}" width="${mmStr(smtPad.width)}" height="${mmStr(smtPad.height)}"${cornerRadiusAttr} shape="rect" />`
6917
+ );
6918
+ } else if (smtPad.shape === "pill") {
6855
6919
  elementStrings.push(
6856
- `<smtpad portHints={${JSON.stringify(mapPortHints(smtPad.port_hints, options.portHintsMap))}} pcbX="${mmStr(smtPad.x)}" pcbY="${mmStr(smtPad.y)}" width="${mmStr(smtPad.width)}" height="${mmStr(smtPad.height)}" shape="rect" />`
6920
+ `<smtpad portHints={${JSON.stringify(smtPad.port_hints)}} pcbX="${mmStr(smtPad.x)}" pcbY="${mmStr(smtPad.y)}" width="${mmStr(smtPad.width)}" height="${mmStr(smtPad.height)}" radius="${mmStr(smtPad.radius)}" shape="pill" />`
6857
6921
  );
6858
6922
  } else if (smtPad.shape === "polygon") {
6859
6923
  const pointsStr = smtPad.points.map((p) => `{x: "${mmStr(p.x)}", y: "${mmStr(p.y)}"}`).join(", ");
@@ -7089,6 +7153,7 @@ var convertBetterEasyToTsx = async ({
7089
7153
  cadPositionXMm: cadPlacement?.positionXMm,
7090
7154
  cadPositionYMm: cadPlacement?.positionYMm,
7091
7155
  cadPositionZMm: cadPlacement?.positionZMm,
7156
+ cadModelBounds: cadPlacement?.bounds,
7092
7157
  showDesignator: true
7093
7158
  });
7094
7159
  const [cadComponent] = su(circuitJson).cad_component.list();