jscad-electronics 0.0.194 → 0.0.196
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 +36 -2
- package/dist/index.js +1307 -930
- package/dist/index.js.map +1 -1
- package/dist/vanilla.d.ts +36 -2
- package/dist/vanilla.js +419 -52
- package/dist/vanilla.js.map +1 -1
- package/package.json +1 -1
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/
|
|
183
|
-
import {
|
|
182
|
+
// lib/models/flatheadscrew/register.tsx
|
|
183
|
+
import { flatHeadScrewModelDefinitionSchema } from "@tscircuit/modelprinter";
|
|
184
184
|
|
|
185
185
|
// lib/model-registry.ts
|
|
186
|
-
function defineModelRenderer(
|
|
187
|
-
return
|
|
186
|
+
function defineModelRenderer(model11) {
|
|
187
|
+
return model11;
|
|
188
188
|
}
|
|
189
189
|
var ModelRendererRegistry = class {
|
|
190
190
|
models = /* @__PURE__ */ new Map();
|
|
191
|
-
register(
|
|
192
|
-
if (typeof
|
|
191
|
+
register(model11) {
|
|
192
|
+
if (typeof model11.name !== "string" || !/^[a-z]+$/.test(model11.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(
|
|
198
|
-
throw new Error(`Model renderer "${
|
|
197
|
+
if (this.models.has(model11.name)) {
|
|
198
|
+
throw new Error(`Model renderer "${model11.name}" is already registered`);
|
|
199
199
|
}
|
|
200
|
-
if (
|
|
200
|
+
if (model11.pads !== "none" && model11.pads !== "footprinter") {
|
|
201
201
|
throw new Error('Model renderer pads must be "none" or "footprinter"');
|
|
202
202
|
}
|
|
203
|
-
const { name, schema, render: render2, pads } =
|
|
203
|
+
const { name, schema, render: render2, pads } = model11;
|
|
204
204
|
this.models.set(name, {
|
|
205
205
|
name,
|
|
206
206
|
schema,
|
|
@@ -226,6 +226,161 @@ var ModelRendererRegistry = class {
|
|
|
226
226
|
}
|
|
227
227
|
};
|
|
228
228
|
|
|
229
|
+
// lib/models/flatheadscrew/mesh.ts
|
|
230
|
+
import {
|
|
231
|
+
flatHeadScrewModelPropsSchema
|
|
232
|
+
} from "@tscircuit/modelprinter";
|
|
233
|
+
function createFlatHeadScrewMesh(input, options = {}) {
|
|
234
|
+
const p = flatHeadScrewModelPropsSchema.parse(input);
|
|
235
|
+
const segments = options.radialSegments ?? 96;
|
|
236
|
+
const axial = options.threadStepsPerTurn ?? 24;
|
|
237
|
+
if (!Number.isInteger(segments) || segments < 24 || segments > 192 || segments % 24 !== 0 || !Number.isInteger(axial) || axial < 24 || axial > 96)
|
|
238
|
+
throw new Error(
|
|
239
|
+
"Screw mesh resolution requires 24..192 radial segments divisible by 24 and 24..96 thread steps"
|
|
240
|
+
);
|
|
241
|
+
const positions = [], indices = [];
|
|
242
|
+
const welded = /* @__PURE__ */ new Map();
|
|
243
|
+
const vertex = (x, y, z) => {
|
|
244
|
+
const key = [x, y, z].map((v) => Math.round(v * 1e10)).join(":");
|
|
245
|
+
const existing = welded.get(key);
|
|
246
|
+
if (existing !== void 0) return existing;
|
|
247
|
+
const index = positions.length / 3;
|
|
248
|
+
positions.push(x, y, z);
|
|
249
|
+
welded.set(key, index);
|
|
250
|
+
return index;
|
|
251
|
+
};
|
|
252
|
+
const triangle = (a, b, c) => {
|
|
253
|
+
if (a === b || b === c || c === a) return;
|
|
254
|
+
const point = (i) => positions.slice(3 * i, 3 * i + 3);
|
|
255
|
+
const A = point(a), B = point(b), C = point(c);
|
|
256
|
+
const u = B.map((v2, i) => v2 - A[i]), v = C.map((w, i) => w - A[i]);
|
|
257
|
+
const area = Math.hypot(
|
|
258
|
+
u[1] * v[2] - u[2] * v[1],
|
|
259
|
+
u[2] * v[0] - u[0] * v[2],
|
|
260
|
+
u[0] * v[1] - u[1] * v[0]
|
|
261
|
+
);
|
|
262
|
+
if (area > 1e-12) indices.push(a, b, c);
|
|
263
|
+
};
|
|
264
|
+
const ring = (radiusAt, zAt) => Array.from({ length: segments }, (_, i) => {
|
|
265
|
+
const theta = i * 2 * Math.PI / segments, r = radiusAt(theta);
|
|
266
|
+
return vertex(
|
|
267
|
+
r * Math.cos(theta),
|
|
268
|
+
r * Math.sin(theta),
|
|
269
|
+
typeof zAt === "number" ? zAt : zAt(theta)
|
|
270
|
+
);
|
|
271
|
+
});
|
|
272
|
+
const connect = (a, b) => {
|
|
273
|
+
for (let i = 0; i < segments; i++) {
|
|
274
|
+
const n = (i + 1) % segments;
|
|
275
|
+
triangle(a[i], a[n], b[n]);
|
|
276
|
+
triangle(a[i], b[n], b[i]);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
const cap = (a, z, up) => {
|
|
280
|
+
const c = vertex(0, 0, z);
|
|
281
|
+
for (let i = 0; i < segments; i++) {
|
|
282
|
+
const n = (i + 1) % segments;
|
|
283
|
+
up ? triangle(c, a[i], a[n]) : triangle(c, a[n], a[i]);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
let previous = [];
|
|
287
|
+
const add = (radiusAt, zAt) => {
|
|
288
|
+
const r = ring(radiusAt, zAt);
|
|
289
|
+
if (previous.length) connect(previous, r);
|
|
290
|
+
previous = r;
|
|
291
|
+
return r;
|
|
292
|
+
};
|
|
293
|
+
const major = p.diameter / 2, minor = p.threadRootDiameter / 2, pitch = p.threadPitch;
|
|
294
|
+
const shaftEnd = -p.headHeight - p.underHeadRadius * (Math.sqrt(2) - 1);
|
|
295
|
+
const steps = p.showThreads ? Math.ceil((shaftEnd + p.length) / pitch * axial) : 1;
|
|
296
|
+
if ((steps + 100) * segments > 4e5)
|
|
297
|
+
throw new Error("Screw exceeds mesh resolution limit");
|
|
298
|
+
const levels = /* @__PURE__ */ new Set([
|
|
299
|
+
-p.length,
|
|
300
|
+
-p.length + p.tipChamfer,
|
|
301
|
+
shaftEnd
|
|
302
|
+
]);
|
|
303
|
+
if (p.showThreads)
|
|
304
|
+
for (let i = 0; i <= steps; i++)
|
|
305
|
+
levels.add(-p.length + (shaftEnd + p.length) * i / steps);
|
|
306
|
+
for (const z of [...levels].sort((a, b) => a - b)) {
|
|
307
|
+
const r = add((theta) => {
|
|
308
|
+
const phase = (((z + p.length) / pitch - (p.threadHand === "right" ? 1 : -1) * theta / (2 * Math.PI)) % 1 + 1) % 1;
|
|
309
|
+
const d = Math.min(phase, 1 - phase);
|
|
310
|
+
const groove = Math.min(
|
|
311
|
+
major - minor,
|
|
312
|
+
Math.max(0, (d - 1 / 16) * pitch * Math.sqrt(3))
|
|
313
|
+
);
|
|
314
|
+
const thread = p.showThreads ? major - groove : major;
|
|
315
|
+
return Math.min(
|
|
316
|
+
thread,
|
|
317
|
+
major - Math.max(0, p.tipChamfer - (z + p.length))
|
|
318
|
+
);
|
|
319
|
+
}, z);
|
|
320
|
+
if (z === -p.length) cap(r, z, false);
|
|
321
|
+
}
|
|
322
|
+
add(() => major, shaftEnd);
|
|
323
|
+
const filletCenterR = major + p.underHeadRadius;
|
|
324
|
+
const filletCenterZ = shaftEnd;
|
|
325
|
+
for (let i = 1; i <= 16; i++) {
|
|
326
|
+
const angle = Math.PI - (Math.PI - 3 * Math.PI / 4) * i / 16;
|
|
327
|
+
add(
|
|
328
|
+
() => filletCenterR + p.underHeadRadius * Math.cos(angle),
|
|
329
|
+
filletCenterZ + p.underHeadRadius * Math.sin(angle)
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
const hexRadius = (theta) => p.socketAcrossFlats / 2 / Math.max(
|
|
333
|
+
Math.abs(Math.sin(theta)),
|
|
334
|
+
Math.abs(Math.sin(theta + 2 * Math.PI / 3)),
|
|
335
|
+
Math.abs(Math.sin(theta + 4 * Math.PI / 3))
|
|
336
|
+
);
|
|
337
|
+
add(() => p.headDiameter / 2, 0);
|
|
338
|
+
add(hexRadius, 0);
|
|
339
|
+
add(hexRadius, -p.socketDepth);
|
|
340
|
+
cap(previous, -p.socketDepth, true);
|
|
341
|
+
return { positions, indices };
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// lib/mechanical/indexedMeshToGeom3.ts
|
|
345
|
+
import jscad from "@jscad/modeling";
|
|
346
|
+
function indexedMeshToGeom3(mesh) {
|
|
347
|
+
const polygons = [];
|
|
348
|
+
for (let i = 0; i < mesh.indices.length; i += 3)
|
|
349
|
+
polygons.push(
|
|
350
|
+
mesh.indices.slice(i, i + 3).map((index) => [
|
|
351
|
+
mesh.positions[index * 3],
|
|
352
|
+
mesh.positions[index * 3 + 1],
|
|
353
|
+
mesh.positions[index * 3 + 2]
|
|
354
|
+
])
|
|
355
|
+
);
|
|
356
|
+
return jscad.geometries.geom3.fromPoints(polygons);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// lib/models/flatheadscrew/FlatHeadScrew.tsx
|
|
360
|
+
function createFlatHeadScrewGeom(input, options) {
|
|
361
|
+
return indexedMeshToGeom3(createFlatHeadScrewMesh(input, options));
|
|
362
|
+
}
|
|
363
|
+
function FlatHeadScrew({
|
|
364
|
+
color = "#737e8f",
|
|
365
|
+
...props
|
|
366
|
+
}) {
|
|
367
|
+
return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createFlatHeadScrewGeom(props) }) });
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// lib/models/flatheadscrew/register.tsx
|
|
371
|
+
var model = defineModelRenderer({
|
|
372
|
+
name: "flatheadscrew",
|
|
373
|
+
schema: flatHeadScrewModelDefinitionSchema,
|
|
374
|
+
render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlatHeadScrew, { ...props }),
|
|
375
|
+
pads: "none"
|
|
376
|
+
});
|
|
377
|
+
function register(registry) {
|
|
378
|
+
registry.register(model);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// lib/models/flexscreen/register.tsx
|
|
382
|
+
import { flexScreenModelDefinitionSchema } from "@tscircuit/modelprinter";
|
|
383
|
+
|
|
229
384
|
// lib/Screen.tsx
|
|
230
385
|
var Screen = ({
|
|
231
386
|
width: width10 = 30,
|
|
@@ -898,34 +1053,19 @@ var FlexScreen = (props) => {
|
|
|
898
1053
|
};
|
|
899
1054
|
|
|
900
1055
|
// lib/models/flexscreen/register.tsx
|
|
901
|
-
var
|
|
1056
|
+
var model2 = defineModelRenderer({
|
|
902
1057
|
name: "flexscreen",
|
|
903
1058
|
schema: flexScreenModelDefinitionSchema,
|
|
904
1059
|
render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlexScreen, { ...props }),
|
|
905
1060
|
pads: "footprinter"
|
|
906
1061
|
});
|
|
907
|
-
function
|
|
908
|
-
registry.register(
|
|
1062
|
+
function register2(registry) {
|
|
1063
|
+
registry.register(model2);
|
|
909
1064
|
}
|
|
910
1065
|
|
|
911
1066
|
// lib/models/helicalgear/register.tsx
|
|
912
1067
|
import { helicalGearModelDefinitionSchema } from "@tscircuit/modelprinter";
|
|
913
1068
|
|
|
914
|
-
// lib/mechanical/indexedMeshToGeom3.ts
|
|
915
|
-
import jscad from "@jscad/modeling";
|
|
916
|
-
function indexedMeshToGeom3(mesh) {
|
|
917
|
-
const polygons = [];
|
|
918
|
-
for (let i = 0; i < mesh.indices.length; i += 3)
|
|
919
|
-
polygons.push(
|
|
920
|
-
mesh.indices.slice(i, i + 3).map((index) => [
|
|
921
|
-
mesh.positions[index * 3],
|
|
922
|
-
mesh.positions[index * 3 + 1],
|
|
923
|
-
mesh.positions[index * 3 + 2]
|
|
924
|
-
])
|
|
925
|
-
);
|
|
926
|
-
return jscad.geometries.geom3.fromPoints(polygons);
|
|
927
|
-
}
|
|
928
|
-
|
|
929
1069
|
// lib/mechanical/helical-gear-mesh.ts
|
|
930
1070
|
import {
|
|
931
1071
|
getHelicalGearDimensions,
|
|
@@ -1126,14 +1266,14 @@ function HelicalGear({ color = "#737e8f", ...props }) {
|
|
|
1126
1266
|
}
|
|
1127
1267
|
|
|
1128
1268
|
// lib/models/helicalgear/register.tsx
|
|
1129
|
-
var
|
|
1269
|
+
var model3 = defineModelRenderer({
|
|
1130
1270
|
name: "helicalgear",
|
|
1131
1271
|
schema: helicalGearModelDefinitionSchema,
|
|
1132
1272
|
render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HelicalGear, { ...props }),
|
|
1133
1273
|
pads: "none"
|
|
1134
1274
|
});
|
|
1135
|
-
function
|
|
1136
|
-
registry.register(
|
|
1275
|
+
function register3(registry) {
|
|
1276
|
+
registry.register(model3);
|
|
1137
1277
|
}
|
|
1138
1278
|
|
|
1139
1279
|
// lib/models/hexbolt/register.tsx
|
|
@@ -1274,14 +1414,14 @@ function HexBolt({ color = "#737e8f", ...props }) {
|
|
|
1274
1414
|
}
|
|
1275
1415
|
|
|
1276
1416
|
// lib/models/hexbolt/register.tsx
|
|
1277
|
-
var
|
|
1417
|
+
var model4 = defineModelRenderer({
|
|
1278
1418
|
name: "hexbolt",
|
|
1279
1419
|
schema: hexBoltModelDefinitionSchema,
|
|
1280
1420
|
render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexBolt, { ...props }),
|
|
1281
1421
|
pads: "none"
|
|
1282
1422
|
});
|
|
1283
|
-
function
|
|
1284
|
-
registry.register(
|
|
1423
|
+
function register4(registry) {
|
|
1424
|
+
registry.register(model4);
|
|
1285
1425
|
}
|
|
1286
1426
|
|
|
1287
1427
|
// lib/models/hexsocketbolt/register.tsx
|
|
@@ -1393,14 +1533,14 @@ function HexSocketBolt({
|
|
|
1393
1533
|
}
|
|
1394
1534
|
|
|
1395
1535
|
// lib/models/hexsocketbolt/register.tsx
|
|
1396
|
-
var
|
|
1536
|
+
var model5 = defineModelRenderer({
|
|
1397
1537
|
name: "hexsocketbolt",
|
|
1398
1538
|
schema: hexSocketBoltModelDefinitionSchema,
|
|
1399
1539
|
render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexSocketBolt, { ...props }),
|
|
1400
1540
|
pads: "none"
|
|
1401
1541
|
});
|
|
1402
|
-
function
|
|
1403
|
-
registry.register(
|
|
1542
|
+
function register5(registry) {
|
|
1543
|
+
registry.register(model5);
|
|
1404
1544
|
}
|
|
1405
1545
|
|
|
1406
1546
|
// lib/models/nema/register.tsx
|
|
@@ -1669,14 +1809,233 @@ var NEMA17 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 17
|
|
|
1669
1809
|
var NEMA23 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 23 });
|
|
1670
1810
|
|
|
1671
1811
|
// lib/models/nema/register.tsx
|
|
1672
|
-
var
|
|
1812
|
+
var model6 = defineModelRenderer({
|
|
1673
1813
|
name: "nema",
|
|
1674
1814
|
schema: nemaMotorModelDefinitionSchema,
|
|
1675
1815
|
render: ({ fn, ...props }) => /* @__PURE__ */ jsx(NemaMotor, { ...props }),
|
|
1676
1816
|
pads: "none"
|
|
1677
1817
|
});
|
|
1678
|
-
function
|
|
1679
|
-
registry.register(
|
|
1818
|
+
function register6(registry) {
|
|
1819
|
+
registry.register(model6);
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
// lib/models/panscrew/register.tsx
|
|
1823
|
+
import { panScrewModelDefinitionSchema } from "@tscircuit/modelprinter";
|
|
1824
|
+
|
|
1825
|
+
// lib/models/panscrew/mesh.ts
|
|
1826
|
+
import {
|
|
1827
|
+
panScrewModelPropsSchema
|
|
1828
|
+
} from "@tscircuit/modelprinter";
|
|
1829
|
+
function createPanScrewMesh(input, options = {}) {
|
|
1830
|
+
const p = panScrewModelPropsSchema.parse(input);
|
|
1831
|
+
const segments = options.radialSegments ?? 96;
|
|
1832
|
+
const axial = options.threadStepsPerTurn ?? 24;
|
|
1833
|
+
if (!Number.isInteger(segments) || segments < 24 || segments > 192 || segments % 24 !== 0 || !Number.isInteger(axial) || axial < 24 || axial > 96)
|
|
1834
|
+
throw new Error(
|
|
1835
|
+
"Screw mesh resolution requires 24..192 radial segments divisible by 24 and 24..96 thread steps"
|
|
1836
|
+
);
|
|
1837
|
+
const positions = [], indices = [];
|
|
1838
|
+
const welded = /* @__PURE__ */ new Map();
|
|
1839
|
+
const vertex = (x, y, z) => {
|
|
1840
|
+
const key = [x, y, z].map((v) => Math.round(v * 1e10)).join(":");
|
|
1841
|
+
const existing = welded.get(key);
|
|
1842
|
+
if (existing !== void 0) return existing;
|
|
1843
|
+
const index = positions.length / 3;
|
|
1844
|
+
positions.push(x, y, z);
|
|
1845
|
+
welded.set(key, index);
|
|
1846
|
+
return index;
|
|
1847
|
+
};
|
|
1848
|
+
const triangle = (a, b, c) => {
|
|
1849
|
+
if (a === b || b === c || c === a) return;
|
|
1850
|
+
const point2 = (i) => positions.slice(3 * i, 3 * i + 3);
|
|
1851
|
+
const A = point2(a), B = point2(b), C = point2(c);
|
|
1852
|
+
const u = B.map((v2, i) => v2 - A[i]), v = C.map((w, i) => w - A[i]);
|
|
1853
|
+
const area = Math.hypot(
|
|
1854
|
+
u[1] * v[2] - u[2] * v[1],
|
|
1855
|
+
u[2] * v[0] - u[0] * v[2],
|
|
1856
|
+
u[0] * v[1] - u[1] * v[0]
|
|
1857
|
+
);
|
|
1858
|
+
if (area > 1e-12) indices.push(a, b, c);
|
|
1859
|
+
};
|
|
1860
|
+
const ring = (radiusAt, zAt) => Array.from({ length: segments }, (_, i) => {
|
|
1861
|
+
const theta = i * 2 * Math.PI / segments, r = radiusAt(theta);
|
|
1862
|
+
return vertex(
|
|
1863
|
+
r * Math.cos(theta),
|
|
1864
|
+
r * Math.sin(theta),
|
|
1865
|
+
typeof zAt === "number" ? zAt : zAt(theta)
|
|
1866
|
+
);
|
|
1867
|
+
});
|
|
1868
|
+
const connect = (a, b) => {
|
|
1869
|
+
for (let i = 0; i < segments; i++) {
|
|
1870
|
+
const n = (i + 1) % segments;
|
|
1871
|
+
triangle(a[i], a[n], b[n]);
|
|
1872
|
+
triangle(a[i], b[n], b[i]);
|
|
1873
|
+
}
|
|
1874
|
+
};
|
|
1875
|
+
const cap = (a, z, up) => {
|
|
1876
|
+
const c = vertex(0, 0, z);
|
|
1877
|
+
for (let i = 0; i < segments; i++) {
|
|
1878
|
+
const n = (i + 1) % segments;
|
|
1879
|
+
up ? triangle(c, a[i], a[n]) : triangle(c, a[n], a[i]);
|
|
1880
|
+
}
|
|
1881
|
+
};
|
|
1882
|
+
let previous = [];
|
|
1883
|
+
const add = (radiusAt, zAt) => {
|
|
1884
|
+
const r = ring(radiusAt, zAt);
|
|
1885
|
+
if (previous.length) connect(previous, r);
|
|
1886
|
+
previous = r;
|
|
1887
|
+
return r;
|
|
1888
|
+
};
|
|
1889
|
+
const major = p.diameter / 2, minor = p.threadRootDiameter / 2, pitch = p.threadPitch;
|
|
1890
|
+
const shaftEnd = -p.underHeadRadius;
|
|
1891
|
+
const steps = p.showThreads ? Math.ceil((shaftEnd + p.length) / pitch * axial) : 1;
|
|
1892
|
+
if ((steps + 160) * segments > 4e5)
|
|
1893
|
+
throw new Error("Screw exceeds mesh resolution limit");
|
|
1894
|
+
const levels = /* @__PURE__ */ new Set([
|
|
1895
|
+
-p.length,
|
|
1896
|
+
-p.length + p.tipChamfer,
|
|
1897
|
+
shaftEnd
|
|
1898
|
+
]);
|
|
1899
|
+
if (p.showThreads)
|
|
1900
|
+
for (let i = 0; i <= steps; i++)
|
|
1901
|
+
levels.add(-p.length + (shaftEnd + p.length) * i / steps);
|
|
1902
|
+
for (const z of [...levels].sort((a, b) => a - b)) {
|
|
1903
|
+
const r = add((theta) => {
|
|
1904
|
+
const phase = (((z + p.length) / pitch - (p.threadHand === "right" ? 1 : -1) * theta / (2 * Math.PI)) % 1 + 1) % 1;
|
|
1905
|
+
const d = Math.min(phase, 1 - phase);
|
|
1906
|
+
const groove = Math.min(
|
|
1907
|
+
major - minor,
|
|
1908
|
+
Math.max(0, (d - 1 / 16) * pitch * Math.sqrt(3))
|
|
1909
|
+
);
|
|
1910
|
+
const thread = p.showThreads ? major - groove : major;
|
|
1911
|
+
return Math.min(
|
|
1912
|
+
thread,
|
|
1913
|
+
major - Math.max(0, p.tipChamfer - (z + p.length))
|
|
1914
|
+
);
|
|
1915
|
+
}, z);
|
|
1916
|
+
if (z === -p.length) cap(r, z, false);
|
|
1917
|
+
}
|
|
1918
|
+
add(() => major, shaftEnd);
|
|
1919
|
+
const filletCenterR = major + p.underHeadRadius;
|
|
1920
|
+
const filletCenterZ = shaftEnd;
|
|
1921
|
+
for (let i = 1; i <= 16; i++) {
|
|
1922
|
+
const angle = Math.PI - (Math.PI - Math.PI / 2) * i / 16;
|
|
1923
|
+
add(
|
|
1924
|
+
() => filletCenterR + p.underHeadRadius * Math.cos(angle),
|
|
1925
|
+
filletCenterZ + p.underHeadRadius * Math.sin(angle)
|
|
1926
|
+
);
|
|
1927
|
+
}
|
|
1928
|
+
const crown = (r) => p.headHeight - p.crownRadius + Math.sqrt(p.crownRadius * p.crownRadius - r * r);
|
|
1929
|
+
const rad265 = p.recessOuterWingAngle * Math.PI / 180, rad28 = p.recessInnerWingAngle * Math.PI / 180;
|
|
1930
|
+
const tg = (p.recessReferenceDiameter - p.recessG) / 2 / Math.tan(rad265);
|
|
1931
|
+
const totalDepth = tg + p.recessG / 2 * Math.tan(rad28);
|
|
1932
|
+
const tb = tg + (p.recessG - p.recessB) / 2 * Math.tan(rad28);
|
|
1933
|
+
const beta = p.recessBeta * Math.PI / 180;
|
|
1934
|
+
const alphaProjected = Math.atan(
|
|
1935
|
+
Math.tan(p.recessAlpha * Math.PI / 360) / Math.cos(beta)
|
|
1936
|
+
);
|
|
1937
|
+
const cornerProjected = Math.atan(
|
|
1938
|
+
Math.tan(46 * Math.PI / 180) / Math.cos(beta)
|
|
1939
|
+
);
|
|
1940
|
+
const dre = p.recessE / 2 / Math.tan(alphaProjected);
|
|
1941
|
+
const cornerRadius = (z, theta) => {
|
|
1942
|
+
const depth = p.recessReferencePlaneHeight - z;
|
|
1943
|
+
const b = p.recessB / 2 - (depth - tb) * Math.tan(beta);
|
|
1944
|
+
const delta = Math.abs(
|
|
1945
|
+
(theta - Math.PI / 4 + Math.PI / 4 + 4 * Math.PI) % (Math.PI / 2) - Math.PI / 4
|
|
1946
|
+
);
|
|
1947
|
+
const ca = Math.cos(delta), sa = Math.sin(delta);
|
|
1948
|
+
const tanA = Math.tan(alphaProjected), tanC = Math.tan(cornerProjected);
|
|
1949
|
+
const first = tanA * b / (tanA * ca - sa);
|
|
1950
|
+
const corner = first * ca <= b + dre ? first : (tanC * (b + dre) - p.recessE / 2) / (tanC * ca - sa);
|
|
1951
|
+
return Math.max(0, corner);
|
|
1952
|
+
};
|
|
1953
|
+
const recessRadius = (z, theta) => {
|
|
1954
|
+
const depth = p.recessReferencePlaneHeight - z;
|
|
1955
|
+
const outer = depth <= tg ? p.recessReferenceDiameter / 2 - depth * Math.tan(rad265) : (totalDepth - depth) / Math.tan(rad28);
|
|
1956
|
+
return Math.max(0, Math.min(outer, cornerRadius(z, theta)));
|
|
1957
|
+
};
|
|
1958
|
+
const entryRadius = p.recessRadius, sphereZ = p.headHeight - p.crownRadius, slope = Math.tan(rad265), line = p.recessReferenceDiameter / 2 - slope * p.recessReferencePlaneHeight + entryRadius / Math.cos(rad265), offset = slope * sphereZ + line, innerSphere = p.crownRadius - entryRadius, centerAboveSphere = (-slope * offset + Math.sqrt((1 + slope * slope) * innerSphere ** 2 - offset ** 2)) / (1 + slope * slope), entryCenterZ = sphereZ + centerAboveSphere, entryCenterR = slope * entryCenterZ + line, entryStart = Math.atan2(centerAboveSphere, entryCenterR), entryEnd = Math.PI - rad265, mouthR = entryCenterR + entryRadius * Math.cos(entryStart), wallZ = entryCenterZ + entryRadius * Math.sin(entryEnd);
|
|
1959
|
+
add(() => p.headDiameter / 2, 0);
|
|
1960
|
+
add(() => p.headDiameter / 2, crown(p.headDiameter / 2));
|
|
1961
|
+
const opening = Array.from({ length: segments }, (_, i) => {
|
|
1962
|
+
const theta = i * 2 * Math.PI / segments;
|
|
1963
|
+
let lo = 0, hi = mouthR;
|
|
1964
|
+
for (let n = 0; n < 48; n++) {
|
|
1965
|
+
const r = (lo + hi) / 2;
|
|
1966
|
+
if (r < cornerRadius(crown(r), theta)) lo = r;
|
|
1967
|
+
else hi = r;
|
|
1968
|
+
}
|
|
1969
|
+
return (lo + hi) / 2;
|
|
1970
|
+
});
|
|
1971
|
+
for (let n = 1; n <= 20; n++) {
|
|
1972
|
+
const r = (theta) => {
|
|
1973
|
+
const i = Math.round(theta * segments / (2 * Math.PI)) % segments;
|
|
1974
|
+
return p.headDiameter / 2 + (opening[i] - p.headDiameter / 2) * n / 20;
|
|
1975
|
+
};
|
|
1976
|
+
add(r, (theta) => crown(r(theta)));
|
|
1977
|
+
}
|
|
1978
|
+
const entryClips = Array.from({ length: segments }, (_, i) => {
|
|
1979
|
+
const theta = i * 2 * Math.PI / segments;
|
|
1980
|
+
const point2 = (angle2) => ({
|
|
1981
|
+
r: entryCenterR + entryRadius * Math.cos(angle2),
|
|
1982
|
+
z: entryCenterZ + entryRadius * Math.sin(angle2)
|
|
1983
|
+
});
|
|
1984
|
+
const outside = (angle2) => {
|
|
1985
|
+
const q = point2(angle2);
|
|
1986
|
+
return q.r > cornerRadius(q.z, theta);
|
|
1987
|
+
};
|
|
1988
|
+
if (!outside(entryStart)) return { angle: entryStart, ...point2(entryStart) };
|
|
1989
|
+
if (outside(entryEnd))
|
|
1990
|
+
return { angle: entryEnd, r: cornerRadius(wallZ, theta), z: wallZ };
|
|
1991
|
+
let lo = entryStart, hi = entryEnd;
|
|
1992
|
+
for (let n = 0; n < 48; n++) {
|
|
1993
|
+
const angle2 = (lo + hi) / 2;
|
|
1994
|
+
if (outside(angle2)) lo = angle2;
|
|
1995
|
+
else hi = angle2;
|
|
1996
|
+
}
|
|
1997
|
+
const angle = (lo + hi) / 2;
|
|
1998
|
+
return { angle, ...point2(angle) };
|
|
1999
|
+
});
|
|
2000
|
+
for (let n = 0; n <= 24; n++) {
|
|
2001
|
+
const angle = entryStart + (entryEnd - entryStart) * n / 24;
|
|
2002
|
+
const r = entryCenterR + entryRadius * Math.cos(angle), z = entryCenterZ + entryRadius * Math.sin(angle);
|
|
2003
|
+
const clip = (theta) => entryClips[Math.round(theta * segments / (2 * Math.PI)) % segments];
|
|
2004
|
+
add(
|
|
2005
|
+
(theta) => angle <= clip(theta).angle ? clip(theta).r : r,
|
|
2006
|
+
(theta) => angle <= clip(theta).angle ? clip(theta).z : z
|
|
2007
|
+
);
|
|
2008
|
+
}
|
|
2009
|
+
const floor = p.recessReferencePlaneHeight - totalDepth;
|
|
2010
|
+
const driveLevels = /* @__PURE__ */ new Set([p.recessReferencePlaneHeight - tg]);
|
|
2011
|
+
for (let n = 1; n < 48; n++)
|
|
2012
|
+
driveLevels.add(wallZ + (floor - wallZ) * n / 48);
|
|
2013
|
+
for (const z of [...driveLevels].filter((z2) => z2 < wallZ && z2 > floor).sort((a, b) => b - a)) {
|
|
2014
|
+
add((theta) => recessRadius(z, theta), z);
|
|
2015
|
+
}
|
|
2016
|
+
const point = vertex(0, 0, floor);
|
|
2017
|
+
for (let i = 0; i < segments; i++)
|
|
2018
|
+
triangle(point, previous[i], previous[(i + 1) % segments]);
|
|
2019
|
+
return { positions, indices };
|
|
2020
|
+
}
|
|
2021
|
+
|
|
2022
|
+
// lib/models/panscrew/PanScrew.tsx
|
|
2023
|
+
function createPanScrewGeom(input, options) {
|
|
2024
|
+
return indexedMeshToGeom3(createPanScrewMesh(input, options));
|
|
2025
|
+
}
|
|
2026
|
+
function PanScrew({ color = "#737e8f", ...props }) {
|
|
2027
|
+
return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createPanScrewGeom(props) }) });
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
// lib/models/panscrew/register.tsx
|
|
2031
|
+
var model7 = defineModelRenderer({
|
|
2032
|
+
name: "panscrew",
|
|
2033
|
+
schema: panScrewModelDefinitionSchema,
|
|
2034
|
+
render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PanScrew, { ...props }),
|
|
2035
|
+
pads: "none"
|
|
2036
|
+
});
|
|
2037
|
+
function register7(registry) {
|
|
2038
|
+
registry.register(model7);
|
|
1680
2039
|
}
|
|
1681
2040
|
|
|
1682
2041
|
// lib/models/sheetmetal/register.tsx
|
|
@@ -1836,14 +2195,14 @@ function SheetMetal({ color = "#737e8f", ...props }) {
|
|
|
1836
2195
|
}
|
|
1837
2196
|
|
|
1838
2197
|
// lib/models/sheetmetal/register.tsx
|
|
1839
|
-
var
|
|
2198
|
+
var model8 = defineModelRenderer({
|
|
1840
2199
|
name: "sheetmetal",
|
|
1841
2200
|
schema: sheetMetalModelDefinitionSchema,
|
|
1842
2201
|
render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SheetMetal, { ...props }),
|
|
1843
2202
|
pads: "none"
|
|
1844
2203
|
});
|
|
1845
|
-
function
|
|
1846
|
-
registry.register(
|
|
2204
|
+
function register8(registry) {
|
|
2205
|
+
registry.register(model8);
|
|
1847
2206
|
}
|
|
1848
2207
|
|
|
1849
2208
|
// lib/models/spurgear/register.tsx
|
|
@@ -1858,14 +2217,14 @@ function SpurGear({ color = "#737e8f", ...props }) {
|
|
|
1858
2217
|
}
|
|
1859
2218
|
|
|
1860
2219
|
// lib/models/spurgear/register.tsx
|
|
1861
|
-
var
|
|
2220
|
+
var model9 = defineModelRenderer({
|
|
1862
2221
|
name: "spurgear",
|
|
1863
2222
|
schema: spurGearModelDefinitionSchema,
|
|
1864
2223
|
render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SpurGear, { ...props }),
|
|
1865
2224
|
pads: "none"
|
|
1866
2225
|
});
|
|
1867
|
-
function
|
|
1868
|
-
registry.register(
|
|
2226
|
+
function register9(registry) {
|
|
2227
|
+
registry.register(model9);
|
|
1869
2228
|
}
|
|
1870
2229
|
|
|
1871
2230
|
// lib/models/wormgear/register.tsx
|
|
@@ -2057,14 +2416,14 @@ function WormGear({ color = "#737e8f", ...props }) {
|
|
|
2057
2416
|
}
|
|
2058
2417
|
|
|
2059
2418
|
// lib/models/wormgear/register.tsx
|
|
2060
|
-
var
|
|
2419
|
+
var model10 = defineModelRenderer({
|
|
2061
2420
|
name: "wormgear",
|
|
2062
2421
|
schema: wormGearModelDefinitionSchema,
|
|
2063
2422
|
render: ({ fn, ...props }) => /* @__PURE__ */ jsx(WormGear, { ...props }),
|
|
2064
2423
|
pads: "none"
|
|
2065
2424
|
});
|
|
2066
|
-
function
|
|
2067
|
-
registry.register(
|
|
2425
|
+
function register10(registry) {
|
|
2426
|
+
registry.register(model10);
|
|
2068
2427
|
}
|
|
2069
2428
|
|
|
2070
2429
|
// lib/generated/model-renderers.ts
|
|
@@ -2077,6 +2436,8 @@ function registerAllModelRenderers(registry) {
|
|
|
2077
2436
|
register6(registry);
|
|
2078
2437
|
register7(registry);
|
|
2079
2438
|
register8(registry);
|
|
2439
|
+
register9(registry);
|
|
2440
|
+
register10(registry);
|
|
2080
2441
|
}
|
|
2081
2442
|
|
|
2082
2443
|
// lib/default-model-registry.ts
|
|
@@ -9633,10 +9994,10 @@ var SOT143 = ({ footprint = "sot143" }) => {
|
|
|
9633
9994
|
var Footprinter3d = ({ footprint }) => {
|
|
9634
9995
|
const modelFn = mp3.string(footprint.split("_", 1)[0]).params().fn;
|
|
9635
9996
|
if (mp3.getModelNames().includes(modelFn)) {
|
|
9636
|
-
const
|
|
9637
|
-
const renderer = modelRendererRegistry.get(
|
|
9997
|
+
const model11 = mp3.string(footprint).json();
|
|
9998
|
+
const renderer = modelRendererRegistry.get(model11.fn);
|
|
9638
9999
|
if (renderer) {
|
|
9639
|
-
return renderer.render(
|
|
10000
|
+
return renderer.render(model11);
|
|
9640
10001
|
}
|
|
9641
10002
|
}
|
|
9642
10003
|
let normalizedFootprint = footprint;
|
|
@@ -10587,6 +10948,7 @@ function createJSCADRenderer(jscad4) {
|
|
|
10587
10948
|
return { createJSCADRoot };
|
|
10588
10949
|
}
|
|
10589
10950
|
export {
|
|
10951
|
+
FlatHeadScrew,
|
|
10590
10952
|
Fragment,
|
|
10591
10953
|
HelicalGear,
|
|
10592
10954
|
HexBolt,
|
|
@@ -10595,10 +10957,13 @@ export {
|
|
|
10595
10957
|
NEMA23,
|
|
10596
10958
|
NEMA8,
|
|
10597
10959
|
NemaMotor,
|
|
10960
|
+
PanScrew,
|
|
10598
10961
|
SheetMetal,
|
|
10599
10962
|
SpurGear,
|
|
10600
10963
|
WormGear,
|
|
10601
10964
|
convertCSGToThreeGeom,
|
|
10965
|
+
createFlatHeadScrewGeom,
|
|
10966
|
+
createFlatHeadScrewMesh,
|
|
10602
10967
|
createHelicalGearGeom,
|
|
10603
10968
|
createHelicalGearMesh,
|
|
10604
10969
|
createHexBoltGeom,
|
|
@@ -10606,6 +10971,8 @@ export {
|
|
|
10606
10971
|
createHexSocketBoltGeom,
|
|
10607
10972
|
createHexSocketBoltMesh,
|
|
10608
10973
|
createJSCADRenderer,
|
|
10974
|
+
createPanScrewGeom,
|
|
10975
|
+
createPanScrewMesh,
|
|
10609
10976
|
createSheetMetalGeom,
|
|
10610
10977
|
createSheetMetalMesh,
|
|
10611
10978
|
createSpurGearGeom,
|