brepjs-sheetmetal 0.3.0 → 0.4.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/dist/brepjs-sheetmetal.cjs +178 -156
- package/dist/brepjs-sheetmetal.js +178 -156
- package/package.json +5 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { box, curveEndPoint, curveStartPoint, cut, cylinder, err, extrude, face, faceCenter, fuse, getBounds, getEdges, getFaces, getSolids, getSurfaceType, intersect, isErr, isOk, isPlanarWire, isSolid, isValid, line, measureArea, measureVolume, normalAt, ok, pointOnSurface, rotate, sharedEdges, translate, validationError, vecAdd, vecCross, vecDot, vecLength, vecNormalize, vecScale, vecSub, wire, wireLoop } from "brepjs";
|
|
2
|
-
|
|
2
|
+
// src/materials.ts
|
|
3
3
|
var DEFAULT_K_FACTOR = .44;
|
|
4
4
|
function gauge(name, thickness, kFactor = DEFAULT_K_FACTOR) {
|
|
5
5
|
return {
|
|
@@ -37,8 +37,7 @@ var MATERIALS = {
|
|
|
37
37
|
function getMaterial(name) {
|
|
38
38
|
return MATERIALS[name];
|
|
39
39
|
}
|
|
40
|
-
|
|
41
|
-
//#region src/bendTableFns.ts
|
|
40
|
+
// src/bendTableFns.ts
|
|
42
41
|
var DEG_TO_RAD = Math.PI / 180;
|
|
43
42
|
var registry = /* @__PURE__ */ new Map();
|
|
44
43
|
/**
|
|
@@ -377,8 +376,7 @@ function ensureStarterTables() {
|
|
|
377
376
|
});
|
|
378
377
|
}
|
|
379
378
|
}
|
|
380
|
-
|
|
381
|
-
//#region src/allowanceFns.ts
|
|
379
|
+
// src/allowanceFns.ts
|
|
382
380
|
function validateRule(rule) {
|
|
383
381
|
if (!Number.isFinite(rule.innerRadius) || rule.innerRadius < 0) return err(validationError("INVALID_RADIUS", `innerRadius must be a finite, non-negative number, got ${rule.innerRadius}`));
|
|
384
382
|
if (!Number.isFinite(rule.kFactor) || rule.kFactor < 0 || rule.kFactor > 1) return err(validationError("INVALID_K_FACTOR", `kFactor must be in [0, 1], got ${rule.kFactor}`));
|
|
@@ -412,8 +410,7 @@ function neutralRadius(thickness, rule) {
|
|
|
412
410
|
if (!ruleCheck.ok) return ruleCheck;
|
|
413
411
|
return ok(rule.innerRadius + rule.kFactor * thickness);
|
|
414
412
|
}
|
|
415
|
-
|
|
416
|
-
//#region src/featureTreeFns.ts
|
|
413
|
+
// src/featureTreeFns.ts
|
|
417
414
|
var ROOT_FLAT_ID = "root";
|
|
418
415
|
/**
|
|
419
416
|
* Build the feature graph for an authored part. Each flange contributes a flat
|
|
@@ -504,7 +501,7 @@ function buildFeatureTree(graph, rootId = ROOT_FLAT_ID) {
|
|
|
504
501
|
adjacency.get(edge.parent)?.push(edge);
|
|
505
502
|
adjacency.get(edge.child)?.push(edge);
|
|
506
503
|
}
|
|
507
|
-
const visited = new Set([rootId]);
|
|
504
|
+
const visited = /* @__PURE__ */ new Set([rootId]);
|
|
508
505
|
const treeEdges = /* @__PURE__ */ new Set();
|
|
509
506
|
const bends = [];
|
|
510
507
|
const queue = [rootId];
|
|
@@ -558,8 +555,7 @@ function featureTree(part, rootId = ROOT_FLAT_ID) {
|
|
|
558
555
|
if (!graph.ok) return graph;
|
|
559
556
|
return buildFeatureTree(graph.value, rootId);
|
|
560
557
|
}
|
|
561
|
-
|
|
562
|
-
//#region src/internal.ts
|
|
558
|
+
// src/internal.ts
|
|
563
559
|
/**
|
|
564
560
|
* OCCT boolean fuse returns a compound wrapping the unioned solid. Extract the
|
|
565
561
|
* single solid so a part's cached shape is a true `Solid` (clean STEP/GLB
|
|
@@ -582,8 +578,7 @@ function sideFromAxisDir(axisDir) {
|
|
|
582
578
|
if (Math.abs(axisDir[1]) > .5) return "xmax";
|
|
583
579
|
if (Math.abs(axisDir[0]) > .5) return "ymax";
|
|
584
580
|
}
|
|
585
|
-
|
|
586
|
-
//#region src/unfoldFns.ts
|
|
581
|
+
// src/unfoldFns.ts
|
|
587
582
|
/**
|
|
588
583
|
* Tree-driven analytic unfold of an arbitrary straight-bend part into its flat
|
|
589
584
|
* pattern. Walks the feature tree in BFS order placing every flat in the flat
|
|
@@ -673,18 +668,20 @@ function unfold(part) {
|
|
|
673
668
|
direction: p.direction,
|
|
674
669
|
inward: [-p.frame.v[0], -p.frame.v[1]]
|
|
675
670
|
})).concat(contourResult.value.bendLines).concat(hemJogResult.value.bendLines);
|
|
671
|
+
const pattern = {
|
|
672
|
+
outline: outlineResult.value,
|
|
673
|
+
bendLines,
|
|
674
|
+
holes: holesResult.value,
|
|
675
|
+
formCuts: formsResult.value.cuts,
|
|
676
|
+
formMarkers: formsResult.value.markers,
|
|
677
|
+
formHinges: formsResult.value.hinges,
|
|
678
|
+
loftedDevelopments: loftedResult.value,
|
|
679
|
+
developedArea: layout.developedArea
|
|
680
|
+
};
|
|
681
|
+
const report = reportFromLayout(layout);
|
|
676
682
|
return ok({
|
|
677
|
-
pattern
|
|
678
|
-
|
|
679
|
-
bendLines,
|
|
680
|
-
holes: holesResult.value,
|
|
681
|
-
formCuts: formsResult.value.cuts,
|
|
682
|
-
formMarkers: formsResult.value.markers,
|
|
683
|
-
formHinges: formsResult.value.hinges,
|
|
684
|
-
loftedDevelopments: loftedResult.value,
|
|
685
|
-
developedArea: layout.developedArea
|
|
686
|
-
},
|
|
687
|
-
report: reportFromLayout(layout),
|
|
683
|
+
pattern,
|
|
684
|
+
report,
|
|
688
685
|
warnings
|
|
689
686
|
});
|
|
690
687
|
}
|
|
@@ -1288,8 +1285,7 @@ function reportFromLayout(layout) {
|
|
|
1288
1285
|
totalFlatSize: [maxX - minX, maxY - minY]
|
|
1289
1286
|
};
|
|
1290
1287
|
}
|
|
1291
|
-
|
|
1292
|
-
//#region src/foreignUnfoldFns.ts
|
|
1288
|
+
// src/foreignUnfoldFns.ts
|
|
1293
1289
|
/** Default neutral-axis K-factor for a purely geometric unfold (mid-surface). */
|
|
1294
1290
|
var DEFAULT_FOREIGN_K = .5;
|
|
1295
1291
|
/** Relative tolerance for the cylinder-fit residual (fraction of the radius). */
|
|
@@ -1307,7 +1303,8 @@ function sampleFace(face, n) {
|
|
|
1307
1303
|
for (let i = 0; i < n; i += 1) {
|
|
1308
1304
|
const u = n === 1 ? .5 : i / (n - 1);
|
|
1309
1305
|
for (let j = 0; j < n; j += 1) {
|
|
1310
|
-
const
|
|
1306
|
+
const v = n === 1 ? .5 : j / (n - 1);
|
|
1307
|
+
const point = pointOnSurface(face, u, v);
|
|
1311
1308
|
const normal = normalAt(face, point);
|
|
1312
1309
|
const len = vecLength(normal);
|
|
1313
1310
|
if (len < GEOM_TOL) continue;
|
|
@@ -1398,7 +1395,7 @@ function axisFromNormals(normals) {
|
|
|
1398
1395
|
}
|
|
1399
1396
|
/** An orthonormal pair spanning the plane perpendicular to `axis`. */
|
|
1400
1397
|
function perpBasis(axis) {
|
|
1401
|
-
const
|
|
1398
|
+
const seed = Math.abs(axis[0]) < .9 ? [
|
|
1402
1399
|
1,
|
|
1403
1400
|
0,
|
|
1404
1401
|
0
|
|
@@ -1406,7 +1403,8 @@ function perpBasis(axis) {
|
|
|
1406
1403
|
0,
|
|
1407
1404
|
1,
|
|
1408
1405
|
0
|
|
1409
|
-
]
|
|
1406
|
+
];
|
|
1407
|
+
const e1 = vecNormalize(vecCross(axis, seed));
|
|
1410
1408
|
return {
|
|
1411
1409
|
e1,
|
|
1412
1410
|
e2: vecNormalize(vecCross(axis, e1))
|
|
@@ -1415,7 +1413,9 @@ function perpBasis(axis) {
|
|
|
1415
1413
|
/** Perpendicular distance from `p` to the line through `o` with unit direction `d`. */
|
|
1416
1414
|
function distanceToAxis(p, o, d) {
|
|
1417
1415
|
const w = vecSub(p, o);
|
|
1418
|
-
|
|
1416
|
+
const along = vecDot(w, d);
|
|
1417
|
+
const perp = vecSub(w, vecScale(d, along));
|
|
1418
|
+
return vecLength(perp);
|
|
1419
1419
|
}
|
|
1420
1420
|
/** Algebraic (Kåsa) least-squares circle fit to 2D points. */
|
|
1421
1421
|
function fitCircle2(pts) {
|
|
@@ -1620,7 +1620,8 @@ function detectThickness(planar) {
|
|
|
1620
1620
|
const fb = planar[j];
|
|
1621
1621
|
if (fa === void 0 || fb === void 0) continue;
|
|
1622
1622
|
const na = faceNormal(fa);
|
|
1623
|
-
|
|
1623
|
+
const nb = faceNormal(fb);
|
|
1624
|
+
if (vecDot(na, nb) > -.99) continue;
|
|
1624
1625
|
const ca = faceCenter(fa);
|
|
1625
1626
|
const cb = faceCenter(fb);
|
|
1626
1627
|
const gap = Math.abs(vecDot(vecSub(cb, ca), na));
|
|
@@ -1649,7 +1650,8 @@ function pairFlats(planar, thickness, warnings) {
|
|
|
1649
1650
|
if (j === i || used.has(j)) continue;
|
|
1650
1651
|
const fb = planar[j];
|
|
1651
1652
|
if (fb === void 0) continue;
|
|
1652
|
-
|
|
1653
|
+
const nb = faceNormal(fb);
|
|
1654
|
+
if (vecDot(na, nb) > -.99) continue;
|
|
1653
1655
|
const cb = faceCenter(fb);
|
|
1654
1656
|
const gap = Math.abs(vecDot(vecSub(cb, ca), na));
|
|
1655
1657
|
const e = Math.abs(gap - thickness);
|
|
@@ -1818,7 +1820,7 @@ function layoutForeign(flats, graph, thickness, kFactor, warnings) {
|
|
|
1818
1820
|
adjacency.get(e.flats[0])?.push(e);
|
|
1819
1821
|
adjacency.get(e.flats[1])?.push(e);
|
|
1820
1822
|
}
|
|
1821
|
-
const visited = new Set([0]);
|
|
1823
|
+
const visited = /* @__PURE__ */ new Set([0]);
|
|
1822
1824
|
const treeEdges = /* @__PURE__ */ new Set();
|
|
1823
1825
|
const treeBends = [];
|
|
1824
1826
|
const queue = [0];
|
|
@@ -1912,23 +1914,26 @@ function layoutForeign(flats, graph, thickness, kFactor, warnings) {
|
|
|
1912
1914
|
});
|
|
1913
1915
|
}
|
|
1914
1916
|
const bbox = aabb2(rects);
|
|
1915
|
-
const
|
|
1917
|
+
const outline = buildRectOutline2(bbox);
|
|
1918
|
+
const outlineWire = wireLoop(outline);
|
|
1916
1919
|
if (!outlineWire.ok) return outlineWire;
|
|
1920
|
+
const pattern = {
|
|
1921
|
+
outline: outlineWire.value,
|
|
1922
|
+
bendLines,
|
|
1923
|
+
holes: [],
|
|
1924
|
+
formCuts: [],
|
|
1925
|
+
formMarkers: [],
|
|
1926
|
+
formHinges: [],
|
|
1927
|
+
loftedDevelopments: [],
|
|
1928
|
+
developedArea
|
|
1929
|
+
};
|
|
1930
|
+
const report = {
|
|
1931
|
+
bends: bendReportRows,
|
|
1932
|
+
totalFlatSize: [bbox.x1 - bbox.x0, bbox.y1 - bbox.y0]
|
|
1933
|
+
};
|
|
1917
1934
|
return ok({
|
|
1918
|
-
pattern
|
|
1919
|
-
|
|
1920
|
-
bendLines,
|
|
1921
|
-
holes: [],
|
|
1922
|
-
formCuts: [],
|
|
1923
|
-
formMarkers: [],
|
|
1924
|
-
formHinges: [],
|
|
1925
|
-
loftedDevelopments: [],
|
|
1926
|
-
developedArea
|
|
1927
|
-
},
|
|
1928
|
-
report: {
|
|
1929
|
-
bends: bendReportRows,
|
|
1930
|
-
totalFlatSize: [bbox.x1 - bbox.x0, bbox.y1 - bbox.y0]
|
|
1931
|
-
}
|
|
1935
|
+
pattern,
|
|
1936
|
+
report
|
|
1932
1937
|
});
|
|
1933
1938
|
}
|
|
1934
1939
|
/** Map a 3D in-plane point through a placed flat's affine map. */
|
|
@@ -2018,7 +2023,9 @@ function parentFootprintCentreAlong(parent, axisInPlane, axisRef) {
|
|
|
2018
2023
|
min = Math.min(min, v);
|
|
2019
2024
|
max = Math.max(max, v);
|
|
2020
2025
|
}
|
|
2021
|
-
|
|
2026
|
+
const mid = (min + max) / 2;
|
|
2027
|
+
const refAlong = vecDot(axisRef, axisInPlane);
|
|
2028
|
+
return vecAdd(axisRef, vecScale(axisInPlane, mid - refAlong));
|
|
2022
2029
|
}
|
|
2023
2030
|
/** In-plane run extent of a flat along `out` (perpendicular to the bend axis). */
|
|
2024
2031
|
function inPlaneRun(flat, out) {
|
|
@@ -2034,7 +2041,8 @@ function inPlaneRun(flat, out) {
|
|
|
2034
2041
|
}
|
|
2035
2042
|
/** Run direction of a child flat pointing away from the bend axis. */
|
|
2036
2043
|
function runDirectionAway(flat, out, axisOrigin) {
|
|
2037
|
-
|
|
2044
|
+
const toCenter = vecSub(flat.center, axisOrigin);
|
|
2045
|
+
return vecDot(toCenter, out) >= 0 ? out : vecScale(out, -1);
|
|
2038
2046
|
}
|
|
2039
2047
|
/**
|
|
2040
2048
|
* The child corner that develops onto the strip-far near point: minimum along the
|
|
@@ -2160,13 +2168,13 @@ function bendAxialExtent(bend) {
|
|
|
2160
2168
|
* parent flat's mid-surface, 'down' otherwise.
|
|
2161
2169
|
*/
|
|
2162
2170
|
function bendDirection(bend, parent) {
|
|
2163
|
-
|
|
2171
|
+
const toAxis = vecSub(bend.fit.axisOrigin, parent.center);
|
|
2172
|
+
return vecDot(toAxis, parent.normal) >= 0 ? "up" : "down";
|
|
2164
2173
|
}
|
|
2165
2174
|
function faceNormal(face) {
|
|
2166
2175
|
return vecNormalize(normalAt(face, faceCenter(face)));
|
|
2167
2176
|
}
|
|
2168
|
-
|
|
2169
|
-
//#region src/authorFns.ts
|
|
2177
|
+
// src/authorFns.ts
|
|
2170
2178
|
/**
|
|
2171
2179
|
* Stable edge reference for flange attachment. The base flat is `face-0`; every
|
|
2172
2180
|
* flange face is `face-<n+1>` in authoring order. The leading edge of a flat is
|
|
@@ -2494,10 +2502,10 @@ function parentEdge(f, side) {
|
|
|
2494
2502
|
length = f.uLen;
|
|
2495
2503
|
a = o;
|
|
2496
2504
|
b = uTop;
|
|
2497
|
-
break;
|
|
2498
2505
|
}
|
|
2499
2506
|
const dir = vecNormalize(vecCross(f.n, out));
|
|
2500
|
-
const
|
|
2507
|
+
const toB = vecSub(b, a);
|
|
2508
|
+
const start = vecDot(toB, dir) >= 0 ? a : b;
|
|
2501
2509
|
return {
|
|
2502
2510
|
dir,
|
|
2503
2511
|
out,
|
|
@@ -2610,14 +2618,15 @@ function frameTransform$1(axisT, runT, nT, edgeStart, offset) {
|
|
|
2610
2618
|
const applyR = (v) => vecAdd(vecAdd(vecScale(runT, v[0]), vecScale(axisT, v[1])), vecScale(nT, v[2]));
|
|
2611
2619
|
return {
|
|
2612
2620
|
solid: (s) => {
|
|
2613
|
-
|
|
2621
|
+
const rotated = aa.angleDeg === 0 ? s : rotate(s, aa.angleDeg, {
|
|
2614
2622
|
at: [
|
|
2615
2623
|
0,
|
|
2616
2624
|
0,
|
|
2617
2625
|
0
|
|
2618
2626
|
],
|
|
2619
2627
|
axis: aa.axis
|
|
2620
|
-
})
|
|
2628
|
+
});
|
|
2629
|
+
return translate(rotated, target);
|
|
2621
2630
|
},
|
|
2622
2631
|
point: (p) => vecAdd(applyR(p), target),
|
|
2623
2632
|
vector: applyR
|
|
@@ -2679,12 +2688,13 @@ function matrixToAxisAngle$2(m) {
|
|
|
2679
2688
|
};
|
|
2680
2689
|
}
|
|
2681
2690
|
const denom = 2 * Math.sin(angle);
|
|
2691
|
+
const axis = [
|
|
2692
|
+
(m21 - m12) / denom,
|
|
2693
|
+
(m02 - m20) / denom,
|
|
2694
|
+
(m10 - m01) / denom
|
|
2695
|
+
];
|
|
2682
2696
|
return {
|
|
2683
|
-
axis: vecNormalize(
|
|
2684
|
-
(m21 - m12) / denom,
|
|
2685
|
-
(m02 - m20) / denom,
|
|
2686
|
-
(m10 - m01) / denom
|
|
2687
|
-
]),
|
|
2697
|
+
axis: vecNormalize(axis),
|
|
2688
2698
|
angleDeg
|
|
2689
2699
|
};
|
|
2690
2700
|
}
|
|
@@ -2706,14 +2716,15 @@ function buildBendPatch$1(axisOrigin, thetaDeg, r, width, thickness, direction)
|
|
|
2706
2716
|
});
|
|
2707
2717
|
let tube = outer;
|
|
2708
2718
|
if (r > 1e-9) {
|
|
2709
|
-
const
|
|
2719
|
+
const inner = cylinder(r, width, {
|
|
2710
2720
|
at: axisOrigin,
|
|
2711
2721
|
axis: [
|
|
2712
2722
|
0,
|
|
2713
2723
|
1,
|
|
2714
2724
|
0
|
|
2715
2725
|
]
|
|
2716
|
-
})
|
|
2726
|
+
});
|
|
2727
|
+
const carved = cut(outer, inner);
|
|
2717
2728
|
if (!carved.ok) return carved;
|
|
2718
2729
|
tube = carved.value;
|
|
2719
2730
|
}
|
|
@@ -2731,39 +2742,47 @@ function buildBendPatch$1(axisOrigin, thetaDeg, r, width, thickness, direction)
|
|
|
2731
2742
|
function buildWedge$1(axisOrigin, thetaDeg, outerR, width, direction) {
|
|
2732
2743
|
const span = outerR * 2 + 2;
|
|
2733
2744
|
const margin = 1;
|
|
2734
|
-
const
|
|
2745
|
+
const blockA = box(span, width + 2, 2 * span);
|
|
2746
|
+
const halfA = translate(blockA, [
|
|
2735
2747
|
axisOrigin[0],
|
|
2736
2748
|
axisOrigin[1] - margin,
|
|
2737
2749
|
axisOrigin[2] - span
|
|
2738
2750
|
]);
|
|
2739
|
-
|
|
2751
|
+
const halfB = rotate(halfA, (direction === "up" ? 1 : -1) * (180 - thetaDeg), {
|
|
2740
2752
|
at: axisOrigin,
|
|
2741
2753
|
axis: [
|
|
2742
2754
|
0,
|
|
2743
2755
|
1,
|
|
2744
2756
|
0
|
|
2745
2757
|
]
|
|
2746
|
-
})
|
|
2758
|
+
});
|
|
2759
|
+
return intersect(halfA, halfB);
|
|
2747
2760
|
}
|
|
2748
2761
|
/** The flange flat, built lying along +X past the bend, then folded to angle θ. */
|
|
2749
2762
|
function buildFlangeFlat(axisOrigin, thetaDeg, width, thickness, length, direction) {
|
|
2750
|
-
if (direction === "up")
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
at: axisOrigin,
|
|
2756
|
-
axis: [
|
|
2757
|
-
0,
|
|
2758
|
-
1,
|
|
2763
|
+
if (direction === "up") {
|
|
2764
|
+
const flat = box(length, width, thickness);
|
|
2765
|
+
const positioned = translate(flat, [
|
|
2766
|
+
axisOrigin[0],
|
|
2767
|
+
axisOrigin[1],
|
|
2759
2768
|
0
|
|
2760
|
-
]
|
|
2761
|
-
|
|
2762
|
-
|
|
2769
|
+
]);
|
|
2770
|
+
return rotate(positioned, -thetaDeg, {
|
|
2771
|
+
at: axisOrigin,
|
|
2772
|
+
axis: [
|
|
2773
|
+
0,
|
|
2774
|
+
1,
|
|
2775
|
+
0
|
|
2776
|
+
]
|
|
2777
|
+
});
|
|
2778
|
+
}
|
|
2779
|
+
const flat = box(length, width, thickness);
|
|
2780
|
+
const positioned = translate(flat, [
|
|
2763
2781
|
axisOrigin[0],
|
|
2764
2782
|
axisOrigin[1],
|
|
2765
2783
|
-thickness
|
|
2766
|
-
])
|
|
2784
|
+
]);
|
|
2785
|
+
return rotate(positioned, thetaDeg, {
|
|
2767
2786
|
at: axisOrigin,
|
|
2768
2787
|
axis: [
|
|
2769
2788
|
0,
|
|
@@ -2772,8 +2791,7 @@ function buildFlangeFlat(axisOrigin, thetaDeg, width, thickness, length, directi
|
|
|
2772
2791
|
]
|
|
2773
2792
|
});
|
|
2774
2793
|
}
|
|
2775
|
-
|
|
2776
|
-
//#region src/reliefFns.ts
|
|
2794
|
+
// src/reliefFns.ts
|
|
2777
2795
|
var EPS$6 = 1e-6;
|
|
2778
2796
|
var Z_AXIS$1 = [
|
|
2779
2797
|
0,
|
|
@@ -3047,7 +3065,8 @@ function cornerPoint$1(originA, dirA, originB, dirB) {
|
|
|
3047
3065
|
const e = vecDot(dirB, w0);
|
|
3048
3066
|
const denom = a * c - b * b;
|
|
3049
3067
|
if (Math.abs(denom) < 1e-9) return originA;
|
|
3050
|
-
|
|
3068
|
+
const sc = (b * e - c * d) / denom;
|
|
3069
|
+
return vecAdd(originA, vecScale(dirA, sc));
|
|
3051
3070
|
}
|
|
3052
3071
|
/** In-plane perpendicular to `axis` pointing toward the part center (into the parent). */
|
|
3053
3072
|
function inwardRun(axisOrigin, axis, center) {
|
|
@@ -3080,11 +3099,12 @@ function parentEdgeLength(part, flange) {
|
|
|
3080
3099
|
*/
|
|
3081
3100
|
function slotTool3d(at, along, inward, width, depth, thickness) {
|
|
3082
3101
|
const margin = thickness + 2;
|
|
3083
|
-
const
|
|
3102
|
+
const rotPerp = [
|
|
3084
3103
|
-along[1],
|
|
3085
3104
|
along[0],
|
|
3086
3105
|
0
|
|
3087
|
-
]
|
|
3106
|
+
];
|
|
3107
|
+
const y0 = vecDot(rotPerp, inward) >= 0 ? 0 : -depth;
|
|
3088
3108
|
let tool = box(width, depth, thickness + 2 * margin);
|
|
3089
3109
|
tool = translate(tool, [
|
|
3090
3110
|
-width / 2,
|
|
@@ -3109,7 +3129,8 @@ function squareTool(solid, cornerXY, side) {
|
|
|
3109
3129
|
const b = getBounds(solid);
|
|
3110
3130
|
const margin = 2;
|
|
3111
3131
|
const h = side / 2;
|
|
3112
|
-
|
|
3132
|
+
const tool = box(side, side, b.zMax - b.zMin + 4);
|
|
3133
|
+
return translate(tool, [
|
|
3113
3134
|
cornerXY[0] - h,
|
|
3114
3135
|
cornerXY[1] - h,
|
|
3115
3136
|
b.zMin - margin
|
|
@@ -3134,8 +3155,7 @@ function toPt2$1(v) {
|
|
|
3134
3155
|
function dist2(a, b) {
|
|
3135
3156
|
return Math.hypot(a[0] - b[0], a[1] - b[1]);
|
|
3136
3157
|
}
|
|
3137
|
-
|
|
3138
|
-
//#region src/cutoutFns.ts
|
|
3158
|
+
// src/cutoutFns.ts
|
|
3139
3159
|
var EPS$5 = 1e-6;
|
|
3140
3160
|
/** A hair of over-cut so the tool pokes through both faces cleanly. */
|
|
3141
3161
|
var HAIR$1 = .05;
|
|
@@ -3363,8 +3383,7 @@ function polygonArea(loop) {
|
|
|
3363
3383
|
}
|
|
3364
3384
|
return Math.abs(sum) / 2;
|
|
3365
3385
|
}
|
|
3366
|
-
|
|
3367
|
-
//#region src/tabFns.ts
|
|
3386
|
+
// src/tabFns.ts
|
|
3368
3387
|
var EPS$4 = 1e-6;
|
|
3369
3388
|
/**
|
|
3370
3389
|
* Fuse a rectangular tab onto a named flat region's edge — additive material (the
|
|
@@ -3506,8 +3525,7 @@ function devRect(local, dev) {
|
|
|
3506
3525
|
y1
|
|
3507
3526
|
];
|
|
3508
3527
|
}
|
|
3509
|
-
|
|
3510
|
-
//#region src/formFns.ts
|
|
3528
|
+
// src/formFns.ts
|
|
3511
3529
|
var EPS$3 = 1e-6;
|
|
3512
3530
|
var HAIR = .05;
|
|
3513
3531
|
var CIRCLE_SEGMENTS = 48;
|
|
@@ -3602,18 +3620,20 @@ function embossForm(part, partSolid, spec, regionId, world, dev, ext) {
|
|
|
3602
3620
|
let solid;
|
|
3603
3621
|
if (spec.form === "emboss") {
|
|
3604
3622
|
const base = vecAdd(faceCentre, vecScale(world.n, -.05));
|
|
3605
|
-
const
|
|
3623
|
+
const bump = cylinder(r, spec.height + HAIR, {
|
|
3606
3624
|
at: base,
|
|
3607
3625
|
axis: world.n
|
|
3608
|
-
})
|
|
3626
|
+
});
|
|
3627
|
+
const fused = fuse(partSolid, bump);
|
|
3609
3628
|
if (!fused.ok) return fused;
|
|
3610
3629
|
solid = normalizeSolid(fused.value);
|
|
3611
3630
|
} else {
|
|
3612
3631
|
const top = vecAdd(faceCentre, vecScale(world.n, HAIR));
|
|
3613
|
-
const
|
|
3632
|
+
const tool = cylinder(r, spec.height + HAIR, {
|
|
3614
3633
|
at: top,
|
|
3615
3634
|
axis: vecScale(world.n, -1)
|
|
3616
|
-
})
|
|
3635
|
+
});
|
|
3636
|
+
const cutResult = cut(partSolid, tool);
|
|
3617
3637
|
if (!cutResult.ok) return cutResult;
|
|
3618
3638
|
solid = normalizeSolid(cutResult.value);
|
|
3619
3639
|
}
|
|
@@ -3705,7 +3725,8 @@ function buildLouverFlap(f, x0, x1, y0, width, height, thickness, sign) {
|
|
|
3705
3725
|
const n = vecNormalize(f.n);
|
|
3706
3726
|
const v = vecNormalize(vecCross(n, u));
|
|
3707
3727
|
const hingeCorner = vecAdd(vecAdd(vecAdd(f.origin, vecScale(f.u, x0)), vecScale(f.v, y0)), vecScale(f.n, thickness));
|
|
3708
|
-
|
|
3728
|
+
const placed = mapLocalToWorld(flap, u, v, n, hingeCorner);
|
|
3729
|
+
return ok(placed);
|
|
3709
3730
|
}
|
|
3710
3731
|
/** Map a solid built in a canonical XYZ frame onto world axes (uT, vT, nT) at origin. */
|
|
3711
3732
|
function mapLocalToWorld(s, uT, vT, nT, origin) {
|
|
@@ -3720,14 +3741,15 @@ function mapLocalToWorld(s, uT, vT, nT, origin) {
|
|
|
3720
3741
|
vT[2],
|
|
3721
3742
|
nT[2]
|
|
3722
3743
|
]);
|
|
3723
|
-
|
|
3744
|
+
const rotated = aa.angleDeg === 0 ? s : rotate(s, aa.angleDeg, {
|
|
3724
3745
|
at: [
|
|
3725
3746
|
0,
|
|
3726
3747
|
0,
|
|
3727
3748
|
0
|
|
3728
3749
|
],
|
|
3729
3750
|
axis: aa.axis
|
|
3730
|
-
})
|
|
3751
|
+
});
|
|
3752
|
+
return translate(rotated, origin);
|
|
3731
3753
|
}
|
|
3732
3754
|
/** Axis-angle of a 3×3 row-major rotation matrix (columns = target basis). */
|
|
3733
3755
|
function matrixToAxisAngle$1(m) {
|
|
@@ -3785,12 +3807,13 @@ function matrixToAxisAngle$1(m) {
|
|
|
3785
3807
|
};
|
|
3786
3808
|
}
|
|
3787
3809
|
const denom = 2 * Math.sin(angle);
|
|
3810
|
+
const axis = [
|
|
3811
|
+
(m21 - m12) / denom,
|
|
3812
|
+
(m02 - m20) / denom,
|
|
3813
|
+
(m10 - m01) / denom
|
|
3814
|
+
];
|
|
3788
3815
|
return {
|
|
3789
|
-
axis: vecNormalize(
|
|
3790
|
-
(m21 - m12) / denom,
|
|
3791
|
-
(m02 - m20) / denom,
|
|
3792
|
-
(m10 - m01) / denom
|
|
3793
|
-
]),
|
|
3816
|
+
axis: vecNormalize(axis),
|
|
3794
3817
|
angleDeg
|
|
3795
3818
|
};
|
|
3796
3819
|
}
|
|
@@ -3803,8 +3826,7 @@ function circleLocal(c, r) {
|
|
|
3803
3826
|
}
|
|
3804
3827
|
return pts;
|
|
3805
3828
|
}
|
|
3806
|
-
|
|
3807
|
-
//#region src/validateFns.ts
|
|
3829
|
+
// src/validateFns.ts
|
|
3808
3830
|
var OVERLAP_TOL = 1e-6;
|
|
3809
3831
|
/**
|
|
3810
3832
|
* Manufacturability checks for an authored sheet-metal part. Returns a list of
|
|
@@ -3986,8 +4008,7 @@ function pairKey(a, b) {
|
|
|
3986
4008
|
function boundsOverlap(a, b) {
|
|
3987
4009
|
return a.xMin < b.xMax - OVERLAP_TOL && b.xMin < a.xMax - OVERLAP_TOL && a.yMin < b.yMax - OVERLAP_TOL && b.yMin < a.yMax - OVERLAP_TOL && a.zMin < b.zMax - OVERLAP_TOL && b.zMin < a.zMax - OVERLAP_TOL;
|
|
3988
4010
|
}
|
|
3989
|
-
|
|
3990
|
-
//#region src/foldFns.ts
|
|
4011
|
+
// src/foldFns.ts
|
|
3991
4012
|
/**
|
|
3992
4013
|
* Fold a flat pattern up into a 3D part. Each {@link FoldRegion} folds about its
|
|
3993
4014
|
* fold line off its parent region, exactly inverting {@link unfold}: folding by an
|
|
@@ -4645,8 +4666,7 @@ function uniqueSorted(values) {
|
|
|
4645
4666
|
}
|
|
4646
4667
|
return out;
|
|
4647
4668
|
}
|
|
4648
|
-
|
|
4649
|
-
//#region src/miterFns.ts
|
|
4669
|
+
// src/miterFns.ts
|
|
4650
4670
|
/**
|
|
4651
4671
|
* General miter primitive: cut a sheet-metal part by a plane, removing the
|
|
4652
4672
|
* material on the `+normal` side. The tool is a half-space block sized to the
|
|
@@ -4705,7 +4725,8 @@ function cornerPoint(originA, dirA, originB, dirB) {
|
|
|
4705
4725
|
const e = vecDot(dirB, w0);
|
|
4706
4726
|
const denom = a * c - b * b;
|
|
4707
4727
|
if (Math.abs(denom) < 1e-9) return originA;
|
|
4708
|
-
|
|
4728
|
+
const sc = (b * e - c * d) / denom;
|
|
4729
|
+
return vecAdd(originA, vecScale(dirA, sc));
|
|
4709
4730
|
}
|
|
4710
4731
|
/**
|
|
4711
4732
|
* Normal of the miter plane between two flanges whose bend axes are `dirA`/`dirB`.
|
|
@@ -4737,13 +4758,14 @@ function halfSpaceTool(solid, plane) {
|
|
|
4737
4758
|
-size / 2,
|
|
4738
4759
|
0
|
|
4739
4760
|
]);
|
|
4740
|
-
|
|
4761
|
+
const aligned = alignZTo(tool, normal);
|
|
4762
|
+
return ok(translate(aligned, plane.origin));
|
|
4741
4763
|
}
|
|
4742
4764
|
/** Rotate a shape so its local +Z axis points along `target` (about the origin). */
|
|
4743
4765
|
function alignZTo(shape, target) {
|
|
4744
4766
|
const dot = vecDot(Z_AXIS, target);
|
|
4745
|
-
if (dot >
|
|
4746
|
-
if (dot <
|
|
4767
|
+
if (dot > 1 - 1e-9) return shape;
|
|
4768
|
+
if (dot < -1 + 1e-9) return rotate(shape, 180, {
|
|
4747
4769
|
at: [
|
|
4748
4770
|
0,
|
|
4749
4771
|
0,
|
|
@@ -4756,7 +4778,8 @@ function alignZTo(shape, target) {
|
|
|
4756
4778
|
]
|
|
4757
4779
|
});
|
|
4758
4780
|
const axis = vecNormalize(vecCross(Z_AXIS, target));
|
|
4759
|
-
|
|
4781
|
+
const angleDeg = Math.acos(Math.max(-1, Math.min(1, dot))) * 180 / Math.PI;
|
|
4782
|
+
return rotate(shape, angleDeg, {
|
|
4760
4783
|
at: [
|
|
4761
4784
|
0,
|
|
4762
4785
|
0,
|
|
@@ -4765,8 +4788,7 @@ function alignZTo(shape, target) {
|
|
|
4765
4788
|
axis
|
|
4766
4789
|
});
|
|
4767
4790
|
}
|
|
4768
|
-
|
|
4769
|
-
//#region src/contourFlangeFns.ts
|
|
4791
|
+
// src/contourFlangeFns.ts
|
|
4770
4792
|
/**
|
|
4771
4793
|
* Author a contour flange: an OPEN 2D profile (alternating line/arc segments) swept
|
|
4772
4794
|
* along one straight edge of the base flat. Each arc is a cylindrical bend, each
|
|
@@ -4887,7 +4909,8 @@ function authorContourFlange(part, spec) {
|
|
|
4887
4909
|
function buildLineLeg(base, frame, span, thickness, legLength) {
|
|
4888
4910
|
const place = frameTransform(frame.run, frame.axis, frame.n, frame.origin);
|
|
4889
4911
|
const canon = box(legLength, span, thickness);
|
|
4890
|
-
const
|
|
4912
|
+
const placed = place.solid(canon);
|
|
4913
|
+
const fused = fuse(base, placed);
|
|
4891
4914
|
if (!fused.ok) return fused;
|
|
4892
4915
|
const nextOrigin = vecAdd(frame.origin, vecScale(frame.run, legLength));
|
|
4893
4916
|
return ok({
|
|
@@ -4919,7 +4942,8 @@ function buildArcBend(base, frame, span, thickness, seg) {
|
|
|
4919
4942
|
const place = frameTransform(frame.run, frame.axis, frame.n, frame.origin);
|
|
4920
4943
|
const patch = buildBendPatch(canonOrigin, seg.angleDeg, r, span, thickness, seg.direction);
|
|
4921
4944
|
if (!patch.ok) return patch;
|
|
4922
|
-
const
|
|
4945
|
+
const placed = place.solid(patch.value);
|
|
4946
|
+
const fused = fuse(base, placed);
|
|
4923
4947
|
if (!fused.ok) return fused;
|
|
4924
4948
|
const theta = seg.angleDeg * Math.PI / 180;
|
|
4925
4949
|
const a = -sign * theta;
|
|
@@ -4976,14 +5000,15 @@ function frameTransform(runT, axisT, nT, origin) {
|
|
|
4976
5000
|
const applyR = (v) => vecAdd(vecAdd(vecScale(runT, v[0]), vecScale(axisT, v[1])), vecScale(nT, v[2]));
|
|
4977
5001
|
return {
|
|
4978
5002
|
solid: (s) => {
|
|
4979
|
-
|
|
5003
|
+
const rotated = aa.angleDeg === 0 ? s : rotate(s, aa.angleDeg, {
|
|
4980
5004
|
at: [
|
|
4981
5005
|
0,
|
|
4982
5006
|
0,
|
|
4983
5007
|
0
|
|
4984
5008
|
],
|
|
4985
5009
|
axis: aa.axis
|
|
4986
|
-
})
|
|
5010
|
+
});
|
|
5011
|
+
return translate(rotated, origin);
|
|
4987
5012
|
},
|
|
4988
5013
|
point: (p) => vecAdd(applyR(p), origin),
|
|
4989
5014
|
vector: applyR
|
|
@@ -5044,10 +5069,10 @@ function baseEdge(part, side) {
|
|
|
5044
5069
|
length = uLen;
|
|
5045
5070
|
a = o;
|
|
5046
5071
|
b = uTop;
|
|
5047
|
-
break;
|
|
5048
5072
|
}
|
|
5049
5073
|
const dir = vecNormalize(vecCross(n, out));
|
|
5050
|
-
const
|
|
5074
|
+
const toB = vecSub(b, a);
|
|
5075
|
+
const start = vecDot(toB, dir) >= 0 ? a : b;
|
|
5051
5076
|
return {
|
|
5052
5077
|
dir,
|
|
5053
5078
|
out,
|
|
@@ -5094,10 +5119,10 @@ function regionEdge(frame, side) {
|
|
|
5094
5119
|
length = frame.uLen;
|
|
5095
5120
|
a = o;
|
|
5096
5121
|
b = uTop;
|
|
5097
|
-
break;
|
|
5098
5122
|
}
|
|
5099
5123
|
const dir = vecNormalize(vecCross(frame.n, out));
|
|
5100
|
-
const
|
|
5124
|
+
const toB = vecSub(b, a);
|
|
5125
|
+
const start = vecDot(toB, dir) >= 0 ? a : b;
|
|
5101
5126
|
return {
|
|
5102
5127
|
dir,
|
|
5103
5128
|
out,
|
|
@@ -5131,14 +5156,15 @@ function buildBendPatch(axisOrigin, thetaDeg, r, width, thickness, direction) {
|
|
|
5131
5156
|
});
|
|
5132
5157
|
let tube = outer;
|
|
5133
5158
|
if (r > 1e-9) {
|
|
5134
|
-
const
|
|
5159
|
+
const inner = cylinder(r, width, {
|
|
5135
5160
|
at: axisOrigin,
|
|
5136
5161
|
axis: [
|
|
5137
5162
|
0,
|
|
5138
5163
|
1,
|
|
5139
5164
|
0
|
|
5140
5165
|
]
|
|
5141
|
-
})
|
|
5166
|
+
});
|
|
5167
|
+
const carved = cut(outer, inner);
|
|
5142
5168
|
if (!carved.ok) return carved;
|
|
5143
5169
|
tube = carved.value;
|
|
5144
5170
|
}
|
|
@@ -5149,19 +5175,21 @@ function buildBendPatch(axisOrigin, thetaDeg, r, width, thickness, direction) {
|
|
|
5149
5175
|
function buildWedge(axisOrigin, thetaDeg, outerR, width, direction) {
|
|
5150
5176
|
const span = outerR * 2 + 2;
|
|
5151
5177
|
const margin = 1;
|
|
5152
|
-
const
|
|
5178
|
+
const blockA = box(span, width + 2, 2 * span);
|
|
5179
|
+
const halfA = translate(blockA, [
|
|
5153
5180
|
axisOrigin[0],
|
|
5154
5181
|
axisOrigin[1] - margin,
|
|
5155
5182
|
axisOrigin[2] - span
|
|
5156
5183
|
]);
|
|
5157
|
-
|
|
5184
|
+
const halfB = rotate(halfA, (direction === "up" ? 1 : -1) * (180 - thetaDeg), {
|
|
5158
5185
|
at: axisOrigin,
|
|
5159
5186
|
axis: [
|
|
5160
5187
|
0,
|
|
5161
5188
|
1,
|
|
5162
5189
|
0
|
|
5163
5190
|
]
|
|
5164
|
-
})
|
|
5191
|
+
});
|
|
5192
|
+
return intersect(halfA, halfB);
|
|
5165
5193
|
}
|
|
5166
5194
|
/** Axis-angle of a 3×3 rotation matrix (row-major). */
|
|
5167
5195
|
function matrixToAxisAngle(m) {
|
|
@@ -5219,17 +5247,17 @@ function matrixToAxisAngle(m) {
|
|
|
5219
5247
|
};
|
|
5220
5248
|
}
|
|
5221
5249
|
const denom = 2 * Math.sin(angle);
|
|
5250
|
+
const axis = [
|
|
5251
|
+
(m21 - m12) / denom,
|
|
5252
|
+
(m02 - m20) / denom,
|
|
5253
|
+
(m10 - m01) / denom
|
|
5254
|
+
];
|
|
5222
5255
|
return {
|
|
5223
|
-
axis: vecNormalize(
|
|
5224
|
-
(m21 - m12) / denom,
|
|
5225
|
-
(m02 - m20) / denom,
|
|
5226
|
-
(m10 - m01) / denom
|
|
5227
|
-
]),
|
|
5256
|
+
axis: vecNormalize(axis),
|
|
5228
5257
|
angleDeg
|
|
5229
5258
|
};
|
|
5230
5259
|
}
|
|
5231
|
-
|
|
5232
|
-
//#region src/loftedFlangeFns.ts
|
|
5260
|
+
// src/loftedFlangeFns.ts
|
|
5233
5261
|
/**
|
|
5234
5262
|
* Relative out-of-plane tolerance for the per-quad developability test: a quad is
|
|
5235
5263
|
* twisted (non-developable) when its far corner sits off the diagonal-triangle plane
|
|
@@ -5349,10 +5377,13 @@ function buildQuadPlate(id, a0, a1, b1, b0, thickness) {
|
|
|
5349
5377
|
}
|
|
5350
5378
|
/** A flat triangle (p0,p1,p2) extruded by `thickness` along its own normal. */
|
|
5351
5379
|
function buildTrianglePlate(id, p0, p1, p2, thickness) {
|
|
5380
|
+
const e0 = line(p0, p1);
|
|
5381
|
+
const e1 = line(p1, p2);
|
|
5382
|
+
const e2 = line(p2, p0);
|
|
5352
5383
|
const loopResult = wireLoop([
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5384
|
+
e0,
|
|
5385
|
+
e1,
|
|
5386
|
+
e2
|
|
5356
5387
|
]);
|
|
5357
5388
|
if (!loopResult.ok) return loopResult;
|
|
5358
5389
|
const loop = loopResult.value;
|
|
@@ -5538,8 +5569,7 @@ function closedLoopWire(loop) {
|
|
|
5538
5569
|
}
|
|
5539
5570
|
return wireLoop(edges);
|
|
5540
5571
|
}
|
|
5541
|
-
|
|
5542
|
-
//#region src/hemFns.ts
|
|
5572
|
+
// src/hemFns.ts
|
|
5543
5573
|
/**
|
|
5544
5574
|
* A small clearance baked into a CLOSED hem's curl radius. A true closed hem folds
|
|
5545
5575
|
* the return flat against the parent with zero gap; modelling that exactly makes the
|
|
@@ -5732,8 +5762,7 @@ function splitAngle(totalDeg) {
|
|
|
5732
5762
|
const per = totalDeg / n;
|
|
5733
5763
|
return Array.from({ length: n }, () => per);
|
|
5734
5764
|
}
|
|
5735
|
-
|
|
5736
|
-
//#region src/jogFns.ts
|
|
5765
|
+
// src/jogFns.ts
|
|
5737
5766
|
/**
|
|
5738
5767
|
* Author a jog (joggle): two opposite bends (`+θ` then `−θ`) that step a flat by
|
|
5739
5768
|
* `offsetHeight` perpendicular to its plane, then continue parallel past the step.
|
|
@@ -5892,8 +5921,7 @@ function jogId(spec) {
|
|
|
5892
5921
|
function resolveRegion(region) {
|
|
5893
5922
|
return region === "base" || region === "face-0" ? ROOT_FLAT_ID : region;
|
|
5894
5923
|
}
|
|
5895
|
-
|
|
5896
|
-
//#region src/dxfFns.ts
|
|
5924
|
+
// src/dxfFns.ts
|
|
5897
5925
|
var DEFAULT_TEXT_HEIGHT = 2.5;
|
|
5898
5926
|
var LAYER_OUTLINE = "OUTLINE";
|
|
5899
5927
|
var LAYER_BEND_UP = "BEND_UP";
|
|
@@ -6102,8 +6130,7 @@ function pathPoints(wire) {
|
|
|
6102
6130
|
function toPt2(v) {
|
|
6103
6131
|
return [v[0], v[1]];
|
|
6104
6132
|
}
|
|
6105
|
-
|
|
6106
|
-
//#region src/polygonFns.ts
|
|
6133
|
+
// src/polygonFns.ts
|
|
6107
6134
|
/**
|
|
6108
6135
|
* 2D simple-polygon geometry for true-shape (no-fit-polygon) nesting: an ordered
|
|
6109
6136
|
* vertex loop plus the overlap predicate that is the correctness backbone of the
|
|
@@ -6346,8 +6373,7 @@ function pointSegmentDistance(p, a, b) {
|
|
|
6346
6373
|
const dy = p[1] - (a[1] + t * vy);
|
|
6347
6374
|
return Math.hypot(dx, dy);
|
|
6348
6375
|
}
|
|
6349
|
-
|
|
6350
|
-
//#region src/nestFns.ts
|
|
6376
|
+
// src/nestFns.ts
|
|
6351
6377
|
var EPS = 1e-9;
|
|
6352
6378
|
/**
|
|
6353
6379
|
* Bounding-box nest: arrange developed flat patterns onto stock sheets to reduce
|
|
@@ -6813,8 +6839,7 @@ function nestToDXF$1(result, patterns, sheetIndex, options) {
|
|
|
6813
6839
|
}
|
|
6814
6840
|
return multiPatternToDXF(placed, options ?? {});
|
|
6815
6841
|
}
|
|
6816
|
-
|
|
6817
|
-
//#region src/reportFns.ts
|
|
6842
|
+
// src/reportFns.ts
|
|
6818
6843
|
/**
|
|
6819
6844
|
* Build the bend-table JSON report directly from an authored part. Walks the
|
|
6820
6845
|
* same tree layout the unfold consumes so the per-bend values and the total flat
|
|
@@ -6857,8 +6882,7 @@ function reportFromUnfold(result) {
|
|
|
6857
6882
|
function reportToJSON(report) {
|
|
6858
6883
|
return JSON.stringify(report, null, 2);
|
|
6859
6884
|
}
|
|
6860
|
-
|
|
6861
|
-
//#region src/api.ts
|
|
6885
|
+
// src/api.ts
|
|
6862
6886
|
/** Author a straight-bend part: a base flat plus folded-up flanges. */
|
|
6863
6887
|
function author(spec) {
|
|
6864
6888
|
return authorPart(spec);
|
|
@@ -7020,8 +7044,7 @@ function bendTable(id) {
|
|
|
7020
7044
|
function resolveAllowance(rule, angleDeg, thickness, onWarning) {
|
|
7021
7045
|
return resolveBendAllowance(rule, angleDeg, thickness, onWarning);
|
|
7022
7046
|
}
|
|
7023
|
-
|
|
7024
|
-
//#region src/facade.ts
|
|
7047
|
+
// src/facade.ts
|
|
7025
7048
|
/** Thrown by the fluent facade when an underlying `Result<T>` is an `Err`. */
|
|
7026
7049
|
var SheetMetalError = class extends Error {
|
|
7027
7050
|
code;
|
|
@@ -7291,5 +7314,4 @@ function foldFlat(input) {
|
|
|
7291
7314
|
function fromSolid(solid, opts) {
|
|
7292
7315
|
return new ForeignSolidHandle(solid, opts);
|
|
7293
7316
|
}
|
|
7294
|
-
//#endregion
|
|
7295
7317
|
export { ALUMINUM_GAUGES, DEFAULT_K_FACTOR, ForeignSolidHandle, MATERIALS, ROOT_FLAT_ID, STEEL_GAUGES, SheetMetalBuilder, SheetMetalError, SheetMetalPartHandle, addBendRelief, addBendTable, addCutout, addForm, addHole, addPolygonCutout, addSlot, addTab, allowance, author, authorContourFlange, authorLoftedFlange, authorPart, autoBendReliefs, autoMiterCorner, autoReliefs, baseEdgeRef, bendAllowance, bendRelief, bendTable, buildFeatureGraph, buildFeatureTree, buildReport, contourFlange, cornerRelief, developed, developedLength, emboss, featureTree, fitCylinder, flatPatternToDXF, flatPatternToPolylines, fold, foldFlat, fold$1 as foldPart, foldWithWarnings, fromPart, fromSolid, getBendTable, getMaterial, hem, jog, loftedFlange, louver, miter, miterCorner, miterCut, multiPatternToDXF, nest, nestToDXF, neutralRadius, partToFlatInput, patternBbox, patternToFlatInput, pointInPolygon, polygonBounds, polygonsOverlap, polygonsOverlapWithClearance, registerBendTable, relieveCorner, report, reportFrom, reportFromUnfold, reportJSON, reportToJSON, resolveAllowance, resolveBendAllowance, segmentsIntersect, sheetMetal, signedArea, tabAndSlot, toDXF, transformPolygon, unfold, unfoldForeignSolid, unfold$1 as unfoldPart, unfoldSolid, validate, validatePart, wireToPolygon };
|