jscad-electronics 0.0.210 → 0.0.212

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/vanilla.js CHANGED
@@ -179,28 +179,28 @@ var FootprintPlatedHole = ({
179
179
  throw new Error("Shape not supported: " + hole.shape);
180
180
  };
181
181
 
182
- // lib/models/buttonscrew/register.tsx
183
- import { buttonScrewModelDefinitionSchema } from "@tscircuit/modelprinter";
182
+ // lib/models/ballbearing/register.tsx
183
+ import { ballBearingModelDefinitionSchema } from "@tscircuit/modelprinter";
184
184
 
185
185
  // lib/model-registry.ts
186
- function defineModelRenderer(model24) {
187
- return model24;
186
+ function defineModelRenderer(model26) {
187
+ return model26;
188
188
  }
189
189
  var ModelRendererRegistry = class {
190
190
  models = /* @__PURE__ */ new Map();
191
- register(model24) {
192
- if (typeof model24.name !== "string" || !/^[a-z]+$/.test(model24.name)) {
191
+ register(model26) {
192
+ if (typeof model26.name !== "string" || !/^[a-z]+$/.test(model26.name)) {
193
193
  throw new Error(
194
194
  "Model renderer names must contain only lowercase letters"
195
195
  );
196
196
  }
197
- if (this.models.has(model24.name)) {
198
- throw new Error(`Model renderer "${model24.name}" is already registered`);
197
+ if (this.models.has(model26.name)) {
198
+ throw new Error(`Model renderer "${model26.name}" is already registered`);
199
199
  }
200
- if (model24.pads !== "none" && model24.pads !== "footprinter") {
200
+ if (model26.pads !== "none" && model26.pads !== "footprinter") {
201
201
  throw new Error('Model renderer pads must be "none" or "footprinter"');
202
202
  }
203
- const { name, schema, render: render2, pads } = model24;
203
+ const { name, schema, render: render2, pads } = model26;
204
204
  this.models.set(name, {
205
205
  name,
206
206
  schema,
@@ -226,6 +226,287 @@ var ModelRendererRegistry = class {
226
226
  }
227
227
  };
228
228
 
229
+ // lib/mechanical/indexedMeshToGeom3.ts
230
+ import jscad from "@jscad/modeling";
231
+ function indexedMeshToGeom3(mesh) {
232
+ const polygons = [];
233
+ for (let i = 0; i < mesh.indices.length; i += 3)
234
+ polygons.push(
235
+ mesh.indices.slice(i, i + 3).map((index) => [
236
+ mesh.positions[index * 3],
237
+ mesh.positions[index * 3 + 1],
238
+ mesh.positions[index * 3 + 2]
239
+ ])
240
+ );
241
+ return jscad.geometries.geom3.fromPoints(polygons);
242
+ }
243
+
244
+ // lib/models/ballbearing/mesh.ts
245
+ import {
246
+ getBallBearingDimensions
247
+ } from "@tscircuit/modelprinter";
248
+ function createBallBearingMesh(input = {}, options = {}) {
249
+ const d = getBallBearingDimensions(input);
250
+ const segments = segmentsFor(options.segments);
251
+ checkPrecision([
252
+ d.outerDiameter,
253
+ d.boreRadius,
254
+ d.width,
255
+ d.outerRadius - d.boreRadius,
256
+ d.ballRadius
257
+ ]);
258
+ const c = d.rimChamfer, mid = d.midZ, half = d.grooveHalfWidth;
259
+ const innerProfile = [
260
+ [d.innerRaceOuterRadius - c, 0],
261
+ [d.innerRaceOuterRadius, c]
262
+ ];
263
+ for (let i = 0; i <= 24; i++) {
264
+ const z = mid - half + 2 * half * i / 24;
265
+ innerProfile.push([
266
+ d.pitchRadius - Math.sqrt(Math.max(0, d.grooveRadius ** 2 - (z - mid) ** 2)),
267
+ z
268
+ ]);
269
+ }
270
+ innerProfile.push(
271
+ [d.innerRaceOuterRadius, d.width - c],
272
+ [d.innerRaceOuterRadius - c, d.width],
273
+ [d.boreRadius + c, d.width],
274
+ [d.boreRadius, d.width - c],
275
+ [d.boreRadius, c],
276
+ [d.boreRadius + c, 0]
277
+ );
278
+ const outerProfile = [
279
+ [d.outerRadius - c, 0],
280
+ [d.outerRadius, c],
281
+ [d.outerRadius, d.width - c],
282
+ [d.outerRadius - c, d.width],
283
+ [d.outerRaceInnerRadius + c, d.width],
284
+ [d.outerRaceInnerRadius, d.width - c]
285
+ ];
286
+ for (let i = 0; i <= 24; i++) {
287
+ const z = mid + half - 2 * half * i / 24;
288
+ outerProfile.push([
289
+ d.pitchRadius + Math.sqrt(Math.max(0, d.grooveRadius ** 2 - (z - mid) ** 2)),
290
+ z
291
+ ]);
292
+ }
293
+ outerProfile.push(
294
+ [d.outerRaceInnerRadius, c],
295
+ [d.outerRaceInnerRadius + c, 0]
296
+ );
297
+ const parts = [
298
+ {
299
+ name: "inner race",
300
+ color: "#9da4ac",
301
+ mesh: revolve(innerProfile, segments)
302
+ },
303
+ {
304
+ name: "outer race",
305
+ color: "#9da4ac",
306
+ mesh: revolve(outerProfile, segments)
307
+ }
308
+ ];
309
+ for (let i = 0; i < d.ballCount; i++) {
310
+ const phase = i * Math.PI * 2 / d.ballCount;
311
+ const center = [
312
+ d.pitchRadius * Math.cos(phase),
313
+ d.pitchRadius * Math.sin(phase),
314
+ mid
315
+ ];
316
+ parts.push({
317
+ name: `ball ${i + 1}`,
318
+ color: "#d5d9df",
319
+ mesh: sphere(center, d.ballRadius),
320
+ center,
321
+ radius: d.ballRadius
322
+ });
323
+ const separator = (i + 0.5) * Math.PI * 2 / d.ballCount;
324
+ parts.push({
325
+ name: `cage separator ${i + 1}`,
326
+ color: "#b89b58",
327
+ mesh: annularSector(
328
+ d.cageInnerRadius,
329
+ d.cageOuterRadius,
330
+ mid - 1.1 * d.ballRadius,
331
+ mid + 1.1 * d.ballRadius,
332
+ separator - d.cageSeparatorHalfAngle,
333
+ separator + d.cageSeparatorHalfAngle,
334
+ segments
335
+ )
336
+ });
337
+ }
338
+ for (const sign of [-1, 1]) {
339
+ const z0 = mid + (sign === -1 ? -1.25 : 1.1) * d.ballRadius;
340
+ const z1 = mid + (sign === -1 ? -1.1 : 1.25) * d.ballRadius;
341
+ parts.push({
342
+ name: `cage ${sign < 0 ? "lower" : "upper"} band`,
343
+ color: "#b89b58",
344
+ mesh: revolve(
345
+ [
346
+ [d.cageOuterRadius, z0],
347
+ [d.cageOuterRadius, z1],
348
+ [d.cageInnerRadius, z1],
349
+ [d.cageInnerRadius, z0]
350
+ ],
351
+ segments
352
+ )
353
+ });
354
+ }
355
+ for (const sign of [-1, 1]) {
356
+ const face2 = sign < 0 ? d.bottomSideShielded ? "shielded" : d.bottomSideSealed ? "sealed" : "open" : d.topSideShielded ? "shielded" : d.topSideSealed ? "sealed" : "open";
357
+ if (face2 === "open") continue;
358
+ const t = d.closureThickness;
359
+ const ri = d.innerRaceOuterRadius, ro = d.outerRaceInnerRadius;
360
+ const shape = face2 === "shielded" ? [
361
+ [ro, 0],
362
+ [ro, t * 0.45],
363
+ [ri, t * 0.45],
364
+ [ri, 0]
365
+ ] : [
366
+ [ro, 0],
367
+ [ro, t],
368
+ [ri, t],
369
+ [ri, 0],
370
+ [ri + 0.15 * (ro - ri), 0.5 * t],
371
+ [ro - 0.15 * (ro - ri), 0.5 * t]
372
+ ];
373
+ const profile = sign === -1 ? shape : shape.map(([r, z]) => [r, d.width - z]).reverse();
374
+ parts.push({
375
+ name: `${face2} ${sign < 0 ? "lower" : "upper"}`,
376
+ color: face2 === "sealed" ? "#252a30" : "#b5bbc3",
377
+ mesh: revolve(profile, segments)
378
+ });
379
+ }
380
+ return { ...combine(parts), parts };
381
+ }
382
+ function segmentsFor(value = 96) {
383
+ if (!Number.isInteger(value) || value < 96 || value > 192 || value % 24 !== 0)
384
+ throw new Error("Segments must be a multiple of 24 from 96 to 192");
385
+ return value;
386
+ }
387
+ function checkPrecision(lengths) {
388
+ const largest = Math.max(...lengths);
389
+ if (!lengths.every(Number.isFinite) || largest > 1e6 || Math.min(...lengths) < Math.max(1e-5, largest * 1e-7))
390
+ throw new Error(
391
+ "Bearing dimensions exceed the renderer's numerical resolution"
392
+ );
393
+ }
394
+ function revolve(profile, segments) {
395
+ const positions = [];
396
+ const indices = [];
397
+ for (const [radius, z] of profile)
398
+ for (let i = 0; i < segments; i++) {
399
+ const angle = i * Math.PI * 2 / segments;
400
+ const r = typeof radius === "number" ? radius : radius(angle);
401
+ positions.push(r * Math.cos(angle), r * Math.sin(angle), z);
402
+ }
403
+ for (let j = 0; j < profile.length; j++)
404
+ for (let i = 0; i < segments; i++) {
405
+ const a = j * segments + i;
406
+ const b = j * segments + (i + 1) % segments;
407
+ const c = (j + 1) % profile.length * segments + (i + 1) % segments;
408
+ const e = (j + 1) % profile.length * segments + i;
409
+ indices.push(a, b, c, a, c, e);
410
+ }
411
+ return { positions, indices };
412
+ }
413
+ function annularSector(inner, outer, z0, z1, start, end, segments) {
414
+ const steps = Math.max(
415
+ 2,
416
+ Math.ceil((end - start) / (2 * Math.PI) * segments)
417
+ );
418
+ const count = steps + 1;
419
+ const profile = [
420
+ [outer, z0],
421
+ [outer, z1],
422
+ [inner, z1],
423
+ [inner, z0]
424
+ ];
425
+ const positions = [];
426
+ const indices = [];
427
+ for (const [r, z] of profile)
428
+ for (let i = 0; i <= steps; i++) {
429
+ const angle = start + (end - start) * i / steps;
430
+ positions.push(r * Math.cos(angle), r * Math.sin(angle), z);
431
+ }
432
+ for (let j = 0; j < 4; j++)
433
+ for (let i = 0; i < steps; i++) {
434
+ const a2 = j * count + i;
435
+ const b2 = a2 + 1;
436
+ const c2 = (j + 1) % 4 * count + i + 1;
437
+ const e2 = (j + 1) % 4 * count + i;
438
+ indices.push(a2, b2, c2, a2, c2, e2);
439
+ }
440
+ indices.push(0, count, 2 * count, 0, 2 * count, 3 * count);
441
+ const a = steps, b = count + steps, c = 2 * count + steps, e = 3 * count + steps;
442
+ indices.push(a, c, b, a, e, c);
443
+ return { positions, indices };
444
+ }
445
+ function sphere(center, radius) {
446
+ const longitude = 24;
447
+ const latitude = 12;
448
+ const positions = [center[0], center[1], center[2] + radius];
449
+ const indices = [];
450
+ for (let j = 1; j < latitude; j++) {
451
+ const polar = j * Math.PI / latitude;
452
+ for (let i = 0; i < longitude; i++) {
453
+ const azimuth = i * Math.PI * 2 / longitude;
454
+ positions.push(
455
+ center[0] + radius * Math.sin(polar) * Math.cos(azimuth),
456
+ center[1] + radius * Math.sin(polar) * Math.sin(azimuth),
457
+ center[2] + radius * Math.cos(polar)
458
+ );
459
+ }
460
+ }
461
+ const south = positions.length / 3;
462
+ positions.push(center[0], center[1], center[2] - radius);
463
+ for (let i = 0; i < longitude; i++) {
464
+ const next = (i + 1) % longitude;
465
+ indices.push(0, 1 + i, 1 + next);
466
+ for (let j = 0; j < latitude - 2; j++) {
467
+ const a = 1 + j * longitude + i, b = 1 + (j + 1) * longitude + i;
468
+ const c = 1 + (j + 1) * longitude + next, e = 1 + j * longitude + next;
469
+ indices.push(a, b, c, a, c, e);
470
+ }
471
+ const last = 1 + (latitude - 2) * longitude;
472
+ indices.push(south, last + next, last + i);
473
+ }
474
+ return { positions, indices };
475
+ }
476
+ function combine(parts) {
477
+ const positions = [];
478
+ const indices = [];
479
+ for (const { mesh } of parts) {
480
+ const offset = positions.length / 3;
481
+ positions.push(...mesh.positions);
482
+ indices.push(...mesh.indices.map((index) => index + offset));
483
+ }
484
+ return { positions, indices };
485
+ }
486
+
487
+ // lib/models/ballbearing/BallBearing.tsx
488
+ function createBallBearingGeom(input = {}) {
489
+ return indexedMeshToGeom3(createBallBearingMesh(input));
490
+ }
491
+ function BallBearing({ color, ...props }) {
492
+ const { parts } = createBallBearingMesh(props);
493
+ return /* @__PURE__ */ jsx(Fragment2, { children: parts.map((part) => /* @__PURE__ */ jsx(Colorize, { color: color ?? part.color, children: /* @__PURE__ */ jsx(Custom, { geometry: indexedMeshToGeom3(part.mesh) }) }, part.name)) });
494
+ }
495
+
496
+ // lib/models/ballbearing/register.tsx
497
+ var model = defineModelRenderer({
498
+ name: "ballbearing",
499
+ schema: ballBearingModelDefinitionSchema,
500
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(BallBearing, { ...props }),
501
+ pads: "none"
502
+ });
503
+ function register(registry) {
504
+ registry.register(model);
505
+ }
506
+
507
+ // lib/models/buttonscrew/register.tsx
508
+ import { buttonScrewModelDefinitionSchema } from "@tscircuit/modelprinter";
509
+
229
510
  // lib/models/buttonscrew/mesh.ts
230
511
  import {
231
512
  buttonScrewModelPropsSchema,
@@ -338,21 +619,6 @@ function createButtonScrewMesh(input, options = {}) {
338
619
  return { positions: m.positions, indices: m.indices };
339
620
  }
340
621
 
341
- // lib/mechanical/indexedMeshToGeom3.ts
342
- import jscad from "@jscad/modeling";
343
- function indexedMeshToGeom3(mesh) {
344
- const polygons = [];
345
- for (let i = 0; i < mesh.indices.length; i += 3)
346
- polygons.push(
347
- mesh.indices.slice(i, i + 3).map((index) => [
348
- mesh.positions[index * 3],
349
- mesh.positions[index * 3 + 1],
350
- mesh.positions[index * 3 + 2]
351
- ])
352
- );
353
- return jscad.geometries.geom3.fromPoints(polygons);
354
- }
355
-
356
622
  // lib/models/buttonscrew/ButtonScrew.tsx
357
623
  function createButtonScrewGeom(input, resolution4) {
358
624
  return indexedMeshToGeom3(createButtonScrewMesh(input, resolution4));
@@ -362,14 +628,14 @@ function ButtonScrew({ color = "#737e8f", ...props }) {
362
628
  }
363
629
 
364
630
  // lib/models/buttonscrew/register.tsx
365
- var model = defineModelRenderer({
631
+ var model2 = defineModelRenderer({
366
632
  name: "buttonscrew",
367
633
  schema: buttonScrewModelDefinitionSchema,
368
634
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ButtonScrew, { ...props }),
369
635
  pads: "none"
370
636
  });
371
- function register(registry) {
372
- registry.register(model);
637
+ function register2(registry) {
638
+ registry.register(model2);
373
639
  }
374
640
 
375
641
  // lib/models/cablegrommet/register.tsx
@@ -444,14 +710,14 @@ function CableGrommet({
444
710
  }
445
711
 
446
712
  // lib/models/cablegrommet/register.tsx
447
- var model2 = defineModelRenderer({
713
+ var model3 = defineModelRenderer({
448
714
  name: "cablegrommet",
449
715
  schema: cableGrommetModelDefinitionSchema,
450
716
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(CableGrommet, { ...props }),
451
717
  pads: "none"
452
718
  });
453
- function register2(registry) {
454
- registry.register(model2);
719
+ function register3(registry) {
720
+ registry.register(model3);
455
721
  }
456
722
 
457
723
  // lib/models/clampingshaftcollar/register.tsx
@@ -752,14 +1018,14 @@ function ClampingShaftCollar({
752
1018
  }
753
1019
 
754
1020
  // lib/models/clampingshaftcollar/register.tsx
755
- var model3 = defineModelRenderer({
1021
+ var model4 = defineModelRenderer({
756
1022
  name: "clampingshaftcollar",
757
1023
  schema: clampingShaftCollarModelDefinitionSchema,
758
1024
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ClampingShaftCollar, { ...props }),
759
1025
  pads: "none"
760
1026
  });
761
- function register3(registry) {
762
- registry.register(model3);
1027
+ function register4(registry) {
1028
+ registry.register(model4);
763
1029
  }
764
1030
 
765
1031
  // lib/models/compressionspring/register.tsx
@@ -965,14 +1231,14 @@ function CompressionSpring({
965
1231
  }
966
1232
 
967
1233
  // lib/models/compressionspring/register.tsx
968
- var model4 = defineModelRenderer({
1234
+ var model5 = defineModelRenderer({
969
1235
  name: "compressionspring",
970
1236
  schema: compressionSpringModelDefinitionSchema,
971
1237
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(CompressionSpring, { ...props }),
972
1238
  pads: "none"
973
1239
  });
974
- function register4(registry) {
975
- registry.register(model4);
1240
+ function register5(registry) {
1241
+ registry.register(model5);
976
1242
  }
977
1243
 
978
1244
  // lib/models/flangedbushing/register.tsx
@@ -1028,14 +1294,14 @@ function FlangedBushing({
1028
1294
  }
1029
1295
 
1030
1296
  // lib/models/flangedbushing/register.tsx
1031
- var model5 = defineModelRenderer({
1297
+ var model6 = defineModelRenderer({
1032
1298
  name: "flangedbushing",
1033
1299
  schema: flangedBushingModelDefinitionSchema,
1034
1300
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlangedBushing, { ...props }),
1035
1301
  pads: "none"
1036
1302
  });
1037
- function register5(registry) {
1038
- registry.register(model5);
1303
+ function register6(registry) {
1304
+ registry.register(model6);
1039
1305
  }
1040
1306
 
1041
1307
  // lib/models/flatheadscrew/register.tsx
@@ -1168,14 +1434,14 @@ function FlatHeadScrew({
1168
1434
  }
1169
1435
 
1170
1436
  // lib/models/flatheadscrew/register.tsx
1171
- var model6 = defineModelRenderer({
1437
+ var model7 = defineModelRenderer({
1172
1438
  name: "flatheadscrew",
1173
1439
  schema: flatHeadScrewModelDefinitionSchema,
1174
1440
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlatHeadScrew, { ...props }),
1175
1441
  pads: "none"
1176
1442
  });
1177
- function register6(registry) {
1178
- registry.register(model6);
1443
+ function register7(registry) {
1444
+ registry.register(model7);
1179
1445
  }
1180
1446
 
1181
1447
  // lib/models/flexscreen/register.tsx
@@ -1853,14 +2119,14 @@ var FlexScreen = (props) => {
1853
2119
  };
1854
2120
 
1855
2121
  // lib/models/flexscreen/register.tsx
1856
- var model7 = defineModelRenderer({
2122
+ var model8 = defineModelRenderer({
1857
2123
  name: "flexscreen",
1858
2124
  schema: flexScreenModelDefinitionSchema,
1859
2125
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlexScreen, { ...props }),
1860
2126
  pads: "footprinter"
1861
2127
  });
1862
- function register7(registry) {
1863
- registry.register(model7);
2128
+ function register8(registry) {
2129
+ registry.register(model8);
1864
2130
  }
1865
2131
 
1866
2132
  // lib/models/helicalgear/register.tsx
@@ -2066,14 +2332,14 @@ function HelicalGear({ color = "#737e8f", ...props }) {
2066
2332
  }
2067
2333
 
2068
2334
  // lib/models/helicalgear/register.tsx
2069
- var model8 = defineModelRenderer({
2335
+ var model9 = defineModelRenderer({
2070
2336
  name: "helicalgear",
2071
2337
  schema: helicalGearModelDefinitionSchema,
2072
2338
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HelicalGear, { ...props }),
2073
2339
  pads: "none"
2074
2340
  });
2075
- function register8(registry) {
2076
- registry.register(model8);
2341
+ function register9(registry) {
2342
+ registry.register(model9);
2077
2343
  }
2078
2344
 
2079
2345
  // lib/models/hexbolt/register.tsx
@@ -2214,14 +2480,14 @@ function HexBolt({ color = "#737e8f", ...props }) {
2214
2480
  }
2215
2481
 
2216
2482
  // lib/models/hexbolt/register.tsx
2217
- var model9 = defineModelRenderer({
2483
+ var model10 = defineModelRenderer({
2218
2484
  name: "hexbolt",
2219
2485
  schema: hexBoltModelDefinitionSchema,
2220
2486
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexBolt, { ...props }),
2221
2487
  pads: "none"
2222
2488
  });
2223
- function register9(registry) {
2224
- registry.register(model9);
2489
+ function register10(registry) {
2490
+ registry.register(model10);
2225
2491
  }
2226
2492
 
2227
2493
  // lib/models/hexnut/register.tsx
@@ -2344,14 +2610,14 @@ function HexNut({ color = "#737e8f", ...props }) {
2344
2610
  }
2345
2611
 
2346
2612
  // lib/models/hexnut/register.tsx
2347
- var model10 = defineModelRenderer({
2613
+ var model11 = defineModelRenderer({
2348
2614
  name: "hexnut",
2349
2615
  schema: hexNutModelDefinitionSchema,
2350
2616
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexNut, { ...props }),
2351
2617
  pads: "none"
2352
2618
  });
2353
- function register10(registry) {
2354
- registry.register(model10);
2619
+ function register11(registry) {
2620
+ registry.register(model11);
2355
2621
  }
2356
2622
 
2357
2623
  // lib/models/hexsocketbolt/register.tsx
@@ -2463,14 +2729,142 @@ function HexSocketBolt({
2463
2729
  }
2464
2730
 
2465
2731
  // lib/models/hexsocketbolt/register.tsx
2466
- var model11 = defineModelRenderer({
2732
+ var model12 = defineModelRenderer({
2467
2733
  name: "hexsocketbolt",
2468
2734
  schema: hexSocketBoltModelDefinitionSchema,
2469
2735
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexSocketBolt, { ...props }),
2470
2736
  pads: "none"
2471
2737
  });
2472
- function register11(registry) {
2473
- registry.register(model11);
2738
+ function register12(registry) {
2739
+ registry.register(model12);
2740
+ }
2741
+
2742
+ // lib/models/hollowpositioningarmtube/register.tsx
2743
+ import { hollowPositioningArmTubeModelDefinitionSchema } from "@tscircuit/modelprinter";
2744
+
2745
+ // lib/models/hollowpositioningarmtube/mesh.ts
2746
+ import {
2747
+ getHollowPositioningArmTubeDimensions,
2748
+ getHollowPositioningArmTubeFrame,
2749
+ hollowPositioningArmTubeModelPropsSchema
2750
+ } from "@tscircuit/modelprinter";
2751
+ function createHollowPositioningArmTubeMesh(input, options = {}) {
2752
+ const props = hollowPositioningArmTubeModelPropsSchema.parse(input);
2753
+ const dimensions = getHollowPositioningArmTubeDimensions(props);
2754
+ const radialSegments = options.radialSegments ?? 24;
2755
+ const segmentsPerRib = options.segmentsPerRib ?? 4;
2756
+ for (const [name, value, minimum, maximum] of [
2757
+ ["radialSegments", radialSegments, 12, 128],
2758
+ ["segmentsPerRib", segmentsPerRib, 4, 32]
2759
+ ])
2760
+ if (!Number.isInteger(value) || value < minimum || value > maximum || value % 4 !== 0)
2761
+ throw new Error(
2762
+ `${name} must be a multiple of four in [${minimum},${maximum}]`
2763
+ );
2764
+ const { totalLength, bendLength, minimumWallThickness } = dimensions;
2765
+ const innerRadius = props.innerDiameter / 2;
2766
+ const scale = Math.max(totalLength, props.outerDiameter);
2767
+ const tolerance = scale * 1e-10;
2768
+ if (Math.min(innerRadius, minimumWallThickness, totalLength) <= tolerance)
2769
+ throw new Error(
2770
+ "Hollow positioning arm tube wall, bore or length exceeds mesh resolution limit"
2771
+ );
2772
+ const sagitta = Math.min(innerRadius, minimumWallThickness) * 0.02;
2773
+ const angleStep = Math.min(
2774
+ Math.PI / 36,
2775
+ 2 * Math.acos(1 - Math.min(sagitta / props.bendRadius, 1))
2776
+ );
2777
+ const bendSteps = props.bendAngle === 0 ? 0 : Math.ceil(props.bendAngle * Math.PI / 180 / angleStep);
2778
+ const ribSteps = props.ribDepth === 0 ? 0 : Math.ceil(totalLength / props.ribPitch * segmentsPerRib);
2779
+ const maximumRings = Math.floor(25e4 / (2 * radialSegments));
2780
+ if (!Number.isSafeInteger(bendSteps + ribSteps) || bendSteps + ribSteps + 5 > maximumRings)
2781
+ throw new Error(
2782
+ "Hollow positioning arm tube exceeds mesh resolution limit (250000 vertices)"
2783
+ );
2784
+ const samples = [
2785
+ 0,
2786
+ props.startLength,
2787
+ props.startLength + bendLength,
2788
+ totalLength
2789
+ ];
2790
+ for (let i = 1; i < bendSteps; i++)
2791
+ samples.push(props.startLength + bendLength * i / bendSteps);
2792
+ for (let i = 1; i < ribSteps; i++)
2793
+ samples.push(i * props.ribPitch / segmentsPerRib);
2794
+ samples.sort((a, b) => a - b);
2795
+ const stations = samples.filter(
2796
+ (s, i) => i === 0 || s - samples[i - 1] > tolerance
2797
+ );
2798
+ if (totalLength - stations[stations.length - 1] <= tolerance)
2799
+ stations[stations.length - 1] = totalLength;
2800
+ const positions = [];
2801
+ const indices = [];
2802
+ const stride = radialSegments * 2;
2803
+ for (const s of stations) {
2804
+ const { position, normal } = getHollowPositioningArmTubeFrame(props, s);
2805
+ const outerRadius = props.outerDiameter / 2 - (props.ribDepth === 0 ? 0 : props.ribDepth / 2 * (1 + Math.cos(2 * Math.PI * (s / props.ribPitch % 1))));
2806
+ for (const radius of [outerRadius, innerRadius])
2807
+ for (let j = 0; j < radialSegments; j++) {
2808
+ const angle = j * 2 * Math.PI / radialSegments;
2809
+ const cosine = j === radialSegments / 4 || j === 3 * radialSegments / 4 ? 0 : Math.cos(angle);
2810
+ const sine = j === 0 || j === radialSegments / 2 ? 0 : Math.sin(angle);
2811
+ positions.push(
2812
+ position[0] + radius * cosine * normal[0],
2813
+ radius * sine,
2814
+ position[2] + radius * cosine * normal[2]
2815
+ );
2816
+ }
2817
+ }
2818
+ const quad = (a, b, c, d) => {
2819
+ indices.push(a, b, c, a, c, d);
2820
+ };
2821
+ for (let ring = 0; ring + 1 < stations.length; ring++)
2822
+ for (let j = 0; j < radialSegments; j++) {
2823
+ const next = (j + 1) % radialSegments;
2824
+ const a = ring * stride;
2825
+ const b = (ring + 1) * stride;
2826
+ quad(a + j, a + next, b + next, b + j);
2827
+ quad(
2828
+ a + radialSegments + j,
2829
+ b + radialSegments + j,
2830
+ b + radialSegments + next,
2831
+ a + radialSegments + next
2832
+ );
2833
+ }
2834
+ for (let j = 0; j < radialSegments; j++) {
2835
+ const next = (j + 1) % radialSegments;
2836
+ quad(j, radialSegments + j, radialSegments + next, next);
2837
+ const end = (stations.length - 1) * stride;
2838
+ quad(
2839
+ end + j,
2840
+ end + next,
2841
+ end + radialSegments + next,
2842
+ end + radialSegments + j
2843
+ );
2844
+ }
2845
+ return { positions, indices };
2846
+ }
2847
+
2848
+ // lib/models/hollowpositioningarmtube/HollowPositioningArmTube.tsx
2849
+ function createHollowPositioningArmTubeGeom(input) {
2850
+ return indexedMeshToGeom3(createHollowPositioningArmTubeMesh(input));
2851
+ }
2852
+ function HollowPositioningArmTube({
2853
+ color = "#343943",
2854
+ ...props
2855
+ }) {
2856
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createHollowPositioningArmTubeGeom(props) }) });
2857
+ }
2858
+
2859
+ // lib/models/hollowpositioningarmtube/register.tsx
2860
+ var model13 = defineModelRenderer({
2861
+ name: "hollowpositioningarmtube",
2862
+ schema: hollowPositioningArmTubeModelDefinitionSchema,
2863
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HollowPositioningArmTube, { ...props }),
2864
+ pads: "none"
2865
+ });
2866
+ function register13(registry) {
2867
+ registry.register(model13);
2474
2868
  }
2475
2869
 
2476
2870
  // lib/models/nema/register.tsx
@@ -2739,14 +3133,14 @@ var NEMA17 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 17
2739
3133
  var NEMA23 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 23 });
2740
3134
 
2741
3135
  // lib/models/nema/register.tsx
2742
- var model12 = defineModelRenderer({
3136
+ var model14 = defineModelRenderer({
2743
3137
  name: "nema",
2744
3138
  schema: nemaMotorModelDefinitionSchema,
2745
3139
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(NemaMotor, { ...props }),
2746
3140
  pads: "none"
2747
3141
  });
2748
- function register12(registry) {
2749
- registry.register(model12);
3142
+ function register14(registry) {
3143
+ registry.register(model14);
2750
3144
  }
2751
3145
 
2752
3146
  // lib/models/panscrew/register.tsx
@@ -2958,14 +3352,14 @@ function PanScrew({ color = "#737e8f", ...props }) {
2958
3352
  }
2959
3353
 
2960
3354
  // lib/models/panscrew/register.tsx
2961
- var model13 = defineModelRenderer({
3355
+ var model15 = defineModelRenderer({
2962
3356
  name: "panscrew",
2963
3357
  schema: panScrewModelDefinitionSchema,
2964
3358
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PanScrew, { ...props }),
2965
3359
  pads: "none"
2966
3360
  });
2967
- function register13(registry) {
2968
- registry.register(model13);
3361
+ function register15(registry) {
3362
+ registry.register(model15);
2969
3363
  }
2970
3364
 
2971
3365
  // lib/models/plainbushing/register.tsx
@@ -3028,14 +3422,14 @@ function PlainBushing({
3028
3422
  }
3029
3423
 
3030
3424
  // lib/models/plainbushing/register.tsx
3031
- var model14 = defineModelRenderer({
3425
+ var model16 = defineModelRenderer({
3032
3426
  name: "plainbushing",
3033
3427
  schema: plainBushingModelDefinitionSchema,
3034
3428
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PlainBushing, { ...props }),
3035
3429
  pads: "none"
3036
3430
  });
3037
- function register14(registry) {
3038
- registry.register(model14);
3431
+ function register16(registry) {
3432
+ registry.register(model16);
3039
3433
  }
3040
3434
 
3041
3435
  // lib/models/rigidcoupler/register.tsx
@@ -3079,14 +3473,14 @@ function RigidCoupler({
3079
3473
  }
3080
3474
 
3081
3475
  // lib/models/rigidcoupler/register.tsx
3082
- var model15 = defineModelRenderer({
3476
+ var model17 = defineModelRenderer({
3083
3477
  name: "rigidcoupler",
3084
3478
  schema: rigidCouplerModelDefinitionSchema,
3085
3479
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(RigidCoupler, { ...props }),
3086
3480
  pads: "none"
3087
3481
  });
3088
- function register15(registry) {
3089
- registry.register(model15);
3482
+ function register17(registry) {
3483
+ registry.register(model17);
3090
3484
  }
3091
3485
 
3092
3486
  // lib/models/shaftcollar/register.tsx
@@ -3125,14 +3519,14 @@ function ShaftCollar({ color = "#737e8f", ...props }) {
3125
3519
  }
3126
3520
 
3127
3521
  // lib/models/shaftcollar/register.tsx
3128
- var model16 = defineModelRenderer({
3522
+ var model18 = defineModelRenderer({
3129
3523
  name: "shaftcollar",
3130
3524
  schema: shaftCollarModelDefinitionSchema,
3131
3525
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ShaftCollar, { ...props }),
3132
3526
  pads: "none"
3133
3527
  });
3134
- function register16(registry) {
3135
- registry.register(model16);
3528
+ function register18(registry) {
3529
+ registry.register(model18);
3136
3530
  }
3137
3531
 
3138
3532
  // lib/models/sheetmetal/register.tsx
@@ -3292,14 +3686,14 @@ function SheetMetal({ color = "#737e8f", ...props }) {
3292
3686
  }
3293
3687
 
3294
3688
  // lib/models/sheetmetal/register.tsx
3295
- var model17 = defineModelRenderer({
3689
+ var model19 = defineModelRenderer({
3296
3690
  name: "sheetmetal",
3297
3691
  schema: sheetMetalModelDefinitionSchema,
3298
3692
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SheetMetal, { ...props }),
3299
3693
  pads: "none"
3300
3694
  });
3301
- function register17(registry) {
3302
- registry.register(model17);
3695
+ function register19(registry) {
3696
+ registry.register(model19);
3303
3697
  }
3304
3698
 
3305
3699
  // lib/models/spurgear/register.tsx
@@ -3314,14 +3708,14 @@ function SpurGear({ color = "#737e8f", ...props }) {
3314
3708
  }
3315
3709
 
3316
3710
  // lib/models/spurgear/register.tsx
3317
- var model18 = defineModelRenderer({
3711
+ var model20 = defineModelRenderer({
3318
3712
  name: "spurgear",
3319
3713
  schema: spurGearModelDefinitionSchema,
3320
3714
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SpurGear, { ...props }),
3321
3715
  pads: "none"
3322
3716
  });
3323
- function register18(registry) {
3324
- registry.register(model18);
3717
+ function register20(registry) {
3718
+ registry.register(model20);
3325
3719
  }
3326
3720
 
3327
3721
  // lib/models/threadedrod/register.tsx
@@ -3423,14 +3817,14 @@ function ThreadedRod({ color = "#737e8f", ...props }) {
3423
3817
  }
3424
3818
 
3425
3819
  // lib/models/threadedrod/register.tsx
3426
- var model19 = defineModelRenderer({
3820
+ var model21 = defineModelRenderer({
3427
3821
  name: "threadedrod",
3428
3822
  schema: threadedRodModelDefinitionSchema,
3429
3823
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ThreadedRod, { ...props }),
3430
3824
  pads: "none"
3431
3825
  });
3432
- function register19(registry) {
3433
- registry.register(model19);
3826
+ function register21(registry) {
3827
+ registry.register(model21);
3434
3828
  }
3435
3829
 
3436
3830
  // lib/models/tslotextrusion/register.tsx
@@ -3580,14 +3974,14 @@ function TSlotExtrusion({
3580
3974
  }
3581
3975
 
3582
3976
  // lib/models/tslotextrusion/register.tsx
3583
- var model20 = defineModelRenderer({
3977
+ var model22 = defineModelRenderer({
3584
3978
  name: "tslotextrusion",
3585
3979
  schema: tSlotExtrusionModelDefinitionSchema,
3586
3980
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotExtrusion, { ...props }),
3587
3981
  pads: "none"
3588
3982
  });
3589
- function register20(registry) {
3590
- registry.register(model20);
3983
+ function register22(registry) {
3984
+ registry.register(model22);
3591
3985
  }
3592
3986
 
3593
3987
  // lib/models/tslotgusset/register.tsx
@@ -3640,14 +4034,14 @@ function TSlotGusset({ color = "#8995a3", ...props }) {
3640
4034
  }
3641
4035
 
3642
4036
  // lib/models/tslotgusset/register.tsx
3643
- var model21 = defineModelRenderer({
4037
+ var model23 = defineModelRenderer({
3644
4038
  name: "tslotgusset",
3645
4039
  schema: tSlotGussetModelDefinitionSchema,
3646
4040
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotGusset, { ...props }),
3647
4041
  pads: "none"
3648
4042
  });
3649
- function register21(registry) {
3650
- registry.register(model21);
4043
+ function register23(registry) {
4044
+ registry.register(model23);
3651
4045
  }
3652
4046
 
3653
4047
  // lib/models/tslotinsidecorner/register.tsx
@@ -3727,14 +4121,14 @@ function TSlotInsideCorner({
3727
4121
  }
3728
4122
 
3729
4123
  // lib/models/tslotinsidecorner/register.tsx
3730
- var model22 = defineModelRenderer({
4124
+ var model24 = defineModelRenderer({
3731
4125
  name: "tslotinsidecorner",
3732
4126
  schema: tSlotInsideCornerModelDefinitionSchema,
3733
4127
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotInsideCorner, { ...props }),
3734
4128
  pads: "none"
3735
4129
  });
3736
- function register22(registry) {
3737
- registry.register(model22);
4130
+ function register24(registry) {
4131
+ registry.register(model24);
3738
4132
  }
3739
4133
 
3740
4134
  // lib/models/wormgear/register.tsx
@@ -3926,14 +4320,14 @@ function WormGear({ color = "#737e8f", ...props }) {
3926
4320
  }
3927
4321
 
3928
4322
  // lib/models/wormgear/register.tsx
3929
- var model23 = defineModelRenderer({
4323
+ var model25 = defineModelRenderer({
3930
4324
  name: "wormgear",
3931
4325
  schema: wormGearModelDefinitionSchema,
3932
4326
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(WormGear, { ...props }),
3933
4327
  pads: "none"
3934
4328
  });
3935
- function register23(registry) {
3936
- registry.register(model23);
4329
+ function register25(registry) {
4330
+ registry.register(model25);
3937
4331
  }
3938
4332
 
3939
4333
  // lib/generated/model-renderers.ts
@@ -3961,6 +4355,8 @@ function registerAllModelRenderers(registry) {
3961
4355
  register21(registry);
3962
4356
  register22(registry);
3963
4357
  register23(registry);
4358
+ register24(registry);
4359
+ register25(registry);
3964
4360
  }
3965
4361
 
3966
4362
  // lib/default-model-registry.ts
@@ -11517,10 +11913,10 @@ var SOT143 = ({ footprint = "sot143" }) => {
11517
11913
  var Footprinter3d = ({ footprint }) => {
11518
11914
  const modelFn = mp3.string(footprint.split("_", 1)[0]).params().fn;
11519
11915
  if (mp3.getModelNames().includes(modelFn)) {
11520
- const model24 = mp3.string(footprint).json();
11521
- const renderer = modelRendererRegistry.get(model24.fn);
11916
+ const model26 = mp3.string(footprint).json();
11917
+ const renderer = modelRendererRegistry.get(model26.fn);
11522
11918
  if (renderer) {
11523
- return renderer.render(model24);
11919
+ return renderer.render(model26);
11524
11920
  }
11525
11921
  }
11526
11922
  let normalizedFootprint = footprint;
@@ -12471,6 +12867,7 @@ function createJSCADRenderer(jscad8) {
12471
12867
  return { createJSCADRoot };
12472
12868
  }
12473
12869
  export {
12870
+ BallBearing,
12474
12871
  ButtonScrew,
12475
12872
  CableGrommet,
12476
12873
  ClampingShaftCollar,
@@ -12482,6 +12879,7 @@ export {
12482
12879
  HexBolt,
12483
12880
  HexNut,
12484
12881
  HexSocketBolt,
12882
+ HollowPositioningArmTube,
12485
12883
  NEMA17,
12486
12884
  NEMA23,
12487
12885
  NEMA8,
@@ -12498,6 +12896,8 @@ export {
12498
12896
  ThreadedRod,
12499
12897
  WormGear,
12500
12898
  convertCSGToThreeGeom,
12899
+ createBallBearingGeom,
12900
+ createBallBearingMesh,
12501
12901
  createButtonScrewGeom,
12502
12902
  createButtonScrewMesh,
12503
12903
  createCableGrommetGeom,
@@ -12518,6 +12918,8 @@ export {
12518
12918
  createHexNutMesh,
12519
12919
  createHexSocketBoltGeom,
12520
12920
  createHexSocketBoltMesh,
12921
+ createHollowPositioningArmTubeGeom,
12922
+ createHollowPositioningArmTubeMesh,
12521
12923
  createJSCADRenderer,
12522
12924
  createPanScrewGeom,
12523
12925
  createPanScrewMesh,