brepjs 8.0.0 → 8.0.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.
Files changed (124) hide show
  1. package/dist/2d/blueprints/booleanHelpers.d.ts +32 -0
  2. package/dist/2d/blueprints/booleanHelpers.d.ts.map +1 -0
  3. package/dist/2d/blueprints/booleanOperations.d.ts +5 -3
  4. package/dist/2d/blueprints/booleanOperations.d.ts.map +1 -1
  5. package/dist/2d/blueprints/intersectionSegments.d.ts +12 -0
  6. package/dist/2d/blueprints/intersectionSegments.d.ts.map +1 -0
  7. package/dist/2d/blueprints/segmentAssembly.d.ts +31 -0
  8. package/dist/2d/blueprints/segmentAssembly.d.ts.map +1 -0
  9. package/dist/2d.cjs +2 -2
  10. package/dist/2d.js +8 -8
  11. package/dist/{Blueprint-D3JfGJTz.js → Blueprint-B9fhnpFp.js} +117 -30
  12. package/dist/{Blueprint-CVctc41Z.cjs → Blueprint-VGbo3izk.cjs} +111 -24
  13. package/dist/{boolean2D-BdZATaHs.cjs → boolean2D-B1XrGVgx.cjs} +426 -345
  14. package/dist/{boolean2D-hOw5Qay5.js → boolean2D-_WiqPxWZ.js} +391 -310
  15. package/dist/{booleanFns-BBSVKhL2.cjs → booleanFns-BxW-N3rP.cjs} +12 -16
  16. package/dist/{booleanFns-CqehfzcK.js → booleanFns-CkccZ7UL.js} +14 -18
  17. package/dist/brepjs.cjs +133 -62
  18. package/dist/brepjs.js +290 -217
  19. package/dist/{cast-DQaUibmm.js → cast-C4Ff_1Qe.js} +2 -2
  20. package/dist/{cast-DkB0GKmQ.cjs → cast-DIiyxDLo.cjs} +2 -2
  21. package/dist/core/disposal.d.ts +1 -1
  22. package/dist/core/disposal.d.ts.map +1 -1
  23. package/dist/core.cjs +3 -3
  24. package/dist/core.js +3 -3
  25. package/dist/cornerFinder-BndBNtJE.cjs +58 -0
  26. package/dist/cornerFinder-DzGzfiqb.js +59 -0
  27. package/dist/curveBuilders-BUoFO1UG.cjs +196 -0
  28. package/dist/curveBuilders-CBlIWlbU.js +197 -0
  29. package/dist/{curveFns-BilyYL_s.cjs → curveFns-BrJDkaWi.cjs} +31 -44
  30. package/dist/{curveFns-CdVE4da7.js → curveFns-BshHA9Ys.js} +31 -44
  31. package/dist/{drawFns-921SkhDL.js → drawFns-Btmlh_Oz.js} +13 -14
  32. package/dist/{drawFns-CUyx50gi.cjs → drawFns-D2eDcf4k.cjs} +58 -59
  33. package/dist/{faceFns-DHu-2JpA.js → faceFns-DDzCECn3.js} +3 -3
  34. package/dist/{faceFns-BwK7FP7N.cjs → faceFns-NDRFeekj.cjs} +3 -3
  35. package/dist/helpers-Ck8GJ58k.cjs +203 -0
  36. package/dist/helpers-jku2V1DY.js +204 -0
  37. package/dist/io.cjs +4 -4
  38. package/dist/io.js +4 -4
  39. package/dist/kernel/occtAdapter.d.ts +1 -0
  40. package/dist/kernel/occtAdapter.d.ts.map +1 -1
  41. package/dist/kernel/sweepOps.d.ts +8 -0
  42. package/dist/kernel/sweepOps.d.ts.map +1 -1
  43. package/dist/kernel/types.d.ts +1 -0
  44. package/dist/kernel/types.d.ts.map +1 -1
  45. package/dist/loft-Bk9EM0gZ.js +373 -0
  46. package/dist/loft-DJXwxV_L.cjs +372 -0
  47. package/dist/{measurement-C5JGCuUP.js → measurement-DlXaTzKc.js} +3 -3
  48. package/dist/{measurement-fxm_pW7x.cjs → measurement-LcGh4wV0.cjs} +3 -3
  49. package/dist/measurement.cjs +1 -1
  50. package/dist/measurement.js +1 -1
  51. package/dist/{meshFns-AqAjTTVl.js → meshFns-Djzdn-CS.js} +1 -1
  52. package/dist/{meshFns-BhrZGi6w.cjs → meshFns-c8lDKfYy.cjs} +1 -1
  53. package/dist/{occtBoundary-du8_ex-p.cjs → occtBoundary-6kQSl3cF.cjs} +21 -0
  54. package/dist/{occtBoundary-CwegMzqc.js → occtBoundary-CqXvDhZY.js} +26 -5
  55. package/dist/operations/extrude.d.ts.map +1 -1
  56. package/dist/operations/extrudeFns.d.ts.map +1 -1
  57. package/dist/operations/extrudeUtils.d.ts +17 -0
  58. package/dist/operations/extrudeUtils.d.ts.map +1 -1
  59. package/dist/{operations-C1rWoba2.js → operations-CrQlFDHc.js} +30 -7
  60. package/dist/{operations-BP1wVDw0.cjs → operations-Do-WZGXc.cjs} +30 -7
  61. package/dist/operations.cjs +2 -2
  62. package/dist/operations.js +4 -4
  63. package/dist/query/cornerFinder.d.ts +48 -0
  64. package/dist/query/cornerFinder.d.ts.map +1 -0
  65. package/dist/query/directionUtils.d.ts +6 -0
  66. package/dist/query/directionUtils.d.ts.map +1 -0
  67. package/dist/query/edgeFinder.d.ts +15 -0
  68. package/dist/query/edgeFinder.d.ts.map +1 -0
  69. package/dist/query/faceFinder.d.ts +15 -0
  70. package/dist/query/faceFinder.d.ts.map +1 -0
  71. package/dist/query/finderCore.d.ts +35 -0
  72. package/dist/query/finderCore.d.ts.map +1 -0
  73. package/dist/query/finderFns.d.ts +21 -106
  74. package/dist/query/finderFns.d.ts.map +1 -1
  75. package/dist/query/shapeDistanceFilter.d.ts +11 -0
  76. package/dist/query/shapeDistanceFilter.d.ts.map +1 -0
  77. package/dist/query/vertexFinder.d.ts +16 -0
  78. package/dist/query/vertexFinder.d.ts.map +1 -0
  79. package/dist/query/wireFinder.d.ts +10 -0
  80. package/dist/query/wireFinder.d.ts.map +1 -0
  81. package/dist/query.cjs +42 -5
  82. package/dist/query.js +40 -2
  83. package/dist/{shapeFns-BrF97sKt.js → shapeFns-DQtpzndX.js} +17 -18
  84. package/dist/{shapeFns-BvOndshS.cjs → shapeFns-cN4qGpbO.cjs} +6 -7
  85. package/dist/{shapeTypes-DKhwEnUM.cjs → shapeTypes-BJ3Hmskg.cjs} +24 -20
  86. package/dist/{shapeTypes-BlSElW8z.js → shapeTypes-C9sUsmEW.js} +32 -28
  87. package/dist/sketching/Sketcher.d.ts.map +1 -1
  88. package/dist/sketching/Sketcher2d.d.ts +12 -4
  89. package/dist/sketching/Sketcher2d.d.ts.map +1 -1
  90. package/dist/sketching/ellipseUtils.d.ts +29 -0
  91. package/dist/sketching/ellipseUtils.d.ts.map +1 -0
  92. package/dist/sketching.cjs +2 -2
  93. package/dist/sketching.js +2 -2
  94. package/dist/topology/booleanFns.d.ts.map +1 -1
  95. package/dist/topology/curveBuilders.d.ts +75 -0
  96. package/dist/topology/curveBuilders.d.ts.map +1 -0
  97. package/dist/topology/curveFns.d.ts.map +1 -1
  98. package/dist/topology/primitiveFns.d.ts.map +1 -1
  99. package/dist/topology/shapeFns.d.ts.map +1 -1
  100. package/dist/topology/shapeHelpers.d.ts +6 -173
  101. package/dist/topology/shapeHelpers.d.ts.map +1 -1
  102. package/dist/topology/shapeUtils.d.ts +13 -0
  103. package/dist/topology/shapeUtils.d.ts.map +1 -0
  104. package/dist/topology/solidBuilders.d.ts +70 -0
  105. package/dist/topology/solidBuilders.d.ts.map +1 -0
  106. package/dist/topology/surfaceBuilders.d.ts +35 -0
  107. package/dist/topology/surfaceBuilders.d.ts.map +1 -0
  108. package/dist/topology/wrapperFns.d.ts +1 -0
  109. package/dist/topology/wrapperFns.d.ts.map +1 -1
  110. package/dist/{topology-tFzqSrGH.js → topology-CtfUZwLR.js} +8 -8
  111. package/dist/{topology-CIooytHH.cjs → topology-DXq8dLsi.cjs} +8 -8
  112. package/dist/topology.cjs +7 -7
  113. package/dist/topology.js +31 -31
  114. package/dist/{vectors-CBuaMeZv.js → vectors-BVgXsYWl.js} +1 -1
  115. package/dist/{vectors-ChWEZPwy.cjs → vectors-DK2hEKcI.cjs} +1 -1
  116. package/dist/vectors.cjs +2 -2
  117. package/dist/vectors.js +2 -2
  118. package/package.json +1 -1
  119. package/dist/loft-BzWFokmC.cjs +0 -178
  120. package/dist/loft-CtG5nMq5.js +0 -179
  121. package/dist/query-V6nV-VfL.js +0 -396
  122. package/dist/query-hMSmOWJP.cjs +0 -395
  123. package/dist/shapeHelpers-B2SXz1p4.cjs +0 -488
  124. package/dist/shapeHelpers-BcoZf2N9.js +0 -489
@@ -1,395 +0,0 @@
1
- "use strict";
2
- const occtBoundary = require("./occtBoundary-du8_ex-p.cjs");
3
- const shapeTypes = require("./shapeTypes-DKhwEnUM.cjs");
4
- const vecOps = require("./vecOps-CjRL1jau.cjs");
5
- const result = require("./result.cjs");
6
- const cast = require("./cast-DkB0GKmQ.cjs");
7
- const shapeFns = require("./shapeFns-BvOndshS.cjs");
8
- const faceFns = require("./faceFns-BwK7FP7N.cjs");
9
- const measurement = require("./measurement-fxm_pW7x.cjs");
10
- const curveFns = require("./curveFns-BilyYL_s.cjs");
11
- const errors = require("./errors-DK1VAdP4.cjs");
12
- const PRECISION_INTERSECTION = 1e-9;
13
- const PRECISION_OFFSET = 1e-8;
14
- const PRECISION_POINT = 1e-6;
15
- const samePoint = ([x0, y0], [x1, y1], precision = PRECISION_POINT) => {
16
- return Math.abs(x0 - x1) <= precision && Math.abs(y0 - y1) <= precision;
17
- };
18
- const add2d = ([x0, y0], [x1, y1]) => {
19
- return [x0 + x1, y0 + y1];
20
- };
21
- const subtract2d = ([x0, y0], [x1, y1]) => {
22
- return [x0 - x1, y0 - y1];
23
- };
24
- const scalarMultiply2d = ([x0, y0], scalar) => {
25
- return [x0 * scalar, y0 * scalar];
26
- };
27
- const distance2d = ([x0, y0], [x1, y1] = [0, 0]) => {
28
- return Math.sqrt((x0 - x1) ** 2 + (y0 - y1) ** 2);
29
- };
30
- const squareDistance2d = ([x0, y0], [x1, y1] = [0, 0]) => {
31
- return (x0 - x1) ** 2 + (y0 - y1) ** 2;
32
- };
33
- function crossProduct2d([x0, y0], [x1, y1]) {
34
- return x0 * y1 - y0 * x1;
35
- }
36
- const angle2d = ([x0, y0], [x1, y1] = [0, 0]) => {
37
- return Math.atan2(y1 * x0 - y0 * x1, x0 * x1 + y0 * y1);
38
- };
39
- const polarAngle2d = ([x0, y0], [x1, y1] = [0, 0]) => {
40
- return Math.atan2(y1 - y0, x1 - x0);
41
- };
42
- const normalize2d = ([x0, y0]) => {
43
- const l = distance2d([x0, y0]);
44
- if (l < 1e-12) {
45
- result.bug("normalize2d", "Cannot normalize zero-length vector");
46
- }
47
- return [x0 / l, y0 / l];
48
- };
49
- const rotate2d = (point, angle, center = [0, 0]) => {
50
- const [px0, py0] = point;
51
- const [cx, cy] = center;
52
- const px = px0 - cx;
53
- const py = py0 - cy;
54
- const sinA = Math.sin(angle);
55
- const cosA = Math.cos(angle);
56
- const xnew = px * cosA - py * sinA;
57
- const ynew = px * sinA + py * cosA;
58
- return [xnew + cx, ynew + cy];
59
- };
60
- const polarToCartesian = (r, theta) => {
61
- const x = Math.cos(theta) * r;
62
- const y = Math.sin(theta) * r;
63
- return [x, y];
64
- };
65
- const cartesianToPolar = ([x, y]) => {
66
- const r = distance2d([x, y]);
67
- const theta = Math.atan2(y, x);
68
- return [r, theta];
69
- };
70
- function createFinder(topoKind, filters, getNormal) {
71
- const withFilter = (pred) => createFinder(topoKind, [...filters, pred]);
72
- const shouldKeep = (element) => filters.every((f) => f(element));
73
- const extractElements = (shape) => {
74
- const result2 = [];
75
- for (const raw of cast.iterTopo(shape.wrapped, topoKind)) {
76
- const element = shapeTypes.castShape(errors.unwrap(cast.downcast(raw)));
77
- if (shouldKeep(element)) {
78
- result2.push(element);
79
- }
80
- }
81
- return result2;
82
- };
83
- const finder = {
84
- _filters: filters,
85
- _topoKind: topoKind,
86
- when: (pred) => withFilter(pred),
87
- inList: (elements) => {
88
- const hashSet = /* @__PURE__ */ new Map();
89
- for (const e of elements) {
90
- const h = shapeFns.getHashCode(e);
91
- const bucket = hashSet.get(h);
92
- if (bucket) bucket.push(e);
93
- else hashSet.set(h, [e]);
94
- }
95
- return withFilter((el) => {
96
- const bucket = hashSet.get(shapeFns.getHashCode(el));
97
- return !!bucket && bucket.some((e) => shapeFns.isSameShape(e, el));
98
- });
99
- },
100
- not: (builderFn) => {
101
- const inner = builderFn(createFinder(topoKind, []));
102
- return withFilter((el) => !inner.shouldKeep(el));
103
- },
104
- either: (fns) => {
105
- const builtFinders = fns.map((fn) => fn(createFinder(topoKind, [])));
106
- return withFilter((el) => builtFinders.some((f) => f.shouldKeep(el)));
107
- },
108
- findAll: (shape) => extractElements(shape),
109
- findUnique: (shape) => {
110
- const elements = extractElements(shape);
111
- if (elements.length !== 1) {
112
- return errors.err(
113
- errors.queryError(
114
- "FINDER_NOT_UNIQUE",
115
- `Finder expected a unique match but found ${elements.length} element(s)`
116
- )
117
- );
118
- }
119
- return errors.ok(elements[0]);
120
- },
121
- shouldKeep
122
- };
123
- return finder;
124
- }
125
- const DIRECTIONS = {
126
- X: [1, 0, 0],
127
- Y: [0, 1, 0],
128
- Z: [0, 0, 1]
129
- };
130
- function resolveDir(dir) {
131
- if (typeof dir === "string") return DIRECTIONS[dir] ?? [0, 0, 1];
132
- return dir;
133
- }
134
- function edgeFinder() {
135
- return createEdgeFinder([]);
136
- }
137
- function createEdgeFinder(filters) {
138
- const base = createFinder("edge", filters);
139
- const withFilter = (pred) => createEdgeFinder([...filters, pred]);
140
- return {
141
- ...base,
142
- when: (pred) => createEdgeFinder([...filters, pred]),
143
- inList: (elements) => createEdgeFinder([...base.inList(elements)._filters]),
144
- not: (fn) => createEdgeFinder([...base.not(fn)._filters]),
145
- either: (fns) => createEdgeFinder([
146
- ...base.either(fns)._filters
147
- ]),
148
- inDirection: (dir = "Z", angle = 0) => {
149
- const d = vecOps.vecNormalize(resolveDir(dir));
150
- return withFilter((edge) => {
151
- const oc = occtBoundary.getKernel().oc;
152
- const r = shapeTypes.gcWithScope();
153
- const adaptor = r(new oc.BRepAdaptor_Curve_2(edge.wrapped));
154
- const tmpPnt = r(new oc.gp_Pnt_1());
155
- const tmpVec = r(new oc.gp_Vec_1());
156
- const mid = (Number(adaptor.FirstParameter()) + Number(adaptor.LastParameter())) / 2;
157
- adaptor.D1(mid, tmpPnt, tmpVec);
158
- const tangent = vecOps.vecNormalize([tmpVec.X(), tmpVec.Y(), tmpVec.Z()]);
159
- const ang = Math.acos(Math.min(1, Math.abs(vecOps.vecDot(tangent, d))));
160
- return Math.abs(ang - vecOps.DEG2RAD * angle) < 1e-6;
161
- });
162
- },
163
- ofLength: (length, tolerance = 1e-3) => withFilter((edge) => Math.abs(curveFns.curveLength(edge) - length) < tolerance),
164
- ofCurveType: (curveType) => withFilter((edge) => curveFns.getCurveType(edge) === curveType),
165
- parallelTo: (dir = "Z") => createEdgeFinder([...filters]).inDirection(dir, 0),
166
- atDistance: (distance, point = [0, 0, 0]) => withFilter((edge) => {
167
- const oc = occtBoundary.getKernel().oc;
168
- const r = shapeTypes.gcWithScope();
169
- const pnt = r(occtBoundary.toOcPnt(point));
170
- const vtxMaker = r(new oc.BRepBuilderAPI_MakeVertex(pnt));
171
- const vtx = vtxMaker.Vertex();
172
- const distTool = r(new oc.BRepExtrema_DistShapeShape_1());
173
- distTool.LoadS1(vtx);
174
- distTool.LoadS2(edge.wrapped);
175
- const progress = r(new oc.Message_ProgressRange_1());
176
- distTool.Perform(progress);
177
- const d = distTool.Value();
178
- return Math.abs(d - distance) < 1e-6;
179
- })
180
- };
181
- }
182
- function faceFinder() {
183
- return createFaceFinder([]);
184
- }
185
- function createFaceFinder(filters) {
186
- const base = createFinder("face", filters);
187
- const withFilter = (pred) => createFaceFinder([...filters, pred]);
188
- return {
189
- ...base,
190
- when: (pred) => createFaceFinder([...filters, pred]),
191
- inList: (elements) => createFaceFinder([...base.inList(elements)._filters]),
192
- not: (fn) => createFaceFinder([...base.not(fn)._filters]),
193
- either: (fns) => createFaceFinder([
194
- ...base.either(fns)._filters
195
- ]),
196
- inDirection: (dir = "Z", angle = 0) => {
197
- const d = vecOps.vecNormalize(resolveDir(dir));
198
- return withFilter((face) => {
199
- const n = faceFns.normalAt(face);
200
- const ang = Math.acos(Math.min(1, Math.abs(vecOps.vecDot(vecOps.vecNormalize(n), d))));
201
- return Math.abs(ang - vecOps.DEG2RAD * angle) < 1e-6;
202
- });
203
- },
204
- parallelTo: (dir = "Z") => createFaceFinder([...filters]).inDirection(dir, 0),
205
- ofSurfaceType: (surfaceType) => withFilter((face) => errors.unwrap(faceFns.getSurfaceType(face)) === surfaceType),
206
- ofArea: (area, tolerance = 1e-3) => withFilter((face) => Math.abs(measurement.measureArea(face) - area) < tolerance),
207
- atDistance: (distance, point = [0, 0, 0]) => withFilter((face) => {
208
- const oc = occtBoundary.getKernel().oc;
209
- const r = shapeTypes.gcWithScope();
210
- const pnt = r(occtBoundary.toOcPnt(point));
211
- const vtxMaker = r(new oc.BRepBuilderAPI_MakeVertex(pnt));
212
- const vtx = vtxMaker.Vertex();
213
- const distTool = r(new oc.BRepExtrema_DistShapeShape_1());
214
- distTool.LoadS1(vtx);
215
- distTool.LoadS2(face.wrapped);
216
- const progress = r(new oc.Message_ProgressRange_1());
217
- distTool.Perform(progress);
218
- const d = distTool.Value();
219
- return Math.abs(d - distance) < 1e-6;
220
- })
221
- };
222
- }
223
- function wireFinder() {
224
- return createWireFinder([]);
225
- }
226
- function createWireFinder(filters) {
227
- const base = createFinder("wire", filters);
228
- const withFilter = (pred) => createWireFinder([...filters, pred]);
229
- return {
230
- ...base,
231
- when: (pred) => createWireFinder([...filters, pred]),
232
- inList: (elements) => createWireFinder([...base.inList(elements)._filters]),
233
- not: (fn) => createWireFinder([...base.not(fn)._filters]),
234
- either: (fns) => createWireFinder([
235
- ...base.either(fns)._filters
236
- ]),
237
- isClosed: () => withFilter((wire) => curveFns.curveIsClosed(wire)),
238
- isOpen: () => withFilter((wire) => !curveFns.curveIsClosed(wire)),
239
- ofEdgeCount: (count) => withFilter((wire) => {
240
- let edgeCount = 0;
241
- for (const _raw of cast.iterTopo(wire.wrapped, "edge")) {
242
- edgeCount++;
243
- }
244
- return edgeCount === count;
245
- })
246
- };
247
- }
248
- function vertexFinder() {
249
- return createVertexFinder([]);
250
- }
251
- function createVertexFinder(filters) {
252
- const base = createFinder("vertex", filters);
253
- const withFilter = (pred) => createVertexFinder([...filters, pred]);
254
- return {
255
- ...base,
256
- when: (pred) => createVertexFinder([...filters, pred]),
257
- inList: (elements) => createVertexFinder([...base.inList(elements)._filters]),
258
- not: (fn) => createVertexFinder([
259
- ...base.not(fn)._filters
260
- ]),
261
- either: (fns) => createVertexFinder([
262
- ...base.either(fns)._filters
263
- ]),
264
- nearestTo: (point) => {
265
- const newFilters = [...filters];
266
- const finderWithNearestTo = createVertexFinderWithNearest(newFilters, point);
267
- return finderWithNearestTo;
268
- },
269
- atPosition: (point, tolerance = 1e-4) => withFilter((vertex) => {
270
- const pos = shapeFns.vertexPosition(vertex);
271
- return vecOps.vecDistance(pos, point) < tolerance;
272
- }),
273
- withinBox: (min, max) => withFilter((vertex) => {
274
- const pos = shapeFns.vertexPosition(vertex);
275
- return pos[0] >= min[0] - 1e-6 && pos[0] <= max[0] + 1e-6 && pos[1] >= min[1] - 1e-6 && pos[1] <= max[1] + 1e-6 && pos[2] >= min[2] - 1e-6 && pos[2] <= max[2] + 1e-6;
276
- }),
277
- atDistance: (distance, point = [0, 0, 0], tolerance = 1e-4) => withFilter((vertex) => {
278
- const pos = shapeFns.vertexPosition(vertex);
279
- return Math.abs(vecOps.vecDistance(pos, point) - distance) < tolerance;
280
- })
281
- };
282
- }
283
- function createVertexFinderWithNearest(filters, nearestPoint) {
284
- const baseFinder = createVertexFinder(filters);
285
- const findAllNearest = (shape) => {
286
- const candidates = baseFinder.findAll(shape);
287
- if (candidates.length === 0) return [];
288
- let bestIdx = 0;
289
- let bestDist = vecOps.vecDistance(shapeFns.vertexPosition(candidates[0]), nearestPoint);
290
- for (let i = 1; i < candidates.length; i++) {
291
- const d = vecOps.vecDistance(shapeFns.vertexPosition(candidates[i]), nearestPoint);
292
- if (d < bestDist) {
293
- bestDist = d;
294
- bestIdx = i;
295
- }
296
- }
297
- return [candidates[bestIdx]];
298
- };
299
- const findUniqueNearest = (shape) => {
300
- const nearest = findAllNearest(shape);
301
- if (nearest.length === 0) {
302
- return errors.err(
303
- errors.queryError("FINDER_NOT_UNIQUE", "Finder expected a unique match but found 0 element(s)")
304
- );
305
- }
306
- return errors.ok(nearest[0]);
307
- };
308
- return {
309
- ...baseFinder,
310
- findAll: findAllNearest,
311
- findUnique: findUniqueNearest
312
- };
313
- }
314
- const PI_2 = 2 * Math.PI;
315
- const positiveHalfAngle = (angle) => {
316
- const limitedAngle = angle % PI_2;
317
- const coterminalAngle = limitedAngle < 0 ? limitedAngle + PI_2 : limitedAngle;
318
- if (coterminalAngle < Math.PI) return coterminalAngle;
319
- if (coterminalAngle === Math.PI) return 0;
320
- return Math.abs(coterminalAngle - PI_2);
321
- };
322
- function blueprintCorners(blueprint) {
323
- return blueprint.curves.map((curve, index) => ({
324
- firstCurve: curve,
325
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
326
- secondCurve: blueprint.curves[(index + 1) % blueprint.curves.length],
327
- point: curve.lastPoint
328
- }));
329
- }
330
- function cornerFinder() {
331
- return createCornerFinder([]);
332
- }
333
- function createCornerFinder(filters) {
334
- const withFilter = (pred) => createCornerFinder([...filters, pred]);
335
- const shouldKeep = (corner) => filters.every((f) => f(corner));
336
- return {
337
- shouldKeep,
338
- when: (pred) => withFilter(pred),
339
- inList: (points) => withFilter((corner) => points.some((p) => samePoint(p, corner.point))),
340
- atDistance: (distance, point = [0, 0]) => withFilter((corner) => Math.abs(distance2d(point, corner.point) - distance) < 1e-9),
341
- atPoint: (point) => withFilter((corner) => samePoint(point, corner.point)),
342
- inBox: (corner1, corner2) => {
343
- const minX = Math.min(corner1[0], corner2[0]);
344
- const maxX = Math.max(corner1[0], corner2[0]);
345
- const minY = Math.min(corner1[1], corner2[1]);
346
- const maxY = Math.max(corner1[1], corner2[1]);
347
- return withFilter((corner) => {
348
- const [x, y] = corner.point;
349
- return x >= minX && x <= maxX && y >= minY && y <= maxY;
350
- });
351
- },
352
- ofAngle: (angle) => withFilter((corner) => {
353
- const tgt1 = corner.firstCurve.tangentAt(1);
354
- const tgt2 = corner.secondCurve.tangentAt(0);
355
- return Math.abs(positiveHalfAngle(angle2d(tgt1, tgt2)) - positiveHalfAngle(vecOps.DEG2RAD * angle)) < 1e-9;
356
- }),
357
- not: (fn) => {
358
- const inner = fn(createCornerFinder([]));
359
- return withFilter((corner) => !inner.shouldKeep(corner));
360
- },
361
- either: (fns) => {
362
- const builtFinders = fns.map((fn) => fn(createCornerFinder([])));
363
- return withFilter((corner) => builtFinders.some((f) => f.shouldKeep(corner)));
364
- },
365
- find: (blueprint) => blueprintCorners(blueprint).filter(shouldKeep)
366
- };
367
- }
368
- function getSingleFace(f, shape) {
369
- if (typeof f === "object" && "_topoKind" in f) {
370
- return f.findUnique(shape);
371
- }
372
- if (typeof f !== "function" && shapeTypes.isFace(f)) return errors.ok(f);
373
- const fnResult = f(faceFinder());
374
- return fnResult.findUnique(shape);
375
- }
376
- exports.PRECISION_INTERSECTION = PRECISION_INTERSECTION;
377
- exports.PRECISION_OFFSET = PRECISION_OFFSET;
378
- exports.add2d = add2d;
379
- exports.cartesianToPolar = cartesianToPolar;
380
- exports.cornerFinder = cornerFinder;
381
- exports.crossProduct2d = crossProduct2d;
382
- exports.distance2d = distance2d;
383
- exports.edgeFinder = edgeFinder;
384
- exports.faceFinder = faceFinder;
385
- exports.getSingleFace = getSingleFace;
386
- exports.normalize2d = normalize2d;
387
- exports.polarAngle2d = polarAngle2d;
388
- exports.polarToCartesian = polarToCartesian;
389
- exports.rotate2d = rotate2d;
390
- exports.samePoint = samePoint;
391
- exports.scalarMultiply2d = scalarMultiply2d;
392
- exports.squareDistance2d = squareDistance2d;
393
- exports.subtract2d = subtract2d;
394
- exports.vertexFinder = vertexFinder;
395
- exports.wireFinder = wireFinder;