@tscircuit/3d-viewer 0.0.490 → 0.0.491

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 +124 -141
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -12269,7 +12269,7 @@ var require_expand = __commonJS({
12269
12269
  var expandGeom2 = require_expandGeom2();
12270
12270
  var expandGeom3 = require_expandGeom3();
12271
12271
  var expandPath2 = require_expandPath2();
12272
- var expand3 = (options, ...objects) => {
12272
+ var expand2 = (options, ...objects) => {
12273
12273
  objects = flatten(objects);
12274
12274
  if (objects.length === 0) throw new Error("wrong number of arguments");
12275
12275
  const results = objects.map((object) => {
@@ -12280,7 +12280,7 @@ var require_expand = __commonJS({
12280
12280
  });
12281
12281
  return results.length === 1 ? results[0] : results;
12282
12282
  };
12283
- module.exports = expand3;
12283
+ module.exports = expand2;
12284
12284
  }
12285
12285
  });
12286
12286
 
@@ -12478,7 +12478,7 @@ var require_extrudeRectangularPath2 = __commonJS({
12478
12478
  "node_modules/@jscad/modeling/src/operations/extrusions/extrudeRectangularPath2.js"(exports, module) {
12479
12479
  "use strict";
12480
12480
  var path2 = require_path2();
12481
- var expand3 = require_expand();
12481
+ var expand2 = require_expand();
12482
12482
  var extrudeLinearGeom2 = require_extrudeLinearGeom2();
12483
12483
  var extrudeRectangularPath2 = (options, geometry) => {
12484
12484
  const defaults = {
@@ -12490,7 +12490,7 @@ var require_extrudeRectangularPath2 = __commonJS({
12490
12490
  options.offset = [0, 0, height10];
12491
12491
  const points = path2.toPoints(geometry);
12492
12492
  if (points.length === 0) throw new Error("the given geometry cannot be empty");
12493
- const newgeometry = expand3(options, geometry);
12493
+ const newgeometry = expand2(options, geometry);
12494
12494
  return extrudeLinearGeom2(options, newgeometry);
12495
12495
  };
12496
12496
  module.exports = extrudeRectangularPath2;
@@ -12504,7 +12504,7 @@ var require_extrudeRectangularGeom2 = __commonJS({
12504
12504
  var { area } = require_utils();
12505
12505
  var geom2 = require_geom2();
12506
12506
  var path2 = require_path2();
12507
- var expand3 = require_expand();
12507
+ var expand2 = require_expand();
12508
12508
  var extrudeLinearGeom2 = require_extrudeLinearGeom2();
12509
12509
  var extrudeRectangularGeom2 = (options, geometry) => {
12510
12510
  const defaults = {
@@ -12518,7 +12518,7 @@ var require_extrudeRectangularGeom2 = __commonJS({
12518
12518
  if (outlines.length === 0) throw new Error("the given geometry cannot be empty");
12519
12519
  const newparts = outlines.map((outline) => {
12520
12520
  if (area(outline) < 0) outline.reverse();
12521
- return expand3(options, path2.fromPoints({ closed: true }, outline));
12521
+ return expand2(options, path2.fromPoints({ closed: true }, outline));
12522
12522
  });
12523
12523
  const allsides = newparts.reduce((sides2, part) => sides2.concat(geom2.toSides(part)), []);
12524
12524
  const newgeometry = geom2.create(allsides);
@@ -30825,7 +30825,7 @@ import * as THREE16 from "three";
30825
30825
  // package.json
30826
30826
  var package_default = {
30827
30827
  name: "@tscircuit/3d-viewer",
30828
- version: "0.0.489",
30828
+ version: "0.0.490",
30829
30829
  main: "./dist/index.js",
30830
30830
  module: "./dist/index.js",
30831
30831
  type: "module",
@@ -32705,7 +32705,6 @@ var platedHole = (plated_hole, ctx, options = {}) => {
32705
32705
 
32706
32706
  // src/BoardGeomBuilder.ts
32707
32707
  var import_extrusions4 = __toESM(require_extrusions(), 1);
32708
- var import_expansions2 = __toESM(require_expansions(), 1);
32709
32708
 
32710
32709
  // src/geoms/brep-converter.ts
32711
32710
  var import_primitives5 = __toESM(require_primitives(), 1);
@@ -33353,95 +33352,68 @@ var BoardGeomBuilder = class {
33353
33352
  this.platedHoleGeoms = this.platedHoleGeoms.map(
33354
33353
  (phg) => (0, import_colors3.colorize)(colors.copper, (0, import_booleans5.subtract)(phg, copperCut))
33355
33354
  );
33356
- } else if (hole.hole_shape === "pill" || hole.hole_shape === "rotated_pill") {
33357
- const holeWidth = hole.hole_width;
33358
- const holeHeight = hole.hole_height;
33359
- const holeRadius = Math.min(holeWidth, holeHeight) / 2;
33360
- const rectLength = Math.abs(holeWidth - holeHeight);
33361
- const isRotated = hole.hole_shape === "rotated_pill";
33362
- let pillHole;
33363
- if (holeWidth > holeHeight) {
33364
- pillHole = (0, import_booleans5.union)(
33365
- (0, import_primitives7.cuboid)({
33366
- center: [hole.x, hole.y, 0],
33367
- size: [rectLength, holeHeight, holeDepth]
33368
- }),
33369
- (0, import_primitives7.cylinder)({
33370
- center: [hole.x - rectLength / 2, hole.y, 0],
33371
- radius: holeRadius,
33372
- height: holeDepth
33373
- }),
33374
- (0, import_primitives7.cylinder)({
33375
- center: [hole.x + rectLength / 2, hole.y, 0],
33376
- radius: holeRadius,
33377
- height: holeDepth
33378
- })
33355
+ } else if (hole.hole_shape === "pill" || hole.hole_shape === "rotated_pill" || hole.hole_shape === "oval") {
33356
+ const holeWidth = hole.hole_width ?? hole.hole_diameter;
33357
+ const holeHeight = hole.hole_height ?? hole.hole_diameter;
33358
+ const rotation2 = hole.ccw_rotation ?? hole.rotation ?? 0;
33359
+ const copperInset2 = 0.02;
33360
+ const createHoleGeom = (w, h2, depth, isOval) => {
33361
+ if (w <= 0 || h2 <= 0) return null;
33362
+ if (isOval) {
33363
+ return (0, import_transforms6.translate)(
33364
+ [0, 0, -depth / 2],
33365
+ (0, import_extrusions4.extrudeLinear)(
33366
+ { height: depth },
33367
+ (0, import_primitives7.ellipse)({ radius: [w / 2, h2 / 2] })
33368
+ )
33369
+ );
33370
+ }
33371
+ const radius = Math.min(w, h2) / 2;
33372
+ const length2 = Math.abs(w - h2);
33373
+ if (w > h2) {
33374
+ return (0, import_booleans5.union)(
33375
+ (0, import_primitives7.cuboid)({ center: [0, 0, 0], size: [length2, h2, depth] }),
33376
+ (0, import_primitives7.cylinder)({ center: [-length2 / 2, 0, 0], radius, height: depth }),
33377
+ (0, import_primitives7.cylinder)({ center: [length2 / 2, 0, 0], radius, height: depth })
33378
+ );
33379
+ }
33380
+ return (0, import_booleans5.union)(
33381
+ (0, import_primitives7.cuboid)({ center: [0, 0, 0], size: [w, length2, depth] }),
33382
+ (0, import_primitives7.cylinder)({ center: [0, -length2 / 2, 0], radius, height: depth }),
33383
+ (0, import_primitives7.cylinder)({ center: [0, length2 / 2, 0], radius, height: depth })
33379
33384
  );
33380
- } else {
33381
- pillHole = (0, import_booleans5.union)(
33382
- (0, import_primitives7.cuboid)({
33383
- center: [hole.x, hole.y, 0],
33384
- size: [holeWidth, rectLength, holeDepth]
33385
- }),
33386
- (0, import_primitives7.cylinder)({
33387
- center: [hole.x, hole.y - rectLength / 2, 0],
33388
- radius: holeRadius,
33389
- height: holeDepth
33390
- }),
33391
- (0, import_primitives7.cylinder)({
33392
- center: [hole.x, hole.y + rectLength / 2, 0],
33393
- radius: holeRadius,
33394
- height: holeDepth
33395
- })
33385
+ };
33386
+ let boardHole = createHoleGeom(
33387
+ holeWidth,
33388
+ holeHeight,
33389
+ holeDepth,
33390
+ hole.hole_shape === "oval"
33391
+ );
33392
+ let copperCut = createHoleGeom(
33393
+ holeWidth - 2 * copperInset2,
33394
+ holeHeight - 2 * copperInset2,
33395
+ holeDepth,
33396
+ hole.hole_shape === "oval"
33397
+ );
33398
+ if (boardHole && rotation2 !== 0) {
33399
+ boardHole = (0, import_transforms6.rotateZ)(rotation2 * Math.PI / 180, boardHole);
33400
+ }
33401
+ if (copperCut && rotation2 !== 0) {
33402
+ copperCut = (0, import_transforms6.rotateZ)(rotation2 * Math.PI / 180, copperCut);
33403
+ }
33404
+ if (boardHole) {
33405
+ const positionedBoardHole = (0, import_transforms6.translate)([hole.x, hole.y, 0], boardHole);
33406
+ this.boardGeom = (0, import_booleans5.subtract)(this.boardGeom, positionedBoardHole);
33407
+ this.padGeoms = this.padGeoms.map(
33408
+ (pg) => (0, import_colors3.colorize)(colors.copper, (0, import_booleans5.subtract)(pg, positionedBoardHole))
33396
33409
  );
33397
33410
  }
33398
- if (isRotated) {
33399
- const rotationRadians = hole.ccw_rotation * Math.PI / 180;
33400
- pillHole = (0, import_transforms6.rotateZ)(rotationRadians, pillHole);
33411
+ if (copperCut) {
33412
+ const positionedCopperCut = (0, import_transforms6.translate)([hole.x, hole.y, 0], copperCut);
33413
+ this.platedHoleGeoms = this.platedHoleGeoms.map(
33414
+ (phg) => (0, import_colors3.colorize)(colors.copper, (0, import_booleans5.subtract)(phg, positionedCopperCut))
33415
+ );
33401
33416
  }
33402
- this.boardGeom = (0, import_booleans5.subtract)(this.boardGeom, pillHole);
33403
- this.padGeoms = this.padGeoms.map(
33404
- (pg) => (0, import_colors3.colorize)(colors.copper, (0, import_booleans5.subtract)(pg, pillHole))
33405
- );
33406
- const copperPill = (0, import_expansions2.expand)({ delta: -copperInset }, pillHole);
33407
- this.platedHoleGeoms = this.platedHoleGeoms.map(
33408
- (phg) => (0, import_colors3.colorize)(colors.copper, (0, import_booleans5.subtract)(phg, copperPill))
33409
- );
33410
- } else if (hole.hole_shape === "oval") {
33411
- const holeWidth = hole.hole_width;
33412
- const holeHeight = hole.hole_height;
33413
- const ellipseGeom = (0, import_transforms6.translate)(
33414
- [hole.x, hole.y, 0],
33415
- (0, import_transforms6.translate)(
33416
- [0, 0, -holeDepth / 2],
33417
- (0, import_extrusions4.extrudeLinear)(
33418
- { height: holeDepth },
33419
- (0, import_primitives7.ellipse)({ radius: [holeWidth / 2, holeHeight / 2] })
33420
- )
33421
- )
33422
- );
33423
- this.boardGeom = (0, import_booleans5.subtract)(this.boardGeom, ellipseGeom);
33424
- this.padGeoms = this.padGeoms.map(
33425
- (pg) => (0, import_colors3.colorize)(colors.copper, (0, import_booleans5.subtract)(pg, ellipseGeom))
33426
- );
33427
- const copperEllipseGeom = (0, import_transforms6.translate)(
33428
- [hole.x, hole.y, 0],
33429
- (0, import_transforms6.translate)(
33430
- [0, 0, -holeDepth / 2],
33431
- (0, import_extrusions4.extrudeLinear)(
33432
- { height: holeDepth },
33433
- (0, import_primitives7.ellipse)({
33434
- radius: [
33435
- holeWidth / 2 - copperInset,
33436
- holeHeight / 2 - copperInset
33437
- ]
33438
- })
33439
- )
33440
- )
33441
- );
33442
- this.platedHoleGeoms = this.platedHoleGeoms.map(
33443
- (phg) => (0, import_colors3.colorize)(colors.copper, (0, import_booleans5.subtract)(phg, copperEllipseGeom))
33444
- );
33445
33417
  }
33446
33418
  }
33447
33419
  processPad(pad2) {
@@ -36344,16 +36316,7 @@ function createPlatedHoleDrill({
36344
36316
  }
36345
36317
 
36346
36318
  // src/utils/manifold/process-non-plated-holes.ts
36347
- function isCircleHole(hole) {
36348
- return hole.hole_shape === "circle" && typeof hole.hole_diameter === "number";
36349
- }
36350
- function isPillHole(hole) {
36351
- return hole.hole_shape === "pill" && typeof hole.hole_width === "number" && typeof hole.hole_height === "number";
36352
- }
36353
- function isRotatedPillHole(hole) {
36354
- return hole.hole_shape === "rotated_pill" && typeof hole.hole_width === "number" && typeof hole.hole_height === "number" && typeof hole.ccw_rotation === "number";
36355
- }
36356
- function processNonPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup) {
36319
+ function processNonPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbThickness, manifoldInstancesForCleanup) {
36357
36320
  const nonPlatedHoleBoardDrills = [];
36358
36321
  const pcbHoles = su14(circuitJson).pcb_hole.list();
36359
36322
  const createPillOp = (width10, height10, depth) => {
@@ -36367,52 +36330,71 @@ function processNonPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, m
36367
36330
  manifoldInstancesForCleanup.push(pillOp);
36368
36331
  return pillOp;
36369
36332
  };
36333
+ const createEllipsePoints2 = (w, h2, segments) => {
36334
+ const points = [];
36335
+ for (let i = 0; i < segments; i++) {
36336
+ const theta = 2 * Math.PI * i / segments;
36337
+ points.push([w / 2 * Math.cos(theta), h2 / 2 * Math.sin(theta)]);
36338
+ }
36339
+ return points;
36340
+ };
36370
36341
  pcbHoles.forEach((hole) => {
36371
- if (isCircleHole(hole)) {
36372
- const translatedDrill = createCircleHoleDrill({
36342
+ const holeShape = hole.hole_shape;
36343
+ const holeX = hole.x;
36344
+ const holeY = hole.y;
36345
+ const drillDepth = pcbThickness * 1.2;
36346
+ const rotation2 = hole.ccw_rotation ?? hole.rotation ?? 0;
36347
+ const holeW = hole.hole_width ?? hole.hole_diameter;
36348
+ const holeH = hole.hole_height ?? hole.hole_diameter;
36349
+ let holeOp = null;
36350
+ if (holeShape === "circle") {
36351
+ holeOp = createCircleHoleDrill({
36373
36352
  Manifold,
36374
- x: hole.x,
36375
- y: hole.y,
36353
+ x: holeX,
36354
+ y: holeY,
36376
36355
  diameter: hole.hole_diameter,
36377
36356
  thickness: pcbThickness,
36378
36357
  segments: SMOOTH_CIRCLE_SEGMENTS
36379
36358
  });
36380
- manifoldInstancesForCleanup.push(translatedDrill);
36381
- nonPlatedHoleBoardDrills.push(translatedDrill);
36382
- } else if (isPillHole(hole)) {
36383
- const holeW = hole.hole_width;
36384
- const holeH = hole.hole_height;
36385
- const drillDepth = pcbThickness * 1.2;
36386
- const pillDrillOp = createPillOp(holeW, holeH, drillDepth);
36387
- const translatedPillDrill = pillDrillOp.translate([hole.x, hole.y, 0]);
36388
- manifoldInstancesForCleanup.push(translatedPillDrill);
36389
- nonPlatedHoleBoardDrills.push(translatedPillDrill);
36390
- } else if (isRotatedPillHole(hole)) {
36391
- const holeW = hole.hole_width;
36392
- const holeH = hole.hole_height;
36393
- const drillDepth = pcbThickness * 1.2;
36394
- let pillDrillOp = createPillOp(holeW, holeH, drillDepth);
36395
- const rotatedOp = pillDrillOp.rotate([0, 0, hole.ccw_rotation]);
36396
- manifoldInstancesForCleanup.push(rotatedOp);
36397
- pillDrillOp = rotatedOp;
36398
- const translatedPillDrill = pillDrillOp.translate([hole.x, hole.y, 0]);
36399
- manifoldInstancesForCleanup.push(translatedPillDrill);
36400
- nonPlatedHoleBoardDrills.push(translatedPillDrill);
36401
- } else if (hole.hole_shape === "oval") {
36402
- const holeW = hole.hole_width;
36403
- const holeH = hole.hole_height;
36404
- const drillDepth = pcbThickness * 1.2;
36405
- const ovalDrillOp = Manifold.cylinder(
36359
+ nonPlatedHoleBoardDrills.push(holeOp);
36360
+ manifoldInstancesForCleanup.push(holeOp);
36361
+ return;
36362
+ }
36363
+ if (holeShape === "pill" || holeShape === "rotated_pill") {
36364
+ holeOp = createPillOp(holeW, holeH, drillDepth);
36365
+ } else if (holeShape === "oval") {
36366
+ let points = createEllipsePoints2(holeW, holeH, SMOOTH_CIRCLE_SEGMENTS);
36367
+ let area = 0;
36368
+ for (let i = 0; i < points.length; i++) {
36369
+ const j = (i + 1) % points.length;
36370
+ area += points[i][0] * points[j][1];
36371
+ area -= points[j][0] * points[i][1];
36372
+ }
36373
+ if (area <= 0) {
36374
+ points = points.reverse();
36375
+ }
36376
+ const crossSection = CrossSection.ofPolygons([points]);
36377
+ manifoldInstancesForCleanup.push(crossSection);
36378
+ holeOp = Manifold.extrude(
36379
+ crossSection,
36406
36380
  drillDepth,
36407
- 1,
36408
- 1,
36409
- SMOOTH_CIRCLE_SEGMENTS,
36381
+ 0,
36382
+ 0,
36383
+ [1, 1],
36410
36384
  true
36411
- ).scale([holeW / 2, holeH / 2, 1]);
36412
- manifoldInstancesForCleanup.push(ovalDrillOp);
36413
- const translatedOvalDrill = ovalDrillOp.translate([hole.x, hole.y, 0]);
36414
- manifoldInstancesForCleanup.push(translatedOvalDrill);
36415
- nonPlatedHoleBoardDrills.push(translatedOvalDrill);
36385
+ // center
36386
+ );
36387
+ manifoldInstancesForCleanup.push(holeOp);
36388
+ }
36389
+ if (holeOp) {
36390
+ if (rotation2 !== 0) {
36391
+ const rotatedOp = holeOp.rotate([0, 0, rotation2]);
36392
+ manifoldInstancesForCleanup.push(rotatedOp);
36393
+ holeOp = rotatedOp;
36394
+ }
36395
+ const translatedHole = holeOp.translate([holeX, holeY, 0]);
36396
+ manifoldInstancesForCleanup.push(translatedHole);
36397
+ nonPlatedHoleBoardDrills.push(translatedHole);
36416
36398
  }
36417
36399
  });
36418
36400
  return { nonPlatedHoleBoardDrills };
@@ -37712,6 +37694,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
37712
37694
  let holeUnion = null;
37713
37695
  const { nonPlatedHoleBoardDrills } = processNonPlatedHolesForManifold(
37714
37696
  Manifold,
37697
+ CrossSection,
37715
37698
  circuitJson,
37716
37699
  currentPcbThickness,
37717
37700
  manifoldInstancesForCleanup.current
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/3d-viewer",
3
- "version": "0.0.490",
3
+ "version": "0.0.491",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",