brepjs 12.7.1 → 12.7.3

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 (61) hide show
  1. package/dist/2d.cjs +2 -2
  2. package/dist/2d.js +11 -11
  3. package/dist/{Blueprint-CtuUvzex.js → Blueprint-C3lWY1Jf.js} +21 -20
  4. package/dist/{Blueprint-CoFJDAQd.cjs → Blueprint-CnDVffSX.cjs} +3 -2
  5. package/dist/{boolean2D-x2irapGj.js → boolean2D-CwZAIJDS.js} +15 -17
  6. package/dist/{boolean2D-Dk-vLBdl.cjs → boolean2D-DyQJt8Na.cjs} +3 -5
  7. package/dist/{booleanFns-DtOkwLHI.js → booleanFns-CcNUsgI8.js} +3 -3
  8. package/dist/{booleanFns-BJjYqwJ5.cjs → booleanFns-D7HmkpYt.cjs} +2 -2
  9. package/dist/brepjs.cjs +99 -43
  10. package/dist/brepjs.js +1006 -950
  11. package/dist/core.cjs +1 -1
  12. package/dist/core.js +1 -1
  13. package/dist/{cornerFinder-BESZIitp.cjs → cornerFinder-3zfbQvXg.cjs} +1 -1
  14. package/dist/{cornerFinder-FY38t0zq.js → cornerFinder-BV-l1BCw.js} +1 -1
  15. package/dist/{curveFns-LRNGcHXh.js → curveFns-CloOqAQ_.js} +11 -11
  16. package/dist/{drawFns-D8QyY7cg.js → drawFns-5myJTgtX.js} +69 -325
  17. package/dist/{drawFns-BEeoD1yO.cjs → drawFns-CDNafQhv.cjs} +64 -320
  18. package/dist/{helpers-DNzVfe-Z.cjs → helpers-6kn30cSD.cjs} +1 -1
  19. package/dist/{helpers-DeFPsrcI.js → helpers-C9KvE1RW.js} +6 -6
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/io.cjs +2 -2
  23. package/dist/io.js +2 -2
  24. package/dist/kernel/brepkitAdapter.d.ts.map +1 -1
  25. package/dist/kernel/brepkitWasmTypes.d.ts +5 -1
  26. package/dist/kernel/brepkitWasmTypes.d.ts.map +1 -1
  27. package/dist/{loft-DsVv4yxU.js → loft-BcZUCGKi.js} +1 -1
  28. package/dist/{meshFns-BU2l_yOm.cjs → meshFns-3gy0empP.cjs} +1 -1
  29. package/dist/{meshFns-HNwWuM4v.js → meshFns-DsLRd3tA.js} +1 -1
  30. package/dist/{operations-D-gTZNtM.cjs → operations-DLFzmdFX.cjs} +2 -2
  31. package/dist/{operations-D_3rrfrE.js → operations-Dcz6YlOt.js} +3 -3
  32. package/dist/operations.cjs +1 -1
  33. package/dist/operations.js +2 -2
  34. package/dist/query.cjs +2 -2
  35. package/dist/query.js +4 -4
  36. package/dist/{shapeFns-DHlLNHTn.cjs → shapeFns-D-MOoqJd.cjs} +4 -0
  37. package/dist/{shapeFns-CbXxLvV_.js → shapeFns-D2PlLFE6.js} +11 -7
  38. package/dist/sketching/Sketcher.d.ts +31 -77
  39. package/dist/sketching/Sketcher.d.ts.map +1 -1
  40. package/dist/sketching/Sketcher2d.d.ts +1 -1
  41. package/dist/sketching/Sketcher2d.d.ts.map +1 -1
  42. package/dist/sketching/draw.d.ts +2 -2
  43. package/dist/sketching/draw.d.ts.map +1 -1
  44. package/dist/sketching/sketcherlib.d.ts +32 -1
  45. package/dist/sketching/sketcherlib.d.ts.map +1 -1
  46. package/dist/sketching.cjs +2 -2
  47. package/dist/sketching.js +2 -2
  48. package/dist/{surfaceBuilders-D7ZH2QNS.js → surfaceBuilders-D6iDVPIM.js} +12 -12
  49. package/dist/topology/shapeFns.d.ts +5 -0
  50. package/dist/topology/shapeFns.d.ts.map +1 -1
  51. package/dist/{topology-BHnY7Szr.cjs → topology-CKtCGLmb.cjs} +3 -3
  52. package/dist/{topology-C1eZ86dI.js → topology-DxD58iQ6.js} +5 -5
  53. package/dist/topology.cjs +5 -4
  54. package/dist/topology.d.ts +1 -1
  55. package/dist/topology.d.ts.map +1 -1
  56. package/dist/topology.js +23 -22
  57. package/dist/{vectors-TlfO1hu2.cjs → vectors-BafmMf96.cjs} +0 -5
  58. package/dist/{vectors-cec8p8NQ.js → vectors-CESkzEm6.js} +1 -6
  59. package/dist/vectors.cjs +1 -1
  60. package/dist/vectors.js +1 -1
  61. package/package.json +2 -2
package/dist/core.cjs CHANGED
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const types = require("./types-CA_xrgDq.cjs");
4
4
  const vecOps = require("./vecOps-CjRL1jau.cjs");
5
5
  const errors = require("./errors-9fDehDNc.cjs");
6
- const vectors = require("./vectors-TlfO1hu2.cjs");
6
+ const vectors = require("./vectors-BafmMf96.cjs");
7
7
  const shapeTypes = require("./shapeTypes-7xEam9Ri.cjs");
8
8
  const result = require("./result.cjs");
9
9
  exports.resolveDirection = types.resolveDirection;
package/dist/core.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { r, t, a } from "./types-CWDdqcrq.js";
2
2
  import { D, H, R, v, a as a2, b, c, d, e, f, g, h, i, j, k, l, m, n, o } from "./vecOps-ZDdZWbwT.js";
3
3
  import { O, a as a3, c as c2, b as b2, e as e2, f as f2, i as i2, d as d2, g as g2, k as k2, m as m2, h as h2, j as j2, l as l2, o as o2, q, s, t as t2, n as n2, p, u, r as r2, v as v2, w, x, y } from "./errors-B7kgv0cd.js";
4
- import { c as c3, a as a4, p as p2, r as r3, t as t3 } from "./vectors-cec8p8NQ.js";
4
+ import { c as c3, a as a4, p as p2, r as r3, t as t3 } from "./vectors-CESkzEm6.js";
5
5
  import { D as D2, c as c4, a as a5, b as b3, d as d3, g as g3, i as i3, e as e3, f as f3, h as h3, j as j3, k as k3, l as l3, m as m3, n as n3, o as o3, p as p3, q as q2, r as r4, s as s2, t as t4, u as u2, v as v3, w as w2, x as x2, y as y2, z, A } from "./shapeTypes-CpSaBLDv.js";
6
6
  import { BrepBugError, bug } from "./result.js";
7
7
  export {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  const vecOps = require("./vecOps-CjRL1jau.cjs");
3
- const helpers = require("./helpers-DNzVfe-Z.cjs");
3
+ const helpers = require("./helpers-6kn30cSD.cjs");
4
4
  const PI_2 = 2 * Math.PI;
5
5
  function positiveHalfAngle(angle) {
6
6
  const limitedAngle = angle % PI_2;
@@ -1,5 +1,5 @@
1
1
  import { D as DEG2RAD } from "./vecOps-ZDdZWbwT.js";
2
- import { a as angle2d, s as samePoint, d as distance2d } from "./helpers-DeFPsrcI.js";
2
+ import { a as angle2d, s as samePoint, d as distance2d } from "./helpers-C9KvE1RW.js";
3
3
  const PI_2 = 2 * Math.PI;
4
4
  function positiveHalfAngle(angle) {
5
5
  const limitedAngle = angle % PI_2;
@@ -97,18 +97,18 @@ function offsetWire2D(wire, offset, kind = "arc") {
97
97
  return ok(wrapped);
98
98
  }
99
99
  export {
100
- curveEndPoint as a,
101
- getCurveType as b,
102
- curveTangentAt as c,
103
- curveStartPoint as d,
104
- curveIsClosed as e,
105
- flipOrientation as f,
100
+ curveTangentAt as a,
101
+ curveIsClosed as b,
102
+ curveStartPoint as c,
103
+ curvePointAt as d,
104
+ curveEndPoint as e,
105
+ curveLength as f,
106
106
  getOrientation as g,
107
- curvePointAt as h,
108
- curveLength as i,
109
- approximateCurve as j,
110
- curveIsPeriodic as k,
111
- curvePeriod as l,
107
+ approximateCurve as h,
108
+ curveIsPeriodic as i,
109
+ curvePeriod as j,
110
+ flipOrientation as k,
111
+ getCurveType as l,
112
112
  interpolateCurve as m,
113
113
  offsetWire2D as o
114
114
  };
@@ -44,22 +44,22 @@ var __callDispose = (stack, error, hasError) => {
44
44
  return next();
45
45
  };
46
46
  import { r as unwrap, g as isOk, e as err, y as validationError, o as ok } from "./errors-B7kgv0cd.js";
47
- import { r as resolvePlane, b as planeToWorld, d as planeToLocal } from "./vectors-cec8p8NQ.js";
47
+ import { r as resolvePlane, b as planeToWorld } from "./vectors-CESkzEm6.js";
48
48
  import { a as toVec3 } from "./types-CWDdqcrq.js";
49
- import { n as vecScale, j as vecNormalize, v as vecAdd, o as vecSub, b as vecCross, m as vecRotate, R as RAD2DEG, g as vecLength, e as vecEquals, D as DEG2RAD } from "./vecOps-ZDdZWbwT.js";
50
- import { b as Flatbush, c as convertSvgEllipseParams, d as defaultsSplineOptions, S as Sketch, r as roundedRectangleBlueprint, e as Blueprints, C as CompoundBlueprint, f as cut2D, i as intersectCurves, g as fuse2D, m as make2dOffset, h as filletCurves, j as chamferCurves, o as organiseBlueprints, a as BlueprintSketcher, k as intersect2D, B as BaseSketcher2d, p as polysidesBlueprint } from "./boolean2D-x2irapGj.js";
49
+ import { j as vecNormalize, b as vecCross, o as vecSub, n as vecScale, m as vecRotate, D as DEG2RAD, g as vecLength } from "./vecOps-ZDdZWbwT.js";
50
+ import { b as Flatbush, B as BaseSketcher2d, S as Sketch, r as roundedRectangleBlueprint, c as Blueprints, C as CompoundBlueprint, d as cut2D, i as intersectCurves, f as fuse2D, m as make2dOffset, e as filletCurves, g as chamferCurves, o as organiseBlueprints, a as BlueprintSketcher, h as intersect2D, p as polysidesBlueprint } from "./boolean2D-CwZAIJDS.js";
51
51
  import { d as downcast, c as cast, e as faceCenter, n as normalAt, o as outerWire } from "./faceFns-B6ebRh5I.js";
52
- import { c as curveTangentAt, a as curveEndPoint, f as flipOrientation, b as getCurveType, o as offsetWire2D } from "./curveFns-LRNGcHXh.js";
53
- import { a as makeLine, d as makeThreePointArc, e as makeTangentArc, f as makeEllipseArc, g as makeBezierCurve, b as assembleWire, h as addHolesInFace, m as makeFace, i as makeCircle, j as makeEllipse, c as makeHelix, k as makeBSplineApproximation } from "./surfaceBuilders-D7ZH2QNS.js";
54
- import { D as DisposalScope, B as getKernel, G as createWire, I as createFace, k as isFace, c as castShape } from "./shapeTypes-CpSaBLDv.js";
55
- import { m as mirror, B as Blueprint, C as Curve2D, a as make2dSegmentCurve, b as make2dArcFromCenter, c as approximateAsSvgCompatibleCurve, d as BoundingBox2d, e as edgeToCurve, f as make2dInerpolatedBSplineCurve, g as make2dCircle, h as make2dEllipse, i as deserializeCurve2D } from "./Blueprint-CtuUvzex.js";
52
+ import { o as offsetWire2D } from "./curveFns-CloOqAQ_.js";
53
+ import { b as assembleWire, d as addHolesInFace, m as makeFace, e as makeCircle, f as makeEllipse, c as makeHelix, g as makeBSplineApproximation } from "./surfaceBuilders-D6iDVPIM.js";
54
+ import { D as DisposalScope, G as createWire, I as createFace, B as getKernel, k as isFace, c as castShape } from "./shapeTypes-CpSaBLDv.js";
55
+ import { c as curvesAsEdgesOnPlane, m as mirror, B as Blueprint, C as Curve2D, a as make2dSegmentCurve, b as make2dArcFromCenter, d as approximateAsSvgCompatibleCurve, e as BoundingBox2d, f as edgeToCurve, g as make2dInerpolatedBSplineCurve, h as make2dCircle, i as make2dEllipse, j as deserializeCurve2D } from "./Blueprint-C3lWY1Jf.js";
56
56
  import { bug } from "./result.js";
57
- import { d as distance2d, p as polarAngle2d, f as polarToCartesian, P as PRECISION_OFFSET, h as squareDistance2d, s as samePoint$1, e as subtract2d, c as add2d } from "./helpers-DeFPsrcI.js";
58
- import { d as getEdges } from "./shapeFns-CbXxLvV_.js";
57
+ import { s as samePoint$1, P as PRECISION_OFFSET, f as squareDistance2d, e as subtract2d, c as add2d } from "./helpers-C9KvE1RW.js";
58
+ import { d as getEdges } from "./shapeFns-D2PlLFE6.js";
59
59
  import { a as makeCompound, b as makeSolid } from "./solidBuilders-BXhh5hP2.js";
60
- import { b as basicFaceExtrusion, r as revolution, c as complexExtrude, t as twistExtrude } from "./loft-DsVv4yxU.js";
60
+ import { b as basicFaceExtrusion, r as revolution, c as complexExtrude, t as twistExtrude } from "./loft-BcZUCGKi.js";
61
61
  import opentype from "opentype.js";
62
- import { c as cornerFinder } from "./cornerFinder-FY38t0zq.js";
62
+ import { c as cornerFinder } from "./cornerFinder-BV-l1BCw.js";
63
63
  const stitchCurves = (curves, precision = 1e-7) => {
64
64
  const startPoints = new Flatbush(curves.length);
65
65
  curves.forEach((c) => {
@@ -108,350 +108,94 @@ const stitchCurves = (curves, precision = 1e-7) => {
108
108
  });
109
109
  return stitchedCurves;
110
110
  };
111
- class Sketcher {
111
+ class Sketcher extends BaseSketcher2d {
112
112
  plane;
113
- pointer;
114
- firstPoint;
115
- pendingEdges;
116
- _mirrorWire;
117
113
  constructor(plane, origin) {
114
+ super();
118
115
  this.plane = plane && typeof plane !== "string" ? { ...plane } : resolvePlane(plane ?? "XY", origin);
119
- this.pointer = [...this.plane.origin];
120
- this.firstPoint = [...this.plane.origin];
121
- this.pendingEdges = [];
122
- this._mirrorWire = false;
123
116
  }
124
- /** Release all kernel edges held by this sketcher. */
117
+ /** Release resources held by this sketcher (lightweight — no kernel handles during drawing). */
125
118
  delete() {
126
- for (const edge of this.pendingEdges) {
127
- edge.delete();
128
- }
129
- this.pendingEdges = [];
130
- }
131
- _updatePointer(newPointer) {
132
- this.pointer = newPointer;
133
- }
134
- /** Move the pen to an absolute 2D position before drawing any edges. */
135
- movePointerTo([x, y]) {
136
- if (this.pendingEdges.length)
137
- bug("Sketcher.movePointerTo", "You can only move the pointer if there is no edge defined");
138
- this._updatePointer(planeToWorld(this.plane, [x, y]));
139
- this.firstPoint = this.pointer;
140
- return this;
141
- }
142
- /** Draw a straight line to an absolute 2D point on the sketch plane. */
143
- lineTo([x, y]) {
144
- const endPoint = planeToWorld(this.plane, [x, y]);
145
- this.pendingEdges.push(makeLine(this.pointer, endPoint));
146
- this._updatePointer(endPoint);
147
- return this;
148
- }
149
- /** Draw a straight line by relative horizontal and vertical distances. */
150
- line(xDist, yDist) {
151
- const [px, py] = planeToLocal(this.plane, this.pointer);
152
- return this.lineTo([xDist + px, yDist + py]);
153
- }
154
- /** Draw a vertical line of the given signed distance. */
155
- vLine(distance) {
156
- return this.line(0, distance);
157
- }
158
- /** Draw a horizontal line of the given signed distance. */
159
- hLine(distance) {
160
- return this.line(distance, 0);
161
- }
162
- /** Draw a vertical line to an absolute Y coordinate. */
163
- vLineTo(yPos) {
164
- const [px] = planeToLocal(this.plane, this.pointer);
165
- return this.lineTo([px, yPos]);
166
- }
167
- /** Draw a horizontal line to an absolute X coordinate. */
168
- hLineTo(xPos) {
169
- const [, py] = planeToLocal(this.plane, this.pointer);
170
- return this.lineTo([xPos, py]);
171
- }
172
- /** Draw a line in polar coordinates (distance and angle in degrees) from the current point. */
173
- polarLine(distance, angle) {
174
- const angleInRads = angle * DEG2RAD;
175
- const [x, y] = polarToCartesian(distance, angleInRads);
176
- return this.line(x, y);
177
- }
178
- /** Draw a line to a point given in polar coordinates [r, theta] from the origin. */
179
- polarLineTo([r, theta]) {
180
- const angleInRads = theta * DEG2RAD;
181
- const point = polarToCartesian(r, angleInRads);
182
- return this.lineTo(point);
183
- }
184
- /** Draw a line tangent to the previous edge, extending by the given distance. */
185
- tangentLine(distance) {
186
- const previousEdge = this.pendingEdges.length ? this.pendingEdges[this.pendingEdges.length - 1] : null;
187
- if (!previousEdge)
188
- bug("Sketcher.tangentLine", "You need a previous edge to create a tangent line");
189
- const tangent = curveTangentAt(previousEdge, 1);
190
- const scaledTangent = vecScale(vecNormalize(tangent), distance);
191
- const endPoint = vecAdd(scaledTangent, this.pointer);
192
- this.pendingEdges.push(makeLine(this.pointer, endPoint));
193
- this._updatePointer(endPoint);
194
- return this;
195
- }
196
- /** Draw a circular arc passing through an inner point to an absolute end point. */
197
- threePointsArcTo(end, innerPoint) {
198
- const gpoint1 = planeToWorld(this.plane, innerPoint);
199
- const gpoint2 = planeToWorld(this.plane, end);
200
- this.pendingEdges.push(makeThreePointArc(this.pointer, gpoint1, gpoint2));
201
- this._updatePointer(gpoint2);
202
- return this;
203
- }
204
- /** Draw a circular arc through a via-point to an end point, both given as relative distances. */
205
- threePointsArc(xDist, yDist, viaXDist, viaYDist) {
206
- const [px, py] = planeToLocal(this.plane, this.pointer);
207
- return this.threePointsArcTo([px + xDist, py + yDist], [px + viaXDist, py + viaYDist]);
208
- }
209
- /** Draw a circular arc tangent to the previous edge, ending at an absolute point. */
210
- tangentArcTo(end) {
211
- const endPoint = planeToWorld(this.plane, end);
212
- const previousEdge = this.pendingEdges.length ? this.pendingEdges[this.pendingEdges.length - 1] : null;
213
- if (!previousEdge)
214
- bug("Sketcher.tangentArcTo", "You need a previous edge to create a tangent arc");
215
- const prevEnd = curveEndPoint(previousEdge);
216
- const prevTangent = curveTangentAt(previousEdge, 1);
217
- this.pendingEdges.push(makeTangentArc(prevEnd, prevTangent, endPoint));
218
- this._updatePointer(endPoint);
219
- return this;
220
- }
221
- /** Draw a circular arc tangent to the previous edge, ending at a relative offset. */
222
- tangentArc(xDist, yDist) {
223
- const [px, py] = planeToLocal(this.plane, this.pointer);
224
- return this.tangentArcTo([xDist + px, yDist + py]);
225
- }
226
- /** Draw a circular arc to an absolute end point, bulging by the given sagitta. */
119
+ this.pendingCurves = [];
120
+ }
121
+ /**
122
+ * Override to preserve the original Sketcher's sagitta direction convention.
123
+ *
124
+ * BaseSketcher2d computes the perpendicular as `[-dy, dx]` (counter-clockwise rotation),
125
+ * but the original Sketcher used `cross(diff, plane.zDir)` which produces `[dy, -dx]`
126
+ * (clockwise rotation) for standard planes. Negating the sagitta compensates for this,
127
+ * ensuring all sagitta/bulge arcs curve the same way as the original 3D implementation.
128
+ */
227
129
  sagittaArcTo(end, sagitta) {
228
- const startPoint = this.pointer;
229
- const endPoint = planeToWorld(this.plane, end);
230
- const sum = vecAdd(endPoint, startPoint);
231
- const midPoint = vecScale(sum, 0.5);
232
- const diff = vecSub(endPoint, startPoint);
233
- const crossResult = vecCross(diff, this.plane.zDir);
234
- const sagDirection = vecNormalize(crossResult);
235
- const sagVector = vecScale(sagDirection, sagitta);
236
- const sagPoint = vecAdd(midPoint, sagVector);
237
- this.pendingEdges.push(makeThreePointArc(this.pointer, sagPoint, endPoint));
238
- this._updatePointer(endPoint);
239
- return this;
240
- }
241
- /** Draw a circular arc to a relative end point, bulging by the given sagitta. */
242
- sagittaArc(xDist, yDist, sagitta) {
243
- const [px, py] = planeToLocal(this.plane, this.pointer);
244
- return this.sagittaArcTo([xDist + px, yDist + py], sagitta);
245
- }
246
- /** Draw a vertical sagitta arc of the given distance and bulge. */
247
- vSagittaArc(distance, sagitta) {
248
- return this.sagittaArc(0, distance, sagitta);
249
- }
250
- /** Draw a horizontal sagitta arc of the given distance and bulge. */
251
- hSagittaArc(distance, sagitta) {
252
- return this.sagittaArc(distance, 0, sagitta);
253
- }
254
- /** Draw an arc to an absolute end point using a bulge factor (sagitta as fraction of half-chord). */
255
- bulgeArcTo(end, bulge) {
256
- if (!bulge) return this.lineTo(end);
257
- const [px, py] = planeToLocal(this.plane, this.pointer);
258
- const halfChord = distance2d([px, py], end) / 2;
259
- const bulgeAsSagitta = -bulge * halfChord;
260
- return this.sagittaArcTo(end, bulgeAsSagitta);
261
- }
262
- /** Draw an arc to a relative end point using a bulge factor. */
263
- bulgeArc(xDist, yDist, bulge) {
264
- const [px, py] = planeToLocal(this.plane, this.pointer);
265
- return this.bulgeArcTo([xDist + px, yDist + py], bulge);
266
- }
267
- /** Draw a vertical bulge arc of the given distance and bulge factor. */
268
- vBulgeArc(distance, bulge) {
269
- return this.bulgeArc(0, distance, bulge);
270
- }
271
- /** Draw a horizontal bulge arc of the given distance and bulge factor. */
272
- hBulgeArc(distance, bulge) {
273
- return this.bulgeArc(distance, 0, bulge);
274
- }
275
- /** Draw an elliptical arc to an absolute end point (SVG-style parameters). */
276
- ellipseTo(end, horizontalRadius, verticalRadius, rotation = 0, longAxis = false, sweep = false) {
277
- const [startX, startY] = planeToLocal(this.plane, this.pointer);
278
- let rotationAngle = rotation;
279
- let majorRadius = horizontalRadius;
280
- let minorRadius = verticalRadius;
281
- if (horizontalRadius < verticalRadius) {
282
- rotationAngle = rotation + 90;
283
- majorRadius = verticalRadius;
284
- minorRadius = horizontalRadius;
285
- }
286
- const { cx, cy, rx, ry, startAngle, endAngle, clockwise } = convertSvgEllipseParams(
287
- [startX, startY],
288
- end,
289
- majorRadius,
290
- minorRadius,
291
- rotationAngle * DEG2RAD,
292
- longAxis,
293
- sweep
294
- );
295
- const xDir = vecRotate(this.plane.xDir, this.plane.zDir, rotationAngle * DEG2RAD);
296
- let arc = unwrap(
297
- makeEllipseArc(
298
- rx,
299
- ry,
300
- clockwise ? startAngle : endAngle,
301
- clockwise ? endAngle : startAngle,
302
- planeToWorld(this.plane, [cx, cy]),
303
- this.plane.zDir,
304
- xDir
305
- )
306
- );
307
- if (!clockwise) {
308
- arc = flipOrientation(arc);
309
- }
310
- this.pendingEdges.push(arc);
311
- this._updatePointer(planeToWorld(this.plane, end));
312
- return this;
313
- }
314
- /** Draw an elliptical arc to a relative end point (SVG-style parameters). */
315
- ellipse(xDist, yDist, horizontalRadius, verticalRadius, rotation = 0, longAxis = false, sweep = false) {
316
- const [px, py] = planeToLocal(this.plane, this.pointer);
317
- return this.ellipseTo(
318
- [xDist + px, yDist + py],
319
- horizontalRadius,
320
- verticalRadius,
321
- rotation,
322
- longAxis,
323
- sweep
324
- );
130
+ return super.sagittaArcTo(end, -sagitta);
325
131
  }
326
- /** Draw a half-ellipse arc to an absolute end point with a given minor radius. */
327
- halfEllipseTo(end, verticalRadius, sweep = false) {
328
- const [px, py] = planeToLocal(this.plane, this.pointer);
329
- const start = [px, py];
330
- const angle = polarAngle2d(end, start);
331
- const distance = distance2d(end, start);
332
- return this.ellipseTo(end, distance / 2, verticalRadius, angle * RAD2DEG, false, sweep);
333
- }
334
- /** Draw a half-ellipse arc to a relative end point with a given minor radius. */
335
- halfEllipse(xDist, yDist, verticalRadius, sweep = false) {
336
- const [px, py] = planeToLocal(this.plane, this.pointer);
337
- return this.halfEllipseTo([xDist + px, yDist + py], verticalRadius, sweep);
338
- }
339
- /** Draw a Bezier curve to an absolute end point through one or more control points. */
340
- bezierCurveTo(end, controlPoints) {
341
- let cp;
342
- if (controlPoints.length === 2 && !Array.isArray(controlPoints[0])) {
343
- cp = [controlPoints];
344
- } else {
345
- cp = controlPoints;
346
- }
347
- const inWorldPoints = cp.map((p) => planeToWorld(this.plane, p));
348
- const endPoint = planeToWorld(this.plane, end);
349
- this.pendingEdges.push(unwrap(makeBezierCurve([this.pointer, ...inWorldPoints, endPoint])));
350
- this._updatePointer(endPoint);
351
- return this;
352
- }
353
- /** Draw a quadratic Bezier curve to an absolute end point with a single control point. */
354
- quadraticBezierCurveTo(end, controlPoint) {
355
- return this.bezierCurveTo(end, [controlPoint]);
356
- }
357
- /** Draw a cubic Bezier curve to an absolute end point with start and end control points. */
358
- cubicBezierCurveTo(end, startControlPoint, endControlPoint) {
359
- return this.bezierCurveTo(end, [startControlPoint, endControlPoint]);
360
- }
361
- /** Draw a smooth cubic Bezier spline to an absolute end point, blending tangent with the previous edge. */
362
- smoothSplineTo(end, config) {
132
+ buildWire() {
363
133
  var _stack = [];
364
134
  try {
365
- const _scope = __using(_stack, new DisposalScope());
366
- const { endTangent, startTangent, startFactor, endFactor } = defaultsSplineOptions(config);
367
- const endPoint = planeToWorld(this.plane, end);
368
- const previousEdge = this.pendingEdges.length ? this.pendingEdges[this.pendingEdges.length - 1] : null;
369
- const diff = vecSub(endPoint, this.pointer);
370
- const defaultDistance = vecLength(diff) * 0.25;
371
- let startPoleDirection;
372
- if (startTangent) {
373
- startPoleDirection = planeToWorld(this.plane, startTangent);
374
- } else if (!previousEdge) {
375
- startPoleDirection = planeToWorld(this.plane, [1, 0]);
376
- } else if (getCurveType(previousEdge) === "BEZIER_CURVE") {
377
- const previousPole = getKernel().getBezierPenultimatePole(previousEdge.wrapped);
378
- if (previousPole) {
379
- startPoleDirection = vecSub(this.pointer, previousPole);
380
- } else {
381
- startPoleDirection = curveTangentAt(previousEdge, 1);
382
- }
383
- } else {
384
- startPoleDirection = curveTangentAt(previousEdge, 1);
385
- }
386
- const poleDistance = vecScale(vecNormalize(startPoleDirection), startFactor * defaultDistance);
387
- const startControl = vecAdd(this.pointer, poleDistance);
388
- let endPoleDirection;
389
- if (endTangent === "symmetric") {
390
- endPoleDirection = vecScale(startPoleDirection, -1);
391
- } else {
392
- endPoleDirection = planeToWorld(this.plane, endTangent);
393
- }
394
- const endPoleDistance = vecScale(vecNormalize(endPoleDirection), endFactor * defaultDistance);
395
- const endControl = vecSub(endPoint, endPoleDistance);
396
- this.pendingEdges.push(
397
- unwrap(makeBezierCurve([this.pointer, startControl, endControl, endPoint]))
135
+ if (!this.pendingCurves.length) bug("Sketcher.buildWire", "No lines to convert into a wire");
136
+ const scope = __using(_stack, new DisposalScope());
137
+ const edges = curvesAsEdgesOnPlane(this.pendingCurves, this.plane).map(
138
+ (e) => scope.register(e)
398
139
  );
399
- this._updatePointer(endPoint);
400
- return this;
140
+ return unwrap(assembleWire(edges));
401
141
  } catch (_) {
402
142
  var _error = _, _hasError = true;
403
143
  } finally {
404
144
  __callDispose(_stack, _error, _hasError);
405
145
  }
406
146
  }
407
- /** Draw a smooth cubic Bezier spline to a relative end point, blending tangent with the previous edge. */
408
- smoothSpline(xDist, yDist, splineConfig = {}) {
409
- const [px, py] = planeToLocal(this.plane, this.pointer);
410
- return this.smoothSplineTo([xDist + px, yDist + py], splineConfig);
147
+ /** Finish drawing and return the open-wire Sketch (does not close the path). */
148
+ done() {
149
+ return new Sketch(this.buildWire(), {
150
+ defaultOrigin: this.plane.origin,
151
+ defaultDirection: this.plane.zDir
152
+ });
153
+ }
154
+ /** Close the path with a straight line to the start point and return the Sketch. */
155
+ close() {
156
+ this._closeSketch();
157
+ return this.done();
411
158
  }
412
- _mirrorWireOnStartEnd(wire) {
413
- const diff = vecSub(this.pointer, this.firstPoint);
159
+ /**
160
+ * Close the path by mirroring all edges about the line from first to last point.
161
+ *
162
+ * Mirrors in 3D after assembling the partial wire to ensure exact endpoint
163
+ * matching across kernels.
164
+ */
165
+ closeWithMirror() {
166
+ if (samePoint$1(this.pointer, this.firstPoint))
167
+ bug(
168
+ "Sketcher.closeWithMirror",
169
+ "Cannot close with a mirror when the sketch is already closed"
170
+ );
171
+ const wire = this.buildWire();
172
+ const pointer3d = planeToWorld(this.plane, this.pointer);
173
+ const firstPoint3d = planeToWorld(this.plane, this.firstPoint);
174
+ const diff = vecSub(pointer3d, firstPoint3d);
414
175
  const startToEndVector = vecNormalize(diff);
415
176
  const normal = vecCross(startToEndVector, this.plane.zDir);
416
177
  const clonedWrapped = unwrap(downcast(wire.wrapped));
417
- const mirroredRaw = mirror(clonedWrapped, normal, this.pointer);
178
+ const mirroredRaw = mirror(clonedWrapped, normal, pointer3d);
418
179
  const mirroredWrapped = unwrap(downcast(mirroredRaw));
419
180
  const mirroredWire = createWire(mirroredWrapped);
420
181
  const combinedWire = unwrap(assembleWire([wire, mirroredWire]));
421
- return combinedWire;
422
- }
423
- buildWire() {
424
- if (!this.pendingEdges.length) bug("Sketcher.buildWire", "No lines to convert into a wire");
425
- let wire = unwrap(assembleWire(this.pendingEdges));
426
- if (this._mirrorWire) {
427
- wire = this._mirrorWireOnStartEnd(wire);
428
- }
429
- return wire;
430
- }
431
- _closeSketch() {
432
- if (!vecEquals(this.pointer, this.firstPoint) && !this._mirrorWire) {
433
- const [endX, endY] = planeToLocal(this.plane, this.firstPoint);
434
- this.lineTo([endX, endY]);
435
- }
436
- }
437
- /** Finish drawing and return the open-wire Sketch (does not close the path). */
438
- done() {
439
- const sketch = new Sketch(this.buildWire(), {
182
+ return new Sketch(combinedWire, {
440
183
  defaultOrigin: this.plane.origin,
441
184
  defaultDirection: this.plane.zDir
442
185
  });
443
- return sketch;
444
186
  }
445
- /** Close the path with a straight line to the start point and return the Sketch. */
446
- close() {
187
+ /**
188
+ * Close the path and apply a custom corner treatment between the last and first segments.
189
+ *
190
+ * @param radius - Fillet/chamfer radius, or a custom corner function.
191
+ * @param mode - Corner treatment type.
192
+ * @returns The closed {@link Sketch}.
193
+ */
194
+ closeWithCustomCorner(radius, mode = "fillet") {
447
195
  this._closeSketch();
196
+ this._customCornerLastWithFirst(radius, mode);
448
197
  return this.done();
449
198
  }
450
- /** Close the path by mirroring all edges about the line from first to last point. */
451
- closeWithMirror() {
452
- this._mirrorWire = true;
453
- return this.close();
454
- }
455
199
  }
456
200
  const guessFaceFromWires = (wires) => {
457
201
  const wireShapes = wires.map((w) => w.wrapped);