@mlightcad/geometry-engine 1.0.7 → 2.0.1

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.
@@ -0,0 +1,166 @@
1
+ var __read = (this && this.__read) || function (o, n) {
2
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
3
+ if (!m) return o;
4
+ var i = m.call(o), r, ar = [], e;
5
+ try {
6
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
7
+ }
8
+ catch (error) { e = { error: error }; }
9
+ finally {
10
+ try {
11
+ if (r && !r.done && (m = i["return"])) m.call(i);
12
+ }
13
+ finally { if (e) throw e.error; }
14
+ }
15
+ return ar;
16
+ };
17
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
18
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
19
+ if (ar || !(i in from)) {
20
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
21
+ ar[i] = from[i];
22
+ }
23
+ }
24
+ return to.concat(ar || Array.prototype.slice.call(from));
25
+ };
26
+ import { calculateCurveLength, evaluateNurbsPoint, generateChordKnots, generateSqrtChordKnots, generateUniformKnots } from '../util';
27
+ import { AcGeCatmullRomCurve3d } from './AcGeCatmullRomCurve3d';
28
+ /**
29
+ * A NURBS curve implementation that can be used by other curve classes
30
+ */
31
+ var AcGeNurbsCurve = /** @class */ (function () {
32
+ function AcGeNurbsCurve(degree, knots, controlPoints, weights) {
33
+ this._degree = degree;
34
+ this._knots = __spreadArray([], __read(knots), false);
35
+ this._controlPoints = controlPoints.map(function (p) { return ({ x: p.x, y: p.y, z: p.z }); });
36
+ this._weights = weights
37
+ ? __spreadArray([], __read(weights), false) : new Array(controlPoints.length).fill(1.0);
38
+ }
39
+ /**
40
+ * Get the degree of the NURBS curve
41
+ */
42
+ AcGeNurbsCurve.prototype.degree = function () {
43
+ return this._degree;
44
+ };
45
+ /**
46
+ * Get the knot vector
47
+ */
48
+ AcGeNurbsCurve.prototype.knots = function () {
49
+ return __spreadArray([], __read(this._knots), false);
50
+ };
51
+ /**
52
+ * Get the control points
53
+ */
54
+ AcGeNurbsCurve.prototype.controlPoints = function () {
55
+ return this._controlPoints.map(function (p) { return ({ x: p.x, y: p.y, z: p.z }); });
56
+ };
57
+ /**
58
+ * Get the weights
59
+ */
60
+ AcGeNurbsCurve.prototype.weights = function () {
61
+ return __spreadArray([], __read(this._weights), false);
62
+ };
63
+ /**
64
+ * Calculate a point on the curve at parameter u
65
+ */
66
+ AcGeNurbsCurve.prototype.point = function (u) {
67
+ // Convert AcGePoint3dLike[] to number[][] for utility functions
68
+ var controlPointsArray = this._controlPoints.map(function (p) { return [p.x, p.y, p.z]; });
69
+ return evaluateNurbsPoint(u, this._degree, this._knots, controlPointsArray, this._weights);
70
+ };
71
+ /**
72
+ * Calculate curve length using numerical integration
73
+ */
74
+ AcGeNurbsCurve.prototype.length = function () {
75
+ // Convert AcGePoint3dLike[] to number[][] for utility functions
76
+ var controlPointsArray = this._controlPoints.map(function (p) { return [p.x, p.y, p.z]; });
77
+ return calculateCurveLength(this._degree, this._knots, controlPointsArray, this._weights);
78
+ };
79
+ /**
80
+ * Create a NURBS curve from control points and knots
81
+ */
82
+ AcGeNurbsCurve.byKnotsControlPointsWeights = function (degree, knots, controlPoints, weights) {
83
+ return new AcGeNurbsCurve(degree, knots, controlPoints, weights);
84
+ };
85
+ /**
86
+ * Create a NURBS curve from fit points using interpolation
87
+ */
88
+ AcGeNurbsCurve.byPoints = function (points, degree, parameterization) {
89
+ if (parameterization === void 0) { parameterization = 'Uniform'; }
90
+ // Generate knots based on parameterization type
91
+ var knots;
92
+ switch (parameterization) {
93
+ case 'Chord':
94
+ knots = generateChordKnots(degree, points);
95
+ break;
96
+ case 'SqrtChord':
97
+ knots = generateSqrtChordKnots(degree, points);
98
+ break;
99
+ case 'Uniform':
100
+ default:
101
+ knots = generateUniformKnots(degree, points.length);
102
+ break;
103
+ }
104
+ // Convert number[][] to AcGePoint3dLike[] for control points
105
+ var controlPoints = points.map(function (p) { return ({ x: p[0], y: p[1], z: p[2] }); });
106
+ var weights = new Array(controlPoints.length).fill(1.0);
107
+ return new AcGeNurbsCurve(degree, knots, controlPoints, weights);
108
+ };
109
+ /**
110
+ * Get the valid parameter range for this curve
111
+ */
112
+ AcGeNurbsCurve.prototype.getParameterRange = function () {
113
+ var startParam = this._knots[this._degree];
114
+ var endParam = this._knots[this._knots.length - this._degree - 1];
115
+ return { start: startParam, end: endParam };
116
+ };
117
+ /**
118
+ * Get points along the curve
119
+ * @param divisions - Number of divisions to create
120
+ * @returns Array of points along the curve
121
+ */
122
+ AcGeNurbsCurve.prototype.getPoints = function (divisions) {
123
+ var points = [];
124
+ var _a = this.getParameterRange(), start = _a.start, end = _a.end;
125
+ for (var i = 0; i <= divisions; i++) {
126
+ var t = start + (end - start) * (i / divisions);
127
+ points.push(this.point(t));
128
+ }
129
+ return points;
130
+ };
131
+ /**
132
+ * Check if the curve is closed by comparing start and end points
133
+ */
134
+ AcGeNurbsCurve.prototype.isClosed = function (tolerance) {
135
+ if (tolerance === void 0) { tolerance = 1e-6; }
136
+ var _a = this.getParameterRange(), start = _a.start, end = _a.end;
137
+ var startPoint = this.point(start);
138
+ var endPoint = this.point(end);
139
+ var dx = startPoint[0] - endPoint[0];
140
+ var dy = startPoint[1] - endPoint[1];
141
+ var dz = startPoint[2] - endPoint[2];
142
+ return Math.sqrt(dx * dx + dy * dy + dz * dz) < tolerance;
143
+ };
144
+ /**
145
+ * Create a closed NURBS curve using Catmull-Rom interpolation for smooth closure
146
+ */
147
+ AcGeNurbsCurve.createClosedCurve = function (points, degree, parameterization) {
148
+ if (parameterization === void 0) { parameterization = 'Chord'; }
149
+ if (points.length < 4) {
150
+ throw new Error('At least 4 points are required for a closed NURBS curve');
151
+ }
152
+ // Create a closed Catmull-Rom curve
153
+ var catmullRomCurve = new AcGeCatmullRomCurve3d(points, true, 'centripetal');
154
+ // Get points along the curve for NURBS interpolation
155
+ // Use more divisions for smoother curve
156
+ var divisions = Math.max(50, points.length * 2);
157
+ var curvePoints = catmullRomCurve.getPoints(divisions);
158
+ // Convert AcGePoint3d[] back to number[][]
159
+ var nurbsPoints = curvePoints.map(function (point) { return [point.x, point.y, point.z]; });
160
+ // Create NURBS curve from the interpolated points
161
+ return AcGeNurbsCurve.byPoints(nurbsPoints, degree, parameterization);
162
+ };
163
+ return AcGeNurbsCurve;
164
+ }());
165
+ export { AcGeNurbsCurve };
166
+ //# sourceMappingURL=AcGeNurbsCurve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AcGeNurbsCurve.js","sourceRoot":"","sources":["../../src/geometry/AcGeNurbsCurve.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AACA,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAO/D;;GAEG;AACH;IAME,wBACE,MAAc,EACd,KAAe,EACf,aAAgC,EAChC,OAAkB;QAElB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACrB,IAAI,CAAC,MAAM,4BAAO,KAAK,SAAC,CAAA;QACxB,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAA5B,CAA4B,CAAC,CAAA;QAC1E,IAAI,CAAC,QAAQ,GAAG,OAAO;YACrB,CAAC,0BAAK,OAAO,UACb,CAAC,CAAC,IAAI,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC/C,CAAC;IAED;;OAEG;IACH,+BAAM,GAAN;QACE,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED;;OAEG;IACH,8BAAK,GAAL;QACE,gCAAW,IAAI,CAAC,MAAM,UAAC;IACzB,CAAC;IAED;;OAEG;IACH,sCAAa,GAAb;QACE,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAA5B,CAA4B,CAAC,CAAA;IACnE,CAAC;IAED;;OAEG;IACH,gCAAO,GAAP;QACE,gCAAW,IAAI,CAAC,QAAQ,UAAC;IAC3B,CAAC;IAED;;OAEG;IACH,8BAAK,GAAL,UAAM,CAAS;QACb,gEAAgE;QAChE,IAAM,kBAAkB,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAf,CAAe,CAAC,CAAA;QACxE,OAAO,kBAAkB,CACvB,CAAC,EACD,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,MAAM,EACX,kBAAkB,EAClB,IAAI,CAAC,QAAQ,CACd,CAAA;IACH,CAAC;IAED;;OAEG;IACH,+BAAM,GAAN;QACE,gEAAgE;QAChE,IAAM,kBAAkB,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAf,CAAe,CAAC,CAAA;QACxE,OAAO,oBAAoB,CACzB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,MAAM,EACX,kBAAkB,EAClB,IAAI,CAAC,QAAQ,CACd,CAAA;IACH,CAAC;IAED;;OAEG;IACI,0CAA2B,GAAlC,UACE,MAAc,EACd,KAAe,EACf,aAAgC,EAChC,OAAkB;QAElB,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,CAAA;IAClE,CAAC;IAED;;OAEG;IACI,uBAAQ,GAAf,UACE,MAAkB,EAClB,MAAc,EACd,gBAA0D;QAA1D,iCAAA,EAAA,4BAA0D;QAE1D,gDAAgD;QAChD,IAAI,KAAe,CAAA;QACnB,QAAQ,gBAAgB,EAAE,CAAC;YACzB,KAAK,OAAO;gBACV,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;gBAC1C,MAAK;YACP,KAAK,WAAW;gBACd,KAAK,GAAG,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;gBAC9C,MAAK;YACP,KAAK,SAAS,CAAC;YACf;gBACE,KAAK,GAAG,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;gBACnD,MAAK;QACT,CAAC;QAED,6DAA6D;QAC7D,IAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAA/B,CAA+B,CAAC,CAAA;QACtE,IAAM,OAAO,GAAG,IAAI,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAEzD,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,CAAA;IAClE,CAAC;IAED;;OAEG;IACH,0CAAiB,GAAjB;QACE,IAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC5C,IAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAA;QACnE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAA;IAC7C,CAAC;IAED;;;;OAIG;IACH,kCAAS,GAAT,UAAU,SAAiB;QACzB,IAAM,MAAM,GAAe,EAAE,CAAA;QACvB,IAAA,KAAiB,IAAI,CAAC,iBAAiB,EAAE,EAAvC,KAAK,WAAA,EAAE,GAAG,SAA6B,CAAA;QAE/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,IAAM,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;YACjD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAED;;OAEG;IACH,iCAAQ,GAAR,UAAS,SAAwB;QAAxB,0BAAA,EAAA,gBAAwB;QACzB,IAAA,KAAiB,IAAI,CAAC,iBAAiB,EAAE,EAAvC,KAAK,WAAA,EAAE,GAAG,SAA6B,CAAA;QAC/C,IAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACpC,IAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAEhC,IAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;QACtC,IAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;QACtC,IAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;QAEtC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAA;IAC3D,CAAC;IAED;;OAEG;IACI,gCAAiB,GAAxB,UACE,MAAyB,EACzB,MAAc,EACd,gBAAwD;QAAxD,iCAAA,EAAA,0BAAwD;QAExD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAA;QAC5E,CAAC;QAED,oCAAoC;QACpC,IAAM,eAAe,GAAG,IAAI,qBAAqB,CAC/C,MAAM,EACN,IAAI,EACJ,aAAa,CACd,CAAA;QAED,qDAAqD;QACrD,wCAAwC;QACxC,IAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QACjD,IAAM,WAAW,GAAG,eAAe,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;QAExD,2CAA2C;QAC3C,IAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,UAAA,KAAK,IAAI,OAAA,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAA3B,CAA2B,CAAC,CAAA;QAEzE,kDAAkD;QAClD,OAAO,cAAc,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAA;IACvE,CAAC;IACH,qBAAC;AAAD,CAAC,AA9LD,IA8LC"}
@@ -1,63 +1,22 @@
1
1
  import { AcGeBox3d, AcGeMatrix3d, AcGePoint3d, AcGePoint3dLike, AcGePointLike } from '../math';
2
2
  import { AcGeCurve3d } from './AcGeCurve3d';
3
- export type AcGeKnotParameterizationType = 'Uniform' | 'Chord' | 'SqrtChord';
4
- /**
5
- * Lightweight NURBS curve implementation
6
- */
7
- declare class NurbsCurve {
8
- private _degree;
9
- private _knots;
10
- private _controlPoints;
11
- private _weights;
12
- constructor(degree: number, knots: number[], controlPoints: number[][], weights?: number[]);
13
- degree(): number;
14
- knots(): number[];
15
- controlPoints(): number[][];
16
- weights(): number[];
17
- /**
18
- * Calculate a point on the curve at parameter u
19
- */
20
- point(u: number): number[];
21
- /**
22
- * Calculate curve length using numerical integration
23
- */
24
- length(): number;
25
- /**
26
- * Create a NURBS curve from control points and knots
27
- */
28
- static byKnotsControlPointsWeights(degree: number, knots: number[], controlPoints: number[][], weights?: number[]): NurbsCurve;
29
- /**
30
- * Create a NURBS curve from fit points using interpolation
31
- */
32
- static byPoints(points: number[][], degree: number, parameterization?: AcGeKnotParameterizationType): NurbsCurve;
33
- }
3
+ import { AcGeKnotParameterizationType, AcGeNurbsCurve } from './AcGeNurbsCurve';
34
4
  export declare class AcGeSpline3d extends AcGeCurve3d {
35
5
  private _nurbsCurve;
36
6
  private _fitPoints?;
37
7
  private _knotParameterization?;
38
8
  private _controlPoints;
39
9
  private _closed;
40
- private _originalControlPoints?;
41
- private _originalKnots?;
42
- private _originalWeights?;
43
- constructor(controlPoints: AcGePointLike[], knots: number[], weights?: number[]);
44
- constructor(fitPoints: AcGePointLike[], knotParam: AcGeKnotParameterizationType);
10
+ constructor(controlPoints: AcGePoint3dLike[], knots: number[], weights?: number[], closed?: boolean);
11
+ constructor(fitPoints: AcGePointLike[], knotParam: AcGeKnotParameterizationType, closed?: boolean);
45
12
  /**
46
- * Set the closed property and rebuild the curve if necessary
47
- */
48
- private setClosed;
49
- /**
50
- * Make the spline closed by adding control points and adjusting knots
51
- */
52
- private makeClosed;
53
- /**
54
- * Make the spline open by restoring the original curve
13
+ * Build the NURBS curve using stored data
55
14
  */
56
- private makeOpen;
15
+ private buildCurve;
57
16
  /**
58
- * Create periodic knot vector for closed curve
17
+ * Set the closed property and rebuild the curve if necessary
59
18
  */
60
- private createClosedKnotVector;
19
+ private setClosed;
61
20
  /**
62
21
  * Degree of the spline to be created.
63
22
  */
@@ -90,15 +49,15 @@ export declare class AcGeSpline3d extends AcGeCurve3d {
90
49
  * @param index Input index (0 based) of point to get
91
50
  * @returns
92
51
  */
93
- getControlPointAt(index: number): import("../math").AcGeVectorLike;
52
+ getControlPointAt(index: number): import("../math").AcGeVector3dLike;
94
53
  /**
95
- * Divide this spline into the specified number of points
54
+ * Divide this spline into the specified nubmer of points
96
55
  * those points as an array of points.
97
- * @param numPoints Input the number of points returned
56
+ * @param numPoints Input the nubmer of points returned
98
57
  * @returns Return an array of point
99
58
  */
100
59
  getPoints(numPoints?: number): AcGePoint3d[];
101
- getCurvePoints(curve: NurbsCurve, count: number): number[][];
60
+ getCurvePoints(curve: AcGeNurbsCurve, count: number): number[][];
102
61
  /**
103
62
  * @inheritdoc
104
63
  */
@@ -116,11 +75,11 @@ export declare class AcGeSpline3d extends AcGeCurve3d {
116
75
  */
117
76
  private toNurbsPoints;
118
77
  /**
119
- * Convert input points to points in geometry engine format
120
- * @param points Input points to convert
121
- * @returns Return converted points
78
+ * Create a closed spline from fit points using AcGeNurbsCurve.createClosedCurve
79
+ * @param fitPoints - Array of fit points defining the curve
80
+ * @param parameterization - Knot parameterization type for NURBS
81
+ * @returns A closed spline
122
82
  */
123
- private toGePoints;
83
+ static createClosedSpline(fitPoints: AcGePoint3dLike[], parameterization?: AcGeKnotParameterizationType): AcGeSpline3d;
124
84
  }
125
- export {};
126
85
  //# sourceMappingURL=AcGeSpline3d.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AcGeSpline3d.d.ts","sourceRoot":"","sources":["../../src/geometry/AcGeSpline3d.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AcGeSpline3d.d.ts","sourceRoot":"","sources":["../../src/geometry/AcGeSpline3d.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,SAAS,EACT,YAAY,EACZ,WAAW,EACX,eAAe,EACf,aAAa,EACd,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,4BAA4B,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAE/E,qBAAa,YAAa,SAAQ,WAAW;IAC3C,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,UAAU,CAAC,CAAmB;IACtC,OAAO,CAAC,qBAAqB,CAAC,CAA8B;IAC5D,OAAO,CAAC,cAAc,CAAmB;IACzC,OAAO,CAAC,OAAO,CAAS;gBAGtB,aAAa,EAAE,eAAe,EAAE,EAChC,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,CAAC,EAAE,MAAM,EAAE,EAClB,MAAM,CAAC,EAAE,OAAO;gBAGhB,SAAS,EAAE,aAAa,EAAE,EAC1B,SAAS,EAAE,4BAA4B,EACvC,MAAM,CAAC,EAAE,OAAO;IAoElB;;OAEG;IACH,OAAO,CAAC,UAAU;IAgDlB;;OAEG;IACH,OAAO,CAAC,SAAS;IAUjB;;OAEG;IACH,IAAI,MAAM,WAET;IAED,IAAI,oBAAoB,6CAEvB;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,WAAW,CAM5B;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,WAAW,CAM1B;IAED;;OAEG;IACH,IAAI,MAAM,WAET;IAED;;;;;;OAMG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe;IAU7C;;;;;;OAMG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM;IAM/B;;;;;OAKG;IACH,SAAS,CAAC,SAAS,GAAE,MAAY,GAAG,WAAW,EAAE;IAsBjD,cAAc,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM;IAkBnD;;OAEG;IACH,oBAAoB;IAKpB,IAAI,MAAM,IAGQ,OAAO,CADxB;IACD,IAAI,MAAM,CAAC,KAAK,EAAE,OAAO,EAExB;IAED;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,YAAY;IAM/B;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAQrB;;;;;OAKG;IACH,MAAM,CAAC,kBAAkB,CACvB,SAAS,EAAE,eAAe,EAAE,EAC5B,gBAAgB,GAAE,4BAAwC,GACzD,YAAY;CAQhB"}
@@ -13,144 +13,94 @@ var __extends = (this && this.__extends) || (function () {
13
13
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14
14
  };
15
15
  })();
16
- var __read = (this && this.__read) || function (o, n) {
17
- var m = typeof Symbol === "function" && o[Symbol.iterator];
18
- if (!m) return o;
19
- var i = m.call(o), r, ar = [], e;
20
- try {
21
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
22
- }
23
- catch (error) { e = { error: error }; }
24
- finally {
25
- try {
26
- if (r && !r.done && (m = i["return"])) m.call(i);
27
- }
28
- finally { if (e) throw e.error; }
29
- }
30
- return ar;
31
- };
32
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
33
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
34
- if (ar || !(i in from)) {
35
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
36
- ar[i] = from[i];
37
- }
38
- }
39
- return to.concat(ar || Array.prototype.slice.call(from));
40
- };
41
16
  import { AcCmErrors } from '@mlightcad/common';
42
17
  import { AcGeBox3d, AcGePoint3d } from '../math';
43
- import { calculateCurveLength, evaluateNurbsPoint, generateChordKnots, generateSqrtChordKnots, generateUniformKnots, interpolateControlPoints } from '../util';
44
18
  import { AcGeCurve3d } from './AcGeCurve3d';
45
- /**
46
- * Lightweight NURBS curve implementation
47
- */
48
- var NurbsCurve = /** @class */ (function () {
49
- function NurbsCurve(degree, knots, controlPoints, weights) {
50
- this._degree = degree;
51
- this._knots = __spreadArray([], __read(knots), false);
52
- this._controlPoints = controlPoints.map(function (p) { return __spreadArray([], __read(p), false); });
53
- this._weights = weights
54
- ? __spreadArray([], __read(weights), false) : new Array(controlPoints.length).fill(1.0);
55
- }
56
- NurbsCurve.prototype.degree = function () {
57
- return this._degree;
58
- };
59
- NurbsCurve.prototype.knots = function () {
60
- return __spreadArray([], __read(this._knots), false);
61
- };
62
- NurbsCurve.prototype.controlPoints = function () {
63
- return this._controlPoints.map(function (p) { return __spreadArray([], __read(p), false); });
64
- };
65
- NurbsCurve.prototype.weights = function () {
66
- return __spreadArray([], __read(this._weights), false);
67
- };
68
- /**
69
- * Calculate a point on the curve at parameter u
70
- */
71
- NurbsCurve.prototype.point = function (u) {
72
- return evaluateNurbsPoint(u, this._degree, this._knots, this._controlPoints, this._weights);
73
- };
74
- /**
75
- * Calculate curve length using numerical integration
76
- */
77
- NurbsCurve.prototype.length = function () {
78
- return calculateCurveLength(this._degree, this._knots, this._controlPoints, this._weights);
79
- };
80
- /**
81
- * Create a NURBS curve from control points and knots
82
- */
83
- NurbsCurve.byKnotsControlPointsWeights = function (degree, knots, controlPoints, weights) {
84
- return new NurbsCurve(degree, knots, controlPoints, weights);
85
- };
86
- /**
87
- * Create a NURBS curve from fit points using interpolation
88
- */
89
- NurbsCurve.byPoints = function (points, degree, parameterization) {
90
- if (parameterization === void 0) { parameterization = 'Uniform'; }
91
- // Generate knots based on parameterization type
92
- var knots;
93
- switch (parameterization) {
94
- case 'Chord':
95
- knots = generateChordKnots(degree, points);
96
- break;
97
- case 'SqrtChord':
98
- knots = generateSqrtChordKnots(degree, points);
99
- break;
100
- case 'Uniform':
101
- default:
102
- knots = generateUniformKnots(degree, points.length);
103
- break;
104
- }
105
- // Generate control points from fit points
106
- var controlPoints = interpolateControlPoints(points);
107
- var weights = new Array(controlPoints.length).fill(1.0);
108
- return new NurbsCurve(degree, knots, controlPoints, weights);
109
- };
110
- return NurbsCurve;
111
- }());
19
+ import { AcGeNurbsCurve } from './AcGeNurbsCurve';
112
20
  var AcGeSpline3d = /** @class */ (function (_super) {
113
21
  __extends(AcGeSpline3d, _super);
114
- function AcGeSpline3d(a, b, c) {
22
+ function AcGeSpline3d(a, b, c, d) {
115
23
  var _this = _super.call(this) || this;
116
- var argsLength = +(a !== undefined) + +(b !== undefined) + +(c !== undefined);
117
- if (argsLength != 2 && argsLength != 3) {
24
+ var argsLength = +(a !== undefined) +
25
+ +(b !== undefined) +
26
+ +(c !== undefined) +
27
+ +(d !== undefined);
28
+ if (argsLength < 2 || argsLength > 4) {
118
29
  throw AcCmErrors.ILLEGAL_PARAMETERS;
119
30
  }
120
31
  // For now, we support 3 degree only
121
32
  var degree = 3;
122
- _this._closed = false;
123
- if (argsLength == 2 && !Array.isArray(b)) {
33
+ _this._closed = d || false;
34
+ if (!Array.isArray(b)) {
35
+ // Constructor with fit points
124
36
  _this._fitPoints = a;
125
37
  _this._knotParameterization = b;
38
+ // Handle closed parameter for fit points constructor
39
+ if (argsLength >= 3) {
40
+ _this._closed = c;
41
+ }
126
42
  // Validate minimum number of fit points for degree 3
127
43
  if (_this._fitPoints.length < 4) {
128
44
  throw AcCmErrors.ILLEGAL_PARAMETERS;
129
45
  }
130
46
  var points = _this.toNurbsPoints(_this._fitPoints);
131
- _this._nurbsCurve = NurbsCurve.byPoints(points, degree, _this._knotParameterization);
132
- _this._controlPoints = _this.toGePoints(_this._nurbsCurve.controlPoints());
133
- // Store original data for potential reopening
134
- _this._originalControlPoints = __spreadArray([], __read(_this._controlPoints), false);
135
- _this._originalKnots = __spreadArray([], __read(_this._nurbsCurve.knots()), false);
136
- _this._originalWeights = __spreadArray([], __read(_this._nurbsCurve.weights()), false);
47
+ _this._nurbsCurve = AcGeNurbsCurve.byPoints(points, degree, _this._knotParameterization);
48
+ _this._controlPoints = _this._nurbsCurve.controlPoints();
137
49
  }
138
50
  else {
51
+ // Constructor with control points
139
52
  _this._controlPoints = a;
53
+ // Handle closed parameter for control points constructor
54
+ if (argsLength >= 4) {
55
+ _this._closed = d;
56
+ }
140
57
  // Validate minimum number of control points for degree 3
141
58
  if (_this._controlPoints.length < 4) {
142
59
  throw AcCmErrors.ILLEGAL_PARAMETERS;
143
60
  }
144
- var points = _this.toNurbsPoints(_this._controlPoints);
145
- _this._nurbsCurve = NurbsCurve.byKnotsControlPointsWeights(degree, b, points, c);
146
- // Store original data for potential reopening
147
- _this._originalControlPoints = __spreadArray([], __read(_this._controlPoints), false);
148
- _this._originalKnots = __spreadArray([], __read(_this._nurbsCurve.knots()), false);
149
- _this._originalWeights = c
150
- ? __spreadArray([], __read(c), false) : new Array(_this._controlPoints.length).fill(1.0);
61
+ _this._nurbsCurve = AcGeNurbsCurve.byKnotsControlPointsWeights(degree, b, _this._controlPoints, c);
62
+ }
63
+ // Apply closed state if specified
64
+ if (_this._closed) {
65
+ _this.buildCurve();
151
66
  }
152
67
  return _this;
153
68
  }
69
+ /**
70
+ * Build the NURBS curve using stored data
71
+ */
72
+ AcGeSpline3d.prototype.buildCurve = function () {
73
+ var degree = 3;
74
+ if (this._fitPoints && this._knotParameterization) {
75
+ // Build from fit points
76
+ if (this._closed) {
77
+ // Create closed curve from fit points
78
+ this._nurbsCurve = AcGeNurbsCurve.createClosedCurve(this._fitPoints, degree, this._knotParameterization);
79
+ }
80
+ else {
81
+ // Create open curve from fit points
82
+ var points = this.toNurbsPoints(this._fitPoints);
83
+ this._nurbsCurve = AcGeNurbsCurve.byPoints(points, degree, this._knotParameterization);
84
+ }
85
+ this._controlPoints = this._nurbsCurve.controlPoints();
86
+ }
87
+ else if (this._controlPoints) {
88
+ // Build from control points
89
+ if (this._closed) {
90
+ // Create closed curve from control points
91
+ var parameterization = this._knotParameterization || 'Chord';
92
+ this._nurbsCurve = AcGeNurbsCurve.createClosedCurve(this._controlPoints, degree, parameterization);
93
+ this._controlPoints = this._nurbsCurve.controlPoints();
94
+ }
95
+ else {
96
+ // Create open curve from control points
97
+ // Get knots and weights from the current NURBS curve
98
+ var knots = this._nurbsCurve.knots();
99
+ var weights = this._nurbsCurve.weights();
100
+ this._nurbsCurve = AcGeNurbsCurve.byKnotsControlPointsWeights(degree, knots, this._controlPoints, weights);
101
+ }
102
+ }
103
+ };
154
104
  /**
155
105
  * Set the closed property and rebuild the curve if necessary
156
106
  */
@@ -160,57 +110,7 @@ var AcGeSpline3d = /** @class */ (function (_super) {
160
110
  }
161
111
  this._closed = closed;
162
112
  this._boundingBoxNeedsUpdate = true;
163
- if (closed) {
164
- this.makeClosed();
165
- }
166
- else {
167
- this.makeOpen();
168
- }
169
- };
170
- /**
171
- * Make the spline closed by adding control points and adjusting knots
172
- */
173
- AcGeSpline3d.prototype.makeClosed = function () {
174
- var degree = this._nurbsCurve.degree();
175
- var originalControlPoints = this._nurbsCurve.controlPoints();
176
- var originalWeights = this._nurbsCurve.weights();
177
- var n = originalControlPoints.length;
178
- // Append the first 'degree' control points to the end for periodicity
179
- var closedControlPoints = __spreadArray(__spreadArray([], __read(originalControlPoints), false), __read(originalControlPoints.slice(0, degree)), false);
180
- var closedWeights = __spreadArray(__spreadArray([], __read(originalWeights), false), __read(originalWeights.slice(0, degree)), false);
181
- // Create a periodic (non-clamped) uniform knot vector
182
- var closedKnots = this.createClosedKnotVector(n, degree);
183
- // Create new NURBS curve
184
- this._nurbsCurve = NurbsCurve.byKnotsControlPointsWeights(degree, closedKnots, closedControlPoints, closedWeights);
185
- this._controlPoints = this.toGePoints(closedControlPoints);
186
- };
187
- /**
188
- * Make the spline open by restoring the original curve
189
- */
190
- AcGeSpline3d.prototype.makeOpen = function () {
191
- if (!this._originalControlPoints ||
192
- !this._originalKnots ||
193
- !this._originalWeights) {
194
- throw new Error('Original curve data not available');
195
- }
196
- var degree = this._nurbsCurve.degree();
197
- var originalPoints = this.toNurbsPoints(this._originalControlPoints);
198
- // Create new NURBS curve with original data
199
- this._nurbsCurve = NurbsCurve.byKnotsControlPointsWeights(degree, this._originalKnots, originalPoints, this._originalWeights);
200
- this._controlPoints = __spreadArray([], __read(this._originalControlPoints), false);
201
- };
202
- /**
203
- * Create periodic knot vector for closed curve
204
- */
205
- AcGeSpline3d.prototype.createClosedKnotVector = function (n, degree) {
206
- // For periodic B-spline: knots go from 0 to n (not n+degree+1), no repeated knots at ends
207
- // Number of knots = n + 2*degree + 1
208
- var m = n + 2 * degree + 1;
209
- var knots = [];
210
- for (var i = 0; i < m; i++) {
211
- knots.push(i);
212
- }
213
- return knots;
113
+ this.buildCurve();
214
114
  };
215
115
  Object.defineProperty(AcGeSpline3d.prototype, "degree", {
216
116
  /**
@@ -248,10 +148,6 @@ var AcGeSpline3d = /** @class */ (function (_super) {
248
148
  * The end point of this spline
249
149
  */
250
150
  get: function () {
251
- if (this._closed) {
252
- // For closed splines, the end point should be the same as the start point
253
- return this.startPoint;
254
- }
255
151
  var knots = this._nurbsCurve.knots();
256
152
  var degree = this._nurbsCurve.degree();
257
153
  var endParam = knots[knots.length - degree - 1];
@@ -300,38 +196,28 @@ var AcGeSpline3d = /** @class */ (function (_super) {
300
196
  return this._controlPoints[newIndex];
301
197
  };
302
198
  /**
303
- * Divide this spline into the specified number of points
199
+ * Divide this spline into the specified nubmer of points
304
200
  * those points as an array of points.
305
- * @param numPoints Input the number of points returned
201
+ * @param numPoints Input the nubmer of points returned
306
202
  * @returns Return an array of point
307
203
  */
308
204
  AcGeSpline3d.prototype.getPoints = function (numPoints) {
309
205
  if (numPoints === void 0) { numPoints = 100; }
310
206
  var curve = this._nurbsCurve;
311
207
  var points = [];
208
+ // Get the knot vector from the curve
312
209
  var knots = curve.knots();
313
- var degree = curve.degree();
210
+ // The valid parameter range is between knots[degree] and knots[knots.length - degree - 1]
211
+ var degree = this._nurbsCurve.degree();
314
212
  var startParam = knots[degree];
315
213
  var endParam = knots[knots.length - degree - 1];
316
- if (this._closed) {
317
- // Sample numPoints-1 points, then append the first point to close the loop
318
- var period = endParam - startParam;
319
- var step = period / (numPoints - 1);
320
- for (var i = 0; i < numPoints - 1; i++) {
321
- var t = startParam + i * step;
322
- var pt = curve.point(t);
323
- points.push(new AcGePoint3d(pt[0], pt[1], pt[2]));
324
- }
325
- // Append the first point to close the loop
326
- points.push(points[0]);
327
- }
328
- else {
329
- var step = (endParam - startParam) / (numPoints - 1);
330
- for (var i = 0; i < numPoints; i++) {
331
- var t = i === numPoints - 1 ? endParam : startParam + i * step;
332
- var pt = curve.point(t);
333
- points.push(new AcGePoint3d(pt[0], pt[1], pt[2]));
334
- }
214
+ // Adjust step size for correct range
215
+ var step = (endParam - startParam) / (numPoints - 1);
216
+ for (var i = 0; i < numPoints; i++) {
217
+ // For the last point, use endParam exactly to avoid floating-point issues
218
+ var t = i === numPoints - 1 ? endParam : startParam + i * step;
219
+ var point = curve.point(t);
220
+ points.push(new AcGePoint3d(point[0], point[1], point[2]));
335
221
  }
336
222
  return points;
337
223
  };
@@ -386,16 +272,18 @@ var AcGeSpline3d = /** @class */ (function (_super) {
386
272
  return nurbsPoints;
387
273
  };
388
274
  /**
389
- * Convert input points to points in geometry engine format
390
- * @param points Input points to convert
391
- * @returns Return converted points
275
+ * Create a closed spline from fit points using AcGeNurbsCurve.createClosedCurve
276
+ * @param fitPoints - Array of fit points defining the curve
277
+ * @param parameterization - Knot parameterization type for NURBS
278
+ * @returns A closed spline
392
279
  */
393
- AcGeSpline3d.prototype.toGePoints = function (points) {
394
- var gePoints = new Array(points.length);
395
- points.forEach(function (point, index) {
396
- gePoints[index] = { x: point[0], y: point[1], z: point[2] };
397
- });
398
- return gePoints;
280
+ AcGeSpline3d.createClosedSpline = function (fitPoints, parameterization) {
281
+ if (parameterization === void 0) { parameterization = 'Uniform'; }
282
+ if (fitPoints.length < 4) {
283
+ throw new Error('At least 4 points are required for a closed spline');
284
+ }
285
+ // Create spline using the constructor with fit points and closed=true
286
+ return new AcGeSpline3d(fitPoints, parameterization, true);
399
287
  };
400
288
  return AcGeSpline3d;
401
289
  }(AcGeCurve3d));