@toolpath/dfm 0.4.0 → 0.5.0
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 +47 -5
- package/dist/{chunk-5MPHT7BC.js → chunk-4IRNLDE6.js} +548 -142
- package/dist/{feature-record-DHbkVpx0.d.ts → feature-record-CfjgDCJU.d.ts} +163 -99
- package/dist/index.d.ts +18 -2
- package/dist/index.js +97 -76
- package/dist/model/index.d.ts +61 -15
- package/dist/model/index.js +241 -31
- package/package.json +3 -3
package/dist/model/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CRITICAL_COLOR,
|
|
3
3
|
FILE_KIND,
|
|
4
|
+
ID_KINDS,
|
|
4
5
|
LENGTH_PLACES,
|
|
6
|
+
MILLING_RULES,
|
|
5
7
|
RULE_COLORS,
|
|
8
|
+
TURNING_RULES,
|
|
6
9
|
TYPE_SUBJECT,
|
|
7
10
|
WARNING_COLOR,
|
|
8
11
|
breaks,
|
|
@@ -26,10 +29,12 @@ import {
|
|
|
26
29
|
runStart,
|
|
27
30
|
sameDepth,
|
|
28
31
|
serializeRuleSet,
|
|
32
|
+
subjectInfo,
|
|
29
33
|
trimmedCurve,
|
|
34
|
+
turnedTypeLabel,
|
|
30
35
|
unitLabel,
|
|
31
36
|
worseUpward
|
|
32
|
-
} from "../chunk-
|
|
37
|
+
} from "../chunk-4IRNLDE6.js";
|
|
33
38
|
|
|
34
39
|
// src/model/broken-rules.ts
|
|
35
40
|
var byColor = (hits) => [...hits].sort((a, b) => compareColors(a.rule.color, b.rule.color));
|
|
@@ -41,12 +46,12 @@ var worstHits = (hits) => {
|
|
|
41
46
|
return true;
|
|
42
47
|
});
|
|
43
48
|
};
|
|
44
|
-
var brokenRules = (check, tag, units) => worstHits(check.hitsByTag.get(tag.toLowerCase()) ?? []).map((hit) => {
|
|
49
|
+
var brokenRules = (check, tag, units, vocabulary = MILLING_RULES) => worstHits(check.hitsByTag.get(tag.toLowerCase()) ?? []).map((hit) => {
|
|
45
50
|
const figure = hitFigure(hit, units);
|
|
46
51
|
return {
|
|
47
52
|
key: hit.rule.id,
|
|
48
53
|
color: hit.rule.color,
|
|
49
|
-
text: describeRule(hit.rule, units),
|
|
54
|
+
text: describeRule(hit.rule, units, vocabulary),
|
|
50
55
|
...figure ? { figure } : {}
|
|
51
56
|
};
|
|
52
57
|
});
|
|
@@ -106,9 +111,9 @@ var featureIs = (subject, featureType, sheet) => {
|
|
|
106
111
|
return false;
|
|
107
112
|
}
|
|
108
113
|
};
|
|
109
|
-
var at = (
|
|
114
|
+
var at = (record2, path) => path.split(".").reduce(
|
|
110
115
|
(value, key) => typeof value === "object" && value !== null ? value[key] : void 0,
|
|
111
|
-
|
|
116
|
+
record2
|
|
112
117
|
);
|
|
113
118
|
var readPath = (datasheet, metric) => {
|
|
114
119
|
for (const path of metric.path ?? []) {
|
|
@@ -217,6 +222,22 @@ var requiredTags = (features) => {
|
|
|
217
222
|
features.filter((feature) => feature.regionIdxs.some((region) => owners.get(region) === 1)).map((feature) => feature.tag.toLowerCase())
|
|
218
223
|
);
|
|
219
224
|
};
|
|
225
|
+
var worstColor = (hits) => hits?.map((hit) => hit.rule.color).sort(compareColors)[0];
|
|
226
|
+
var ruleResults = (rules, features, hitsByTag, required) => rules.map((rule) => {
|
|
227
|
+
const hits = features.flatMap((feature) => {
|
|
228
|
+
const tag = feature.tag.toLowerCase();
|
|
229
|
+
const hit = hitsByTag.get(tag)?.find((each) => each.rule.id === rule.id);
|
|
230
|
+
return hit ? [{ tag: feature.tag, value: hit.value, metric: hit.metric, required: required.has(tag) }] : [];
|
|
231
|
+
});
|
|
232
|
+
const [first] = hits;
|
|
233
|
+
const up = first ? worseUpward(rule, first.metric) : true;
|
|
234
|
+
hits.sort((a, b) => up ? b.value - a.value : a.value - b.value);
|
|
235
|
+
return {
|
|
236
|
+
rule,
|
|
237
|
+
tags: hits.filter((hit) => hit.required).map((hit) => hit.tag),
|
|
238
|
+
otherTags: hits.filter((hit) => !hit.required).map((hit) => hit.tag)
|
|
239
|
+
};
|
|
240
|
+
});
|
|
220
241
|
var QUALIFIERS = ["undercut", "filleted", "tslot", "dovetail"];
|
|
221
242
|
var EDGE_TYPES = ["fillet", "chamfer", "sink"];
|
|
222
243
|
var featureComplexity = (featureType) => {
|
|
@@ -226,7 +247,6 @@ var featureComplexity = (featureType) => {
|
|
|
226
247
|
};
|
|
227
248
|
var CONTOUR = "contour_surface";
|
|
228
249
|
var unavoidableFaces = (features, hitsByTag, regionAreas) => {
|
|
229
|
-
const worstColor = (feature) => hitsByTag.get(feature.tag.toLowerCase())?.map((hit) => hit.rule.color).sort(compareColors)[0];
|
|
230
250
|
const areaOf = (feature) => [...new Set(feature.regionIdxs)].reduce(
|
|
231
251
|
(sum, region) => sum + (regionAreas.get(region) ?? 0),
|
|
232
252
|
0
|
|
@@ -242,7 +262,7 @@ var unavoidableFaces = (features, hitsByTag, regionAreas) => {
|
|
|
242
262
|
for (const [region, candidates] of owners) {
|
|
243
263
|
const colored = candidates.map((feature) => ({
|
|
244
264
|
feature,
|
|
245
|
-
color: worstColor(feature),
|
|
265
|
+
color: worstColor(hitsByTag.get(feature.tag.toLowerCase())),
|
|
246
266
|
area: areaOf(feature)
|
|
247
267
|
}));
|
|
248
268
|
const isContour = ({ feature }) => feature.featureType === CONTOUR;
|
|
@@ -269,10 +289,10 @@ var unavoidableFaces = (features, hitsByTag, regionAreas) => {
|
|
|
269
289
|
};
|
|
270
290
|
var withSurroundedFaces = (check, features, adjacency) => {
|
|
271
291
|
const paintedFor = new Map(check.paintedFaces);
|
|
272
|
-
const
|
|
292
|
+
const regionsOf2 = /* @__PURE__ */ new Map();
|
|
273
293
|
for (const feature of features) {
|
|
274
294
|
const key = feature.tag.toLowerCase();
|
|
275
|
-
|
|
295
|
+
regionsOf2.set(key, new Set(feature.regionIdxs));
|
|
276
296
|
const whole = check.paintedWhole.get(key);
|
|
277
297
|
if (whole) {
|
|
278
298
|
for (const region of feature.regionIdxs)
|
|
@@ -290,7 +310,7 @@ var withSurroundedFaces = (check, features, adjacency) => {
|
|
|
290
310
|
counts.set(key, { paint: paint2, count: (counts.get(key)?.count ?? 0) + 1 });
|
|
291
311
|
}
|
|
292
312
|
const most = Math.max(0, ...[...counts.values()].map(({ count }) => count));
|
|
293
|
-
const [paint] = [...counts].filter(([key, { count }]) => count === most &&
|
|
313
|
+
const [paint] = [...counts].filter(([key, { count }]) => count === most && regionsOf2.get(key)?.has(region)).map(([, { paint: paint2 }]) => paint2).sort((a, b) => compareColors(a.color, b.color));
|
|
294
314
|
if (paint) surrounded.set(region, paint);
|
|
295
315
|
}
|
|
296
316
|
if (surrounded.size === 0) return check;
|
|
@@ -304,25 +324,10 @@ var checkPart = (features, sources, rules) => {
|
|
|
304
324
|
featureHits(features, feature, sources, rules)
|
|
305
325
|
])
|
|
306
326
|
);
|
|
307
|
-
const byRule = rules.map((rule) => {
|
|
308
|
-
const hits = features.flatMap((feature) => {
|
|
309
|
-
const tag = feature.tag.toLowerCase();
|
|
310
|
-
const hit = hitsByTag.get(tag)?.find((each) => each.rule.id === rule.id);
|
|
311
|
-
return hit ? [{ tag: feature.tag, value: hit.value, metric: hit.metric, required: required.has(tag) }] : [];
|
|
312
|
-
});
|
|
313
|
-
const [first] = hits;
|
|
314
|
-
const up = first ? worseUpward(rule, first.metric) : true;
|
|
315
|
-
hits.sort((a, b) => up ? b.value - a.value : a.value - b.value);
|
|
316
|
-
return {
|
|
317
|
-
rule,
|
|
318
|
-
tags: hits.filter((hit) => hit.required).map((hit) => hit.tag),
|
|
319
|
-
otherTags: hits.filter((hit) => !hit.required).map((hit) => hit.tag)
|
|
320
|
-
};
|
|
321
|
-
});
|
|
322
327
|
return {
|
|
323
328
|
hitsByTag,
|
|
324
329
|
required,
|
|
325
|
-
byRule,
|
|
330
|
+
byRule: ruleResults(rules, features, hitsByTag, required),
|
|
326
331
|
...unavoidableFaces(features, hitsByTag, sources.regionAreas)
|
|
327
332
|
};
|
|
328
333
|
};
|
|
@@ -715,8 +720,8 @@ var featureMeasurements = ({
|
|
|
715
720
|
if (ld && top !== null && bottom !== void 0) {
|
|
716
721
|
const across = ld.basis === "bore" ? `D = facts.diameter = ${mm(ld.across)}` : ld.basis === "pinch" ? `D = widest tool (the tightest pinch disc, tolerance taken out) = ${mm(ld.across)}${ld.atLeast ? " (at most, so L/D is at least)" : ""}` : `D = widest tool = 2 \xD7 inside corner radius = ${mm(ld.across)}${ld.atLeast ? " (at most, so L/D is at least)" : ""} (no pinch points reported)`;
|
|
717
722
|
const ratioOf = (depth) => {
|
|
718
|
-
const
|
|
719
|
-
return ld.atLeast ? `\u2265 ${
|
|
723
|
+
const ratio2 = (depth / ld.across).toFixed(3);
|
|
724
|
+
return ld.atLeast ? `\u2265 ${ratio2}` : ratio2;
|
|
720
725
|
};
|
|
721
726
|
if (ld.drilling) {
|
|
722
727
|
rows.push({
|
|
@@ -948,16 +953,16 @@ var undercutRows = (sheet, undercut, top, length) => {
|
|
|
948
953
|
);
|
|
949
954
|
if (top !== null && zMin !== void 0) {
|
|
950
955
|
const reach = top - zMin;
|
|
951
|
-
const
|
|
956
|
+
const ratio2 = (reach / head).toFixed(3);
|
|
952
957
|
rows.push({
|
|
953
958
|
key: "topLd",
|
|
954
959
|
label: "L/D to top of part",
|
|
955
960
|
milling: true,
|
|
956
|
-
value:
|
|
961
|
+
value: ratio2,
|
|
957
962
|
derivation: [
|
|
958
963
|
`L = depth below top of part = ${mm(reach)}`,
|
|
959
964
|
`D = max cutting diameter = ${mm(head)}`,
|
|
960
|
-
`L / D = ${mm(reach)} / ${mm(head)} = ${
|
|
965
|
+
`L / D = ${mm(reach)} / ${mm(head)} = ${ratio2}`
|
|
961
966
|
]
|
|
962
967
|
});
|
|
963
968
|
}
|
|
@@ -1208,14 +1213,217 @@ var placePinchTool = (mark, triangles, direction, origin = { x: 0, y: 0, z: 0 })
|
|
|
1208
1213
|
across: asVec(across)
|
|
1209
1214
|
};
|
|
1210
1215
|
};
|
|
1216
|
+
|
|
1217
|
+
// src/model/turned-check.ts
|
|
1218
|
+
var regionsOf = (feature) => Array.isArray(feature.regionIdxs) ? feature.regionIdxs : [];
|
|
1219
|
+
var stretchKey = (feature) => {
|
|
1220
|
+
const regions = regionsOf(feature);
|
|
1221
|
+
return regions.length === 0 ? `tag:${feature.featureTag}` : `${feature.featureType}:${[...regions].sort((a, b) => a - b).join(",")}`;
|
|
1222
|
+
};
|
|
1223
|
+
var isApproach = (value) => value === "PlusZ" || value === "MinusZ";
|
|
1224
|
+
var turnedStretches = (features) => {
|
|
1225
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1226
|
+
for (const feature of features) {
|
|
1227
|
+
const key = stretchKey(feature);
|
|
1228
|
+
groups.set(key, [...groups.get(key) ?? [], feature]);
|
|
1229
|
+
}
|
|
1230
|
+
const merged = [...groups.values()].flatMap((copies) => {
|
|
1231
|
+
const [first] = copies;
|
|
1232
|
+
if (!first) return [];
|
|
1233
|
+
const approaches = [...new Set(copies.map((each) => each.approach).filter(isApproach))];
|
|
1234
|
+
const only = approaches.length === 1 ? approaches[0] : void 0;
|
|
1235
|
+
const z = only === "PlusZ" ? 1 : only === "MinusZ" ? -1 : 0;
|
|
1236
|
+
return [{ first, copies, approaches, machiningDirection: { x: 0, y: 0, z } }];
|
|
1237
|
+
});
|
|
1238
|
+
const numbered = dfmFeatures(
|
|
1239
|
+
merged.map(({ first, machiningDirection }) => ({
|
|
1240
|
+
featureTag: first.featureTag,
|
|
1241
|
+
featureType: first.featureType,
|
|
1242
|
+
machiningDirection,
|
|
1243
|
+
regionIdxs: regionsOf(first)
|
|
1244
|
+
}))
|
|
1245
|
+
);
|
|
1246
|
+
return merged.flatMap(({ copies, approaches }, at2) => {
|
|
1247
|
+
const feature = numbered[at2];
|
|
1248
|
+
return feature ? [{ ...feature, copies, approaches }] : [];
|
|
1249
|
+
});
|
|
1250
|
+
};
|
|
1251
|
+
var record = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
1252
|
+
var finite = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
1253
|
+
var ratio = (top, bottom) => top !== null && bottom !== null && bottom > 0 ? top / bottom : null;
|
|
1254
|
+
var narrowestStep = (facts) => {
|
|
1255
|
+
const steps = Array.isArray(facts.steps) ? facts.steps : [];
|
|
1256
|
+
const diameters = steps.map((step) => finite(record(step)?.diameter)).filter((each) => each !== null && each > 0);
|
|
1257
|
+
return diameters.length > 0 ? Math.min(...diameters) : null;
|
|
1258
|
+
};
|
|
1259
|
+
var threadSpec = (facts, field) => finite(record(facts.threadSpec)?.[field]) ?? finite(record(record(facts.thread)?.threadSpec)?.[field]);
|
|
1260
|
+
var partEnds = (stretches) => {
|
|
1261
|
+
const zs = stretches.flatMap(
|
|
1262
|
+
(stretch) => stretch.copies.flatMap((copy) => {
|
|
1263
|
+
const sheet = record(copy.datasheet);
|
|
1264
|
+
return [finite(sheet?.zMin), finite(sheet?.zMax)].filter(
|
|
1265
|
+
(each) => each !== null
|
|
1266
|
+
);
|
|
1267
|
+
})
|
|
1268
|
+
);
|
|
1269
|
+
return zs.length > 0 ? { low: Math.min(...zs), high: Math.max(...zs) } : null;
|
|
1270
|
+
};
|
|
1271
|
+
var turnedLd = (sheet, facts, kind, approach, ends) => {
|
|
1272
|
+
if (kind === "AxialHole") return ratio(finite(facts.depth), narrowestStep(facts));
|
|
1273
|
+
const inside = ID_KINDS;
|
|
1274
|
+
if (!kind || !inside.includes(kind) || !ends || !approach) return null;
|
|
1275
|
+
const zMin = finite(sheet.zMin);
|
|
1276
|
+
const zMax = finite(sheet.zMax);
|
|
1277
|
+
const reach = approach === "PlusZ" ? zMin === null ? null : ends.high - zMin : zMax === null ? null : zMax - ends.low;
|
|
1278
|
+
const rMin = finite(sheet.rMin);
|
|
1279
|
+
const bore = finite(sheet.entryDiameter) ?? (rMin === null ? null : 2 * rMin);
|
|
1280
|
+
return ratio(reach, bore);
|
|
1281
|
+
};
|
|
1282
|
+
var HAIR = 1e-3;
|
|
1283
|
+
var FLAT_CONE = 179.5;
|
|
1284
|
+
var copyMeasure = (metric, copy, ends) => {
|
|
1285
|
+
const sheet = record(copy.datasheet);
|
|
1286
|
+
if (!sheet) return null;
|
|
1287
|
+
const facts = record(sheet.facts) ?? {};
|
|
1288
|
+
const kind = typeof facts.kind === "string" ? facts.kind : kindOfType(copy.featureType);
|
|
1289
|
+
const kinds = metric.kinds;
|
|
1290
|
+
if (kinds && !(kind && kinds.includes(kind))) return null;
|
|
1291
|
+
const doubled = (value) => {
|
|
1292
|
+
const radius = finite(value);
|
|
1293
|
+
return radius === null ? null : 2 * radius;
|
|
1294
|
+
};
|
|
1295
|
+
switch (metric.key) {
|
|
1296
|
+
case "maxDiameter":
|
|
1297
|
+
return doubled(sheet.rMax);
|
|
1298
|
+
case "minDiameter":
|
|
1299
|
+
return doubled(sheet.rMin);
|
|
1300
|
+
case "length": {
|
|
1301
|
+
const zMin = finite(sheet.zMin);
|
|
1302
|
+
const zMax = finite(sheet.zMax);
|
|
1303
|
+
return zMin === null || zMax === null || zMax - zMin < HAIR ? null : zMax - zMin;
|
|
1304
|
+
}
|
|
1305
|
+
case "ld":
|
|
1306
|
+
return turnedLd(sheet, facts, kind, copy.approach ?? null, ends);
|
|
1307
|
+
case "grooveWidth":
|
|
1308
|
+
return finite(facts.width);
|
|
1309
|
+
case "grooveDepth":
|
|
1310
|
+
case "threadDepth":
|
|
1311
|
+
case "holeDepth":
|
|
1312
|
+
return finite(facts.depth);
|
|
1313
|
+
case "grooveAspect":
|
|
1314
|
+
return ratio(finite(facts.depth), finite(facts.width));
|
|
1315
|
+
case "threadPitch":
|
|
1316
|
+
return finite(facts.pitch) ?? threadSpec(facts, "threadPitch");
|
|
1317
|
+
case "threadDiameter":
|
|
1318
|
+
return threadSpec(facts, "basicDiameter");
|
|
1319
|
+
case "holeDiameter":
|
|
1320
|
+
return narrowestStep(facts);
|
|
1321
|
+
case "holeSteps":
|
|
1322
|
+
return Array.isArray(facts.steps) ? facts.steps.length : null;
|
|
1323
|
+
case "flatBottom": {
|
|
1324
|
+
if (facts.bottom === void 0) return 0;
|
|
1325
|
+
const cone = finite(record(facts.bottom)?.coneDeg);
|
|
1326
|
+
return cone === null ? null : cone >= FLAT_CONE ? 1 : 0;
|
|
1327
|
+
}
|
|
1328
|
+
// Zero is a figure here: a sharp corner, which a "radius ≤" rule is most of all about.
|
|
1329
|
+
case "cornerRadius":
|
|
1330
|
+
return finite(sheet.minConcaveRadius);
|
|
1331
|
+
case "sharpCorner": {
|
|
1332
|
+
const radius = finite(sheet.minConcaveRadius);
|
|
1333
|
+
return radius === null ? 0 : radius <= HAIR ? 1 : 0;
|
|
1334
|
+
}
|
|
1335
|
+
// Absent where nothing stands between the feature and its end: nothing to pass, so clean.
|
|
1336
|
+
case "entryDiameter":
|
|
1337
|
+
return finite(sheet.entryDiameter);
|
|
1338
|
+
case "axialTool":
|
|
1339
|
+
return typeof sheet.mounting === "string" ? sheet.mounting === "Axial" ? 1 : 0 : null;
|
|
1340
|
+
case "tolerance":
|
|
1341
|
+
return finite(record(sheet.toleranceBand)?.atolMax);
|
|
1342
|
+
default:
|
|
1343
|
+
return null;
|
|
1344
|
+
}
|
|
1345
|
+
};
|
|
1346
|
+
var kindOfType = (featureType) => featureType.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
1347
|
+
var stretchFacts = (stretch) => stretch.copies.map((copy) => record(record(copy.datasheet)?.facts)).find((each) => each !== void 0);
|
|
1348
|
+
var stretchIs = (subject, stretch) => {
|
|
1349
|
+
const type = stretch.featureType.toLowerCase();
|
|
1350
|
+
if (subject.startsWith(TYPE_SUBJECT)) return type === subject.slice(TYPE_SUBJECT.length);
|
|
1351
|
+
const facts = stretchFacts(stretch);
|
|
1352
|
+
const kind = typeof facts?.kind === "string" ? facts.kind : kindOfType(type);
|
|
1353
|
+
const hole = kind === "AxialHole";
|
|
1354
|
+
switch (subject) {
|
|
1355
|
+
case "any":
|
|
1356
|
+
return true;
|
|
1357
|
+
case "thread":
|
|
1358
|
+
return kind === "OdThread" || kind === "IdThread" || hole && record(facts?.thread) !== void 0;
|
|
1359
|
+
case "throughHole":
|
|
1360
|
+
return hole && facts?.through === true;
|
|
1361
|
+
case "blindHole":
|
|
1362
|
+
return hole && facts?.through === false;
|
|
1363
|
+
case "threadedHole":
|
|
1364
|
+
return hole && record(facts?.thread) !== void 0;
|
|
1365
|
+
default: {
|
|
1366
|
+
const kinds = subjectInfo(subject, TURNING_RULES)?.kinds;
|
|
1367
|
+
return kinds !== void 0 && kinds.includes(kind);
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
};
|
|
1371
|
+
var stretchHit = (stretch, rule, metric, ends) => {
|
|
1372
|
+
if (metric.quantity === "presence") return { rule, metric, value: 1 };
|
|
1373
|
+
const measured = stretch.copies.filter((copy) => record(copy.datasheet) !== void 0);
|
|
1374
|
+
if (measured.length === 0) return null;
|
|
1375
|
+
const values = [];
|
|
1376
|
+
for (const copy of measured) {
|
|
1377
|
+
const value2 = copyMeasure(metric, copy, ends);
|
|
1378
|
+
if (value2 === null || !breaks(rule, metric.quantity, value2)) return null;
|
|
1379
|
+
values.push(value2);
|
|
1380
|
+
}
|
|
1381
|
+
const value = worseUpward(rule, metric) ? Math.min(...values) : Math.max(...values);
|
|
1382
|
+
return { rule, metric, value };
|
|
1383
|
+
};
|
|
1384
|
+
var checkTurnedPart = (stretches, rules) => {
|
|
1385
|
+
const ends = partEnds(stretches);
|
|
1386
|
+
const hitsByTag = new Map(
|
|
1387
|
+
stretches.map((stretch) => [
|
|
1388
|
+
stretch.tag.toLowerCase(),
|
|
1389
|
+
rules.flatMap((rule) => {
|
|
1390
|
+
const metric = metricInfo(rule.metric, TURNING_RULES);
|
|
1391
|
+
if (!metric || !stretchIs(rule.subject, stretch)) return [];
|
|
1392
|
+
const hit = stretchHit(stretch, rule, metric, ends);
|
|
1393
|
+
return hit ? [hit] : [];
|
|
1394
|
+
})
|
|
1395
|
+
])
|
|
1396
|
+
);
|
|
1397
|
+
const required = new Set(stretches.map((stretch) => stretch.tag.toLowerCase()));
|
|
1398
|
+
const paintedFaces = /* @__PURE__ */ new Map();
|
|
1399
|
+
for (const stretch of stretches) {
|
|
1400
|
+
const color = worstColor(hitsByTag.get(stretch.tag.toLowerCase()));
|
|
1401
|
+
if (!color) continue;
|
|
1402
|
+
for (const region of stretch.regionIdxs) {
|
|
1403
|
+
const painted = paintedFaces.get(region);
|
|
1404
|
+
if (!painted || compareColors(color, painted.color) < 0)
|
|
1405
|
+
paintedFaces.set(region, { tag: stretch.tag, color });
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
return {
|
|
1409
|
+
hitsByTag,
|
|
1410
|
+
required,
|
|
1411
|
+
byRule: ruleResults(rules, stretches, hitsByTag, required),
|
|
1412
|
+
paintedFaces,
|
|
1413
|
+
paintedWhole: /* @__PURE__ */ new Map()
|
|
1414
|
+
};
|
|
1415
|
+
};
|
|
1211
1416
|
export {
|
|
1212
1417
|
CRITICAL_COLOR,
|
|
1213
1418
|
FILE_KIND,
|
|
1419
|
+
MILLING_RULES,
|
|
1214
1420
|
PINCH_TOOL_MM,
|
|
1215
1421
|
RULE_COLORS,
|
|
1422
|
+
TURNING_RULES,
|
|
1216
1423
|
WARNING_COLOR,
|
|
1217
1424
|
brokenRules,
|
|
1218
1425
|
checkPart,
|
|
1426
|
+
checkTurnedPart,
|
|
1219
1427
|
compareColors,
|
|
1220
1428
|
describeRule,
|
|
1221
1429
|
dfmFeatures,
|
|
@@ -1242,5 +1450,7 @@ export {
|
|
|
1242
1450
|
sameDepth,
|
|
1243
1451
|
serializeRuleSet,
|
|
1244
1452
|
trimmedCurve,
|
|
1453
|
+
turnedStretches,
|
|
1454
|
+
turnedTypeLabel,
|
|
1245
1455
|
withSurroundedFaces
|
|
1246
1456
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toolpath/dfm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Toolpath DFM rules: the rule list, the rules and the part checker, and the feature panel",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"engines": {
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
"tsup": "8.5.1",
|
|
65
65
|
"typescript": "5.9.3",
|
|
66
66
|
"vitest": "4.1.10",
|
|
67
|
-
"@toolpath/
|
|
68
|
-
"@toolpath/
|
|
67
|
+
"@toolpath/api": "^0.8.1",
|
|
68
|
+
"@toolpath/ui": "^1.0.0"
|
|
69
69
|
},
|
|
70
70
|
"scripts": {
|
|
71
71
|
"build": "tsup src/index.ts src/model/index.ts --format esm --dts --clean --external react --external react-dom --external @toolpath/ui",
|