@code3d/screws 0.0.1-alpha.0 → 0.0.1-alpha.2
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/README.md +18 -0
- package/bld/library/index.js +460 -2
- package/bld/library/index.js.map +7 -1
- package/bld/library/thread.d.ts.map +1 -1
- package/package.json +12 -6
- package/src/library/thread.ts +1 -41
- package/src/library/tsconfig.json +2 -1
- package/bld/library/iso-4762.js +0 -219
- package/bld/library/iso-4762.js.map +0 -1
- package/bld/library/thread.js +0 -181
- package/bld/library/thread.js.map +0 -1
package/README.md
CHANGED
|
@@ -44,3 +44,21 @@ Named mounting references such as `headBottom`, `shaftBottom`, and
|
|
|
44
44
|
`tool.shaftBottom.on(plate.down.flip())` aligns the shaft's lower boundary with
|
|
45
45
|
the plate's lower boundary without rotating the hole tool. `flip()` reverses
|
|
46
46
|
facing while preserving the offset coordinate frame.
|
|
47
|
+
|
|
48
|
+
## Install and explore
|
|
49
|
+
|
|
50
|
+
The App includes Screws when using its built-in Core. In Node or a project with
|
|
51
|
+
its own Core installation, install both packages:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
npm install @code3d/core @code3d/screws
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- [Public exports](src/library/index.ts), [ISO 4762 definitions and builders](src/library/iso-4762.ts),
|
|
58
|
+
and [thread geometry](src/library/thread.ts).
|
|
59
|
+
- [Complete mounting example](../app/examples/website/fastener.ts) and [behavior tests](test/iso-4762.test.ts).
|
|
60
|
+
- [Core relations and topology](../core/README.md), [modeling reference](../web/src/content/docs/docs/reference/screws.mdx),
|
|
61
|
+
and [agent modeling workflow](../../docs/agents/modeling.md).
|
|
62
|
+
|
|
63
|
+
From the repository root, run `npm run build:packages` and
|
|
64
|
+
`npm test --workspace @code3d/screws`.
|
package/bld/library/index.js
CHANGED
|
@@ -1,2 +1,460 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// packages/screws/src/library/iso-4762.ts
|
|
9
|
+
var iso_4762_exports = {};
|
|
10
|
+
__export(iso_4762_exports, {
|
|
11
|
+
clearanceHole: () => clearanceHole,
|
|
12
|
+
resolveSpecification: () => resolveSpecification,
|
|
13
|
+
screw: () => screw,
|
|
14
|
+
specifications: () => specifications,
|
|
15
|
+
threadLength: () => threadLength
|
|
16
|
+
});
|
|
17
|
+
import {
|
|
18
|
+
cylinder,
|
|
19
|
+
cut,
|
|
20
|
+
frustum,
|
|
21
|
+
regularPrism,
|
|
22
|
+
union
|
|
23
|
+
} from "@code3d/core";
|
|
24
|
+
|
|
25
|
+
// packages/screws/src/library/thread.ts
|
|
26
|
+
import {
|
|
27
|
+
definePrimitive,
|
|
28
|
+
replicad
|
|
29
|
+
} from "@code3d/core/replicad";
|
|
30
|
+
var { Plane, draw, makeCylinder, makeHelix, makeSolid, weldShellsAndFaces } = replicad;
|
|
31
|
+
var loopSteps = Array.from({ length: 21 }, (_, index) => index / 20);
|
|
32
|
+
var helicalThread = definePrimitive(
|
|
33
|
+
(options) => {
|
|
34
|
+
validateHelicalThread(options);
|
|
35
|
+
const {
|
|
36
|
+
majorDiameter,
|
|
37
|
+
minorDiameter,
|
|
38
|
+
leftHanded = false,
|
|
39
|
+
...dimensions
|
|
40
|
+
} = options;
|
|
41
|
+
return makeHelicalThreadShape({
|
|
42
|
+
...dimensions,
|
|
43
|
+
majorRadius: majorDiameter / 2,
|
|
44
|
+
minorRadius: minorDiameter / 2,
|
|
45
|
+
leftHanded
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
function validateHelicalThread({
|
|
50
|
+
pitch,
|
|
51
|
+
y,
|
|
52
|
+
majorDiameter,
|
|
53
|
+
minorDiameter,
|
|
54
|
+
rootWidth,
|
|
55
|
+
crestWidth
|
|
56
|
+
}) {
|
|
57
|
+
assertPositive("pitch", pitch);
|
|
58
|
+
assertPositive("y", y);
|
|
59
|
+
assertPositive("majorDiameter", majorDiameter);
|
|
60
|
+
assertPositive("minorDiameter", minorDiameter);
|
|
61
|
+
assertPositive("rootWidth", rootWidth);
|
|
62
|
+
assertPositive("crestWidth", crestWidth);
|
|
63
|
+
if (y < pitch) {
|
|
64
|
+
throw new Error("y must be at least one thread pitch.");
|
|
65
|
+
}
|
|
66
|
+
if (minorDiameter >= majorDiameter) {
|
|
67
|
+
throw new Error("minorDiameter must be smaller than majorDiameter.");
|
|
68
|
+
}
|
|
69
|
+
if (crestWidth >= rootWidth || rootWidth > pitch) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
"The thread profile requires crestWidth < rootWidth <= pitch."
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
__name(validateHelicalThread, "validateHelicalThread");
|
|
76
|
+
function makeHelicalThreadShape({
|
|
77
|
+
pitch,
|
|
78
|
+
y,
|
|
79
|
+
majorRadius,
|
|
80
|
+
minorRadius,
|
|
81
|
+
rootWidth,
|
|
82
|
+
crestWidth,
|
|
83
|
+
leftHanded
|
|
84
|
+
}) {
|
|
85
|
+
const toothHeight = majorRadius - minorRadius;
|
|
86
|
+
const profile = threadProfile(rootWidth, crestWidth, toothHeight);
|
|
87
|
+
const teeth = fadedThread(pitch, minorRadius, y, profile, leftHanded);
|
|
88
|
+
const core = makeCylinder(minorRadius + 0.05, y);
|
|
89
|
+
const threaded = core.fuse(teeth);
|
|
90
|
+
core.delete();
|
|
91
|
+
teeth.delete();
|
|
92
|
+
return threaded.rotate(-90, [0, 0, 0], [1, 0, 0]).translate([0, -y / 2, 0]);
|
|
93
|
+
}
|
|
94
|
+
__name(makeHelicalThreadShape, "makeHelicalThreadShape");
|
|
95
|
+
function threadProfile(rootWidth, crestWidth, toothHeight) {
|
|
96
|
+
const rootHalf = rootWidth / 2;
|
|
97
|
+
const crestHalf = crestWidth / 2;
|
|
98
|
+
return draw([rootHalf, -0.05]).vLine(0.05).lineTo([crestHalf, toothHeight]).hLineTo(-crestHalf).lineTo([-rootHalf, 0]).vLine(-0.05).close();
|
|
99
|
+
}
|
|
100
|
+
__name(threadProfile, "threadProfile");
|
|
101
|
+
function fadedThread(pitch, radius, length, profile, leftHanded) {
|
|
102
|
+
const bottomEnd = fadedEnd(pitch, radius, profile, true, leftHanded);
|
|
103
|
+
const totalLoops = length / pitch - 0.5;
|
|
104
|
+
const fullLoops = Math.floor(totalLoops);
|
|
105
|
+
const leftover = totalLoops - fullLoops;
|
|
106
|
+
const singleLoop = basicThreadLoop(
|
|
107
|
+
pitch,
|
|
108
|
+
radius,
|
|
109
|
+
profile,
|
|
110
|
+
1,
|
|
111
|
+
"none",
|
|
112
|
+
leftHanded
|
|
113
|
+
);
|
|
114
|
+
const shells = Array.from(
|
|
115
|
+
{ length: fullLoops },
|
|
116
|
+
(_, index) => singleLoop.clone().translate([0, 0, index * pitch])
|
|
117
|
+
);
|
|
118
|
+
singleLoop.delete();
|
|
119
|
+
if (leftover > 1e-9) {
|
|
120
|
+
shells.push(
|
|
121
|
+
basicThreadLoop(
|
|
122
|
+
pitch,
|
|
123
|
+
radius,
|
|
124
|
+
profile,
|
|
125
|
+
leftover,
|
|
126
|
+
"none",
|
|
127
|
+
leftHanded
|
|
128
|
+
).translate([0, 0, fullLoops * pitch])
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
const topEnd = fadedEnd(pitch, radius, profile, false, leftHanded).translate([0, 0, totalLoops * pitch]).rotate(360 * leftover, [0, 0, 0], [0, 0, 1]);
|
|
132
|
+
const thread = makeSolid([bottomEnd, ...shells, topEnd]).translate([
|
|
133
|
+
0,
|
|
134
|
+
0,
|
|
135
|
+
pitch / 4
|
|
136
|
+
]);
|
|
137
|
+
bottomEnd.delete();
|
|
138
|
+
shells.forEach((shell) => shell.delete());
|
|
139
|
+
topEnd.delete();
|
|
140
|
+
return thread;
|
|
141
|
+
}
|
|
142
|
+
__name(fadedThread, "fadedThread");
|
|
143
|
+
function basicThreadLoop(pitch, radius, profile, loopFraction, includeEnd, leftHanded) {
|
|
144
|
+
const helix = makeHelix(
|
|
145
|
+
pitch,
|
|
146
|
+
pitch * clamp(loopFraction, 0, 1),
|
|
147
|
+
radius,
|
|
148
|
+
[0, 0, 0],
|
|
149
|
+
[0, 0, 1],
|
|
150
|
+
leftHanded
|
|
151
|
+
);
|
|
152
|
+
const profiles = loopSteps.map((step) => {
|
|
153
|
+
const position = helix.pointAt(step);
|
|
154
|
+
const tangent = helix.tangentAt(step);
|
|
155
|
+
const plane = new Plane(position, [0, 0, 1], tangent);
|
|
156
|
+
const sketch = profile.sketchOnPlane(plane);
|
|
157
|
+
plane.delete();
|
|
158
|
+
return sketch;
|
|
159
|
+
});
|
|
160
|
+
helix.delete();
|
|
161
|
+
const ends = [];
|
|
162
|
+
if (includeEnd === "first" || includeEnd === "both") {
|
|
163
|
+
ends.push(profiles[0].faces());
|
|
164
|
+
}
|
|
165
|
+
if (includeEnd === "last" || includeEnd === "both") {
|
|
166
|
+
const face = profiles.at(-1).faces();
|
|
167
|
+
face.wrapped.Reverse();
|
|
168
|
+
ends.push(face);
|
|
169
|
+
}
|
|
170
|
+
const shell = profiles[0].loftWith(profiles.slice(1), { ruled: false }, true);
|
|
171
|
+
if (ends.length === 0) return shell;
|
|
172
|
+
const closed = weldShellsAndFaces([shell, ...ends]);
|
|
173
|
+
shell.delete();
|
|
174
|
+
ends.forEach((face) => face.delete());
|
|
175
|
+
return closed;
|
|
176
|
+
}
|
|
177
|
+
__name(basicThreadLoop, "basicThreadLoop");
|
|
178
|
+
function fadedEnd(pitch, radius, profile, bottom, leftHanded) {
|
|
179
|
+
const length = pitch / 4;
|
|
180
|
+
const helix = makeHelix(
|
|
181
|
+
pitch,
|
|
182
|
+
length,
|
|
183
|
+
radius,
|
|
184
|
+
[0, 0, 0],
|
|
185
|
+
[0, 0, bottom ? -1 : 1],
|
|
186
|
+
leftHanded
|
|
187
|
+
);
|
|
188
|
+
const profiles = loopSteps.map((step, index) => {
|
|
189
|
+
const position = helix.pointAt(step);
|
|
190
|
+
let tangent = helix.tangentAt(step);
|
|
191
|
+
if (bottom) tangent = tangent.multiply(-1);
|
|
192
|
+
const plane = new Plane(position, [0, 0, 1], tangent);
|
|
193
|
+
const sketch = profile.scale((loopSteps.length - index) / loopSteps.length, [0, 0]).sketchOnPlane(plane);
|
|
194
|
+
plane.delete();
|
|
195
|
+
return sketch;
|
|
196
|
+
});
|
|
197
|
+
helix.delete();
|
|
198
|
+
const endFace = profiles.at(-1).faces();
|
|
199
|
+
const shell = profiles[0].loftWith(profiles.slice(1), { ruled: false }, true);
|
|
200
|
+
const closed = weldShellsAndFaces([shell, endFace]);
|
|
201
|
+
shell.delete();
|
|
202
|
+
endFace.delete();
|
|
203
|
+
return bottom ? closed.rotate(180, [0, 0, 0], [0, 0, 1]) : closed;
|
|
204
|
+
}
|
|
205
|
+
__name(fadedEnd, "fadedEnd");
|
|
206
|
+
function assertPositive(name, value) {
|
|
207
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
208
|
+
throw new Error(`${name} must be a positive finite number.`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
__name(assertPositive, "assertPositive");
|
|
212
|
+
function clamp(value, minimum, maximum) {
|
|
213
|
+
return Math.min(Math.max(value, minimum), maximum);
|
|
214
|
+
}
|
|
215
|
+
__name(clamp, "clamp");
|
|
216
|
+
|
|
217
|
+
// packages/screws/src/library/iso-4762.ts
|
|
218
|
+
var specifications = {
|
|
219
|
+
M3: {
|
|
220
|
+
designation: "M3",
|
|
221
|
+
nominalDiameter: 3,
|
|
222
|
+
pitch: 0.5,
|
|
223
|
+
headDiameter: 5.5,
|
|
224
|
+
headHeight: 3,
|
|
225
|
+
hexSocketWidth: 2.5,
|
|
226
|
+
hexSocketDepth: 1.3,
|
|
227
|
+
underHeadRadius: 0.1,
|
|
228
|
+
clearance: { close: 3.2, normal: 3.4, loose: 3.6 },
|
|
229
|
+
counterboreDiameter: 6
|
|
230
|
+
},
|
|
231
|
+
M4: {
|
|
232
|
+
designation: "M4",
|
|
233
|
+
nominalDiameter: 4,
|
|
234
|
+
pitch: 0.7,
|
|
235
|
+
headDiameter: 7,
|
|
236
|
+
headHeight: 4,
|
|
237
|
+
hexSocketWidth: 3,
|
|
238
|
+
hexSocketDepth: 2,
|
|
239
|
+
underHeadRadius: 0.2,
|
|
240
|
+
clearance: { close: 4.3, normal: 4.5, loose: 4.8 },
|
|
241
|
+
counterboreDiameter: 8
|
|
242
|
+
},
|
|
243
|
+
M5: {
|
|
244
|
+
designation: "M5",
|
|
245
|
+
nominalDiameter: 5,
|
|
246
|
+
pitch: 0.8,
|
|
247
|
+
headDiameter: 8.5,
|
|
248
|
+
headHeight: 5,
|
|
249
|
+
hexSocketWidth: 4,
|
|
250
|
+
hexSocketDepth: 2.5,
|
|
251
|
+
underHeadRadius: 0.2,
|
|
252
|
+
clearance: { close: 5.3, normal: 5.5, loose: 5.8 },
|
|
253
|
+
counterboreDiameter: 10
|
|
254
|
+
},
|
|
255
|
+
M6: {
|
|
256
|
+
designation: "M6",
|
|
257
|
+
nominalDiameter: 6,
|
|
258
|
+
pitch: 1,
|
|
259
|
+
headDiameter: 10,
|
|
260
|
+
headHeight: 6,
|
|
261
|
+
hexSocketWidth: 5,
|
|
262
|
+
hexSocketDepth: 3,
|
|
263
|
+
underHeadRadius: 0.25,
|
|
264
|
+
clearance: { close: 6.4, normal: 6.6, loose: 7 },
|
|
265
|
+
counterboreDiameter: 11
|
|
266
|
+
},
|
|
267
|
+
M8: {
|
|
268
|
+
designation: "M8",
|
|
269
|
+
nominalDiameter: 8,
|
|
270
|
+
pitch: 1.25,
|
|
271
|
+
headDiameter: 13,
|
|
272
|
+
headHeight: 8,
|
|
273
|
+
hexSocketWidth: 6,
|
|
274
|
+
hexSocketDepth: 4,
|
|
275
|
+
underHeadRadius: 0.4,
|
|
276
|
+
clearance: { close: 8.4, normal: 9, loose: 10 },
|
|
277
|
+
counterboreDiameter: 15
|
|
278
|
+
},
|
|
279
|
+
M10: {
|
|
280
|
+
designation: "M10",
|
|
281
|
+
nominalDiameter: 10,
|
|
282
|
+
pitch: 1.5,
|
|
283
|
+
headDiameter: 16,
|
|
284
|
+
headHeight: 10,
|
|
285
|
+
hexSocketWidth: 8,
|
|
286
|
+
hexSocketDepth: 5,
|
|
287
|
+
underHeadRadius: 0.4,
|
|
288
|
+
clearance: { close: 10.5, normal: 11, loose: 12 },
|
|
289
|
+
counterboreDiameter: 18
|
|
290
|
+
},
|
|
291
|
+
M12: {
|
|
292
|
+
designation: "M12",
|
|
293
|
+
nominalDiameter: 12,
|
|
294
|
+
pitch: 1.75,
|
|
295
|
+
headDiameter: 18,
|
|
296
|
+
headHeight: 12,
|
|
297
|
+
hexSocketWidth: 10,
|
|
298
|
+
hexSocketDepth: 6,
|
|
299
|
+
underHeadRadius: 0.6,
|
|
300
|
+
clearance: { close: 13, normal: 13.5, loose: 14.5 },
|
|
301
|
+
counterboreDiameter: 20
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
function screw(input, length) {
|
|
305
|
+
const spec = resolveSpecification(input);
|
|
306
|
+
validateSpec(spec);
|
|
307
|
+
if (!Number.isFinite(length) || length <= spec.pitch + spec.underHeadRadius) {
|
|
308
|
+
throw new Error(
|
|
309
|
+
"Screw length must leave room for at least one full thread pitch."
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
const headChamfer = Math.min(spec.pitch / 2, spec.headHeight * 0.12);
|
|
313
|
+
const headBarrel = cylinder(
|
|
314
|
+
spec.headDiameter / 2,
|
|
315
|
+
spec.headHeight - headChamfer
|
|
316
|
+
);
|
|
317
|
+
const headTop = frustum(
|
|
318
|
+
spec.headDiameter / 2,
|
|
319
|
+
spec.headDiameter / 2 - headChamfer,
|
|
320
|
+
headChamfer
|
|
321
|
+
).relate((top) => top.on(headBarrel.up));
|
|
322
|
+
const headBlank = union([headBarrel, headTop]);
|
|
323
|
+
const socketToolY = spec.hexSocketDepth + 0.2;
|
|
324
|
+
const socketTool = regularPrism(
|
|
325
|
+
spec.hexSocketWidth / Math.sqrt(3),
|
|
326
|
+
socketToolY,
|
|
327
|
+
6,
|
|
328
|
+
30
|
|
329
|
+
).relate(
|
|
330
|
+
(tool) => tool.center.on(headBlank.up).offset(0, -spec.hexSocketDepth / 2 + 0.1, 0)
|
|
331
|
+
);
|
|
332
|
+
const head = cut(headBlank, [socketTool]);
|
|
333
|
+
const transition = frustum(
|
|
334
|
+
spec.nominalDiameter / 2,
|
|
335
|
+
spec.nominalDiameter / 2 + spec.underHeadRadius,
|
|
336
|
+
spec.underHeadRadius
|
|
337
|
+
).relate((part) => part.on(head.down));
|
|
338
|
+
const bodyLength = length - spec.underHeadRadius;
|
|
339
|
+
const threadedLength = Math.min(bodyLength, threadLength(spec, length));
|
|
340
|
+
const plainLength = bodyLength - threadedLength;
|
|
341
|
+
const overlap = Math.min(0.08, spec.pitch / 10);
|
|
342
|
+
const parts = [head, transition];
|
|
343
|
+
let previous = transition;
|
|
344
|
+
if (plainLength > overlap) {
|
|
345
|
+
const shank = cylinder(
|
|
346
|
+
spec.nominalDiameter / 2,
|
|
347
|
+
plainLength + overlap
|
|
348
|
+
).relate((part) => part.on(previous.down).offset(0, -overlap, 0));
|
|
349
|
+
parts.push(shank);
|
|
350
|
+
previous = shank;
|
|
351
|
+
}
|
|
352
|
+
const fundamentalHeight = Math.sqrt(3) / 2 * spec.pitch;
|
|
353
|
+
const minorDiameter = spec.nominalDiameter - 2 * (5 / 8 * fundamentalHeight);
|
|
354
|
+
const thread = helicalThread({
|
|
355
|
+
pitch: spec.pitch,
|
|
356
|
+
y: threadedLength + overlap,
|
|
357
|
+
majorDiameter: spec.nominalDiameter,
|
|
358
|
+
minorDiameter,
|
|
359
|
+
rootWidth: 3 / 4 * spec.pitch,
|
|
360
|
+
crestWidth: 1 / 8 * spec.pitch
|
|
361
|
+
}).relate((part) => part.on(previous.down).offset(0, -overlap, 0));
|
|
362
|
+
parts.push(thread);
|
|
363
|
+
return union(parts).expose({
|
|
364
|
+
headTop: head.up,
|
|
365
|
+
headBottom: head.down,
|
|
366
|
+
shankTop: transition.up,
|
|
367
|
+
shankBottom: thread.down,
|
|
368
|
+
shankAxis: thread.axis
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
__name(screw, "screw");
|
|
372
|
+
function clearanceHole(input, optionsOrDepth) {
|
|
373
|
+
const options = typeof optionsOrDepth === "number" ? { depth: optionsOrDepth } : optionsOrDepth;
|
|
374
|
+
const spec = resolveSpecification(input);
|
|
375
|
+
validateSpec(spec);
|
|
376
|
+
if (!Number.isFinite(options.depth) || options.depth <= 0) {
|
|
377
|
+
throw new Error("Hole depth must be a positive finite number.");
|
|
378
|
+
}
|
|
379
|
+
const fit = options.fit ?? "normal";
|
|
380
|
+
const diameter = options.diameter ?? spec.clearance[fit];
|
|
381
|
+
if (!Number.isFinite(diameter) || diameter <= spec.nominalDiameter) {
|
|
382
|
+
throw new Error(
|
|
383
|
+
"Clearance-hole diameter must exceed the nominal screw diameter."
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
const shaft = cylinder(diameter / 2, options.depth);
|
|
387
|
+
const counterboreOption = options.counterbore ?? true;
|
|
388
|
+
if (counterboreOption === false) {
|
|
389
|
+
return shaft.expose({
|
|
390
|
+
shaftTop: shaft.up,
|
|
391
|
+
shaftBottom: shaft.down,
|
|
392
|
+
shaftAxis: shaft.axis
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
const counterbore = counterboreOption === true ? {} : counterboreOption;
|
|
396
|
+
const axialClearance = counterbore.axialClearance ?? 0.5;
|
|
397
|
+
const counterboreDepth = counterbore.depth ?? spec.headHeight + axialClearance;
|
|
398
|
+
const counterboreDiameter = counterbore.diameter ?? spec.counterboreDiameter;
|
|
399
|
+
if (!Number.isFinite(counterboreDepth) || counterboreDepth <= 0 || counterboreDepth > options.depth) {
|
|
400
|
+
throw new Error("Counterbore depth must be within the total hole depth.");
|
|
401
|
+
}
|
|
402
|
+
if (!Number.isFinite(counterboreDiameter) || counterboreDiameter < spec.headDiameter) {
|
|
403
|
+
throw new Error("Counterbore diameter must accommodate the screw head.");
|
|
404
|
+
}
|
|
405
|
+
const recess = cylinder(
|
|
406
|
+
counterboreDiameter / 2,
|
|
407
|
+
counterboreDepth + 0.2
|
|
408
|
+
).relate(
|
|
409
|
+
(tool) => tool.center.on(shaft.up).offset(0, -counterboreDepth / 2 + 0.1, 0)
|
|
410
|
+
);
|
|
411
|
+
return union([shaft, recess]).expose({
|
|
412
|
+
shaftTop: shaft.up,
|
|
413
|
+
shaftBottom: shaft.down,
|
|
414
|
+
shaftAxis: shaft.axis,
|
|
415
|
+
counterboreTop: recess.up,
|
|
416
|
+
counterboreBottom: recess.down
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
__name(clearanceHole, "clearanceHole");
|
|
420
|
+
function resolveSpecification(input) {
|
|
421
|
+
return typeof input === "string" ? specifications[input] : input;
|
|
422
|
+
}
|
|
423
|
+
__name(resolveSpecification, "resolveSpecification");
|
|
424
|
+
function threadLength(spec, length) {
|
|
425
|
+
if (length <= 125) return 2 * spec.nominalDiameter + 12;
|
|
426
|
+
if (length <= 200) return 2 * spec.nominalDiameter + 18;
|
|
427
|
+
return 2 * spec.nominalDiameter + 31;
|
|
428
|
+
}
|
|
429
|
+
__name(threadLength, "threadLength");
|
|
430
|
+
function validateSpec(spec) {
|
|
431
|
+
const values = [
|
|
432
|
+
spec.nominalDiameter,
|
|
433
|
+
spec.pitch,
|
|
434
|
+
spec.headDiameter,
|
|
435
|
+
spec.headHeight,
|
|
436
|
+
spec.hexSocketWidth,
|
|
437
|
+
spec.hexSocketDepth,
|
|
438
|
+
spec.underHeadRadius,
|
|
439
|
+
spec.clearance.close,
|
|
440
|
+
spec.clearance.normal,
|
|
441
|
+
spec.clearance.loose,
|
|
442
|
+
spec.counterboreDiameter
|
|
443
|
+
];
|
|
444
|
+
if (values.some((value) => !Number.isFinite(value) || value <= 0)) {
|
|
445
|
+
throw new Error(
|
|
446
|
+
"Fastener specifications must contain positive finite dimensions."
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
if (spec.headDiameter <= spec.nominalDiameter) {
|
|
450
|
+
throw new Error("Head diameter must exceed the nominal thread diameter.");
|
|
451
|
+
}
|
|
452
|
+
if (spec.hexSocketDepth >= spec.headHeight) {
|
|
453
|
+
throw new Error("Hex socket depth must be smaller than the head height.");
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
__name(validateSpec, "validateSpec");
|
|
457
|
+
export {
|
|
458
|
+
iso_4762_exports as ISO4762
|
|
459
|
+
};
|
|
460
|
+
//# sourceMappingURL=index.js.map
|
package/bld/library/index.js.map
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/library/iso-4762.ts", "../../src/library/thread.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n cylinder,\n cut,\n frustum,\n regularPrism,\n union,\n type CanonicalElements,\n type Bound,\n type LineAnchor,\n type SolidModel,\n} from '@code3d/core';\nimport {helicalThread} from './thread.js';\n\nexport type ClearanceFit = 'close' | 'normal' | 'loose';\n\nexport type Specification = Readonly<{\n designation: string;\n nominalDiameter: number;\n pitch: number;\n headDiameter: number;\n headHeight: number;\n hexSocketWidth: number;\n hexSocketDepth: number;\n underHeadRadius: number;\n clearance: Readonly<Record<ClearanceFit, number>>;\n counterboreDiameter: number;\n}>;\n\n// ISO 4762 coarse-thread socket-head cap screws; millimetres.\n// Clearance series follow ISO 273. Counterbores follow DIN 974-1 normal series.\nexport const specifications = {\n M3: {\n designation: 'M3',\n nominalDiameter: 3,\n pitch: 0.5,\n headDiameter: 5.5,\n headHeight: 3,\n hexSocketWidth: 2.5,\n hexSocketDepth: 1.3,\n underHeadRadius: 0.1,\n clearance: {close: 3.2, normal: 3.4, loose: 3.6},\n counterboreDiameter: 6,\n },\n M4: {\n designation: 'M4',\n nominalDiameter: 4,\n pitch: 0.7,\n headDiameter: 7,\n headHeight: 4,\n hexSocketWidth: 3,\n hexSocketDepth: 2,\n underHeadRadius: 0.2,\n clearance: {close: 4.3, normal: 4.5, loose: 4.8},\n counterboreDiameter: 8,\n },\n M5: {\n designation: 'M5',\n nominalDiameter: 5,\n pitch: 0.8,\n headDiameter: 8.5,\n headHeight: 5,\n hexSocketWidth: 4,\n hexSocketDepth: 2.5,\n underHeadRadius: 0.2,\n clearance: {close: 5.3, normal: 5.5, loose: 5.8},\n counterboreDiameter: 10,\n },\n M6: {\n designation: 'M6',\n nominalDiameter: 6,\n pitch: 1,\n headDiameter: 10,\n headHeight: 6,\n hexSocketWidth: 5,\n hexSocketDepth: 3,\n underHeadRadius: 0.25,\n clearance: {close: 6.4, normal: 6.6, loose: 7},\n counterboreDiameter: 11,\n },\n M8: {\n designation: 'M8',\n nominalDiameter: 8,\n pitch: 1.25,\n headDiameter: 13,\n headHeight: 8,\n hexSocketWidth: 6,\n hexSocketDepth: 4,\n underHeadRadius: 0.4,\n clearance: {close: 8.4, normal: 9, loose: 10},\n counterboreDiameter: 15,\n },\n M10: {\n designation: 'M10',\n nominalDiameter: 10,\n pitch: 1.5,\n headDiameter: 16,\n headHeight: 10,\n hexSocketWidth: 8,\n hexSocketDepth: 5,\n underHeadRadius: 0.4,\n clearance: {close: 10.5, normal: 11, loose: 12},\n counterboreDiameter: 18,\n },\n M12: {\n designation: 'M12',\n nominalDiameter: 12,\n pitch: 1.75,\n headDiameter: 18,\n headHeight: 12,\n hexSocketWidth: 10,\n hexSocketDepth: 6,\n underHeadRadius: 0.6,\n clearance: {close: 13, normal: 13.5, loose: 14.5},\n counterboreDiameter: 20,\n },\n} as const satisfies Readonly<Record<string, Specification>>;\n\nexport type Size = keyof typeof specifications;\nexport type ScrewInput = Size | Specification;\n\nexport type CounterboreOptions = Readonly<{\n diameter?: number;\n depth?: number;\n axialClearance?: number;\n}>;\n\nexport type ClearanceHoleOptions = Readonly<{\n depth: number;\n fit?: ClearanceFit;\n diameter?: number;\n counterbore?: boolean | CounterboreOptions;\n}>;\n\nexport type PlainClearanceHoleOptions = ClearanceHoleOptions &\n Readonly<{\n counterbore: false;\n }>;\n\nexport type CounterboredHoleOptions = Omit<\n ClearanceHoleOptions,\n 'counterbore'\n> &\n Readonly<{\n counterbore?: true | CounterboreOptions;\n }>;\n\nexport type SocketCapScrewElements = CanonicalElements &\n Readonly<{\n headTop: Bound;\n headBottom: Bound;\n shankTop: Bound;\n shankBottom: Bound;\n shankAxis: LineAnchor;\n }>;\n\nexport type SocketCapHoleElements = CanonicalElements &\n Readonly<{\n shaftTop: Bound;\n shaftBottom: Bound;\n shaftAxis: LineAnchor;\n }>;\n\nexport type CounterboredSocketCapHoleElements = SocketCapHoleElements &\n Readonly<{\n counterboreTop: Bound;\n counterboreBottom: Bound;\n }>;\n\nexport type Screw = SolidModel<SocketCapScrewElements>;\nexport type ClearanceHole = SolidModel<SocketCapHoleElements>;\nexport type CounterboredHole = SolidModel<CounterboredSocketCapHoleElements>;\n\n/**\n * @code3d.arguments ['M6', 18]\n * @code3d.arguments ['M8', 30]\n * @code3d.param length {kind: 'length'}\n */\nexport function screw(input: ScrewInput, length: number): Screw {\n const spec = resolveSpecification(input);\n validateSpec(spec);\n if (!Number.isFinite(length) || length <= spec.pitch + spec.underHeadRadius) {\n throw new Error(\n 'Screw length must leave room for at least one full thread pitch.',\n );\n }\n\n const headChamfer = Math.min(spec.pitch / 2, spec.headHeight * 0.12);\n const headBarrel = cylinder(\n spec.headDiameter / 2,\n spec.headHeight - headChamfer,\n );\n const headTop = frustum(\n spec.headDiameter / 2,\n spec.headDiameter / 2 - headChamfer,\n headChamfer,\n ).relate(top => top.on(headBarrel.up));\n const headBlank = union([headBarrel, headTop]);\n\n const socketToolY = spec.hexSocketDepth + 0.2;\n const socketTool = regularPrism(\n spec.hexSocketWidth / Math.sqrt(3),\n socketToolY,\n 6,\n 30,\n ).relate(tool =>\n tool.center.on(headBlank.up).offset(0, -spec.hexSocketDepth / 2 + 0.1, 0),\n );\n const head = cut(headBlank, [socketTool]);\n\n const transition = frustum(\n spec.nominalDiameter / 2,\n spec.nominalDiameter / 2 + spec.underHeadRadius,\n spec.underHeadRadius,\n ).relate(part => part.on(head.down));\n const bodyLength = length - spec.underHeadRadius;\n const threadedLength = Math.min(bodyLength, threadLength(spec, length));\n const plainLength = bodyLength - threadedLength;\n const overlap = Math.min(0.08, spec.pitch / 10);\n const parts = [head, transition];\n let previous = transition;\n\n if (plainLength > overlap) {\n const shank = cylinder(\n spec.nominalDiameter / 2,\n plainLength + overlap,\n ).relate(part => part.on(previous.down).offset(0, -overlap, 0));\n parts.push(shank);\n previous = shank;\n }\n\n const fundamentalHeight = (Math.sqrt(3) / 2) * spec.pitch;\n const minorDiameter =\n spec.nominalDiameter - 2 * ((5 / 8) * fundamentalHeight);\n const thread = helicalThread({\n pitch: spec.pitch,\n y: threadedLength + overlap,\n majorDiameter: spec.nominalDiameter,\n minorDiameter,\n rootWidth: (3 / 4) * spec.pitch,\n crestWidth: (1 / 8) * spec.pitch,\n }).relate(part => part.on(previous.down).offset(0, -overlap, 0));\n parts.push(thread);\n\n return union(parts).expose({\n headTop: head.up,\n headBottom: head.down,\n shankTop: transition.up,\n shankBottom: thread.down,\n shankAxis: thread.axis,\n });\n}\n\n/**\n * @code3d.arguments ['M6', 10]\n * @code3d.arguments ['M6', {depth: 10, counterbore: false}]\n * @code3d.param depth {kind: 'length', constraints: {exclusiveMin: 0}}\n */\nexport function clearanceHole(\n input: ScrewInput,\n depth: number,\n): CounterboredHole;\nexport function clearanceHole(\n input: ScrewInput,\n options: PlainClearanceHoleOptions,\n): ClearanceHole;\nexport function clearanceHole(\n input: ScrewInput,\n options: CounterboredHoleOptions,\n): CounterboredHole;\nexport function clearanceHole(\n input: ScrewInput,\n options: ClearanceHoleOptions,\n): ClearanceHole | CounterboredHole;\nexport function clearanceHole(\n input: ScrewInput,\n optionsOrDepth: ClearanceHoleOptions | number,\n): ClearanceHole | CounterboredHole {\n const options: ClearanceHoleOptions =\n typeof optionsOrDepth === 'number'\n ? {depth: optionsOrDepth}\n : optionsOrDepth;\n const spec = resolveSpecification(input);\n validateSpec(spec);\n if (!Number.isFinite(options.depth) || options.depth <= 0) {\n throw new Error('Hole depth must be a positive finite number.');\n }\n const fit = options.fit ?? 'normal';\n const diameter = options.diameter ?? spec.clearance[fit];\n if (!Number.isFinite(diameter) || diameter <= spec.nominalDiameter) {\n throw new Error(\n 'Clearance-hole diameter must exceed the nominal screw diameter.',\n );\n }\n const shaft = cylinder(diameter / 2, options.depth);\n const counterboreOption = options.counterbore ?? true;\n if (counterboreOption === false) {\n return shaft.expose({\n shaftTop: shaft.up,\n shaftBottom: shaft.down,\n shaftAxis: shaft.axis,\n });\n }\n\n const counterbore = counterboreOption === true ? {} : counterboreOption;\n const axialClearance = counterbore.axialClearance ?? 0.5;\n const counterboreDepth =\n counterbore.depth ?? spec.headHeight + axialClearance;\n const counterboreDiameter = counterbore.diameter ?? spec.counterboreDiameter;\n if (\n !Number.isFinite(counterboreDepth) ||\n counterboreDepth <= 0 ||\n counterboreDepth > options.depth\n ) {\n throw new Error('Counterbore depth must be within the total hole depth.');\n }\n if (\n !Number.isFinite(counterboreDiameter) ||\n counterboreDiameter < spec.headDiameter\n ) {\n throw new Error('Counterbore diameter must accommodate the screw head.');\n }\n const recess = cylinder(\n counterboreDiameter / 2,\n counterboreDepth + 0.2,\n ).relate(tool =>\n tool.center.on(shaft.up).offset(0, -counterboreDepth / 2 + 0.1, 0),\n );\n return union([shaft, recess]).expose({\n shaftTop: shaft.up,\n shaftBottom: shaft.down,\n shaftAxis: shaft.axis,\n counterboreTop: recess.up,\n counterboreBottom: recess.down,\n });\n}\n\nexport function resolveSpecification(input: ScrewInput): Specification {\n return typeof input === 'string' ? specifications[input] : input;\n}\n\nexport function threadLength(spec: Specification, length: number): number {\n if (length <= 125) return 2 * spec.nominalDiameter + 12;\n if (length <= 200) return 2 * spec.nominalDiameter + 18;\n return 2 * spec.nominalDiameter + 31;\n}\n\nfunction validateSpec(spec: Specification): void {\n const values = [\n spec.nominalDiameter,\n spec.pitch,\n spec.headDiameter,\n spec.headHeight,\n spec.hexSocketWidth,\n spec.hexSocketDepth,\n spec.underHeadRadius,\n spec.clearance.close,\n spec.clearance.normal,\n spec.clearance.loose,\n spec.counterboreDiameter,\n ];\n if (values.some(value => !Number.isFinite(value) || value <= 0)) {\n throw new Error(\n 'Fastener specifications must contain positive finite dimensions.',\n );\n }\n if (spec.headDiameter <= spec.nominalDiameter) {\n throw new Error('Head diameter must exceed the nominal thread diameter.');\n }\n if (spec.hexSocketDepth >= spec.headHeight) {\n throw new Error('Hex socket depth must be smaller than the head height.');\n }\n}\n", "import {\n definePrimitive,\n replicad,\n type Drawing,\n type Face,\n type Shape3D,\n type Sketch,\n} from '@code3d/core/replicad';\n\nconst {Plane, draw, makeCylinder, makeHelix, makeSolid, weldShellsAndFaces} =\n replicad;\n\ntype HelicalThreadOptions = Readonly<{\n pitch: number;\n y: number;\n majorDiameter: number;\n minorDiameter: number;\n rootWidth: number;\n crestWidth: number;\n leftHanded?: boolean;\n}>;\n\nconst loopSteps = Array.from({length: 21}, (_, index) => index / 20);\n\nexport const helicalThread = definePrimitive(\n (options: HelicalThreadOptions) => {\n validateHelicalThread(options);\n const {\n majorDiameter,\n minorDiameter,\n leftHanded = false,\n ...dimensions\n } = options;\n return makeHelicalThreadShape({\n ...dimensions,\n majorRadius: majorDiameter / 2,\n minorRadius: minorDiameter / 2,\n leftHanded,\n });\n },\n);\n\nfunction validateHelicalThread({\n pitch,\n y,\n majorDiameter,\n minorDiameter,\n rootWidth,\n crestWidth,\n}: HelicalThreadOptions): void {\n assertPositive('pitch', pitch);\n assertPositive('y', y);\n assertPositive('majorDiameter', majorDiameter);\n assertPositive('minorDiameter', minorDiameter);\n assertPositive('rootWidth', rootWidth);\n assertPositive('crestWidth', crestWidth);\n if (y < pitch) {\n throw new Error('y must be at least one thread pitch.');\n }\n if (minorDiameter >= majorDiameter) {\n throw new Error('minorDiameter must be smaller than majorDiameter.');\n }\n if (crestWidth >= rootWidth || rootWidth > pitch) {\n throw new Error(\n 'The thread profile requires crestWidth < rootWidth <= pitch.',\n );\n }\n}\n\ntype HelicalThreadShapeOptions = Readonly<{\n pitch: number;\n y: number;\n majorRadius: number;\n minorRadius: number;\n rootWidth: number;\n crestWidth: number;\n leftHanded: boolean;\n}>;\n\n/**\n * Builds a closed external thread around its minor-diameter core. The lofted\n * end treatment follows the MIT-licensed replicad-threads construction by\n * Steve Genoud, adapted here to code3d's Y-axis and geometry ownership model.\n */\nfunction makeHelicalThreadShape({\n pitch,\n y,\n majorRadius,\n minorRadius,\n rootWidth,\n crestWidth,\n leftHanded,\n}: HelicalThreadShapeOptions): Shape3D {\n const toothHeight = majorRadius - minorRadius;\n const profile = threadProfile(rootWidth, crestWidth, toothHeight);\n const teeth = fadedThread(pitch, minorRadius, y, profile, leftHanded);\n const core = makeCylinder(minorRadius + 0.05, y);\n const threaded = core.fuse(teeth);\n core.delete();\n teeth.delete();\n return threaded.rotate(-90, [0, 0, 0], [1, 0, 0]).translate([0, -y / 2, 0]);\n}\n\nfunction threadProfile(\n rootWidth: number,\n crestWidth: number,\n toothHeight: number,\n): Drawing {\n const rootHalf = rootWidth / 2;\n const crestHalf = crestWidth / 2;\n return draw([rootHalf, -0.05])\n .vLine(0.05)\n .lineTo([crestHalf, toothHeight])\n .hLineTo(-crestHalf)\n .lineTo([-rootHalf, 0])\n .vLine(-0.05)\n .close();\n}\n\nfunction fadedThread(\n pitch: number,\n radius: number,\n length: number,\n profile: Drawing,\n leftHanded: boolean,\n): Shape3D {\n const bottomEnd = fadedEnd(pitch, radius, profile, true, leftHanded);\n const totalLoops = length / pitch - 0.5;\n const fullLoops = Math.floor(totalLoops);\n const leftover = totalLoops - fullLoops;\n const singleLoop = basicThreadLoop(\n pitch,\n radius,\n profile,\n 1,\n 'none',\n leftHanded,\n );\n const shells = Array.from({length: fullLoops}, (_, index) =>\n singleLoop.clone().translate([0, 0, index * pitch]),\n );\n singleLoop.delete();\n if (leftover > 1e-9) {\n shells.push(\n basicThreadLoop(\n pitch,\n radius,\n profile,\n leftover,\n 'none',\n leftHanded,\n ).translate([0, 0, fullLoops * pitch]),\n );\n }\n const topEnd = fadedEnd(pitch, radius, profile, false, leftHanded)\n .translate([0, 0, totalLoops * pitch])\n .rotate(360 * leftover, [0, 0, 0], [0, 0, 1]);\n const thread = makeSolid([bottomEnd, ...shells, topEnd]).translate([\n 0,\n 0,\n pitch / 4,\n ]);\n bottomEnd.delete();\n shells.forEach(shell => shell.delete());\n topEnd.delete();\n return thread;\n}\n\nfunction basicThreadLoop(\n pitch: number,\n radius: number,\n profile: Drawing,\n loopFraction: number,\n includeEnd: 'none' | 'first' | 'last' | 'both',\n leftHanded: boolean,\n) {\n const helix = makeHelix(\n pitch,\n pitch * clamp(loopFraction, 0, 1),\n radius,\n [0, 0, 0],\n [0, 0, 1],\n leftHanded,\n );\n const profiles = loopSteps.map(step => {\n const position = helix.pointAt(step);\n const tangent = helix.tangentAt(step);\n const plane = new Plane(position, [0, 0, 1], tangent);\n const sketch = profile.sketchOnPlane(plane) as Sketch;\n plane.delete();\n return sketch;\n });\n helix.delete();\n\n const ends: Face[] = [];\n if (includeEnd === 'first' || includeEnd === 'both') {\n ends.push(profiles[0].faces());\n }\n if (includeEnd === 'last' || includeEnd === 'both') {\n const face = profiles.at(-1)!.faces();\n face.wrapped.Reverse();\n ends.push(face);\n }\n const shell = profiles[0].loftWith(profiles.slice(1), {ruled: false}, true);\n if (ends.length === 0) return shell;\n const closed = weldShellsAndFaces([shell, ...ends]);\n shell.delete();\n ends.forEach(face => face.delete());\n return closed;\n}\n\nfunction fadedEnd(\n pitch: number,\n radius: number,\n profile: Drawing,\n bottom: boolean,\n leftHanded: boolean,\n) {\n const length = pitch / 4;\n const helix = makeHelix(\n pitch,\n length,\n radius,\n [0, 0, 0],\n [0, 0, bottom ? -1 : 1],\n leftHanded,\n );\n const profiles = loopSteps.map((step, index) => {\n const position = helix.pointAt(step);\n let tangent = helix.tangentAt(step);\n if (bottom) tangent = tangent.multiply(-1);\n const plane = new Plane(position, [0, 0, 1], tangent);\n const sketch = profile\n .scale((loopSteps.length - index) / loopSteps.length, [0, 0])\n .sketchOnPlane(plane) as Sketch;\n plane.delete();\n return sketch;\n });\n helix.delete();\n const endFace = profiles.at(-1)!.faces();\n const shell = profiles[0].loftWith(profiles.slice(1), {ruled: false}, true);\n const closed = weldShellsAndFaces([shell, endFace]);\n shell.delete();\n endFace.delete();\n return bottom ? closed.rotate(180, [0, 0, 0], [0, 0, 1]) : closed;\n}\n\nfunction assertPositive(name: string, value: number): void {\n if (!Number.isFinite(value) || value <= 0) {\n throw new Error(`${name} must be a positive finite number.`);\n }\n}\n\nfunction clamp(value: number, minimum: number, maximum: number): number {\n return Math.min(Math.max(value, minimum), maximum);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAKK;;;ACVP;AAAA,EACE;AAAA,EACA;AAAA,OAKK;AAEP,IAAM,EAAC,OAAO,MAAM,cAAc,WAAW,WAAW,mBAAkB,IACxE;AAYF,IAAM,YAAY,MAAM,KAAK,EAAC,QAAQ,GAAE,GAAG,CAAC,GAAG,UAAU,QAAQ,EAAE;AAE5D,IAAM,gBAAgB;AAAA,EAC3B,CAAC,YAAkC;AACjC,0BAAsB,OAAO;AAC7B,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,aAAa;AAAA,MACb,GAAG;AAAA,IACL,IAAI;AACJ,WAAO,uBAAuB;AAAA,MAC5B,GAAG;AAAA,MACH,aAAa,gBAAgB;AAAA,MAC7B,aAAa,gBAAgB;AAAA,MAC7B;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,sBAAsB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA+B;AAC7B,iBAAe,SAAS,KAAK;AAC7B,iBAAe,KAAK,CAAC;AACrB,iBAAe,iBAAiB,aAAa;AAC7C,iBAAe,iBAAiB,aAAa;AAC7C,iBAAe,aAAa,SAAS;AACrC,iBAAe,cAAc,UAAU;AACvC,MAAI,IAAI,OAAO;AACb,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AACA,MAAI,iBAAiB,eAAe;AAClC,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACrE;AACA,MAAI,cAAc,aAAa,YAAY,OAAO;AAChD,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAzBS;AA0CT,SAAS,uBAAuB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuC;AACrC,QAAM,cAAc,cAAc;AAClC,QAAM,UAAU,cAAc,WAAW,YAAY,WAAW;AAChE,QAAM,QAAQ,YAAY,OAAO,aAAa,GAAG,SAAS,UAAU;AACpE,QAAM,OAAO,aAAa,cAAc,MAAM,CAAC;AAC/C,QAAM,WAAW,KAAK,KAAK,KAAK;AAChC,OAAK,OAAO;AACZ,QAAM,OAAO;AACb,SAAO,SAAS,OAAO,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;AAC5E;AAjBS;AAmBT,SAAS,cACP,WACA,YACA,aACS;AACT,QAAM,WAAW,YAAY;AAC7B,QAAM,YAAY,aAAa;AAC/B,SAAO,KAAK,CAAC,UAAU,KAAK,CAAC,EAC1B,MAAM,IAAI,EACV,OAAO,CAAC,WAAW,WAAW,CAAC,EAC/B,QAAQ,CAAC,SAAS,EAClB,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,EACrB,MAAM,KAAK,EACX,MAAM;AACX;AAdS;AAgBT,SAAS,YACP,OACA,QACA,QACA,SACA,YACS;AACT,QAAM,YAAY,SAAS,OAAO,QAAQ,SAAS,MAAM,UAAU;AACnE,QAAM,aAAa,SAAS,QAAQ;AACpC,QAAM,YAAY,KAAK,MAAM,UAAU;AACvC,QAAM,WAAW,aAAa;AAC9B,QAAM,aAAa;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,SAAS,MAAM;AAAA,IAAK,EAAC,QAAQ,UAAS;AAAA,IAAG,CAAC,GAAG,UACjD,WAAW,MAAM,EAAE,UAAU,CAAC,GAAG,GAAG,QAAQ,KAAK,CAAC;AAAA,EACpD;AACA,aAAW,OAAO;AAClB,MAAI,WAAW,MAAM;AACnB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,EAAE,UAAU,CAAC,GAAG,GAAG,YAAY,KAAK,CAAC;AAAA,IACvC;AAAA,EACF;AACA,QAAM,SAAS,SAAS,OAAO,QAAQ,SAAS,OAAO,UAAU,EAC9D,UAAU,CAAC,GAAG,GAAG,aAAa,KAAK,CAAC,EACpC,OAAO,MAAM,UAAU,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAC9C,QAAM,SAAS,UAAU,CAAC,WAAW,GAAG,QAAQ,MAAM,CAAC,EAAE,UAAU;AAAA,IACjE;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV,CAAC;AACD,YAAU,OAAO;AACjB,SAAO,QAAQ,WAAS,MAAM,OAAO,CAAC;AACtC,SAAO,OAAO;AACd,SAAO;AACT;AA/CS;AAiDT,SAAS,gBACP,OACA,QACA,SACA,cACA,YACA,YACA;AACA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,QAAQ,MAAM,cAAc,GAAG,CAAC;AAAA,IAChC;AAAA,IACA,CAAC,GAAG,GAAG,CAAC;AAAA,IACR,CAAC,GAAG,GAAG,CAAC;AAAA,IACR;AAAA,EACF;AACA,QAAM,WAAW,UAAU,IAAI,UAAQ;AACrC,UAAM,WAAW,MAAM,QAAQ,IAAI;AACnC,UAAM,UAAU,MAAM,UAAU,IAAI;AACpC,UAAM,QAAQ,IAAI,MAAM,UAAU,CAAC,GAAG,GAAG,CAAC,GAAG,OAAO;AACpD,UAAM,SAAS,QAAQ,cAAc,KAAK;AAC1C,UAAM,OAAO;AACb,WAAO;AAAA,EACT,CAAC;AACD,QAAM,OAAO;AAEb,QAAM,OAAe,CAAC;AACtB,MAAI,eAAe,WAAW,eAAe,QAAQ;AACnD,SAAK,KAAK,SAAS,CAAC,EAAE,MAAM,CAAC;AAAA,EAC/B;AACA,MAAI,eAAe,UAAU,eAAe,QAAQ;AAClD,UAAM,OAAO,SAAS,GAAG,EAAE,EAAG,MAAM;AACpC,SAAK,QAAQ,QAAQ;AACrB,SAAK,KAAK,IAAI;AAAA,EAChB;AACA,QAAM,QAAQ,SAAS,CAAC,EAAE,SAAS,SAAS,MAAM,CAAC,GAAG,EAAC,OAAO,MAAK,GAAG,IAAI;AAC1E,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,QAAM,SAAS,mBAAmB,CAAC,OAAO,GAAG,IAAI,CAAC;AAClD,QAAM,OAAO;AACb,OAAK,QAAQ,UAAQ,KAAK,OAAO,CAAC;AAClC,SAAO;AACT;AAzCS;AA2CT,SAAS,SACP,OACA,QACA,SACA,QACA,YACA;AACA,QAAM,SAAS,QAAQ;AACvB,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,GAAG,GAAG,CAAC;AAAA,IACR,CAAC,GAAG,GAAG,SAAS,KAAK,CAAC;AAAA,IACtB;AAAA,EACF;AACA,QAAM,WAAW,UAAU,IAAI,CAAC,MAAM,UAAU;AAC9C,UAAM,WAAW,MAAM,QAAQ,IAAI;AACnC,QAAI,UAAU,MAAM,UAAU,IAAI;AAClC,QAAI,OAAQ,WAAU,QAAQ,SAAS,EAAE;AACzC,UAAM,QAAQ,IAAI,MAAM,UAAU,CAAC,GAAG,GAAG,CAAC,GAAG,OAAO;AACpD,UAAM,SAAS,QACZ,OAAO,UAAU,SAAS,SAAS,UAAU,QAAQ,CAAC,GAAG,CAAC,CAAC,EAC3D,cAAc,KAAK;AACtB,UAAM,OAAO;AACb,WAAO;AAAA,EACT,CAAC;AACD,QAAM,OAAO;AACb,QAAM,UAAU,SAAS,GAAG,EAAE,EAAG,MAAM;AACvC,QAAM,QAAQ,SAAS,CAAC,EAAE,SAAS,SAAS,MAAM,CAAC,GAAG,EAAC,OAAO,MAAK,GAAG,IAAI;AAC1E,QAAM,SAAS,mBAAmB,CAAC,OAAO,OAAO,CAAC;AAClD,QAAM,OAAO;AACb,UAAQ,OAAO;AACf,SAAO,SAAS,OAAO,OAAO,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI;AAC7D;AAlCS;AAoCT,SAAS,eAAe,MAAc,OAAqB;AACzD,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,GAAG;AACzC,UAAM,IAAI,MAAM,GAAG,IAAI,oCAAoC;AAAA,EAC7D;AACF;AAJS;AAMT,SAAS,MAAM,OAAe,SAAiB,SAAyB;AACtE,SAAO,KAAK,IAAI,KAAK,IAAI,OAAO,OAAO,GAAG,OAAO;AACnD;AAFS;;;AD/NF,IAAM,iBAAiB;AAAA,EAC5B,IAAI;AAAA,IACF,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,WAAW,EAAC,OAAO,KAAK,QAAQ,KAAK,OAAO,IAAG;AAAA,IAC/C,qBAAqB;AAAA,EACvB;AAAA,EACA,IAAI;AAAA,IACF,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,WAAW,EAAC,OAAO,KAAK,QAAQ,KAAK,OAAO,IAAG;AAAA,IAC/C,qBAAqB;AAAA,EACvB;AAAA,EACA,IAAI;AAAA,IACF,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,WAAW,EAAC,OAAO,KAAK,QAAQ,KAAK,OAAO,IAAG;AAAA,IAC/C,qBAAqB;AAAA,EACvB;AAAA,EACA,IAAI;AAAA,IACF,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,WAAW,EAAC,OAAO,KAAK,QAAQ,KAAK,OAAO,EAAC;AAAA,IAC7C,qBAAqB;AAAA,EACvB;AAAA,EACA,IAAI;AAAA,IACF,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,WAAW,EAAC,OAAO,KAAK,QAAQ,GAAG,OAAO,GAAE;AAAA,IAC5C,qBAAqB;AAAA,EACvB;AAAA,EACA,KAAK;AAAA,IACH,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,WAAW,EAAC,OAAO,MAAM,QAAQ,IAAI,OAAO,GAAE;AAAA,IAC9C,qBAAqB;AAAA,EACvB;AAAA,EACA,KAAK;AAAA,IACH,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,WAAW,EAAC,OAAO,IAAI,QAAQ,MAAM,OAAO,KAAI;AAAA,IAChD,qBAAqB;AAAA,EACvB;AACF;AA8DO,SAAS,MAAM,OAAmB,QAAuB;AAC9D,QAAM,OAAO,qBAAqB,KAAK;AACvC,eAAa,IAAI;AACjB,MAAI,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,KAAK,QAAQ,KAAK,iBAAiB;AAC3E,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cAAc,KAAK,IAAI,KAAK,QAAQ,GAAG,KAAK,aAAa,IAAI;AACnE,QAAM,aAAa;AAAA,IACjB,KAAK,eAAe;AAAA,IACpB,KAAK,aAAa;AAAA,EACpB;AACA,QAAM,UAAU;AAAA,IACd,KAAK,eAAe;AAAA,IACpB,KAAK,eAAe,IAAI;AAAA,IACxB;AAAA,EACF,EAAE,OAAO,SAAO,IAAI,GAAG,WAAW,EAAE,CAAC;AACrC,QAAM,YAAY,MAAM,CAAC,YAAY,OAAO,CAAC;AAE7C,QAAM,cAAc,KAAK,iBAAiB;AAC1C,QAAM,aAAa;AAAA,IACjB,KAAK,iBAAiB,KAAK,KAAK,CAAC;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE;AAAA,IAAO,UACP,KAAK,OAAO,GAAG,UAAU,EAAE,EAAE,OAAO,GAAG,CAAC,KAAK,iBAAiB,IAAI,KAAK,CAAC;AAAA,EAC1E;AACA,QAAM,OAAO,IAAI,WAAW,CAAC,UAAU,CAAC;AAExC,QAAM,aAAa;AAAA,IACjB,KAAK,kBAAkB;AAAA,IACvB,KAAK,kBAAkB,IAAI,KAAK;AAAA,IAChC,KAAK;AAAA,EACP,EAAE,OAAO,UAAQ,KAAK,GAAG,KAAK,IAAI,CAAC;AACnC,QAAM,aAAa,SAAS,KAAK;AACjC,QAAM,iBAAiB,KAAK,IAAI,YAAY,aAAa,MAAM,MAAM,CAAC;AACtE,QAAM,cAAc,aAAa;AACjC,QAAM,UAAU,KAAK,IAAI,MAAM,KAAK,QAAQ,EAAE;AAC9C,QAAM,QAAQ,CAAC,MAAM,UAAU;AAC/B,MAAI,WAAW;AAEf,MAAI,cAAc,SAAS;AACzB,UAAM,QAAQ;AAAA,MACZ,KAAK,kBAAkB;AAAA,MACvB,cAAc;AAAA,IAChB,EAAE,OAAO,UAAQ,KAAK,GAAG,SAAS,IAAI,EAAE,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC;AAC9D,UAAM,KAAK,KAAK;AAChB,eAAW;AAAA,EACb;AAEA,QAAM,oBAAqB,KAAK,KAAK,CAAC,IAAI,IAAK,KAAK;AACpD,QAAM,gBACJ,KAAK,kBAAkB,KAAM,IAAI,IAAK;AACxC,QAAM,SAAS,cAAc;AAAA,IAC3B,OAAO,KAAK;AAAA,IACZ,GAAG,iBAAiB;AAAA,IACpB,eAAe,KAAK;AAAA,IACpB;AAAA,IACA,WAAY,IAAI,IAAK,KAAK;AAAA,IAC1B,YAAa,IAAI,IAAK,KAAK;AAAA,EAC7B,CAAC,EAAE,OAAO,UAAQ,KAAK,GAAG,SAAS,IAAI,EAAE,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC;AAC/D,QAAM,KAAK,MAAM;AAEjB,SAAO,MAAM,KAAK,EAAE,OAAO;AAAA,IACzB,SAAS,KAAK;AAAA,IACd,YAAY,KAAK;AAAA,IACjB,UAAU,WAAW;AAAA,IACrB,aAAa,OAAO;AAAA,IACpB,WAAW,OAAO;AAAA,EACpB,CAAC;AACH;AAzEgB;AAgGT,SAAS,cACd,OACA,gBACkC;AAClC,QAAM,UACJ,OAAO,mBAAmB,WACtB,EAAC,OAAO,eAAc,IACtB;AACN,QAAM,OAAO,qBAAqB,KAAK;AACvC,eAAa,IAAI;AACjB,MAAI,CAAC,OAAO,SAAS,QAAQ,KAAK,KAAK,QAAQ,SAAS,GAAG;AACzD,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AACA,QAAM,MAAM,QAAQ,OAAO;AAC3B,QAAM,WAAW,QAAQ,YAAY,KAAK,UAAU,GAAG;AACvD,MAAI,CAAC,OAAO,SAAS,QAAQ,KAAK,YAAY,KAAK,iBAAiB;AAClE,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,QAAQ,SAAS,WAAW,GAAG,QAAQ,KAAK;AAClD,QAAM,oBAAoB,QAAQ,eAAe;AACjD,MAAI,sBAAsB,OAAO;AAC/B,WAAO,MAAM,OAAO;AAAA,MAClB,UAAU,MAAM;AAAA,MAChB,aAAa,MAAM;AAAA,MACnB,WAAW,MAAM;AAAA,IACnB,CAAC;AAAA,EACH;AAEA,QAAM,cAAc,sBAAsB,OAAO,CAAC,IAAI;AACtD,QAAM,iBAAiB,YAAY,kBAAkB;AACrD,QAAM,mBACJ,YAAY,SAAS,KAAK,aAAa;AACzC,QAAM,sBAAsB,YAAY,YAAY,KAAK;AACzD,MACE,CAAC,OAAO,SAAS,gBAAgB,KACjC,oBAAoB,KACpB,mBAAmB,QAAQ,OAC3B;AACA,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,MACE,CAAC,OAAO,SAAS,mBAAmB,KACpC,sBAAsB,KAAK,cAC3B;AACA,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AACA,QAAM,SAAS;AAAA,IACb,sBAAsB;AAAA,IACtB,mBAAmB;AAAA,EACrB,EAAE;AAAA,IAAO,UACP,KAAK,OAAO,GAAG,MAAM,EAAE,EAAE,OAAO,GAAG,CAAC,mBAAmB,IAAI,KAAK,CAAC;AAAA,EACnE;AACA,SAAO,MAAM,CAAC,OAAO,MAAM,CAAC,EAAE,OAAO;AAAA,IACnC,UAAU,MAAM;AAAA,IAChB,aAAa,MAAM;AAAA,IACnB,WAAW,MAAM;AAAA,IACjB,gBAAgB,OAAO;AAAA,IACvB,mBAAmB,OAAO;AAAA,EAC5B,CAAC;AACH;AA7DgB;AA+DT,SAAS,qBAAqB,OAAkC;AACrE,SAAO,OAAO,UAAU,WAAW,eAAe,KAAK,IAAI;AAC7D;AAFgB;AAIT,SAAS,aAAa,MAAqB,QAAwB;AACxE,MAAI,UAAU,IAAK,QAAO,IAAI,KAAK,kBAAkB;AACrD,MAAI,UAAU,IAAK,QAAO,IAAI,KAAK,kBAAkB;AACrD,SAAO,IAAI,KAAK,kBAAkB;AACpC;AAJgB;AAMhB,SAAS,aAAa,MAA2B;AAC/C,QAAM,SAAS;AAAA,IACb,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,UAAU;AAAA,IACf,KAAK,UAAU;AAAA,IACf,KAAK,UAAU;AAAA,IACf,KAAK;AAAA,EACP;AACA,MAAI,OAAO,KAAK,WAAS,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,CAAC,GAAG;AAC/D,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,gBAAgB,KAAK,iBAAiB;AAC7C,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,MAAI,KAAK,kBAAkB,KAAK,YAAY;AAC1C,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACF;AAzBS;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/library/thread.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/library/thread.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,aAAa;WAXjB,MAAM;OACV,MAAM;mBACM,MAAM;mBACN,MAAM;eACV,MAAM;gBACL,MAAM;iBACL,OAAO;wCAqBrB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code3d/screws",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
"author": "vilicvane",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"scripts": {
|
|
11
|
-
"prepack": "
|
|
12
|
-
"test": "
|
|
13
|
-
"test:run": "node --test \"test/*.test.ts\"",
|
|
14
|
-
"test:types": "node ../../node_modules/typescript/bin/tsc --noEmit -p test/tsconfig.json"
|
|
11
|
+
"prepack": "npm run build",
|
|
12
|
+
"test": "npm run build && npm run test:types && npm run test:run",
|
|
13
|
+
"test:run": "node --import ../../test/source-loader.mjs --test --test-concurrency=1 \"test/*.test.ts\"",
|
|
14
|
+
"test:types": "node ../../node_modules/typescript/bin/tsc --noEmit -p test/tsconfig.json",
|
|
15
|
+
"build": "node ../../scripts/build-packages.mjs @code3d/screws"
|
|
15
16
|
},
|
|
16
17
|
"exports": {
|
|
17
18
|
".": {
|
|
@@ -25,9 +26,14 @@
|
|
|
25
26
|
"src"
|
|
26
27
|
],
|
|
27
28
|
"peerDependencies": {
|
|
28
|
-
"@code3d/core": "^0.0.1-alpha.
|
|
29
|
+
"@code3d/core": "^0.0.1-alpha.2"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
31
32
|
"@code3d/core": "*"
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/vilicvane/code3d.git",
|
|
37
|
+
"directory": "packages/screws"
|
|
32
38
|
}
|
|
33
39
|
}
|
package/src/library/thread.ts
CHANGED
|
@@ -21,9 +21,6 @@ type HelicalThreadOptions = Readonly<{
|
|
|
21
21
|
}>;
|
|
22
22
|
|
|
23
23
|
const loopSteps = Array.from({length: 21}, (_, index) => index / 20);
|
|
24
|
-
const threadBreps = new Map<string, string>();
|
|
25
|
-
const maximumCachedBrepCharacters = 8 * 1024 * 1024;
|
|
26
|
-
let cachedBrepCharacters = 0;
|
|
27
24
|
|
|
28
25
|
export const helicalThread = definePrimitive(
|
|
29
26
|
(options: HelicalThreadOptions) => {
|
|
@@ -34,7 +31,7 @@ export const helicalThread = definePrimitive(
|
|
|
34
31
|
leftHanded = false,
|
|
35
32
|
...dimensions
|
|
36
33
|
} = options;
|
|
37
|
-
return
|
|
34
|
+
return makeHelicalThreadShape({
|
|
38
35
|
...dimensions,
|
|
39
36
|
majorRadius: majorDiameter / 2,
|
|
40
37
|
minorRadius: minorDiameter / 2,
|
|
@@ -80,43 +77,6 @@ type HelicalThreadShapeOptions = Readonly<{
|
|
|
80
77
|
leftHanded: boolean;
|
|
81
78
|
}>;
|
|
82
79
|
|
|
83
|
-
function cachedHelicalThreadShape(options: HelicalThreadShapeOptions): Shape3D {
|
|
84
|
-
const key = JSON.stringify([
|
|
85
|
-
options.pitch,
|
|
86
|
-
options.y,
|
|
87
|
-
options.majorRadius,
|
|
88
|
-
options.minorRadius,
|
|
89
|
-
options.rootWidth,
|
|
90
|
-
options.crestWidth,
|
|
91
|
-
options.leftHanded,
|
|
92
|
-
]);
|
|
93
|
-
let brep = threadBreps.get(key);
|
|
94
|
-
if (brep === undefined) {
|
|
95
|
-
const shape = makeHelicalThreadShape(options);
|
|
96
|
-
try {
|
|
97
|
-
brep = shape.serialize();
|
|
98
|
-
} finally {
|
|
99
|
-
shape.delete();
|
|
100
|
-
}
|
|
101
|
-
if (brep.length <= maximumCachedBrepCharacters) {
|
|
102
|
-
threadBreps.set(key, brep);
|
|
103
|
-
cachedBrepCharacters += brep.length;
|
|
104
|
-
while (cachedBrepCharacters > maximumCachedBrepCharacters) {
|
|
105
|
-
const [oldestKey, oldestBrep] = threadBreps.entries().next().value!;
|
|
106
|
-
threadBreps.delete(oldestKey);
|
|
107
|
-
cachedBrepCharacters -= oldestBrep.length;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
} else {
|
|
111
|
-
threadBreps.delete(key);
|
|
112
|
-
threadBreps.set(key, brep);
|
|
113
|
-
}
|
|
114
|
-
// Cache data, not native handles or disposable models. Each invocation owns
|
|
115
|
-
// a fresh shape in the current kernel. Reading both misses and hits also
|
|
116
|
-
// applies the same B-Rep normalization before core identifies the geometry.
|
|
117
|
-
return replicad.deserializeShape(brep) as Shape3D;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
80
|
/**
|
|
121
81
|
* Builds a closed external thread around its minor-diameter core. The lofted
|
|
122
82
|
* end treatment follows the MIT-licensed replicad-threads construction by
|
package/bld/library/iso-4762.js
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import { cylinder, cut, frustum, regularPrism, union, } from '@code3d/core';
|
|
2
|
-
import { helicalThread } from './thread.js';
|
|
3
|
-
// ISO 4762 coarse-thread socket-head cap screws; millimetres.
|
|
4
|
-
// Clearance series follow ISO 273. Counterbores follow DIN 974-1 normal series.
|
|
5
|
-
export const specifications = {
|
|
6
|
-
M3: {
|
|
7
|
-
designation: 'M3',
|
|
8
|
-
nominalDiameter: 3,
|
|
9
|
-
pitch: 0.5,
|
|
10
|
-
headDiameter: 5.5,
|
|
11
|
-
headHeight: 3,
|
|
12
|
-
hexSocketWidth: 2.5,
|
|
13
|
-
hexSocketDepth: 1.3,
|
|
14
|
-
underHeadRadius: 0.1,
|
|
15
|
-
clearance: { close: 3.2, normal: 3.4, loose: 3.6 },
|
|
16
|
-
counterboreDiameter: 6,
|
|
17
|
-
},
|
|
18
|
-
M4: {
|
|
19
|
-
designation: 'M4',
|
|
20
|
-
nominalDiameter: 4,
|
|
21
|
-
pitch: 0.7,
|
|
22
|
-
headDiameter: 7,
|
|
23
|
-
headHeight: 4,
|
|
24
|
-
hexSocketWidth: 3,
|
|
25
|
-
hexSocketDepth: 2,
|
|
26
|
-
underHeadRadius: 0.2,
|
|
27
|
-
clearance: { close: 4.3, normal: 4.5, loose: 4.8 },
|
|
28
|
-
counterboreDiameter: 8,
|
|
29
|
-
},
|
|
30
|
-
M5: {
|
|
31
|
-
designation: 'M5',
|
|
32
|
-
nominalDiameter: 5,
|
|
33
|
-
pitch: 0.8,
|
|
34
|
-
headDiameter: 8.5,
|
|
35
|
-
headHeight: 5,
|
|
36
|
-
hexSocketWidth: 4,
|
|
37
|
-
hexSocketDepth: 2.5,
|
|
38
|
-
underHeadRadius: 0.2,
|
|
39
|
-
clearance: { close: 5.3, normal: 5.5, loose: 5.8 },
|
|
40
|
-
counterboreDiameter: 10,
|
|
41
|
-
},
|
|
42
|
-
M6: {
|
|
43
|
-
designation: 'M6',
|
|
44
|
-
nominalDiameter: 6,
|
|
45
|
-
pitch: 1,
|
|
46
|
-
headDiameter: 10,
|
|
47
|
-
headHeight: 6,
|
|
48
|
-
hexSocketWidth: 5,
|
|
49
|
-
hexSocketDepth: 3,
|
|
50
|
-
underHeadRadius: 0.25,
|
|
51
|
-
clearance: { close: 6.4, normal: 6.6, loose: 7 },
|
|
52
|
-
counterboreDiameter: 11,
|
|
53
|
-
},
|
|
54
|
-
M8: {
|
|
55
|
-
designation: 'M8',
|
|
56
|
-
nominalDiameter: 8,
|
|
57
|
-
pitch: 1.25,
|
|
58
|
-
headDiameter: 13,
|
|
59
|
-
headHeight: 8,
|
|
60
|
-
hexSocketWidth: 6,
|
|
61
|
-
hexSocketDepth: 4,
|
|
62
|
-
underHeadRadius: 0.4,
|
|
63
|
-
clearance: { close: 8.4, normal: 9, loose: 10 },
|
|
64
|
-
counterboreDiameter: 15,
|
|
65
|
-
},
|
|
66
|
-
M10: {
|
|
67
|
-
designation: 'M10',
|
|
68
|
-
nominalDiameter: 10,
|
|
69
|
-
pitch: 1.5,
|
|
70
|
-
headDiameter: 16,
|
|
71
|
-
headHeight: 10,
|
|
72
|
-
hexSocketWidth: 8,
|
|
73
|
-
hexSocketDepth: 5,
|
|
74
|
-
underHeadRadius: 0.4,
|
|
75
|
-
clearance: { close: 10.5, normal: 11, loose: 12 },
|
|
76
|
-
counterboreDiameter: 18,
|
|
77
|
-
},
|
|
78
|
-
M12: {
|
|
79
|
-
designation: 'M12',
|
|
80
|
-
nominalDiameter: 12,
|
|
81
|
-
pitch: 1.75,
|
|
82
|
-
headDiameter: 18,
|
|
83
|
-
headHeight: 12,
|
|
84
|
-
hexSocketWidth: 10,
|
|
85
|
-
hexSocketDepth: 6,
|
|
86
|
-
underHeadRadius: 0.6,
|
|
87
|
-
clearance: { close: 13, normal: 13.5, loose: 14.5 },
|
|
88
|
-
counterboreDiameter: 20,
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
/**
|
|
92
|
-
* @code3d.arguments ['M6', 18]
|
|
93
|
-
* @code3d.arguments ['M8', 30]
|
|
94
|
-
* @code3d.param length {kind: 'length'}
|
|
95
|
-
*/
|
|
96
|
-
export function screw(input, length) {
|
|
97
|
-
const spec = resolveSpecification(input);
|
|
98
|
-
validateSpec(spec);
|
|
99
|
-
if (!Number.isFinite(length) || length <= spec.pitch + spec.underHeadRadius) {
|
|
100
|
-
throw new Error('Screw length must leave room for at least one full thread pitch.');
|
|
101
|
-
}
|
|
102
|
-
const headChamfer = Math.min(spec.pitch / 2, spec.headHeight * 0.12);
|
|
103
|
-
const headBarrel = cylinder(spec.headDiameter / 2, spec.headHeight - headChamfer);
|
|
104
|
-
const headTop = frustum(spec.headDiameter / 2, spec.headDiameter / 2 - headChamfer, headChamfer).relate(top => top.on(headBarrel.up));
|
|
105
|
-
const headBlank = union([headBarrel, headTop]);
|
|
106
|
-
const socketToolY = spec.hexSocketDepth + 0.2;
|
|
107
|
-
const socketTool = regularPrism(spec.hexSocketWidth / Math.sqrt(3), socketToolY, 6, 30).relate(tool => tool.center.on(headBlank.up).offset(0, -spec.hexSocketDepth / 2 + 0.1, 0));
|
|
108
|
-
const head = cut(headBlank, [socketTool]);
|
|
109
|
-
const transition = frustum(spec.nominalDiameter / 2, spec.nominalDiameter / 2 + spec.underHeadRadius, spec.underHeadRadius).relate(part => part.on(head.down));
|
|
110
|
-
const bodyLength = length - spec.underHeadRadius;
|
|
111
|
-
const threadedLength = Math.min(bodyLength, threadLength(spec, length));
|
|
112
|
-
const plainLength = bodyLength - threadedLength;
|
|
113
|
-
const overlap = Math.min(0.08, spec.pitch / 10);
|
|
114
|
-
const parts = [head, transition];
|
|
115
|
-
let previous = transition;
|
|
116
|
-
if (plainLength > overlap) {
|
|
117
|
-
const shank = cylinder(spec.nominalDiameter / 2, plainLength + overlap).relate(part => part.on(previous.down).offset(0, -overlap, 0));
|
|
118
|
-
parts.push(shank);
|
|
119
|
-
previous = shank;
|
|
120
|
-
}
|
|
121
|
-
const fundamentalHeight = (Math.sqrt(3) / 2) * spec.pitch;
|
|
122
|
-
const minorDiameter = spec.nominalDiameter - 2 * ((5 / 8) * fundamentalHeight);
|
|
123
|
-
const thread = helicalThread({
|
|
124
|
-
pitch: spec.pitch,
|
|
125
|
-
y: threadedLength + overlap,
|
|
126
|
-
majorDiameter: spec.nominalDiameter,
|
|
127
|
-
minorDiameter,
|
|
128
|
-
rootWidth: (3 / 4) * spec.pitch,
|
|
129
|
-
crestWidth: (1 / 8) * spec.pitch,
|
|
130
|
-
}).relate(part => part.on(previous.down).offset(0, -overlap, 0));
|
|
131
|
-
parts.push(thread);
|
|
132
|
-
return union(parts).expose({
|
|
133
|
-
headTop: head.up,
|
|
134
|
-
headBottom: head.down,
|
|
135
|
-
shankTop: transition.up,
|
|
136
|
-
shankBottom: thread.down,
|
|
137
|
-
shankAxis: thread.axis,
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
export function clearanceHole(input, optionsOrDepth) {
|
|
141
|
-
const options = typeof optionsOrDepth === 'number'
|
|
142
|
-
? { depth: optionsOrDepth }
|
|
143
|
-
: optionsOrDepth;
|
|
144
|
-
const spec = resolveSpecification(input);
|
|
145
|
-
validateSpec(spec);
|
|
146
|
-
if (!Number.isFinite(options.depth) || options.depth <= 0) {
|
|
147
|
-
throw new Error('Hole depth must be a positive finite number.');
|
|
148
|
-
}
|
|
149
|
-
const fit = options.fit ?? 'normal';
|
|
150
|
-
const diameter = options.diameter ?? spec.clearance[fit];
|
|
151
|
-
if (!Number.isFinite(diameter) || diameter <= spec.nominalDiameter) {
|
|
152
|
-
throw new Error('Clearance-hole diameter must exceed the nominal screw diameter.');
|
|
153
|
-
}
|
|
154
|
-
const shaft = cylinder(diameter / 2, options.depth);
|
|
155
|
-
const counterboreOption = options.counterbore ?? true;
|
|
156
|
-
if (counterboreOption === false) {
|
|
157
|
-
return shaft.expose({
|
|
158
|
-
shaftTop: shaft.up,
|
|
159
|
-
shaftBottom: shaft.down,
|
|
160
|
-
shaftAxis: shaft.axis,
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
const counterbore = counterboreOption === true ? {} : counterboreOption;
|
|
164
|
-
const axialClearance = counterbore.axialClearance ?? 0.5;
|
|
165
|
-
const counterboreDepth = counterbore.depth ?? spec.headHeight + axialClearance;
|
|
166
|
-
const counterboreDiameter = counterbore.diameter ?? spec.counterboreDiameter;
|
|
167
|
-
if (!Number.isFinite(counterboreDepth) ||
|
|
168
|
-
counterboreDepth <= 0 ||
|
|
169
|
-
counterboreDepth > options.depth) {
|
|
170
|
-
throw new Error('Counterbore depth must be within the total hole depth.');
|
|
171
|
-
}
|
|
172
|
-
if (!Number.isFinite(counterboreDiameter) ||
|
|
173
|
-
counterboreDiameter < spec.headDiameter) {
|
|
174
|
-
throw new Error('Counterbore diameter must accommodate the screw head.');
|
|
175
|
-
}
|
|
176
|
-
const recess = cylinder(counterboreDiameter / 2, counterboreDepth + 0.2).relate(tool => tool.center.on(shaft.up).offset(0, -counterboreDepth / 2 + 0.1, 0));
|
|
177
|
-
return union([shaft, recess]).expose({
|
|
178
|
-
shaftTop: shaft.up,
|
|
179
|
-
shaftBottom: shaft.down,
|
|
180
|
-
shaftAxis: shaft.axis,
|
|
181
|
-
counterboreTop: recess.up,
|
|
182
|
-
counterboreBottom: recess.down,
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
export function resolveSpecification(input) {
|
|
186
|
-
return typeof input === 'string' ? specifications[input] : input;
|
|
187
|
-
}
|
|
188
|
-
export function threadLength(spec, length) {
|
|
189
|
-
if (length <= 125)
|
|
190
|
-
return 2 * spec.nominalDiameter + 12;
|
|
191
|
-
if (length <= 200)
|
|
192
|
-
return 2 * spec.nominalDiameter + 18;
|
|
193
|
-
return 2 * spec.nominalDiameter + 31;
|
|
194
|
-
}
|
|
195
|
-
function validateSpec(spec) {
|
|
196
|
-
const values = [
|
|
197
|
-
spec.nominalDiameter,
|
|
198
|
-
spec.pitch,
|
|
199
|
-
spec.headDiameter,
|
|
200
|
-
spec.headHeight,
|
|
201
|
-
spec.hexSocketWidth,
|
|
202
|
-
spec.hexSocketDepth,
|
|
203
|
-
spec.underHeadRadius,
|
|
204
|
-
spec.clearance.close,
|
|
205
|
-
spec.clearance.normal,
|
|
206
|
-
spec.clearance.loose,
|
|
207
|
-
spec.counterboreDiameter,
|
|
208
|
-
];
|
|
209
|
-
if (values.some(value => !Number.isFinite(value) || value <= 0)) {
|
|
210
|
-
throw new Error('Fastener specifications must contain positive finite dimensions.');
|
|
211
|
-
}
|
|
212
|
-
if (spec.headDiameter <= spec.nominalDiameter) {
|
|
213
|
-
throw new Error('Head diameter must exceed the nominal thread diameter.');
|
|
214
|
-
}
|
|
215
|
-
if (spec.hexSocketDepth >= spec.headHeight) {
|
|
216
|
-
throw new Error('Hex socket depth must be smaller than the head height.');
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
//# sourceMappingURL=iso-4762.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"iso-4762.js","sourceRoot":"","sources":["../../src/library/iso-4762.ts"],"names":[],"mappings":"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"}
|
package/bld/library/thread.js
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { definePrimitive, replicad, } from '@code3d/core/replicad';
|
|
2
|
-
const { Plane, draw, makeCylinder, makeHelix, makeSolid, weldShellsAndFaces } = replicad;
|
|
3
|
-
const loopSteps = Array.from({ length: 21 }, (_, index) => index / 20);
|
|
4
|
-
const threadBreps = new Map();
|
|
5
|
-
const maximumCachedBrepCharacters = 8 * 1024 * 1024;
|
|
6
|
-
let cachedBrepCharacters = 0;
|
|
7
|
-
export const helicalThread = definePrimitive((options) => {
|
|
8
|
-
validateHelicalThread(options);
|
|
9
|
-
const { majorDiameter, minorDiameter, leftHanded = false, ...dimensions } = options;
|
|
10
|
-
return cachedHelicalThreadShape({
|
|
11
|
-
...dimensions,
|
|
12
|
-
majorRadius: majorDiameter / 2,
|
|
13
|
-
minorRadius: minorDiameter / 2,
|
|
14
|
-
leftHanded,
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
function validateHelicalThread({ pitch, y, majorDiameter, minorDiameter, rootWidth, crestWidth, }) {
|
|
18
|
-
assertPositive('pitch', pitch);
|
|
19
|
-
assertPositive('y', y);
|
|
20
|
-
assertPositive('majorDiameter', majorDiameter);
|
|
21
|
-
assertPositive('minorDiameter', minorDiameter);
|
|
22
|
-
assertPositive('rootWidth', rootWidth);
|
|
23
|
-
assertPositive('crestWidth', crestWidth);
|
|
24
|
-
if (y < pitch) {
|
|
25
|
-
throw new Error('y must be at least one thread pitch.');
|
|
26
|
-
}
|
|
27
|
-
if (minorDiameter >= majorDiameter) {
|
|
28
|
-
throw new Error('minorDiameter must be smaller than majorDiameter.');
|
|
29
|
-
}
|
|
30
|
-
if (crestWidth >= rootWidth || rootWidth > pitch) {
|
|
31
|
-
throw new Error('The thread profile requires crestWidth < rootWidth <= pitch.');
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
function cachedHelicalThreadShape(options) {
|
|
35
|
-
const key = JSON.stringify([
|
|
36
|
-
options.pitch,
|
|
37
|
-
options.y,
|
|
38
|
-
options.majorRadius,
|
|
39
|
-
options.minorRadius,
|
|
40
|
-
options.rootWidth,
|
|
41
|
-
options.crestWidth,
|
|
42
|
-
options.leftHanded,
|
|
43
|
-
]);
|
|
44
|
-
let brep = threadBreps.get(key);
|
|
45
|
-
if (brep === undefined) {
|
|
46
|
-
const shape = makeHelicalThreadShape(options);
|
|
47
|
-
try {
|
|
48
|
-
brep = shape.serialize();
|
|
49
|
-
}
|
|
50
|
-
finally {
|
|
51
|
-
shape.delete();
|
|
52
|
-
}
|
|
53
|
-
if (brep.length <= maximumCachedBrepCharacters) {
|
|
54
|
-
threadBreps.set(key, brep);
|
|
55
|
-
cachedBrepCharacters += brep.length;
|
|
56
|
-
while (cachedBrepCharacters > maximumCachedBrepCharacters) {
|
|
57
|
-
const [oldestKey, oldestBrep] = threadBreps.entries().next().value;
|
|
58
|
-
threadBreps.delete(oldestKey);
|
|
59
|
-
cachedBrepCharacters -= oldestBrep.length;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
threadBreps.delete(key);
|
|
65
|
-
threadBreps.set(key, brep);
|
|
66
|
-
}
|
|
67
|
-
// Cache data, not native handles or disposable models. Each invocation owns
|
|
68
|
-
// a fresh shape in the current kernel. Reading both misses and hits also
|
|
69
|
-
// applies the same B-Rep normalization before core identifies the geometry.
|
|
70
|
-
return replicad.deserializeShape(brep);
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Builds a closed external thread around its minor-diameter core. The lofted
|
|
74
|
-
* end treatment follows the MIT-licensed replicad-threads construction by
|
|
75
|
-
* Steve Genoud, adapted here to code3d's Y-axis and geometry ownership model.
|
|
76
|
-
*/
|
|
77
|
-
function makeHelicalThreadShape({ pitch, y, majorRadius, minorRadius, rootWidth, crestWidth, leftHanded, }) {
|
|
78
|
-
const toothHeight = majorRadius - minorRadius;
|
|
79
|
-
const profile = threadProfile(rootWidth, crestWidth, toothHeight);
|
|
80
|
-
const teeth = fadedThread(pitch, minorRadius, y, profile, leftHanded);
|
|
81
|
-
const core = makeCylinder(minorRadius + 0.05, y);
|
|
82
|
-
const threaded = core.fuse(teeth);
|
|
83
|
-
core.delete();
|
|
84
|
-
teeth.delete();
|
|
85
|
-
return threaded.rotate(-90, [0, 0, 0], [1, 0, 0]).translate([0, -y / 2, 0]);
|
|
86
|
-
}
|
|
87
|
-
function threadProfile(rootWidth, crestWidth, toothHeight) {
|
|
88
|
-
const rootHalf = rootWidth / 2;
|
|
89
|
-
const crestHalf = crestWidth / 2;
|
|
90
|
-
return draw([rootHalf, -0.05])
|
|
91
|
-
.vLine(0.05)
|
|
92
|
-
.lineTo([crestHalf, toothHeight])
|
|
93
|
-
.hLineTo(-crestHalf)
|
|
94
|
-
.lineTo([-rootHalf, 0])
|
|
95
|
-
.vLine(-0.05)
|
|
96
|
-
.close();
|
|
97
|
-
}
|
|
98
|
-
function fadedThread(pitch, radius, length, profile, leftHanded) {
|
|
99
|
-
const bottomEnd = fadedEnd(pitch, radius, profile, true, leftHanded);
|
|
100
|
-
const totalLoops = length / pitch - 0.5;
|
|
101
|
-
const fullLoops = Math.floor(totalLoops);
|
|
102
|
-
const leftover = totalLoops - fullLoops;
|
|
103
|
-
const singleLoop = basicThreadLoop(pitch, radius, profile, 1, 'none', leftHanded);
|
|
104
|
-
const shells = Array.from({ length: fullLoops }, (_, index) => singleLoop.clone().translate([0, 0, index * pitch]));
|
|
105
|
-
singleLoop.delete();
|
|
106
|
-
if (leftover > 1e-9) {
|
|
107
|
-
shells.push(basicThreadLoop(pitch, radius, profile, leftover, 'none', leftHanded).translate([0, 0, fullLoops * pitch]));
|
|
108
|
-
}
|
|
109
|
-
const topEnd = fadedEnd(pitch, radius, profile, false, leftHanded)
|
|
110
|
-
.translate([0, 0, totalLoops * pitch])
|
|
111
|
-
.rotate(360 * leftover, [0, 0, 0], [0, 0, 1]);
|
|
112
|
-
const thread = makeSolid([bottomEnd, ...shells, topEnd]).translate([
|
|
113
|
-
0,
|
|
114
|
-
0,
|
|
115
|
-
pitch / 4,
|
|
116
|
-
]);
|
|
117
|
-
bottomEnd.delete();
|
|
118
|
-
shells.forEach(shell => shell.delete());
|
|
119
|
-
topEnd.delete();
|
|
120
|
-
return thread;
|
|
121
|
-
}
|
|
122
|
-
function basicThreadLoop(pitch, radius, profile, loopFraction, includeEnd, leftHanded) {
|
|
123
|
-
const helix = makeHelix(pitch, pitch * clamp(loopFraction, 0, 1), radius, [0, 0, 0], [0, 0, 1], leftHanded);
|
|
124
|
-
const profiles = loopSteps.map(step => {
|
|
125
|
-
const position = helix.pointAt(step);
|
|
126
|
-
const tangent = helix.tangentAt(step);
|
|
127
|
-
const plane = new Plane(position, [0, 0, 1], tangent);
|
|
128
|
-
const sketch = profile.sketchOnPlane(plane);
|
|
129
|
-
plane.delete();
|
|
130
|
-
return sketch;
|
|
131
|
-
});
|
|
132
|
-
helix.delete();
|
|
133
|
-
const ends = [];
|
|
134
|
-
if (includeEnd === 'first' || includeEnd === 'both') {
|
|
135
|
-
ends.push(profiles[0].faces());
|
|
136
|
-
}
|
|
137
|
-
if (includeEnd === 'last' || includeEnd === 'both') {
|
|
138
|
-
const face = profiles.at(-1).faces();
|
|
139
|
-
face.wrapped.Reverse();
|
|
140
|
-
ends.push(face);
|
|
141
|
-
}
|
|
142
|
-
const shell = profiles[0].loftWith(profiles.slice(1), { ruled: false }, true);
|
|
143
|
-
if (ends.length === 0)
|
|
144
|
-
return shell;
|
|
145
|
-
const closed = weldShellsAndFaces([shell, ...ends]);
|
|
146
|
-
shell.delete();
|
|
147
|
-
ends.forEach(face => face.delete());
|
|
148
|
-
return closed;
|
|
149
|
-
}
|
|
150
|
-
function fadedEnd(pitch, radius, profile, bottom, leftHanded) {
|
|
151
|
-
const length = pitch / 4;
|
|
152
|
-
const helix = makeHelix(pitch, length, radius, [0, 0, 0], [0, 0, bottom ? -1 : 1], leftHanded);
|
|
153
|
-
const profiles = loopSteps.map((step, index) => {
|
|
154
|
-
const position = helix.pointAt(step);
|
|
155
|
-
let tangent = helix.tangentAt(step);
|
|
156
|
-
if (bottom)
|
|
157
|
-
tangent = tangent.multiply(-1);
|
|
158
|
-
const plane = new Plane(position, [0, 0, 1], tangent);
|
|
159
|
-
const sketch = profile
|
|
160
|
-
.scale((loopSteps.length - index) / loopSteps.length, [0, 0])
|
|
161
|
-
.sketchOnPlane(plane);
|
|
162
|
-
plane.delete();
|
|
163
|
-
return sketch;
|
|
164
|
-
});
|
|
165
|
-
helix.delete();
|
|
166
|
-
const endFace = profiles.at(-1).faces();
|
|
167
|
-
const shell = profiles[0].loftWith(profiles.slice(1), { ruled: false }, true);
|
|
168
|
-
const closed = weldShellsAndFaces([shell, endFace]);
|
|
169
|
-
shell.delete();
|
|
170
|
-
endFace.delete();
|
|
171
|
-
return bottom ? closed.rotate(180, [0, 0, 0], [0, 0, 1]) : closed;
|
|
172
|
-
}
|
|
173
|
-
function assertPositive(name, value) {
|
|
174
|
-
if (!Number.isFinite(value) || value <= 0) {
|
|
175
|
-
throw new Error(`${name} must be a positive finite number.`);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
function clamp(value, minimum, maximum) {
|
|
179
|
-
return Math.min(Math.max(value, minimum), maximum);
|
|
180
|
-
}
|
|
181
|
-
//# sourceMappingURL=thread.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"thread.js","sourceRoot":"","sources":["../../src/library/thread.ts"],"names":[],"mappings":"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"}
|