jscad-electronics 0.0.200 → 0.0.201

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.d.ts CHANGED
@@ -3,7 +3,7 @@ import { BufferGeometry } from 'three';
3
3
  import * as jscadModeling from '@jscad/modeling';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import * as _jscad_modeling_src_geometries_types from '@jscad/modeling/src/geometries/types';
6
- import { ButtonScrewModelPropsInput, FlangedBushingModelPropsInput, FlatHeadScrewModelPropsInput, SpurGearModelPropsInput, HelicalGearModelPropsInput, HexBoltModelPropsInput, HexNutModelPropsInput, HexSocketBoltModelPropsInput, NemaMotorModelPropsInput, PanScrewModelPropsInput, PlainBushingModelPropsInput, SheetMetalModelPropsInput, WormGearModelPropsInput } from '@tscircuit/modelprinter';
6
+ import { ButtonScrewModelPropsInput, CableGrommetModelPropsInput, FlangedBushingModelPropsInput, FlatHeadScrewModelPropsInput, SpurGearModelPropsInput, HelicalGearModelPropsInput, HexBoltModelPropsInput, HexNutModelPropsInput, HexSocketBoltModelPropsInput, NemaMotorModelPropsInput, PanScrewModelPropsInput, PlainBushingModelPropsInput, SheetMetalModelPropsInput, WormGearModelPropsInput } from '@tscircuit/modelprinter';
7
7
 
8
8
  type VNode = {
9
9
  type: any;
@@ -45,6 +45,23 @@ type ButtonScrewProps = ButtonScrewModelPropsInput & {
45
45
  declare function createButtonScrewGeom(input: ButtonScrewModelPropsInput, resolution?: ButtonScrewMeshOptions): _jscad_modeling_src_geometries_types.Geom3;
46
46
  declare function ButtonScrew({ color, ...props }: ButtonScrewProps): react_jsx_runtime.JSX.Element;
47
47
 
48
+ interface CableGrommetMesh {
49
+ positions: number[];
50
+ indices: number[];
51
+ }
52
+ interface CableGrommetMeshOptions {
53
+ /** Requested minimum; thin root walls can require more circular segments. */
54
+ radialSegments?: number;
55
+ }
56
+ /** Square-shouldered annulus centered on Z=0, with an open axial cable bore. */
57
+ declare function createCableGrommetMesh(input: CableGrommetModelPropsInput, options?: CableGrommetMeshOptions): CableGrommetMesh;
58
+
59
+ type CableGrommetProps = CableGrommetModelPropsInput & {
60
+ color?: string;
61
+ };
62
+ declare function createCableGrommetGeom(input: CableGrommetModelPropsInput): _jscad_modeling_src_geometries_types.Geom3;
63
+ declare function CableGrommet({ color, ...props }: CableGrommetProps): react_jsx_runtime.JSX.Element;
64
+
48
65
  /** Shared ring vertices and outward counterclockwise triangles, in millimeters. */
49
66
  interface FlangedBushingMesh {
50
67
  positions: number[];
@@ -263,4 +280,4 @@ declare function createJSCADRenderer(jscad: typeof jscadModeling): {
263
280
  };
264
281
  };
265
282
 
266
- export { ButtonScrew, type ButtonScrewMesh, type ButtonScrewMeshOptions, type ButtonScrewProps, type ColoredGeom, FlangedBushing, type FlangedBushingMesh, type FlangedBushingProps, FlatHeadScrew, type FlatHeadScrewMesh, type FlatHeadScrewMeshOptions, type FlatHeadScrewProps, Fragment, HelicalGear, type HelicalGearMesh, type HelicalGearProps, HexBolt, type HexBoltMesh, type HexBoltMeshOptions, type HexBoltProps, HexNut, type HexNutMesh, type HexNutMeshOptions, type HexNutProps, HexSocketBolt, type HexSocketBoltMesh, type HexSocketBoltProps, NEMA17, NEMA23, NEMA8, type NemaFrameMotorProps, NemaMotor, type NemaMotorProps, PanScrew, type PanScrewMesh, type PanScrewMeshOptions, type PanScrewProps, PlainBushing, type PlainBushingMesh, type PlainBushingProps, type RenderResult, SheetMetal, type SheetMetalMesh, type SheetMetalProps, SpurGear, type SpurGearMesh, type SpurGearProps, type VNode, WormGear, type WormGearMesh, type WormGearProps, convertCSGToThreeGeom, createButtonScrewGeom, createButtonScrewMesh, createFlangedBushingGeom, createFlangedBushingMesh, createFlatHeadScrewGeom, createFlatHeadScrewMesh, createHelicalGearGeom, createHelicalGearMesh, createHexBoltGeom, createHexBoltMesh, createHexNutGeom, createHexNutMesh, createHexSocketBoltGeom, createHexSocketBoltMesh, createJSCADRenderer, createPanScrewGeom, createPanScrewMesh, createPlainBushingGeom, createPlainBushingMesh, createSheetMetalGeom, createSheetMetalMesh, createSpurGearGeom, createSpurGearMesh, createWormGearGeom, createWormGearMesh, getJscadModelForFootprint, getJscadModelForFootprintWithPads, h };
283
+ export { ButtonScrew, type ButtonScrewMesh, type ButtonScrewMeshOptions, type ButtonScrewProps, CableGrommet, type CableGrommetMesh, type CableGrommetMeshOptions, type CableGrommetProps, type ColoredGeom, FlangedBushing, type FlangedBushingMesh, type FlangedBushingProps, FlatHeadScrew, type FlatHeadScrewMesh, type FlatHeadScrewMeshOptions, type FlatHeadScrewProps, Fragment, HelicalGear, type HelicalGearMesh, type HelicalGearProps, HexBolt, type HexBoltMesh, type HexBoltMeshOptions, type HexBoltProps, HexNut, type HexNutMesh, type HexNutMeshOptions, type HexNutProps, HexSocketBolt, type HexSocketBoltMesh, type HexSocketBoltProps, NEMA17, NEMA23, NEMA8, type NemaFrameMotorProps, NemaMotor, type NemaMotorProps, PanScrew, type PanScrewMesh, type PanScrewMeshOptions, type PanScrewProps, PlainBushing, type PlainBushingMesh, type PlainBushingProps, type RenderResult, SheetMetal, type SheetMetalMesh, type SheetMetalProps, SpurGear, type SpurGearMesh, type SpurGearProps, type VNode, WormGear, type WormGearMesh, type WormGearProps, convertCSGToThreeGeom, createButtonScrewGeom, createButtonScrewMesh, createCableGrommetGeom, createCableGrommetMesh, createFlangedBushingGeom, createFlangedBushingMesh, createFlatHeadScrewGeom, createFlatHeadScrewMesh, createHelicalGearGeom, createHelicalGearMesh, createHexBoltGeom, createHexBoltMesh, createHexNutGeom, createHexNutMesh, createHexSocketBoltGeom, createHexSocketBoltMesh, createJSCADRenderer, createPanScrewGeom, createPanScrewMesh, createPlainBushingGeom, createPlainBushingMesh, createSheetMetalGeom, createSheetMetalMesh, createSpurGearGeom, createSpurGearMesh, createWormGearGeom, createWormGearMesh, getJscadModelForFootprint, getJscadModelForFootprintWithPads, h };
package/dist/vanilla.js CHANGED
@@ -183,24 +183,24 @@ var FootprintPlatedHole = ({
183
183
  import { buttonScrewModelDefinitionSchema } from "@tscircuit/modelprinter";
184
184
 
185
185
  // lib/model-registry.ts
186
- function defineModelRenderer(model15) {
187
- return model15;
186
+ function defineModelRenderer(model16) {
187
+ return model16;
188
188
  }
189
189
  var ModelRendererRegistry = class {
190
190
  models = /* @__PURE__ */ new Map();
191
- register(model15) {
192
- if (typeof model15.name !== "string" || !/^[a-z]+$/.test(model15.name)) {
191
+ register(model16) {
192
+ if (typeof model16.name !== "string" || !/^[a-z]+$/.test(model16.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(model15.name)) {
198
- throw new Error(`Model renderer "${model15.name}" is already registered`);
197
+ if (this.models.has(model16.name)) {
198
+ throw new Error(`Model renderer "${model16.name}" is already registered`);
199
199
  }
200
- if (model15.pads !== "none" && model15.pads !== "footprinter") {
200
+ if (model16.pads !== "none" && model16.pads !== "footprinter") {
201
201
  throw new Error('Model renderer pads must be "none" or "footprinter"');
202
202
  }
203
- const { name, schema, render: render2, pads } = model15;
203
+ const { name, schema, render: render2, pads } = model16;
204
204
  this.models.set(name, {
205
205
  name,
206
206
  schema,
@@ -372,6 +372,88 @@ function register(registry) {
372
372
  registry.register(model);
373
373
  }
374
374
 
375
+ // lib/models/cablegrommet/register.tsx
376
+ import { cableGrommetModelDefinitionSchema } from "@tscircuit/modelprinter";
377
+
378
+ // lib/models/cablegrommet/mesh.ts
379
+ import {
380
+ cableGrommetModelPropsSchema,
381
+ getCableGrommetDimensions
382
+ } from "@tscircuit/modelprinter";
383
+ function createCableGrommetMesh(input, options = {}) {
384
+ const props = cableGrommetModelPropsSchema.parse(input);
385
+ const dimensions = getCableGrommetDimensions(props);
386
+ const inner = props.innerDiameter / 2;
387
+ const root = dimensions.grooveRootDiameter / 2;
388
+ const outer = props.outerDiameter / 2;
389
+ const requested = options.radialSegments ?? 96;
390
+ if (!Number.isInteger(requested) || requested < 12 || requested > 4096 || requested % 4 !== 0)
391
+ throw new Error(
392
+ "Grommet radial segments must be a multiple of four in [12,4096]"
393
+ );
394
+ const wallAngle = Math.acos((inner + root) / (2 * root));
395
+ const segments = Math.max(requested, 4 * Math.ceil(Math.PI / wallAngle / 4));
396
+ if (!Number.isFinite(segments) || segments > 4096)
397
+ throw new Error(
398
+ "Grommet wall exceeds mesh resolution limit (4096 segments)"
399
+ );
400
+ const section = [
401
+ [inner, -props.height / 2],
402
+ [outer, -props.height / 2],
403
+ [outer, dimensions.grooveStartZ],
404
+ [root, dimensions.grooveStartZ],
405
+ [root, dimensions.grooveEndZ],
406
+ [outer, dimensions.grooveEndZ],
407
+ [outer, props.height / 2],
408
+ [inner, props.height / 2]
409
+ ];
410
+ const positions = [];
411
+ const indices = [];
412
+ for (const [radius, z] of section)
413
+ for (let sample = 0; sample < segments; sample++) {
414
+ const angle = sample * 2 * Math.PI / segments;
415
+ positions.push(radius * Math.cos(angle), radius * Math.sin(angle), z);
416
+ }
417
+ for (let ring = 0; ring < section.length; ring++) {
418
+ const a = ring * segments;
419
+ const b = (ring + 1) % section.length * segments;
420
+ for (let sample = 0; sample < segments; sample++) {
421
+ const next = (sample + 1) % segments;
422
+ indices.push(
423
+ a + sample,
424
+ a + next,
425
+ b + next,
426
+ a + sample,
427
+ b + next,
428
+ b + sample
429
+ );
430
+ }
431
+ }
432
+ return { positions, indices };
433
+ }
434
+
435
+ // lib/models/cablegrommet/CableGrommet.tsx
436
+ function createCableGrommetGeom(input) {
437
+ return indexedMeshToGeom3(createCableGrommetMesh(input));
438
+ }
439
+ function CableGrommet({
440
+ color = "#343943",
441
+ ...props
442
+ }) {
443
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createCableGrommetGeom(props) }) });
444
+ }
445
+
446
+ // lib/models/cablegrommet/register.tsx
447
+ var model2 = defineModelRenderer({
448
+ name: "cablegrommet",
449
+ schema: cableGrommetModelDefinitionSchema,
450
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(CableGrommet, { ...props }),
451
+ pads: "none"
452
+ });
453
+ function register2(registry) {
454
+ registry.register(model2);
455
+ }
456
+
375
457
  // lib/models/flangedbushing/register.tsx
376
458
  import { flangedBushingModelDefinitionSchema } from "@tscircuit/modelprinter";
377
459
 
@@ -425,14 +507,14 @@ function FlangedBushing({
425
507
  }
426
508
 
427
509
  // lib/models/flangedbushing/register.tsx
428
- var model2 = defineModelRenderer({
510
+ var model3 = defineModelRenderer({
429
511
  name: "flangedbushing",
430
512
  schema: flangedBushingModelDefinitionSchema,
431
513
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlangedBushing, { ...props }),
432
514
  pads: "none"
433
515
  });
434
- function register2(registry) {
435
- registry.register(model2);
516
+ function register3(registry) {
517
+ registry.register(model3);
436
518
  }
437
519
 
438
520
  // lib/models/flatheadscrew/register.tsx
@@ -565,14 +647,14 @@ function FlatHeadScrew({
565
647
  }
566
648
 
567
649
  // lib/models/flatheadscrew/register.tsx
568
- var model3 = defineModelRenderer({
650
+ var model4 = defineModelRenderer({
569
651
  name: "flatheadscrew",
570
652
  schema: flatHeadScrewModelDefinitionSchema,
571
653
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlatHeadScrew, { ...props }),
572
654
  pads: "none"
573
655
  });
574
- function register3(registry) {
575
- registry.register(model3);
656
+ function register4(registry) {
657
+ registry.register(model4);
576
658
  }
577
659
 
578
660
  // lib/models/flexscreen/register.tsx
@@ -1250,14 +1332,14 @@ var FlexScreen = (props) => {
1250
1332
  };
1251
1333
 
1252
1334
  // lib/models/flexscreen/register.tsx
1253
- var model4 = defineModelRenderer({
1335
+ var model5 = defineModelRenderer({
1254
1336
  name: "flexscreen",
1255
1337
  schema: flexScreenModelDefinitionSchema,
1256
1338
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlexScreen, { ...props }),
1257
1339
  pads: "footprinter"
1258
1340
  });
1259
- function register4(registry) {
1260
- registry.register(model4);
1341
+ function register5(registry) {
1342
+ registry.register(model5);
1261
1343
  }
1262
1344
 
1263
1345
  // lib/models/helicalgear/register.tsx
@@ -1463,14 +1545,14 @@ function HelicalGear({ color = "#737e8f", ...props }) {
1463
1545
  }
1464
1546
 
1465
1547
  // lib/models/helicalgear/register.tsx
1466
- var model5 = defineModelRenderer({
1548
+ var model6 = defineModelRenderer({
1467
1549
  name: "helicalgear",
1468
1550
  schema: helicalGearModelDefinitionSchema,
1469
1551
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HelicalGear, { ...props }),
1470
1552
  pads: "none"
1471
1553
  });
1472
- function register5(registry) {
1473
- registry.register(model5);
1554
+ function register6(registry) {
1555
+ registry.register(model6);
1474
1556
  }
1475
1557
 
1476
1558
  // lib/models/hexbolt/register.tsx
@@ -1611,14 +1693,14 @@ function HexBolt({ color = "#737e8f", ...props }) {
1611
1693
  }
1612
1694
 
1613
1695
  // lib/models/hexbolt/register.tsx
1614
- var model6 = defineModelRenderer({
1696
+ var model7 = defineModelRenderer({
1615
1697
  name: "hexbolt",
1616
1698
  schema: hexBoltModelDefinitionSchema,
1617
1699
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexBolt, { ...props }),
1618
1700
  pads: "none"
1619
1701
  });
1620
- function register6(registry) {
1621
- registry.register(model6);
1702
+ function register7(registry) {
1703
+ registry.register(model7);
1622
1704
  }
1623
1705
 
1624
1706
  // lib/models/hexnut/register.tsx
@@ -1741,14 +1823,14 @@ function HexNut({ color = "#737e8f", ...props }) {
1741
1823
  }
1742
1824
 
1743
1825
  // lib/models/hexnut/register.tsx
1744
- var model7 = defineModelRenderer({
1826
+ var model8 = defineModelRenderer({
1745
1827
  name: "hexnut",
1746
1828
  schema: hexNutModelDefinitionSchema,
1747
1829
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexNut, { ...props }),
1748
1830
  pads: "none"
1749
1831
  });
1750
- function register7(registry) {
1751
- registry.register(model7);
1832
+ function register8(registry) {
1833
+ registry.register(model8);
1752
1834
  }
1753
1835
 
1754
1836
  // lib/models/hexsocketbolt/register.tsx
@@ -1860,14 +1942,14 @@ function HexSocketBolt({
1860
1942
  }
1861
1943
 
1862
1944
  // lib/models/hexsocketbolt/register.tsx
1863
- var model8 = defineModelRenderer({
1945
+ var model9 = defineModelRenderer({
1864
1946
  name: "hexsocketbolt",
1865
1947
  schema: hexSocketBoltModelDefinitionSchema,
1866
1948
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexSocketBolt, { ...props }),
1867
1949
  pads: "none"
1868
1950
  });
1869
- function register8(registry) {
1870
- registry.register(model8);
1951
+ function register9(registry) {
1952
+ registry.register(model9);
1871
1953
  }
1872
1954
 
1873
1955
  // lib/models/nema/register.tsx
@@ -2136,14 +2218,14 @@ var NEMA17 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 17
2136
2218
  var NEMA23 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 23 });
2137
2219
 
2138
2220
  // lib/models/nema/register.tsx
2139
- var model9 = defineModelRenderer({
2221
+ var model10 = defineModelRenderer({
2140
2222
  name: "nema",
2141
2223
  schema: nemaMotorModelDefinitionSchema,
2142
2224
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(NemaMotor, { ...props }),
2143
2225
  pads: "none"
2144
2226
  });
2145
- function register9(registry) {
2146
- registry.register(model9);
2227
+ function register10(registry) {
2228
+ registry.register(model10);
2147
2229
  }
2148
2230
 
2149
2231
  // lib/models/panscrew/register.tsx
@@ -2355,14 +2437,14 @@ function PanScrew({ color = "#737e8f", ...props }) {
2355
2437
  }
2356
2438
 
2357
2439
  // lib/models/panscrew/register.tsx
2358
- var model10 = defineModelRenderer({
2440
+ var model11 = defineModelRenderer({
2359
2441
  name: "panscrew",
2360
2442
  schema: panScrewModelDefinitionSchema,
2361
2443
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PanScrew, { ...props }),
2362
2444
  pads: "none"
2363
2445
  });
2364
- function register10(registry) {
2365
- registry.register(model10);
2446
+ function register11(registry) {
2447
+ registry.register(model11);
2366
2448
  }
2367
2449
 
2368
2450
  // lib/models/plainbushing/register.tsx
@@ -2425,14 +2507,14 @@ function PlainBushing({
2425
2507
  }
2426
2508
 
2427
2509
  // lib/models/plainbushing/register.tsx
2428
- var model11 = defineModelRenderer({
2510
+ var model12 = defineModelRenderer({
2429
2511
  name: "plainbushing",
2430
2512
  schema: plainBushingModelDefinitionSchema,
2431
2513
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PlainBushing, { ...props }),
2432
2514
  pads: "none"
2433
2515
  });
2434
- function register11(registry) {
2435
- registry.register(model11);
2516
+ function register12(registry) {
2517
+ registry.register(model12);
2436
2518
  }
2437
2519
 
2438
2520
  // lib/models/sheetmetal/register.tsx
@@ -2592,14 +2674,14 @@ function SheetMetal({ color = "#737e8f", ...props }) {
2592
2674
  }
2593
2675
 
2594
2676
  // lib/models/sheetmetal/register.tsx
2595
- var model12 = defineModelRenderer({
2677
+ var model13 = defineModelRenderer({
2596
2678
  name: "sheetmetal",
2597
2679
  schema: sheetMetalModelDefinitionSchema,
2598
2680
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SheetMetal, { ...props }),
2599
2681
  pads: "none"
2600
2682
  });
2601
- function register12(registry) {
2602
- registry.register(model12);
2683
+ function register13(registry) {
2684
+ registry.register(model13);
2603
2685
  }
2604
2686
 
2605
2687
  // lib/models/spurgear/register.tsx
@@ -2614,14 +2696,14 @@ function SpurGear({ color = "#737e8f", ...props }) {
2614
2696
  }
2615
2697
 
2616
2698
  // lib/models/spurgear/register.tsx
2617
- var model13 = defineModelRenderer({
2699
+ var model14 = defineModelRenderer({
2618
2700
  name: "spurgear",
2619
2701
  schema: spurGearModelDefinitionSchema,
2620
2702
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SpurGear, { ...props }),
2621
2703
  pads: "none"
2622
2704
  });
2623
- function register13(registry) {
2624
- registry.register(model13);
2705
+ function register14(registry) {
2706
+ registry.register(model14);
2625
2707
  }
2626
2708
 
2627
2709
  // lib/models/wormgear/register.tsx
@@ -2813,14 +2895,14 @@ function WormGear({ color = "#737e8f", ...props }) {
2813
2895
  }
2814
2896
 
2815
2897
  // lib/models/wormgear/register.tsx
2816
- var model14 = defineModelRenderer({
2898
+ var model15 = defineModelRenderer({
2817
2899
  name: "wormgear",
2818
2900
  schema: wormGearModelDefinitionSchema,
2819
2901
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(WormGear, { ...props }),
2820
2902
  pads: "none"
2821
2903
  });
2822
- function register14(registry) {
2823
- registry.register(model14);
2904
+ function register15(registry) {
2905
+ registry.register(model15);
2824
2906
  }
2825
2907
 
2826
2908
  // lib/generated/model-renderers.ts
@@ -2839,6 +2921,7 @@ function registerAllModelRenderers(registry) {
2839
2921
  register12(registry);
2840
2922
  register13(registry);
2841
2923
  register14(registry);
2924
+ register15(registry);
2842
2925
  }
2843
2926
 
2844
2927
  // lib/default-model-registry.ts
@@ -10395,10 +10478,10 @@ var SOT143 = ({ footprint = "sot143" }) => {
10395
10478
  var Footprinter3d = ({ footprint }) => {
10396
10479
  const modelFn = mp3.string(footprint.split("_", 1)[0]).params().fn;
10397
10480
  if (mp3.getModelNames().includes(modelFn)) {
10398
- const model15 = mp3.string(footprint).json();
10399
- const renderer = modelRendererRegistry.get(model15.fn);
10481
+ const model16 = mp3.string(footprint).json();
10482
+ const renderer = modelRendererRegistry.get(model16.fn);
10400
10483
  if (renderer) {
10401
- return renderer.render(model15);
10484
+ return renderer.render(model16);
10402
10485
  }
10403
10486
  }
10404
10487
  let normalizedFootprint = footprint;
@@ -11350,6 +11433,7 @@ function createJSCADRenderer(jscad4) {
11350
11433
  }
11351
11434
  export {
11352
11435
  ButtonScrew,
11436
+ CableGrommet,
11353
11437
  FlangedBushing,
11354
11438
  FlatHeadScrew,
11355
11439
  Fragment,
@@ -11369,6 +11453,8 @@ export {
11369
11453
  convertCSGToThreeGeom,
11370
11454
  createButtonScrewGeom,
11371
11455
  createButtonScrewMesh,
11456
+ createCableGrommetGeom,
11457
+ createCableGrommetMesh,
11372
11458
  createFlangedBushingGeom,
11373
11459
  createFlangedBushingMesh,
11374
11460
  createFlatHeadScrewGeom,